diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2015-07-05 14:21:36 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2015-07-05 14:21:36 +0000 |
commit | 1a82d4c088707c791c792f6822f611b47a12bdfe (patch) | |
tree | 7c411f9b5d807f7f204fdd16965d8925a82b6d18 /tools | |
parent | 3a0822f094b578157263e04114075ad7df81db41 (diff) |
Notes
Diffstat (limited to 'tools')
34 files changed, 1055 insertions, 810 deletions
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 7859b49c9de7..c9c5a1fdfa08 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -75,14 +75,11 @@ add_llvm_tool_subdirectory(gold) add_llvm_external_project(clang) add_llvm_external_project(llgo) +add_llvm_external_project(lld) +add_llvm_external_project(lldb) -if( NOT LLVM_INCLUDE_TOOLS STREQUAL "bootstrap-only" ) - add_llvm_external_project(lld) - add_llvm_external_project(lldb) - - # Automatically add remaining sub-directories containing a 'CMakeLists.txt' - # file as external projects. - add_llvm_implicit_external_projects() -endif() +# Automatically add remaining sub-directories containing a 'CMakeLists.txt' +# file as external projects. +add_llvm_implicit_external_projects() set(LLVM_COMMON_DEPENDS ${LLVM_COMMON_DEPENDS} PARENT_SCOPE) diff --git a/tools/dsymutil/DebugMap.cpp b/tools/dsymutil/DebugMap.cpp index 1a81848847f6..cc7c0dc778b3 100644 --- a/tools/dsymutil/DebugMap.cpp +++ b/tools/dsymutil/DebugMap.cpp @@ -216,11 +216,13 @@ MappingTraits<dsymutil::DebugMapObject>::YamlDMO::denormalize(IO &IO) { // during the test, we can't hardcode the symbols addresses, so // look them up here and rewrite them. for (const auto &Sym : ErrOrObjectFile->symbols()) { - StringRef Name; uint64_t Address; - if (Sym.getName(Name) || Sym.getAddress(Address)) + if (Sym.getAddress(Address)) continue; - SymbolAddresses[Name] = Address; + ErrorOr<StringRef> Name = Sym.getName(); + if (!Name) + continue; + SymbolAddresses[*Name] = Address; } } diff --git a/tools/dsymutil/DwarfLinker.cpp b/tools/dsymutil/DwarfLinker.cpp index 052c1daadbda..6e9087c70eca 100644 --- a/tools/dsymutil/DwarfLinker.cpp +++ b/tools/dsymutil/DwarfLinker.cpp @@ -60,33 +60,23 @@ using HalfOpenIntervalMap = typedef HalfOpenIntervalMap<uint64_t, int64_t> FunctionIntervals; -// FIXME: Delete this structure once DIE::Values has a stable iterator we can -// use instead. +// FIXME: Delete this structure. struct PatchLocation { - DIE *Die; - unsigned Index; + DIE::value_iterator I; - PatchLocation() : Die(nullptr), Index(0) {} - PatchLocation(DIE &Die, unsigned Index) : Die(&Die), Index(Index) {} - PatchLocation(DIE &Die) - : Die(&Die), Index(std::distance(Die.values_begin(), Die.values_end())) {} + PatchLocation() = default; + PatchLocation(DIE::value_iterator I) : I(I) {} void set(uint64_t New) const { - assert(Die); - assert((signed)Index < - std::distance(Die->values_begin(), Die->values_end())); - const auto &Old = Die->values_begin()[Index]; + assert(I); + const auto &Old = *I; assert(Old.getType() == DIEValue::isInteger); - Die->setValue(Index, - DIEValue(Old.getAttribute(), Old.getForm(), DIEInteger(New))); + *I = DIEValue(Old.getAttribute(), Old.getForm(), DIEInteger(New)); } uint64_t get() const { - assert(Die); - assert((signed)Index < - std::distance(Die->values_begin(), Die->values_end())); - assert(Die->values_begin()[Index].getType() == DIEValue::isInteger); - return Die->values_begin()[Index].getDIEInteger().getValue(); + assert(I); + return I->getDIEInteger().getValue(); } }; @@ -123,8 +113,8 @@ public: unsigned getUniqueID() const { return ID; } - DIE *getOutputUnitDIE() const { return CUDie.get(); } - void setOutputUnitDIE(DIE *Die) { CUDie.reset(Die); } + DIE *getOutputUnitDIE() const { return CUDie; } + void setOutputUnitDIE(DIE *Die) { CUDie = Die; } DIEInfo &getInfo(unsigned Idx) { return Info[Idx]; } const DIEInfo &getInfo(unsigned Idx) const { return Info[Idx]; } @@ -204,7 +194,7 @@ private: DWARFUnit &OrigUnit; unsigned ID; std::vector<DIEInfo> Info; ///< DIE info indexed by DIE index. - std::unique_ptr<DIE> CUDie; ///< Root of the linked DIE tree. + DIE *CUDie; ///< Root of the linked DIE tree. uint64_t StartOffset; uint64_t NextUnitOffset; @@ -1437,10 +1427,10 @@ void DwarfLinker::endDebugObject() { ValidRelocs.clear(); Ranges.clear(); - for (auto *Block : DIEBlocks) - Block->~DIEBlock(); - for (auto *Loc : DIELocs) - Loc->~DIELoc(); + for (auto I = DIEBlocks.begin(), E = DIEBlocks.end(); I != E; ++I) + (*I)->~DIEBlock(); + for (auto I = DIELocs.begin(), E = DIELocs.end(); I != E; ++I) + (*I)->~DIELoc(); DIEBlocks.clear(); DIELocs.clear(); @@ -1461,8 +1451,8 @@ void DwarfLinker::findValidRelocsMachO(const object::SectionRef &Section, object::DataRefImpl RelocDataRef = Reloc.getRawDataRefImpl(); MachO::any_relocation_info MachOReloc = Obj.getRelocation(RelocDataRef); unsigned RelocSize = 1 << Obj.getAnyRelocationLength(MachOReloc); - uint64_t Offset64; - if ((RelocSize != 4 && RelocSize != 8) || Reloc.getOffset(Offset64)) { + uint64_t Offset64 = Reloc.getOffset(); + if ((RelocSize != 4 && RelocSize != 8)) { reportWarning(" unsupported relocation in debug_info section."); continue; } @@ -1472,12 +1462,12 @@ void DwarfLinker::findValidRelocsMachO(const object::SectionRef &Section, auto Sym = Reloc.getSymbol(); if (Sym != Obj.symbol_end()) { - StringRef SymbolName; - if (Sym->getName(SymbolName)) { + ErrorOr<StringRef> SymbolName = Sym->getName(); + if (!SymbolName) { reportWarning("error getting relocation symbol name."); continue; } - if (const auto *Mapping = DMO.lookupSymbol(SymbolName)) + if (const auto *Mapping = DMO.lookupSymbol(*SymbolName)) ValidRelocs.emplace_back(Offset64, RelocSize, Addend, Mapping); } else if (const auto *Mapping = DMO.lookupObjectAddress(Addend)) { // Do not store the addend. The addend was the address of the @@ -1837,7 +1827,7 @@ unsigned DwarfLinker::cloneStringAttribute(DIE &Die, AttributeSpec AttrSpec, // Switch everything to out of line strings. const char *String = *Val.getAsCString(&U); unsigned Offset = StringPool.getStringOffset(String); - Die.addValue(dwarf::Attribute(AttrSpec.Attr), dwarf::DW_FORM_strp, + Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr), dwarf::DW_FORM_strp, DIEInteger(Offset)); return 4; } @@ -1871,7 +1861,7 @@ unsigned DwarfLinker::cloneDieReferenceAttribute( assert(Ref > InputDIE.getOffset()); // We haven't cloned this DIE yet. Just create an empty one and // store it. It'll get really cloned when we process it. - RefInfo.Clone = new DIE(dwarf::Tag(RefDie->getTag())); + RefInfo.Clone = DIE::get(DIEAlloc, dwarf::Tag(RefDie->getTag())); } NewRefDie = RefInfo.Clone; @@ -1887,18 +1877,21 @@ unsigned DwarfLinker::cloneDieReferenceAttribute( uint32_t NewRefOffset = RefUnit->getStartOffset() + NewRefDie->getOffset(); Attr = NewRefOffset; + Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr), + dwarf::DW_FORM_ref_addr, DIEInteger(Attr)); } else { // A forward reference. Note and fixup later. Attr = 0xBADDEF; - Unit.noteForwardReference(NewRefDie, RefUnit, PatchLocation(Die)); + Unit.noteForwardReference( + NewRefDie, RefUnit, + Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr), + dwarf::DW_FORM_ref_addr, DIEInteger(Attr))); } - Die.addValue(dwarf::Attribute(AttrSpec.Attr), dwarf::DW_FORM_ref_addr, - DIEInteger(Attr)); return AttrSize; } - Die.addValue(dwarf::Attribute(AttrSpec.Attr), dwarf::Form(AttrSpec.Form), - DIEEntry(*NewRefDie)); + Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr), + dwarf::Form(AttrSpec.Form), DIEEntry(*NewRefDie)); return AttrSize; } @@ -1930,8 +1923,8 @@ unsigned DwarfLinker::cloneBlockAttribute(DIE &Die, AttributeSpec AttrSpec, dwarf::Form(AttrSpec.Form), Block); ArrayRef<uint8_t> Bytes = *Val.getAsBlock(); for (auto Byte : Bytes) - Attr->addValue(static_cast<dwarf::Attribute>(0), dwarf::DW_FORM_data1, - DIEInteger(Byte)); + Attr->addValue(DIEAlloc, static_cast<dwarf::Attribute>(0), + dwarf::DW_FORM_data1, DIEInteger(Byte)); // FIXME: If DIEBlock and DIELoc just reuses the Size field of // the DIE class, this if could be replaced by // Attr->setSize(Bytes.size()). @@ -1941,7 +1934,7 @@ unsigned DwarfLinker::cloneBlockAttribute(DIE &Die, AttributeSpec AttrSpec, else Block->ComputeSize(&Streamer->getAsmPrinter()); } - Die.addValue(Value); + Die.addValue(DIEAlloc, Value); return AttrSize; } @@ -1975,7 +1968,7 @@ unsigned DwarfLinker::cloneAddressAttribute(DIE &Die, AttributeSpec AttrSpec, Addr = (Info.OrigHighPc ? Info.OrigHighPc : Addr) + Info.PCOffset; } - Die.addValue(static_cast<dwarf::Attribute>(AttrSpec.Attr), + Die.addValue(DIEAlloc, static_cast<dwarf::Attribute>(AttrSpec.Attr), static_cast<dwarf::Form>(AttrSpec.Form), DIEInteger(Addr)); return Unit.getOrigUnit().getAddressByteSize(); } @@ -2004,20 +1997,20 @@ unsigned DwarfLinker::cloneScalarAttribute( &Unit.getOrigUnit(), &InputDIE); return 0; } - DIEInteger Attr(Value); + PatchLocation Patch = + Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr), + dwarf::Form(AttrSpec.Form), DIEInteger(Value)); if (AttrSpec.Attr == dwarf::DW_AT_ranges) - Unit.noteRangeAttribute(Die, PatchLocation(Die)); + Unit.noteRangeAttribute(Die, Patch); // A more generic way to check for location attributes would be // nice, but it's very unlikely that any other attribute needs a // location list. else if (AttrSpec.Attr == dwarf::DW_AT_location || AttrSpec.Attr == dwarf::DW_AT_frame_base) - Unit.noteLocationAttribute(PatchLocation(Die), Info.PCOffset); + Unit.noteLocationAttribute(Patch, Info.PCOffset); else if (AttrSpec.Attr == dwarf::DW_AT_declaration && Value) Info.IsDeclaration = true; - Die.addValue(dwarf::Attribute(AttrSpec.Attr), dwarf::Form(AttrSpec.Form), - Attr); return AttrSize; } @@ -2170,7 +2163,7 @@ DIE *DwarfLinker::cloneDIE(const DWARFDebugInfoEntryMinimal &InputDIE, // (see cloneDieReferenceAttribute()). DIE *Die = Info.Clone; if (!Die) - Die = Info.Clone = new DIE(dwarf::Tag(InputDIE.getTag())); + Die = Info.Clone = DIE::get(DIEAlloc, dwarf::Tag(InputDIE.getTag())); assert(Die->getTag() == InputDIE.getTag()); Die->setOffset(OutOffset); @@ -2262,7 +2255,7 @@ DIE *DwarfLinker::cloneDIE(const DWARFDebugInfoEntryMinimal &InputDIE, for (auto *Child = InputDIE.getFirstChild(); Child && !Child->isNULL(); Child = Child->getSibling()) { if (DIE *Clone = cloneDIE(*Child, Unit, PCOffset, OutOffset)) { - Die->addChild(std::unique_ptr<DIE>(Clone)); + Die->addChild(Clone); OutOffset = Clone->getOffset() + Clone->getSize(); } } @@ -2364,6 +2357,16 @@ static void insertLineSequence(std::vector<DWARFDebugLine::Row> &Seq, Seq.clear(); } +static void patchStmtList(DIE &Die, DIEInteger Offset) { + for (auto &V : Die.values()) + if (V.getAttribute() == dwarf::DW_AT_stmt_list) { + V = DIEValue(V.getAttribute(), V.getForm(), Offset); + return; + } + + llvm_unreachable("Didn't find DW_AT_stmt_list in cloned DIE!"); +} + /// \brief Extract the line table for \p Unit from \p OrigDwarf, and /// recreate a relocated version of these for the address ranges that /// are present in the binary. @@ -2376,18 +2379,8 @@ void DwarfLinker::patchLineTableForUnit(CompileUnit &Unit, return; // Update the cloned DW_AT_stmt_list with the correct debug_line offset. - if (auto *OutputDIE = Unit.getOutputUnitDIE()) { - auto Stmt = - std::find_if(OutputDIE->values_begin(), OutputDIE->values_end(), - [](const DIEValue &Value) { - return Value.getAttribute() == dwarf::DW_AT_stmt_list; - }); - assert(Stmt != OutputDIE->values_end() && - "Didn't find DW_AT_stmt_list in cloned DIE!"); - OutputDIE->setValue(Stmt - OutputDIE->values_begin(), - DIEValue(Stmt->getAttribute(), Stmt->getForm(), - DIEInteger(Streamer->getLineSectionSize()))); - } + if (auto *OutputDIE = Unit.getOutputUnitDIE()) + patchStmtList(*OutputDIE, DIEInteger(Streamer->getLineSectionSize())); // Parse the original line info for the unit. DWARFDebugLine::LineTable LineTable; diff --git a/tools/dsymutil/MachODebugMapParser.cpp b/tools/dsymutil/MachODebugMapParser.cpp index b803e410199d..c58545aec999 100644 --- a/tools/dsymutil/MachODebugMapParser.cpp +++ b/tools/dsymutil/MachODebugMapParser.cpp @@ -160,7 +160,7 @@ void MachODebugMapParser::handleStabSymbolTableEntry(uint32_t StringIndex, // symbol table to find its address as it might not be in the // debug map (for common symbols). Value = getMainBinarySymbolAddress(Name); - if (Value == UnknownAddressOrSize) + if (Value == UnknownAddress) return; break; case MachO::N_FUN: @@ -197,12 +197,14 @@ void MachODebugMapParser::loadCurrentObjectFileSymbols() { CurrentObjectAddresses.clear(); for (auto Sym : CurrentObjectHolder.Get().symbols()) { - StringRef Name; + uint64_t Addr; - if (Sym.getAddress(Addr) || Addr == UnknownAddressOrSize || - Sym.getName(Name)) + if (Sym.getAddress(Addr) || Addr == UnknownAddress) + continue; + ErrorOr<StringRef> Name = Sym.getName(); + if (!Name) continue; - CurrentObjectAddresses[Name] = Addr; + CurrentObjectAddresses[*Name] = Addr; } } @@ -212,7 +214,7 @@ void MachODebugMapParser::loadCurrentObjectFileSymbols() { uint64_t MachODebugMapParser::getMainBinarySymbolAddress(StringRef Name) { auto Sym = MainBinarySymbolAddresses.find(Name); if (Sym == MainBinarySymbolAddresses.end()) - return UnknownAddressOrSize; + return UnknownAddress; return Sym->second; } @@ -222,21 +224,24 @@ void MachODebugMapParser::loadMainBinarySymbols() { const MachOObjectFile &MainBinary = MainBinaryHolder.GetAs<MachOObjectFile>(); section_iterator Section = MainBinary.section_end(); for (const auto &Sym : MainBinary.symbols()) { - SymbolRef::Type Type; + SymbolRef::Type Type = Sym.getType(); // Skip undefined and STAB entries. - if (Sym.getType(Type) || (Type & SymbolRef::ST_Debug) || - (Type & SymbolRef::ST_Unknown)) + if ((Type & SymbolRef::ST_Debug) || (Type & SymbolRef::ST_Unknown)) continue; - StringRef Name; uint64_t Addr; // The only symbols of interest are the global variables. These // are the only ones that need to be queried because the address // of common data won't be described in the debug map. All other // addresses should be fetched for the debug map. - if (Sym.getAddress(Addr) || Addr == UnknownAddressOrSize || + if (Sym.getAddress(Addr) || Addr == UnknownAddress || !(Sym.getFlags() & SymbolRef::SF_Global) || Sym.getSection(Section) || - Section->isText() || Sym.getName(Name) || Name.size() == 0 || - Name[0] == '\0') + Section->isText()) + continue; + ErrorOr<StringRef> NameOrErr = Sym.getName(); + if (!NameOrErr) + continue; + StringRef Name = *NameOrErr; + if (Name.size() == 0 || Name[0] == '\0') continue; MainBinarySymbolAddresses[Name] = Addr; } diff --git a/tools/lli/OrcLazyJIT.h b/tools/lli/OrcLazyJIT.h index 92572256e36e..fe86adbf9516 100644 --- a/tools/lli/OrcLazyJIT.h +++ b/tools/lli/OrcLazyJIT.h @@ -50,7 +50,6 @@ public: OrcLazyJIT(std::unique_ptr<TargetMachine> TM, LLVMContext &Context, CallbackManagerBuilder &BuildCallbackMgr) : TM(std::move(TM)), - Mang(this->TM->getDataLayout()), ObjectLayer(), CompileLayer(ObjectLayer, orc::SimpleCompiler(*this->TM)), IRDumpLayer(CompileLayer, createDebugDumper()), @@ -137,7 +136,7 @@ private: std::string MangledName; { raw_string_ostream MangledNameStream(MangledName); - Mang.getNameWithPrefix(MangledNameStream, Name); + Mangler::getNameWithPrefix(MangledNameStream, Name, *TM->getDataLayout()); } return MangledName; } @@ -145,7 +144,6 @@ private: static TransformFtor createDebugDumper(); std::unique_ptr<TargetMachine> TM; - Mangler Mang; SectionMemoryManager CCMgrMemMgr; ObjLayerT ObjectLayer; diff --git a/tools/llvm-ar/llvm-ar.cpp b/tools/llvm-ar/llvm-ar.cpp index 6782b9c126ab..0fd2df4f5aa9 100644 --- a/tools/llvm-ar/llvm-ar.cpp +++ b/tools/llvm-ar/llvm-ar.cpp @@ -724,7 +724,7 @@ int main(int argc, char **argv) { StringRef Stem = sys::path::stem(ToolName); if (Stem.find("ranlib") == StringRef::npos && Stem.find("lib") != StringRef::npos) - return libDriverMain(argc, const_cast<const char **>(argv)); + return libDriverMain(makeArrayRef(argv, argc)); // Have the command line options parsed and handle things // like --help and --version. diff --git a/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp b/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp index 58b02be7b92f..7672951f9c9b 100644 --- a/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp +++ b/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp @@ -146,26 +146,30 @@ static const char *GetCodeName(unsigned CodeID, unsigned BlockID, if (CurStreamType != LLVMIRBitstream) return nullptr; +#define STRINGIFY_CODE(PREFIX, CODE) \ + case bitc::PREFIX##_##CODE: \ + return #CODE; switch (BlockID) { default: return nullptr; case bitc::MODULE_BLOCK_ID: switch (CodeID) { default: return nullptr; - case bitc::MODULE_CODE_VERSION: return "VERSION"; - case bitc::MODULE_CODE_TRIPLE: return "TRIPLE"; - case bitc::MODULE_CODE_DATALAYOUT: return "DATALAYOUT"; - case bitc::MODULE_CODE_ASM: return "ASM"; - case bitc::MODULE_CODE_SECTIONNAME: return "SECTIONNAME"; - case bitc::MODULE_CODE_DEPLIB: return "DEPLIB"; // FIXME: Remove in 4.0 - case bitc::MODULE_CODE_GLOBALVAR: return "GLOBALVAR"; - case bitc::MODULE_CODE_FUNCTION: return "FUNCTION"; - case bitc::MODULE_CODE_ALIAS: return "ALIAS"; - case bitc::MODULE_CODE_PURGEVALS: return "PURGEVALS"; - case bitc::MODULE_CODE_GCNAME: return "GCNAME"; + STRINGIFY_CODE(MODULE_CODE, VERSION) + STRINGIFY_CODE(MODULE_CODE, TRIPLE) + STRINGIFY_CODE(MODULE_CODE, DATALAYOUT) + STRINGIFY_CODE(MODULE_CODE, ASM) + STRINGIFY_CODE(MODULE_CODE, SECTIONNAME) + STRINGIFY_CODE(MODULE_CODE, DEPLIB) // FIXME: Remove in 4.0 + STRINGIFY_CODE(MODULE_CODE, GLOBALVAR) + STRINGIFY_CODE(MODULE_CODE, FUNCTION) + STRINGIFY_CODE(MODULE_CODE, ALIAS) + STRINGIFY_CODE(MODULE_CODE, PURGEVALS) + STRINGIFY_CODE(MODULE_CODE, GCNAME) } case bitc::PARAMATTR_BLOCK_ID: switch (CodeID) { default: return nullptr; + // FIXME: Should these be different? case bitc::PARAMATTR_CODE_ENTRY_OLD: return "ENTRY"; case bitc::PARAMATTR_CODE_ENTRY: return "ENTRY"; case bitc::PARAMATTR_GRP_CODE_ENTRY: return "ENTRY"; @@ -173,112 +177,129 @@ static const char *GetCodeName(unsigned CodeID, unsigned BlockID, case bitc::TYPE_BLOCK_ID_NEW: switch (CodeID) { default: return nullptr; - case bitc::TYPE_CODE_NUMENTRY: return "NUMENTRY"; - case bitc::TYPE_CODE_VOID: return "VOID"; - case bitc::TYPE_CODE_FLOAT: return "FLOAT"; - case bitc::TYPE_CODE_DOUBLE: return "DOUBLE"; - case bitc::TYPE_CODE_LABEL: return "LABEL"; - case bitc::TYPE_CODE_OPAQUE: return "OPAQUE"; - case bitc::TYPE_CODE_INTEGER: return "INTEGER"; - case bitc::TYPE_CODE_POINTER: return "POINTER"; - case bitc::TYPE_CODE_ARRAY: return "ARRAY"; - case bitc::TYPE_CODE_VECTOR: return "VECTOR"; - case bitc::TYPE_CODE_X86_FP80: return "X86_FP80"; - case bitc::TYPE_CODE_FP128: return "FP128"; - case bitc::TYPE_CODE_PPC_FP128: return "PPC_FP128"; - case bitc::TYPE_CODE_METADATA: return "METADATA"; - case bitc::TYPE_CODE_STRUCT_ANON: return "STRUCT_ANON"; - case bitc::TYPE_CODE_STRUCT_NAME: return "STRUCT_NAME"; - case bitc::TYPE_CODE_STRUCT_NAMED: return "STRUCT_NAMED"; - case bitc::TYPE_CODE_FUNCTION: return "FUNCTION"; + STRINGIFY_CODE(TYPE_CODE, NUMENTRY) + STRINGIFY_CODE(TYPE_CODE, VOID) + STRINGIFY_CODE(TYPE_CODE, FLOAT) + STRINGIFY_CODE(TYPE_CODE, DOUBLE) + STRINGIFY_CODE(TYPE_CODE, LABEL) + STRINGIFY_CODE(TYPE_CODE, OPAQUE) + STRINGIFY_CODE(TYPE_CODE, INTEGER) + STRINGIFY_CODE(TYPE_CODE, POINTER) + STRINGIFY_CODE(TYPE_CODE, ARRAY) + STRINGIFY_CODE(TYPE_CODE, VECTOR) + STRINGIFY_CODE(TYPE_CODE, X86_FP80) + STRINGIFY_CODE(TYPE_CODE, FP128) + STRINGIFY_CODE(TYPE_CODE, PPC_FP128) + STRINGIFY_CODE(TYPE_CODE, METADATA) + STRINGIFY_CODE(TYPE_CODE, STRUCT_ANON) + STRINGIFY_CODE(TYPE_CODE, STRUCT_NAME) + STRINGIFY_CODE(TYPE_CODE, STRUCT_NAMED) + STRINGIFY_CODE(TYPE_CODE, FUNCTION) } case bitc::CONSTANTS_BLOCK_ID: switch (CodeID) { default: return nullptr; - case bitc::CST_CODE_SETTYPE: return "SETTYPE"; - case bitc::CST_CODE_NULL: return "NULL"; - case bitc::CST_CODE_UNDEF: return "UNDEF"; - case bitc::CST_CODE_INTEGER: return "INTEGER"; - case bitc::CST_CODE_WIDE_INTEGER: return "WIDE_INTEGER"; - case bitc::CST_CODE_FLOAT: return "FLOAT"; - case bitc::CST_CODE_AGGREGATE: return "AGGREGATE"; - case bitc::CST_CODE_STRING: return "STRING"; - case bitc::CST_CODE_CSTRING: return "CSTRING"; - case bitc::CST_CODE_CE_BINOP: return "CE_BINOP"; - case bitc::CST_CODE_CE_CAST: return "CE_CAST"; - case bitc::CST_CODE_CE_GEP: return "CE_GEP"; - case bitc::CST_CODE_CE_INBOUNDS_GEP: return "CE_INBOUNDS_GEP"; - case bitc::CST_CODE_CE_SELECT: return "CE_SELECT"; - case bitc::CST_CODE_CE_EXTRACTELT: return "CE_EXTRACTELT"; - case bitc::CST_CODE_CE_INSERTELT: return "CE_INSERTELT"; - case bitc::CST_CODE_CE_SHUFFLEVEC: return "CE_SHUFFLEVEC"; - case bitc::CST_CODE_CE_CMP: return "CE_CMP"; - case bitc::CST_CODE_INLINEASM: return "INLINEASM"; - case bitc::CST_CODE_CE_SHUFVEC_EX: return "CE_SHUFVEC_EX"; + STRINGIFY_CODE(CST_CODE, SETTYPE) + STRINGIFY_CODE(CST_CODE, NULL) + STRINGIFY_CODE(CST_CODE, UNDEF) + STRINGIFY_CODE(CST_CODE, INTEGER) + STRINGIFY_CODE(CST_CODE, WIDE_INTEGER) + STRINGIFY_CODE(CST_CODE, FLOAT) + STRINGIFY_CODE(CST_CODE, AGGREGATE) + STRINGIFY_CODE(CST_CODE, STRING) + STRINGIFY_CODE(CST_CODE, CSTRING) + STRINGIFY_CODE(CST_CODE, CE_BINOP) + STRINGIFY_CODE(CST_CODE, CE_CAST) + STRINGIFY_CODE(CST_CODE, CE_GEP) + STRINGIFY_CODE(CST_CODE, CE_INBOUNDS_GEP) + STRINGIFY_CODE(CST_CODE, CE_SELECT) + STRINGIFY_CODE(CST_CODE, CE_EXTRACTELT) + STRINGIFY_CODE(CST_CODE, CE_INSERTELT) + STRINGIFY_CODE(CST_CODE, CE_SHUFFLEVEC) + STRINGIFY_CODE(CST_CODE, CE_CMP) + STRINGIFY_CODE(CST_CODE, INLINEASM) + STRINGIFY_CODE(CST_CODE, CE_SHUFVEC_EX) case bitc::CST_CODE_BLOCKADDRESS: return "CST_CODE_BLOCKADDRESS"; - case bitc::CST_CODE_DATA: return "DATA"; + STRINGIFY_CODE(CST_CODE, DATA) } case bitc::FUNCTION_BLOCK_ID: switch (CodeID) { default: return nullptr; - case bitc::FUNC_CODE_DECLAREBLOCKS: return "DECLAREBLOCKS"; - - case bitc::FUNC_CODE_INST_BINOP: return "INST_BINOP"; - case bitc::FUNC_CODE_INST_CAST: return "INST_CAST"; - case bitc::FUNC_CODE_INST_GEP_OLD: - return "INST_GEP_OLD"; - case bitc::FUNC_CODE_INST_INBOUNDS_GEP_OLD: - return "INST_INBOUNDS_GEP_OLD"; - case bitc::FUNC_CODE_INST_SELECT: return "INST_SELECT"; - case bitc::FUNC_CODE_INST_EXTRACTELT: return "INST_EXTRACTELT"; - case bitc::FUNC_CODE_INST_INSERTELT: return "INST_INSERTELT"; - case bitc::FUNC_CODE_INST_SHUFFLEVEC: return "INST_SHUFFLEVEC"; - case bitc::FUNC_CODE_INST_CMP: return "INST_CMP"; - - case bitc::FUNC_CODE_INST_RET: return "INST_RET"; - case bitc::FUNC_CODE_INST_BR: return "INST_BR"; - case bitc::FUNC_CODE_INST_SWITCH: return "INST_SWITCH"; - case bitc::FUNC_CODE_INST_INVOKE: return "INST_INVOKE"; - case bitc::FUNC_CODE_INST_UNREACHABLE: return "INST_UNREACHABLE"; - - case bitc::FUNC_CODE_INST_PHI: return "INST_PHI"; - case bitc::FUNC_CODE_INST_ALLOCA: return "INST_ALLOCA"; - case bitc::FUNC_CODE_INST_LOAD: return "INST_LOAD"; - case bitc::FUNC_CODE_INST_VAARG: return "INST_VAARG"; - case bitc::FUNC_CODE_INST_STORE: return "INST_STORE"; - case bitc::FUNC_CODE_INST_EXTRACTVAL: return "INST_EXTRACTVAL"; - case bitc::FUNC_CODE_INST_INSERTVAL: return "INST_INSERTVAL"; - case bitc::FUNC_CODE_INST_CMP2: return "INST_CMP2"; - case bitc::FUNC_CODE_INST_VSELECT: return "INST_VSELECT"; - case bitc::FUNC_CODE_DEBUG_LOC_AGAIN: return "DEBUG_LOC_AGAIN"; - case bitc::FUNC_CODE_INST_CALL: return "INST_CALL"; - case bitc::FUNC_CODE_DEBUG_LOC: return "DEBUG_LOC"; - case bitc::FUNC_CODE_INST_GEP: - return "INST_GEP"; + STRINGIFY_CODE(FUNC_CODE, DECLAREBLOCKS) + STRINGIFY_CODE(FUNC_CODE, INST_BINOP) + STRINGIFY_CODE(FUNC_CODE, INST_CAST) + STRINGIFY_CODE(FUNC_CODE, INST_GEP_OLD) + STRINGIFY_CODE(FUNC_CODE, INST_INBOUNDS_GEP_OLD) + STRINGIFY_CODE(FUNC_CODE, INST_SELECT) + STRINGIFY_CODE(FUNC_CODE, INST_EXTRACTELT) + STRINGIFY_CODE(FUNC_CODE, INST_INSERTELT) + STRINGIFY_CODE(FUNC_CODE, INST_SHUFFLEVEC) + STRINGIFY_CODE(FUNC_CODE, INST_CMP) + STRINGIFY_CODE(FUNC_CODE, INST_RET) + STRINGIFY_CODE(FUNC_CODE, INST_BR) + STRINGIFY_CODE(FUNC_CODE, INST_SWITCH) + STRINGIFY_CODE(FUNC_CODE, INST_INVOKE) + STRINGIFY_CODE(FUNC_CODE, INST_UNREACHABLE) + STRINGIFY_CODE(FUNC_CODE, INST_PHI) + STRINGIFY_CODE(FUNC_CODE, INST_ALLOCA) + STRINGIFY_CODE(FUNC_CODE, INST_LOAD) + STRINGIFY_CODE(FUNC_CODE, INST_VAARG) + STRINGIFY_CODE(FUNC_CODE, INST_STORE) + STRINGIFY_CODE(FUNC_CODE, INST_EXTRACTVAL) + STRINGIFY_CODE(FUNC_CODE, INST_INSERTVAL) + STRINGIFY_CODE(FUNC_CODE, INST_CMP2) + STRINGIFY_CODE(FUNC_CODE, INST_VSELECT) + STRINGIFY_CODE(FUNC_CODE, DEBUG_LOC_AGAIN) + STRINGIFY_CODE(FUNC_CODE, INST_CALL) + STRINGIFY_CODE(FUNC_CODE, DEBUG_LOC) + STRINGIFY_CODE(FUNC_CODE, INST_GEP) } case bitc::VALUE_SYMTAB_BLOCK_ID: switch (CodeID) { default: return nullptr; - case bitc::VST_CODE_ENTRY: return "ENTRY"; - case bitc::VST_CODE_BBENTRY: return "BBENTRY"; + STRINGIFY_CODE(VST_CODE, ENTRY) + STRINGIFY_CODE(VST_CODE, BBENTRY) } case bitc::METADATA_ATTACHMENT_ID: switch(CodeID) { default:return nullptr; - case bitc::METADATA_ATTACHMENT: return "METADATA_ATTACHMENT"; + STRINGIFY_CODE(METADATA, ATTACHMENT) } case bitc::METADATA_BLOCK_ID: switch(CodeID) { default:return nullptr; - case bitc::METADATA_STRING: return "METADATA_STRING"; - case bitc::METADATA_NAME: return "METADATA_NAME"; - case bitc::METADATA_KIND: return "METADATA_KIND"; - case bitc::METADATA_NODE: return "METADATA_NODE"; - case bitc::METADATA_VALUE: return "METADATA_VALUE"; - case bitc::METADATA_OLD_NODE: return "METADATA_OLD_NODE"; - case bitc::METADATA_OLD_FN_NODE: return "METADATA_OLD_FN_NODE"; - case bitc::METADATA_NAMED_NODE: return "METADATA_NAMED_NODE"; + STRINGIFY_CODE(METADATA, STRING) + STRINGIFY_CODE(METADATA, NAME) + STRINGIFY_CODE(METADATA, KIND) + STRINGIFY_CODE(METADATA, NODE) + STRINGIFY_CODE(METADATA, VALUE) + STRINGIFY_CODE(METADATA, OLD_NODE) + STRINGIFY_CODE(METADATA, OLD_FN_NODE) + STRINGIFY_CODE(METADATA, NAMED_NODE) + STRINGIFY_CODE(METADATA, DISTINCT_NODE) + STRINGIFY_CODE(METADATA, LOCATION) + STRINGIFY_CODE(METADATA, GENERIC_DEBUG) + STRINGIFY_CODE(METADATA, SUBRANGE) + STRINGIFY_CODE(METADATA, ENUMERATOR) + STRINGIFY_CODE(METADATA, BASIC_TYPE) + STRINGIFY_CODE(METADATA, FILE) + STRINGIFY_CODE(METADATA, DERIVED_TYPE) + STRINGIFY_CODE(METADATA, COMPOSITE_TYPE) + STRINGIFY_CODE(METADATA, SUBROUTINE_TYPE) + STRINGIFY_CODE(METADATA, COMPILE_UNIT) + STRINGIFY_CODE(METADATA, SUBPROGRAM) + STRINGIFY_CODE(METADATA, LEXICAL_BLOCK) + STRINGIFY_CODE(METADATA, LEXICAL_BLOCK_FILE) + STRINGIFY_CODE(METADATA, NAMESPACE) + STRINGIFY_CODE(METADATA, TEMPLATE_TYPE) + STRINGIFY_CODE(METADATA, TEMPLATE_VALUE) + STRINGIFY_CODE(METADATA, GLOBAL_VAR) + STRINGIFY_CODE(METADATA, LOCAL_VAR) + STRINGIFY_CODE(METADATA, EXPRESSION) + STRINGIFY_CODE(METADATA, OBJC_PROPERTY) + STRINGIFY_CODE(METADATA, IMPORTED_ENTITY) + STRINGIFY_CODE(METADATA, MODULE) } case bitc::USELIST_BLOCK_ID: switch(CodeID) { @@ -287,6 +308,7 @@ static const char *GetCodeName(unsigned CodeID, unsigned BlockID, case bitc::USELIST_CODE_BB: return "USELIST_CODE_BB"; } } +#undef STRINGIFY_CODE } struct PerRecordStats { diff --git a/tools/llvm-cov/CodeCoverage.cpp b/tools/llvm-cov/CodeCoverage.cpp index 4ff53301881d..8dc4d665f23c 100644 --- a/tools/llvm-cov/CodeCoverage.cpp +++ b/tools/llvm-cov/CodeCoverage.cpp @@ -89,7 +89,7 @@ public: LoadedSourceFiles; bool CompareFilenamesOnly; StringMap<std::string> RemappedFilenames; - llvm::Triple::ArchType CoverageArch; + std::string CoverageArch; }; } @@ -349,15 +349,12 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) { Filters.push_back(std::unique_ptr<CoverageFilter>(StatFilterer)); } - if (Arch.empty()) - CoverageArch = llvm::Triple::ArchType::UnknownArch; - else { - CoverageArch = Triple(Arch).getArch(); - if (CoverageArch == llvm::Triple::ArchType::UnknownArch) { - errs() << "error: Unknown architecture: " << Arch << "\n"; - return 1; - } + if (!Arch.empty() && + Triple(Arch).getArch() == llvm::Triple::ArchType::UnknownArch) { + errs() << "error: Unknown architecture: " << Arch << "\n"; + return 1; } + CoverageArch = Arch; for (const auto &File : InputSourceFiles) { SmallString<128> Path(File); diff --git a/tools/llvm-cxxdump/llvm-cxxdump.cpp b/tools/llvm-cxxdump/llvm-cxxdump.cpp index ef42211cf897..c627a662a962 100644 --- a/tools/llvm-cxxdump/llvm-cxxdump.cpp +++ b/tools/llvm-cxxdump/llvm-cxxdump.cpp @@ -16,6 +16,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/Object/Archive.h" #include "llvm/Object/ObjectFile.h" +#include "llvm/Object/SymbolSize.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Endian.h" #include "llvm/Support/FileSystem.h" @@ -96,14 +97,12 @@ static bool collectRelocatedSymbols(const ObjectFile *Obj, const object::symbol_iterator RelocSymI = Reloc.getSymbol(); if (RelocSymI == Obj->symbol_end()) continue; - StringRef RelocSymName; - if (error(RelocSymI->getName(RelocSymName))) - return true; - uint64_t Offset; - if (error(Reloc.getOffset(Offset))) + ErrorOr<StringRef> RelocSymName = RelocSymI->getName(); + if (error(RelocSymName.getError())) return true; + uint64_t Offset = Reloc.getOffset(); if (Offset >= SymOffset && Offset < SymEnd) { - *I = RelocSymName; + *I = *RelocSymName; ++I; } } @@ -122,14 +121,12 @@ static bool collectRelocationOffsets( const object::symbol_iterator RelocSymI = Reloc.getSymbol(); if (RelocSymI == Obj->symbol_end()) continue; - StringRef RelocSymName; - if (error(RelocSymI->getName(RelocSymName))) - return true; - uint64_t Offset; - if (error(Reloc.getOffset(Offset))) + ErrorOr<StringRef> RelocSymName = RelocSymI->getName(); + if (error(RelocSymName.getError())) return true; + uint64_t Offset = Reloc.getOffset(); if (Offset >= SymOffset && Offset < SymEnd) - Collection[std::make_pair(SymName, Offset - SymOffset)] = RelocSymName; + Collection[std::make_pair(SymName, Offset - SymOffset)] = *RelocSymName; } } return false; @@ -187,10 +184,16 @@ static void dumpCXXData(const ObjectFile *Obj) { uint8_t BytesInAddress = Obj->getBytesInAddress(); - for (const object::SymbolRef &Sym : Obj->symbols()) { - StringRef SymName; - if (error(Sym.getName(SymName))) + std::vector<std::pair<SymbolRef, uint64_t>> SymAddr = + object::computeSymbolSizes(*Obj); + + for (auto &P : SymAddr) { + object::SymbolRef Sym = P.first; + uint64_t SymSize = P.second; + ErrorOr<StringRef> SymNameOrErr = Sym.getName(); + if (error(SymNameOrErr.getError())) return; + StringRef SymName = *SymNameOrErr; object::section_iterator SecI(Obj->section_begin()); if (error(Sym.getSection(SecI))) return; @@ -207,7 +210,6 @@ static void dumpCXXData(const ObjectFile *Obj) { uint64_t SymAddress; if (error(Sym.getAddress(SymAddress))) return; - uint64_t SymSize = Sym.getSize(); uint64_t SecAddress = Sec.getAddress(); uint64_t SecSize = Sec.getSize(); uint64_t SymOffset = SymAddress - SecAddress; diff --git a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp index c1cb0218ac38..db3fcf6ee7bd 100644 --- a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp +++ b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp @@ -69,22 +69,27 @@ DumpType("debug-dump", cl::init(DIDT_All), clEnumValN(DIDT_StrOffsetsDwo, "str_offsets.dwo", ".debug_str_offsets.dwo"), clEnumValEnd)); +static int ReturnValue = EXIT_SUCCESS; + +static bool error(StringRef Filename, std::error_code EC) { + if (!EC) + return false; + errs() << Filename << ": " << EC.message() << "\n"; + ReturnValue = EXIT_FAILURE; + return true; +} + static void DumpInput(StringRef Filename) { ErrorOr<std::unique_ptr<MemoryBuffer>> BuffOrErr = MemoryBuffer::getFileOrSTDIN(Filename); - - if (std::error_code EC = BuffOrErr.getError()) { - errs() << Filename << ": " << EC.message() << "\n"; + if (error(Filename, BuffOrErr.getError())) return; - } std::unique_ptr<MemoryBuffer> Buff = std::move(BuffOrErr.get()); ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr = ObjectFile::createObjectFile(Buff->getMemBufferRef()); - if (std::error_code EC = ObjOrErr.getError()) { - errs() << Filename << ": " << EC.message() << '\n'; + if (error(Filename, ObjOrErr.getError())) return; - } ObjectFile &Obj = *ObjOrErr.get(); std::unique_ptr<DIContext> DICtx(new DWARFContextInMemory(Obj)); @@ -109,5 +114,5 @@ int main(int argc, char **argv) { std::for_each(InputFilenames.begin(), InputFilenames.end(), DumpInput); - return 0; + return ReturnValue; } diff --git a/tools/llvm-nm/llvm-nm.cpp b/tools/llvm-nm/llvm-nm.cpp index 8013f5842399..c88f37334564 100644 --- a/tools/llvm-nm/llvm-nm.cpp +++ b/tools/llvm-nm/llvm-nm.cpp @@ -250,15 +250,7 @@ static char isSymbolList64Bit(SymbolicFile &Obj) { return false; if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj)) return MachO->is64Bit(); - if (isa<ELF32LEObjectFile>(Obj)) - return false; - if (isa<ELF64LEObjectFile>(Obj)) - return true; - if (isa<ELF32BEObjectFile>(Obj)) - return false; - if (isa<ELF64BEObjectFile>(Obj)) - return true; - return false; + return cast<ELFObjectFileBase>(Obj).getBytesInAddress() == 8; } static StringRef CurrentFilename; @@ -569,7 +561,7 @@ static void sortAndPrintSymbolList(SymbolicFile &Obj, bool printName, continue; if ((I->TypeChar == 'U') && DefinedOnly) continue; - if (SizeSort && !PrintAddress && I->Size == UnknownAddressOrSize) + if (SizeSort && !PrintAddress) continue; if (PrintFileName) { if (!ArchitectureName.empty()) @@ -586,16 +578,15 @@ static void sortAndPrintSymbolList(SymbolicFile &Obj, bool printName, char SymbolAddrStr[18] = ""; char SymbolSizeStr[18] = ""; - if (OutputFormat == sysv || I->Address == UnknownAddressOrSize) + if (OutputFormat == sysv || I->Address == UnknownAddress) strcpy(SymbolAddrStr, printBlanks); if (OutputFormat == sysv) strcpy(SymbolSizeStr, printBlanks); - if (I->Address != UnknownAddressOrSize) + if (I->Address != UnknownAddress) format(printFormat, I->Address) .print(SymbolAddrStr, sizeof(SymbolAddrStr)); - if (I->Size != UnknownAddressOrSize) - format(printFormat, I->Size).print(SymbolSizeStr, sizeof(SymbolSizeStr)); + format(printFormat, I->Size).print(SymbolSizeStr, sizeof(SymbolSizeStr)); // If OutputFormat is darwin or we are printing Mach-O symbols in hex and // we have a MachOObjectFile, call darwinPrintSymbol to print as darwin's @@ -613,8 +604,7 @@ static void sortAndPrintSymbolList(SymbolicFile &Obj, bool printName, outs() << SymbolAddrStr << ' '; if (PrintSize) { outs() << SymbolSizeStr; - if (I->Size != UnknownAddressOrSize) - outs() << ' '; + outs() << ' '; } outs() << I->TypeChar; if (I->TypeChar == '-' && MachO) @@ -632,25 +622,20 @@ static void sortAndPrintSymbolList(SymbolicFile &Obj, bool printName, SymbolList.clear(); } -template <class ELFT> -static char getSymbolNMTypeChar(ELFObjectFile<ELFT> &Obj, +static char getSymbolNMTypeChar(ELFObjectFileBase &Obj, basic_symbol_iterator I) { - typedef typename ELFObjectFile<ELFT>::Elf_Sym Elf_Sym; - typedef typename ELFObjectFile<ELFT>::Elf_Shdr Elf_Shdr; - // OK, this is ELF - symbol_iterator SymI(I); + elf_symbol_iterator SymI(I); - DataRefImpl Symb = I->getRawDataRefImpl(); - const Elf_Sym *ESym = Obj.getSymbol(Symb); - const ELFFile<ELFT> &EF = *Obj.getELFFile(); - const Elf_Shdr *ESec = EF.getSection(ESym); + elf_section_iterator SecI = Obj.section_end(); + if (error(SymI->getSection(SecI))) + return '?'; - if (ESec) { - switch (ESec->sh_type) { + if (SecI != Obj.section_end()) { + switch (SecI->getType()) { case ELF::SHT_PROGBITS: case ELF::SHT_DYNAMIC: - switch (ESec->sh_flags) { + switch (SecI->getFlags()) { case (ELF::SHF_ALLOC | ELF::SHF_EXECINSTR): return 't'; case (ELF::SHF_TLS | ELF::SHF_ALLOC | ELF::SHF_WRITE): @@ -667,17 +652,17 @@ static char getSymbolNMTypeChar(ELFObjectFile<ELFT> &Obj, } } - if (ESym->getType() == ELF::STT_SECTION) { - StringRef Name; - if (error(SymI->getName(Name))) + if (SymI->getELFType() == ELF::STT_SECTION) { + ErrorOr<StringRef> Name = SymI->getName(); + if (error(Name.getError())) return '?'; - return StringSwitch<char>(Name) + return StringSwitch<char>(*Name) .StartsWith(".debug", 'N') .StartsWith(".note", 'n') .Default('?'); } - return '?'; + return 'n'; } static char getSymbolNMTypeChar(COFFObjectFile &Obj, symbol_iterator I) { @@ -685,11 +670,11 @@ static char getSymbolNMTypeChar(COFFObjectFile &Obj, symbol_iterator I) { // OK, this is COFF. symbol_iterator SymI(I); - StringRef Name; - if (error(SymI->getName(Name))) + ErrorOr<StringRef> Name = SymI->getName(); + if (error(Name.getError())) return '?'; - char Ret = StringSwitch<char>(Name) + char Ret = StringSwitch<char>(*Name) .StartsWith(".debug", 'N') .StartsWith(".sxdata", 'N') .Default('?'); @@ -784,26 +769,12 @@ static char getSymbolNMTypeChar(IRObjectFile &Obj, basic_symbol_iterator I) { return getSymbolNMTypeChar(*GV); } -template <class ELFT> -static bool isELFObject(ELFObjectFile<ELFT> &Obj, symbol_iterator I) { - typedef typename ELFObjectFile<ELFT>::Elf_Sym Elf_Sym; - - DataRefImpl Symb = I->getRawDataRefImpl(); - const Elf_Sym *ESym = Obj.getSymbol(Symb); - - return ESym->getType() == ELF::STT_OBJECT; -} - static bool isObject(SymbolicFile &Obj, basic_symbol_iterator I) { - if (ELF32LEObjectFile *ELF = dyn_cast<ELF32LEObjectFile>(&Obj)) - return isELFObject(*ELF, I); - if (ELF64LEObjectFile *ELF = dyn_cast<ELF64LEObjectFile>(&Obj)) - return isELFObject(*ELF, I); - if (ELF32BEObjectFile *ELF = dyn_cast<ELF32BEObjectFile>(&Obj)) - return isELFObject(*ELF, I); - if (ELF64BEObjectFile *ELF = dyn_cast<ELF64BEObjectFile>(&Obj)) - return isELFObject(*ELF, I); - return false; + auto *ELF = dyn_cast<ELFObjectFileBase>(&Obj); + if (!ELF) + return false; + + return elf_symbol_iterator(I)->getELFType() == ELF::STT_OBJECT; } static char getNMTypeChar(SymbolicFile &Obj, basic_symbol_iterator I) { @@ -830,14 +801,8 @@ static char getNMTypeChar(SymbolicFile &Obj, basic_symbol_iterator I) { Ret = getSymbolNMTypeChar(*COFF, I); else if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj)) Ret = getSymbolNMTypeChar(*MachO, I); - else if (ELF32LEObjectFile *ELF = dyn_cast<ELF32LEObjectFile>(&Obj)) - Ret = getSymbolNMTypeChar(*ELF, I); - else if (ELF64LEObjectFile *ELF = dyn_cast<ELF64LEObjectFile>(&Obj)) - Ret = getSymbolNMTypeChar(*ELF, I); - else if (ELF32BEObjectFile *ELF = dyn_cast<ELF32BEObjectFile>(&Obj)) - Ret = getSymbolNMTypeChar(*ELF, I); else - Ret = getSymbolNMTypeChar(cast<ELF64BEObjectFile>(Obj), I); + Ret = getSymbolNMTypeChar(cast<ELFObjectFileBase>(Obj), I); if (Symflags & object::SymbolRef::SF_Global) Ret = toupper(Ret); @@ -871,8 +836,8 @@ static unsigned getNsectForSegSect(MachOObjectFile *Obj) { // It is called once for each symbol in a Mach-O file from // dumpSymbolNamesFromObject() and returns the section number for that symbol // if it is in a section, else it returns 0. -static unsigned getNsectInMachO(MachOObjectFile &Obj, basic_symbol_iterator I) { - DataRefImpl Symb = I->getRawDataRefImpl(); +static unsigned getNsectInMachO(MachOObjectFile &Obj, BasicSymbolRef Sym) { + DataRefImpl Symb = Sym.getRawDataRefImpl(); if (Obj.is64Bit()) { MachO::nlist_64 STE = Obj.getSymbol64TableEntry(Symb); if ((STE.n_type & MachO::N_TYPE) == MachO::N_SECT) @@ -889,17 +854,16 @@ static void dumpSymbolNamesFromObject(SymbolicFile &Obj, bool printName, std::string ArchiveName = std::string(), std::string ArchitectureName = std::string()) { - basic_symbol_iterator IBegin = Obj.symbol_begin(); - basic_symbol_iterator IEnd = Obj.symbol_end(); + auto Symbols = Obj.symbols(); if (DynamicSyms) { - if (!Obj.isELF()) { + const auto *E = dyn_cast<ELFObjectFileBase>(&Obj); + if (!E) { error("File format has no dynamic symbol table", Obj.getFileName()); return; } - std::pair<symbol_iterator, symbol_iterator> IDyn = - getELFDynamicSymbolIterators(&Obj); - IBegin = IDyn.first; - IEnd = IDyn.second; + auto DynSymbols = E->getDynamicSymbolIterators(); + Symbols = + make_range<basic_symbol_iterator>(DynSymbols.begin(), DynSymbols.end()); } std::string NameBuffer; raw_string_ostream OS(NameBuffer); @@ -913,13 +877,13 @@ static void dumpSymbolNamesFromObject(SymbolicFile &Obj, bool printName, if (Nsect == 0) return; } - for (basic_symbol_iterator I = IBegin; I != IEnd; ++I) { - uint32_t SymFlags = I->getFlags(); + for (BasicSymbolRef Sym : Symbols) { + uint32_t SymFlags = Sym.getFlags(); if (!DebugSyms && (SymFlags & SymbolRef::SF_FormatSpecific)) continue; if (WithoutAliases) { if (IRObjectFile *IR = dyn_cast<IRObjectFile>(&Obj)) { - const GlobalValue *GV = IR->getSymbolGV(I->getRawDataRefImpl()); + const GlobalValue *GV = IR->getSymbolGV(Sym.getRawDataRefImpl()); if (GV && isa<GlobalAlias>(GV)) continue; } @@ -927,23 +891,24 @@ static void dumpSymbolNamesFromObject(SymbolicFile &Obj, bool printName, // If a "-s segname sectname" option was specified and this is a Mach-O // file and this section appears in this file, Nsect will be non-zero then // see if this symbol is a symbol from that section and if not skip it. - if (Nsect && Nsect != getNsectInMachO(*MachO, I)) + if (Nsect && Nsect != getNsectInMachO(*MachO, Sym)) continue; NMSymbol S; - S.Size = UnknownAddressOrSize; - S.Address = UnknownAddressOrSize; - if (PrintSize && isa<ELFObjectFileBase>(Obj)) { - symbol_iterator SymI = I; - S.Size = SymI->getSize(); + S.Size = 0; + S.Address = UnknownAddress; + if (PrintSize) { + if (isa<ELFObjectFileBase>(&Obj)) + S.Size = ELFSymbolRef(Sym).getSize(); } - if (PrintAddress && isa<ObjectFile>(Obj)) - if (error(symbol_iterator(I)->getAddress(S.Address))) + if (PrintAddress && isa<ObjectFile>(Obj)) { + if (error(SymbolRef(Sym).getAddress(S.Address))) break; - S.TypeChar = getNMTypeChar(Obj, I); - if (error(I->printName(OS))) + } + S.TypeChar = getNMTypeChar(Obj, Sym); + if (error(Sym.printName(OS))) break; OS << '\0'; - S.Symb = I->getRawDataRefImpl(); + S.Symb = Sym.getRawDataRefImpl(); SymbolList.push_back(S); } diff --git a/tools/llvm-objdump/CMakeLists.txt b/tools/llvm-objdump/CMakeLists.txt index d717653685c8..1f2721ab5452 100644 --- a/tools/llvm-objdump/CMakeLists.txt +++ b/tools/llvm-objdump/CMakeLists.txt @@ -1,5 +1,6 @@ set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} + CodeGen DebugInfoDWARF MC MCDisassembler diff --git a/tools/llvm-objdump/COFFDump.cpp b/tools/llvm-objdump/COFFDump.cpp index 976a92154bda..58bdddfa9918 100644 --- a/tools/llvm-objdump/COFFDump.cpp +++ b/tools/llvm-objdump/COFFDump.cpp @@ -177,9 +177,7 @@ static std::error_code resolveSymbol(const std::vector<RelocationRef> &Rels, for (std::vector<RelocationRef>::const_iterator I = Rels.begin(), E = Rels.end(); I != E; ++I) { - uint64_t Ofs; - if (std::error_code EC = I->getOffset(Ofs)) - return EC; + uint64_t Ofs = I->getOffset(); if (Ofs == Offset) { Sym = *I->getSymbol(); return std::error_code(); @@ -215,8 +213,10 @@ static std::error_code resolveSymbolName(const std::vector<RelocationRef> &Rels, SymbolRef Sym; if (std::error_code EC = resolveSymbol(Rels, Offset, Sym)) return EC; - if (std::error_code EC = Sym.getName(Name)) + ErrorOr<StringRef> NameOrErr = Sym.getName(); + if (std::error_code EC = NameOrErr.getError()) return EC; + Name = *NameOrErr; return std::error_code(); } diff --git a/tools/llvm-objdump/ELFDump.cpp b/tools/llvm-objdump/ELFDump.cpp index 9c091a410d8f..2d0d7d7db0f3 100644 --- a/tools/llvm-objdump/ELFDump.cpp +++ b/tools/llvm-objdump/ELFDump.cpp @@ -24,9 +24,9 @@ using namespace llvm::object; template <class ELFT> void printProgramHeaders(const ELFFile<ELFT> *o) { typedef ELFFile<ELFT> ELFO; outs() << "Program Header:\n"; - for (typename ELFO::Elf_Phdr_Iter pi = o->begin_program_headers(), - pe = o->end_program_headers(); - pi != pe; ++pi) { + for (typename ELFO::Elf_Phdr_Iter pi = o->program_header_begin(), + pe = o->program_header_end(); + pi != pe; ++pi) { switch (pi->p_type) { case ELF::PT_LOAD: outs() << " LOAD "; diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index 1730bf3859f0..5263c33bf2dc 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -178,9 +178,8 @@ static const Target *GetTarget(const MachOObjectFile *MachOObj, struct SymbolSorter { bool operator()(const SymbolRef &A, const SymbolRef &B) { - SymbolRef::Type AType, BType; - A.getType(AType); - B.getType(BType); + SymbolRef::Type AType = A.getType(); + SymbolRef::Type BType = B.getType(); uint64_t AAddr, BAddr; if (AType != SymbolRef::ST_Function) @@ -283,9 +282,10 @@ static void getSectionsAndSymbols(MachOObjectFile *MachOObj, SmallVectorImpl<uint64_t> &FoundFns, uint64_t &BaseSegmentAddress) { for (const SymbolRef &Symbol : MachOObj->symbols()) { - StringRef SymName; - Symbol.getName(SymName); - if (!SymName.startswith("ltmp")) + ErrorOr<StringRef> SymName = Symbol.getName(); + if (std::error_code EC = SymName.getError()) + report_fatal_error(EC.message()); + if (!SymName->startswith("ltmp")) Symbols.push_back(Symbol); } @@ -362,9 +362,10 @@ static void PrintIndirectSymbolTable(MachOObjectFile *O, bool verbose, if (indirect_symbol < Symtab.nsyms) { symbol_iterator Sym = O->getSymbolByIndex(indirect_symbol); SymbolRef Symbol = *Sym; - StringRef SymName; - Symbol.getName(SymName); - outs() << SymName; + ErrorOr<StringRef> SymName = Symbol.getName(); + if (std::error_code EC = SymName.getError()) + report_fatal_error(EC.message()); + outs() << *SymName; } else { outs() << "?"; } @@ -588,14 +589,15 @@ static void CreateSymbolAddressMap(MachOObjectFile *O, SymbolAddressMap *AddrMap) { // Create a map of symbol addresses to symbol names. for (const SymbolRef &Symbol : O->symbols()) { - SymbolRef::Type ST; - Symbol.getType(ST); + SymbolRef::Type ST = Symbol.getType(); if (ST == SymbolRef::ST_Function || ST == SymbolRef::ST_Data || ST == SymbolRef::ST_Other) { uint64_t Address; Symbol.getAddress(Address); - StringRef SymName; - Symbol.getName(SymName); + ErrorOr<StringRef> SymNameOrErr = Symbol.getName(); + if (std::error_code EC = SymNameOrErr.getError()) + report_fatal_error(EC.message()); + StringRef SymName = *SymNameOrErr; if (!SymName.startswith(".objc")) (*AddrMap)[Address] = SymName; } @@ -798,8 +800,7 @@ static void DumpLiteralPointerSection(MachOObjectFile *O, RE = O->getRelocation(Rel); isExtern = O->getPlainRelocationExternal(RE); if (isExtern) { - uint64_t RelocOffset; - Reloc.getOffset(RelocOffset); + uint64_t RelocOffset = Reloc.getOffset(); symbol_iterator RelocSym = Reloc.getSymbol(); Relocs.push_back(std::make_pair(RelocOffset, *RelocSym)); } @@ -833,9 +834,10 @@ static void DumpLiteralPointerSection(MachOObjectFile *O, [&](const std::pair<uint64_t, SymbolRef> &P) { return P.first == i; }); if (Reloc != Relocs.end()) { symbol_iterator RelocSym = Reloc->second; - StringRef SymName; - RelocSym->getName(SymName); - outs() << "external relocation entry for symbol:" << SymName << "\n"; + ErrorOr<StringRef> SymName = RelocSym->getName(); + if (std::error_code EC = SymName.getError()) + report_fatal_error(EC.message()); + outs() << "external relocation entry for symbol:" << *SymName << "\n"; continue; } @@ -1765,8 +1767,7 @@ static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset, bool r_scattered = false; uint32_t r_value, pair_r_value, r_type; for (const RelocationRef &Reloc : info->S.relocations()) { - uint64_t RelocOffset; - Reloc.getOffset(RelocOffset); + uint64_t RelocOffset = Reloc.getOffset(); if (RelocOffset == sect_offset) { Rel = Reloc.getRawDataRefImpl(); RE = info->O->getRelocation(Rel); @@ -1797,9 +1798,10 @@ static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset, } } if (reloc_found && isExtern) { - StringRef SymName; - Symbol.getName(SymName); - const char *name = SymName.data(); + ErrorOr<StringRef> SymName = Symbol.getName(); + if (std::error_code EC = SymName.getError()) + report_fatal_error(EC.message()); + const char *name = SymName->data(); op_info->AddSymbol.Present = 1; op_info->AddSymbol.Name = name; // For i386 extern relocation entries the value in the instruction is @@ -1843,8 +1845,7 @@ static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset, bool isExtern = false; SymbolRef Symbol; for (const RelocationRef &Reloc : info->S.relocations()) { - uint64_t RelocOffset; - Reloc.getOffset(RelocOffset); + uint64_t RelocOffset = Reloc.getOffset(); if (RelocOffset == sect_offset) { Rel = Reloc.getRawDataRefImpl(); RE = info->O->getRelocation(Rel); @@ -1864,9 +1865,10 @@ static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset, // is the offset from the external symbol. if (info->O->getAnyRelocationPCRel(RE)) op_info->Value -= Pc + Offset + Size; - StringRef SymName; - Symbol.getName(SymName); - const char *name = SymName.data(); + ErrorOr<StringRef> SymName = Symbol.getName(); + if (std::error_code EC = SymName.getError()) + report_fatal_error(EC.message()); + const char *name = SymName->data(); unsigned Type = info->O->getAnyRelocationType(RE); if (Type == MachO::X86_64_RELOC_SUBTRACTOR) { DataRefImpl RelNext = Rel; @@ -1880,9 +1882,10 @@ static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset, op_info->SubtractSymbol.Name = name; symbol_iterator RelocSymNext = info->O->getSymbolByIndex(SymbolNum); Symbol = *RelocSymNext; - StringRef SymNameNext; - Symbol.getName(SymNameNext); - name = SymNameNext.data(); + ErrorOr<StringRef> SymNameNext = Symbol.getName(); + if (std::error_code EC = SymNameNext.getError()) + report_fatal_error(EC.message()); + name = SymNameNext->data(); } } // TODO: add the VariantKinds to op_info->VariantKind for relocation types @@ -1913,8 +1916,7 @@ static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset, auto Reloc = std::find_if(info->S.relocations().begin(), info->S.relocations().end(), [&](const RelocationRef &Reloc) { - uint64_t RelocOffset; - Reloc.getOffset(RelocOffset); + uint64_t RelocOffset = Reloc.getOffset(); return RelocOffset == sect_offset; }); @@ -1950,9 +1952,10 @@ static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset, } if (isExtern) { - StringRef SymName; - Symbol.getName(SymName); - const char *name = SymName.data(); + ErrorOr<StringRef> SymName = Symbol.getName(); + if (std::error_code EC = SymName.getError()) + report_fatal_error(EC.message()); + const char *name = SymName->data(); op_info->AddSymbol.Present = 1; op_info->AddSymbol.Name = name; switch (r_type) { @@ -2040,8 +2043,7 @@ static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset, auto Reloc = std::find_if(info->S.relocations().begin(), info->S.relocations().end(), [&](const RelocationRef &Reloc) { - uint64_t RelocOffset; - Reloc.getOffset(RelocOffset); + uint64_t RelocOffset = Reloc.getOffset(); return RelocOffset == sect_offset; }); @@ -2063,9 +2065,10 @@ static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset, // NOTE: Scattered relocations don't exist on arm64. if (!info->O->getPlainRelocationExternal(RE)) return 0; - StringRef SymName; - Reloc->getSymbol()->getName(SymName); - const char *name = SymName.data(); + ErrorOr<StringRef> SymName = Reloc->getSymbol()->getName(); + if (std::error_code EC = SymName.getError()) + report_fatal_error(EC.message()); + const char *name = SymName->data(); op_info->AddSymbol.Present = 1; op_info->AddSymbol.Name = name; @@ -2192,9 +2195,10 @@ static const char *GuessIndirectSymbol(uint64_t ReferenceValue, if (indirect_symbol < Symtab.nsyms) { symbol_iterator Sym = info->O->getSymbolByIndex(indirect_symbol); SymbolRef Symbol = *Sym; - StringRef SymName; - Symbol.getName(SymName); - const char *name = SymName.data(); + ErrorOr<StringRef> SymName = Symbol.getName(); + if (std::error_code EC = SymName.getError()) + report_fatal_error(EC.message()); + const char *name = SymName->data(); return name; } } @@ -2226,9 +2230,10 @@ static const char *GuessIndirectSymbol(uint64_t ReferenceValue, if (indirect_symbol < Symtab.nsyms) { symbol_iterator Sym = info->O->getSymbolByIndex(indirect_symbol); SymbolRef Symbol = *Sym; - StringRef SymName; - Symbol.getName(SymName); - const char *name = SymName.data(); + ErrorOr<StringRef> SymName = Symbol.getName(); + if (std::error_code EC = SymName.getError()) + report_fatal_error(EC.message()); + const char *name = SymName->data(); return name; } } @@ -2417,10 +2422,9 @@ static const char *get_pointer_32(uint32_t Address, uint32_t &offset, // for the specified section offset in the specified section reference. // If no relocation information is found and a non-zero ReferenceValue for the // symbol is passed, look up that address in the info's AddrMap. -static const char * -get_symbol_64(uint32_t sect_offset, SectionRef S, DisassembleInfo *info, - uint64_t &n_value, - uint64_t ReferenceValue = UnknownAddressOrSize) { +static const char *get_symbol_64(uint32_t sect_offset, SectionRef S, + DisassembleInfo *info, uint64_t &n_value, + uint64_t ReferenceValue = UnknownAddress) { n_value = 0; if (!info->verbose) return nullptr; @@ -2432,8 +2436,7 @@ get_symbol_64(uint32_t sect_offset, SectionRef S, DisassembleInfo *info, bool isExtern = false; SymbolRef Symbol; for (const RelocationRef &Reloc : S.relocations()) { - uint64_t RelocOffset; - Reloc.getOffset(RelocOffset); + uint64_t RelocOffset = Reloc.getOffset(); if (RelocOffset == sect_offset) { Rel = Reloc.getRawDataRefImpl(); RE = info->O->getRelocation(Rel); @@ -2454,12 +2457,14 @@ get_symbol_64(uint32_t sect_offset, SectionRef S, DisassembleInfo *info, const char *SymbolName = nullptr; if (reloc_found && isExtern) { Symbol.getAddress(n_value); - if (n_value == UnknownAddressOrSize) + if (n_value == UnknownAddress) n_value = 0; - StringRef name; - Symbol.getName(name); - if (!name.empty()) { - SymbolName = name.data(); + ErrorOr<StringRef> NameOrError = Symbol.getName(); + if (std::error_code EC = NameOrError.getError()) + report_fatal_error(EC.message()); + StringRef Name = *NameOrError; + if (!Name.empty()) { + SymbolName = Name.data(); return SymbolName; } } @@ -2475,7 +2480,7 @@ get_symbol_64(uint32_t sect_offset, SectionRef S, DisassembleInfo *info, // We did not find an external relocation entry so look up the ReferenceValue // as an address of a symbol and if found return that symbol's name. - if (ReferenceValue != UnknownAddressOrSize) + if (ReferenceValue != UnknownAddress) SymbolName = GuessSymbolName(ReferenceValue, info->AddrMap); return SymbolName; @@ -5614,8 +5619,7 @@ static const char *GuessLiteralPointer(uint64_t ReferenceValue, bool isExtern = false; SymbolRef Symbol; for (const RelocationRef &Reloc : info->S.relocations()) { - uint64_t RelocOffset; - Reloc.getOffset(RelocOffset); + uint64_t RelocOffset = Reloc.getOffset(); if (RelocOffset == sect_offset) { Rel = Reloc.getRawDataRefImpl(); RE = info->O->getRelocation(Rel); @@ -6109,8 +6113,7 @@ static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF, // Parse relocations. std::vector<std::pair<uint64_t, SymbolRef>> Relocs; for (const RelocationRef &Reloc : Sections[SectIdx].relocations()) { - uint64_t RelocOffset; - Reloc.getOffset(RelocOffset); + uint64_t RelocOffset = Reloc.getOffset(); uint64_t SectionAddress = Sections[SectIdx].getAddress(); RelocOffset -= SectionAddress; @@ -6125,14 +6128,15 @@ static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF, SymbolAddressMap AddrMap; bool DisSymNameFound = false; for (const SymbolRef &Symbol : MachOOF->symbols()) { - SymbolRef::Type ST; - Symbol.getType(ST); + SymbolRef::Type ST = Symbol.getType(); if (ST == SymbolRef::ST_Function || ST == SymbolRef::ST_Data || ST == SymbolRef::ST_Other) { uint64_t Address; Symbol.getAddress(Address); - StringRef SymName; - Symbol.getName(SymName); + ErrorOr<StringRef> SymNameOrErr = Symbol.getName(); + if (std::error_code EC = SymNameOrErr.getError()) + report_fatal_error(EC.message()); + StringRef SymName = *SymNameOrErr; AddrMap[Address] = SymName; if (!DisSymName.empty() && DisSymName == SymName) DisSymNameFound = true; @@ -6171,11 +6175,12 @@ static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF, // Disassemble symbol by symbol. for (unsigned SymIdx = 0; SymIdx != Symbols.size(); SymIdx++) { - StringRef SymName; - Symbols[SymIdx].getName(SymName); + ErrorOr<StringRef> SymNameOrErr = Symbols[SymIdx].getName(); + if (std::error_code EC = SymNameOrErr.getError()) + report_fatal_error(EC.message()); + StringRef SymName = *SymNameOrErr; - SymbolRef::Type ST; - Symbols[SymIdx].getType(ST); + SymbolRef::Type ST = Symbols[SymIdx].getType(); if (ST != SymbolRef::ST_Function) continue; @@ -6200,8 +6205,7 @@ static void DisassembleMachO(StringRef Filename, MachOObjectFile *MachOOF, uint64_t NextSym = 0; uint64_t NextSymIdx = SymIdx + 1; while (Symbols.size() > NextSymIdx) { - SymbolRef::Type NextSymType; - Symbols[NextSymIdx].getType(NextSymType); + SymbolRef::Type NextSymType = Symbols[NextSymIdx].getType(); if (NextSymType == SymbolRef::ST_Function) { containsNextSym = Sections[SectIdx].containsSymbol(Symbols[NextSymIdx]); @@ -6437,7 +6441,10 @@ static void findUnwindRelocNameAddend(const MachOObjectFile *Obj, const RelocationRef &Reloc, uint64_t Addr, StringRef &Name, uint64_t &Addend) { if (Reloc.getSymbol() != Obj->symbol_end()) { - Reloc.getSymbol()->getName(Name); + ErrorOr<StringRef> NameOrErr = Reloc.getSymbol()->getName(); + if (std::error_code EC = NameOrErr.getError()) + report_fatal_error(EC.message()); + Name = *NameOrErr; Addend = Addr; return; } @@ -6463,7 +6470,10 @@ static void findUnwindRelocNameAddend(const MachOObjectFile *Obj, Sym->second.getSection(SymSection); if (RelocSection == *SymSection) { // There's a valid symbol in the same section before this reference. - Sym->second.getName(Name); + ErrorOr<StringRef> NameOrErr = Sym->second.getName(); + if (std::error_code EC = NameOrErr.getError()) + report_fatal_error(EC.message()); + Name = *NameOrErr; Addend = Addr - Sym->first; return; } @@ -6480,7 +6490,7 @@ static void printUnwindRelocDest(const MachOObjectFile *Obj, StringRef Name; uint64_t Addend; - if (!Reloc.getObjectFile()) + if (!Reloc.getObject()) return; findUnwindRelocNameAddend(Obj, Symbols, Reloc, Addr, Name, Addend); @@ -6516,8 +6526,7 @@ printMachOCompactUnwindSection(const MachOObjectFile *Obj, // Next we need to look at the relocations to find out what objects are // actually being referred to. for (const RelocationRef &Reloc : CompactUnwind.relocations()) { - uint64_t RelocAddress; - Reloc.getOffset(RelocAddress); + uint64_t RelocAddress = Reloc.getOffset(); uint32_t EntryIdx = RelocAddress / EntrySize; uint32_t OffsetInEntry = RelocAddress - EntryIdx * EntrySize; @@ -6553,7 +6562,7 @@ printMachOCompactUnwindSection(const MachOObjectFile *Obj, << format("0x%08" PRIx32, Entry.CompactEncoding) << '\n'; // 4. The personality function, if present. - if (Entry.PersonalityReloc.getObjectFile()) { + if (Entry.PersonalityReloc.getObject()) { outs() << " personality function: " << format("0x%" PRIx64, Entry.PersonalityAddr) << ' '; printUnwindRelocDest(Obj, Symbols, Entry.PersonalityReloc, @@ -6562,7 +6571,7 @@ printMachOCompactUnwindSection(const MachOObjectFile *Obj, } // 5. This entry's language-specific data area. - if (Entry.LSDAReloc.getObjectFile()) { + if (Entry.LSDAReloc.getObject()) { outs() << " LSDA: " << format("0x%" PRIx64, Entry.LSDAAddr) << ' '; printUnwindRelocDest(Obj, Symbols, Entry.LSDAReloc, Entry.LSDAAddr); diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index 1152a154b4db..786981854609 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -17,9 +17,11 @@ //===----------------------------------------------------------------------===// #include "llvm-objdump.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Triple.h" +#include "llvm/CodeGen/FaultMaps.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCDisassembler.h" @@ -153,6 +155,9 @@ cl::opt<bool> llvm::PrintImmHex("print-imm-hex", cl::desc("Use hex format for immediate values")); +cl::opt<bool> PrintFaultMaps("fault-map-section", + cl::desc("Display contents of faultmap section")); + static StringRef ToolName; static int ReturnValue = EXIT_SUCCESS; @@ -207,9 +212,8 @@ static const Target *getTarget(const ObjectFile *Obj = nullptr) { } bool llvm::RelocAddressLess(RelocationRef a, RelocationRef b) { - uint64_t a_addr, b_addr; - if (error(a.getOffset(a_addr))) return false; - if (error(b.getOffset(b_addr))) return false; + uint64_t a_addr = a.getOffset(); + uint64_t b_addr = b.getOffset(); return a_addr < b_addr; } @@ -294,60 +298,68 @@ PrettyPrinter &selectPrettyPrinter(Triple const &Triple) { } template <class ELFT> -static const typename ELFObjectFile<ELFT>::Elf_Rel * -getRel(const ELFFile<ELFT> &EF, DataRefImpl Rel) { - typedef typename ELFObjectFile<ELFT>::Elf_Rel Elf_Rel; - return EF.template getEntry<Elf_Rel>(Rel.d.a, Rel.d.b); -} - -template <class ELFT> -static const typename ELFObjectFile<ELFT>::Elf_Rela * -getRela(const ELFFile<ELFT> &EF, DataRefImpl Rela) { - typedef typename ELFObjectFile<ELFT>::Elf_Rela Elf_Rela; - return EF.template getEntry<Elf_Rela>(Rela.d.a, Rela.d.b); -} - -template <class ELFT> static std::error_code getRelocationValueString(const ELFObjectFile<ELFT> *Obj, DataRefImpl Rel, SmallVectorImpl<char> &Result) { typedef typename ELFObjectFile<ELFT>::Elf_Sym Elf_Sym; typedef typename ELFObjectFile<ELFT>::Elf_Shdr Elf_Shdr; + typedef typename ELFObjectFile<ELFT>::Elf_Rel Elf_Rel; + typedef typename ELFObjectFile<ELFT>::Elf_Rela Elf_Rela; + const ELFFile<ELFT> &EF = *Obj->getELFFile(); - const Elf_Shdr *sec = EF.getSection(Rel.d.a); + ErrorOr<const Elf_Shdr *> SecOrErr = EF.getSection(Rel.d.a); + if (std::error_code EC = SecOrErr.getError()) + return EC; + const Elf_Shdr *Sec = *SecOrErr; + ErrorOr<const Elf_Shdr *> SymTabOrErr = EF.getSection(Sec->sh_link); + if (std::error_code EC = SymTabOrErr.getError()) + return EC; + const Elf_Shdr *SymTab = *SymTabOrErr; + assert(SymTab->sh_type == ELF::SHT_SYMTAB || + SymTab->sh_type == ELF::SHT_DYNSYM); + ErrorOr<const Elf_Shdr *> StrTabSec = EF.getSection(SymTab->sh_link); + if (std::error_code EC = StrTabSec.getError()) + return EC; + ErrorOr<StringRef> StrTabOrErr = EF.getStringTable(*StrTabSec); + if (std::error_code EC = StrTabOrErr.getError()) + return EC; + StringRef StrTab = *StrTabOrErr; uint8_t type; StringRef res; int64_t addend = 0; uint16_t symbol_index = 0; - switch (sec->sh_type) { + switch (Sec->sh_type) { default: return object_error::parse_failed; case ELF::SHT_REL: { - type = getRel(EF, Rel)->getType(EF.isMips64EL()); - symbol_index = getRel(EF, Rel)->getSymbol(EF.isMips64EL()); + const Elf_Rel *ERel = Obj->getRel(Rel); + type = ERel->getType(EF.isMips64EL()); + symbol_index = ERel->getSymbol(EF.isMips64EL()); // TODO: Read implicit addend from section data. break; } case ELF::SHT_RELA: { - type = getRela(EF, Rel)->getType(EF.isMips64EL()); - symbol_index = getRela(EF, Rel)->getSymbol(EF.isMips64EL()); - addend = getRela(EF, Rel)->r_addend; + const Elf_Rela *ERela = Obj->getRela(Rel); + type = ERela->getType(EF.isMips64EL()); + symbol_index = ERela->getSymbol(EF.isMips64EL()); + addend = ERela->r_addend; break; } } const Elf_Sym *symb = - EF.template getEntry<Elf_Sym>(sec->sh_link, symbol_index); + EF.template getEntry<Elf_Sym>(Sec->sh_link, symbol_index); StringRef Target; - const Elf_Shdr *SymSec = EF.getSection(symb); + ErrorOr<const Elf_Shdr *> SymSec = EF.getSection(symb); + if (std::error_code EC = SymSec.getError()) + return EC; if (symb->getType() == ELF::STT_SECTION) { - ErrorOr<StringRef> SecName = EF.getSectionName(SymSec); + ErrorOr<StringRef> SecName = EF.getSectionName(*SymSec); if (std::error_code EC = SecName.getError()) return EC; Target = *SecName; } else { - ErrorOr<StringRef> SymName = - EF.getSymbolName(EF.getSection(sec->sh_link), symb); + ErrorOr<StringRef> SymName = symb->getName(StrTab); if (!SymName) return SymName.getError(); Target = *SymName; @@ -421,9 +433,10 @@ static std::error_code getRelocationValueString(const COFFObjectFile *Obj, const RelocationRef &Rel, SmallVectorImpl<char> &Result) { symbol_iterator SymI = Rel.getSymbol(); - StringRef SymName; - if (std::error_code EC = SymI->getName(SymName)) + ErrorOr<StringRef> SymNameOrErr = SymI->getName(); + if (std::error_code EC = SymNameOrErr.getError()) return EC; + StringRef SymName = *SymNameOrErr; Result.append(SymName.begin(), SymName.end()); return std::error_code(); } @@ -443,15 +456,15 @@ static void printRelocationTargetName(const MachOObjectFile *O, for (const SymbolRef &Symbol : O->symbols()) { std::error_code ec; uint64_t Addr; - StringRef Name; + ErrorOr<StringRef> Name = Symbol.getName(); if ((ec = Symbol.getAddress(Addr))) report_fatal_error(ec.message()); if (Addr != Val) continue; - if ((ec = Symbol.getName(Name))) - report_fatal_error(ec.message()); - fmt << Name; + if (std::error_code EC = Name.getError()) + report_fatal_error(EC.message()); + fmt << *Name; return; } @@ -481,7 +494,9 @@ static void printRelocationTargetName(const MachOObjectFile *O, if (isExtern) { symbol_iterator SI = O->symbol_begin(); advance(SI, Val); - SI->getName(S); + ErrorOr<StringRef> SOrErr = SI->getName(); + if (!error(SOrErr.getError())) + S = *SOrErr; } else { section_iterator SI = O->section_begin(); // Adjust for the fact that sections are 1-indexed. @@ -672,7 +687,7 @@ static std::error_code getRelocationValueString(const MachOObjectFile *Obj, static std::error_code getRelocationValueString(const RelocationRef &Rel, SmallVectorImpl<char> &Result) { - const ObjectFile *Obj = Rel.getObjectFile(); + const ObjectFile *Obj = Rel.getObject(); if (auto *ELF = dyn_cast<ELFObjectFileBase>(Obj)) return getRelocationValueString(ELF, Rel, Result); if (auto *COFF = dyn_cast<COFFObjectFile>(Obj)) @@ -681,6 +696,39 @@ static std::error_code getRelocationValueString(const RelocationRef &Rel, return getRelocationValueString(MachO, Rel, Result); } +/// @brief Indicates whether this relocation should hidden when listing +/// relocations, usually because it is the trailing part of a multipart +/// relocation that will be printed as part of the leading relocation. +static bool getHidden(RelocationRef RelRef) { + const ObjectFile *Obj = RelRef.getObject(); + auto *MachO = dyn_cast<MachOObjectFile>(Obj); + if (!MachO) + return false; + + unsigned Arch = MachO->getArch(); + DataRefImpl Rel = RelRef.getRawDataRefImpl(); + uint64_t Type = MachO->getRelocationType(Rel); + + // On arches that use the generic relocations, GENERIC_RELOC_PAIR + // is always hidden. + if (Arch == Triple::x86 || Arch == Triple::arm || Arch == Triple::ppc) { + if (Type == MachO::GENERIC_RELOC_PAIR) + return true; + } else if (Arch == Triple::x86_64) { + // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows + // an X86_64_RELOC_SUBTRACTOR. + if (Type == MachO::X86_64_RELOC_UNSIGNED && Rel.d.a > 0) { + DataRefImpl RelPrev = Rel; + RelPrev.d.a--; + uint64_t PrevType = MachO->getRelocationType(RelPrev); + if (PrevType == MachO::X86_64_RELOC_SUBTRACTOR) + return true; + } + } + + return false; +} + static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { const Target *TheTarget = getTarget(Obj); // getTarget() will have already issued a diagnostic if necessary, so @@ -779,16 +827,16 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { uint64_t Address; if (error(Symbol.getAddress(Address))) break; - if (Address == UnknownAddressOrSize) + if (Address == UnknownAddress) continue; Address -= SectionAddr; if (Address >= SectSize) continue; - StringRef Name; - if (error(Symbol.getName(Name))) + ErrorOr<StringRef> Name = Symbol.getName(); + if (error(Name.getError())) break; - Symbols.push_back(std::make_pair(Address, Name)); + Symbols.push_back(std::make_pair(Address, *Name)); } } @@ -877,19 +925,17 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { // Print relocation for instruction. while (rel_cur != rel_end) { - bool hidden = false; - uint64_t addr; + bool hidden = getHidden(*rel_cur); + uint64_t addr = rel_cur->getOffset(); SmallString<16> name; SmallString<32> val; // If this relocation is hidden, skip it. - if (error(rel_cur->getHidden(hidden))) goto skip_print_rel; if (hidden) goto skip_print_rel; - if (error(rel_cur->getOffset(addr))) goto skip_print_rel; // Stop when rel_cur's address is past the current instruction. if (addr >= Index + Size) break; - if (error(rel_cur->getTypeName(name))) goto skip_print_rel; + rel_cur->getTypeName(name); if (error(getRelocationValueString(*rel_cur, val))) goto skip_print_rel; outs() << format(Fmt.data(), SectionAddr + addr) << name @@ -919,18 +965,13 @@ void llvm::PrintRelocations(const ObjectFile *Obj) { continue; outs() << "RELOCATION RECORDS FOR [" << secname << "]:\n"; for (const RelocationRef &Reloc : Section.relocations()) { - bool hidden; - uint64_t address; + bool hidden = getHidden(Reloc); + uint64_t address = Reloc.getOffset(); SmallString<32> relocname; SmallString<32> valuestr; - if (error(Reloc.getHidden(hidden))) - continue; if (hidden) continue; - if (error(Reloc.getTypeName(relocname))) - continue; - if (error(Reloc.getOffset(address))) - continue; + Reloc.getTypeName(relocname); if (error(getRelocationValueString(Reloc, valuestr))) continue; outs() << format(Fmt.data(), address) << " " << relocname << " " @@ -1073,21 +1114,21 @@ void llvm::PrintSymbolTable(const ObjectFile *o) { } for (const SymbolRef &Symbol : o->symbols()) { uint64_t Address; - SymbolRef::Type Type; + SymbolRef::Type Type = Symbol.getType(); uint32_t Flags = Symbol.getFlags(); section_iterator Section = o->section_end(); if (error(Symbol.getAddress(Address))) continue; - if (error(Symbol.getType(Type))) - continue; - uint64_t Size = Symbol.getSize(); if (error(Symbol.getSection(Section))) continue; StringRef Name; if (Type == SymbolRef::ST_Debug && Section != o->section_end()) { Section->getName(Name); - } else if (error(Symbol.getName(Name))) { - continue; + } else { + ErrorOr<StringRef> NameOrErr = Symbol.getName(); + if (error(NameOrErr.getError())) + continue; + Name = *NameOrErr; } bool Global = Flags & SymbolRef::SF_Global; @@ -1096,15 +1137,11 @@ void llvm::PrintSymbolTable(const ObjectFile *o) { bool Common = Flags & SymbolRef::SF_Common; bool Hidden = Flags & SymbolRef::SF_Hidden; - if (Common) { - uint32_t Alignment = Symbol.getAlignment(); - Address = Size; - Size = Alignment; - } - if (Address == UnknownAddressOrSize) + if (Common) + Address = Symbol.getCommonSize(); + + if (Address == UnknownAddress) Address = 0; - if (Size == UnknownAddressOrSize) - Size = 0; char GlobLoc = ' '; if (Type != SymbolRef::ST_Unknown) GlobLoc = Global ? 'g' : 'l'; @@ -1146,8 +1183,14 @@ void llvm::PrintSymbolTable(const ObjectFile *o) { SectionName = ""; outs() << SectionName; } - outs() << '\t' - << format("%08" PRIx64 " ", Size); + + outs() << '\t'; + if (Common || isa<ELFObjectFileBase>(o)) { + uint64_t Val = + Common ? Symbol.getAlignment() : ELFSymbolRef(Symbol).getSize(); + outs() << format("\t %08" PRIx64 " ", Val); + } + if (Hidden) { outs() << ".hidden "; } @@ -1226,6 +1269,49 @@ void llvm::printWeakBindTable(const ObjectFile *o) { } } +static void printFaultMaps(const ObjectFile *Obj) { + const char *FaultMapSectionName = nullptr; + + if (isa<ELFObjectFileBase>(Obj)) { + FaultMapSectionName = ".llvm_faultmaps"; + } else if (isa<MachOObjectFile>(Obj)) { + FaultMapSectionName = "__llvm_faultmaps"; + } else { + errs() << "This operation is only currently supported " + "for ELF and Mach-O executable files.\n"; + return; + } + + Optional<object::SectionRef> FaultMapSection; + + for (auto Sec : Obj->sections()) { + StringRef Name; + Sec.getName(Name); + if (Name == FaultMapSectionName) { + FaultMapSection = Sec; + break; + } + } + + outs() << "FaultMap table:\n"; + + if (!FaultMapSection.hasValue()) { + outs() << "<not found>\n"; + return; + } + + StringRef FaultMapContents; + if (error(FaultMapSection.getValue().getContents(FaultMapContents))) { + errs() << "Could not read the " << FaultMapContents << " section!\n"; + return; + } + + FaultMapParser FMP(FaultMapContents.bytes_begin(), + FaultMapContents.bytes_end()); + + outs() << FMP; +} + static void printPrivateFileHeader(const ObjectFile *o) { if (o->isELF()) { printELFFileHeader(o); @@ -1265,6 +1351,8 @@ static void DumpObject(const ObjectFile *o) { printLazyBindTable(o); if (WeakBind) printWeakBindTable(o); + if (PrintFaultMaps) + printFaultMaps(o); } /// @brief Dump each object file in \a a; @@ -1362,7 +1450,8 @@ int main(int argc, char **argv) { && !(DylibsUsed && MachOOpt) && !(DylibId && MachOOpt) && !(ObjcMetaData && MachOOpt) - && !(DumpSections.size() != 0 && MachOOpt)) { + && !(DumpSections.size() != 0 && MachOOpt) + && !PrintFaultMaps) { cl::PrintHelpMessage(); return 2; } diff --git a/tools/llvm-readobj/ARMEHABIPrinter.h b/tools/llvm-readobj/ARMEHABIPrinter.h index b15421d7571f..dd2490d503db 100644 --- a/tools/llvm-readobj/ARMEHABIPrinter.h +++ b/tools/llvm-readobj/ARMEHABIPrinter.h @@ -312,8 +312,6 @@ class PrinterContext { typedef typename object::ELFFile<ET>::Elf_Shdr Elf_Shdr; typedef typename object::ELFFile<ET>::Elf_Rel_Iter Elf_Rel_iterator; - typedef typename object::ELFFile<ET>::Elf_Sym_Iter Elf_Sym_iterator; - typedef typename object::ELFFile<ET>::Elf_Shdr_Iter Elf_Shdr_iterator; static const size_t IndexTableEntrySize; @@ -344,13 +342,13 @@ template <typename ET> const size_t PrinterContext<ET>::IndexTableEntrySize = 8; template <typename ET> -ErrorOr<StringRef> PrinterContext<ET>::FunctionAtAddress(unsigned Section, - uint64_t Address) const { - for (Elf_Sym_iterator SI = ELF->begin_symbols(), SE = ELF->end_symbols(); - SI != SE; ++SI) - if (SI->st_shndx == Section && SI->st_value == Address && - SI->getType() == ELF::STT_FUNC) - return ELF->getSymbolName(SI); +ErrorOr<StringRef> +PrinterContext<ET>::FunctionAtAddress(unsigned Section, + uint64_t Address) const { + for (const Elf_Sym &Sym : ELF->symbols()) + if (Sym.st_shndx == Section && Sym.st_value == Address && + Sym.getType() == ELF::STT_FUNC) + return ELF->getSymbolName(&Sym, false); return readobj_error::unknown_symbol; } @@ -366,10 +364,9 @@ PrinterContext<ET>::FindExceptionTable(unsigned IndexSectionIndex, /// handling table. Use this symbol to recover the actual exception handling /// table. - for (Elf_Shdr_iterator SI = ELF->begin_sections(), SE = ELF->end_sections(); - SI != SE; ++SI) { - if (SI->sh_type == ELF::SHT_REL && SI->sh_info == IndexSectionIndex) { - for (Elf_Rel_iterator RI = ELF->begin_rel(&*SI), RE = ELF->end_rel(&*SI); + for (const Elf_Shdr &Sec : ELF->sections()) { + if (Sec.sh_type == ELF::SHT_REL && Sec.sh_info == IndexSectionIndex) { + for (Elf_Rel_iterator RI = ELF->rel_begin(&Sec), RE = ELF->rel_end(&Sec); RI != RE; ++RI) { if (RI->r_offset == static_cast<unsigned>(IndexTableOffset)) { typename object::ELFFile<ET>::Elf_Rela RelA; @@ -378,9 +375,12 @@ PrinterContext<ET>::FindExceptionTable(unsigned IndexSectionIndex, RelA.r_addend = 0; std::pair<const Elf_Shdr *, const Elf_Sym *> Symbol = - ELF->getRelocationSymbol(&(*SI), &RelA); + ELF->getRelocationSymbol(&Sec, &RelA); - return ELF->getSection(Symbol.second); + ErrorOr<const Elf_Shdr *> Ret = ELF->getSection(Symbol.second); + if (std::error_code EC = Ret.getError()) + report_fatal_error(EC.message()); + return *Ret; } } } @@ -528,20 +528,18 @@ void PrinterContext<ET>::PrintUnwindInformation() const { DictScope UI(SW, "UnwindInformation"); int SectionIndex = 0; - for (Elf_Shdr_iterator SI = ELF->begin_sections(), SE = ELF->end_sections(); - SI != SE; ++SI, ++SectionIndex) { - if (SI->sh_type == ELF::SHT_ARM_EXIDX) { - const Elf_Shdr *IT = &(*SI); - + for (const Elf_Shdr &Sec : ELF->sections()) { + if (Sec.sh_type == ELF::SHT_ARM_EXIDX) { DictScope UIT(SW, "UnwindIndexTable"); SW.printNumber("SectionIndex", SectionIndex); - if (ErrorOr<StringRef> SectionName = ELF->getSectionName(IT)) + if (ErrorOr<StringRef> SectionName = ELF->getSectionName(&Sec)) SW.printString("SectionName", *SectionName); - SW.printHex("SectionOffset", IT->sh_offset); + SW.printHex("SectionOffset", Sec.sh_offset); - PrintIndexTable(SectionIndex, IT); + PrintIndexTable(SectionIndex, &Sec); } + ++SectionIndex; } } } diff --git a/tools/llvm-readobj/ARMWinEHPrinter.cpp b/tools/llvm-readobj/ARMWinEHPrinter.cpp index 62252fcda5f9..a1ea79f3688e 100644 --- a/tools/llvm-readobj/ARMWinEHPrinter.cpp +++ b/tools/llvm-readobj/ARMWinEHPrinter.cpp @@ -198,13 +198,8 @@ Decoder::getSectionContaining(const COFFObjectFile &COFF, uint64_t VA) { ErrorOr<object::SymbolRef> Decoder::getSymbol(const COFFObjectFile &COFF, uint64_t VA, bool FunctionOnly) { for (const auto &Symbol : COFF.symbols()) { - if (FunctionOnly) { - SymbolRef::Type Type; - if (std::error_code EC = Symbol.getType(Type)) - return EC; - if (Type != SymbolRef::ST_Function) - continue; - } + if (FunctionOnly && Symbol.getType() != SymbolRef::ST_Function) + continue; uint64_t Address; if (std::error_code EC = Symbol.getAddress(Address)) @@ -219,9 +214,7 @@ ErrorOr<SymbolRef> Decoder::getRelocatedSymbol(const COFFObjectFile &, const SectionRef &Section, uint64_t Offset) { for (const auto &Relocation : Section.relocations()) { - uint64_t RelocationOffset; - if (auto Error = Relocation.getOffset(RelocationOffset)) - return Error; + uint64_t RelocationOffset = Relocation.getOffset(); if (RelocationOffset == Offset) return *Relocation.getSymbol(); } @@ -574,12 +567,12 @@ bool Decoder::dumpXDataRecord(const COFFObjectFile &COFF, if (!Symbol) Symbol = getSymbol(COFF, Address, /*FunctionOnly=*/true); - StringRef Name; - if (Symbol) - Symbol->getName(Name); + ErrorOr<StringRef> Name = Symbol->getName(); + if (std::error_code EC = Name.getError()) + report_fatal_error(EC.message()); ListScope EHS(SW, "ExceptionHandler"); - SW.printString("Routine", formatSymbol(Name, Address)); + SW.printString("Routine", formatSymbol(*Name, Address)); SW.printHex("Parameter", Parameter); } @@ -608,7 +601,10 @@ bool Decoder::dumpUnpackedEntry(const COFFObjectFile &COFF, StringRef FunctionName; uint64_t FunctionAddress; if (Function) { - Function->getName(FunctionName); + ErrorOr<StringRef> FunctionNameOrErr = Function->getName(); + if (std::error_code EC = FunctionNameOrErr.getError()) + report_fatal_error(EC.message()); + FunctionName = *FunctionNameOrErr; Function->getAddress(FunctionAddress); } else { const pe32_header *PEHeader; @@ -620,13 +616,14 @@ bool Decoder::dumpUnpackedEntry(const COFFObjectFile &COFF, SW.printString("Function", formatSymbol(FunctionName, FunctionAddress)); if (XDataRecord) { - StringRef Name; - uint64_t Address; + ErrorOr<StringRef> Name = XDataRecord->getName(); + if (std::error_code EC = Name.getError()) + report_fatal_error(EC.message()); - XDataRecord->getName(Name); + uint64_t Address; XDataRecord->getAddress(Address); - SW.printString("ExceptionRecord", formatSymbol(Name, Address)); + SW.printString("ExceptionRecord", formatSymbol(*Name, Address)); section_iterator SI = COFF.section_end(); if (XDataRecord->getSection(SI)) @@ -665,7 +662,10 @@ bool Decoder::dumpPackedEntry(const object::COFFObjectFile &COFF, StringRef FunctionName; uint64_t FunctionAddress; if (Function) { - Function->getName(FunctionName); + ErrorOr<StringRef> FunctionNameOrErr = Function->getName(); + if (std::error_code EC = FunctionNameOrErr.getError()) + report_fatal_error(EC.message()); + FunctionName = *FunctionNameOrErr; Function->getAddress(FunctionAddress); } else { const pe32_header *PEHeader; diff --git a/tools/llvm-readobj/CMakeLists.txt b/tools/llvm-readobj/CMakeLists.txt index 30f336f76ca8..87407a258021 100644 --- a/tools/llvm-readobj/CMakeLists.txt +++ b/tools/llvm-readobj/CMakeLists.txt @@ -1,5 +1,4 @@ set(LLVM_LINK_COMPONENTS - ${LLVM_TARGETS_TO_BUILD} Object Support ) diff --git a/tools/llvm-readobj/COFFDumper.cpp b/tools/llvm-readobj/COFFDumper.cpp index 4a1d5da30e65..f5effe292441 100644 --- a/tools/llvm-readobj/COFFDumper.cpp +++ b/tools/llvm-readobj/COFFDumper.cpp @@ -16,6 +16,7 @@ #include "ARMWinEHPrinter.h" #include "Error.h" #include "ObjDumper.h" +#include "StackMapPrinter.h" #include "StreamWriter.h" #include "Win64EHDumper.h" #include "llvm/ADT/DenseMap.h" @@ -60,7 +61,7 @@ public: void printCOFFExports() override; void printCOFFDirectives() override; void printCOFFBaseReloc() override; - + void printStackMap() const override; private: void printSymbol(const SymbolRef &Sym); void printRelocation(const SectionRef &Section, const RelocationRef &Reloc); @@ -120,9 +121,7 @@ std::error_code COFFDumper::resolveSymbol(const coff_section *Section, uint64_t Offset, SymbolRef &Sym) { const auto &Relocations = RelocMap[Section]; for (const auto &Relocation : Relocations) { - uint64_t RelocationOffset; - if (std::error_code EC = Relocation.getOffset(RelocationOffset)) - return EC; + uint64_t RelocationOffset = Relocation.getOffset(); if (RelocationOffset == Offset) { Sym = *Relocation.getSymbol(); @@ -140,8 +139,10 @@ std::error_code COFFDumper::resolveSymbolName(const coff_section *Section, SymbolRef Symbol; if (std::error_code EC = resolveSymbol(Section, Offset, Symbol)) return EC; - if (std::error_code EC = Symbol.getName(Name)) + ErrorOr<StringRef> NameOrErr = Symbol.getName(); + if (std::error_code EC = NameOrErr.getError()) return EC; + Name = *NameOrErr; return std::error_code(); } @@ -804,19 +805,18 @@ void COFFDumper::printRelocations() { void COFFDumper::printRelocation(const SectionRef &Section, const RelocationRef &Reloc) { - uint64_t Offset; - uint64_t RelocType; + uint64_t Offset = Reloc.getOffset(); + uint64_t RelocType = Reloc.getType(); SmallString<32> RelocName; StringRef SymbolName; - if (error(Reloc.getOffset(Offset))) - return; - if (error(Reloc.getType(RelocType))) - return; - if (error(Reloc.getTypeName(RelocName))) - return; + Reloc.getTypeName(RelocName); symbol_iterator Symbol = Reloc.getSymbol(); - if (Symbol != Obj->symbol_end() && error(Symbol->getName(SymbolName))) - return; + if (Symbol != Obj->symbol_end()) { + ErrorOr<StringRef> SymbolNameOrErr = Symbol->getName(); + if (error(SymbolNameOrErr.getError())) + return; + SymbolName = *SymbolNameOrErr; + } if (opts::ExpandRelocs) { DictScope Group(W, "Relocation"); @@ -1140,3 +1140,32 @@ void COFFDumper::printCOFFBaseReloc() { W.printHex("Address", RVA); } } + +void COFFDumper::printStackMap() const { + object::SectionRef StackMapSection; + for (auto Sec : Obj->sections()) { + StringRef Name; + Sec.getName(Name); + if (Name == ".llvm_stackmaps") { + StackMapSection = Sec; + break; + } + } + + if (StackMapSection == object::SectionRef()) + return; + + StringRef StackMapContents; + StackMapSection.getContents(StackMapContents); + ArrayRef<uint8_t> StackMapContentsArray( + reinterpret_cast<const uint8_t*>(StackMapContents.data()), + StackMapContents.size()); + + if (Obj->isLittleEndian()) + prettyPrintStackMap( + llvm::outs(), + StackMapV1Parser<support::little>(StackMapContentsArray)); + else + prettyPrintStackMap(llvm::outs(), + StackMapV1Parser<support::big>(StackMapContentsArray)); +} diff --git a/tools/llvm-readobj/ELFDumper.cpp b/tools/llvm-readobj/ELFDumper.cpp index 99969fd469f9..a4b25efeb9ba 100644 --- a/tools/llvm-readobj/ELFDumper.cpp +++ b/tools/llvm-readobj/ELFDumper.cpp @@ -17,6 +17,7 @@ #include "ARMEHABIPrinter.h" #include "Error.h" #include "ObjDumper.h" +#include "StackMapPrinter.h" #include "StreamWriter.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallString.h" @@ -47,6 +48,7 @@ public: void printFileHeaders() override; void printSections() override; void printRelocations() override; + void printDynamicRelocations() override; void printSymbols() override; void printDynamicSymbols() override; void printUnwindInfo() override; @@ -60,12 +62,14 @@ public: void printMipsABIFlags() override; void printMipsReginfo() override; + void printStackMap() const override; + private: typedef ELFFile<ELFT> ELFO; typedef typename ELFO::Elf_Shdr Elf_Shdr; typedef typename ELFO::Elf_Sym Elf_Sym; - void printSymbol(typename ELFO::Elf_Sym_Iter Symbol); + void printSymbol(const Elf_Sym *Symbol, bool IsDynamic); void printRelocations(const Elf_Shdr *Sec); void printRelocation(const Elf_Shdr *Sec, typename ELFO::Elf_Rela Rel); @@ -119,9 +123,10 @@ std::error_code createELFDumper(const object::ObjectFile *Obj, template <typename ELFO> static std::string getFullSymbolName(const ELFO &Obj, - typename ELFO::Elf_Sym_Iter Symbol) { - StringRef SymbolName = errorOrDefault(Obj.getSymbolName(Symbol)); - if (!Symbol.isDynamic()) + const typename ELFO::Elf_Sym *Symbol, + bool IsDynamic) { + StringRef SymbolName = errorOrDefault(Obj.getSymbolName(Symbol, IsDynamic)); + if (!IsDynamic) return SymbolName; std::string FullSymbolName(SymbolName); @@ -139,7 +144,7 @@ static std::string getFullSymbolName(const ELFO &Obj, template <typename ELFO> static void -getSectionNameIndex(const ELFO &Obj, typename ELFO::Elf_Sym_Iter Symbol, +getSectionNameIndex(const ELFO &Obj, const typename ELFO::Elf_Sym *Symbol, StringRef &SectionName, unsigned &SectionIndex) { SectionIndex = Symbol->st_shndx; if (Symbol->isUndefined()) @@ -156,11 +161,10 @@ getSectionNameIndex(const ELFO &Obj, typename ELFO::Elf_Sym_Iter Symbol, SectionName = "Reserved"; else { if (SectionIndex == SHN_XINDEX) - SectionIndex = Obj.getSymbolTableIndex(&*Symbol); - assert(SectionIndex != SHN_XINDEX && - "getSymbolTableIndex should handle this"); - const typename ELFO::Elf_Shdr *Sec = Obj.getSection(SectionIndex); - SectionName = errorOrDefault(Obj.getSectionName(Sec)); + SectionIndex = Obj.getExtendedSymbolTableIndex(&*Symbol); + ErrorOr<const typename ELFO::Elf_Shdr *> Sec = Obj.getSection(SectionIndex); + if (!error(Sec.getError())) + SectionName = errorOrDefault(Obj.getSectionName(*Sec)); } } @@ -382,7 +386,8 @@ static const EnumEntry<unsigned> ElfMachineType[] = { LLVM_READOBJ_ENUM_ENT(ELF, EM_RL78 ), LLVM_READOBJ_ENUM_ENT(ELF, EM_VIDEOCORE5 ), LLVM_READOBJ_ENUM_ENT(ELF, EM_78KOR ), - LLVM_READOBJ_ENUM_ENT(ELF, EM_56800EX ) + LLVM_READOBJ_ENUM_ENT(ELF, EM_56800EX ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_AMDGPU ) }; static const EnumEntry<unsigned> ElfSymbolBindings[] = { @@ -574,7 +579,13 @@ void ELFDumper<ELFT>::printFileHeaders() { W.printEnum ("DataEncoding", Header->e_ident[ELF::EI_DATA], makeArrayRef(ElfDataEncoding)); W.printNumber("FileVersion", Header->e_ident[ELF::EI_VERSION]); - W.printEnum ("OS/ABI", Header->e_ident[ELF::EI_OSABI], + + // Handle architecture specific OS/ABI values. + if (Header->e_machine == ELF::EM_AMDGPU && + Header->e_ident[ELF::EI_OSABI] == ELF::ELFOSABI_AMDGPU_HSA) + W.printHex("OS/ABI", "AMDGPU_HSA", ELF::ELFOSABI_AMDGPU_HSA); + else + W.printEnum ("OS/ABI", Header->e_ident[ELF::EI_OSABI], makeArrayRef(ElfOSABI)); W.printNumber("ABIVersion", Header->e_ident[ELF::EI_ABIVERSION]); W.printBinary("Unused", makeArrayRef(Header->e_ident).slice(ELF::EI_PAD)); @@ -606,46 +617,44 @@ void ELFDumper<ELFT>::printSections() { ListScope SectionsD(W, "Sections"); int SectionIndex = -1; - for (typename ELFO::Elf_Shdr_Iter SecI = Obj->begin_sections(), - SecE = Obj->end_sections(); - SecI != SecE; ++SecI) { + for (const typename ELFO::Elf_Shdr &Sec : Obj->sections()) { ++SectionIndex; - const Elf_Shdr *Section = &*SecI; - StringRef Name = errorOrDefault(Obj->getSectionName(Section)); + StringRef Name = errorOrDefault(Obj->getSectionName(&Sec)); DictScope SectionD(W, "Section"); W.printNumber("Index", SectionIndex); - W.printNumber("Name", Name, Section->sh_name); + W.printNumber("Name", Name, Sec.sh_name); W.printHex("Type", - getElfSectionType(Obj->getHeader()->e_machine, Section->sh_type), - Section->sh_type); - W.printFlags ("Flags", Section->sh_flags, makeArrayRef(ElfSectionFlags)); - W.printHex ("Address", Section->sh_addr); - W.printHex ("Offset", Section->sh_offset); - W.printNumber("Size", Section->sh_size); - W.printNumber("Link", Section->sh_link); - W.printNumber("Info", Section->sh_info); - W.printNumber("AddressAlignment", Section->sh_addralign); - W.printNumber("EntrySize", Section->sh_entsize); + getElfSectionType(Obj->getHeader()->e_machine, Sec.sh_type), + Sec.sh_type); + W.printFlags("Flags", Sec.sh_flags, makeArrayRef(ElfSectionFlags)); + W.printHex("Address", Sec.sh_addr); + W.printHex("Offset", Sec.sh_offset); + W.printNumber("Size", Sec.sh_size); + W.printNumber("Link", Sec.sh_link); + W.printNumber("Info", Sec.sh_info); + W.printNumber("AddressAlignment", Sec.sh_addralign); + W.printNumber("EntrySize", Sec.sh_entsize); if (opts::SectionRelocations) { ListScope D(W, "Relocations"); - printRelocations(Section); + printRelocations(&Sec); } if (opts::SectionSymbols) { ListScope D(W, "Symbols"); - for (typename ELFO::Elf_Sym_Iter SymI = Obj->begin_symbols(), - SymE = Obj->end_symbols(); - SymI != SymE; ++SymI) { - if (Obj->getSection(&*SymI) == Section) - printSymbol(SymI); + for (const typename ELFO::Elf_Sym &Sym : Obj->symbols()) { + ErrorOr<const Elf_Shdr *> SymSec = Obj->getSection(&Sym); + if (!SymSec) + continue; + if (*SymSec == &Sec) + printSymbol(&Sym, false); } } - if (opts::SectionData && Section->sh_type != ELF::SHT_NOBITS) { - ArrayRef<uint8_t> Data = errorOrDefault(Obj->getSectionContents(Section)); + if (opts::SectionData && Sec.sh_type != ELF::SHT_NOBITS) { + ArrayRef<uint8_t> Data = errorOrDefault(Obj->getSectionContents(&Sec)); W.printBinaryBlock("SectionData", StringRef((const char *)Data.data(), Data.size())); } @@ -657,32 +666,63 @@ void ELFDumper<ELFT>::printRelocations() { ListScope D(W, "Relocations"); int SectionNumber = -1; - for (typename ELFO::Elf_Shdr_Iter SecI = Obj->begin_sections(), - SecE = Obj->end_sections(); - SecI != SecE; ++SecI) { + for (const typename ELFO::Elf_Shdr &Sec : Obj->sections()) { ++SectionNumber; - if (SecI->sh_type != ELF::SHT_REL && SecI->sh_type != ELF::SHT_RELA) + if (Sec.sh_type != ELF::SHT_REL && Sec.sh_type != ELF::SHT_RELA) continue; - StringRef Name = errorOrDefault(Obj->getSectionName(&*SecI)); + StringRef Name = errorOrDefault(Obj->getSectionName(&Sec)); W.startLine() << "Section (" << SectionNumber << ") " << Name << " {\n"; W.indent(); - printRelocations(&*SecI); + printRelocations(&Sec); W.unindent(); W.startLine() << "}\n"; } } +template<class ELFT> +void ELFDumper<ELFT>::printDynamicRelocations() { + W.startLine() << "Dynamic Relocations {\n"; + W.indent(); + for (typename ELFO::Elf_Rela_Iter RelI = Obj->dyn_rela_begin(), + RelE = Obj->dyn_rela_end(); + RelI != RelE; ++RelI) { + SmallString<32> RelocName; + Obj->getRelocationTypeName(RelI->getType(Obj->isMips64EL()), RelocName); + StringRef SymbolName; + uint32_t SymIndex = RelI->getSymbol(Obj->isMips64EL()); + const typename ELFO::Elf_Sym *Sym = Obj->dynamic_symbol_begin() + SymIndex; + SymbolName = errorOrDefault(Obj->getSymbolName(Sym, true)); + if (opts::ExpandRelocs) { + DictScope Group(W, "Relocation"); + W.printHex("Offset", RelI->r_offset); + W.printNumber("Type", RelocName, (int)RelI->getType(Obj->isMips64EL())); + W.printString("Symbol", SymbolName.size() > 0 ? SymbolName : "-"); + W.printHex("Addend", RelI->r_addend); + } + else { + raw_ostream& OS = W.startLine(); + OS << W.hex(RelI->r_offset) + << " " << RelocName + << " " << (SymbolName.size() > 0 ? SymbolName : "-") + << " " << W.hex(RelI->r_addend) + << "\n"; + } + } + W.unindent(); + W.startLine() << "}\n"; +} + template <class ELFT> void ELFDumper<ELFT>::printRelocations(const Elf_Shdr *Sec) { switch (Sec->sh_type) { case ELF::SHT_REL: - for (typename ELFO::Elf_Rel_Iter RI = Obj->begin_rel(Sec), - RE = Obj->end_rel(Sec); + for (typename ELFO::Elf_Rel_Iter RI = Obj->rel_begin(Sec), + RE = Obj->rel_end(Sec); RI != RE; ++RI) { typename ELFO::Elf_Rela Rela; Rela.r_offset = RI->r_offset; @@ -692,8 +732,8 @@ void ELFDumper<ELFT>::printRelocations(const Elf_Shdr *Sec) { } break; case ELF::SHT_RELA: - for (typename ELFO::Elf_Rela_Iter RI = Obj->begin_rela(Sec), - RE = Obj->end_rela(Sec); + for (typename ELFO::Elf_Rela_Iter RI = Obj->rela_begin(Sec), + RE = Obj->rela_end(Sec); RI != RE; ++RI) { printRelocation(Sec, *RI); } @@ -710,12 +750,20 @@ void ELFDumper<ELFT>::printRelocation(const Elf_Shdr *Sec, std::pair<const Elf_Shdr *, const Elf_Sym *> Sym = Obj->getRelocationSymbol(Sec, &Rel); if (Sym.second && Sym.second->getType() == ELF::STT_SECTION) { - const Elf_Shdr *Sec = Obj->getSection(Sym.second); - ErrorOr<StringRef> SecName = Obj->getSectionName(Sec); - if (SecName) - TargetName = SecName.get(); + ErrorOr<const Elf_Shdr *> Sec = Obj->getSection(Sym.second); + if (!error(Sec.getError())) { + ErrorOr<StringRef> SecName = Obj->getSectionName(*Sec); + if (SecName) + TargetName = SecName.get(); + } } else if (Sym.first) { - TargetName = errorOrDefault(Obj->getSymbolName(Sym.first, Sym.second)); + const Elf_Shdr *SymTable = Sym.first; + ErrorOr<const Elf_Shdr *> StrTableSec = Obj->getSection(SymTable->sh_link); + if (!error(StrTableSec.getError())) { + ErrorOr<StringRef> StrTableOrErr = Obj->getStringTable(*StrTableSec); + if (!error(StrTableOrErr.getError())) + TargetName = errorOrDefault(Sym.second->getName(*StrTableOrErr)); + } } if (opts::ExpandRelocs) { @@ -736,30 +784,25 @@ void ELFDumper<ELFT>::printRelocation(const Elf_Shdr *Sec, template<class ELFT> void ELFDumper<ELFT>::printSymbols() { ListScope Group(W, "Symbols"); - for (typename ELFO::Elf_Sym_Iter SymI = Obj->begin_symbols(), - SymE = Obj->end_symbols(); - SymI != SymE; ++SymI) { - printSymbol(SymI); - } + for (const typename ELFO::Elf_Sym &Sym : Obj->symbols()) + printSymbol(&Sym, false); } template<class ELFT> void ELFDumper<ELFT>::printDynamicSymbols() { ListScope Group(W, "DynamicSymbols"); - for (typename ELFO::Elf_Sym_Iter SymI = Obj->begin_dynamic_symbols(), - SymE = Obj->end_dynamic_symbols(); - SymI != SymE; ++SymI) { - printSymbol(SymI); - } + for (const typename ELFO::Elf_Sym &Sym : Obj->dynamic_symbols()) + printSymbol(&Sym, true); } template <class ELFT> -void ELFDumper<ELFT>::printSymbol(typename ELFO::Elf_Sym_Iter Symbol) { +void ELFDumper<ELFT>::printSymbol(const typename ELFO::Elf_Sym *Symbol, + bool IsDynamic) { unsigned SectionIndex = 0; StringRef SectionName; getSectionNameIndex(*Obj, Symbol, SectionName, SectionIndex); - std::string FullSymbolName = getFullSymbolName(*Obj, Symbol); + std::string FullSymbolName = getFullSymbolName(*Obj, Symbol, IsDynamic); DictScope D(W, "Symbol"); W.printNumber("Name", FullSymbolName, Symbol->st_name); @@ -987,6 +1030,9 @@ static void printValue(const ELFFile<ELFT> *O, uint64_t Type, uint64_t Value, case DT_FLAGS_1: printFlags(Value, makeArrayRef(ElfDynamicDTFlags1), OS); break; + default: + OS << format("0x%" PRIX64, Value); + break; } } @@ -1056,9 +1102,9 @@ template<class ELFT> void ELFDumper<ELFT>::printProgramHeaders() { ListScope L(W, "ProgramHeaders"); - for (typename ELFO::Elf_Phdr_Iter PI = Obj->begin_program_headers(), - PE = Obj->end_program_headers(); - PI != PE; ++PI) { + for (typename ELFO::Elf_Phdr_Iter PI = Obj->program_header_begin(), + PE = Obj->program_header_end(); + PI != PE; ++PI) { DictScope P(W, "ProgramHeader"); W.printHex ("Type", getElfSegmentType(Obj->getHeader()->e_machine, PI->p_type), @@ -1086,12 +1132,11 @@ template <> void ELFDumper<ELFType<support::little, false>>::printAttributes() { } DictScope BA(W, "BuildAttributes"); - for (ELFO::Elf_Shdr_Iter SI = Obj->begin_sections(), SE = Obj->end_sections(); - SI != SE; ++SI) { - if (SI->sh_type != ELF::SHT_ARM_ATTRIBUTES) + for (const ELFO::Elf_Shdr &Sec : Obj->sections()) { + if (Sec.sh_type != ELF::SHT_ARM_ATTRIBUTES) continue; - ErrorOr<ArrayRef<uint8_t> > Contents = Obj->getSectionContents(&(*SI)); + ErrorOr<ArrayRef<uint8_t>> Contents = Obj->getSectionContents(&Sec); if (!Contents) continue; @@ -1115,13 +1160,13 @@ template <class ELFT> class MipsGOTParser { public: typedef object::ELFFile<ELFT> ObjectFile; typedef typename ObjectFile::Elf_Shdr Elf_Shdr; + typedef typename ObjectFile::Elf_Sym Elf_Sym; MipsGOTParser(const ObjectFile *Obj, StreamWriter &W) : Obj(Obj), W(W) {} void parseGOT(const Elf_Shdr &GOTShdr); private: - typedef typename ObjectFile::Elf_Sym_Iter Elf_Sym_Iter; typedef typename ObjectFile::Elf_Addr GOTEntry; typedef typename ObjectFile::template ELFEntityIterator<const GOTEntry> GOTIter; @@ -1135,7 +1180,7 @@ private: bool getGOTTags(uint64_t &LocalGotNum, uint64_t &GotSym); void printGotEntry(uint64_t GotAddr, GOTIter BeginIt, GOTIter It); void printGlobalGotEntry(uint64_t GotAddr, GOTIter BeginIt, GOTIter It, - Elf_Sym_Iter Sym); + const Elf_Sym *Sym, bool IsDynamic); }; } @@ -1161,8 +1206,8 @@ void MipsGOTParser<ELFT>::parseGOT(const Elf_Shdr &GOTShdr) { return; } - Elf_Sym_Iter DynSymBegin = Obj->begin_dynamic_symbols(); - Elf_Sym_Iter DynSymEnd = Obj->end_dynamic_symbols(); + const Elf_Sym *DynSymBegin = Obj->dynamic_symbol_begin(); + const Elf_Sym *DynSymEnd = Obj->dynamic_symbol_end(); std::size_t DynSymTotal = std::size_t(std::distance(DynSymBegin, DynSymEnd)); if (DtGotSym > DynSymTotal) { @@ -1210,10 +1255,10 @@ void MipsGOTParser<ELFT>::parseGOT(const Elf_Shdr &GOTShdr) { ListScope GS(W, "Global entries"); GOTIter GotGlobalEnd = makeGOTIter(*GOT, DtLocalGotNum + GlobalGotNum); - Elf_Sym_Iter GotDynSym = DynSymBegin + DtGotSym; + const Elf_Sym *GotDynSym = DynSymBegin + DtGotSym; for (; It != GotGlobalEnd; ++It) { DictScope D(W, "Entry"); - printGlobalGotEntry(GOTShdr.sh_addr, GotBegin, It, GotDynSym++); + printGlobalGotEntry(GOTShdr.sh_addr, GotBegin, It, GotDynSym++, true); } } @@ -1274,7 +1319,8 @@ void MipsGOTParser<ELFT>::printGotEntry(uint64_t GotAddr, GOTIter BeginIt, template <class ELFT> void MipsGOTParser<ELFT>::printGlobalGotEntry(uint64_t GotAddr, GOTIter BeginIt, - GOTIter It, Elf_Sym_Iter Sym) { + GOTIter It, const Elf_Sym *Sym, + bool IsDynamic) { printGotEntry(GotAddr, BeginIt, It); W.printHex("Value", Sym->st_value); @@ -1285,7 +1331,7 @@ void MipsGOTParser<ELFT>::printGlobalGotEntry(uint64_t GotAddr, GOTIter BeginIt, getSectionNameIndex(*Obj, Sym, SectionName, SectionIndex); W.printHex("Section", SectionName, SectionIndex); - std::string FullSymbolName = getFullSymbolName(*Obj, Sym); + std::string FullSymbolName = getFullSymbolName(*Obj, Sym, IsDynamic); W.printNumber("Name", FullSymbolName, Sym->st_name); } @@ -1452,3 +1498,25 @@ template <class ELFT> void ELFDumper<ELFT>::printMipsReginfo() { W.printHex("Co-Proc Mask2", Reginfo->ri_cprmask[2]); W.printHex("Co-Proc Mask3", Reginfo->ri_cprmask[3]); } + +template <class ELFT> void ELFDumper<ELFT>::printStackMap() const { + const typename ELFFile<ELFT>::Elf_Shdr *StackMapSection = nullptr; + for (const auto &Sec : Obj->sections()) { + ErrorOr<StringRef> Name = Obj->getSectionName(&Sec); + if (*Name == ".llvm_stackmaps") { + StackMapSection = &Sec; + break; + } + } + + if (!StackMapSection) + return; + + StringRef StackMapContents; + ErrorOr<ArrayRef<uint8_t>> StackMapContentsArray = + Obj->getSectionContents(StackMapSection); + + prettyPrintStackMap( + llvm::outs(), + StackMapV1Parser<ELFT::TargetEndianness>(*StackMapContentsArray)); +} diff --git a/tools/llvm-readobj/MachODumper.cpp b/tools/llvm-readobj/MachODumper.cpp index aeb563a25ff3..adb99b0acd7f 100644 --- a/tools/llvm-readobj/MachODumper.cpp +++ b/tools/llvm-readobj/MachODumper.cpp @@ -14,6 +14,7 @@ #include "llvm-readobj.h" #include "Error.h" #include "ObjDumper.h" +#include "StackMapPrinter.h" #include "StreamWriter.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" @@ -37,6 +38,7 @@ public: void printSymbols() override; void printDynamicSymbols() override; void printUnwindInfo() override; + void printStackMap() const override; private: template<class MachHeader> @@ -459,12 +461,9 @@ void MachODumper::printRelocation(const RelocationRef &Reloc) { void MachODumper::printRelocation(const MachOObjectFile *Obj, const RelocationRef &Reloc) { - uint64_t Offset; + uint64_t Offset = Reloc.getOffset(); SmallString<32> RelocName; - if (error(Reloc.getOffset(Offset))) - return; - if (error(Reloc.getTypeName(RelocName))) - return; + Reloc.getTypeName(RelocName); DataRefImpl DR = Reloc.getRawDataRefImpl(); MachO::any_relocation_info RE = Obj->getRelocation(DR); @@ -475,8 +474,10 @@ void MachODumper::printRelocation(const MachOObjectFile *Obj, if (IsExtern) { symbol_iterator Symbol = Reloc.getSymbol(); if (Symbol != Obj->symbol_end()) { - if (error(Symbol->getName(TargetName))) + ErrorOr<StringRef> TargetNameOrErr = Symbol->getName(); + if (error(TargetNameOrErr.getError())) return; + TargetName = *TargetNameOrErr; } } else if (!IsScattered) { section_iterator SecI = Obj->getRelocationSection(DR); @@ -539,8 +540,8 @@ void MachODumper::printDynamicSymbols() { void MachODumper::printSymbol(const SymbolRef &Symbol) { StringRef SymbolName; - if (Symbol.getName(SymbolName)) - SymbolName = ""; + if (ErrorOr<StringRef> SymbolNameOrErr = Symbol.getName()) + SymbolName = *SymbolNameOrErr; MachOSymbol MOSymbol; getSymbol(Obj, Symbol.getRawDataRefImpl(), MOSymbol); @@ -573,3 +574,32 @@ void MachODumper::printSymbol(const SymbolRef &Symbol) { void MachODumper::printUnwindInfo() { W.startLine() << "UnwindInfo not implemented.\n"; } + +void MachODumper::printStackMap() const { + object::SectionRef StackMapSection; + for (auto Sec : Obj->sections()) { + StringRef Name; + Sec.getName(Name); + if (Name == "__llvm_stackmaps") { + StackMapSection = Sec; + break; + } + } + + if (StackMapSection == object::SectionRef()) + return; + + StringRef StackMapContents; + StackMapSection.getContents(StackMapContents); + ArrayRef<uint8_t> StackMapContentsArray( + reinterpret_cast<const uint8_t*>(StackMapContents.data()), + StackMapContents.size()); + + if (Obj->isLittleEndian()) + prettyPrintStackMap( + llvm::outs(), + StackMapV1Parser<support::little>(StackMapContentsArray)); + else + prettyPrintStackMap(llvm::outs(), + StackMapV1Parser<support::big>(StackMapContentsArray)); +} diff --git a/tools/llvm-readobj/ObjDumper.h b/tools/llvm-readobj/ObjDumper.h index 323f5e319cf3..27e15b256cc5 100644 --- a/tools/llvm-readobj/ObjDumper.h +++ b/tools/llvm-readobj/ObjDumper.h @@ -33,6 +33,7 @@ public: virtual void printUnwindInfo() = 0; // Only implemented for ELF at this time. + virtual void printDynamicRelocations() { } virtual void printDynamicTable() { } virtual void printNeededLibraries() { } virtual void printProgramHeaders() { } @@ -51,6 +52,8 @@ public: virtual void printCOFFDirectives() { } virtual void printCOFFBaseReloc() { } + virtual void printStackMap() const = 0; + protected: StreamWriter& W; }; diff --git a/tools/llvm-readobj/StackMapPrinter.h b/tools/llvm-readobj/StackMapPrinter.h new file mode 100644 index 000000000000..92645bcf9172 --- /dev/null +++ b/tools/llvm-readobj/StackMapPrinter.h @@ -0,0 +1,80 @@ +//===-------- StackMapPrinter.h - Pretty-print stackmaps --------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TOOLS_LLVM_READOBJ_STACKMAPPRINTER_H +#define LLVM_TOOLS_LLVM_READOBJ_STACKMAPPRINTER_H + +#include "llvm/Object/StackMapParser.h" + +namespace llvm { + +// Pretty print a stackmap to the given ostream. +template <typename OStreamT, typename StackMapParserT> +void prettyPrintStackMap(OStreamT &OS, const StackMapParserT &SMP) { + + OS << "LLVM StackMap Version: " << SMP.getVersion() + << "\nNum Functions: " << SMP.getNumFunctions(); + + // Functions: + for (const auto &F : SMP.functions()) + OS << "\n Function address: " << F.getFunctionAddress() + << ", stack size: " << F.getStackSize(); + + // Constants: + OS << "\nNum Constants: " << SMP.getNumConstants(); + unsigned ConstantIndex = 0; + for (const auto &C : SMP.constants()) + OS << "\n #" << ++ConstantIndex << ": " << C.getValue(); + + // Records: + OS << "\nNum Records: " << SMP.getNumRecords(); + for (const auto &R : SMP.records()) { + OS << "\n Record ID: " << R.getID() + << ", instruction offset: " << R.getInstructionOffset() + << "\n " << R.getNumLocations() << " locations:"; + + unsigned LocationIndex = 0; + for (const auto &Loc : R.locations()) { + OS << "\n #" << ++LocationIndex << ": "; + switch (Loc.getKind()) { + case StackMapParserT::LocationKind::Register: + OS << "Register R#" << Loc.getDwarfRegNum(); + break; + case StackMapParserT::LocationKind::Direct: + OS << "Direct R#" << Loc.getDwarfRegNum() << " + " + << Loc.getOffset(); + break; + case StackMapParserT::LocationKind::Indirect: + OS << "Indirect [R#" << Loc.getDwarfRegNum() << " + " + << Loc.getOffset() << "]"; + break; + case StackMapParserT::LocationKind::Constant: + OS << "Constant " << Loc.getSmallConstant(); + break; + case StackMapParserT::LocationKind::ConstantIndex: + OS << "ConstantIndex #" << Loc.getConstantIndex() << " (" + << SMP.getConstant(Loc.getConstantIndex()).getValue() << ")"; + break; + } + } + + OS << "\n " << R.getNumLiveOuts() << " live-outs: [ "; + for (const auto &LO : R.liveouts()) + OS << "R#" << LO.getDwarfRegNum() << " (" + << LO.getSizeInBytes() << "-bytes) "; + OS << "]\n"; + } + + OS << "\n"; + +} + +} + +#endif diff --git a/tools/llvm-readobj/Win64EHDumper.cpp b/tools/llvm-readobj/Win64EHDumper.cpp index b148c5d2abda..5a8af4135bd7 100644 --- a/tools/llvm-readobj/Win64EHDumper.cpp +++ b/tools/llvm-readobj/Win64EHDumper.cpp @@ -118,19 +118,19 @@ static std::string formatSymbol(const Dumper::Context &Ctx, std::string Buffer; raw_string_ostream OS(Buffer); - StringRef Name; SymbolRef Symbol; - if (Ctx.ResolveSymbol(Section, Offset, Symbol, Ctx.UserData) || - Symbol.getName(Name)) { - OS << format(" (0x%" PRIX64 ")", Offset); - return OS.str(); + if (!Ctx.ResolveSymbol(Section, Offset, Symbol, Ctx.UserData)) { + if (ErrorOr<StringRef> Name = Symbol.getName()) { + OS << *Name; + if (Displacement > 0) + OS << format(" +0x%X (0x%" PRIX64 ")", Displacement, Offset); + else + OS << format(" (0x%" PRIX64 ")", Offset); + return OS.str(); + } } - OS << Name; - if (Displacement > 0) - OS << format(" +0x%X (0x%" PRIX64 ")", Displacement, Offset); - else - OS << format(" (0x%" PRIX64 ")", Offset); + OS << format(" (0x%" PRIX64 ")", Offset); return OS.str(); } diff --git a/tools/llvm-readobj/llvm-readobj.cpp b/tools/llvm-readobj/llvm-readobj.cpp index f960796a4cb9..c5bccf979609 100644 --- a/tools/llvm-readobj/llvm-readobj.cpp +++ b/tools/llvm-readobj/llvm-readobj.cpp @@ -40,7 +40,6 @@ #include <string> #include <system_error> - using namespace llvm; using namespace llvm::object; @@ -91,6 +90,10 @@ namespace opts { cl::desc("Alias for --relocations"), cl::aliasopt(Relocations)); + // -dyn-relocations + cl::opt<bool> DynRelocs("dyn-relocations", + cl::desc("Display the dynamic relocation entries in the file")); + // -symbols, -t cl::opt<bool> Symbols("symbols", cl::desc("Display the symbol table")); @@ -173,6 +176,12 @@ namespace opts { cl::opt<bool> COFFBaseRelocs("coff-basereloc", cl::desc("Display the PE/COFF .reloc section")); + + // -stackmap + cl::opt<bool> + PrintStackMap("stackmap", + cl::desc("Display contents of stackmap section")); + } // namespace opts static int ReturnValue = EXIT_SUCCESS; @@ -190,9 +199,8 @@ bool error(std::error_code EC) { } bool relocAddressLess(RelocationRef a, RelocationRef b) { - uint64_t a_addr, b_addr; - if (error(a.getOffset(a_addr))) exit(ReturnValue); - if (error(b.getOffset(b_addr))) exit(ReturnValue); + uint64_t a_addr = a.getOffset(); + uint64_t b_addr = b.getOffset(); return a_addr < b_addr; } @@ -280,6 +288,8 @@ static void dumpObject(const ObjectFile *Obj) { Dumper->printSections(); if (opts::Relocations) Dumper->printRelocations(); + if (opts::DynRelocs) + Dumper->printDynamicRelocations(); if (opts::Symbols) Dumper->printSymbols(); if (opts::DynamicSymbols) @@ -311,8 +321,10 @@ static void dumpObject(const ObjectFile *Obj) { Dumper->printCOFFDirectives(); if (opts::COFFBaseRelocs) Dumper->printCOFFBaseReloc(); -} + if (opts::PrintStackMap) + Dumper->printStackMap(); +} /// @brief Dumps each object file in \a Arc; static void dumpArchive(const Archive *Arc) { @@ -374,15 +386,11 @@ static void dumpInput(StringRef File) { reportError(File, readobj_error::unrecognized_file_format); } - int main(int argc, const char *argv[]) { sys::PrintStackTraceOnErrorSignal(); PrettyStackTraceProgram X(argc, argv); llvm_shutdown_obj Y; - // Initialize targets. - llvm::InitializeAllTargetInfos(); - // Register the target printer for --version. cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion); diff --git a/tools/llvm-rtdyld/llvm-rtdyld.cpp b/tools/llvm-rtdyld/llvm-rtdyld.cpp index f857b2ef9735..98c6f5c4399c 100644 --- a/tools/llvm-rtdyld/llvm-rtdyld.cpp +++ b/tools/llvm-rtdyld/llvm-rtdyld.cpp @@ -25,6 +25,7 @@ #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/Object/MachO.h" +#include "llvm/Object/SymbolSize.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/ManagedStatic.h" @@ -81,6 +82,12 @@ Dylibs("dylib", static cl::opt<std::string> TripleName("triple", cl::desc("Target triple for disassembler")); +static cl::opt<std::string> +MCPU("mcpu", + cl::desc("Target a specific cpu type (-mcpu=help for details)"), + cl::value_desc("cpu-name"), + cl::init("")); + static cl::list<std::string> CheckFiles("check", cl::desc("File containing RuntimeDyld verifier checks."), @@ -252,63 +259,21 @@ static int printLineInfoForInput(bool LoadObjects, bool UseDebugObj) { std::unique_ptr<DIContext> Context( new DWARFContextInMemory(*SymbolObj,LoadedObjInfo.get())); - // FIXME: This is generally useful. Figure out a place in lib/Object to - // put utility functions. - std::map<object::SectionRef, std::vector<uint64_t>> FuncAddresses; - if (!isa<ELFObjectFileBase>(SymbolObj)) { - for (object::SymbolRef Sym : SymbolObj->symbols()) { - object::SymbolRef::Type SymType; - if (Sym.getType(SymType)) - continue; - if (SymType != object::SymbolRef::ST_Function) - continue; - uint64_t Addr; - if (Sym.getAddress(Addr)) - continue; - object::section_iterator Sec = SymbolObj->section_end(); - if (Sym.getSection(Sec)) - continue; - std::vector<uint64_t> &Addrs = FuncAddresses[*Sec]; - if (Addrs.empty()) { - uint64_t SecAddr = Sec->getAddress(); - uint64_t SecSize = Sec->getSize(); - Addrs.push_back(SecAddr + SecSize); - } - Addrs.push_back(Addr); - } - for (auto &Pair : FuncAddresses) { - std::vector<uint64_t> &Addrs = Pair.second; - array_pod_sort(Addrs.begin(), Addrs.end()); - } - } + std::vector<std::pair<SymbolRef, uint64_t>> SymAddr = + object::computeSymbolSizes(*SymbolObj); // Use symbol info to iterate functions in the object. - for (object::SymbolRef Sym : SymbolObj->symbols()) { - object::SymbolRef::Type SymType; - if (Sym.getType(SymType)) - continue; - if (SymType == object::SymbolRef::ST_Function) { - StringRef Name; - uint64_t Addr; - if (Sym.getName(Name)) + for (const auto &P : SymAddr) { + object::SymbolRef Sym = P.first; + if (Sym.getType() == object::SymbolRef::ST_Function) { + ErrorOr<StringRef> Name = Sym.getName(); + if (!Name) continue; + uint64_t Addr; if (Sym.getAddress(Addr)) continue; - uint64_t Size; - if (isa<ELFObjectFileBase>(SymbolObj)) { - Size = Sym.getSize(); - } else { - object::section_iterator Sec = SymbolObj->section_end(); - if (Sym.getSection(Sec)) - continue; - const std::vector<uint64_t> &Addrs = FuncAddresses[*Sec]; - auto AddrI = std::find(Addrs.begin(), Addrs.end(), Addr); - assert(AddrI != Addrs.end() && (AddrI + 1) != Addrs.end()); - assert(*AddrI == Addr); - Size = *(AddrI + 1) - Addr; - } - + uint64_t Size = P.second; // If we're not using the debug object, compute the address of the // symbol in memory (rather than that in the unrelocated object file) // and use that to query the DWARFContext. @@ -323,7 +288,8 @@ static int printLineInfoForInput(bool LoadObjects, bool UseDebugObj) { Addr += SectionLoadAddress - Sec->getAddress(); } - outs() << "Function: " << Name << ", Size = " << Size << ", Addr = " << Addr << "\n"; + outs() << "Function: " << *Name << ", Size = " << Size + << ", Addr = " << Addr << "\n"; DILineInfoTable Lines = Context->getLineInfoForAddressRange(Addr, Size); DILineInfoTable::iterator Begin = Lines.begin(); @@ -575,7 +541,7 @@ static int linkAndVerify() { TripleName = TheTriple.getTriple(); std::unique_ptr<MCSubtargetInfo> STI( - TheTarget->createMCSubtargetInfo(TripleName, "", "")); + TheTarget->createMCSubtargetInfo(TripleName, MCPU, "")); assert(STI && "Unable to create subtarget info!"); std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName)); diff --git a/tools/llvm-stress/llvm-stress.cpp b/tools/llvm-stress/llvm-stress.cpp index f5e718ba65b6..727d03f9d6ea 100644 --- a/tools/llvm-stress/llvm-stress.cpp +++ b/tools/llvm-stress/llvm-stress.cpp @@ -96,24 +96,21 @@ private: /// Generate an empty function with a default argument list. Function *GenEmptyFunction(Module *M) { - // Type Definitions - std::vector<Type*> ArgsTy; // Define a few arguments LLVMContext &Context = M->getContext(); - ArgsTy.push_back(PointerType::get(IntegerType::getInt8Ty(Context), 0)); - ArgsTy.push_back(PointerType::get(IntegerType::getInt32Ty(Context), 0)); - ArgsTy.push_back(PointerType::get(IntegerType::getInt64Ty(Context), 0)); - ArgsTy.push_back(IntegerType::getInt32Ty(Context)); - ArgsTy.push_back(IntegerType::getInt64Ty(Context)); - ArgsTy.push_back(IntegerType::getInt8Ty(Context)); - - FunctionType *FuncTy = FunctionType::get(Type::getVoidTy(Context), ArgsTy, 0); + Type* ArgsTy[] = { + Type::getInt8PtrTy(Context), + Type::getInt32PtrTy(Context), + Type::getInt64PtrTy(Context), + Type::getInt32Ty(Context), + Type::getInt64Ty(Context), + Type::getInt8Ty(Context) + }; + + auto *FuncTy = FunctionType::get(Type::getVoidTy(Context), ArgsTy, false); // Pick a unique name to describe the input parameters - std::stringstream ss; - ss<<"autogen_SD"<<SeedCL; - Function *Func = Function::Create(FuncTy, GlobalValue::ExternalLinkage, - ss.str(), M); - + Twine Name = "autogen_SD" + Twine{SeedCL}; + auto *Func = Function::Create(FuncTy, GlobalValue::ExternalLinkage, Name, M); Func->setCallingConv(CallingConv::C); return Func; } @@ -620,59 +617,45 @@ static void FillFunction(Function *F, Random &R) { Modifier::PieceTable PT; // Consider arguments as legal values. - for (Function::arg_iterator it = F->arg_begin(), e = F->arg_end(); - it != e; ++it) - PT.push_back(it); + for (auto &arg : F->args()) + PT.push_back(&arg); // List of modifiers which add new random instructions. - std::vector<Modifier*> Modifiers; - std::unique_ptr<Modifier> LM(new LoadModifier(BB, &PT, &R)); - std::unique_ptr<Modifier> SM(new StoreModifier(BB, &PT, &R)); - std::unique_ptr<Modifier> EE(new ExtractElementModifier(BB, &PT, &R)); - std::unique_ptr<Modifier> SHM(new ShuffModifier(BB, &PT, &R)); - std::unique_ptr<Modifier> IE(new InsertElementModifier(BB, &PT, &R)); - std::unique_ptr<Modifier> BM(new BinModifier(BB, &PT, &R)); - std::unique_ptr<Modifier> CM(new CastModifier(BB, &PT, &R)); - std::unique_ptr<Modifier> SLM(new SelectModifier(BB, &PT, &R)); - std::unique_ptr<Modifier> PM(new CmpModifier(BB, &PT, &R)); - Modifiers.push_back(LM.get()); - Modifiers.push_back(SM.get()); - Modifiers.push_back(EE.get()); - Modifiers.push_back(SHM.get()); - Modifiers.push_back(IE.get()); - Modifiers.push_back(BM.get()); - Modifiers.push_back(CM.get()); - Modifiers.push_back(SLM.get()); - Modifiers.push_back(PM.get()); + std::vector<std::unique_ptr<Modifier>> Modifiers; + Modifiers.emplace_back(new LoadModifier(BB, &PT, &R)); + Modifiers.emplace_back(new StoreModifier(BB, &PT, &R)); + auto SM = Modifiers.back().get(); + Modifiers.emplace_back(new ExtractElementModifier(BB, &PT, &R)); + Modifiers.emplace_back(new ShuffModifier(BB, &PT, &R)); + Modifiers.emplace_back(new InsertElementModifier(BB, &PT, &R)); + Modifiers.emplace_back(new BinModifier(BB, &PT, &R)); + Modifiers.emplace_back(new CastModifier(BB, &PT, &R)); + Modifiers.emplace_back(new SelectModifier(BB, &PT, &R)); + Modifiers.emplace_back(new CmpModifier(BB, &PT, &R)); // Generate the random instructions - AllocaModifier AM(BB, &PT, &R); AM.ActN(5); // Throw in a few allocas - ConstModifier COM(BB, &PT, &R); COM.ActN(40); // Throw in a few constants + AllocaModifier{BB, &PT, &R}.ActN(5); // Throw in a few allocas + ConstModifier{BB, &PT, &R}.ActN(40); // Throw in a few constants - for (unsigned i=0; i< SizeCL / Modifiers.size(); ++i) - for (std::vector<Modifier*>::iterator it = Modifiers.begin(), - e = Modifiers.end(); it != e; ++it) { - (*it)->Act(); - } + for (unsigned i = 0; i < SizeCL / Modifiers.size(); ++i) + for (auto &Mod : Modifiers) + Mod->Act(); SM->ActN(5); // Throw in a few stores. } static void IntroduceControlFlow(Function *F, Random &R) { std::vector<Instruction*> BoolInst; - for (BasicBlock::iterator it = F->begin()->begin(), - e = F->begin()->end(); it != e; ++it) { - if (it->getType() == IntegerType::getInt1Ty(F->getContext())) - BoolInst.push_back(it); + for (auto &Instr : F->front()) { + if (Instr.getType() == IntegerType::getInt1Ty(F->getContext())) + BoolInst.push_back(&Instr); } std::random_shuffle(BoolInst.begin(), BoolInst.end(), R); - for (std::vector<Instruction*>::iterator it = BoolInst.begin(), - e = BoolInst.end(); it != e; ++it) { - Instruction *Instr = *it; + for (auto *Instr : BoolInst) { BasicBlock *Curr = Instr->getParent(); - BasicBlock::iterator Loc= Instr; + BasicBlock::iterator Loc = Instr; BasicBlock *Next = Curr->splitBasicBlock(Loc, "CF"); Instr->moveBefore(Curr->getTerminator()); if (Curr != &F->getEntryBlock()) { @@ -688,7 +671,7 @@ int main(int argc, char **argv) { cl::ParseCommandLineOptions(argc, argv, "llvm codegen stress-tester\n"); llvm_shutdown_obj Y; - std::unique_ptr<Module> M(new Module("/tmp/autogen.bc", getGlobalContext())); + auto M = make_unique<Module>("/tmp/autogen.bc", getGlobalContext()); Function *F = GenEmptyFunction(M.get()); // Pick an initial seed value diff --git a/tools/llvm-symbolizer/LLVMSymbolize.cpp b/tools/llvm-symbolizer/LLVMSymbolize.cpp index b8fa83839cf7..ec3fe4868db3 100644 --- a/tools/llvm-symbolizer/LLVMSymbolize.cpp +++ b/tools/llvm-symbolizer/LLVMSymbolize.cpp @@ -19,6 +19,7 @@ #include "llvm/DebugInfo/PDB/PDBContext.h" #include "llvm/Object/ELFObjectFile.h" #include "llvm/Object/MachO.h" +#include "llvm/Object/SymbolSize.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compression.h" #include "llvm/Support/DataExtractor.h" @@ -32,6 +33,7 @@ #if defined(_MSC_VER) #include <Windows.h> #include <DbgHelp.h> +#pragma comment(lib, "dbghelp.lib") #endif namespace llvm { @@ -71,30 +73,20 @@ ModuleInfo::ModuleInfo(ObjectFile *Obj, DIContext *DICtx) } } } - for (const SymbolRef &Symbol : Module->symbols()) { - addSymbol(Symbol, OpdExtractor.get(), OpdAddress); - } - bool NoSymbolTable = (Module->symbol_begin() == Module->symbol_end()); - if (NoSymbolTable && Module->isELF()) { - // Fallback to dynamic symbol table, if regular symbol table is stripped. - std::pair<symbol_iterator, symbol_iterator> IDyn = - getELFDynamicSymbolIterators(Module); - for (symbol_iterator si = IDyn.first, se = IDyn.second; si != se; ++si) { - addSymbol(*si, OpdExtractor.get(), OpdAddress); - } - } + std::vector<std::pair<SymbolRef, uint64_t>> Symbols = + computeSymbolSizes(*Module); + for (auto &P : Symbols) + addSymbol(P.first, P.second, OpdExtractor.get(), OpdAddress); } -void ModuleInfo::addSymbol(const SymbolRef &Symbol, DataExtractor *OpdExtractor, - uint64_t OpdAddress) { - SymbolRef::Type SymbolType; - if (error(Symbol.getType(SymbolType))) - return; +void ModuleInfo::addSymbol(const SymbolRef &Symbol, uint64_t SymbolSize, + DataExtractor *OpdExtractor, uint64_t OpdAddress) { + SymbolRef::Type SymbolType = Symbol.getType(); if (SymbolType != SymbolRef::ST_Function && SymbolType != SymbolRef::ST_Data) return; uint64_t SymbolAddress; if (error(Symbol.getAddress(SymbolAddress)) || - SymbolAddress == UnknownAddressOrSize) + SymbolAddress == UnknownAddress) return; if (OpdExtractor) { // For big-endian PowerPC64 ELF, symbols in the .opd section refer to @@ -108,19 +100,10 @@ void ModuleInfo::addSymbol(const SymbolRef &Symbol, DataExtractor *OpdExtractor, OpdExtractor->isValidOffsetForAddress(OpdOffset32)) SymbolAddress = OpdExtractor->getAddress(&OpdOffset32); } - uint64_t SymbolSize; - // Getting symbol size is linear for Mach-O files, so assume that symbol - // occupies the memory range up to the following symbol. - if (isa<MachOObjectFile>(Module)) - SymbolSize = 0; - else { - SymbolSize = Symbol.getSize(); - if (SymbolSize == UnknownAddressOrSize) - return; - } - StringRef SymbolName; - if (error(Symbol.getName(SymbolName))) + ErrorOr<StringRef> SymbolNameOrErr = Symbol.getName(); + if (error(SymbolNameOrErr.getError())) return; + StringRef SymbolName = *SymbolNameOrErr; // Mach-O symbol table names have leading underscore, skip it. if (Module->isMachO() && SymbolName.size() > 0 && SymbolName[0] == '_') SymbolName = SymbolName.drop_front(); @@ -436,7 +419,7 @@ LLVMSymbolizer::getObjectFileFromBinary(Binary *Bin, if (I != ObjectFileForArch.end()) return I->second; ErrorOr<std::unique_ptr<ObjectFile>> ParsedObj = - UB->getObjectForArch(Triple(ArchName).getArch()); + UB->getObjectForArch(ArchName); if (ParsedObj) { Res = ParsedObj.get().get(); ParsedBinariesAndObjects.push_back(std::move(ParsedObj.get())); diff --git a/tools/llvm-symbolizer/LLVMSymbolize.h b/tools/llvm-symbolizer/LLVMSymbolize.h index 1c2006fbbe75..be246c3f8712 100644 --- a/tools/llvm-symbolizer/LLVMSymbolize.h +++ b/tools/llvm-symbolizer/LLVMSymbolize.h @@ -119,7 +119,7 @@ private: uint64_t &Size) const; // For big-endian PowerPC64 ELF, OpdAddress is the address of the .opd // (function descriptor) section and OpdExtractor refers to its contents. - void addSymbol(const SymbolRef &Symbol, + void addSymbol(const SymbolRef &Symbol, uint64_t SymbolSize, DataExtractor *OpdExtractor = nullptr, uint64_t OpdAddress = 0); ObjectFile *Module; diff --git a/tools/lto/lto.cpp b/tools/lto/lto.cpp index e55708c70f89..5c712f18c9ee 100644 --- a/tools/lto/lto.cpp +++ b/tools/lto/lto.cpp @@ -223,20 +223,8 @@ lto_symbol_attributes lto_module_get_symbol_attribute(lto_module_t mod, return unwrap(mod)->getSymbolAttributes(index); } -unsigned int lto_module_get_num_deplibs(lto_module_t mod) { - return unwrap(mod)->getDependentLibraryCount(); -} - -const char* lto_module_get_deplib(lto_module_t mod, unsigned int index) { - return unwrap(mod)->getDependentLibrary(index); -} - -unsigned int lto_module_get_num_linkeropts(lto_module_t mod) { - return unwrap(mod)->getLinkerOptCount(); -} - -const char* lto_module_get_linkeropt(lto_module_t mod, unsigned int index) { - return unwrap(mod)->getLinkerOpt(index); +const char* lto_module_get_linkeropts(lto_module_t mod) { + return unwrap(mod)->getLinkerOpts(); } void lto_codegen_set_diagnostic_handler(lto_code_gen_t cg, diff --git a/tools/lto/lto.exports b/tools/lto/lto.exports index 9145a6ff4dd4..8bc2b0f9d312 100644 --- a/tools/lto/lto.exports +++ b/tools/lto/lto.exports @@ -8,10 +8,7 @@ lto_module_create_from_memory lto_module_create_from_memory_with_path lto_module_create_in_local_context lto_module_create_in_codegen_context -lto_module_get_deplib -lto_module_get_linkeropt -lto_module_get_num_deplibs -lto_module_get_num_linkeropts +lto_module_get_linkeropts lto_module_get_num_symbols lto_module_get_symbol_attribute lto_module_get_symbol_name @@ -42,6 +39,7 @@ lto_codegen_compile_to_file lto_codegen_optimize lto_codegen_compile_optimized lto_codegen_set_should_internalize +lto_codegen_set_should_embed_uselists LLVMCreateDisasm LLVMCreateDisasmCPU LLVMDisasmDispose diff --git a/tools/obj2yaml/coff2yaml.cpp b/tools/obj2yaml/coff2yaml.cpp index 1e29107029ed..f675bfe4e618 100644 --- a/tools/obj2yaml/coff2yaml.cpp +++ b/tools/obj2yaml/coff2yaml.cpp @@ -120,7 +120,10 @@ void COFFDumper::dumpSections(unsigned NumSections) { const object::coff_relocation *reloc = Obj.getCOFFRelocation(Reloc); COFFYAML::Relocation Rel; object::symbol_iterator Sym = Reloc.getSymbol(); - Sym->getName(Rel.SymbolName); + ErrorOr<StringRef> SymbolNameOrErr = Sym->getName(); + if (std::error_code EC = SymbolNameOrErr.getError()) + report_fatal_error(EC.message()); + Rel.SymbolName = *SymbolNameOrErr; Rel.VirtualAddress = reloc->VirtualAddress; Rel.Type = reloc->Type; Relocations.push_back(Rel); diff --git a/tools/obj2yaml/elf2yaml.cpp b/tools/obj2yaml/elf2yaml.cpp index eeabb0f130c3..9afcedef6398 100644 --- a/tools/obj2yaml/elf2yaml.cpp +++ b/tools/obj2yaml/elf2yaml.cpp @@ -23,12 +23,12 @@ template <class ELFT> class ELFDumper { typedef object::Elf_Sym_Impl<ELFT> Elf_Sym; typedef typename object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr; - typedef typename object::ELFFile<ELFT>::Elf_Sym_Iter Elf_Sym_Iter; typedef typename object::ELFFile<ELFT>::Elf_Word Elf_Word; const object::ELFFile<ELFT> &Obj; - std::error_code dumpSymbol(Elf_Sym_Iter Sym, ELFYAML::Symbol &S); + std::error_code dumpSymbol(const Elf_Sym *Sym, bool IsDynamic, + ELFYAML::Symbol &S); std::error_code dumpCommonSection(const Elf_Shdr *Shdr, ELFYAML::Section &S); std::error_code dumpCommonRelocationSection(const Elf_Shdr *Shdr, ELFYAML::RelocationSection &S); @@ -115,14 +115,14 @@ ErrorOr<ELFYAML::Object *> ELFDumper<ELFT>::dump() { // Dump symbols bool IsFirstSym = true; - for (auto SI = Obj.begin_symbols(), SE = Obj.end_symbols(); SI != SE; ++SI) { + for (auto SI = Obj.symbol_begin(), SE = Obj.symbol_end(); SI != SE; ++SI) { if (IsFirstSym) { IsFirstSym = false; continue; } ELFYAML::Symbol S; - if (std::error_code EC = ELFDumper<ELFT>::dumpSymbol(SI, S)) + if (std::error_code EC = ELFDumper<ELFT>::dumpSymbol(SI, false, S)) return EC; switch (SI->getBinding()) @@ -145,19 +145,22 @@ ErrorOr<ELFYAML::Object *> ELFDumper<ELFT>::dump() { } template <class ELFT> -std::error_code ELFDumper<ELFT>::dumpSymbol(Elf_Sym_Iter Sym, +std::error_code ELFDumper<ELFT>::dumpSymbol(const Elf_Sym *Sym, bool IsDynamic, ELFYAML::Symbol &S) { S.Type = Sym->getType(); S.Value = Sym->st_value; S.Size = Sym->st_size; S.Other = Sym->st_other; - ErrorOr<StringRef> NameOrErr = Obj.getSymbolName(Sym); + ErrorOr<StringRef> NameOrErr = Obj.getSymbolName(Sym, IsDynamic); if (std::error_code EC = NameOrErr.getError()) return EC; S.Name = NameOrErr.get(); - const Elf_Shdr *Shdr = Obj.getSection(&*Sym); + ErrorOr<const Elf_Shdr *> ShdrOrErr = Obj.getSection(&*Sym); + if (std::error_code EC = ShdrOrErr.getError()) + return EC; + const Elf_Shdr *Shdr = *ShdrOrErr; if (!Shdr) return obj2yaml_error::success; @@ -182,8 +185,16 @@ std::error_code ELFDumper<ELFT>::dumpRelocation(const Elf_Shdr *Shdr, if (!NamePair.first) return obj2yaml_error::success; - ErrorOr<StringRef> NameOrErr = - Obj.getSymbolName(NamePair.first, NamePair.second); + const Elf_Shdr *SymTab = NamePair.first; + ErrorOr<const Elf_Shdr *> StrTabSec = Obj.getSection(SymTab->sh_link); + if (std::error_code EC = StrTabSec.getError()) + return EC; + ErrorOr<StringRef> StrTabOrErr = Obj.getStringTable(*StrTabSec); + if (std::error_code EC = StrTabOrErr.getError()) + return EC; + StringRef StrTab = *StrTabOrErr; + + ErrorOr<StringRef> NameOrErr = NamePair.second->getName(StrTab); if (std::error_code EC = NameOrErr.getError()) return EC; R.Symbol = NameOrErr.get(); @@ -205,12 +216,13 @@ std::error_code ELFDumper<ELFT>::dumpCommonSection(const Elf_Shdr *Shdr, S.Name = NameOrErr.get(); if (Shdr->sh_link != ELF::SHN_UNDEF) { - if (const Elf_Shdr *LinkSection = Obj.getSection(Shdr->sh_link)) { - NameOrErr = Obj.getSectionName(LinkSection); - if (std::error_code EC = NameOrErr.getError()) - return EC; - S.Link = NameOrErr.get(); - } + ErrorOr<const Elf_Shdr *> LinkSection = Obj.getSection(Shdr->sh_link); + if (std::error_code EC = LinkSection.getError()) + return EC; + NameOrErr = Obj.getSectionName(*LinkSection); + if (std::error_code EC = NameOrErr.getError()) + return EC; + S.Link = NameOrErr.get(); } return obj2yaml_error::success; @@ -223,12 +235,14 @@ ELFDumper<ELFT>::dumpCommonRelocationSection(const Elf_Shdr *Shdr, if (std::error_code EC = dumpCommonSection(Shdr, S)) return EC; - if (const Elf_Shdr *InfoSection = Obj.getSection(Shdr->sh_info)) { - ErrorOr<StringRef> NameOrErr = Obj.getSectionName(InfoSection); - if (std::error_code EC = NameOrErr.getError()) - return EC; - S.Info = NameOrErr.get(); - } + ErrorOr<const Elf_Shdr *> InfoSection = Obj.getSection(Shdr->sh_info); + if (std::error_code EC = InfoSection.getError()) + return EC; + + ErrorOr<StringRef> NameOrErr = Obj.getSectionName(*InfoSection); + if (std::error_code EC = NameOrErr.getError()) + return EC; + S.Info = NameOrErr.get(); return obj2yaml_error::success; } @@ -242,8 +256,7 @@ ELFDumper<ELFT>::dumpRelSection(const Elf_Shdr *Shdr) { if (std::error_code EC = dumpCommonRelocationSection(Shdr, *S)) return EC; - for (auto RI = Obj.begin_rel(Shdr), RE = Obj.end_rel(Shdr); RI != RE; - ++RI) { + for (auto RI = Obj.rel_begin(Shdr), RE = Obj.rel_end(Shdr); RI != RE; ++RI) { ELFYAML::Relocation R; if (std::error_code EC = dumpRelocation(Shdr, &*RI, R)) return EC; @@ -262,7 +275,7 @@ ELFDumper<ELFT>::dumpRelaSection(const Elf_Shdr *Shdr) { if (std::error_code EC = dumpCommonRelocationSection(Shdr, *S)) return EC; - for (auto RI = Obj.begin_rela(Shdr), RE = Obj.end_rela(Shdr); RI != RE; + for (auto RI = Obj.rela_begin(Shdr), RE = Obj.rela_end(Shdr); RI != RE; ++RI) { ELFYAML::Relocation R; if (std::error_code EC = dumpRelocation(Shdr, &*RI, R)) @@ -299,11 +312,20 @@ ErrorOr<ELFYAML::Group *> ELFDumper<ELFT>::dumpGroup(const Elf_Shdr *Shdr) { return EC; // Get sh_info which is the signature. const Elf_Sym *symbol = Obj.getSymbol(Shdr->sh_info); - const Elf_Shdr *symtab = Obj.getSection(Shdr->sh_link); + ErrorOr<const Elf_Shdr *> Symtab = Obj.getSection(Shdr->sh_link); + if (std::error_code EC = Symtab.getError()) + return EC; + ErrorOr<const Elf_Shdr *> StrTabSec = Obj.getSection((*Symtab)->sh_link); + if (std::error_code EC = StrTabSec.getError()) + return EC; + ErrorOr<StringRef> StrTabOrErr = Obj.getStringTable(*StrTabSec); + if (std::error_code EC = StrTabOrErr.getError()) + return EC; + StringRef StrTab = *StrTabOrErr; auto sectionContents = Obj.getSectionContents(Shdr); if (std::error_code ec = sectionContents.getError()) return ec; - ErrorOr<StringRef> symbolName = Obj.getSymbolName(symtab, symbol); + ErrorOr<StringRef> symbolName = symbol->getName(StrTab); if (std::error_code EC = symbolName.getError()) return EC; S->Info = *symbolName; @@ -315,8 +337,10 @@ ErrorOr<ELFYAML::Group *> ELFDumper<ELFT>::dumpGroup(const Elf_Shdr *Shdr) { if (groupMembers[i] == llvm::ELF::GRP_COMDAT) { s.sectionNameOrType = "GRP_COMDAT"; } else { - const Elf_Shdr *sHdr = Obj.getSection(groupMembers[i]); - ErrorOr<StringRef> sectionName = Obj.getSectionName(sHdr); + ErrorOr<const Elf_Shdr *> sHdr = Obj.getSection(groupMembers[i]); + if (std::error_code EC = sHdr.getError()) + return EC; + ErrorOr<StringRef> sectionName = Obj.getSectionName(*sHdr); if (std::error_code ec = sectionName.getError()) return ec; s.sectionNameOrType = *sectionName; |