tinycc-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Tinycc-devel] Win64 PE JIT codegen: Bad unwind info / runtime funct


From: grischka
Subject: Re: [Tinycc-devel] Win64 PE JIT codegen: Bad unwind info / runtime function tables
Date: Wed, 08 Nov 2017 18:42:08 +0100
User-agent: Thunderbird 2.0.0.23 (Windows/20090812)

Janus Lynggaard Thorborg wrote:
Okay, so I thought everything was good, but it turns out one of the real
issues was adding mixing object files and compilations into one tcc state,
something my unit tests didn't cover. So here's a dump of the
RUNTIME_FUNCTION array passed to RtlAddFunctionTable, where I compiled some
stuff using *tcc_compile_string* and *tcc_add_file("someobject.o")*:
[...]
As can be seen, from runtime function 14, the function entries start to
overlap again. Probably, there's a missing segment/section offset somewhere
when TCC adds runtime functions from different contexts/sections/object
files?

Yes, I already wondered how it can work if for file output (exe/dll)
we handle R_XXX_RELATIVE in pe_relocate_rva() but don't do anything
like that for -run.  Not surprisingly it doesn't work.

Attached is a patch to correct this.  It removes pe_relocate_rva()
altogether and instead handles R_XXX_RELATIVE in the relocate backends
(as it should be).

It also sets the uw_pdata section in case it was not set by any
compilation, that is if you wanted to run just already compiled
object files.

If it works I'll push that later.

--- grischka

commit 7354711b9b6ba022f3b5f4959e057859b877e9cb
Author: grischka <grischka>
Date:   Mon Nov 6 10:45:43 2017 +0100

    win32/64: integrate pe_relocate_rva
    
    This fixes relocation of the unwind data on win64

diff --git a/arm-link.c b/arm-link.c
index aee35af..92a24eb 100644
--- a/arm-link.c
+++ b/arm-link.c
@@ -382,6 +382,12 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, 
unsigned char *ptr, addr_t
             /* Nothing to do.  Normally used to indicate a dependency
                on a certain symbol (like for exception handling under EABI).  
*/
             return;
+        case R_ARM_RELATIVE:
+#ifdef TCC_TARGET_PE
+            add32le(ptr, val - s1->pe_imagebase);
+#endif
+            /* do nothing */
+            return;
         default:
             fprintf(stderr,"FIXME: handle reloc type %x at %x [%p] to %x\n",
                 type, (unsigned)addr, ptr, (unsigned)val);
diff --git a/arm64-link.c b/arm64-link.c
index 73e503e..59322c5 100644
--- a/arm64-link.c
+++ b/arm64-link.c
@@ -240,6 +240,12 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, 
unsigned char *ptr, addr_t
 #endif
             write64le(ptr, val - rel->r_addend);
             return;
+        case R_AARCH64_RELATIVE:
+#ifdef TCC_TARGET_PE
+            add32le(ptr, val - s1->pe_imagebase);
+#endif
+            /* do nothing */
+            return;
         default:
             fprintf(stderr, "FIXME: handle reloc type %x at %x [%p] to %x\n",
                     type, (unsigned)addr, ptr, (unsigned)val);
diff --git a/i386-link.c b/i386-link.c
index b446644..aea3c21 100644
--- a/i386-link.c
+++ b/i386-link.c
@@ -226,6 +226,9 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, 
unsigned char *ptr, addr_t
             write16le(ptr, read16le(ptr) + val - addr);
             return;
         case R_386_RELATIVE:
+#ifdef TCC_TARGET_PE
+            add32le(ptr, val - s1->pe_imagebase);
+#endif
             /* do nothing */
             return;
         case R_386_COPY:
diff --git a/tcc.h b/tcc.h
index da26298..02f4196 100644
--- a/tcc.h
+++ b/tcc.h
@@ -803,6 +803,7 @@ struct TCCState {
     unsigned pe_characteristics;
     unsigned pe_file_align;
     unsigned pe_stack_size;
+    addr_t pe_imagebase;
 # ifdef TCC_TARGET_X86_64
     Section *uw_pdata;
     int uw_sym;
diff --git a/tccpe.c b/tccpe.c
index a67023d..094e2f3 100644
--- a/tccpe.c
+++ b/tccpe.c
@@ -967,7 +967,7 @@ static void pe_build_exports(struct pe_info *pe)
     for (ord = 0; ord < sym_count; ++ord)
     {
         p = sorted[ord], sym_index = p->index, name = p->name;
-        /* insert actual address later in pe_relocate_rva */
+        /* insert actual address later in relocate_section() */
         put_elf_reloc(symtab_section, pe->thunk,
             func_o, R_XXX_RELATIVE, sym_index);
         *(DWORD*)(pe->thunk->data + name_o)
@@ -1181,26 +1181,6 @@ static int pe_assign_addresses (struct pe_info *pe)
     return 0;
 }
 
-/* ------------------------------------------------------------- */
-static void pe_relocate_rva (struct pe_info *pe, Section *s)
-{
-    Section *sr = s->reloc;
-    ElfW_Rel *rel, *rel_end;
-    rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
-    for(rel = (ElfW_Rel *)sr->data; rel < rel_end; rel++) {
-        if (ELFW(R_TYPE)(rel->r_info) == R_XXX_RELATIVE) {
-            int sym_index = ELFW(R_SYM)(rel->r_info);
-            DWORD addr = s->sh_addr;
-            if (sym_index) {
-                ElfW(Sym) *sym = (ElfW(Sym) *)symtab_section->data + sym_index;
-                addr = sym->st_value;
-            }
-            // printf("reloc rva %08x %08x %s\n", (DWORD)rel->r_offset, addr, 
s->name);
-            *(DWORD*)(s->data + rel->r_offset) += addr - pe->imagebase;
-        }
-    }
-}
-
 
/*----------------------------------------------------------------------------*/
 
 static int pe_isafunc(int sym_index)
@@ -1633,7 +1613,7 @@ static int pe_load_res(TCCState *s1, int fd)
 {
     struct pe_rsrc_header hdr;
     Section *rsrc_section;
-    int i, ret = -1;
+    int i, ret = -1, sym_index = 0;
     BYTE *ptr;
     unsigned offs;
 
@@ -1651,6 +1631,7 @@ static int pe_load_res(TCCState *s1, int fd)
     if (!read_mem(fd, offs, ptr, hdr.sectionhdr.SizeOfRawData))
         goto quit;
     offs = hdr.sectionhdr.PointerToRelocations;
+    sym_index = put_elf_sym(symtab_section, 0, 0, 0, 0, rsrc_section->sh_num, 
NULL);
     for (i = 0; i < hdr.sectionhdr.NumberOfRelocations; ++i)
     {
         struct pe_rsrc_reloc rel;
@@ -1660,7 +1641,7 @@ static int pe_load_res(TCCState *s1, int fd)
         if (rel.type != RSRC_RELTYPE)
             goto quit;
         put_elf_reloc(symtab_section, rsrc_section,
-            rel.offset, R_XXX_RELATIVE, 0);
+            rel.offset, R_XXX_RELATIVE, sym_index);
         offs += sizeof rel;
     }
     ret = 0;
@@ -1830,7 +1811,7 @@ ST_FUNC void pe_add_unwind_data(unsigned start, unsigned 
end, unsigned stack)
 
     /* put relocations on it */
     for (n = o + sizeof *p; o < n; o += sizeof p->BeginAddress)
-        put_elf_reloc(symtab_section, pd, o,  R_X86_64_RELATIVE, s1->uw_sym);
+        put_elf_reloc(symtab_section, pd, o, R_XXX_RELATIVE, s1->uw_sym);
 }
 #endif
 /* ------------------------------------------------------------- */
@@ -1980,11 +1961,11 @@ ST_FUNC int pe_output_file(TCCState *s1, const char 
*filename)
     else if (filename) {
         pe_assign_addresses(&pe);
         relocate_syms(s1, s1->symtab, 0);
+        s1->pe_imagebase = pe.imagebase;
         for (i = 1; i < s1->nb_sections; ++i) {
             Section *s = s1->sections[i];
             if (s->reloc) {
                 relocate_section(s1, s);
-                pe_relocate_rva(&pe, s);
             }
         }
         pe.start_addr = (DWORD)
@@ -2000,6 +1981,9 @@ ST_FUNC int pe_output_file(TCCState *s1, const char 
*filename)
         pe.thunk = data_section;
         pe_build_imports(&pe);
         s1->runtime_main = pe.start_symbol;
+#ifdef TCC_TARGET_X86_64
+        s1->uw_pdata = find_section(s1, ".pdata");
+#endif
 #endif
     }
 
diff --git a/tccrun.c b/tccrun.c
index d0501a0..bea67eb 100644
--- a/tccrun.c
+++ b/tccrun.c
@@ -239,6 +239,10 @@ static int tcc_relocate_ex(TCCState *s1, void *ptr, addr_t 
ptr_diff)
     if (0 == mem)
         return offset + RUN_SECTION_ALIGNMENT;
 
+#ifdef TCC_TARGET_PE
+    s1->pe_imagebase = mem;
+#endif
+
     /* relocate each section */
     for(i = 1; i < s1->nb_sections; i++) {
         s = s1->sections[i];
@@ -307,11 +311,11 @@ static void *win64_add_function_table(TCCState *s1)
         RtlAddFunctionTable(
             (RUNTIME_FUNCTION*)p,
             s1->uw_pdata->data_offset / sizeof (RUNTIME_FUNCTION),
-            text_section->sh_addr
+            s1->pe_imagebase
             );
         s1->uw_pdata = NULL;
     }
-    return p;;
+    return p;
 }
 
 static void win64_del_function_table(void *p)
diff --git a/x86_64-link.c b/x86_64-link.c
index c0c5e13..a96144c 100644
--- a/x86_64-link.c
+++ b/x86_64-link.c
@@ -287,6 +287,9 @@ void relocate(TCCState *s1, ElfW_Rel *rel, int type, 
unsigned char *ptr, addr_t
             add64le(ptr, val - s1->got->sh_addr);
             break;
         case R_X86_64_RELATIVE:
+#ifdef TCC_TARGET_PE
+            add32le(ptr, val - s1->pe_imagebase);
+#endif
             /* do nothing */
             break;
     }






reply via email to

[Prev in Thread] Current Thread [Next in Thread]