diff options
author | Stephen Hines <srhines@google.com> | 2014-05-29 02:49:00 -0700 |
---|---|---|
committer | Stephen Hines <srhines@google.com> | 2014-05-29 02:49:00 -0700 |
commit | dce4a407a24b04eebc6a376f8e62b41aaa7b071f (patch) | |
tree | dcebc53f2b182f145a2e659393bf9a0472cedf23 /lib/MC | |
parent | 220b921aed042f9e520c26cffd8282a94c66c3d5 (diff) | |
download | external_llvm-dce4a407a24b04eebc6a376f8e62b41aaa7b071f.zip external_llvm-dce4a407a24b04eebc6a376f8e62b41aaa7b071f.tar.gz external_llvm-dce4a407a24b04eebc6a376f8e62b41aaa7b071f.tar.bz2 |
Update LLVM for 3.5 rebase (r209712).
Change-Id: I149556c940fb7dc92d075273c87ff584f400941f
Diffstat (limited to 'lib/MC')
42 files changed, 1240 insertions, 1329 deletions
diff --git a/lib/MC/Android.mk b/lib/MC/Android.mk index abf346b..975f4e3 100644 --- a/lib/MC/Android.mk +++ b/lib/MC/Android.mk @@ -20,7 +20,6 @@ mc_SRC_FILES := \ MCELFStreamer.cpp \ MCExpr.cpp \ MCExternalSymbolizer.cpp \ - MCFixup.cpp \ MCInst.cpp \ MCInstPrinter.cpp \ MCInstrAnalysis.cpp \ @@ -35,13 +34,14 @@ mc_SRC_FILES := \ MCRegisterInfo.cpp \ MCRelocationInfo.cpp \ MCSection.cpp \ - MCSectionCOFF.cpp \ + MCSectionCOFF.cpp \ MCSectionELF.cpp \ MCSectionMachO.cpp \ MCStreamer.cpp \ MCSubtargetInfo.cpp \ MCSymbol.cpp \ MCSymbolizer.cpp \ + MCTargetOptions.cpp \ MCValue.cpp \ MCWin64EH.cpp \ WinCOFFObjectWriter.cpp \ diff --git a/lib/MC/CMakeLists.txt b/lib/MC/CMakeLists.txt index ab7dabc..6a384c1 100644 --- a/lib/MC/CMakeLists.txt +++ b/lib/MC/CMakeLists.txt @@ -16,7 +16,6 @@ add_llvm_library(LLVMMC MCELF.cpp MCELFObjectTargetWriter.cpp MCELFStreamer.cpp - MCFixup.cpp MCFunction.cpp MCExpr.cpp MCExternalSymbolizer.cpp @@ -45,6 +44,7 @@ add_llvm_library(LLVMMC MCSubtargetInfo.cpp MCSymbol.cpp MCSymbolizer.cpp + MCTargetOptions.cpp MCValue.cpp MCWin64EH.cpp MachObjectWriter.cpp diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp index e9b8fe2..0a54627 100644 --- a/lib/MC/ELFObjectWriter.cpp +++ b/lib/MC/ELFObjectWriter.cpp @@ -17,6 +17,7 @@ #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringMap.h" #include "llvm/MC/MCAsmBackend.h" +#include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCAsmLayout.h" #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCContext.h" @@ -27,6 +28,8 @@ #include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCValue.h" +#include "llvm/Object/StringTableBuilder.h" +#include "llvm/Support/Compression.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Endian.h" #include "llvm/Support/ELF.h" @@ -105,10 +108,9 @@ class ELFObjectWriter : public MCObjectWriter { static bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind); static bool RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant); static uint64_t SymbolValue(MCSymbolData &Data, const MCAsmLayout &Layout); - static bool isInSymtab(const MCAssembler &Asm, const MCSymbolData &Data, + static bool isInSymtab(const MCAsmLayout &Layout, const MCSymbolData &Data, bool Used, bool Renamed); - static bool isLocal(const MCSymbolData &Data, bool isSignature, - bool isUsedInReloc); + static bool isLocal(const MCSymbolData &Data, bool isUsedInReloc); static bool IsELFMetaDataSection(const MCSectionData &SD); static uint64_t DataSectionSize(const MCSectionData &SD); static uint64_t GetSectionFileSize(const MCAsmLayout &Layout, @@ -131,11 +133,11 @@ class ELFObjectWriter : public MCObjectWriter { MCSymbolData *SymbolData; uint64_t StringIndex; uint32_t SectionIndex; + StringRef Name; // Support lexicographic sorting. bool operator<(const ELFSymbolData &RHS) const { - return SymbolData->getSymbol().getName() < - RHS.SymbolData->getSymbol().getName(); + return Name < RHS.Name; } }; @@ -148,13 +150,13 @@ class ELFObjectWriter : public MCObjectWriter { llvm::DenseMap<const MCSectionData *, std::vector<ELFRelocationEntry>> Relocations; - DenseMap<const MCSection*, uint64_t> SectionStringTableIndex; + StringTableBuilder ShStrTabBuilder; /// @} /// @name Symbol Table Data /// @{ - SmallString<256> StringTable; + StringTableBuilder StrTabBuilder; std::vector<uint64_t> FileSymbolData; std::vector<ELFSymbolData> LocalSymbolData; std::vector<ELFSymbolData> ExternalSymbolData; @@ -214,7 +216,8 @@ class ELFObjectWriter : public MCObjectWriter { const MCAsmLayout &Layout, SectionIndexMapTy &SectionIndexMap); - bool shouldRelocateWithSymbol(const MCSymbolRefExpr *RefA, + bool shouldRelocateWithSymbol(const MCAssembler &Asm, + const MCSymbolRefExpr *RefA, const MCSymbolData *SD, uint64_t C, unsigned Type) const; @@ -253,6 +256,8 @@ class ELFObjectWriter : public MCObjectWriter { void CreateRelocationSections(MCAssembler &Asm, MCAsmLayout &Layout, RelMapTy &RelMap); + void CompressDebugSections(MCAssembler &Asm, MCAsmLayout &Layout); + void WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout, const RelMapTy &RelMap); @@ -481,43 +486,18 @@ void ELFObjectWriter::WriteHeader(const MCAssembler &Asm, Write16(ShstrtabIndex); } -uint64_t ELFObjectWriter::SymbolValue(MCSymbolData &OrigData, +uint64_t ELFObjectWriter::SymbolValue(MCSymbolData &Data, const MCAsmLayout &Layout) { - MCSymbolData *Data = &OrigData; - if (Data->isCommon() && Data->isExternal()) - return Data->getCommonAlignment(); - - const MCSymbol *Symbol = &Data->getSymbol(); - bool IsThumbFunc = OrigData.getFlags() & ELF_Other_ThumbFunc; - - uint64_t Res = 0; - if (Symbol->isVariable()) { - const MCExpr *Expr = Symbol->getVariableValue(); - MCValue Value; - if (!Expr->EvaluateAsRelocatable(Value, &Layout)) - llvm_unreachable("Invalid expression"); + if (Data.isCommon() && Data.isExternal()) + return Data.getCommonAlignment(); - assert(!Value.getSymB()); - - Res = Value.getConstant(); - - if (const MCSymbolRefExpr *A = Value.getSymA()) { - Symbol = &A->getSymbol(); - Data = &Layout.getAssembler().getSymbolData(*Symbol); - } else { - Symbol = 0; - Data = 0; - } - } + uint64_t Res; + if (!Layout.getSymbolOffset(&Data, Res)) + return 0; - if (IsThumbFunc) + if (Layout.getAssembler().isThumbFunc(&Data.getSymbol())) Res |= 1; - if (!Symbol || !Symbol->isInSection()) - return Res; - - Res += Layout.getSymbolOffset(Data); - return Res; } @@ -526,15 +506,17 @@ void ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, // The presence of symbol versions causes undefined symbols and // versions declared with @@@ to be renamed. - for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), - ie = Asm.symbol_end(); it != ie; ++it) { - const MCSymbol &Alias = it->getSymbol(); - const MCSymbol &Symbol = Alias.AliasedSymbol(); - MCSymbolData &SD = Asm.getSymbolData(Symbol); + for (MCSymbolData &OriginalData : Asm.symbols()) { + const MCSymbol &Alias = OriginalData.getSymbol(); // Not an alias. - if (&Symbol == &Alias) + if (!Alias.isVariable()) + continue; + auto *Ref = dyn_cast<MCSymbolRefExpr>(Alias.getVariableValue()); + if (!Ref) continue; + const MCSymbol &Symbol = Ref->getSymbol(); + MCSymbolData &SD = Asm.getSymbolData(Symbol); StringRef AliasName = Alias.getName(); size_t Pos = AliasName.find('@'); @@ -543,8 +525,8 @@ void ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, // Aliases defined with .symvar copy the binding from the symbol they alias. // This is the first place we are able to copy this information. - it->setExternal(SD.isExternal()); - MCELF::SetBinding(*it, MCELF::GetBinding(SD)); + OriginalData.setExternal(SD.isExternal()); + MCELF::SetBinding(OriginalData, MCELF::GetBinding(SD)); StringRef Rest = AliasName.substr(Pos); if (!Symbol.isUndefined() && !Rest.startswith("@@@")) @@ -594,26 +576,14 @@ static uint8_t mergeTypeForSet(uint8_t origType, uint8_t newType) { return Type; } -static const MCSymbol *getBaseSymbol(const MCAsmLayout &Layout, - const MCSymbol &Symbol) { - if (!Symbol.isVariable()) - return &Symbol; - - const MCExpr *Expr = Symbol.getVariableValue(); - MCValue Value; - if (!Expr->EvaluateAsRelocatable(Value, &Layout)) - llvm_unreachable("Invalid Expression"); - assert(!Value.getSymB()); - const MCSymbolRefExpr *A = Value.getSymA(); - if (!A) - return nullptr; - return getBaseSymbol(Layout, A->getSymbol()); -} - void ELFObjectWriter::WriteSymbol(SymbolTableWriter &Writer, ELFSymbolData &MSD, const MCAsmLayout &Layout) { MCSymbolData &OrigData = *MSD.SymbolData; - const MCSymbol *Base = getBaseSymbol(Layout, OrigData.getSymbol()); + assert((!OrigData.getFragment() || + (&OrigData.getFragment()->getParent()->getSection() == + &OrigData.getSymbol().getSection())) && + "The symbol's section doesn't match the fragment's symbol"); + const MCSymbol *Base = Layout.getBaseSymbol(OrigData.getSymbol()); // This has to be in sync with when computeSymbolTable uses SHN_ABS or // SHN_COMMON. @@ -627,8 +597,6 @@ void ELFObjectWriter::WriteSymbol(SymbolTableWriter &Writer, ELFSymbolData &MSD, BaseSD = &Layout.getAssembler().getSymbolData(*Base); Type = mergeTypeForSet(Type, MCELF::GetType(*BaseSD)); } - if (OrigData.getFlags() & ELF_Other_ThumbFunc) - Type = ELF::STT_FUNC; uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift); // Other and Visibility share the same byte with Visibility using the lower @@ -638,8 +606,6 @@ void ELFObjectWriter::WriteSymbol(SymbolTableWriter &Writer, ELFSymbolData &MSD, Other |= Visibility; uint64_t Value = SymbolValue(OrigData, Layout); - if (OrigData.getFlags() & ELF_Other_ThumbFunc) - Value |= 1; uint64_t Size = 0; const MCExpr *ESize = OrigData.getSize(); @@ -664,7 +630,6 @@ void ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF, SectionIndexMapTy &SectionIndexMap) { // The string table must be emitted first because we need the index // into the string table for all the symbol names. - assert(StringTable.size() && "Missing string table"); // FIXME: Make sure the start of the symbol table is aligned. @@ -725,7 +690,8 @@ void ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF, // It is always valid to create a relocation with a symbol. It is preferable // to use a relocation with a section if that is possible. Using the section // allows us to omit some local symbols from the symbol table. -bool ELFObjectWriter::shouldRelocateWithSymbol(const MCSymbolRefExpr *RefA, +bool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm, + const MCSymbolRefExpr *RefA, const MCSymbolData *SD, uint64_t C, unsigned Type) const { @@ -809,11 +775,37 @@ bool ELFObjectWriter::shouldRelocateWithSymbol(const MCSymbolRefExpr *RefA, if (Flags & ELF::SHF_TLS) return true; + // If the symbol is a thumb function the final relocation must set the lowest + // 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)) + return true; + if (TargetObjectWriter->needsRelocateWithSymbol(Type)) return true; return false; } +static const MCSymbol *getWeakRef(const MCSymbolRefExpr &Ref) { + const MCSymbol &Sym = Ref.getSymbol(); + + if (Ref.getKind() == MCSymbolRefExpr::VK_WEAKREF) + return &Sym; + + if (!Sym.isVariable()) + return nullptr; + + const MCExpr *Expr = Sym.getVariableValue(); + const auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr); + if (!Inner) + return nullptr; + + if (Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF) + return &Inner->getSymbol(); + return nullptr; +} + void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, @@ -868,7 +860,7 @@ void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, const MCSymbolData *SymAD = SymA ? &Asm.getSymbolData(*SymA) : nullptr; unsigned Type = GetRelocType(Target, Fixup, IsPCRel); - bool RelocateWithSymbol = shouldRelocateWithSymbol(RefA, SymAD, C, Type); + bool RelocateWithSymbol = shouldRelocateWithSymbol(Asm, RefA, SymAD, C, Type); if (!RelocateWithSymbol && SymA && !SymA->isUndefined()) C += Layout.getSymbolOffset(SymAD); @@ -899,8 +891,8 @@ void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, if (const MCSymbol *R = Renames.lookup(SymA)) SymA = R; - if (RefA->getKind() == MCSymbolRefExpr::VK_WEAKREF) - WeakrefUsedInReloc.insert(SymA); + if (const MCSymbol *WeakRef = getWeakRef(*RefA)) + WeakrefUsedInReloc.insert(WeakRef); else UsedInReloc.insert(SymA); } @@ -913,13 +905,13 @@ void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, uint64_t ELFObjectWriter::getSymbolIndexInSymbolTable(const MCAssembler &Asm, const MCSymbol *S) { - MCSymbolData &SD = Asm.getSymbolData(*S); + const MCSymbolData &SD = Asm.getSymbolData(*S); return SD.getIndex(); } -bool ELFObjectWriter::isInSymtab(const MCAssembler &Asm, - const MCSymbolData &Data, - bool Used, bool Renamed) { +bool ELFObjectWriter::isInSymtab(const MCAsmLayout &Layout, + const MCSymbolData &Data, bool Used, + bool Renamed) { const MCSymbol &Symbol = Data.getSymbol(); if (Symbol.isVariable()) { const MCExpr *Expr = Symbol.getVariableValue(); @@ -938,9 +930,11 @@ bool ELFObjectWriter::isInSymtab(const MCAssembler &Asm, if (Symbol.getName() == "_GLOBAL_OFFSET_TABLE_") return true; - const MCSymbol &A = Symbol.AliasedSymbol(); - if (Symbol.isVariable() && !A.isVariable() && A.isUndefined()) - return false; + if (Symbol.isVariable()) { + const MCSymbol *Base = Layout.getBaseSymbol(Symbol); + if (Base && Base->isUndefined()) + return false; + } bool IsGlobal = MCELF::GetBinding(Data) == ELF::STB_GLOBAL; if (!Symbol.isVariable() && Symbol.isUndefined() && !IsGlobal) @@ -952,20 +946,16 @@ bool ELFObjectWriter::isInSymtab(const MCAssembler &Asm, return true; } -bool ELFObjectWriter::isLocal(const MCSymbolData &Data, bool isSignature, - bool isUsedInReloc) { +bool ELFObjectWriter::isLocal(const MCSymbolData &Data, bool isUsedInReloc) { if (Data.isExternal()) return false; const MCSymbol &Symbol = Data.getSymbol(); - const MCSymbol &RefSymbol = Symbol.AliasedSymbol(); - - if (RefSymbol.isUndefined() && !RefSymbol.isVariable()) { - if (isSignature && !isUsedInReloc) - return true; + if (Symbol.isDefined()) + return true; + if (isUsedInReloc) return false; - } return true; } @@ -1013,58 +1003,36 @@ ELFObjectWriter::computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout, MCELF::SetBinding(Data, ELF::STB_GLOBAL); } - // Index 0 is always the empty string. - StringMap<uint64_t> StringIndexMap; - StringTable += '\x00'; - - // FIXME: We could optimize suffixes in strtab in the same way we - // optimize them in shstrtab. - - for (MCAssembler::const_file_name_iterator it = Asm.file_names_begin(), - ie = Asm.file_names_end(); - it != ie; - ++it) { - StringRef Name = *it; - uint64_t &Entry = StringIndexMap[Name]; - if (!Entry) { - Entry = StringTable.size(); - StringTable += Name; - StringTable += '\x00'; - } - FileSymbolData.push_back(Entry); - } - // Add the data for the symbols. - for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), - ie = Asm.symbol_end(); it != ie; ++it) { - const MCSymbol &Symbol = it->getSymbol(); + for (MCSymbolData &SD : Asm.symbols()) { + const MCSymbol &Symbol = SD.getSymbol(); bool Used = UsedInReloc.count(&Symbol); bool WeakrefUsed = WeakrefUsedInReloc.count(&Symbol); bool isSignature = RevGroupMap.count(&Symbol); - if (!isInSymtab(Asm, *it, + if (!isInSymtab(Layout, SD, Used || WeakrefUsed || isSignature, Renames.count(&Symbol))) continue; ELFSymbolData MSD; - MSD.SymbolData = it; - const MCSymbol *BaseSymbol = getBaseSymbol(Layout, Symbol); + MSD.SymbolData = &SD; + const MCSymbol *BaseSymbol = Layout.getBaseSymbol(Symbol); // Undefined symbols are global, but this is the first place we // are able to set it. - bool Local = isLocal(*it, isSignature, Used); - if (!Local && MCELF::GetBinding(*it) == ELF::STB_LOCAL) { + bool Local = isLocal(SD, Used); + if (!Local && MCELF::GetBinding(SD) == ELF::STB_LOCAL) { assert(BaseSymbol); - MCSymbolData &SD = Asm.getSymbolData(*BaseSymbol); - MCELF::SetBinding(*it, ELF::STB_GLOBAL); + MCSymbolData &BaseData = Asm.getSymbolData(*BaseSymbol); MCELF::SetBinding(SD, ELF::STB_GLOBAL); + MCELF::SetBinding(BaseData, ELF::STB_GLOBAL); } if (!BaseSymbol) { MSD.SectionIndex = ELF::SHN_ABS; - } else if (it->isCommon()) { + } else if (SD.isCommon()) { assert(!Local); MSD.SectionIndex = ELF::SHN_COMMON; } else if (BaseSymbol->isUndefined()) { @@ -1073,7 +1041,7 @@ ELFObjectWriter::computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout, else MSD.SectionIndex = ELF::SHN_UNDEF; if (!Used && WeakrefUsed) - MCELF::SetBinding(*it, ELF::STB_WEAK); + MCELF::SetBinding(SD, ELF::STB_WEAK); } else { const MCSectionELF &Section = static_cast<const MCSectionELF&>(BaseSymbol->getSection()); @@ -1085,7 +1053,6 @@ ELFObjectWriter::computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout, // @@ in defined ones. StringRef Name = Symbol.getName(); SmallString<32> Buf; - size_t Pos = Name.find("@@@"); if (Pos != StringRef::npos) { Buf += Name.substr(0, Pos); @@ -1093,14 +1060,8 @@ ELFObjectWriter::computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout, Buf += Name.substr(Pos + Skip); Name = Buf; } + MSD.Name = StrTabBuilder.add(Name); - uint64_t &Entry = StringIndexMap[Name]; - if (!Entry) { - Entry = StringTable.size(); - StringTable += Name; - StringTable += '\x00'; - } - MSD.StringIndex = Entry; if (MSD.SectionIndex == ELF::SHN_UNDEF) UndefinedSymbolData.push_back(MSD); else if (Local) @@ -1109,6 +1070,21 @@ ELFObjectWriter::computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout, ExternalSymbolData.push_back(MSD); } + for (auto i = Asm.file_names_begin(), e = Asm.file_names_end(); i != e; ++i) + StrTabBuilder.add(*i); + + StrTabBuilder.finalize(); + + for (auto i = Asm.file_names_begin(), e = Asm.file_names_end(); i != e; ++i) + FileSymbolData.push_back(StrTabBuilder.getOffset(*i)); + + for (ELFSymbolData& MSD : LocalSymbolData) + MSD.StringIndex = StrTabBuilder.getOffset(MSD.Name); + for (ELFSymbolData& MSD : ExternalSymbolData) + MSD.StringIndex = StrTabBuilder.getOffset(MSD.Name); + for (ELFSymbolData& MSD : UndefinedSymbolData) + MSD.StringIndex = StrTabBuilder.getOffset(MSD.Name); + // Symbols are required to be in lexicographic order. array_pod_sort(LocalSymbolData.begin(), LocalSymbolData.end()); array_pod_sort(ExternalSymbolData.begin(), ExternalSymbolData.end()); @@ -1168,6 +1144,151 @@ void ELFObjectWriter::CreateRelocationSections(MCAssembler &Asm, } } +static SmallVector<char, 128> +getUncompressedData(MCAsmLayout &Layout, + MCSectionData::FragmentListType &Fragments) { + SmallVector<char, 128> UncompressedData; + for (const MCFragment &F : Fragments) { + const SmallVectorImpl<char> *Contents; + switch (F.getKind()) { + case MCFragment::FT_Data: + Contents = &cast<MCDataFragment>(F).getContents(); + break; + case MCFragment::FT_Dwarf: + Contents = &cast<MCDwarfLineAddrFragment>(F).getContents(); + break; + case MCFragment::FT_DwarfFrame: + Contents = &cast<MCDwarfCallFrameFragment>(F).getContents(); + break; + default: + llvm_unreachable( + "Not expecting any other fragment types in a debug_* section"); + } + UncompressedData.append(Contents->begin(), Contents->end()); + } + return UncompressedData; +} + +// Include the debug info compression header: +// "ZLIB" followed by 8 bytes representing the uncompressed size of the section, +// useful for consumers to preallocate a buffer to decompress into. +static bool +prependCompressionHeader(uint64_t Size, + SmallVectorImpl<char> &CompressedContents) { + static const StringRef Magic = "ZLIB"; + if (Size <= Magic.size() + sizeof(Size) + CompressedContents.size()) + return false; + if (sys::IsLittleEndianHost) + Size = sys::SwapByteOrder(Size); + CompressedContents.insert(CompressedContents.begin(), + Magic.size() + sizeof(Size), 0); + std::copy(Magic.begin(), Magic.end(), CompressedContents.begin()); + std::copy(reinterpret_cast<char *>(&Size), + reinterpret_cast<char *>(&Size + 1), + CompressedContents.begin() + Magic.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()); + + // Gather the uncompressed data from all the fragments, recording the + // alignment fragment, if seen, and any fixups. + SmallVector<char, 128> UncompressedData = + getUncompressedData(Layout, Fragments); + + SmallVectorImpl<char> &CompressedContents = CompressedFragment->getContents(); + + 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); + } +} + +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) + 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(), @@ -1274,23 +1395,6 @@ void ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm, } } -static int compareBySuffix(const MCSectionELF *const *a, - const MCSectionELF *const *b) { - const StringRef &NameA = (*a)->getSectionName(); - const StringRef &NameB = (*b)->getSectionName(); - const unsigned sizeA = NameA.size(); - const unsigned sizeB = NameB.size(); - const unsigned len = std::min(sizeA, sizeB); - for (unsigned int i = 0; i < len; ++i) { - char ca = NameA[sizeA - i - 1]; - char cb = NameB[sizeB - i - 1]; - if (ca != cb) - return cb - ca; - } - - return sizeB - sizeA; -} - void ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm, MCAsmLayout &Layout, SectionIndexMapTy &SectionIndexMap, @@ -1331,45 +1435,20 @@ void ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm, WriteSymbolTable(F, Asm, Layout, SectionIndexMap); F = new MCDataFragment(&StrtabSD); - F->getContents().append(StringTable.begin(), StringTable.end()); + F->getContents().append(StrTabBuilder.data().begin(), + StrTabBuilder.data().end()); F = new MCDataFragment(&ShstrtabSD); - std::vector<const MCSectionELF*> Sections; - for (MCAssembler::const_iterator it = Asm.begin(), - ie = Asm.end(); it != ie; ++it) { + // Section header string table. + for (auto it = Asm.begin(), ie = Asm.end(); it != ie; ++it) { const MCSectionELF &Section = static_cast<const MCSectionELF&>(it->getSection()); - Sections.push_back(&Section); - } - array_pod_sort(Sections.begin(), Sections.end(), compareBySuffix); - - // Section header string table. - // - // The first entry of a string table holds a null character so skip - // section 0. - uint64_t Index = 1; - F->getContents().push_back('\x00'); - - for (unsigned int I = 0, E = Sections.size(); I != E; ++I) { - const MCSectionELF &Section = *Sections[I]; - - StringRef Name = Section.getSectionName(); - if (I != 0) { - StringRef PreviousName = Sections[I - 1]->getSectionName(); - if (PreviousName.endswith(Name)) { - SectionStringTableIndex[&Section] = Index - Name.size() - 1; - continue; - } - } - // Remember the index into the string table so we can write it - // into the sh_name field of the section header table. - SectionStringTableIndex[&Section] = Index; - - Index += Name.size() + 1; - F->getContents().append(Name.begin(), Name.end()); - F->getContents().push_back('\x00'); + ShStrTabBuilder.add(Section.getSectionName()); } + ShStrTabBuilder.finalize(); + F->getContents().append(ShStrTabBuilder.data().begin(), + ShStrTabBuilder.data().end()); } void ELFObjectWriter::CreateIndexedSections(MCAssembler &Asm, @@ -1437,7 +1516,7 @@ void ELFObjectWriter::WriteSection(MCAssembler &Asm, switch(Section.getType()) { case ELF::SHT_DYNAMIC: - sh_link = SectionStringTableIndex[&Section]; + sh_link = ShStrTabBuilder.getOffset(Section.getSectionName()); sh_info = 0; break; @@ -1518,7 +1597,8 @@ void ELFObjectWriter::WriteSection(MCAssembler &Asm, } } - WriteSecHdrEntry(SectionStringTableIndex[&Section], Section.getType(), + WriteSecHdrEntry(ShStrTabBuilder.getOffset(Section.getSectionName()), + Section.getType(), Section.getFlags(), 0, Offset, Size, sh_link, sh_info, Alignment, Section.getEntrySize()); } @@ -1652,6 +1732,8 @@ void ELFObjectWriter::WriteObject(MCAssembler &Asm, unsigned NumUserSections = Asm.size(); + CompressDebugSections(Asm, const_cast<MCAsmLayout &>(Layout)); + DenseMap<const MCSectionELF*, const MCSectionELF*> RelMap; CreateRelocationSections(Asm, const_cast<MCAsmLayout&>(Layout), RelMap); diff --git a/lib/MC/MCAsmInfo.cpp b/lib/MC/MCAsmInfo.cpp index 9667145..c0777a6 100644 --- a/lib/MC/MCAsmInfo.cpp +++ b/lib/MC/MCAsmInfo.cpp @@ -61,8 +61,8 @@ MCAsmInfo::MCAsmInfo() { UsesELFSectionDirectiveForBSS = false; AlignmentIsInBytes = true; TextAlignFillValue = 0; - GPRel64Directive = 0; - GPRel32Directive = 0; + GPRel64Directive = nullptr; + GPRel32Directive = nullptr; GlobalDirective = "\t.globl\t"; HasSetDirective = true; HasAggressiveSymbolFolding = true; @@ -72,7 +72,7 @@ MCAsmInfo::MCAsmInfo() { HasSingleParameterDotFile = true; HasIdentDirective = false; HasNoDeadStrip = false; - WeakRefDirective = 0; + WeakRefDirective = nullptr; HasWeakDefDirective = false; HasWeakDefCanBeHiddenDirective = false; HasLinkOnceDirective = false; diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index 884ccf9..7f8ae54 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -9,6 +9,7 @@ #include "llvm/MC/MCStreamer.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Twine.h" #include "llvm/MC/MCAsmBackend.h" @@ -31,6 +32,7 @@ #include "llvm/Support/MathExtras.h" #include "llvm/Support/Path.h" #include <cctype> +#include <unordered_map> using namespace llvm; namespace { @@ -49,34 +51,24 @@ private: unsigned IsVerboseAsm : 1; unsigned ShowInst : 1; - unsigned UseCFI : 1; unsigned UseDwarfDirectory : 1; - enum EHSymbolFlags { EHGlobal = 1, - EHWeakDefinition = 1 << 1, - EHPrivateExtern = 1 << 2 }; - DenseMap<const MCSymbol*, unsigned> FlagMap; - - DenseMap<const MCSymbol*, MCSymbolData*> SymbolMap; - void EmitRegisterName(int64_t Register); void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override; void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override; public: MCAsmStreamer(MCContext &Context, formatted_raw_ostream &os, - bool isVerboseAsm, bool useCFI, bool useDwarfDirectory, + 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), UseCFI(useCFI), - UseDwarfDirectory(useDwarfDirectory) { + ShowInst(showInst), UseDwarfDirectory(useDwarfDirectory) { if (InstPrinter && IsVerboseAsm) InstPrinter->setCommentStream(CommentStream); } - ~MCAsmStreamer() {} inline void EmitEOL() { // If we don't have any comments, just emit a \n. @@ -130,7 +122,6 @@ public: void EmitLabel(MCSymbol *Symbol) override; void EmitDebugLabel(MCSymbol *Symbol) override; - void EmitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol) override; void EmitAssemblerFlag(MCAssemblerFlag Flag) override; void EmitLinkerOptions(ArrayRef<std::string> Options) override; void EmitDataRegion(MCDataRegionType Kind) override; @@ -140,12 +131,6 @@ public: void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override; void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override; - void EmitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel, - const MCSymbol *Label, - unsigned PointerSize) override; - void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, - const MCSymbol *Label) override; - bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override; void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override; @@ -167,7 +152,7 @@ public: void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) override; - void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, + void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = nullptr, uint64_t Size = 0, unsigned ByteAlignment = 0) override; void EmitTBSSSymbol (const MCSection *Section, MCSymbol *Symbol, @@ -175,7 +160,8 @@ public: void EmitBytes(StringRef Data) override; - void EmitValueImpl(const MCExpr *Value, unsigned Size) override; + void EmitValueImpl(const MCExpr *Value, unsigned Size, + const SMLoc &Loc = SMLoc()) override; void EmitIntValue(uint64_t Value, unsigned Size) override; void EmitULEB128Value(const MCExpr *Value) override; @@ -254,8 +240,6 @@ public: void EmitRawTextImpl(StringRef String) override; void FinishImpl() override; - - virtual MCSymbolData &getOrCreateSymbolData(const MCSymbol *Symbol) override; }; } // end anonymous namespace. @@ -321,21 +305,6 @@ void MCAsmStreamer::ChangeSection(const MCSection *Section, Section->PrintSwitchToSection(*MAI, OS, Subsection); } -void MCAsmStreamer::EmitEHSymAttributes(const MCSymbol *Symbol, - MCSymbol *EHSymbol) { - if (UseCFI) - return; - - unsigned Flags = FlagMap.lookup(Symbol); - - if (Flags & EHGlobal) - EmitSymbolAttribute(EHSymbol, MCSA_Global); - if (Flags & EHWeakDefinition) - EmitSymbolAttribute(EHSymbol, MCSA_WeakDefinition); - if (Flags & EHPrivateExtern) - EmitSymbolAttribute(EHSymbol, MCSA_PrivateExtern); -} - void MCAsmStreamer::EmitLabel(MCSymbol *Symbol) { assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); MCStreamer::EmitLabel(Symbol); @@ -441,22 +410,6 @@ void MCAsmStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) { EmitEOL(); } -void MCAsmStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta, - const MCSymbol *LastLabel, - const MCSymbol *Label, - unsigned PointerSize) { - EmitDwarfSetLineAddr(LineDelta, Label, PointerSize); -} - -void MCAsmStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, - const MCSymbol *Label) { - EmitIntValue(dwarf::DW_CFA_advance_loc4, 1); - const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel); - AddrDelta = ForceExpAbs(AddrDelta); - EmitValue(AddrDelta, 4); -} - - bool MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) { switch (Attribute) { @@ -486,7 +439,6 @@ bool MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol, return true; case MCSA_Global: // .globl/.global OS << MAI->getGlobalDirective(); - FlagMap[Symbol] |= EHGlobal; break; case MCSA_Hidden: OS << "\t.hidden\t"; break; case MCSA_IndirectSymbol: OS << "\t.indirect_symbol\t"; break; @@ -497,14 +449,12 @@ bool MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol, case MCSA_SymbolResolver: OS << "\t.symbol_resolver\t"; break; case MCSA_PrivateExtern: OS << "\t.private_extern\t"; - FlagMap[Symbol] |= EHPrivateExtern; break; case MCSA_Protected: OS << "\t.protected\t"; break; case MCSA_Reference: OS << "\t.reference\t"; break; case MCSA_Weak: OS << "\t.weak\t"; break; case MCSA_WeakDefinition: OS << "\t.weak_definition\t"; - FlagMap[Symbol] |= EHWeakDefinition; break; // .weak_reference case MCSA_WeakReference: OS << MAI->getWeakRefDirective(); break; @@ -560,7 +510,7 @@ void MCAsmStreamer::EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) { void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) { // Common symbols do not belong to any actual section. - AssignSection(Symbol, NULL); + AssignSection(Symbol, nullptr); OS << "\t.comm\t" << *Symbol << ',' << Size; if (ByteAlignment != 0) { @@ -579,7 +529,7 @@ void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlign) { // Common symbols do not belong to any actual section. - AssignSection(Symbol, NULL); + AssignSection(Symbol, nullptr); OS << "\t.lcomm\t" << *Symbol << ',' << Size; if (ByteAlign > 1) { @@ -610,7 +560,7 @@ void MCAsmStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol, const MCSectionMachO *MOSection = ((const MCSectionMachO*)Section); OS << MOSection->getSegmentName() << "," << MOSection->getSectionName(); - if (Symbol != NULL) { + if (Symbol) { OS << ',' << *Symbol << ',' << Size; if (ByteAlignment != 0) OS << ',' << Log2_32(ByteAlignment); @@ -625,7 +575,7 @@ void MCAsmStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) { AssignSection(Symbol, Section); - assert(Symbol != NULL && "Symbol shouldn't be NULL!"); + assert(Symbol && "Symbol shouldn't be NULL!"); // Instead of using the Section we'll just use the shortcut. // This is a mach-o specific directive and section. OS << ".tbss " << *Symbol << ", " << Size; @@ -702,11 +652,12 @@ void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size) { EmitValue(MCConstantExpr::Create(Value, getContext()), Size); } -void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size) { +void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, + const SMLoc &Loc) { assert(Size <= 8 && "Invalid size"); assert(getCurrentSection().first && "Cannot emit contents before setting section!"); - const char *Directive = 0; + const char *Directive = nullptr; switch (Size) { default: break; case 1: Directive = MAI->getData8bitsDirective(); break; @@ -775,13 +726,13 @@ void MCAsmStreamer::EmitSLEB128Value(const MCExpr *Value) { } void MCAsmStreamer::EmitGPRel64Value(const MCExpr *Value) { - assert(MAI->getGPRel64Directive() != 0); + assert(MAI->getGPRel64Directive() != nullptr); OS << MAI->getGPRel64Directive() << *Value; EmitEOL(); } void MCAsmStreamer::EmitGPRel32Value(const MCExpr *Value) { - assert(MAI->getGPRel32Directive() != 0); + assert(MAI->getGPRel32Directive() != nullptr); OS << MAI->getGPRel32Directive() << *Value; EmitEOL(); } @@ -973,10 +924,6 @@ void MCAsmStreamer::EmitIdent(StringRef IdentString) { void MCAsmStreamer::EmitCFISections(bool EH, bool Debug) { MCStreamer::EmitCFISections(EH, Debug); - - if (!UseCFI) - return; - OS << "\t.cfi_sections "; if (EH) { OS << ".eh_frame"; @@ -990,11 +937,6 @@ void MCAsmStreamer::EmitCFISections(bool EH, bool Debug) { } void MCAsmStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) { - if (!UseCFI) { - RecordProcStart(Frame); - return; - } - OS << "\t.cfi_startproc"; if (Frame.IsSimple) OS << " simple"; @@ -1002,11 +944,6 @@ void MCAsmStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) { } void MCAsmStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) { - if (!UseCFI) { - RecordProcEnd(Frame); - return; - } - // Put a dummy non-null value in Frame.End to mark that this frame has been // closed. Frame.End = (MCSymbol *) 1; @@ -1027,10 +964,6 @@ void MCAsmStreamer::EmitRegisterName(int64_t Register) { void MCAsmStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) { MCStreamer::EmitCFIDefCfa(Register, Offset); - - if (!UseCFI) - return; - OS << "\t.cfi_def_cfa "; EmitRegisterName(Register); OS << ", " << Offset; @@ -1039,20 +972,12 @@ void MCAsmStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) { void MCAsmStreamer::EmitCFIDefCfaOffset(int64_t Offset) { MCStreamer::EmitCFIDefCfaOffset(Offset); - - if (!UseCFI) - return; - OS << "\t.cfi_def_cfa_offset " << Offset; EmitEOL(); } void MCAsmStreamer::EmitCFIDefCfaRegister(int64_t Register) { MCStreamer::EmitCFIDefCfaRegister(Register); - - if (!UseCFI) - return; - OS << "\t.cfi_def_cfa_register "; EmitRegisterName(Register); EmitEOL(); @@ -1060,10 +985,6 @@ void MCAsmStreamer::EmitCFIDefCfaRegister(int64_t Register) { void MCAsmStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) { this->MCStreamer::EmitCFIOffset(Register, Offset); - - if (!UseCFI) - return; - OS << "\t.cfi_offset "; EmitRegisterName(Register); OS << ", " << Offset; @@ -1073,50 +994,30 @@ void MCAsmStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) { void MCAsmStreamer::EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding) { MCStreamer::EmitCFIPersonality(Sym, Encoding); - - if (!UseCFI) - return; - OS << "\t.cfi_personality " << Encoding << ", " << *Sym; EmitEOL(); } void MCAsmStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) { MCStreamer::EmitCFILsda(Sym, Encoding); - - if (!UseCFI) - return; - OS << "\t.cfi_lsda " << Encoding << ", " << *Sym; EmitEOL(); } void MCAsmStreamer::EmitCFIRememberState() { MCStreamer::EmitCFIRememberState(); - - if (!UseCFI) - return; - OS << "\t.cfi_remember_state"; EmitEOL(); } void MCAsmStreamer::EmitCFIRestoreState() { MCStreamer::EmitCFIRestoreState(); - - if (!UseCFI) - return; - OS << "\t.cfi_restore_state"; EmitEOL(); } void MCAsmStreamer::EmitCFISameValue(int64_t Register) { MCStreamer::EmitCFISameValue(Register); - - if (!UseCFI) - return; - OS << "\t.cfi_same_value "; EmitRegisterName(Register); EmitEOL(); @@ -1124,10 +1025,6 @@ void MCAsmStreamer::EmitCFISameValue(int64_t Register) { void MCAsmStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) { MCStreamer::EmitCFIRelOffset(Register, Offset); - - if (!UseCFI) - return; - OS << "\t.cfi_rel_offset "; EmitRegisterName(Register); OS << ", " << Offset; @@ -1136,50 +1033,30 @@ void MCAsmStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) { void MCAsmStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) { MCStreamer::EmitCFIAdjustCfaOffset(Adjustment); - - if (!UseCFI) - return; - OS << "\t.cfi_adjust_cfa_offset " << Adjustment; EmitEOL(); } void MCAsmStreamer::EmitCFISignalFrame() { MCStreamer::EmitCFISignalFrame(); - - if (!UseCFI) - return; - OS << "\t.cfi_signal_frame"; EmitEOL(); } void MCAsmStreamer::EmitCFIUndefined(int64_t Register) { MCStreamer::EmitCFIUndefined(Register); - - if (!UseCFI) - return; - OS << "\t.cfi_undefined " << Register; EmitEOL(); } void MCAsmStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) { MCStreamer::EmitCFIRegister(Register1, Register2); - - if (!UseCFI) - return; - OS << "\t.cfi_register " << Register1 << ", " << Register2; EmitEOL(); } void MCAsmStreamer::EmitCFIWindowSave() { MCStreamer::EmitCFIWindowSave(); - - if (!UseCFI) - return; - OS << "\t.cfi_window_save"; EmitEOL(); } @@ -1257,14 +1134,17 @@ void MCAsmStreamer::EmitWin64EHHandlerData() { void MCAsmStreamer::EmitWin64EHPushReg(unsigned Register) { MCStreamer::EmitWin64EHPushReg(Register); - OS << "\t.seh_pushreg " << Register; + OS << "\t.seh_pushreg "; + EmitRegisterName(Register); EmitEOL(); } void MCAsmStreamer::EmitWin64EHSetFrame(unsigned Register, unsigned Offset) { MCStreamer::EmitWin64EHSetFrame(Register, Offset); - OS << "\t.seh_setframe " << Register << ", " << Offset; + OS << "\t.seh_setframe "; + EmitRegisterName(Register); + OS << ", " << Offset; EmitEOL(); } @@ -1278,14 +1158,18 @@ void MCAsmStreamer::EmitWin64EHAllocStack(unsigned Size) { void MCAsmStreamer::EmitWin64EHSaveReg(unsigned Register, unsigned Offset) { MCStreamer::EmitWin64EHSaveReg(Register, Offset); - OS << "\t.seh_savereg " << Register << ", " << Offset; + OS << "\t.seh_savereg "; + EmitRegisterName(Register); + OS << ", " << Offset; EmitEOL(); } void MCAsmStreamer::EmitWin64EHSaveXMM(unsigned Register, unsigned Offset) { MCStreamer::EmitWin64EHSaveXMM(Register, Offset); - OS << "\t.seh_savexmm " << Register << ", " << Offset; + OS << "\t.seh_savexmm "; + EmitRegisterName(Register); + OS << ", " << Offset; EmitEOL(); } @@ -1455,26 +1339,13 @@ void MCAsmStreamer::FinishImpl() { EmitLabel(Label); } } - - if (!UseCFI) - EmitFrames(AsmBackend.get(), false); -} - -MCSymbolData &MCAsmStreamer::getOrCreateSymbolData(const MCSymbol *Symbol) { - MCSymbolData *&Entry = SymbolMap[Symbol]; - - if (!Entry) - Entry = new MCSymbolData(*Symbol, 0, 0, 0); - - return *Entry; } MCStreamer *llvm::createAsmStreamer(MCContext &Context, formatted_raw_ostream &OS, - bool isVerboseAsm, bool useCFI, - bool useDwarfDirectory, MCInstPrinter *IP, - MCCodeEmitter *CE, MCAsmBackend *MAB, - bool ShowInst) { - return new MCAsmStreamer(Context, OS, isVerboseAsm, useCFI, useDwarfDirectory, - IP, CE, MAB, ShowInst); + bool isVerboseAsm, bool useDwarfDirectory, + MCInstPrinter *IP, MCCodeEmitter *CE, + MCAsmBackend *MAB, bool ShowInst) { + return new MCAsmStreamer(Context, OS, isVerboseAsm, useDwarfDirectory, IP, CE, + MAB, ShowInst); } diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp index 724ca29..886a5f5 100644 --- a/lib/MC/MCAssembler.cpp +++ b/lib/MC/MCAssembler.cpp @@ -7,7 +7,6 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "assembler" #include "llvm/MC/MCAssembler.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringExtras.h" @@ -28,12 +27,11 @@ #include "llvm/Support/LEB128.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/Compression.h" -#include "llvm/Support/Host.h" - +#include <tuple> using namespace llvm; +#define DEBUG_TYPE "assembler" + namespace { namespace stats { STATISTIC(EmittedFragments, "Number of emitted assembler fragments - total"); @@ -119,36 +117,89 @@ uint64_t MCAsmLayout::getFragmentOffset(const MCFragment *F) const { return F->Offset; } -uint64_t MCAsmLayout::getSymbolOffset(const MCSymbolData *SD) const { +// Simple getSymbolOffset helper for the non-varibale case. +static bool getLabelOffset(const MCAsmLayout &Layout, const MCSymbolData &SD, + bool ReportError, uint64_t &Val) { + if (!SD.getFragment()) { + if (ReportError) + report_fatal_error("unable to evaluate offset to undefined symbol '" + + SD.getSymbol().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(); - // If this is a variable, then recursively evaluate now. - if (S.isVariable()) { - MCValue Target; - if (!S.getVariableValue()->EvaluateAsRelocatable(Target, this)) - report_fatal_error("unable to evaluate offset for variable '" + - S.getName() + "'"); + if (!S.isVariable()) + return getLabelOffset(Layout, *SD, ReportError, Val); - // Verify that any used symbols are defined. - if (Target.getSymA() && Target.getSymA()->getSymbol().isUndefined()) - report_fatal_error("unable to evaluate offset to undefined symbol '" + - Target.getSymA()->getSymbol().getName() + "'"); - if (Target.getSymB() && Target.getSymB()->getSymbol().isUndefined()) - report_fatal_error("unable to evaluate offset to undefined symbol '" + - Target.getSymB()->getSymbol().getName() + "'"); - - uint64_t Offset = Target.getConstant(); - if (Target.getSymA()) - Offset += getSymbolOffset(&Assembler.getSymbolData( - Target.getSymA()->getSymbol())); - if (Target.getSymB()) - Offset -= getSymbolOffset(&Assembler.getSymbolData( - Target.getSymB()->getSymbol())); - return Offset; + // If SD is a variable, evaluate it. + MCValue Target; + if (!S.getVariableValue()->EvaluateAsValue(Target, &Layout)) + 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)) + return false; + Offset += ValA; } - assert(SD->getFragment() && "Invalid getOffset() on undefined symbol!"); - return getFragmentOffset(SD->getFragment()) + SD->getOffset(); + const MCSymbolRefExpr *B = Target.getSymB(); + if (B) { + uint64_t ValB; + if (!getLabelOffset(Layout, Asm.getSymbolData(B->getSymbol()), ReportError, + ValB)) + return false; + Offset -= ValB; + } + + Val = Offset; + return true; +} + +bool MCAsmLayout::getSymbolOffset(const MCSymbolData *SD, uint64_t &Val) const { + return getSymbolOffsetImpl(*this, SD, false, Val); +} + +uint64_t MCAsmLayout::getSymbolOffset(const MCSymbolData *SD) const { + uint64_t Val; + getSymbolOffsetImpl(*this, SD, true, Val); + return Val; +} + +const MCSymbol *MCAsmLayout::getBaseSymbol(const MCSymbol &Symbol) const { + if (!Symbol.isVariable()) + return &Symbol; + + const MCExpr *Expr = Symbol.getVariableValue(); + MCValue Value; + if (!Expr->EvaluateAsValue(Value, this)) + llvm_unreachable("Invalid Expression"); + + const MCSymbolRefExpr *RefB = Value.getSymB(); + if (RefB) + Assembler.getContext().FatalError( + SMLoc(), Twine("symbol '") + RefB->getSymbol().getName() + + "' could not be evaluated in a subtraction expression"); + + const MCSymbolRefExpr *A = Value.getSymA(); + if (!A) + return nullptr; + + return &A->getSymbol(); } uint64_t MCAsmLayout::getSectionAddressSize(const MCSectionData *SD) const { @@ -215,7 +266,7 @@ MCFragment::~MCFragment() { } MCFragment::MCFragment(FragmentType _Kind, MCSectionData *_Parent) - : Kind(_Kind), Parent(_Parent), Atom(0), Offset(~UINT64_C(0)) + : Kind(_Kind), Parent(_Parent), Atom(nullptr), Offset(~UINT64_C(0)) { if (Parent) Parent->getFragmentList().push_back(this); @@ -233,40 +284,7 @@ MCEncodedFragmentWithFixups::~MCEncodedFragmentWithFixups() { /* *** */ -const SmallVectorImpl<char> &MCCompressedFragment::getCompressedContents() const { - assert(getParent()->size() == 1 && - "Only compress sections containing a single fragment"); - if (CompressedContents.empty()) { - std::unique_ptr<MemoryBuffer> CompressedSection; - zlib::Status Success = - zlib::compress(StringRef(getContents().data(), getContents().size()), - CompressedSection); - (void)Success; - assert(Success == zlib::StatusOK); - CompressedContents.push_back('Z'); - CompressedContents.push_back('L'); - CompressedContents.push_back('I'); - CompressedContents.push_back('B'); - uint64_t Size = getContents().size(); - if (sys::IsLittleEndianHost) - Size = sys::SwapByteOrder(Size); - CompressedContents.append(reinterpret_cast<char *>(&Size), - reinterpret_cast<char *>(&Size + 1)); - CompressedContents.append(CompressedSection->getBuffer().begin(), - CompressedSection->getBuffer().end()); - } - return CompressedContents; -} - -SmallVectorImpl<char> &MCCompressedFragment::getContents() { - assert(CompressedContents.empty() && - "Fragment contents should not be altered after compression"); - return MCDataFragment::getContents(); -} - -/* *** */ - -MCSectionData::MCSectionData() : Section(0) {} +MCSectionData::MCSectionData() : Section(nullptr) {} MCSectionData::MCSectionData(const MCSection &_Section, MCAssembler *A) : Section(&_Section), @@ -286,7 +304,7 @@ MCSectionData::getSubsectionInsertionPoint(unsigned Subsection) { SmallVectorImpl<std::pair<unsigned, MCFragment *> >::iterator MI = std::lower_bound(SubsectionFragmentMap.begin(), SubsectionFragmentMap.end(), - std::make_pair(Subsection, (MCFragment *)0)); + std::make_pair(Subsection, (MCFragment *)nullptr)); bool ExactMatch = false; if (MI != SubsectionFragmentMap.end()) { ExactMatch = MI->first == Subsection; @@ -311,13 +329,13 @@ MCSectionData::getSubsectionInsertionPoint(unsigned Subsection) { /* *** */ -MCSymbolData::MCSymbolData() : Symbol(0) {} +MCSymbolData::MCSymbolData() : Symbol(nullptr) {} MCSymbolData::MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment, uint64_t _Offset, MCAssembler *A) : Symbol(&_Symbol), Fragment(_Fragment), Offset(_Offset), IsExternal(false), IsPrivateExtern(false), - CommonSize(0), SymbolSize(0), CommonAlign(0), + CommonSize(0), SymbolSize(nullptr), CommonAlign(0), Flags(0), Index(0) { if (A) @@ -358,6 +376,31 @@ void MCAssembler::reset() { getLOHContainer().reset(); } +bool MCAssembler::isThumbFunc(const MCSymbol *Symbol) const { + if (ThumbFuncs.count(Symbol)) + return true; + + if (!Symbol->isVariable()) + return false; + + // FIXME: It looks like gas supports some cases of the form "foo + 2". It + // is not clear if that is a bug or a feature. + const MCExpr *Expr = Symbol->getVariableValue(); + const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(Expr); + if (!Ref) + return false; + + if (Ref->getKind() != MCSymbolRefExpr::VK_None) + return false; + + const MCSymbol &Sym = Ref->getSymbol(); + if (!isThumbFunc(&Sym)) + return false; + + ThumbFuncs.insert(Symbol); // Cache it. + return true; +} + bool MCAssembler::isSymbolLinkerVisible(const MCSymbol &Symbol) const { // Non-temporary labels should always be visible to the linker. if (!Symbol.isTemporary()) @@ -378,13 +421,13 @@ const MCSymbolData *MCAssembler::getAtom(const MCSymbolData *SD) const { // Absolute and undefined symbols have no defining atom. if (!SD->getFragment()) - return 0; + return nullptr; // Non-linker visible symbols in sections which can't be atomized have no // defining atom. if (!getBackend().isSectionAtomizable( SD->getFragment()->getParent()->getSection())) - return 0; + return nullptr; // Otherwise, return the atom for the containing fragment. return SD->getFragment()->getAtom(); @@ -467,8 +510,6 @@ uint64_t MCAssembler::computeFragmentSize(const MCAsmLayout &Layout, case MCFragment::FT_Relaxable: case MCFragment::FT_CompactEncodedInst: return cast<MCEncodedFragment>(F).getContents().size(); - case MCFragment::FT_Compressed: - return cast<MCCompressedFragment>(F).getCompressedContents().size(); case MCFragment::FT_Fill: return cast<MCFillFragment>(F).getSize(); @@ -657,11 +698,6 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout, break; } - case MCFragment::FT_Compressed: - ++stats::EmittedDataFragments; - OW->WriteBytes(cast<MCCompressedFragment>(F).getCompressedContents()); - break; - case MCFragment::FT_Data: ++stats::EmittedDataFragments; writeFragmentContents(F, OW); @@ -738,7 +774,6 @@ void MCAssembler::writeSectionData(const MCSectionData *SD, ie = SD->end(); it != ie; ++it) { switch (it->getKind()) { default: llvm_unreachable("Invalid fragment in virtual section!"); - case MCFragment::FT_Compressed: case MCFragment::FT_Data: { // Check that we aren't trying to write a non-zero contents (or fixups) // into a virtual section. This is to support clients which use standard @@ -992,7 +1027,7 @@ bool MCAssembler::layoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD) { // remain NULL if none were relaxed. // When a fragment is relaxed, all the fragments following it should get // invalidated because their offset is going to change. - MCFragment *FirstRelaxedFragment = NULL; + MCFragment *FirstRelaxedFragment = nullptr; // Attempt to relax all the fragments in the section. for (MCSectionData::iterator I = SD.begin(), IE = SD.end(); I != IE; ++I) { @@ -1070,8 +1105,6 @@ void MCFragment::dump() { switch (getKind()) { case MCFragment::FT_Align: OS << "MCAlignFragment"; break; case MCFragment::FT_Data: OS << "MCDataFragment"; break; - case MCFragment::FT_Compressed: - OS << "MCCompressedFragment"; break; case MCFragment::FT_CompactEncodedInst: OS << "MCCompactEncodedInstFragment"; break; case MCFragment::FT_Fill: OS << "MCFillFragment"; break; @@ -1098,7 +1131,6 @@ void MCFragment::dump() { << " MaxBytesToEmit:" << AF->getMaxBytesToEmit() << ">"; break; } - case MCFragment::FT_Compressed: case MCFragment::FT_Data: { const MCDataFragment *DF = cast<MCDataFragment>(this); OS << "\n "; diff --git a/lib/MC/MCContext.cpp b/lib/MC/MCContext.cpp index 73ffdc0..c163268 100644 --- a/lib/MC/MCContext.cpp +++ b/lib/MC/MCContext.cpp @@ -29,19 +29,13 @@ using namespace llvm; -typedef std::pair<std::string, std::string> SectionGroupPair; - -typedef StringMap<const MCSectionMachO*> MachOUniqueMapTy; -typedef std::map<SectionGroupPair, const MCSectionELF *> ELFUniqueMapTy; -typedef std::map<SectionGroupPair, const MCSectionCOFF *> COFFUniqueMapTy; - 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), CurrentDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0), DwarfLocSeen(false), - GenDwarfForAssembly(false), GenDwarfFileNumber(0), + GenDwarfForAssembly(false), GenDwarfFileNumber(0), DwarfVersion(4), AllowTemporaryLabels(true), DwarfCompileUnitID(0), AutoReset(DoAutoReset) { @@ -49,12 +43,8 @@ MCContext::MCContext(const MCAsmInfo *mai, const MCRegisterInfo *mri, if (EC) CompilationDir.clear(); - MachOUniquingMap = 0; - ELFUniquingMap = 0; - COFFUniquingMap = 0; - SecureLogFile = getenv("AS_SECURE_LOG_FILE"); - SecureLog = 0; + SecureLog = nullptr; SecureLogUsed = false; if (SrcMgr && SrcMgr->getNumBuffers() > 0) @@ -88,13 +78,9 @@ void MCContext::reset() { DwarfCompileUnitID = 0; CurrentDwarfLoc = MCDwarfLoc(0,0,0,DWARF2_FLAG_IS_STMT,0,0); - // If we have the MachO uniquing map, free it. - delete (MachOUniqueMapTy*)MachOUniquingMap; - delete (ELFUniqueMapTy*)ELFUniquingMap; - delete (COFFUniqueMapTy*)COFFUniquingMap; - MachOUniquingMap = 0; - ELFUniquingMap = 0; - COFFUniquingMap = 0; + MachOUniquingMap.clear(); + ELFUniquingMap.clear(); + COFFUniquingMap.clear(); NextUniqueID = 0; AllowTemporaryLabels = true; @@ -225,11 +211,6 @@ getMachOSection(StringRef Segment, StringRef Section, // may not have the same flags as the requested section, if so this should be // diagnosed by the client as an error. - // Create the map if it doesn't already exist. - if (MachOUniquingMap == 0) - MachOUniquingMap = new MachOUniqueMapTy(); - MachOUniqueMapTy &Map = *(MachOUniqueMapTy*)MachOUniquingMap; - // Form the name to look up. SmallString<64> Name; Name += Segment; @@ -237,7 +218,7 @@ getMachOSection(StringRef Segment, StringRef Section, Name += Section; // Do the lookup, if we have a hit, return it. - const MCSectionMachO *&Entry = Map[Name.str()]; + const MCSectionMachO *&Entry = MachOUniquingMap[Name.str()]; if (Entry) return Entry; // Otherwise, return a new section. @@ -251,42 +232,48 @@ getELFSection(StringRef Section, unsigned Type, unsigned Flags, return getELFSection(Section, Type, Flags, Kind, 0, ""); } +void MCContext::renameELFSection(const 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); +} + const MCSectionELF *MCContext:: getELFSection(StringRef Section, unsigned Type, unsigned Flags, SectionKind Kind, unsigned EntrySize, StringRef Group) { - if (ELFUniquingMap == 0) - ELFUniquingMap = new ELFUniqueMapTy(); - ELFUniqueMapTy &Map = *(ELFUniqueMapTy*)ELFUniquingMap; - - SmallString<32> ZDebugName; - if (MAI->compressDebugSections() && Section.startswith(".debug_") && - Section != ".debug_frame" && Section != ".debug_line") - Section = (".z" + Section.drop_front(1)).toStringRef(ZDebugName); - // Do the lookup, if we have a hit, return it. - std::pair<ELFUniqueMapTy::iterator, bool> Entry = Map.insert( - std::make_pair(SectionGroupPair(Section, Group), (MCSectionELF *)0)); - if (!Entry.second) return Entry.first->second; + auto IterBool = ELFUniquingMap.insert( + std::make_pair(SectionGroupPair(Section, Group), nullptr)); + auto &Entry = *IterBool.first; + if (!IterBool.second) return Entry.second; // Possibly refine the entry size first. if (!EntrySize) { EntrySize = MCSectionELF::DetermineEntrySize(Kind); } - MCSymbol *GroupSym = NULL; + MCSymbol *GroupSym = nullptr; if (!Group.empty()) GroupSym = GetOrCreateSymbol(Group); - MCSectionELF *Result = new (*this) MCSectionELF( - Entry.first->first.first, Type, Flags, Kind, EntrySize, GroupSym); - Entry.first->second = Result; + StringRef CachedName = Entry.first.first; + MCSectionELF *Result = new (*this) + MCSectionELF(CachedName, Type, Flags, Kind, EntrySize, GroupSym); + Entry.second = Result; return Result; } const MCSectionELF *MCContext::CreateELFGroupSection() { MCSectionELF *Result = new (*this) MCSectionELF(".group", ELF::SHT_GROUP, 0, - SectionKind::getReadOnly(), 4, NULL); + SectionKind::getReadOnly(), 4, nullptr); return Result; } @@ -294,26 +281,21 @@ const MCSectionCOFF * MCContext::getCOFFSection(StringRef Section, unsigned Characteristics, SectionKind Kind, StringRef COMDATSymName, int Selection, const MCSectionCOFF *Assoc) { - if (COFFUniquingMap == 0) - COFFUniquingMap = new COFFUniqueMapTy(); - COFFUniqueMapTy &Map = *(COFFUniqueMapTy*)COFFUniquingMap; - // Do the lookup, if we have a hit, return it. SectionGroupPair P(Section, COMDATSymName); - std::pair<COFFUniqueMapTy::iterator, bool> Entry = - Map.insert(std::make_pair(P, (MCSectionCOFF *)0)); - COFFUniqueMapTy::iterator Iter = Entry.first; - if (!Entry.second) + auto IterBool = COFFUniquingMap.insert(std::make_pair(P, nullptr)); + auto Iter = IterBool.first; + if (!IterBool.second) return Iter->second; - const MCSymbol *COMDATSymbol = NULL; + const MCSymbol *COMDATSymbol = nullptr; if (!COMDATSymName.empty()) COMDATSymbol = GetOrCreateSymbol(COMDATSymName); - MCSectionCOFF *Result = - new (*this) MCSectionCOFF(Iter->first.first, Characteristics, - COMDATSymbol, Selection, Assoc, Kind); + StringRef CachedName = Iter->first.first; + MCSectionCOFF *Result = new (*this) MCSectionCOFF( + CachedName, Characteristics, COMDATSymbol, Selection, Assoc, Kind); Iter->second = Result; return Result; @@ -326,14 +308,10 @@ MCContext::getCOFFSection(StringRef Section, unsigned Characteristics, } const MCSectionCOFF *MCContext::getCOFFSection(StringRef Section) { - if (COFFUniquingMap == 0) - COFFUniquingMap = new COFFUniqueMapTy(); - COFFUniqueMapTy &Map = *(COFFUniqueMapTy*)COFFUniquingMap; - SectionGroupPair P(Section, ""); - COFFUniqueMapTy::iterator Iter = Map.find(P); - if (Iter == Map.end()) - return 0; + auto Iter = COFFUniquingMap.find(P); + if (Iter == COFFUniquingMap.end()) + return nullptr; return Iter->second; } @@ -361,7 +339,7 @@ bool MCContext::isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID) { return !MCDwarfFiles[FileNumber].Name.empty(); } -void MCContext::FatalError(SMLoc Loc, const Twine &Msg) { +void MCContext::FatalError(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/lib/MC/MCDisassembler.cpp b/lib/MC/MCDisassembler.cpp index 7a2b1a1..77d9ce1 100644 --- a/lib/MC/MCDisassembler.cpp +++ b/lib/MC/MCDisassembler.cpp @@ -16,20 +16,6 @@ using namespace llvm; MCDisassembler::~MCDisassembler() { } -void MCDisassembler::setupForSymbolicDisassembly( - LLVMOpInfoCallback GetOpInfo, LLVMSymbolLookupCallback SymbolLookUp, - void *DisInfo, MCContext *Ctx, std::unique_ptr<MCRelocationInfo> &RelInfo) { - this->GetOpInfo = GetOpInfo; - this->SymbolLookUp = SymbolLookUp; - this->DisInfo = DisInfo; - this->Ctx = Ctx; - assert(Ctx != 0 && "No MCContext given for symbolic disassembly"); - if (!Symbolizer) - Symbolizer.reset(new MCExternalSymbolizer(*Ctx, std::move(RelInfo), - GetOpInfo, SymbolLookUp, - DisInfo)); -} - bool MCDisassembler::tryAddingSymbolicOperand(MCInst &Inst, int64_t Value, uint64_t Address, bool IsBranch, uint64_t Offset, diff --git a/lib/MC/MCDisassembler/Disassembler.cpp b/lib/MC/MCDisassembler/Disassembler.cpp index b935b83..0530c26 100644 --- a/lib/MC/MCDisassembler/Disassembler.cpp +++ b/lib/MC/MCDisassembler/Disassembler.cpp @@ -41,20 +41,20 @@ LLVMDisasmContextRef LLVMCreateDisasmCPU(const char *Triple, const char *CPU, std::string Error; const Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error); if (!TheTarget) - return 0; + return nullptr; const MCRegisterInfo *MRI = TheTarget->createMCRegInfo(Triple); if (!MRI) - return 0; + return nullptr; // Get the assembler info needed to setup the MCContext. const MCAsmInfo *MAI = TheTarget->createMCAsmInfo(*MRI, Triple); if (!MAI) - return 0; + return nullptr; const MCInstrInfo *MII = TheTarget->createMCInstrInfo(); if (!MII) - return 0; + return nullptr; // Package up features to be passed to target/subtarget std::string FeaturesStr; @@ -62,41 +62,40 @@ LLVMDisasmContextRef LLVMCreateDisasmCPU(const char *Triple, const char *CPU, const MCSubtargetInfo *STI = TheTarget->createMCSubtargetInfo(Triple, CPU, FeaturesStr); if (!STI) - return 0; + return nullptr; // Set up the MCContext for creating symbols and MCExpr's. - MCContext *Ctx = new MCContext(MAI, MRI, 0); + MCContext *Ctx = new MCContext(MAI, MRI, nullptr); if (!Ctx) - return 0; + return nullptr; // Set up disassembler. - MCDisassembler *DisAsm = TheTarget->createMCDisassembler(*STI); + MCDisassembler *DisAsm = TheTarget->createMCDisassembler(*STI, *Ctx); if (!DisAsm) - return 0; + return nullptr; std::unique_ptr<MCRelocationInfo> RelInfo( TheTarget->createMCRelocationInfo(Triple, *Ctx)); if (!RelInfo) - return 0; + return nullptr; std::unique_ptr<MCSymbolizer> Symbolizer(TheTarget->createMCSymbolizer( Triple, GetOpInfo, SymbolLookUp, DisInfo, Ctx, RelInfo.release())); DisAsm->setSymbolizer(std::move(Symbolizer)); - DisAsm->setupForSymbolicDisassembly(GetOpInfo, SymbolLookUp, DisInfo, - Ctx, RelInfo); + // Set up the instruction printer. int AsmPrinterVariant = MAI->getAssemblerDialect(); MCInstPrinter *IP = TheTarget->createMCInstPrinter(AsmPrinterVariant, *MAI, *MII, *MRI, *STI); if (!IP) - return 0; + return nullptr; LLVMDisasmContext *DC = new LLVMDisasmContext(Triple, DisInfo, TagType, GetOpInfo, SymbolLookUp, TheTarget, MAI, MRI, STI, MII, Ctx, DisAsm, IP); if (!DC) - return 0; + return nullptr; DC->setCPU(CPU); return DC; diff --git a/lib/MC/MCDwarf.cpp b/lib/MC/MCDwarf.cpp index 72836ff..be6731a 100644 --- a/lib/MC/MCDwarf.cpp +++ b/lib/MC/MCDwarf.cpp @@ -9,6 +9,7 @@ #include "llvm/MC/MCDwarf.h" #include "llvm/ADT/Hashing.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/Twine.h" #include "llvm/Config/config.h" @@ -16,8 +17,8 @@ #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCObjectFileInfo.h" +#include "llvm/MC/MCObjectStreamer.h" #include "llvm/MC/MCRegisterInfo.h" -#include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" @@ -62,7 +63,7 @@ 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(MCStreamer *MCOS, const MCSection *Section) { +void MCLineEntry::Make(MCObjectStreamer *MCOS, const MCSection *Section) { if (!MCOS->getContext().getDwarfLocSeen()) return; @@ -113,7 +114,7 @@ static inline const MCExpr *MakeStartMinusEndExpr(const MCStreamer &MCOS, // in the LineSection. // static inline void -EmitDwarfLineTable(MCStreamer *MCOS, const MCSection *Section, +EmitDwarfLineTable(MCObjectStreamer *MCOS, const MCSection *Section, const MCLineSection::MCLineEntryCollection &LineEntries) { unsigned FileNum = 1; unsigned LastLine = 1; @@ -121,7 +122,7 @@ EmitDwarfLineTable(MCStreamer *MCOS, const MCSection *Section, unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; unsigned Isa = 0; unsigned Discriminator = 0; - MCSymbol *LastLabel = NULL; + MCSymbol *LastLabel = nullptr; // Loop through each MCLineEntry and encode the dwarf line number table. for (auto it = LineEntries.begin(), @@ -204,7 +205,7 @@ EmitDwarfLineTable(MCStreamer *MCOS, const MCSection *Section, // // This emits the Dwarf file and the line tables. // -void MCDwarfLineTable::Emit(MCStreamer *MCOS) { +void MCDwarfLineTable::Emit(MCObjectStreamer *MCOS) { MCContext &context = MCOS->getContext(); auto &LineTables = context.getMCDwarfLineTables(); @@ -318,7 +319,7 @@ MCDwarfLineTableHeader::Emit(MCStreamer *MCOS, return std::make_pair(LineStartSym, LineEndSym); } -void MCDwarfLineTable::EmitCU(MCStreamer *MCOS) const { +void MCDwarfLineTable::EmitCU(MCObjectStreamer *MCOS) const { MCSymbol *LineEndSym = Header.Emit(MCOS).second; // Put out the line tables. @@ -644,8 +645,8 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS, const MCExpr *Length = MakeStartMinusEndExpr(*MCOS, *InfoStart, *InfoEnd, 4); MCOS->EmitAbsValue(Length, 4); - // The 2 byte DWARF version, which is 2. - MCOS->EmitIntValue(2, 2); + // The 2 byte DWARF version. + MCOS->EmitIntValue(context.getDwarfVersion(), 2); // The 4 byte offset to the debug abbrevs from the start of the .debug_abbrev, // it is at the start of that section so this is zero. @@ -688,7 +689,7 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS, const SmallVectorImpl<std::string> &MCDwarfDirs = context.getMCDwarfDirs(); if (MCDwarfDirs.size() > 0) { MCOS->EmitBytes(MCDwarfDirs[0]); - MCOS->EmitBytes("/"); + MCOS->EmitBytes(sys::path::get_separator()); } const SmallVectorImpl<MCDwarfFile> &MCDwarfFiles = MCOS->getContext().getMCDwarfFiles(); @@ -727,28 +728,24 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS, // Third part: the list of label DIEs. // Loop on saved info for dwarf labels and create the DIEs for them. - const std::vector<const MCGenDwarfLabelEntry *> &Entries = - MCOS->getContext().getMCGenDwarfLabelEntries(); - for (std::vector<const MCGenDwarfLabelEntry *>::const_iterator it = - Entries.begin(), ie = Entries.end(); it != ie; - ++it) { - const MCGenDwarfLabelEntry *Entry = *it; - + const std::vector<MCGenDwarfLabelEntry> &Entries = + MCOS->getContext().getMCGenDwarfLabelEntries(); + for (const auto &Entry : Entries) { // The DW_TAG_label DIE abbrev (2). MCOS->EmitULEB128IntValue(2); // AT_name, of the label without any leading underbar. - MCOS->EmitBytes(Entry->getName()); + MCOS->EmitBytes(Entry.getName()); MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string. // AT_decl_file, index into the file table. - MCOS->EmitIntValue(Entry->getFileNumber(), 4); + MCOS->EmitIntValue(Entry.getFileNumber(), 4); // AT_decl_line, source line number. - MCOS->EmitIntValue(Entry->getLineNumber(), 4); + MCOS->EmitIntValue(Entry.getLineNumber(), 4); // AT_low_pc, start address of the label. - const MCExpr *AT_low_pc = MCSymbolRefExpr::Create(Entry->getLabel(), + const MCExpr *AT_low_pc = MCSymbolRefExpr::Create(Entry.getLabel(), MCSymbolRefExpr::VK_None, context); MCOS->EmitValue(AT_low_pc, AddrSize); @@ -761,14 +758,6 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS, // Add the NULL DIE terminating the DW_TAG_unspecified_parameters DIE's. MCOS->EmitIntValue(0, 1); } - // Deallocate the MCGenDwarfLabelEntry classes that saved away the info - // for the dwarf labels. - for (std::vector<const MCGenDwarfLabelEntry *>::const_iterator it = - Entries.begin(), ie = Entries.end(); it != ie; - ++it) { - const MCGenDwarfLabelEntry *Entry = *it; - delete Entry; - } // Add the NULL DIE terminating the Compile Unit DIE's. MCOS->EmitIntValue(0, 1); @@ -790,8 +779,8 @@ void MCGenDwarfInfo::Emit(MCStreamer *MCOS) { MCSymbol *LineSectionSymbol = nullptr; if (CreateDwarfSectionSymbols) LineSectionSymbol = MCOS->getDwarfLineTableSymbol(0); - MCSymbol *AbbrevSectionSymbol = NULL; - MCSymbol *InfoSectionSymbol = NULL; + MCSymbol *AbbrevSectionSymbol = nullptr; + MCSymbol *InfoSectionSymbol = nullptr; MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfInfoSection()); if (CreateDwarfSectionSymbols) { InfoSectionSymbol = context.CreateTempSymbol(); @@ -856,9 +845,8 @@ void MCGenDwarfLabelEntry::Make(MCSymbol *Symbol, MCStreamer *MCOS, MCOS->EmitLabel(Label); // Create and entry for the info and add it to the other entries. - MCGenDwarfLabelEntry *Entry = - new MCGenDwarfLabelEntry(Name, FileNumber, LineNumber, Label); - MCOS->getContext().addMCGenDwarfLabelEntry(Entry); + MCOS->getContext().addMCGenDwarfLabelEntry( + MCGenDwarfLabelEntry(Name, FileNumber, LineNumber, Label)); } static int getDataAlignmentFactor(MCStreamer &streamer) { @@ -894,7 +882,7 @@ static unsigned getSizeForEncoding(MCStreamer &streamer, static void EmitFDESymbol(MCStreamer &streamer, const MCSymbol &symbol, unsigned symbolEncoding, bool isEH, - const char *comment = 0) { + const char *comment = nullptr) { MCContext &context = streamer.getContext(); const MCAsmInfo *asmInfo = context.getAsmInfo(); const MCExpr *v = asmInfo->getExprForFDESymbol(&symbol, @@ -923,13 +911,11 @@ namespace { class FrameEmitterImpl { int CFAOffset; int CIENum; - bool UsingCFI; bool IsEH; const MCSymbol *SectionStart; public: - FrameEmitterImpl(bool usingCFI, bool isEH) - : CFAOffset(0), CIENum(0), UsingCFI(usingCFI), IsEH(isEH), - SectionStart(0) {} + FrameEmitterImpl(bool isEH) + : CFAOffset(0), CIENum(0), IsEH(isEH), SectionStart(nullptr) {} void setSectionStart(const MCSymbol *Label) { SectionStart = Label; } @@ -937,20 +923,20 @@ namespace { void EmitCompactUnwind(MCStreamer &streamer, const MCDwarfFrameInfo &frame); - const MCSymbol &EmitCIE(MCStreamer &streamer, + const MCSymbol &EmitCIE(MCObjectStreamer &streamer, const MCSymbol *personality, unsigned personalityEncoding, const MCSymbol *lsda, bool IsSignalFrame, unsigned lsdaEncoding, bool IsSimple); - MCSymbol *EmitFDE(MCStreamer &streamer, + MCSymbol *EmitFDE(MCObjectStreamer &streamer, const MCSymbol &cieStart, const MCDwarfFrameInfo &frame); - void EmitCFIInstructions(MCStreamer &streamer, + void EmitCFIInstructions(MCObjectStreamer &streamer, ArrayRef<MCCFIInstruction> Instrs, MCSymbol *BaseLabel); - void EmitCFIInstruction(MCStreamer &Streamer, + void EmitCFIInstruction(MCObjectStreamer &Streamer, const MCCFIInstruction &Instr); }; @@ -1001,7 +987,7 @@ static void EmitEncodingByte(MCStreamer &Streamer, unsigned Encoding, Streamer.EmitIntValue(Encoding, 1); } -void FrameEmitterImpl::EmitCFIInstruction(MCStreamer &Streamer, +void FrameEmitterImpl::EmitCFIInstruction(MCObjectStreamer &Streamer, const MCCFIInstruction &Instr) { int dataAlignmentFactor = getDataAlignmentFactor(Streamer); bool VerboseAsm = Streamer.isVerboseAsm(); @@ -1153,7 +1139,7 @@ void FrameEmitterImpl::EmitCFIInstruction(MCStreamer &Streamer, /// EmitFrameMoves - Emit frame instructions to describe the layout of the /// frame. -void FrameEmitterImpl::EmitCFIInstructions(MCStreamer &streamer, +void FrameEmitterImpl::EmitCFIInstructions(MCObjectStreamer &streamer, ArrayRef<MCCFIInstruction> Instrs, MCSymbol *BaseLabel) { for (unsigned i = 0, N = Instrs.size(); i < N; ++i) { @@ -1214,7 +1200,7 @@ void FrameEmitterImpl::EmitCompactUnwind(MCStreamer &Streamer, Encoding |= 0x40000000; // Range Start - unsigned FDEEncoding = MOFI->getFDEEncoding(UsingCFI); + unsigned FDEEncoding = MOFI->getFDEEncoding(); unsigned Size = getSizeForEncoding(Streamer, FDEEncoding); if (VerboseAsm) Streamer.AddComment("Range Start"); Streamer.EmitSymbolValue(Frame.Function, Size); @@ -1248,7 +1234,7 @@ void FrameEmitterImpl::EmitCompactUnwind(MCStreamer &Streamer, Streamer.EmitIntValue(0, Size); // No LSDA } -const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer, +const MCSymbol &FrameEmitterImpl::EmitCIE(MCObjectStreamer &streamer, const MCSymbol *personality, unsigned personalityEncoding, const MCSymbol *lsda, @@ -1346,8 +1332,7 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer, EmitEncodingByte(streamer, lsdaEncoding, "LSDA Encoding"); // Encoding of the FDE pointers - EmitEncodingByte(streamer, MOFI->getFDEEncoding(UsingCFI), - "FDE Encoding"); + EmitEncodingByte(streamer, MOFI->getFDEEncoding(), "FDE Encoding"); } // Initial Instructions @@ -1356,7 +1341,7 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer, if (!IsSimple) { const std::vector<MCCFIInstruction> &Instructions = MAI->getInitialFrameState(); - EmitCFIInstructions(streamer, Instructions, NULL); + EmitCFIInstructions(streamer, Instructions, nullptr); } // Padding @@ -1366,7 +1351,7 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer, return *sectionStart; } -MCSymbol *FrameEmitterImpl::EmitFDE(MCStreamer &streamer, +MCSymbol *FrameEmitterImpl::EmitFDE(MCObjectStreamer &streamer, const MCSymbol &cieStart, const MCDwarfFrameInfo &frame) { MCContext &context = streamer.getContext(); @@ -1405,8 +1390,8 @@ MCSymbol *FrameEmitterImpl::EmitFDE(MCStreamer &streamer, } // PC Begin - unsigned PCEncoding = IsEH ? MOFI->getFDEEncoding(UsingCFI) - : (unsigned)dwarf::DW_EH_PE_absptr; + unsigned PCEncoding = + IsEH ? MOFI->getFDEEncoding() : (unsigned)dwarf::DW_EH_PE_absptr; unsigned PCSize = getSizeForEncoding(streamer, PCEncoding); EmitFDESymbol(streamer, *frame.Begin, PCEncoding, IsEH, "FDE initial location"); @@ -1443,8 +1428,12 @@ MCSymbol *FrameEmitterImpl::EmitFDE(MCStreamer &streamer, namespace { struct CIEKey { - static const CIEKey getEmptyKey() { return CIEKey(0, 0, -1, false, false); } - static const CIEKey getTombstoneKey() { return CIEKey(0, -1, 0, false, false); } + static const CIEKey getEmptyKey() { + return CIEKey(nullptr, 0, -1, false, false); + } + static const CIEKey getTombstoneKey() { + return CIEKey(nullptr, -1, 0, false, false); + } CIEKey(const MCSymbol* Personality_, unsigned PersonalityEncoding_, unsigned LsdaEncoding_, bool IsSignalFrame_, bool IsSimple_) : @@ -1487,13 +1476,13 @@ namespace llvm { }; } -void MCDwarfFrameEmitter::Emit(MCStreamer &Streamer, MCAsmBackend *MAB, - bool UsingCFI, bool IsEH) { +void MCDwarfFrameEmitter::Emit(MCObjectStreamer &Streamer, MCAsmBackend *MAB, + bool IsEH) { Streamer.generateCompactUnwindEncodings(MAB); MCContext &Context = Streamer.getContext(); const MCObjectFileInfo *MOFI = Context.getObjectFileInfo(); - FrameEmitterImpl Emitter(UsingCFI, IsEH); + FrameEmitterImpl Emitter(IsEH); ArrayRef<MCDwarfFrameInfo> FrameArray = Streamer.getFrameInfos(); // Emit the compact unwind info if available. @@ -1526,10 +1515,10 @@ void MCDwarfFrameEmitter::Emit(MCStreamer &Streamer, MCAsmBackend *MAB, Streamer.EmitLabel(SectionStart); Emitter.setSectionStart(SectionStart); - MCSymbol *FDEEnd = NULL; + MCSymbol *FDEEnd = nullptr; DenseMap<CIEKey, const MCSymbol*> CIEStarts; - const MCSymbol *DummyDebugKey = NULL; + const MCSymbol *DummyDebugKey = nullptr; NeedsEHFrameSection = !MOFI->getSupportsCompactUnwindWithoutEHFrame(); for (unsigned i = 0, n = FrameArray.size(); i < n; ++i) { const MCDwarfFrameInfo &Frame = FrameArray[i]; @@ -1537,7 +1526,7 @@ void MCDwarfFrameEmitter::Emit(MCStreamer &Streamer, MCAsmBackend *MAB, // Emit the label from the previous iteration if (FDEEnd) { Streamer.EmitLabel(FDEEnd); - FDEEnd = NULL; + FDEEnd = nullptr; } if (!NeedsEHFrameSection && Frame.CompactUnwindEncoding != @@ -1564,7 +1553,7 @@ void MCDwarfFrameEmitter::Emit(MCStreamer &Streamer, MCAsmBackend *MAB, Streamer.EmitLabel(FDEEnd); } -void MCDwarfFrameEmitter::EmitAdvanceLoc(MCStreamer &Streamer, +void MCDwarfFrameEmitter::EmitAdvanceLoc(MCObjectStreamer &Streamer, uint64_t AddrDelta) { MCContext &Context = Streamer.getContext(); SmallString<256> Tmp; diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp index f710c3e..767348c 100644 --- a/lib/MC/MCELFStreamer.cpp +++ b/lib/MC/MCELFStreamer.cpp @@ -275,11 +275,12 @@ void MCELFStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, EmitCommonSymbol(Symbol, Size, ByteAlignment); } -void MCELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size) { +void MCELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, + const SMLoc &Loc) { if (getCurrentSectionData()->isBundleLocked()) report_fatal_error("Emitting values inside a locked bundle is forbidden"); fixSymbolsInTLSFixups(Value); - MCObjectStreamer::EmitValueImpl(Value, Size); + MCObjectStreamer::EmitValueImpl(Value, Size, Loc); } void MCELFStreamer::EmitValueToAlignment(unsigned ByteAlignment, @@ -537,7 +538,7 @@ void MCELFStreamer::Flush() { } void MCELFStreamer::FinishImpl() { - EmitFrames(NULL, true); + EmitFrames(nullptr); Flush(); @@ -559,10 +560,6 @@ void MCELFStreamer::EmitThumbFunc(MCSymbol *Func) { llvm_unreachable("Generic ELF doesn't support this directive"); } -MCSymbolData &MCELFStreamer::getOrCreateSymbolData(const MCSymbol *Symbol) { - return getAssembler().getOrCreateSymbolData(*Symbol); -} - void MCELFStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { llvm_unreachable("ELF doesn't support this directive"); } diff --git a/lib/MC/MCExpr.cpp b/lib/MC/MCExpr.cpp index 7f2c478..f724716 100644 --- a/lib/MC/MCExpr.cpp +++ b/lib/MC/MCExpr.cpp @@ -7,7 +7,6 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "mcexpr" #include "llvm/MC/MCExpr.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringSwitch.h" @@ -23,6 +22,8 @@ #include "llvm/Support/raw_ostream.h" using namespace llvm; +#define DEBUG_TYPE "mcexpr" + namespace { namespace stats { STATISTIC(MCExprEvaluate, "Number of MCExpr evaluations"); @@ -270,6 +271,8 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) { case VK_Mips_GOT_LO16: return "GOT_LO16"; case VK_Mips_CALL_HI16: return "CALL_HI16"; case VK_Mips_CALL_LO16: return "CALL_LO16"; + case VK_Mips_PCREL_HI16: return "PCREL_HI16"; + case VK_Mips_PCREL_LO16: return "PCREL_LO16"; case VK_COFF_IMGREL32: return "IMGREL32"; } llvm_unreachable("Invalid variant kind"); @@ -284,6 +287,8 @@ MCSymbolRefExpr::getVariantKindForName(StringRef Name) { .Case("gotoff", VK_GOTOFF) .Case("GOTPCREL", VK_GOTPCREL) .Case("gotpcrel", VK_GOTPCREL) + .Case("GOT_PREL", VK_GOTPCREL) + .Case("got_prel", VK_GOTPCREL) .Case("GOTTPOFF", VK_GOTTPOFF) .Case("gottpoff", VK_GOTTPOFF) .Case("INDNTPOFF", VK_INDNTPOFF) @@ -444,12 +449,12 @@ void MCTargetExpr::anchor() {} /* *** */ bool MCExpr::EvaluateAsAbsolute(int64_t &Res) const { - return EvaluateAsAbsolute(Res, 0, 0, 0); + return EvaluateAsAbsolute(Res, nullptr, nullptr, nullptr); } bool MCExpr::EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout) const { - return EvaluateAsAbsolute(Res, &Layout.getAssembler(), &Layout, 0); + return EvaluateAsAbsolute(Res, &Layout.getAssembler(), &Layout, nullptr); } bool MCExpr::EvaluateAsAbsolute(int64_t &Res, @@ -459,7 +464,7 @@ bool MCExpr::EvaluateAsAbsolute(int64_t &Res, } bool MCExpr::EvaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const { - return EvaluateAsAbsolute(Res, &Asm, 0, 0); + return EvaluateAsAbsolute(Res, &Asm, nullptr, nullptr); } bool MCExpr::EvaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm, @@ -477,7 +482,8 @@ bool MCExpr::EvaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm, // absolutize differences across sections and that is what the MachO writer // uses Addrs for. bool IsRelocatable = - EvaluateAsRelocatableImpl(Value, Asm, Layout, Addrs, /*InSet*/ Addrs); + EvaluateAsRelocatableImpl(Value, Asm, Layout, Addrs, /*InSet*/ Addrs, + /*ForceVarExpansion*/ false); // Record the current value. Res = Value.getConstant(); @@ -505,8 +511,8 @@ static void AttemptToFoldSymbolOffsetDifference(const MCAssembler *Asm, if (!Asm->getWriter().IsSymbolRefDifferenceFullyResolved(*Asm, A, B, InSet)) return; - MCSymbolData &AD = Asm->getSymbolData(SA); - MCSymbolData &BD = Asm->getSymbolData(SB); + const MCSymbolData &AD = Asm->getSymbolData(SA); + const MCSymbolData &BD = Asm->getSymbolData(SB); if (AD.getFragment() == BD.getFragment()) { Addend += (AD.getOffset() - BD.getOffset()); @@ -518,7 +524,7 @@ static void AttemptToFoldSymbolOffsetDifference(const MCAssembler *Asm, // Clear the symbol expr pointers to indicate we have folded these // operands. - A = B = 0; + A = B = nullptr; return; } @@ -544,7 +550,7 @@ static void AttemptToFoldSymbolOffsetDifference(const MCAssembler *Asm, // Clear the symbol expr pointers to indicate we have folded these // operands. - A = B = 0; + A = B = nullptr; } /// \brief Evaluate the result of an add between (conceptually) two MCValues. @@ -627,15 +633,21 @@ static bool EvaluateSymbolicAdd(const MCAssembler *Asm, bool MCExpr::EvaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout) const { - MCAssembler *Assembler = Layout ? &Layout->getAssembler() : 0; - return EvaluateAsRelocatableImpl(Res, Assembler, Layout, 0, false); + MCAssembler *Assembler = Layout ? &Layout->getAssembler() : nullptr; + return EvaluateAsRelocatableImpl(Res, Assembler, Layout, nullptr, false, + /*ForceVarExpansion*/ false); } -bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, - const MCAssembler *Asm, +bool MCExpr::EvaluateAsValue(MCValue &Res, const MCAsmLayout *Layout) const { + MCAssembler *Assembler = Layout ? &Layout->getAssembler() : nullptr; + return EvaluateAsRelocatableImpl(Res, Assembler, Layout, nullptr, false, + /*ForceVarExpansion*/ true); +} + +bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, const MCAsmLayout *Layout, - const SectionAddrMap *Addrs, - bool InSet) const { + const SectionAddrMap *Addrs, bool InSet, + bool ForceVarExpansion) const { ++stats::MCExprEvaluate; switch (getKind()) { @@ -652,9 +664,9 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, const MCAsmInfo &MCAsmInfo = SRE->getMCAsmInfo(); // Evaluate recursively if this is a variable. - if (Sym.isVariable()) { - if (Sym.getVariableValue()->EvaluateAsRelocatableImpl(Res, Asm, Layout, - Addrs, true)) { + if (Sym.isVariable() && SRE->getKind() == MCSymbolRefExpr::VK_None) { + if (Sym.getVariableValue()->EvaluateAsRelocatableImpl( + Res, Asm, Layout, Addrs, true, ForceVarExpansion)) { const MCSymbolRefExpr *A = Res.getSymA(); const MCSymbolRefExpr *B = Res.getSymB(); @@ -668,15 +680,16 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, if (!A && !B) return true; } else { + if (ForceVarExpansion) + return true; bool IsSymbol = A && A->getSymbol().isDefined(); - bool IsWeakRef = SRE->getKind() == MCSymbolRefExpr::VK_WEAKREF; - if (!IsSymbol && !IsWeakRef) + if (!IsSymbol) return true; } } } - Res = MCValue::get(SRE, 0, 0); + Res = MCValue::get(SRE, nullptr, 0); return true; } @@ -684,8 +697,8 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, const MCUnaryExpr *AUE = cast<MCUnaryExpr>(this); MCValue Value; - if (!AUE->getSubExpr()->EvaluateAsRelocatableImpl(Value, Asm, Layout, - Addrs, InSet)) + if (!AUE->getSubExpr()->EvaluateAsRelocatableImpl(Value, Asm, Layout, Addrs, + InSet, ForceVarExpansion)) return false; switch (AUE->getOpcode()) { @@ -718,10 +731,10 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, const MCBinaryExpr *ABE = cast<MCBinaryExpr>(this); MCValue LHSValue, RHSValue; - if (!ABE->getLHS()->EvaluateAsRelocatableImpl(LHSValue, Asm, Layout, - Addrs, InSet) || - !ABE->getRHS()->EvaluateAsRelocatableImpl(RHSValue, Asm, Layout, - Addrs, InSet)) + if (!ABE->getLHS()->EvaluateAsRelocatableImpl(LHSValue, Asm, Layout, Addrs, + InSet, ForceVarExpansion) || + !ABE->getRHS()->EvaluateAsRelocatableImpl(RHSValue, Asm, Layout, Addrs, + InSet, ForceVarExpansion)) return false; // We only support a few operations on non-constant expressions, handle @@ -795,7 +808,7 @@ const MCSection *MCExpr::FindAssociatedSection() const { if (Sym.isDefined()) return &Sym.getSection(); - return 0; + return nullptr; } case Unary: diff --git a/lib/MC/MCExternalSymbolizer.cpp b/lib/MC/MCExternalSymbolizer.cpp index 839516e..7c3073a 100644 --- a/lib/MC/MCExternalSymbolizer.cpp +++ b/lib/MC/MCExternalSymbolizer.cpp @@ -83,7 +83,7 @@ bool MCExternalSymbolizer::tryAddingSymbolicOperand(MCInst &MI, return false; } - const MCExpr *Add = NULL; + const MCExpr *Add = nullptr; if (SymbolicOp.AddSymbol.Present) { if (SymbolicOp.AddSymbol.Name) { StringRef Name(SymbolicOp.AddSymbol.Name); @@ -94,7 +94,7 @@ bool MCExternalSymbolizer::tryAddingSymbolicOperand(MCInst &MI, } } - const MCExpr *Sub = NULL; + const MCExpr *Sub = nullptr; if (SymbolicOp.SubtractSymbol.Present) { if (SymbolicOp.SubtractSymbol.Name) { StringRef Name(SymbolicOp.SubtractSymbol.Name); @@ -105,7 +105,7 @@ bool MCExternalSymbolizer::tryAddingSymbolicOperand(MCInst &MI, } } - const MCExpr *Off = NULL; + const MCExpr *Off = nullptr; if (SymbolicOp.Value != 0) Off = MCConstantExpr::Create(SymbolicOp.Value, Ctx); @@ -116,17 +116,17 @@ bool MCExternalSymbolizer::tryAddingSymbolicOperand(MCInst &MI, LHS = MCBinaryExpr::CreateSub(Add, Sub, Ctx); else LHS = MCUnaryExpr::CreateMinus(Sub, Ctx); - if (Off != 0) + if (Off) Expr = MCBinaryExpr::CreateAdd(LHS, Off, Ctx); else Expr = LHS; } else if (Add) { - if (Off != 0) + if (Off) Expr = MCBinaryExpr::CreateAdd(Add, Off, Ctx); else Expr = Add; } else { - if (Off != 0) + if (Off) Expr = Off; else Expr = MCConstantExpr::Create(0, Ctx); @@ -189,7 +189,7 @@ MCSymbolizer *createMCSymbolizer(StringRef TT, LLVMOpInfoCallback GetOpInfo, void *DisInfo, MCContext *Ctx, MCRelocationInfo *RelInfo) { - assert(Ctx != 0 && "No MCContext given for symbolic disassembly"); + assert(Ctx && "No MCContext given for symbolic disassembly"); return new MCExternalSymbolizer(*Ctx, std::unique_ptr<MCRelocationInfo>(RelInfo), diff --git a/lib/MC/MCFixup.cpp b/lib/MC/MCFixup.cpp deleted file mode 100644 index 8f15db5..0000000 --- a/lib/MC/MCFixup.cpp +++ /dev/null @@ -1,37 +0,0 @@ -//===- MCFixup.cpp - Assembly Fixup Implementation ------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "llvm/MC/MCFixup.h" -using namespace llvm; - -static MCSymbolRefExpr::VariantKind getAccessVariant(const MCExpr *Expr) { - switch (Expr->getKind()) { - case MCExpr::Unary: - case MCExpr::Target: - llvm_unreachable("unsupported"); - - case MCExpr::Constant: - return MCSymbolRefExpr::VK_None; - - case MCExpr::SymbolRef: { - const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(Expr); - return SRE->getKind(); - } - case MCExpr::Binary: { - const MCBinaryExpr *ABE = cast<MCBinaryExpr>(Expr); - assert(getAccessVariant(ABE->getRHS()) == MCSymbolRefExpr::VK_None); - return getAccessVariant(ABE->getLHS()); - } - } - llvm_unreachable("unknown MCExpr kind"); -} - -MCSymbolRefExpr::VariantKind MCFixup::getAccessVariant() const { - return ::getAccessVariant(getValue()); -} diff --git a/lib/MC/MCFunction.cpp b/lib/MC/MCFunction.cpp index 767e1e0..1ddc250 100644 --- a/lib/MC/MCFunction.cpp +++ b/lib/MC/MCFunction.cpp @@ -20,22 +20,17 @@ MCFunction::MCFunction(StringRef Name, MCModule *Parent) : Name(Name), ParentModule(Parent) {} -MCFunction::~MCFunction() { - for (iterator I = begin(), E = end(); I != E; ++I) - delete *I; -} - MCBasicBlock &MCFunction::createBlock(const MCTextAtom &TA) { - MCBasicBlock *MCBB = new MCBasicBlock(TA, this); - Blocks.push_back(MCBB); - return *MCBB; + std::unique_ptr<MCBasicBlock> MCBB(new MCBasicBlock(TA, this)); + Blocks.push_back(std::move(MCBB)); + return *Blocks.back(); } MCBasicBlock *MCFunction::find(uint64_t StartAddr) { for (const_iterator I = begin(), E = end(); I != E; ++I) if ((*I)->getInsts()->getBeginAddr() == StartAddr) - return *I; - return 0; + return I->get(); + return nullptr; } const MCBasicBlock *MCFunction::find(uint64_t StartAddr) const { diff --git a/lib/MC/MCInst.cpp b/lib/MC/MCInst.cpp index 124cc14..d7b80f5 100644 --- a/lib/MC/MCInst.cpp +++ b/lib/MC/MCInst.cpp @@ -34,7 +34,7 @@ void MCOperand::print(raw_ostream &OS, const MCAsmInfo *MAI) const { #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) void MCOperand::dump() const { - print(dbgs(), 0); + print(dbgs(), nullptr); dbgs() << "\n"; } #endif @@ -66,7 +66,7 @@ void MCInst::dump_pretty(raw_ostream &OS, const MCAsmInfo *MAI, #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) void MCInst::dump() const { - print(dbgs(), 0); + print(dbgs(), nullptr); dbgs() << "\n"; } #endif diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp index 7e437f4..37d05e9 100644 --- a/lib/MC/MCMachOStreamer.cpp +++ b/lib/MC/MCMachOStreamer.cpp @@ -89,7 +89,7 @@ public: } void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) override; - void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, + void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = nullptr, uint64_t Size = 0, unsigned ByteAlignment = 0) override; virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment = 0) override; @@ -172,7 +172,7 @@ void MCMachOStreamer::EmitDataRegion(DataRegionData::KindTy Kind) { MCSymbol *Start = getContext().CreateTempSymbol(); EmitLabel(Start); // Record the region for the object writer to use. - DataRegionData Data = { Kind, Start, NULL }; + DataRegionData Data = { Kind, Start, nullptr }; std::vector<DataRegionData> &Regions = getAssembler().getDataRegions(); Regions.push_back(Data); } @@ -183,7 +183,7 @@ void MCMachOStreamer::EmitDataRegionEnd() { std::vector<DataRegionData> &Regions = getAssembler().getDataRegions(); assert(Regions.size() && "Mismatched .end_data_region!"); DataRegionData &Data = Regions.back(); - assert(Data.End == NULL && "Mismatched .end_data_region!"); + assert(!Data.End && "Mismatched .end_data_region!"); // Create a temporary label to mark the end of the data region. Data.End = getContext().CreateTempSymbol(); EmitLabel(Data.End); @@ -237,10 +237,6 @@ void MCMachOStreamer::EmitThumbFunc(MCSymbol *Symbol) { // Remember that the function is a thumb function. Fixup and relocation // values will need adjusted. getAssembler().setIsThumbFunc(Symbol); - - // Mark the thumb bit on the symbol. - MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); - SD.setFlags(SD.getFlags() | SF_ThumbFunc); } bool MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol, @@ -352,7 +348,7 @@ void MCMachOStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, // FIXME: Darwin 'as' does appear to allow redef of a .comm by itself. assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); - AssignSection(Symbol, NULL); + AssignSection(Symbol, nullptr); MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); SD.setExternal(true); @@ -422,7 +418,7 @@ void MCMachOStreamer::EmitInstToData(const MCInst &Inst, } void MCMachOStreamer::FinishImpl() { - EmitFrames(&getAssembler().getBackend(), true); + EmitFrames(&getAssembler().getBackend()); // We have to set the fragment atom associations so we can relax properly for // Mach-O. @@ -430,13 +426,12 @@ void MCMachOStreamer::FinishImpl() { // First, scan the symbol table to build a lookup table from fragments to // defining symbols. DenseMap<const MCFragment*, MCSymbolData*> DefiningSymbolMap; - for (MCAssembler::symbol_iterator it = getAssembler().symbol_begin(), - ie = getAssembler().symbol_end(); it != ie; ++it) { - if (getAssembler().isSymbolLinkerVisible(it->getSymbol()) && - it->getFragment()) { + for (MCSymbolData &SD : getAssembler().symbols()) { + if (getAssembler().isSymbolLinkerVisible(SD.getSymbol()) && + SD.getFragment()) { // An atom defining symbol should never be internal to a fragment. - assert(it->getOffset() == 0 && "Invalid offset in atom defining symbol!"); - DefiningSymbolMap[it->getFragment()] = it; + assert(SD.getOffset() == 0 && "Invalid offset in atom defining symbol!"); + DefiningSymbolMap[SD.getFragment()] = &SD; } } @@ -444,7 +439,7 @@ void MCMachOStreamer::FinishImpl() { // symbol. for (MCAssembler::iterator it = getAssembler().begin(), ie = getAssembler().end(); it != ie; ++it) { - MCSymbolData *CurrentAtom = 0; + MCSymbolData *CurrentAtom = nullptr; for (MCSectionData::iterator it2 = it->begin(), ie2 = it->end(); it2 != ie2; ++it2) { if (MCSymbolData *SD = DefiningSymbolMap.lookup(it2)) diff --git a/lib/MC/MCModule.cpp b/lib/MC/MCModule.cpp index 7e9e18a..3ed7356 100644 --- a/lib/MC/MCModule.cpp +++ b/lib/MC/MCModule.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/ADT/STLExtras.h" #include "llvm/MC/MCModule.h" #include "llvm/MC/MCAtom.h" #include "llvm/MC/MCFunction.h" @@ -77,7 +78,7 @@ const MCAtom *MCModule::findAtomContaining(uint64_t Addr) const { Addr, AtomComp); if (I != atom_end() && (*I)->getBeginAddr() <= Addr) return *I; - return 0; + return nullptr; } MCAtom *MCModule::findAtomContaining(uint64_t Addr) { @@ -90,7 +91,7 @@ const MCAtom *MCModule::findFirstAtomAfter(uint64_t Addr) const { Addr, AtomCompInv); if (I != atom_end()) return *I; - return 0; + return nullptr; } MCAtom *MCModule::findFirstAtomAfter(uint64_t Addr) { @@ -99,8 +100,9 @@ MCAtom *MCModule::findFirstAtomAfter(uint64_t Addr) { } MCFunction *MCModule::createFunction(StringRef Name) { - Functions.push_back(new MCFunction(Name, this)); - return Functions.back(); + std::unique_ptr<MCFunction> MCF(new MCFunction(Name, this)); + Functions.push_back(std::move(MCF)); + return Functions.back().get(); } static bool CompBBToAtom(MCBasicBlock *BB, const MCTextAtom *Atom) { @@ -130,13 +132,11 @@ void MCModule::trackBBForAtom(const MCTextAtom *Atom, MCBasicBlock *BB) { BBsByAtom.insert(I, BB); } +MCModule::MCModule() : Entrypoint(0) { } + MCModule::~MCModule() { for (AtomListTy::iterator AI = atom_begin(), AE = atom_end(); AI != AE; ++AI) delete *AI; - for (FunctionListTy::iterator FI = func_begin(), - FE = func_end(); - FI != FE; ++FI) - delete *FI; } diff --git a/lib/MC/MCModuleYAML.cpp b/lib/MC/MCModuleYAML.cpp index 102971b..f81cb14 100644 --- a/lib/MC/MCModuleYAML.cpp +++ b/lib/MC/MCModuleYAML.cpp @@ -19,6 +19,7 @@ #include "llvm/MC/MCRegisterInfo.h" #include "llvm/Object/YAML.h" #include "llvm/Support/Allocator.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/YAMLTraits.h" #include <vector> @@ -162,12 +163,14 @@ template <> struct ScalarTraits<MCModuleYAML::Operand> { static void output(const MCModuleYAML::Operand &, void *, llvm::raw_ostream &); static StringRef input(StringRef, void *, MCModuleYAML::Operand &); + static bool mustQuote(StringRef) { return false; } }; template <> struct ScalarTraits<MCModuleYAML::OpcodeEnum> { static void output(const MCModuleYAML::OpcodeEnum &, void *, llvm::raw_ostream &); static StringRef input(StringRef, void *, MCModuleYAML::OpcodeEnum &); + static bool mustQuote(StringRef) { return false; } }; void ScalarEnumerationTraits<MCAtom::AtomKind>::enumeration( @@ -276,7 +279,7 @@ class MCModule2YAML { const MCModule &MCM; MCModuleYAML::Module YAMLModule; void dumpAtom(const MCAtom *MCA); - void dumpFunction(const MCFunction *MCF); + void dumpFunction(const MCFunction &MCF); void dumpBasicBlock(const MCBasicBlock *MCBB); public: @@ -300,7 +303,7 @@ MCModule2YAML::MCModule2YAML(const MCModule &MCM) : MCM(MCM), YAMLModule() { dumpAtom(*AI); for (MCModule::const_func_iterator FI = MCM.func_begin(), FE = MCM.func_end(); FI != FE; ++FI) - dumpFunction(*FI); + dumpFunction(**FI); } void MCModule2YAML::dumpAtom(const MCAtom *MCA) { @@ -328,22 +331,22 @@ void MCModule2YAML::dumpAtom(const MCAtom *MCA) { } } -void MCModule2YAML::dumpFunction(const MCFunction *MCF) { +void MCModule2YAML::dumpFunction(const MCFunction &MCF) { YAMLModule.Functions.resize(YAMLModule.Functions.size() + 1); MCModuleYAML::Function &F = YAMLModule.Functions.back(); - F.Name = MCF->getName(); - for (MCFunction::const_iterator BBI = MCF->begin(), BBE = MCF->end(); + F.Name = MCF.getName(); + for (MCFunction::const_iterator BBI = MCF.begin(), BBE = MCF.end(); BBI != BBE; ++BBI) { - const MCBasicBlock *MCBB = *BBI; + const MCBasicBlock &MCBB = **BBI; F.BasicBlocks.resize(F.BasicBlocks.size() + 1); MCModuleYAML::BasicBlock &BB = F.BasicBlocks.back(); - BB.Address = MCBB->getInsts()->getBeginAddr(); - for (MCBasicBlock::pred_const_iterator PI = MCBB->pred_begin(), - PE = MCBB->pred_end(); + BB.Address = MCBB.getInsts()->getBeginAddr(); + for (MCBasicBlock::pred_const_iterator PI = MCBB.pred_begin(), + PE = MCBB.pred_end(); PI != PE; ++PI) BB.Preds.push_back((*PI)->getInsts()->getBeginAddr()); - for (MCBasicBlock::succ_const_iterator SI = MCBB->succ_begin(), - SE = MCBB->succ_end(); + for (MCBasicBlock::succ_const_iterator SI = MCBB.succ_begin(), + SE = MCBB.succ_end(); SI != SE; ++SI) BB.Succs.push_back((*SI)->getInsts()->getBeginAddr()); } diff --git a/lib/MC/MCNullStreamer.cpp b/lib/MC/MCNullStreamer.cpp index 894eada..4f2740e 100644 --- a/lib/MC/MCNullStreamer.cpp +++ b/lib/MC/MCNullStreamer.cpp @@ -41,11 +41,6 @@ namespace { void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override {} void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override {} - void EmitDwarfAdvanceLineAddr(int64_t LineDelta, - const MCSymbol *LastLabel, - const MCSymbol *Label, - unsigned PointerSize) override {} - bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override { return true; @@ -64,13 +59,14 @@ namespace { unsigned ByteAlignment) override {} void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) override {} - void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, + void EmitZerofill(const 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) override {} void EmitBytes(StringRef Data) override {} - void EmitValueImpl(const MCExpr *Value, unsigned Size) override {} + void EmitValueImpl(const MCExpr *Value, unsigned Size, + const SMLoc &Loc = SMLoc()) override {} void EmitULEB128Value(const MCExpr *Value) override {} void EmitSLEB128Value(const MCExpr *Value) override {} void EmitGPRel32Value(const MCExpr *Value) override {} diff --git a/lib/MC/MCObjectDisassembler.cpp b/lib/MC/MCObjectDisassembler.cpp index 146da6d..8a258cb 100644 --- a/lib/MC/MCObjectDisassembler.cpp +++ b/lib/MC/MCObjectDisassembler.cpp @@ -31,10 +31,12 @@ using namespace llvm; using namespace object; +#define DEBUG_TYPE "mc" + MCObjectDisassembler::MCObjectDisassembler(const ObjectFile &Obj, const MCDisassembler &Dis, const MCInstrAnalysis &MIA) - : Obj(Obj), Dis(Dis), MIA(MIA), MOS(0) {} + : Obj(Obj), Dis(Dis), MIA(MIA), MOS(nullptr) {} uint64_t MCObjectDisassembler::getEntrypoint() { for (const SymbolRef &Symbol : Obj.symbols()) { @@ -115,8 +117,8 @@ void MCObjectDisassembler::buildSectionAtoms(MCModule *Module) { Section.getName(SecName); if (isText) { - MCTextAtom *Text = 0; - MCDataAtom *InvalidData = 0; + MCTextAtom *Text = nullptr; + MCDataAtom *InvalidData = nullptr; uint64_t InstSize; for (uint64_t Index = 0; Index < SecSize; Index += InstSize) { @@ -129,11 +131,11 @@ void MCObjectDisassembler::buildSectionAtoms(MCModule *Module) { Text->setName(SecName); } Text->addInst(Inst, InstSize); - InvalidData = 0; + InvalidData = nullptr; } else { assert(InstSize && "getInstruction() consumed no bytes"); if (!InvalidData) { - Text = 0; + Text = nullptr; InvalidData = Module->createDataAtom(CurAddr, CurAddr+InstSize - 1); } for (uint64_t I = 0; I < InstSize; ++I) @@ -160,7 +162,7 @@ namespace { BBInfoSetTy Preds; MCObjectDisassembler::AddressSetTy SuccAddrs; - BBInfo() : Atom(0), BB(0) {} + BBInfo() : Atom(nullptr), BB(nullptr) {} void addSucc(BBInfo &Succ) { Succs.insert(&Succ); @@ -480,7 +482,7 @@ MCObjectDisassembler::createFunction(MCModule *Module, uint64_t BeginAddr, continue; // FIXME: MCModule should provide a findFunctionByAddr() if ((*FI)->getEntryBlock()->getInsts()->getBeginAddr() == BeginAddr) - return *FI; + return FI->get(); } // Finally, just create a new one. diff --git a/lib/MC/MCObjectFileInfo.cpp b/lib/MC/MCObjectFileInfo.cpp index 3b011c8..9d413af 100644 --- a/lib/MC/MCObjectFileInfo.cpp +++ b/lib/MC/MCObjectFileInfo.cpp @@ -10,6 +10,7 @@ #include "llvm/MC/MCObjectFileInfo.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Triple.h" +#include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCSectionCOFF.h" @@ -22,12 +23,13 @@ void MCObjectFileInfo::InitMachOMCObjectFileInfo(Triple T) { IsFunctionEHFrameSymbolPrivate = false; SupportsWeakOmittedEHFrame = false; - if (T.isOSDarwin() && T.getArch() == Triple::arm64) + if (T.isOSDarwin() && + (T.getArch() == Triple::arm64 || T.getArch() == Triple::aarch64)) SupportsCompactUnwindWithoutEHFrame = true; PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; - LSDAEncoding = FDEEncoding = FDECFIEncoding = dwarf::DW_EH_PE_pcrel; + LSDAEncoding = FDECFIEncoding = dwarf::DW_EH_PE_pcrel; TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; @@ -44,7 +46,7 @@ void MCObjectFileInfo::InitMachOMCObjectFileInfo(Triple T) { SectionKind::getDataRel()); // BSSSection might not be expected initialized on msvc. - BSSSection = 0; + BSSSection = nullptr; TLSDataSection // .tdata = Ctx->getMachOSection("__DATA", "__thread_data", @@ -147,10 +149,11 @@ void MCObjectFileInfo::InitMachOMCObjectFileInfo(Triple T) { LSDASection = Ctx->getMachOSection("__TEXT", "__gcc_except_tab", 0, SectionKind::getReadOnlyWithRel()); - COFFDebugSymbolsSection = 0; + COFFDebugSymbolsSection = nullptr; if ((T.isMacOSX() && !T.isMacOSXVersionLT(10, 6)) || - (T.isOSDarwin() && T.getArch() == Triple::arm64)) { + (T.isOSDarwin() && + (T.getArch() == Triple::arm64 || T.getArch() == Triple::aarch64))) { CompactUnwindSection = Ctx->getMachOSection("__LD", "__compact_unwind", MachO::S_ATTR_DEBUG, @@ -158,7 +161,7 @@ void MCObjectFileInfo::InitMachOMCObjectFileInfo(Triple T) { if (T.getArch() == Triple::x86_64 || T.getArch() == Triple::x86) CompactUnwindDwarfEHFrameOnly = 0x04000000; - else if (T.getArch() == Triple::arm64) + else if (T.getArch() == Triple::arm64 || T.getArch() == Triple::aarch64) CompactUnwindDwarfEHFrameOnly = 0x03000000; } @@ -245,29 +248,40 @@ void MCObjectFileInfo::InitMachOMCObjectFileInfo(Triple T) { } void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) { - if (T.getArch() == Triple::mips || - T.getArch() == Triple::mipsel) + switch (T.getArch()) { + case Triple::mips: + case Triple::mipsel: FDECFIEncoding = dwarf::DW_EH_PE_sdata4; - else if (T.getArch() == Triple::mips64 || - T.getArch() == Triple::mips64el) + break; + case Triple::mips64: + case Triple::mips64el: FDECFIEncoding = dwarf::DW_EH_PE_sdata8; - else + break; + default: FDECFIEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; + break; + } - if (T.getArch() == Triple::x86) { + switch (T.getArch()) { + case Triple::arm: + case Triple::armeb: + case Triple::thumb: + case Triple::thumbeb: + if (Ctx->getAsmInfo()->getExceptionHandlingType() == ExceptionHandling::ARM) + break; + // Fallthrough if not using EHABI + case Triple::x86: PersonalityEncoding = (RelocM == Reloc::PIC_) ? dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_absptr; LSDAEncoding = (RelocM == Reloc::PIC_) ? dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_absptr; - FDEEncoding = (RelocM == Reloc::PIC_) - ? dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 - : dwarf::DW_EH_PE_absptr; TTypeEncoding = (RelocM == Reloc::PIC_) ? dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_absptr; - } else if (T.getArch() == Triple::x86_64) { + break; + case Triple::x86_64: if (RelocM == Reloc::PIC_) { PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | ((CMModel == CodeModel::Small || CMModel == CodeModel::Medium) @@ -275,7 +289,6 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) { LSDAEncoding = dwarf::DW_EH_PE_pcrel | (CMModel == CodeModel::Small ? dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_sdata8); - FDEEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | ((CMModel == CodeModel::Small || CMModel == CodeModel::Medium) ? dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_sdata8); @@ -285,12 +298,14 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) { ? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr; LSDAEncoding = (CMModel == CodeModel::Small) ? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr; - FDEEncoding = dwarf::DW_EH_PE_udata4; TTypeEncoding = (CMModel == CodeModel::Small) ? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr; } - } else if (T.getArch() == Triple::aarch64 || - T.getArch() == Triple::aarch64_be ) { + break; + case Triple::aarch64: + case Triple::aarch64_be: + case Triple::arm64: + case Triple::arm64_be: // The small model guarantees static code/data size < 4GB, but not where it // will be in memory. Most of these could end up >2GB away so even a signed // pc-relative 32-bit address is insufficient, theoretically. @@ -298,65 +313,64 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) { PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8; LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8; - FDEEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8; } else { PersonalityEncoding = dwarf::DW_EH_PE_absptr; LSDAEncoding = dwarf::DW_EH_PE_absptr; - FDEEncoding = dwarf::DW_EH_PE_udata4; TTypeEncoding = dwarf::DW_EH_PE_absptr; } - } else if (T.getArch() == Triple::ppc64 || T.getArch() == Triple::ppc64le) { + break; + case Triple::ppc64: + case Triple::ppc64le: PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8; LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8; - FDEEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8; TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8; - } else if (T.getArch() == Triple::sparc) { + break; + case Triple::sparc: if (RelocM == Reloc::PIC_) { LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; - FDEEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; } else { LSDAEncoding = dwarf::DW_EH_PE_absptr; PersonalityEncoding = dwarf::DW_EH_PE_absptr; - FDEEncoding = dwarf::DW_EH_PE_udata4; TTypeEncoding = dwarf::DW_EH_PE_absptr; } - } else if (T.getArch() == Triple::sparcv9) { + break; + case Triple::sparcv9: LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; if (RelocM == Reloc::PIC_) { PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; - FDEEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; } else { PersonalityEncoding = dwarf::DW_EH_PE_absptr; - FDEEncoding = dwarf::DW_EH_PE_udata4; TTypeEncoding = dwarf::DW_EH_PE_absptr; } - } else if (T.getArch() == Triple::systemz) { + break; + case Triple::systemz: // All currently-defined code models guarantee that 4-byte PC-relative // values will be in range. if (RelocM == Reloc::PIC_) { PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; - FDEEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; } else { PersonalityEncoding = dwarf::DW_EH_PE_absptr; LSDAEncoding = dwarf::DW_EH_PE_absptr; - FDEEncoding = dwarf::DW_EH_PE_absptr; TTypeEncoding = dwarf::DW_EH_PE_absptr; } + break; + default: + break; } // Solaris requires different flags for .eh_frame to seemingly every other @@ -461,7 +475,7 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) { ELF::SHF_ALLOC, SectionKind::getReadOnly()); - COFFDebugSymbolsSection = 0; + COFFDebugSymbolsSection = nullptr; // Debug Info Sections. DwarfAbbrevSection = @@ -548,6 +562,10 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) { void MCObjectFileInfo::InitCOFFMCObjectFileInfo(Triple T) { + // The object file format cannot represent common symbols with explicit + // alignments. + CommDirectiveSupportsAlignment = false; + // COFF BSSSection = Ctx->getCOFFSection(".bss", @@ -716,7 +734,7 @@ void MCObjectFileInfo::InitCOFFMCObjectFileInfo(Triple T) { DrectveSection = Ctx->getCOFFSection(".drectve", - COFF::IMAGE_SCN_LNK_INFO, + COFF::IMAGE_SCN_LNK_INFO | COFF::IMAGE_SCN_LNK_REMOVE, SectionKind::getMetadata()); PDataSection = @@ -751,17 +769,17 @@ void MCObjectFileInfo::InitMCObjectFileInfo(StringRef TT, Reloc::Model relocm, IsFunctionEHFrameSymbolPrivate = true; SupportsCompactUnwindWithoutEHFrame = false; - PersonalityEncoding = LSDAEncoding = FDEEncoding = FDECFIEncoding = - TTypeEncoding = dwarf::DW_EH_PE_absptr; + PersonalityEncoding = LSDAEncoding = FDECFIEncoding = TTypeEncoding = + dwarf::DW_EH_PE_absptr; CompactUnwindDwarfEHFrameOnly = 0; - EHFrameSection = 0; // Created on demand. - CompactUnwindSection = 0; // Used only by selected targets. - DwarfAccelNamesSection = 0; // Used only by selected targets. - DwarfAccelObjCSection = 0; // Used only by selected targets. - DwarfAccelNamespaceSection = 0; // Used only by selected targets. - DwarfAccelTypesSection = 0; // Used only by selected targets. + EHFrameSection = nullptr; // Created on demand. + CompactUnwindSection = nullptr; // Used only by selected targets. + DwarfAccelNamesSection = nullptr; // Used only by selected targets. + DwarfAccelObjCSection = nullptr; // Used only by selected targets. + DwarfAccelNamespaceSection = nullptr; // Used only by selected targets. + DwarfAccelTypesSection = nullptr; // Used only by selected targets. Triple T(TT); Triple::ArchType Arch = T.getArch(); @@ -769,14 +787,15 @@ void MCObjectFileInfo::InitMCObjectFileInfo(StringRef TT, Reloc::Model relocm, // cellspu-apple-darwin. Perhaps we should fix in Triple? if ((Arch == Triple::x86 || Arch == Triple::x86_64 || Arch == Triple::arm || Arch == Triple::thumb || - Arch == Triple::arm64 || + Arch == Triple::arm64 || Arch == Triple::aarch64 || Arch == Triple::ppc || Arch == Triple::ppc64 || Arch == Triple::UnknownArch) && (T.isOSDarwin() || T.isOSBinFormatMachO())) { Env = IsMachO; InitMachOMCObjectFileInfo(T); - } else if ((Arch == Triple::x86 || Arch == Triple::x86_64) && - T.getObjectFormat() != Triple::ELF && T.isOSWindows()) { + } else if ((Arch == Triple::x86 || Arch == Triple::x86_64 || + Arch == Triple::arm || Arch == Triple::thumb) && + (T.isOSWindows() && T.getObjectFormat() == Triple::COFF)) { Env = IsCOFF; InitCOFFMCObjectFileInfo(T); } else { diff --git a/lib/MC/MCObjectStreamer.cpp b/lib/MC/MCObjectStreamer.cpp index 4451264..a1aa602 100644 --- a/lib/MC/MCObjectStreamer.cpp +++ b/lib/MC/MCObjectStreamer.cpp @@ -20,7 +20,6 @@ #include "llvm/MC/MCSection.h" #include "llvm/MC/MCSymbol.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/MC/MCSectionELF.h" using namespace llvm; MCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, @@ -28,12 +27,13 @@ MCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, : MCStreamer(Context), Assembler(new MCAssembler(Context, TAB, *Emitter_, *TAB.createObjectWriter(OS), OS)), - CurSectionData(0) {} + CurSectionData(nullptr), EmitEHFrame(true), EmitDebugFrame(false) {} MCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *Emitter_, MCAssembler *_Assembler) - : MCStreamer(Context), Assembler(_Assembler), CurSectionData(0) {} + : MCStreamer(Context), Assembler(_Assembler), CurSectionData(nullptr), + EmitEHFrame(true), EmitDebugFrame(false) {} MCObjectStreamer::~MCObjectStreamer() { delete &Assembler->getBackend(); @@ -45,18 +45,31 @@ MCObjectStreamer::~MCObjectStreamer() { void MCObjectStreamer::reset() { if (Assembler) Assembler->reset(); - CurSectionData = 0; + CurSectionData = nullptr; CurInsertionPoint = MCSectionData::iterator(); + EmitEHFrame = true; + EmitDebugFrame = false; MCStreamer::reset(); } +void MCObjectStreamer::EmitFrames(MCAsmBackend *MAB) { + if (!getNumFrameInfos()) + return; + + if (EmitEHFrame) + MCDwarfFrameEmitter::Emit(*this, MAB, true); + + if (EmitDebugFrame) + MCDwarfFrameEmitter::Emit(*this, MAB, false); +} + MCFragment *MCObjectStreamer::getCurrentFragment() const { assert(getCurrentSectionData() && "No current section!"); if (CurInsertionPoint != getCurrentSectionData()->getFragmentList().begin()) return std::prev(CurInsertionPoint); - return 0; + return nullptr; } MCDataFragment *MCObjectStreamer::getOrCreateDataFragment() const { @@ -64,11 +77,7 @@ MCDataFragment *MCObjectStreamer::getOrCreateDataFragment() const { // 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())) { - const auto *Sec = dyn_cast<MCSectionELF>(&getCurrentSectionData()->getSection()); - if (Sec && Sec->getSectionName().startswith(".zdebug_")) - F = new MCCompressedFragment(); - else - F = new MCDataFragment(); + F = new MCDataFragment(); insert(F); } return F; @@ -102,7 +111,14 @@ const MCExpr *MCObjectStreamer::AddValueSymbols(const MCExpr *Value) { return Value; } -void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size) { +void MCObjectStreamer::EmitCFISections(bool EH, bool Debug) { + MCStreamer::EmitCFISections(EH, Debug); + EmitEHFrame = EH; + EmitDebugFrame = Debug; +} + +void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, + const SMLoc &Loc) { MCDataFragment *DF = getOrCreateDataFragment(); MCLineEntry::Make(this, getCurrentSection().first); @@ -115,7 +131,7 @@ void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size) { } DF->getFixups().push_back( MCFixup::Create(DF->getContents().size(), Value, - MCFixup::getKindForSize(Size, false))); + MCFixup::getKindForSize(Size, false), Loc)); DF->getContents().resize(DF->getContents().size() + Size, 0); } diff --git a/lib/MC/MCObjectSymbolizer.cpp b/lib/MC/MCObjectSymbolizer.cpp index ba80d15..b149596 100644 --- a/lib/MC/MCObjectSymbolizer.cpp +++ b/lib/MC/MCObjectSymbolizer.cpp @@ -215,11 +215,11 @@ const SectionRef *MCObjectSymbolizer::findSectionContaining(uint64_t Addr) { It = std::lower_bound(SortedSections.begin(), EndIt, Addr, SectionStartsBefore); if (It == EndIt) - return 0; + return nullptr; uint64_t SAddr; It->getAddress(SAddr); uint64_t SSize; It->getSize(SSize); if (Addr >= SAddr + SSize) - return 0; + return nullptr; return &*It; } @@ -229,7 +229,7 @@ const RelocationRef *MCObjectSymbolizer::findRelocationAt(uint64_t Addr) { AddrToRelocMap::const_iterator RI = AddrToReloc.find(Addr); if (RI == AddrToReloc.end()) - return 0; + return nullptr; return &RI->second; } @@ -257,40 +257,12 @@ void MCObjectSymbolizer::buildSectionList() { void MCObjectSymbolizer::buildRelocationByAddrMap() { for (const SectionRef &Section : Obj->sections()) { - section_iterator RelSecI = Section.getRelocatedSection(); - if (RelSecI == Obj->section_end()) - continue; - - uint64_t StartAddr; RelSecI->getAddress(StartAddr); - uint64_t Size; RelSecI->getSize(Size); - bool RequiredForExec; - RelSecI->isRequiredForExecution(RequiredForExec); - if (RequiredForExec == false || Size == 0) - continue; for (const RelocationRef &Reloc : Section.relocations()) { - // FIXME: libObject is inconsistent regarding error handling. The - // overwhelming majority of methods always return object_error::success, - // and assert for simple errors.. Here, ELFObjectFile::getRelocationOffset - // asserts when the file type isn't ET_REL. - // This workaround handles x86-64 elf, the only one that has a relocinfo. - uint64_t Offset; - if (Obj->isELF()) { - const ELF64LEObjectFile *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj); - if (ELFObj == 0) - break; - if (ELFObj->getELFFile()->getHeader()->e_type == ELF::ET_REL) { - Reloc.getOffset(Offset); - Offset += StartAddr; - } else { - Reloc.getAddress(Offset); - } - } else { - Reloc.getOffset(Offset); - Offset += StartAddr; - } + uint64_t Address; + Reloc.getAddress(Address); // At a specific address, only keep the first relocation. - if (AddrToReloc.find(Offset) == AddrToReloc.end()) - AddrToReloc[Offset] = Reloc; + if (AddrToReloc.find(Address) == AddrToReloc.end()) + AddrToReloc[Address] = Reloc; } } } diff --git a/lib/MC/MCParser/AsmLexer.cpp b/lib/MC/MCParser/AsmLexer.cpp index a3b68d8..bca516e 100644 --- a/lib/MC/MCParser/AsmLexer.cpp +++ b/lib/MC/MCParser/AsmLexer.cpp @@ -22,8 +22,8 @@ using namespace llvm; AsmLexer::AsmLexer(const MCAsmInfo &_MAI) : MAI(_MAI) { - CurBuf = NULL; - CurPtr = NULL; + CurBuf = nullptr; + CurPtr = nullptr; isAtStartOfLine = true; AllowAtInIdentifier = !StringRef(MAI.getCommentString()).startswith("@"); } @@ -39,7 +39,7 @@ void AsmLexer::setBuffer(const MemoryBuffer *buf, const char *ptr) { else CurPtr = CurBuf->getBufferStart(); - TokStart = 0; + TokStart = nullptr; } /// ReturnError - Set the error to the specified string at the specified @@ -218,7 +218,7 @@ static void SkipIgnoredIntegerSuffix(const char *&CurPtr) { // Look ahead to search for first non-hex digit, if it's [hH], then we treat the // integer as a hexadecimal, possibly with leading zeroes. static unsigned doLookAhead(const char *&CurPtr, unsigned DefaultRadix) { - const char *FirstHex = 0; + const char *FirstHex = nullptr; const char *LookAhead = CurPtr; while (1) { if (isdigit(*LookAhead)) { diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index 910a424..168597f 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -39,6 +39,7 @@ #include "llvm/Support/SourceMgr.h" #include "llvm/Support/raw_ostream.h" #include <cctype> +#include <deque> #include <set> #include <string> #include <vector> @@ -59,8 +60,9 @@ struct MCAsmMacroParameter { StringRef Name; MCAsmMacroArgument Value; bool Required; + bool Vararg; - MCAsmMacroParameter() : Required(false) { } + MCAsmMacroParameter() : Required(false), Vararg(false) {} }; typedef std::vector<MCAsmMacroParameter> MCAsmMacroParameters; @@ -110,7 +112,7 @@ struct ParseStatementInfo { SmallVectorImpl<AsmRewrite> *AsmRewrites; - ParseStatementInfo() : Opcode(~0U), ParseError(false), AsmRewrites(0) {} + ParseStatementInfo() : Opcode(~0U), ParseError(false), AsmRewrites(nullptr) {} ParseStatementInfo(SmallVectorImpl<AsmRewrite> *rewrites) : Opcode(~0), ParseError(false), AsmRewrites(rewrites) {} @@ -292,7 +294,7 @@ private: void handleMacroExit(); /// \brief Extract AsmTokens for a macro argument. - bool parseMacroArgument(MCAsmMacroArgument &MA); + bool parseMacroArgument(MCAsmMacroArgument &MA, bool Vararg); /// \brief Parse all macro arguments for a given macro. bool parseMacroArguments(const MCAsmMacro *M, MCAsmMacroArguments &A); @@ -495,9 +497,9 @@ 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(0), CurBuffer(0), MacrosEnabledFlag(true), - CppHashLineNumber(0), AssemblerDialect(~0U), IsDarwin(false), - ParsingInlineAsm(false) { + PlatformParser(nullptr), CurBuffer(0), MacrosEnabledFlag(true), + HadError(false), CppHashLineNumber(0), AssemblerDialect(~0U), + IsDarwin(false), ParsingInlineAsm(false) { // Save the old handler. SavedDiagHandler = SrcMgr.getDiagHandler(); SavedDiagContext = SrcMgr.getDiagContext(); @@ -526,7 +528,8 @@ AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx, MCStreamer &_Out, } AsmParser::~AsmParser() { - assert(ActiveMacros.empty() && "Unexpected active macro instantiation!"); + assert((HadError || ActiveMacros.empty()) && + "Unexpected active macro instantiation!"); // Destroy any macros. for (StringMap<MCAsmMacro *>::iterator it = MacroMap.begin(), @@ -959,7 +962,7 @@ AsmParser::applyModifierToExpr(const MCExpr *E, switch (E->getKind()) { case MCExpr::Target: case MCExpr::Constant: - return 0; + return nullptr; case MCExpr::SymbolRef: { const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E); @@ -977,7 +980,7 @@ AsmParser::applyModifierToExpr(const MCExpr *E, const MCUnaryExpr *UE = cast<MCUnaryExpr>(E); const MCExpr *Sub = applyModifierToExpr(UE->getSubExpr(), Variant); if (!Sub) - return 0; + return nullptr; return MCUnaryExpr::Create(UE->getOpcode(), Sub, getContext()); } @@ -987,7 +990,7 @@ AsmParser::applyModifierToExpr(const MCExpr *E, const MCExpr *RHS = applyModifierToExpr(BE->getRHS(), Variant); if (!LHS && !RHS) - return 0; + return nullptr; if (!LHS) LHS = BE->getLHS(); @@ -1013,7 +1016,7 @@ AsmParser::applyModifierToExpr(const MCExpr *E, /// bool AsmParser::parseExpression(const MCExpr *&Res, SMLoc &EndLoc) { // Parse the expression. - Res = 0; + Res = nullptr; if (parsePrimaryExpr(Res, EndLoc) || parseBinOpRHS(1, Res, EndLoc)) return true; @@ -1050,7 +1053,7 @@ bool AsmParser::parseExpression(const MCExpr *&Res, SMLoc &EndLoc) { } bool AsmParser::parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) { - Res = 0; + Res = nullptr; return parseParenExpr(Res, EndLoc) || parseBinOpRHS(1, Res, EndLoc); } @@ -1701,7 +1704,7 @@ void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) { if (Parser->SavedDiagHandler) Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext); else - Diag.print(0, OS); + Diag.print(nullptr, OS); return; } @@ -1723,7 +1726,7 @@ void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) { if (Parser->SavedDiagHandler) Parser->SavedDiagHandler(NewDiag, Parser->SavedDiagContext); else - NewDiag.print(0, OS); + NewDiag.print(nullptr, OS); } // FIXME: This is mostly duplicated from the function in AsmLexer.cpp. The @@ -1739,6 +1742,7 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body, ArrayRef<MCAsmMacroParameter> Parameters, ArrayRef<MCAsmMacroArgument> A, const SMLoc &L) { unsigned NParameters = Parameters.size(); + bool HasVararg = NParameters ? Parameters.back().Vararg : false; if ((!IsDarwin || NParameters != 0) && NParameters != A.size()) return Error(L, "Wrong number of arguments"); @@ -1820,13 +1824,16 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body, Pos = I; } } else { + bool VarargParameter = HasVararg && Index == (NParameters - 1); for (MCAsmMacroArgument::const_iterator it = A[Index].begin(), ie = A[Index].end(); it != ie; ++it) - if (it->getKind() == AsmToken::String) - OS << it->getStringContents(); - else + // 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(); } @@ -1890,7 +1897,16 @@ private: }; } -bool AsmParser::parseMacroArgument(MCAsmMacroArgument &MA) { +bool AsmParser::parseMacroArgument(MCAsmMacroArgument &MA, bool Vararg) { + + if (Vararg) { + if (Lexer.isNot(AsmToken::EndOfStatement)) { + StringRef Str = parseStringToEndOfStatement(); + MA.push_back(AsmToken(AsmToken::String, Str)); + } + return false; + } + unsigned ParenLevel = 0; unsigned AddTokens = 0; @@ -1961,6 +1977,7 @@ bool AsmParser::parseMacroArguments(const MCAsmMacro *M, // Parse two kinds of macro invocations: // - macros defined without any parameters accept an arbitrary number of them // - macros defined with parameters accept at most that many of them + bool HasVararg = NParameters ? M->Parameters.back().Vararg : false; for (unsigned Parameter = 0; !NParameters || Parameter < NParameters; ++Parameter) { SMLoc IDLoc = Lexer.getLoc(); @@ -1989,7 +2006,8 @@ bool AsmParser::parseMacroArguments(const MCAsmMacro *M, return true; } - if (parseMacroArgument(FA.Value)) + bool Vararg = HasVararg && Parameter == (NParameters - 1); + if (parseMacroArgument(FA.Value, Vararg)) return true; unsigned PI = Parameter; @@ -2050,7 +2068,7 @@ bool AsmParser::parseMacroArguments(const MCAsmMacro *M, const MCAsmMacro *AsmParser::lookupMacro(StringRef Name) { StringMap<MCAsmMacro *>::iterator I = MacroMap.find(Name); - return (I == MacroMap.end()) ? NULL : I->getValue(); + return (I == MacroMap.end()) ? nullptr : I->getValue(); } void AsmParser::defineMacro(StringRef Name, const MCAsmMacro &Macro) { @@ -2364,7 +2382,7 @@ bool AsmParser::parseDirectiveValue(unsigned Size) { return Error(ExprLoc, "literal value out of range for directive"); getStreamer().EmitIntValue(IntValue, Size); } else - getStreamer().EmitValue(Value, Size); + getStreamer().EmitValue(Value, Size, ExprLoc); if (getLexer().is(AsmToken::EndOfStatement)) break; @@ -3240,6 +3258,12 @@ bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) { MCAsmMacroParameters Parameters; while (getLexer().isNot(AsmToken::EndOfStatement)) { + + if (Parameters.size() && Parameters.back().Vararg) + return Error(Lexer.getLoc(), + "Vararg parameter '" + Parameters.back().Name + + "' should be last one in the list of parameters."); + MCAsmMacroParameter Parameter; if (parseIdentifier(Parameter.Name)) return TokError("expected identifier in '.macro' directive"); @@ -3257,6 +3281,8 @@ bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) { if (Qualifier == "req") Parameter.Required = true; + else if (Qualifier == "vararg" && !IsDarwin) + Parameter.Vararg = true; else return Error(QualLoc, Qualifier + " is not a valid parameter qualifier " "for '" + Parameter.Name + "' in macro '" + Name + "'"); @@ -3268,7 +3294,7 @@ bool AsmParser::parseDirectiveMacro(SMLoc DirectiveLoc) { SMLoc ParamLoc; ParamLoc = Lexer.getLoc(); - if (parseMacroArgument(Parameter.Value)) + if (parseMacroArgument(Parameter.Value, /*Vararg=*/false )) return true; if (Parameter.Required) @@ -3906,9 +3932,9 @@ bool AsmParser::parseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) { MCSymbol *Sym = getContext().LookupSymbol(Name); if (expect_defined) - TheCondState.CondMet = (Sym != NULL && !Sym->isUndefined()); + TheCondState.CondMet = (Sym && !Sym->isUndefined()); else - TheCondState.CondMet = (Sym == NULL || Sym->isUndefined()); + TheCondState.CondMet = (!Sym || Sym->isUndefined()); TheCondState.Ignore = !TheCondState.CondMet; } @@ -4151,7 +4177,7 @@ MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) { // Check whether we have reached the end of the file. if (getLexer().is(AsmToken::Eof)) { Error(DirectiveLoc, "no matching '.endr' in definition"); - return 0; + return nullptr; } if (Lexer.is(AsmToken::Identifier) && @@ -4166,7 +4192,7 @@ MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) { Lex(); if (Lexer.isNot(AsmToken::EndOfStatement)) { TokError("unexpected token in '.endr' directive"); - return 0; + return nullptr; } break; } @@ -4260,7 +4286,7 @@ bool AsmParser::parseDirectiveIrp(SMLoc DirectiveLoc) { Lex(); MCAsmMacroArguments A; - if (parseMacroArguments(0, A)) + if (parseMacroArguments(nullptr, A)) return true; // Eat the end of statement. @@ -4300,7 +4326,7 @@ bool AsmParser::parseDirectiveIrpc(SMLoc DirectiveLoc) { Lex(); MCAsmMacroArguments A; - if (parseMacroArguments(0, A)) + if (parseMacroArguments(nullptr, A)) return true; if (A.size() != 1 || A.front().size() != 1) diff --git a/lib/MC/MCParser/COFFAsmParser.cpp b/lib/MC/MCParser/COFFAsmParser.cpp index 76d3f81..decf01c 100644 --- a/lib/MC/MCParser/COFFAsmParser.cpp +++ b/lib/MC/MCParser/COFFAsmParser.cpp @@ -293,7 +293,7 @@ bool COFFAsmParser::ParseSectionSwitch(StringRef Section, unsigned Characteristics, SectionKind Kind) { return ParseSectionSwitch(Section, Characteristics, Kind, "", - COFF::IMAGE_COMDAT_SELECT_ANY, 0); + COFF::IMAGE_COMDAT_SELECT_ANY, nullptr); } bool COFFAsmParser::ParseSectionSwitch(StringRef Section, @@ -359,7 +359,7 @@ bool COFFAsmParser::ParseDirectiveSection(StringRef, SMLoc) { } COFF::COMDATType Type = COFF::IMAGE_COMDAT_SELECT_ANY; - const MCSectionCOFF *Assoc = 0; + const MCSectionCOFF *Assoc = nullptr; StringRef COMDATSymName; if (getLexer().is(AsmToken::Comma)) { Lex(); @@ -504,7 +504,7 @@ bool COFFAsmParser::parseCOMDATTypeAndAssoc(COFF::COMDATType &Type, /// ::= .linkonce [ identifier [ identifier ] ] bool COFFAsmParser::ParseDirectiveLinkOnce(StringRef, SMLoc Loc) { COFF::COMDATType Type = COFF::IMAGE_COMDAT_SELECT_ANY; - const MCSectionCOFF *Assoc = 0; + const MCSectionCOFF *Assoc = nullptr; if (getLexer().is(AsmToken::Identifier)) if (parseCOMDATTypeAndAssoc(Type, Assoc)) return true; diff --git a/lib/MC/MCParser/DarwinAsmParser.cpp b/lib/MC/MCParser/DarwinAsmParser.cpp index 0856b6e..f74b30a 100644 --- a/lib/MC/MCParser/DarwinAsmParser.cpp +++ b/lib/MC/MCParser/DarwinAsmParser.cpp @@ -17,6 +17,7 @@ #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SourceMgr.h" using namespace llvm; @@ -612,8 +613,8 @@ bool DarwinAsmParser::parseDirectivePopSection(StringRef, SMLoc) { /// ::= .previous bool DarwinAsmParser::parseDirectivePrevious(StringRef DirName, SMLoc) { MCSectionSubPair PreviousSection = getStreamer().getPreviousSection(); - if (PreviousSection.first == NULL) - return TokError(".previous without corresponding .section"); + if (!PreviousSection.first) + return TokError(".previous without corresponding .section"); getStreamer().SwitchSection(PreviousSection.first, PreviousSection.second); return false; } @@ -630,13 +631,13 @@ bool DarwinAsmParser::parseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) { // Get the secure log path. const char *SecureLogFile = getContext().getSecureLogFile(); - if (SecureLogFile == NULL) + if (!SecureLogFile) return Error(IDLoc, ".secure_log_unique used but AS_SECURE_LOG_FILE " "environment variable unset."); // Open the secure log file if we haven't already. raw_ostream *OS = getContext().getSecureLog(); - if (OS == NULL) { + if (!OS) { std::string Err; OS = new raw_fd_ostream(SecureLogFile, Err, sys::fs::F_Append | sys::fs::F_Text); diff --git a/lib/MC/MCParser/ELFAsmParser.cpp b/lib/MC/MCParser/ELFAsmParser.cpp index d79dd67..95c4971 100644 --- a/lib/MC/MCParser/ELFAsmParser.cpp +++ b/lib/MC/MCParser/ELFAsmParser.cpp @@ -193,7 +193,7 @@ bool ELFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) { bool ELFAsmParser::ParseSectionSwitch(StringRef Section, unsigned Type, unsigned Flags, SectionKind Kind) { - const MCExpr *Subsection = 0; + const MCExpr *Subsection = nullptr; if (getLexer().isNot(AsmToken::EndOfStatement)) { if (getParser().parseExpression(Subsection)) return true; @@ -411,7 +411,7 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush) { int64_t Size = 0; StringRef GroupName; unsigned Flags = 0; - const MCExpr *Subsection = 0; + const MCExpr *Subsection = nullptr; bool UseLastGroup = false; // Set the defaults first. @@ -554,7 +554,7 @@ EndStmt: bool ELFAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) { MCSectionSubPair PreviousSection = getStreamer().getPreviousSection(); - if (PreviousSection.first == NULL) + if (PreviousSection.first == nullptr) return TokError(".previous without corresponding .section"); getStreamer().SwitchSection(PreviousSection.first, PreviousSection.second); @@ -730,7 +730,7 @@ bool ELFAsmParser::ParseDirectiveWeakref(StringRef, SMLoc) { } bool ELFAsmParser::ParseDirectiveSubsection(StringRef, SMLoc) { - const MCExpr *Subsection = 0; + const MCExpr *Subsection = nullptr; if (getLexer().isNot(AsmToken::EndOfStatement)) { if (getParser().parseExpression(Subsection)) return true; diff --git a/lib/MC/MCParser/MCAsmLexer.cpp b/lib/MC/MCParser/MCAsmLexer.cpp index 3867691..530814b 100644 --- a/lib/MC/MCParser/MCAsmLexer.cpp +++ b/lib/MC/MCParser/MCAsmLexer.cpp @@ -13,7 +13,7 @@ using namespace llvm; MCAsmLexer::MCAsmLexer() : CurTok(AsmToken::Error, StringRef()), - TokStart(0), SkipSpace(true) { + TokStart(nullptr), SkipSpace(true) { } MCAsmLexer::~MCAsmLexer() { diff --git a/lib/MC/MCParser/MCAsmParser.cpp b/lib/MC/MCParser/MCAsmParser.cpp index 6e1ebad..e417aa9 100644 --- a/lib/MC/MCParser/MCAsmParser.cpp +++ b/lib/MC/MCParser/MCAsmParser.cpp @@ -17,7 +17,7 @@ #include "llvm/Support/raw_ostream.h" using namespace llvm; -MCAsmParser::MCAsmParser() : TargetParser(0), ShowParsedOperands(0) { +MCAsmParser::MCAsmParser() : TargetParser(nullptr), ShowParsedOperands(0) { } MCAsmParser::~MCAsmParser() { diff --git a/lib/MC/MCRelocationInfo.cpp b/lib/MC/MCRelocationInfo.cpp index 7d2ec1f..a00c009 100644 --- a/lib/MC/MCRelocationInfo.cpp +++ b/lib/MC/MCRelocationInfo.cpp @@ -23,14 +23,14 @@ MCRelocationInfo::~MCRelocationInfo() { const MCExpr * MCRelocationInfo::createExprForRelocation(object::RelocationRef Rel) { - return 0; + return nullptr; } const MCExpr * MCRelocationInfo::createExprForCAPIVariantKind(const MCExpr *SubExpr, unsigned VariantKind) { if (VariantKind != LLVMDisassembler_VariantKind_None) - return 0; + return nullptr; return SubExpr; } diff --git a/lib/MC/MCSectionCOFF.cpp b/lib/MC/MCSectionCOFF.cpp index ad9ca88..335b8cd 100644 --- a/lib/MC/MCSectionCOFF.cpp +++ b/lib/MC/MCSectionCOFF.cpp @@ -34,7 +34,7 @@ void MCSectionCOFF::setSelection(int Selection, const MCSectionCOFF *Assoc) const { assert(Selection != 0 && "invalid COMDAT selection type"); assert((Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) == - (Assoc != 0) && + (Assoc != nullptr) && "associative COMDAT section must have an associated section"); this->Selection = Selection; this->Assoc = Assoc; @@ -62,7 +62,8 @@ void MCSectionCOFF::PrintSwitchToSection(const MCAsmInfo &MAI, OS << 'r'; if (getCharacteristics() & COFF::IMAGE_SCN_MEM_DISCARDABLE) OS << 'n'; - + if (getCharacteristics() & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA) + OS << 'd'; OS << '"'; if (getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) { diff --git a/lib/MC/MCSectionMachO.cpp b/lib/MC/MCSectionMachO.cpp index 9cc534d..46beda4 100644 --- a/lib/MC/MCSectionMachO.cpp +++ b/lib/MC/MCSectionMachO.cpp @@ -20,7 +20,7 @@ static const struct { const char *AssemblerName, *EnumName; } SectionTypeDescriptors[MachO::LAST_KNOWN_SECTION_TYPE+1] = { { "regular", "S_REGULAR" }, // 0x00 - { 0, "S_ZEROFILL" }, // 0x01 + { nullptr, "S_ZEROFILL" }, // 0x01 { "cstring_literals", "S_CSTRING_LITERALS" }, // 0x02 { "4byte_literals", "S_4BYTE_LITERALS" }, // 0x03 { "8byte_literals", "S_8BYTE_LITERALS" }, // 0x04 @@ -31,11 +31,11 @@ static const struct { { "mod_init_funcs", "S_MOD_INIT_FUNC_POINTERS" }, // 0x09 { "mod_term_funcs", "S_MOD_TERM_FUNC_POINTERS" }, // 0x0A { "coalesced", "S_COALESCED" }, // 0x0B - { 0, /*FIXME??*/ "S_GB_ZEROFILL" }, // 0x0C + { nullptr, /*FIXME??*/ "S_GB_ZEROFILL" }, // 0x0C { "interposing", "S_INTERPOSING" }, // 0x0D { "16byte_literals", "S_16BYTE_LITERALS" }, // 0x0E - { 0, /*FIXME??*/ "S_DTRACE_DOF" }, // 0x0F - { 0, /*FIXME??*/ "S_LAZY_DYLIB_SYMBOL_POINTERS" }, // 0x10 + { nullptr, /*FIXME??*/ "S_DTRACE_DOF" }, // 0x0F + { nullptr, /*FIXME??*/ "S_LAZY_DYLIB_SYMBOL_POINTERS" }, // 0x10 { "thread_local_regular", "S_THREAD_LOCAL_REGULAR" }, // 0x11 { "thread_local_zerofill", "S_THREAD_LOCAL_ZEROFILL" }, // 0x12 { "thread_local_variables", "S_THREAD_LOCAL_VARIABLES" }, // 0x13 @@ -62,11 +62,11 @@ ENTRY("no_dead_strip", S_ATTR_NO_DEAD_STRIP) ENTRY("live_support", S_ATTR_LIVE_SUPPORT) ENTRY("self_modifying_code", S_ATTR_SELF_MODIFYING_CODE) ENTRY("debug", S_ATTR_DEBUG) -ENTRY(0 /*FIXME*/, S_ATTR_SOME_INSTRUCTIONS) -ENTRY(0 /*FIXME*/, S_ATTR_EXT_RELOC) -ENTRY(0 /*FIXME*/, S_ATTR_LOC_RELOC) +ENTRY(nullptr /*FIXME*/, S_ATTR_SOME_INSTRUCTIONS) +ENTRY(nullptr /*FIXME*/, S_ATTR_EXT_RELOC) +ENTRY(nullptr /*FIXME*/, S_ATTR_LOC_RELOC) #undef ENTRY - { 0, "none", 0 }, // used if section has no attributes but has a stub size + { 0, "none", nullptr }, // used if section has no attributes but has a stub size }; MCSectionMachO::MCSectionMachO(StringRef Segment, StringRef Section, diff --git a/lib/MC/MCStreamer.cpp b/lib/MC/MCStreamer.cpp index 8fa55aa..7dccf0d 100644 --- a/lib/MC/MCStreamer.cpp +++ b/lib/MC/MCStreamer.cpp @@ -37,8 +37,7 @@ void MCTargetStreamer::finish() {} void MCTargetStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {} MCStreamer::MCStreamer(MCContext &Ctx) - : Context(Ctx), EmitEHFrame(true), EmitDebugFrame(false), - CurrentW64UnwindInfo(0), LastSymbol(0) { + : Context(Ctx), CurrentW64UnwindInfo(nullptr), LastSymbol(nullptr) { SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>()); } @@ -51,10 +50,8 @@ void MCStreamer::reset() { for (unsigned i = 0; i < getNumW64UnwindInfos(); ++i) delete W64UnwindInfos[i]; W64UnwindInfos.clear(); - EmitEHFrame = true; - EmitDebugFrame = false; - CurrentW64UnwindInfo = 0; - LastSymbol = 0; + CurrentW64UnwindInfo = nullptr; + LastSymbol = nullptr; SectionStack.clear(); SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>()); } @@ -147,8 +144,9 @@ void MCStreamer::EmitAbsValue(const MCExpr *Value, unsigned Size) { } -void MCStreamer::EmitValue(const MCExpr *Value, unsigned Size) { - EmitValueImpl(Value, Size); +void MCStreamer::EmitValue(const MCExpr *Value, unsigned Size, + const SMLoc &Loc) { + EmitValueImpl(Value, Size, Loc); } void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size) { @@ -203,7 +201,7 @@ MCSymbol *MCStreamer::getDwarfLineTableSymbol(unsigned CUID) { MCDwarfFrameInfo *MCStreamer::getCurrentFrameInfo() { if (FrameInfos.empty()) - return 0; + return nullptr; return &FrameInfos.back(); } @@ -258,8 +256,6 @@ void MCStreamer::EmitCompactUnwindEncoding(uint32_t CompactUnwindEncoding) { void MCStreamer::EmitCFISections(bool EH, bool Debug) { assert(EH || Debug); - EmitEHFrame = EH; - EmitDebugFrame = Debug; } void MCStreamer::EmitCFIStartProc(bool IsSimple) { @@ -278,6 +274,10 @@ void MCStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) { } void MCStreamer::RecordProcStart(MCDwarfFrameInfo &Frame) { + // Report an error if we haven't seen a symbol yet where we'd bind + // .cfi_startproc. + if (!LastSymbol) + report_fatal_error("No symbol to start a frame"); Frame.Function = LastSymbol; // We need to create a local symbol to avoid relocations. Frame.Begin = getContext().CreateTempSymbol(); @@ -610,17 +610,6 @@ void MCStreamer::EmitRawText(const Twine &T) { EmitRawTextImpl(T.toStringRef(Str)); } -void MCStreamer::EmitFrames(MCAsmBackend *MAB, bool usingCFI) { - if (!getNumFrameInfos()) - return; - - if (EmitEHFrame) - MCDwarfFrameEmitter::Emit(*this, MAB, usingCFI, true); - - if (EmitDebugFrame) - MCDwarfFrameEmitter::Emit(*this, MAB, usingCFI, false); -} - void MCStreamer::EmitW64Tables() { if (!getNumW64UnwindInfos()) return; @@ -639,11 +628,6 @@ void MCStreamer::Finish() { FinishImpl(); } -MCSymbolData &MCStreamer::getOrCreateSymbolData(const MCSymbol *Symbol) { - report_fatal_error("Not supported!"); - return *(static_cast<MCSymbolData*>(0)); -} - void MCStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { Symbol->setVariableValue(Value); diff --git a/lib/MC/MCSubtargetInfo.cpp b/lib/MC/MCSubtargetInfo.cpp index 8d8e290..4424c91 100644 --- a/lib/MC/MCSubtargetInfo.cpp +++ b/lib/MC/MCSubtargetInfo.cpp @@ -24,9 +24,7 @@ MCSchedModel MCSchedModel::DefaultSchedModel; // For unknown processors. void MCSubtargetInfo::InitMCProcessorInfo(StringRef CPU, StringRef FS) { SubtargetFeatures Features(FS); - FeatureBits = Features.getFeatureBits(CPU, ProcDesc, NumProcs, - ProcFeatures, NumFeatures); - + FeatureBits = Features.getFeatureBits(CPU, ProcDesc, ProcFeatures); InitCPUSchedModel(CPU); } @@ -40,16 +38,15 @@ MCSubtargetInfo::InitCPUSchedModel(StringRef CPU) { void MCSubtargetInfo::InitMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS, - const SubtargetFeatureKV *PF, - const SubtargetFeatureKV *PD, + ArrayRef<SubtargetFeatureKV> PF, + ArrayRef<SubtargetFeatureKV> PD, const SubtargetInfoKV *ProcSched, const MCWriteProcResEntry *WPR, const MCWriteLatencyEntry *WL, const MCReadAdvanceEntry *RA, const InstrStage *IS, const unsigned *OC, - const unsigned *FP, - unsigned NF, unsigned NP) { + const unsigned *FP) { TargetTriple = TT; ProcFeatures = PF; ProcDesc = PD; @@ -61,8 +58,6 @@ MCSubtargetInfo::InitMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS, Stages = IS; OperandCycles = OC; ForwardingPaths = FP; - NumFeatures = NF; - NumProcs = NP; InitMCProcessorInfo(CPU, FS); } @@ -78,8 +73,7 @@ uint64_t MCSubtargetInfo::ToggleFeature(uint64_t FB) { /// bits. This version will also change all implied bits. uint64_t MCSubtargetInfo::ToggleFeature(StringRef FS) { SubtargetFeatures Features; - FeatureBits = Features.ToggleFeature(FeatureBits, FS, - ProcFeatures, NumFeatures); + FeatureBits = Features.ToggleFeature(FeatureBits, FS, ProcFeatures); return FeatureBits; } @@ -88,6 +82,7 @@ const MCSchedModel * MCSubtargetInfo::getSchedModelForCPU(StringRef CPU) const { assert(ProcSchedModels && "Processor machine model not available!"); + unsigned NumProcs = ProcDesc.size(); #ifndef NDEBUG for (size_t i = 1; i < NumProcs; i++) { assert(strcmp(ProcSchedModels[i - 1].Key, ProcSchedModels[i].Key) < 0 && diff --git a/lib/MC/MCTargetOptions.cpp b/lib/MC/MCTargetOptions.cpp new file mode 100644 index 0000000..8e946d5 --- /dev/null +++ b/lib/MC/MCTargetOptions.cpp @@ -0,0 +1,19 @@ +//===- lib/MC/MCTargetOptions.cpp - MC Target Options --------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/MC/MCTargetOptions.h" + +namespace llvm { + +MCTargetOptions::MCTargetOptions() + : SanitizeAddress(false), MCRelaxAll(false), MCNoExecStack(false), + MCSaveTempLabels(false), MCUseDwarfDirectory(false), + ShowMCEncoding(false), ShowMCInst(false), AsmVerbose(false) {} + +} // end namespace llvm diff --git a/lib/MC/MCValue.cpp b/lib/MC/MCValue.cpp index 68ecffb..9dfc56e 100644 --- a/lib/MC/MCValue.cpp +++ b/lib/MC/MCValue.cpp @@ -10,6 +10,7 @@ #include "llvm/MC/MCValue.h" #include "llvm/MC/MCExpr.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -38,6 +39,23 @@ void MCValue::print(raw_ostream &OS, const MCAsmInfo *MAI) const { #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) void MCValue::dump() const { - print(dbgs(), 0); + print(dbgs(), nullptr); } #endif + +MCSymbolRefExpr::VariantKind MCValue::getAccessVariant() const { + const MCSymbolRefExpr *B = getSymB(); + if (B) { + if (B->getKind() != MCSymbolRefExpr::VK_None) + llvm_unreachable("unsupported"); + } + + const MCSymbolRefExpr *A = getSymA(); + if (!A) + return MCSymbolRefExpr::VK_None; + + MCSymbolRefExpr::VariantKind Kind = A->getKind(); + if (Kind == MCSymbolRefExpr::VK_WEAKREF) + return MCSymbolRefExpr::VK_None; + return Kind; +} diff --git a/lib/MC/MachObjectWriter.cpp b/lib/MC/MachObjectWriter.cpp index 5fcea5f..cbaf0b8 100644 --- a/lib/MC/MachObjectWriter.cpp +++ b/lib/MC/MachObjectWriter.cpp @@ -26,6 +26,8 @@ #include <vector> using namespace llvm; +#define DEBUG_TYPE "mc" + void MachObjectWriter::reset() { Relocations.clear(); IndirectSymBase.clear(); @@ -349,6 +351,9 @@ void MachObjectWriter::WriteNlist(MachSymbolData &MSD, } } + if (Layout.getAssembler().isThumbFunc(&Symbol)) + Flags |= SF_ThumbFunc; + // struct nlist (12 bytes) Write32(MSD.StringIndex); @@ -516,15 +521,14 @@ ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable, // table, 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 (MCAssembler::symbol_iterator it = Asm.symbol_begin(), - ie = Asm.symbol_end(); it != ie; ++it) { - const MCSymbol &Symbol = it->getSymbol(); + for (MCSymbolData &SD : Asm.symbols()) { + const MCSymbol &Symbol = SD.getSymbol(); // Ignore non-linker visible symbols. - if (!Asm.isSymbolLinkerVisible(it->getSymbol())) + if (!Asm.isSymbolLinkerVisible(SD.getSymbol())) continue; - if (!it->isExternal() && !Symbol.isUndefined()) + if (!SD.isExternal() && !Symbol.isUndefined()) continue; uint64_t &Entry = StringIndexMap[Symbol.getName()]; @@ -535,7 +539,7 @@ ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable, } MachSymbolData MSD; - MSD.SymbolData = it; + MSD.SymbolData = &SD; MSD.StringIndex = Entry; if (Symbol.isUndefined()) { @@ -552,15 +556,14 @@ ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable, } // Now add the data for local symbols. - for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), - ie = Asm.symbol_end(); it != ie; ++it) { - const MCSymbol &Symbol = it->getSymbol(); + for (MCSymbolData &SD : Asm.symbols()) { + const MCSymbol &Symbol = SD.getSymbol(); // Ignore non-linker visible symbols. - if (!Asm.isSymbolLinkerVisible(it->getSymbol())) + if (!Asm.isSymbolLinkerVisible(SD.getSymbol())) continue; - if (it->isExternal() || Symbol.isUndefined()) + if (SD.isExternal() || Symbol.isUndefined()) continue; uint64_t &Entry = StringIndexMap[Symbol.getName()]; @@ -571,7 +574,7 @@ ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable, } MachSymbolData MSD; - MSD.SymbolData = it; + MSD.SymbolData = &SD; MSD.StringIndex = Entry; if (Symbol.isAbsolute()) { @@ -621,10 +624,7 @@ void MachObjectWriter::computeSectionAddresses(const MCAssembler &Asm, void MachObjectWriter::markAbsoluteVariableSymbols(MCAssembler &Asm, const MCAsmLayout &Layout) { - for (MCAssembler::symbol_iterator i = Asm.symbol_begin(), - e = Asm.symbol_end(); - i != e; ++i) { - MCSymbolData &SD = *i; + for (MCSymbolData &SD : Asm.symbols()) { if (!SD.getSymbol().isVariable()) continue; @@ -669,7 +669,7 @@ 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 = 0, *B_Base = 0; + const MCSymbolData *A_Base = nullptr, *B_Base = nullptr; const MCSymbol &SA = DataA.getSymbol().AliasedSymbol(); const MCSection &SecA = SA.getSection(); diff --git a/lib/MC/SubtargetFeature.cpp b/lib/MC/SubtargetFeature.cpp index 2fb91f2..27525c7 100644 --- a/lib/MC/SubtargetFeature.cpp +++ b/lib/MC/SubtargetFeature.cpp @@ -51,40 +51,12 @@ static inline bool isEnabled(const StringRef Feature) { return Ch == '+'; } -/// PrependFlag - Return a string with a prepended flag; '+' or '-'. -/// -static inline std::string PrependFlag(const StringRef Feature, - bool IsEnabled) { - assert(!Feature.empty() && "Empty string"); - if (hasFlag(Feature)) - return Feature; - std::string Prefix = IsEnabled ? "+" : "-"; - Prefix += Feature; - return Prefix; -} - /// Split - Splits a string of comma separated items in to a vector of strings. /// static void Split(std::vector<std::string> &V, const StringRef S) { - if (S.empty()) - return; - - // Start at beginning of string. - size_t Pos = 0; - while (true) { - // Find the next comma - size_t Comma = S.find(',', Pos); - // If no comma found then the rest of the string is used - if (Comma == std::string::npos) { - // Add string to vector - V.push_back(S.substr(Pos)); - break; - } - // Otherwise add substring to vector - V.push_back(S.substr(Pos, Comma - Pos)); - // Advance to next item - Pos = Comma + 1; - } + SmallVector<StringRef, 2> Tmp; + S.split(Tmp, ",", -1, false /* KeepEmpty */); + V.assign(Tmp.begin(), Tmp.end()); } /// Join a vector of strings to a string with a comma separating each element. @@ -109,63 +81,55 @@ static std::string Join(const std::vector<std::string> &V) { } /// Adding features. -void SubtargetFeatures::AddFeature(const StringRef String, - bool IsEnabled) { - // Don't add empty features - if (!String.empty()) { - // Convert to lowercase, prepend flag and add to vector - Features.push_back(PrependFlag(String.lower(), IsEnabled)); - } +void SubtargetFeatures::AddFeature(const StringRef String) { + // Don't add empty features or features we already have. + 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()); } /// Find KV in array using binary search. -static const SubtargetFeatureKV *Find(StringRef S, const SubtargetFeatureKV *A, - size_t L) { - // Determine the end of the array - const SubtargetFeatureKV *Hi = A + L; +static const SubtargetFeatureKV *Find(StringRef S, + ArrayRef<SubtargetFeatureKV> A) { // Binary search the array - const SubtargetFeatureKV *F = std::lower_bound(A, Hi, S); + auto F = std::lower_bound(A.begin(), A.end(), S); // If not found then return NULL - if (F == Hi || StringRef(F->Key) != S) return NULL; + if (F == A.end() || StringRef(F->Key) != S) return nullptr; // Return the found array item return F; } /// getLongestEntryLength - Return the length of the longest entry in the table. /// -static size_t getLongestEntryLength(const SubtargetFeatureKV *Table, - size_t Size) { +static size_t getLongestEntryLength(ArrayRef<SubtargetFeatureKV> Table) { size_t MaxLen = 0; - for (size_t i = 0; i < Size; i++) - MaxLen = std::max(MaxLen, std::strlen(Table[i].Key)); + for (auto &I : Table) + MaxLen = std::max(MaxLen, std::strlen(I.Key)); return MaxLen; } /// Display help for feature choices. /// -static void Help(const SubtargetFeatureKV *CPUTable, size_t CPUTableSize, - const SubtargetFeatureKV *FeatTable, size_t FeatTableSize) { +static void Help(ArrayRef<SubtargetFeatureKV> CPUTable, + ArrayRef<SubtargetFeatureKV> FeatTable) { // Determine the length of the longest CPU and Feature entries. - unsigned MaxCPULen = getLongestEntryLength(CPUTable, CPUTableSize); - unsigned MaxFeatLen = getLongestEntryLength(FeatTable, FeatTableSize); + unsigned MaxCPULen = getLongestEntryLength(CPUTable); + unsigned MaxFeatLen = getLongestEntryLength(FeatTable); // Print the CPU table. errs() << "Available CPUs for this target:\n\n"; - for (size_t i = 0; i != CPUTableSize; i++) - errs() << format(" %-*s - %s.\n", - MaxCPULen, CPUTable[i].Key, CPUTable[i].Desc); + for (auto &CPU : CPUTable) + errs() << format(" %-*s - %s.\n", MaxCPULen, CPU.Key, CPU.Desc); errs() << '\n'; // Print the Feature table. errs() << "Available features for this target:\n\n"; - for (size_t i = 0; i != FeatTableSize; i++) - errs() << format(" %-*s - %s.\n", - MaxFeatLen, FeatTable[i].Key, FeatTable[i].Desc); + for (auto &Feature : FeatTable) + errs() << format(" %-*s - %s.\n", MaxFeatLen, Feature.Key, Feature.Desc); errs() << '\n'; errs() << "Use +feature to enable a feature, or -feature to disable it.\n" "For example, llc -mcpu=mycpu -mattr=+feature1,-feature2\n"; - std::exit(1); } //===----------------------------------------------------------------------===// @@ -187,16 +151,13 @@ std::string SubtargetFeatures::getString() const { /// static void SetImpliedBits(uint64_t &Bits, const SubtargetFeatureKV *FeatureEntry, - const SubtargetFeatureKV *FeatureTable, - size_t FeatureTableSize) { - for (size_t i = 0; i < FeatureTableSize; ++i) { - const SubtargetFeatureKV &FE = FeatureTable[i]; - + ArrayRef<SubtargetFeatureKV> FeatureTable) { + for (auto &FE : FeatureTable) { if (FeatureEntry->Value == FE.Value) continue; if (FeatureEntry->Implies & FE.Value) { Bits |= FE.Value; - SetImpliedBits(Bits, &FE, FeatureTable, FeatureTableSize); + SetImpliedBits(Bits, &FE, FeatureTable); } } } @@ -206,16 +167,13 @@ void SetImpliedBits(uint64_t &Bits, const SubtargetFeatureKV *FeatureEntry, /// static void ClearImpliedBits(uint64_t &Bits, const SubtargetFeatureKV *FeatureEntry, - const SubtargetFeatureKV *FeatureTable, - size_t FeatureTableSize) { - for (size_t i = 0; i < FeatureTableSize; ++i) { - const SubtargetFeatureKV &FE = FeatureTable[i]; - + ArrayRef<SubtargetFeatureKV> FeatureTable) { + for (auto &FE : FeatureTable) { if (FeatureEntry->Value == FE.Value) continue; if (FE.Implies & FeatureEntry->Value) { Bits &= ~FE.Value; - ClearImpliedBits(Bits, &FE, FeatureTable, FeatureTableSize); + ClearImpliedBits(Bits, &FE, FeatureTable); } } } @@ -224,23 +182,23 @@ void ClearImpliedBits(uint64_t &Bits, const SubtargetFeatureKV *FeatureEntry, /// bits. uint64_t SubtargetFeatures::ToggleFeature(uint64_t Bits, const StringRef Feature, - const SubtargetFeatureKV *FeatureTable, - size_t FeatureTableSize) { + ArrayRef<SubtargetFeatureKV> FeatureTable) { + // Find feature in table. const SubtargetFeatureKV *FeatureEntry = - Find(StripFlag(Feature), FeatureTable, FeatureTableSize); + Find(StripFlag(Feature), FeatureTable); // If there is a match if (FeatureEntry) { if ((Bits & FeatureEntry->Value) == FeatureEntry->Value) { Bits &= ~FeatureEntry->Value; // For each feature that implies this, clear it. - ClearImpliedBits(Bits, FeatureEntry, FeatureTable, FeatureTableSize); + ClearImpliedBits(Bits, FeatureEntry, FeatureTable); } else { Bits |= FeatureEntry->Value; // For each feature that this implies, set it. - SetImpliedBits(Bits, FeatureEntry, FeatureTable, FeatureTableSize); + SetImpliedBits(Bits, FeatureEntry, FeatureTable); } } else { errs() << "'" << Feature @@ -254,20 +212,20 @@ SubtargetFeatures::ToggleFeature(uint64_t Bits, const StringRef Feature, /// getFeatureBits - Get feature bits a CPU. /// -uint64_t SubtargetFeatures::getFeatureBits(const StringRef CPU, - const SubtargetFeatureKV *CPUTable, - size_t CPUTableSize, - const SubtargetFeatureKV *FeatureTable, - size_t FeatureTableSize) { - if (!FeatureTableSize || !CPUTableSize) +uint64_t +SubtargetFeatures::getFeatureBits(const StringRef CPU, + ArrayRef<SubtargetFeatureKV> CPUTable, + ArrayRef<SubtargetFeatureKV> FeatureTable) { + + if (CPUTable.empty() || FeatureTable.empty()) return 0; #ifndef NDEBUG - for (size_t i = 1; i < CPUTableSize; i++) { + for (size_t i = 1, e = CPUTable.size(); i != e; ++i) { assert(strcmp(CPUTable[i - 1].Key, CPUTable[i].Key) < 0 && "CPU table is not sorted"); } - for (size_t i = 1; i < FeatureTableSize; i++) { + for (size_t i = 1, e = FeatureTable.size(); i != e; ++i) { assert(strcmp(FeatureTable[i - 1].Key, FeatureTable[i].Key) < 0 && "CPU features table is not sorted"); } @@ -276,21 +234,21 @@ uint64_t SubtargetFeatures::getFeatureBits(const StringRef CPU, // Check if help is needed if (CPU == "help") - Help(CPUTable, CPUTableSize, FeatureTable, FeatureTableSize); + Help(CPUTable, FeatureTable); // Find CPU entry if CPU name is specified. - if (!CPU.empty()) { - const SubtargetFeatureKV *CPUEntry = Find(CPU, CPUTable, CPUTableSize); + else if (!CPU.empty()) { + const SubtargetFeatureKV *CPUEntry = Find(CPU, CPUTable); + // If there is a match if (CPUEntry) { // Set base feature bits Bits = CPUEntry->Value; // Set the feature implied by this CPU feature, if any. - for (size_t i = 0; i < FeatureTableSize; ++i) { - const SubtargetFeatureKV &FE = FeatureTable[i]; + for (auto &FE : FeatureTable) { if (CPUEntry->Value & FE.Value) - SetImpliedBits(Bits, &FE, FeatureTable, FeatureTableSize); + SetImpliedBits(Bits, &FE, FeatureTable); } } else { errs() << "'" << CPU @@ -300,16 +258,14 @@ uint64_t SubtargetFeatures::getFeatureBits(const StringRef CPU, } // Iterate through each feature - for (size_t i = 0, E = Features.size(); i < E; i++) { - const StringRef Feature = Features[i]; - + for (auto &Feature : Features) { // Check for help if (Feature == "+help") - Help(CPUTable, CPUTableSize, FeatureTable, FeatureTableSize); + Help(CPUTable, FeatureTable); // Find feature in table. const SubtargetFeatureKV *FeatureEntry = - Find(StripFlag(Feature), FeatureTable, FeatureTableSize); + Find(StripFlag(Feature), FeatureTable); // If there is a match if (FeatureEntry) { // Enable/disable feature in bits @@ -317,12 +273,12 @@ uint64_t SubtargetFeatures::getFeatureBits(const StringRef CPU, Bits |= FeatureEntry->Value; // For each feature that this implies, set it. - SetImpliedBits(Bits, FeatureEntry, FeatureTable, FeatureTableSize); + SetImpliedBits(Bits, FeatureEntry, FeatureTable); } else { Bits &= ~FeatureEntry->Value; // For each feature that implies this, clear it. - ClearImpliedBits(Bits, FeatureEntry, FeatureTable, FeatureTableSize); + ClearImpliedBits(Bits, FeatureEntry, FeatureTable); } } else { errs() << "'" << Feature @@ -337,8 +293,8 @@ uint64_t SubtargetFeatures::getFeatureBits(const StringRef CPU, /// print - Print feature string. /// void SubtargetFeatures::print(raw_ostream &OS) const { - for (size_t i = 0, e = Features.size(); i != e; ++i) - OS << Features[i] << " "; + for (auto &F : Features) + OS << F << " "; OS << "\n"; } diff --git a/lib/MC/WinCOFFObjectWriter.cpp b/lib/MC/WinCOFFObjectWriter.cpp index 500acd8..961cbc6 100644 --- a/lib/MC/WinCOFFObjectWriter.cpp +++ b/lib/MC/WinCOFFObjectWriter.cpp @@ -11,12 +11,11 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "WinCOFFObjectWriter" - #include "llvm/MC/MCWinCOFFObjectWriter.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Twine.h" #include "llvm/MC/MCAsmLayout.h" #include "llvm/MC/MCAssembler.h" @@ -35,6 +34,8 @@ using namespace llvm; +#define DEBUG_TYPE "WinCOFFObjectWriter" + namespace { typedef SmallString<COFF::NameSize> name; @@ -81,7 +82,7 @@ struct COFFRelocation { COFF::relocation Data; COFFSymbol *Symb; - COFFRelocation() : Symb(NULL) {} + COFFRelocation() : Symb(nullptr) {} static size_t size() { return COFF::RelocationSize; } }; @@ -118,8 +119,8 @@ public: class WinCOFFObjectWriter : public MCObjectWriter { public: - typedef std::vector<COFFSymbol*> symbols; - typedef std::vector<COFFSection*> sections; + 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<MCSection const *, COFFSection *> section_map; @@ -137,7 +138,6 @@ public: symbol_map SymbolMap; WinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW, raw_ostream &OS); - virtual ~WinCOFFObjectWriter(); COFFSymbol *createSymbol(StringRef Name); COFFSymbol *GetOrCreateCOFFSymbol(const MCSymbol * Symbol); @@ -160,7 +160,7 @@ public: // Entity writing methods. void WriteFileHeader(const COFF::header &Header); - void WriteSymbol(const COFFSymbol *S); + void WriteSymbol(const COFFSymbol &S); void WriteAuxiliarySymbols(const COFFSymbol::AuxiliarySymbols &S); void WriteSectionHeader(const COFF::section &S); void WriteRelocation(const COFF::relocation &R); @@ -192,10 +192,10 @@ static inline void write_uint32_le(void *Data, uint32_t const &Value) { COFFSymbol::COFFSymbol(StringRef name) : Name(name.begin(), name.end()) - , Other(NULL) - , Section(NULL) + , Other(nullptr) + , Section(nullptr) , Relocations(0) - , MCData(NULL) { + , MCData(nullptr) { memset(&Data, 0, sizeof(Data)); } @@ -214,7 +214,7 @@ void COFFSymbol::set_name_offset(uint32_t Offset) { /// logic to decide if the symbol should be reported in the symbol table bool COFFSymbol::should_keep() const { // no section means its external, keep it - if (Section == NULL) + if (!Section) return true; // if it has relocations pointing at it, keep it @@ -244,8 +244,8 @@ bool COFFSymbol::should_keep() const { COFFSection::COFFSection(StringRef name) : Name(name) - , MCData(NULL) - , Symbol(NULL) { + , MCData(nullptr) + , Symbol(nullptr) { memset(&Header, 0, sizeof(Header)); } @@ -308,13 +308,6 @@ WinCOFFObjectWriter::WinCOFFObjectWriter(MCWinCOFFObjectTargetWriter *MOTW, Header.Machine = TargetObjectWriter->getMachine(); } -WinCOFFObjectWriter::~WinCOFFObjectWriter() { - for (symbols::iterator I = Symbols.begin(), E = Symbols.end(); I != E; ++I) - delete *I; - for (sections::iterator I = Sections.begin(), E = Sections.end(); I != E; ++I) - delete *I; -} - COFFSymbol *WinCOFFObjectWriter::createSymbol(StringRef Name) { return createCOFFEntity<COFFSymbol>(Name, Symbols); } @@ -338,11 +331,9 @@ COFFSection *WinCOFFObjectWriter::createSection(StringRef Name) { template <typename object_t, typename list_t> object_t *WinCOFFObjectWriter::createCOFFEntity(StringRef Name, list_t &List) { - object_t *Object = new object_t(Name); - - List.push_back(Object); + List.push_back(make_unique<object_t>(Name)); - return Object; + return List.back().get(); } /// This function takes a section data object from the assembler @@ -394,7 +385,19 @@ void WinCOFFObjectWriter::DefineSection(MCSectionData const &SectionData) { SectionMap[&SectionData.getSection()] = coff_section; } -/// This function takes a section data object from the assembler +static uint64_t getSymbolValue(const MCSymbolData &Data, + const MCAsmLayout &Layout) { + if (Data.isCommon() && Data.isExternal()) + return Data.getCommonSize(); + + uint64_t Res; + if (!Layout.getSymbolOffset(&Data, Res)) + return 0; + + return Res; +} + +/// This function takes a symbol data object from the assembler /// and creates the associated COFF symbol staging object. void WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData, MCAssembler &Assembler, @@ -436,31 +439,29 @@ void WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData, coff_symbol->MCData = &SymbolData; } else { - const MCSymbolData &ResSymData = - Assembler.getSymbolData(Symbol.AliasedSymbol()); - - if (Symbol.isVariable()) { - int64_t Addr; - if (Symbol.getVariableValue()->EvaluateAsAbsolute(Addr, Layout)) - coff_symbol->Data.Value = Addr; - } + const MCSymbolData &ResSymData = Assembler.getSymbolData(Symbol); + const MCSymbol *Base = Layout.getBaseSymbol(Symbol); + coff_symbol->Data.Value = getSymbolValue(ResSymData, Layout); 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 external = ResSymData.isExternal() || (ResSymData.Fragment == NULL); + bool external = ResSymData.isExternal() || !ResSymData.Fragment; coff_symbol->Data.StorageClass = external ? COFF::IMAGE_SYM_CLASS_EXTERNAL : COFF::IMAGE_SYM_CLASS_STATIC; } - if (Symbol.isAbsolute() || Symbol.AliasedSymbol().isVariable()) + if (!Base) { coff_symbol->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE; - else if (ResSymData.Fragment != NULL) - coff_symbol->Section = - SectionMap[&ResSymData.Fragment->getParent()->getSection()]; + } else { + const MCSymbolData &BaseData = Assembler.getSymbolData(*Base); + if (BaseData.Fragment) + coff_symbol->Section = + SectionMap[&BaseData.Fragment->getParent()->getSection()]; + } coff_symbol->MCData = &ResSymData; } @@ -561,14 +562,14 @@ void WinCOFFObjectWriter::WriteFileHeader(const COFF::header &Header) { WriteLE16(Header.Characteristics); } -void WinCOFFObjectWriter::WriteSymbol(const COFFSymbol *S) { - WriteBytes(StringRef(S->Data.Name, COFF::NameSize)); - WriteLE32(S->Data.Value); - WriteLE16(S->Data.SectionNumber); - WriteLE16(S->Data.Type); - Write8(S->Data.StorageClass); - Write8(S->Data.NumberOfAuxSymbols); - WriteAuxiliarySymbols(S->Aux); +void WinCOFFObjectWriter::WriteSymbol(const COFFSymbol &S) { + WriteBytes(StringRef(S.Data.Name, COFF::NameSize)); + WriteLE32(S.Data.Value); + WriteLE16(S.Data.SectionNumber); + WriteLE16(S.Data.Type); + Write8(S.Data.StorageClass); + Write8(S.Data.NumberOfAuxSymbols); + WriteAuxiliarySymbols(S.Aux); } void WinCOFFObjectWriter::WriteAuxiliarySymbols( @@ -640,16 +641,42 @@ void WinCOFFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, // "Define" each section & symbol. This creates section & symbol // entries in the staging area. - for (MCAssembler::const_iterator i = Asm.begin(), e = Asm.end(); i != e; i++) - DefineSection(*i); + static_assert(sizeof(((COFF::AuxiliaryFile *)nullptr)->FileName) == COFF::SymbolSize, + "size mismatch for COFF::AuxiliaryFile::FileName"); + 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 Count = (FI->size() + COFF::SymbolSize - 1) / COFF::SymbolSize; + + COFFSymbol *file = createSymbol(".file"); + file->Data.SectionNumber = COFF::IMAGE_SYM_DEBUG; + file->Data.StorageClass = COFF::IMAGE_SYM_CLASS_FILE; + file->Aux.resize(Count); + + unsigned Offset = 0; + unsigned Length = FI->size(); + for (auto & Aux : file->Aux) { + Aux.AuxType = ATFile; + + if (Length > COFF::SymbolSize) { + memcpy(Aux.Aux.File.FileName, FI->c_str() + Offset, COFF::SymbolSize); + Length = Length - COFF::SymbolSize; + } else { + memcpy(Aux.Aux.File.FileName, FI->c_str() + Offset, Length); + memset(&Aux.Aux.File.FileName[Length], 0, COFF::SymbolSize - Length); + Length = 0; + } - for (MCAssembler::const_symbol_iterator i = Asm.symbol_begin(), - e = Asm.symbol_end(); - i != e; i++) { - if (ExportSymbol(*i, Asm)) { - DefineSymbol(*i, Asm, Layout); + Offset = Offset + COFF::SymbolSize; } } + + for (const auto & Section : Asm) + DefineSection(Section); + + for (MCSymbolData &SD : Asm.symbols()) + if (ExportSymbol(SD, Asm)) + DefineSymbol(SD, Asm, Layout); } void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm, @@ -659,7 +686,7 @@ void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm, MCValue Target, bool &IsPCRel, uint64_t &FixedValue) { - assert(Target.getSymA() != NULL && "Relocation must reference a symbol!"); + assert(Target.getSymA() && "Relocation must reference a symbol!"); const MCSymbol &Symbol = Target.getSymA()->getSymbol(); const MCSymbol &A = Symbol.AliasedSymbol(); @@ -668,7 +695,7 @@ void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm, Fixup.getLoc(), Twine("symbol '") + A.getName() + "' can not be undefined"); - MCSymbolData &A_SD = Asm.getSymbolData(A); + const MCSymbolData &A_SD = Asm.getSymbolData(A); MCSectionData const *SectionData = Fragment->getParent(); @@ -685,7 +712,7 @@ void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm, if (SymB) { const MCSymbol *B = &SymB->getSymbol(); - MCSymbolData &B_SD = Asm.getSymbolData(*B); + const MCSymbolData &B_SD = Asm.getSymbolData(*B); if (!B_SD.getFragment()) Asm.getContext().FatalError( Fixup.getLoc(), @@ -737,11 +764,52 @@ void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm, // FIXME: Can anyone explain what this does other than adjust for the size // of the offset? - if (Reloc.Data.Type == COFF::IMAGE_REL_AMD64_REL32 || - Reloc.Data.Type == COFF::IMAGE_REL_I386_REL32) + if ((Header.Machine == COFF::IMAGE_FILE_MACHINE_AMD64 && + Reloc.Data.Type == COFF::IMAGE_REL_AMD64_REL32) || + (Header.Machine == COFF::IMAGE_FILE_MACHINE_I386 && + Reloc.Data.Type == COFF::IMAGE_REL_I386_REL32)) FixedValue += 4; - coff_section->Relocations.push_back(Reloc); + if (Header.Machine == COFF::IMAGE_FILE_MACHINE_ARMNT) { + switch (Reloc.Data.Type) { + case COFF::IMAGE_REL_ARM_ABSOLUTE: + case COFF::IMAGE_REL_ARM_ADDR32: + case COFF::IMAGE_REL_ARM_ADDR32NB: + case COFF::IMAGE_REL_ARM_TOKEN: + case COFF::IMAGE_REL_ARM_SECTION: + case COFF::IMAGE_REL_ARM_SECREL: + 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). + case COFF::IMAGE_REL_ARM_BRANCH24: + case COFF::IMAGE_REL_ARM_BLX24: + case COFF::IMAGE_REL_ARM_MOV32A: + // IMAGE_REL_ARM_BRANCH24, IMAGE_REL_ARM_BLX24, IMAGE_REL_ARM_MOV32A are + // only used for ARM mode code, which is documented as being unsupported + // by Windows on ARM. Empirical proof indicates that masm is able to + // generate the relocations however the rest of the MSVC toolchain is + // unable to handle it. + llvm_unreachable("unsupported relocation"); + break; + case COFF::IMAGE_REL_ARM_MOV32T: + break; + case COFF::IMAGE_REL_ARM_BRANCH20T: + case COFF::IMAGE_REL_ARM_BRANCH24T: + case COFF::IMAGE_REL_ARM_BLX23T: + // IMAGE_REL_BRANCH20T, IMAGE_REL_ARM_BRANCH24T, IMAGE_REL_ARM_BLX23T all + // perform a 4 byte adjustment to the relocation. Relative branches are + // offset by 4 on ARM, however, because there is no RELA relocations, all + // branches are offset by 4. + FixedValue = FixedValue + 4; + break; + } + } + + if (TargetObjectWriter->recordRelocation(Fixup)) + coff_section->Relocations.push_back(Reloc); } void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, @@ -750,77 +818,64 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, Header.NumberOfSections = 0; DenseMap<COFFSection *, uint16_t> SectionIndices; - for (sections::iterator i = Sections.begin(), - e = Sections.end(); i != e; i++) { - if (Layout.getSectionAddressSize((*i)->MCData) > 0) { + for (auto & Section : Sections) { + if (Layout.getSectionAddressSize(Section->MCData) > 0) { size_t Number = ++Header.NumberOfSections; - SectionIndices[*i] = Number; - MakeSectionReal(**i, Number); + SectionIndices[Section.get()] = Number; + MakeSectionReal(*Section, Number); } else { - (*i)->Number = -1; + Section->Number = -1; } } Header.NumberOfSymbols = 0; - for (symbols::iterator i = Symbols.begin(), e = Symbols.end(); i != e; i++) { - COFFSymbol *coff_symbol = *i; - MCSymbolData const *SymbolData = coff_symbol->MCData; - + for (auto & Symbol : Symbols) { // Update section number & offset for symbols that have them. - if ((SymbolData != NULL) && (SymbolData->Fragment != NULL)) { - assert(coff_symbol->Section != NULL); + if (Symbol->Section) + Symbol->Data.SectionNumber = Symbol->Section->Number; - coff_symbol->Data.SectionNumber = coff_symbol->Section->Number; - coff_symbol->Data.Value = Layout.getFragmentOffset(SymbolData->Fragment) - + SymbolData->Offset; - } - - if (coff_symbol->should_keep()) { - MakeSymbolReal(*coff_symbol, Header.NumberOfSymbols++); + if (Symbol->should_keep()) { + MakeSymbolReal(*Symbol, Header.NumberOfSymbols++); // Update auxiliary symbol info. - coff_symbol->Data.NumberOfAuxSymbols = coff_symbol->Aux.size(); - Header.NumberOfSymbols += coff_symbol->Data.NumberOfAuxSymbols; + Symbol->Data.NumberOfAuxSymbols = Symbol->Aux.size(); + Header.NumberOfSymbols += Symbol->Data.NumberOfAuxSymbols; } else - coff_symbol->Index = -1; + Symbol->Index = -1; } // Fixup weak external references. - for (symbols::iterator i = Symbols.begin(), e = Symbols.end(); i != e; i++) { - COFFSymbol *coff_symbol = *i; - if (coff_symbol->Other != NULL) { - assert(coff_symbol->Index != -1); - assert(coff_symbol->Aux.size() == 1 && - "Symbol must contain one aux symbol!"); - assert(coff_symbol->Aux[0].AuxType == ATWeakExternal && + for (auto & Symbol : Symbols) { + if (Symbol->Other) { + assert(Symbol->Index != -1); + assert(Symbol->Aux.size() == 1 && "Symbol must contain one aux symbol!"); + assert(Symbol->Aux[0].AuxType == ATWeakExternal && "Symbol's aux symbol must be a Weak External!"); - coff_symbol->Aux[0].Aux.WeakExternal.TagIndex = coff_symbol->Other->Index; + Symbol->Aux[0].Aux.WeakExternal.TagIndex = Symbol->Other->Index; } } // Fixup associative COMDAT sections. - for (sections::iterator i = Sections.begin(), - e = Sections.end(); i != e; i++) { - if ((*i)->Symbol->Aux[0].Aux.SectionDefinition.Selection != + for (auto & Section : Sections) { + if (Section->Symbol->Aux[0].Aux.SectionDefinition.Selection != COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) continue; - const MCSectionCOFF &MCSec = static_cast<const MCSectionCOFF &>( - (*i)->MCData->getSection()); + const MCSectionCOFF &MCSec = + static_cast<const MCSectionCOFF &>(Section->MCData->getSection()); COFFSection *Assoc = SectionMap.lookup(MCSec.getAssocSection()); - if (!Assoc) { + if (!Assoc) report_fatal_error(Twine("Missing associated COMDAT section ") + MCSec.getAssocSection()->getSectionName() + " for section " + MCSec.getSectionName()); - } // Skip this section if the associated section is unused. if (Assoc->Number == -1) continue; - (*i)->Symbol->Aux[0].Aux.SectionDefinition.Number = SectionIndices[Assoc]; + Section->Symbol->Aux[0].Aux.SectionDefinition.Number = SectionIndices[Assoc]; } @@ -831,15 +886,13 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, offset += COFF::HeaderSize; offset += COFF::SectionSize * Header.NumberOfSections; - for (MCAssembler::const_iterator i = Asm.begin(), - e = Asm.end(); - i != e; i++) { - COFFSection *Sec = SectionMap[&i->getSection()]; + for (const auto & Section : Asm) { + COFFSection *Sec = SectionMap[&Section.getSection()]; if (Sec->Number == -1) continue; - Sec->Header.SizeOfRawData = Layout.getSectionAddressSize(i); + Sec->Header.SizeOfRawData = Layout.getSectionAddressSize(&Section); if (IsPhysicalSection(Sec)) { Sec->Header.PointerToRawData = offset; @@ -866,16 +919,14 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, offset += COFF::RelocationSize * Sec->Relocations.size(); - for (relocations::iterator cr = Sec->Relocations.begin(), - er = Sec->Relocations.end(); - cr != er; ++cr) { - assert((*cr).Symb->Index != -1); - (*cr).Data.SymbolTableIndex = (*cr).Symb->Index; + for (auto & Relocation : Sec->Relocations) { + assert(Relocation.Symb->Index != -1); + Relocation.Data.SymbolTableIndex = Relocation.Symb->Index; } } - assert(Sec->Symbol->Aux.size() == 1 - && "Section's symbol must have one aux!"); + assert(Sec->Symbol->Aux.size() == 1 && + "Section's symbol must have one aux!"); AuxSymbol &Aux = Sec->Symbol->Aux[0]; assert(Aux.AuxType == ATSectionDefinition && "Section's symbol's aux symbol must be a Section Definition!"); @@ -898,13 +949,13 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, sections::iterator i, ie; MCAssembler::const_iterator j, je; - for (i = Sections.begin(), ie = Sections.end(); i != ie; i++) - if ((*i)->Number != -1) { - if ((*i)->Relocations.size() >= 0xffff) { - (*i)->Header.Characteristics |= COFF::IMAGE_SCN_LNK_NRELOC_OVFL; - } - WriteSectionHeader((*i)->Header); + for (auto & Section : Sections) { + if (Section->Number != -1) { + if (Section->Relocations.size() >= 0xffff) + Section->Header.Characteristics |= COFF::IMAGE_SCN_LNK_NRELOC_OVFL; + WriteSectionHeader(Section->Header); } + } for (i = Sections.begin(), ie = Sections.end(), j = Asm.begin(), je = Asm.end(); @@ -934,11 +985,8 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, WriteRelocation(r); } - for (relocations::const_iterator k = (*i)->Relocations.begin(), - ke = (*i)->Relocations.end(); - k != ke; k++) { - WriteRelocation(k->Data); - } + for (const auto & Relocation : (*i)->Relocations) + WriteRelocation(Relocation.Data); } else assert((*i)->Header.PointerToRelocations == 0 && "Section::PointerToRelocations is insane!"); @@ -948,9 +996,9 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, assert(OS.tell() == Header.PointerToSymbolTable && "Header::PointerToSymbolTable is insane!"); - for (symbols::iterator i = Symbols.begin(), e = Symbols.end(); i != e; i++) - if ((*i)->Index != -1) - WriteSymbol(*i); + for (auto & Symbol : Symbols) + if (Symbol->Index != -1) + WriteSymbol(*Symbol); OS.write((char const *)&Strings.Data.front(), Strings.Data.size()); } diff --git a/lib/MC/WinCOFFStreamer.cpp b/lib/MC/WinCOFFStreamer.cpp index 5bd7b8f..e6df465 100644 --- a/lib/MC/WinCOFFStreamer.cpp +++ b/lib/MC/WinCOFFStreamer.cpp @@ -7,12 +7,11 @@ // //===----------------------------------------------------------------------===// // -// This file contains an implementation of a Win32 COFF object file streamer. +// This file contains an implementation of a Windows COFF object file streamer. // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "WinCOFFStreamer" - +#include "llvm/ADT/StringExtras.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCAsmBackend.h" #include "llvm/MC/MCAsmLayout.h" @@ -27,6 +26,7 @@ #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCValue.h" #include "llvm/MC/MCWin64EH.h" +#include "llvm/MC/MCWinCOFFStreamer.h" #include "llvm/Support/COFF.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" @@ -35,95 +35,33 @@ using namespace llvm; -namespace { -class WinCOFFStreamer : public MCObjectStreamer { -public: - MCSymbol const *CurSymbol; - - WinCOFFStreamer(MCContext &Context, - MCAsmBackend &MAB, - MCCodeEmitter &CE, - raw_ostream &OS); - - void AddCommonSymbol(MCSymbol *Symbol, uint64_t Size, - unsigned ByteAlignment, bool External); - - // MCStreamer interface - - void InitSections() override; - void EmitLabel(MCSymbol *Symbol) override; - void EmitDebugLabel(MCSymbol *Symbol) override; - void EmitAssemblerFlag(MCAssemblerFlag Flag) override; - void EmitThumbFunc(MCSymbol *Func) override; - bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override; - void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override; - void BeginCOFFSymbolDef(MCSymbol const *Symbol) override; - void EmitCOFFSymbolStorageClass(int StorageClass) override; - void EmitCOFFSymbolType(int Type) override; - void EndCOFFSymbolDef() override; - void EmitCOFFSectionIndex(MCSymbol const *Symbol) override; - void EmitCOFFSecRel32(MCSymbol const *Symbol) override; - void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) override; - void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, - unsigned ByteAlignment) override; - void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, - unsigned ByteAlignment) override; - void EmitZerofill(const MCSection *Section, MCSymbol *Symbol, - uint64_t Size,unsigned ByteAlignment) override; - void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, - uint64_t Size, unsigned ByteAlignment) override; - void EmitFileDirective(StringRef Filename) override; - void EmitIdent(StringRef IdentString) override; - void EmitWin64EHHandlerData() override; - void FinishImpl() override; - -private: - void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo &STI) override { - MCDataFragment *DF = getOrCreateDataFragment(); - - SmallVector<MCFixup, 4> Fixups; - SmallString<256> Code; - raw_svector_ostream VecOS(Code); - getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups, STI); - VecOS.flush(); - - // Add the fixups and data. - for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { - Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size()); - DF->getFixups().push_back(Fixups[i]); - } - DF->getContents().append(Code.begin(), Code.end()); - } -}; -} // end anonymous namespace. - -WinCOFFStreamer::WinCOFFStreamer(MCContext &Context, MCAsmBackend &MAB, - MCCodeEmitter &CE, raw_ostream &OS) - : MCObjectStreamer(Context, MAB, OS, &CE), CurSymbol(NULL) {} - -void WinCOFFStreamer::AddCommonSymbol(MCSymbol *Symbol, uint64_t Size, - unsigned ByteAlignment, bool External) { - assert(!Symbol->isInSection() && "Symbol must not already have a section!"); +#define DEBUG_TYPE "WinCOFFStreamer" - const MCSection *Section = getContext().getObjectFileInfo()->getBSSSection(); - MCSectionData &SectionData = getAssembler().getOrCreateSectionData(*Section); - if (SectionData.getAlignment() < ByteAlignment) - SectionData.setAlignment(ByteAlignment); +namespace llvm { +MCWinCOFFStreamer::MCWinCOFFStreamer(MCContext &Context, MCAsmBackend &MAB, + MCCodeEmitter &CE, raw_ostream &OS) + : MCObjectStreamer(Context, MAB, OS, &CE), CurSymbol(nullptr) {} - MCSymbolData &SymbolData = getAssembler().getOrCreateSymbolData(*Symbol); - SymbolData.setExternal(External); +void MCWinCOFFStreamer::EmitInstToData(const MCInst &Inst, + const MCSubtargetInfo &STI) { + MCDataFragment *DF = getOrCreateDataFragment(); - AssignSection(Symbol, Section); + SmallVector<MCFixup, 4> Fixups; + SmallString<256> Code; + raw_svector_ostream VecOS(Code); + getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups, STI); + VecOS.flush(); - if (ByteAlignment != 1) - new MCAlignFragment(ByteAlignment, 0, 0, ByteAlignment, &SectionData); + // Add the fixups and data. + for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { + Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size()); + DF->getFixups().push_back(Fixups[i]); + } - SymbolData.setFragment(new MCFillFragment(0, 0, Size, &SectionData)); + DF->getContents().append(Code.begin(), Code.end()); } -// MCStreamer interface - -void WinCOFFStreamer::InitSections() { +void MCWinCOFFStreamer::InitSections() { // FIXME: this is identical to the ELF one. // 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. @@ -139,165 +77,182 @@ void WinCOFFStreamer::InitSections() { SwitchSection(getContext().getObjectFileInfo()->getTextSection()); } -void WinCOFFStreamer::EmitLabel(MCSymbol *Symbol) { +void MCWinCOFFStreamer::EmitLabel(MCSymbol *Symbol) { assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); MCObjectStreamer::EmitLabel(Symbol); } -void WinCOFFStreamer::EmitDebugLabel(MCSymbol *Symbol) { +void MCWinCOFFStreamer::EmitDebugLabel(MCSymbol *Symbol) { EmitLabel(Symbol); } -void WinCOFFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) { + +void MCWinCOFFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) { llvm_unreachable("not implemented"); } -void WinCOFFStreamer::EmitThumbFunc(MCSymbol *Func) { +void MCWinCOFFStreamer::EmitThumbFunc(MCSymbol *Func) { llvm_unreachable("not implemented"); } -bool WinCOFFStreamer::EmitSymbolAttribute(MCSymbol *Symbol, - MCSymbolAttr Attribute) { +bool MCWinCOFFStreamer::EmitSymbolAttribute(MCSymbol *Symbol, + MCSymbolAttr Attribute) { assert(Symbol && "Symbol must be non-null!"); - assert((Symbol->isInSection() - ? Symbol->getSection().getVariant() == MCSection::SV_COFF - : true) && "Got non-COFF section in the COFF backend!"); + assert((!Symbol->isInSection() || + Symbol->getSection().getVariant() == MCSection::SV_COFF) && + "Got non-COFF section in the COFF backend!"); + + MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); + switch (Attribute) { + default: return false; case MCSA_WeakReference: - case MCSA_Weak: { - MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); - SD.modifyFlags(COFF::SF_WeakExternal, COFF::SF_WeakExternal); - SD.setExternal(true); - } + case MCSA_Weak: + SD.modifyFlags(COFF::SF_WeakExternal, COFF::SF_WeakExternal); + SD.setExternal(true); break; - case MCSA_Global: - getAssembler().getOrCreateSymbolData(*Symbol).setExternal(true); + SD.setExternal(true); break; - - default: - return false; } return true; } -void WinCOFFStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { +void MCWinCOFFStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { llvm_unreachable("not implemented"); } -void WinCOFFStreamer::BeginCOFFSymbolDef(MCSymbol const *Symbol) { - assert((Symbol->isInSection() - ? Symbol->getSection().getVariant() == MCSection::SV_COFF - : true) && "Got non-COFF section in the COFF backend!"); - assert(CurSymbol == NULL && "EndCOFFSymbolDef must be called between calls " - "to BeginCOFFSymbolDef!"); +void MCWinCOFFStreamer::BeginCOFFSymbolDef(MCSymbol const *Symbol) { + assert((!Symbol->isInSection() || + Symbol->getSection().getVariant() == MCSection::SV_COFF) && + "Got non-COFF section in the COFF backend!"); + + if (CurSymbol) + FatalError("starting a new symbol definition without completing the " + "previous one"); CurSymbol = Symbol; } -void WinCOFFStreamer::EmitCOFFSymbolStorageClass(int StorageClass) { - assert(CurSymbol != NULL && "BeginCOFFSymbolDef must be called first!"); - assert((StorageClass & ~0xFF) == 0 && "StorageClass must only have data in " - "the first byte!"); +void MCWinCOFFStreamer::EmitCOFFSymbolStorageClass(int StorageClass) { + if (!CurSymbol) + FatalError("storage class specified outside of symbol definition"); + + if (StorageClass & ~0xff) + FatalError(Twine("storage class value '") + itostr(StorageClass) + + "' out of range"); - getAssembler().getOrCreateSymbolData(*CurSymbol).modifyFlags( - StorageClass << COFF::SF_ClassShift, - COFF::SF_ClassMask); + MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*CurSymbol); + SD.modifyFlags(StorageClass << COFF::SF_ClassShift, COFF::SF_ClassMask); } -void WinCOFFStreamer::EmitCOFFSymbolType(int Type) { - assert(CurSymbol != NULL && "BeginCOFFSymbolDef must be called first!"); - assert((Type & ~0xFFFF) == 0 && "Type must only have data in the first 2 " - "bytes"); +void MCWinCOFFStreamer::EmitCOFFSymbolType(int Type) { + if (!CurSymbol) + FatalError("symbol type specified outside of a symbol definition"); + + if (Type & ~0xffff) + FatalError(Twine("type value '") + itostr(Type) + "' out of range"); - getAssembler().getOrCreateSymbolData(*CurSymbol).modifyFlags( - Type << COFF::SF_TypeShift, - COFF::SF_TypeMask); + MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*CurSymbol); + SD.modifyFlags(Type << COFF::SF_TypeShift, COFF::SF_TypeMask); } -void WinCOFFStreamer::EndCOFFSymbolDef() { - assert(CurSymbol != NULL && "BeginCOFFSymbolDef must be called first!"); - CurSymbol = NULL; +void MCWinCOFFStreamer::EndCOFFSymbolDef() { + if (!CurSymbol) + FatalError("ending symbol definition without starting one"); + CurSymbol = nullptr; } -void WinCOFFStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) { +void MCWinCOFFStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) { MCDataFragment *DF = getOrCreateDataFragment(); - DF->getFixups().push_back(MCFixup::Create( - DF->getContents().size(), MCSymbolRefExpr::Create(Symbol, getContext()), - FK_SecRel_2)); + const MCSymbolRefExpr *SRE = MCSymbolRefExpr::Create(Symbol, getContext()); + MCFixup Fixup = MCFixup::Create(DF->getContents().size(), SRE, FK_SecRel_2); + DF->getFixups().push_back(Fixup); DF->getContents().resize(DF->getContents().size() + 4, 0); } -void WinCOFFStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) { +void MCWinCOFFStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) { MCDataFragment *DF = getOrCreateDataFragment(); - DF->getFixups().push_back(MCFixup::Create( - DF->getContents().size(), MCSymbolRefExpr::Create(Symbol, getContext()), - FK_SecRel_4)); + const MCSymbolRefExpr *SRE = MCSymbolRefExpr::Create(Symbol, getContext()); + MCFixup Fixup = MCFixup::Create(DF->getContents().size(), SRE, FK_SecRel_4); + DF->getFixups().push_back(Fixup); DF->getContents().resize(DF->getContents().size() + 4, 0); } -void WinCOFFStreamer::EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) { - llvm_unreachable("not implemented"); +void MCWinCOFFStreamer::EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) { + llvm_unreachable("not supported"); } -void WinCOFFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, - unsigned ByteAlignment) { - assert((Symbol->isInSection() - ? Symbol->getSection().getVariant() == MCSection::SV_COFF - : true) && "Got non-COFF section in the COFF backend!"); - AddCommonSymbol(Symbol, Size, ByteAlignment, true); +void MCWinCOFFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment) { + assert((!Symbol->isInSection() || + Symbol->getSection().getVariant() == MCSection::SV_COFF) && + "Got non-COFF section in the COFF backend!"); + + if (ByteAlignment > 32) + report_fatal_error("alignment is limited to 32-bytes"); + + AssignSection(Symbol, nullptr); + + MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); + SD.setExternal(true); + SD.setCommon(Size, ByteAlignment); } -void WinCOFFStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, - unsigned ByteAlignment) { - assert((Symbol->isInSection() - ? Symbol->getSection().getVariant() == MCSection::SV_COFF - : true) && "Got non-COFF section in the COFF backend!"); - AddCommonSymbol(Symbol, Size, ByteAlignment, false); +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); + + MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); + SD.setExternal(false); + + AssignSection(Symbol, Section); + + if (ByteAlignment != 1) + new MCAlignFragment(ByteAlignment, /*_Value=*/0, /*_ValueSize=*/0, + ByteAlignment, &SectionData); + + MCFillFragment *Fragment = + new MCFillFragment(/*_Value=*/0, /*_ValueSize=*/0, Size, &SectionData); + SD.setFragment(Fragment); } -void WinCOFFStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol, - uint64_t Size,unsigned ByteAlignment) { +void MCWinCOFFStreamer::EmitZerofill(const MCSection *Section, + MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment) { llvm_unreachable("not implemented"); } -void WinCOFFStreamer::EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, - uint64_t Size, unsigned ByteAlignment) { +void MCWinCOFFStreamer::EmitTBSSSymbol(const MCSection *Section, + MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment) { llvm_unreachable("not implemented"); } -void WinCOFFStreamer::EmitFileDirective(StringRef Filename) { - // Ignore for now, linkers don't care, and proper debug - // info will be a much large effort. +void MCWinCOFFStreamer::EmitFileDirective(StringRef Filename) { + getAssembler().addFileName(Filename); } // TODO: Implement this if you want to emit .comment section in COFF obj files. -void WinCOFFStreamer::EmitIdent(StringRef IdentString) { - llvm_unreachable("unsupported directive"); +void MCWinCOFFStreamer::EmitIdent(StringRef IdentString) { + llvm_unreachable("not implemented"); } -void WinCOFFStreamer::EmitWin64EHHandlerData() { - MCStreamer::EmitWin64EHHandlerData(); - - // We have to emit the unwind info now, because this directive - // actually switches to the .xdata section! - MCWin64EHUnwindEmitter::EmitUnwindInfo(*this, getCurrentW64UnwindInfo()); +void MCWinCOFFStreamer::EmitWin64EHHandlerData() { + llvm_unreachable("not implemented"); } -void WinCOFFStreamer::FinishImpl() { - EmitFrames(NULL, true); - EmitW64Tables(); +void MCWinCOFFStreamer::FinishImpl() { MCObjectStreamer::FinishImpl(); } -namespace llvm -{ - MCStreamer *createWinCOFFStreamer(MCContext &Context, - MCAsmBackend &MAB, - MCCodeEmitter &CE, - raw_ostream &OS, - bool RelaxAll) { - WinCOFFStreamer *S = new WinCOFFStreamer(Context, MAB, CE, OS); - S->getAssembler().setRelaxAll(RelaxAll); - return S; - } +LLVM_ATTRIBUTE_NORETURN +void MCWinCOFFStreamer::FatalError(const Twine &Msg) const { + getContext().FatalError(SMLoc(), Msg); +} } + |