From 2aa29ee7c150994d5be4acf9d13a678d97f07816 Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Sun, 20 Mar 2016 22:56:31 +0000 Subject: [PATCH] [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 --- lld/COFF/InputFiles.cpp | 21 +++++++-------------- 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 bc866b61ed4d..8ff6b9ceb187 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 WeakAliases; + llvm::SmallVector, 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(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 6a263fbaddf6..76a13c987e19 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 COFFObj; llvm::BumpPtrAllocator Alloc;