class DefinedAbsolute;
class DefinedRelative;
class StringChunk;
-struct Symbol;
class SymbolBody;
// Short aliases.
bool SaveTemps = false;
// Used for SafeSEH.
- Symbol *SEHTable = nullptr;
- Symbol *SEHCount = nullptr;
+ SymbolBody *SEHTable = nullptr;
+ SymbolBody *SEHCount = nullptr;
// Used for /opt:lldlto=N
unsigned LTOOptLevel = 2;
};
for (auto E : Entries) {
StringRef Entry = Symtab->findMangle(mangle(E[0]));
- if (!Entry.empty() && !isa<Undefined>(Symtab->find(Entry)->body()))
+ if (!Entry.empty() && !isa<Undefined>(Symtab->find(Entry)))
return mangle(E[1]);
}
return "";
for (auto Pair : Config->AlternateNames) {
StringRef From = Pair.first;
StringRef To = Pair.second;
- Symbol *Sym = Symtab->find(From);
+ SymbolBody *Sym = Symtab->find(From);
if (!Sym)
continue;
- if (auto *U = dyn_cast<Undefined>(Sym->body()))
+ if (auto *U = dyn_cast<Undefined>(Sym))
if (!U->WeakAlias)
U->WeakAlias = Symtab->addUndefined(To);
}
Args.hasArg(OPT_export_all_symbols))) {
AutoExporter Exporter;
- Symtab->forEachSymbol([=](Symbol *S) {
- auto *Def = dyn_cast<Defined>(S->body());
+ Symtab->forEachSymbol([=](SymbolBody *S) {
+ auto *Def = dyn_cast<Defined>(S);
if (!Exporter.shouldExport(Def))
return;
Export E;
StringRef Name = Pair.first;
uint32_t Alignment = Pair.second;
- Symbol *Sym = Symtab->find(Name);
+ SymbolBody *Sym = Symtab->find(Name);
if (!Sym) {
warn("/aligncomm symbol " + Name + " not found");
continue;
}
- auto *DC = dyn_cast<DefinedCommon>(Sym->body());
+ auto *DC = dyn_cast<DefinedCommon>(Sym);
if (!DC) {
warn("/aligncomm symbol " + Name + " of wrong kind");
continue;
SymbolBody *Source, SymbolBody *Target) {
if (auto *U = dyn_cast<Undefined>(Source)) {
if (U->WeakAlias && U->WeakAlias != Target)
- Symtab->reportDuplicate(Source->symbol(), F);
+ Symtab->reportDuplicate(Source, F);
U->WeakAlias = Target;
}
}
SymbolBody *ObjFile::createUndefined(COFFSymbolRef Sym) {
StringRef Name;
COFFObj->getSymbolName(Sym, Name);
- return Symtab->addUndefined(Name, this, Sym.isWeakExternal())->body();
+ return Symtab->addUndefined(Name, this, Sym.isWeakExternal());
}
SymbolBody *ObjFile::createDefined(COFFSymbolRef Sym, const void *AuxP,
auto *C = make<CommonChunk>(Sym);
Chunks.push_back(C);
COFFObj->getSymbolName(Sym, Name);
- Symbol *S =
+ SymbolBody *S =
Symtab->addCommon(this, Name, Sym.getValue(), Sym.getGeneric(), C);
- return S->body();
+ return S;
}
if (Sym.isAbsolute()) {
COFFObj->getSymbolName(Sym, Name);
return nullptr;
}
if (Sym.isExternal())
- return Symtab->addAbsolute(Name, Sym)->body();
+ return Symtab->addAbsolute(Name, Sym);
else
return make<DefinedAbsolute>(Name, Sym);
}
DefinedRegular *B;
if (Sym.isExternal()) {
COFFObj->getSymbolName(Sym, Name);
- Symbol *S =
+ SymbolBody *S =
Symtab->addRegular(this, Name, SC->isCOMDAT(), Sym.getGeneric(), SC);
- B = cast<DefinedRegular>(S->body());
+ B = cast<DefinedRegular>(S);
} else
B = make<DefinedRegular>(this, /*Name*/ "", SC->isCOMDAT(),
/*IsExternal*/ false, Sym.getGeneric(), SC);
MB.getBuffer(), Saver.save(ParentName + MB.getBufferIdentifier()))));
for (const lto::InputFile::Symbol &ObjSym : Obj->symbols()) {
StringRef SymName = Saver.save(ObjSym.getName());
- Symbol *Sym;
+ SymbolBody *Sym;
if (ObjSym.isUndefined()) {
Sym = Symtab->addUndefined(SymName, this, false);
} else if (ObjSym.isCommon()) {
Sym = Symtab->addUndefined(SymName, this, true);
std::string Fallback = ObjSym.getCOFFWeakExternalFallback();
SymbolBody *Alias = Symtab->addUndefined(Saver.save(Fallback));
- checkAndSetWeakAlias(Symtab, this, Sym->body(), Alias);
+ checkAndSetWeakAlias(Symtab, this, Sym, Alias);
} else {
bool IsCOMDAT = ObjSym.getComdatIndex() != -1;
Sym = Symtab->addRegular(this, SymName, IsCOMDAT);
}
- SymbolBodies.push_back(Sym->body());
+ SymbolBodies.push_back(Sym);
}
Directives = Obj->getCOFFLinkerOpts();
}
class DefinedImportThunk;
class Lazy;
class SectionChunk;
-struct Symbol;
class SymbolBody;
class Undefined;
BitcodeCompiler::~BitcodeCompiler() = default;
-static void undefine(Symbol *S) {
- replaceBody<Undefined>(S, S->body()->getName());
-}
+static void undefine(SymbolBody *S) { replaceBody<Undefined>(S, S->getName()); }
void BitcodeCompiler::add(BitcodeFile &F) {
lto::InputFile &Obj = *F.Obj;
// Provide a resolution to the LTO API for each symbol.
for (const lto::InputFile::Symbol &ObjSym : Obj.symbols()) {
- SymbolBody *B = SymBodies[SymNum];
- Symbol *Sym = B->symbol();
+ SymbolBody *Sym = SymBodies[SymNum];
lto::SymbolResolution &R = Resols[SymNum];
++SymNum;
// flags an undefined in IR with a definition in ASM as prevailing.
// Once IRObjectFile is fixed to report only one symbol this hack can
// be removed.
- R.Prevailing = !ObjSym.isUndefined() && B->getFile() == &F;
+ R.Prevailing = !ObjSym.isUndefined() && Sym->getFile() == &F;
R.VisibleToRegularObj = Sym->IsUsedInRegularObj;
if (R.Prevailing)
undefine(Sym);
// Compute the public and global symbols.
auto &GsiBuilder = Builder.getGsiBuilder();
std::vector<PublicSym32> Publics;
- Symtab->forEachSymbol([&Publics](Symbol *S) {
+ Symtab->forEachSymbol([&Publics](SymbolBody *S) {
// Only emit defined, live symbols that have a chunk.
- auto *Def = dyn_cast<Defined>(S->body());
+ auto *Def = dyn_cast<Defined>(S);
if (Def && Def->isLive() && Def->getChunk())
Publics.push_back(createPublic(Def));
});
/// Checks if an existing symbol S should be kept or replaced by a new symbol.
/// Returns SP_EXISTING when S should be kept, SP_NEW when the new symbol
/// should be kept, and SP_CONFLICT if no valid resolution exists.
-static SymbolPreference compareDefined(Symbol *S, bool WasInserted,
+static SymbolPreference compareDefined(SymbolBody *S, bool WasInserted,
bool NewIsCOMDAT) {
// If the symbol wasn't previously known, the new symbol wins by default.
- if (WasInserted || !isa<Defined>(S->body()))
+ if (WasInserted || !isa<Defined>(S))
return SP_NEW;
// If the existing symbol is a DefinedRegular, both it and the new symbol
// must be comdats. In that case, we have no reason to prefer one symbol
// over the other, and we keep the existing one. If one of the symbols
// is not a comdat, we report a conflict.
- if (auto *R = dyn_cast<DefinedRegular>(S->body())) {
+ if (auto *R = dyn_cast<DefinedRegular>(S)) {
if (NewIsCOMDAT && R->isCOMDAT())
return SP_EXISTING;
else
SmallPtrSet<SymbolBody *, 8> Undefs;
for (auto &I : Symtab) {
- Symbol *Sym = I.second;
- auto *Undef = dyn_cast<Undefined>(Sym->body());
+ SymbolBody *Sym = I.second;
+ auto *Undef = dyn_cast<Undefined>(Sym);
if (!Undef)
continue;
if (!Sym->IsUsedInRegularObj)
// A weak alias may have been resolved, so check for that.
if (Defined *D = Undef->getWeakAlias()) {
- // We resolve weak aliases by replacing the alias's SymbolBody with the
- // target's SymbolBody. This causes all SymbolBody pointers referring to
- // the old symbol to instead refer to the new symbol. However, we can't
- // just blindly copy sizeof(Symbol::Body) bytes from D to Sym->Body
- // because D may be an internal symbol, and internal symbols are stored as
- // "unparented" SymbolBodies. For that reason we need to check which type
- // of symbol we are dealing with and copy the correct number of bytes.
- if (isa<DefinedRegular>(D))
- memcpy(Sym->Body.buffer, D, sizeof(DefinedRegular));
- else if (isa<DefinedAbsolute>(D))
- memcpy(Sym->Body.buffer, D, sizeof(DefinedAbsolute));
- else
- // No other internal symbols are possible.
- Sym->Body = D->symbol()->Body;
+ memcpy(Sym, D, sizeof(SymbolUnion));
continue;
}
// If we can resolve a symbol by removing __imp_ prefix, do that.
// This odd rule is for compatibility with MSVC linker.
if (Name.startswith("__imp_")) {
- Symbol *Imp = find(Name.substr(strlen("__imp_")));
- if (Imp && isa<Defined>(Imp->body())) {
- auto *D = cast<Defined>(Imp->body());
+ SymbolBody *Imp = find(Name.substr(strlen("__imp_")));
+ if (Imp && isa<Defined>(Imp)) {
+ auto *D = cast<Defined>(Imp);
replaceBody<DefinedLocalImport>(Sym, Name, D);
- LocalImportChunks.push_back(
- cast<DefinedLocalImport>(Sym->body())->getChunk());
+ LocalImportChunks.push_back(cast<DefinedLocalImport>(Sym)->getChunk());
continue;
}
}
// They are replaced with dummy defined symbols.
if (Config->Force)
replaceBody<DefinedAbsolute>(Sym, Name, 0);
- Undefs.insert(Sym->body());
+ Undefs.insert(Sym);
}
if (Undefs.empty())
errorOrWarn(toString(File) + ": undefined symbol: " + Sym->getName());
}
-std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name) {
- Symbol *&Sym = Symtab[CachedHashStringRef(Name)];
+std::pair<SymbolBody *, bool> SymbolTable::insert(StringRef Name) {
+ SymbolBody *&Sym = Symtab[CachedHashStringRef(Name)];
if (Sym)
return {Sym, false};
- Sym = make<Symbol>();
+ Sym = (SymbolBody *)make<SymbolUnion>();
Sym->IsUsedInRegularObj = false;
Sym->PendingArchiveLoad = false;
return {Sym, true};
}
-Symbol *SymbolTable::addUndefined(StringRef Name, InputFile *F,
- bool IsWeakAlias) {
- Symbol *S;
+SymbolBody *SymbolTable::addUndefined(StringRef Name, InputFile *F,
+ bool IsWeakAlias) {
+ SymbolBody *S;
bool WasInserted;
std::tie(S, WasInserted) = insert(Name);
if (!F || !isa<BitcodeFile>(F))
S->IsUsedInRegularObj = true;
- if (WasInserted || (isa<Lazy>(S->body()) && IsWeakAlias)) {
+ if (WasInserted || (isa<Lazy>(S) && IsWeakAlias)) {
replaceBody<Undefined>(S, Name);
return S;
}
- if (auto *L = dyn_cast<Lazy>(S->body())) {
+ if (auto *L = dyn_cast<Lazy>(S)) {
if (!S->PendingArchiveLoad) {
S->PendingArchiveLoad = true;
L->File->addMember(&L->Sym);
void SymbolTable::addLazy(ArchiveFile *F, const Archive::Symbol Sym) {
StringRef Name = Sym.getName();
- Symbol *S;
+ SymbolBody *S;
bool WasInserted;
std::tie(S, WasInserted) = insert(Name);
if (WasInserted) {
replaceBody<Lazy>(S, F, Sym);
return;
}
- auto *U = dyn_cast<Undefined>(S->body());
+ auto *U = dyn_cast<Undefined>(S);
if (!U || U->WeakAlias || S->PendingArchiveLoad)
return;
S->PendingArchiveLoad = true;
F->addMember(&Sym);
}
-void SymbolTable::reportDuplicate(Symbol *Existing, InputFile *NewFile) {
- error("duplicate symbol: " + toString(*Existing->body()) + " in " +
- toString(Existing->body()->getFile()) + " and in " +
+void SymbolTable::reportDuplicate(SymbolBody *Existing, InputFile *NewFile) {
+ error("duplicate symbol: " + toString(*Existing) + " in " +
+ toString(Existing->getFile()) + " and in " +
(NewFile ? toString(NewFile) : "(internal)"));
}
-Symbol *SymbolTable::addAbsolute(StringRef N, COFFSymbolRef Sym) {
- Symbol *S;
+SymbolBody *SymbolTable::addAbsolute(StringRef N, COFFSymbolRef Sym) {
+ SymbolBody *S;
bool WasInserted;
std::tie(S, WasInserted) = insert(N);
S->IsUsedInRegularObj = true;
- if (WasInserted || isa<Undefined>(S->body()) || isa<Lazy>(S->body()))
+ if (WasInserted || isa<Undefined>(S) || isa<Lazy>(S))
replaceBody<DefinedAbsolute>(S, N, Sym);
- else if (!isa<DefinedCOFF>(S->body()))
+ else if (!isa<DefinedCOFF>(S))
reportDuplicate(S, nullptr);
return S;
}
-Symbol *SymbolTable::addAbsolute(StringRef N, uint64_t VA) {
- Symbol *S;
+SymbolBody *SymbolTable::addAbsolute(StringRef N, uint64_t VA) {
+ SymbolBody *S;
bool WasInserted;
std::tie(S, WasInserted) = insert(N);
S->IsUsedInRegularObj = true;
- if (WasInserted || isa<Undefined>(S->body()) || isa<Lazy>(S->body()))
+ if (WasInserted || isa<Undefined>(S) || isa<Lazy>(S))
replaceBody<DefinedAbsolute>(S, N, VA);
- else if (!isa<DefinedCOFF>(S->body()))
+ else if (!isa<DefinedCOFF>(S))
reportDuplicate(S, nullptr);
return S;
}
-Symbol *SymbolTable::addSynthetic(StringRef N, Chunk *C) {
- Symbol *S;
+SymbolBody *SymbolTable::addSynthetic(StringRef N, Chunk *C) {
+ SymbolBody *S;
bool WasInserted;
std::tie(S, WasInserted) = insert(N);
S->IsUsedInRegularObj = true;
- if (WasInserted || isa<Undefined>(S->body()) || isa<Lazy>(S->body()))
+ if (WasInserted || isa<Undefined>(S) || isa<Lazy>(S))
replaceBody<DefinedSynthetic>(S, N, C);
- else if (!isa<DefinedCOFF>(S->body()))
+ else if (!isa<DefinedCOFF>(S))
reportDuplicate(S, nullptr);
return S;
}
-Symbol *SymbolTable::addRegular(InputFile *F, StringRef N, bool IsCOMDAT,
- const coff_symbol_generic *Sym,
- SectionChunk *C) {
- Symbol *S;
+SymbolBody *SymbolTable::addRegular(InputFile *F, StringRef N, bool IsCOMDAT,
+ const coff_symbol_generic *Sym,
+ SectionChunk *C) {
+ SymbolBody *S;
bool WasInserted;
std::tie(S, WasInserted) = insert(N);
if (!isa<BitcodeFile>(F))
return S;
}
-Symbol *SymbolTable::addCommon(InputFile *F, StringRef N, uint64_t Size,
- const coff_symbol_generic *Sym, CommonChunk *C) {
- Symbol *S;
+SymbolBody *SymbolTable::addCommon(InputFile *F, StringRef N, uint64_t Size,
+ const coff_symbol_generic *Sym,
+ CommonChunk *C) {
+ SymbolBody *S;
bool WasInserted;
std::tie(S, WasInserted) = insert(N);
if (!isa<BitcodeFile>(F))
S->IsUsedInRegularObj = true;
- if (WasInserted || !isa<DefinedCOFF>(S->body()))
+ if (WasInserted || !isa<DefinedCOFF>(S))
replaceBody<DefinedCommon>(S, F, N, Size, Sym, C);
- else if (auto *DC = dyn_cast<DefinedCommon>(S->body()))
+ else if (auto *DC = dyn_cast<DefinedCommon>(S))
if (Size > DC->getSize())
replaceBody<DefinedCommon>(S, F, N, Size, Sym, C);
return S;
}
DefinedImportData *SymbolTable::addImportData(StringRef N, ImportFile *F) {
- Symbol *S;
+ SymbolBody *S;
bool WasInserted;
std::tie(S, WasInserted) = insert(N);
S->IsUsedInRegularObj = true;
- if (WasInserted || isa<Undefined>(S->body()) || isa<Lazy>(S->body())) {
+ if (WasInserted || isa<Undefined>(S) || isa<Lazy>(S)) {
replaceBody<DefinedImportData>(S, N, F);
- return cast<DefinedImportData>(S->body());
+ return cast<DefinedImportData>(S);
}
reportDuplicate(S, F);
DefinedImportThunk *SymbolTable::addImportThunk(StringRef Name,
DefinedImportData *ID,
uint16_t Machine) {
- Symbol *S;
+ SymbolBody *S;
bool WasInserted;
std::tie(S, WasInserted) = insert(Name);
S->IsUsedInRegularObj = true;
- if (WasInserted || isa<Undefined>(S->body()) || isa<Lazy>(S->body())) {
+ if (WasInserted || isa<Undefined>(S) || isa<Lazy>(S)) {
replaceBody<DefinedImportThunk>(S, Name, ID, Machine);
- return cast<DefinedImportThunk>(S->body());
+ return cast<DefinedImportThunk>(S);
}
reportDuplicate(S, ID->File);
return Res;
}
-Symbol *SymbolTable::find(StringRef Name) {
+SymbolBody *SymbolTable::find(StringRef Name) {
auto It = Symtab.find(CachedHashStringRef(Name));
if (It == Symtab.end())
return nullptr;
return It->second;
}
-Symbol *SymbolTable::findUnderscore(StringRef Name) {
+SymbolBody *SymbolTable::findUnderscore(StringRef Name) {
if (Config->Machine == I386)
return find(("_" + Name).str());
return find(Name);
}
StringRef SymbolTable::findMangle(StringRef Name) {
- if (Symbol *Sym = find(Name))
- if (!isa<Undefined>(Sym->body()))
+ if (SymbolBody *Sym = find(Name))
+ if (!isa<Undefined>(Sym))
return Name;
if (Config->Machine != I386)
return findByPrefix(("?" + Name + "@@Y").str());
}
SymbolBody *SymbolTable::addUndefined(StringRef Name) {
- return addUndefined(Name, nullptr, false)->body();
+ return addUndefined(Name, nullptr, false);
}
std::vector<StringRef> SymbolTable::compileBitcodeFiles() {
class Lazy;
class SectionChunk;
class SymbolBody;
-struct Symbol;
// SymbolTable is a bucket of all known symbols, including defined,
// undefined, or lazy symbols (the last one is symbols in archive
std::vector<Chunk *> getChunks();
// Returns a symbol for a given name. Returns a nullptr if not found.
- Symbol *find(StringRef Name);
- Symbol *findUnderscore(StringRef Name);
+ SymbolBody *find(StringRef Name);
+ SymbolBody *findUnderscore(StringRef Name);
// Occasionally we have to resolve an undefined symbol to its
// mangled symbol. This function tries to find a mangled name
// Creates an Undefined symbol for a given name.
SymbolBody *addUndefined(StringRef Name);
- Symbol *addSynthetic(StringRef N, Chunk *C);
- Symbol *addAbsolute(StringRef N, uint64_t VA);
+ SymbolBody *addSynthetic(StringRef N, Chunk *C);
+ SymbolBody *addAbsolute(StringRef N, uint64_t VA);
- Symbol *addUndefined(StringRef Name, InputFile *F, bool IsWeakAlias);
+ SymbolBody *addUndefined(StringRef Name, InputFile *F, bool IsWeakAlias);
void addLazy(ArchiveFile *F, const Archive::Symbol Sym);
- Symbol *addAbsolute(StringRef N, COFFSymbolRef S);
- Symbol *addRegular(InputFile *F, StringRef N, bool IsCOMDAT,
- const llvm::object::coff_symbol_generic *S = nullptr,
- SectionChunk *C = nullptr);
- Symbol *addCommon(InputFile *F, StringRef N, uint64_t Size,
- const llvm::object::coff_symbol_generic *S = nullptr,
- CommonChunk *C = nullptr);
+ SymbolBody *addAbsolute(StringRef N, COFFSymbolRef S);
+ SymbolBody *addRegular(InputFile *F, StringRef N, bool IsCOMDAT,
+ const llvm::object::coff_symbol_generic *S = nullptr,
+ SectionChunk *C = nullptr);
+ SymbolBody *addCommon(InputFile *F, StringRef N, uint64_t Size,
+ const llvm::object::coff_symbol_generic *S = nullptr,
+ CommonChunk *C = nullptr);
DefinedImportData *addImportData(StringRef N, ImportFile *F);
DefinedImportThunk *addImportThunk(StringRef Name, DefinedImportData *S,
uint16_t Machine);
- void reportDuplicate(Symbol *Existing, InputFile *NewFile);
+ void reportDuplicate(SymbolBody *Existing, InputFile *NewFile);
// A list of chunks which to be added to .rdata.
std::vector<Chunk *> LocalImportChunks;
}
private:
- std::pair<Symbol *, bool> insert(StringRef Name);
+ std::pair<SymbolBody *, bool> insert(StringRef Name);
StringRef findByPrefix(StringRef Prefix);
- llvm::DenseMap<llvm::CachedHashStringRef, Symbol *> Symtab;
+ llvm::DenseMap<llvm::CachedHashStringRef, SymbolBody *> Symtab;
std::unique_ptr<BitcodeCompiler> LTO;
};
class ArchiveFile;
class InputFile;
class ObjFile;
-struct Symbol;
class SymbolTable;
// The base class for real symbol classes.
// after calling markLive.
bool isLive() const;
- Symbol *symbol();
- const Symbol *symbol() const {
- return const_cast<SymbolBody *>(this)->symbol();
- }
-
protected:
friend SymbolTable;
explicit SymbolBody(Kind K, StringRef N = "")
// symbols from being written to the symbol table more than once.
unsigned WrittenToSymtab : 1;
+ // True if this symbol was referenced by a regular (non-bitcode) object.
+ unsigned IsUsedInRegularObj : 1;
+
+ // True if we've seen both a lazy and an undefined symbol with this symbol
+ // name, which means that we have enqueued an archive member load and should
+ // not load any more archive members to resolve the same symbol.
+ unsigned PendingArchiveLoad : 1;
+
protected:
StringRef Name;
};
llvm_unreachable("unknown symbol kind");
}
-// A real symbol object, SymbolBody, is usually stored within a Symbol. There's
-// always one Symbol for each symbol name. The resolver updates the SymbolBody
-// stored in the Body field of this object as it resolves symbols. Symbol also
-// holds computed properties of symbol names.
-struct Symbol {
- // True if this symbol was referenced by a regular (non-bitcode) object.
- unsigned IsUsedInRegularObj : 1;
-
- // True if we've seen both a lazy and an undefined symbol with this symbol
- // name, which means that we have enqueued an archive member load and should
- // not load any more archive members to resolve the same symbol.
- unsigned PendingArchiveLoad : 1;
-
- // This field is used to store the Symbol's SymbolBody. This instantiation of
- // AlignedCharArrayUnion gives us a struct with a char array field that is
- // large and aligned enough to store any derived class of SymbolBody.
- llvm::AlignedCharArrayUnion<
- DefinedRegular, DefinedCommon, DefinedAbsolute, DefinedSynthetic, Lazy,
- Undefined, DefinedImportData, DefinedImportThunk, DefinedLocalImport>
- Body;
-
- SymbolBody *body() {
- return reinterpret_cast<SymbolBody *>(Body.buffer);
- }
- const SymbolBody *body() const { return const_cast<Symbol *>(this)->body(); }
+// A buffer class that is large enough to hold any SymbolBody-derived
+// object. We allocate memory using this class and instantiate a symbol
+// using the placement new.
+union SymbolUnion {
+ alignas(DefinedCOFF) char A[sizeof(DefinedCOFF)];
+ alignas(DefinedRegular) char B[sizeof(DefinedRegular)];
+ alignas(DefinedCommon) char C[sizeof(DefinedCommon)];
+ alignas(DefinedAbsolute) char D[sizeof(DefinedAbsolute)];
+ alignas(DefinedSynthetic) char E[sizeof(DefinedSynthetic)];
+ alignas(Lazy) char F[sizeof(Lazy)];
+ alignas(Undefined) char G[sizeof(Undefined)];
+ alignas(DefinedImportData) char H[sizeof(DefinedImportData)];
+ alignas(DefinedImportThunk) char I[sizeof(DefinedImportThunk)];
+ alignas(DefinedLocalImport) char J[sizeof(DefinedLocalImport)];
};
template <typename T, typename... ArgT>
-void replaceBody(Symbol *S, ArgT &&... Arg) {
- static_assert(sizeof(T) <= sizeof(S->Body), "Body too small");
- static_assert(alignof(T) <= alignof(decltype(S->Body)),
- "Body not aligned enough");
+void replaceBody(SymbolBody *S, ArgT &&... Arg) {
+ static_assert(sizeof(T) <= sizeof(SymbolUnion), "Symbol too small");
+ static_assert(alignof(T) <= alignof(SymbolUnion),
+ "SymbolUnion not aligned enough");
assert(static_cast<SymbolBody *>(static_cast<T *>(nullptr)) == nullptr &&
"Not a SymbolBody");
- new (S->Body.buffer) T(std::forward<ArgT>(Arg)...);
-}
-
-inline Symbol *SymbolBody::symbol() {
- assert(isExternal());
- return reinterpret_cast<Symbol *>(reinterpret_cast<char *>(this) -
- offsetof(Symbol, Body));
+ new (S) T(std::forward<ArgT>(Arg)...);
}
} // namespace coff
Dir[BASE_RELOCATION_TABLE].RelativeVirtualAddress = Sec->getRVA();
Dir[BASE_RELOCATION_TABLE].Size = Sec->getVirtualSize();
}
- if (Symbol *Sym = Symtab->findUnderscore("_tls_used")) {
- if (Defined *B = dyn_cast<Defined>(Sym->body())) {
+ if (SymbolBody *Sym = Symtab->findUnderscore("_tls_used")) {
+ if (Defined *B = dyn_cast<Defined>(Sym)) {
Dir[TLS_TABLE].RelativeVirtualAddress = B->getRVA();
Dir[TLS_TABLE].Size = Config->is64()
? sizeof(object::coff_tls_directory64)
Dir[DEBUG_DIRECTORY].RelativeVirtualAddress = DebugDirectory->getRVA();
Dir[DEBUG_DIRECTORY].Size = DebugDirectory->getSize();
}
- if (Symbol *Sym = Symtab->findUnderscore("_load_config_used")) {
- if (auto *B = dyn_cast<DefinedRegular>(Sym->body())) {
+ if (SymbolBody *Sym = Symtab->findUnderscore("_load_config_used")) {
+ if (auto *B = dyn_cast<DefinedRegular>(Sym)) {
SectionChunk *SC = B->getChunk();
assert(B->getRVA() >= SC->getRVA());
uint64_t OffsetInChunk = B->getRVA() - SC->getRVA();
// Replace the absolute table symbol with a synthetic symbol pointing to the
// SEHTable chunk so that we can emit base relocations for it and resolve
// section relative relocations.
- Symbol *T = Symtab->find("___safe_se_handler_table");
- Symbol *C = Symtab->find("___safe_se_handler_count");
- replaceBody<DefinedSynthetic>(T, T->body()->getName(), SEHTable);
- cast<DefinedAbsolute>(C->body())->setVA(SEHTable->getSize() / 4);
+ SymbolBody *T = Symtab->find("___safe_se_handler_table");
+ SymbolBody *C = Symtab->find("___safe_se_handler_count");
+ replaceBody<DefinedSynthetic>(T, T->getName(), SEHTable);
+ cast<DefinedAbsolute>(C)->setVA(SEHTable->getSize() / 4);
}
// Handles /section options to allow users to overwrite