Subversion Repositories Kolibri OS

Rev

Rev 9080 | Rev 9085 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 9080 Rev 9084
Line 116... Line 116...
116
                                (epep)->error_code, epep_errors[(epep)->error_code], __LINE__); exit(-1)
116
                                (epep)->error_code, epep_errors[(epep)->error_code], __LINE__); exit(-1)
Line 117... Line 117...
117
 
117
 
118
#define ERROR_CDICT(cdict) printf("Error: cdict returned %u at "__FILE__":%u", \
118
#define ERROR_CDICT(cdict) printf("Error: cdict returned %u at "__FILE__":%u", \
Line -... Line 119...
-
 
119
                                  (cdict)->error_code, __LINE__); exit(-1);
-
 
120
 
-
 
121
static int emit_logs;
-
 
122
 
-
 
123
static int log_info(const char *fmt, ...) {
-
 
124
	if (emit_logs) {
-
 
125
		va_list ap;
-
 
126
		va_start(ap, fmt);
-
 
127
		vprintf(fmt, ap);
-
 
128
		va_end(ap);
-
 
129
	}
119
                                  (cdict)->error_code, __LINE__); exit(-1);
130
}
120
 
131
 
121
static void fwrite8(FILE *f, uint8_t b) {
132
static void fwrite8(FILE *f, uint8_t b) {
Line 122... Line 133...
122
	fputc(b, f);
133
	fputc(b, f);
Line 168... Line 179...
168
	FILE *out = fopen(outname, "wb");
179
	FILE *out = fopen(outname, "wb");
169
	char *strtab = cvec_char_new(1024);
180
	char *strtab = cvec_char_new(1024);
170
	size_t size_of_sections = 0;
181
	size_t size_of_sections = 0;
171
	size_t number_of_relocations = 0;
182
	size_t number_of_relocations = 0;
Line 172... Line 183...
172
 
183
 
173
	printf("Calculating all sections size and relocations count... ");
184
	log_info("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++) {
185
	for (size_t sec_i = 0; sec_i < cvec_pchar_size(&ir->section_names_set); sec_i++) {
Line 175... Line 186...
175
		char *name = ir->section_names_set[sec_i];
186
		char *name = ir->section_names_set[sec_i];
176
 
187
 
177
		SectionInfo si = cdict_CStr_SectionInfo_get_v(&ir->info_per_section, name);
188
		SectionInfo si = cdict_CStr_SectionInfo_get_v(&ir->info_per_section, name);
178
		size_of_sections += si.size;
189
		size_of_sections += si.size;
179
		number_of_relocations += si.number_of_relocations;
190
		number_of_relocations += si.number_of_relocations;
Line 180... Line 191...
180
	}
191
	}
181
	printf("Done: %u & %u\n", size_of_sections, number_of_relocations);
192
	log_info("Done: %u & %u\n", size_of_sections, number_of_relocations);
182
 
193
 
183
	size_t fisrt_section_offset = 20 + 40 * cvec_pchar_size(&ir->section_names_set);
194
	size_t fisrt_section_offset = 20 + 40 * cvec_pchar_size(&ir->section_names_set);
Line 184... Line 195...
184
	size_t offset_to_first_relocation = fisrt_section_offset + size_of_sections;
195
	size_t offset_to_first_relocation = fisrt_section_offset + size_of_sections;
Line 185... Line 196...
185
	size_t offset_to_next_relocation = offset_to_first_relocation;
196
	size_t offset_to_next_relocation = offset_to_first_relocation;
186
	size_t next_section_offset = fisrt_section_offset;
197
	size_t next_section_offset = fisrt_section_offset;
187
 
198
 
188
	size_t PointerToSymbolTable = fisrt_section_offset + size_of_sections + number_of_relocations * 10;
199
	size_t PointerToSymbolTable = fisrt_section_offset + size_of_sections + number_of_relocations * 10;
189
 
200
 
190
	// COFF Header
201
	// COFF Header
191
	printf("Writing COFF header... ");
202
	log_info("Writing COFF header... ");
192
	fwrite16(out, 0x14c);                                   // Machine
203
	fwrite16(out, 0x14c);                                   // Machine
193
	fwrite16(out, cvec_pchar_size(&ir->section_names_set)); // NumberOfSections
204
	fwrite16(out, cvec_pchar_size(&ir->section_names_set)); // NumberOfSections
194
	fwrite32(out, 0);                                       // TimeDataStamp
205
	fwrite32(out, 0);                                       // TimeDataStamp
Line 195... Line 206...
195
	fwrite32(out, PointerToSymbolTable);                    // PointerToSymbolTable
206
	fwrite32(out, PointerToSymbolTable);                    // PointerToSymbolTable
196
	fwrite32(out, ir->number_of_symbols);                   // NumberOfSymbols
207
	fwrite32(out, ir->number_of_symbols);                   // NumberOfSymbols
197
	fwrite16(out, 0);                                       // SizeOfOptionalHeader
208
	fwrite16(out, 0);                                       // SizeOfOptionalHeader
198
	fwrite16(out, 0);                                       // Characteristics
209
	fwrite16(out, 0);                                       // Characteristics
199
	printf("Done.\n");
210
	log_info("Done.\n");
Line 200... Line 211...
200
 
211
 
201
	// Section Headers
212
	// Section Headers
202
	printf("Writing section headers {\n");
213
	log_info("Writing section headers {\n");
203
	for (size_t sec_i = 0; sec_i < cvec_pchar_size(&ir->section_names_set); sec_i++) {
214
	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];
215
		char *name = ir->section_names_set[sec_i];
205
		SectionInfo si = cdict_CStr_SectionInfo_get_v(&ir->info_per_section, name);
216
		SectionInfo si = cdict_CStr_SectionInfo_get_v(&ir->info_per_section, name);
206
 
217
 
Line 228... Line 239...
228
		offset_to_next_relocation += si.number_of_relocations * 10;
239
		offset_to_next_relocation += si.number_of_relocations * 10;
229
		fwrite32(out, 0);                         // PointerToLinenumbers
240
		fwrite32(out, 0);                         // PointerToLinenumbers
230
		fwrite16(out, si.number_of_relocations);  // NumberOfRelocations
241
		fwrite16(out, si.number_of_relocations);  // NumberOfRelocations
231
		fwrite16(out, 0);                         // NumberOfLinenumbers
242
		fwrite16(out, 0);                         // NumberOfLinenumbers
232
		fwrite32(out, si.characteristics);        // Characteristics
243
		fwrite32(out, si.characteristics);        // Characteristics
233
		printf("Done.\n");
244
		log_info("Done.\n");
234
	}
245
	}
235
	printf("}\n");
246
	log_info("}\n");
Line 236... Line 247...
236
 
247
 
237
	// Section data
248
	// Section data
238
	printf("Writing sections {\n");
249
	log_info("Writing sections {\n");
239
	for (size_t sec_i = 0; sec_i < cvec_pchar_size(&ir->section_names_set); sec_i++) {
250
	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];
251
		char *name = ir->section_names_set[sec_i];
Line 241... Line 252...
241
		SectionInfo si = cdict_CStr_SectionInfo_get_v(&ir->info_per_section, name);
252
		SectionInfo si = cdict_CStr_SectionInfo_get_v(&ir->info_per_section, name);
242
 
253
 
243
		printf(" Writing %s... ", name);
254
		log_info(" Writing %s... ", name);
244
		for (size_t i = 0; i < cvec_ObjIdSecId_size(&si.source); i++) {
255
		for (size_t i = 0; i < cvec_ObjIdSecId_size(&si.source); i++) {
245
			ObjIdSecId id = cvec_ObjIdSecId_at(&si.source, i);
256
			ObjIdSecId id = cvec_ObjIdSecId_at(&si.source, i);
Line 266... Line 277...
266
				}
277
				}
267
			}
278
			}
Line 268... Line 279...
268
 
279
 
269
			fwrite(buf, 1, sh.SizeOfRawData, out);
280
			fwrite(buf, 1, sh.SizeOfRawData, out);
270
		}
281
		}
271
		printf("Done.\n");
282
		log_info("Done.\n");
272
	}
283
	}
Line 273... Line 284...
273
	printf("}\n");
284
	log_info("}\n");
274
 
285
 
Line 275... Line 286...
275
	// COFF Relocations
286
	// COFF Relocations
276
	char **undefined_symbols = cvec_pchar_new(8);
287
	char **undefined_symbols = cvec_pchar_new(8);
277
 
288
 
278
	printf("Writing COFF Relocations {\n");
289
	log_info("Writing COFF Relocations {\n");
Line 279... Line 290...
279
	for (size_t sec_i = 0; sec_i < cvec_pchar_size(&ir->section_names_set); sec_i++) {
290
	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];
291
		char *name = ir->section_names_set[sec_i];
281
		SectionInfo si = cdict_CStr_SectionInfo_get_v(&ir->info_per_section, name);
292
		SectionInfo si = cdict_CStr_SectionInfo_get_v(&ir->info_per_section, name);
282
 
293
 
283
		printf(" Writing relocations of %s {\n", name);
294
		log_info(" Writing relocations of %s {\n", name);
Line 304... Line 315...
304
				EpepCoffRelocation rel = { 0 };
315
				EpepCoffRelocation rel = { 0 };
Line 305... Line 316...
305
 
316
 
306
				if (!epep_get_section_relocation_by_index(epep, &sh, &rel, rel_i)) {
317
				if (!epep_get_section_relocation_by_index(epep, &sh, &rel, rel_i)) {
307
					ERROR_EPEP(epep);
318
					ERROR_EPEP(epep);
308
				}
319
				}
309
				printf("  { %02x, %02x, %02x }", rel.VirtualAddress, rel.SymbolTableIndex, rel.Type);
320
				log_info("  { %02x, %02x, %02x }", rel.VirtualAddress, rel.SymbolTableIndex, rel.Type);
310
				rel.VirtualAddress += object->section_offsets[sec_i];
321
				rel.VirtualAddress += object->section_offsets[sec_i];
311
				{
322
				{
312
					size_t index = rel.SymbolTableIndex;
323
					size_t index = rel.SymbolTableIndex;
Line 339... Line 350...
339
					if (old_sym.name == NULL) {
350
					if (old_sym.name == NULL) {
340
						add_name_to_set(strdup(name), &undefined_symbols);
351
						add_name_to_set(strdup(name), &undefined_symbols);
341
					}
352
					}
Line 342... Line 353...
342
 
353
 
343
					rel.SymbolTableIndex = old_sym.index;
354
					rel.SymbolTableIndex = old_sym.index;
344
					printf(" -> { %02x, %02x, %02x }: ", rel.VirtualAddress, rel.SymbolTableIndex, rel.Type);
355
					log_info(" -> { %02x, %02x, %02x }: ", rel.VirtualAddress, rel.SymbolTableIndex, rel.Type);
345
					printf("New relocation of %s in %s\n", name, sh.Name);
356
					log_info("New relocation of %s in %s\n", name, sh.Name);
346
				}
357
				}
347
				fwrite(&rel, 1, 10, out);
358
				fwrite(&rel, 1, 10, out);
348
			}
359
			}
349
		}
360
		}
350
		printf(" }\n");
361
		log_info(" }\n");
351
	}
362
	}
Line 352... Line 363...
352
	printf("}\n");
363
	log_info("}\n");
353
 
364
 
354
	if (cvec_pchar_size(&undefined_symbols) > 0) {
365
	if (cvec_pchar_size(&undefined_symbols) > 0) {
355
		printf("Undefined symbols found, aborting\nUndefined:\n");
366
		printf("Undefined symbols found, aborting\nUndefined:\n");
356
		for (int i = 0; i < cvec_pchar_size(&undefined_symbols); i++) {
367
		for (int i = 0; i < cvec_pchar_size(&undefined_symbols); i++) {
357
			printf("%s\n", undefined_symbols[i]);
368
			printf("%s\n", undefined_symbols[i]);
358
		}
369
		}
Line 359... Line 370...
359
		exit(-1);
370
		exit(-1);
360
	}
371
	}
361
 
372
 
362
	// Symbols Table
373
	// Symbols Table
Line 363... Line 374...
363
	printf("Writing symbols {\n");
374
	log_info("Writing symbols {\n");
Line 401... Line 412...
401
			} else {
412
			} else {
402
				memcpy(sec_name, sh.Name, 8);
413
				memcpy(sec_name, sh.Name, 8);
403
				sec_name[8] = '\0';
414
				sec_name[8] = '\0';
404
			}
415
			}
Line 405... Line 416...
405
 
416
 
406
			printf("%s:\n", sym.name);
417
			log_info("%s:\n", sym.name);
407
			printf(" Section:      %s\n", sec_name);
418
			log_info(" Section:      %s\n", sec_name);
Line 408... Line 419...
408
			printf(" StorageClass: %u\n", sym.sym.symbol.StorageClass);
419
			log_info(" StorageClass: %u\n", sym.sym.symbol.StorageClass);
Line 409... Line 420...
409
 
420
 
410
			sym.sym.symbol.SectionNumber = get_section_number(&ir->section_names_set, sec_name);
421
			sym.sym.symbol.SectionNumber = get_section_number(&ir->section_names_set, sec_name);
Line 427... Line 438...
427
		}
438
		}
428
		for (size_t aux_i = 0; aux_i < sym.sym.symbol.NumberOfAuxSymbols; aux_i++) {
439
		for (size_t aux_i = 0; aux_i < sym.sym.symbol.NumberOfAuxSymbols; aux_i++) {
429
			fwrite(&sym.auxes[aux_i].symbol, 1, 18, out);
440
			fwrite(&sym.auxes[aux_i].symbol, 1, 18, out);
430
		}
441
		}
431
	}
442
	}
432
	printf("}\n");
443
	log_info("}\n");
Line 433... Line 444...
433
 
444
 
434
	// COFF String Table
445
	// COFF String Table
435
	printf("Writing COFF String Table... ");
446
	log_info("Writing COFF String Table... ");
436
	fwrite32(out, cvec_pchar_size(&strtab) + 4);
447
	fwrite32(out, cvec_pchar_size(&strtab) + 4);
437
	fwrite(strtab, 1, cvec_pchar_size(&strtab), out);
448
	fwrite(strtab, 1, cvec_pchar_size(&strtab), out);
438
	printf("Done.\n");
449
	log_info("Done.\n");
Line 439... Line 450...
439
}
450
}
440
 
451
 
441
static ObjectIr parse_objects(int argc, char **argv) {
452
static ObjectIr parse_objects(int argc, char **argv) {
442
	CoffObject *objects = cvec_CoffObject_new(128);
453
	CoffObject *objects = cvec_CoffObject_new(128);
443
	char **section_names_set = cvec_pchar_new(4);
454
	char **section_names_set = cvec_pchar_new(4);
Line 444... Line 455...
444
	char **sym_name_set = cvec_pchar_new(128);
455
	char **sym_name_set = cvec_pchar_new(128);
-
 
456
	size_t number_of_symbols = 0;
-
 
457
 
-
 
458
	for (int i = 1; i < argc; i++) {
-
 
459
		// If one arg is NULL, that means it was a parameter and was cleared
-
 
460
		// It's not a input file name
-
 
461
		if (argv[i] == NULL) {
445
	size_t number_of_symbols = 0;
462
			continue;
Line 446... Line 463...
446
 
463
		}
447
	for (int i = 1; i < argc; i++) {
464
 
448
		printf("Primary parsing of %s... ", argv[i]);
465
		log_info("Primary parsing of %s... ", argv[i]);
Line 463... Line 480...
463
			}
480
			}
464
		}
481
		}
Line 465... Line 482...
465
 
482
 
Line 466... Line 483...
466
		cvec_CoffObject_push_back(&objects, object);
483
		cvec_CoffObject_push_back(&objects, object);
467
 
484
 
Line 468... Line 485...
468
		printf("Done.\n");
485
		log_info("Done.\n");
Line 469... Line 486...
469
	}
486
	}
Line 479... Line 496...
479
	if (!cdict_CStr_SectionInfo_init(&info_per_section)) {
496
	if (!cdict_CStr_SectionInfo_init(&info_per_section)) {
480
		ERROR_CDICT(&info_per_section);
497
		ERROR_CDICT(&info_per_section);
481
	}
498
	}
Line 482... Line 499...
482
 
499
 
483
	for (size_t i = 0; i < cvec_CoffObject_size(&objects); i++) {
500
	for (size_t i = 0; i < cvec_CoffObject_size(&objects); i++) {
Line 484... Line 501...
484
		printf("Secondary parsing of %s {\n", objects[i].name);
501
		log_info("Secondary parsing of %s {\n", objects[i].name);
Line 485... Line 502...
485
 
502
 
486
		Epep *epep = &(objects[i].epep);
503
		Epep *epep = &(objects[i].epep);
Line 494... Line 511...
494
		if (!epep_get_string_table(epep, strtab)) {
511
		if (!epep_get_string_table(epep, strtab)) {
495
			ERROR_EPEP(epep);
512
			ERROR_EPEP(epep);
496
		}
513
		}
Line 497... Line 514...
497
 
514
 
498
		// Fill symbols table
515
		// Fill symbols table
499
		printf(" Symbols {\n");
516
		log_info(" Symbols {\n");
500
		for (size_t sym_i = 0; sym_i < epep->coffFileHeader.NumberOfSymbols; sym_i++) {
517
		for (size_t sym_i = 0; sym_i < epep->coffFileHeader.NumberOfSymbols; sym_i++) {
Line 501... Line 518...
501
			EpepCoffSymbol sym = { 0 };
518
			EpepCoffSymbol sym = { 0 };
502
 
519
 
Line 545... Line 562...
545
				if (!cdict_CStr_Symbol_add_vv(&symtab, strdup(name), new_sym, CDICT_NO_CHECK)) {
562
				if (!cdict_CStr_Symbol_add_vv(&symtab, strdup(name), new_sym, CDICT_NO_CHECK)) {
546
					ERROR_CDICT(&symtab);
563
					ERROR_CDICT(&symtab);
547
				}
564
				}
548
				number_of_symbols++;
565
				number_of_symbols++;
Line 549... Line 566...
549
 
566
 
Line 550... Line 567...
550
				printf("  Symbol #%u: %s (%u auxes, #%u)\n", sym_i, name, cvec_EpepCoffSymbol_size(&auxes), number_of_symbols - 1);
567
				log_info("  Symbol #%u: %s (%u auxes, #%u)\n", sym_i, name, cvec_EpepCoffSymbol_size(&auxes), number_of_symbols - 1);
551
 
568
 
Line 552... Line 569...
552
				add_name_to_set(strdup(name), &sym_name_set);
569
				add_name_to_set(strdup(name), &sym_name_set);
553
			}
570
			}
554
 
571
 
Line 555... Line 572...
555
			sym_i += sym.symbol.NumberOfAuxSymbols;
572
			sym_i += sym.symbol.NumberOfAuxSymbols;
556
		}
573
		}
557
		printf(" }\n");
574
		log_info(" }\n");
558
 
575
 
Line 559... Line 576...
559
		// Set section offsets and fill unique section name set
576
		// Set section offsets and fill unique section name set
560
		printf(" Sections {\n");
577
		log_info(" Sections {\n");
Line 589... Line 606...
589
			si.characteristics |= sh.Characteristics;
606
			si.characteristics |= sh.Characteristics;
590
			si.number_of_relocations += sh.NumberOfRelocations;
607
			si.number_of_relocations += sh.NumberOfRelocations;
591
			cvec_ObjIdSecId_push_back(&si.source, (ObjIdSecId){ i, sec_i });
608
			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);
609
			cdict_CStr_SectionInfo_add_vv(&info_per_section, strdup(name), si, CDICT_REPLACE_EXIST);
Line 593... Line 610...
593
 
610
 
594
			printf("  Section #%llu {\n", sec_i);
611
			log_info("  Section #%llu {\n", sec_i);
595
			printf("   Name:                      %s\n", name);
612
			log_info("   Name:                      %s\n", name);
596
			printf("   Virtual Address:           %u\n", sh.VirtualAddress);
613
			log_info("   Virtual Address:           %u\n", sh.VirtualAddress);
597
			printf("   Characteristics:           %08x\n", sh.Characteristics);
614
			log_info("   Characteristics:           %08x\n", sh.Characteristics);
598
			printf("   Offset in the big section: %u\n", objects[i].section_offsets[sec_i]);
615
			log_info("   Offset in the big section: %u\n", objects[i].section_offsets[sec_i]);
Line 599... Line 616...
599
			printf("  }\n");
616
			log_info("  }\n");
600
 
-
 
601
			if (sh.VirtualAddress != 0) {
-
 
602
				printf("\n\n\n\n");
-
 
603
				for (int i = 0; i < 42; i++) {
-
 
604
					printf("!!!");
617
 
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
				}
618
			if (sh.VirtualAddress != 0) {
610
				printf("\n\n\n\n");
619
				printf("Warning: Handling of section with Virtual Address another that 0 is not implemented");
611
			}
620
			}
612
		}
621
		}
613
		printf(" }\n");
622
		log_info(" }\n");
Line 614... Line 623...
614
		printf("}\n");
623
		log_info("}\n");
615
	}
624
	}
616
 
625
 
Line 626... Line 635...
626
 
635
 
627
int first_arg(int argc, char **argv, const char *arg) {
636
int first_arg(int argc, char **argv, const char *arg) {
628
	return argc >= 2 && !strcmp(argv[1], arg);
637
	return argc >= 2 && !strcmp(argv[1], arg);
Line -... Line 638...
-
 
638
}
-
 
639
 
-
 
640
int arg_got_flag(int argc, char **argv, ...) {
-
 
641
	char *arg_names[8];
-
 
642
	int arg_name_c = 0;
-
 
643
 
-
 
644
	va_list ap;
-
 
645
	va_start(ap, argv);
-
 
646
	for (char *arg_name = va_arg(ap, char *); arg_name; arg_name = va_arg(ap, char *)) {
-
 
647
		if (arg_name_c >= 8) {
-
 
648
			printf("Internal error: Too many parameter aliases passed to %s", __func__);
-
 
649
			exit(-1);
-
 
650
		}
-
 
651
		arg_names[arg_name_c++] = arg_name;
-
 
652
	}
-
 
653
	va_end(ap);
-
 
654
 
-
 
655
	for (int i = 1; i < argc; i++) {
-
 
656
		for (int arg_name_i = 0; arg_name_i < arg_name_c; arg_name_i++) {
-
 
657
			char *arg_name = arg_names[arg_name_i];
-
 
658
			if (!strcmp(argv[i], arg_name)) {
-
 
659
				argv[i] = NULL; // Do not handle this argument as a input name
-
 
660
				return 1;
-
 
661
			}
-
 
662
		}
-
 
663
	}
-
 
664
	return 0;
629
}
665
}
630
 
666
 
Line 631... Line 667...
631
int main(int argc, char **argv) {
667
int main(int argc, char **argv) {
632
	const char *outname = "a.out.obj";
668
	const char *outname = "a.out.obj";
Line 645... Line 681...
645
		printf("  %s [-h|-help|--help]\n", argv[0]);
681
		printf("  %s [-h|-help|--help]\n", argv[0]);
646
		printf("    Output this help\n");
682
		printf("    Output this help\n");
647
		return 0;
683
		return 0;
648
	}
684
	}
Line -... Line 685...
-
 
685
 
-
 
686
	emit_logs = arg_got_flag(argc, argv, "-v", "-verbose", "--verbose", 0);
649
 
687
 
650
	ObjectIr ir = parse_objects(argc, argv);
688
	ObjectIr ir = parse_objects(argc, argv);
651
	build(&ir, outname);
689
	build(&ir, outname);
652
	return 0;
690
	return 0;