diff options
author | Peter Collingbourne <peter@pcc.me.uk> | 2015-07-04 01:03:36 +0300 |
---|---|---|
committer | Peter Collingbourne <peter@pcc.me.uk> | 2015-07-04 01:03:36 +0300 |
commit | da2f094bbba0e18e856bcc5449b3d2d77efd3e2a (patch) | |
tree | a36e3e57c408f1dba05f4361113f0265d6413dff /lld | |
parent | d74b4f0a3201cf39ffa57cc24fbdeaf1ab471223 (diff) |
COFF: Fix the case where an object defines a weak external and its alias.
This worked before, but only by accident, and only with assertions disabled.
We ended up storing a DefinedRegular symbol in the WeakAlias field,
and never using it as an Undefined.
Differential Revision: http://reviews.llvm.org/D10934
llvm-svn: 241376
Diffstat (limited to 'lld')
-rw-r--r-- | lld/COFF/InputFiles.cpp | 2 | ||||
-rw-r--r-- | lld/COFF/SymbolTable.cpp | 9 | ||||
-rw-r--r-- | lld/COFF/Symbols.h | 2 | ||||
-rw-r--r-- | lld/test/COFF/weak-external.test | 29 |
4 files changed, 36 insertions, 6 deletions
diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp index 395d51067c79..3bb3c6f36d4e 100644 --- a/lld/COFF/InputFiles.cpp +++ b/lld/COFF/InputFiles.cpp @@ -199,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 = cast<Undefined>(SparseSymbolBodies[Aux->TagIndex]); + U->WeakAlias = SparseSymbolBodies[Aux->TagIndex]; return U; } diff --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp index 4a08c49757c6..0bc8ff3fafaa 100644 --- a/lld/COFF/SymbolTable.cpp +++ b/lld/COFF/SymbolTable.cpp @@ -126,10 +126,11 @@ bool SymbolTable::reportRemainingUndefines() { if (!Undef) continue; StringRef Name = Undef->getName(); - // A weak alias may have been resovled, so check for that. A weak alias - // may be an weak alias to other symbol, so check recursively. - for (Undefined *U = Undef->WeakAlias; U; U = U->WeakAlias) { - if (auto *D = dyn_cast<Defined>(U->repl())) { + // A weak alias may have been resolved, so check for that. A weak alias + // may be a weak alias to another symbol, so check recursively. + for (SymbolBody *A = Undef->WeakAlias; A; + A = cast<Undefined>(A)->WeakAlias) { + if (auto *D = dyn_cast<Defined>(A->repl())) { Sym->Body = D; goto next; } diff --git a/lld/COFF/Symbols.h b/lld/COFF/Symbols.h index 459d04c47348..e695c39feb3f 100644 --- a/lld/COFF/Symbols.h +++ b/lld/COFF/Symbols.h @@ -253,7 +253,7 @@ public: // undefined symbol a second chance if it would remain undefined. // If it remains undefined, it'll be replaced with whatever the // Alias pointer points to. - Undefined *WeakAlias = nullptr; + SymbolBody *WeakAlias = nullptr; }; // Windows-specific classes. diff --git a/lld/test/COFF/weak-external.test b/lld/test/COFF/weak-external.test new file mode 100644 index 000000000000..294fecda8155 --- /dev/null +++ b/lld/test/COFF/weak-external.test @@ -0,0 +1,29 @@ +# RUN: yaml2obj %s > %t.obj +# RUN: lld -flavor link2 /out:%t.exe /entry:g /subsystem:console %t.obj + +--- +header: + Machine: IMAGE_FILE_MACHINE_AMD64 + Characteristics: [ ] +sections: + - Name: '.text' + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + 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 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_WEAK_EXTERNAL + WeakExternal: + TagIndex: 0 + Characteristics: IMAGE_WEAK_EXTERN_SEARCH_LIBRARY +... |