Rev 8618 | Rev 8948 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
8579 | Boppan | 1 | // TODO: Substract section's RVA from external and static defined symbol's value |
2 | // TODO: Substract section's RVA from relocations |
||
3 | |||
4 | #include |
||
5 | #include |
||
6 | #include |
||
7 | #include |
||
8 | #include |
||
9 | |||
10 | #define EPEP_INST |
||
11 | #include "epep/epep.h" |
||
12 | |||
13 | typedef char *pchar; |
||
14 | |||
15 | typedef struct { |
||
16 | Epep epep; |
||
17 | char *name; |
||
18 | size_t *section_offsets; |
||
19 | } CoffObject; |
||
20 | |||
21 | typedef struct { |
||
22 | size_t obj_id; |
||
23 | size_t sec_id; |
||
24 | } ObjIdSecId; |
||
25 | |||
26 | typedef struct { |
||
27 | ObjIdSecId *source; |
||
28 | uint32_t characteristics; |
||
29 | size_t size; |
||
30 | size_t number_of_relocations; |
||
31 | } SectionInfo; |
||
32 | |||
33 | typedef struct { |
||
34 | EpepCoffSymbol sym; |
||
35 | EpepCoffSymbol *auxes; |
||
36 | char *name; |
||
37 | size_t object_index; |
||
38 | size_t index; |
||
39 | } Symbol; |
||
40 | |||
41 | #define CDICT_VAL_T SectionInfo |
||
42 | #define CDICT_INST |
||
43 | #include "cdict/cdict.h" |
||
44 | |||
45 | #define CDICT_VAL_T Symbol |
||
46 | #define CDICT_INST |
||
47 | #include "cdict/cdict.h" |
||
48 | |||
49 | typedef struct { |
||
50 | CoffObject *objects; |
||
51 | char **section_names_set; |
||
52 | CDict_CStr_SectionInfo info_per_section; |
||
53 | CDict_CStr_Symbol symtab; |
||
54 | char **sym_name_set; |
||
55 | size_t number_of_symbols; |
||
56 | } ObjectIr; |
||
57 | |||
58 | #define CVEC_INST |
||
59 | #define CVEC_TYPE CoffObject |
||
60 | #include "cvec/cvec.h" |
||
61 | |||
62 | #define CVEC_INST |
||
63 | #define CVEC_TYPE size_t |
||
64 | #include "cvec/cvec.h" |
||
65 | |||
66 | #define CVEC_INST |
||
67 | #define CVEC_TYPE pchar |
||
68 | #include "cvec/cvec.h" |
||
69 | |||
70 | #define CVEC_INST |
||
71 | #define CVEC_TYPE char |
||
72 | #include "cvec/cvec.h" |
||
73 | |||
74 | #define CVEC_INST |
||
75 | #define CVEC_TYPE ObjIdSecId |
||
76 | #include "cvec/cvec.h" |
||
77 | |||
78 | #define CVEC_INST |
||
79 | #define CVEC_TYPE EpepCoffSymbol |
||
80 | #include "cvec/cvec.h" |
||
81 | |||
82 | #define ERROR_EPEP(epep) printf("Error: epep returned %u at "__FILE__":%u", \ |
||
83 | (epep)->error_code, __LINE__); exit(-1) |
||
84 | |||
85 | #define ERROR_CDICT(cdict) printf("Error: cdict returned %u at "__FILE__":%u", \ |
||
86 | (cdict)->error_code, __LINE__); exit(-1); |
||
87 | |||
88 | static void fwrite8(FILE *f, uint8_t b) { |
||
89 | fputc(b, f); |
||
90 | } |
||
91 | |||
92 | static void fwrite16(FILE *f, uint16_t w) { |
||
93 | fputc((w & 0x00ff) >> 0, f); |
||
94 | fputc((w & 0xff00) >> 8, f); |
||
95 | } |
||
96 | |||
97 | static void fwrite32(FILE *f, uint32_t d) { |
||
98 | fputc((d & 0x000000ff) >> 0, f); |
||
99 | fputc((d & 0x0000ff00) >> 8, f); |
||
100 | fputc((d & 0x00ff0000) >> 16, f); |
||
101 | fputc((d & 0xff000000) >> 24, f); |
||
102 | } |
||
103 | |||
104 | static size_t strtab_add(char **strtab, char *str) { |
||
105 | size_t res = cvec_char_size(strtab); |
||
106 | |||
107 | for (char *p = str; *p; p++) { |
||
108 | cvec_char_push_back(strtab, *p); |
||
109 | } |
||
110 | cvec_char_push_back(strtab, '\0'); |
||
111 | return res + 4; |
||
112 | } |
||
113 | |||
114 | static size_t get_section_number(char ***section_names_set, char *sec_name) { |
||
115 | for (size_t i = 0; i < cvec_pchar_size(section_names_set); i++) { |
||
116 | char *it = cvec_pchar_at(section_names_set, i); |
||
117 | if (!strcmp(it, sec_name)) { |
||
118 | return i + 1; |
||
119 | } |
||
120 | } |
||
121 | return 0; |
||
122 | } |
||
123 | |||
124 | static void add_name_to_set(char *sym_name, char ***set) { |
||
125 | for (size_t i = 0; i < cvec_pchar_size(set); i++) { |
||
126 | char *it = cvec_pchar_at(set, i); |
||
127 | if (!strcmp(it, sym_name)) { |
||
128 | return; |
||
129 | } |
||
130 | } |
||
131 | cvec_pchar_push_back(set, sym_name); |
||
132 | } |
||
133 | |||
134 | static void build(ObjectIr *ir) { |
||
135 | FILE *out = fopen("a.out.obj", "wb"); |
||
136 | char *strtab = cvec_char_new(1024); |
||
137 | size_t size_of_sections = 0; |
||
138 | size_t number_of_relocations = 0; |
||
139 | |||
140 | printf("Calculating all sections size and relocations count... "); |
||
141 | for (size_t sec_i = 0; sec_i < cvec_pchar_size(&ir->section_names_set); sec_i++) { |
||
142 | char *name = ir->section_names_set[sec_i]; |
||
143 | |||
144 | SectionInfo si = cdict_CStr_SectionInfo_get_v(&ir->info_per_section, name); |
||
145 | size_of_sections += si.size; |
||
146 | number_of_relocations += si.number_of_relocations; |
||
147 | } |
||
148 | printf("Done: %u & %u\n", size_of_sections, number_of_relocations); |
||
149 | |||
150 | size_t fisrt_section_offset = 20 + 40 * cvec_pchar_size(&ir->section_names_set); |
||
151 | size_t offset_to_first_relocation = fisrt_section_offset + size_of_sections; |
||
152 | size_t offset_to_next_relocation = offset_to_first_relocation; |
||
153 | size_t next_section_offset = fisrt_section_offset; |
||
154 | |||
155 | size_t PointerToSymbolTable = fisrt_section_offset + size_of_sections + number_of_relocations * 10; |
||
156 | |||
157 | // COFF Header |
||
158 | printf("Writing COFF header... "); |
||
159 | fwrite16(out, 0x14c); // Machine |
||
160 | fwrite16(out, cvec_pchar_size(&ir->section_names_set)); // NumberOfSections |
||
161 | fwrite32(out, 0); // TimeDataStamp |
||
162 | fwrite32(out, PointerToSymbolTable); // PointerToSymbolTable |
||
163 | fwrite32(out, ir->number_of_symbols); // NumberOfSymbols |
||
164 | fwrite16(out, 0); // SizeOfOptionalHeader |
||
165 | fwrite16(out, 0); // Characteristics |
||
166 | printf("Done.\n"); |
||
167 | |||
168 | // Section Headers |
||
169 | printf("Writing section headers {\n"); |
||
170 | for (size_t sec_i = 0; sec_i < cvec_pchar_size(&ir->section_names_set); sec_i++) { |
||
171 | char *name = ir->section_names_set[sec_i]; |
||
172 | SectionInfo si = cdict_CStr_SectionInfo_get_v(&ir->info_per_section, name); |
||
173 | |||
174 | // Name |
||
175 | printf(" Writing %s Section Header... ", name); |
||
176 | if (strlen(name) <= 8) { |
||
177 | for (size_t i = 0; i < 8; i++) { |
||
178 | size_t sl = strlen(name); |
||
179 | fwrite8(out, i < sl ? name[i] : '\0'); |
||
180 | } |
||
181 | } else { |
||
182 | fwrite8(out, '/'); |
||
183 | |||
184 | size_t strtab_index = strtab_add(&strtab, name); |
||
185 | char numstr[8] = { 0 }; |
||
186 | sprintf(numstr, "%u", strtab_index); |
||
187 | fwrite(numstr, 1, 7, out); |
||
188 | } |
||
189 | fwrite32(out, 0); // VirtualSize |
||
190 | fwrite32(out, 0); // VirtualAddress |
||
191 | fwrite32(out, si.size); // SizeOfRawData |
||
192 | fwrite32(out, next_section_offset); // PointerToRawData |
||
193 | next_section_offset += si.size; |
||
194 | fwrite32(out, offset_to_next_relocation); // PointerToRelocations |
||
195 | offset_to_next_relocation += si.number_of_relocations * 10; |
||
196 | fwrite32(out, 0); // PointerToLinenumbers |
||
197 | fwrite16(out, si.number_of_relocations); // NumberOfRelocations |
||
198 | fwrite16(out, 0); // NumberOfLinenumbers |
||
199 | fwrite32(out, si.characteristics); // Characteristics |
||
200 | printf("Done.\n"); |
||
201 | } |
||
202 | printf("}\n"); |
||
203 | |||
204 | // Section data |
||
205 | printf("Writing sections {\n"); |
||
206 | for (size_t sec_i = 0; sec_i < cvec_pchar_size(&ir->section_names_set); sec_i++) { |
||
207 | char *name = ir->section_names_set[sec_i]; |
||
208 | SectionInfo si = cdict_CStr_SectionInfo_get_v(&ir->info_per_section, name); |
||
209 | |||
210 | printf(" Writing %s... ", name); |
||
211 | for (size_t i = 0; i < cvec_ObjIdSecId_size(&si.source); i++) { |
||
212 | ObjIdSecId id = cvec_ObjIdSecId_at(&si.source, i); |
||
213 | CoffObject *object = &ir->objects[id.obj_id]; |
||
214 | Epep *epep = &object->epep; |
||
215 | |||
216 | EpepSectionHeader sh = { 0 }; |
||
217 | if (!epep_get_section_header_by_index(epep, &sh, id.sec_id)) { |
||
218 | ERROR_EPEP(epep); |
||
219 | } |
||
8618 | Boppan | 220 | |
221 | // If the section contains uninitialized data (BSS) |
||
222 | // it should be filled by zeroes |
||
223 | // Yes, current implementation emits BSS sections too |
||
224 | // cause KOS has no idea they should be allocated automatically |
||
225 | // cause FASM has no idea they should be generated without contents |
||
226 | // cause Tomasz Grysztar didn't care |
||
227 | char *buf = calloc(sh.SizeOfRawData, 1); |
||
228 | |||
229 | // Othervice it should be filled by its contents from source object |
||
230 | if (!(sh.Characteristics & 0x00000080)) { |
||
231 | if (!epep_get_section_contents(epep, &sh, buf)) { |
||
232 | ERROR_EPEP(epep); |
||
233 | } |
||
8579 | Boppan | 234 | } |
8618 | Boppan | 235 | |
8579 | Boppan | 236 | fwrite(buf, 1, sh.SizeOfRawData, out); |
237 | } |
||
238 | printf("Done.\n"); |
||
239 | } |
||
240 | printf("}\n"); |
||
241 | |||
242 | // COFF Relocations |
||
243 | printf("Writing COFF Relocations {\n"); |
||
244 | for (size_t sec_i = 0; sec_i < cvec_pchar_size(&ir->section_names_set); sec_i++) { |
||
245 | char *name = ir->section_names_set[sec_i]; |
||
246 | SectionInfo si = cdict_CStr_SectionInfo_get_v(&ir->info_per_section, name); |
||
247 | |||
248 | printf(" Writing relocations of %s {\n", name); |
||
249 | for (size_t i = 0; i < cvec_ObjIdSecId_size(&si.source); i++) { |
||
250 | ObjIdSecId id = cvec_ObjIdSecId_at(&si.source, i); |
||
251 | CoffObject *object = &ir->objects[id.obj_id]; |
||
252 | Epep *epep = &object->epep; |
||
253 | |||
254 | size_t strtab_size = 0; |
||
255 | if (!epep_get_string_table_size(epep, &strtab_size)) { |
||
256 | ERROR_EPEP(epep); |
||
257 | } |
||
258 | |||
259 | char *obj_strtab = malloc(strtab_size); |
||
260 | if (!epep_get_string_table(epep, obj_strtab)) { |
||
261 | ERROR_EPEP(epep); |
||
262 | } |
||
263 | |||
264 | EpepSectionHeader sh = { 0 }; |
||
265 | if (!epep_get_section_header_by_index(epep, &sh, id.sec_id)) { |
||
266 | ERROR_EPEP(epep); |
||
267 | } |
||
268 | for (size_t rel_i = 0; rel_i < sh.NumberOfRelocations; rel_i++) { |
||
269 | EpepCoffRelocation rel = { 0 }; |
||
270 | |||
271 | if (!epep_get_section_relocation_by_index(epep, &sh, &rel, rel_i)) { |
||
272 | ERROR_EPEP(epep); |
||
273 | } |
||
274 | printf(" { %02x, %02x, %02x }", rel.VirtualAddress, rel.SymbolTableIndex, rel.Type); |
||
275 | rel.VirtualAddress += object->section_offsets[sec_i]; |
||
276 | { |
||
277 | size_t index = rel.SymbolTableIndex; |
||
278 | EpepCoffSymbol sym = { 0 }; |
||
279 | |||
280 | if (!epep_get_symbol_by_index(epep, &sym, index)) { |
||
281 | ERROR_EPEP(epep); |
||
282 | } |
||
283 | |||
284 | size_t name_max = 1024; |
||
285 | char name[name_max]; |
||
286 | |||
287 | if (sym.symbol.Zeroes == 0) { |
||
288 | strcpy(name, &obj_strtab[sym.symbol.Offset]); |
||
289 | } else { |
||
290 | memcpy(name, sym.symbol.ShortName, 8); |
||
291 | name[8] = '\0'; |
||
292 | } |
||
293 | |||
294 | if (!strcmp(name, "_EXPORTS")) { |
||
295 | strcpy(name, "EXPORTS"); |
||
296 | } |
||
297 | |||
298 | if (sym.symbol.StorageClass != 2) { |
||
299 | sprintf(name, "%s@%s", name, object->name); |
||
300 | } |
||
301 | |||
302 | Symbol old_sym = cdict_CStr_Symbol_get_v(&ir->symtab, name); |
||
303 | |||
304 | if (old_sym.name == NULL) { |
||
305 | printf("Internal error: Symbol of %s relocation not found", name); |
||
306 | exit(-1); |
||
307 | } |
||
308 | |||
309 | rel.SymbolTableIndex = old_sym.index; |
||
310 | printf(" -> { %02x, %02x, %02x }: ", rel.VirtualAddress, rel.SymbolTableIndex, rel.Type); |
||
311 | printf("New relocation of %s in %s\n", name, sh.Name); |
||
312 | } |
||
313 | fwrite(&rel, 1, 10, out); |
||
314 | } |
||
315 | } |
||
316 | printf(" }\n"); |
||
317 | } |
||
318 | printf("}\n"); |
||
319 | |||
320 | // Symbols Table |
||
321 | printf("Writing symbols {\n"); |
||
322 | for (size_t sym_i = 0; sym_i < cvec_pchar_size(&ir->sym_name_set); sym_i++) { |
||
323 | char *name = ir->sym_name_set[sym_i]; |
||
324 | |||
325 | Symbol sym = cdict_CStr_Symbol_get_v(&ir->symtab, name); |
||
326 | |||
327 | if (sym.sym.symbol.SectionNumber == 0xffff || |
||
328 | sym.sym.symbol.SectionNumber == 0xfffe || |
||
329 | (sym.sym.symbol.StorageClass != 2 && sym.sym.symbol.StorageClass != 3)) { |
||
330 | fwrite(&sym.sym.symbol, 1, 18, out); |
||
331 | } else { |
||
332 | size_t sec_name_max = 1024; |
||
333 | char sec_name[sec_name_max]; |
||
334 | |||
335 | size_t object_index = sym.object_index; |
||
336 | CoffObject *object = &ir->objects[object_index]; |
||
337 | Epep *epep = &object->epep; |
||
338 | size_t section_offset = object->section_offsets[sym.sym.symbol.SectionNumber - 1]; |
||
339 | |||
340 | size_t strtab_size = 0; |
||
341 | if (!epep_get_string_table_size(epep, &strtab_size)) { |
||
342 | ERROR_EPEP(epep); |
||
343 | } |
||
344 | |||
345 | char *obj_strtab = malloc(strtab_size); |
||
346 | if (!epep_get_string_table(epep, obj_strtab)) { |
||
347 | ERROR_EPEP(epep); |
||
348 | } |
||
349 | |||
350 | EpepSectionHeader sh = { 0 }; |
||
351 | if (!epep_get_section_header_by_index(epep, &sh, sym.sym.symbol.SectionNumber - 1)) { |
||
352 | ERROR_EPEP(epep); |
||
353 | } |
||
354 | |||
355 | if (sh.Name[0] == '/') { |
||
356 | strcpy(sec_name, &obj_strtab[atoi(&sh.Name[1])]); |
||
357 | } else { |
||
358 | memcpy(sec_name, sh.Name, 8); |
||
359 | sec_name[8] = '\0'; |
||
360 | } |
||
361 | |||
362 | printf("%s:\n", sym.name); |
||
363 | printf(" Section: %s\n", sec_name); |
||
364 | printf(" StorageClass: %u\n", sym.sym.symbol.StorageClass); |
||
365 | |||
366 | sym.sym.symbol.SectionNumber = get_section_number(&ir->section_names_set, sec_name); |
||
367 | |||
368 | if (sym.sym.symbol.SectionNumber == 0) { |
||
369 | printf("Internal error: %s section is not found in output file"); |
||
370 | exit(-1); |
||
371 | } |
||
372 | |||
373 | sym.sym.symbol.Value += section_offset; |
||
374 | |||
375 | if (strlen(sym.name) <= 8) { |
||
376 | strcpy(sym.sym.symbol.ShortName, sym.name); |
||
377 | } else { |
||
378 | sym.sym.symbol.Zeroes = 0; |
||
379 | sym.sym.symbol.Offset = strtab_add(&strtab, name); |
||
380 | } |
||
381 | |||
382 | fwrite(&sym.sym.symbol, 1, 18, out); |
||
383 | } |
||
384 | for (size_t aux_i = 0; aux_i < sym.sym.symbol.NumberOfAuxSymbols; aux_i++) { |
||
385 | fwrite(&sym.auxes[aux_i].symbol, 1, 18, out); |
||
386 | } |
||
387 | } |
||
388 | printf("}\n"); |
||
389 | |||
390 | // COFF String Table |
||
391 | printf("Writing COFF String Table... "); |
||
392 | fwrite32(out, cvec_pchar_size(&strtab) + 4); |
||
393 | fwrite(strtab, 1, cvec_pchar_size(&strtab), out); |
||
394 | printf("Done.\n"); |
||
395 | } |
||
396 | |||
397 | static ObjectIr parse_objects(int argc, char **argv) { |
||
398 | CoffObject *objects = cvec_CoffObject_new(128); |
||
399 | char **section_names_set = cvec_pchar_new(4); |
||
400 | char **sym_name_set = cvec_pchar_new(128); |
||
401 | size_t number_of_symbols = 0; |
||
402 | |||
403 | for (int i = 1; i < argc; i++) { |
||
404 | printf("Primary parsing of %s... ", argv[i]); |
||
405 | |||
406 | CoffObject object = { 0 }; |
||
407 | object.name = argv[i]; |
||
408 | object.section_offsets = cvec_size_t_new(128); |
||
409 | |||
410 | { |
||
411 | FILE *fp = fopen(object.name, "rb"); |
||
412 | if (!fp) { |
||
413 | printf("Error: Can't open \"%s\"", object.name); |
||
414 | exit(-1); |
||
415 | } |
||
416 | |||
417 | if (!epep_init(&object.epep, fp)) { |
||
418 | ERROR_EPEP(&object.epep); |
||
419 | } |
||
420 | } |
||
421 | |||
422 | cvec_CoffObject_push_back(&objects, object); |
||
423 | |||
424 | printf("Done.\n"); |
||
425 | } |
||
426 | |||
427 | CDict_CStr_Symbol symtab; |
||
428 | |||
429 | if (!cdict_CStr_Symbol_init(&symtab)) { |
||
430 | ERROR_CDICT(&symtab); |
||
431 | } |
||
432 | |||
433 | CDict_CStr_SectionInfo info_per_section; |
||
434 | |||
435 | if (!cdict_CStr_SectionInfo_init(&info_per_section)) { |
||
436 | ERROR_CDICT(&info_per_section); |
||
437 | } |
||
438 | |||
439 | for (size_t i = 0; i < cvec_CoffObject_size(&objects); i++) { |
||
440 | printf("Secondary parsing of %s {\n", objects[i].name); |
||
441 | |||
442 | Epep *epep = &(objects[i].epep); |
||
443 | |||
444 | size_t strtab_size = 0; |
||
445 | if (!epep_get_string_table_size(epep, &strtab_size)) { |
||
446 | ERROR_EPEP(epep); |
||
447 | } |
||
448 | |||
449 | char *strtab = malloc(strtab_size); |
||
450 | if (!epep_get_string_table(epep, strtab)) { |
||
451 | ERROR_EPEP(epep); |
||
452 | } |
||
453 | |||
454 | // Fill symbols table |
||
455 | printf(" Symbols {\n"); |
||
456 | for (size_t sym_i = 0; sym_i < epep->coffFileHeader.NumberOfSymbols; sym_i++) { |
||
457 | EpepCoffSymbol sym = { 0 }; |
||
458 | |||
459 | if (!epep_get_symbol_by_index(epep, &sym, sym_i)) { |
||
460 | ERROR_EPEP(epep); |
||
461 | } |
||
462 | |||
463 | size_t name_max = 1024; |
||
464 | char name[name_max]; |
||
465 | |||
466 | if (sym.symbol.Zeroes == 0) { |
||
467 | strcpy(name, &strtab[sym.symbol.Offset]); |
||
468 | } else { |
||
469 | memcpy(name, sym.symbol.ShortName, 8); |
||
470 | name[8] = '\0'; |
||
471 | } |
||
472 | |||
473 | if (!strcmp(name, "_EXPORTS")) { |
||
474 | strcpy(name, "EXPORTS"); |
||
475 | } |
||
476 | |||
477 | if (sym.symbol.StorageClass != 2) { |
||
478 | sprintf(name, "%s@%s", name, objects[i].name); |
||
479 | } |
||
480 | |||
481 | if (sym.symbol.StorageClass != 2 || sym.symbol.SectionNumber) { |
||
482 | if (memcmp(cdict_CStr_Symbol_get_v(&symtab, name).sym.symbol.ShortName, "\0\0\0\0\0\0\0\0", 8)) { |
||
483 | printf("Error: Redefinition of \"%s\"", name); |
||
484 | exit(-1); |
||
485 | } |
||
486 | |||
487 | EpepCoffSymbol *auxes = cvec_EpepCoffSymbol_new(1); |
||
488 | size_t index = number_of_symbols; |
||
489 | |||
490 | for (size_t aux_i = 0; aux_i < sym.symbol.NumberOfAuxSymbols; aux_i++) { |
||
491 | EpepCoffSymbol aux = { 0 }; |
||
492 | |||
493 | if (!epep_get_symbol_by_index(epep, &aux, sym_i + aux_i)) { |
||
494 | ERROR_EPEP(epep); |
||
495 | } |
||
496 | cvec_EpepCoffSymbol_push_back(&auxes, aux); |
||
497 | number_of_symbols++; |
||
498 | } |
||
499 | |||
500 | Symbol new_sym = { sym, auxes, strdup(name), i, index }; |
||
501 | if (!cdict_CStr_Symbol_add_vv(&symtab, strdup(name), new_sym, CDICT_NO_CHECK)) { |
||
502 | ERROR_CDICT(&symtab); |
||
503 | } |
||
504 | number_of_symbols++; |
||
505 | |||
506 | printf(" Symbol #%u: %s (%u auxes, #%u)\n", sym_i, name, cvec_EpepCoffSymbol_size(&auxes), number_of_symbols - 1); |
||
507 | |||
508 | add_name_to_set(strdup(name), &sym_name_set); |
||
509 | } |
||
510 | |||
511 | sym_i += sym.symbol.NumberOfAuxSymbols; |
||
512 | } |
||
513 | printf(" }\n"); |
||
514 | |||
515 | // Set section offsets and fill unique section name set |
||
516 | printf(" Sections {\n"); |
||
517 | for (size_t sec_i = 0; sec_i < epep->coffFileHeader.NumberOfSections; sec_i++) { |
||
518 | EpepSectionHeader sh = { 0 }; |
||
519 | |||
520 | if (!epep_get_section_header_by_index(epep, &sh, sec_i)) { |
||
521 | ERROR_EPEP(epep); |
||
522 | } |
||
523 | |||
524 | size_t name_max = 1024; |
||
525 | char name[name_max]; |
||
526 | |||
527 | if (sh.Name[0] == '/') { |
||
528 | strcpy(name, &strtab[atoi(&sh.Name[1])]); |
||
529 | } else { |
||
530 | memcpy(name, sh.Name, 8); |
||
531 | name[8] = '\0'; |
||
532 | } |
||
533 | |||
534 | add_name_to_set(strdup(name), §ion_names_set); |
||
535 | |||
536 | SectionInfo si = cdict_CStr_SectionInfo_get_v(&info_per_section, name); |
||
537 | if (si.source == NULL) { |
||
538 | si.source = cvec_ObjIdSecId_new(32); |
||
539 | } |
||
540 | |||
541 | size_t sec_offset = si.size; |
||
542 | cvec_size_t_push_back(&objects[i].section_offsets, sec_offset); |
||
543 | |||
544 | si.size += sh.SizeOfRawData; |
||
545 | si.characteristics |= sh.Characteristics; |
||
546 | si.number_of_relocations += sh.NumberOfRelocations; |
||
547 | cvec_ObjIdSecId_push_back(&si.source, (ObjIdSecId){ i, sec_i }); |
||
548 | cdict_CStr_SectionInfo_add_vv(&info_per_section, strdup(name), si, CDICT_REPLACE_EXIST); |
||
549 | |||
550 | printf(" Section #%llu {\n", sec_i); |
||
551 | printf(" Name: %s\n", name); |
||
552 | printf(" Virtual Address: %u\n", sh.VirtualAddress); |
||
553 | printf(" Characteristics: %08x\n", sh.Characteristics); |
||
554 | printf(" Offset in the big section: %u\n", objects[i].section_offsets[sec_i]); |
||
555 | printf(" }\n"); |
||
556 | } |
||
557 | printf(" }\n"); |
||
558 | printf("}\n"); |
||
559 | } |
||
560 | |||
561 | ObjectIr ir; |
||
562 | ir.objects = objects; |
||
563 | ir.section_names_set = section_names_set; |
||
564 | ir.info_per_section = info_per_section; |
||
565 | ir.symtab = symtab; |
||
566 | ir.sym_name_set = sym_name_set; |
||
567 | ir.number_of_symbols = number_of_symbols; |
||
568 | return ir; |
||
569 | } |
||
570 | |||
571 | int main(int argc, char **argv) { |
||
572 | ObjectIr ir = parse_objects(argc, argv); |
||
573 | build(&ir); |
||
8620 | Boppan | 574 | return 0; |
8579 | Boppan | 575 | }>>>>>>=>>>>>>>>>=>>>>> |