Subversion Repositories Kolibri OS

Rev

Rev 8620 | Rev 8959 | 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
276
	printf("Writing COFF Relocations {\n");
277
	for (size_t sec_i = 0; sec_i < cvec_pchar_size(&ir->section_names_set); sec_i++) {
278
		char *name = ir->section_names_set[sec_i];
279
		SectionInfo si = cdict_CStr_SectionInfo_get_v(&ir->info_per_section, name);
280
 
281
		printf(" Writing relocations of %s {\n", name);
282
		for (size_t i = 0; i < cvec_ObjIdSecId_size(&si.source); i++) {
283
			ObjIdSecId id = cvec_ObjIdSecId_at(&si.source, i);
284
			CoffObject *object = &ir->objects[id.obj_id];
285
			Epep *epep = &object->epep;
286
 
287
			size_t strtab_size = 0;
288
			if (!epep_get_string_table_size(epep, &strtab_size)) {
289
				ERROR_EPEP(epep);
290
			}
291
 
292
			char *obj_strtab = malloc(strtab_size);
293
			if (!epep_get_string_table(epep, obj_strtab)) {
294
				ERROR_EPEP(epep);
295
			}
296
 
297
			EpepSectionHeader sh = { 0 };
298
			if (!epep_get_section_header_by_index(epep, &sh, id.sec_id)) {
299
				ERROR_EPEP(epep);
300
			}
301
			for (size_t rel_i = 0; rel_i < sh.NumberOfRelocations; rel_i++) {
302
				EpepCoffRelocation rel = { 0 };
303
 
304
				if (!epep_get_section_relocation_by_index(epep, &sh, &rel, rel_i)) {
305
					ERROR_EPEP(epep);
306
				}
307
				printf("  { %02x, %02x, %02x }", rel.VirtualAddress, rel.SymbolTableIndex, rel.Type);
308
				rel.VirtualAddress += object->section_offsets[sec_i];
309
				{
310
					size_t index = rel.SymbolTableIndex;
311
					EpepCoffSymbol sym = { 0 };
312
 
313
					if (!epep_get_symbol_by_index(epep, &sym, index)) {
314
						ERROR_EPEP(epep);
315
					}
316
 
317
					size_t name_max = 1024;
318
					char name[name_max];
319
 
320
					if (sym.symbol.Zeroes == 0) {
321
						strcpy(name, &obj_strtab[sym.symbol.Offset]);
322
					} else {
323
						memcpy(name, sym.symbol.ShortName, 8);
324
						name[8] = '\0';
325
					}
326
 
327
					if (!strcmp(name, "_EXPORTS")) {
328
						strcpy(name, "EXPORTS");
329
					}
330
 
331
					if (sym.symbol.StorageClass != 2) {
332
						sprintf(name, "%s@%s", name, object->name);
333
					}
334
 
335
					Symbol old_sym = cdict_CStr_Symbol_get_v(&ir->symtab, name);
336
 
337
					if (old_sym.name == NULL) {
338
						printf("Internal error: Symbol of %s relocation not found", name);
339
						exit(-1);
340
					}
341
 
342
					rel.SymbolTableIndex = old_sym.index;
343
					printf(" -> { %02x, %02x, %02x }: ", rel.VirtualAddress, rel.SymbolTableIndex, rel.Type);
344
					printf("New relocation of %s in %s\n", name, sh.Name);
345
				}
346
				fwrite(&rel, 1, 10, out);
347
			}
348
		}
349
		printf(" }\n");
350
	}
351
	printf("}\n");
352
 
353
	// Symbols Table
354
	printf("Writing symbols {\n");
355
	for (size_t sym_i = 0; sym_i < cvec_pchar_size(&ir->sym_name_set); sym_i++) {
356
		char *name = ir->sym_name_set[sym_i];
357
 
358
		Symbol sym = cdict_CStr_Symbol_get_v(&ir->symtab, name);
359
 
360
		if (sym.sym.symbol.SectionNumber == 0xffff ||
361
			sym.sym.symbol.SectionNumber == 0xfffe ||
362
			(sym.sym.symbol.StorageClass != 2 && sym.sym.symbol.StorageClass != 3)) {
363
			fwrite(&sym.sym.symbol, 1, 18, out);
364
		} else {
365
			size_t sec_name_max = 1024;
366
			char sec_name[sec_name_max];
367
 
368
			size_t object_index = sym.object_index;
369
			CoffObject *object = &ir->objects[object_index];
370
			Epep *epep = &object->epep;
371
			size_t section_offset = object->section_offsets[sym.sym.symbol.SectionNumber - 1];
372
 
373
			size_t strtab_size = 0;
374
			if (!epep_get_string_table_size(epep, &strtab_size)) {
375
				ERROR_EPEP(epep);
376
			}
377
 
378
			char *obj_strtab = malloc(strtab_size);
379
			if (!epep_get_string_table(epep, obj_strtab)) {
380
				ERROR_EPEP(epep);
381
			}
382
 
383
			EpepSectionHeader sh = { 0 };
384
			if (!epep_get_section_header_by_index(epep, &sh, sym.sym.symbol.SectionNumber - 1)) {
385
				ERROR_EPEP(epep);
386
			}
387
 
388
			if (sh.Name[0] == '/') {
389
				strcpy(sec_name, &obj_strtab[atoi(&sh.Name[1])]);
390
			} else {
391
				memcpy(sec_name, sh.Name, 8);
392
				sec_name[8] = '\0';
393
			}
394
 
395
			printf("%s:\n", sym.name);
396
			printf(" Section:      %s\n", sec_name);
397
			printf(" StorageClass: %u\n", sym.sym.symbol.StorageClass);
398
 
399
			sym.sym.symbol.SectionNumber = get_section_number(&ir->section_names_set, sec_name);
400
 
401
			if (sym.sym.symbol.SectionNumber == 0) {
402
				printf("Internal error: %s section is not found in output file");
403
				exit(-1);
404
			}
405
 
406
			sym.sym.symbol.Value += section_offset;
407
 
408
			if (strlen(sym.name) <= 8) {
409
				strcpy(sym.sym.symbol.ShortName, sym.name);
410
			} else {
411
				sym.sym.symbol.Zeroes = 0;
412
				sym.sym.symbol.Offset = strtab_add(&strtab, name);
413
			}
414
 
415
			fwrite(&sym.sym.symbol, 1, 18, out);
416
		}
417
		for (size_t aux_i = 0; aux_i < sym.sym.symbol.NumberOfAuxSymbols; aux_i++) {
418
			fwrite(&sym.auxes[aux_i].symbol, 1, 18, out);
419
		}
420
	}
421
	printf("}\n");
422
 
423
	// COFF String Table
424
	printf("Writing COFF String Table... ");
425
	fwrite32(out, cvec_pchar_size(&strtab) + 4);
426
	fwrite(strtab, 1, cvec_pchar_size(&strtab), out);
427
	printf("Done.\n");
428
}
429
 
430
static ObjectIr parse_objects(int argc, char **argv) {
431
	CoffObject *objects = cvec_CoffObject_new(128);
432
	char **section_names_set = cvec_pchar_new(4);
433
	char **sym_name_set = cvec_pchar_new(128);
434
	size_t number_of_symbols = 0;
435
 
436
	for (int i = 1; i < argc; i++) {
437
		printf("Primary parsing of %s... ", argv[i]);
438
 
439
		CoffObject object = { 0 };
440
		object.name = argv[i];
441
		object.section_offsets = cvec_size_t_new(128);
442
 
443
		{
444
			FILE *fp = fopen(object.name, "rb");
445
			if (!fp) {
446
				printf("Error: Can't open \"%s\"", object.name);
447
				exit(-1);
448
			}
449
 
450
			if (!epep_init(&object.epep, fp)) {
451
				ERROR_EPEP(&object.epep);
452
			}
453
		}
454
 
455
		cvec_CoffObject_push_back(&objects, object);
456
 
457
		printf("Done.\n");
458
	}
459
 
460
	CDict_CStr_Symbol symtab;
461
 
462
	if (!cdict_CStr_Symbol_init(&symtab)) {
463
		ERROR_CDICT(&symtab);
464
	}
465
 
466
	CDict_CStr_SectionInfo info_per_section;
467
 
468
	if (!cdict_CStr_SectionInfo_init(&info_per_section)) {
469
		ERROR_CDICT(&info_per_section);
470
	}
471
 
472
	for (size_t i = 0; i < cvec_CoffObject_size(&objects); i++) {
473
		printf("Secondary parsing of %s {\n", objects[i].name);
474
 
475
		Epep *epep = &(objects[i].epep);
476
 
477
		size_t strtab_size = 0;
478
		if (!epep_get_string_table_size(epep, &strtab_size)) {
479
			ERROR_EPEP(epep);
480
		}
481
 
482
		char *strtab = malloc(strtab_size);
483
		if (!epep_get_string_table(epep, strtab)) {
484
			ERROR_EPEP(epep);
485
		}
486
 
487
		// Fill symbols table
488
		printf(" Symbols {\n");
489
		for (size_t sym_i = 0; sym_i < epep->coffFileHeader.NumberOfSymbols; sym_i++) {
490
			EpepCoffSymbol sym = { 0 };
491
 
492
			if (!epep_get_symbol_by_index(epep, &sym, sym_i)) {
493
				ERROR_EPEP(epep);
494
			}
495
 
496
			size_t name_max = 1024;
497
			char name[name_max];
498
 
499
			if (sym.symbol.Zeroes == 0) {
500
				strcpy(name, &strtab[sym.symbol.Offset]);
501
			} else {
502
				memcpy(name, sym.symbol.ShortName, 8);
503
				name[8] = '\0';
504
			}
505
 
506
			if (!strcmp(name, "_EXPORTS")) {
507
				strcpy(name, "EXPORTS");
508
			}
509
 
510
			if (sym.symbol.StorageClass != 2) {
511
				sprintf(name, "%s@%s", name, objects[i].name);
512
			}
513
 
514
			if (sym.symbol.StorageClass != 2 || sym.symbol.SectionNumber) {
515
				if (memcmp(cdict_CStr_Symbol_get_v(&symtab, name).sym.symbol.ShortName, "\0\0\0\0\0\0\0\0", 8)) {
516
					printf("Error: Redefinition of \"%s\"", name);
517
					exit(-1);
518
				}
519
 
520
				EpepCoffSymbol *auxes = cvec_EpepCoffSymbol_new(1);
521
				size_t index = number_of_symbols;
522
 
523
				for (size_t aux_i = 0; aux_i < sym.symbol.NumberOfAuxSymbols; aux_i++) {
524
					EpepCoffSymbol aux = { 0 };
525
 
526
					if (!epep_get_symbol_by_index(epep, &aux, sym_i + aux_i)) {
527
						ERROR_EPEP(epep);
528
					}
529
					cvec_EpepCoffSymbol_push_back(&auxes, aux);
530
					number_of_symbols++;
531
				}
532
 
533
				Symbol new_sym = { sym, auxes, strdup(name), i, index };
534
				if (!cdict_CStr_Symbol_add_vv(&symtab, strdup(name), new_sym, CDICT_NO_CHECK)) {
535
					ERROR_CDICT(&symtab);
536
				}
537
				number_of_symbols++;
538
 
539
				printf("  Symbol #%u: %s (%u auxes, #%u)\n", sym_i, name, cvec_EpepCoffSymbol_size(&auxes), number_of_symbols - 1);
540
 
541
				add_name_to_set(strdup(name), &sym_name_set);
542
			}
543
 
544
			sym_i += sym.symbol.NumberOfAuxSymbols;
545
		}
546
		printf(" }\n");
547
 
548
		// Set section offsets and fill unique section name set
549
		printf(" Sections {\n");
550
		for (size_t sec_i = 0; sec_i < epep->coffFileHeader.NumberOfSections; sec_i++) {
551
			EpepSectionHeader sh = { 0 };
552
 
553
			if (!epep_get_section_header_by_index(epep, &sh, sec_i)) {
554
				ERROR_EPEP(epep);
555
			}
556
 
557
			size_t name_max = 1024;
558
			char name[name_max];
559
 
560
			if (sh.Name[0] == '/') {
561
				strcpy(name, &strtab[atoi(&sh.Name[1])]);
562
			} else {
563
				memcpy(name, sh.Name, 8);
564
				name[8] = '\0';
565
			}
566
 
567
			add_name_to_set(strdup(name), §ion_names_set);
568
 
569
			SectionInfo si = cdict_CStr_SectionInfo_get_v(&info_per_section, name);
570
			if (si.source == NULL) {
571
				si.source = cvec_ObjIdSecId_new(32);
572
			}
573
 
574
			size_t sec_offset = si.size;
575
			cvec_size_t_push_back(&objects[i].section_offsets, sec_offset);
576
 
577
			si.size += sh.SizeOfRawData;
578
			si.characteristics |= sh.Characteristics;
579
			si.number_of_relocations += sh.NumberOfRelocations;
580
			cvec_ObjIdSecId_push_back(&si.source, (ObjIdSecId){ i, sec_i });
581
			cdict_CStr_SectionInfo_add_vv(&info_per_section, strdup(name), si, CDICT_REPLACE_EXIST);
582
 
583
			printf("  Section #%llu {\n", sec_i);
584
			printf("   Name:                      %s\n", name);
585
			printf("   Virtual Address:           %u\n", sh.VirtualAddress);
586
			printf("   Characteristics:           %08x\n", sh.Characteristics);
587
			printf("   Offset in the big section: %u\n", objects[i].section_offsets[sec_i]);
588
			printf("  }\n");
589
		}
590
		printf(" }\n");
591
		printf("}\n");
592
	}
593
 
594
	ObjectIr ir;
595
	ir.objects = objects;
596
	ir.section_names_set = section_names_set;
597
	ir.info_per_section = info_per_section;
598
	ir.symtab = symtab;
599
	ir.sym_name_set = sym_name_set;
600
	ir.number_of_symbols = number_of_symbols;
601
	return ir;
602
}
603
 
604
int main(int argc, char **argv) {
605
	ObjectIr ir = parse_objects(argc, argv);
606
	build(&ir);
8620 Boppan 607
	return 0;
8579 Boppan 608
}