summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2016-03-20 22:56:31 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2016-03-20 22:56:31 +0000
commit2aa29ee7c150994d5be4acf9d13a678d97f07816 (patch)
treef9ff313839bb74cdc90d832cac0515d676921709
parent4af44f3c13fb1ab6745a694a21d349861b472d90 (diff)
downloadbcm5719-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.cpp21
-rw-r--r--lld/COFF/InputFiles.h1
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;
OpenPOWER on IntegriCloud