X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;ds=sidebyside;f=lib%2FMC%2FELFObjectWriter.cpp;h=2975a9bfbcdd8e7e987b6a0dc50f99b697be190b;hb=fd64e0f71a38c69a3b8d120937bc0d1cfa62b59e;hp=a211dcfecf8c09828328a1de3ccad3a9b3be7b31;hpb=ab78d674357534c2f57976c9fdab01440bee84b7;p=oota-llvm.git diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp index a211dcfecf8..2975a9bfbcd 100644 --- a/lib/MC/ELFObjectWriter.cpp +++ b/lib/MC/ELFObjectWriter.cpp @@ -71,7 +71,6 @@ public: class ELFObjectWriter : public MCObjectWriter { static bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind); - static bool RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant); static uint64_t SymbolValue(const MCSymbol &Sym, const MCAsmLayout &Layout); static bool isInSymtab(const MCAsmLayout &Layout, const MCSymbol &Symbol, bool Used, bool Renamed); @@ -120,8 +119,6 @@ class ELFObjectWriter : public MCObjectWriter { /// @} - bool NeedsGOT; - // This holds the symbol table index of the last local symbol. unsigned LastLocalSymbolIndex; // This holds the .strtab section index. @@ -148,8 +145,7 @@ class ELFObjectWriter : public MCObjectWriter { public: ELFObjectWriter(MCELFObjectTargetWriter *MOTW, raw_pwrite_stream &OS, bool IsLittleEndian) - : MCObjectWriter(OS, IsLittleEndian), TargetObjectWriter(MOTW), - NeedsGOT(false) {} + : MCObjectWriter(OS, IsLittleEndian), TargetObjectWriter(MOTW) {} void reset() override { UsedInReloc.clear(); @@ -161,7 +157,6 @@ class ELFObjectWriter : public MCObjectWriter { LocalSymbolData.clear(); ExternalSymbolData.clear(); UndefinedSymbolData.clear(); - NeedsGOT = false; SectionTable.clear(); MCObjectWriter::reset(); } @@ -191,9 +186,6 @@ class ELFObjectWriter : public MCObjectWriter { typedef std::map> SectionOffsetsTy; - void writeSymbolTable(MCContext &Ctx, const MCAsmLayout &Layout, - SectionOffsetsTy &SectionOffsets); - bool shouldRelocateWithSymbol(const MCAssembler &Asm, const MCSymbolRefExpr *RefA, const MCSymbol *Sym, uint64_t C, @@ -217,7 +209,8 @@ class ELFObjectWriter : public MCObjectWriter { /// \param RevGroupMap - Maps a signature symbol to the group section. void computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout, const SectionIndexMapTy &SectionIndexMap, - const RevGroupMapTy &RevGroupMap); + const RevGroupMapTy &RevGroupMap, + SectionOffsetsTy &SectionOffsets); MCSectionELF *createRelocationSection(MCContext &Ctx, const MCSectionELF &Sec); @@ -231,7 +224,7 @@ class ELFObjectWriter : public MCObjectWriter { 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, @@ -319,27 +312,6 @@ bool ELFObjectWriter::isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind) { return FKI.Flags & MCFixupKindInfo::FKF_IsPCRel; } -bool ELFObjectWriter::RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant) { - switch (Variant) { - default: - return false; - case MCSymbolRefExpr::VK_GOT: - case MCSymbolRefExpr::VK_PLT: - case MCSymbolRefExpr::VK_GOTPCREL: - case MCSymbolRefExpr::VK_GOTOFF: - case MCSymbolRefExpr::VK_TPOFF: - case MCSymbolRefExpr::VK_TLSGD: - case MCSymbolRefExpr::VK_GOTTPOFF: - case MCSymbolRefExpr::VK_INDNTPOFF: - case MCSymbolRefExpr::VK_NTPOFF: - case MCSymbolRefExpr::VK_GOTNTPOFF: - case MCSymbolRefExpr::VK_TLSLDM: - case MCSymbolRefExpr::VK_DTPOFF: - case MCSymbolRefExpr::VK_TLSLD: - return true; - } -} - ELFObjectWriter::~ELFObjectWriter() {} @@ -491,8 +463,7 @@ void ELFObjectWriter::WriteSymbol(SymbolTableWriter &Writer, ELFSymbolData &MSD, 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); @@ -535,76 +506,6 @@ void ELFObjectWriter::WriteSymbol(SymbolTableWriter &Writer, ELFSymbolData &MSD, MSD.SectionIndex, IsReserved); } -void ELFObjectWriter::writeSymbolTable(MCContext &Ctx, - const MCAsmLayout &Layout, - SectionOffsetsTy &SectionOffsets) { - 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(), SymtabSection->getAlignment()); - WriteZeros(Padding); - - uint64_t SecStart = OS.tell(); - - // The first entry is the undefined symbol entry. - Writer.writeSymbol(0, 0, 0, 0, 0, 0, false); - - 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); - } - - // Write the symbol table entries. - LastLocalSymbolIndex = FileSymbolData.size() + LocalSymbolData.size() + 1; - - 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++; - } - - uint64_t SecEnd = OS.tell(); - SectionOffsets[SymtabSection] = std::make_pair(SecStart, SecEnd); - - ArrayRef ShndxIndexes = Writer.getShndxIndexes(); - if (ShndxIndexes.empty()) { - assert(SymtabShndxSectionIndex == 0); - return; - } - assert(SymtabShndxSectionIndex != 0); - - SecStart = OS.tell(); - const MCSectionELF *SymtabShndxSection = - SectionTable[SymtabShndxSectionIndex - 1]; - for (uint32_t Index : ShndxIndexes) - write(Index); - SecEnd = OS.tell(); - SectionOffsets[SymtabShndxSection] = std::make_pair(SecStart, SecEnd); -} - // It is always valid to create a relocation with a symbol. It is preferable // to use a relocation with a section if that is possible. Using the section // allows us to omit some local symbols from the symbol table. @@ -751,9 +652,7 @@ void ELFObjectWriter::RecordRelocation(MCAssembler &Asm, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, bool &IsPCRel, uint64_t &FixedValue) { - const MCSectionData *FixupSectionD = Fragment->getParent(); - const MCSectionELF &FixupSection = - cast(FixupSectionD->getSection()); + const MCSectionELF &FixupSection = cast(*Fragment->getParent()); uint64_t C = Target.getConstant(); uint64_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); @@ -814,19 +713,11 @@ void ELFObjectWriter::RecordRelocation(MCAssembler &Asm, FixedValue = C; - // FIXME: What is this!?!? - MCSymbolRefExpr::VariantKind Modifier = - RefA ? RefA->getKind() : MCSymbolRefExpr::VK_None; - if (RelocNeedsGOT(Modifier)) - NeedsGOT = true; - if (!RelocateWithSymbol) { const MCSection *SecA = (SymA && !SymA->isUndefined()) ? &SymA->getSection() : nullptr; auto *ELFSec = cast_or_null(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; @@ -885,6 +776,9 @@ 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; @@ -907,9 +801,11 @@ bool ELFObjectWriter::isLocal(const MCSymbol &Symbol, bool isUsedInReloc) { void ELFObjectWriter::computeSymbolTable( MCAssembler &Asm, const MCAsmLayout &Layout, - const SectionIndexMapTy &SectionIndexMap, - const RevGroupMapTy &RevGroupMap) { + const SectionIndexMapTy &SectionIndexMap, const RevGroupMapTy &RevGroupMap, + SectionOffsetsTy &SectionOffsets) { MCContext &Ctx = Asm.getContext(); + SymbolTableWriter Writer(*this, is64Bit()); + // Symbol table unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32; MCSectionELF *SymtabSection = @@ -917,15 +813,14 @@ void ELFObjectWriter::computeSymbolTable( 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) { - StringRef Name = "_GLOBAL_OFFSET_TABLE_"; - MCSymbol *Sym = Asm.getContext().getOrCreateSymbol(Name); - MCSymbolData &Data = Asm.getOrCreateSymbolData(*Sym); - Data.setExternal(true); - MCELF::SetBinding(Data, ELF::STB_GLOBAL); - } + uint64_t Padding = + OffsetToAlignment(OS.tell(), SymtabSection->getAlignment()); + WriteZeros(Padding); + + uint64_t SecStart = OS.tell(); + + // The first entry is the undefined symbol entry. + Writer.writeSymbol(0, 0, 0, 0, 0, 0, false); // Add the data for the symbols. bool HasLargeSectionIndex = false; @@ -1036,22 +931,13 @@ void ELFObjectWriter::computeSymbolTable( SymtabShndxSection->setAlignment(4); } - for (auto i = Asm.file_names_begin(), e = Asm.file_names_end(); i != e; ++i) - StrTabBuilder.add(*i); + for (const std::string &Name : Asm.getFileNames()) + StrTabBuilder.add(Name); StrTabBuilder.finalize(StringTableBuilder::ELF); - for (auto i = Asm.file_names_begin(), e = Asm.file_names_end(); i != e; ++i) - FileSymbolData.push_back(StrTabBuilder.getOffset(*i)); - - for (ELFSymbolData &MSD : LocalSymbolData) - MSD.StringIndex = MCELF::GetType(MSD.Symbol->getData()) == ELF::STT_SECTION - ? 0 - : StrTabBuilder.getOffset(MSD.Name); - for (ELFSymbolData &MSD : ExternalSymbolData) - MSD.StringIndex = StrTabBuilder.getOffset(MSD.Name); - for (ELFSymbolData& MSD : UndefinedSymbolData) - MSD.StringIndex = StrTabBuilder.getOffset(MSD.Name); + for (const std::string &Name : Asm.getFileNames()) + FileSymbolData.push_back(StrTabBuilder.getOffset(Name)); // Symbols are required to be in lexicographic order. array_pod_sort(LocalSymbolData.begin(), LocalSymbolData.end()); @@ -1061,13 +947,71 @@ void ELFObjectWriter::computeSymbolTable( // Set the symbol indices. Local symbols must come before all other // symbols with non-local bindings. unsigned Index = FileSymbolData.size() + 1; - for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) - LocalSymbolData[i].Symbol->setIndex(Index++); - for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) - ExternalSymbolData[i].Symbol->setIndex(Index++); - for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) - UndefinedSymbolData[i].Symbol->setIndex(Index++); + 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); + 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); + } + + // Write the symbol table entries. + LastLocalSymbolIndex = FileSymbolData.size() + LocalSymbolData.size() + 1; + + 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++; + } + + uint64_t SecEnd = OS.tell(); + SectionOffsets[SymtabSection] = std::make_pair(SecStart, SecEnd); + + ArrayRef ShndxIndexes = Writer.getShndxIndexes(); + if (ShndxIndexes.empty()) { + assert(SymtabShndxSectionIndex == 0); + return; + } + assert(SymtabShndxSectionIndex != 0); + + SecStart = OS.tell(); + const MCSectionELF *SymtabShndxSection = + SectionTable[SymtabShndxSectionIndex - 1]; + for (uint32_t Index : ShndxIndexes) + write(Index); + SecEnd = OS.tell(); + SectionOffsets[SymtabShndxSection] = std::make_pair(SecStart, SecEnd); } MCSectionELF * @@ -1099,7 +1043,7 @@ ELFObjectWriter::createRelocationSection(MCContext &Ctx, static SmallVector getUncompressedData(const MCAsmLayout &Layout, - const MCSectionData::FragmentListType &Fragments) { + const MCSection::FragmentListType &Fragments) { SmallVector UncompressedData; for (const MCFragment &F : Fragments) { const SmallVectorImpl *Contents; @@ -1142,10 +1086,9 @@ prependCompressionHeader(uint64_t Size, 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(SD.getSection()); + MCSectionELF &Section = static_cast(Sec); StringRef SectionName = Section.getSectionName(); // Compressing debug_frame requires handling alignment fragments which is @@ -1153,12 +1096,12 @@ void ELFObjectWriter::writeSectionData(const MCAssembler &Asm, // 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 UncompressedData = getUncompressedData(Layout, Fragments); @@ -1167,12 +1110,12 @@ void ELFObjectWriter::writeSectionData(const MCAssembler &Asm, 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, @@ -1317,12 +1260,10 @@ void ELFObjectWriter::writeSectionHeader( const std::pair &Offsets = SectionOffsets.find(Section)->second; uint64_t Size; - if (Type == ELF::SHT_NOBITS) { - const MCSectionData &SD = Asm.getSectionData(*Section); - Size = Layout.getSectionAddressSize(&SD); - } else { + if (Type == ELF::SHT_NOBITS) + Size = Layout.getSectionAddressSize(Section); + else Size = Offsets.second - Offsets.first; - } writeSection(SectionIndexMap, GroupSymbolIndex, Offsets.first, Size, *Section); @@ -1348,8 +1289,8 @@ void ELFObjectWriter::WriteObject(MCAssembler &Asm, SectionOffsetsTy SectionOffsets; std::vector Groups; std::vector Relocations; - for (const MCSectionData &SD : Asm) { - const MCSectionELF &Section = static_cast(SD.getSection()); + for (MCSection &Sec : Asm) { + MCSectionELF &Section = static_cast(Sec); uint64_t Padding = OffsetToAlignment(OS.tell(), Section.getAlignment()); WriteZeros(Padding); @@ -1358,7 +1299,7 @@ void ELFObjectWriter::WriteObject(MCAssembler &Asm, uint64_t SecStart = OS.tell(); const MCSymbol *SignatureSymbol = Section.getGroup(); - writeSectionData(Asm, SD, Layout); + writeSectionData(Asm, Section, Layout); uint64_t SecEnd = OS.tell(); SectionOffsets[&Section] = std::make_pair(SecStart, SecEnd); @@ -1406,7 +1347,7 @@ void ELFObjectWriter::WriteObject(MCAssembler &Asm, } // Compute symbol table information. - computeSymbolTable(Asm, Layout, SectionIndexMap, RevGroupMap); + computeSymbolTable(Asm, Layout, SectionIndexMap, RevGroupMap, SectionOffsets); for (MCSectionELF *RelSection : Relocations) { uint64_t Padding = OffsetToAlignment(OS.tell(), RelSection->getAlignment()); @@ -1421,8 +1362,6 @@ void ELFObjectWriter::WriteObject(MCAssembler &Asm, SectionOffsets[RelSection] = std::make_pair(SecStart, SecEnd); } - writeSymbolTable(Ctx, Layout, SectionOffsets); - { uint64_t SecStart = OS.tell(); const MCSectionELF *Sec = createStringTable(Ctx);