[commit: ghc] master: Fix ExtraSymbols jump table on Windows. (2f1017b)

git at git.haskell.org git at git.haskell.org
Tue Feb 14 15:54:32 UTC 2017


Repository : ssh://git@git.haskell.org/ghc

On branch  : master
Link       : http://ghc.haskell.org/trac/ghc/changeset/2f1017b924740e66f093b0baba62ac0b1528abf8/ghc

>---------------------------------------------------------------

commit 2f1017b924740e66f093b0baba62ac0b1528abf8
Author: Tamar Christina <tamar at zhox.com>
Date:   Tue Feb 14 09:44:53 2017 -0500

    Fix ExtraSymbols jump table on Windows.
    
    This corrects the `jump islands` calculations for Windows.  The code was
    incorrectly creating a new entry for every `usage` of a symbol instead
    of every used symbol. e.g. if a symbol is used 5 times it used to create
    5 jump islands. This is incorrect and not in line with what the `ELF`
    and `Mach-O` linkers do. Also since we allocate `n` spaces where `n` is
    number of symbols, we would quickly run out of space and abort.
    
    Test Plan: ./validate
    
    Reviewers: simonmar, hvr, erikd, bgamari, austin
    
    Reviewed By: bgamari
    
    Subscribers: thomie, #ghc_windows_task_force
    
    Differential Revision: https://phabricator.haskell.org/D3026


>---------------------------------------------------------------

2f1017b924740e66f093b0baba62ac0b1528abf8
 rts/linker/PEi386.c | 37 +++++++++++++++++++++----------------
 1 file changed, 21 insertions(+), 16 deletions(-)

diff --git a/rts/linker/PEi386.c b/rts/linker/PEi386.c
index bfac34f..b62f1eb 100644
--- a/rts/linker/PEi386.c
+++ b/rts/linker/PEi386.c
@@ -73,6 +73,7 @@ static uint8_t* cstring_from_COFF_symbol_name(
 #if defined(x86_64_HOST_ARCH)
 static size_t makeSymbolExtra_PEi386(
     ObjectCode* oc,
+    uint64_t index,
     size_t s,
     SymbolName* symbol);
 #endif
@@ -346,7 +347,7 @@ bool removeLibrarySearchPath_PEi386(HsPtr dll_path_index)
         }
     }
 
-    return result == 0;
+    return !result;
 }
 
 
@@ -869,8 +870,7 @@ ocVerifyImage_PEi386 ( ObjectCode* oc )
                    rel->VirtualAddress );
          sym = (COFF_symbol*)
                myindex ( sizeof_COFF_symbol, symtab, rel->SymbolTableIndex );
-         /* Hmm..mysterious looking offset - what's it for? SOF */
-         printName ( sym->N.ShortName, strtab -10 );
+         printName ( sym->N.ShortName, strtab );
          debugBelch("'\n" );
       }
 
@@ -1185,24 +1185,25 @@ ocAllocateSymbolExtras_PEi386 ( ObjectCode* oc )
 }
 
 static size_t
-makeSymbolExtra_PEi386( ObjectCode* oc, size_t s, char* symbol )
+makeSymbolExtra_PEi386( ObjectCode* oc, uint64_t index, size_t s, char* symbol )
 {
     unsigned int curr_thunk;
     SymbolExtra *extra;
-
-    curr_thunk = oc->first_symbol_extra;
-    if (curr_thunk >= oc->n_symbol_extras) {
-      barf("Can't allocate thunk for %s", symbol);
+    curr_thunk = oc->first_symbol_extra + index;
+    if (index >= oc->n_symbol_extras) {
+      IF_DEBUG(linker, debugBelch("makeSymbolExtra first:%d, num:%lu, member:%s, index:%llu\n", curr_thunk, oc->n_symbol_extras, oc->archiveMemberName, index));
+      barf("Can't allocate thunk for `%s' in `%" PATH_FMT "' with member `%s'", symbol, oc->fileName, oc->archiveMemberName);
     }
 
     extra = oc->symbol_extras + curr_thunk;
 
-    // jmp *-14(%rip)
-    static uint8_t jmp[] = { 0xFF, 0x25, 0xF2, 0xFF, 0xFF, 0xFF };
-    extra->addr = (uint64_t)s;
-    memcpy(extra->jumpIsland, jmp, 6);
-
-    oc->first_symbol_extra++;
+    if (!extra->addr)
+    {
+        // jmp *-14(%rip)
+        static uint8_t jmp[] = { 0xFF, 0x25, 0xF2, 0xFF, 0xFF, 0xFF };
+        extra->addr = (uint64_t)s;
+        memcpy(extra->jumpIsland, jmp, 6);
+    }
 
     return (size_t)extra->jumpIsland;
 }
@@ -1313,6 +1314,10 @@ ocResolve_PEi386 ( ObjectCode* oc )
          sym = (COFF_symbol*)
                myindex ( sizeof_COFF_symbol,
                          symtab, reltab_j->SymbolTableIndex );
+         uint64_t symIndex = ((uint64_t)myindex(sizeof_COFF_symbol, symtab,
+                                                reltab_j->SymbolTableIndex)
+                                        - (uint64_t)symtab) / sizeof_COFF_symbol;
+
          IF_DEBUG(linker,
                   debugBelch(
                             "reloc sec %2d num %3d:  type 0x%-4x   "
@@ -1389,7 +1394,7 @@ ocResolve_PEi386 ( ObjectCode* oc )
                    v = S + ((size_t)A);
                    if (v >> 32) {
                        copyName ( sym->N.ShortName, strtab, symbol, 1000-1 );
-                       S = makeSymbolExtra_PEi386(oc, S, (char *)symbol);
+                       S = makeSymbolExtra_PEi386(oc, symIndex, S, (char *)symbol);
                        /* And retry */
                        v = S + ((size_t)A);
                        if (v >> 32) {
@@ -1407,7 +1412,7 @@ ocResolve_PEi386 ( ObjectCode* oc )
                    if ((v >> 32) && ((-v) >> 32)) {
                        /* Make the trampoline then */
                        copyName ( sym->N.ShortName, strtab, symbol, 1000-1 );
-                       S = makeSymbolExtra_PEi386(oc, S, (char *)symbol);
+                       S = makeSymbolExtra_PEi386(oc, symIndex, S, (char *)symbol);
                        /* And retry */
                        v = ((intptr_t)S) + ((intptr_t)(int32_t)A) - ((intptr_t)pP) - 4;
                        if ((v >> 32) && ((-v) >> 32)) {



More information about the ghc-commits mailing list