[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