diff options
Diffstat (limited to 'contrib/llvm/lib/MC')
44 files changed, 2482 insertions, 2491 deletions
diff --git a/contrib/llvm/lib/MC/ConstantPools.cpp b/contrib/llvm/lib/MC/ConstantPools.cpp index a239a8f..a723aa8 100644 --- a/contrib/llvm/lib/MC/ConstantPools.cpp +++ b/contrib/llvm/lib/MC/ConstantPools.cpp @@ -37,7 +37,7 @@ void ConstantPool::emitEntries(MCStreamer &Streamer) { const MCExpr *ConstantPool::addEntry(const MCExpr *Value, MCContext &Context, unsigned Size) { - MCSymbol *CPEntryLabel = Context.CreateTempSymbol(); + MCSymbol *CPEntryLabel = Context.createTempSymbol(); Entries.push_back(ConstantPoolEntry(CPEntryLabel, Value, Size)); return MCSymbolRefExpr::Create(CPEntryLabel, Context); @@ -48,8 +48,7 @@ bool ConstantPool::empty() { return Entries.empty(); } // // AssemblerConstantPools implementation // -ConstantPool * -AssemblerConstantPools::getConstantPool(const MCSection *Section) { +ConstantPool *AssemblerConstantPools::getConstantPool(MCSection *Section) { ConstantPoolMapTy::iterator CP = ConstantPools.find(Section); if (CP == ConstantPools.end()) return nullptr; @@ -58,11 +57,11 @@ AssemblerConstantPools::getConstantPool(const MCSection *Section) { } ConstantPool & -AssemblerConstantPools::getOrCreateConstantPool(const MCSection *Section) { +AssemblerConstantPools::getOrCreateConstantPool(MCSection *Section) { return ConstantPools[Section]; } -static void emitConstantPool(MCStreamer &Streamer, const MCSection *Section, +static void emitConstantPool(MCStreamer &Streamer, MCSection *Section, ConstantPool &CP) { if (!CP.empty()) { Streamer.SwitchSection(Section); @@ -75,7 +74,7 @@ void AssemblerConstantPools::emitAll(MCStreamer &Streamer) { for (ConstantPoolMapTy::iterator CPI = ConstantPools.begin(), CPE = ConstantPools.end(); CPI != CPE; ++CPI) { - const MCSection *Section = CPI->first; + MCSection *Section = CPI->first; ConstantPool &CP = CPI->second; emitConstantPool(Streamer, Section, CP); @@ -83,7 +82,7 @@ void AssemblerConstantPools::emitAll(MCStreamer &Streamer) { } void AssemblerConstantPools::emitForCurrentSection(MCStreamer &Streamer) { - const MCSection *Section = Streamer.getCurrentSection().first; + MCSection *Section = Streamer.getCurrentSection().first; if (ConstantPool *CP = getConstantPool(Section)) { emitConstantPool(Streamer, Section, *CP); } @@ -92,7 +91,7 @@ void AssemblerConstantPools::emitForCurrentSection(MCStreamer &Streamer) { const MCExpr *AssemblerConstantPools::addEntry(MCStreamer &Streamer, const MCExpr *Expr, unsigned Size) { - const MCSection *Section = Streamer.getCurrentSection().first; + MCSection *Section = Streamer.getCurrentSection().first; return getOrCreateConstantPool(Section).addEntry(Expr, Streamer.getContext(), Size); } diff --git a/contrib/llvm/lib/MC/ELFObjectWriter.cpp b/contrib/llvm/lib/MC/ELFObjectWriter.cpp index e2439ab..18746d1 100644 --- a/contrib/llvm/lib/MC/ELFObjectWriter.cpp +++ b/contrib/llvm/lib/MC/ELFObjectWriter.cpp @@ -41,94 +41,53 @@ using namespace llvm; #define DEBUG_TYPE "reloc-info" namespace { -class FragmentWriter { - bool IsLittleEndian; - -public: - FragmentWriter(bool IsLittleEndian); - template <typename T> void write(MCDataFragment &F, T Val); -}; typedef DenseMap<const MCSectionELF *, uint32_t> SectionIndexMapTy; +class ELFObjectWriter; + class SymbolTableWriter { - MCAssembler &Asm; - FragmentWriter &FWriter; + ELFObjectWriter &EWriter; bool Is64Bit; - SectionIndexMapTy &SectionIndexMap; - // The symbol .symtab fragment we are writting to. - MCDataFragment *SymtabF; - - // .symtab_shndx fragment we are writting to. - MCDataFragment *ShndxF; + // indexes we are going to write to .symtab_shndx. + std::vector<uint32_t> ShndxIndexes; // The numbel of symbols written so far. unsigned NumWritten; void createSymtabShndx(); - template <typename T> void write(MCDataFragment &F, T Value); + template <typename T> void write(T Value); public: - SymbolTableWriter(MCAssembler &Asm, FragmentWriter &FWriter, bool Is64Bit, - SectionIndexMapTy &SectionIndexMap, - MCDataFragment *SymtabF); + SymbolTableWriter(ELFObjectWriter &EWriter, bool Is64Bit); void writeSymbol(uint32_t name, uint8_t info, uint64_t value, uint64_t size, uint8_t other, uint32_t shndx, bool Reserved); -}; - -struct ELFRelocationEntry { - uint64_t Offset; // Where is the relocation. - 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), Symbol(Symbol), Type(Type), Addend(Addend) {} + ArrayRef<uint32_t> getShndxIndexes() const { return ShndxIndexes; } }; class ELFObjectWriter : public MCObjectWriter { - FragmentWriter FWriter; - - protected: - 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 MCAsmLayout &Layout, const MCSymbolData &Data, + static uint64_t SymbolValue(const MCSymbol &Sym, const MCAsmLayout &Layout); + static bool isInSymtab(const MCAsmLayout &Layout, const MCSymbol &Symbol, bool Used, bool Renamed); - 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, - const MCSectionData &SD); - static uint64_t GetSectionAddressSize(const MCAsmLayout &Layout, - const MCSectionData &SD); - - void WriteDataSectionData(MCAssembler &Asm, - 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. + static bool isLocal(const MCSymbol &Symbol, bool isUsedInReloc); + + /// Helper struct for containing some precomputed information on symbols. struct ELFSymbolData { - MCSymbolData *SymbolData; + const MCSymbol *Symbol; uint64_t StringIndex; uint32_t SectionIndex; StringRef Name; // Support lexicographic sorting. bool operator<(const ELFSymbolData &RHS) const { - unsigned LHSType = MCELF::GetType(*SymbolData); - unsigned RHSType = MCELF::GetType(*RHS.SymbolData); + unsigned LHSType = MCELF::GetType(Symbol->getData()); + unsigned RHSType = MCELF::GetType(RHS.Symbol->getData()); if (LHSType == ELF::STT_SECTION && RHSType != ELF::STT_SECTION) return false; if (LHSType != ELF::STT_SECTION && RHSType == ELF::STT_SECTION) @@ -146,9 +105,8 @@ class ELFObjectWriter : public MCObjectWriter { SmallPtrSet<const MCSymbol *, 16> WeakrefUsedInReloc; DenseMap<const MCSymbol *, const MCSymbol *> Renames; - llvm::DenseMap<const MCSectionData *, std::vector<ELFRelocationEntry>> - Relocations; - StringTableBuilder ShStrTabBuilder; + llvm::DenseMap<const MCSectionELF *, std::vector<ELFRelocationEntry>> + Relocations; /// @} /// @name Symbol Table Data @@ -170,9 +128,12 @@ class ELFObjectWriter : public MCObjectWriter { unsigned StringTableIndex; // This holds the .symtab section index. unsigned SymbolTableIndex; + // This holds the .symtab_shndx section index. + unsigned SymtabShndxSectionIndex = 0; - unsigned ShstrtabIndex; - + // Sections in the order they are to be output in the section table. + std::vector<const MCSectionELF *> SectionTable; + unsigned addToSectionTable(const MCSectionELF *Sec); // TargetObjectWriter wrappers. bool is64Bit() const { return TargetObjectWriter->is64Bit(); } @@ -185,12 +146,27 @@ class ELFObjectWriter : public MCObjectWriter { } public: - ELFObjectWriter(MCELFObjectTargetWriter *MOTW, raw_ostream &_OS, + ELFObjectWriter(MCELFObjectTargetWriter *MOTW, raw_pwrite_stream &OS, bool IsLittleEndian) - : MCObjectWriter(_OS, IsLittleEndian), FWriter(IsLittleEndian), - TargetObjectWriter(MOTW), NeedsGOT(false) {} + : MCObjectWriter(OS, IsLittleEndian), TargetObjectWriter(MOTW), + NeedsGOT(false) {} + + void reset() override { + UsedInReloc.clear(); + WeakrefUsedInReloc.clear(); + Renames.clear(); + Relocations.clear(); + StrTabBuilder.clear(); + FileSymbolData.clear(); + LocalSymbolData.clear(); + ExternalSymbolData.clear(); + UndefinedSymbolData.clear(); + NeedsGOT = false; + SectionTable.clear(); + MCObjectWriter::reset(); + } - virtual ~ELFObjectWriter(); + ~ELFObjectWriter() override; void WriteWord(uint64_t W) { if (is64Bit()) @@ -199,27 +175,31 @@ class ELFObjectWriter : public MCObjectWriter { Write32(W); } - template <typename T> void write(MCDataFragment &F, T Value) { - FWriter.write(F, Value); + template <typename T> void write(T Val) { + if (IsLittleEndian) + support::endian::Writer<support::little>(OS).write(Val); + else + support::endian::Writer<support::big>(OS).write(Val); } - void WriteHeader(const MCAssembler &Asm, - uint64_t SectionDataSize, - unsigned NumberOfSections); + void writeHeader(const MCAssembler &Asm); void WriteSymbol(SymbolTableWriter &Writer, ELFSymbolData &MSD, const MCAsmLayout &Layout); - void WriteSymbolTable(MCDataFragment *SymtabF, MCAssembler &Asm, - const MCAsmLayout &Layout, - SectionIndexMapTy &SectionIndexMap); + // Start and end offset of each section + typedef std::map<const MCSectionELF *, std::pair<uint64_t, uint64_t>> + SectionOffsetsTy; + + void writeSymbolTable(MCContext &Ctx, const MCAsmLayout &Layout, + SectionOffsetsTy &SectionOffsets); bool shouldRelocateWithSymbol(const MCAssembler &Asm, const MCSymbolRefExpr *RefA, - const MCSymbolData *SD, uint64_t C, + const MCSymbol *Sym, 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; @@ -227,129 +207,74 @@ class ELFObjectWriter : public MCObjectWriter { uint64_t getSymbolIndexInSymbolTable(const MCAssembler &Asm, const MCSymbol *S); - // Map from a group section to the signature symbol - 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; + // Map from a signature symbol to the group section index + typedef DenseMap<const MCSymbol *, unsigned> RevGroupMapTy; /// Compute the symbol table data /// /// \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); + MCSectionELF *createRelocationSection(MCContext &Ctx, + const MCSectionELF &Sec); - void CreateRelocationSections(MCAssembler &Asm, MCAsmLayout &Layout, - RelMapTy &RelMap); - - void CompressDebugSections(MCAssembler &Asm, MCAsmLayout &Layout); - - void WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout, - const RelMapTy &RelMap); - - void CreateMetadataSections(MCAssembler &Asm, MCAsmLayout &Layout, - SectionIndexMapTy &SectionIndexMap, - const RelMapTy &RelMap); - - // 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); + const MCSectionELF *createStringTable(MCContext &Ctx); void ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout) override; - void WriteSectionHeader(MCAssembler &Asm, const GroupMapTy &GroupMap, - const MCAsmLayout &Layout, + void writeSectionHeader(const MCAssembler &Asm, const MCAsmLayout &Layout, const SectionIndexMapTy &SectionIndexMap, - const SectionOffsetMapTy &SectionOffsetMap); + const SectionOffsetsTy &SectionOffsets); - void ComputeSectionOrder(MCAssembler &Asm, - std::vector<const MCSectionELF*> &Sections); + void writeSectionData(const MCAssembler &Asm, MCSection &Sec, + const MCAsmLayout &Layout); void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags, - uint64_t Address, uint64_t Offset, - uint64_t Size, uint32_t Link, uint32_t Info, - uint64_t Alignment, uint64_t EntrySize); + uint64_t Address, uint64_t Offset, uint64_t Size, + uint32_t Link, uint32_t Info, uint64_t Alignment, + uint64_t EntrySize); - void WriteRelocationsFragment(const MCAssembler &Asm, - MCDataFragment *F, - const MCSectionData *SD); + void writeRelocations(const MCAssembler &Asm, const MCSectionELF &Sec); - bool - IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, - const MCSymbolData &DataA, - const MCFragment &FB, - bool InSet, - bool IsPCRel) const override; + bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, + const MCSymbol &SymA, + const MCFragment &FB, + bool InSet, + bool IsPCRel) const override; + + bool isWeak(const MCSymbol &Sym) const override; void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout) override; - void WriteSection(MCAssembler &Asm, - const SectionIndexMapTy &SectionIndexMap, - uint32_t GroupSymbolIndex, - uint64_t Offset, uint64_t Size, uint64_t Alignment, + void writeSection(const SectionIndexMapTy &SectionIndexMap, + uint32_t GroupSymbolIndex, uint64_t Offset, uint64_t Size, const MCSectionELF &Section); }; } -FragmentWriter::FragmentWriter(bool IsLittleEndian) - : IsLittleEndian(IsLittleEndian) {} - -template <typename T> void FragmentWriter::write(MCDataFragment &F, T Val) { - if (IsLittleEndian) - Val = support::endian::byte_swap<T, support::little>(Val); - else - Val = support::endian::byte_swap<T, support::big>(Val); - const char *Start = (const char *)&Val; - F.getContents().append(Start, Start + sizeof(T)); +unsigned ELFObjectWriter::addToSectionTable(const MCSectionELF *Sec) { + SectionTable.push_back(Sec); + StrTabBuilder.add(Sec->getSectionName()); + return SectionTable.size(); } void SymbolTableWriter::createSymtabShndx() { - if (ShndxF) + if (!ShndxIndexes.empty()) return; - MCContext &Ctx = Asm.getContext(); - const MCSectionELF *SymtabShndxSection = - Ctx.getELFSection(".symtab_shndxr", ELF::SHT_SYMTAB_SHNDX, 0, - SectionKind::getReadOnly(), 4, ""); - MCSectionData *SymtabShndxSD = - &Asm.getOrCreateSectionData(*SymtabShndxSection); - SymtabShndxSD->setAlignment(4); - ShndxF = new MCDataFragment(SymtabShndxSD); - unsigned Index = SectionIndexMap.size() + 1; - SectionIndexMap[SymtabShndxSection] = Index; - - for (unsigned I = 0; I < NumWritten; ++I) - write(*ShndxF, uint32_t(0)); + ShndxIndexes.resize(NumWritten); } -template <typename T> -void SymbolTableWriter::write(MCDataFragment &F, T Value) { - FWriter.write(F, Value); +template <typename T> void SymbolTableWriter::write(T Value) { + EWriter.write(Value); } -SymbolTableWriter::SymbolTableWriter(MCAssembler &Asm, FragmentWriter &FWriter, - bool Is64Bit, - SectionIndexMapTy &SectionIndexMap, - MCDataFragment *SymtabF) - : Asm(Asm), FWriter(FWriter), Is64Bit(Is64Bit), - SectionIndexMap(SectionIndexMap), SymtabF(SymtabF), ShndxF(nullptr), - NumWritten(0) {} +SymbolTableWriter::SymbolTableWriter(ELFObjectWriter &EWriter, bool Is64Bit) + : EWriter(EWriter), Is64Bit(Is64Bit), NumWritten(0) {} void SymbolTableWriter::writeSymbol(uint32_t name, uint8_t info, uint64_t value, uint64_t size, uint8_t other, @@ -359,31 +284,29 @@ void SymbolTableWriter::writeSymbol(uint32_t name, uint8_t info, uint64_t value, if (LargeIndex) createSymtabShndx(); - if (ShndxF) { + if (!ShndxIndexes.empty()) { if (LargeIndex) - write(*ShndxF, shndx); + ShndxIndexes.push_back(shndx); else - write(*ShndxF, uint32_t(0)); + ShndxIndexes.push_back(0); } uint16_t Index = LargeIndex ? uint16_t(ELF::SHN_XINDEX) : shndx; - raw_svector_ostream OS(SymtabF->getContents()); - if (Is64Bit) { - write(*SymtabF, name); // st_name - write(*SymtabF, info); // st_info - write(*SymtabF, other); // st_other - write(*SymtabF, Index); // st_shndx - write(*SymtabF, value); // st_value - write(*SymtabF, size); // st_size + write(name); // st_name + write(info); // st_info + write(other); // st_other + write(Index); // st_shndx + write(value); // st_value + write(size); // st_size } else { - write(*SymtabF, name); // st_name - write(*SymtabF, uint32_t(value)); // st_value - write(*SymtabF, uint32_t(size)); // st_size - write(*SymtabF, info); // st_info - write(*SymtabF, other); // st_other - write(*SymtabF, Index); // st_shndx + write(name); // st_name + write(uint32_t(value)); // st_value + write(uint32_t(size)); // st_size + write(info); // st_info + write(other); // st_other + write(Index); // st_shndx } ++NumWritten; @@ -421,9 +344,7 @@ ELFObjectWriter::~ELFObjectWriter() {} // Emit the ELF header. -void ELFObjectWriter::WriteHeader(const MCAssembler &Asm, - uint64_t SectionDataSize, - unsigned NumberOfSections) { +void ELFObjectWriter::writeHeader(const MCAssembler &Asm) { // ELF Header // ---------- // @@ -432,10 +353,7 @@ void ELFObjectWriter::WriteHeader(const MCAssembler &Asm, // emitWord method behaves differently for ELF32 and ELF64, writing // 4 bytes in the former and 8 in the latter. - Write8(0x7f); // e_ident[EI_MAG0] - Write8('E'); // e_ident[EI_MAG1] - Write8('L'); // e_ident[EI_MAG2] - Write8('F'); // e_ident[EI_MAG3] + WriteBytes(ELF::ElfMagic); // e_ident[EI_MAG0] to e_ident[EI_MAG3] Write8(is64Bit() ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS] @@ -456,8 +374,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(0); // e_shoff = sec hdr table off in bytes // e_flags = whatever the target wants Write32(Asm.getELFHeaderEFlags()); @@ -472,28 +389,24 @@ void ELFObjectWriter::WriteHeader(const MCAssembler &Asm, Write16(is64Bit() ? sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr)); // e_shnum = # of section header ents - if (NumberOfSections >= ELF::SHN_LORESERVE) - Write16(ELF::SHN_UNDEF); - else - Write16(NumberOfSections); + Write16(0); // e_shstrndx = Section # of '.shstrtab' - if (ShstrtabIndex >= ELF::SHN_LORESERVE) - Write16(ELF::SHN_XINDEX); - else - Write16(ShstrtabIndex); + assert(StringTableIndex < ELF::SHN_LORESERVE); + Write16(StringTableIndex); } -uint64_t ELFObjectWriter::SymbolValue(MCSymbolData &Data, +uint64_t ELFObjectWriter::SymbolValue(const MCSymbol &Sym, const MCAsmLayout &Layout) { + MCSymbolData &Data = Sym.getData(); if (Data.isCommon() && Data.isExternal()) return Data.getCommonAlignment(); uint64_t Res; - if (!Layout.getSymbolOffset(&Data, Res)) + if (!Layout.getSymbolOffset(Sym, Res)) return 0; - if (Layout.getAssembler().isThumbFunc(&Data.getSymbol())) + if (Layout.getAssembler().isThumbFunc(&Sym)) Res |= 1; return Res; @@ -504,8 +417,8 @@ void ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, // The presence of symbol versions causes undefined symbols and // versions declared with @@@ to be renamed. - for (MCSymbolData &OriginalData : Asm.symbols()) { - const MCSymbol &Alias = OriginalData.getSymbol(); + for (const MCSymbol &Alias : Asm.symbols()) { + MCSymbolData &OriginalData = Alias.getData(); // Not an alias. if (!Alias.isVariable()) @@ -576,12 +489,11 @@ static uint8_t mergeTypeForSet(uint8_t origType, uint8_t newType) { void ELFObjectWriter::WriteSymbol(SymbolTableWriter &Writer, ELFSymbolData &MSD, const MCAsmLayout &Layout) { - MCSymbolData &OrigData = *MSD.SymbolData; + MCSymbolData &OrigData = MSD.Symbol->getData(); assert((!OrigData.getFragment() || - (&OrigData.getFragment()->getParent()->getSection() == - &OrigData.getSymbol().getSection())) && + (OrigData.getFragment()->getParent() == &MSD.Symbol->getSection())) && "The symbol's section doesn't match the fragment's symbol"); - const MCSymbol *Base = Layout.getBaseSymbol(OrigData.getSymbol()); + const MCSymbol *Base = Layout.getBaseSymbol(*MSD.Symbol); // This has to be in sync with when computeSymbolTable uses SHN_ABS or // SHN_COMMON. @@ -603,7 +515,7 @@ void ELFObjectWriter::WriteSymbol(SymbolTableWriter &Writer, ELFSymbolData &MSD, uint8_t Other = MCELF::getOther(OrigData) << (ELF_STO_Shift - ELF_STV_Shift); Other |= Visibility; - uint64_t Value = SymbolValue(OrigData, Layout); + uint64_t Value = SymbolValue(*MSD.Symbol, Layout); uint64_t Size = 0; const MCExpr *ESize = OrigData.getSize(); @@ -612,7 +524,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; } @@ -622,16 +534,21 @@ void ELFObjectWriter::WriteSymbol(SymbolTableWriter &Writer, ELFSymbolData &MSD, MSD.SectionIndex, IsReserved); } -void ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF, - MCAssembler &Asm, +void ELFObjectWriter::writeSymbolTable(MCContext &Ctx, const MCAsmLayout &Layout, - SectionIndexMapTy &SectionIndexMap) { + 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. - // FIXME: Make sure the start of the symbol table is aligned. + SymbolTableWriter Writer(*this, is64Bit()); - SymbolTableWriter Writer(Asm, FWriter, is64Bit(), SectionIndexMap, SymtabF); + 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); @@ -651,7 +568,7 @@ void ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF, for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) { ELFSymbolData &MSD = ExternalSymbolData[i]; - MCSymbolData &Data = *MSD.SymbolData; + 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"); @@ -662,11 +579,29 @@ void ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF, for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) { ELFSymbolData &MSD = UndefinedSymbolData[i]; - MCSymbolData &Data = *MSD.SymbolData; + 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<uint32_t> 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 @@ -674,9 +609,10 @@ void ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF, // allows us to omit some local symbols from the symbol table. bool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm, const MCSymbolRefExpr *RefA, - const MCSymbolData *SD, - uint64_t C, + const MCSymbol *Sym, uint64_t C, unsigned Type) const { + MCSymbolData *SD = Sym ? &Sym->getData() : nullptr; + // A PCRel relocation to an absolute value has no symbol (or section). We // represent that with a relocation to a null section. if (!RefA) @@ -711,8 +647,8 @@ bool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm, // An undefined symbol is not in any section, so the relocation has to point // to the symbol itself. - const MCSymbol &Sym = SD->getSymbol(); - if (Sym.isUndefined()) + assert(Sym && "Expected a symbol"); + if (Sym->isUndefined()) return true; unsigned Binding = MCELF::GetBinding(*SD); @@ -739,7 +675,7 @@ bool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm, // If we change such a relocation to use the section, the linker would think // that it pointed to another string and subtracting 42 at runtime will // produce the wrong value. - auto &Sec = cast<MCSectionELF>(Sym.getSection()); + auto &Sec = cast<MCSectionELF>(Sym->getSection()); unsigned Flags = Sec.getFlags(); if (Flags & ELF::SHF_MERGE) { if (C != 0) @@ -762,7 +698,7 @@ bool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm, // 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 (Asm.isThumbFunc(&Sym)) + if (Asm.isThumbFunc(Sym)) return true; if (TargetObjectWriter->needsRelocateWithSymbol(*SD, Type)) @@ -789,14 +725,32 @@ static const MCSymbol *getWeakRef(const MCSymbolRefExpr &Ref) { return nullptr; } -void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, +// True if the assembler knows nothing about the final value of the symbol. +// This doesn't cover the comdat issues, since in those cases the assembler +// can at least know that all symbols in the section will move together. +static bool isWeak(const MCSymbolData &D) { + if (MCELF::GetType(D) == ELF::STT_GNU_IFUNC) + return true; + + switch (MCELF::GetBinding(D)) { + default: + llvm_unreachable("Unknown binding"); + case ELF::STB_LOCAL: + return false; + case ELF::STB_GLOBAL: + return false; + case ELF::STB_WEAK: + case ELF::STB_GNU_UNIQUE: + return true; + } +} + +void ELFObjectWriter::RecordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, - const MCFixup &Fixup, - MCValue Target, - bool &IsPCRel, - uint64_t &FixedValue) { - const MCSectionData *FixupSection = Fragment->getParent(); + const MCFixup &Fixup, MCValue Target, + bool &IsPCRel, uint64_t &FixedValue) { + const MCSectionELF &FixupSection = cast<MCSectionELF>(*Fragment->getParent()); uint64_t C = Target.getConstant(); uint64_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); @@ -812,26 +766,29 @@ void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, // or (A + C - R). If B = R + K and the relocation is not pcrel, we can // replace B to implement it: (A - R - K + C) if (IsPCRel) - Asm.getContext().FatalError( + Asm.getContext().reportFatalError( Fixup.getLoc(), "No relocation available to represent this relative expression"); const MCSymbol &SymB = RefB->getSymbol(); if (SymB.isUndefined()) - Asm.getContext().FatalError( + Asm.getContext().reportFatalError( Fixup.getLoc(), Twine("symbol '") + SymB.getName() + "' can not be undefined in a subtraction expression"); assert(!SymB.isAbsolute() && "Should have been folded"); const MCSection &SecB = SymB.getSection(); - if (&SecB != &FixupSection->getSection()) - Asm.getContext().FatalError( + if (&SecB != &FixupSection) + Asm.getContext().reportFatalError( Fixup.getLoc(), "Cannot represent a difference across sections"); - const MCSymbolData &SymBD = Asm.getSymbolData(SymB); - uint64_t SymBOffset = Layout.getSymbolOffset(&SymBD); + if (::isWeak(SymB.getData())) + Asm.getContext().reportFatalError( + Fixup.getLoc(), "Cannot represent a subtraction with a weak symbol"); + + uint64_t SymBOffset = Layout.getSymbolOffset(SymB); uint64_t K = SymBOffset - FixupOffset; IsPCRel = true; C -= K; @@ -840,12 +797,11 @@ void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, // We either rejected the fixup or folded B into C at this point. const MCSymbolRefExpr *RefA = Target.getSymA(); const MCSymbol *SymA = RefA ? &RefA->getSymbol() : nullptr; - const MCSymbolData *SymAD = SymA ? &Asm.getSymbolData(*SymA) : nullptr; unsigned Type = GetRelocType(Target, Fixup, IsPCRel); - bool RelocateWithSymbol = shouldRelocateWithSymbol(Asm, RefA, SymAD, C, Type); + bool RelocateWithSymbol = shouldRelocateWithSymbol(Asm, RefA, SymA, C, Type); if (!RelocateWithSymbol && SymA && !SymA->isUndefined()) - C += Layout.getSymbolOffset(SymAD); + C += Layout.getSymbolOffset(*SymA); uint64_t Addend = 0; if (hasRelocationAddend()) { @@ -869,7 +825,7 @@ void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, ELFSec ? Asm.getContext().getOrCreateSectionSymbol(*ELFSec) : nullptr; ELFRelocationEntry Rec(FixupOffset, SectionSymbol, Type, Addend); - Relocations[FixupSection].push_back(Rec); + Relocations[&FixupSection].push_back(Rec); return; } @@ -883,7 +839,7 @@ void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, UsedInReloc.insert(SymA); } ELFRelocationEntry Rec(FixupOffset, SymA, Type, Addend); - Relocations[FixupSection].push_back(Rec); + Relocations[&FixupSection].push_back(Rec); return; } @@ -891,14 +847,14 @@ void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, 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, - const MCSymbolData &Data, bool Used, + const MCSymbol &Symbol, bool Used, bool Renamed) { - const MCSymbol &Symbol = Data.getSymbol(); + const MCSymbolData &Data = Symbol.getData(); if (Symbol.isVariable()) { const MCExpr *Expr = Symbol.getVariableValue(); if (const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(Expr)) { @@ -932,11 +888,11 @@ bool ELFObjectWriter::isInSymtab(const MCAsmLayout &Layout, return true; } -bool ELFObjectWriter::isLocal(const MCSymbolData &Data, bool isUsedInReloc) { +bool ELFObjectWriter::isLocal(const MCSymbol &Symbol, bool isUsedInReloc) { + const MCSymbolData &Data = Symbol.getData(); if (Data.isExternal()) return false; - const MCSymbol &Symbol = Data.getSymbol(); if (Symbol.isDefined()) return true; @@ -946,69 +902,48 @@ bool ELFObjectWriter::isLocal(const MCSymbolData &Data, bool isUsedInReloc) { return true; } -void ELFObjectWriter::ComputeIndexMap(MCAssembler &Asm, - SectionIndexMapTy &SectionIndexMap, - const RelMapTy &RelMap) { - unsigned Index = 1; - for (MCAssembler::iterator it = Asm.begin(), - ie = Asm.end(); it != ie; ++it) { - const MCSectionELF &Section = - static_cast<const MCSectionELF &>(it->getSection()); - if (Section.getType() != ELF::SHT_GROUP) - continue; - SectionIndexMap[&Section] = Index++; - } - - for (MCAssembler::iterator it = Asm.begin(), - ie = Asm.end(); it != ie; ++it) { - const MCSectionELF &Section = - static_cast<const MCSectionELF &>(it->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) - SectionIndexMap[RelSection] = Index++; - } -} +void ELFObjectWriter::computeSymbolTable( + 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); -void -ELFObjectWriter::computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout, - const SectionIndexMapTy &SectionIndexMap, - 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? if (NeedsGOT) { StringRef Name = "_GLOBAL_OFFSET_TABLE_"; - MCSymbol *Sym = Asm.getContext().GetOrCreateSymbol(Name); + MCSymbol *Sym = Asm.getContext().getOrCreateSymbol(Name); MCSymbolData &Data = Asm.getOrCreateSymbolData(*Sym); Data.setExternal(true); MCELF::SetBinding(Data, ELF::STB_GLOBAL); } // Add the data for the symbols. - for (MCSymbolData &SD : Asm.symbols()) { - const MCSymbol &Symbol = SD.getSymbol(); + bool HasLargeSectionIndex = false; + for (const MCSymbol &Symbol : Asm.symbols()) { + MCSymbolData &SD = Symbol.getData(); bool Used = UsedInReloc.count(&Symbol); bool WeakrefUsed = WeakrefUsedInReloc.count(&Symbol); bool isSignature = RevGroupMap.count(&Symbol); - if (!isInSymtab(Layout, SD, - Used || WeakrefUsed || isSignature, + if (!isInSymtab(Layout, Symbol, Used || WeakrefUsed || isSignature, Renames.count(&Symbol))) continue; ELFSymbolData MSD; - MSD.SymbolData = &SD; + MSD.Symbol = &Symbol; 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(SD, Used); + bool Local = isLocal(Symbol, Used); if (!Local && MCELF::GetBinding(SD) == ELF::STB_LOCAL) { assert(BaseSymbol); MCSymbolData &BaseData = Asm.getSymbolData(*BaseSymbol); @@ -1022,10 +957,13 @@ ELFObjectWriter::computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout, assert(!Local); MSD.SectionIndex = ELF::SHN_COMMON; } else if (BaseSymbol->isUndefined()) { - if (isSignature && !Used) - MSD.SectionIndex = SectionIndexMap.lookup(RevGroupMap.lookup(&Symbol)); - else + if (isSignature && !Used) { + MSD.SectionIndex = RevGroupMap.lookup(&Symbol); + if (MSD.SectionIndex >= ELF::SHN_LORESERVE) + HasLargeSectionIndex = true; + } else { MSD.SectionIndex = ELF::SHN_UNDEF; + } if (!Used && WeakrefUsed) MCELF::SetBinding(SD, ELF::STB_WEAK); } else { @@ -1033,18 +971,47 @@ ELFObjectWriter::computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout, 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 - // @@ 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 @@ -1059,6 +1026,13 @@ ELFObjectWriter::computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout, 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); @@ -1068,7 +1042,7 @@ ELFObjectWriter::computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout, FileSymbolData.push_back(StrTabBuilder.getOffset(*i)); for (ELFSymbolData &MSD : LocalSymbolData) - MSD.StringIndex = MCELF::GetType(*MSD.SymbolData) == ELF::STT_SECTION + MSD.StringIndex = MCELF::GetType(MSD.Symbol->getData()) == ELF::STT_SECTION ? 0 : StrTabBuilder.getOffset(MSD.Name); for (ELFSymbolData &MSD : ExternalSymbolData) @@ -1085,57 +1059,44 @@ ELFObjectWriter::computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout, // symbols with non-local bindings. unsigned Index = FileSymbolData.size() + 1; for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) - LocalSymbolData[i].SymbolData->setIndex(Index++); + LocalSymbolData[i].Symbol->setIndex(Index++); for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) - ExternalSymbolData[i].SymbolData->setIndex(Index++); + ExternalSymbolData[i].Symbol->setIndex(Index++); for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) - UndefinedSymbolData[i].SymbolData->setIndex(Index++); + UndefinedSymbolData[i].Symbol->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; - - MCContext &Ctx = Asm.getContext(); - const MCSectionELF &Section = - static_cast<const MCSectionELF&>(SD.getSection()); +MCSectionELF * +ELFObjectWriter::createRelocationSection(MCContext &Ctx, + const MCSectionELF &Sec) { + if (Relocations[&Sec].empty()) + return nullptr; - const StringRef SectionName = Section.getSectionName(); - std::string RelaSectionName = hasRelocationAddend() ? ".rela" : ".rel"; - RelaSectionName += SectionName; + const StringRef SectionName = Sec.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 (Sec.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); - } + MCSectionELF *RelaSection = Ctx.createELFRelSection( + RelaSectionName, hasRelocationAddend() ? ELF::SHT_RELA : ELF::SHT_REL, + Flags, EntrySize, Sec.getGroup(), &Sec); + RelaSection->setAlignment(is64Bit() ? 8 : 4); + return RelaSection; } static SmallVector<char, 128> -getUncompressedData(MCAsmLayout &Layout, - MCSectionData::FragmentListType &Fragments) { +getUncompressedData(const MCAsmLayout &Layout, + const MCSection::FragmentListType &Fragments) { SmallVector<char, 128> UncompressedData; for (const MCFragment &F : Fragments) { const SmallVectorImpl<char> *Contents; @@ -1164,7 +1125,7 @@ getUncompressedData(MCAsmLayout &Layout, 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) @@ -1178,123 +1139,41 @@ prependCompressionHeader(uint64_t Size, return true; } -// Return a single fragment containing the compressed contents of the whole -// section. Null if the section was not compressed for any reason. -static std::unique_ptr<MCDataFragment> -getCompressedFragment(MCAsmLayout &Layout, - MCSectionData::FragmentListType &Fragments) { - std::unique_ptr<MCDataFragment> CompressedFragment(new MCDataFragment()); +void ELFObjectWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec, + const MCAsmLayout &Layout) { + MCSectionELF &Section = static_cast<MCSectionELF &>(Sec); + StringRef SectionName = Section.getSectionName(); + + // Compressing debug_frame requires handling alignment fragments which is + // more work (possibly generalizing MCAssembler.cpp:writeFragment to allow + // for writing to arbitrary buffers) for little benefit. + if (!Asm.getContext().getAsmInfo()->compressDebugSections() || + !SectionName.startswith(".debug_") || SectionName == ".debug_frame") { + Asm.writeSectionData(&Section, Layout); + return; + } - // Gather the uncompressed data from all the fragments, recording the - // alignment fragment, if seen, and any fixups. + // Gather the uncompressed data from all the fragments. + const MCSection::FragmentListType &Fragments = Section.getFragmentList(); SmallVector<char, 128> UncompressedData = getUncompressedData(Layout, Fragments); - SmallVectorImpl<char> &CompressedContents = CompressedFragment->getContents(); - + SmallVector<char, 128> CompressedContents; zlib::Status Success = zlib::compress( StringRef(UncompressedData.data(), UncompressedData.size()), CompressedContents); - if (Success != zlib::StatusOK) - return nullptr; - - if (!prependCompressionHeader(UncompressedData.size(), CompressedContents)) - return nullptr; - - return CompressedFragment; -} - -typedef DenseMap<const MCSectionData *, std::vector<MCSymbolData *>> -DefiningSymbolMap; - -static void UpdateSymbols(const MCAsmLayout &Layout, - const std::vector<MCSymbolData *> &Symbols, - MCFragment &NewFragment) { - for (MCSymbolData *Sym : Symbols) { - Sym->setOffset(Sym->getOffset() + - Layout.getFragmentOffset(Sym->getFragment())); - Sym->setFragment(&NewFragment); + if (Success != zlib::StatusOK) { + Asm.writeSectionData(&Section, Layout); + return; } -} - -static void CompressDebugSection(MCAssembler &Asm, MCAsmLayout &Layout, - const DefiningSymbolMap &DefiningSymbols, - const MCSectionELF &Section, - MCSectionData &SD) { - StringRef SectionName = Section.getSectionName(); - MCSectionData::FragmentListType &Fragments = SD.getFragmentList(); - - std::unique_ptr<MCDataFragment> CompressedFragment = - getCompressedFragment(Layout, Fragments); - // Leave the section as-is if the fragments could not be compressed. - if (!CompressedFragment) + if (!prependCompressionHeader(UncompressedData.size(), CompressedContents)) { + Asm.writeSectionData(&Section, Layout); 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()); - Fragments.clear(); - - // Complete the initialization of the new fragment - CompressedFragment->setParent(&SD); - CompressedFragment->setLayoutOrder(0); - Fragments.push_back(CompressedFragment.release()); - - // Rename from .debug_* to .zdebug_* + } Asm.getContext().renameELFSection(&Section, (".z" + SectionName.drop_front(1)).str()); -} - -void ELFObjectWriter::CompressDebugSections(MCAssembler &Asm, - MCAsmLayout &Layout) { - 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<const MCSectionELF &>(SD.getSection()); - StringRef SectionName = Section.getSectionName(); - - // Compressing debug_frame requires handling alignment fragments which is - // more work (possibly generalizing MCAssembler.cpp:writeFragment to allow - // for writing to arbitrary buffers) for little benefit. - if (!SectionName.startswith(".debug_") || SectionName == ".debug_frame") - continue; - - CompressDebugSection(Asm, Layout, DefiningSymbols, Section, SD); - } -} - -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()); - - const MCSectionELF *RelaSection = RelMap.lookup(&Section); - if (!RelaSection) - continue; - MCSectionData &RelaSD = Asm.getOrCreateSectionData(*RelaSection); - RelaSD.setAlignment(is64Bit() ? 8 : 4); - - MCDataFragment *F = new MCDataFragment(&RelaSD); - WriteRelocationsFragment(Asm, F, &*it); - } + OS << CompressedContents; } void ELFObjectWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type, @@ -1315,30 +1194,13 @@ void ELFObjectWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type, WriteWord(EntrySize); // sh_entsize } -// ELF doesn't require relocations to be in any order. We sort by the r_offset, -// just to match gnu as for easier comparison. The use type is an arbitrary way -// of making the sort deterministic. -static int cmpRel(const ELFRelocationEntry *AP, const ELFRelocationEntry *BP) { - const ELFRelocationEntry &A = *AP; - const ELFRelocationEntry &B = *BP; - if (A.Offset != B.Offset) - return B.Offset - A.Offset; - if (B.Type != A.Type) - return A.Type - B.Type; - llvm_unreachable("ELFRelocs might be unstable!"); -} - -static void sortRelocs(const MCAssembler &Asm, - std::vector<ELFRelocationEntry> &Relocs) { - array_pod_sort(Relocs.begin(), Relocs.end(), cmpRel); -} +void ELFObjectWriter::writeRelocations(const MCAssembler &Asm, + const MCSectionELF &Sec) { + std::vector<ELFRelocationEntry> &Relocs = Relocations[&Sec]; -void ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm, - MCDataFragment *F, - const MCSectionData *SD) { - std::vector<ELFRelocationEntry> &Relocs = Relocations[SD]; - - sortRelocs(Asm, Relocs); + // Sort the relocation entries. Most targets just sort by Offset, but some + // (e.g., MIPS) have additional constraints. + TargetObjectWriter->sortRelocs(Asm, Relocs); for (unsigned i = 0, e = Relocs.size(); i != e; ++i) { const ELFRelocationEntry &Entry = Relocs[e - i - 1]; @@ -1346,171 +1208,59 @@ void ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm, Entry.Symbol ? getSymbolIndexInSymbolTable(Asm, Entry.Symbol) : 0; if (is64Bit()) { - write(*F, Entry.Offset); + write(Entry.Offset); if (TargetObjectWriter->isN64()) { - write(*F, uint32_t(Index)); + write(uint32_t(Index)); - write(*F, TargetObjectWriter->getRSsym(Entry.Type)); - write(*F, TargetObjectWriter->getRType3(Entry.Type)); - write(*F, TargetObjectWriter->getRType2(Entry.Type)); - write(*F, TargetObjectWriter->getRType(Entry.Type)); + write(TargetObjectWriter->getRSsym(Entry.Type)); + write(TargetObjectWriter->getRType3(Entry.Type)); + write(TargetObjectWriter->getRType2(Entry.Type)); + write(TargetObjectWriter->getRType(Entry.Type)); } else { struct ELF::Elf64_Rela ERE64; ERE64.setSymbolAndType(Index, Entry.Type); - write(*F, ERE64.r_info); + write(ERE64.r_info); } if (hasRelocationAddend()) - write(*F, Entry.Addend); + write(Entry.Addend); } else { - write(*F, uint32_t(Entry.Offset)); + write(uint32_t(Entry.Offset)); struct ELF::Elf32_Rela ERE32; ERE32.setSymbolAndType(Index, Entry.Type); - write(*F, ERE32.r_info); + write(ERE32.r_info); if (hasRelocationAddend()) - write(*F, uint32_t(Entry.Addend)); + write(uint32_t(Entry.Addend)); } } } -void ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm, - MCAsmLayout &Layout, - SectionIndexMapTy &SectionIndexMap, - const RelMapTy &RelMap) { - MCContext &Ctx = Asm.getContext(); - MCDataFragment *F; - - unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32; - - // 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()); - MCSectionData &ShstrtabSD = Asm.getOrCreateSectionData(*ShstrtabSection); - ShstrtabSD.setAlignment(1); - - const MCSectionELF *SymtabSection = - Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, - SectionKind::getReadOnly(), - EntrySize, ""); - MCSectionData &SymtabSD = Asm.getOrCreateSectionData(*SymtabSection); - SymtabSD.setAlignment(is64Bit() ? 8 : 4); - - const MCSectionELF *StrtabSection; - StrtabSection = Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0, - SectionKind::getReadOnly()); - MCSectionData &StrtabSD = Asm.getOrCreateSectionData(*StrtabSection); - StrtabSD.setAlignment(1); - - ComputeIndexMap(Asm, SectionIndexMap, RelMap); - - ShstrtabIndex = SectionIndexMap.lookup(ShstrtabSection); - SymbolTableIndex = SectionIndexMap.lookup(SymtabSection); - StringTableIndex = SectionIndexMap.lookup(StrtabSection); - - // Symbol table - F = new MCDataFragment(&SymtabSD); - WriteSymbolTable(F, Asm, Layout, SectionIndexMap); - - F = new MCDataFragment(&StrtabSD); - F->getContents().append(StrTabBuilder.data().begin(), - StrTabBuilder.data().end()); - - F = new MCDataFragment(&ShstrtabSD); - - // Section header string table. - for (auto it = Asm.begin(), ie = Asm.end(); it != ie; ++it) { - const MCSectionELF &Section = - static_cast<const MCSectionELF&>(it->getSection()); - ShStrTabBuilder.add(Section.getSectionName()); - } - ShStrTabBuilder.finalize(StringTableBuilder::ELF); - F->getContents().append(ShStrTabBuilder.data().begin(), - ShStrTabBuilder.data().end()); -} - -void ELFObjectWriter::CreateIndexedSections(MCAssembler &Asm, - MCAsmLayout &Layout, - GroupMapTy &GroupMap, - RevGroupMapTy &RevGroupMap, - SectionIndexMapTy &SectionIndexMap, - const RelMapTy &RelMap) { - MCContext &Ctx = Asm.getContext(); - - // Build the groups - for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end(); - it != ie; ++it) { - const MCSectionELF &Section = - static_cast<const MCSectionELF&>(it->getSection()); - if (!(Section.getFlags() & ELF::SHF_GROUP)) - continue; - - const MCSymbol *SignatureSymbol = Section.getGroup(); - Asm.getOrCreateSymbolData(*SignatureSymbol); - const MCSectionELF *&Group = RevGroupMap[SignatureSymbol]; - if (!Group) { - Group = Ctx.CreateELFGroupSection(); - MCSectionData &Data = Asm.getOrCreateSectionData(*Group); - Data.setAlignment(4); - MCDataFragment *F = new MCDataFragment(&Data); - write(*F, uint32_t(ELF::GRP_COMDAT)); - } - GroupMap[Group] = SignatureSymbol; - } - - ComputeIndexMap(Asm, SectionIndexMap, RelMap); - - // Add sections to the groups - for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end(); - it != ie; ++it) { - const MCSectionELF &Section = - static_cast<const MCSectionELF&>(it->getSection()); - if (!(Section.getFlags() & ELF::SHF_GROUP)) - continue; - const MCSectionELF *Group = RevGroupMap[Section.getGroup()]; - MCSectionData &Data = Asm.getOrCreateSectionData(*Group); - // FIXME: we could use the previous fragment - MCDataFragment *F = new MCDataFragment(&Data); - uint32_t Index = SectionIndexMap.lookup(&Section); - write(*F, Index); - } +const MCSectionELF *ELFObjectWriter::createStringTable(MCContext &Ctx) { + 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, - uint64_t Alignment, - 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; switch(Section.getType()) { - case ELF::SHT_DYNAMIC: - sh_link = ShStrTabBuilder.getOffset(Section.getSectionName()); - sh_info = 0; + default: + // Nothing to do. break; + case ELF::SHT_DYNAMIC: + llvm_unreachable("SHT_DYNAMIC in a relocatable object"); + 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,286 +1275,225 @@ 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(), - Section.getFlags(), 0, Offset, Size, sh_link, sh_info, - Alignment, Section.getEntrySize()); + WriteSecHdrEntry(StrTabBuilder.getOffset(Section.getSectionName()), + Section.getType(), Section.getFlags(), 0, Offset, Size, + sh_link, sh_info, Section.getAlignment(), + Section.getEntrySize()); } -bool ELFObjectWriter::IsELFMetaDataSection(const MCSectionData &SD) { - return SD.getOrdinal() == ~UINT32_C(0) && - !SD.getSection().isVirtualSection(); -} - -uint64_t ELFObjectWriter::DataSectionSize(const MCSectionData &SD) { - uint64_t Ret = 0; - for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e; - ++i) { - const MCFragment &F = *i; - assert(F.getKind() == MCFragment::FT_Data); - Ret += cast<MCDataFragment>(F).getContents().size(); - } - return Ret; -} - -uint64_t ELFObjectWriter::GetSectionFileSize(const MCAsmLayout &Layout, - const MCSectionData &SD) { - if (IsELFMetaDataSection(SD)) - return DataSectionSize(SD); - return Layout.getSectionFileSize(&SD); -} - -uint64_t ELFObjectWriter::GetSectionAddressSize(const MCAsmLayout &Layout, - const MCSectionData &SD) { - if (IsELFMetaDataSection(SD)) - return DataSectionSize(SD); - return Layout.getSectionAddressSize(&SD); -} - -void ELFObjectWriter::WriteDataSectionData(MCAssembler &Asm, - const MCAsmLayout &Layout, - const MCSectionELF &Section) { - const MCSectionData &SD = Asm.getOrCreateSectionData(Section); - - uint64_t Padding = OffsetToAlignment(OS.tell(), SD.getAlignment()); - WriteZeros(Padding); - - if (IsELFMetaDataSection(SD)) { - for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e; - ++i) { - const MCFragment &F = *i; - assert(F.getKind() == MCFragment::FT_Data); - WriteBytes(cast<MCDataFragment>(F).getContents()); - } - } else { - Asm.writeSectionData(&SD, Layout); - } -} - -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; - Sections.resize(NumSections - 1); - - for (SectionIndexMapTy::const_iterator i= - SectionIndexMap.begin(), e = SectionIndexMap.end(); i != e; ++i) { - const std::pair<const MCSectionELF*, uint32_t> &p = *i; - Sections[p.second - 1] = p.first; - } +void ELFObjectWriter::writeSectionHeader( + const MCAssembler &Asm, const MCAsmLayout &Layout, + const SectionIndexMapTy &SectionIndexMap, + const SectionOffsetsTy &SectionOffsets) { + const unsigned NumSections = SectionTable.size(); // Null section first. uint64_t FirstSectionSize = - NumSections >= ELF::SHN_LORESERVE ? NumSections : 0; - uint32_t FirstSectionLink = - ShstrtabIndex >= ELF::SHN_LORESERVE ? ShstrtabIndex : 0; - WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, FirstSectionLink, 0, 0, 0); - - for (unsigned i = 0; i < NumSections - 1; ++i) { - const MCSectionELF &Section = *Sections[i]; - const MCSectionData &SD = Asm.getOrCreateSectionData(Section); + (NumSections + 1) >= ELF::SHN_LORESERVE ? NumSections + 1 : 0; + WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, 0, 0, 0, 0); + + for (const MCSectionELF *Section : SectionTable) { uint32_t GroupSymbolIndex; - if (Section.getType() != ELF::SHT_GROUP) + unsigned Type = Section->getType(); + if (Type != ELF::SHT_GROUP) GroupSymbolIndex = 0; else - GroupSymbolIndex = getSymbolIndexInSymbolTable(Asm, - GroupMap.lookup(&Section)); + GroupSymbolIndex = getSymbolIndexInSymbolTable(Asm, Section->getGroup()); - uint64_t Size = GetSectionAddressSize(Layout, SD); - - WriteSection(Asm, SectionIndexMap, GroupSymbolIndex, - SectionOffsetMap.lookup(&Section), Size, - SD.getAlignment(), Section); - } -} - -void ELFObjectWriter::ComputeSectionOrder(MCAssembler &Asm, - std::vector<const MCSectionELF*> &Sections) { - for (MCAssembler::iterator it = Asm.begin(), - ie = Asm.end(); it != ie; ++it) { - const MCSectionELF &Section = - static_cast<const MCSectionELF &>(it->getSection()); - if (Section.getType() == ELF::SHT_GROUP) - Sections.push_back(&Section); - } - - for (MCAssembler::iterator it = Asm.begin(), - ie = Asm.end(); it != ie; ++it) { - const MCSectionELF &Section = - static_cast<const MCSectionELF &>(it->getSection()); - if (Section.getType() != ELF::SHT_GROUP && - Section.getType() != ELF::SHT_REL && - Section.getType() != ELF::SHT_RELA) - Sections.push_back(&Section); - } + const std::pair<uint64_t, uint64_t> &Offsets = + SectionOffsets.find(Section)->second; + uint64_t Size; + if (Type == ELF::SHT_NOBITS) + Size = Layout.getSectionAddressSize(Section); + else + Size = Offsets.second - Offsets.first; - for (MCAssembler::iterator it = Asm.begin(), - ie = Asm.end(); it != ie; ++it) { - const MCSectionELF &Section = - static_cast<const MCSectionELF &>(it->getSection()); - if (Section.getType() == ELF::SHT_REL || - Section.getType() == ELF::SHT_RELA) - Sections.push_back(&Section); + writeSection(SectionIndexMap, GroupSymbolIndex, Offsets.first, Size, + *Section); } } void ELFObjectWriter::WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout) { - GroupMapTy GroupMap; + MCContext &Ctx = Asm.getContext(); + MCSectionELF *StrtabSection = + Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0); + StringTableIndex = addToSectionTable(StrtabSection); + RevGroupMapTy RevGroupMap; SectionIndexMapTy SectionIndexMap; - unsigned NumUserSections = Asm.size(); + std::map<const MCSymbol *, std::vector<const MCSectionELF *>> GroupMembers; - CompressDebugSections(Asm, const_cast<MCAsmLayout &>(Layout)); + // Write out the ELF header ... + writeHeader(Asm); - DenseMap<const MCSectionELF*, const MCSectionELF*> RelMap; - CreateRelocationSections(Asm, const_cast<MCAsmLayout&>(Layout), RelMap); + // ... then the sections ... + SectionOffsetsTy SectionOffsets; + std::vector<MCSectionELF *> Groups; + std::vector<MCSectionELF *> Relocations; + for (MCSection &Sec : Asm) { + MCSectionELF &Section = static_cast<MCSectionELF &>(Sec); - 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; + uint64_t Padding = OffsetToAlignment(OS.tell(), Section.getAlignment()); + WriteZeros(Padding); - unsigned NumRegularSections = NumUserSections + NumIndexedSections; + // Remember the offset into the file for this section. + uint64_t SecStart = OS.tell(); - // Compute symbol table information. - computeSymbolTable(Asm, Layout, SectionIndexMap, RevGroupMap, - NumRegularSections); + const MCSymbol *SignatureSymbol = Section.getGroup(); + writeSectionData(Asm, Section, Layout); - WriteRelocations(Asm, const_cast<MCAsmLayout&>(Layout), RelMap); + uint64_t SecEnd = OS.tell(); + SectionOffsets[&Section] = std::make_pair(SecStart, SecEnd); - CreateMetadataSections(const_cast<MCAssembler&>(Asm), - const_cast<MCAsmLayout&>(Layout), - SectionIndexMap, - RelMap); + MCSectionELF *RelSection = createRelocationSection(Ctx, Section); - uint64_t NaturalAlignment = is64Bit() ? 8 : 4; - uint64_t HeaderSize = is64Bit() ? sizeof(ELF::Elf64_Ehdr) : - sizeof(ELF::Elf32_Ehdr); - uint64_t FileOff = HeaderSize; + if (SignatureSymbol) { + Asm.getOrCreateSymbolData(*SignatureSymbol); + unsigned &GroupIdx = RevGroupMap[SignatureSymbol]; + if (!GroupIdx) { + MCSectionELF *Group = Ctx.createELFGroupSection(SignatureSymbol); + GroupIdx = addToSectionTable(Group); + Group->setAlignment(4); + Groups.push_back(Group); + } + GroupMembers[SignatureSymbol].push_back(&Section); + if (RelSection) + GroupMembers[SignatureSymbol].push_back(RelSection); + } - std::vector<const MCSectionELF*> Sections; - ComputeSectionOrder(Asm, Sections); - unsigned NumSections = Sections.size(); - SectionOffsetMapTy SectionOffsetMap; - for (unsigned i = 0; i < NumRegularSections + 1; ++i) { - const MCSectionELF &Section = *Sections[i]; - const MCSectionData &SD = Asm.getOrCreateSectionData(Section); + SectionIndexMap[&Section] = addToSectionTable(&Section); + if (RelSection) { + SectionIndexMap[RelSection] = addToSectionTable(RelSection); + Relocations.push_back(RelSection); + } + } - FileOff = RoundUpToAlignment(FileOff, SD.getAlignment()); + for (MCSectionELF *Group : Groups) { + uint64_t Padding = OffsetToAlignment(OS.tell(), Group->getAlignment()); + WriteZeros(Padding); // Remember the offset into the file for this section. - SectionOffsetMap[&Section] = FileOff; + 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); + } - // Get the size of the section in the output file (including padding). - FileOff += GetSectionFileSize(Layout, SD); + uint64_t SecEnd = OS.tell(); + SectionOffsets[Group] = std::make_pair(SecStart, SecEnd); } - FileOff = RoundUpToAlignment(FileOff, NaturalAlignment); - - const unsigned SectionHeaderOffset = FileOff - HeaderSize; - - uint64_t SectionHeaderEntrySize = is64Bit() ? - sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr); - FileOff += (NumSections + 1) * SectionHeaderEntrySize; - - for (unsigned i = NumRegularSections + 1; i < NumSections; ++i) { - const MCSectionELF &Section = *Sections[i]; - const MCSectionData &SD = Asm.getOrCreateSectionData(Section); + // Compute symbol table information. + computeSymbolTable(Asm, Layout, SectionIndexMap, RevGroupMap); - FileOff = RoundUpToAlignment(FileOff, SD.getAlignment()); + for (MCSectionELF *RelSection : Relocations) { + uint64_t Padding = OffsetToAlignment(OS.tell(), RelSection->getAlignment()); + WriteZeros(Padding); // Remember the offset into the file for this section. - SectionOffsetMap[&Section] = FileOff; + uint64_t SecStart = OS.tell(); + + writeRelocations(Asm, *RelSection->getAssociatedSection()); - // Get the size of the section in the output file (including padding). - FileOff += GetSectionFileSize(Layout, SD); + uint64_t SecEnd = OS.tell(); + SectionOffsets[RelSection] = std::make_pair(SecStart, SecEnd); } - // Write out the ELF header ... - WriteHeader(Asm, SectionHeaderOffset, NumSections + 1); + writeSymbolTable(Ctx, Layout, SectionOffsets); - // ... then the regular sections ... - // + because of .shstrtab - for (unsigned i = 0; i < NumRegularSections + 1; ++i) - WriteDataSectionData(Asm, Layout, *Sections[i]); + { + uint64_t SecStart = OS.tell(); + const MCSectionELF *Sec = createStringTable(Ctx); + uint64_t SecEnd = OS.tell(); + SectionOffsets[Sec] = std::make_pair(SecStart, SecEnd); + } + uint64_t NaturalAlignment = is64Bit() ? 8 : 4; uint64_t Padding = OffsetToAlignment(OS.tell(), NaturalAlignment); WriteZeros(Padding); + const unsigned SectionHeaderOffset = OS.tell(); + // ... then the section header table ... - WriteSectionHeader(Asm, GroupMap, Layout, SectionIndexMap, - SectionOffsetMap); + writeSectionHeader(Asm, Layout, SectionIndexMap, SectionOffsets); + + uint16_t NumSections = (SectionTable.size() + 1 >= ELF::SHN_LORESERVE) + ? (uint16_t)ELF::SHN_UNDEF + : SectionTable.size() + 1; + if (sys::IsLittleEndianHost != IsLittleEndian) + sys::swapByteOrder(NumSections); + unsigned NumSectionsOffset; + + if (is64Bit()) { + uint64_t Val = SectionHeaderOffset; + if (sys::IsLittleEndianHost != IsLittleEndian) + sys::swapByteOrder(Val); + OS.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val), + offsetof(ELF::Elf64_Ehdr, e_shoff)); + NumSectionsOffset = offsetof(ELF::Elf64_Ehdr, e_shnum); + } else { + uint32_t Val = SectionHeaderOffset; + if (sys::IsLittleEndianHost != IsLittleEndian) + sys::swapByteOrder(Val); + OS.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val), + offsetof(ELF::Elf32_Ehdr, e_shoff)); + NumSectionsOffset = offsetof(ELF::Elf32_Ehdr, e_shnum); + } + OS.pwrite(reinterpret_cast<char *>(&NumSections), sizeof(NumSections), + NumSectionsOffset); +} - // ... 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 MCSymbol &SymA, const MCFragment &FB, + bool InSet, bool IsPCRel) const { + if (IsPCRel) { + assert(!InSet); + if (::isWeak(SymA.getData())) + return false; + } + return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(Asm, SymA, FB, + InSet, IsPCRel); } -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::isWeak(const MCSymbol &Sym) const { + const MCSymbolData &SD = Sym.getData(); + if (::isWeak(SD)) + return true; + + // It is invalid to replace a reference to a global in a comdat + // with a reference to a local since out of comdat references + // to a local are forbidden. + // We could try to return false for more cases, like the reference + // being in the same comdat or Sym being an alias to another global, + // but it is not clear if it is worth the effort. + if (MCELF::GetBinding(SD) != ELF::STB_GLOBAL) return false; - return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl( - Asm, DataA, FB,InSet, IsPCRel); + + if (!Sym.isInSection()) + return false; + + const auto &Sec = cast<MCSectionELF>(Sym.getSection()); + return Sec.getGroup(); } MCObjectWriter *llvm::createELFObjectWriter(MCELFObjectTargetWriter *MOTW, - raw_ostream &OS, + raw_pwrite_stream &OS, bool IsLittleEndian) { return new ELFObjectWriter(MOTW, OS, IsLittleEndian); } diff --git a/contrib/llvm/lib/MC/MCAsmInfo.cpp b/contrib/llvm/lib/MC/MCAsmInfo.cpp index 04b8042..b61f5b1 100644 --- a/contrib/llvm/lib/MC/MCAsmInfo.cpp +++ b/contrib/llvm/lib/MC/MCAsmInfo.cpp @@ -39,6 +39,7 @@ MCAsmInfo::MCAsmInfo() { CommentString = "#"; LabelSuffix = ":"; UseAssignmentForEHBegin = false; + NeedsLocalForSize = false; PrivateGlobalPrefix = "L"; PrivateLabelPrefix = PrivateGlobalPrefix; LinkerPrivateGlobalPrefix = ""; @@ -68,6 +69,7 @@ MCAsmInfo::MCAsmInfo() { HasAggressiveSymbolFolding = true; COMMDirectiveAlignmentIsInBytes = true; LCOMMDirectiveAlignmentType = LCOMM::NoAlignment; + HasFunctionAlignment = true; HasDotTypeDotSizeDirective = true; HasSingleParameterDotFile = true; HasIdentDirective = false; @@ -88,6 +90,7 @@ MCAsmInfo::MCAsmInfo() { DwarfRegNumForCFI = false; NeedsDwarfSectionOffsetDirective = false; UseParensForSymbolVariant = false; + UseLogicalShr = true; // FIXME: Clang's logic should be synced with the logic used to initialize // this member and the two implementations should be merged. @@ -129,7 +132,7 @@ MCAsmInfo::getExprForFDESymbol(const MCSymbol *Sym, MCContext &Context = Streamer.getContext(); const MCExpr *Res = MCSymbolRefExpr::Create(Sym, Context); - MCSymbol *PCSym = Context.CreateTempSymbol(); + MCSymbol *PCSym = Context.createTempSymbol(); Streamer.EmitLabel(PCSym); const MCExpr *PC = MCSymbolRefExpr::Create(PCSym, Context); return MCBinaryExpr::CreateSub(Res, PC, Context); diff --git a/contrib/llvm/lib/MC/MCAsmInfoCOFF.cpp b/contrib/llvm/lib/MC/MCAsmInfoCOFF.cpp index bb3f0d3..97fc76a 100644 --- a/contrib/llvm/lib/MC/MCAsmInfoCOFF.cpp +++ b/contrib/llvm/lib/MC/MCAsmInfoCOFF.cpp @@ -36,6 +36,10 @@ MCAsmInfoCOFF::MCAsmInfoCOFF() { NeedsDwarfSectionOffsetDirective = true; UseIntegratedAssembler = true; + + // FIXME: For now keep the previous behavior, AShr. Need to double-check + // other COFF-targeting assemblers and change this if necessary. + UseLogicalShr = false; } void MCAsmInfoMicrosoft::anchor() { } diff --git a/contrib/llvm/lib/MC/MCAsmInfoDarwin.cpp b/contrib/llvm/lib/MC/MCAsmInfoDarwin.cpp index 04cc0ff..bb90ff2 100644 --- a/contrib/llvm/lib/MC/MCAsmInfoDarwin.cpp +++ b/contrib/llvm/lib/MC/MCAsmInfoDarwin.cpp @@ -16,7 +16,6 @@ #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCSectionMachO.h" -#include "llvm/MC/MCStreamer.h" using namespace llvm; bool MCAsmInfoDarwin::isSectionAtomizableBySymbols( @@ -27,25 +26,14 @@ bool MCAsmInfoDarwin::isSectionAtomizableBySymbols( // contain. // Sections holding 2 byte strings require symbols in order to be atomized. // There is no dedicated section for 4 byte strings. - if (SMO.getKind().isMergeable1ByteCString()) + if (SMO.getType() == MachO::S_CSTRING_LITERALS) return false; - if (SMO.getSegmentName() == "__TEXT" && - SMO.getSectionName() == "__objc_classname" && - SMO.getType() == MachO::S_CSTRING_LITERALS) - return false; - - if (SMO.getSegmentName() == "__TEXT" && - SMO.getSectionName() == "__objc_methname" && - SMO.getType() == MachO::S_CSTRING_LITERALS) - return false; - - if (SMO.getSegmentName() == "__TEXT" && - SMO.getSectionName() == "__objc_methtype" && - SMO.getType() == MachO::S_CSTRING_LITERALS) + if (SMO.getSegmentName() == "__DATA" && SMO.getSectionName() == "__cfstring") return false; - if (SMO.getSegmentName() == "__DATA" && SMO.getSectionName() == "__cfstring") + if (SMO.getSegmentName() == "__DATA" && + SMO.getSectionName() == "__objc_classrefs") return false; switch (SMO.getType()) { @@ -105,4 +93,9 @@ MCAsmInfoDarwin::MCAsmInfoDarwin() { UseIntegratedAssembler = true; SetDirectiveSuppressesReloc = true; + + // FIXME: For now keep the previous behavior, AShr, matching the previous + // behavior of as(1) (both -q and -Q: resp. LLVM and gas v1.38). + // If/when this changes, the AArch64 Darwin special case can go away. + UseLogicalShr = false; } diff --git a/contrib/llvm/lib/MC/MCAsmInfoELF.cpp b/contrib/llvm/lib/MC/MCAsmInfoELF.cpp index 2fe626e..2bff6e0 100644 --- a/contrib/llvm/lib/MC/MCAsmInfoELF.cpp +++ b/contrib/llvm/lib/MC/MCAsmInfoELF.cpp @@ -20,10 +20,8 @@ using namespace llvm; void MCAsmInfoELF::anchor() { } -const MCSection * -MCAsmInfoELF::getNonexecutableStackSection(MCContext &Ctx) const { - return Ctx.getELFSection(".note.GNU-stack", ELF::SHT_PROGBITS, - 0, SectionKind::getMetadata()); +MCSection *MCAsmInfoELF::getNonexecutableStackSection(MCContext &Ctx) const { + return Ctx.getELFSection(".note.GNU-stack", ELF::SHT_PROGBITS, 0); } MCAsmInfoELF::MCAsmInfoELF() { diff --git a/contrib/llvm/lib/MC/MCAsmStreamer.cpp b/contrib/llvm/lib/MC/MCAsmStreamer.cpp index 1fe0f63..cabe63b 100644 --- a/contrib/llvm/lib/MC/MCAsmStreamer.cpp +++ b/contrib/llvm/lib/MC/MCAsmStreamer.cpp @@ -36,11 +36,10 @@ using namespace llvm; namespace { -class MCAsmStreamer : public MCStreamer { -protected: +class MCAsmStreamer final : public MCStreamer { + std::unique_ptr<formatted_raw_ostream> OSOwner; formatted_raw_ostream &OS; const MCAsmInfo *MAI; -private: std::unique_ptr<MCInstPrinter> InstPrinter; std::unique_ptr<MCCodeEmitter> Emitter; std::unique_ptr<MCAsmBackend> AsmBackend; @@ -57,16 +56,18 @@ private: void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override; public: - MCAsmStreamer(MCContext &Context, formatted_raw_ostream &os, + MCAsmStreamer(MCContext &Context, std::unique_ptr<formatted_raw_ostream> os, bool isVerboseAsm, bool useDwarfDirectory, MCInstPrinter *printer, MCCodeEmitter *emitter, MCAsmBackend *asmbackend, bool showInst) - : MCStreamer(Context), OS(os), MAI(Context.getAsmInfo()), - InstPrinter(printer), Emitter(emitter), AsmBackend(asmbackend), - CommentStream(CommentToEmit), IsVerboseAsm(isVerboseAsm), - ShowInst(showInst), UseDwarfDirectory(useDwarfDirectory) { - if (InstPrinter && IsVerboseAsm) - InstPrinter->setCommentStream(CommentStream); + : MCStreamer(Context), OSOwner(std::move(os)), OS(*OSOwner), + MAI(Context.getAsmInfo()), InstPrinter(printer), Emitter(emitter), + AsmBackend(asmbackend), CommentStream(CommentToEmit), + IsVerboseAsm(isVerboseAsm), ShowInst(showInst), + UseDwarfDirectory(useDwarfDirectory) { + assert(InstPrinter); + if (IsVerboseAsm) + InstPrinter->setCommentStream(CommentStream); } inline void EmitEOL() { @@ -114,8 +115,7 @@ public: /// @name MCStreamer Interface /// @{ - void ChangeSection(const MCSection *Section, - const MCExpr *Subsection) override; + void ChangeSection(MCSection *Section, const MCExpr *Subsection) override; void EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override; void EmitLabel(MCSymbol *Symbol) override; @@ -150,11 +150,11 @@ public: void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) override; - void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = nullptr, + void EmitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr, uint64_t Size = 0, unsigned ByteAlignment = 0) override; - void EmitTBSSSymbol (const MCSection *Section, MCSymbol *Symbol, - uint64_t Size, unsigned ByteAlignment = 0) override; + void EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment = 0) override; void EmitBytes(StringRef Data) override; @@ -267,7 +267,7 @@ void MCAsmStreamer::EmitCommentsAndEOL() { } CommentStream.flush(); - StringRef Comments = CommentToEmit.str(); + StringRef Comments = CommentToEmit; assert(Comments.back() == '\n' && "Comment array not newline terminated"); @@ -297,7 +297,7 @@ void MCAsmStreamer::emitRawComment(const Twine &T, bool TabPrefix) { EmitEOL(); } -void MCAsmStreamer::ChangeSection(const MCSection *Section, +void MCAsmStreamer::ChangeSection(MCSection *Section, const MCExpr *Subsection) { assert(Section && "Cannot switch to a null section!"); Section->PrintSwitchToSection(*MAI, OS, Subsection); @@ -542,7 +542,7 @@ void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, EmitEOL(); } -void MCAsmStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol, +void MCAsmStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) { if (Symbol) AssignSection(Symbol, Section); @@ -565,7 +565,7 @@ void MCAsmStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol, // .tbss sym, size, align // This depends that the symbol has already been mangled from the original, // e.g. _a. -void MCAsmStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, +void MCAsmStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) { AssignSection(Symbol, Section); @@ -946,7 +946,7 @@ void MCAsmStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) { } void MCAsmStreamer::EmitRegisterName(int64_t Register) { - if (InstPrinter && !MAI->useDwarfRegNumForCFI()) { + if (!MAI->useDwarfRegNumForCFI()) { const MCRegisterInfo *MRI = getContext().getRegisterInfo(); unsigned LLVMRegister = MRI->getLLVMRegNum(Register, true); InstPrinter->printRegName(OS, LLVMRegister); @@ -1102,7 +1102,7 @@ void MCAsmStreamer::EmitWinEHHandlerData() { // We only do this so the section switch that terminates the handler // data block is visible. WinEH::FrameInfo *CurFrame = getCurrentWinFrameInfo(); - if (const MCSection *XData = WinEH::UnwindEmitter::getXDataSection( + if (MCSection *XData = WinEH::UnwindEmitter::getXDataSection( CurFrame->Function, getContext())) SwitchSectionNoChange(XData); @@ -1167,7 +1167,7 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst, SmallString<256> Code; SmallVector<MCFixup, 4> Fixups; raw_svector_ostream VecOS(Code); - Emitter->EncodeInstruction(Inst, VecOS, Fixups, STI); + Emitter->encodeInstruction(Inst, VecOS, Fixups, STI); VecOS.flush(); // If we are showing fixups, create symbolic markers in the encoded @@ -1256,15 +1256,12 @@ void MCAsmStreamer::EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &S // Show the MCInst if enabled. if (ShowInst) { - Inst.dump_pretty(GetCommentOS(), MAI, InstPrinter.get(), "\n "); + Inst.dump_pretty(GetCommentOS(), InstPrinter.get(), "\n "); GetCommentOS() << "\n"; } - // If we have an AsmPrinter, use that to print, otherwise print the MCInst. - if (InstPrinter) - InstPrinter->printInst(&Inst, OS, ""); - else - Inst.print(OS, MAI); + InstPrinter->printInst(&Inst, OS, "", STI); + EmitEOL(); } @@ -1314,10 +1311,10 @@ void MCAsmStreamer::FinishImpl() { } MCStreamer *llvm::createAsmStreamer(MCContext &Context, - formatted_raw_ostream &OS, + std::unique_ptr<formatted_raw_ostream> OS, bool isVerboseAsm, bool useDwarfDirectory, MCInstPrinter *IP, MCCodeEmitter *CE, MCAsmBackend *MAB, bool ShowInst) { - return new MCAsmStreamer(Context, OS, isVerboseAsm, useDwarfDirectory, IP, CE, - MAB, ShowInst); + return new MCAsmStreamer(Context, std::move(OS), isVerboseAsm, + useDwarfDirectory, IP, CE, MAB, ShowInst); } diff --git a/contrib/llvm/lib/MC/MCAssembler.cpp b/contrib/llvm/lib/MC/MCAssembler.cpp index e3c2443..868b0f1 100644 --- a/contrib/llvm/lib/MC/MCAssembler.cpp +++ b/contrib/llvm/lib/MC/MCAssembler.cpp @@ -69,19 +69,19 @@ MCAsmLayout::MCAsmLayout(MCAssembler &Asm) { // Compute the section layout order. Virtual sections must go last. for (MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); it != ie; ++it) - if (!it->getSection().isVirtualSection()) + if (!it->isVirtualSection()) SectionOrder.push_back(&*it); for (MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); it != ie; ++it) - if (it->getSection().isVirtualSection()) + if (it->isVirtualSection()) SectionOrder.push_back(&*it); } bool MCAsmLayout::isFragmentValid(const MCFragment *F) const { - const MCSectionData &SD = *F->getParent(); - const MCFragment *LastValid = LastValidFragment.lookup(&SD); + const MCSection *Sec = F->getParent(); + const MCFragment *LastValid = LastValidFragment.lookup(Sec); if (!LastValid) return false; - assert(LastValid->getParent() == F->getParent()); + assert(LastValid->getParent() == Sec); return F->getLayoutOrder() <= LastValid->getLayoutOrder(); } @@ -92,16 +92,14 @@ void MCAsmLayout::invalidateFragmentsFrom(MCFragment *F) { // Otherwise, reset the last valid fragment to the previous fragment // (if this is the first fragment, it will be NULL). - const MCSectionData &SD = *F->getParent(); - LastValidFragment[&SD] = F->getPrevNode(); + LastValidFragment[F->getParent()] = F->getPrevNode(); } void MCAsmLayout::ensureValid(const MCFragment *F) const { - MCSectionData &SD = *F->getParent(); - - MCFragment *Cur = LastValidFragment[&SD]; + MCSection *Sec = F->getParent(); + MCFragment *Cur = LastValidFragment[Sec]; if (!Cur) - Cur = &*SD.begin(); + Cur = Sec->begin(); else Cur = Cur->getNextNode(); @@ -120,41 +118,36 @@ uint64_t MCAsmLayout::getFragmentOffset(const MCFragment *F) const { } // Simple getSymbolOffset helper for the non-varibale case. -static bool getLabelOffset(const MCAsmLayout &Layout, const MCSymbolData &SD, +static bool getLabelOffset(const MCAsmLayout &Layout, const MCSymbol &S, bool ReportError, uint64_t &Val) { + const MCSymbolData &SD = S.getData(); if (!SD.getFragment()) { if (ReportError) report_fatal_error("unable to evaluate offset to undefined symbol '" + - SD.getSymbol().getName() + "'"); + S.getName() + "'"); return false; } Val = Layout.getFragmentOffset(SD.getFragment()) + SD.getOffset(); return true; } -static bool getSymbolOffsetImpl(const MCAsmLayout &Layout, - const MCSymbolData *SD, bool ReportError, - uint64_t &Val) { - const MCSymbol &S = SD->getSymbol(); - +static bool getSymbolOffsetImpl(const MCAsmLayout &Layout, const MCSymbol &S, + bool ReportError, uint64_t &Val) { if (!S.isVariable()) - return getLabelOffset(Layout, *SD, ReportError, Val); + return getLabelOffset(Layout, S, ReportError, Val); // If SD is a variable, evaluate it. MCValue Target; - if (!S.getVariableValue()->EvaluateAsValue(Target, &Layout, nullptr)) + if (!S.getVariableValue()->EvaluateAsRelocatable(Target, &Layout, nullptr)) report_fatal_error("unable to evaluate offset for variable '" + S.getName() + "'"); uint64_t Offset = Target.getConstant(); - const MCAssembler &Asm = Layout.getAssembler(); - const MCSymbolRefExpr *A = Target.getSymA(); if (A) { uint64_t ValA; - if (!getLabelOffset(Layout, Asm.getSymbolData(A->getSymbol()), ReportError, - ValA)) + if (!getLabelOffset(Layout, A->getSymbol(), ReportError, ValA)) return false; Offset += ValA; } @@ -162,8 +155,7 @@ static bool getSymbolOffsetImpl(const MCAsmLayout &Layout, const MCSymbolRefExpr *B = Target.getSymB(); if (B) { uint64_t ValB; - if (!getLabelOffset(Layout, Asm.getSymbolData(B->getSymbol()), ReportError, - ValB)) + if (!getLabelOffset(Layout, B->getSymbol(), ReportError, ValB)) return false; Offset -= ValB; } @@ -172,13 +164,13 @@ static bool getSymbolOffsetImpl(const MCAsmLayout &Layout, return true; } -bool MCAsmLayout::getSymbolOffset(const MCSymbolData *SD, uint64_t &Val) const { - return getSymbolOffsetImpl(*this, SD, false, Val); +bool MCAsmLayout::getSymbolOffset(const MCSymbol &S, uint64_t &Val) const { + return getSymbolOffsetImpl(*this, S, false, Val); } -uint64_t MCAsmLayout::getSymbolOffset(const MCSymbolData *SD) const { +uint64_t MCAsmLayout::getSymbolOffset(const MCSymbol &S) const { uint64_t Val; - getSymbolOffsetImpl(*this, SD, true, Val); + getSymbolOffsetImpl(*this, S, true, Val); return Val; } @@ -188,12 +180,12 @@ const MCSymbol *MCAsmLayout::getBaseSymbol(const MCSymbol &Symbol) const { const MCExpr *Expr = Symbol.getVariableValue(); MCValue Value; - if (!Expr->EvaluateAsValue(Value, this, nullptr)) + if (!Expr->evaluateAsValue(Value, *this)) llvm_unreachable("Invalid Expression"); const MCSymbolRefExpr *RefB = Value.getSymB(); if (RefB) - Assembler.getContext().FatalError( + Assembler.getContext().reportFatalError( SMLoc(), Twine("symbol '") + RefB->getSymbol().getName() + "' could not be evaluated in a subtraction expression"); @@ -201,26 +193,37 @@ const MCSymbol *MCAsmLayout::getBaseSymbol(const MCSymbol &Symbol) const { if (!A) return nullptr; - return &A->getSymbol(); + const MCSymbol &ASym = A->getSymbol(); + const MCAssembler &Asm = getAssembler(); + const MCSymbolData &ASD = Asm.getSymbolData(ASym); + if (ASD.isCommon()) { + // FIXME: we should probably add a SMLoc to MCExpr. + Asm.getContext().reportFatalError(SMLoc(), + "Common symbol " + ASym.getName() + + " cannot be used in assignment expr"); + } + + return &ASym; } -uint64_t MCAsmLayout::getSectionAddressSize(const MCSectionData *SD) const { +uint64_t MCAsmLayout::getSectionAddressSize(const MCSection *Sec) const { // The size is the last fragment's end offset. - const MCFragment &F = SD->getFragmentList().back(); + const MCFragment &F = Sec->getFragmentList().back(); return getFragmentOffset(&F) + getAssembler().computeFragmentSize(*this, F); } -uint64_t MCAsmLayout::getSectionFileSize(const MCSectionData *SD) const { +uint64_t MCAsmLayout::getSectionFileSize(const MCSection *Sec) const { // Virtual sections have no file size. - if (SD->getSection().isVirtualSection()) + if (Sec->isVirtualSection()) return 0; // Otherwise, the file size is the same as the address space size. - return getSectionAddressSize(SD); + return getSectionAddressSize(Sec); } -uint64_t MCAsmLayout::computeBundlePadding(const MCFragment *F, - uint64_t FOffset, uint64_t FSize) { +uint64_t llvm::computeBundlePadding(const MCAssembler &Assembler, + const MCFragment *F, + uint64_t FOffset, uint64_t FSize) { uint64_t BundleSize = Assembler.getBundleAlignSize(); assert(BundleSize > 0 && "computeBundlePadding should only be called if bundling is enabled"); @@ -267,9 +270,8 @@ MCFragment::MCFragment() : Kind(FragmentType(~0)) { MCFragment::~MCFragment() { } -MCFragment::MCFragment(FragmentType _Kind, MCSectionData *_Parent) - : Kind(_Kind), Parent(_Parent), Atom(nullptr), Offset(~UINT64_C(0)) -{ +MCFragment::MCFragment(FragmentType Kind, MCSection *Parent) + : Kind(Kind), Parent(Parent), Atom(nullptr), Offset(~UINT64_C(0)) { if (Parent) Parent->getFragmentList().push_back(this); } @@ -286,84 +288,6 @@ MCEncodedFragmentWithFixups::~MCEncodedFragmentWithFixups() { /* *** */ -MCSectionData::MCSectionData() : Section(nullptr) {} - -MCSectionData::MCSectionData(const MCSection &_Section, MCAssembler *A) - : Section(&_Section), - Ordinal(~UINT32_C(0)), - Alignment(1), - BundleLockState(NotBundleLocked), - BundleLockNestingDepth(0), - BundleGroupBeforeFirstInst(false), - HasInstructions(false) -{ - if (A) - A->getSectionList().push_back(this); -} - -MCSectionData::iterator -MCSectionData::getSubsectionInsertionPoint(unsigned Subsection) { - if (Subsection == 0 && SubsectionFragmentMap.empty()) - return end(); - - SmallVectorImpl<std::pair<unsigned, MCFragment *> >::iterator MI = - std::lower_bound(SubsectionFragmentMap.begin(), SubsectionFragmentMap.end(), - std::make_pair(Subsection, (MCFragment *)nullptr)); - bool ExactMatch = false; - if (MI != SubsectionFragmentMap.end()) { - ExactMatch = MI->first == Subsection; - if (ExactMatch) - ++MI; - } - iterator IP; - if (MI == SubsectionFragmentMap.end()) - IP = end(); - else - IP = MI->second; - if (!ExactMatch && Subsection != 0) { - // The GNU as documentation claims that subsections have an alignment of 4, - // although this appears not to be the case. - MCFragment *F = new MCDataFragment(); - SubsectionFragmentMap.insert(MI, std::make_pair(Subsection, F)); - getFragmentList().insert(IP, F); - F->setParent(this); - } - return IP; -} - -void MCSectionData::setBundleLockState(BundleLockStateType NewState) { - if (NewState == NotBundleLocked) { - if (BundleLockNestingDepth == 0) { - report_fatal_error("Mismatched bundle_lock/unlock directives"); - } - if (--BundleLockNestingDepth == 0) { - BundleLockState = NotBundleLocked; - } - return; - } - - // If any of the directives is an align_to_end directive, the whole nested - // group is align_to_end. So don't downgrade from align_to_end to just locked. - if (BundleLockState != BundleLockedAlignToEnd) { - BundleLockState = NewState; - } - ++BundleLockNestingDepth; -} - -/* *** */ - -MCSymbolData::MCSymbolData() : Symbol(nullptr) {} - -MCSymbolData::MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment, - uint64_t _Offset, MCAssembler *A) - : Symbol(&_Symbol), Fragment(_Fragment), Offset(_Offset), - SymbolSize(nullptr), CommonAlign(-1U), Flags(0), Index(0) { - if (A) - A->getSymbolList().push_back(this); -} - -/* *** */ - MCAssembler::MCAssembler(MCContext &Context_, MCAsmBackend &Backend_, MCCodeEmitter &Emitter_, MCObjectWriter &Writer_, raw_ostream &OS_) @@ -379,8 +303,6 @@ MCAssembler::~MCAssembler() { void MCAssembler::reset() { Sections.clear(); Symbols.clear(); - SectionMap.clear(); - SymbolMap.clear(); IndirectSymbols.clear(); DataRegions.clear(); LinkerOptions.clear(); @@ -425,6 +347,16 @@ bool MCAssembler::isThumbFunc(const MCSymbol *Symbol) const { return true; } +void MCAssembler::addLocalUsedInReloc(const MCSymbol &Sym) { + assert(Sym.isTemporary()); + LocalsUsedInReloc.insert(&Sym); +} + +bool MCAssembler::isLocalUsedInReloc(const MCSymbol &Sym) const { + assert(Sym.isTemporary()); + return LocalsUsedInReloc.count(&Sym); +} + bool MCAssembler::isSymbolLinkerVisible(const MCSymbol &Symbol) const { // Non-temporary labels should always be visible to the linker. if (!Symbol.isTemporary()) @@ -434,39 +366,29 @@ bool MCAssembler::isSymbolLinkerVisible(const MCSymbol &Symbol) const { if (!Symbol.isInSection()) return false; - // Otherwise, check if the section requires symbols even for temporary labels. - return getBackend().doesSectionRequireSymbols(Symbol.getSection()); + if (isLocalUsedInReloc(Symbol)) + return true; + + return false; } -const MCSymbolData *MCAssembler::getAtom(const MCSymbolData *SD) const { +const MCSymbol *MCAssembler::getAtom(const MCSymbol &S) const { // Linker visible symbols define atoms. - if (isSymbolLinkerVisible(SD->getSymbol())) - return SD; + if (isSymbolLinkerVisible(S)) + return &S; // Absolute and undefined symbols have no defining atom. - if (!SD->getFragment()) + if (!S.getData().getFragment()) return nullptr; // Non-linker visible symbols in sections which can't be atomized have no // defining atom. if (!getContext().getAsmInfo()->isSectionAtomizableBySymbols( - SD->getFragment()->getParent()->getSection())) + *S.getData().getFragment()->getParent())) return nullptr; // Otherwise, return the atom for the containing fragment. - return SD->getFragment()->getAtom(); -} - -// Try to fully compute Expr to an absolute value and if that fails produce -// a relocatable expr. -// FIXME: Should this be the behavior of EvaluateAsRelocatable itself? -static bool evaluate(const MCExpr &Expr, const MCAsmLayout &Layout, - const MCFixup &Fixup, MCValue &Target) { - if (Expr.EvaluateAsValue(Target, &Layout, &Fixup)) { - if (Target.isAbsolute()) - return true; - } - return Expr.EvaluateAsRelocatable(Target, &Layout, &Fixup); + return S.getData().getFragment()->getAtom(); } bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout, @@ -478,8 +400,8 @@ bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout, // probably merge the two into a single callback that tries to evaluate a // fixup and records a relocation if one is needed. const MCExpr *Expr = Fixup.getValue(); - if (!evaluate(*Expr, Layout, Fixup, Target)) - getContext().FatalError(Fixup.getLoc(), "expected relocatable expression"); + if (!Expr->EvaluateAsRelocatable(Target, &Layout, &Fixup)) + getContext().reportFatalError(Fixup.getLoc(), "expected relocatable expression"); bool IsPCRel = Backend.getFixupKindInfo( Fixup.getKind()).Flags & MCFixupKindInfo::FKF_IsPCRel; @@ -493,14 +415,11 @@ bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout, } else { const MCSymbolRefExpr *A = Target.getSymA(); const MCSymbol &SA = A->getSymbol(); - if (A->getKind() != MCSymbolRefExpr::VK_None || - SA.AliasedSymbol().isUndefined()) { + if (A->getKind() != MCSymbolRefExpr::VK_None || SA.isUndefined()) { IsResolved = false; } else { - const MCSymbolData &DataA = getSymbolData(SA); - IsResolved = - getWriter().IsSymbolRefDifferenceFullyResolvedImpl(*this, DataA, - *DF, false, true); + IsResolved = getWriter().IsSymbolRefDifferenceFullyResolvedImpl( + *this, SA, *DF, false, true); } } } else { @@ -510,14 +429,14 @@ bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout, Value = Target.getConstant(); if (const MCSymbolRefExpr *A = Target.getSymA()) { - const MCSymbol &Sym = A->getSymbol().AliasedSymbol(); + const MCSymbol &Sym = A->getSymbol(); if (Sym.isDefined()) - Value += Layout.getSymbolOffset(&getSymbolData(Sym)); + Value += Layout.getSymbolOffset(Sym); } if (const MCSymbolRefExpr *B = Target.getSymB()) { - const MCSymbol &Sym = B->getSymbol().AliasedSymbol(); + const MCSymbol &Sym = B->getSymbol(); if (Sym.isDefined()) - Value -= Layout.getSymbolOffset(&getSymbolData(Sym)); + Value -= Layout.getSymbolOffset(Sym); } @@ -630,7 +549,12 @@ void MCAsmLayout::layoutFragment(MCFragment *F) { // The fragment's offset will point to after the padding, and its computed // size won't include the padding. // - if (Assembler.isBundlingEnabled() && F->hasInstructions()) { + // When the -mc-relax-all flag is used, we optimize bundling by writting the + // bundle padding directly into fragments when the instructions are emitted + // inside the streamer. + // + if (Assembler.isBundlingEnabled() && !Assembler.getRelaxAll() && + F->hasInstructions()) { assert(isa<MCEncodedFragment>(F) && "Only MCEncodedFragment implementations have instructions"); uint64_t FSize = Assembler.computeFragmentSize(*this, *F); @@ -638,7 +562,8 @@ void MCAsmLayout::layoutFragment(MCFragment *F) { if (FSize > Assembler.getBundleAlignSize()) report_fatal_error("Fragment can't be larger than a bundle size"); - uint64_t RequiredBundlePadding = computeBundlePadding(F, F->Offset, FSize); + uint64_t RequiredBundlePadding = computeBundlePadding(Assembler, F, + F->Offset, FSize); if (RequiredBundlePadding > UINT8_MAX) report_fatal_error("Padding cannot exceed 255 bytes"); F->setBundlePadding(static_cast<uint8_t>(RequiredBundlePadding)); @@ -653,24 +578,18 @@ static void writeFragmentContents(const MCFragment &F, MCObjectWriter *OW) { OW->WriteBytes(EF.getContents()); } -/// \brief Write the fragment \p F to the output file. -static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout, - const MCFragment &F) { - MCObjectWriter *OW = &Asm.getWriter(); - - // FIXME: Embed in fragments instead? - uint64_t FragmentSize = Asm.computeFragmentSize(Layout, F); - +void MCAssembler::writeFragmentPadding(const MCFragment &F, uint64_t FSize, + MCObjectWriter *OW) const { // Should NOP padding be written out before this fragment? unsigned BundlePadding = F.getBundlePadding(); if (BundlePadding > 0) { - assert(Asm.isBundlingEnabled() && + assert(isBundlingEnabled() && "Writing bundle padding with disabled bundling"); assert(F.hasInstructions() && "Writing bundle padding for a fragment without instructions"); - unsigned TotalLength = BundlePadding + static_cast<unsigned>(FragmentSize); - if (F.alignToBundleEnd() && TotalLength > Asm.getBundleAlignSize()) { + unsigned TotalLength = BundlePadding + static_cast<unsigned>(FSize); + if (F.alignToBundleEnd() && TotalLength > getBundleAlignSize()) { // If the padding itself crosses a bundle boundary, it must be emitted // in 2 pieces, since even nop instructions must not cross boundaries. // v--------------v <- BundleAlignSize @@ -679,16 +598,27 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout, // | Prev |####|####| F | // ---------------------------- // ^-------------------^ <- TotalLength - unsigned DistanceToBoundary = TotalLength - Asm.getBundleAlignSize(); - if (!Asm.getBackend().writeNopData(DistanceToBoundary, OW)) + unsigned DistanceToBoundary = TotalLength - getBundleAlignSize(); + if (!getBackend().writeNopData(DistanceToBoundary, OW)) report_fatal_error("unable to write NOP sequence of " + Twine(DistanceToBoundary) + " bytes"); BundlePadding -= DistanceToBoundary; } - if (!Asm.getBackend().writeNopData(BundlePadding, OW)) + if (!getBackend().writeNopData(BundlePadding, OW)) report_fatal_error("unable to write NOP sequence of " + Twine(BundlePadding) + " bytes"); } +} + +/// \brief Write the fragment \p F to the output file. +static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout, + const MCFragment &F) { + MCObjectWriter *OW = &Asm.getWriter(); + + // FIXME: Embed in fragments instead? + uint64_t FragmentSize = Asm.computeFragmentSize(Layout, F); + + Asm.writeFragmentPadding(F, FragmentSize, OW); // This variable (and its dummy usage) is to participate in the assert at // the end of the function. @@ -773,7 +703,7 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout, case MCFragment::FT_LEB: { const MCLEBFragment &LF = cast<MCLEBFragment>(F); - OW->WriteBytes(LF.getContents().str()); + OW->WriteBytes(LF.getContents()); break; } @@ -789,12 +719,12 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout, case MCFragment::FT_Dwarf: { const MCDwarfLineAddrFragment &OF = cast<MCDwarfLineAddrFragment>(F); - OW->WriteBytes(OF.getContents().str()); + OW->WriteBytes(OF.getContents()); break; } case MCFragment::FT_DwarfFrame: { const MCDwarfCallFrameFragment &CF = cast<MCDwarfCallFrameFragment>(F); - OW->WriteBytes(CF.getContents().str()); + OW->WriteBytes(CF.getContents()); break; } } @@ -803,15 +733,15 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout, "The stream should advance by fragment size"); } -void MCAssembler::writeSectionData(const MCSectionData *SD, +void MCAssembler::writeSectionData(const MCSection *Sec, const MCAsmLayout &Layout) const { // Ignore virtual sections. - if (SD->getSection().isVirtualSection()) { - assert(Layout.getSectionFileSize(SD) == 0 && "Invalid size for section!"); + if (Sec->isVirtualSection()) { + assert(Layout.getSectionFileSize(Sec) == 0 && "Invalid size for section!"); // Check that contents are only things legal inside a virtual section. - for (MCSectionData::const_iterator it = SD->begin(), - ie = SD->end(); it != ie; ++it) { + for (MCSection::const_iterator it = Sec->begin(), ie = Sec->end(); it != ie; + ++it) { switch (it->getKind()) { default: llvm_unreachable("Invalid fragment in virtual section!"); case MCFragment::FT_Data: { @@ -823,7 +753,7 @@ void MCAssembler::writeSectionData(const MCSectionData *SD, "Cannot have fixups in virtual section!"); for (unsigned i = 0, e = DF.getContents().size(); i != e; ++i) if (DF.getContents()[i]) { - if (auto *ELFSec = dyn_cast<const MCSectionELF>(&SD->getSection())) + if (auto *ELFSec = dyn_cast<const MCSectionELF>(Sec)) report_fatal_error("non-zero initializer found in section '" + ELFSec->getSectionName() + "'"); else @@ -852,12 +782,12 @@ void MCAssembler::writeSectionData(const MCSectionData *SD, uint64_t Start = getWriter().getStream().tell(); (void)Start; - for (MCSectionData::const_iterator it = SD->begin(), ie = SD->end(); - it != ie; ++it) + for (MCSection::const_iterator it = Sec->begin(), ie = Sec->end(); it != ie; + ++it) writeFragment(*this, Layout, *it); assert(getWriter().getStream().tell() - Start == - Layout.getSectionAddressSize(SD)); + Layout.getSectionAddressSize(Sec)); } std::pair<uint64_t, bool> MCAssembler::handleFixup(const MCAsmLayout &Layout, @@ -892,18 +822,18 @@ void MCAssembler::Finish() { // Create dummy fragments to eliminate any empty sections, this simplifies // layout. if (it->getFragmentList().empty()) - new MCDataFragment(it); + new MCDataFragment(&*it); it->setOrdinal(SectionIndex++); } // Assign layout order indices to sections and fragments. for (unsigned i = 0, e = Layout.getSectionOrder().size(); i != e; ++i) { - MCSectionData *SD = Layout.getSectionOrder()[i]; - SD->setLayoutOrder(i); + MCSection *Sec = Layout.getSectionOrder()[i]; + Sec->setLayoutOrder(i); unsigned FragmentIndex = 0; - for (MCSectionData::iterator iFrag = SD->begin(), iFragEnd = SD->end(); + for (MCSection::iterator iFrag = Sec->begin(), iFragEnd = Sec->end(); iFrag != iFragEnd; ++iFrag) iFrag->setLayoutOrder(FragmentIndex++); } @@ -931,8 +861,8 @@ void MCAssembler::Finish() { // Evaluate and apply the fixups, generating relocation entries as necessary. for (MCAssembler::iterator it = begin(), ie = end(); it != ie; ++it) { - for (MCSectionData::iterator it2 = it->begin(), - ie2 = it->end(); it2 != ie2; ++it2) { + for (MCSection::iterator it2 = it->begin(), ie2 = it->end(); it2 != ie2; + ++it2) { MCEncodedFragmentWithFixups *F = dyn_cast<MCEncodedFragmentWithFixups>(it2); if (F) { @@ -1005,7 +935,7 @@ bool MCAssembler::relaxInstruction(MCAsmLayout &Layout, SmallVector<MCFixup, 4> Fixups; SmallString<256> Code; raw_svector_ostream VecOS(Code); - getEmitter().EncodeInstruction(Relaxed, VecOS, Fixups, F.getSubtargetInfo()); + getEmitter().encodeInstruction(Relaxed, VecOS, Fixups, F.getSubtargetInfo()); VecOS.flush(); // Update the fragment. @@ -1018,7 +948,10 @@ bool MCAssembler::relaxInstruction(MCAsmLayout &Layout, bool MCAssembler::relaxLEB(MCAsmLayout &Layout, MCLEBFragment &LF) { uint64_t OldSize = LF.getContents().size(); - int64_t Value = LF.getValue().evaluateKnownAbsolute(Layout); + int64_t Value; + bool Abs = LF.getValue().evaluateKnownAbsolute(Value, Layout); + if (!Abs) + report_fatal_error("sleb128 and uleb128 expressions must be absolute"); SmallString<8> &Data = LF.getContents(); Data.clear(); raw_svector_ostream OSE(Data); @@ -1034,7 +967,10 @@ bool MCAssembler::relaxDwarfLineAddr(MCAsmLayout &Layout, MCDwarfLineAddrFragment &DF) { MCContext &Context = Layout.getAssembler().getContext(); uint64_t OldSize = DF.getContents().size(); - int64_t AddrDelta = DF.getAddrDelta().evaluateKnownAbsolute(Layout); + int64_t AddrDelta; + bool Abs = DF.getAddrDelta().evaluateKnownAbsolute(AddrDelta, Layout); + assert(Abs && "We created a line delta with an invalid expression"); + (void) Abs; int64_t LineDelta; LineDelta = DF.getLineDelta(); SmallString<8> &Data = DF.getContents(); @@ -1049,7 +985,10 @@ bool MCAssembler::relaxDwarfCallFrameFragment(MCAsmLayout &Layout, MCDwarfCallFrameFragment &DF) { MCContext &Context = Layout.getAssembler().getContext(); uint64_t OldSize = DF.getContents().size(); - int64_t AddrDelta = DF.getAddrDelta().evaluateKnownAbsolute(Layout); + int64_t AddrDelta; + bool Abs = DF.getAddrDelta().evaluateKnownAbsolute(AddrDelta, Layout); + assert(Abs && "We created call frame with an invalid expression"); + (void) Abs; SmallString<8> &Data = DF.getContents(); Data.clear(); raw_svector_ostream OSE(Data); @@ -1058,7 +997,7 @@ bool MCAssembler::relaxDwarfCallFrameFragment(MCAsmLayout &Layout, return OldSize != Data.size(); } -bool MCAssembler::layoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD) { +bool MCAssembler::layoutSectionOnce(MCAsmLayout &Layout, MCSection &Sec) { // Holds the first fragment which needed relaxing during this layout. It will // remain NULL if none were relaxed. // When a fragment is relaxed, all the fragments following it should get @@ -1066,7 +1005,7 @@ bool MCAssembler::layoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD) { MCFragment *FirstRelaxedFragment = nullptr; // Attempt to relax all the fragments in the section. - for (MCSectionData::iterator I = SD.begin(), IE = SD.end(); I != IE; ++I) { + for (MCSection::iterator I = Sec.begin(), IE = Sec.end(); I != IE; ++I) { // Check if this is a fragment that needs relaxation. bool RelaxedFrag = false; switch(I->getKind()) { @@ -1105,8 +1044,8 @@ bool MCAssembler::layoutOnce(MCAsmLayout &Layout) { bool WasRelaxed = false; for (iterator it = begin(), ie = end(); it != ie; ++it) { - MCSectionData &SD = *it; - while (layoutSectionOnce(Layout, SD)) + MCSection &Sec = *it; + while (layoutSectionOnce(Layout, Sec)) WasRelaxed = true; } @@ -1245,27 +1184,14 @@ void MCFragment::dump() { OS << ">"; } -void MCSectionData::dump() { - raw_ostream &OS = llvm::errs(); - - OS << "<MCSectionData"; - OS << " Alignment:" << getAlignment() - << " Fragments:[\n "; - for (iterator it = begin(), ie = end(); it != ie; ++it) { - if (it != begin()) OS << ",\n "; - it->dump(); - } - OS << "]>"; -} - void MCSymbolData::dump() const { raw_ostream &OS = llvm::errs(); - OS << "<MCSymbolData Symbol:" << getSymbol() + OS << "<MCSymbolData" << " Fragment:" << getFragment(); if (!isCommon()) OS << " Offset:" << getOffset(); - OS << " Flags:" << getFlags() << " Index:" << getIndex(); + OS << " Flags:" << getFlags(); if (isCommon()) OS << " (common, size:" << getCommonSize() << " align: " << getCommonAlignment() << ")"; @@ -1290,7 +1216,11 @@ void MCAssembler::dump() { for (symbol_iterator it = symbol_begin(), ie = symbol_end(); it != ie; ++it) { if (it != symbol_begin()) OS << ",\n "; + OS << "("; it->dump(); + OS << ", Index:" << it->getIndex() << ", "; + it->getData().dump(); + OS << ")"; } OS << "]>\n"; } diff --git a/contrib/llvm/lib/MC/MCCodeGenInfo.cpp b/contrib/llvm/lib/MC/MCCodeGenInfo.cpp index d9dcfd0..347ec2c 100644 --- a/contrib/llvm/lib/MC/MCCodeGenInfo.cpp +++ b/contrib/llvm/lib/MC/MCCodeGenInfo.cpp @@ -15,7 +15,7 @@ #include "llvm/MC/MCCodeGenInfo.h" using namespace llvm; -void MCCodeGenInfo::InitMCCodeGenInfo(Reloc::Model RM, CodeModel::Model CM, +void MCCodeGenInfo::initMCCodeGenInfo(Reloc::Model RM, CodeModel::Model CM, CodeGenOpt::Level OL) { RelocationModel = RM; CMModel = CM; diff --git a/contrib/llvm/lib/MC/MCContext.cpp b/contrib/llvm/lib/MC/MCContext.cpp index b41e6d8..1f2f034 100644 --- a/contrib/llvm/lib/MC/MCContext.cpp +++ b/contrib/llvm/lib/MC/MCContext.cpp @@ -10,6 +10,7 @@ #include "llvm/MC/MCContext.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/Twine.h" +#include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCDwarf.h" #include "llvm/MC/MCLabel.h" @@ -18,6 +19,7 @@ #include "llvm/MC/MCSectionCOFF.h" #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCSectionMachO.h" +#include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" #include "llvm/Support/ELF.h" #include "llvm/Support/ErrorHandling.h" @@ -33,7 +35,7 @@ MCContext::MCContext(const MCAsmInfo *mai, const MCRegisterInfo *mri, const MCObjectFileInfo *mofi, const SourceMgr *mgr, bool DoAutoReset) : SrcMgr(mgr), MAI(mai), MRI(mri), MOFI(mofi), Allocator(), - Symbols(Allocator), UsedNames(Allocator), NextUniqueID(0), + Symbols(Allocator), UsedNames(Allocator), CurrentDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0), DwarfLocSeen(false), GenDwarfForAssembly(false), GenDwarfFileNumber(0), DwarfVersion(4), AllowTemporaryLabels(true), DwarfCompileUnitID(0), @@ -53,7 +55,6 @@ MCContext::MCContext(const MCAsmInfo *mai, const MCRegisterInfo *mri, } MCContext::~MCContext() { - if (AutoReset) reset(); @@ -61,7 +62,7 @@ MCContext::~MCContext() { // we don't need to free them here. // If the stream for the .secure_log_unique directive was created free it. - delete (raw_ostream*)SecureLog; + delete (raw_ostream *)SecureLog; } //===----------------------------------------------------------------------===// @@ -69,6 +70,14 @@ MCContext::~MCContext() { //===----------------------------------------------------------------------===// void MCContext::reset() { + // Call the destructors so the fragments are freed + for (auto &I : ELFUniquingMap) + I.second->~MCSectionELF(); + for (auto &I : COFFUniquingMap) + I.second->~MCSectionCOFF(); + for (auto &I : MachOUniquingMap) + I.second->~MCSectionMachO(); + UsedNames.clear(); Symbols.clear(); Allocator.Reset(); @@ -76,17 +85,17 @@ void MCContext::reset() { CompilationDir.clear(); MainFileName.clear(); MCDwarfLineTablesCUMap.clear(); - SectionStartEndSyms.clear(); + SectionsForRanges.clear(); MCGenDwarfLabelEntries.clear(); DwarfDebugFlags = StringRef(); DwarfCompileUnitID = 0; - CurrentDwarfLoc = MCDwarfLoc(0,0,0,DWARF2_FLAG_IS_STMT,0,0); + CurrentDwarfLoc = MCDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0); MachOUniquingMap.clear(); ELFUniquingMap.clear(); COFFUniquingMap.clear(); - NextUniqueID = 0; + NextID.clear(); AllowTemporaryLabels = true; DwarfLocSeen = false; GenDwarfForAssembly = false; @@ -97,13 +106,15 @@ void MCContext::reset() { // Symbol Manipulation //===----------------------------------------------------------------------===// -MCSymbol *MCContext::GetOrCreateSymbol(StringRef Name) { - assert(!Name.empty() && "Normal symbols cannot be unnamed!"); +MCSymbol *MCContext::getOrCreateSymbol(const Twine &Name) { + SmallString<128> NameSV; + StringRef NameRef = Name.toStringRef(NameSV); - MCSymbol *&Sym = Symbols[Name]; + assert(!NameRef.empty() && "Normal symbols cannot be unnamed!"); + MCSymbol *&Sym = Symbols[NameRef]; if (!Sym) - Sym = CreateSymbol(Name); + Sym = CreateSymbol(NameRef, false); return Sym; } @@ -122,7 +133,7 @@ MCSymbol *MCContext::getOrCreateSectionSymbol(const MCSectionELF &Section) { } auto NameIter = UsedNames.insert(std::make_pair(Name, true)).first; - Sym = new (*this) MCSymbol(NameIter->getKey(), /*isTemporary*/ false); + Sym = new (*this) MCSymbol(&*NameIter, /*isTemporary*/ false); if (!OldSym) OldSym = Sym; @@ -130,53 +141,66 @@ MCSymbol *MCContext::getOrCreateSectionSymbol(const MCSectionELF &Section) { return Sym; } -MCSymbol *MCContext::getOrCreateFrameAllocSymbol(StringRef FuncName) { - return GetOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + - "frameallocation_" + FuncName); +MCSymbol *MCContext::getOrCreateFrameAllocSymbol(StringRef FuncName, + unsigned Idx) { + return getOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + FuncName + + "$frame_escape_" + Twine(Idx)); } -MCSymbol *MCContext::CreateSymbol(StringRef Name) { +MCSymbol *MCContext::getOrCreateParentFrameOffsetSymbol(StringRef FuncName) { + return getOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + FuncName + + "$parent_frame_offset"); +} + +MCSymbol *MCContext::getOrCreateLSDASymbol(StringRef FuncName) { + return getOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + "__ehtable$" + + FuncName); +} + +MCSymbol *MCContext::CreateSymbol(StringRef Name, bool AlwaysAddSuffix) { // Determine whether this is an assembler temporary or normal label, if used. - bool isTemporary = false; + bool IsTemporary = false; if (AllowTemporaryLabels) - isTemporary = Name.startswith(MAI->getPrivateGlobalPrefix()); + IsTemporary = Name.startswith(MAI->getPrivateGlobalPrefix()); + + if (IsTemporary && AlwaysAddSuffix && !UseNamesOnTempLabels) + return new (*this) MCSymbol(nullptr, true); - auto NameEntry = UsedNames.insert(std::make_pair(Name, true)); - if (!NameEntry.second) { - assert(isTemporary && "Cannot rename non-temporary symbols"); - SmallString<128> NewName = Name; - do { + SmallString<128> NewName = Name; + bool AddSuffix = AlwaysAddSuffix; + unsigned &NextUniqueID = NextID[Name]; + for (;;) { + if (AddSuffix) { NewName.resize(Name.size()); raw_svector_ostream(NewName) << NextUniqueID++; - NameEntry = UsedNames.insert(std::make_pair(NewName, true)); - } while (!NameEntry.second); + } + auto NameEntry = UsedNames.insert(std::make_pair(NewName, true)); + if (NameEntry.second) { + // Ok, we found a name. Have the MCSymbol object itself refer to the copy + // of the string that is embedded in the UsedNames entry. + MCSymbol *Result = new (*this) MCSymbol(&*NameEntry.first, IsTemporary); + return Result; + } + assert(IsTemporary && "Cannot rename non-temporary symbols"); + AddSuffix = true; } - - // Ok, the entry doesn't already exist. Have the MCSymbol object itself refer - // to the copy of the string that is embedded in the UsedNames entry. - MCSymbol *Result = - new (*this) MCSymbol(NameEntry.first->getKey(), isTemporary); - - return Result; + llvm_unreachable("Infinite loop"); } -MCSymbol *MCContext::GetOrCreateSymbol(const Twine &Name) { +MCSymbol *MCContext::createTempSymbol(const Twine &Name, bool AlwaysAddSuffix) { SmallString<128> NameSV; - return GetOrCreateSymbol(Name.toStringRef(NameSV)); + raw_svector_ostream(NameSV) << MAI->getPrivateGlobalPrefix() << Name; + return CreateSymbol(NameSV, AlwaysAddSuffix); } -MCSymbol *MCContext::CreateLinkerPrivateTempSymbol() { +MCSymbol *MCContext::createLinkerPrivateTempSymbol() { SmallString<128> NameSV; - raw_svector_ostream(NameSV) - << MAI->getLinkerPrivateGlobalPrefix() << "tmp" << NextUniqueID++; - return CreateSymbol(NameSV); + raw_svector_ostream(NameSV) << MAI->getLinkerPrivateGlobalPrefix() << "tmp"; + return CreateSymbol(NameSV, true); } -MCSymbol *MCContext::CreateTempSymbol() { - SmallString<128> NameSV; - raw_svector_ostream(NameSV) - << MAI->getPrivateGlobalPrefix() << "tmp" << NextUniqueID++; - return CreateSymbol(NameSV); +MCSymbol *MCContext::createTempSymbol() { + return createTempSymbol("tmp", true); } unsigned MCContext::NextInstance(unsigned LocalLabelVal) { @@ -197,16 +221,16 @@ MCSymbol *MCContext::getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal, unsigned Instance) { MCSymbol *&Sym = LocalSymbols[std::make_pair(LocalLabelVal, Instance)]; if (!Sym) - Sym = CreateTempSymbol(); + Sym = createTempSymbol(); return Sym; } -MCSymbol *MCContext::CreateDirectionalLocalSymbol(unsigned LocalLabelVal) { +MCSymbol *MCContext::createDirectionalLocalSymbol(unsigned LocalLabelVal) { unsigned Instance = NextInstance(LocalLabelVal); return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance); } -MCSymbol *MCContext::GetDirectionalLocalSymbol(unsigned LocalLabelVal, +MCSymbol *MCContext::getDirectionalLocalSymbol(unsigned LocalLabelVal, bool Before) { unsigned Instance = GetInstance(LocalLabelVal); if (!Before) @@ -214,24 +238,20 @@ MCSymbol *MCContext::GetDirectionalLocalSymbol(unsigned LocalLabelVal, return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance); } -MCSymbol *MCContext::LookupSymbol(StringRef Name) const { - return Symbols.lookup(Name); -} - -MCSymbol *MCContext::LookupSymbol(const Twine &Name) const { +MCSymbol *MCContext::lookupSymbol(const Twine &Name) const { SmallString<128> NameSV; - Name.toVector(NameSV); - return LookupSymbol(NameSV.str()); + StringRef NameRef = Name.toStringRef(NameSV); + return Symbols.lookup(NameRef); } //===----------------------------------------------------------------------===// // Section Management //===----------------------------------------------------------------------===// -const MCSectionMachO *MCContext:: -getMachOSection(StringRef Segment, StringRef Section, - unsigned TypeAndAttributes, - unsigned Reserved2, SectionKind Kind) { +MCSectionMachO *MCContext::getMachOSection(StringRef Segment, StringRef Section, + unsigned TypeAndAttributes, + unsigned Reserved2, SectionKind Kind, + const char *BeginSymName) { // We unique sections by their segment/section pair. The returned section // may not have the same flags as the requested section, if so this should be @@ -244,107 +264,149 @@ getMachOSection(StringRef Segment, StringRef Section, Name += Section; // Do the lookup, if we have a hit, return it. - const MCSectionMachO *&Entry = MachOUniquingMap[Name.str()]; - if (Entry) return Entry; + MCSectionMachO *&Entry = MachOUniquingMap[Name]; + if (Entry) + return Entry; + + MCSymbol *Begin = nullptr; + if (BeginSymName) + Begin = createTempSymbol(BeginSymName, false); // Otherwise, return a new section. return Entry = new (*this) MCSectionMachO(Segment, Section, TypeAndAttributes, - Reserved2, Kind); -} - -const MCSectionELF *MCContext:: -getELFSection(StringRef Section, unsigned Type, unsigned Flags, - SectionKind Kind) { - return getELFSection(Section, Type, Flags, Kind, 0, ""); + Reserved2, Kind, Begin); } -void MCContext::renameELFSection(const MCSectionELF *Section, StringRef Name) { +void MCContext::renameELFSection(MCSectionELF *Section, StringRef Name) { StringRef GroupName; if (const MCSymbol *Group = Section->getGroup()) GroupName = Group->getName(); - ELFUniquingMap.erase(SectionGroupPair(Section->getSectionName(), GroupName)); - auto I = - ELFUniquingMap.insert(std::make_pair(SectionGroupPair(Name, GroupName), - Section)).first; - StringRef CachedName = I->first.first; - const_cast<MCSectionELF*>(Section)->setSectionName(CachedName); + unsigned UniqueID = Section->getUniqueID(); + ELFUniquingMap.erase( + ELFSectionKey{Section->getSectionName(), GroupName, UniqueID}); + auto I = ELFUniquingMap.insert(std::make_pair( + ELFSectionKey{Name, GroupName, UniqueID}, + Section)) + .first; + StringRef CachedName = I->first.SectionName; + const_cast<MCSectionELF *>(Section)->setSectionName(CachedName); +} + +MCSectionELF *MCContext::createELFRelSection(StringRef Name, unsigned Type, + unsigned Flags, unsigned EntrySize, + const MCSymbol *Group, + const MCSectionELF *Associated) { + StringMap<bool>::iterator I; + bool Inserted; + std::tie(I, Inserted) = ELFRelSecNames.insert(std::make_pair(Name, true)); + + return new (*this) + MCSectionELF(I->getKey(), Type, Flags, SectionKind::getReadOnly(), + EntrySize, Group, true, nullptr, Associated); } -const MCSectionELF *MCContext:: -getELFSection(StringRef Section, unsigned Type, unsigned Flags, - SectionKind Kind, unsigned EntrySize, StringRef Group) { +MCSectionELF *MCContext::getELFSection(StringRef Section, unsigned Type, + unsigned Flags, unsigned EntrySize, + StringRef Group, unsigned UniqueID, + const char *BeginSymName) { + MCSymbol *GroupSym = nullptr; + if (!Group.empty()) + GroupSym = getOrCreateSymbol(Group); + + return getELFSection(Section, Type, Flags, EntrySize, GroupSym, UniqueID, + BeginSymName, nullptr); +} + +MCSectionELF *MCContext::getELFSection(StringRef Section, unsigned Type, + unsigned Flags, unsigned EntrySize, + const MCSymbol *GroupSym, + unsigned UniqueID, + const char *BeginSymName, + const MCSectionELF *Associated) { + StringRef Group = ""; + if (GroupSym) + Group = GroupSym->getName(); // Do the lookup, if we have a hit, return it. auto IterBool = ELFUniquingMap.insert( - std::make_pair(SectionGroupPair(Section, Group), nullptr)); + std::make_pair(ELFSectionKey{Section, Group, UniqueID}, nullptr)); auto &Entry = *IterBool.first; - if (!IterBool.second) return Entry.second; + if (!IterBool.second) + return Entry.second; - // Possibly refine the entry size first. - if (!EntrySize) { - EntrySize = MCSectionELF::DetermineEntrySize(Kind); - } + StringRef CachedName = Entry.first.SectionName; - MCSymbol *GroupSym = nullptr; - if (!Group.empty()) - GroupSym = GetOrCreateSymbol(Group); + SectionKind Kind; + if (Flags & ELF::SHF_EXECINSTR) + Kind = SectionKind::getText(); + else + Kind = SectionKind::getReadOnly(); - StringRef CachedName = Entry.first.first; - MCSectionELF *Result = new (*this) - MCSectionELF(CachedName, Type, Flags, Kind, EntrySize, GroupSym); + MCSymbol *Begin = nullptr; + if (BeginSymName) + Begin = createTempSymbol(BeginSymName, false); + + MCSectionELF *Result = + new (*this) MCSectionELF(CachedName, Type, Flags, Kind, EntrySize, + GroupSym, UniqueID, Begin, Associated); Entry.second = Result; return Result; } -const MCSectionELF *MCContext::CreateELFGroupSection() { - MCSectionELF *Result = - new (*this) MCSectionELF(".group", ELF::SHT_GROUP, 0, - SectionKind::getReadOnly(), 4, nullptr); +MCSectionELF *MCContext::createELFGroupSection(const MCSymbol *Group) { + MCSectionELF *Result = new (*this) + MCSectionELF(".group", ELF::SHT_GROUP, 0, SectionKind::getReadOnly(), 4, + Group, ~0, nullptr, nullptr); return Result; } -const MCSectionCOFF *MCContext::getCOFFSection(StringRef Section, - unsigned Characteristics, - SectionKind Kind, - StringRef COMDATSymName, - int Selection) { - // Do the lookup, if we have a hit, return it. +MCSectionCOFF *MCContext::getCOFFSection(StringRef Section, + unsigned Characteristics, + SectionKind Kind, + StringRef COMDATSymName, int Selection, + const char *BeginSymName) { + MCSymbol *COMDATSymbol = nullptr; + if (!COMDATSymName.empty()) { + COMDATSymbol = getOrCreateSymbol(COMDATSymName); + COMDATSymName = COMDATSymbol->getName(); + } - SectionGroupTriple T(Section, COMDATSymName, Selection); + // Do the lookup, if we have a hit, return it. + COFFSectionKey T{Section, COMDATSymName, Selection}; auto IterBool = COFFUniquingMap.insert(std::make_pair(T, nullptr)); auto Iter = IterBool.first; if (!IterBool.second) return Iter->second; - MCSymbol *COMDATSymbol = nullptr; - if (!COMDATSymName.empty()) - COMDATSymbol = GetOrCreateSymbol(COMDATSymName); + MCSymbol *Begin = nullptr; + if (BeginSymName) + Begin = createTempSymbol(BeginSymName, false); - StringRef CachedName = std::get<0>(Iter->first); - MCSectionCOFF *Result = new (*this) - MCSectionCOFF(CachedName, Characteristics, COMDATSymbol, Selection, Kind); + StringRef CachedName = Iter->first.SectionName; + MCSectionCOFF *Result = new (*this) MCSectionCOFF( + CachedName, Characteristics, COMDATSymbol, Selection, Kind, Begin); Iter->second = Result; return Result; } -const MCSectionCOFF * -MCContext::getCOFFSection(StringRef Section, unsigned Characteristics, - SectionKind Kind) { - return getCOFFSection(Section, Characteristics, Kind, "", 0); +MCSectionCOFF *MCContext::getCOFFSection(StringRef Section, + unsigned Characteristics, + SectionKind Kind, + const char *BeginSymName) { + return getCOFFSection(Section, Characteristics, Kind, "", 0, BeginSymName); } -const MCSectionCOFF *MCContext::getCOFFSection(StringRef Section) { - SectionGroupTriple T(Section, "", 0); +MCSectionCOFF *MCContext::getCOFFSection(StringRef Section) { + COFFSectionKey T{Section, "", 0}; auto Iter = COFFUniquingMap.find(T); if (Iter == COFFUniquingMap.end()) return nullptr; return Iter->second; } -const MCSectionCOFF * -MCContext::getAssociativeCOFFSection(const MCSectionCOFF *Sec, - const MCSymbol *KeySym) { +MCSectionCOFF *MCContext::getAssociativeCOFFSection(MCSectionCOFF *Sec, + const MCSymbol *KeySym) { // Return the normal section if we don't have to be associative. if (!KeySym) return Sec; @@ -362,11 +424,11 @@ MCContext::getAssociativeCOFFSection(const MCSectionCOFF *Sec, // Dwarf Management //===----------------------------------------------------------------------===// -/// GetDwarfFile - takes a file name an number to place in the dwarf file and +/// getDwarfFile - takes a file name an number to place in the dwarf file and /// directory tables. If the file number has already been allocated it is an /// error and zero is returned and the client reports the error, else the /// allocated file number is returned. The file numbers may be in any order. -unsigned MCContext::GetDwarfFile(StringRef Directory, StringRef FileName, +unsigned MCContext::getDwarfFile(StringRef Directory, StringRef FileName, unsigned FileNumber, unsigned CUID) { MCDwarfLineTable &Table = MCDwarfLineTablesCUMap[CUID]; return Table.getFile(Directory, FileName, FileNumber); @@ -375,37 +437,26 @@ unsigned MCContext::GetDwarfFile(StringRef Directory, StringRef FileName, /// isValidDwarfFileNumber - takes a dwarf file number and returns true if it /// currently is assigned and false otherwise. bool MCContext::isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID) { - const SmallVectorImpl<MCDwarfFile>& MCDwarfFiles = getMCDwarfFiles(CUID); - if(FileNumber == 0 || FileNumber >= MCDwarfFiles.size()) + const SmallVectorImpl<MCDwarfFile> &MCDwarfFiles = getMCDwarfFiles(CUID); + if (FileNumber == 0 || FileNumber >= MCDwarfFiles.size()) return false; return !MCDwarfFiles[FileNumber].Name.empty(); } -/// finalizeDwarfSections - Emit end symbols for each non-empty code section. -/// Also remove empty sections from SectionStartEndSyms, to avoid generating +/// Remove empty sections from SectionStartEndSyms, to avoid generating /// useless debug info for them. void MCContext::finalizeDwarfSections(MCStreamer &MCOS) { - MCContext &context = MCOS.getContext(); - - auto sec = SectionStartEndSyms.begin(); - while (sec != SectionStartEndSyms.end()) { - assert(sec->second.first && "Start symbol must be set by now"); - MCOS.SwitchSection(sec->first); - if (MCOS.mayHaveInstructions()) { - MCSymbol *SectionEndSym = context.CreateTempSymbol(); - MCOS.EmitLabel(SectionEndSym); - sec->second.second = SectionEndSym; - ++sec; - } else { - MapVector<const MCSection *, std::pair<MCSymbol *, MCSymbol *> >::iterator - to_erase = sec; - sec = SectionStartEndSyms.erase(to_erase); - } + std::vector<MCSection *> Keep; + for (MCSection *Sec : SectionsForRanges) { + if (MCOS.mayHaveInstructions(*Sec)) + Keep.push_back(Sec); } + SectionsForRanges.clear(); + SectionsForRanges.insert(Keep.begin(), Keep.end()); } -void MCContext::FatalError(SMLoc Loc, const Twine &Msg) const { +void MCContext::reportFatalError(SMLoc Loc, const Twine &Msg) const { // If we have a source manager and a location, use it. Otherwise just // use the generic report_fatal_error(). if (!SrcMgr || Loc == SMLoc()) diff --git a/contrib/llvm/lib/MC/MCDisassembler/Disassembler.cpp b/contrib/llvm/lib/MC/MCDisassembler/Disassembler.cpp index d27d83b..716d76a 100644 --- a/contrib/llvm/lib/MC/MCDisassembler/Disassembler.cpp +++ b/contrib/llvm/lib/MC/MCDisassembler/Disassembler.cpp @@ -33,22 +33,22 @@ using namespace llvm; // disassembler context. If not, it returns NULL. // LLVMDisasmContextRef -LLVMCreateDisasmCPUFeatures(const char *Triple, const char *CPU, +LLVMCreateDisasmCPUFeatures(const char *TT, const char *CPU, const char *Features, void *DisInfo, int TagType, LLVMOpInfoCallback GetOpInfo, LLVMSymbolLookupCallback SymbolLookUp) { // Get the target. std::string Error; - const Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error); + const Target *TheTarget = TargetRegistry::lookupTarget(TT, Error); if (!TheTarget) return nullptr; - const MCRegisterInfo *MRI = TheTarget->createMCRegInfo(Triple); + const MCRegisterInfo *MRI = TheTarget->createMCRegInfo(TT); if (!MRI) return nullptr; // Get the assembler info needed to setup the MCContext. - const MCAsmInfo *MAI = TheTarget->createMCAsmInfo(*MRI, Triple); + const MCAsmInfo *MAI = TheTarget->createMCAsmInfo(*MRI, TT); if (!MAI) return nullptr; @@ -56,8 +56,8 @@ LLVMCreateDisasmCPUFeatures(const char *Triple, const char *CPU, if (!MII) return nullptr; - const MCSubtargetInfo *STI = TheTarget->createMCSubtargetInfo(Triple, CPU, - Features); + const MCSubtargetInfo *STI = + TheTarget->createMCSubtargetInfo(TT, CPU, Features); if (!STI) return nullptr; @@ -72,25 +72,24 @@ LLVMCreateDisasmCPUFeatures(const char *Triple, const char *CPU, return nullptr; std::unique_ptr<MCRelocationInfo> RelInfo( - TheTarget->createMCRelocationInfo(Triple, *Ctx)); + TheTarget->createMCRelocationInfo(TT, *Ctx)); if (!RelInfo) return nullptr; std::unique_ptr<MCSymbolizer> Symbolizer(TheTarget->createMCSymbolizer( - Triple, GetOpInfo, SymbolLookUp, DisInfo, Ctx, RelInfo.release())); + TT, GetOpInfo, SymbolLookUp, DisInfo, Ctx, std::move(RelInfo))); DisAsm->setSymbolizer(std::move(Symbolizer)); // Set up the instruction printer. int AsmPrinterVariant = MAI->getAssemblerDialect(); - MCInstPrinter *IP = TheTarget->createMCInstPrinter(AsmPrinterVariant, - *MAI, *MII, *MRI, *STI); + MCInstPrinter *IP = TheTarget->createMCInstPrinter( + Triple(TT), AsmPrinterVariant, *MAI, *MII, *MRI); if (!IP) return nullptr; - LLVMDisasmContext *DC = new LLVMDisasmContext(Triple, DisInfo, TagType, - GetOpInfo, SymbolLookUp, - TheTarget, MAI, MRI, - STI, MII, Ctx, DisAsm, IP); + LLVMDisasmContext *DC = + new LLVMDisasmContext(TT, DisInfo, TagType, GetOpInfo, SymbolLookUp, + TheTarget, MAI, MRI, STI, MII, Ctx, DisAsm, IP); if (!DC) return nullptr; @@ -98,19 +97,19 @@ LLVMCreateDisasmCPUFeatures(const char *Triple, const char *CPU, return DC; } -LLVMDisasmContextRef LLVMCreateDisasmCPU(const char *Triple, const char *CPU, - void *DisInfo, int TagType, - LLVMOpInfoCallback GetOpInfo, - LLVMSymbolLookupCallback SymbolLookUp){ - return LLVMCreateDisasmCPUFeatures(Triple, CPU, "", DisInfo, TagType, - GetOpInfo, SymbolLookUp); +LLVMDisasmContextRef +LLVMCreateDisasmCPU(const char *TT, const char *CPU, void *DisInfo, int TagType, + LLVMOpInfoCallback GetOpInfo, + LLVMSymbolLookupCallback SymbolLookUp) { + return LLVMCreateDisasmCPUFeatures(TT, CPU, "", DisInfo, TagType, GetOpInfo, + SymbolLookUp); } -LLVMDisasmContextRef LLVMCreateDisasm(const char *Triple, void *DisInfo, +LLVMDisasmContextRef LLVMCreateDisasm(const char *TT, void *DisInfo, int TagType, LLVMOpInfoCallback GetOpInfo, LLVMSymbolLookupCallback SymbolLookUp) { - return LLVMCreateDisasmCPUFeatures(Triple, "", "", DisInfo, TagType, - GetOpInfo, SymbolLookUp); + return LLVMCreateDisasmCPUFeatures(TT, "", "", DisInfo, TagType, GetOpInfo, + SymbolLookUp); } // @@ -268,7 +267,7 @@ size_t LLVMDisasmInstruction(LLVMDisasmContextRef DCR, uint8_t *Bytes, SmallVector<char, 64> InsnStr; raw_svector_ostream OS(InsnStr); formatted_raw_ostream FormattedOS(OS); - IP->printInst(&Inst, FormattedOS, AnnotationsStr); + IP->printInst(&Inst, FormattedOS, AnnotationsStr, *DC->getSubtargetInfo()); if (DC->getOptions() & LLVMDisassembler_Option_PrintLatency) emitLatency(DC, Inst); @@ -312,11 +311,10 @@ int LLVMSetDisasmOptions(LLVMDisasmContextRef DCR, uint64_t Options){ const MCAsmInfo *MAI = DC->getAsmInfo(); const MCInstrInfo *MII = DC->getInstrInfo(); const MCRegisterInfo *MRI = DC->getRegisterInfo(); - const MCSubtargetInfo *STI = DC->getSubtargetInfo(); int AsmPrinterVariant = MAI->getAssemblerDialect(); AsmPrinterVariant = AsmPrinterVariant == 0 ? 1 : 0; MCInstPrinter *IP = DC->getTarget()->createMCInstPrinter( - AsmPrinterVariant, *MAI, *MII, *MRI, *STI); + Triple(DC->getTripleName()), AsmPrinterVariant, *MAI, *MII, *MRI); if (IP) { DC->setIP(IP); DC->addOptions(LLVMDisassembler_Option_AsmPrinterVariant); diff --git a/contrib/llvm/lib/MC/MCDisassembler/MCExternalSymbolizer.cpp b/contrib/llvm/lib/MC/MCDisassembler/MCExternalSymbolizer.cpp index 0145623..1262e2a 100644 --- a/contrib/llvm/lib/MC/MCDisassembler/MCExternalSymbolizer.cpp +++ b/contrib/llvm/lib/MC/MCDisassembler/MCExternalSymbolizer.cpp @@ -87,7 +87,7 @@ bool MCExternalSymbolizer::tryAddingSymbolicOperand(MCInst &MI, if (SymbolicOp.AddSymbol.Present) { if (SymbolicOp.AddSymbol.Name) { StringRef Name(SymbolicOp.AddSymbol.Name); - MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name); + MCSymbol *Sym = Ctx.getOrCreateSymbol(Name); Add = MCSymbolRefExpr::Create(Sym, Ctx); } else { Add = MCConstantExpr::Create((int)SymbolicOp.AddSymbol.Value, Ctx); @@ -98,7 +98,7 @@ bool MCExternalSymbolizer::tryAddingSymbolicOperand(MCInst &MI, if (SymbolicOp.SubtractSymbol.Present) { if (SymbolicOp.SubtractSymbol.Name) { StringRef Name(SymbolicOp.SubtractSymbol.Name); - MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name); + MCSymbol *Sym = Ctx.getOrCreateSymbol(Name); Sub = MCSymbolRefExpr::Create(Sym, Ctx); } else { Sub = MCConstantExpr::Create((int)SymbolicOp.SubtractSymbol.Value, Ctx); @@ -136,7 +136,7 @@ bool MCExternalSymbolizer::tryAddingSymbolicOperand(MCInst &MI, if (!Expr) return false; - MI.addOperand(MCOperand::CreateExpr(Expr)); + MI.addOperand(MCOperand::createExpr(Expr)); return true; } @@ -186,13 +186,11 @@ void MCExternalSymbolizer::tryAddingPcLoadReferenceComment(raw_ostream &cStream, namespace llvm { MCSymbolizer *createMCSymbolizer(StringRef TT, LLVMOpInfoCallback GetOpInfo, LLVMSymbolLookupCallback SymbolLookUp, - void *DisInfo, - MCContext *Ctx, - MCRelocationInfo *RelInfo) { + void *DisInfo, MCContext *Ctx, + std::unique_ptr<MCRelocationInfo> &&RelInfo) { assert(Ctx && "No MCContext given for symbolic disassembly"); - return new MCExternalSymbolizer(*Ctx, - std::unique_ptr<MCRelocationInfo>(RelInfo), - GetOpInfo, SymbolLookUp, DisInfo); + return new MCExternalSymbolizer(*Ctx, std::move(RelInfo), GetOpInfo, + SymbolLookUp, DisInfo); } } diff --git a/contrib/llvm/lib/MC/MCDwarf.cpp b/contrib/llvm/lib/MC/MCDwarf.cpp index 5effb01..a7e83f6 100644 --- a/contrib/llvm/lib/MC/MCDwarf.cpp +++ b/contrib/llvm/lib/MC/MCDwarf.cpp @@ -64,12 +64,12 @@ static inline uint64_t ScaleAddrDelta(MCContext &Context, uint64_t AddrDelta) { // and if there is information from the last .loc directive that has yet to have // a line entry made for it is made. // -void MCLineEntry::Make(MCObjectStreamer *MCOS, const MCSection *Section) { +void MCLineEntry::Make(MCObjectStreamer *MCOS, MCSection *Section) { if (!MCOS->getContext().getDwarfLocSeen()) return; // Create a symbol at in the current section for use in the line entry. - MCSymbol *LineSym = MCOS->getContext().CreateTempSymbol(); + MCSymbol *LineSym = MCOS->getContext().createTempSymbol(); // Set the value of the symbol to use for the MCLineEntry. MCOS->EmitLabel(LineSym); @@ -80,7 +80,7 @@ void MCLineEntry::Make(MCObjectStreamer *MCOS, const MCSection *Section) { MCLineEntry LineEntry(LineSym, DwarfLoc); // clear DwarfLocSeen saying the current .loc info is now used. - MCOS->getContext().ClearDwarfLocSeen(); + MCOS->getContext().clearDwarfLocSeen(); // Add the line entry to this section's entries. MCOS->getContext() @@ -115,7 +115,7 @@ static inline const MCExpr *MakeStartMinusEndExpr(const MCStreamer &MCOS, // in the LineSection. // static inline void -EmitDwarfLineTable(MCObjectStreamer *MCOS, const MCSection *Section, +EmitDwarfLineTable(MCObjectStreamer *MCOS, MCSection *Section, const MCLineSection::MCLineEntryCollection &LineEntries) { unsigned FileNum = 1; unsigned LastLine = 1; @@ -179,28 +179,19 @@ EmitDwarfLineTable(MCObjectStreamer *MCOS, const MCSection *Section, } // Emit a DW_LNE_end_sequence for the end of the section. - // Using the pointer Section create a temporary label at the end of the - // section and use that and the LastLabel to compute the address delta - // and use INT64_MAX as the line delta which is the signal that this is - // actually a DW_LNE_end_sequence. + // Use the section end label to compute the address delta and use INT64_MAX + // as the line delta which is the signal that this is actually a + // DW_LNE_end_sequence. + MCSymbol *SectionEnd = MCOS->endSection(Section); - // Switch to the section to be able to create a symbol at its end. - // TODO: keep track of the last subsection so that this symbol appears in the - // correct place. - MCOS->SwitchSection(Section); + // Switch back the dwarf line section, in case endSection had to switch the + // section. + MCContext &Ctx = MCOS->getContext(); + MCOS->SwitchSection(Ctx.getObjectFileInfo()->getDwarfLineSection()); - MCContext &context = MCOS->getContext(); - // Create a symbol at the end of the section. - MCSymbol *SectionEnd = context.CreateTempSymbol(); - // Set the value of the symbol, as we are at the end of the section. - MCOS->EmitLabel(SectionEnd); - - // Switch back the dwarf line section. - MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfLineSection()); - - const MCAsmInfo *asmInfo = MCOS->getContext().getAsmInfo(); + const MCAsmInfo *AsmInfo = Ctx.getAsmInfo(); MCOS->EmitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, SectionEnd, - asmInfo->getPointerSize()); + AsmInfo->getPointerSize()); } // @@ -243,7 +234,8 @@ std::pair<MCSymbol *, MCSymbol *> MCDwarfLineTableHeader::Emit(MCStreamer *MCOS) 0, // length of DW_LNS_set_epilogue_begin 1 // DW_LNS_set_isa }; - assert(array_lengthof(StandardOpcodeLengths) == (DWARF2_LINE_OPCODE_BASE - 1)); + assert(array_lengthof(StandardOpcodeLengths) == + (DWARF2_LINE_OPCODE_BASE - 1)); return Emit(MCOS, StandardOpcodeLengths); } @@ -253,7 +245,7 @@ static const MCExpr *forceExpAbs(MCStreamer &OS, const MCExpr* Expr) { if (Context.getAsmInfo()->hasAggressiveSymbolFolding()) return Expr; - MCSymbol *ABS = Context.CreateTempSymbol(); + MCSymbol *ABS = Context.createTempSymbol(); OS.EmitAssignment(ABS, Expr); return MCSymbolRefExpr::Create(ABS, Context); } @@ -272,12 +264,12 @@ MCDwarfLineTableHeader::Emit(MCStreamer *MCOS, // Create a symbol at the beginning of the line table. MCSymbol *LineStartSym = Label; if (!LineStartSym) - LineStartSym = context.CreateTempSymbol(); + LineStartSym = context.createTempSymbol(); // Set the value of the symbol, as we are at the start of the line table. MCOS->EmitLabel(LineStartSym); // Create a symbol for the end of the section (to be set when we get there). - MCSymbol *LineEndSym = context.CreateTempSymbol(); + MCSymbol *LineEndSym = context.createTempSymbol(); // The first 4 bytes is the total length of the information for this // compilation unit (not including these 4 bytes for the length). @@ -288,7 +280,7 @@ MCDwarfLineTableHeader::Emit(MCStreamer *MCOS, MCOS->EmitIntValue(2, 2); // Create a symbol for the end of the prologue (to be set when we get there). - MCSymbol *ProEndSym = context.CreateTempSymbol(); // Lprologue_end + MCSymbol *ProEndSym = context.createTempSymbol(); // Lprologue_end // Length of the prologue, is the next 4 bytes. Which is the start of the // section to the end of the prologue. Not including the 4 bytes for the @@ -368,8 +360,10 @@ unsigned MCDwarfLineTableHeader::getFile(StringRef &Directory, FileNumber = SourceIdMap.size() + 1; assert((MCDwarfFiles.empty() || FileNumber == MCDwarfFiles.size()) && "Don't mix autonumbered and explicit numbered line table usage"); + SmallString<256> Buffer; auto IterBool = SourceIdMap.insert( - std::make_pair((Directory + Twine('\0') + FileName).str(), FileNumber)); + std::make_pair((Directory + Twine('\0') + FileName).toStringRef(Buffer), + FileNumber)); if (!IterBool.second) return IterBool.first->second; } @@ -446,7 +440,7 @@ void MCDwarfLineAddr::Encode(MCContext &Context, int64_t LineDelta, if (LineDelta == INT64_MAX) { if (AddrDelta == MAX_SPECIAL_ADDR_DELTA) OS << char(dwarf::DW_LNS_const_add_pc); - else { + else if (AddrDelta) { OS << char(dwarf::DW_LNS_advance_pc); encodeULEB128(AddrDelta, OS); } @@ -616,9 +610,9 @@ static void EmitGenDwarfAranges(MCStreamer *MCOS, // Now emit the table of pairs of PointerSize'ed values for the section // addresses and sizes. - for (const auto &sec : Sections) { - MCSymbol *StartSymbol = sec.second.first; - MCSymbol *EndSymbol = sec.second.second; + for (MCSection *Sec : Sections) { + const MCSymbol *StartSymbol = Sec->getBeginSymbol(); + MCSymbol *EndSymbol = Sec->getEndSymbol(context); assert(StartSymbol && "StartSymbol must not be NULL"); assert(EndSymbol && "EndSymbol must not be NULL"); @@ -648,9 +642,9 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS, // Create a symbol at the start and end of this section used in here for the // expression to calculate the length in the header. - MCSymbol *InfoStart = context.CreateTempSymbol(); + MCSymbol *InfoStart = context.createTempSymbol(); MCOS->EmitLabel(InfoStart); - MCSymbol *InfoEnd = context.CreateTempSymbol(); + MCSymbol *InfoEnd = context.createTempSymbol(); // First part: the header. @@ -705,8 +699,8 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS, const auto TextSection = Sections.begin(); assert(TextSection != Sections.end() && "No text section found"); - MCSymbol *StartSymbol = TextSection->second.first; - MCSymbol *EndSymbol = TextSection->second.second; + MCSymbol *StartSymbol = (*TextSection)->getBeginSymbol(); + MCSymbol *EndSymbol = (*TextSection)->getEndSymbol(context); assert(StartSymbol && "StartSymbol must not be NULL"); assert(EndSymbol && "EndSymbol must not be NULL"); @@ -811,10 +805,9 @@ static void EmitGenDwarfRanges(MCStreamer *MCOS) { MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfRangesSection()); - for (const auto sec : Sections) { - - MCSymbol *StartSymbol = sec.second.first; - MCSymbol *EndSymbol = sec.second.second; + for (MCSection *Sec : Sections) { + const MCSymbol *StartSymbol = Sec->getBeginSymbol(); + MCSymbol *EndSymbol = Sec->getEndSymbol(context); assert(StartSymbol && "StartSymbol must not be NULL"); assert(EndSymbol && "EndSymbol must not be NULL"); @@ -871,18 +864,18 @@ void MCGenDwarfInfo::Emit(MCStreamer *MCOS) { MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfInfoSection()); if (CreateDwarfSectionSymbols) { - InfoSectionSymbol = context.CreateTempSymbol(); + InfoSectionSymbol = context.createTempSymbol(); MCOS->EmitLabel(InfoSectionSymbol); } MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfAbbrevSection()); if (CreateDwarfSectionSymbols) { - AbbrevSectionSymbol = context.CreateTempSymbol(); + AbbrevSectionSymbol = context.createTempSymbol(); MCOS->EmitLabel(AbbrevSectionSymbol); } if (UseRangesSection) { MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfRangesSection()); if (CreateDwarfSectionSymbols) { - RangesSectionSymbol = context.CreateTempSymbol(); + RangesSectionSymbol = context.createTempSymbol(); MCOS->EmitLabel(RangesSectionSymbol); } } @@ -940,7 +933,7 @@ void MCGenDwarfLabelEntry::Make(MCSymbol *Symbol, MCStreamer *MCOS, // values so that they don't have things like an ARM thumb bit from the // original symbol. So when used they won't get a low bit set after // relocation. - MCSymbol *Label = context.CreateTempSymbol(); + MCSymbol *Label = context.createTempSymbol(); MCOS->EmitLabel(Label); // Create and entry for the info and add it to the other entries. @@ -1007,11 +1000,13 @@ static void EmitPersonality(MCStreamer &streamer, const MCSymbol &symbol, namespace { class FrameEmitterImpl { int CFAOffset; + int InitialCFAOffset; bool IsEH; const MCSymbol *SectionStart; public: FrameEmitterImpl(bool isEH) - : CFAOffset(0), IsEH(isEH), SectionStart(nullptr) {} + : CFAOffset(0), InitialCFAOffset(0), IsEH(isEH), SectionStart(nullptr) { + } void setSectionStart(const MCSymbol *Label) { SectionStart = Label; } @@ -1045,11 +1040,16 @@ static void emitEncodingByte(MCObjectStreamer &Streamer, unsigned Encoding) { void FrameEmitterImpl::EmitCFIInstruction(MCObjectStreamer &Streamer, const MCCFIInstruction &Instr) { int dataAlignmentFactor = getDataAlignmentFactor(Streamer); + auto *MRI = Streamer.getContext().getRegisterInfo(); switch (Instr.getOperation()) { case MCCFIInstruction::OpRegister: { unsigned Reg1 = Instr.getRegister(); unsigned Reg2 = Instr.getRegister2(); + if (!IsEH) { + Reg1 = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg1, true), false); + Reg2 = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg2, true), false); + } Streamer.EmitIntValue(dwarf::DW_CFA_register, 1); Streamer.EmitULEB128IntValue(Reg1); Streamer.EmitULEB128IntValue(Reg2); @@ -1082,8 +1082,11 @@ void FrameEmitterImpl::EmitCFIInstruction(MCObjectStreamer &Streamer, return; } case MCCFIInstruction::OpDefCfa: { + unsigned Reg = Instr.getRegister(); + if (!IsEH) + Reg = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg, true), false); Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa, 1); - Streamer.EmitULEB128IntValue(Instr.getRegister()); + Streamer.EmitULEB128IntValue(Reg); CFAOffset = -Instr.getOffset(); Streamer.EmitULEB128IntValue(CFAOffset); @@ -1091,8 +1094,11 @@ void FrameEmitterImpl::EmitCFIInstruction(MCObjectStreamer &Streamer, } case MCCFIInstruction::OpDefCfaRegister: { + unsigned Reg = Instr.getRegister(); + if (!IsEH) + Reg = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg, true), false); Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_register, 1); - Streamer.EmitULEB128IntValue(Instr.getRegister()); + Streamer.EmitULEB128IntValue(Reg); return; } @@ -1103,6 +1109,9 @@ void FrameEmitterImpl::EmitCFIInstruction(MCObjectStreamer &Streamer, Instr.getOperation() == MCCFIInstruction::OpRelOffset; unsigned Reg = Instr.getRegister(); + if (!IsEH) + Reg = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg, true), false); + int Offset = Instr.getOffset(); if (IsRelative) Offset -= CFAOffset; @@ -1136,6 +1145,8 @@ void FrameEmitterImpl::EmitCFIInstruction(MCObjectStreamer &Streamer, } case MCCFIInstruction::OpRestore: { unsigned Reg = Instr.getRegister(); + if (!IsEH) + Reg = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg, true), false); Streamer.EmitIntValue(dwarf::DW_CFA_restore | Reg, 1); return; } @@ -1234,6 +1245,20 @@ void FrameEmitterImpl::EmitCompactUnwind(MCObjectStreamer &Streamer, Streamer.EmitIntValue(0, Size); // No LSDA } +static unsigned getCIEVersion(bool IsEH, unsigned DwarfVersion) { + if (IsEH) + return 1; + switch (DwarfVersion) { + case 2: + return 1; + case 3: + return 3; + case 4: + return 4; + } + llvm_unreachable("Unknown version"); +} + const MCSymbol &FrameEmitterImpl::EmitCIE(MCObjectStreamer &streamer, const MCSymbol *personality, unsigned personalityEncoding, @@ -1245,10 +1270,10 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCObjectStreamer &streamer, const MCRegisterInfo *MRI = context.getRegisterInfo(); const MCObjectFileInfo *MOFI = context.getObjectFileInfo(); - MCSymbol *sectionStart = context.CreateTempSymbol(); + MCSymbol *sectionStart = context.createTempSymbol(); streamer.EmitLabel(sectionStart); - MCSymbol *sectionEnd = context.CreateTempSymbol(); + MCSymbol *sectionEnd = context.createTempSymbol(); // Length const MCExpr *Length = MakeStartMinusEndExpr(streamer, *sectionStart, @@ -1260,9 +1285,7 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCObjectStreamer &streamer, streamer.EmitIntValue(CIE_ID, 4); // Version - // For DWARF2, we use CIE version 1 - // For DWARF3+, we use CIE version 3 - uint8_t CIEVersion = context.getDwarfVersion() <= 2 ? 1 : 3; + uint8_t CIEVersion = getCIEVersion(IsEH, context.getDwarfVersion()); streamer.EmitIntValue(CIEVersion, 1); // Augmentation String @@ -1276,10 +1299,18 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCObjectStreamer &streamer, Augmentation += "R"; if (IsSignalFrame) Augmentation += "S"; - streamer.EmitBytes(Augmentation.str()); + streamer.EmitBytes(Augmentation); } streamer.EmitIntValue(0, 1); + if (CIEVersion >= 4) { + // Address Size + streamer.EmitIntValue(context.getAsmInfo()->getPointerSize(), 1); + + // Segment Descriptor Size + streamer.EmitIntValue(0, 1); + } + // Code Alignment Factor streamer.EmitULEB128IntValue(context.getAsmInfo()->getMinInstAlignment()); @@ -1290,10 +1321,10 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCObjectStreamer &streamer, if (CIEVersion == 1) { assert(MRI->getRARegister() <= 255 && "DWARF 2 encodes return_address_register in one byte"); - streamer.EmitIntValue(MRI->getDwarfRegNum(MRI->getRARegister(), true), 1); + streamer.EmitIntValue(MRI->getDwarfRegNum(MRI->getRARegister(), IsEH), 1); } else { streamer.EmitULEB128IntValue( - MRI->getDwarfRegNum(MRI->getRARegister(), true)); + MRI->getDwarfRegNum(MRI->getRARegister(), IsEH)); } // Augmentation Data Length (optional) @@ -1337,6 +1368,8 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCObjectStreamer &streamer, EmitCFIInstructions(streamer, Instructions, nullptr); } + InitialCFAOffset = CFAOffset; + // Padding streamer.EmitValueToAlignment(IsEH ? 4 : MAI->getPointerSize()); @@ -1348,10 +1381,12 @@ MCSymbol *FrameEmitterImpl::EmitFDE(MCObjectStreamer &streamer, const MCSymbol &cieStart, const MCDwarfFrameInfo &frame) { MCContext &context = streamer.getContext(); - MCSymbol *fdeStart = context.CreateTempSymbol(); - MCSymbol *fdeEnd = context.CreateTempSymbol(); + MCSymbol *fdeStart = context.createTempSymbol(); + MCSymbol *fdeEnd = context.createTempSymbol(); const MCObjectFileInfo *MOFI = context.getObjectFileInfo(); + CFAOffset = InitialCFAOffset; + // Length const MCExpr *Length = MakeStartMinusEndExpr(streamer, *fdeStart, *fdeEnd, 0); emitAbsValue(streamer, Length, 4); @@ -1485,12 +1520,12 @@ void MCDwarfFrameEmitter::Emit(MCObjectStreamer &Streamer, MCAsmBackend *MAB, if (!NeedsEHFrameSection) return; - const MCSection &Section = - IsEH ? *const_cast<MCObjectFileInfo*>(MOFI)->getEHFrameSection() : - *MOFI->getDwarfFrameSection(); + MCSection &Section = + IsEH ? *const_cast<MCObjectFileInfo *>(MOFI)->getEHFrameSection() + : *MOFI->getDwarfFrameSection(); Streamer.SwitchSection(&Section); - MCSymbol *SectionStart = Context.CreateTempSymbol(); + MCSymbol *SectionStart = Context.createTempSymbol(); Streamer.EmitLabel(SectionStart); Emitter.setSectionStart(SectionStart); diff --git a/contrib/llvm/lib/MC/MCELF.cpp b/contrib/llvm/lib/MC/MCELF.cpp index 386c209..3690634 100644 --- a/contrib/llvm/lib/MC/MCELF.cpp +++ b/contrib/llvm/lib/MC/MCELF.cpp @@ -21,7 +21,7 @@ namespace llvm { void MCELF::SetBinding(MCSymbolData &SD, unsigned Binding) { assert(Binding == ELF::STB_LOCAL || Binding == ELF::STB_GLOBAL || - Binding == ELF::STB_WEAK); + Binding == ELF::STB_WEAK || Binding == ELF::STB_GNU_UNIQUE); uint32_t OtherFlags = SD.getFlags() & ~(0xf << ELF_STB_Shift); SD.setFlags(OtherFlags | (Binding << ELF_STB_Shift)); } @@ -29,7 +29,7 @@ void MCELF::SetBinding(MCSymbolData &SD, unsigned Binding) { unsigned MCELF::GetBinding(const MCSymbolData &SD) { uint32_t Binding = (SD.getFlags() & (0xf << ELF_STB_Shift)) >> ELF_STB_Shift; assert(Binding == ELF::STB_LOCAL || Binding == ELF::STB_GLOBAL || - Binding == ELF::STB_WEAK); + Binding == ELF::STB_WEAK || Binding == ELF::STB_GNU_UNIQUE); return Binding; } diff --git a/contrib/llvm/lib/MC/MCELFObjectTargetWriter.cpp b/contrib/llvm/lib/MC/MCELFObjectTargetWriter.cpp index 84176dc..dc3d6c3 100644 --- a/contrib/llvm/lib/MC/MCELFObjectTargetWriter.cpp +++ b/contrib/llvm/lib/MC/MCELFObjectTargetWriter.cpp @@ -28,3 +28,24 @@ bool MCELFObjectTargetWriter::needsRelocateWithSymbol(const MCSymbolData &SD, unsigned Type) const { return false; } + +// ELF doesn't require relocations to be in any order. We sort by the Offset, +// just to match gnu as for easier comparison. The use type is an arbitrary way +// of making the sort deterministic. +static int cmpRel(const ELFRelocationEntry *AP, const ELFRelocationEntry *BP) { + const ELFRelocationEntry &A = *AP; + const ELFRelocationEntry &B = *BP; + if (A.Offset != B.Offset) + return B.Offset - A.Offset; + if (B.Type != A.Type) + return A.Type - B.Type; + //llvm_unreachable("ELFRelocs might be unstable!"); + return 0; +} + + +void +MCELFObjectTargetWriter::sortRelocs(const MCAssembler &Asm, + std::vector<ELFRelocationEntry> &Relocs) { + array_pod_sort(Relocs.begin(), Relocs.end(), cmpRel); +} diff --git a/contrib/llvm/lib/MC/MCELFStreamer.cpp b/contrib/llvm/lib/MC/MCELFStreamer.cpp index bdc4a84..653a1d2 100644 --- a/contrib/llvm/lib/MC/MCELFStreamer.cpp +++ b/contrib/llvm/lib/MC/MCELFStreamer.cpp @@ -15,6 +15,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/MC/MCAsmBackend.h" +#include "llvm/MC/MCAsmLayout.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCCodeEmitter.h" @@ -32,13 +33,60 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/ELF.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/TargetRegistry.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; +bool MCELFStreamer::isBundleLocked() const { + return getCurrentSectionData()->isBundleLocked(); +} + MCELFStreamer::~MCELFStreamer() { } +void MCELFStreamer::mergeFragment(MCDataFragment *DF, + MCEncodedFragmentWithFixups *EF) { + MCAssembler &Assembler = getAssembler(); + + if (Assembler.isBundlingEnabled() && Assembler.getRelaxAll()) { + uint64_t FSize = EF->getContents().size(); + + if (FSize > Assembler.getBundleAlignSize()) + report_fatal_error("Fragment can't be larger than a bundle size"); + + uint64_t RequiredBundlePadding = computeBundlePadding( + Assembler, EF, DF->getContents().size(), FSize); + + if (RequiredBundlePadding > UINT8_MAX) + report_fatal_error("Padding cannot exceed 255 bytes"); + + if (RequiredBundlePadding > 0) { + SmallString<256> Code; + raw_svector_ostream VecOS(Code); + MCObjectWriter *OW = Assembler.getBackend().createObjectWriter(VecOS); + + EF->setBundlePadding(static_cast<uint8_t>(RequiredBundlePadding)); + + Assembler.writeFragmentPadding(*EF, FSize, OW); + VecOS.flush(); + delete OW; + + DF->getContents().append(Code.begin(), Code.end()); + } + } + + flushPendingLabels(DF, DF->getContents().size()); + + for (unsigned i = 0, e = EF->getFixups().size(); i != e; ++i) { + EF->getFixups()[i].setOffset(EF->getFixups()[i].getOffset() + + DF->getContents().size()); + DF->getFixups().push_back(EF->getFixups()[i]); + } + DF->setHasInstructions(true); + DF->getContents().append(EF->getContents().begin(), EF->getContents().end()); +} + void MCELFStreamer::InitSections(bool NoExecStack) { // This emulates the same behavior of GNU as. This makes it easier // to compare the output as the major sections are in the same order. @@ -87,13 +135,24 @@ void MCELFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) { llvm_unreachable("invalid assembler flag!"); } -void MCELFStreamer::ChangeSection(const MCSection *Section, +// If bundle aligment is used and there are any instructions in the section, it +// needs to be aligned to at least the bundle size. +static void setSectionAlignmentForBundling(const MCAssembler &Assembler, + MCSection *Section) { + if (Section && Assembler.isBundlingEnabled() && Section->hasInstructions() && + Section->getAlignment() < Assembler.getBundleAlignSize()) + Section->setAlignment(Assembler.getBundleAlignSize()); +} + +void MCELFStreamer::ChangeSection(MCSection *Section, const MCExpr *Subsection) { - MCSectionData *CurSection = getCurrentSectionData(); - if (CurSection && CurSection->isBundleLocked()) + MCSection *CurSection = getCurrentSectionData(); + if (CurSection && isBundleLocked()) report_fatal_error("Unterminated .bundle_lock when changing a section"); MCAssembler &Asm = getAssembler(); + // Ensure the previous section gets aligned if necessary. + setSectionAlignmentForBundling(Asm, CurSection); auto *SectionELF = static_cast<const MCSectionELF *>(Section); const MCSymbol *Grp = SectionELF->getGroup(); if (Grp) @@ -122,12 +181,11 @@ void MCELFStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) { // If neither T1 < T2 nor T2 < T1 according to this ordering, use T2 (the user // provided type). static unsigned CombineSymbolTypes(unsigned T1, unsigned T2) { - unsigned TypeOrdering[] = {ELF::STT_NOTYPE, ELF::STT_OBJECT, ELF::STT_FUNC, - ELF::STT_GNU_IFUNC, ELF::STT_TLS}; - for (unsigned i = 0; i != array_lengthof(TypeOrdering); ++i) { - if (T1 == TypeOrdering[i]) + for (unsigned Type : {ELF::STT_NOTYPE, ELF::STT_OBJECT, ELF::STT_FUNC, + ELF::STT_GNU_IFUNC, ELF::STT_TLS}) { + if (T1 == Type) return T2; - if (T2 == TypeOrdering[i]) + if (T2 == Type) return T1; } @@ -143,7 +201,7 @@ bool MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol, // important for matching the string table that 'as' generates. IndirectSymbolData ISD; ISD.Symbol = Symbol; - ISD.SectionData = getCurrentSectionData(); + ISD.Section = getCurrentSectionData(); getAssembler().getIndirectSymbols().push_back(ISD); return true; } @@ -171,10 +229,16 @@ bool MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol, return false; case MCSA_NoDeadStrip: - case MCSA_ELF_TypeGnuUniqueObject: // Ignore for now. break; + case MCSA_ELF_TypeGnuUniqueObject: + MCELF::SetType(SD, CombineSymbolTypes(MCELF::GetType(SD), ELF::STT_OBJECT)); + MCELF::SetBinding(SD, ELF::STB_GNU_UNIQUE); + SD.setExternal(true); + BindingExplicitlySet.insert(Symbol); + break; + case MCSA_Global: MCELF::SetBinding(SD, ELF::STB_GLOBAL); SD.setExternal(true); @@ -253,15 +317,12 @@ void MCELFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, MCELF::SetType(SD, ELF::STT_OBJECT); if (MCELF::GetBinding(SD) == ELF_STB_Local) { - const MCSection *Section = getAssembler().getContext().getELFSection(".bss", - ELF::SHT_NOBITS, - ELF::SHF_WRITE | - ELF::SHF_ALLOC, - SectionKind::getBSS()); + MCSection *Section = getAssembler().getContext().getELFSection( + ".bss", ELF::SHT_NOBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC); AssignSection(Symbol, Section); - struct LocalCommon L = {&SD, Size, ByteAlignment}; + struct LocalCommon L = {Symbol, Size, ByteAlignment}; LocalCommons.push_back(L); } else { SD.setCommon(Size, ByteAlignment); @@ -287,7 +348,7 @@ void MCELFStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, void MCELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, const SMLoc &Loc) { - if (getCurrentSectionData()->isBundleLocked()) + if (isBundleLocked()) report_fatal_error("Emitting values inside a locked bundle is forbidden"); fixSymbolsInTLSFixups(Value); MCObjectStreamer::EmitValueImpl(Value, Size, Loc); @@ -297,7 +358,7 @@ void MCELFStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value, unsigned ValueSize, unsigned MaxBytesToEmit) { - if (getCurrentSectionData()->isBundleLocked()) + if (isBundleLocked()) report_fatal_error("Emitting values inside a locked bundle is forbidden"); MCObjectStreamer::EmitValueToAlignment(ByteAlignment, Value, ValueSize, MaxBytesToEmit); @@ -311,9 +372,8 @@ void MCELFStreamer::EmitFileDirective(StringRef Filename) { } void MCELFStreamer::EmitIdent(StringRef IdentString) { - const MCSection *Comment = getAssembler().getContext().getELFSection( - ".comment", ELF::SHT_PROGBITS, ELF::SHF_MERGE | ELF::SHF_STRINGS, - SectionKind::getReadOnly(), 1, ""); + MCSection *Comment = getAssembler().getContext().getELFSection( + ".comment", ELF::SHT_PROGBITS, ELF::SHF_MERGE | ELF::SHF_STRINGS, 1, ""); PushSection(); SwitchSection(Comment); if (!SeenIdent) { @@ -422,7 +482,7 @@ void MCELFStreamer::EmitInstToData(const MCInst &Inst, SmallVector<MCFixup, 4> Fixups; SmallString<256> Code; raw_svector_ostream VecOS(Code); - Assembler.getEmitter().EncodeInstruction(Inst, VecOS, Fixups, STI); + Assembler.getEmitter().encodeInstruction(Inst, VecOS, Fixups, STI); VecOS.flush(); for (unsigned i = 0, e = Fixups.size(); i != e; ++i) @@ -446,12 +506,21 @@ void MCELFStreamer::EmitInstToData(const MCInst &Inst, MCDataFragment *DF; if (Assembler.isBundlingEnabled()) { - MCSectionData *SD = getCurrentSectionData(); - if (SD->isBundleLocked() && !SD->isBundleGroupBeforeFirstInst()) + MCSection &Sec = *getCurrentSectionData(); + if (Assembler.getRelaxAll() && isBundleLocked()) + // If the -mc-relax-all flag is used and we are bundle-locked, we re-use + // the current bundle group. + DF = BundleGroups.back(); + else if (Assembler.getRelaxAll() && !isBundleLocked()) + // When not in a bundle-locked group and the -mc-relax-all flag is used, + // we create a new temporary fragment which will be later merged into + // the current fragment. + DF = new MCDataFragment(); + else if (isBundleLocked() && !Sec.isBundleGroupBeforeFirstInst()) // If we are bundle-locked, we re-use the current fragment. // The bundle-locking directive ensures this is a new data fragment. DF = cast<MCDataFragment>(getCurrentFragment()); - else if (!SD->isBundleLocked() && Fixups.size() == 0) { + else if (!isBundleLocked() && Fixups.size() == 0) { // Optimize memory usage by emitting the instruction to a // MCCompactEncodedInstFragment when not in a bundle-locked group and // there are no fixups registered. @@ -463,7 +532,7 @@ void MCELFStreamer::EmitInstToData(const MCInst &Inst, DF = new MCDataFragment(); insert(DF); } - if (SD->getBundleLockState() == MCSectionData::BundleLockedAlignToEnd) { + if (Sec.getBundleLockState() == MCSection::BundleLockedAlignToEnd) { // If this fragment is for a group marked "align_to_end", set a flag // in the fragment. This can happen after the fragment has already been // created if there are nested bundle_align groups and an inner one @@ -473,7 +542,7 @@ void MCELFStreamer::EmitInstToData(const MCInst &Inst, // We're now emitting an instruction in a bundle group, so this flag has // to be turned off. - SD->setBundleGroupBeforeFirstInst(false); + Sec.setBundleGroupBeforeFirstInst(false); } else { DF = getOrCreateDataFragment(); } @@ -485,6 +554,13 @@ void MCELFStreamer::EmitInstToData(const MCInst &Inst, } DF->setHasInstructions(true); DF->getContents().append(Code.begin(), Code.end()); + + if (Assembler.isBundlingEnabled() && Assembler.getRelaxAll()) { + if (!isBundleLocked()) { + mergeFragment(getOrCreateDataFragment(), DF); + delete DF; + } + } } void MCELFStreamer::EmitBundleAlignMode(unsigned AlignPow2) { @@ -498,59 +574,88 @@ void MCELFStreamer::EmitBundleAlignMode(unsigned AlignPow2) { } void MCELFStreamer::EmitBundleLock(bool AlignToEnd) { - MCSectionData *SD = getCurrentSectionData(); + MCSection &Sec = *getCurrentSectionData(); // Sanity checks // if (!getAssembler().isBundlingEnabled()) report_fatal_error(".bundle_lock forbidden when bundling is disabled"); - if (!SD->isBundleLocked()) - SD->setBundleGroupBeforeFirstInst(true); + if (!isBundleLocked()) + Sec.setBundleGroupBeforeFirstInst(true); - SD->setBundleLockState(AlignToEnd ? MCSectionData::BundleLockedAlignToEnd : - MCSectionData::BundleLocked); + if (getAssembler().getRelaxAll() && !isBundleLocked()) { + // TODO: drop the lock state and set directly in the fragment + MCDataFragment *DF = new MCDataFragment(); + BundleGroups.push_back(DF); + } + + Sec.setBundleLockState(AlignToEnd ? MCSection::BundleLockedAlignToEnd + : MCSection::BundleLocked); } void MCELFStreamer::EmitBundleUnlock() { - MCSectionData *SD = getCurrentSectionData(); + MCSection &Sec = *getCurrentSectionData(); // Sanity checks if (!getAssembler().isBundlingEnabled()) report_fatal_error(".bundle_unlock forbidden when bundling is disabled"); - else if (!SD->isBundleLocked()) + else if (!isBundleLocked()) report_fatal_error(".bundle_unlock without matching lock"); - else if (SD->isBundleGroupBeforeFirstInst()) + else if (Sec.isBundleGroupBeforeFirstInst()) report_fatal_error("Empty bundle-locked group is forbidden"); - SD->setBundleLockState(MCSectionData::NotBundleLocked); + // When the -mc-relax-all flag is used, we emit instructions to fragments + // stored on a stack. When the bundle unlock is emited, we pop a fragment + // from the stack a merge it to the one below. + if (getAssembler().getRelaxAll()) { + assert(!BundleGroups.empty() && "There are no bundle groups"); + MCDataFragment *DF = BundleGroups.back(); + + // FIXME: Use BundleGroups to track the lock state instead. + Sec.setBundleLockState(MCSection::NotBundleLocked); + + // FIXME: Use more separate fragments for nested groups. + if (!isBundleLocked()) { + mergeFragment(getOrCreateDataFragment(), DF); + BundleGroups.pop_back(); + delete DF; + } + + if (Sec.getBundleLockState() != MCSection::BundleLockedAlignToEnd) + getOrCreateDataFragment()->setAlignToBundleEnd(false); + } else + Sec.setBundleLockState(MCSection::NotBundleLocked); } void MCELFStreamer::Flush() { for (std::vector<LocalCommon>::const_iterator i = LocalCommons.begin(), e = LocalCommons.end(); i != e; ++i) { - MCSymbolData *SD = i->SD; + const MCSymbol &Symbol = *i->Symbol; uint64_t Size = i->Size; unsigned ByteAlignment = i->ByteAlignment; - const MCSymbol &Symbol = SD->getSymbol(); - const MCSection &Section = Symbol.getSection(); + MCSection &Section = Symbol.getSection(); - MCSectionData &SectData = getAssembler().getOrCreateSectionData(Section); - new MCAlignFragment(ByteAlignment, 0, 1, ByteAlignment, &SectData); + getAssembler().registerSection(Section); + new MCAlignFragment(ByteAlignment, 0, 1, ByteAlignment, &Section); - MCFragment *F = new MCFillFragment(0, 0, Size, &SectData); - SD->setFragment(F); + MCFragment *F = new MCFillFragment(0, 0, Size, &Section); + Symbol.getData().setFragment(F); // Update the maximum alignment of the section if necessary. - if (ByteAlignment > SectData.getAlignment()) - SectData.setAlignment(ByteAlignment); + if (ByteAlignment > Section.getAlignment()) + Section.setAlignment(ByteAlignment); } LocalCommons.clear(); } void MCELFStreamer::FinishImpl() { + // Ensure the last section gets aligned if necessary. + MCSection *CurSection = getCurrentSectionData(); + setSectionAlignmentForBundling(getAssembler(), CurSection); + EmitFrames(nullptr); Flush(); @@ -559,7 +664,7 @@ void MCELFStreamer::FinishImpl() { } MCStreamer *llvm::createELFStreamer(MCContext &Context, MCAsmBackend &MAB, - raw_ostream &OS, MCCodeEmitter *CE, + raw_pwrite_stream &OS, MCCodeEmitter *CE, bool RelaxAll) { MCELFStreamer *S = new MCELFStreamer(Context, MAB, OS, CE); if (RelaxAll) @@ -591,12 +696,12 @@ void MCELFStreamer::EndCOFFSymbolDef() { llvm_unreachable("ELF doesn't support this directive"); } -void MCELFStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol, +void MCELFStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) { llvm_unreachable("ELF doesn't support this directive"); } -void MCELFStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, +void MCELFStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) { llvm_unreachable("ELF doesn't support this directive"); } diff --git a/contrib/llvm/lib/MC/MCExpr.cpp b/contrib/llvm/lib/MC/MCExpr.cpp index 709dc6b..7f048d7 100644 --- a/contrib/llvm/lib/MC/MCExpr.cpp +++ b/contrib/llvm/lib/MC/MCExpr.cpp @@ -89,6 +89,7 @@ void MCExpr::print(raw_ostream &OS) const { OS << '+'; break; + case MCBinaryExpr::AShr: OS << ">>"; break; case MCBinaryExpr::And: OS << '&'; break; case MCBinaryExpr::Div: OS << '/'; break; case MCBinaryExpr::EQ: OS << "=="; break; @@ -96,6 +97,7 @@ void MCExpr::print(raw_ostream &OS) const { case MCBinaryExpr::GTE: OS << ">="; break; case MCBinaryExpr::LAnd: OS << "&&"; break; case MCBinaryExpr::LOr: OS << "||"; break; + case MCBinaryExpr::LShr: OS << ">>"; break; case MCBinaryExpr::LT: OS << '<'; break; case MCBinaryExpr::LTE: OS << "<="; break; case MCBinaryExpr::Mod: OS << '%'; break; @@ -103,7 +105,6 @@ void MCExpr::print(raw_ostream &OS) const { case MCBinaryExpr::NE: OS << "!="; break; case MCBinaryExpr::Or: OS << '|'; break; case MCBinaryExpr::Shl: OS << "<<"; break; - case MCBinaryExpr::Shr: OS << ">>"; break; case MCBinaryExpr::Sub: OS << '-'; break; case MCBinaryExpr::Xor: OS << '^'; break; } @@ -123,7 +124,7 @@ void MCExpr::print(raw_ostream &OS) const { #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) void MCExpr::dump() const { - print(dbgs()); + dbgs() << *this; dbgs() << '\n'; } #endif @@ -163,7 +164,7 @@ const MCSymbolRefExpr *MCSymbolRefExpr::Create(const MCSymbol *Sym, const MCSymbolRefExpr *MCSymbolRefExpr::Create(StringRef Name, VariantKind Kind, MCContext &Ctx) { - return Create(Ctx.GetOrCreateSymbol(Name), Kind, Ctx); + return Create(Ctx.getOrCreateSymbol(Name), Kind, Ctx); } StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) { @@ -192,6 +193,7 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) { case VK_GOTPAGE: return "GOTPAGE"; case VK_GOTPAGEOFF: return "GOTPAGEOFF"; case VK_SECREL: return "SECREL32"; + case VK_SIZE: return "SIZE"; case VK_WEAKREF: return "WEAKREF"; case VK_ARM_NONE: return "none"; case VK_ARM_TARGET1: return "target1"; @@ -281,6 +283,18 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) { case VK_Mips_PCREL_HI16: return "PCREL_HI16"; case VK_Mips_PCREL_LO16: return "PCREL_LO16"; case VK_COFF_IMGREL32: return "IMGREL"; + case VK_Hexagon_PCREL: return "PCREL"; + case VK_Hexagon_LO16: return "LO16"; + case VK_Hexagon_HI16: return "HI16"; + case VK_Hexagon_GPREL: return "GPREL"; + case VK_Hexagon_GD_GOT: return "GDGOT"; + case VK_Hexagon_LD_GOT: return "LDGOT"; + case VK_Hexagon_GD_PLT: return "GDPLT"; + case VK_Hexagon_LD_PLT: return "LDPLT"; + case VK_Hexagon_IE: return "IE"; + case VK_Hexagon_IE_GOT: return "IEGOT"; + case VK_TPREL: return "tprel"; + case VK_DTPREL: return "dtprel"; } llvm_unreachable("Invalid variant kind"); } @@ -311,6 +325,7 @@ MCSymbolRefExpr::getVariantKindForName(StringRef Name) { .Case("gotpageoff", VK_GOTPAGEOFF) .Case("imgrel", VK_COFF_IMGREL32) .Case("secrel32", VK_SECREL) + .Case("size", VK_SIZE) .Case("l", VK_PPC_LO) .Case("h", VK_PPC_HI) .Case("ha", VK_PPC_HA) @@ -404,13 +419,10 @@ bool MCExpr::EvaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const { return EvaluateAsAbsolute(Res, &Asm, nullptr, nullptr); } -int64_t MCExpr::evaluateKnownAbsolute(const MCAsmLayout &Layout) const { - int64_t Res; - bool Abs = - evaluateAsAbsolute(Res, &Layout.getAssembler(), &Layout, nullptr, true); - (void)Abs; - assert(Abs && "Not actually absolute"); - return Res; +bool MCExpr::evaluateKnownAbsolute(int64_t &Res, + const MCAsmLayout &Layout) const { + return evaluateAsAbsolute(Res, &Layout.getAssembler(), &Layout, nullptr, + true); } bool MCExpr::EvaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm, @@ -433,8 +445,8 @@ bool MCExpr::evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm, return true; } - bool IsRelocatable = EvaluateAsRelocatableImpl( - Value, Asm, Layout, nullptr, Addrs, InSet, /*ForceVarExpansion*/ false); + bool IsRelocatable = + EvaluateAsRelocatableImpl(Value, Asm, Layout, nullptr, Addrs, InSet); // Record the current value. Res = Value.getConstant(); @@ -443,13 +455,10 @@ bool MCExpr::evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm, } /// \brief Helper method for \see EvaluateSymbolAdd(). -static void AttemptToFoldSymbolOffsetDifference(const MCAssembler *Asm, - const MCAsmLayout *Layout, - const SectionAddrMap *Addrs, - bool InSet, - const MCSymbolRefExpr *&A, - const MCSymbolRefExpr *&B, - int64_t &Addend) { +static void AttemptToFoldSymbolOffsetDifference( + const MCAssembler *Asm, const MCAsmLayout *Layout, + const SectionAddrMap *Addrs, bool InSet, const MCSymbolRefExpr *&A, + const MCSymbolRefExpr *&B, int64_t &Addend) { if (!A || !B) return; @@ -482,15 +491,15 @@ static void AttemptToFoldSymbolOffsetDifference(const MCAssembler *Asm, if (!Layout) return; - const MCSectionData &SecA = *AD.getFragment()->getParent(); - const MCSectionData &SecB = *BD.getFragment()->getParent(); + const MCSection &SecA = *AD.getFragment()->getParent(); + const MCSection &SecB = *BD.getFragment()->getParent(); if ((&SecA != &SecB) && !Addrs) return; // Eagerly evaluate. - Addend += (Layout->getSymbolOffset(&Asm->getSymbolData(A->getSymbol())) - - Layout->getSymbolOffset(&Asm->getSymbolData(B->getSymbol()))); + Addend += Layout->getSymbolOffset(A->getSymbol()) - + Layout->getSymbolOffset(B->getSymbol()); if (Addrs && (&SecA != &SecB)) Addend += (Addrs->lookup(&SecA) - Addrs->lookup(&SecB)); @@ -523,13 +532,11 @@ static void AttemptToFoldSymbolOffsetDifference(const MCAssembler *Asm, /// They might look redundant, but this function can be used before layout /// is done (see the object streamer for example) and having the Asm argument /// lets us avoid relaxations early. -static bool EvaluateSymbolicAdd(const MCAssembler *Asm, - const MCAsmLayout *Layout, - const SectionAddrMap *Addrs, - bool InSet, - const MCValue &LHS,const MCSymbolRefExpr *RHS_A, - const MCSymbolRefExpr *RHS_B, int64_t RHS_Cst, - MCValue &Res) { +static bool +EvaluateSymbolicAdd(const MCAssembler *Asm, const MCAsmLayout *Layout, + const SectionAddrMap *Addrs, bool InSet, const MCValue &LHS, + const MCSymbolRefExpr *RHS_A, const MCSymbolRefExpr *RHS_B, + int64_t RHS_Cst, MCValue &Res) { // FIXME: This routine (and other evaluation parts) are *incredibly* sloppy // about dealing with modifiers. This will ultimately bite us, one day. const MCSymbolRefExpr *LHS_A = LHS.getSymA(); @@ -587,21 +594,28 @@ bool MCExpr::EvaluateAsRelocatable(MCValue &Res, const MCFixup *Fixup) const { MCAssembler *Assembler = Layout ? &Layout->getAssembler() : nullptr; return EvaluateAsRelocatableImpl(Res, Assembler, Layout, Fixup, nullptr, - false, /*ForceVarExpansion*/ false); + false); } -bool MCExpr::EvaluateAsValue(MCValue &Res, const MCAsmLayout *Layout, - const MCFixup *Fixup) const { - MCAssembler *Assembler = Layout ? &Layout->getAssembler() : nullptr; - return EvaluateAsRelocatableImpl(Res, Assembler, Layout, Fixup, nullptr, - false, /*ForceVarExpansion*/ true); +bool MCExpr::evaluateAsValue(MCValue &Res, const MCAsmLayout &Layout) const { + MCAssembler *Assembler = &Layout.getAssembler(); + return EvaluateAsRelocatableImpl(Res, Assembler, &Layout, nullptr, nullptr, + true); +} + +static bool canExpand(const MCSymbol &Sym, const MCAssembler *Asm, bool InSet) { + if (InSet) + return true; + if (!Asm) + return false; + return !Asm->getWriter().isWeak(Sym); } bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, const MCAsmLayout *Layout, const MCFixup *Fixup, - const SectionAddrMap *Addrs, bool InSet, - bool ForceVarExpansion) const { + const SectionAddrMap *Addrs, + bool InSet) const { ++stats::MCExprEvaluate; switch (getKind()) { @@ -618,28 +632,24 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, const MCSymbol &Sym = SRE->getSymbol(); // Evaluate recursively if this is a variable. - if (Sym.isVariable() && SRE->getKind() == MCSymbolRefExpr::VK_None) { + if (Sym.isVariable() && SRE->getKind() == MCSymbolRefExpr::VK_None && + canExpand(Sym, Asm, InSet)) { + bool IsMachO = SRE->hasSubsectionsViaSymbols(); if (Sym.getVariableValue()->EvaluateAsRelocatableImpl( - Res, Asm, Layout, Fixup, Addrs, true, ForceVarExpansion)) { + Res, Asm, Layout, Fixup, Addrs, InSet || IsMachO)) { + if (!IsMachO) + return true; + const MCSymbolRefExpr *A = Res.getSymA(); const MCSymbolRefExpr *B = Res.getSymB(); - - if (SRE->hasSubsectionsViaSymbols()) { - // FIXME: This is small hack. Given - // a = b + 4 - // .long a - // the OS X assembler will completely drop the 4. We should probably - // include it in the relocation or produce an error if that is not - // possible. - if (!A && !B) - return true; - } else { - if (ForceVarExpansion) - return true; - bool IsSymbol = A && A->getSymbol().isDefined(); - if (!IsSymbol) - return true; - } + // FIXME: This is small hack. Given + // a = b + 4 + // .long a + // the OS X assembler will completely drop the 4. We should probably + // include it in the relocation or produce an error if that is not + // possible. + if (!A && !B) + return true; } } @@ -651,9 +661,8 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, const MCUnaryExpr *AUE = cast<MCUnaryExpr>(this); MCValue Value; - if (!AUE->getSubExpr()->EvaluateAsRelocatableImpl(Value, Asm, Layout, - Fixup, Addrs, InSet, - ForceVarExpansion)) + if (!AUE->getSubExpr()->EvaluateAsRelocatableImpl(Value, Asm, Layout, Fixup, + Addrs, InSet)) return false; switch (AUE->getOpcode()) { @@ -686,12 +695,10 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, const MCBinaryExpr *ABE = cast<MCBinaryExpr>(this); MCValue LHSValue, RHSValue; - if (!ABE->getLHS()->EvaluateAsRelocatableImpl(LHSValue, Asm, Layout, - Fixup, Addrs, InSet, - ForceVarExpansion) || - !ABE->getRHS()->EvaluateAsRelocatableImpl(RHSValue, Asm, Layout, - Fixup, Addrs, InSet, - ForceVarExpansion)) + if (!ABE->getLHS()->EvaluateAsRelocatableImpl(LHSValue, Asm, Layout, Fixup, + Addrs, InSet) || + !ABE->getRHS()->EvaluateAsRelocatableImpl(RHSValue, Asm, Layout, Fixup, + Addrs, InSet)) return false; // We only support a few operations on non-constant expressions, handle @@ -704,23 +711,22 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, // Negate RHS and add. return EvaluateSymbolicAdd(Asm, Layout, Addrs, InSet, LHSValue, RHSValue.getSymB(), RHSValue.getSymA(), - -RHSValue.getConstant(), - Res); + -RHSValue.getConstant(), Res); case MCBinaryExpr::Add: return EvaluateSymbolicAdd(Asm, Layout, Addrs, InSet, LHSValue, RHSValue.getSymA(), RHSValue.getSymB(), - RHSValue.getConstant(), - Res); + RHSValue.getConstant(), Res); } } // FIXME: We need target hooks for the evaluation. It may be limited in - // width, and gas defines the result of comparisons and right shifts - // differently from Apple as. + // width, and gas defines the result of comparisons differently from + // Apple as. int64_t LHS = LHSValue.getConstant(), RHS = RHSValue.getConstant(); int64_t Result = 0; switch (ABE->getOpcode()) { + case MCBinaryExpr::AShr: Result = LHS >> RHS; break; case MCBinaryExpr::Add: Result = LHS + RHS; break; case MCBinaryExpr::And: Result = LHS & RHS; break; case MCBinaryExpr::Div: Result = LHS / RHS; break; @@ -729,6 +735,7 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, case MCBinaryExpr::GTE: Result = LHS >= RHS; break; case MCBinaryExpr::LAnd: Result = LHS && RHS; break; case MCBinaryExpr::LOr: Result = LHS || RHS; break; + case MCBinaryExpr::LShr: Result = uint64_t(LHS) >> uint64_t(RHS); break; case MCBinaryExpr::LT: Result = LHS < RHS; break; case MCBinaryExpr::LTE: Result = LHS <= RHS; break; case MCBinaryExpr::Mod: Result = LHS % RHS; break; @@ -736,7 +743,6 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, case MCBinaryExpr::NE: Result = LHS != RHS; break; case MCBinaryExpr::Or: Result = LHS | RHS; break; case MCBinaryExpr::Shl: Result = LHS << RHS; break; - case MCBinaryExpr::Shr: Result = LHS >> RHS; break; case MCBinaryExpr::Sub: Result = LHS - RHS; break; case MCBinaryExpr::Xor: Result = LHS ^ RHS; break; } @@ -749,7 +755,7 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, llvm_unreachable("Invalid assembly expression kind!"); } -const MCSection *MCExpr::FindAssociatedSection() const { +MCSection *MCExpr::FindAssociatedSection() const { switch (getKind()) { case Target: // We never look through target specific expressions. @@ -773,8 +779,8 @@ const MCSection *MCExpr::FindAssociatedSection() const { case Binary: { const MCBinaryExpr *BE = cast<MCBinaryExpr>(this); - const MCSection *LHS_S = BE->getLHS()->FindAssociatedSection(); - const MCSection *RHS_S = BE->getRHS()->FindAssociatedSection(); + MCSection *LHS_S = BE->getLHS()->FindAssociatedSection(); + MCSection *RHS_S = BE->getRHS()->FindAssociatedSection(); // If either section is absolute, return the other. if (LHS_S == MCSymbol::AbsolutePseudoSection) @@ -782,6 +788,10 @@ const MCSection *MCExpr::FindAssociatedSection() const { if (RHS_S == MCSymbol::AbsolutePseudoSection) return LHS_S; + // Not always correct, but probably the best we can do without more context. + if (BE->getOpcode() == MCBinaryExpr::Sub) + return MCSymbol::AbsolutePseudoSection; + // Otherwise, return the first non-null section. return LHS_S ? LHS_S : RHS_S; } diff --git a/contrib/llvm/lib/MC/MCInst.cpp b/contrib/llvm/lib/MC/MCInst.cpp index d7b80f5..7ef69be 100644 --- a/contrib/llvm/lib/MC/MCInst.cpp +++ b/contrib/llvm/lib/MC/MCInst.cpp @@ -15,7 +15,7 @@ using namespace llvm; -void MCOperand::print(raw_ostream &OS, const MCAsmInfo *MAI) const { +void MCOperand::print(raw_ostream &OS) const { OS << "<MCOperand "; if (!isValid()) OS << "INVALID"; @@ -34,22 +34,21 @@ void MCOperand::print(raw_ostream &OS, const MCAsmInfo *MAI) const { #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) void MCOperand::dump() const { - print(dbgs(), nullptr); + print(dbgs()); dbgs() << "\n"; } #endif -void MCInst::print(raw_ostream &OS, const MCAsmInfo *MAI) const { +void MCInst::print(raw_ostream &OS) const { OS << "<MCInst " << getOpcode(); for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { OS << " "; - getOperand(i).print(OS, MAI); + getOperand(i).print(OS); } OS << ">"; } -void MCInst::dump_pretty(raw_ostream &OS, const MCAsmInfo *MAI, - const MCInstPrinter *Printer, +void MCInst::dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer, StringRef Separator) const { OS << "<MCInst #" << getOpcode(); @@ -59,14 +58,14 @@ void MCInst::dump_pretty(raw_ostream &OS, const MCAsmInfo *MAI, for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { OS << Separator; - getOperand(i).print(OS, MAI); + getOperand(i).print(OS); } OS << ">"; } #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) void MCInst::dump() const { - print(dbgs(), nullptr); + print(dbgs()); dbgs() << "\n"; } #endif diff --git a/contrib/llvm/lib/MC/MCInstPrinter.cpp b/contrib/llvm/lib/MC/MCInstPrinter.cpp index ba71245..0dc3121 100644 --- a/contrib/llvm/lib/MC/MCInstPrinter.cpp +++ b/contrib/llvm/lib/MC/MCInstPrinter.cpp @@ -69,11 +69,11 @@ static bool needsLeadingZero(uint64_t Value) return false; } -format_object1<int64_t> MCInstPrinter::formatDec(const int64_t Value) const { +format_object<int64_t> MCInstPrinter::formatDec(int64_t Value) const { return format("%" PRId64, Value); } -format_object1<int64_t> MCInstPrinter::formatHex(const int64_t Value) const { +format_object<int64_t> MCInstPrinter::formatHex(int64_t Value) const { switch(PrintHexStyle) { case HexStyle::C: if (Value < 0) @@ -96,7 +96,7 @@ format_object1<int64_t> MCInstPrinter::formatHex(const int64_t Value) const { llvm_unreachable("unsupported print style"); } -format_object1<uint64_t> MCInstPrinter::formatHex(const uint64_t Value) const { +format_object<uint64_t> MCInstPrinter::formatHex(uint64_t Value) const { switch(PrintHexStyle) { case HexStyle::C: return format("0x%" PRIx64, Value); diff --git a/contrib/llvm/lib/MC/MCInstrDesc.cpp b/contrib/llvm/lib/MC/MCInstrDesc.cpp new file mode 100644 index 0000000..decc2d8 --- /dev/null +++ b/contrib/llvm/lib/MC/MCInstrDesc.cpp @@ -0,0 +1,70 @@ +//===------ llvm/MC/MCInstrDesc.cpp- Instruction Descriptors --------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines methods on the MCOperandInfo and MCInstrDesc classes, which +// are used to describe target instructions and their operands. +// +//===----------------------------------------------------------------------===// + +#include "llvm/MC/MCInstrDesc.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCRegisterInfo.h" +#include "llvm/MC/MCSubtargetInfo.h" + +using namespace llvm; + +bool MCInstrDesc::getDeprecatedInfo(MCInst &MI, MCSubtargetInfo &STI, + std::string &Info) const { + if (ComplexDeprecationInfo) + return ComplexDeprecationInfo(MI, STI, Info); + if (DeprecatedFeature != -1 && STI.getFeatureBits()[DeprecatedFeature]) { + // FIXME: it would be nice to include the subtarget feature here. + Info = "deprecated"; + return true; + } + return false; +} +bool MCInstrDesc::mayAffectControlFlow(const MCInst &MI, + const MCRegisterInfo &RI) const { + if (isBranch() || isCall() || isReturn() || isIndirectBranch()) + return true; + unsigned PC = RI.getProgramCounter(); + if (PC == 0) + return false; + if (hasDefOfPhysReg(MI, PC, RI)) + return true; + // A variadic instruction may define PC in the variable operand list. + // There's currently no indication of which entries in a variable + // list are defs and which are uses. While that's the case, this function + // needs to assume they're defs in order to be conservatively correct. + for (int i = NumOperands, e = MI.getNumOperands(); i != e; ++i) { + if (MI.getOperand(i).isReg() && + RI.isSubRegisterEq(PC, MI.getOperand(i).getReg())) + return true; + } + return false; +} + +bool MCInstrDesc::hasImplicitDefOfPhysReg(unsigned Reg, + const MCRegisterInfo *MRI) const { + if (const uint16_t *ImpDefs = ImplicitDefs) + for (; *ImpDefs; ++ImpDefs) + if (*ImpDefs == Reg || (MRI && MRI->isSubRegister(Reg, *ImpDefs))) + return true; + return false; +} + +bool MCInstrDesc::hasDefOfPhysReg(const MCInst &MI, unsigned Reg, + const MCRegisterInfo &RI) const { + for (int i = 0, e = NumDefs; i != e; ++i) + if (MI.getOperand(i).isReg() && + RI.isSubRegisterEq(Reg, MI.getOperand(i).getReg())) + return true; + return hasImplicitDefOfPhysReg(Reg, &RI); +} diff --git a/contrib/llvm/lib/MC/MCLinkerOptimizationHint.cpp b/contrib/llvm/lib/MC/MCLinkerOptimizationHint.cpp index 7739878..2c9c67c 100644 --- a/contrib/llvm/lib/MC/MCLinkerOptimizationHint.cpp +++ b/contrib/llvm/lib/MC/MCLinkerOptimizationHint.cpp @@ -9,7 +9,7 @@ #include "llvm/MC/MCLinkerOptimizationHint.h" #include "llvm/MC/MCAsmLayout.h" -#include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCAssembler.h" #include "llvm/Support/LEB128.h" using namespace llvm; @@ -25,11 +25,9 @@ using namespace llvm; void MCLOHDirective::Emit_impl(raw_ostream &OutStream, const MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const { - const MCAssembler &Asm = Layout.getAssembler(); encodeULEB128(Kind, OutStream); encodeULEB128(Args.size(), OutStream); for (LOHArgs::const_iterator It = Args.begin(), EndIt = Args.end(); It != EndIt; ++It) - encodeULEB128(ObjWriter.getSymbolAddress(&Asm.getSymbolData(**It), Layout), - OutStream); + encodeULEB128(ObjWriter.getSymbolAddress(**It, Layout), OutStream); } diff --git a/contrib/llvm/lib/MC/MCMachOStreamer.cpp b/contrib/llvm/lib/MC/MCMachOStreamer.cpp index a147c3d..6297340 100644 --- a/contrib/llvm/lib/MC/MCMachOStreamer.cpp +++ b/contrib/llvm/lib/MC/MCMachOStreamer.cpp @@ -26,6 +26,7 @@ #include "llvm/MC/MCSymbol.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/TargetRegistry.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -39,6 +40,9 @@ private: /// need for local relocations. False by default. bool LabelSections; + bool DWARFMustBeAtTheEnd; + bool CreatedADWARFSection; + /// HasSectionLabel - map of which sections have already had a non-local /// label emitted to them. Used so we don't emit extraneous linker local /// labels in the middle of the section. @@ -50,10 +54,10 @@ private: void EmitDataRegionEnd(); public: - MCMachOStreamer(MCContext &Context, MCAsmBackend &MAB, raw_ostream &OS, - MCCodeEmitter *Emitter, bool label) - : MCObjectStreamer(Context, MAB, OS, Emitter), - LabelSections(label) {} + MCMachOStreamer(MCContext &Context, MCAsmBackend &MAB, raw_pwrite_stream &OS, + MCCodeEmitter *Emitter, bool DWARFMustBeAtTheEnd, bool label) + : MCObjectStreamer(Context, MAB, OS, Emitter), LabelSections(label), + DWARFMustBeAtTheEnd(DWARFMustBeAtTheEnd), CreatedADWARFSection(false) {} /// state management void reset() override { @@ -64,7 +68,7 @@ public: /// @name MCStreamer Interface /// @{ - void ChangeSection(const MCSection *Sect, const MCExpr *Subsect) override; + void ChangeSection(MCSection *Sect, const MCExpr *Subsect) override; void EmitLabel(MCSymbol *Symbol) override; void EmitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol) override; void EmitAssemblerFlag(MCAssemblerFlag Flag) override; @@ -94,9 +98,9 @@ public: } void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) override; - void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = nullptr, + void EmitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr, uint64_t Size = 0, unsigned ByteAlignment = 0) override; - void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, uint64_t Size, + void EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment = 0) override; void EmitFileDirective(StringRef Filename) override { @@ -119,14 +123,47 @@ public: } // end anonymous namespace. -void MCMachOStreamer::ChangeSection(const MCSection *Section, +static bool canGoAfterDWARF(const MCSectionMachO &MSec) { + // These sections are created by the assembler itself after the end of + // the .s file. + StringRef SegName = MSec.getSegmentName(); + StringRef SecName = MSec.getSectionName(); + + if (SegName == "__LD" && SecName == "__compact_unwind") + return true; + + if (SegName == "__IMPORT") { + if (SecName == "__jump_table") + return true; + + if (SecName == "__pointers") + return true; + } + + if (SegName == "__TEXT" && SecName == "__eh_frame") + return true; + + if (SegName == "__DATA" && SecName == "__nl_symbol_ptr") + return true; + + return false; +} + +void MCMachOStreamer::ChangeSection(MCSection *Section, const MCExpr *Subsection) { // Change the section normally. - MCObjectStreamer::ChangeSection(Section, Subsection); + bool Created = MCObjectStreamer::changeSectionImpl(Section, Subsection); + const MCSectionMachO &MSec = *cast<MCSectionMachO>(Section); + StringRef SegName = MSec.getSegmentName(); + if (SegName == "__DWARF") + CreatedADWARFSection = true; + else if (Created && DWARFMustBeAtTheEnd && !canGoAfterDWARF(MSec)) + assert(!CreatedADWARFSection && "Creating regular section after DWARF"); + // Output a linker-local symbol so we don't need section-relative local // relocations. The linker hates us when we do that. if (LabelSections && !HasSectionLabel[Section]) { - MCSymbol *Label = getContext().CreateLinkerPrivateTempSymbol(); + MCSymbol *Label = getContext().createLinkerPrivateTempSymbol(); EmitLabel(Label); HasSectionLabel[Section] = true; } @@ -171,7 +208,7 @@ void MCMachOStreamer::EmitDataRegion(DataRegionData::KindTy Kind) { if (!getAssembler().getBackend().hasDataInCodeSupport()) return; // Create a temporary label to mark the start of the data region. - MCSymbol *Start = getContext().CreateTempSymbol(); + MCSymbol *Start = getContext().createTempSymbol(); EmitLabel(Start); // Record the region for the object writer to use. DataRegionData Data = { Kind, Start, nullptr }; @@ -183,11 +220,11 @@ void MCMachOStreamer::EmitDataRegionEnd() { if (!getAssembler().getBackend().hasDataInCodeSupport()) return; std::vector<DataRegionData> &Regions = getAssembler().getDataRegions(); - assert(Regions.size() && "Mismatched .end_data_region!"); + assert(!Regions.empty() && "Mismatched .end_data_region!"); DataRegionData &Data = Regions.back(); assert(!Data.End && "Mismatched .end_data_region!"); // Create a temporary label to mark the end of the data region. - Data.End = getContext().CreateTempSymbol(); + Data.End = getContext().createTempSymbol(); EmitLabel(Data.End); } @@ -250,7 +287,7 @@ bool MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol, // important for matching the string table that 'as' generates. IndirectSymbolData ISD; ISD.Symbol = Symbol; - ISD.SectionData = getCurrentSectionData(); + ISD.Section = getCurrentSectionData(); getAssembler().getIndirectSymbols().push_back(ISD); return true; } @@ -364,9 +401,9 @@ void MCMachOStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, Symbol, Size, ByteAlignment); } -void MCMachOStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol, +void MCMachOStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) { - MCSectionData &SectData = getAssembler().getOrCreateSectionData(*Section); + getAssembler().registerSection(*Section); // The symbol may not be present, which only creates the section. if (!Symbol) @@ -381,21 +418,21 @@ void MCMachOStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol, // Emit an align fragment if necessary. if (ByteAlignment != 1) - new MCAlignFragment(ByteAlignment, 0, 0, ByteAlignment, &SectData); + new MCAlignFragment(ByteAlignment, 0, 0, ByteAlignment, Section); - MCFragment *F = new MCFillFragment(0, 0, Size, &SectData); + MCFragment *F = new MCFillFragment(0, 0, Size, Section); SD.setFragment(F); AssignSection(Symbol, Section); // Update the maximum alignment on the zero fill section if necessary. - if (ByteAlignment > SectData.getAlignment()) - SectData.setAlignment(ByteAlignment); + if (ByteAlignment > Section->getAlignment()) + Section->setAlignment(ByteAlignment); } // This should always be called with the thread local bss section. Like the // .zerofill directive this doesn't actually switch sections on us. -void MCMachOStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, +void MCMachOStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) { EmitZerofill(Section, Symbol, Size, ByteAlignment); return; @@ -408,7 +445,7 @@ void MCMachOStreamer::EmitInstToData(const MCInst &Inst, SmallVector<MCFixup, 4> Fixups; SmallString<256> Code; raw_svector_ostream VecOS(Code); - getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups, STI); + getAssembler().getEmitter().encodeInstruction(Inst, VecOS, Fixups, STI); VecOS.flush(); // Add the fixups and data. @@ -427,13 +464,13 @@ void MCMachOStreamer::FinishImpl() { // First, scan the symbol table to build a lookup table from fragments to // defining symbols. - DenseMap<const MCFragment*, MCSymbolData*> DefiningSymbolMap; - for (MCSymbolData &SD : getAssembler().symbols()) { - if (getAssembler().isSymbolLinkerVisible(SD.getSymbol()) && - SD.getFragment()) { + DenseMap<const MCFragment *, const MCSymbol *> DefiningSymbolMap; + for (const MCSymbol &Symbol : getAssembler().symbols()) { + MCSymbolData &SD = Symbol.getData(); + if (getAssembler().isSymbolLinkerVisible(Symbol) && SD.getFragment()) { // An atom defining symbol should never be internal to a fragment. assert(SD.getOffset() == 0 && "Invalid offset in atom defining symbol!"); - DefiningSymbolMap[SD.getFragment()] = &SD; + DefiningSymbolMap[SD.getFragment()] = &Symbol; } } @@ -441,11 +478,11 @@ void MCMachOStreamer::FinishImpl() { // symbol. for (MCAssembler::iterator it = getAssembler().begin(), ie = getAssembler().end(); it != ie; ++it) { - MCSymbolData *CurrentAtom = nullptr; - for (MCSectionData::iterator it2 = it->begin(), - ie2 = it->end(); it2 != ie2; ++it2) { - if (MCSymbolData *SD = DefiningSymbolMap.lookup(it2)) - CurrentAtom = SD; + const MCSymbol *CurrentAtom = nullptr; + for (MCSection::iterator it2 = it->begin(), ie2 = it->end(); it2 != ie2; + ++it2) { + if (const MCSymbol *Symbol = DefiningSymbolMap.lookup(it2)) + CurrentAtom = Symbol; it2->setAtom(CurrentAtom); } } @@ -454,10 +491,11 @@ void MCMachOStreamer::FinishImpl() { } MCStreamer *llvm::createMachOStreamer(MCContext &Context, MCAsmBackend &MAB, - raw_ostream &OS, MCCodeEmitter *CE, - bool RelaxAll, + raw_pwrite_stream &OS, MCCodeEmitter *CE, + bool RelaxAll, bool DWARFMustBeAtTheEnd, bool LabelSections) { - MCMachOStreamer *S = new MCMachOStreamer(Context, MAB, OS, CE, LabelSections); + MCMachOStreamer *S = new MCMachOStreamer(Context, MAB, OS, CE, + DWARFMustBeAtTheEnd, LabelSections); if (RelaxAll) S->getAssembler().setRelaxAll(true); return S; diff --git a/contrib/llvm/lib/MC/MCNullStreamer.cpp b/contrib/llvm/lib/MC/MCNullStreamer.cpp index fc56728..eb2d912 100644 --- a/contrib/llvm/lib/MC/MCNullStreamer.cpp +++ b/contrib/llvm/lib/MC/MCNullStreamer.cpp @@ -31,7 +31,7 @@ namespace { void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) override {} - void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = nullptr, + void EmitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr, uint64_t Size = 0, unsigned ByteAlignment = 0) override {} void EmitGPRel32Value(const MCExpr *Value) override {} }; diff --git a/contrib/llvm/lib/MC/MCObjectFileInfo.cpp b/contrib/llvm/lib/MC/MCObjectFileInfo.cpp index 858181d..e99f036 100644 --- a/contrib/llvm/lib/MC/MCObjectFileInfo.cpp +++ b/contrib/llvm/lib/MC/MCObjectFileInfo.cpp @@ -183,82 +183,60 @@ void MCObjectFileInfo::InitMachOMCObjectFileInfo(Triple T) { // Debug Information. DwarfAccelNamesSection = - Ctx->getMachOSection("__DWARF", "__apple_names", - MachO::S_ATTR_DEBUG, - SectionKind::getMetadata()); + Ctx->getMachOSection("__DWARF", "__apple_names", MachO::S_ATTR_DEBUG, + SectionKind::getMetadata(), "names_begin"); DwarfAccelObjCSection = - Ctx->getMachOSection("__DWARF", "__apple_objc", - MachO::S_ATTR_DEBUG, - SectionKind::getMetadata()); + Ctx->getMachOSection("__DWARF", "__apple_objc", MachO::S_ATTR_DEBUG, + SectionKind::getMetadata(), "objc_begin"); // 16 character section limit... DwarfAccelNamespaceSection = - Ctx->getMachOSection("__DWARF", "__apple_namespac", - MachO::S_ATTR_DEBUG, - SectionKind::getMetadata()); + Ctx->getMachOSection("__DWARF", "__apple_namespac", MachO::S_ATTR_DEBUG, + SectionKind::getMetadata(), "namespac_begin"); DwarfAccelTypesSection = - Ctx->getMachOSection("__DWARF", "__apple_types", - MachO::S_ATTR_DEBUG, - SectionKind::getMetadata()); + Ctx->getMachOSection("__DWARF", "__apple_types", MachO::S_ATTR_DEBUG, + SectionKind::getMetadata(), "types_begin"); DwarfAbbrevSection = - Ctx->getMachOSection("__DWARF", "__debug_abbrev", - MachO::S_ATTR_DEBUG, - SectionKind::getMetadata()); + Ctx->getMachOSection("__DWARF", "__debug_abbrev", MachO::S_ATTR_DEBUG, + SectionKind::getMetadata(), "section_abbrev"); DwarfInfoSection = - Ctx->getMachOSection("__DWARF", "__debug_info", - MachO::S_ATTR_DEBUG, - SectionKind::getMetadata()); + Ctx->getMachOSection("__DWARF", "__debug_info", MachO::S_ATTR_DEBUG, + SectionKind::getMetadata(), "section_info"); DwarfLineSection = - Ctx->getMachOSection("__DWARF", "__debug_line", - MachO::S_ATTR_DEBUG, - SectionKind::getMetadata()); + Ctx->getMachOSection("__DWARF", "__debug_line", MachO::S_ATTR_DEBUG, + SectionKind::getMetadata(), "section_line"); DwarfFrameSection = - Ctx->getMachOSection("__DWARF", "__debug_frame", - MachO::S_ATTR_DEBUG, - SectionKind::getMetadata()); + Ctx->getMachOSection("__DWARF", "__debug_frame", MachO::S_ATTR_DEBUG, + SectionKind::getMetadata()); DwarfPubNamesSection = - Ctx->getMachOSection("__DWARF", "__debug_pubnames", - MachO::S_ATTR_DEBUG, - SectionKind::getMetadata()); + Ctx->getMachOSection("__DWARF", "__debug_pubnames", MachO::S_ATTR_DEBUG, + SectionKind::getMetadata()); DwarfPubTypesSection = - Ctx->getMachOSection("__DWARF", "__debug_pubtypes", - MachO::S_ATTR_DEBUG, - SectionKind::getMetadata()); + Ctx->getMachOSection("__DWARF", "__debug_pubtypes", MachO::S_ATTR_DEBUG, + SectionKind::getMetadata()); DwarfGnuPubNamesSection = - Ctx->getMachOSection("__DWARF", "__debug_gnu_pubn", - MachO::S_ATTR_DEBUG, - SectionKind::getMetadata()); + Ctx->getMachOSection("__DWARF", "__debug_gnu_pubn", MachO::S_ATTR_DEBUG, + SectionKind::getMetadata()); DwarfGnuPubTypesSection = - Ctx->getMachOSection("__DWARF", "__debug_gnu_pubt", - MachO::S_ATTR_DEBUG, - SectionKind::getMetadata()); + Ctx->getMachOSection("__DWARF", "__debug_gnu_pubt", MachO::S_ATTR_DEBUG, + SectionKind::getMetadata()); DwarfStrSection = - Ctx->getMachOSection("__DWARF", "__debug_str", - MachO::S_ATTR_DEBUG, - SectionKind::getMetadata()); + Ctx->getMachOSection("__DWARF", "__debug_str", MachO::S_ATTR_DEBUG, + SectionKind::getMetadata(), "info_string"); DwarfLocSection = - Ctx->getMachOSection("__DWARF", "__debug_loc", - MachO::S_ATTR_DEBUG, - SectionKind::getMetadata()); + Ctx->getMachOSection("__DWARF", "__debug_loc", MachO::S_ATTR_DEBUG, + SectionKind::getMetadata(), "section_debug_loc"); DwarfARangesSection = - Ctx->getMachOSection("__DWARF", "__debug_aranges", - MachO::S_ATTR_DEBUG, - SectionKind::getMetadata()); + Ctx->getMachOSection("__DWARF", "__debug_aranges", MachO::S_ATTR_DEBUG, + SectionKind::getMetadata()); DwarfRangesSection = - Ctx->getMachOSection("__DWARF", "__debug_ranges", - MachO::S_ATTR_DEBUG, - SectionKind::getMetadata()); - DwarfMacroInfoSection = - Ctx->getMachOSection("__DWARF", "__debug_macinfo", - MachO::S_ATTR_DEBUG, - SectionKind::getMetadata()); + Ctx->getMachOSection("__DWARF", "__debug_ranges", MachO::S_ATTR_DEBUG, + SectionKind::getMetadata(), "debug_range"); DwarfDebugInlineSection = - Ctx->getMachOSection("__DWARF", "__debug_inlined", - MachO::S_ATTR_DEBUG, - SectionKind::getMetadata()); - StackMapSection = - Ctx->getMachOSection("__LLVM_STACKMAPS", "__llvm_stackmaps", 0, - SectionKind::getMetadata()); + Ctx->getMachOSection("__DWARF", "__debug_inlined", MachO::S_ATTR_DEBUG, + SectionKind::getMetadata()); + StackMapSection = Ctx->getMachOSection("__LLVM_STACKMAPS", "__llvm_stackmaps", + 0, SectionKind::getMetadata()); TLSExtraDataSection = TLSTLVSection; } @@ -359,6 +337,7 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) { TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8; break; + case Triple::sparcel: case Triple::sparc: if (RelocM == Reloc::PIC_) { LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; @@ -416,83 +395,54 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) { // ELF - BSSSection = - Ctx->getELFSection(".bss", ELF::SHT_NOBITS, - ELF::SHF_WRITE | ELF::SHF_ALLOC, - SectionKind::getBSS()); - - TextSection = - Ctx->getELFSection(".text", ELF::SHT_PROGBITS, - ELF::SHF_EXECINSTR | - ELF::SHF_ALLOC, - SectionKind::getText()); - - DataSection = - Ctx->getELFSection(".data", ELF::SHT_PROGBITS, - ELF::SHF_WRITE |ELF::SHF_ALLOC, - SectionKind::getDataRel()); + BSSSection = Ctx->getELFSection(".bss", ELF::SHT_NOBITS, + ELF::SHF_WRITE | ELF::SHF_ALLOC); + + TextSection = Ctx->getELFSection(".text", ELF::SHT_PROGBITS, + ELF::SHF_EXECINSTR | ELF::SHF_ALLOC); + + DataSection = Ctx->getELFSection(".data", ELF::SHT_PROGBITS, + ELF::SHF_WRITE | ELF::SHF_ALLOC); ReadOnlySection = - Ctx->getELFSection(".rodata", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC, - SectionKind::getReadOnly()); + Ctx->getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC); TLSDataSection = - Ctx->getELFSection(".tdata", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC | ELF::SHF_TLS | - ELF::SHF_WRITE, - SectionKind::getThreadData()); - - TLSBSSSection = - Ctx->getELFSection(".tbss", ELF::SHT_NOBITS, - ELF::SHF_ALLOC | ELF::SHF_TLS | - ELF::SHF_WRITE, - SectionKind::getThreadBSS()); - - DataRelSection = - Ctx->getELFSection(".data.rel", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC |ELF::SHF_WRITE, - SectionKind::getDataRel()); - - DataRelLocalSection = - Ctx->getELFSection(".data.rel.local", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC |ELF::SHF_WRITE, - SectionKind::getDataRelLocal()); - - DataRelROSection = - Ctx->getELFSection(".data.rel.ro", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC |ELF::SHF_WRITE, - SectionKind::getReadOnlyWithRel()); - - DataRelROLocalSection = - Ctx->getELFSection(".data.rel.ro.local", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC |ELF::SHF_WRITE, - SectionKind::getReadOnlyWithRelLocal()); + Ctx->getELFSection(".tdata", ELF::SHT_PROGBITS, + ELF::SHF_ALLOC | ELF::SHF_TLS | ELF::SHF_WRITE); + + TLSBSSSection = Ctx->getELFSection( + ".tbss", ELF::SHT_NOBITS, ELF::SHF_ALLOC | ELF::SHF_TLS | ELF::SHF_WRITE); + + DataRelSection = Ctx->getELFSection(".data.rel", ELF::SHT_PROGBITS, + ELF::SHF_ALLOC | ELF::SHF_WRITE); + + DataRelLocalSection = Ctx->getELFSection(".data.rel.local", ELF::SHT_PROGBITS, + ELF::SHF_ALLOC | ELF::SHF_WRITE); + + DataRelROSection = Ctx->getELFSection(".data.rel.ro", ELF::SHT_PROGBITS, + ELF::SHF_ALLOC | ELF::SHF_WRITE); + + DataRelROLocalSection = Ctx->getELFSection( + ".data.rel.ro.local", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_WRITE); MergeableConst4Section = - Ctx->getELFSection(".rodata.cst4", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC |ELF::SHF_MERGE, - SectionKind::getMergeableConst4()); + Ctx->getELFSection(".rodata.cst4", ELF::SHT_PROGBITS, + ELF::SHF_ALLOC | ELF::SHF_MERGE, 4, ""); MergeableConst8Section = - Ctx->getELFSection(".rodata.cst8", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC |ELF::SHF_MERGE, - SectionKind::getMergeableConst8()); + Ctx->getELFSection(".rodata.cst8", ELF::SHT_PROGBITS, + ELF::SHF_ALLOC | ELF::SHF_MERGE, 8, ""); MergeableConst16Section = - Ctx->getELFSection(".rodata.cst16", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC |ELF::SHF_MERGE, - SectionKind::getMergeableConst16()); + Ctx->getELFSection(".rodata.cst16", ELF::SHT_PROGBITS, + ELF::SHF_ALLOC | ELF::SHF_MERGE, 16, ""); - StaticCtorSection = - Ctx->getELFSection(".ctors", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC |ELF::SHF_WRITE, - SectionKind::getDataRel()); + StaticCtorSection = Ctx->getELFSection(".ctors", ELF::SHT_PROGBITS, + ELF::SHF_ALLOC | ELF::SHF_WRITE); - StaticDtorSection = - Ctx->getELFSection(".dtors", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC |ELF::SHF_WRITE, - SectionKind::getDataRel()); + StaticDtorSection = Ctx->getELFSection(".dtors", ELF::SHT_PROGBITS, + ELF::SHF_ALLOC | ELF::SHF_WRITE); // Exception Handling Sections. @@ -500,162 +450,112 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) { // it contains relocatable pointers. In PIC mode, this is probably a big // runtime hit for C++ apps. Either the contents of the LSDA need to be // adjusted or this should be a data section. - LSDASection = - Ctx->getELFSection(".gcc_except_table", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC, - SectionKind::getReadOnly()); + LSDASection = Ctx->getELFSection(".gcc_except_table", ELF::SHT_PROGBITS, + ELF::SHF_ALLOC); COFFDebugSymbolsSection = nullptr; // Debug Info Sections. - DwarfAbbrevSection = - Ctx->getELFSection(".debug_abbrev", ELF::SHT_PROGBITS, 0, - SectionKind::getMetadata()); + DwarfAbbrevSection = Ctx->getELFSection(".debug_abbrev", ELF::SHT_PROGBITS, 0, + "section_abbrev"); DwarfInfoSection = - Ctx->getELFSection(".debug_info", ELF::SHT_PROGBITS, 0, - SectionKind::getMetadata()); - DwarfLineSection = - Ctx->getELFSection(".debug_line", ELF::SHT_PROGBITS, 0, - SectionKind::getMetadata()); - DwarfFrameSection = - Ctx->getELFSection(".debug_frame", ELF::SHT_PROGBITS, 0, - SectionKind::getMetadata()); + Ctx->getELFSection(".debug_info", ELF::SHT_PROGBITS, 0, "section_info"); + DwarfLineSection = Ctx->getELFSection(".debug_line", ELF::SHT_PROGBITS, 0); + DwarfFrameSection = Ctx->getELFSection(".debug_frame", ELF::SHT_PROGBITS, 0); DwarfPubNamesSection = - Ctx->getELFSection(".debug_pubnames", ELF::SHT_PROGBITS, 0, - SectionKind::getMetadata()); + Ctx->getELFSection(".debug_pubnames", ELF::SHT_PROGBITS, 0); DwarfPubTypesSection = - Ctx->getELFSection(".debug_pubtypes", ELF::SHT_PROGBITS, 0, - SectionKind::getMetadata()); + Ctx->getELFSection(".debug_pubtypes", ELF::SHT_PROGBITS, 0); DwarfGnuPubNamesSection = - Ctx->getELFSection(".debug_gnu_pubnames", ELF::SHT_PROGBITS, 0, - SectionKind::getMetadata()); + Ctx->getELFSection(".debug_gnu_pubnames", ELF::SHT_PROGBITS, 0); DwarfGnuPubTypesSection = - Ctx->getELFSection(".debug_gnu_pubtypes", ELF::SHT_PROGBITS, 0, - SectionKind::getMetadata()); + Ctx->getELFSection(".debug_gnu_pubtypes", ELF::SHT_PROGBITS, 0); DwarfStrSection = - Ctx->getELFSection(".debug_str", ELF::SHT_PROGBITS, - ELF::SHF_MERGE | ELF::SHF_STRINGS, - SectionKind::getMergeable1ByteCString()); - DwarfLocSection = - Ctx->getELFSection(".debug_loc", ELF::SHT_PROGBITS, 0, - SectionKind::getMetadata()); + Ctx->getELFSection(".debug_str", ELF::SHT_PROGBITS, + ELF::SHF_MERGE | ELF::SHF_STRINGS, 1, ""); + DwarfLocSection = Ctx->getELFSection(".debug_loc", ELF::SHT_PROGBITS, 0); DwarfARangesSection = - Ctx->getELFSection(".debug_aranges", ELF::SHT_PROGBITS, 0, - SectionKind::getMetadata()); + Ctx->getELFSection(".debug_aranges", ELF::SHT_PROGBITS, 0); DwarfRangesSection = - Ctx->getELFSection(".debug_ranges", ELF::SHT_PROGBITS, 0, - SectionKind::getMetadata()); - DwarfMacroInfoSection = - Ctx->getELFSection(".debug_macinfo", ELF::SHT_PROGBITS, 0, - SectionKind::getMetadata()); + Ctx->getELFSection(".debug_ranges", ELF::SHT_PROGBITS, 0, "debug_range"); // DWARF5 Experimental Debug Info // Accelerator Tables DwarfAccelNamesSection = - Ctx->getELFSection(".apple_names", ELF::SHT_PROGBITS, 0, - SectionKind::getMetadata()); + Ctx->getELFSection(".apple_names", ELF::SHT_PROGBITS, 0, "names_begin"); DwarfAccelObjCSection = - Ctx->getELFSection(".apple_objc", ELF::SHT_PROGBITS, 0, - SectionKind::getMetadata()); - DwarfAccelNamespaceSection = - Ctx->getELFSection(".apple_namespaces", ELF::SHT_PROGBITS, 0, - SectionKind::getMetadata()); + Ctx->getELFSection(".apple_objc", ELF::SHT_PROGBITS, 0, "objc_begin"); + DwarfAccelNamespaceSection = Ctx->getELFSection( + ".apple_namespaces", ELF::SHT_PROGBITS, 0, "namespac_begin"); DwarfAccelTypesSection = - Ctx->getELFSection(".apple_types", ELF::SHT_PROGBITS, 0, - SectionKind::getMetadata()); + Ctx->getELFSection(".apple_types", ELF::SHT_PROGBITS, 0, "types_begin"); // Fission Sections DwarfInfoDWOSection = - Ctx->getELFSection(".debug_info.dwo", ELF::SHT_PROGBITS, 0, - SectionKind::getMetadata()); + Ctx->getELFSection(".debug_info.dwo", ELF::SHT_PROGBITS, 0); DwarfTypesDWOSection = - Ctx->getELFSection(".debug_types.dwo", ELF::SHT_PROGBITS, 0, - SectionKind::getMetadata()); + Ctx->getELFSection(".debug_types.dwo", ELF::SHT_PROGBITS, 0); DwarfAbbrevDWOSection = - Ctx->getELFSection(".debug_abbrev.dwo", ELF::SHT_PROGBITS, 0, - SectionKind::getMetadata()); + Ctx->getELFSection(".debug_abbrev.dwo", ELF::SHT_PROGBITS, 0); DwarfStrDWOSection = - Ctx->getELFSection(".debug_str.dwo", ELF::SHT_PROGBITS, - ELF::SHF_MERGE | ELF::SHF_STRINGS, - SectionKind::getMergeable1ByteCString()); + Ctx->getELFSection(".debug_str.dwo", ELF::SHT_PROGBITS, + ELF::SHF_MERGE | ELF::SHF_STRINGS, 1, ""); DwarfLineDWOSection = - Ctx->getELFSection(".debug_line.dwo", ELF::SHT_PROGBITS, 0, - SectionKind::getMetadata()); + Ctx->getELFSection(".debug_line.dwo", ELF::SHT_PROGBITS, 0); DwarfLocDWOSection = - Ctx->getELFSection(".debug_loc.dwo", ELF::SHT_PROGBITS, 0, - SectionKind::getMetadata()); + Ctx->getELFSection(".debug_loc.dwo", ELF::SHT_PROGBITS, 0, "skel_loc"); DwarfStrOffDWOSection = - Ctx->getELFSection(".debug_str_offsets.dwo", ELF::SHT_PROGBITS, 0, - SectionKind::getMetadata()); + Ctx->getELFSection(".debug_str_offsets.dwo", ELF::SHT_PROGBITS, 0); DwarfAddrSection = - Ctx->getELFSection(".debug_addr", ELF::SHT_PROGBITS, 0, - SectionKind::getMetadata()); + Ctx->getELFSection(".debug_addr", ELF::SHT_PROGBITS, 0, "addr_sec"); StackMapSection = - Ctx->getELFSection(".llvm_stackmaps", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC, - SectionKind::getMetadata()); - + Ctx->getELFSection(".llvm_stackmaps", ELF::SHT_PROGBITS, ELF::SHF_ALLOC); } - void MCObjectFileInfo::InitCOFFMCObjectFileInfo(Triple T) { bool IsWoA = T.getArch() == Triple::arm || T.getArch() == Triple::thumb; CommDirectiveSupportsAlignment = true; // COFF - BSSSection = - Ctx->getCOFFSection(".bss", - COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA | - COFF::IMAGE_SCN_MEM_READ | - COFF::IMAGE_SCN_MEM_WRITE, - SectionKind::getBSS()); - TextSection = - Ctx->getCOFFSection(".text", - (IsWoA ? COFF::IMAGE_SCN_MEM_16BIT - : (COFF::SectionCharacteristics)0) | - COFF::IMAGE_SCN_CNT_CODE | - COFF::IMAGE_SCN_MEM_EXECUTE | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getText()); - DataSection = - Ctx->getCOFFSection(".data", - COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | - COFF::IMAGE_SCN_MEM_READ | - COFF::IMAGE_SCN_MEM_WRITE, - SectionKind::getDataRel()); - ReadOnlySection = - Ctx->getCOFFSection(".rdata", - COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getReadOnly()); + BSSSection = Ctx->getCOFFSection( + ".bss", COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_MEM_WRITE, + SectionKind::getBSS()); + TextSection = Ctx->getCOFFSection( + ".text", + (IsWoA ? COFF::IMAGE_SCN_MEM_16BIT : (COFF::SectionCharacteristics)0) | + COFF::IMAGE_SCN_CNT_CODE | COFF::IMAGE_SCN_MEM_EXECUTE | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getText()); + DataSection = Ctx->getCOFFSection( + ".data", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ | + COFF::IMAGE_SCN_MEM_WRITE, + SectionKind::getDataRel()); + ReadOnlySection = Ctx->getCOFFSection( + ".rdata", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ, + SectionKind::getReadOnly()); if (T.isKnownWindowsMSVCEnvironment() || T.isWindowsItaniumEnvironment()) { StaticCtorSection = - Ctx->getCOFFSection(".CRT$XCU", - COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getReadOnly()); + Ctx->getCOFFSection(".CRT$XCU", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getReadOnly()); StaticDtorSection = - Ctx->getCOFFSection(".CRT$XTX", - COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getReadOnly()); + Ctx->getCOFFSection(".CRT$XTX", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getReadOnly()); } else { - StaticCtorSection = - Ctx->getCOFFSection(".ctors", - COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | - COFF::IMAGE_SCN_MEM_READ | - COFF::IMAGE_SCN_MEM_WRITE, - SectionKind::getDataRel()); - StaticDtorSection = - Ctx->getCOFFSection(".dtors", - COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | - COFF::IMAGE_SCN_MEM_READ | - COFF::IMAGE_SCN_MEM_WRITE, - SectionKind::getDataRel()); + StaticCtorSection = Ctx->getCOFFSection( + ".ctors", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_MEM_WRITE, + SectionKind::getDataRel()); + StaticDtorSection = Ctx->getCOFFSection( + ".dtors", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_MEM_WRITE, + SectionKind::getDataRel()); } // FIXME: We're emitting LSDA info into a readonly section on COFF, even @@ -675,163 +575,149 @@ void MCObjectFileInfo::InitCOFFMCObjectFileInfo(Triple T) { // Debug info. COFFDebugSymbolsSection = - Ctx->getCOFFSection(".debug$S", - COFF::IMAGE_SCN_MEM_DISCARDABLE | - COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getMetadata()); - - DwarfAbbrevSection = - Ctx->getCOFFSection(".debug_abbrev", - COFF::IMAGE_SCN_MEM_DISCARDABLE | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getMetadata()); - DwarfInfoSection = - Ctx->getCOFFSection(".debug_info", - COFF::IMAGE_SCN_MEM_DISCARDABLE | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getMetadata()); - DwarfLineSection = - Ctx->getCOFFSection(".debug_line", - COFF::IMAGE_SCN_MEM_DISCARDABLE | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getMetadata()); - DwarfFrameSection = - Ctx->getCOFFSection(".debug_frame", - COFF::IMAGE_SCN_MEM_DISCARDABLE | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getMetadata()); - DwarfPubNamesSection = - Ctx->getCOFFSection(".debug_pubnames", - COFF::IMAGE_SCN_MEM_DISCARDABLE | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getMetadata()); - DwarfPubTypesSection = - Ctx->getCOFFSection(".debug_pubtypes", - COFF::IMAGE_SCN_MEM_DISCARDABLE | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getMetadata()); - DwarfGnuPubNamesSection = - Ctx->getCOFFSection(".debug_gnu_pubnames", - COFF::IMAGE_SCN_MEM_DISCARDABLE | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getMetadata()); - DwarfGnuPubTypesSection = - Ctx->getCOFFSection(".debug_gnu_pubtypes", - COFF::IMAGE_SCN_MEM_DISCARDABLE | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getMetadata()); - DwarfStrSection = - Ctx->getCOFFSection(".debug_str", - COFF::IMAGE_SCN_MEM_DISCARDABLE | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getMetadata()); - DwarfLocSection = - Ctx->getCOFFSection(".debug_loc", - COFF::IMAGE_SCN_MEM_DISCARDABLE | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getMetadata()); - DwarfARangesSection = - Ctx->getCOFFSection(".debug_aranges", - COFF::IMAGE_SCN_MEM_DISCARDABLE | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getMetadata()); - DwarfRangesSection = - Ctx->getCOFFSection(".debug_ranges", - COFF::IMAGE_SCN_MEM_DISCARDABLE | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getMetadata()); - DwarfMacroInfoSection = - Ctx->getCOFFSection(".debug_macinfo", - COFF::IMAGE_SCN_MEM_DISCARDABLE | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getMetadata()); - DwarfInfoDWOSection = - Ctx->getCOFFSection(".debug_info.dwo", - COFF::IMAGE_SCN_MEM_DISCARDABLE | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getMetadata()); - DwarfTypesDWOSection = - Ctx->getCOFFSection(".debug_types.dwo", COFF::IMAGE_SCN_MEM_DISCARDABLE | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getMetadata()); - DwarfAbbrevDWOSection = - Ctx->getCOFFSection(".debug_abbrev.dwo", - COFF::IMAGE_SCN_MEM_DISCARDABLE | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getMetadata()); - DwarfStrDWOSection = - Ctx->getCOFFSection(".debug_str.dwo", - COFF::IMAGE_SCN_MEM_DISCARDABLE | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getMetadata()); - DwarfLineDWOSection = - Ctx->getCOFFSection(".debug_line.dwo", - COFF::IMAGE_SCN_MEM_DISCARDABLE | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getMetadata()); - DwarfLocDWOSection = - Ctx->getCOFFSection(".debug_loc.dwo", - COFF::IMAGE_SCN_MEM_DISCARDABLE | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getMetadata()); - DwarfStrOffDWOSection = - Ctx->getCOFFSection(".debug_str_offsets.dwo", - COFF::IMAGE_SCN_MEM_DISCARDABLE | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getMetadata()); - - DwarfAddrSection = - Ctx->getCOFFSection(".debug_addr", - COFF::IMAGE_SCN_MEM_DISCARDABLE | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getMetadata()); - - DwarfAccelNamesSection = - Ctx->getCOFFSection(".apple_names", - COFF::IMAGE_SCN_MEM_DISCARDABLE | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getMetadata()); - DwarfAccelNamespaceSection = - Ctx->getCOFFSection(".apple_namespaces", - COFF::IMAGE_SCN_MEM_DISCARDABLE | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getMetadata()); - DwarfAccelTypesSection = - Ctx->getCOFFSection(".apple_types", - COFF::IMAGE_SCN_MEM_DISCARDABLE | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getMetadata()); - DwarfAccelObjCSection = - Ctx->getCOFFSection(".apple_objc", - COFF::IMAGE_SCN_MEM_DISCARDABLE | - COFF::IMAGE_SCN_MEM_READ, + Ctx->getCOFFSection(".debug$S", COFF::IMAGE_SCN_MEM_DISCARDABLE | + COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ, SectionKind::getMetadata()); - DrectveSection = - Ctx->getCOFFSection(".drectve", - COFF::IMAGE_SCN_LNK_INFO | - COFF::IMAGE_SCN_LNK_REMOVE, - SectionKind::getMetadata()); - - PDataSection = - Ctx->getCOFFSection(".pdata", - COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getDataRel()); - - XDataSection = - Ctx->getCOFFSection(".xdata", - COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getDataRel()); - - TLSDataSection = - Ctx->getCOFFSection(".tls$", - COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | - COFF::IMAGE_SCN_MEM_READ | - COFF::IMAGE_SCN_MEM_WRITE, - SectionKind::getDataRel()); + DwarfAbbrevSection = Ctx->getCOFFSection( + ".debug_abbrev", + COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getMetadata(), "section_abbrev"); + DwarfInfoSection = Ctx->getCOFFSection( + ".debug_info", + COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getMetadata(), "section_info"); + DwarfLineSection = Ctx->getCOFFSection( + ".debug_line", + COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getMetadata(), "section_line"); + + DwarfFrameSection = Ctx->getCOFFSection( + ".debug_frame", + COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getMetadata()); + DwarfPubNamesSection = Ctx->getCOFFSection( + ".debug_pubnames", + COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getMetadata()); + DwarfPubTypesSection = Ctx->getCOFFSection( + ".debug_pubtypes", + COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getMetadata()); + DwarfGnuPubNamesSection = Ctx->getCOFFSection( + ".debug_gnu_pubnames", + COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getMetadata()); + DwarfGnuPubTypesSection = Ctx->getCOFFSection( + ".debug_gnu_pubtypes", + COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getMetadata()); + DwarfStrSection = Ctx->getCOFFSection( + ".debug_str", + COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getMetadata(), "info_string"); + DwarfLocSection = Ctx->getCOFFSection( + ".debug_loc", + COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getMetadata(), "section_debug_loc"); + DwarfARangesSection = Ctx->getCOFFSection( + ".debug_aranges", + COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getMetadata()); + DwarfRangesSection = Ctx->getCOFFSection( + ".debug_ranges", + COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getMetadata(), "debug_range"); + DwarfInfoDWOSection = Ctx->getCOFFSection( + ".debug_info.dwo", + COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getMetadata(), "section_info_dwo"); + DwarfTypesDWOSection = Ctx->getCOFFSection( + ".debug_types.dwo", + COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getMetadata(), "section_types_dwo"); + DwarfAbbrevDWOSection = Ctx->getCOFFSection( + ".debug_abbrev.dwo", + COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getMetadata(), "section_abbrev_dwo"); + DwarfStrDWOSection = Ctx->getCOFFSection( + ".debug_str.dwo", + COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getMetadata(), "skel_string"); + DwarfLineDWOSection = Ctx->getCOFFSection( + ".debug_line.dwo", + COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getMetadata()); + DwarfLocDWOSection = Ctx->getCOFFSection( + ".debug_loc.dwo", + COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getMetadata(), "skel_loc"); + DwarfStrOffDWOSection = Ctx->getCOFFSection( + ".debug_str_offsets.dwo", + COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getMetadata()); + DwarfAddrSection = Ctx->getCOFFSection( + ".debug_addr", + COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getMetadata(), "addr_sec"); + DwarfAccelNamesSection = Ctx->getCOFFSection( + ".apple_names", + COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getMetadata(), "names_begin"); + DwarfAccelNamespaceSection = Ctx->getCOFFSection( + ".apple_namespaces", + COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getMetadata(), "namespac_begin"); + DwarfAccelTypesSection = Ctx->getCOFFSection( + ".apple_types", + COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getMetadata(), "types_begin"); + DwarfAccelObjCSection = Ctx->getCOFFSection( + ".apple_objc", + COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getMetadata(), "objc_begin"); + + DrectveSection = Ctx->getCOFFSection( + ".drectve", COFF::IMAGE_SCN_LNK_INFO | COFF::IMAGE_SCN_LNK_REMOVE, + SectionKind::getMetadata()); + + PDataSection = Ctx->getCOFFSection( + ".pdata", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ, + SectionKind::getDataRel()); + + XDataSection = Ctx->getCOFFSection( + ".xdata", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ, + SectionKind::getDataRel()); + + TLSDataSection = Ctx->getCOFFSection( + ".tls$", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ | + COFF::IMAGE_SCN_MEM_WRITE, + SectionKind::getDataRel()); } void MCObjectFileInfo::InitMCObjectFileInfo(StringRef T, Reloc::Model relocm, @@ -868,7 +754,7 @@ void MCObjectFileInfo::InitMCObjectFileInfo(StringRef T, Reloc::Model relocm, Arch == Triple::aarch64 || Arch == Triple::ppc || Arch == Triple::ppc64 || Arch == Triple::UnknownArch) && - (TT.isOSDarwin() || TT.isOSBinFormatMachO())) { + TT.isOSBinFormatMachO()) { Env = IsMachO; InitMachOMCObjectFileInfo(TT); } else if ((Arch == Triple::x86 || Arch == Triple::x86_64 || @@ -882,9 +768,9 @@ void MCObjectFileInfo::InitMCObjectFileInfo(StringRef T, Reloc::Model relocm, } } -const MCSection *MCObjectFileInfo::getDwarfTypesSection(uint64_t Hash) const { +MCSection *MCObjectFileInfo::getDwarfTypesSection(uint64_t Hash) const { return Ctx->getELFSection(".debug_types", ELF::SHT_PROGBITS, ELF::SHF_GROUP, - SectionKind::getMetadata(), 0, utostr(Hash)); + 0, utostr(Hash)); } void MCObjectFileInfo::InitEHFrameSection() { @@ -898,9 +784,7 @@ void MCObjectFileInfo::InitEHFrameSection() { SectionKind::getReadOnly()); else if (Env == IsELF) EHFrameSection = - Ctx->getELFSection(".eh_frame", EHSectionType, - EHSectionFlags, - SectionKind::getDataRel()); + Ctx->getELFSection(".eh_frame", EHSectionType, EHSectionFlags); else EHFrameSection = Ctx->getCOFFSection(".eh_frame", diff --git a/contrib/llvm/lib/MC/MCObjectStreamer.cpp b/contrib/llvm/lib/MC/MCObjectStreamer.cpp index 08fe501..176f5e7 100644 --- a/contrib/llvm/lib/MC/MCObjectStreamer.cpp +++ b/contrib/llvm/lib/MC/MCObjectStreamer.cpp @@ -20,21 +20,17 @@ #include "llvm/MC/MCSection.h" #include "llvm/MC/MCSymbol.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/TargetRegistry.h" using namespace llvm; MCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, - raw_ostream &OS, MCCodeEmitter *Emitter_) + raw_pwrite_stream &OS, + MCCodeEmitter *Emitter_) : MCStreamer(Context), Assembler(new MCAssembler(Context, TAB, *Emitter_, *TAB.createObjectWriter(OS), OS)), CurSectionData(nullptr), EmitEHFrame(true), EmitDebugFrame(false) {} -MCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, - raw_ostream &OS, MCCodeEmitter *Emitter_, - MCAssembler *_Assembler) - : MCStreamer(Context), Assembler(_Assembler), CurSectionData(nullptr), - EmitEHFrame(true), EmitDebugFrame(false) {} - MCObjectStreamer::~MCObjectStreamer() { delete &Assembler->getBackend(); delete &Assembler->getEmitter(); @@ -42,7 +38,7 @@ MCObjectStreamer::~MCObjectStreamer() { delete Assembler; } -void MCObjectStreamer::flushPendingLabels(MCFragment *F) { +void MCObjectStreamer::flushPendingLabels(MCFragment *F, uint64_t FOffset) { if (PendingLabels.size()) { if (!F) { F = new MCDataFragment(); @@ -51,17 +47,40 @@ void MCObjectStreamer::flushPendingLabels(MCFragment *F) { } for (MCSymbolData *SD : PendingLabels) { SD->setFragment(F); - SD->setOffset(0); + SD->setOffset(FOffset); } PendingLabels.clear(); } } +bool MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi, + const MCSymbol *Lo, + unsigned Size) { + // Must have symbol data. + if (!Assembler->hasSymbolData(*Hi) || !Assembler->hasSymbolData(*Lo)) + return false; + auto &HiD = Assembler->getSymbolData(*Hi); + auto &LoD = Assembler->getSymbolData(*Lo); + + // Must both be assigned to the same (valid) fragment. + if (!HiD.getFragment() || HiD.getFragment() != LoD.getFragment()) + return false; + + // Must be a data fragment. + if (!isa<MCDataFragment>(HiD.getFragment())) + return false; + + assert(HiD.getOffset() >= LoD.getOffset() && + "Expected Hi to be greater than Lo"); + EmitIntValue(HiD.getOffset() - LoD.getOffset(), Size); + return true; +} + void MCObjectStreamer::reset() { if (Assembler) Assembler->reset(); CurSectionData = nullptr; - CurInsertionPoint = MCSectionData::iterator(); + CurInsertionPoint = MCSection::iterator(); EmitEHFrame = true; EmitDebugFrame = false; PendingLabels.clear(); @@ -92,7 +111,8 @@ MCDataFragment *MCObjectStreamer::getOrCreateDataFragment() { MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment()); // When bundling is enabled, we don't want to add data to a fragment that // already has instructions (see MCELFStreamer::EmitInstToData for details) - if (!F || (Assembler->isBundlingEnabled() && F->hasInstructions())) { + if (!F || (Assembler->isBundlingEnabled() && !Assembler->getRelaxAll() && + F->hasInstructions())) { F = new MCDataFragment(); insert(F); } @@ -123,19 +143,19 @@ void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, return; } DF->getFixups().push_back( - MCFixup::Create(DF->getContents().size(), Value, + MCFixup::create(DF->getContents().size(), Value, MCFixup::getKindForSize(Size, false), Loc)); DF->getContents().resize(DF->getContents().size() + Size, 0); } void MCObjectStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) { // We need to create a local symbol to avoid relocations. - Frame.Begin = getContext().CreateTempSymbol(); + Frame.Begin = getContext().createTempSymbol(); EmitLabel(Frame.Begin); } void MCObjectStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) { - Frame.End = getContext().CreateTempSymbol(); + Frame.End = getContext().createTempSymbol(); EmitLabel(Frame.End); } @@ -148,7 +168,9 @@ void MCObjectStreamer::EmitLabel(MCSymbol *Symbol) { // If there is a current fragment, mark the symbol as pointing into it. // Otherwise queue the label and set its fragment pointer when we emit the // next fragment. - if (auto *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment())) { + auto *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment()); + if (F && !(getAssembler().isBundlingEnabled() && + getAssembler().getRelaxAll())) { SD.setFragment(F); SD.setOffset(F->getContents().size()); } else { @@ -179,12 +201,18 @@ void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias, report_fatal_error("This file format doesn't support weak aliases."); } -void MCObjectStreamer::ChangeSection(const MCSection *Section, +void MCObjectStreamer::ChangeSection(MCSection *Section, const MCExpr *Subsection) { + changeSectionImpl(Section, Subsection); +} + +bool MCObjectStreamer::changeSectionImpl(MCSection *Section, + const MCExpr *Subsection) { assert(Section && "Cannot switch to a null section!"); flushPendingLabels(nullptr); - CurSectionData = &getAssembler().getOrCreateSectionData(*Section); + bool Created = getAssembler().registerSection(*Section); + CurSectionData = Section; int64_t IntSubsection = 0; if (Subsection && @@ -193,7 +221,8 @@ void MCObjectStreamer::ChangeSection(const MCSection *Section, if (IntSubsection < 0 || IntSubsection > 8192) report_fatal_error("Subsection number out of range"); CurInsertionPoint = - CurSectionData->getSubsectionInsertionPoint(unsigned(IntSubsection)); + CurSectionData->getSubsectionInsertionPoint(unsigned(IntSubsection)); + return Created; } void MCObjectStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { @@ -201,12 +230,16 @@ void MCObjectStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { MCStreamer::EmitAssignment(Symbol, Value); } +bool MCObjectStreamer::mayHaveInstructions(MCSection &Sec) const { + return Sec.hasInstructions(); +} + void MCObjectStreamer::EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) { MCStreamer::EmitInstruction(Inst, STI); - MCSectionData *SD = getCurrentSectionData(); - SD->setHasInstructions(true); + MCSection *Sec = getCurrentSectionData(); + Sec->setHasInstructions(true); // Now that a machine instruction has been assembled into this section, make // a line entry for any .loc directive that has been seen. @@ -225,7 +258,7 @@ void MCObjectStreamer::EmitInstruction(const MCInst &Inst, // group. We want to emit all such instructions into the same data // fragment. if (Assembler.getRelaxAll() || - (Assembler.isBundlingEnabled() && SD->isBundleLocked())) { + (Assembler.isBundlingEnabled() && Sec->isBundleLocked())) { MCInst Relaxed; getAssembler().getBackend().relaxInstruction(Inst, Relaxed); while (getAssembler().getBackend().mayNeedRelaxation(Relaxed)) @@ -240,6 +273,9 @@ void MCObjectStreamer::EmitInstruction(const MCInst &Inst, void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &STI) { + if (getAssembler().getRelaxAll() && getAssembler().isBundlingEnabled()) + llvm_unreachable("All instructions should have already been relaxed"); + // Always create a new, separate fragment here, because its size can change // during relaxation. MCRelaxableFragment *IF = new MCRelaxableFragment(Inst, STI); @@ -247,7 +283,7 @@ void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst, SmallString<128> Code; raw_svector_ostream VecOS(Code); - getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, IF->getFixups(), + getAssembler().getEmitter().encodeInstruction(Inst, VecOS, IF->getFixups(), STI); VecOS.flush(); IF->getContents().append(Code.begin(), Code.end()); @@ -348,8 +384,9 @@ void MCObjectStreamer::EmitValueToAlignment(unsigned ByteAlignment, insert(new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit)); // Update the maximum alignment on the current section if necessary. - if (ByteAlignment > getCurrentSectionData()->getAlignment()) - getCurrentSectionData()->setAlignment(ByteAlignment); + MCSection *CurSec = getCurrentSection().first; + if (ByteAlignment > CurSec->getAlignment()) + CurSec->setAlignment(ByteAlignment); } void MCObjectStreamer::EmitCodeAlignment(unsigned ByteAlignment, @@ -366,7 +403,7 @@ bool MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset, return false; } - MCSymbol *CurrentPos = getContext().CreateTempSymbol(); + MCSymbol *CurrentPos = getContext().createTempSymbol(); EmitLabel(CurrentPos); MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; const MCExpr *Ref = @@ -384,7 +421,7 @@ bool MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset, void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) { MCDataFragment *DF = getOrCreateDataFragment(); - DF->getFixups().push_back(MCFixup::Create(DF->getContents().size(), + DF->getFixups().push_back(MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4)); DF->getContents().resize(DF->getContents().size() + 4, 0); } @@ -393,7 +430,7 @@ void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) { void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) { MCDataFragment *DF = getOrCreateDataFragment(); - DF->getFixups().push_back(MCFixup::Create(DF->getContents().size(), + DF->getFixups().push_back(MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4)); DF->getContents().resize(DF->getContents().size() + 8, 0); } diff --git a/contrib/llvm/lib/MC/MCObjectWriter.cpp b/contrib/llvm/lib/MC/MCObjectWriter.cpp index 94d7cd6..5cc629b 100644 --- a/contrib/llvm/lib/MC/MCObjectWriter.cpp +++ b/contrib/llvm/lib/MC/MCObjectWriter.cpp @@ -17,11 +17,9 @@ using namespace llvm; MCObjectWriter::~MCObjectWriter() { } -bool -MCObjectWriter::IsSymbolRefDifferenceFullyResolved(const MCAssembler &Asm, - const MCSymbolRefExpr *A, - const MCSymbolRefExpr *B, - bool InSet) const { +bool MCObjectWriter::IsSymbolRefDifferenceFullyResolved( + const MCAssembler &Asm, const MCSymbolRefExpr *A, const MCSymbolRefExpr *B, + bool InSet) const { // Modified symbol references cannot be resolved. if (A->getKind() != MCSymbolRefExpr::VK_None || B->getKind() != MCSymbolRefExpr::VK_None) @@ -29,7 +27,7 @@ MCObjectWriter::IsSymbolRefDifferenceFullyResolved(const MCAssembler &Asm, const MCSymbol &SA = A->getSymbol(); const MCSymbol &SB = B->getSymbol(); - if (SA.AliasedSymbol().isUndefined() || SB.AliasedSymbol().isUndefined()) + if (SA.isUndefined() || SB.isUndefined()) return false; const MCSymbolData &DataA = Asm.getSymbolData(SA); @@ -37,20 +35,17 @@ MCObjectWriter::IsSymbolRefDifferenceFullyResolved(const MCAssembler &Asm, if(!DataA.getFragment() || !DataB.getFragment()) return false; - return IsSymbolRefDifferenceFullyResolvedImpl(Asm, DataA, - *DataB.getFragment(), - InSet, - false); + return IsSymbolRefDifferenceFullyResolvedImpl(Asm, SA, *DataB.getFragment(), + InSet, false); } -bool -MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, - const MCSymbolData &DataA, - const MCFragment &FB, - bool InSet, - bool IsPCRel) const { - const MCSection &SecA = DataA.getSymbol().AliasedSymbol().getSection(); - const MCSection &SecB = FB.getParent()->getSection(); +bool MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl( + const MCAssembler &Asm, const MCSymbol &SymA, const MCFragment &FB, + bool InSet, bool IsPCRel) const { + const MCSection &SecA = SymA.getSection(); + const MCSection &SecB = *FB.getParent(); // On ELF and COFF A - B is absolute if A and B are in the same section. return &SecA == &SecB; } + +bool MCObjectWriter::isWeak(const MCSymbol &) const { return false; } diff --git a/contrib/llvm/lib/MC/MCParser/AsmLexer.cpp b/contrib/llvm/lib/MC/MCParser/AsmLexer.cpp index 5c8ec66..b983d99 100644 --- a/contrib/llvm/lib/MC/MCParser/AsmLexer.cpp +++ b/contrib/llvm/lib/MC/MCParser/AsmLexer.cpp @@ -21,7 +21,7 @@ #include <cstdlib> using namespace llvm; -AsmLexer::AsmLexer(const MCAsmInfo &_MAI) : MAI(_MAI) { +AsmLexer::AsmLexer(const MCAsmInfo &MAI) : MAI(MAI) { CurPtr = nullptr; isAtStartOfLine = true; AllowAtInIdentifier = !StringRef(MAI.getCommentString()).startswith("@"); diff --git a/contrib/llvm/lib/MC/MCParser/AsmParser.cpp b/contrib/llvm/lib/MC/MCParser/AsmParser.cpp index e2a4fc1..1e805fd 100644 --- a/contrib/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/contrib/llvm/lib/MC/MCParser/AsmParser.cpp @@ -111,8 +111,8 @@ struct ParseStatementInfo { /// \brief The concrete assembly parser instance. class AsmParser : public MCAsmParser { - AsmParser(const AsmParser &) LLVM_DELETED_FUNCTION; - void operator=(const AsmParser &) LLVM_DELETED_FUNCTION; + AsmParser(const AsmParser &) = delete; + void operator=(const AsmParser &) = delete; private: AsmLexer Lexer; MCContext &Ctx; @@ -147,6 +147,9 @@ private: /// Boolean tracking whether macro substitution is enabled. unsigned MacrosEnabledFlag : 1; + /// \brief Keeps track of how many .macro's have been instantiated. + unsigned NumOfMacroInstantiations; + /// Flag tracking whether any errors have been encountered. unsigned HadError : 1; @@ -175,7 +178,7 @@ private: public: AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out, const MCAsmInfo &MAI); - virtual ~AsmParser(); + ~AsmParser() override; bool Run(bool NoInitialTextSection, bool NoFinalize = false) override; @@ -184,6 +187,10 @@ public: ExtensionDirectiveMap[Directive] = Handler; } + void addAliasForDirective(StringRef Directive, StringRef Alias) override { + DirectiveKindMap[Directive] = DirectiveKindMap[Alias]; + } + public: /// @name MCAsmParser Interface /// { @@ -247,7 +254,7 @@ private: ArrayRef<MCAsmMacroParameter> Parameters); bool expandMacro(raw_svector_ostream &OS, StringRef Body, ArrayRef<MCAsmMacroParameter> Parameters, - ArrayRef<MCAsmMacroArgument> A, + ArrayRef<MCAsmMacroArgument> A, bool EnableAtPseudoVariable, const SMLoc &L); /// \brief Are macros enabled in the parser? @@ -319,6 +326,9 @@ private: bool parseAssignment(StringRef Name, bool allow_redef, bool NoDeadStrip = false); + unsigned getBinOpPrecedence(AsmToken::TokenKind K, + MCBinaryExpr::Opcode &Kind); + bool parseBinOpRHS(unsigned Precedence, const MCExpr *&Res, SMLoc &EndLoc); bool parseParenExpr(const MCExpr *&Res, SMLoc &EndLoc); bool parseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc); @@ -339,8 +349,8 @@ private: DK_WEAK_DEF_CAN_BE_HIDDEN, DK_COMM, DK_COMMON, DK_LCOMM, DK_ABORT, DK_INCLUDE, DK_INCBIN, DK_CODE16, DK_CODE16GCC, DK_REPT, DK_IRP, DK_IRPC, DK_IF, DK_IFEQ, DK_IFGE, DK_IFGT, DK_IFLE, DK_IFLT, DK_IFNE, DK_IFB, - DK_IFNB, DK_IFC, DK_IFEQS, DK_IFNC, DK_IFDEF, DK_IFNDEF, DK_IFNOTDEF, - DK_ELSEIF, DK_ELSE, DK_ENDIF, + DK_IFNB, DK_IFC, DK_IFEQS, DK_IFNC, DK_IFNES, DK_IFDEF, DK_IFNDEF, + DK_IFNOTDEF, DK_ELSEIF, DK_ELSE, DK_ENDIF, DK_SPACE, DK_SKIP, DK_FILE, DK_LINE, DK_LOC, DK_STABS, DK_CFI_SECTIONS, DK_CFI_STARTPROC, DK_CFI_ENDPROC, DK_CFI_DEF_CFA, DK_CFI_DEF_CFA_OFFSET, DK_CFI_ADJUST_CFA_OFFSET, DK_CFI_DEF_CFA_REGISTER, @@ -435,8 +445,8 @@ private: bool parseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank); // ".ifc" or ".ifnc", depending on ExpectEqual. bool parseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual); - // ".ifeqs" - bool parseDirectiveIfeqs(SMLoc DirectiveLoc); + // ".ifeqs" or ".ifnes", depending on ExpectEqual. + bool parseDirectiveIfeqs(SMLoc DirectiveLoc, bool ExpectEqual); // ".ifdef" or ".ifndef", depending on expect_defined bool parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined); bool parseDirectiveElseIf(SMLoc DirectiveLoc); // ".elseif" @@ -486,10 +496,10 @@ extern MCAsmParserExtension *createCOFFAsmParser(); enum { DEFAULT_ADDRSPACE = 0 }; -AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx, MCStreamer &_Out, - const MCAsmInfo &_MAI) - : Lexer(_MAI), Ctx(_Ctx), Out(_Out), MAI(_MAI), SrcMgr(_SM), - PlatformParser(nullptr), CurBuffer(_SM.getMainFileID()), +AsmParser::AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out, + const MCAsmInfo &MAI) + : Lexer(MAI), Ctx(Ctx), Out(Out), MAI(MAI), SrcMgr(SM), + PlatformParser(nullptr), CurBuffer(SM.getMainFileID()), MacrosEnabledFlag(true), HadError(false), CppHashLineNumber(0), AssemblerDialect(~0U), IsDarwin(false), ParsingInlineAsm(false) { // Save the old handler. @@ -500,7 +510,7 @@ AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx, MCStreamer &_Out, Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer()); // Initialize the platform / file format parser. - switch (_Ctx.getObjectFileInfo()->getObjectFileType()) { + switch (Ctx.getObjectFileInfo()->getObjectFileType()) { case MCObjectFileInfo::IsCOFF: PlatformParser.reset(createCOFFAsmParser()); break; @@ -515,6 +525,8 @@ AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx, MCStreamer &_Out, PlatformParser->Initialize(*this); initializeDirectiveKindMap(); + + NumOfMacroInstantiations = 0; } AsmParser::~AsmParser() { @@ -618,12 +630,13 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) { // If we are generating dwarf for assembly source files save the initial text // section and generate a .file directive. if (getContext().getGenDwarfForAssembly()) { - MCSymbol *SectionStartSym = getContext().CreateTempSymbol(); + MCSymbol *SectionStartSym = getContext().createTempSymbol(); getStreamer().EmitLabel(SectionStartSym); - auto InsertResult = getContext().addGenDwarfSection( - getStreamer().getCurrentSection().first); - assert(InsertResult.second && ".text section should not have debug info yet"); - InsertResult.first->second.first = SectionStartSym; + MCSection *Sec = getStreamer().getCurrentSection().first; + bool InsertResult = getContext().addGenDwarfSection(Sec); + assert(InsertResult && ".text section should not have debug info yet"); + (void)InsertResult; + Sec->setBeginSymbol(SectionStartSym); getContext().setGenDwarfFileNumber(getStreamer().EmitDwarfFileDirective( 0, StringRef(), getContext().getMainFileName())); } @@ -786,7 +799,7 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { if (Lexer.getMAI().getDollarIsPC()) { // This is a '$' reference, which references the current PC. Emit a // temporary label to the streamer and refer to it. - MCSymbol *Sym = Ctx.CreateTempSymbol(); + MCSymbol *Sym = Ctx.createTempSymbol(); Out.EmitLabel(Sym); Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext()); @@ -843,7 +856,7 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { } } - MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName); + MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName); // If this is an absolute variable reference, substitute it now to preserve // semantics in the face of reassignment. @@ -881,7 +894,7 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { } if (IDVal == "f" || IDVal == "b") { MCSymbol *Sym = - Ctx.GetDirectionalLocalSymbol(IntVal, IDVal == "b"); + Ctx.getDirectionalLocalSymbol(IntVal, IDVal == "b"); Res = MCSymbolRefExpr::Create(Sym, Variant, getContext()); if (IDVal == "b" && Sym->isUndefined()) return Error(Loc, "invalid reference to undefined symbol"); @@ -902,7 +915,7 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { case AsmToken::Dot: { // This is a '.' reference, which references the current PC. Emit a // temporary label to the streamer and refer to it. - MCSymbol *Sym = Ctx.CreateTempSymbol(); + MCSymbol *Sym = Ctx.createTempSymbol(); Out.EmitLabel(Sym); Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext()); EndLoc = Lexer.getTok().getEndLoc(); @@ -1063,8 +1076,8 @@ bool AsmParser::parseAbsoluteExpression(int64_t &Res) { return false; } -static unsigned getBinOpPrecedence(AsmToken::TokenKind K, - MCBinaryExpr::Opcode &Kind) { +unsigned AsmParser::getBinOpPrecedence(AsmToken::TokenKind K, + MCBinaryExpr::Opcode &Kind) { switch (K) { default: return 0; // not a binop. @@ -1116,7 +1129,7 @@ static unsigned getBinOpPrecedence(AsmToken::TokenKind K, Kind = MCBinaryExpr::Shl; return 4; case AsmToken::GreaterGreater: - Kind = MCBinaryExpr::Shr; + Kind = MAI.shouldUseLogicalShr() ? MCBinaryExpr::LShr : MCBinaryExpr::AShr; return 4; // High Intermediate Precedence: +, - @@ -1244,9 +1257,11 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info, case DK_IFC: return parseDirectiveIfc(IDLoc, true); case DK_IFEQS: - return parseDirectiveIfeqs(IDLoc); + return parseDirectiveIfeqs(IDLoc, true); case DK_IFNC: return parseDirectiveIfc(IDLoc, false); + case DK_IFNES: + return parseDirectiveIfeqs(IDLoc, false); case DK_IFDEF: return parseDirectiveIfdef(IDLoc, true); case DK_IFNDEF: @@ -1295,9 +1310,9 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info, IDVal.size(), RewrittenLabel)); IDVal = RewrittenLabel; } - Sym = getContext().GetOrCreateSymbol(IDVal); + Sym = getContext().getOrCreateSymbol(IDVal); } else - Sym = Ctx.CreateDirectionalLocalSymbol(LocalLabelVal); + Sym = Ctx.createDirectionalLocalSymbol(LocalLabelVal); Sym->redefineIfPossible(); @@ -1758,7 +1773,8 @@ static bool isIdentifierChar(char c) { bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body, ArrayRef<MCAsmMacroParameter> Parameters, - ArrayRef<MCAsmMacroArgument> A, const SMLoc &L) { + ArrayRef<MCAsmMacroArgument> A, + bool EnableAtPseudoVariable, const SMLoc &L) { unsigned NParameters = Parameters.size(); bool HasVararg = NParameters ? Parameters.back().Vararg : false; if ((!IsDarwin || NParameters != 0) && NParameters != A.size()) @@ -1824,36 +1840,47 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body, Pos += 2; } else { unsigned I = Pos + 1; - while (isIdentifierChar(Body[I]) && I + 1 != End) + + // Check for the \@ pseudo-variable. + if (EnableAtPseudoVariable && Body[I] == '@' && I + 1 != End) ++I; + else + while (isIdentifierChar(Body[I]) && I + 1 != End) + ++I; const char *Begin = Body.data() + Pos + 1; StringRef Argument(Begin, I - (Pos + 1)); unsigned Index = 0; - for (; Index < NParameters; ++Index) - if (Parameters[Index].Name == Argument) - break; - if (Index == NParameters) { - if (Body[Pos + 1] == '(' && Body[Pos + 2] == ')') - Pos += 3; - else { - OS << '\\' << Argument; - Pos = I; - } + if (Argument == "@") { + OS << NumOfMacroInstantiations; + Pos += 2; } else { - bool VarargParameter = HasVararg && Index == (NParameters - 1); - for (MCAsmMacroArgument::const_iterator it = A[Index].begin(), - ie = A[Index].end(); - it != ie; ++it) - // We expect no quotes around the string's contents when - // parsing for varargs. - if (it->getKind() != AsmToken::String || VarargParameter) - OS << it->getString(); - else - OS << it->getStringContents(); - - Pos += 1 + Argument.size(); + for (; Index < NParameters; ++Index) + if (Parameters[Index].Name == Argument) + break; + + if (Index == NParameters) { + if (Body[Pos + 1] == '(' && Body[Pos + 2] == ')') + Pos += 3; + else { + OS << '\\' << Argument; + Pos = I; + } + } else { + bool VarargParameter = HasVararg && Index == (NParameters - 1); + for (MCAsmMacroArgument::const_iterator it = A[Index].begin(), + ie = A[Index].end(); + it != ie; ++it) + // We expect no quotes around the string's contents when + // parsing for varargs. + if (it->getKind() != AsmToken::String || VarargParameter) + OS << it->getString(); + else + OS << it->getStringContents(); + + Pos += 1 + Argument.size(); + } } } // Update the scan point. @@ -2111,7 +2138,7 @@ bool AsmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc) { StringRef Body = M->Body; raw_svector_ostream OS(Buf); - if (expandMacro(OS, Body, M->Parameters, A, getTok().getLoc())) + if (expandMacro(OS, Body, M->Parameters, A, true, getTok().getLoc())) return true; // We include the .endmacro in the buffer as our cue to exit the macro @@ -2127,6 +2154,8 @@ bool AsmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc) { NameLoc, CurBuffer, getTok().getLoc(), TheCondStack.size()); ActiveMacros.push_back(MI); + ++NumOfMacroInstantiations; + // Jump to the macro instantiation and prime the lexer. CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Instantiation), SMLoc()); Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer()); @@ -2189,7 +2218,7 @@ bool AsmParser::parseAssignment(StringRef Name, bool allow_redef, // Validate that the LHS is allowed to be a variable (either it has not been // used as a symbol, or it is an absolute symbol). - MCSymbol *Sym = getContext().LookupSymbol(Name); + MCSymbol *Sym = getContext().lookupSymbol(Name); if (Sym) { // Diagnose assignment to a label. // @@ -2218,7 +2247,7 @@ bool AsmParser::parseAssignment(StringRef Name, bool allow_redef, } return false; } else - Sym = getContext().GetOrCreateSymbol(Name); + Sym = getContext().getOrCreateSymbol(Name); Sym->setRedefinable(allow_redef); @@ -2791,7 +2820,7 @@ bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) { if (FileNumber == -1) getStreamer().EmitFileDirective(Filename); else { - if (getContext().getGenDwarfForAssembly() == true) + if (getContext().getGenDwarfForAssembly()) Error(DirectiveLoc, "input can't have .file dwarf directives when -g is " "used to generate dwarf debug info for assembly code"); @@ -3158,7 +3187,7 @@ bool AsmParser::parseDirectiveCFIPersonalityOrLsda(bool IsPersonality) { if (parseIdentifier(Name)) return TokError("expected identifier in directive"); - MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); + MCSymbol *Sym = getContext().getOrCreateSymbol(Name); if (IsPersonality) getStreamer().EmitCFIPersonality(Sym, Encoding); @@ -3275,7 +3304,7 @@ bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) { MCAsmMacroParameters Parameters; while (getLexer().isNot(AsmToken::EndOfStatement)) { - if (Parameters.size() && Parameters.back().Vararg) + if (!Parameters.empty() && Parameters.back().Vararg) return Error(Lexer.getLoc(), "Vararg parameter '" + Parameters.back().Name + "' should be last one in the list of parameters."); @@ -3672,7 +3701,7 @@ bool AsmParser::parseDirectiveSymbolAttribute(MCSymbolAttr Attr) { if (parseIdentifier(Name)) return Error(Loc, "expected identifier in directive"); - MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); + MCSymbol *Sym = getContext().getOrCreateSymbol(Name); // Assembler local symbols don't make any sense here. Complain loudly. if (Sym->isTemporary()) @@ -3705,7 +3734,7 @@ bool AsmParser::parseDirectiveComm(bool IsLocal) { return TokError("expected identifier in directive"); // Handle the identifier as the key symbol. - MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); + MCSymbol *Sym = getContext().getOrCreateSymbol(Name); if (getLexer().isNot(AsmToken::Comma)) return TokError("unexpected token in directive"); @@ -3943,9 +3972,12 @@ bool AsmParser::parseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual) { /// parseDirectiveIfeqs /// ::= .ifeqs string1, string2 -bool AsmParser::parseDirectiveIfeqs(SMLoc DirectiveLoc) { +bool AsmParser::parseDirectiveIfeqs(SMLoc DirectiveLoc, bool ExpectEqual) { if (Lexer.isNot(AsmToken::String)) { - TokError("expected string parameter for '.ifeqs' directive"); + if (ExpectEqual) + TokError("expected string parameter for '.ifeqs' directive"); + else + TokError("expected string parameter for '.ifnes' directive"); eatToEndOfStatement(); return true; } @@ -3954,7 +3986,10 @@ bool AsmParser::parseDirectiveIfeqs(SMLoc DirectiveLoc) { Lex(); if (Lexer.isNot(AsmToken::Comma)) { - TokError("expected comma after first string for '.ifeqs' directive"); + if (ExpectEqual) + TokError("expected comma after first string for '.ifeqs' directive"); + else + TokError("expected comma after first string for '.ifnes' directive"); eatToEndOfStatement(); return true; } @@ -3962,7 +3997,10 @@ bool AsmParser::parseDirectiveIfeqs(SMLoc DirectiveLoc) { Lex(); if (Lexer.isNot(AsmToken::String)) { - TokError("expected string parameter for '.ifeqs' directive"); + if (ExpectEqual) + TokError("expected string parameter for '.ifeqs' directive"); + else + TokError("expected string parameter for '.ifnes' directive"); eatToEndOfStatement(); return true; } @@ -3972,7 +4010,7 @@ bool AsmParser::parseDirectiveIfeqs(SMLoc DirectiveLoc) { TheCondStack.push_back(TheCondState); TheCondState.TheCond = AsmCond::IfCond; - TheCondState.CondMet = String1 == String2; + TheCondState.CondMet = ExpectEqual == (String1 == String2); TheCondState.Ignore = !TheCondState.CondMet; return false; @@ -3993,7 +4031,7 @@ bool AsmParser::parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) { Lex(); - MCSymbol *Sym = getContext().LookupSymbol(Name); + MCSymbol *Sym = getContext().lookupSymbol(Name); if (expect_defined) TheCondState.CondMet = (Sym && !Sym->isUndefined()); @@ -4219,6 +4257,7 @@ void AsmParser::initializeDirectiveKindMap() { DirectiveKindMap[".ifc"] = DK_IFC; DirectiveKindMap[".ifeqs"] = DK_IFEQS; DirectiveKindMap[".ifnc"] = DK_IFNC; + DirectiveKindMap[".ifnes"] = DK_IFNES; DirectiveKindMap[".ifdef"] = DK_IFDEF; DirectiveKindMap[".ifndef"] = DK_IFNDEF; DirectiveKindMap[".ifnotdef"] = DK_IFNOTDEF; @@ -4362,7 +4401,8 @@ bool AsmParser::parseDirectiveRept(SMLoc DirectiveLoc, StringRef Dir) { SmallString<256> Buf; raw_svector_ostream OS(Buf); while (Count--) { - if (expandMacro(OS, M->Body, None, None, getTok().getLoc())) + // Note that the AtPseudoVariable is disabled for instantiations of .rep(t). + if (expandMacro(OS, M->Body, None, None, false, getTok().getLoc())) return true; } instantiateMacroLikeBody(M, DirectiveLoc, OS); @@ -4401,7 +4441,9 @@ bool AsmParser::parseDirectiveIrp(SMLoc DirectiveLoc) { raw_svector_ostream OS(Buf); for (MCAsmMacroArguments::iterator i = A.begin(), e = A.end(); i != e; ++i) { - if (expandMacro(OS, M->Body, Parameter, *i, getTok().getLoc())) + // Note that the AtPseudoVariable is enabled for instantiations of .irp. + // This is undocumented, but GAS seems to support it. + if (expandMacro(OS, M->Body, Parameter, *i, true, getTok().getLoc())) return true; } @@ -4448,7 +4490,9 @@ bool AsmParser::parseDirectiveIrpc(SMLoc DirectiveLoc) { MCAsmMacroArgument Arg; Arg.push_back(AsmToken(AsmToken::Identifier, Values.slice(I, I + 1))); - if (expandMacro(OS, M->Body, Parameter, Arg, getTok().getLoc())) + // Note that the AtPseudoVariable is enabled for instantiations of .irpc. + // This is undocumented, but GAS seems to support it. + if (expandMacro(OS, M->Body, Parameter, Arg, true, getTok().getLoc())) return true; } @@ -4594,7 +4638,7 @@ bool AsmParser::parseMSInlineAsm( ++InputIdx; OutputDecls.push_back(OpDecl); OutputDeclsAddressOf.push_back(Operand.needAddressOf()); - OutputConstraints.push_back('=' + Operand.getConstraint().str()); + OutputConstraints.push_back(("=" + Operand.getConstraint()).str()); AsmStrRewrites.push_back(AsmRewrite(AOK_Output, Start, SymName.size())); } else { InputDecls.push_back(OpDecl); diff --git a/contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp b/contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp index 18bdb03..82f7f22 100644 --- a/contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp +++ b/contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp @@ -272,7 +272,7 @@ bool COFFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) { if (getParser().parseIdentifier(Name)) return TokError("expected identifier in directive"); - MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); + MCSymbol *Sym = getContext().getOrCreateSymbol(Name); getStreamer().EmitSymbolAttribute(Sym, Attr); @@ -398,7 +398,7 @@ bool COFFAsmParser::ParseDirectiveDef(StringRef, SMLoc) { if (getParser().parseIdentifier(SymbolName)) return TokError("expected identifier in directive"); - MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName); + MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName); getStreamer().BeginCOFFSymbolDef(Sym); @@ -446,7 +446,7 @@ bool COFFAsmParser::ParseDirectiveSecRel32(StringRef, SMLoc) { if (getLexer().isNot(AsmToken::EndOfStatement)) return TokError("unexpected token in directive"); - MCSymbol *Symbol = getContext().GetOrCreateSymbol(SymbolID); + MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID); Lex(); getStreamer().EmitCOFFSecRel32(Symbol); @@ -461,7 +461,7 @@ bool COFFAsmParser::ParseDirectiveSecIdx(StringRef, SMLoc) { if (getLexer().isNot(AsmToken::EndOfStatement)) return TokError("unexpected token in directive"); - MCSymbol *Symbol = getContext().GetOrCreateSymbol(SymbolID); + MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID); Lex(); getStreamer().EmitCOFFSectionIndex(Symbol); @@ -524,7 +524,7 @@ bool COFFAsmParser::ParseSEHDirectiveStartProc(StringRef, SMLoc) { if (getLexer().isNot(AsmToken::EndOfStatement)) return TokError("unexpected token in directive"); - MCSymbol *Symbol = getContext().GetOrCreateSymbol(SymbolID); + MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID); Lex(); getStreamer().EmitWinCFIStartProc(Symbol); @@ -568,7 +568,7 @@ bool COFFAsmParser::ParseSEHDirectiveHandler(StringRef, SMLoc) { if (getLexer().isNot(AsmToken::EndOfStatement)) return TokError("unexpected token in directive"); - MCSymbol *handler = getContext().GetOrCreateSymbol(SymbolID); + MCSymbol *handler = getContext().getOrCreateSymbol(SymbolID); Lex(); getStreamer().EmitWinEHHandler(handler, unwind, except); diff --git a/contrib/llvm/lib/MC/MCParser/DarwinAsmParser.cpp b/contrib/llvm/lib/MC/MCParser/DarwinAsmParser.cpp index 3ea745e..dc664e8 100644 --- a/contrib/llvm/lib/MC/MCParser/DarwinAsmParser.cpp +++ b/contrib/llvm/lib/MC/MCParser/DarwinAsmParser.cpp @@ -407,7 +407,7 @@ bool DarwinAsmParser::parseDirectiveDesc(StringRef, SMLoc) { return TokError("expected identifier in directive"); // Handle the identifier as the key symbol. - MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); + MCSymbol *Sym = getContext().getOrCreateSymbol(Name); if (getLexer().isNot(AsmToken::Comma)) return TokError("unexpected token in '.desc' directive"); @@ -444,7 +444,7 @@ bool DarwinAsmParser::parseDirectiveIndirectSymbol(StringRef, SMLoc Loc) { if (getParser().parseIdentifier(Name)) return TokError("expected identifier in .indirect_symbol directive"); - MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); + MCSymbol *Sym = getContext().getOrCreateSymbol(Name); // Assembler local symbols don't make any sense here. Complain loudly. if (Sym->isTemporary()) @@ -519,7 +519,7 @@ bool DarwinAsmParser::parseDirectiveLsym(StringRef, SMLoc) { return TokError("expected identifier in directive"); // Handle the identifier as the key symbol. - MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); + MCSymbol *Sym = getContext().getOrCreateSymbol(Name); if (getLexer().isNot(AsmToken::Comma)) return TokError("unexpected token in '.lsym' directive"); @@ -626,7 +626,7 @@ bool DarwinAsmParser::parseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) { if (getLexer().isNot(AsmToken::EndOfStatement)) return TokError("unexpected token in '.secure_log_unique' directive"); - if (getContext().getSecureLogUsed() != false) + if (getContext().getSecureLogUsed()) return Error(IDLoc, ".secure_log_unique specified multiple times"); // Get the secure log path. @@ -695,7 +695,7 @@ bool DarwinAsmParser::parseDirectiveTBSS(StringRef, SMLoc) { return TokError("expected identifier in directive"); // Handle the identifier as the key symbol. - MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); + MCSymbol *Sym = getContext().getOrCreateSymbol(Name); if (getLexer().isNot(AsmToken::Comma)) return TokError("unexpected token in directive"); @@ -778,7 +778,7 @@ bool DarwinAsmParser::parseDirectiveZerofill(StringRef, SMLoc) { return TokError("expected identifier in directive"); // handle the identifier as the key symbol. - MCSymbol *Sym = getContext().GetOrCreateSymbol(IDStr); + MCSymbol *Sym = getContext().getOrCreateSymbol(IDStr); if (getLexer().isNot(AsmToken::Comma)) return TokError("unexpected token in directive"); diff --git a/contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp b/contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp index e302004..87b15ff 100644 --- a/contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp +++ b/contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp @@ -174,7 +174,7 @@ bool ELFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) { if (getParser().parseIdentifier(Name)) return TokError("expected identifier in directive"); - MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); + MCSymbol *Sym = getContext().getOrCreateSymbol(Name); getStreamer().EmitSymbolAttribute(Sym, Attr); @@ -199,8 +199,7 @@ bool ELFAsmParser::ParseSectionSwitch(StringRef Section, unsigned Type, return true; } - getStreamer().SwitchSection(getContext().getELFSection( - Section, Type, Flags, Kind), + getStreamer().SwitchSection(getContext().getELFSection(Section, Type, Flags), Subsection); return false; @@ -210,7 +209,7 @@ bool ELFAsmParser::ParseDirectiveSize(StringRef, SMLoc) { StringRef Name; if (getParser().parseIdentifier(Name)) return TokError("expected identifier in directive"); - MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); + MCSymbol *Sym = getContext().getOrCreateSymbol(Name); if (getLexer().isNot(AsmToken::Comma)) return TokError("unexpected token in directive"); @@ -269,40 +268,6 @@ bool ELFAsmParser::ParseSectionName(StringRef &SectionName) { return false; } -static SectionKind computeSectionKind(unsigned Flags, unsigned ElemSize) { - if (Flags & ELF::SHF_EXECINSTR) - return SectionKind::getText(); - if (Flags & ELF::SHF_TLS) - return SectionKind::getThreadData(); - if (Flags & ELF::SHF_MERGE) { - if (Flags & ELF::SHF_STRINGS) { - switch (ElemSize) { - default: - break; - case 1: - return SectionKind::getMergeable1ByteCString(); - case 2: - return SectionKind::getMergeable2ByteCString(); - case 4: - return SectionKind::getMergeable4ByteCString(); - } - } else { - switch (ElemSize) { - default: - break; - case 4: - return SectionKind::getMergeableConst4(); - case 8: - return SectionKind::getMergeableConst8(); - case 16: - return SectionKind::getMergeableConst16(); - } - } - } - - return SectionKind::getDataRel(); -} - static unsigned parseSectionFlags(StringRef flagsStr, bool *UseLastGroup) { unsigned flags = 0; @@ -413,6 +378,8 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) { unsigned Flags = 0; const MCExpr *Subsection = nullptr; bool UseLastGroup = false; + StringRef UniqueStr; + int64_t UniqueID = ~0; // Set the defaults first. if (SectionName == ".fini" || SectionName == ".init" || @@ -497,6 +464,22 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) { return TokError("Linkage must be 'comdat'"); } } + if (getLexer().is(AsmToken::Comma)) { + Lex(); + if (getParser().parseIdentifier(UniqueStr)) + return TokError("expected identifier in directive"); + if (UniqueStr != "unique") + return TokError("expected 'unique'"); + if (getLexer().isNot(AsmToken::Comma)) + return TokError("expected commma"); + Lex(); + if (getParser().parseAbsoluteExpression(UniqueID)) + return true; + if (UniqueID < 0) + return TokError("unique id must be positive"); + if (!isUInt<32>(UniqueID) || UniqueID == ~0U) + return TokError("unique id is too large"); + } } } @@ -544,22 +527,19 @@ EndStmt: } } - SectionKind Kind = computeSectionKind(Flags, Size); - const MCSection *ELFSection = getContext().getELFSection( - SectionName, Type, Flags, Kind, Size, GroupName); + MCSection *ELFSection = getContext().getELFSection(SectionName, Type, Flags, + Size, GroupName, UniqueID); getStreamer().SwitchSection(ELFSection, Subsection); if (getContext().getGenDwarfForAssembly()) { - auto &Sections = getContext().getGenDwarfSectionSyms(); - auto InsertResult = Sections.insert( - std::make_pair(ELFSection, std::make_pair(nullptr, nullptr))); - if (InsertResult.second) { + bool InsertResult = getContext().addGenDwarfSection(ELFSection); + if (InsertResult) { if (getContext().getDwarfVersion() <= 2) Warning(loc, "DWARF2 only supports one section per compilation unit"); - MCSymbol *SectionStartSymbol = getContext().CreateTempSymbol(); + MCSymbol *SectionStartSymbol = getContext().createTempSymbol(); getStreamer().EmitLabel(SectionStartSymbol); - InsertResult.first->second.first = SectionStartSymbol; + ELFSection->setBeginSymbol(SectionStartSymbol); } } @@ -600,7 +580,7 @@ bool ELFAsmParser::ParseDirectiveType(StringRef, SMLoc) { return TokError("expected identifier in directive"); // Handle the identifier as the key symbol. - MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); + MCSymbol *Sym = getContext().getOrCreateSymbol(Name); // NOTE the comma is optional in all cases. It is only documented as being // optional in the first case, however, GAS will silently treat the comma as @@ -679,8 +659,8 @@ bool ELFAsmParser::ParseDirectiveSymver(StringRef, SMLoc) { if (AliasName.find('@') == StringRef::npos) return TokError("expected a '@' in the name"); - MCSymbol *Alias = getContext().GetOrCreateSymbol(AliasName); - MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); + MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName); + MCSymbol *Sym = getContext().getOrCreateSymbol(Name); const MCExpr *Value = MCSymbolRefExpr::Create(Sym, getContext()); getStreamer().EmitAssignment(Alias, Value); @@ -697,9 +677,7 @@ bool ELFAsmParser::ParseDirectiveVersion(StringRef, SMLoc) { Lex(); - const MCSection *Note = - getContext().getELFSection(".note", ELF::SHT_NOTE, 0, - SectionKind::getReadOnly()); + MCSection *Note = getContext().getELFSection(".note", ELF::SHT_NOTE, 0); getStreamer().PushSection(); getStreamer().SwitchSection(Note); @@ -731,9 +709,9 @@ bool ELFAsmParser::ParseDirectiveWeakref(StringRef, SMLoc) { if (getParser().parseIdentifier(Name)) return TokError("expected identifier in directive"); - MCSymbol *Alias = getContext().GetOrCreateSymbol(AliasName); + MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName); - MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); + MCSymbol *Sym = getContext().getOrCreateSymbol(Name); getStreamer().EmitWeakReference(Alias, Sym); return false; diff --git a/contrib/llvm/lib/MC/MCSection.cpp b/contrib/llvm/lib/MC/MCSection.cpp index ccf4a7d..04f932b 100644 --- a/contrib/llvm/lib/MC/MCSection.cpp +++ b/contrib/llvm/lib/MC/MCSection.cpp @@ -8,8 +8,10 @@ //===----------------------------------------------------------------------===// #include "llvm/MC/MCSection.h" +#include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCSymbol.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -17,6 +19,90 @@ using namespace llvm; // MCSection //===----------------------------------------------------------------------===// +MCSection::MCSection(SectionVariant V, SectionKind K, MCSymbol *Begin) + : Begin(Begin), HasInstructions(false), Variant(V), Kind(K) {} + +MCSymbol *MCSection::getEndSymbol(MCContext &Ctx) { + if (!End) + End = Ctx.createTempSymbol("sec_end", true); + return End; +} + +bool MCSection::hasEnded() const { return End && End->isInSection(); } + MCSection::~MCSection() { } +void MCSection::setBundleLockState(BundleLockStateType NewState) { + if (NewState == NotBundleLocked) { + if (BundleLockNestingDepth == 0) { + report_fatal_error("Mismatched bundle_lock/unlock directives"); + } + if (--BundleLockNestingDepth == 0) { + BundleLockState = NotBundleLocked; + } + return; + } + + // If any of the directives is an align_to_end directive, the whole nested + // group is align_to_end. So don't downgrade from align_to_end to just locked. + if (BundleLockState != BundleLockedAlignToEnd) { + BundleLockState = NewState; + } + ++BundleLockNestingDepth; +} + +MCSection::iterator +MCSection::getSubsectionInsertionPoint(unsigned Subsection) { + if (Subsection == 0 && SubsectionFragmentMap.empty()) + return end(); + + SmallVectorImpl<std::pair<unsigned, MCFragment *>>::iterator MI = + std::lower_bound(SubsectionFragmentMap.begin(), + SubsectionFragmentMap.end(), + std::make_pair(Subsection, (MCFragment *)nullptr)); + bool ExactMatch = false; + if (MI != SubsectionFragmentMap.end()) { + ExactMatch = MI->first == Subsection; + if (ExactMatch) + ++MI; + } + iterator IP; + if (MI == SubsectionFragmentMap.end()) + IP = end(); + else + IP = MI->second; + if (!ExactMatch && Subsection != 0) { + // The GNU as documentation claims that subsections have an alignment of 4, + // although this appears not to be the case. + MCFragment *F = new MCDataFragment(); + SubsectionFragmentMap.insert(MI, std::make_pair(Subsection, F)); + getFragmentList().insert(IP, F); + F->setParent(this); + } + + return IP; +} + +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) +void MCSection::dump() { + raw_ostream &OS = llvm::errs(); + + OS << "<MCSection"; + OS << " Fragments:[\n "; + for (auto it = begin(), ie = end(); it != ie; ++it) { + if (it != begin()) + OS << ",\n "; + it->dump(); + } + OS << "]>"; +} +#endif + +MCSection::iterator MCSection::begin() { return Fragments.begin(); } + +MCSection::iterator MCSection::end() { return Fragments.end(); } + +MCSection::reverse_iterator MCSection::rbegin() { return Fragments.rbegin(); } + +MCSection::reverse_iterator MCSection::rend() { return Fragments.rend(); } diff --git a/contrib/llvm/lib/MC/MCSectionELF.cpp b/contrib/llvm/lib/MC/MCSectionELF.cpp index a29bb97..3cd8453 100644 --- a/contrib/llvm/lib/MC/MCSectionELF.cpp +++ b/contrib/llvm/lib/MC/MCSectionELF.cpp @@ -24,6 +24,9 @@ MCSectionELF::~MCSectionELF() {} // anchor. bool MCSectionELF::ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const { + if (isUnique()) + return false; + // FIXME: Does .section .bss/.data/.text work everywhere?? if (Name == ".text" || Name == ".data" || (Name == ".bss" && !MAI.usesELFSectionDirectiveForBSS())) @@ -144,6 +147,10 @@ void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI, printName(OS, Group->getName()); OS << ",comdat"; } + + if (isUnique()) + OS << ",unique," << UniqueID; + OS << '\n'; if (Subsection) @@ -157,13 +164,3 @@ bool MCSectionELF::UseCodeAlign() const { bool MCSectionELF::isVirtualSection() const { return getType() == ELF::SHT_NOBITS; } - -unsigned MCSectionELF::DetermineEntrySize(SectionKind Kind) { - if (Kind.isMergeable1ByteCString()) return 1; - if (Kind.isMergeable2ByteCString()) return 2; - if (Kind.isMergeable4ByteCString()) return 4; - if (Kind.isMergeableConst4()) return 4; - if (Kind.isMergeableConst8()) return 8; - if (Kind.isMergeableConst16()) return 16; - return 0; -} diff --git a/contrib/llvm/lib/MC/MCSectionMachO.cpp b/contrib/llvm/lib/MC/MCSectionMachO.cpp index 46beda4..c9f1591 100644 --- a/contrib/llvm/lib/MC/MCSectionMachO.cpp +++ b/contrib/llvm/lib/MC/MCSectionMachO.cpp @@ -70,8 +70,10 @@ ENTRY(nullptr /*FIXME*/, S_ATTR_LOC_RELOC) }; MCSectionMachO::MCSectionMachO(StringRef Segment, StringRef Section, - unsigned TAA, unsigned reserved2, SectionKind K) - : MCSection(SV_MachO, K), TypeAndAttributes(TAA), Reserved2(reserved2) { + unsigned TAA, unsigned reserved2, SectionKind K, + MCSymbol *Begin) + : MCSection(SV_MachO, K, Begin), TypeAndAttributes(TAA), + Reserved2(reserved2) { assert(Segment.size() <= 16 && Section.size() <= 16 && "Segment or section string too long"); for (unsigned i = 0; i != 16; ++i) { diff --git a/contrib/llvm/lib/MC/MCStreamer.cpp b/contrib/llvm/lib/MC/MCStreamer.cpp index f11ee66..9e0cc6b 100644 --- a/contrib/llvm/lib/MC/MCStreamer.cpp +++ b/contrib/llvm/lib/MC/MCStreamer.cpp @@ -14,8 +14,10 @@ #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCInst.h" #include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCObjectWriter.h" +#include "llvm/MC/MCSection.h" #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCWin64EH.h" #include "llvm/Support/ErrorHandling.h" @@ -144,7 +146,7 @@ void MCStreamer::EmitZeros(uint64_t NumBytes) { unsigned MCStreamer::EmitDwarfFileDirective(unsigned FileNo, StringRef Directory, StringRef Filename, unsigned CUID) { - return getContext().GetDwarfFile(Directory, Filename, FileNo, CUID); + return getContext().getDwarfFile(Directory, Filename, FileNo, CUID); } void MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line, @@ -161,7 +163,7 @@ MCSymbol *MCStreamer::getDwarfLineTableSymbol(unsigned CUID) { if (!Table.getLabel()) { StringRef Prefix = Context.getAsmInfo()->getPrivateGlobalPrefix(); Table.setLabel( - Context.GetOrCreateSymbol(Prefix + "line_table_start" + Twine(CUID))); + Context.getOrCreateSymbol(Prefix + "line_table_start" + Twine(CUID))); } return Table.getLabel(); } @@ -186,7 +188,7 @@ void MCStreamer::InitSections(bool NoExecStack) { SwitchSection(getContext().getObjectFileInfo()->getTextSection()); } -void MCStreamer::AssignSection(MCSymbol *Symbol, const MCSection *Section) { +void MCStreamer::AssignSection(MCSymbol *Symbol, MCSection *Section) { if (Section) Symbol->setSection(*Section); else @@ -250,7 +252,7 @@ void MCStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) { MCSymbol *MCStreamer::EmitCFICommon() { EnsureValidDwarfFrame(); - MCSymbol *Label = getContext().CreateTempSymbol(); + MCSymbol *Label = getContext().createTempSymbol(); EmitLabel(Label); return Label; } @@ -397,7 +399,7 @@ void MCStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol) { if (CurrentWinFrameInfo && !CurrentWinFrameInfo->End) report_fatal_error("Starting a function before ending the previous one!"); - MCSymbol *StartProc = getContext().CreateTempSymbol(); + MCSymbol *StartProc = getContext().createTempSymbol(); EmitLabel(StartProc); WinFrameInfos.push_back(new WinEH::FrameInfo(Symbol, StartProc)); @@ -409,7 +411,7 @@ void MCStreamer::EmitWinCFIEndProc() { if (CurrentWinFrameInfo->ChainedParent) report_fatal_error("Not all chained regions terminated!"); - MCSymbol *Label = getContext().CreateTempSymbol(); + MCSymbol *Label = getContext().createTempSymbol(); EmitLabel(Label); CurrentWinFrameInfo->End = Label; } @@ -417,7 +419,7 @@ void MCStreamer::EmitWinCFIEndProc() { void MCStreamer::EmitWinCFIStartChained() { EnsureValidWinFrameInfo(); - MCSymbol *StartProc = getContext().CreateTempSymbol(); + MCSymbol *StartProc = getContext().createTempSymbol(); EmitLabel(StartProc); WinFrameInfos.push_back(new WinEH::FrameInfo(CurrentWinFrameInfo->Function, @@ -430,7 +432,7 @@ void MCStreamer::EmitWinCFIEndChained() { if (!CurrentWinFrameInfo->ChainedParent) report_fatal_error("End of a chained region outside a chained region!"); - MCSymbol *Label = getContext().CreateTempSymbol(); + MCSymbol *Label = getContext().createTempSymbol(); EmitLabel(Label); CurrentWinFrameInfo->End = Label; @@ -461,7 +463,7 @@ void MCStreamer::EmitWinEHHandlerData() { void MCStreamer::EmitWinCFIPushReg(unsigned Register) { EnsureValidWinFrameInfo(); - MCSymbol *Label = getContext().CreateTempSymbol(); + MCSymbol *Label = getContext().createTempSymbol(); EmitLabel(Label); WinEH::Instruction Inst = Win64EH::Instruction::PushNonVol(Label, Register); @@ -477,7 +479,7 @@ void MCStreamer::EmitWinCFISetFrame(unsigned Register, unsigned Offset) { if (Offset > 240) report_fatal_error("Frame offset must be less than or equal to 240!"); - MCSymbol *Label = getContext().CreateTempSymbol(); + MCSymbol *Label = getContext().createTempSymbol(); EmitLabel(Label); WinEH::Instruction Inst = @@ -493,7 +495,7 @@ void MCStreamer::EmitWinCFIAllocStack(unsigned Size) { if (Size & 7) report_fatal_error("Misaligned stack allocation!"); - MCSymbol *Label = getContext().CreateTempSymbol(); + MCSymbol *Label = getContext().createTempSymbol(); EmitLabel(Label); WinEH::Instruction Inst = Win64EH::Instruction::Alloc(Label, Size); @@ -505,7 +507,7 @@ void MCStreamer::EmitWinCFISaveReg(unsigned Register, unsigned Offset) { if (Offset & 7) report_fatal_error("Misaligned saved register offset!"); - MCSymbol *Label = getContext().CreateTempSymbol(); + MCSymbol *Label = getContext().createTempSymbol(); EmitLabel(Label); WinEH::Instruction Inst = @@ -518,7 +520,7 @@ void MCStreamer::EmitWinCFISaveXMM(unsigned Register, unsigned Offset) { if (Offset & 0x0F) report_fatal_error("Misaligned saved vector register offset!"); - MCSymbol *Label = getContext().CreateTempSymbol(); + MCSymbol *Label = getContext().createTempSymbol(); EmitLabel(Label); WinEH::Instruction Inst = @@ -531,7 +533,7 @@ void MCStreamer::EmitWinCFIPushFrame(bool Code) { if (CurrentWinFrameInfo->Instructions.size() > 0) report_fatal_error("If present, PushMachFrame must be the first UOP"); - MCSymbol *Label = getContext().CreateTempSymbol(); + MCSymbol *Label = getContext().createTempSymbol(); EmitLabel(Label); WinEH::Instruction Inst = Win64EH::Instruction::PushMachFrame(Label, Code); @@ -541,7 +543,7 @@ void MCStreamer::EmitWinCFIPushFrame(bool Code) { void MCStreamer::EmitWinCFIEndProlog() { EnsureValidWinFrameInfo(); - MCSymbol *Label = getContext().CreateTempSymbol(); + MCSymbol *Label = getContext().createTempSymbol(); EmitLabel(Label); CurrentWinFrameInfo->PrologEnd = Label; @@ -638,9 +640,9 @@ void MCStreamer::EmitCOFFSymbolType(int Type) {} void MCStreamer::EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {} void MCStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) {} -void MCStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, +void MCStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) {} -void MCStreamer::ChangeSection(const MCSection *, const MCExpr *) {} +void MCStreamer::ChangeSection(MCSection *, const MCExpr *) {} void MCStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {} void MCStreamer::EmitBytes(StringRef Data) {} void MCStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, @@ -661,3 +663,29 @@ void MCStreamer::EmitBundleAlignMode(unsigned AlignPow2) {} void MCStreamer::EmitBundleLock(bool AlignToEnd) {} void MCStreamer::FinishImpl() {} void MCStreamer::EmitBundleUnlock() {} + +void MCStreamer::SwitchSection(MCSection *Section, const MCExpr *Subsection) { + assert(Section && "Cannot switch to a null section!"); + MCSectionSubPair curSection = SectionStack.back().first; + SectionStack.back().second = curSection; + if (MCSectionSubPair(Section, Subsection) != curSection) { + SectionStack.back().first = MCSectionSubPair(Section, Subsection); + assert(!Section->hasEnded() && "Section already ended"); + ChangeSection(Section, Subsection); + MCSymbol *Sym = Section->getBeginSymbol(); + if (Sym && !Sym->isInSection()) + EmitLabel(Sym); + } +} + +MCSymbol *MCStreamer::endSection(MCSection *Section) { + // TODO: keep track of the last subsection so that this symbol appears in the + // correct place. + MCSymbol *Sym = Section->getEndSymbol(Context); + if (Sym->isInSection()) + return Sym; + + SwitchSection(Section); + EmitLabel(Sym); + return Sym; +} diff --git a/contrib/llvm/lib/MC/MCSubtargetInfo.cpp b/contrib/llvm/lib/MC/MCSubtargetInfo.cpp index b8e42bd..6abdd3a 100644 --- a/contrib/llvm/lib/MC/MCSubtargetInfo.cpp +++ b/contrib/llvm/lib/MC/MCSubtargetInfo.cpp @@ -35,7 +35,7 @@ MCSubtargetInfo::InitCPUSchedModel(StringRef CPU) { } void -MCSubtargetInfo::InitMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS, +MCSubtargetInfo::InitMCSubtargetInfo(StringRef TT, StringRef C, StringRef FS, ArrayRef<SubtargetFeatureKV> PF, ArrayRef<SubtargetFeatureKV> PD, const SubtargetInfoKV *ProcSched, @@ -46,6 +46,7 @@ MCSubtargetInfo::InitMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS, const unsigned *OC, const unsigned *FP) { TargetTriple = TT; + CPU = C; ProcFeatures = PF; ProcDesc = PD; ProcSchedModels = ProcSched; @@ -62,14 +63,19 @@ MCSubtargetInfo::InitMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS, /// ToggleFeature - Toggle a feature and returns the re-computed feature /// bits. This version does not change the implied bits. -uint64_t MCSubtargetInfo::ToggleFeature(uint64_t FB) { +FeatureBitset MCSubtargetInfo::ToggleFeature(uint64_t FB) { + FeatureBits.flip(FB); + return FeatureBits; +} + +FeatureBitset MCSubtargetInfo::ToggleFeature(const FeatureBitset &FB) { FeatureBits ^= FB; return FeatureBits; } /// ToggleFeature - Toggle a feature and returns the re-computed feature /// bits. This version will also change all implied bits. -uint64_t MCSubtargetInfo::ToggleFeature(StringRef FS) { +FeatureBitset MCSubtargetInfo::ToggleFeature(StringRef FS) { SubtargetFeatures Features; FeatureBits = Features.ToggleFeature(FeatureBits, FS, ProcFeatures); return FeatureBits; @@ -92,9 +98,10 @@ MCSubtargetInfo::getSchedModelForCPU(StringRef CPU) const { const SubtargetInfoKV *Found = std::lower_bound(ProcSchedModels, ProcSchedModels+NumProcs, CPU); if (Found == ProcSchedModels+NumProcs || StringRef(Found->Key) != CPU) { - errs() << "'" << CPU - << "' is not a recognized processor for this target" - << " (ignoring processor)\n"; + if (CPU != "help") // Don't error if the user asked for help. + errs() << "'" << CPU + << "' is not a recognized processor for this target" + << " (ignoring processor)\n"; return MCSchedModel::GetDefaultSchedModel(); } assert(Found->Value && "Missing processor SchedModel value"); diff --git a/contrib/llvm/lib/MC/MCSymbol.cpp b/contrib/llvm/lib/MC/MCSymbol.cpp index 2416525..ddc3814 100644 --- a/contrib/llvm/lib/MC/MCSymbol.cpp +++ b/contrib/llvm/lib/MC/MCSymbol.cpp @@ -14,8 +14,7 @@ using namespace llvm; // Sentinel value for the absolute pseudo section. -const MCSection *MCSymbol::AbsolutePseudoSection = - reinterpret_cast<const MCSection *>(1); +MCSection *MCSymbol::AbsolutePseudoSection = reinterpret_cast<MCSection *>(1); static bool isAcceptableChar(char C) { if ((C < 'a' || C > 'z') && @@ -39,29 +38,11 @@ static bool NameNeedsQuoting(StringRef Str) { return false; } -const MCSymbol &MCSymbol::AliasedSymbol() const { - const MCSymbol *S = this; - while (S->isVariable()) { - const MCExpr *Value = S->getVariableValue(); - if (Value->getKind() != MCExpr::SymbolRef) - return *S; - const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Value); - S = &Ref->getSymbol(); - } - return *S; -} - void MCSymbol::setVariableValue(const MCExpr *Value) { assert(!IsUsed && "Cannot set a variable that has already been used."); assert(Value && "Invalid variable value!"); this->Value = Value; - - // Variables should always be marked as in the same "section" as the value. - const MCSection *Section = Value->FindAssociatedSection(); - if (Section) - setSection(*Section); - else - setUndefined(); + this->Section = nullptr; } void MCSymbol::print(raw_ostream &OS) const { @@ -69,6 +50,10 @@ void MCSymbol::print(raw_ostream &OS) const { // some targets support quoting names with funny characters. If the name // contains a funny character, then print it quoted. StringRef Name = getName(); + if (Name.empty()) { + OS << "\"\""; + return; + } if (!NameNeedsQuoting(Name)) { OS << Name; return; @@ -88,7 +73,5 @@ void MCSymbol::print(raw_ostream &OS) const { } #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) -void MCSymbol::dump() const { - print(dbgs()); -} +void MCSymbol::dump() const { dbgs() << *this; } #endif diff --git a/contrib/llvm/lib/MC/MCValue.cpp b/contrib/llvm/lib/MC/MCValue.cpp index 9dfc56e..495a2b6 100644 --- a/contrib/llvm/lib/MC/MCValue.cpp +++ b/contrib/llvm/lib/MC/MCValue.cpp @@ -15,7 +15,7 @@ using namespace llvm; -void MCValue::print(raw_ostream &OS, const MCAsmInfo *MAI) const { +void MCValue::print(raw_ostream &OS) const { if (isAbsolute()) { OS << getConstant(); return; @@ -26,11 +26,11 @@ void MCValue::print(raw_ostream &OS, const MCAsmInfo *MAI) const { if (getRefKind()) OS << ':' << getRefKind() << ':'; - getSymA()->print(OS); + OS << *getSymA(); if (getSymB()) { OS << " - "; - getSymB()->print(OS); + OS << *getSymB(); } if (getConstant()) @@ -39,7 +39,7 @@ void MCValue::print(raw_ostream &OS, const MCAsmInfo *MAI) const { #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) void MCValue::dump() const { - print(dbgs(), nullptr); + print(dbgs()); } #endif diff --git a/contrib/llvm/lib/MC/MCWin64EH.cpp b/contrib/llvm/lib/MC/MCWin64EH.cpp index dfadb3c..f87ea67 100644 --- a/contrib/llvm/lib/MC/MCWin64EH.cpp +++ b/contrib/llvm/lib/MC/MCWin64EH.cpp @@ -153,7 +153,7 @@ static void EmitUnwindInfo(MCStreamer &streamer, WinEH::FrameInfo *info) { return; MCContext &context = streamer.getContext(); - MCSymbol *Label = context.CreateTempSymbol(); + MCSymbol *Label = context.createTempSymbol(); streamer.EmitValueToAlignment(4); streamer.EmitLabel(Label); @@ -224,16 +224,14 @@ void UnwindEmitter::Emit(MCStreamer &Streamer) const { // Emit the unwind info structs first. for (const auto &CFI : Streamer.getWinFrameInfos()) { - const MCSection *XData = - getXDataSection(CFI->Function, Context); + MCSection *XData = getXDataSection(CFI->Function, Context); Streamer.SwitchSection(XData); EmitUnwindInfo(Streamer, CFI); } // Now emit RUNTIME_FUNCTION entries. for (const auto &CFI : Streamer.getWinFrameInfos()) { - const MCSection *PData = - getPDataSection(CFI->Function, Context); + MCSection *PData = getPDataSection(CFI->Function, Context); Streamer.SwitchSection(PData); EmitRuntimeFunction(Streamer, CFI); } @@ -244,8 +242,7 @@ void UnwindEmitter::EmitUnwindInfo(MCStreamer &Streamer, // Switch sections (the static function above is meant to be called from // here and from Emit(). MCContext &context = Streamer.getContext(); - const MCSection *xdataSect = - getXDataSection(info->Function, context); + MCSection *xdataSect = getXDataSection(info->Function, context); Streamer.SwitchSection(xdataSect); llvm::EmitUnwindInfo(Streamer, info); diff --git a/contrib/llvm/lib/MC/MCWinEH.cpp b/contrib/llvm/lib/MC/MCWinEH.cpp index 47eaf0f..d5d9ead 100644 --- a/contrib/llvm/lib/MC/MCWinEH.cpp +++ b/contrib/llvm/lib/MC/MCWinEH.cpp @@ -11,6 +11,7 @@ #include "llvm/MC/MCContext.h" #include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCSectionCOFF.h" +#include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCWinEH.h" #include "llvm/Support/COFF.h" @@ -24,9 +25,10 @@ namespace WinEH { /// associated with that comdat. If the code described is not in the main .text /// section, make a new section for it. Otherwise use the main unwind info /// section. -static const MCSection *getUnwindInfoSection( - StringRef SecName, const MCSectionCOFF *UnwindSec, const MCSymbol *Function, - MCContext &Context) { +static MCSection *getUnwindInfoSection(StringRef SecName, + MCSectionCOFF *UnwindSec, + const MCSymbol *Function, + MCContext &Context) { if (Function && Function->isInSection()) { // If Function is in a COMDAT, get or create an unwind info section in that // COMDAT group. @@ -58,16 +60,16 @@ static const MCSection *getUnwindInfoSection( } -const MCSection *UnwindEmitter::getPDataSection(const MCSymbol *Function, - MCContext &Context) { - const MCSectionCOFF *PData = +MCSection *UnwindEmitter::getPDataSection(const MCSymbol *Function, + MCContext &Context) { + MCSectionCOFF *PData = cast<MCSectionCOFF>(Context.getObjectFileInfo()->getPDataSection()); return getUnwindInfoSection(".pdata", PData, Function, Context); } -const MCSection *UnwindEmitter::getXDataSection(const MCSymbol *Function, - MCContext &Context) { - const MCSectionCOFF *XData = +MCSection *UnwindEmitter::getXDataSection(const MCSymbol *Function, + MCContext &Context) { + MCSectionCOFF *XData = cast<MCSectionCOFF>(Context.getObjectFileInfo()->getXDataSection()); return getUnwindInfoSection(".xdata", XData, Function, Context); } diff --git a/contrib/llvm/lib/MC/MachObjectWriter.cpp b/contrib/llvm/lib/MC/MachObjectWriter.cpp index d3751bd..ce34ba0 100644 --- a/contrib/llvm/lib/MC/MachObjectWriter.cpp +++ b/contrib/llvm/lib/MC/MachObjectWriter.cpp @@ -23,6 +23,7 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MachO.h" +#include "llvm/Support/raw_ostream.h" #include <vector> using namespace llvm; @@ -38,15 +39,14 @@ void MachObjectWriter::reset() { MCObjectWriter::reset(); } -bool MachObjectWriter:: -doesSymbolRequireExternRelocation(const MCSymbolData *SD) { +bool MachObjectWriter::doesSymbolRequireExternRelocation(const MCSymbol &S) { // Undefined symbols are always extern. - if (SD->getSymbol().isUndefined()) + if (S.isUndefined()) return true; // References to weak definitions require external relocation entries; the // definition may not always be the one in the same object file. - if (SD->getFlags() & SF_WeakDefinition) + if (S.getData().getFlags() & SF_WeakDefinition) return true; // Otherwise, we can use an internal relocation. @@ -55,8 +55,7 @@ doesSymbolRequireExternRelocation(const MCSymbolData *SD) { bool MachObjectWriter:: MachSymbolData::operator<(const MachSymbolData &RHS) const { - return SymbolData->getSymbol().getName() < - RHS.SymbolData->getSymbol().getName(); + return Symbol->getName() < RHS.Symbol->getName(); } bool MachObjectWriter::isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind) { @@ -69,13 +68,11 @@ bool MachObjectWriter::isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind) { uint64_t MachObjectWriter::getFragmentAddress(const MCFragment *Fragment, const MCAsmLayout &Layout) const { return getSectionAddress(Fragment->getParent()) + - Layout.getFragmentOffset(Fragment); + Layout.getFragmentOffset(Fragment); } -uint64_t MachObjectWriter::getSymbolAddress(const MCSymbolData* SD, +uint64_t MachObjectWriter::getSymbolAddress(const MCSymbol &S, const MCAsmLayout &Layout) const { - const MCSymbol &S = SD->getSymbol(); - // If this is a variable, then recursively evaluate now. if (S.isVariable()) { if (const MCConstantExpr *C = @@ -98,29 +95,27 @@ uint64_t MachObjectWriter::getSymbolAddress(const MCSymbolData* SD, uint64_t Address = Target.getConstant(); if (Target.getSymA()) - Address += getSymbolAddress(&Layout.getAssembler().getSymbolData( - Target.getSymA()->getSymbol()), Layout); + Address += getSymbolAddress(Target.getSymA()->getSymbol(), Layout); if (Target.getSymB()) - Address += getSymbolAddress(&Layout.getAssembler().getSymbolData( - Target.getSymB()->getSymbol()), Layout); + Address += getSymbolAddress(Target.getSymB()->getSymbol(), Layout); return Address; } - return getSectionAddress(SD->getFragment()->getParent()) + - Layout.getSymbolOffset(SD); + return getSectionAddress(S.getData().getFragment()->getParent()) + + Layout.getSymbolOffset(S); } -uint64_t MachObjectWriter::getPaddingSize(const MCSectionData *SD, +uint64_t MachObjectWriter::getPaddingSize(const MCSection *Sec, const MCAsmLayout &Layout) const { - uint64_t EndAddr = getSectionAddress(SD) + Layout.getSectionAddressSize(SD); - unsigned Next = SD->getLayoutOrder() + 1; + uint64_t EndAddr = getSectionAddress(Sec) + Layout.getSectionAddressSize(Sec); + unsigned Next = Sec->getLayoutOrder() + 1; if (Next >= Layout.getSectionOrder().size()) return 0; - const MCSectionData &NextSD = *Layout.getSectionOrder()[Next]; - if (NextSD.getSection().isVirtualSection()) + const MCSection &NextSec = *Layout.getSectionOrder()[Next]; + if (NextSec.isVirtualSection()) return 0; - return OffsetToAlignment(EndAddr, NextSD.getAlignment()); + return OffsetToAlignment(EndAddr, NextSec.getAlignment()); } void MachObjectWriter::WriteHeader(unsigned NumLoadCommands, @@ -199,15 +194,15 @@ void MachObjectWriter::WriteSegmentLoadCommand(unsigned NumSections, void MachObjectWriter::WriteSection(const MCAssembler &Asm, const MCAsmLayout &Layout, - const MCSectionData &SD, - uint64_t FileOffset, + const MCSection &Sec, uint64_t FileOffset, uint64_t RelocationsStart, unsigned NumRelocations) { - uint64_t SectionSize = Layout.getSectionAddressSize(&SD); + uint64_t SectionSize = Layout.getSectionAddressSize(&Sec); + const MCSectionMachO &Section = cast<MCSectionMachO>(Sec); // The offset is unused for virtual sections. - if (SD.getSection().isVirtualSection()) { - assert(Layout.getSectionFileSize(&SD) == 0 && "Invalid file size!"); + if (Section.isVirtualSection()) { + assert(Layout.getSectionFileSize(&Sec) == 0 && "Invalid file size!"); FileOffset = 0; } @@ -217,28 +212,27 @@ void MachObjectWriter::WriteSection(const MCAssembler &Asm, uint64_t Start = OS.tell(); (void) Start; - const MCSectionMachO &Section = cast<MCSectionMachO>(SD.getSection()); WriteBytes(Section.getSectionName(), 16); WriteBytes(Section.getSegmentName(), 16); if (is64Bit()) { - Write64(getSectionAddress(&SD)); // address + Write64(getSectionAddress(&Sec)); // address Write64(SectionSize); // size } else { - Write32(getSectionAddress(&SD)); // address + Write32(getSectionAddress(&Sec)); // address Write32(SectionSize); // size } Write32(FileOffset); unsigned Flags = Section.getTypeAndAttributes(); - if (SD.hasInstructions()) + if (Section.hasInstructions()) Flags |= MachO::S_ATTR_SOME_INSTRUCTIONS; - assert(isPowerOf2_32(SD.getAlignment()) && "Invalid alignment!"); - Write32(Log2_32(SD.getAlignment())); + assert(isPowerOf2_32(Section.getAlignment()) && "Invalid alignment!"); + Write32(Log2_32(Section.getAlignment())); Write32(NumRelocations ? RelocationsStart : 0); Write32(NumRelocations); Write32(Flags); - Write32(IndirectSymBase.lookup(&SD)); // reserved1 + Write32(IndirectSymBase.lookup(&Sec)); // reserved1 Write32(Section.getStubSize()); // reserved2 if (is64Bit()) Write32(0); // reserved3 @@ -306,37 +300,51 @@ void MachObjectWriter::WriteDysymtabLoadCommand(uint32_t FirstLocalSymbol, MachObjectWriter::MachSymbolData * MachObjectWriter::findSymbolData(const MCSymbol &Sym) { for (auto &Entry : LocalSymbolData) - if (&Entry.SymbolData->getSymbol() == &Sym) + if (Entry.Symbol == &Sym) return &Entry; for (auto &Entry : ExternalSymbolData) - if (&Entry.SymbolData->getSymbol() == &Sym) + if (Entry.Symbol == &Sym) return &Entry; for (auto &Entry : UndefinedSymbolData) - if (&Entry.SymbolData->getSymbol() == &Sym) + if (Entry.Symbol == &Sym) return &Entry; return nullptr; } +const MCSymbol &MachObjectWriter::findAliasedSymbol(const MCSymbol &Sym) const { + const MCSymbol *S = &Sym; + while (S->isVariable()) { + const MCExpr *Value = S->getVariableValue(); + const auto *Ref = dyn_cast<MCSymbolRefExpr>(Value); + if (!Ref) + return *S; + S = &Ref->getSymbol(); + } + return *S; +} + void MachObjectWriter::WriteNlist(MachSymbolData &MSD, const MCAsmLayout &Layout) { - MCSymbolData &Data = *MSD.SymbolData; - const MCSymbol *Symbol = &Data.getSymbol(); - const MCSymbol *AliasedSymbol = &Symbol->AliasedSymbol(); + const MCSymbol *Symbol = MSD.Symbol; + MCSymbolData &Data = Symbol->getData(); + const MCSymbol *AliasedSymbol = &findAliasedSymbol(*Symbol); uint8_t SectionIndex = MSD.SectionIndex; uint8_t Type = 0; uint16_t Flags = Data.getFlags(); uint64_t Address = 0; bool IsAlias = Symbol != AliasedSymbol; + const MCSymbol &OrigSymbol = *Symbol; MachSymbolData *AliaseeInfo; if (IsAlias) { AliaseeInfo = findSymbolData(*AliasedSymbol); if (AliaseeInfo) SectionIndex = AliaseeInfo->SectionIndex; Symbol = AliasedSymbol; + // FIXME: Should this update Data as well? Do we need OrigSymbol at all? } // Set the N_TYPE bits. See <mach-o/nlist.h>. @@ -364,7 +372,7 @@ void MachObjectWriter::WriteNlist(MachSymbolData &MSD, if (IsAlias && Symbol->isUndefined()) Address = AliaseeInfo->StringIndex; else if (Symbol->isDefined()) - Address = getSymbolAddress(&Data, Layout); + Address = getSymbolAddress(OrigSymbol, Layout); else if (Data.isCommon()) { // Common symbols are encoded with the size in the address // field, and their alignment in the flags. @@ -448,14 +456,11 @@ void MachObjectWriter::WriteLinkerOptionsLoadCommand( assert(OS.tell() - Start == Size); } - -void MachObjectWriter::RecordRelocation(const MCAssembler &Asm, +void MachObjectWriter::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) { TargetObjectWriter->RecordRelocation(this, Asm, Layout, Fragment, Fixup, Target, FixedValue); } @@ -472,8 +477,7 @@ void MachObjectWriter::BindIndirectSymbols(MCAssembler &Asm) { // or stub section. for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(), ie = Asm.indirect_symbol_end(); it != ie; ++it) { - const MCSectionMachO &Section = - cast<MCSectionMachO>(it->SectionData->getSection()); + const MCSectionMachO &Section = cast<MCSectionMachO>(*it->Section); if (Section.getType() != MachO::S_NON_LAZY_SYMBOL_POINTERS && Section.getType() != MachO::S_LAZY_SYMBOL_POINTERS && @@ -488,14 +492,13 @@ void MachObjectWriter::BindIndirectSymbols(MCAssembler &Asm) { unsigned IndirectIndex = 0; for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(), ie = Asm.indirect_symbol_end(); it != ie; ++it, ++IndirectIndex) { - const MCSectionMachO &Section = - cast<MCSectionMachO>(it->SectionData->getSection()); + const MCSectionMachO &Section = cast<MCSectionMachO>(*it->Section); if (Section.getType() != MachO::S_NON_LAZY_SYMBOL_POINTERS) continue; // Initialize the section indirect symbol base, if necessary. - IndirectSymBase.insert(std::make_pair(it->SectionData, IndirectIndex)); + IndirectSymBase.insert(std::make_pair(it->Section, IndirectIndex)); Asm.getOrCreateSymbolData(*it->Symbol); } @@ -504,15 +507,14 @@ void MachObjectWriter::BindIndirectSymbols(MCAssembler &Asm) { IndirectIndex = 0; for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(), ie = Asm.indirect_symbol_end(); it != ie; ++it, ++IndirectIndex) { - const MCSectionMachO &Section = - cast<MCSectionMachO>(it->SectionData->getSection()); + const MCSectionMachO &Section = cast<MCSectionMachO>(*it->Section); if (Section.getType() != MachO::S_LAZY_SYMBOL_POINTERS && Section.getType() != MachO::S_SYMBOL_STUBS) continue; // Initialize the section indirect symbol base, if necessary. - IndirectSymBase.insert(std::make_pair(it->SectionData, IndirectIndex)); + IndirectSymBase.insert(std::make_pair(it->Section, IndirectIndex)); // Set the symbol type to undefined lazy, but only on construction. // @@ -534,12 +536,11 @@ void MachObjectWriter::ComputeSymbolTable( unsigned Index = 1; for (MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); it != ie; ++it, ++Index) - SectionIndexMap[&it->getSection()] = Index; + SectionIndexMap[&*it] = Index; assert(Index <= 256 && "Too many sections!"); // Build the string table. - for (MCSymbolData &SD : Asm.symbols()) { - const MCSymbol &Symbol = SD.getSymbol(); + for (const MCSymbol &Symbol : Asm.symbols()) { if (!Asm.isSymbolLinkerVisible(Symbol)) continue; @@ -552,8 +553,8 @@ void MachObjectWriter::ComputeSymbolTable( // The particular order that we collect and then sort the symbols is chosen to // match 'as'. Even though it doesn't matter for correctness, this is // important for letting us diff .o files. - for (MCSymbolData &SD : Asm.symbols()) { - const MCSymbol &Symbol = SD.getSymbol(); + for (const MCSymbol &Symbol : Asm.symbols()) { + MCSymbolData &SD = Symbol.getData(); // Ignore non-linker visible symbols. if (!Asm.isSymbolLinkerVisible(Symbol)) @@ -563,7 +564,7 @@ void MachObjectWriter::ComputeSymbolTable( continue; MachSymbolData MSD; - MSD.SymbolData = &SD; + MSD.Symbol = &Symbol; MSD.StringIndex = StringTable.getOffset(Symbol.getName()); if (Symbol.isUndefined()) { @@ -580,8 +581,8 @@ void MachObjectWriter::ComputeSymbolTable( } // Now add the data for local symbols. - for (MCSymbolData &SD : Asm.symbols()) { - const MCSymbol &Symbol = SD.getSymbol(); + for (const MCSymbol &Symbol : Asm.symbols()) { + MCSymbolData &SD = Symbol.getData(); // Ignore non-linker visible symbols. if (!Asm.isSymbolLinkerVisible(Symbol)) @@ -591,7 +592,7 @@ void MachObjectWriter::ComputeSymbolTable( continue; MachSymbolData MSD; - MSD.SymbolData = &SD; + MSD.Symbol = &Symbol; MSD.StringIndex = StringTable.getOffset(Symbol.getName()); if (Symbol.isAbsolute()) { @@ -611,44 +612,43 @@ void MachObjectWriter::ComputeSymbolTable( // Set the symbol indices. Index = 0; for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) - LocalSymbolData[i].SymbolData->setIndex(Index++); + LocalSymbolData[i].Symbol->setIndex(Index++); for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) - ExternalSymbolData[i].SymbolData->setIndex(Index++); + ExternalSymbolData[i].Symbol->setIndex(Index++); for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) - UndefinedSymbolData[i].SymbolData->setIndex(Index++); + UndefinedSymbolData[i].Symbol->setIndex(Index++); + + for (const MCSection &Section : Asm) { + std::vector<RelAndSymbol> &Relocs = Relocations[&Section]; + for (RelAndSymbol &Rel : Relocs) { + if (!Rel.Sym) + continue; + + // Set the Index and the IsExtern bit. + unsigned Index = Rel.Sym->getIndex(); + assert(isInt<24>(Index)); + if (IsLittleEndian) + Rel.MRE.r_word1 = (Rel.MRE.r_word1 & (~0U << 24)) | Index | (1 << 27); + else + Rel.MRE.r_word1 = (Rel.MRE.r_word1 & 0xff) | Index << 8 | (1 << 4); + } + } } void MachObjectWriter::computeSectionAddresses(const MCAssembler &Asm, const MCAsmLayout &Layout) { uint64_t StartAddress = 0; - const SmallVectorImpl<MCSectionData*> &Order = Layout.getSectionOrder(); + const SmallVectorImpl<MCSection *> &Order = Layout.getSectionOrder(); for (int i = 0, n = Order.size(); i != n ; ++i) { - const MCSectionData *SD = Order[i]; - StartAddress = RoundUpToAlignment(StartAddress, SD->getAlignment()); - SectionAddress[SD] = StartAddress; - StartAddress += Layout.getSectionAddressSize(SD); + const MCSection *Sec = Order[i]; + StartAddress = RoundUpToAlignment(StartAddress, Sec->getAlignment()); + SectionAddress[Sec] = StartAddress; + StartAddress += Layout.getSectionAddressSize(Sec); // Explicitly pad the section to match the alignment requirements of the // following one. This is for 'gas' compatibility, it shouldn't /// strictly be necessary. - StartAddress += getPaddingSize(SD, Layout); - } -} - -void MachObjectWriter::markAbsoluteVariableSymbols(MCAssembler &Asm, - const MCAsmLayout &Layout) { - for (MCSymbolData &SD : Asm.symbols()) { - if (!SD.getSymbol().isVariable()) - continue; - - // Is the variable is a symbol difference (SA - SB + C) expression, - // and neither symbol is external, mark the variable as absolute. - const MCExpr *Expr = SD.getSymbol().getVariableValue(); - MCValue Value; - if (Expr->EvaluateAsRelocatable(Value, &Layout, nullptr)) { - if (Value.getSymA() && Value.getSymB()) - const_cast<MCSymbol*>(&SD.getSymbol())->setAbsolute(); - } + StartAddress += getPaddingSize(Sec, Layout); } } @@ -658,22 +658,11 @@ void MachObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, // Create symbol data for any indirect symbols. BindIndirectSymbols(Asm); - - // Mark symbol difference expressions in variables (from .set or = directives) - // as absolute. - markAbsoluteVariableSymbols(Asm, Layout); - - // Compute symbol table information and bind symbol indices. - ComputeSymbolTable(Asm, LocalSymbolData, ExternalSymbolData, - UndefinedSymbolData); } -bool MachObjectWriter:: -IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, - const MCSymbolData &DataA, - const MCFragment &FB, - bool InSet, - bool IsPCRel) const { +bool MachObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl( + const MCAssembler &Asm, const MCSymbol &SymA, const MCFragment &FB, + bool InSet, bool IsPCRel) const { if (InSet) return true; @@ -682,11 +671,9 @@ IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, // - addr(atom(B)) - offset(B) // and the offsets are not relocatable, so the fixup is fully resolved when // addr(atom(A)) - addr(atom(B)) == 0. - const MCSymbolData *A_Base = nullptr, *B_Base = nullptr; - - const MCSymbol &SA = DataA.getSymbol().AliasedSymbol(); + const MCSymbol &SA = findAliasedSymbol(SymA); const MCSection &SecA = SA.getSection(); - const MCSection &SecB = FB.getParent()->getSection(); + const MCSection &SecB = *FB.getParent(); if (IsPCRel) { // The simple (Darwin, except on x86_64) way of dealing with this was to @@ -736,11 +723,8 @@ IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, if (!FA) return false; - A_Base = FA->getAtom(); - B_Base = FB.getAtom(); - // If the atoms are the same, they are guaranteed to have the same address. - if (A_Base == B_Base) + if (FA->getAtom() == FB.getAtom()) return true; // Otherwise, we can't prove this is fully resolved. @@ -749,6 +733,10 @@ IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, void MachObjectWriter::WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout) { + // Compute symbol table information and bind symbol indices. + ComputeSymbolTable(Asm, LocalSymbolData, ExternalSymbolData, + UndefinedSymbolData); + unsigned NumSections = Asm.size(); const MCAssembler::VersionMinInfoType &VersionInfo = Layout.getAssembler().getVersionMinInfo(); @@ -808,15 +796,15 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm, uint64_t VMSize = 0; for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end(); it != ie; ++it) { - const MCSectionData &SD = *it; - uint64_t Address = getSectionAddress(&SD); - uint64_t Size = Layout.getSectionAddressSize(&SD); - uint64_t FileSize = Layout.getSectionFileSize(&SD); - FileSize += getPaddingSize(&SD, Layout); + const MCSection &Sec = *it; + uint64_t Address = getSectionAddress(&Sec); + uint64_t Size = Layout.getSectionAddressSize(&Sec); + uint64_t FileSize = Layout.getSectionFileSize(&Sec); + FileSize += getPaddingSize(&Sec, Layout); VMSize = std::max(VMSize, Address + Size); - if (SD.getSection().isVirtualSection()) + if (it->isVirtualSection()) continue; SectionDataSize = std::max(SectionDataSize, Address + Size); @@ -839,9 +827,9 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm, uint64_t RelocTableEnd = SectionDataStart + SectionDataFileSize; for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end(); it != ie; ++it) { - std::vector<MachO::any_relocation_info> &Relocs = Relocations[it]; + std::vector<RelAndSymbol> &Relocs = Relocations[&*it]; unsigned NumRelocs = Relocs.size(); - uint64_t SectionStart = SectionDataStart + getSectionAddress(it); + uint64_t SectionStart = SectionDataStart + getSectionAddress(&*it); WriteSection(Asm, Layout, *it, SectionStart, RelocTableEnd, NumRelocs); RelocTableEnd += NumRelocs * sizeof(MachO::any_relocation_info); } @@ -918,11 +906,11 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm, // Write the actual section data. for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end(); it != ie; ++it) { - Asm.writeSectionData(it, Layout); + MCSection &Sec = *it; + Asm.writeSectionData(&Sec, Layout); - uint64_t Pad = getPaddingSize(it, Layout); - for (unsigned int i = 0; i < Pad; ++i) - Write8(0); + uint64_t Pad = getPaddingSize(&Sec, Layout); + WriteZeros(Pad); } // Write the extra padding. @@ -933,10 +921,10 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm, ie = Asm.end(); it != ie; ++it) { // Write the section relocation entries, in reverse order to match 'as' // (approximately, the exact algorithm is more complicated than this). - std::vector<MachO::any_relocation_info> &Relocs = Relocations[it]; + std::vector<RelAndSymbol> &Relocs = Relocations[&*it]; for (unsigned i = 0, e = Relocs.size(); i != e; ++i) { - Write32(Relocs[e - i - 1].r_word0); - Write32(Relocs[e - i - 1].r_word1); + Write32(Relocs[e - i - 1].MRE.r_word0); + Write32(Relocs[e - i - 1].MRE.r_word1); } } @@ -945,12 +933,8 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm, it = Asm.data_region_begin(), ie = Asm.data_region_end(); it != ie; ++it) { const DataRegionData *Data = &(*it); - uint64_t Start = - getSymbolAddress(&Layout.getAssembler().getSymbolData(*Data->Start), - Layout); - uint64_t End = - getSymbolAddress(&Layout.getAssembler().getSymbolData(*Data->End), - Layout); + uint64_t Start = getSymbolAddress(*Data->Start, Layout); + uint64_t End = getSymbolAddress(*Data->End, Layout); DEBUG(dbgs() << "data in code region-- kind: " << Data->Kind << " start: " << Start << "(" << Data->Start->getName() << ")" << " end: " << End << "(" << Data->End->getName() << ")" @@ -981,7 +965,7 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm, // Indirect symbols in the non-lazy symbol pointer section have some // special handling. const MCSectionMachO &Section = - static_cast<const MCSectionMachO&>(it->SectionData->getSection()); + static_cast<const MCSectionMachO &>(*it->Section); if (Section.getType() == MachO::S_NON_LAZY_SYMBOL_POINTERS) { // If this symbol is defined and internal, mark it as such. if (it->Symbol->isDefined() && @@ -994,7 +978,7 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm, } } - Write32(Asm.getSymbolData(*it->Symbol).getIndex()); + Write32(it->Symbol->getIndex()); } // FIXME: Check that offsets match computed ones. @@ -1013,7 +997,7 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm, } MCObjectWriter *llvm::createMachObjectWriter(MCMachObjectTargetWriter *MOTW, - raw_ostream &OS, + raw_pwrite_stream &OS, bool IsLittleEndian) { return new MachObjectWriter(MOTW, OS, IsLittleEndian); } diff --git a/contrib/llvm/lib/MC/SubtargetFeature.cpp b/contrib/llvm/lib/MC/SubtargetFeature.cpp index 587be54..78006e0 100644 --- a/contrib/llvm/lib/MC/SubtargetFeature.cpp +++ b/contrib/llvm/lib/MC/SubtargetFeature.cpp @@ -81,11 +81,12 @@ static std::string Join(const std::vector<std::string> &V) { } /// Adding features. -void SubtargetFeatures::AddFeature(StringRef String) { - // Don't add empty features or features we already have. +void SubtargetFeatures::AddFeature(StringRef String, bool Enable) { + // Don't add empty features. if (!String.empty()) // Convert to lowercase, prepend flag if we don't already have a flag. - Features.push_back(hasFlag(String) ? String.str() : "+" + String.lower()); + Features.push_back(hasFlag(String) ? String.lower() + : (Enable ? "+" : "-") + String.lower()); } /// Find KV in array using binary search. @@ -150,12 +151,12 @@ std::string SubtargetFeatures::getString() const { /// feature, set it. /// static -void SetImpliedBits(uint64_t &Bits, const SubtargetFeatureKV *FeatureEntry, +void SetImpliedBits(FeatureBitset &Bits, const SubtargetFeatureKV *FeatureEntry, ArrayRef<SubtargetFeatureKV> FeatureTable) { for (auto &FE : FeatureTable) { if (FeatureEntry->Value == FE.Value) continue; - if (FeatureEntry->Implies & FE.Value) { + if ((FeatureEntry->Implies & FE.Value).any()) { Bits |= FE.Value; SetImpliedBits(Bits, &FE, FeatureTable); } @@ -166,12 +167,13 @@ void SetImpliedBits(uint64_t &Bits, const SubtargetFeatureKV *FeatureEntry, /// feature, clear it. /// static -void ClearImpliedBits(uint64_t &Bits, const SubtargetFeatureKV *FeatureEntry, +void ClearImpliedBits(FeatureBitset &Bits, + const SubtargetFeatureKV *FeatureEntry, ArrayRef<SubtargetFeatureKV> FeatureTable) { for (auto &FE : FeatureTable) { if (FeatureEntry->Value == FE.Value) continue; - if (FE.Implies & FeatureEntry->Value) { + if ((FE.Implies & FeatureEntry->Value).any()) { Bits &= ~FE.Value; ClearImpliedBits(Bits, &FE, FeatureTable); } @@ -180,8 +182,8 @@ void ClearImpliedBits(uint64_t &Bits, const SubtargetFeatureKV *FeatureEntry, /// ToggleFeature - Toggle a feature and returns the newly updated feature /// bits. -uint64_t -SubtargetFeatures::ToggleFeature(uint64_t Bits, StringRef Feature, +FeatureBitset +SubtargetFeatures::ToggleFeature(FeatureBitset Bits, StringRef Feature, ArrayRef<SubtargetFeatureKV> FeatureTable) { // Find feature in table. @@ -191,7 +193,6 @@ SubtargetFeatures::ToggleFeature(uint64_t Bits, StringRef Feature, if (FeatureEntry) { if ((Bits & FeatureEntry->Value) == FeatureEntry->Value) { Bits &= ~FeatureEntry->Value; - // For each feature that implies this, clear it. ClearImpliedBits(Bits, FeatureEntry, FeatureTable); } else { @@ -212,13 +213,13 @@ SubtargetFeatures::ToggleFeature(uint64_t Bits, StringRef Feature, /// getFeatureBits - Get feature bits a CPU. /// -uint64_t +FeatureBitset SubtargetFeatures::getFeatureBits(StringRef CPU, ArrayRef<SubtargetFeatureKV> CPUTable, ArrayRef<SubtargetFeatureKV> FeatureTable) { if (CPUTable.empty() || FeatureTable.empty()) - return 0; + return FeatureBitset(); #ifndef NDEBUG for (size_t i = 1, e = CPUTable.size(); i != e; ++i) { @@ -230,7 +231,8 @@ SubtargetFeatures::getFeatureBits(StringRef CPU, "CPU features table is not sorted"); } #endif - uint64_t Bits = 0; // Resulting bits + // Resulting bits + FeatureBitset Bits; // Check if help is needed if (CPU == "help") @@ -247,7 +249,7 @@ SubtargetFeatures::getFeatureBits(StringRef CPU, // Set the feature implied by this CPU feature, if any. for (auto &FE : FeatureTable) { - if (CPUEntry->Value & FE.Value) + if ((CPUEntry->Value & FE.Value).any()) SetImpliedBits(Bits, &FE, FeatureTable); } } else { diff --git a/contrib/llvm/lib/MC/WinCOFFObjectWriter.cpp b/contrib/llvm/lib/MC/WinCOFFObjectWriter.cpp index ec0e0f7..c945085 100644 --- a/contrib/llvm/lib/MC/WinCOFFObjectWriter.cpp +++ b/contrib/llvm/lib/MC/WinCOFFObjectWriter.cpp @@ -50,7 +50,7 @@ enum AuxiliaryType { }; struct AuxSymbol { - AuxiliaryType AuxType; + AuxiliaryType AuxType; COFF::Auxiliary Aux; }; @@ -63,14 +63,14 @@ public: typedef SmallVector<AuxSymbol, 1> AuxiliarySymbols; - name Name; - int Index; + name Name; + int Index; AuxiliarySymbols Aux; - COFFSymbol *Other; - COFFSection *Section; - int Relocations; + COFFSymbol *Other; + COFFSection *Section; + int Relocations; - MCSymbolData const *MCData; + const MCSymbol *MC; COFFSymbol(StringRef name); void set_name_offset(uint32_t Offset); @@ -81,7 +81,7 @@ public: // This class contains staging data for a COFF relocation entry. struct COFFRelocation { COFF::relocation Data; - COFFSymbol *Symb; + COFFSymbol *Symb; COFFRelocation() : Symb(nullptr) {} static size_t size() { return COFF::RelocationSize; } @@ -93,11 +93,11 @@ class COFFSection { public: COFF::section Header; - std::string Name; - int Number; - MCSectionData const *MCData; - COFFSymbol *Symbol; - relocations Relocations; + std::string Name; + int Number; + MCSectionCOFF const *MCSection; + COFFSymbol *Symbol; + relocations Relocations; COFFSection(StringRef name); static size_t size(); @@ -105,29 +105,28 @@ public: class WinCOFFObjectWriter : public MCObjectWriter { public: - - typedef std::vector<std::unique_ptr<COFFSymbol>> symbols; + typedef std::vector<std::unique_ptr<COFFSymbol>> symbols; typedef std::vector<std::unique_ptr<COFFSection>> sections; - typedef DenseMap<MCSymbol const *, COFFSymbol *> symbol_map; + typedef DenseMap<MCSymbol const *, COFFSymbol *> symbol_map; typedef DenseMap<MCSection const *, COFFSection *> section_map; std::unique_ptr<MCWinCOFFObjectTargetWriter> TargetObjectWriter; // Root level file contents. COFF::header Header; - sections Sections; - symbols Symbols; + sections Sections; + symbols Symbols; StringTableBuilder Strings; // Maps used during object file creation. section_map SectionMap; - symbol_map SymbolMap; + symbol_map SymbolMap; bool UseBigObj; - WinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW, raw_ostream &OS); - + WinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW, raw_pwrite_stream &OS); + void reset() override { memset(&Header, 0, sizeof(Header)); Header.Machine = TargetObjectWriter->getMachine(); @@ -140,14 +139,14 @@ public: } COFFSymbol *createSymbol(StringRef Name); - COFFSymbol *GetOrCreateCOFFSymbol(const MCSymbol * Symbol); + COFFSymbol *GetOrCreateCOFFSymbol(const MCSymbol *Symbol); COFFSection *createSection(StringRef Name); template <typename object_t, typename list_t> object_t *createCOFFEntity(StringRef Name, list_t &List); - void DefineSection(MCSectionData const &SectionData); - void DefineSymbol(MCSymbolData const &SymbolData, MCAssembler &Assembler, + void defineSection(MCSectionCOFF const &Sec); + void DefineSymbol(const MCSymbol &Symbol, MCAssembler &Assembler, const MCAsmLayout &Layout); void SetSymbolName(COFFSymbol &S); @@ -171,11 +170,13 @@ public: const MCAsmLayout &Layout) override; bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, - const MCSymbolData &DataA, + const MCSymbol &SymA, const MCFragment &FB, bool InSet, bool IsPCRel) const override; - void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, + bool isWeak(const MCSymbol &Sym) const override; + + void RecordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, bool &IsPCRel, uint64_t &FixedValue) override; @@ -193,11 +194,8 @@ static inline void write_uint32_le(void *Data, uint32_t Value) { // Symbol class implementation COFFSymbol::COFFSymbol(StringRef name) - : Name(name.begin(), name.end()) - , Other(nullptr) - , Section(nullptr) - , Relocations(0) - , MCData(nullptr) { + : Name(name.begin(), name.end()), Other(nullptr), Section(nullptr), + Relocations(0), MC(nullptr) { memset(&Data, 0, sizeof(Data)); } @@ -216,22 +214,22 @@ bool COFFSymbol::should_keep() const { return true; // if it has relocations pointing at it, keep it - if (Relocations > 0) { + if (Relocations > 0) { assert(Section->Number != -1 && "Sections with relocations must be real!"); return true; } // if the section its in is being droped, drop it if (Section->Number == -1) - return false; + return false; // if it is the section symbol, keep it if (Section->Symbol == this) return true; // if its temporary, drop it - if (MCData && MCData->getSymbol().isTemporary()) - return false; + if (MC && MC->isTemporary()) + return false; // otherwise, keep it return true; @@ -241,21 +239,17 @@ bool COFFSymbol::should_keep() const { // Section class implementation COFFSection::COFFSection(StringRef name) - : Name(name) - , MCData(nullptr) - , Symbol(nullptr) { + : Name(name), MCSection(nullptr), Symbol(nullptr) { memset(&Header, 0, sizeof(Header)); } -size_t COFFSection::size() { - return COFF::SectionSize; -} +size_t COFFSection::size() { return COFF::SectionSize; } //------------------------------------------------------------------------------ // WinCOFFObjectWriter class implementation WinCOFFObjectWriter::WinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW, - raw_ostream &OS) + raw_pwrite_stream &OS) : MCObjectWriter(OS, true), TargetObjectWriter(MOTW) { memset(&Header, 0, sizeof(Header)); @@ -283,8 +277,7 @@ COFFSection *WinCOFFObjectWriter::createSection(StringRef Name) { /// A template used to lookup or create a symbol/section, and initialize it if /// needed. template <typename object_t, typename list_t> -object_t *WinCOFFObjectWriter::createCOFFEntity(StringRef Name, - list_t &List) { +object_t *WinCOFFObjectWriter::createCOFFEntity(StringRef Name, list_t &List) { List.push_back(make_unique<object_t>(Name)); return List.back().get(); @@ -292,15 +285,9 @@ object_t *WinCOFFObjectWriter::createCOFFEntity(StringRef Name, /// This function takes a section data object from the assembler /// and creates the associated COFF section staging object. -void WinCOFFObjectWriter::DefineSection(MCSectionData const &SectionData) { - assert(SectionData.getSection().getVariant() == MCSection::SV_COFF - && "Got non-COFF section in the COFF backend!"); - // FIXME: Not sure how to verify this (at least in a debug build). - MCSectionCOFF const &Sec = - static_cast<MCSectionCOFF const &>(SectionData.getSection()); - +void WinCOFFObjectWriter::defineSection(MCSectionCOFF const &Sec) { COFFSection *coff_section = createSection(Sec.getSectionName()); - COFFSymbol *coff_symbol = createSymbol(Sec.getSectionName()); + COFFSymbol *coff_symbol = createSymbol(Sec.getSectionName()); if (Sec.getSelection() != COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) { if (const MCSymbol *S = Sec.getCOMDATSymbol()) { COFFSymbol *COMDATSymbol = GetOrCreateCOFFSymbol(S); @@ -323,37 +310,66 @@ void WinCOFFObjectWriter::DefineSection(MCSectionData const &SectionData) { coff_section->Header.Characteristics = Sec.getCharacteristics(); uint32_t &Characteristics = coff_section->Header.Characteristics; - switch (SectionData.getAlignment()) { - case 1: Characteristics |= COFF::IMAGE_SCN_ALIGN_1BYTES; break; - case 2: Characteristics |= COFF::IMAGE_SCN_ALIGN_2BYTES; break; - case 4: Characteristics |= COFF::IMAGE_SCN_ALIGN_4BYTES; break; - case 8: Characteristics |= COFF::IMAGE_SCN_ALIGN_8BYTES; break; - case 16: Characteristics |= COFF::IMAGE_SCN_ALIGN_16BYTES; break; - case 32: Characteristics |= COFF::IMAGE_SCN_ALIGN_32BYTES; break; - case 64: Characteristics |= COFF::IMAGE_SCN_ALIGN_64BYTES; break; - case 128: Characteristics |= COFF::IMAGE_SCN_ALIGN_128BYTES; break; - case 256: Characteristics |= COFF::IMAGE_SCN_ALIGN_256BYTES; break; - case 512: Characteristics |= COFF::IMAGE_SCN_ALIGN_512BYTES; break; - case 1024: Characteristics |= COFF::IMAGE_SCN_ALIGN_1024BYTES; break; - case 2048: Characteristics |= COFF::IMAGE_SCN_ALIGN_2048BYTES; break; - case 4096: Characteristics |= COFF::IMAGE_SCN_ALIGN_4096BYTES; break; - case 8192: Characteristics |= COFF::IMAGE_SCN_ALIGN_8192BYTES; break; + switch (Sec.getAlignment()) { + case 1: + Characteristics |= COFF::IMAGE_SCN_ALIGN_1BYTES; + break; + case 2: + Characteristics |= COFF::IMAGE_SCN_ALIGN_2BYTES; + break; + case 4: + Characteristics |= COFF::IMAGE_SCN_ALIGN_4BYTES; + break; + case 8: + Characteristics |= COFF::IMAGE_SCN_ALIGN_8BYTES; + break; + case 16: + Characteristics |= COFF::IMAGE_SCN_ALIGN_16BYTES; + break; + case 32: + Characteristics |= COFF::IMAGE_SCN_ALIGN_32BYTES; + break; + case 64: + Characteristics |= COFF::IMAGE_SCN_ALIGN_64BYTES; + break; + case 128: + Characteristics |= COFF::IMAGE_SCN_ALIGN_128BYTES; + break; + case 256: + Characteristics |= COFF::IMAGE_SCN_ALIGN_256BYTES; + break; + case 512: + Characteristics |= COFF::IMAGE_SCN_ALIGN_512BYTES; + break; + case 1024: + Characteristics |= COFF::IMAGE_SCN_ALIGN_1024BYTES; + break; + case 2048: + Characteristics |= COFF::IMAGE_SCN_ALIGN_2048BYTES; + break; + case 4096: + Characteristics |= COFF::IMAGE_SCN_ALIGN_4096BYTES; + break; + case 8192: + Characteristics |= COFF::IMAGE_SCN_ALIGN_8192BYTES; + break; default: llvm_unreachable("unsupported section alignment"); } // Bind internal COFF section to MC section. - coff_section->MCData = &SectionData; - SectionMap[&SectionData.getSection()] = coff_section; + coff_section->MCSection = &Sec; + SectionMap[&Sec] = coff_section; } -static uint64_t getSymbolValue(const MCSymbolData &Data, +static uint64_t getSymbolValue(const MCSymbol &Symbol, const MCAsmLayout &Layout) { + const MCSymbolData &Data = Symbol.getData(); if (Data.isCommon() && Data.isExternal()) return Data.getCommonSize(); uint64_t Res; - if (!Layout.getSymbolOffset(&Data, Res)) + if (!Layout.getSymbolOffset(Symbol, Res)) return 0; return Res; @@ -361,33 +377,30 @@ static uint64_t getSymbolValue(const MCSymbolData &Data, /// This function takes a symbol data object from the assembler /// and creates the associated COFF symbol staging object. -void WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData, +void WinCOFFObjectWriter::DefineSymbol(const MCSymbol &Symbol, MCAssembler &Assembler, const MCAsmLayout &Layout) { - MCSymbol const &Symbol = SymbolData.getSymbol(); COFFSymbol *coff_symbol = GetOrCreateCOFFSymbol(&Symbol); SymbolMap[&Symbol] = coff_symbol; - if (SymbolData.getFlags() & COFF::SF_WeakExternal) { + if (Symbol.getData().getFlags() & COFF::SF_WeakExternal) { coff_symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL; if (Symbol.isVariable()) { const MCSymbolRefExpr *SymRef = - dyn_cast<MCSymbolRefExpr>(Symbol.getVariableValue()); + dyn_cast<MCSymbolRefExpr>(Symbol.getVariableValue()); if (!SymRef) report_fatal_error("Weak externals may only alias symbols"); coff_symbol->Other = GetOrCreateCOFFSymbol(&SymRef->getSymbol()); } else { - std::string WeakName = std::string(".weak.") - + Symbol.getName().str() - + ".default"; + std::string WeakName = (".weak." + Symbol.getName() + ".default").str(); COFFSymbol *WeakDefault = createSymbol(WeakName); WeakDefault->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE; - WeakDefault->Data.StorageClass = COFF::IMAGE_SYM_CLASS_EXTERNAL; - WeakDefault->Data.Type = 0; - WeakDefault->Data.Value = 0; + WeakDefault->Data.StorageClass = COFF::IMAGE_SYM_CLASS_EXTERNAL; + WeakDefault->Data.Type = 0; + WeakDefault->Data.Value = 0; coff_symbol->Other = WeakDefault; } @@ -397,22 +410,21 @@ void WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData, coff_symbol->Aux[0].AuxType = ATWeakExternal; coff_symbol->Aux[0].Aux.WeakExternal.TagIndex = 0; coff_symbol->Aux[0].Aux.WeakExternal.Characteristics = - COFF::IMAGE_WEAK_EXTERN_SEARCH_LIBRARY; + COFF::IMAGE_WEAK_EXTERN_SEARCH_LIBRARY; - coff_symbol->MCData = &SymbolData; + coff_symbol->MC = &Symbol; } else { const MCSymbolData &ResSymData = Assembler.getSymbolData(Symbol); const MCSymbol *Base = Layout.getBaseSymbol(Symbol); - coff_symbol->Data.Value = getSymbolValue(ResSymData, Layout); + coff_symbol->Data.Value = getSymbolValue(Symbol, Layout); - coff_symbol->Data.Type = (ResSymData.getFlags() & 0x0000FFFF) >> 0; + coff_symbol->Data.Type = (ResSymData.getFlags() & 0x0000FFFF) >> 0; coff_symbol->Data.StorageClass = (ResSymData.getFlags() & 0x00FF0000) >> 16; // If no storage class was specified in the streamer, define it here. if (coff_symbol->Data.StorageClass == 0) { - bool IsExternal = - ResSymData.isExternal() || - (!ResSymData.getFragment() && !ResSymData.getSymbol().isVariable()); + bool IsExternal = ResSymData.isExternal() || + (!ResSymData.getFragment() && !Symbol.isVariable()); coff_symbol->Data.StorageClass = IsExternal ? COFF::IMAGE_SYM_CLASS_EXTERNAL @@ -424,8 +436,7 @@ void WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData, } else { const MCSymbolData &BaseData = Assembler.getSymbolData(*Base); if (BaseData.getFragment()) { - COFFSection *Sec = - SectionMap[&BaseData.getFragment()->getParent()->getSection()]; + COFFSection *Sec = SectionMap[BaseData.getFragment()->getParent()]; if (coff_symbol->Section && coff_symbol->Section != Sec) report_fatal_error("conflicting sections for symbol"); @@ -434,7 +445,7 @@ void WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData, } } - coff_symbol->MCData = &ResSymData; + coff_symbol->MC = &Symbol; } } @@ -446,7 +457,7 @@ static const uint64_t MaxBase64Offset = 0xFFFFFFFFFULL; // 64^6, including 0 // Encode a string table entry offset in base 64, padded to 6 chars, and // prefixed with a double slash: '//AAAAAA', '//AAAAAB', ... // Buffer must be at least 8 bytes large. No terminating null appended. -static void encodeBase64StringEntry(char* Buffer, uint64_t Value) { +static void encodeBase64StringEntry(char *Buffer, uint64_t Value) { assert(Value > Max7DecimalOffset && Value <= MaxBase64Offset && "Illegal section name encoding for value"); @@ -457,7 +468,7 @@ static void encodeBase64StringEntry(char* Buffer, uint64_t Value) { Buffer[0] = '/'; Buffer[1] = '/'; - char* Ptr = Buffer + 7; + char *Ptr = Buffer + 7; for (unsigned i = 0; i < 6; ++i) { unsigned Rem = Value % 64; Value /= 64; @@ -474,7 +485,7 @@ void WinCOFFObjectWriter::SetSectionName(COFFSection &S) { } else if (StringTableEntry <= Max7DecimalOffset) { // With seven digits, we have to skip the terminating null. Because // sprintf always appends it, we use a larger temporary buffer. - char buffer[9] = { }; + char buffer[9] = {}; std::sprintf(buffer, "/%d", unsigned(StringTableEntry)); std::memcpy(S.Header.Name, buffer, 8); } else if (StringTableEntry <= MaxBase64Offset) { @@ -515,8 +526,8 @@ bool WinCOFFObjectWriter::ExportSymbol(const MCSymbol &Symbol, } bool WinCOFFObjectWriter::IsPhysicalSection(COFFSection *S) { - return (S->Header.Characteristics - & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) == 0; + return (S->Header.Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) == + 0; } //------------------------------------------------------------------------------ @@ -529,8 +540,7 @@ void WinCOFFObjectWriter::WriteFileHeader(const COFF::header &Header) { WriteLE16(COFF::BigObjHeader::MinBigObjectVersion); WriteLE16(Header.Machine); WriteLE32(Header.TimeDateStamp); - for (uint8_t MagicChar : COFF::BigObjMagic) - Write8(MagicChar); + WriteBytes(StringRef(COFF::BigObjMagic, sizeof(COFF::BigObjMagic))); WriteLE32(0); WriteLE32(0); WriteLE32(0); @@ -563,10 +573,10 @@ void WinCOFFObjectWriter::WriteSymbol(const COFFSymbol &S) { } void WinCOFFObjectWriter::WriteAuxiliarySymbols( - const COFFSymbol::AuxiliarySymbols &S) { - for(COFFSymbol::AuxiliarySymbols::const_iterator i = S.begin(), e = S.end(); - i != e; ++i) { - switch(i->AuxType) { + const COFFSymbol::AuxiliarySymbols &S) { + for (COFFSymbol::AuxiliarySymbols::const_iterator i = S.begin(), e = S.end(); + i != e; ++i) { + switch (i->AuxType) { case ATFunctionDefinition: WriteLE32(i->Aux.FunctionDefinition.TagIndex); WriteLE32(i->Aux.FunctionDefinition.TotalSize); @@ -641,54 +651,69 @@ void WinCOFFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, // "Define" each section & symbol. This creates section & symbol // entries in the staging area. for (const auto &Section : Asm) - DefineSection(Section); + defineSection(static_cast<const MCSectionCOFF &>(Section)); - for (MCSymbolData &SD : Asm.symbols()) - if (ExportSymbol(SD.getSymbol(), Asm)) - DefineSymbol(SD, Asm, Layout); + for (const MCSymbol &Symbol : Asm.symbols()) + if (ExportSymbol(Symbol, Asm)) + DefineSymbol(Symbol, Asm, Layout); } bool WinCOFFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl( - const MCAssembler &Asm, const MCSymbolData &DataA, const MCFragment &FB, + const MCAssembler &Asm, const MCSymbol &SymA, const MCFragment &FB, bool InSet, bool IsPCRel) const { // MS LINK expects to be able to replace all references to a function with a // thunk to implement their /INCREMENTAL feature. Make sure we don't optimize // away any relocations to functions. - if ((((DataA.getFlags() & COFF::SF_TypeMask) >> COFF::SF_TypeShift) >> + if ((((SymA.getData().getFlags() & COFF::SF_TypeMask) >> + COFF::SF_TypeShift) >> COFF::SCT_COMPLEX_TYPE_SHIFT) == COFF::IMAGE_SYM_DTYPE_FUNCTION) return false; - return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(Asm, DataA, FB, + return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(Asm, SymA, FB, InSet, IsPCRel); } -void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm, - const MCAsmLayout &Layout, - const MCFragment *Fragment, - const MCFixup &Fixup, - MCValue Target, - bool &IsPCRel, - uint64_t &FixedValue) { +bool WinCOFFObjectWriter::isWeak(const MCSymbol &Sym) const { + const MCSymbolData &SD = Sym.getData(); + if (!SD.isExternal()) + return false; + + if (!Sym.isInSection()) + return false; + + const auto &Sec = cast<MCSectionCOFF>(Sym.getSection()); + if (!Sec.getCOMDATSymbol()) + return false; + + // It looks like for COFF it is invalid to replace a reference to a global + // in a comdat with a reference to a local. + // FIXME: Add a specification reference if available. + return true; +} + +void WinCOFFObjectWriter::RecordRelocation( + MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, + const MCFixup &Fixup, MCValue Target, bool &IsPCRel, uint64_t &FixedValue) { assert(Target.getSymA() && "Relocation must reference a symbol!"); const MCSymbol &Symbol = Target.getSymA()->getSymbol(); - const MCSymbol &A = Symbol.AliasedSymbol(); + const MCSymbol &A = Symbol; if (!Asm.hasSymbolData(A)) - Asm.getContext().FatalError( - Fixup.getLoc(), - Twine("symbol '") + A.getName() + "' can not be undefined"); + Asm.getContext().reportFatalError(Fixup.getLoc(), + Twine("symbol '") + A.getName() + + "' can not be undefined"); const MCSymbolData &A_SD = Asm.getSymbolData(A); - MCSectionData const *SectionData = Fragment->getParent(); + MCSection *Section = Fragment->getParent(); // Mark this symbol as requiring an entry in the symbol table. - assert(SectionMap.find(&SectionData->getSection()) != SectionMap.end() && + assert(SectionMap.find(Section) != SectionMap.end() && "Section must already have been defined in ExecutePostLayoutBinding!"); - assert(SymbolMap.find(&A_SD.getSymbol()) != SymbolMap.end() && + assert(SymbolMap.find(&A) != SymbolMap.end() && "Symbol must already have been defined in ExecutePostLayoutBinding!"); - COFFSection *coff_section = SectionMap[&SectionData->getSection()]; - COFFSymbol *coff_symbol = SymbolMap[&A_SD.getSymbol()]; + COFFSection *coff_section = SectionMap[Section]; + COFFSymbol *coff_symbol = SymbolMap[&A]; const MCSymbolRefExpr *SymB = Target.getSymB(); bool CrossSection = false; @@ -696,13 +721,13 @@ void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm, const MCSymbol *B = &SymB->getSymbol(); const MCSymbolData &B_SD = Asm.getSymbolData(*B); if (!B_SD.getFragment()) - Asm.getContext().FatalError( + Asm.getContext().reportFatalError( Fixup.getLoc(), Twine("symbol '") + B->getName() + "' can not be undefined in a subtraction expression"); if (!A_SD.getFragment()) - Asm.getContext().FatalError( + Asm.getContext().reportFatalError( Fixup.getLoc(), Twine("symbol '") + Symbol.getName() + "' can not be undefined in a subtraction expression"); @@ -710,13 +735,13 @@ void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm, CrossSection = &Symbol.getSection() != &B->getSection(); // Offset of the symbol in the section - int64_t OffsetOfB = Layout.getSymbolOffset(&B_SD); + int64_t OffsetOfB = Layout.getSymbolOffset(*B); // In the case where we have SymbA and SymB, we just need to store the delta // between the two symbols. Update FixedValue to account for the delta, and // skip recording the relocation. if (!CrossSection) { - int64_t OffsetOfA = Layout.getSymbolOffset(&A_SD); + int64_t OffsetOfA = Layout.getSymbolOffset(A); FixedValue = (OffsetOfA - OffsetOfB) + Target.getConstant(); return; } @@ -725,7 +750,7 @@ void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm, int64_t OffsetOfRelocation = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); - FixedValue = OffsetOfRelocation - OffsetOfB; + FixedValue = (OffsetOfRelocation - OffsetOfB) + Target.getConstant(); } else { FixedValue = Target.getConstant(); } @@ -736,18 +761,19 @@ void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm, Reloc.Data.VirtualAddress = Layout.getFragmentOffset(Fragment); // Turn relocations for temporary symbols into section relocations. - if (coff_symbol->MCData->getSymbol().isTemporary() || CrossSection) { + if (coff_symbol->MC->isTemporary() || CrossSection) { Reloc.Symb = coff_symbol->Section->Symbol; - FixedValue += Layout.getFragmentOffset(coff_symbol->MCData->getFragment()) + - coff_symbol->MCData->getOffset(); + FixedValue += + Layout.getFragmentOffset(coff_symbol->MC->getData().getFragment()) + + coff_symbol->MC->getData().getOffset(); } else Reloc.Symb = coff_symbol; ++Reloc.Symb->Relocations; Reloc.Data.VirtualAddress += Fixup.getOffset(); - Reloc.Data.Type = TargetObjectWriter->getRelocType(Target, Fixup, - CrossSection); + Reloc.Data.Type = TargetObjectWriter->getRelocType( + Target, Fixup, CrossSection, Asm.getBackend()); // FIXME: Can anyone explain what this does other than adjust for the size // of the offset? @@ -768,9 +794,9 @@ void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm, break; case COFF::IMAGE_REL_ARM_BRANCH11: case COFF::IMAGE_REL_ARM_BLX11: - // IMAGE_REL_ARM_BRANCH11 and IMAGE_REL_ARM_BLX11 are only used for - // pre-ARMv7, which implicitly rules it out of ARMNT (it would be valid - // for Windows CE). + // IMAGE_REL_ARM_BRANCH11 and IMAGE_REL_ARM_BLX11 are only used for + // pre-ARMv7, which implicitly rules it out of ARMNT (it would be valid + // for Windows CE). case COFF::IMAGE_REL_ARM_BRANCH24: case COFF::IMAGE_REL_ARM_BLX24: case COFF::IMAGE_REL_ARM_MOV32A: @@ -827,8 +853,8 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, Header.NumberOfSections = NumberOfSections; Header.NumberOfSymbols = 0; - for (auto FI = Asm.file_names_begin(), FE = Asm.file_names_end(); - FI != FE; ++FI) { + for (auto FI = Asm.file_names_begin(), FE = Asm.file_names_end(); FI != FE; + ++FI) { // round up to calculate the number of auxiliary symbols required unsigned SymbolSize = UseBigObj ? COFF::Symbol32Size : COFF::Symbol16Size; unsigned Count = (FI->size() + SymbolSize - 1) / SymbolSize; @@ -902,8 +928,7 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) continue; - const MCSectionCOFF &MCSec = - static_cast<const MCSectionCOFF &>(Section->MCData->getSection()); + const MCSectionCOFF &MCSec = *Section->MCSection; const MCSymbol *COMDAT = MCSec.getCOMDATSymbol(); assert(COMDAT); @@ -919,10 +944,10 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, if (Assoc->Number == -1) continue; - Section->Symbol->Aux[0].Aux.SectionDefinition.Number = SectionIndices[Assoc]; + Section->Symbol->Aux[0].Aux.SectionDefinition.Number = + SectionIndices[Assoc]; } - // Assign file offsets to COFF object file structures. unsigned offset = 0; @@ -934,7 +959,7 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, offset += COFF::SectionSize * Header.NumberOfSections; for (const auto &Section : Asm) { - COFFSection *Sec = SectionMap[&Section.getSection()]; + COFFSection *Sec = SectionMap[&Section]; if (Sec->Number == -1) continue; @@ -942,6 +967,8 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, Sec->Header.SizeOfRawData = Layout.getSectionAddressSize(&Section); if (IsPhysicalSection(Sec)) { + // Align the section data to a four byte boundary. + offset = RoundUpToAlignment(offset, 4); Sec->Header.PointerToRawData = offset; offset += Sec->Header.SizeOfRawData; @@ -979,9 +1006,9 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, "Section's symbol's aux symbol must be a Section Definition!"); Aux.Aux.SectionDefinition.Length = Sec->Header.SizeOfRawData; Aux.Aux.SectionDefinition.NumberOfRelocations = - Sec->Header.NumberOfRelocations; + Sec->Header.NumberOfRelocations; Aux.Aux.SectionDefinition.NumberOfLinenumbers = - Sec->Header.NumberOfLineNumbers; + Sec->Header.NumberOfLineNumbers; } Header.PointerToSymbolTable = offset; @@ -1004,18 +1031,24 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, } } - for (i = Sections.begin(), ie = Sections.end(), - j = Asm.begin(), je = Asm.end(); + for (i = Sections.begin(), ie = Sections.end(), j = Asm.begin(), + je = Asm.end(); (i != ie) && (j != je); ++i, ++j) { if ((*i)->Number == -1) continue; if ((*i)->Header.PointerToRawData != 0) { - assert(OS.tell() == (*i)->Header.PointerToRawData && + assert(OS.tell() <= (*i)->Header.PointerToRawData && "Section::PointerToRawData is insane!"); - Asm.writeSectionData(j, Layout); + unsigned SectionDataPadding = (*i)->Header.PointerToRawData - OS.tell(); + assert(SectionDataPadding < 4 && + "Should only need at most three bytes of padding!"); + + WriteZeros(SectionDataPadding); + + Asm.writeSectionData(&*j, Layout); } if ((*i)->Relocations.size() > 0) { @@ -1050,9 +1083,8 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, OS.write(Strings.data().data(), Strings.data().size()); } -MCWinCOFFObjectTargetWriter::MCWinCOFFObjectTargetWriter(unsigned Machine_) : - Machine(Machine_) { -} +MCWinCOFFObjectTargetWriter::MCWinCOFFObjectTargetWriter(unsigned Machine_) + : Machine(Machine_) {} // Pin the vtable to this file. void MCWinCOFFObjectTargetWriter::anchor() {} @@ -1060,9 +1092,8 @@ void MCWinCOFFObjectTargetWriter::anchor() {} //------------------------------------------------------------------------------ // WinCOFFObjectWriter factory function -namespace llvm { - MCObjectWriter *createWinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW, - raw_ostream &OS) { - return new WinCOFFObjectWriter(MOTW, OS); - } +MCObjectWriter * +llvm::createWinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW, + raw_pwrite_stream &OS) { + return new WinCOFFObjectWriter(MOTW, OS); } diff --git a/contrib/llvm/lib/MC/WinCOFFStreamer.cpp b/contrib/llvm/lib/MC/WinCOFFStreamer.cpp index 41a3da7..d2fbd37 100644 --- a/contrib/llvm/lib/MC/WinCOFFStreamer.cpp +++ b/contrib/llvm/lib/MC/WinCOFFStreamer.cpp @@ -39,7 +39,7 @@ using namespace llvm; namespace llvm { MCWinCOFFStreamer::MCWinCOFFStreamer(MCContext &Context, MCAsmBackend &MAB, - MCCodeEmitter &CE, raw_ostream &OS) + MCCodeEmitter &CE, raw_pwrite_stream &OS) : MCObjectStreamer(Context, MAB, OS, &CE), CurSymbol(nullptr) {} void MCWinCOFFStreamer::EmitInstToData(const MCInst &Inst, @@ -49,7 +49,7 @@ void MCWinCOFFStreamer::EmitInstToData(const MCInst &Inst, SmallVector<MCFixup, 4> Fixups; SmallString<256> Code; raw_svector_ostream VecOS(Code); - getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups, STI); + getAssembler().getEmitter().encodeInstruction(Inst, VecOS, Fixups, STI); VecOS.flush(); // Add the fixups and data. @@ -161,7 +161,7 @@ void MCWinCOFFStreamer::EndCOFFSymbolDef() { void MCWinCOFFStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) { MCDataFragment *DF = getOrCreateDataFragment(); const MCSymbolRefExpr *SRE = MCSymbolRefExpr::Create(Symbol, getContext()); - MCFixup Fixup = MCFixup::Create(DF->getContents().size(), SRE, FK_SecRel_2); + MCFixup Fixup = MCFixup::create(DF->getContents().size(), SRE, FK_SecRel_2); DF->getFixups().push_back(Fixup); DF->getContents().resize(DF->getContents().size() + 2, 0); } @@ -169,7 +169,7 @@ void MCWinCOFFStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) { void MCWinCOFFStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) { MCDataFragment *DF = getOrCreateDataFragment(); const MCSymbolRefExpr *SRE = MCSymbolRefExpr::Create(Symbol, getContext()); - MCFixup Fixup = MCFixup::Create(DF->getContents().size(), SRE, FK_SecRel_4); + MCFixup Fixup = MCFixup::create(DF->getContents().size(), SRE, FK_SecRel_4); DF->getFixups().push_back(Fixup); DF->getContents().resize(DF->getContents().size() + 4, 0); } @@ -219,10 +219,10 @@ void MCWinCOFFStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) { assert(!Symbol->isInSection() && "Symbol must not already have a section!"); - const MCSection *Section = getContext().getObjectFileInfo()->getBSSSection(); - MCSectionData &SectionData = getAssembler().getOrCreateSectionData(*Section); - if (SectionData.getAlignment() < ByteAlignment) - SectionData.setAlignment(ByteAlignment); + MCSection *Section = getContext().getObjectFileInfo()->getBSSSection(); + getAssembler().registerSection(*Section); + if (Section->getAlignment() < ByteAlignment) + Section->setAlignment(ByteAlignment); MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); SD.setExternal(false); @@ -230,23 +230,21 @@ void MCWinCOFFStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, AssignSection(Symbol, Section); if (ByteAlignment != 1) - new MCAlignFragment(ByteAlignment, /*_Value=*/0, /*_ValueSize=*/0, - ByteAlignment, &SectionData); + new MCAlignFragment(ByteAlignment, /*Value=*/0, /*ValueSize=*/0, + ByteAlignment, Section); - MCFillFragment *Fragment = - new MCFillFragment(/*_Value=*/0, /*_ValueSize=*/0, Size, &SectionData); + MCFillFragment *Fragment = new MCFillFragment( + /*Value=*/0, /*ValueSize=*/0, Size, Section); SD.setFragment(Fragment); } -void MCWinCOFFStreamer::EmitZerofill(const MCSection *Section, - MCSymbol *Symbol, uint64_t Size, - unsigned ByteAlignment) { +void MCWinCOFFStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol, + uint64_t Size, unsigned ByteAlignment) { llvm_unreachable("not implemented"); } -void MCWinCOFFStreamer::EmitTBSSSymbol(const MCSection *Section, - MCSymbol *Symbol, uint64_t Size, - unsigned ByteAlignment) { +void MCWinCOFFStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, + uint64_t Size, unsigned ByteAlignment) { llvm_unreachable("not implemented"); } @@ -269,7 +267,7 @@ void MCWinCOFFStreamer::FinishImpl() { LLVM_ATTRIBUTE_NORETURN void MCWinCOFFStreamer::FatalError(const Twine &Msg) const { - getContext().FatalError(SMLoc(), Msg); + getContext().reportFatalError(SMLoc(), Msg); } } |