[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
This commit is contained in:
David Majnemer 2016-03-20 22:56:31 +00:00
parent 4af44f3c13
commit 2aa29ee7c1
2 changed files with 7 additions and 15 deletions

View File

@ -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;

View File

@ -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;