win64: try to fix linkage
authorgrischka <grischka>
Thu, 8 May 2014 15:32:29 +0000 (8 17:32 +0200)
committerDavid Mertens <dcmertens.perl@gmail.com>
Wed, 25 Jun 2014 02:09:12 +0000 (24 22:09 -0400)
- 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.

libtcc.c
tccelf.c
x86_64-gen.c

index deda7e6..7caa7c1 100644 (file)
--- 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;
index f0ed22b..2fbe692 100644 (file)
--- 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);
 
index eb201c8..c8fed85 100644 (file)
@@ -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,