X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FMC%2FELFObjectWriter.cpp;h=b3ae4a545f17e98e89689f2bc157e71140d6e616;hp=e4442e10a055118eb3ed7a7728a031c67fb2adde;hb=e93f977e8d84407de9aec402473487737ad1339b;hpb=bce877c84c19efbff64500c227afd40087276070 diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp index e4442e10a05..b3ae4a545f1 100644 --- a/lib/MC/ELFObjectWriter.cpp +++ b/lib/MC/ELFObjectWriter.cpp @@ -31,8 +31,8 @@ #include "llvm/MC/StringTableBuilder.h" #include "llvm/Support/Compression.h" #include "llvm/Support/Debug.h" -#include "llvm/Support/Endian.h" #include "llvm/Support/ELF.h" +#include "llvm/Support/Endian.h" #include "llvm/Support/ErrorHandling.h" #include using namespace llvm; @@ -112,13 +112,7 @@ class ELFObjectWriter : public MCObjectWriter { 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; @@ -185,11 +179,25 @@ class ELFObjectWriter : public MCObjectWriter { } 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) { @@ -204,7 +212,7 @@ class ELFObjectWriter : public MCObjectWriter { } void WriteHeader(const MCAssembler &Asm, - uint64_t SectionDataSize, + uint64_t SectionHeaderOffset, unsigned NumberOfSections); void WriteSymbol(SymbolTableWriter &Writer, ELFSymbolData &MSD, @@ -219,7 +227,7 @@ class ELFObjectWriter : public MCObjectWriter { const MCSymbolData *SD, uint64_t C, unsigned Type) const; - void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, + void RecordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, bool &IsPCRel, uint64_t &FixedValue) override; @@ -231,8 +239,6 @@ class ELFObjectWriter : public MCObjectWriter { typedef DenseMap GroupMapTy; // Map from a signature symbol to the group section typedef DenseMap RevGroupMapTy; - // Map from a section to the section with the relocations - typedef DenseMap RelMapTy; // Map from a section to its offset typedef DenseMap SectionOffsetMapTy; @@ -241,40 +247,32 @@ class ELFObjectWriter : public MCObjectWriter { /// \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, MCAsmLayout &Layout, - 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); @@ -294,12 +292,15 @@ class ELFObjectWriter : public MCObjectWriter { 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, @@ -325,8 +326,7 @@ void SymbolTableWriter::createSymtabShndx() { MCContext &Ctx = Asm.getContext(); const MCSectionELF *SymtabShndxSection = - Ctx.getELFSection(".symtab_shndxr", ELF::SHT_SYMTAB_SHNDX, 0, - SectionKind::getReadOnly(), 4, ""); + Ctx.getELFSection(".symtab_shndxr", ELF::SHT_SYMTAB_SHNDX, 0, 4, ""); MCSectionData *SymtabShndxSD = &Asm.getOrCreateSectionData(*SymtabShndxSection); SymtabShndxSD->setAlignment(4); @@ -422,7 +422,7 @@ ELFObjectWriter::~ELFObjectWriter() // Emit the ELF header. void ELFObjectWriter::WriteHeader(const MCAssembler &Asm, - uint64_t SectionDataSize, + uint64_t SectionHeaderOffset, unsigned NumberOfSections) { // ELF Header // ---------- @@ -456,8 +456,7 @@ void ELFObjectWriter::WriteHeader(const MCAssembler &Asm, 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()); @@ -612,7 +611,7 @@ void ELFObjectWriter::WriteSymbol(SymbolTableWriter &Writer, ELFSymbolData &MSD, 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; } @@ -789,13 +788,15 @@ static const MCSymbol *getWeakRef(const MCSymbolRefExpr &Ref) { return nullptr; } -void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, +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, - const MCFixup &Fixup, - MCValue Target, - bool &IsPCRel, - uint64_t &FixedValue) { + const MCFixup &Fixup, MCValue Target, + bool &IsPCRel, uint64_t &FixedValue) { const MCSectionData *FixupSection = Fragment->getParent(); uint64_t C = Target.getConstant(); uint64_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); @@ -831,6 +832,10 @@ void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, 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; @@ -946,9 +951,8 @@ bool ELFObjectWriter::isLocal(const MCSymbolData &Data, bool isUsedInReloc) { 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) { @@ -961,24 +965,26 @@ void ELFObjectWriter::ComputeIndexMap(MCAssembler &Asm, for (MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); it != ie; ++it) { + const MCSectionData &SD = *it; const MCSectionELF &Section = - static_cast(it->getSection()); + static_cast(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(&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) { @@ -1035,16 +1041,43 @@ ELFObjectWriter::computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout, assert(MSD.SectionIndex && "Invalid section index!"); } - // The @@@ in symbol version is replaced with @ in undefined symbols and - // @@ in defined ones. + // The @@@ in symbol version is replaced with @ in undefined symbols and @@ + // 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 + // trivial. + // + // We thus have to be careful to not perform the symbol version replacement + // blindly: + // + // The ELF format is used on Windows by the MCJIT engine. Thus, on + // Windows, the ELFObjectWriter can encounter symbols mangled using the MS + // Visual Studio C++ name mangling scheme. Symbols mangled using the MSVC + // C++ name mangling can legally have "@@@" as a sub-string. In that case, + // the EFLObjectWriter should not interpret the "@@@" sub-string as + // specifying GNU-style symbol versioning. The ELFObjectWriter therefore + // checks for the MSVC C++ name mangling prefix which is either "?", "@?", + // "__imp_?" or "__imp_@?". + // + // It would have been interesting to perform the MS mangling prefix check + // only when the target triple is of the form *-pc-windows-elf. But, it + // seems that this information is not easily accessible from the + // ELFObjectWriter. StringRef Name = Symbol.getName(); - SmallString<32> Buf; - size_t Pos = Name.find("@@@"); - if (Pos != StringRef::npos) { - Buf += Name.substr(0, Pos); - unsigned Skip = MSD.SectionIndex == ELF::SHN_UNDEF ? 2 : 1; - Buf += Name.substr(Pos + Skip); - Name = Buf; + if (!Name.startswith("?") && !Name.startswith("@?") && + !Name.startswith("__imp_?") && !Name.startswith("__imp_@?")) { + // This symbol isn't following the MSVC C++ name mangling convention. We + // can thus safely interpret the @@@ in symbol names as specifying symbol + // versioning. + SmallString<32> Buf; + size_t Pos = Name.find("@@@"); + if (Pos != StringRef::npos) { + Buf += Name.substr(0, Pos); + unsigned Skip = MSD.SectionIndex == ELF::SHN_UNDEF ? 2 : 1; + Buf += Name.substr(Pos + Skip); + Name = Buf; + } } // Sections have their own string table @@ -1093,44 +1126,34 @@ ELFObjectWriter::computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout, UndefinedSymbolData[i].SymbolData->setIndex(Index++); } -void ELFObjectWriter::CreateRelocationSections(MCAssembler &Asm, - MCAsmLayout &Layout, - 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(SD.getSection()); + MCContext &Ctx = Asm.getContext(); + const MCSectionELF &Section = + static_cast(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, - SectionKind::getReadOnly(), - 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 @@ -1164,7 +1187,7 @@ getUncompressedData(MCAsmLayout &Layout, static bool prependCompressionHeader(uint64_t Size, SmallVectorImpl &CompressedContents) { - static const StringRef Magic = "ZLIB"; + const StringRef Magic = "ZLIB"; if (Size <= Magic.size() + sizeof(Size) + CompressedContents.size()) return false; if (sys::IsLittleEndianHost) @@ -1278,22 +1301,22 @@ void ELFObjectWriter::CompressDebugSections(MCAssembler &Asm, } } -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(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(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); } } @@ -1325,7 +1348,8 @@ static int cmpRel(const ELFRelocationEntry *AP, const ELFRelocationEntry *BP) { 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, @@ -1374,10 +1398,8 @@ void ELFObjectWriter::WriteRelocationsFragment(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; @@ -1385,29 +1407,26 @@ void ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm, // We construct .shstrtab, .symtab and .strtab in this order to match gnu as. const MCSectionELF *ShstrtabSection = - Ctx.getELFSection(".shstrtab", ELF::SHT_STRTAB, 0, - SectionKind::getReadOnly()); + Ctx.getELFSection(".shstrtab", ELF::SHT_STRTAB, 0); MCSectionData &ShstrtabSD = Asm.getOrCreateSectionData(*ShstrtabSection); ShstrtabSD.setAlignment(1); + ShstrtabIndex = SectionIndexMap.size() + 1; + SectionIndexMap[ShstrtabSection] = ShstrtabIndex; const MCSectionELF *SymtabSection = Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, - SectionKind::getReadOnly(), EntrySize, ""); MCSectionData &SymtabSD = Asm.getOrCreateSectionData(*SymtabSection); SymtabSD.setAlignment(is64Bit() ? 8 : 4); + SymbolTableIndex = SectionIndexMap.size() + 1; + SectionIndexMap[SymtabSection] = SymbolTableIndex; const MCSectionELF *StrtabSection; - StrtabSection = Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0, - SectionKind::getReadOnly()); + StrtabSection = Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0); MCSectionData &StrtabSD = Asm.getOrCreateSectionData(*StrtabSection); StrtabSD.setAlignment(1); - - ComputeIndexMap(Asm, SectionIndexMap, RelMap); - - ShstrtabIndex = SectionIndexMap.lookup(ShstrtabSection); - SymbolTableIndex = SectionIndexMap.lookup(SymtabSection); - StringTableIndex = SectionIndexMap.lookup(StrtabSection); + StringTableIndex = SectionIndexMap.size() + 1; + SectionIndexMap[StrtabSection] = StringTableIndex; // Symbol table F = new MCDataFragment(&SymtabSD); @@ -1430,12 +1449,9 @@ void ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm, 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 @@ -1459,7 +1475,7 @@ void ELFObjectWriter::CreateIndexedSections(MCAssembler &Asm, 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(); @@ -1477,7 +1493,7 @@ void ELFObjectWriter::CreateIndexedSections(MCAssembler &Asm, } } -void ELFObjectWriter::WriteSection(MCAssembler &Asm, +void ELFObjectWriter::writeSection(MCAssembler &Asm, const SectionIndexMapTy &SectionIndexMap, uint32_t GroupSymbolIndex, uint64_t Offset, uint64_t Size, @@ -1487,30 +1503,19 @@ void ELFObjectWriter::WriteSection(MCAssembler &Asm, 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, - SectionKind::getReadOnly()); - 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, SectionKind::getReadOnly(), - 0, GroupName); + const MCSectionELF *InfoSection = Section.getAssociatedSection(); sh_info = SectionIndexMap.lookup(InfoSection); break; } @@ -1525,49 +1530,15 @@ void ELFObjectWriter::WriteSection(MCAssembler &Asm, 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, - SectionKind::getText())); - } 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, SectionKind::getText(), 0, - GroupName)); - } - } + Section.getType() == ELF::SHT_ARM_EXIDX) + sh_link = SectionIndexMap.lookup(Section.getAssociatedSection()); WriteSecHdrEntry(ShStrTabBuilder.getOffset(Section.getSectionName()), Section.getType(), @@ -1625,11 +1596,10 @@ void ELFObjectWriter::WriteDataSectionData(MCAssembler &Asm, } } -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 Sections; @@ -1660,9 +1630,9 @@ void ELFObjectWriter::WriteSectionHeader(MCAssembler &Asm, 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); } } @@ -1702,31 +1672,20 @@ void ELFObjectWriter::WriteObject(MCAssembler &Asm, RevGroupMapTy RevGroupMap; SectionIndexMapTy SectionIndexMap; - unsigned NumUserSections = Asm.size(); - CompressDebugSections(Asm, const_cast(Layout)); + createIndexedSections(Asm, const_cast(Layout), GroupMap, + RevGroupMap, SectionIndexMap); - DenseMap RelMap; - CreateRelocationSections(Asm, const_cast(Layout), RelMap); - - const unsigned NumUserAndRelocSections = Asm.size(); - CreateIndexedSections(Asm, const_cast(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(Layout), RelMap); + WriteRelocations(Asm, const_cast(Layout)); CreateMetadataSections(const_cast(Asm), const_cast(Layout), - SectionIndexMap, - RelMap); + SectionIndexMap); uint64_t NaturalAlignment = is64Bit() ? 8 : 4; uint64_t HeaderSize = is64Bit() ? sizeof(ELF::Elf64_Ehdr) : @@ -1752,7 +1711,7 @@ void ELFObjectWriter::WriteObject(MCAssembler &Asm, 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); @@ -1783,24 +1742,25 @@ void ELFObjectWriter::WriteObject(MCAssembler &Asm, 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,