static uint64_t SymbolValue(const MCSymbol &Sym, const MCAsmLayout &Layout);
static bool isInSymtab(const MCAsmLayout &Layout, const MCSymbol &Symbol,
bool Used, bool Renamed);
- static bool isLocal(const MCSymbol &Symbol, bool isUsedInReloc);
+ static bool isLocal(const MCSymbol &Symbol, bool IsUsedInReloc,
+ bool IsSignature);
/// Helper struct for containing some precomputed information on symbols.
struct ELFSymbolData {
const MCSymbol *Symbol;
- uint64_t StringIndex;
uint32_t SectionIndex;
StringRef Name;
// Support lexicographic sorting.
bool operator<(const ELFSymbolData &RHS) const {
- unsigned LHSType = MCELF::GetType(Symbol->getData());
- unsigned RHSType = MCELF::GetType(RHS.Symbol->getData());
+ unsigned LHSType = MCELF::GetType(*Symbol);
+ unsigned RHSType = MCELF::GetType(*RHS.Symbol);
if (LHSType == ELF::STT_SECTION && RHSType != ELF::STT_SECTION)
return false;
if (LHSType != ELF::STT_SECTION && RHSType == ELF::STT_SECTION)
/// @{
StringTableBuilder StrTabBuilder;
- std::vector<uint64_t> FileSymbolData;
- std::vector<ELFSymbolData> LocalSymbolData;
- std::vector<ELFSymbolData> ExternalSymbolData;
- std::vector<ELFSymbolData> UndefinedSymbolData;
/// @}
Renames.clear();
Relocations.clear();
StrTabBuilder.clear();
- FileSymbolData.clear();
- LocalSymbolData.clear();
- ExternalSymbolData.clear();
- UndefinedSymbolData.clear();
SectionTable.clear();
MCObjectWriter::reset();
}
void writeHeader(const MCAssembler &Asm);
- void WriteSymbol(SymbolTableWriter &Writer, ELFSymbolData &MSD,
- const MCAsmLayout &Layout);
+ void writeSymbol(SymbolTableWriter &Writer, uint32_t StringIndex,
+ ELFSymbolData &MSD, const MCAsmLayout &Layout);
// Start and end offset of each section
typedef std::map<const MCSectionELF *, std::pair<uint64_t, uint64_t>>
MCValue Target, bool &IsPCRel,
uint64_t &FixedValue) override;
- uint64_t getSymbolIndexInSymbolTable(const MCAssembler &Asm,
- const MCSymbol *S);
-
// Map from a signature symbol to the group section index
typedef DenseMap<const MCSymbol *, unsigned> RevGroupMapTy;
uint64_t ELFObjectWriter::SymbolValue(const MCSymbol &Sym,
const MCAsmLayout &Layout) {
- MCSymbolData &Data = Sym.getData();
- if (Data.isCommon() && Data.isExternal())
- return Data.getCommonAlignment();
+ if (Sym.isCommon() && Sym.isExternal())
+ return Sym.getCommonAlignment();
uint64_t Res;
if (!Layout.getSymbolOffset(Sym, Res))
// versions declared with @@@ to be renamed.
for (const MCSymbol &Alias : Asm.symbols()) {
- MCSymbolData &OriginalData = Alias.getData();
-
// Not an alias.
if (!Alias.isVariable())
continue;
if (!Ref)
continue;
const MCSymbol &Symbol = Ref->getSymbol();
- MCSymbolData &SD = Asm.getSymbolData(Symbol);
StringRef AliasName = Alias.getName();
size_t Pos = AliasName.find('@');
// Aliases defined with .symvar copy the binding from the symbol they alias.
// This is the first place we are able to copy this information.
- OriginalData.setExternal(SD.isExternal());
- MCELF::SetBinding(OriginalData, MCELF::GetBinding(SD));
+ Alias.setExternal(Symbol.isExternal());
+ MCELF::SetBinding(Alias, MCELF::GetBinding(Symbol));
StringRef Rest = AliasName.substr(Pos);
if (!Symbol.isUndefined() && !Rest.startswith("@@@"))
return Type;
}
-void ELFObjectWriter::WriteSymbol(SymbolTableWriter &Writer, ELFSymbolData &MSD,
+void ELFObjectWriter::writeSymbol(SymbolTableWriter &Writer,
+ uint32_t StringIndex, ELFSymbolData &MSD,
const MCAsmLayout &Layout) {
- MCSymbolData &OrigData = MSD.Symbol->getData();
- assert((!OrigData.getFragment() ||
- (OrigData.getFragment()->getParent() == &MSD.Symbol->getSection())) &&
+ const MCSymbol &Symbol = *MSD.Symbol;
+ assert((!Symbol.getFragment() ||
+ (Symbol.getFragment()->getParent() == &Symbol.getSection())) &&
"The symbol's section doesn't match the fragment's symbol");
- const MCSymbol *Base = Layout.getBaseSymbol(*MSD.Symbol);
+ const MCSymbol *Base = Layout.getBaseSymbol(Symbol);
// This has to be in sync with when computeSymbolTable uses SHN_ABS or
// SHN_COMMON.
- bool IsReserved = !Base || OrigData.isCommon();
+ bool IsReserved = !Base || Symbol.isCommon();
// Binding and Type share the same byte as upper and lower nibbles
- uint8_t Binding = MCELF::GetBinding(OrigData);
- uint8_t Type = MCELF::GetType(OrigData);
- MCSymbolData *BaseSD = nullptr;
+ uint8_t Binding = MCELF::GetBinding(Symbol);
+ uint8_t Type = MCELF::GetType(Symbol);
if (Base) {
- BaseSD = &Layout.getAssembler().getSymbolData(*Base);
- Type = mergeTypeForSet(Type, MCELF::GetType(*BaseSD));
+ Type = mergeTypeForSet(Type, MCELF::GetType(*Base));
}
uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift);
// Other and Visibility share the same byte with Visibility using the lower
// 2 bits
- uint8_t Visibility = MCELF::GetVisibility(OrigData);
- uint8_t Other = MCELF::getOther(OrigData) << (ELF_STO_Shift - ELF_STV_Shift);
+ uint8_t Visibility = MCELF::GetVisibility(Symbol);
+ uint8_t Other = MCELF::getOther(Symbol) << (ELF_STO_Shift - ELF_STV_Shift);
Other |= Visibility;
uint64_t Value = SymbolValue(*MSD.Symbol, Layout);
uint64_t Size = 0;
- const MCExpr *ESize = OrigData.getSize();
+ const MCExpr *ESize = MSD.Symbol->getSize();
if (!ESize && Base)
- ESize = BaseSD->getSize();
+ ESize = Base->getSize();
if (ESize) {
int64_t Res;
}
// Write out the symbol table entry
- Writer.writeSymbol(MSD.StringIndex, Info, Value, Size, Other,
- MSD.SectionIndex, IsReserved);
+ Writer.writeSymbol(StringIndex, Info, Value, Size, Other, MSD.SectionIndex,
+ IsReserved);
}
// It is always valid to create a relocation with a symbol. It is preferable
const MCSymbolRefExpr *RefA,
const MCSymbol *Sym, uint64_t C,
unsigned Type) const {
- MCSymbolData *SD = Sym ? &Sym->getData() : nullptr;
-
// A PCRel relocation to an absolute value has no symbol (or section). We
// represent that with a relocation to a null section.
if (!RefA)
if (Sym->isUndefined())
return true;
- unsigned Binding = MCELF::GetBinding(*SD);
+ unsigned Binding = MCELF::GetBinding(*Sym);
switch(Binding) {
default:
llvm_unreachable("Invalid Binding");
if (Asm.isThumbFunc(Sym))
return true;
- if (TargetObjectWriter->needsRelocateWithSymbol(*SD, Type))
+ if (TargetObjectWriter->needsRelocateWithSymbol(*Sym, Type))
return true;
return false;
}
// True if the assembler knows nothing about the final value of the symbol.
// This doesn't cover the comdat issues, since in those cases the assembler
// can at least know that all symbols in the section will move together.
-static bool isWeak(const MCSymbolData &D) {
- if (MCELF::GetType(D) == ELF::STT_GNU_IFUNC)
+static bool isWeak(const MCSymbol &Sym) {
+ if (MCELF::GetType(Sym) == ELF::STT_GNU_IFUNC)
return true;
- switch (MCELF::GetBinding(D)) {
+ switch (MCELF::GetBinding(Sym)) {
default:
llvm_unreachable("Unknown binding");
case ELF::STB_LOCAL:
Asm.getContext().reportFatalError(
Fixup.getLoc(), "Cannot represent a difference across sections");
- if (::isWeak(SymB.getData()))
+ if (::isWeak(SymB))
Asm.getContext().reportFatalError(
Fixup.getLoc(), "Cannot represent a subtraction with a weak symbol");
return;
}
-
-uint64_t
-ELFObjectWriter::getSymbolIndexInSymbolTable(const MCAssembler &Asm,
- const MCSymbol *S) {
- assert(S->hasData());
- return S->getIndex();
-}
-
bool ELFObjectWriter::isInSymtab(const MCAsmLayout &Layout,
const MCSymbol &Symbol, bool Used,
bool Renamed) {
- const MCSymbolData &Data = Symbol.getData();
if (Symbol.isVariable()) {
const MCExpr *Expr = Symbol.getVariableValue();
if (const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(Expr)) {
return false;
}
- bool IsGlobal = MCELF::GetBinding(Data) == ELF::STB_GLOBAL;
+ bool IsGlobal = MCELF::GetBinding(Symbol) == ELF::STB_GLOBAL;
if (!Symbol.isVariable() && Symbol.isUndefined() && !IsGlobal)
return false;
- if (MCELF::GetType(Data) == ELF::STT_SECTION)
+ if (MCELF::GetType(Symbol) == ELF::STT_SECTION)
return true;
if (Symbol.isTemporary())
return true;
}
-bool ELFObjectWriter::isLocal(const MCSymbol &Symbol, bool isUsedInReloc) {
- const MCSymbolData &Data = Symbol.getData();
- if (Data.isExternal())
+bool ELFObjectWriter::isLocal(const MCSymbol &Symbol, bool IsUsedInReloc,
+ bool IsSignature) {
+ if (Symbol.isExternal())
return false;
if (Symbol.isDefined())
return true;
- if (isUsedInReloc)
+ if (IsUsedInReloc)
return false;
- return true;
+ return IsSignature;
}
void ELFObjectWriter::computeSymbolTable(
// The first entry is the undefined symbol entry.
Writer.writeSymbol(0, 0, 0, 0, 0, 0, false);
+ std::vector<ELFSymbolData> LocalSymbolData;
+ std::vector<ELFSymbolData> ExternalSymbolData;
+
// Add the data for the symbols.
bool HasLargeSectionIndex = false;
for (const MCSymbol &Symbol : Asm.symbols()) {
- MCSymbolData &SD = Symbol.getData();
-
bool Used = UsedInReloc.count(&Symbol);
bool WeakrefUsed = WeakrefUsedInReloc.count(&Symbol);
bool isSignature = RevGroupMap.count(&Symbol);
ELFSymbolData MSD;
MSD.Symbol = &Symbol;
- const MCSymbol *BaseSymbol = Layout.getBaseSymbol(Symbol);
// Undefined symbols are global, but this is the first place we
// are able to set it.
- bool Local = isLocal(Symbol, Used);
- if (!Local && MCELF::GetBinding(SD) == ELF::STB_LOCAL) {
- assert(BaseSymbol);
- MCSymbolData &BaseData = Asm.getSymbolData(*BaseSymbol);
- MCELF::SetBinding(SD, ELF::STB_GLOBAL);
- MCELF::SetBinding(BaseData, ELF::STB_GLOBAL);
- }
+ bool Local = isLocal(Symbol, Used, isSignature);
+ if (!Local && MCELF::GetBinding(Symbol) == ELF::STB_LOCAL)
+ MCELF::SetBinding(Symbol, ELF::STB_GLOBAL);
- if (!BaseSymbol) {
+ if (Symbol.isAbsolute()) {
MSD.SectionIndex = ELF::SHN_ABS;
- } else if (SD.isCommon()) {
+ } else if (Symbol.isCommon()) {
assert(!Local);
MSD.SectionIndex = ELF::SHN_COMMON;
- } else if (BaseSymbol->isUndefined()) {
+ } else if (Symbol.isUndefined()) {
if (isSignature && !Used) {
MSD.SectionIndex = RevGroupMap.lookup(&Symbol);
if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
MSD.SectionIndex = ELF::SHN_UNDEF;
}
if (!Used && WeakrefUsed)
- MCELF::SetBinding(SD, ELF::STB_WEAK);
+ MCELF::SetBinding(Symbol, ELF::STB_WEAK);
} else {
const MCSectionELF &Section =
- static_cast<const MCSectionELF&>(BaseSymbol->getSection());
+ static_cast<const MCSectionELF &>(Symbol.getSection());
MSD.SectionIndex = SectionIndexMap.lookup(&Section);
assert(MSD.SectionIndex && "Invalid section index!");
if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
}
// Sections have their own string table
- if (MCELF::GetType(SD) != ELF::STT_SECTION)
+ if (MCELF::GetType(Symbol) != ELF::STT_SECTION)
MSD.Name = StrTabBuilder.add(Name);
- if (MSD.SectionIndex == ELF::SHN_UNDEF)
- UndefinedSymbolData.push_back(MSD);
- else if (Local)
+ if (Local)
LocalSymbolData.push_back(MSD);
else
ExternalSymbolData.push_back(MSD);
SymtabShndxSection->setAlignment(4);
}
- for (const std::string &Name : Asm.getFileNames())
+ ArrayRef<std::string> FileNames = Asm.getFileNames();
+ for (const std::string &Name : FileNames)
StrTabBuilder.add(Name);
StrTabBuilder.finalize(StringTableBuilder::ELF);
- for (const std::string &Name : Asm.getFileNames())
- FileSymbolData.push_back(StrTabBuilder.getOffset(Name));
+ for (const std::string &Name : FileNames)
+ Writer.writeSymbol(StrTabBuilder.getOffset(Name),
+ ELF::STT_FILE | ELF::STB_LOCAL, 0, 0, ELF::STV_DEFAULT,
+ ELF::SHN_ABS, true);
// Symbols are required to be in lexicographic order.
array_pod_sort(LocalSymbolData.begin(), LocalSymbolData.end());
array_pod_sort(ExternalSymbolData.begin(), ExternalSymbolData.end());
- array_pod_sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end());
// Set the symbol indices. Local symbols must come before all other
// symbols with non-local bindings.
- unsigned Index = FileSymbolData.size() + 1;
+ unsigned Index = FileNames.size() + 1;
for (ELFSymbolData &MSD : LocalSymbolData) {
- MSD.StringIndex = MCELF::GetType(MSD.Symbol->getData()) == ELF::STT_SECTION
- ? 0
- : StrTabBuilder.getOffset(MSD.Name);
- MSD.Symbol->setIndex(Index++);
- }
- for (ELFSymbolData &MSD : ExternalSymbolData) {
- MSD.StringIndex = StrTabBuilder.getOffset(MSD.Name);
- MSD.Symbol->setIndex(Index++);
- }
- for (ELFSymbolData &MSD : UndefinedSymbolData) {
- MSD.StringIndex = StrTabBuilder.getOffset(MSD.Name);
+ unsigned StringIndex = MCELF::GetType(*MSD.Symbol) == ELF::STT_SECTION
+ ? 0
+ : StrTabBuilder.getOffset(MSD.Name);
MSD.Symbol->setIndex(Index++);
- }
-
- for (unsigned i = 0, e = FileSymbolData.size(); i != e; ++i) {
- Writer.writeSymbol(FileSymbolData[i], ELF::STT_FILE | ELF::STB_LOCAL, 0, 0,
- ELF::STV_DEFAULT, ELF::SHN_ABS, true);
+ writeSymbol(Writer, StringIndex, MSD, Layout);
}
// Write the symbol table entries.
- LastLocalSymbolIndex = FileSymbolData.size() + LocalSymbolData.size() + 1;
+ LastLocalSymbolIndex = Index;
- for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) {
- ELFSymbolData &MSD = LocalSymbolData[i];
- WriteSymbol(Writer, MSD, Layout);
- }
-
- for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) {
- ELFSymbolData &MSD = ExternalSymbolData[i];
- MCSymbolData &Data = MSD.Symbol->getData();
- assert(((Data.getFlags() & ELF_STB_Global) ||
- (Data.getFlags() & ELF_STB_Weak)) &&
- "External symbol requires STB_GLOBAL or STB_WEAK flag");
- WriteSymbol(Writer, MSD, Layout);
- if (MCELF::GetBinding(Data) == ELF::STB_LOCAL)
- LastLocalSymbolIndex++;
- }
-
- for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) {
- ELFSymbolData &MSD = UndefinedSymbolData[i];
- MCSymbolData &Data = MSD.Symbol->getData();
- WriteSymbol(Writer, MSD, Layout);
- if (MCELF::GetBinding(Data) == ELF::STB_LOCAL)
- LastLocalSymbolIndex++;
+ for (ELFSymbolData &MSD : ExternalSymbolData) {
+ unsigned StringIndex = StrTabBuilder.getOffset(MSD.Name);
+ MSD.Symbol->setIndex(Index++);
+ writeSymbol(Writer, StringIndex, MSD, Layout);
+ assert(MCELF::GetBinding(*MSD.Symbol) != ELF::STB_LOCAL);
}
uint64_t SecEnd = OS.tell();
for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
const ELFRelocationEntry &Entry = Relocs[e - i - 1];
- unsigned Index =
- Entry.Symbol ? getSymbolIndexInSymbolTable(Asm, Entry.Symbol) : 0;
+ unsigned Index = Entry.Symbol ? Entry.Symbol->getIndex() : 0;
if (is64Bit()) {
write(Entry.Offset);
if (Type != ELF::SHT_GROUP)
GroupSymbolIndex = 0;
else
- GroupSymbolIndex = getSymbolIndexInSymbolTable(Asm, Section->getGroup());
+ GroupSymbolIndex = Section->getGroup()->getIndex();
const std::pair<uint64_t, uint64_t> &Offsets =
SectionOffsets.find(Section)->second;
MCSectionELF *RelSection = createRelocationSection(Ctx, Section);
if (SignatureSymbol) {
- Asm.getOrCreateSymbolData(*SignatureSymbol);
+ Asm.registerSymbol(*SignatureSymbol);
unsigned &GroupIdx = RevGroupMap[SignatureSymbol];
if (!GroupIdx) {
MCSectionELF *Group = Ctx.createELFGroupSection(SignatureSymbol);
bool InSet, bool IsPCRel) const {
if (IsPCRel) {
assert(!InSet);
- if (::isWeak(SymA.getData()))
+ if (::isWeak(SymA))
return false;
}
return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(Asm, SymA, FB,
}
bool ELFObjectWriter::isWeak(const MCSymbol &Sym) const {
- const MCSymbolData &SD = Sym.getData();
- if (::isWeak(SD))
+ if (::isWeak(Sym))
return true;
// It is invalid to replace a reference to a global in a comdat
// We could try to return false for more cases, like the reference
// being in the same comdat or Sym being an alias to another global,
// but it is not clear if it is worth the effort.
- if (MCELF::GetBinding(SD) != ELF::STB_GLOBAL)
+ if (MCELF::GetBinding(Sym) != ELF::STB_GLOBAL)
return false;
if (!Sym.isInSection())