Subversion Repositories Kolibri OS

Rev

Rev 8959 | Rev 9080 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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