const MCAsmLayout &Layout,
const MCSectionELF &Section);
- /*static bool isFixupKindX86RIPRel(unsigned Kind) {
- return Kind == X86::reloc_riprel_4byte ||
- Kind == X86::reloc_riprel_4byte_movq_load;
- }*/
-
- /// ELFSymbolData - Helper struct for containing some precomputed
- /// information on symbols.
+ /// Helper struct for containing some precomputed information on symbols.
struct ELFSymbolData {
MCSymbolData *SymbolData;
uint64_t StringIndex;
}
public:
- ELFObjectWriter(MCELFObjectTargetWriter *MOTW, raw_ostream &_OS,
+ ELFObjectWriter(MCELFObjectTargetWriter *MOTW, raw_ostream &OS,
bool IsLittleEndian)
- : MCObjectWriter(_OS, IsLittleEndian), FWriter(IsLittleEndian),
+ : MCObjectWriter(OS, IsLittleEndian), FWriter(IsLittleEndian),
TargetObjectWriter(MOTW), NeedsGOT(false) {}
+ void reset() override {
+ UsedInReloc.clear();
+ WeakrefUsedInReloc.clear();
+ Renames.clear();
+ Relocations.clear();
+ ShStrTabBuilder.clear();
+ StrTabBuilder.clear();
+ FileSymbolData.clear();
+ LocalSymbolData.clear();
+ ExternalSymbolData.clear();
+ UndefinedSymbolData.clear();
+ MCObjectWriter::reset();
+ }
+
virtual ~ELFObjectWriter();
void WriteWord(uint64_t W) {
}
void WriteHeader(const MCAssembler &Asm,
- uint64_t SectionDataSize,
+ uint64_t SectionHeaderOffset,
unsigned NumberOfSections);
void WriteSymbol(SymbolTableWriter &Writer, ELFSymbolData &MSD,
typedef DenseMap<const MCSectionELF*, const MCSymbol*> GroupMapTy;
// Map from a signature symbol to the group section
typedef DenseMap<const MCSymbol*, const MCSectionELF*> RevGroupMapTy;
- // Map from a section to the section with the relocations
- typedef DenseMap<const MCSectionELF*, const MCSectionELF*> RelMapTy;
// Map from a section to its offset
typedef DenseMap<const MCSectionELF*, uint64_t> SectionOffsetMapTy;
/// \param Asm - The assembler.
/// \param SectionIndexMap - Maps a section to its index.
/// \param RevGroupMap - Maps a signature symbol to the group section.
- /// \param NumRegularSections - Number of non-relocation sections.
void computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout,
const SectionIndexMapTy &SectionIndexMap,
- const RevGroupMapTy &RevGroupMap,
- unsigned NumRegularSections);
+ const RevGroupMapTy &RevGroupMap);
- void ComputeIndexMap(MCAssembler &Asm,
- SectionIndexMapTy &SectionIndexMap,
- const RelMapTy &RelMap);
+ void computeIndexMap(MCAssembler &Asm, SectionIndexMapTy &SectionIndexMap);
- void CreateRelocationSections(MCAssembler &Asm, RelMapTy &RelMap);
+ MCSectionData *createRelocationSection(MCAssembler &Asm,
+ const MCSectionData &SD);
void CompressDebugSections(MCAssembler &Asm, MCAsmLayout &Layout);
- void WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout,
- const RelMapTy &RelMap);
+ void WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout);
void CreateMetadataSections(MCAssembler &Asm, MCAsmLayout &Layout,
- SectionIndexMapTy &SectionIndexMap,
- const RelMapTy &RelMap);
+ SectionIndexMapTy &SectionIndexMap);
// Create the sections that show up in the symbol table. Currently
// those are the .note.GNU-stack section and the group sections.
- void CreateIndexedSections(MCAssembler &Asm, MCAsmLayout &Layout,
- GroupMapTy &GroupMap,
- RevGroupMapTy &RevGroupMap,
- SectionIndexMapTy &SectionIndexMap,
- const RelMapTy &RelMap);
+ void createIndexedSections(MCAssembler &Asm, MCAsmLayout &Layout,
+ GroupMapTy &GroupMap, RevGroupMapTy &RevGroupMap,
+ SectionIndexMapTy &SectionIndexMap);
void ExecutePostLayoutBinding(MCAssembler &Asm,
const MCAsmLayout &Layout) override;
- void WriteSectionHeader(MCAssembler &Asm, const GroupMapTy &GroupMap,
+ void writeSectionHeader(MCAssembler &Asm, const GroupMapTy &GroupMap,
const MCAsmLayout &Layout,
const SectionIndexMapTy &SectionIndexMap,
const SectionOffsetMapTy &SectionOffsetMap);
bool
IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
const MCSymbolData &DataA,
+ const MCSymbolData *DataB,
const MCFragment &FB,
bool InSet,
bool IsPCRel) const override;
+ bool isWeak(const MCSymbolData &SD) const override;
+
void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
- void WriteSection(MCAssembler &Asm,
+ void writeSection(MCAssembler &Asm,
const SectionIndexMapTy &SectionIndexMap,
uint32_t GroupSymbolIndex,
uint64_t Offset, uint64_t Size, uint64_t Alignment,
// Emit the ELF header.
void ELFObjectWriter::WriteHeader(const MCAssembler &Asm,
- uint64_t SectionDataSize,
+ uint64_t SectionHeaderOffset,
unsigned NumberOfSections) {
// ELF Header
// ----------
Write32(ELF::EV_CURRENT); // e_version
WriteWord(0); // e_entry, no entry point in .o file
WriteWord(0); // e_phoff, no program header for .o
- WriteWord(SectionDataSize + (is64Bit() ? sizeof(ELF::Elf64_Ehdr) :
- sizeof(ELF::Elf32_Ehdr))); // e_shoff = sec hdr table off in bytes
+ WriteWord(SectionHeaderOffset); // e_shoff = sec hdr table off in bytes
// e_flags = whatever the target wants
Write32(Asm.getELFHeaderEFlags());
if (ESize) {
int64_t Res;
- if (!ESize->EvaluateAsAbsolute(Res, Layout))
+ if (!ESize->evaluateKnownAbsolute(Res, Layout))
report_fatal_error("Size expression must be absolute.");
Size = Res;
}
return nullptr;
}
+static bool isWeak(const MCSymbolData &D) {
+ return D.getFlags() & ELF_STB_Weak || MCELF::GetType(D) == ELF::STT_GNU_IFUNC;
+}
+
void ELFObjectWriter::RecordRelocation(MCAssembler &Asm,
const MCAsmLayout &Layout,
const MCFragment *Fragment,
Fixup.getLoc(), "Cannot represent a difference across sections");
const MCSymbolData &SymBD = Asm.getSymbolData(SymB);
+ if (::isWeak(SymBD))
+ Asm.getContext().FatalError(
+ Fixup.getLoc(), "Cannot represent a subtraction with a weak symbol");
+
uint64_t SymBOffset = Layout.getSymbolOffset(&SymBD);
uint64_t K = SymBOffset - FixupOffset;
IsPCRel = true;
return true;
}
-void ELFObjectWriter::ComputeIndexMap(MCAssembler &Asm,
- SectionIndexMapTy &SectionIndexMap,
- const RelMapTy &RelMap) {
+void ELFObjectWriter::computeIndexMap(MCAssembler &Asm,
+ SectionIndexMapTy &SectionIndexMap) {
unsigned Index = 1;
for (MCAssembler::iterator it = Asm.begin(),
ie = Asm.end(); it != ie; ++it) {
for (MCAssembler::iterator it = Asm.begin(),
ie = Asm.end(); it != ie; ++it) {
+ const MCSectionData &SD = *it;
const MCSectionELF &Section =
- static_cast<const MCSectionELF &>(it->getSection());
+ static_cast<const MCSectionELF &>(SD.getSection());
if (Section.getType() == ELF::SHT_GROUP ||
Section.getType() == ELF::SHT_REL ||
Section.getType() == ELF::SHT_RELA)
continue;
SectionIndexMap[&Section] = Index++;
- const MCSectionELF *RelSection = RelMap.lookup(&Section);
- if (RelSection)
+ if (MCSectionData *RelSD = createRelocationSection(Asm, SD)) {
+ const MCSectionELF *RelSection =
+ static_cast<const MCSectionELF *>(&RelSD->getSection());
SectionIndexMap[RelSection] = Index++;
+ }
}
}
-void
-ELFObjectWriter::computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout,
- const SectionIndexMapTy &SectionIndexMap,
- const RevGroupMapTy &RevGroupMap,
- unsigned NumRegularSections) {
+void ELFObjectWriter::computeSymbolTable(
+ MCAssembler &Asm, const MCAsmLayout &Layout,
+ const SectionIndexMapTy &SectionIndexMap,
+ const RevGroupMapTy &RevGroupMap) {
// FIXME: Is this the correct place to do this?
// FIXME: Why is an undefined reference to _GLOBAL_OFFSET_TABLE_ needed?
if (NeedsGOT) {
// in defined ones.
//
// FIXME: All name handling should be done before we get to the writer,
- // including dealing with GNU-style version suffixes. Fixing this isn’t
+ // including dealing with GNU-style version suffixes. Fixing this isn't
// trivial.
//
// We thus have to be careful to not perform the symbol version replacement
UndefinedSymbolData[i].SymbolData->setIndex(Index++);
}
-void ELFObjectWriter::CreateRelocationSections(MCAssembler &Asm,
- RelMapTy &RelMap) {
- for (MCAssembler::const_iterator it = Asm.begin(),
- ie = Asm.end(); it != ie; ++it) {
- const MCSectionData &SD = *it;
- if (Relocations[&SD].empty())
- continue;
+MCSectionData *
+ELFObjectWriter::createRelocationSection(MCAssembler &Asm,
+ const MCSectionData &SD) {
+ if (Relocations[&SD].empty())
+ return nullptr;
- MCContext &Ctx = Asm.getContext();
- const MCSectionELF &Section =
- static_cast<const MCSectionELF&>(SD.getSection());
+ MCContext &Ctx = Asm.getContext();
+ const MCSectionELF &Section =
+ static_cast<const MCSectionELF &>(SD.getSection());
- const StringRef SectionName = Section.getSectionName();
- std::string RelaSectionName = hasRelocationAddend() ? ".rela" : ".rel";
- RelaSectionName += SectionName;
+ const StringRef SectionName = Section.getSectionName();
+ std::string RelaSectionName = hasRelocationAddend() ? ".rela" : ".rel";
+ RelaSectionName += SectionName;
- unsigned EntrySize;
- if (hasRelocationAddend())
- EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela);
- else
- EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel);
+ unsigned EntrySize;
+ if (hasRelocationAddend())
+ EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela);
+ else
+ EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel);
- unsigned Flags = 0;
- StringRef Group = "";
- if (Section.getFlags() & ELF::SHF_GROUP) {
- Flags = ELF::SHF_GROUP;
- Group = Section.getGroup()->getName();
- }
+ unsigned Flags = 0;
+ if (Section.getFlags() & ELF::SHF_GROUP)
+ Flags = ELF::SHF_GROUP;
- const MCSectionELF *RelaSection =
- Ctx.getELFSection(RelaSectionName, hasRelocationAddend() ?
- ELF::SHT_RELA : ELF::SHT_REL, Flags,
- EntrySize, Group);
- RelMap[&Section] = RelaSection;
- Asm.getOrCreateSectionData(*RelaSection);
- }
+ const MCSectionELF *RelaSection = Ctx.createELFRelSection(
+ RelaSectionName, hasRelocationAddend() ? ELF::SHT_RELA : ELF::SHT_REL,
+ Flags, EntrySize, Section.getGroup(), &Section);
+ return &Asm.getOrCreateSectionData(*RelaSection);
}
static SmallVector<char, 128>
static bool
prependCompressionHeader(uint64_t Size,
SmallVectorImpl<char> &CompressedContents) {
- static const StringRef Magic = "ZLIB";
+ const StringRef Magic = "ZLIB";
if (Size <= Magic.size() + sizeof(Size) + CompressedContents.size())
return false;
if (sys::IsLittleEndianHost)
}
}
-void ELFObjectWriter::WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout,
- const RelMapTy &RelMap) {
- for (MCAssembler::const_iterator it = Asm.begin(),
- ie = Asm.end(); it != ie; ++it) {
- const MCSectionData &SD = *it;
- const MCSectionELF &Section =
- static_cast<const MCSectionELF&>(SD.getSection());
+void ELFObjectWriter::WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout) {
+ for (MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); it != ie; ++it) {
+ MCSectionData &RelSD = *it;
+ const MCSectionELF &RelSection =
+ static_cast<const MCSectionELF &>(RelSD.getSection());
- const MCSectionELF *RelaSection = RelMap.lookup(&Section);
- if (!RelaSection)
+ unsigned Type = RelSection.getType();
+ if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA)
continue;
- MCSectionData &RelaSD = Asm.getOrCreateSectionData(*RelaSection);
- RelaSD.setAlignment(is64Bit() ? 8 : 4);
- MCDataFragment *F = new MCDataFragment(&RelaSD);
- WriteRelocationsFragment(Asm, F, &*it);
+ const MCSectionELF *Section = RelSection.getAssociatedSection();
+ MCSectionData &SD = Asm.getOrCreateSectionData(*Section);
+ RelSD.setAlignment(is64Bit() ? 8 : 4);
+
+ MCDataFragment *F = new MCDataFragment(&RelSD);
+ WriteRelocationsFragment(Asm, F, &SD);
}
}
return B.Offset - A.Offset;
if (B.Type != A.Type)
return A.Type - B.Type;
- llvm_unreachable("ELFRelocs might be unstable!");
+ //llvm_unreachable("ELFRelocs might be unstable!");
+ return 0;
}
static void sortRelocs(const MCAssembler &Asm,
}
}
-void ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm,
- MCAsmLayout &Layout,
- SectionIndexMapTy &SectionIndexMap,
- const RelMapTy &RelMap) {
+void ELFObjectWriter::CreateMetadataSections(
+ MCAssembler &Asm, MCAsmLayout &Layout, SectionIndexMapTy &SectionIndexMap) {
MCContext &Ctx = Asm.getContext();
MCDataFragment *F;
ShStrTabBuilder.data().end());
}
-void ELFObjectWriter::CreateIndexedSections(MCAssembler &Asm,
- MCAsmLayout &Layout,
- GroupMapTy &GroupMap,
- RevGroupMapTy &RevGroupMap,
- SectionIndexMapTy &SectionIndexMap,
- const RelMapTy &RelMap) {
+void ELFObjectWriter::createIndexedSections(
+ MCAssembler &Asm, MCAsmLayout &Layout, GroupMapTy &GroupMap,
+ RevGroupMapTy &RevGroupMap, SectionIndexMapTy &SectionIndexMap) {
MCContext &Ctx = Asm.getContext();
// Build the groups
GroupMap[Group] = SignatureSymbol;
}
- ComputeIndexMap(Asm, SectionIndexMap, RelMap);
+ computeIndexMap(Asm, SectionIndexMap);
// Add sections to the groups
for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end();
}
}
-void ELFObjectWriter::WriteSection(MCAssembler &Asm,
+void ELFObjectWriter::writeSection(MCAssembler &Asm,
const SectionIndexMapTy &SectionIndexMap,
uint32_t GroupSymbolIndex,
uint64_t Offset, uint64_t Size,
uint64_t sh_info = 0;
switch(Section.getType()) {
+ default:
+ // Nothing to do.
+ break;
+
case ELF::SHT_DYNAMIC:
sh_link = ShStrTabBuilder.getOffset(Section.getSectionName());
- sh_info = 0;
break;
case ELF::SHT_REL:
case ELF::SHT_RELA: {
- const MCSectionELF *SymtabSection;
- const MCSectionELF *InfoSection;
- SymtabSection =
- Asm.getContext().getELFSection(".symtab", ELF::SHT_SYMTAB, 0);
- sh_link = SectionIndexMap.lookup(SymtabSection);
+ sh_link = SymbolTableIndex;
assert(sh_link && ".symtab not found");
-
- // Remove ".rel" and ".rela" prefixes.
- unsigned SecNameLen = (Section.getType() == ELF::SHT_REL) ? 4 : 5;
- StringRef SectionName = Section.getSectionName().substr(SecNameLen);
- StringRef GroupName =
- Section.getGroup() ? Section.getGroup()->getName() : "";
-
- InfoSection = Asm.getContext().getELFSection(SectionName, ELF::SHT_PROGBITS,
- 0, 0, GroupName);
+ const MCSectionELF *InfoSection = Section.getAssociatedSection();
sh_info = SectionIndexMap.lookup(InfoSection);
break;
}
sh_link = SymbolTableIndex;
break;
- case ELF::SHT_PROGBITS:
- case ELF::SHT_STRTAB:
- case ELF::SHT_NOBITS:
- case ELF::SHT_NOTE:
- case ELF::SHT_NULL:
- case ELF::SHT_ARM_ATTRIBUTES:
- case ELF::SHT_INIT_ARRAY:
- case ELF::SHT_FINI_ARRAY:
- case ELF::SHT_PREINIT_ARRAY:
- case ELF::SHT_X86_64_UNWIND:
- case ELF::SHT_MIPS_REGINFO:
- case ELF::SHT_MIPS_OPTIONS:
- case ELF::SHT_MIPS_ABIFLAGS:
- // Nothing to do.
- break;
-
case ELF::SHT_GROUP:
sh_link = SymbolTableIndex;
sh_info = GroupSymbolIndex;
break;
-
- default:
- llvm_unreachable("FIXME: sh_type value not supported!");
}
if (TargetObjectWriter->getEMachine() == ELF::EM_ARM &&
- Section.getType() == ELF::SHT_ARM_EXIDX) {
- StringRef SecName(Section.getSectionName());
- if (SecName == ".ARM.exidx") {
- sh_link = SectionIndexMap.lookup(Asm.getContext().getELFSection(
- ".text", ELF::SHT_PROGBITS, ELF::SHF_EXECINSTR | ELF::SHF_ALLOC));
- } else if (SecName.startswith(".ARM.exidx")) {
- StringRef GroupName =
- Section.getGroup() ? Section.getGroup()->getName() : "";
- sh_link = SectionIndexMap.lookup(Asm.getContext().getELFSection(
- SecName.substr(sizeof(".ARM.exidx") - 1), ELF::SHT_PROGBITS,
- ELF::SHF_EXECINSTR | ELF::SHF_ALLOC, 0, GroupName));
- }
- }
+ Section.getType() == ELF::SHT_ARM_EXIDX)
+ sh_link = SectionIndexMap.lookup(Section.getAssociatedSection());
WriteSecHdrEntry(ShStrTabBuilder.getOffset(Section.getSectionName()),
Section.getType(),
}
}
-void ELFObjectWriter::WriteSectionHeader(MCAssembler &Asm,
- const GroupMapTy &GroupMap,
- const MCAsmLayout &Layout,
- const SectionIndexMapTy &SectionIndexMap,
- const SectionOffsetMapTy &SectionOffsetMap) {
+void ELFObjectWriter::writeSectionHeader(
+ MCAssembler &Asm, const GroupMapTy &GroupMap, const MCAsmLayout &Layout,
+ const SectionIndexMapTy &SectionIndexMap,
+ const SectionOffsetMapTy &SectionOffsetMap) {
const unsigned NumSections = Asm.size() + 1;
std::vector<const MCSectionELF*> Sections;
uint64_t Size = GetSectionAddressSize(Layout, SD);
- WriteSection(Asm, SectionIndexMap, GroupSymbolIndex,
- SectionOffsetMap.lookup(&Section), Size,
- SD.getAlignment(), Section);
+ writeSection(Asm, SectionIndexMap, GroupSymbolIndex,
+ SectionOffsetMap.lookup(&Section), Size, SD.getAlignment(),
+ Section);
}
}
RevGroupMapTy RevGroupMap;
SectionIndexMapTy SectionIndexMap;
- unsigned NumUserSections = Asm.size();
-
CompressDebugSections(Asm, const_cast<MCAsmLayout &>(Layout));
+ createIndexedSections(Asm, const_cast<MCAsmLayout &>(Layout), GroupMap,
+ RevGroupMap, SectionIndexMap);
- DenseMap<const MCSectionELF*, const MCSectionELF*> RelMap;
- CreateRelocationSections(Asm, RelMap);
-
- const unsigned NumUserAndRelocSections = Asm.size();
- CreateIndexedSections(Asm, const_cast<MCAsmLayout&>(Layout), GroupMap,
- RevGroupMap, SectionIndexMap, RelMap);
- const unsigned AllSections = Asm.size();
- const unsigned NumIndexedSections = AllSections - NumUserAndRelocSections;
-
- unsigned NumRegularSections = NumUserSections + NumIndexedSections;
+ unsigned NumRegularSections = Asm.size();
// Compute symbol table information.
- computeSymbolTable(Asm, Layout, SectionIndexMap, RevGroupMap,
- NumRegularSections);
+ computeSymbolTable(Asm, Layout, SectionIndexMap, RevGroupMap);
- WriteRelocations(Asm, const_cast<MCAsmLayout&>(Layout), RelMap);
+ WriteRelocations(Asm, const_cast<MCAsmLayout &>(Layout));
CreateMetadataSections(const_cast<MCAssembler&>(Asm),
const_cast<MCAsmLayout&>(Layout),
- SectionIndexMap,
- RelMap);
+ SectionIndexMap);
uint64_t NaturalAlignment = is64Bit() ? 8 : 4;
uint64_t HeaderSize = is64Bit() ? sizeof(ELF::Elf64_Ehdr) :
FileOff = RoundUpToAlignment(FileOff, NaturalAlignment);
- const unsigned SectionHeaderOffset = FileOff - HeaderSize;
+ const unsigned SectionHeaderOffset = FileOff;
uint64_t SectionHeaderEntrySize = is64Bit() ?
sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr);
WriteZeros(Padding);
// ... then the section header table ...
- WriteSectionHeader(Asm, GroupMap, Layout, SectionIndexMap,
- SectionOffsetMap);
+ writeSectionHeader(Asm, GroupMap, Layout, SectionIndexMap, SectionOffsetMap);
// ... and then the remaining sections ...
for (unsigned i = NumRegularSections + 1; i < NumSections; ++i)
WriteDataSectionData(Asm, Layout, *Sections[i]);
}
-bool
-ELFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
- const MCSymbolData &DataA,
- const MCFragment &FB,
- bool InSet,
- bool IsPCRel) const {
- if (DataA.getFlags() & ELF_STB_Weak || MCELF::GetType(DataA) == ELF::STT_GNU_IFUNC)
+bool ELFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(
+ const MCAssembler &Asm, const MCSymbolData &DataA,
+ const MCSymbolData *DataB, const MCFragment &FB, bool InSet,
+ bool IsPCRel) const {
+ if (!InSet && (::isWeak(DataA) || (DataB && ::isWeak(*DataB))))
return false;
return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(
- Asm, DataA, FB,InSet, IsPCRel);
+ Asm, DataA, DataB, FB, InSet, IsPCRel);
+}
+
+bool ELFObjectWriter::isWeak(const MCSymbolData &SD) const {
+ return ::isWeak(SD);
}
MCObjectWriter *llvm::createELFObjectWriter(MCELFObjectTargetWriter *MOTW,