llvm::DenseMap<const MCSectionELF *, std::vector<ELFRelocationEntry>>
Relocations;
- StringTableBuilder ShStrTabBuilder;
/// @}
/// @name Symbol Table Data
unsigned StringTableIndex;
// This holds the .symtab section index.
unsigned SymbolTableIndex;
-
- unsigned ShstrtabIndex;
+ // This holds the .symtab_shndx section index.
+ unsigned SymtabShndxSectionIndex = 0;
// Sections in the order they are to be output in the section table.
- std::vector<MCSectionELF *> SectionTable;
- unsigned addToSectionTable(MCSectionELF *Sec);
+ std::vector<const MCSectionELF *> SectionTable;
+ unsigned addToSectionTable(const MCSectionELF *Sec);
// TargetObjectWriter wrappers.
bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
WeakrefUsedInReloc.clear();
Renames.clear();
Relocations.clear();
- ShStrTabBuilder.clear();
StrTabBuilder.clear();
FileSymbolData.clear();
LocalSymbolData.clear();
typedef std::map<const MCSectionELF *, std::pair<uint64_t, uint64_t>>
SectionOffsetsTy;
- void WriteSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout,
+ void writeSymbolTable(MCContext &Ctx, const MCAsmLayout &Layout,
SectionOffsetsTy &SectionOffsets);
bool shouldRelocateWithSymbol(const MCAssembler &Asm,
const SectionIndexMapTy &SectionIndexMap,
const RevGroupMapTy &RevGroupMap);
- MCSectionELF *createRelocationSection(MCAssembler &Asm,
+ MCSectionELF *createRelocationSection(MCContext &Ctx,
const MCSectionELF &Sec);
- const MCSectionELF *createSectionHeaderStringTable();
const MCSectionELF *createStringTable(MCContext &Ctx);
void ExecutePostLayoutBinding(MCAssembler &Asm,
const MCAsmLayout &Layout) override;
- void writeSectionHeader(MCAssembler &Asm, const MCAsmLayout &Layout,
+ void writeSectionHeader(const MCAssembler &Asm, const MCAsmLayout &Layout,
const SectionIndexMapTy &SectionIndexMap,
const SectionOffsetsTy &SectionOffsets);
- void writeSectionData(const MCAssembler &Asm, const MCSectionData &SD,
+ void writeSectionData(const MCAssembler &Asm, MCSection &Sec,
const MCAsmLayout &Layout);
void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
bool isWeak(const MCSymbol &Sym) const override;
void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
- void writeSection(MCAssembler &Asm,
- const SectionIndexMapTy &SectionIndexMap,
+ void writeSection(const SectionIndexMapTy &SectionIndexMap,
uint32_t GroupSymbolIndex, uint64_t Offset, uint64_t Size,
const MCSectionELF &Section);
};
}
-unsigned ELFObjectWriter::addToSectionTable(MCSectionELF *Sec) {
+unsigned ELFObjectWriter::addToSectionTable(const MCSectionELF *Sec) {
SectionTable.push_back(Sec);
- ShStrTabBuilder.add(Sec->getSectionName());
+ StrTabBuilder.add(Sec->getSectionName());
return SectionTable.size();
}
Write16(0);
// e_shstrndx = Section # of '.shstrtab'
- assert(ShstrtabIndex < ELF::SHN_LORESERVE);
- Write16(ShstrtabIndex);
+ assert(StringTableIndex < ELF::SHN_LORESERVE);
+ Write16(StringTableIndex);
}
uint64_t ELFObjectWriter::SymbolValue(const MCSymbol &Sym,
const MCAsmLayout &Layout) {
MCSymbolData &OrigData = MSD.Symbol->getData();
assert((!OrigData.getFragment() ||
- (&OrigData.getFragment()->getParent()->getSection() ==
- &MSD.Symbol->getSection())) &&
+ (OrigData.getFragment()->getParent() == &MSD.Symbol->getSection())) &&
"The symbol's section doesn't match the fragment's symbol");
const MCSymbol *Base = Layout.getBaseSymbol(*MSD.Symbol);
MSD.SectionIndex, IsReserved);
}
-void ELFObjectWriter::WriteSymbolTable(MCAssembler &Asm,
+void ELFObjectWriter::writeSymbolTable(MCContext &Ctx,
const MCAsmLayout &Layout,
SectionOffsetsTy &SectionOffsets) {
-
- MCContext &Ctx = Asm.getContext();
-
- unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32;
-
- // Symbol table
- MCSectionELF *SymtabSection =
- Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, EntrySize, "");
- MCSectionData &SymtabSD = Asm.getOrCreateSectionData(*SymtabSection);
- SymtabSD.setAlignment(is64Bit() ? 8 : 4);
- SymbolTableIndex = addToSectionTable(SymtabSection);
+ const MCSectionELF *SymtabSection = SectionTable[SymbolTableIndex - 1];
// The string table must be emitted first because we need the index
// into the string table for all the symbol names.
SymbolTableWriter Writer(*this, is64Bit());
- uint64_t Padding = OffsetToAlignment(OS.tell(), SymtabSD.getAlignment());
+ uint64_t Padding =
+ OffsetToAlignment(OS.tell(), SymtabSection->getAlignment());
WriteZeros(Padding);
uint64_t SecStart = OS.tell();
SectionOffsets[SymtabSection] = std::make_pair(SecStart, SecEnd);
ArrayRef<uint32_t> ShndxIndexes = Writer.getShndxIndexes();
- if (ShndxIndexes.empty())
+ if (ShndxIndexes.empty()) {
+ assert(SymtabShndxSectionIndex == 0);
return;
+ }
+ assert(SymtabShndxSectionIndex != 0);
SecStart = OS.tell();
- MCSectionELF *SymtabShndxSection =
- Ctx.getELFSection(".symtab_shndxr", ELF::SHT_SYMTAB_SHNDX, 0, 4, "");
- addToSectionTable(SymtabShndxSection);
- MCSectionData *SymtabShndxSD =
- &Asm.getOrCreateSectionData(*SymtabShndxSection);
- SymtabShndxSD->setAlignment(4);
+ const MCSectionELF *SymtabShndxSection =
+ SectionTable[SymtabShndxSectionIndex - 1];
for (uint32_t Index : ShndxIndexes)
write(Index);
SecEnd = OS.tell();
const MCFragment *Fragment,
const MCFixup &Fixup, MCValue Target,
bool &IsPCRel, uint64_t &FixedValue) {
- const MCSectionData *FixupSectionD = Fragment->getParent();
- const MCSectionELF &FixupSection =
- cast<MCSectionELF>(FixupSectionD->getSection());
+ const MCSectionELF &FixupSection = cast<MCSectionELF>(*Fragment->getParent());
uint64_t C = Target.getConstant();
uint64_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
const MCSection *SecA =
(SymA && !SymA->isUndefined()) ? &SymA->getSection() : nullptr;
auto *ELFSec = cast_or_null<MCSectionELF>(SecA);
- MCSymbol *SectionSymbol =
- ELFSec ? Asm.getContext().getOrCreateSectionSymbol(*ELFSec)
- : nullptr;
+ const MCSymbol *SectionSymbol = ELFSec ? ELFSec->getBeginSymbol() : nullptr;
ELFRelocationEntry Rec(FixupOffset, SectionSymbol, Type, Addend);
Relocations[&FixupSection].push_back(Rec);
return;
uint64_t
ELFObjectWriter::getSymbolIndexInSymbolTable(const MCAssembler &Asm,
const MCSymbol *S) {
- const MCSymbolData &SD = Asm.getSymbolData(*S);
- return SD.getIndex();
+ assert(S->hasData());
+ return S->getIndex();
}
bool ELFObjectWriter::isInSymtab(const MCAsmLayout &Layout,
if (!Symbol.isVariable() && Symbol.isUndefined() && !IsGlobal)
return false;
+ if (MCELF::GetType(Data) == ELF::STT_SECTION)
+ return true;
+
if (Symbol.isTemporary())
return false;
MCAssembler &Asm, const MCAsmLayout &Layout,
const SectionIndexMapTy &SectionIndexMap,
const RevGroupMapTy &RevGroupMap) {
+ MCContext &Ctx = Asm.getContext();
+ // Symbol table
+ unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32;
+ MCSectionELF *SymtabSection =
+ Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, EntrySize, "");
+ SymtabSection->setAlignment(is64Bit() ? 8 : 4);
+ SymbolTableIndex = addToSectionTable(SymtabSection);
+
// FIXME: Is this the correct place to do this?
// FIXME: Why is an undefined reference to _GLOBAL_OFFSET_TABLE_ needed?
if (NeedsGOT) {
}
// Add the data for the symbols.
+ bool HasLargeSectionIndex = false;
for (const MCSymbol &Symbol : Asm.symbols()) {
MCSymbolData &SD = Symbol.getData();
assert(!Local);
MSD.SectionIndex = ELF::SHN_COMMON;
} else if (BaseSymbol->isUndefined()) {
- if (isSignature && !Used)
+ if (isSignature && !Used) {
MSD.SectionIndex = RevGroupMap.lookup(&Symbol);
- else
+ if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
+ HasLargeSectionIndex = true;
+ } else {
MSD.SectionIndex = ELF::SHN_UNDEF;
+ }
if (!Used && WeakrefUsed)
MCELF::SetBinding(SD, ELF::STB_WEAK);
} else {
static_cast<const MCSectionELF&>(BaseSymbol->getSection());
MSD.SectionIndex = SectionIndexMap.lookup(&Section);
assert(MSD.SectionIndex && "Invalid section index!");
+ if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
+ HasLargeSectionIndex = true;
}
// The @@@ in symbol version is replaced with @ in undefined symbols and @@
ExternalSymbolData.push_back(MSD);
}
+ if (HasLargeSectionIndex) {
+ MCSectionELF *SymtabShndxSection =
+ Ctx.getELFSection(".symtab_shndxr", ELF::SHT_SYMTAB_SHNDX, 0, 4, "");
+ SymtabShndxSectionIndex = addToSectionTable(SymtabShndxSection);
+ SymtabShndxSection->setAlignment(4);
+ }
+
for (auto i = Asm.file_names_begin(), e = Asm.file_names_end(); i != e; ++i)
StrTabBuilder.add(*i);
// symbols with non-local bindings.
unsigned Index = FileSymbolData.size() + 1;
for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i)
- LocalSymbolData[i].Symbol->getData().setIndex(Index++);
+ LocalSymbolData[i].Symbol->setIndex(Index++);
for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i)
- ExternalSymbolData[i].Symbol->getData().setIndex(Index++);
+ ExternalSymbolData[i].Symbol->setIndex(Index++);
for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i)
- UndefinedSymbolData[i].Symbol->getData().setIndex(Index++);
+ UndefinedSymbolData[i].Symbol->setIndex(Index++);
}
MCSectionELF *
-ELFObjectWriter::createRelocationSection(MCAssembler &Asm,
+ELFObjectWriter::createRelocationSection(MCContext &Ctx,
const MCSectionELF &Sec) {
if (Relocations[&Sec].empty())
return nullptr;
- MCContext &Ctx = Asm.getContext();
const StringRef SectionName = Sec.getSectionName();
std::string RelaSectionName = hasRelocationAddend() ? ".rela" : ".rel";
RelaSectionName += SectionName;
MCSectionELF *RelaSection = Ctx.createELFRelSection(
RelaSectionName, hasRelocationAddend() ? ELF::SHT_RELA : ELF::SHT_REL,
Flags, EntrySize, Sec.getGroup(), &Sec);
- MCSectionData &RelSD = Asm.getOrCreateSectionData(*RelaSection);
- RelSD.setAlignment(is64Bit() ? 8 : 4);
+ RelaSection->setAlignment(is64Bit() ? 8 : 4);
return RelaSection;
}
static SmallVector<char, 128>
getUncompressedData(const MCAsmLayout &Layout,
- const MCSectionData::FragmentListType &Fragments) {
+ const MCSection::FragmentListType &Fragments) {
SmallVector<char, 128> UncompressedData;
for (const MCFragment &F : Fragments) {
const SmallVectorImpl<char> *Contents;
return true;
}
-void ELFObjectWriter::writeSectionData(const MCAssembler &Asm,
- const MCSectionData &SD,
+void ELFObjectWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec,
const MCAsmLayout &Layout) {
- MCSectionELF &Section = static_cast<MCSectionELF &>(SD.getSection());
+ MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);
StringRef SectionName = Section.getSectionName();
// Compressing debug_frame requires handling alignment fragments which is
// for writing to arbitrary buffers) for little benefit.
if (!Asm.getContext().getAsmInfo()->compressDebugSections() ||
!SectionName.startswith(".debug_") || SectionName == ".debug_frame") {
- Asm.writeSectionData(&SD, Layout);
+ Asm.writeSectionData(&Section, Layout);
return;
}
// Gather the uncompressed data from all the fragments.
- const MCSectionData::FragmentListType &Fragments = SD.getFragmentList();
+ const MCSection::FragmentListType &Fragments = Section.getFragmentList();
SmallVector<char, 128> UncompressedData =
getUncompressedData(Layout, Fragments);
StringRef(UncompressedData.data(), UncompressedData.size()),
CompressedContents);
if (Success != zlib::StatusOK) {
- Asm.writeSectionData(&SD, Layout);
+ Asm.writeSectionData(&Section, Layout);
return;
}
if (!prependCompressionHeader(UncompressedData.size(), CompressedContents)) {
- Asm.writeSectionData(&SD, Layout);
+ Asm.writeSectionData(&Section, Layout);
return;
}
Asm.getContext().renameELFSection(&Section,
}
}
-const MCSectionELF *ELFObjectWriter::createSectionHeaderStringTable() {
- const MCSectionELF *ShstrtabSection = SectionTable[ShstrtabIndex - 1];
- ShStrTabBuilder.finalize(StringTableBuilder::ELF);
- OS << ShStrTabBuilder.data();
- return ShstrtabSection;
-}
-
const MCSectionELF *ELFObjectWriter::createStringTable(MCContext &Ctx) {
- MCSectionELF *StrtabSection =
- Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0);
- StringTableIndex = addToSectionTable(StrtabSection);
+ const MCSectionELF *StrtabSection = SectionTable[StringTableIndex - 1];
OS << StrTabBuilder.data();
return StrtabSection;
}
-void ELFObjectWriter::writeSection(MCAssembler &Asm,
- const SectionIndexMapTy &SectionIndexMap,
- uint32_t GroupSymbolIndex,
- uint64_t Offset, uint64_t Size,
- const MCSectionELF &Section) {
+void ELFObjectWriter::writeSection(const SectionIndexMapTy &SectionIndexMap,
+ uint32_t GroupSymbolIndex, uint64_t Offset,
+ uint64_t Size, const MCSectionELF &Section) {
uint64_t sh_link = 0;
uint64_t sh_info = 0;
Section.getType() == ELF::SHT_ARM_EXIDX)
sh_link = SectionIndexMap.lookup(Section.getAssociatedSection());
- WriteSecHdrEntry(ShStrTabBuilder.getOffset(Section.getSectionName()),
+ WriteSecHdrEntry(StrTabBuilder.getOffset(Section.getSectionName()),
Section.getType(), Section.getFlags(), 0, Offset, Size,
sh_link, sh_info, Section.getAlignment(),
Section.getEntrySize());
}
void ELFObjectWriter::writeSectionHeader(
- MCAssembler &Asm, const MCAsmLayout &Layout,
+ const MCAssembler &Asm, const MCAsmLayout &Layout,
const SectionIndexMapTy &SectionIndexMap,
const SectionOffsetsTy &SectionOffsets) {
const unsigned NumSections = SectionTable.size();
(NumSections + 1) >= ELF::SHN_LORESERVE ? NumSections + 1 : 0;
WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, 0, 0, 0, 0);
- for (MCSectionELF *Section : SectionTable) {
- const MCSectionData &SD = Asm.getOrCreateSectionData(*Section);
+ for (const MCSectionELF *Section : SectionTable) {
uint32_t GroupSymbolIndex;
unsigned Type = Section->getType();
if (Type != ELF::SHT_GROUP)
const std::pair<uint64_t, uint64_t> &Offsets =
SectionOffsets.find(Section)->second;
- uint64_t Size = Type == ELF::SHT_NOBITS ? Layout.getSectionAddressSize(&SD)
- : Offsets.second - Offsets.first;
+ uint64_t Size;
+ if (Type == ELF::SHT_NOBITS)
+ Size = Layout.getSectionAddressSize(Section);
+ else
+ Size = Offsets.second - Offsets.first;
- writeSection(Asm, SectionIndexMap, GroupSymbolIndex, Offsets.first, Size,
+ writeSection(SectionIndexMap, GroupSymbolIndex, Offsets.first, Size,
*Section);
}
}
void ELFObjectWriter::WriteObject(MCAssembler &Asm,
const MCAsmLayout &Layout) {
MCContext &Ctx = Asm.getContext();
- MCSectionELF *ShstrtabSection =
- Ctx.getELFSection(".shstrtab", ELF::SHT_STRTAB, 0);
- ShstrtabIndex = addToSectionTable(ShstrtabSection);
+ MCSectionELF *StrtabSection =
+ Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0);
+ StringTableIndex = addToSectionTable(StrtabSection);
RevGroupMapTy RevGroupMap;
SectionIndexMapTy SectionIndexMap;
// ... then the sections ...
SectionOffsetsTy SectionOffsets;
- bool ComputedSymtab = false;
- for (const MCSectionData &SD : Asm) {
- MCSectionELF &Section = static_cast<MCSectionELF &>(SD.getSection());
+ std::vector<MCSectionELF *> Groups;
+ std::vector<MCSectionELF *> Relocations;
+ for (MCSection &Sec : Asm) {
+ MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);
- uint64_t Padding = OffsetToAlignment(OS.tell(), SD.getAlignment());
+ uint64_t Padding = OffsetToAlignment(OS.tell(), Section.getAlignment());
WriteZeros(Padding);
// Remember the offset into the file for this section.
uint64_t SecStart = OS.tell();
const MCSymbol *SignatureSymbol = Section.getGroup();
- unsigned Type = Section.getType();
- if (Type == ELF::SHT_GROUP) {
- assert(SignatureSymbol);
- write(uint32_t(ELF::GRP_COMDAT));
- for (const MCSectionELF *Member : GroupMembers[SignatureSymbol]) {
- uint32_t SecIndex = SectionIndexMap.lookup(Member);
- write(SecIndex);
- }
- } else if (Type == ELF::SHT_REL || Type == ELF::SHT_RELA) {
- if (!ComputedSymtab) {
- // Compute symbol table information.
- computeSymbolTable(Asm, Layout, SectionIndexMap, RevGroupMap);
- ComputedSymtab = true;
- }
- writeRelocations(Asm, *Section.getAssociatedSection());
- } else {
- writeSectionData(Asm, SD, Layout);
- }
+ writeSectionData(Asm, Section, Layout);
uint64_t SecEnd = OS.tell();
SectionOffsets[&Section] = std::make_pair(SecStart, SecEnd);
- if (Type == ELF::SHT_GROUP || Type == ELF::SHT_REL || Type == ELF::SHT_RELA)
- continue;
-
- MCSectionELF *RelSection = createRelocationSection(Asm, Section);
+ MCSectionELF *RelSection = createRelocationSection(Ctx, Section);
if (SignatureSymbol) {
Asm.getOrCreateSymbolData(*SignatureSymbol);
if (!GroupIdx) {
MCSectionELF *Group = Ctx.createELFGroupSection(SignatureSymbol);
GroupIdx = addToSectionTable(Group);
- MCSectionData *GroupD = &Asm.getOrCreateSectionData(*Group);
- GroupD->setAlignment(4);
+ Group->setAlignment(4);
+ Groups.push_back(Group);
}
GroupMembers[SignatureSymbol].push_back(&Section);
if (RelSection)
}
SectionIndexMap[&Section] = addToSectionTable(&Section);
- if (RelSection)
+ if (RelSection) {
SectionIndexMap[RelSection] = addToSectionTable(RelSection);
+ Relocations.push_back(RelSection);
+ }
}
- if (!ComputedSymtab) {
- // Compute symbol table information.
- computeSymbolTable(Asm, Layout, SectionIndexMap, RevGroupMap);
- ComputedSymtab = true;
+ for (MCSectionELF *Group : Groups) {
+ uint64_t Padding = OffsetToAlignment(OS.tell(), Group->getAlignment());
+ WriteZeros(Padding);
+
+ // Remember the offset into the file for this section.
+ uint64_t SecStart = OS.tell();
+
+ const MCSymbol *SignatureSymbol = Group->getGroup();
+ assert(SignatureSymbol);
+ write(uint32_t(ELF::GRP_COMDAT));
+ for (const MCSectionELF *Member : GroupMembers[SignatureSymbol]) {
+ uint32_t SecIndex = SectionIndexMap.lookup(Member);
+ write(SecIndex);
+ }
+
+ uint64_t SecEnd = OS.tell();
+ SectionOffsets[Group] = std::make_pair(SecStart, SecEnd);
}
- WriteSymbolTable(Asm, Layout, SectionOffsets);
+ // Compute symbol table information.
+ computeSymbolTable(Asm, Layout, SectionIndexMap, RevGroupMap);
- {
+ for (MCSectionELF *RelSection : Relocations) {
+ uint64_t Padding = OffsetToAlignment(OS.tell(), RelSection->getAlignment());
+ WriteZeros(Padding);
+
+ // Remember the offset into the file for this section.
uint64_t SecStart = OS.tell();
- const MCSectionELF *Sec = createStringTable(Ctx);
+
+ writeRelocations(Asm, *RelSection->getAssociatedSection());
+
uint64_t SecEnd = OS.tell();
- SectionOffsets[Sec] = std::make_pair(SecStart, SecEnd);
+ SectionOffsets[RelSection] = std::make_pair(SecStart, SecEnd);
}
+ writeSymbolTable(Ctx, Layout, SectionOffsets);
+
{
uint64_t SecStart = OS.tell();
- const MCSectionELF *Sec = createSectionHeaderStringTable();
+ const MCSectionELF *Sec = createStringTable(Ctx);
uint64_t SecEnd = OS.tell();
SectionOffsets[Sec] = std::make_pair(SecStart, SecEnd);
}