summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2015-08-17 23:35:43 +0000
committerRui Ueyama <ruiu@google.com>2015-08-17 23:35:43 +0000
commit7171c8219447c3a6803b1f1c21e6af5665aaca08 (patch)
tree675dbc16c0dd70bf51b89e922f765908515eebc3
parenta3f6f9477b0781617102a0e62695fcd0ea5ca942 (diff)
downloadbcm5719-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.cpp6
-rw-r--r--lld/COFF/Symbols.cpp2
-rw-r--r--lld/test/COFF/weak-external.test14
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
...
OpenPOWER on IntegriCloud