From: grischka Date: Thu, 8 May 2014 15:32:29 +0000 (+0200) Subject: win64: try to fix linkage X-Git-Tag: release_0_9_27~875 X-Git-Url: https://repo.or.cz/w/tinycc.git/commitdiff_plain/6e0a658e9619b8e8040332361352b8a883292364 win64: try to fix linkage - revert to R_X86_64_PC32 for near calls on PE - revert to s1->section_align set to zero by default Untested. Compared to release_0_9_26 the pe-image looks back to normal. There are some differences in dissassembly (r10/r11 usage) but maybe that's ok. --- diff --git a/libtcc.c b/libtcc.c index deda7e6a..7caa7c1e 100644 --- a/libtcc.c +++ b/libtcc.c @@ -1033,7 +1033,6 @@ LIBTCCAPI TCCState *tcc_new(void) ".dynhashtab", SHF_PRIVATE); s->alacarte_link = 1; s->nocommon = 1; - s->section_align = ELF_PAGE_SIZE; #ifdef CHAR_IS_UNSIGNED s->char_is_unsigned = 1; diff --git a/tccelf.c b/tccelf.c index f0ed22b7..2fbe692e 100644 --- a/tccelf.c +++ b/tccelf.c @@ -1596,7 +1596,7 @@ ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel) put32(s1->got->data + offset, sym->st_value & 0xffffffff); } -/* Perform relocation to GOT or PLTĀ entries */ +/* Perform relocation to GOT or PLT entries */ ST_FUNC void fill_got(TCCState *s1) { Section *s; @@ -1848,6 +1848,7 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum, int *sec_order) { int i, j, k, file_type, sh_order_index, file_offset; + unsigned long s_align; long long tmp; addr_t addr; ElfW(Phdr) *ph; @@ -1855,10 +1856,12 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum, file_type = s1->output_type; sh_order_index = 1; + file_offset = 0; if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr)); - else - file_offset = 0; + s_align = ELF_PAGE_SIZE; + if (s1->section_align) + s_align = s1->section_align; if (phnum > 0) { if (s1->has_text_addr) { @@ -1866,10 +1869,10 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum, addr = s1->text_addr; /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset % ELF_PAGE_SIZE */ - a_offset = (int) (addr & (s1->section_align - 1)); - p_offset = file_offset & (s1->section_align - 1); + a_offset = (int) (addr & (s_align - 1)); + p_offset = file_offset & (s_align - 1); if (a_offset < p_offset) - a_offset += s1->section_align; + a_offset += s_align; file_offset += (a_offset - p_offset); } else { if (file_type == TCC_OUTPUT_DLL) @@ -1877,7 +1880,7 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum, else addr = ELF_START_ADDR; /* compute address after headers */ - addr += (file_offset & (s1->section_align - 1)); + addr += (file_offset & (s_align - 1)); } ph = &phdr[0]; @@ -1899,7 +1902,7 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum, ph->p_flags = PF_R | PF_X; else ph->p_flags = PF_R | PF_W; - ph->p_align = s1->section_align; + ph->p_align = s_align; /* Decide the layout of sections loaded in memory. This must be done before program headers are filled since they contain @@ -1991,12 +1994,11 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum, 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 & (s1->section_align - 1)) != 0) - addr += s1->section_align; + if ((addr & (s_align - 1)) != 0) + addr += s_align; } else { - addr = (addr + s1->section_align - 1) & ~(s1->section_align - 1); - file_offset = (file_offset + s1->section_align - 1) & - ~(s1->section_align - 1); + addr = (addr + s_align - 1) & ~(s_align - 1); + file_offset = (file_offset + s_align - 1) & ~(s_align - 1); } } } @@ -2469,7 +2471,7 @@ static int elf_output_file(TCCState *s1, const char *filename) goto the_end; } - /* Perform relocation to GOT or PLTĀ entries */ + /* Perform relocation to GOT or PLT entries */ if (file_type == TCC_OUTPUT_EXE && s1->static_link) fill_got(s1); diff --git a/x86_64-gen.c b/x86_64-gen.c index eb201c8a..c8fed850 100644 --- a/x86_64-gen.c +++ b/x86_64-gen.c @@ -288,7 +288,8 @@ static void gen_gotpcrel(int r, Sym *sym, int c) rel = (ElfW(Rela) *)(sr->data + sr->data_offset - sizeof(ElfW(Rela))); rel->r_addend = -4; #else - printf("picpic: %s %x %x | %02x %02x %02x\n", get_tok_str(sym->v, NULL), c, r, + tcc_error("internal error: no GOT on PE: %s %x %x | %02x %02x %02x\n", + get_tok_str(sym->v, NULL), c, r, cur_text_section->data[ind-3], cur_text_section->data[ind-2], cur_text_section->data[ind-1] @@ -603,8 +604,11 @@ static void gcall_or_jmp(int is_jmp) /* constant case */ if (vtop->r & VT_SYM) { /* relocation case */ - greloc(cur_text_section, vtop->sym, - ind + 1, R_X86_64_PLT32); +#ifdef TCC_TARGET_PE + greloc(cur_text_section, vtop->sym, ind + 1, R_X86_64_PC32); +#else + greloc(cur_text_section, vtop->sym, ind + 1, R_X86_64_PLT32); +#endif } else { /* put an empty PC32 relocation */ put_elf_reloc(symtab_section, cur_text_section,