mirror of
https://github.com/frida/tinycc
synced 2024-11-27 18:19:35 +03:00
various fixes and new options for PE format
This commit is contained in:
parent
526c464504
commit
2f73e42d87
4
libtcc.c
4
libtcc.c
@ -1944,6 +1944,10 @@ TCCState *tcc_new(void)
|
||||
/* XXX: currently the PE linker is not ready to support that */
|
||||
s->leading_underscore = 1;
|
||||
#endif
|
||||
|
||||
if (s->section_align == 0)
|
||||
s->section_align = ELF_PAGE_SIZE;
|
||||
|
||||
#ifdef TCC_TARGET_I386
|
||||
s->seg_size = 32;
|
||||
#endif
|
||||
|
39
tcc.c
39
tcc.c
@ -386,8 +386,47 @@ int parse_args(TCCState *s, int argc, char **argv)
|
||||
if (strstart(optarg, "-Ttext,", &p)) {
|
||||
s->text_addr = strtoul(p, NULL, 16);
|
||||
s->has_text_addr = 1;
|
||||
} else if (strstart(optarg, "--section-alignment,", &p)) {
|
||||
s->section_align = strtoul(p, NULL, 16);
|
||||
} else if (strstart(optarg, "--image-base,", &p)) {
|
||||
s->text_addr = strtoul(p, NULL, 16);
|
||||
s->has_text_addr = 1;
|
||||
#ifdef TCC_TARGET_PE
|
||||
} else if (strstart(optarg, "--file-alignment,", &p)) {
|
||||
s->pe_file_align = strtoul(p, NULL, 16);
|
||||
} else if (strstart(optarg, "--subsystem,", &p)) {
|
||||
#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
|
||||
if (!strcmp(p, "native"))
|
||||
s->pe_subsystem = 1;
|
||||
else if (!strcmp(p, "console"))
|
||||
s->pe_subsystem = 3;
|
||||
else if (!strcmp(p, "gui"))
|
||||
s->pe_subsystem = 2;
|
||||
else if (!strcmp(p, "posix"))
|
||||
s->pe_subsystem = 7;
|
||||
else if (!strcmp(p, "efiapp"))
|
||||
s->pe_subsystem = 10;
|
||||
else if (!strcmp(p, "efiboot"))
|
||||
s->pe_subsystem = 11;
|
||||
else if (!strcmp(p, "efiruntime"))
|
||||
s->pe_subsystem = 12;
|
||||
else if (!strcmp(p, "efirom"))
|
||||
s->pe_subsystem = 13;
|
||||
#endif
|
||||
else {
|
||||
error("invalid subsystem '%s'", p);
|
||||
}
|
||||
#endif
|
||||
} else if (strstart(optarg, "--oformat,", &p)) {
|
||||
#if defined(TCC_TARGET_PE)
|
||||
if (strstart(p, "pe-", NULL)) {
|
||||
#else
|
||||
#if defined(TCC_TARGET_X86_64)
|
||||
if (strstart(p, "elf64-", NULL)) {
|
||||
#else
|
||||
if (strstart(p, "elf32-", NULL)) {
|
||||
#endif
|
||||
#endif
|
||||
s->output_format = TCC_OUTPUT_FORMAT_ELF;
|
||||
} else if (!strcmp(p, "binary")) {
|
||||
s->output_format = TCC_OUTPUT_FORMAT_BINARY;
|
||||
|
9
tcc.h
9
tcc.h
@ -515,6 +515,15 @@ struct TCCState {
|
||||
int seg_size;
|
||||
#endif
|
||||
|
||||
/* section alignment */
|
||||
unsigned long section_align;
|
||||
|
||||
#ifdef TCC_TARGET_PE
|
||||
/* PE info */
|
||||
int pe_subsystem;
|
||||
unsigned long pe_file_align;
|
||||
#endif
|
||||
|
||||
#ifndef TCC_TARGET_PE
|
||||
#ifdef TCC_TARGET_X86_64
|
||||
/* write PLT and GOT here */
|
||||
|
20
tccelf.c
20
tccelf.c
@ -1632,10 +1632,10 @@ int elf_output_file(TCCState *s1, const char *filename)
|
||||
addr = s1->text_addr;
|
||||
/* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
|
||||
ELF_PAGE_SIZE */
|
||||
a_offset = addr & (ELF_PAGE_SIZE - 1);
|
||||
p_offset = file_offset & (ELF_PAGE_SIZE - 1);
|
||||
a_offset = addr & (s1->section_align - 1);
|
||||
p_offset = file_offset & (s1->section_align - 1);
|
||||
if (a_offset < p_offset)
|
||||
a_offset += ELF_PAGE_SIZE;
|
||||
a_offset += s1->section_align;
|
||||
file_offset += (a_offset - p_offset);
|
||||
} else {
|
||||
if (file_type == TCC_OUTPUT_DLL)
|
||||
@ -1643,7 +1643,7 @@ int elf_output_file(TCCState *s1, const char *filename)
|
||||
else
|
||||
addr = ELF_START_ADDR;
|
||||
/* compute address after headers */
|
||||
addr += (file_offset & (ELF_PAGE_SIZE - 1));
|
||||
addr += (file_offset & (s1->section_align - 1));
|
||||
}
|
||||
|
||||
/* dynamic relocation table information, for .dynamic section */
|
||||
@ -1661,7 +1661,7 @@ int elf_output_file(TCCState *s1, const char *filename)
|
||||
ph->p_flags = PF_R | PF_X;
|
||||
else
|
||||
ph->p_flags = PF_R | PF_W;
|
||||
ph->p_align = ELF_PAGE_SIZE;
|
||||
ph->p_align = s1->section_align;
|
||||
|
||||
/* we do the following ordering: interp, symbol tables,
|
||||
relocations, progbits, nobits */
|
||||
@ -1731,12 +1731,12 @@ int elf_output_file(TCCState *s1, const char *filename)
|
||||
if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
|
||||
/* if in the middle of a page, we duplicate the page in
|
||||
memory so that one copy is RX and the other is RW */
|
||||
if ((addr & (ELF_PAGE_SIZE - 1)) != 0)
|
||||
addr += ELF_PAGE_SIZE;
|
||||
if ((addr & (s1->section_align - 1)) != 0)
|
||||
addr += s1->section_align;
|
||||
} else {
|
||||
addr = (addr + ELF_PAGE_SIZE - 1) & ~(ELF_PAGE_SIZE - 1);
|
||||
file_offset = (file_offset + ELF_PAGE_SIZE - 1) &
|
||||
~(ELF_PAGE_SIZE - 1);
|
||||
addr = (addr + s1->section_align - 1) & ~(s1->section_align - 1);
|
||||
file_offset = (file_offset + s1->section_align - 1) &
|
||||
~(s1->section_align - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
46
tccpe.c
46
tccpe.c
@ -349,6 +349,9 @@ struct pe_info {
|
||||
DWORD iat_size;
|
||||
DWORD exp_offs;
|
||||
DWORD exp_size;
|
||||
int subsystem;
|
||||
DWORD section_align;
|
||||
DWORD file_align;
|
||||
struct section_info *sec_info;
|
||||
int sec_count;
|
||||
struct pe_import_info **imp_info;
|
||||
@ -417,14 +420,14 @@ ST_FN DWORD umax(DWORD a, DWORD b)
|
||||
return a < b ? b : a;
|
||||
}
|
||||
|
||||
ST_FN DWORD pe_file_align(DWORD n)
|
||||
ST_FN DWORD pe_file_align(struct pe_info *pe, DWORD n)
|
||||
{
|
||||
return (n + (0x200 - 1)) & ~(0x200 - 1);
|
||||
return (n + (pe->file_align - 1)) & ~(pe->file_align - 1);
|
||||
}
|
||||
|
||||
ST_FN DWORD pe_virtual_align(DWORD n)
|
||||
ST_FN DWORD pe_virtual_align(struct pe_info *pe, DWORD n)
|
||||
{
|
||||
return (n + (0x1000 - 1)) & ~(0x1000 - 1);
|
||||
return (n + (pe->section_align - 1)) & ~(pe->section_align - 1);
|
||||
}
|
||||
|
||||
ST_FN void pe_align_section(Section *s, int a)
|
||||
@ -578,7 +581,7 @@ ST_FN int pe_write(struct pe_info *pe)
|
||||
return -1;
|
||||
}
|
||||
|
||||
pe->sizeofheaders = pe_file_align(
|
||||
pe->sizeofheaders = pe_file_align(pe,
|
||||
sizeof (struct pe_header)
|
||||
+ pe->sec_count * sizeof (IMAGE_SECTION_HEADER)
|
||||
);
|
||||
@ -648,11 +651,11 @@ ST_FN int pe_write(struct pe_info *pe)
|
||||
psh->VirtualAddress = addr;
|
||||
psh->Misc.VirtualSize = size;
|
||||
pe_header.opthdr.SizeOfImage =
|
||||
umax(pe_virtual_align(size + addr), pe_header.opthdr.SizeOfImage);
|
||||
umax(pe_virtual_align(pe, size + addr), pe_header.opthdr.SizeOfImage);
|
||||
|
||||
if (si->data_size) {
|
||||
psh->PointerToRawData = file_offset;
|
||||
file_offset = pe_file_align(file_offset + si->data_size);
|
||||
file_offset = pe_file_align(pe, file_offset + si->data_size);
|
||||
psh->SizeOfRawData = file_offset - psh->PointerToRawData;
|
||||
}
|
||||
}
|
||||
@ -1085,7 +1088,7 @@ ST_FN int pe_assign_addresses (struct pe_info *pe)
|
||||
strcpy(si->name, s->name);
|
||||
si->cls = c;
|
||||
si->ord = k;
|
||||
si->sh_addr = s->sh_addr = addr = pe_virtual_align(addr);
|
||||
si->sh_addr = s->sh_addr = addr = pe_virtual_align(pe, addr);
|
||||
si->sh_flags = s->sh_flags;
|
||||
|
||||
if (c == sec_data && NULL == pe->thunk)
|
||||
@ -1649,6 +1652,33 @@ PUB_FN int pe_output_file(TCCState * s1, const char *filename)
|
||||
} else {
|
||||
pe.imagebase = 0x00400000;
|
||||
}
|
||||
|
||||
/* if no subsystem specified, we use "console" subsystem by default */
|
||||
if (s1->pe_subsystem != 0)
|
||||
pe.subsystem = s1->pe_subsystem;
|
||||
else
|
||||
pe.subsystem = 3;
|
||||
|
||||
/* set default file/section alignment */
|
||||
if (pe.subsystem == 1) {
|
||||
pe.section_align = 0x20;
|
||||
pe.file_align = 0x20;
|
||||
} else {
|
||||
pe.section_align = 0x1000;
|
||||
pe.file_align = 0x200;
|
||||
}
|
||||
|
||||
if (s1->section_align != 0)
|
||||
pe.section_align = s1->section_align;
|
||||
if (s1->pe_file_align != 0)
|
||||
pe.file_align = s1->pe_file_align;
|
||||
|
||||
if ((pe.subsystem >= 10) && (pe.subsystem <= 12))
|
||||
pe.imagebase = 0;
|
||||
|
||||
if (s1->has_text_addr)
|
||||
pe.imagebase = s1->text_addr;
|
||||
|
||||
pe_assign_addresses(&pe);
|
||||
relocate_syms(s1, 0);
|
||||
for (i = 1; i < s1->nb_sections; ++i) {
|
||||
|
Loading…
Reference in New Issue
Block a user