diff options
| author | David Majnemer <david.majnemer@gmail.com> | 2016-03-20 22:56:31 +0000 |
|---|---|---|
| committer | David Majnemer <david.majnemer@gmail.com> | 2016-03-20 22:56:31 +0000 |
| commit | 2aa29ee7c150994d5be4acf9d13a678d97f07816 (patch) | |
| tree | f9ff313839bb74cdc90d832cac0515d676921709 | |
| parent | 4af44f3c13fb1ab6745a694a21d349861b472d90 (diff) | |
| download | bcm5719-llvm-2aa29ee7c150994d5be4acf9d13a678d97f07816.tar.gz bcm5719-llvm-2aa29ee7c150994d5be4acf9d13a678d97f07816.zip | |
[COFF] Remove undefined behavior from ObjectFile::createWeakExternal
LLD type-punned an integral type and a pointer type using a pointer
field. This is problematic because the pointer type has alignment
greater than some of the integral values.
This would be less problematic if a union was used but it turns out the
integral values are only present for a short, transient, amount of time.
Let's remove this undefined behavior by skipping the punning altogether
by storing the state in a separate memory location: a vector which
informs us which symbols to process for weak externs.
llvm-svn: 263918
| -rw-r--r-- | lld/COFF/InputFiles.cpp | 21 | ||||
| -rw-r--r-- | lld/COFF/InputFiles.h | 1 |
2 files changed, 7 insertions, 15 deletions
diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp index bc866b61ed4..8ff6b9ceb18 100644 --- a/lld/COFF/InputFiles.cpp +++ b/lld/COFF/InputFiles.cpp @@ -149,7 +149,7 @@ void ObjectFile::initializeSymbols() { uint32_t NumSymbols = COFFObj->getNumberOfSymbols(); SymbolBodies.reserve(NumSymbols); SparseSymbolBodies.resize(NumSymbols); - llvm::SmallVector<Undefined *, 8> WeakAliases; + llvm::SmallVector<std::pair<Undefined *, uint32_t>, 8> WeakAliases; int32_t LastSectionNumber = 0; for (uint32_t I = 0; I < NumSymbols; ++I) { // Get a COFFSymbolRef object. @@ -167,8 +167,10 @@ void ObjectFile::initializeSymbols() { if (Sym.isUndefined()) { Body = createUndefined(Sym); } else if (Sym.isWeakExternal()) { - Body = createWeakExternal(Sym, AuxP); - WeakAliases.push_back((Undefined *)Body); + Body = createUndefined(Sym); + uint32_t TagIndex = + static_cast<const coff_aux_weak_external *>(AuxP)->TagIndex; + WeakAliases.emplace_back((Undefined *)Body, TagIndex); } else { Body = createDefined(Sym, AuxP, IsFirst); } @@ -179,8 +181,8 @@ void ObjectFile::initializeSymbols() { I += Sym.getNumberOfAuxSymbols(); LastSectionNumber = Sym.getSectionNumber(); } - for (Undefined *U : WeakAliases) - U->WeakAlias = SparseSymbolBodies[(uintptr_t)U->WeakAlias]; + for (auto WeakAlias : WeakAliases) + WeakAlias.first->WeakAlias = SparseSymbolBodies[WeakAlias.second]; } Undefined *ObjectFile::createUndefined(COFFSymbolRef Sym) { @@ -189,15 +191,6 @@ Undefined *ObjectFile::createUndefined(COFFSymbolRef Sym) { return new (Alloc) Undefined(Name); } -Undefined *ObjectFile::createWeakExternal(COFFSymbolRef Sym, const void *AuxP) { - StringRef Name; - COFFObj->getSymbolName(Sym, Name); - auto *U = new (Alloc) Undefined(Name); - auto *Aux = (const coff_aux_weak_external *)AuxP; - U->WeakAlias = (Undefined *)(uintptr_t)Aux->TagIndex; - return U; -} - Defined *ObjectFile::createDefined(COFFSymbolRef Sym, const void *AuxP, bool IsFirst) { StringRef Name; diff --git a/lld/COFF/InputFiles.h b/lld/COFF/InputFiles.h index 6a263fbaddf..76a13c987e1 100644 --- a/lld/COFF/InputFiles.h +++ b/lld/COFF/InputFiles.h @@ -147,7 +147,6 @@ private: Defined *createDefined(COFFSymbolRef Sym, const void *Aux, bool IsFirst); Undefined *createUndefined(COFFSymbolRef Sym); - Undefined *createWeakExternal(COFFSymbolRef Sym, const void *Aux); std::unique_ptr<COFFObjectFile> COFFObj; llvm::BumpPtrAllocator Alloc; |

