[OBJ2BIN]
[reactos.git] / reactos / tools / obj2bin / obj2bin.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include "../pecoff.h"
5
6 static
7 void
8 Usage(void)
9 {
10 printf("Converts a coff object file into a raw binary file.\n"
11 "Syntax: obj2bin <source file> <dest file>\n");
12 }
13
14 static
15 void
16 RelocateImage(
17 char *pData,
18 PIMAGE_RELOCATION pReloc,
19 unsigned int cNumRelocs,
20 PIMAGE_SYMBOL pSymbols,
21 unsigned int iOffset)
22 {
23 unsigned int i;
24 WORD *p16;
25
26 for (i = 0; i < cNumRelocs; i++)
27 {
28 switch (pReloc->Type)
29 {
30 case IMAGE_REL_I386_ABSOLUTE:
31 p16 = (void*)(pData + pReloc->VirtualAddress);
32 *p16 = (WORD)(pSymbols[pReloc->SymbolTableIndex].Value + iOffset);
33 break;
34
35 default:
36 printf("Unknown relocatation type %ld\n", pReloc->Type);
37 }
38
39 pReloc++;
40 }
41 }
42
43 int main(int argc, char *argv[])
44 {
45 char *pszSourceFile;
46 char *pszDestFile;
47 unsigned long iOffset;
48 FILE *pSourceFile, *pDestFile;
49 IMAGE_FILE_HEADER FileHeader;
50 IMAGE_SECTION_HEADER SectionHeader;
51 unsigned int i;
52 size_t nSize;
53 void *pData;
54 PIMAGE_RELOCATION pReloc;
55 PIMAGE_SYMBOL pSymbols;
56
57 if ((argc != 4) || (strcmp(argv[1], "--help") == 0))
58 {
59 Usage();
60 return -1;
61 }
62
63 pszSourceFile = argv[1];
64 pszDestFile = argv[2];
65
66 pSourceFile = fopen(pszSourceFile, "rb");
67 if (!pSourceFile)
68 {
69 fprintf(stderr, "Couldn't open source file '%s'\n", pszSourceFile);
70 return -1;
71 }
72
73 pDestFile = fopen(pszDestFile, "wb");
74 if (!pszDestFile)
75 {
76 fprintf(stderr, "Couldn't open dest file '%s'\n", pszDestFile);
77 return -2;
78 }
79
80 iOffset = strtol(argv[3], 0, 16);
81
82 /* Load the coff header */
83 nSize = fread(&FileHeader, 1, sizeof(FileHeader), pSourceFile);
84 if (nSize != sizeof(FileHeader))
85 {
86 fprintf(stderr, "Failed to read source file\n");
87 return -3;
88 }
89
90 /* Jump to section headers (skip optional header) */
91 if (fseek(pSourceFile, FileHeader.SizeOfOptionalHeader, SEEK_CUR))
92 {
93 fprintf(stderr, "Failed to set file pointer\n");
94 return -4;
95 }
96
97 /* Loop all sections */
98 for (i = 0; i < FileHeader.NumberOfSections; i++)
99 {
100 /* Read section header */
101 nSize = fread(&SectionHeader, 1, sizeof(SectionHeader), pSourceFile);
102 if (nSize != sizeof(SectionHeader))
103 {
104 fprintf(stderr, "Failed to read section %ld file\n", i);
105 return -5;
106 }
107
108 /* Check if this is '.text' section */
109 if (strcmp(SectionHeader.Name, ".text") == 0) break;
110 }
111
112 if (i == FileHeader.NumberOfSections)
113 {
114 fprintf(stderr, "No .text section found\n");
115 return -6;
116 }
117
118 /* Move file pointer to the symbol table */
119 if (fseek(pSourceFile, FileHeader.PointerToSymbolTable, SEEK_SET))
120 {
121 fprintf(stderr, "Failed to set file pointer\n");
122 return -7;
123 }
124
125 /* Allocate memory for the symbols */
126 nSize = FileHeader.NumberOfSymbols * sizeof(IMAGE_SYMBOL);
127 pSymbols = malloc(nSize);
128 if (!pSymbols)
129 {
130 fprintf(stderr, "Failed to allocate %ld bytes\n", nSize);
131 return -8;
132 }
133
134 /* Read symbol data */
135 if (!fread(pSymbols, nSize, 1, pSourceFile))
136 {
137 fprintf(stderr, "Failed to read section %ld file\n", i);
138 return -9;
139 }
140
141 /* Move file pointer to the start of the section */
142 if (fseek(pSourceFile, SectionHeader.PointerToRawData, SEEK_SET))
143 {
144 fprintf(stderr, "Failed to set file pointer\n");
145 return -10;
146 }
147
148 /* Allocate memory for the section */
149 pData = malloc(SectionHeader.SizeOfRawData);
150 if (!pData)
151 {
152 fprintf(stderr, "Failed to allocate %ld bytes\n", SectionHeader.SizeOfRawData);
153 return -11;
154 }
155
156 /* Read section data */
157 if (!fread(pData, SectionHeader.SizeOfRawData, 1, pSourceFile))
158 {
159 fprintf(stderr, "Failed to read section %ld file\n", i);
160 return -12;
161 }
162
163 /* Allocate memory for the relocation */
164 nSize = SectionHeader.NumberOfRelocations * sizeof(IMAGE_RELOCATION);
165 pReloc = malloc(nSize);
166 if (!pReloc)
167 {
168 fprintf(stderr, "Failed to allocate %ld bytes\n", nSize);
169 return -13;
170 }
171
172 /* Move file pointer to the relocation table */
173 if (fseek(pSourceFile, SectionHeader.PointerToRelocations, SEEK_SET))
174 {
175 fprintf(stderr, "Failed to set file pointer\n");
176 return -14;
177 }
178
179 /* Read relocation data */
180 if (!fread(pReloc, nSize, 1, pSourceFile))
181 {
182 fprintf(stderr, "Failed to read section %ld file\n", i);
183 return -15;
184 }
185
186 RelocateImage(pData, pReloc, SectionHeader.NumberOfRelocations, pSymbols, iOffset);
187
188 /* Write the section to the destination file */
189 if (!fwrite(pData, SectionHeader.SizeOfRawData, 1, pDestFile))
190 {
191 fprintf(stderr, "Failed to write data\n");
192 return -16;
193 }
194
195 fclose(pDestFile);
196 fclose(pSourceFile);
197
198 return 0;
199 }
200