History

various fixes and new options for PE format

Frederic Feret committed 17 years ago

Commit 2f73e421 parent 526c4645 files · +100 −18Browse files

Unified · Split

5 files
  1. libtcc.c +4 −0
  2. tcc.c +39 −0
  3. tcc.h +9 −0
  4. tccelf.c +10 −10
  5. tccpe.c +38 −8
libtcc.c+4−0
@@ -1944,6 +1944,10 @@ TCCState *tcc_new(void) · 1943 unmodified lines
19441944 /* XXX: currently the PE linker is not ready to support that */
19451945 s->leading_underscore = 1;
19461946 #endif
1947+
1948+ if (s->section_align == 0)
1949+ s->section_align = ELF_PAGE_SIZE;
1950+
19471951 #ifdef TCC_TARGET_I386
19481952 s->seg_size = 32;
19491953 #endif
tcc.c+39−0
@@ -386,8 +386,47 @@ int parse_args(TCCState *s, int argc, char **argv) · 385 unmodified lines
386386 if (strstart(optarg, "-Ttext,", &p)) {
387387 s->text_addr = strtoul(p, NULL, 16);
388388 s->has_text_addr = 1;
389+ } else if (strstart(optarg, "--section-alignment,", &p)) {
390+ s->section_align = strtoul(p, NULL, 16);
391+ } else if (strstart(optarg, "--image-base,", &p)) {
392+ s->text_addr = strtoul(p, NULL, 16);
393+ s->has_text_addr = 1;
394+#ifdef TCC_TARGET_PE
395+ } else if (strstart(optarg, "--file-alignment,", &p)) {
396+ s->pe_file_align = strtoul(p, NULL, 16);
397+ } else if (strstart(optarg, "--subsystem,", &p)) {
398+#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
399+ if (!strcmp(p, "native"))
400+ s->pe_subsystem = 1;
401+ else if (!strcmp(p, "console"))
402+ s->pe_subsystem = 3;
403+ else if (!strcmp(p, "gui"))
404+ s->pe_subsystem = 2;
405+ else if (!strcmp(p, "posix"))
406+ s->pe_subsystem = 7;
407+ else if (!strcmp(p, "efiapp"))
408+ s->pe_subsystem = 10;
409+ else if (!strcmp(p, "efiboot"))
410+ s->pe_subsystem = 11;
411+ else if (!strcmp(p, "efiruntime"))
412+ s->pe_subsystem = 12;
413+ else if (!strcmp(p, "efirom"))
414+ s->pe_subsystem = 13;
415+#endif
416+ else {
417+ error("invalid subsystem '%s'", p);
418+ }
419+#endif
389420 } else if (strstart(optarg, "--oformat,", &p)) {
421+#if defined(TCC_TARGET_PE)
422+ if (strstart(p, "pe-", NULL)) {
423+#else
424+#if defined(TCC_TARGET_X86_64)
425+ if (strstart(p, "elf64-", NULL)) {
426+#else
390427 if (strstart(p, "elf32-", NULL)) {
428+#endif
429+#endif
391430 s->output_format = TCC_OUTPUT_FORMAT_ELF;
392431 } else if (!strcmp(p, "binary")) {
393432 s->output_format = TCC_OUTPUT_FORMAT_BINARY;
tcc.h+9−0
@@ -515,6 +515,15 @@ struct TCCState { · 514 unmodified lines
515515 int seg_size;
516516 #endif
517517
518+ /* section alignment */
519+ unsigned long section_align;
520+
521+#ifdef TCC_TARGET_PE
522+ /* PE info */
523+ int pe_subsystem;
524+ unsigned long pe_file_align;
525+#endif
526+
518527 #ifndef TCC_TARGET_PE
519528 #ifdef TCC_TARGET_X86_64
520529 /* write PLT and GOT here */
tccelf.c+10−10
@@ -1632,10 +1632,10 @@ int elf_output_file(TCCState *s1, const char *filename) · 1631 unmodified lines
16321632 addr = s1->text_addr;
16331633 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
16341634 ELF_PAGE_SIZE */
1635− a_offset = addr & (ELF_PAGE_SIZE - 1);
1636− p_offset = file_offset & (ELF_PAGE_SIZE - 1);
1635+ a_offset = addr & (s1->section_align - 1);
1636+ p_offset = file_offset & (s1->section_align - 1);
16371637 if (a_offset < p_offset)
1638− a_offset += ELF_PAGE_SIZE;
1638+ a_offset += s1->section_align;
16391639 file_offset += (a_offset - p_offset);
16401640 } else {
16411641 if (file_type == TCC_OUTPUT_DLL)
@@ -1643,7 +1643,7 @@ int elf_output_file(TCCState *s1, const char *filename) · 1 unmodified line
16431643 else
16441644 addr = ELF_START_ADDR;
16451645 /* compute address after headers */
1646− addr += (file_offset & (ELF_PAGE_SIZE - 1));
1646+ addr += (file_offset & (s1->section_align - 1));
16471647 }
16481648
16491649 /* dynamic relocation table information, for .dynamic section */
@@ -1661,7 +1661,7 @@ int elf_output_file(TCCState *s1, const char *filename) · 11 unmodified lines
16611661 ph->p_flags = PF_R | PF_X;
16621662 else
16631663 ph->p_flags = PF_R | PF_W;
1664− ph->p_align = ELF_PAGE_SIZE;
1664+ ph->p_align = s1->section_align;
16651665
16661666 /* we do the following ordering: interp, symbol tables,
16671667 relocations, progbits, nobits */
@@ -1731,12 +1731,12 @@ int elf_output_file(TCCState *s1, const char *filename) · 63 unmodified lines
17311731 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
17321732 /* if in the middle of a page, we duplicate the page in
17331733 memory so that one copy is RX and the other is RW */
1734− if ((addr & (ELF_PAGE_SIZE - 1)) != 0)
1735− addr += ELF_PAGE_SIZE;
1734+ if ((addr & (s1->section_align - 1)) != 0)
1735+ addr += s1->section_align;
17361736 } else {
1737− addr = (addr + ELF_PAGE_SIZE - 1) & ~(ELF_PAGE_SIZE - 1);
1738− file_offset = (file_offset + ELF_PAGE_SIZE - 1) &
1739− ~(ELF_PAGE_SIZE - 1);
1737+ addr = (addr + s1->section_align - 1) & ~(s1->section_align - 1);
1738+ file_offset = (file_offset + s1->section_align - 1) &
1739+ ~(s1->section_align - 1);
17401740 }
17411741 }
17421742 }
tccpe.c+38−8
@@ -349,6 +349,9 @@ struct pe_info { · 348 unmodified lines
349349 DWORD iat_size;
350350 DWORD exp_offs;
351351 DWORD exp_size;
352+ int subsystem;
353+ DWORD section_align;
354+ DWORD file_align;
352355 struct section_info *sec_info;
353356 int sec_count;
354357 struct pe_import_info **imp_info;
@@ -417,14 +420,14 @@ ST_FN DWORD umax(DWORD a, DWORD b) · 62 unmodified lines
417420 return a < b ? b : a;
418421 }
419422
420−ST_FN DWORD pe_file_align(DWORD n)
423+ST_FN DWORD pe_file_align(struct pe_info *pe, DWORD n)
421424 {
422− return (n + (0x200 - 1)) & ~(0x200 - 1);
425+ return (n + (pe->file_align - 1)) & ~(pe->file_align - 1);
423426 }
424427
425−ST_FN DWORD pe_virtual_align(DWORD n)
428+ST_FN DWORD pe_virtual_align(struct pe_info *pe, DWORD n)
426429 {
427− return (n + (0x1000 - 1)) & ~(0x1000 - 1);
430+ return (n + (pe->section_align - 1)) & ~(pe->section_align - 1);
428431 }
429432
430433 ST_FN void pe_align_section(Section *s, int a)
@@ -578,7 +581,7 @@ ST_FN int pe_write(struct pe_info *pe) · 147 unmodified lines
578581 return -1;
579582 }
580583
581− pe->sizeofheaders = pe_file_align(
584+ pe->sizeofheaders = pe_file_align(pe,
582585 sizeof (struct pe_header)
583586 + pe->sec_count * sizeof (IMAGE_SECTION_HEADER)
584587 );
@@ -648,11 +651,11 @@ ST_FN int pe_write(struct pe_info *pe) · 63 unmodified lines
648651 psh->VirtualAddress = addr;
649652 psh->Misc.VirtualSize = size;
650653 pe_header.opthdr.SizeOfImage =
651− umax(pe_virtual_align(size + addr), pe_header.opthdr.SizeOfImage);
654+ umax(pe_virtual_align(pe, size + addr), pe_header.opthdr.SizeOfImage);
652655
653656 if (si->data_size) {
654657 psh->PointerToRawData = file_offset;
655− file_offset = pe_file_align(file_offset + si->data_size);
658+ file_offset = pe_file_align(pe, file_offset + si->data_size);
656659 psh->SizeOfRawData = file_offset - psh->PointerToRawData;
657660 }
658661 }
@@ -1085,7 +1088,7 @@ ST_FN int pe_assign_addresses (struct pe_info *pe) · 426 unmodified lines
10851088 strcpy(si->name, s->name);
10861089 si->cls = c;
10871090 si->ord = k;
1088− si->sh_addr = s->sh_addr = addr = pe_virtual_align(addr);
1091+ si->sh_addr = s->sh_addr = addr = pe_virtual_align(pe, addr);
10891092 si->sh_flags = s->sh_flags;
10901093
10911094 if (c == sec_data && NULL == pe->thunk)
@@ -1649,6 +1652,33 @@ PUB_FN int pe_output_file(TCCState * s1, const char *filename) · 557 unmodified lines
16491652 } else {
16501653 pe.imagebase = 0x00400000;
16511654 }
1655+
1656+ /* if no subsystem specified, we use "console" subsystem by default */
1657+ if (s1->pe_subsystem != 0)
1658+ pe.subsystem = s1->pe_subsystem;
1659+ else
1660+ pe.subsystem = 3;
1661+
1662+ /* set default file/section alignment */
1663+ if (pe.subsystem == 1) {
1664+ pe.section_align = 0x20;
1665+ pe.file_align = 0x20;
1666+ } else {
1667+ pe.section_align = 0x1000;
1668+ pe.file_align = 0x200;
1669+ }
1670+
1671+ if (s1->section_align != 0)
1672+ pe.section_align = s1->section_align;
1673+ if (s1->pe_file_align != 0)
1674+ pe.file_align = s1->pe_file_align;
1675+
1676+ if ((pe.subsystem >= 10) && (pe.subsystem <= 12))
1677+ pe.imagebase = 0;
1678+
1679+ if (s1->has_text_addr)
1680+ pe.imagebase = s1->text_addr;
1681+
16521682 pe_assign_addresses(&pe);
16531683 relocate_syms(s1, 0);
16541684 for (i = 1; i < s1->nb_sections; ++i) {

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t