X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FMC%2FELFObjectWriter.cpp;h=e4442e10a055118eb3ed7a7728a031c67fb2adde;hp=bcbf2cc7041101a4a5bd7f5cd38c93c3d493d68c;hb=d8ee23f34c2f4b8472f406067140cb4d37c19cab;hpb=4266ae806798f1e8982a53bb9babe1e508adfc68 diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp index bcbf2cc7041..e4442e10a05 100644 --- a/lib/MC/ELFObjectWriter.cpp +++ b/lib/MC/ELFObjectWriter.cpp @@ -28,6 +28,7 @@ #include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCValue.h" +#include "llvm/MC/StringTableBuilder.h" #include "llvm/Support/Compression.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Endian.h" @@ -80,23 +81,13 @@ public: struct ELFRelocationEntry { uint64_t Offset; // Where is the relocation. - bool UseSymbol; // Relocate with a symbol, not the section. - union { - const MCSymbol *Symbol; // The symbol to relocate with. - const MCSectionData *Section; // The section to relocate with. - }; + const MCSymbol *Symbol; // The symbol to relocate with. unsigned Type; // The type of the relocation. uint64_t Addend; // The addend to use. ELFRelocationEntry(uint64_t Offset, const MCSymbol *Symbol, unsigned Type, uint64_t Addend) - : Offset(Offset), UseSymbol(true), Symbol(Symbol), Type(Type), - Addend(Addend) {} - - ELFRelocationEntry(uint64_t Offset, const MCSectionData *Section, - unsigned Type, uint64_t Addend) - : Offset(Offset), UseSymbol(false), Section(Section), Type(Type), - Addend(Addend) {} + : Offset(Offset), Symbol(Symbol), Type(Type), Addend(Addend) {} }; class ELFObjectWriter : public MCObjectWriter { @@ -107,10 +98,9 @@ class ELFObjectWriter : public MCObjectWriter { static bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind); static bool RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant); static uint64_t SymbolValue(MCSymbolData &Data, const MCAsmLayout &Layout); - static bool isInSymtab(const MCAssembler &Asm, const MCSymbolData &Data, + static bool isInSymtab(const MCAsmLayout &Layout, const MCSymbolData &Data, bool Used, bool Renamed); - static bool isLocal(const MCSymbolData &Data, bool isSignature, - bool isUsedInReloc); + static bool isLocal(const MCSymbolData &Data, bool isUsedInReloc); static bool IsELFMetaDataSection(const MCSectionData &SD); static uint64_t DataSectionSize(const MCSectionData &SD); static uint64_t GetSectionFileSize(const MCAsmLayout &Layout, @@ -133,11 +123,19 @@ class ELFObjectWriter : public MCObjectWriter { MCSymbolData *SymbolData; uint64_t StringIndex; uint32_t SectionIndex; + StringRef Name; // Support lexicographic sorting. bool operator<(const ELFSymbolData &RHS) const { - return SymbolData->getSymbol().getName() < - RHS.SymbolData->getSymbol().getName(); + unsigned LHSType = MCELF::GetType(*SymbolData); + unsigned RHSType = MCELF::GetType(*RHS.SymbolData); + if (LHSType == ELF::STT_SECTION && RHSType != ELF::STT_SECTION) + return false; + if (LHSType != ELF::STT_SECTION && RHSType == ELF::STT_SECTION) + return true; + if (LHSType == ELF::STT_SECTION && RHSType == ELF::STT_SECTION) + return SectionIndex < RHS.SectionIndex; + return Name < RHS.Name; } }; @@ -150,13 +148,13 @@ class ELFObjectWriter : public MCObjectWriter { llvm::DenseMap> Relocations; - DenseMap SectionStringTableIndex; + StringTableBuilder ShStrTabBuilder; /// @} /// @name Symbol Table Data /// @{ - SmallString<256> StringTable; + StringTableBuilder StrTabBuilder; std::vector FileSymbolData; std::vector LocalSymbolData; std::vector ExternalSymbolData; @@ -216,7 +214,8 @@ class ELFObjectWriter : public MCObjectWriter { const MCAsmLayout &Layout, SectionIndexMapTy &SectionIndexMap); - bool shouldRelocateWithSymbol(const MCSymbolRefExpr *RefA, + bool shouldRelocateWithSymbol(const MCAssembler &Asm, + const MCSymbolRefExpr *RefA, const MCSymbolData *SD, uint64_t C, unsigned Type) const; @@ -245,7 +244,7 @@ class ELFObjectWriter : public MCObjectWriter { /// \param NumRegularSections - Number of non-relocation sections. void computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout, const SectionIndexMapTy &SectionIndexMap, - RevGroupMapTy RevGroupMap, + const RevGroupMapTy &RevGroupMap, unsigned NumRegularSections); void ComputeIndexMap(MCAssembler &Asm, @@ -485,43 +484,18 @@ void ELFObjectWriter::WriteHeader(const MCAssembler &Asm, Write16(ShstrtabIndex); } -uint64_t ELFObjectWriter::SymbolValue(MCSymbolData &OrigData, +uint64_t ELFObjectWriter::SymbolValue(MCSymbolData &Data, const MCAsmLayout &Layout) { - MCSymbolData *Data = &OrigData; - if (Data->isCommon() && Data->isExternal()) - return Data->getCommonAlignment(); - - const MCSymbol *Symbol = &Data->getSymbol(); - bool IsThumbFunc = OrigData.getFlags() & ELF_Other_ThumbFunc; - - uint64_t Res = 0; - if (Symbol->isVariable()) { - const MCExpr *Expr = Symbol->getVariableValue(); - MCValue Value; - if (!Expr->EvaluateAsRelocatable(Value, &Layout)) - llvm_unreachable("Invalid expression"); - - assert(!Value.getSymB()); + if (Data.isCommon() && Data.isExternal()) + return Data.getCommonAlignment(); - Res = Value.getConstant(); + uint64_t Res; + if (!Layout.getSymbolOffset(&Data, Res)) + return 0; - if (const MCSymbolRefExpr *A = Value.getSymA()) { - Symbol = &A->getSymbol(); - Data = &Layout.getAssembler().getSymbolData(*Symbol); - } else { - Symbol = nullptr; - Data = nullptr; - } - } - - if (IsThumbFunc) + if (Layout.getAssembler().isThumbFunc(&Data.getSymbol())) Res |= 1; - if (!Symbol || !Symbol->isInSection()) - return Res; - - Res += Layout.getSymbolOffset(Data); - return Res; } @@ -530,15 +504,17 @@ void ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, // The presence of symbol versions causes undefined symbols and // versions declared with @@@ to be renamed. - for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), - ie = Asm.symbol_end(); it != ie; ++it) { - const MCSymbol &Alias = it->getSymbol(); - const MCSymbol &Symbol = Alias.AliasedSymbol(); - MCSymbolData &SD = Asm.getSymbolData(Symbol); + for (MCSymbolData &OriginalData : Asm.symbols()) { + const MCSymbol &Alias = OriginalData.getSymbol(); // Not an alias. - if (&Symbol == &Alias) + if (!Alias.isVariable()) + continue; + auto *Ref = dyn_cast(Alias.getVariableValue()); + if (!Ref) continue; + const MCSymbol &Symbol = Ref->getSymbol(); + MCSymbolData &SD = Asm.getSymbolData(Symbol); StringRef AliasName = Alias.getName(); size_t Pos = AliasName.find('@'); @@ -547,8 +523,8 @@ void ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, // Aliases defined with .symvar copy the binding from the symbol they alias. // This is the first place we are able to copy this information. - it->setExternal(SD.isExternal()); - MCELF::SetBinding(*it, MCELF::GetBinding(SD)); + OriginalData.setExternal(SD.isExternal()); + MCELF::SetBinding(OriginalData, MCELF::GetBinding(SD)); StringRef Rest = AliasName.substr(Pos); if (!Symbol.isUndefined() && !Rest.startswith("@@@")) @@ -598,26 +574,14 @@ static uint8_t mergeTypeForSet(uint8_t origType, uint8_t newType) { return Type; } -static const MCSymbol *getBaseSymbol(const MCAsmLayout &Layout, - const MCSymbol &Symbol) { - if (!Symbol.isVariable()) - return &Symbol; - - const MCExpr *Expr = Symbol.getVariableValue(); - MCValue Value; - if (!Expr->EvaluateAsRelocatable(Value, &Layout)) - llvm_unreachable("Invalid Expression"); - assert(!Value.getSymB()); - const MCSymbolRefExpr *A = Value.getSymA(); - if (!A) - return nullptr; - return getBaseSymbol(Layout, A->getSymbol()); -} - void ELFObjectWriter::WriteSymbol(SymbolTableWriter &Writer, ELFSymbolData &MSD, const MCAsmLayout &Layout) { MCSymbolData &OrigData = *MSD.SymbolData; - const MCSymbol *Base = getBaseSymbol(Layout, OrigData.getSymbol()); + assert((!OrigData.getFragment() || + (&OrigData.getFragment()->getParent()->getSection() == + &OrigData.getSymbol().getSection())) && + "The symbol's section doesn't match the fragment's symbol"); + const MCSymbol *Base = Layout.getBaseSymbol(OrigData.getSymbol()); // This has to be in sync with when computeSymbolTable uses SHN_ABS or // SHN_COMMON. @@ -631,8 +595,6 @@ void ELFObjectWriter::WriteSymbol(SymbolTableWriter &Writer, ELFSymbolData &MSD, BaseSD = &Layout.getAssembler().getSymbolData(*Base); Type = mergeTypeForSet(Type, MCELF::GetType(*BaseSD)); } - if (OrigData.getFlags() & ELF_Other_ThumbFunc) - Type = ELF::STT_FUNC; uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift); // Other and Visibility share the same byte with Visibility using the lower @@ -642,8 +604,6 @@ void ELFObjectWriter::WriteSymbol(SymbolTableWriter &Writer, ELFSymbolData &MSD, Other |= Visibility; uint64_t Value = SymbolValue(OrigData, Layout); - if (OrigData.getFlags() & ELF_Other_ThumbFunc) - Value |= 1; uint64_t Size = 0; const MCExpr *ESize = OrigData.getSize(); @@ -668,7 +628,6 @@ void ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF, SectionIndexMapTy &SectionIndexMap) { // The string table must be emitted first because we need the index // into the string table for all the symbol names. - assert(StringTable.size() && "Missing string table"); // FIXME: Make sure the start of the symbol table is aligned. @@ -690,22 +649,6 @@ void ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF, WriteSymbol(Writer, MSD, Layout); } - // Write out a symbol table entry for each regular section. - for (MCAssembler::const_iterator i = Asm.begin(), e = Asm.end(); i != e; - ++i) { - const MCSectionELF &Section = - static_cast(i->getSection()); - if (Section.getType() == ELF::SHT_RELA || - Section.getType() == ELF::SHT_REL || - Section.getType() == ELF::SHT_STRTAB || - Section.getType() == ELF::SHT_SYMTAB || - Section.getType() == ELF::SHT_SYMTAB_SHNDX) - continue; - Writer.writeSymbol(0, ELF::STT_SECTION, 0, 0, ELF::STV_DEFAULT, - SectionIndexMap.lookup(&Section), false); - LastLocalSymbolIndex++; - } - for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) { ELFSymbolData &MSD = ExternalSymbolData[i]; MCSymbolData &Data = *MSD.SymbolData; @@ -729,7 +672,8 @@ void ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF, // 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. -bool ELFObjectWriter::shouldRelocateWithSymbol(const MCSymbolRefExpr *RefA, +bool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm, + const MCSymbolRefExpr *RefA, const MCSymbolData *SD, uint64_t C, unsigned Type) const { @@ -808,8 +752,9 @@ bool ELFObjectWriter::shouldRelocateWithSymbol(const MCSymbolRefExpr *RefA, } // Most TLS relocations use a got, so they need the symbol. Even those that - // are just an offset (@tpoff), require a symbol in some linkers (gold, - // but not bfd ld). + // are just an offset (@tpoff), require a symbol in gold versions before + // 5efeedf61e4fe720fd3e9a08e6c91c10abb66d42 (2014-09-26) which fixed + // http://sourceware.org/PR16773. if (Flags & ELF::SHF_TLS) return true; @@ -817,14 +762,33 @@ bool ELFObjectWriter::shouldRelocateWithSymbol(const MCSymbolRefExpr *RefA, // bit. With a symbol that is done by just having the symbol have that bit // set, so we would lose the bit if we relocated with the section. // FIXME: We could use the section but add the bit to the relocation value. - if (SD->getFlags() & ELF_Other_ThumbFunc) + if (Asm.isThumbFunc(&Sym)) return true; - if (TargetObjectWriter->needsRelocateWithSymbol(Type)) + if (TargetObjectWriter->needsRelocateWithSymbol(*SD, Type)) return true; return false; } +static const MCSymbol *getWeakRef(const MCSymbolRefExpr &Ref) { + const MCSymbol &Sym = Ref.getSymbol(); + + if (Ref.getKind() == MCSymbolRefExpr::VK_WEAKREF) + return &Sym; + + if (!Sym.isVariable()) + return nullptr; + + const MCExpr *Expr = Sym.getVariableValue(); + const auto *Inner = dyn_cast(Expr); + if (!Inner) + return nullptr; + + if (Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF) + return &Inner->getSymbol(); + return nullptr; +} + void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, @@ -879,7 +843,7 @@ void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, const MCSymbolData *SymAD = SymA ? &Asm.getSymbolData(*SymA) : nullptr; unsigned Type = GetRelocType(Target, Fixup, IsPCRel); - bool RelocateWithSymbol = shouldRelocateWithSymbol(RefA, SymAD, C, Type); + bool RelocateWithSymbol = shouldRelocateWithSymbol(Asm, RefA, SymAD, C, Type); if (!RelocateWithSymbol && SymA && !SymA->isUndefined()) C += Layout.getSymbolOffset(SymAD); @@ -900,8 +864,11 @@ void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, if (!RelocateWithSymbol) { const MCSection *SecA = (SymA && !SymA->isUndefined()) ? &SymA->getSection() : nullptr; - const MCSectionData *SecAD = SecA ? &Asm.getSectionData(*SecA) : nullptr; - ELFRelocationEntry Rec(FixupOffset, SecAD, Type, Addend); + auto *ELFSec = cast_or_null(SecA); + MCSymbol *SectionSymbol = + ELFSec ? Asm.getContext().getOrCreateSectionSymbol(*ELFSec) + : nullptr; + ELFRelocationEntry Rec(FixupOffset, SectionSymbol, Type, Addend); Relocations[FixupSection].push_back(Rec); return; } @@ -910,8 +877,8 @@ void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, if (const MCSymbol *R = Renames.lookup(SymA)) SymA = R; - if (RefA->getKind() == MCSymbolRefExpr::VK_WEAKREF) - WeakrefUsedInReloc.insert(SymA); + if (const MCSymbol *WeakRef = getWeakRef(*RefA)) + WeakrefUsedInReloc.insert(WeakRef); else UsedInReloc.insert(SymA); } @@ -924,13 +891,13 @@ void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, uint64_t ELFObjectWriter::getSymbolIndexInSymbolTable(const MCAssembler &Asm, const MCSymbol *S) { - MCSymbolData &SD = Asm.getSymbolData(*S); + const MCSymbolData &SD = Asm.getSymbolData(*S); return SD.getIndex(); } -bool ELFObjectWriter::isInSymtab(const MCAssembler &Asm, - const MCSymbolData &Data, - bool Used, bool Renamed) { +bool ELFObjectWriter::isInSymtab(const MCAsmLayout &Layout, + const MCSymbolData &Data, bool Used, + bool Renamed) { const MCSymbol &Symbol = Data.getSymbol(); if (Symbol.isVariable()) { const MCExpr *Expr = Symbol.getVariableValue(); @@ -949,9 +916,11 @@ bool ELFObjectWriter::isInSymtab(const MCAssembler &Asm, if (Symbol.getName() == "_GLOBAL_OFFSET_TABLE_") return true; - const MCSymbol &A = Symbol.AliasedSymbol(); - if (Symbol.isVariable() && !A.isVariable() && A.isUndefined()) - return false; + if (Symbol.isVariable()) { + const MCSymbol *Base = Layout.getBaseSymbol(Symbol); + if (Base && Base->isUndefined()) + return false; + } bool IsGlobal = MCELF::GetBinding(Data) == ELF::STB_GLOBAL; if (!Symbol.isVariable() && Symbol.isUndefined() && !IsGlobal) @@ -963,20 +932,16 @@ bool ELFObjectWriter::isInSymtab(const MCAssembler &Asm, return true; } -bool ELFObjectWriter::isLocal(const MCSymbolData &Data, bool isSignature, - bool isUsedInReloc) { +bool ELFObjectWriter::isLocal(const MCSymbolData &Data, bool isUsedInReloc) { if (Data.isExternal()) return false; const MCSymbol &Symbol = Data.getSymbol(); - const MCSymbol &RefSymbol = Symbol.AliasedSymbol(); - - if (RefSymbol.isUndefined() && !RefSymbol.isVariable()) { - if (isSignature && !isUsedInReloc) - return true; + if (Symbol.isDefined()) + return true; + if (isUsedInReloc) return false; - } return true; } @@ -1012,7 +977,7 @@ void ELFObjectWriter::ComputeIndexMap(MCAssembler &Asm, void ELFObjectWriter::computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout, const SectionIndexMapTy &SectionIndexMap, - RevGroupMapTy RevGroupMap, + const RevGroupMapTy &RevGroupMap, unsigned NumRegularSections) { // FIXME: Is this the correct place to do this? // FIXME: Why is an undefined reference to _GLOBAL_OFFSET_TABLE_ needed? @@ -1024,67 +989,45 @@ ELFObjectWriter::computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout, MCELF::SetBinding(Data, ELF::STB_GLOBAL); } - // Index 0 is always the empty string. - StringMap StringIndexMap; - StringTable += '\x00'; - - // FIXME: We could optimize suffixes in strtab in the same way we - // optimize them in shstrtab. - - for (MCAssembler::const_file_name_iterator it = Asm.file_names_begin(), - ie = Asm.file_names_end(); - it != ie; - ++it) { - StringRef Name = *it; - uint64_t &Entry = StringIndexMap[Name]; - if (!Entry) { - Entry = StringTable.size(); - StringTable += Name; - StringTable += '\x00'; - } - FileSymbolData.push_back(Entry); - } - // Add the data for the symbols. - for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), - ie = Asm.symbol_end(); it != ie; ++it) { - const MCSymbol &Symbol = it->getSymbol(); + for (MCSymbolData &SD : Asm.symbols()) { + const MCSymbol &Symbol = SD.getSymbol(); bool Used = UsedInReloc.count(&Symbol); bool WeakrefUsed = WeakrefUsedInReloc.count(&Symbol); bool isSignature = RevGroupMap.count(&Symbol); - if (!isInSymtab(Asm, *it, + if (!isInSymtab(Layout, SD, Used || WeakrefUsed || isSignature, Renames.count(&Symbol))) continue; ELFSymbolData MSD; - MSD.SymbolData = it; - const MCSymbol *BaseSymbol = getBaseSymbol(Layout, Symbol); + MSD.SymbolData = &SD; + 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(*it, isSignature, Used); - if (!Local && MCELF::GetBinding(*it) == ELF::STB_LOCAL) { + bool Local = isLocal(SD, Used); + if (!Local && MCELF::GetBinding(SD) == ELF::STB_LOCAL) { assert(BaseSymbol); - MCSymbolData &SD = Asm.getSymbolData(*BaseSymbol); - MCELF::SetBinding(*it, ELF::STB_GLOBAL); + MCSymbolData &BaseData = Asm.getSymbolData(*BaseSymbol); MCELF::SetBinding(SD, ELF::STB_GLOBAL); + MCELF::SetBinding(BaseData, ELF::STB_GLOBAL); } if (!BaseSymbol) { MSD.SectionIndex = ELF::SHN_ABS; - } else if (it->isCommon()) { + } else if (SD.isCommon()) { assert(!Local); MSD.SectionIndex = ELF::SHN_COMMON; } else if (BaseSymbol->isUndefined()) { if (isSignature && !Used) - MSD.SectionIndex = SectionIndexMap.lookup(RevGroupMap[&Symbol]); + MSD.SectionIndex = SectionIndexMap.lookup(RevGroupMap.lookup(&Symbol)); else MSD.SectionIndex = ELF::SHN_UNDEF; if (!Used && WeakrefUsed) - MCELF::SetBinding(*it, ELF::STB_WEAK); + MCELF::SetBinding(SD, ELF::STB_WEAK); } else { const MCSectionELF &Section = static_cast(BaseSymbol->getSection()); @@ -1096,7 +1039,6 @@ ELFObjectWriter::computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout, // @@ in defined ones. StringRef Name = Symbol.getName(); SmallString<32> Buf; - size_t Pos = Name.find("@@@"); if (Pos != StringRef::npos) { Buf += Name.substr(0, Pos); @@ -1105,13 +1047,10 @@ ELFObjectWriter::computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout, Name = Buf; } - uint64_t &Entry = StringIndexMap[Name]; - if (!Entry) { - Entry = StringTable.size(); - StringTable += Name; - StringTable += '\x00'; - } - MSD.StringIndex = Entry; + // Sections have their own string table + if (MCELF::GetType(SD) != ELF::STT_SECTION) + MSD.Name = StrTabBuilder.add(Name); + if (MSD.SectionIndex == ELF::SHN_UNDEF) UndefinedSymbolData.push_back(MSD); else if (Local) @@ -1120,6 +1059,23 @@ ELFObjectWriter::computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout, ExternalSymbolData.push_back(MSD); } + for (auto i = Asm.file_names_begin(), e = Asm.file_names_end(); i != e; ++i) + StrTabBuilder.add(*i); + + 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.SymbolData) == 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); + // Symbols are required to be in lexicographic order. array_pod_sort(LocalSymbolData.begin(), LocalSymbolData.end()); array_pod_sort(ExternalSymbolData.begin(), ExternalSymbolData.end()); @@ -1131,8 +1087,6 @@ ELFObjectWriter::computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout, for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) LocalSymbolData[i].SymbolData->setIndex(Index++); - Index += NumRegularSections; - for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) ExternalSymbolData[i].SymbolData->setIndex(Index++); for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) @@ -1207,18 +1161,21 @@ getUncompressedData(MCAsmLayout &Layout, // Include the debug info compression header: // "ZLIB" followed by 8 bytes representing the uncompressed size of the section, // useful for consumers to preallocate a buffer to decompress into. -static void +static bool prependCompressionHeader(uint64_t Size, SmallVectorImpl &CompressedContents) { static const StringRef Magic = "ZLIB"; + if (Size <= Magic.size() + sizeof(Size) + CompressedContents.size()) + return false; if (sys::IsLittleEndianHost) - Size = sys::SwapByteOrder(Size); + sys::swapByteOrder(Size); CompressedContents.insert(CompressedContents.begin(), Magic.size() + sizeof(Size), 0); std::copy(Magic.begin(), Magic.end(), CompressedContents.begin()); std::copy(reinterpret_cast(&Size), reinterpret_cast(&Size + 1), CompressedContents.begin() + Magic.size()); + return true; } // Return a single fragment containing the compressed contents of the whole @@ -1241,12 +1198,27 @@ getCompressedFragment(MCAsmLayout &Layout, if (Success != zlib::StatusOK) return nullptr; - prependCompressionHeader(UncompressedData.size(), CompressedContents); + if (!prependCompressionHeader(UncompressedData.size(), CompressedContents)) + return nullptr; return CompressedFragment; } +typedef DenseMap> +DefiningSymbolMap; + +static void UpdateSymbols(const MCAsmLayout &Layout, + const std::vector &Symbols, + MCFragment &NewFragment) { + for (MCSymbolData *Sym : Symbols) { + Sym->setOffset(Sym->getOffset() + + Layout.getFragmentOffset(Sym->getFragment())); + Sym->setFragment(&NewFragment); + } +} + static void CompressDebugSection(MCAssembler &Asm, MCAsmLayout &Layout, + const DefiningSymbolMap &DefiningSymbols, const MCSectionELF &Section, MCSectionData &SD) { StringRef SectionName = Section.getSectionName(); @@ -1259,6 +1231,12 @@ static void CompressDebugSection(MCAssembler &Asm, MCAsmLayout &Layout, if (!CompressedFragment) return; + // Update the fragment+offsets of any symbols referring to fragments in this + // section to refer to the new fragment. + auto I = DefiningSymbols.find(&SD); + if (I != DefiningSymbols.end()) + UpdateSymbols(Layout, I->second, *CompressedFragment); + // Invalidate the layout for the whole section since it will have new and // different fragments now. Layout.invalidateFragmentsFrom(&Fragments.front()); @@ -1279,6 +1257,12 @@ void ELFObjectWriter::CompressDebugSections(MCAssembler &Asm, if (!Asm.getContext().getAsmInfo()->compressDebugSections()) return; + DefiningSymbolMap DefiningSymbols; + + for (MCSymbolData &SD : Asm.symbols()) + if (MCFragment *F = SD.getFragment()) + DefiningSymbols[F->getParent()].push_back(&SD); + for (MCSectionData &SD : Asm) { const MCSectionELF &Section = static_cast(SD.getSection()); @@ -1290,7 +1274,7 @@ void ELFObjectWriter::CompressDebugSections(MCAssembler &Asm, if (!SectionName.startswith(".debug_") || SectionName == ".debug_frame") continue; - CompressDebugSection(Asm, Layout, Section, SD); + CompressDebugSection(Asm, Layout, DefiningSymbols, Section, SD); } } @@ -1358,18 +1342,8 @@ void ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm, for (unsigned i = 0, e = Relocs.size(); i != e; ++i) { const ELFRelocationEntry &Entry = Relocs[e - i - 1]; - - unsigned Index; - if (Entry.UseSymbol) { - Index = getSymbolIndexInSymbolTable(Asm, Entry.Symbol); - } else { - const MCSectionData *Sec = Entry.Section; - if (Sec) - Index = Sec->getOrdinal() + FileSymbolData.size() + - LocalSymbolData.size() + 1; - else - Index = 0; - } + unsigned Index = + Entry.Symbol ? getSymbolIndexInSymbolTable(Asm, Entry.Symbol) : 0; if (is64Bit()) { write(*F, Entry.Offset); @@ -1400,23 +1374,6 @@ void ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm, } } -static int compareBySuffix(const MCSectionELF *const *a, - const MCSectionELF *const *b) { - const StringRef &NameA = (*a)->getSectionName(); - const StringRef &NameB = (*b)->getSectionName(); - const unsigned sizeA = NameA.size(); - const unsigned sizeB = NameB.size(); - const unsigned len = std::min(sizeA, sizeB); - for (unsigned int i = 0; i < len; ++i) { - char ca = NameA[sizeA - i - 1]; - char cb = NameB[sizeB - i - 1]; - if (ca != cb) - return cb - ca; - } - - return sizeB - sizeA; -} - void ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm, MCAsmLayout &Layout, SectionIndexMapTy &SectionIndexMap, @@ -1457,45 +1414,20 @@ void ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm, WriteSymbolTable(F, Asm, Layout, SectionIndexMap); F = new MCDataFragment(&StrtabSD); - F->getContents().append(StringTable.begin(), StringTable.end()); + F->getContents().append(StrTabBuilder.data().begin(), + StrTabBuilder.data().end()); F = new MCDataFragment(&ShstrtabSD); - std::vector Sections; - for (MCAssembler::const_iterator it = Asm.begin(), - ie = Asm.end(); it != ie; ++it) { + // Section header string table. + for (auto it = Asm.begin(), ie = Asm.end(); it != ie; ++it) { const MCSectionELF &Section = static_cast(it->getSection()); - Sections.push_back(&Section); - } - array_pod_sort(Sections.begin(), Sections.end(), compareBySuffix); - - // Section header string table. - // - // The first entry of a string table holds a null character so skip - // section 0. - uint64_t Index = 1; - F->getContents().push_back('\x00'); - - for (unsigned int I = 0, E = Sections.size(); I != E; ++I) { - const MCSectionELF &Section = *Sections[I]; - - StringRef Name = Section.getSectionName(); - if (I != 0) { - StringRef PreviousName = Sections[I - 1]->getSectionName(); - if (PreviousName.endswith(Name)) { - SectionStringTableIndex[&Section] = Index - Name.size() - 1; - continue; - } - } - // Remember the index into the string table so we can write it - // into the sh_name field of the section header table. - SectionStringTableIndex[&Section] = Index; - - Index += Name.size() + 1; - F->getContents().append(Name.begin(), Name.end()); - F->getContents().push_back('\x00'); + ShStrTabBuilder.add(Section.getSectionName()); } + ShStrTabBuilder.finalize(StringTableBuilder::ELF); + F->getContents().append(ShStrTabBuilder.data().begin(), + ShStrTabBuilder.data().end()); } void ELFObjectWriter::CreateIndexedSections(MCAssembler &Asm, @@ -1504,14 +1436,7 @@ void ELFObjectWriter::CreateIndexedSections(MCAssembler &Asm, RevGroupMapTy &RevGroupMap, SectionIndexMapTy &SectionIndexMap, const RelMapTy &RelMap) { - // Create the .note.GNU-stack section if needed. MCContext &Ctx = Asm.getContext(); - if (Asm.getNoExecStack()) { - const MCSectionELF *GnuStackSection = - Ctx.getELFSection(".note.GNU-stack", ELF::SHT_PROGBITS, 0, - SectionKind::getReadOnly()); - Asm.getOrCreateSectionData(*GnuStackSection); - } // Build the groups for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end(); @@ -1563,7 +1488,7 @@ void ELFObjectWriter::WriteSection(MCAssembler &Asm, switch(Section.getType()) { case ELF::SHT_DYNAMIC: - sh_link = SectionStringTableIndex[&Section]; + sh_link = ShStrTabBuilder.getOffset(Section.getSectionName()); sh_info = 0; break; @@ -1612,6 +1537,7 @@ void ELFObjectWriter::WriteSection(MCAssembler &Asm, 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; @@ -1621,8 +1547,7 @@ void ELFObjectWriter::WriteSection(MCAssembler &Asm, break; default: - assert(0 && "FIXME: sh_type value not supported!"); - break; + llvm_unreachable("FIXME: sh_type value not supported!"); } if (TargetObjectWriter->getEMachine() == ELF::EM_ARM && @@ -1644,7 +1569,8 @@ void ELFObjectWriter::WriteSection(MCAssembler &Asm, } } - WriteSecHdrEntry(SectionStringTableIndex[&Section], Section.getType(), + WriteSecHdrEntry(ShStrTabBuilder.getOffset(Section.getSectionName()), + Section.getType(), Section.getFlags(), 0, Offset, Size, sh_link, sh_info, Alignment, Section.getEntrySize()); }