Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/llvm/llvm-project.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lld
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2015-07-04 01:03:36 +0300
committerPeter Collingbourne <peter@pcc.me.uk>2015-07-04 01:03:36 +0300
commitda2f094bbba0e18e856bcc5449b3d2d77efd3e2a (patch)
treea36e3e57c408f1dba05f4361113f0265d6413dff /lld
parentd74b4f0a3201cf39ffa57cc24fbdeaf1ab471223 (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.cpp2
-rw-r--r--lld/COFF/SymbolTable.cpp9
-rw-r--r--lld/COFF/Symbols.h2
-rw-r--r--lld/test/COFF/weak-external.test29
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
+...