diff options
| author | Rui Ueyama <ruiu@google.com> | 2015-08-17 23:35:43 +0000 |
|---|---|---|
| committer | Rui Ueyama <ruiu@google.com> | 2015-08-17 23:35:43 +0000 |
| commit | 7171c8219447c3a6803b1f1c21e6af5665aaca08 (patch) | |
| tree | 675dbc16c0dd70bf51b89e922f765908515eebc3 | |
| parent | a3f6f9477b0781617102a0e62695fcd0ea5ca942 (diff) | |
| download | bcm5719-llvm-7171c8219447c3a6803b1f1c21e6af5665aaca08.tar.gz bcm5719-llvm-7171c8219447c3a6803b1f1c21e6af5665aaca08.zip | |
COFF: Allow forward reference for weak externals
Previously, weak external symbols could reference only symbols that
appeared before them. Although that covers almost all use cases
of weak externals, there are object files out there which contains
weak externals that have forward references.
This patch supports such weak externals.
llvm-svn: 245258
| -rw-r--r-- | lld/COFF/InputFiles.cpp | 6 | ||||
| -rw-r--r-- | lld/COFF/Symbols.cpp | 2 | ||||
| -rw-r--r-- | lld/test/COFF/weak-external.test | 14 |
3 files changed, 13 insertions, 9 deletions
diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp index 1113c5e4af0..5da40d04ce0 100644 --- a/lld/COFF/InputFiles.cpp +++ b/lld/COFF/InputFiles.cpp @@ -154,6 +154,7 @@ void ObjectFile::initializeSymbols() { uint32_t NumSymbols = COFFObj->getNumberOfSymbols(); SymbolBodies.reserve(NumSymbols); SparseSymbolBodies.resize(NumSymbols); + llvm::SmallVector<Undefined *, 8> WeakAliases; int32_t LastSectionNumber = 0; for (uint32_t I = 0; I < NumSymbols; ++I) { // Get a COFFSymbolRef object. @@ -172,6 +173,7 @@ void ObjectFile::initializeSymbols() { Body = createUndefined(Sym); } else if (Sym.isWeakExternal()) { Body = createWeakExternal(Sym, AuxP); + WeakAliases.push_back((Undefined *)Body); } else { Body = createDefined(Sym, AuxP, IsFirst); } @@ -182,6 +184,8 @@ void ObjectFile::initializeSymbols() { I += Sym.getNumberOfAuxSymbols(); LastSectionNumber = Sym.getSectionNumber(); } + for (Undefined *U : WeakAliases) + U->WeakAlias = SparseSymbolBodies[(uintptr_t)U->WeakAlias]; } Undefined *ObjectFile::createUndefined(COFFSymbolRef Sym) { @@ -195,7 +199,7 @@ Undefined *ObjectFile::createWeakExternal(COFFSymbolRef Sym, const void *AuxP) { COFFObj->getSymbolName(Sym, Name); auto *U = new (Alloc) Undefined(Name); auto *Aux = (const coff_aux_weak_external *)AuxP; - U->WeakAlias = SparseSymbolBodies[Aux->TagIndex]; + U->WeakAlias = (Undefined *)(uintptr_t)Aux->TagIndex; return U; } diff --git a/lld/COFF/Symbols.cpp b/lld/COFF/Symbols.cpp index c0324fdb3be..d732d76cfb0 100644 --- a/lld/COFF/Symbols.cpp +++ b/lld/COFF/Symbols.cpp @@ -132,7 +132,7 @@ int SymbolBody::compare(SymbolBody *Other) { auto *RHS = cast<Undefined>(Other); // Tie if both undefined symbols have different weak aliases. if (LHS->WeakAlias && RHS->WeakAlias) { - if (LHS->WeakAlias->repl() != RHS->WeakAlias->repl()) + if (LHS->WeakAlias->getName() != RHS->WeakAlias->getName()) return 0; return uintptr_t(LHS) < uintptr_t(RHS) ? 1 : -1; } diff --git a/lld/test/COFF/weak-external.test b/lld/test/COFF/weak-external.test index 32aa2fc586b..bb0b3f6fcab 100644 --- a/lld/test/COFF/weak-external.test +++ b/lld/test/COFF/weak-external.test @@ -18,12 +18,6 @@ sections: Alignment: 16 SectionData: 00 symbols: - - Name: 'f' - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL - Name: 'g' Value: 0 SectionNumber: 0 @@ -31,6 +25,12 @@ symbols: ComplexType: IMAGE_SYM_DTYPE_FUNCTION StorageClass: IMAGE_SYM_CLASS_WEAK_EXTERNAL WeakExternal: - TagIndex: 0 + TagIndex: 2 Characteristics: IMAGE_WEAK_EXTERN_SEARCH_LIBRARY + - Name: 'f' + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL ... |

