diff --git a/rts/linker/PEi386.c b/rts/linker/PEi386.c index 82eaaaf2261d5a5a1ae97b919fabf3ae91fdd8df..f6e87dd0e65d2e995d4b07fcf0a500037dc84393 100644 --- a/rts/linker/PEi386.c +++ b/rts/linker/PEi386.c @@ -1657,6 +1657,13 @@ ocGetNames_PEi386 ( ObjectCode* oc ) } else if (symStorageClass == IMAGE_SYM_CLASS_WEAK_EXTERNAL) { isWeak = true; + CHECK(getSymNumberOfAuxSymbols (info, sym) == 1); + CHECK(symValue == 0); + COFF_symbol_aux_weak_external *aux = (COFF_symbol_aux_weak_external *) (sym+1); + COFF_symbol* targetSym = &oc->info->symbols[aux->TagIndex]; + int32_t targetSecNumber = getSymSectionNumber (info, targetSym); + Section *targetSection = targetSecNumber > 0 ? &oc->sections[targetSecNumber-1] : NULL; + addr = (SymbolAddr*) ((size_t) targetSection->start + getSymValue(info, targetSym)); } else if ( secNumber == IMAGE_SYM_UNDEFINED && symValue > 0) { /* This symbol isn't in any section at all, ie, global bss. diff --git a/rts/linker/PEi386.h b/rts/linker/PEi386.h index c5c88459a6c535d9e0f18660adc9f6e991011151..cde5974d5408a965f456791b87fcaaa80f2ac3ee 100644 --- a/rts/linker/PEi386.h +++ b/rts/linker/PEi386.h @@ -117,6 +117,12 @@ union _COFF_symbol { COFF_symbol_ex ex; } COFF_symbol; +typedef +struct { + uint32_t TagIndex; + uint32_t Characteristics; +} COFF_symbol_aux_weak_external; + /* A record for storing handles into DLLs. */ typedef struct _OpenedDLL { diff --git a/testsuite/tests/ghci/linking/all.T b/testsuite/tests/ghci/linking/all.T index b4564f02373f4e58fb5c26d7bb14830595bf6c10..197500c0390bce7f32f23e62e0ed00c70e6344a4 100644 --- a/testsuite/tests/ghci/linking/all.T +++ b/testsuite/tests/ghci/linking/all.T @@ -42,8 +42,6 @@ test('ghcilink006', test('T3333', [unless(doing_ghci, skip), - unless(opsys('linux') or opsys('darwin') or ghc_dynamic(), - expect_broken(3333)), when(unregisterised(), fragile(17018))], makefile_test, ['T3333'])