Commit 2f1017b9 authored by Tamar Christina's avatar Tamar Christina Committed by Ben Gamari
Browse files

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
parent 04f67c99
......@@ -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)) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment