Index: lldb/source/Expression/DWARFExpression.cpp =================================================================== --- lldb/source/Expression/DWARFExpression.cpp +++ lldb/source/Expression/DWARFExpression.cpp @@ -69,9 +69,23 @@ void DWARFExpression::DumpLocation(Stream *s, lldb::DescriptionLevel level, ABI *abi) const { + + std::function(uint64_t DwarfRegNum, + bool isEH)> + GetRegName = nullptr; + if (abi) { + auto RegInfo = abi->GetMCRegisterInfo(); + GetRegName = [RegInfo](uint64_t DwarfRegNum, + bool isEH) -> llvm::Optional { + if (llvm::Optional LLVMRegNum = + RegInfo.getLLVMRegNum(DwarfRegNum, isEH)) + if (const char *RegName = RegInfo.getName(*LLVMRegNum)) + return llvm::StringRef(RegName); + return llvm::None; + }; + } llvm::DWARFExpression(m_data.GetAsLLVM(), m_data.GetAddressByteSize()) - .print(s->AsRawOstream(), llvm::DIDumpOptions(), - abi ? &abi->GetMCRegisterInfo() : nullptr, nullptr); + .print(s->AsRawOstream(), llvm::DIDumpOptions(), nullptr, GetRegName); } RegisterKind DWARFExpression::GetRegisterKind() const { return m_reg_kind; } Index: llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h =================================================================== --- llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h +++ llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h @@ -27,7 +27,6 @@ namespace llvm { -class MCRegisterInfo; class MemoryBuffer; class AppleAcceleratorTable; class DWARFCompileUnit; @@ -81,9 +80,6 @@ std::weak_ptr DWP; bool CheckedForDWP = false; std::string DWPName; - - std::unique_ptr RegInfo; - std::function RecoverableErrorHandler = WithColor::defaultErrorHandler; std::function WarningHandler = WithColor::defaultWarningHandler; @@ -125,6 +121,9 @@ const DWARFObject &getDWARFObj() const { return *DObj; } + std::function(uint64_t RegNum, bool isEH)> Callback = + nullptr; + static bool classof(const DIContext *DICtx) { return DICtx->getKind() == CK_DWARF; } @@ -408,8 +407,6 @@ std::shared_ptr getDWOContext(StringRef AbsolutePath); - const MCRegisterInfo *getRegisterInfo() const { return RegInfo.get(); } - function_ref getRecoverableErrorHandler() { return RecoverableErrorHandler; } @@ -435,11 +432,6 @@ std::function WarningHandler = WithColor::defaultWarningHandler); - /// Loads register info for the architecture of the provided object file. - /// Improves readability of dumped DWARF expressions. Requires the caller to - /// have initialized the relevant target descriptions. - Error loadRegisterInfo(const object::ObjectFile &Obj); - /// Get address size from CUs. /// TODO: refactor compile_units() to make this const. uint8_t getCUAddrSize(); Index: llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h =================================================================== --- llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h +++ llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h @@ -162,7 +162,9 @@ /// instead of from .debug_frame. This is needed for register number /// conversion because some register numbers differ between the two sections /// for certain architectures like x86. - void dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH) const; + void dump(raw_ostream &OS, bool IsEH, + std::function(uint64_t RegNum, bool isEH)> + Callback = nullptr) const; bool operator==(const UnwindLocation &RHS) const; }; @@ -220,7 +222,9 @@ /// instead of from .debug_frame. This is needed for register number /// conversion because some register numbers differ between the two sections /// for certain architectures like x86. - void dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH) const; + void dump(raw_ostream &OS, bool IsEH, + std::function(uint64_t RegNum, bool isEH)> + Callback = nullptr) const; /// Returns true if we have any register locations in this object. bool hasLocations() const { return !Locations.empty(); } @@ -301,7 +305,9 @@ /// /// \param IndentLevel specify the indent level as an integer. The UnwindRow /// will be output to the stream preceded by 2 * IndentLevel number of spaces. - void dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH, + void dump(raw_ostream &OS, bool IsEH, + std::function(uint64_t RegNum, bool isEH)> + Callback = nullptr, unsigned IndentLevel = 0) const; }; @@ -346,7 +352,9 @@ /// /// \param IndentLevel specify the indent level as an integer. The UnwindRow /// will be output to the stream preceded by 2 * IndentLevel number of spaces. - void dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH, + void dump(raw_ostream &OS, bool IsEH, + std::function(uint64_t RegNum, bool isEH)> + Callback = nullptr, unsigned IndentLevel = 0) const; /// Create an UnwindTable from a Common Information Entry (CIE). @@ -452,8 +460,10 @@ /// where a problem occurred in case an error is returned. Error parse(DWARFDataExtractor Data, uint64_t *Offset, uint64_t EndOffset); - void dump(raw_ostream &OS, DIDumpOptions DumpOpts, const MCRegisterInfo *MRI, - bool IsEH, unsigned IndentLevel = 1) const; + void dump(raw_ostream &OS, DIDumpOptions DumpOpts, bool IsEH, + std::function(uint64_t RegNum, bool isEH)> + Callback = nullptr, + unsigned IndentLevel = 1) const; void addInstruction(const Instruction &I) { Instructions.push_back(I); } @@ -520,10 +530,11 @@ static ArrayRef getOperandTypes(); /// Print \p Opcode's operand number \p OperandIdx which has value \p Operand. - void printOperand(raw_ostream &OS, DIDumpOptions DumpOpts, - const MCRegisterInfo *MRI, bool IsEH, - const Instruction &Instr, unsigned OperandIdx, - uint64_t Operand) const; + void printOperand( + raw_ostream &OS, DIDumpOptions DumpOpts, bool IsEH, + const Instruction &Instr, unsigned OperandIdx, uint64_t Operand, + std::function(uint64_t RegNum, bool isEH)> Callback = + nullptr) const; }; /// An entry in either debug_frame or eh_frame. This entry can be a CIE or an @@ -546,8 +557,10 @@ CFIProgram &cfis() { return CFIs; } /// Dump the instructions in this CFI fragment - virtual void dump(raw_ostream &OS, DIDumpOptions DumpOpts, - const MCRegisterInfo *MRI, bool IsEH) const = 0; + virtual void + dump(raw_ostream &OS, DIDumpOptions DumpOpts, bool IsEH, + std::function(uint64_t RegNum, bool isEH)> Callback = + nullptr) const = 0; protected: const FrameKind Kind; @@ -601,8 +614,9 @@ uint32_t getLSDAPointerEncoding() const { return LSDAPointerEncoding; } - void dump(raw_ostream &OS, DIDumpOptions DumpOpts, const MCRegisterInfo *MRI, - bool IsEH) const override; + void dump(raw_ostream &OS, DIDumpOptions DumpOpts, bool IsEH, + std::function(uint64_t RegNum, bool isEH)> + Callback = nullptr) const override; private: /// The following fields are defined in section 6.4.1 of the DWARF standard v4 @@ -642,8 +656,9 @@ uint64_t getAddressRange() const { return AddressRange; } Optional getLSDAAddress() const { return LSDAAddress; } - void dump(raw_ostream &OS, DIDumpOptions DumpOpts, const MCRegisterInfo *MRI, - bool IsEH) const override; + void dump(raw_ostream &OS, DIDumpOptions DumpOpts, bool IsEH, + std::function(uint64_t RegNum, bool isEH)> + Callback = nullptr) const override; static bool classof(const FrameEntry *FE) { return FE->getKind() == FK_FDE; } @@ -685,8 +700,9 @@ ~DWARFDebugFrame(); /// Dump the section data into the given stream. - void dump(raw_ostream &OS, DIDumpOptions DumpOpts, const MCRegisterInfo *MRI, - Optional Offset) const; + void dump(raw_ostream &OS, DIDumpOptions DumpOpts, Optional Offset, + std::function(uint64_t RegNum, bool isEH)> + Callback = nullptr) const; /// Parse the section from raw data. \p Data is assumed to contain the whole /// frame section contents to be parsed. Index: llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h =================================================================== --- llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h +++ llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h @@ -65,11 +65,12 @@ /// iff it has successfully reched the end of the list. This means that one /// can attempt to parse another list after the current one (\p Offset will be /// updated to point past the end of the current list). - bool dumpLocationList(uint64_t *Offset, raw_ostream &OS, - Optional BaseAddr, - const MCRegisterInfo *MRI, const DWARFObject &Obj, - DWARFUnit *U, DIDumpOptions DumpOpts, - unsigned Indent) const; + bool dumpLocationList( + uint64_t *Offset, raw_ostream &OS, + Optional BaseAddr, const DWARFObject &Obj, + DWARFUnit *U, DIDumpOptions DumpOpts, unsigned Indent, + std::function(uint64_t RegNum, bool isEH)> Callback = + nullptr) const; Error visitAbsoluteLocationList( uint64_t Offset, Optional BaseAddr, @@ -109,9 +110,10 @@ : DWARFLocationTable(std::move(Data)) {} /// Print the location lists found within the debug_loc section. - void dump(raw_ostream &OS, const MCRegisterInfo *RegInfo, - const DWARFObject &Obj, DIDumpOptions DumpOpts, - Optional Offset) const; + void dump(raw_ostream &OS, const DWARFObject &Obj, DIDumpOptions DumpOpts, + Optional Offset, + std::function(uint64_t RegNum, bool isEH)> + Callback = nullptr) const; Error visitLocationList( uint64_t *Offset, @@ -134,8 +136,9 @@ /// Dump all location lists within the given range. void dumpRange(uint64_t StartOffset, uint64_t Size, raw_ostream &OS, - const MCRegisterInfo *MRI, const DWARFObject &Obj, - DIDumpOptions DumpOpts); + const DWARFObject &Obj, DIDumpOptions DumpOpts, + std::function(uint64_t RegNum, bool isEH)> + Callback = nullptr); protected: void dumpRawEntry(const DWARFLocationEntry &Entry, raw_ostream &OS, Index: llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h =================================================================== --- llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h +++ llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h @@ -94,8 +94,9 @@ uint64_t getEndOffset() const { return EndOffset; } bool isError() const { return Error; } bool print(raw_ostream &OS, DIDumpOptions DumpOpts, - const DWARFExpression *Expr, const MCRegisterInfo *RegInfo, - DWARFUnit *U, bool isEH) const; + const DWARFExpression *Expr, DWARFUnit *U, bool isEH, + std::function(uint64_t RegNum, bool isEH)> + Callback = nullptr) const; /// Verify \p Op. Does not affect the return of \a isError(). static bool verify(const Operation &Op, DWARFUnit *U); @@ -148,15 +149,19 @@ iterator begin() const { return iterator(this, 0); } iterator end() const { return iterator(this, Data.getData().size()); } - void print(raw_ostream &OS, DIDumpOptions DumpOpts, - const MCRegisterInfo *RegInfo, DWARFUnit *U, + void print(raw_ostream &OS, DIDumpOptions DumpOpts, DWARFUnit *U, + std::function(uint64_t RegNum, bool isEH)> + Callback = nullptr, bool IsEH = false) const; /// Print the expression in a format intended to be compact and useful to a /// user, but not perfectly unambiguous, or capable of representing every /// valid DWARF expression. Returns true if the expression was sucessfully /// printed. - bool printCompact(raw_ostream &OS, const MCRegisterInfo &RegInfo); + bool printCompact( + raw_ostream &OS, + std::function(uint64_t RegNum, bool isEH)> Callback = + nullptr); bool verify(DWARFUnit *U); Index: llvm/lib/DebugInfo/DWARF/CMakeLists.txt =================================================================== --- llvm/lib/DebugInfo/DWARF/CMakeLists.txt +++ llvm/lib/DebugInfo/DWARF/CMakeLists.txt @@ -36,6 +36,5 @@ LINK_COMPONENTS BinaryFormat Object - MC Support ) Index: llvm/lib/DebugInfo/DWARF/DWARFContext.cpp =================================================================== --- llvm/lib/DebugInfo/DWARF/DWARFContext.cpp +++ llvm/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -38,7 +38,6 @@ #include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h" #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h" #include "llvm/DebugInfo/DWARF/DWARFVerifier.h" -#include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/TargetRegistry.h" #include "llvm/Object/Decompressor.h" #include "llvm/Object/MachO.h" @@ -308,11 +307,11 @@ return Macro; } -static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts, - DWARFDataExtractor Data, - const MCRegisterInfo *MRI, - const DWARFObject &Obj, - Optional DumpOffset) { +static void dumpLoclistsSection( + raw_ostream &OS, DIDumpOptions DumpOpts, DWARFDataExtractor Data, + const DWARFObject &Obj, Optional DumpOffset, + std::function(uint64_t RegNum, bool isEH)> Callback = + nullptr) { uint64_t Offset = 0; while (Data.isValidOffset(Offset)) { @@ -330,13 +329,13 @@ if (DumpOffset) { if (DumpOffset >= Offset && DumpOffset < EndOffset) { Offset = *DumpOffset; - Loc.dumpLocationList(&Offset, OS, /*BaseAddr=*/None, MRI, Obj, nullptr, - DumpOpts, /*Indent=*/0); + Loc.dumpLocationList(&Offset, OS, /*BaseAddr=*/None, Obj, nullptr, + DumpOpts, /*Indent=*/0, Callback); OS << "\n"; return; } } else { - Loc.dumpRange(Offset, EndOffset - Offset, OS, MRI, Obj, DumpOpts); + Loc.dumpRange(Offset, EndOffset - Offset, OS, Obj, DumpOpts, Callback); } Offset = EndOffset; } @@ -424,21 +423,21 @@ if (const auto *Off = shouldDump(Explicit, ".debug_loc", DIDT_ID_DebugLoc, DObj->getLocSection().Data)) { - getDebugLoc()->dump(OS, getRegisterInfo(), *DObj, LLDumpOpts, *Off); + getDebugLoc()->dump(OS, *DObj, LLDumpOpts, *Off, Callback); } if (const auto *Off = shouldDump(Explicit, ".debug_loclists", DIDT_ID_DebugLoclists, DObj->getLoclistsSection().Data)) { DWARFDataExtractor Data(*DObj, DObj->getLoclistsSection(), isLittleEndian(), 0); - dumpLoclistsSection(OS, LLDumpOpts, Data, getRegisterInfo(), *DObj, *Off); + dumpLoclistsSection(OS, LLDumpOpts, Data, *DObj, *Off, Callback); } if (const auto *Off = shouldDump(ExplicitDWO, ".debug_loclists.dwo", DIDT_ID_DebugLoclists, DObj->getLoclistsDWOSection().Data)) { DWARFDataExtractor Data(*DObj, DObj->getLoclistsDWOSection(), isLittleEndian(), 0); - dumpLoclistsSection(OS, LLDumpOpts, Data, getRegisterInfo(), *DObj, *Off); + dumpLoclistsSection(OS, LLDumpOpts, Data, *DObj, *Off, Callback); } if (const auto *Off = @@ -450,12 +449,11 @@ if (*Off) { uint64_t Offset = **Off; Loc.dumpLocationList(&Offset, OS, - /*BaseAddr=*/None, getRegisterInfo(), *DObj, nullptr, - LLDumpOpts, /*Indent=*/0); + /*BaseAddr=*/None, *DObj, nullptr, LLDumpOpts, + /*Indent=*/0, Callback); OS << "\n"; } else { - Loc.dumpRange(0, Data.getData().size(), OS, getRegisterInfo(), *DObj, - LLDumpOpts); + Loc.dumpRange(0, Data.getData().size(), OS, *DObj, LLDumpOpts, Callback); } } @@ -463,7 +461,7 @@ shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame, DObj->getFrameSection().Data)) { if (Expected DF = getDebugFrame()) - (*DF)->dump(OS, DumpOpts, getRegisterInfo(), *Off); + (*DF)->dump(OS, DumpOpts, *Off, Callback); else RecoverableErrorHandler(DF.takeError()); } @@ -472,7 +470,7 @@ shouldDump(Explicit, ".eh_frame", DIDT_ID_DebugFrame, DObj->getEHFrameSection().Data)) { if (Expected DF = getEHFrame()) - (*DF)->dump(OS, DumpOpts, getRegisterInfo(), *Off); + (*DF)->dump(OS, DumpOpts, *Off, Callback); else RecoverableErrorHandler(DF.takeError()); } @@ -2019,23 +2017,6 @@ std::move(DObj), "", RecoverableErrorHandler, WarningHandler); } -Error DWARFContext::loadRegisterInfo(const object::ObjectFile &Obj) { - // Detect the architecture from the object file. We usually don't need OS - // info to lookup a target and create register info. - Triple TT; - TT.setArch(Triple::ArchType(Obj.getArch())); - TT.setVendor(Triple::UnknownVendor); - TT.setOS(Triple::UnknownOS); - std::string TargetLookupError; - const Target *TheTarget = - TargetRegistry::lookupTarget(TT.str(), TargetLookupError); - if (!TargetLookupError.empty()) - return createStringError(errc::invalid_argument, - TargetLookupError.c_str()); - RegInfo.reset(TheTarget->createMCRegInfo(TT.str())); - return Error::success(); -} - uint8_t DWARFContext::getCUAddrSize() { // In theory, different compile units may have different address byte // sizes, but for simplicity we just use the address byte size of the Index: llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp =================================================================== --- llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp +++ llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp @@ -14,7 +14,6 @@ #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/DebugInfo/DIContext.h" #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h" -#include "llvm/MC/MCRegisterInfo.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/DataExtractor.h" #include "llvm/Support/Errc.h" @@ -29,14 +28,15 @@ using namespace llvm; using namespace dwarf; -static void printRegister(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH, - unsigned RegNum) { - if (MRI) { - if (Optional LLVMRegNum = MRI->getLLVMRegNum(RegNum, IsEH)) { - if (const char *RegName = MRI->getName(*LLVMRegNum)) { - OS << RegName; - return; - } +static void printRegister( + raw_ostream &OS, bool IsEH, unsigned RegNum, + std::function(uint64_t RegNum, bool isEH)> Callback = + nullptr) { + if (Callback) { + auto RegName = Callback(RegNum, IsEH); + if (RegName) { + OS << RegName; + return; } } OS << "reg" << RegNum; @@ -80,8 +80,10 @@ return {Expr, true}; } -void UnwindLocation::dump(raw_ostream &OS, const MCRegisterInfo *MRI, - bool IsEH) const { +void UnwindLocation::dump( + raw_ostream &OS, bool IsEH, + std::function(uint64_t RegNum, bool isEH)> Callback) + const { if (Dereference) OS << '['; switch (Kind) { @@ -103,7 +105,7 @@ OS << Offset; break; case RegPlusOffset: - printRegister(OS, MRI, IsEH, RegNum); + printRegister(OS, IsEH, RegNum, Callback); if (Offset == 0 && !AddrSpace) break; if (Offset >= 0) @@ -113,7 +115,7 @@ OS << " in addrspace" << *AddrSpace; break; case DWARFExpr: - Expr->print(OS, DIDumpOptions(), MRI, nullptr, IsEH); + Expr->print(OS, DIDumpOptions(), nullptr, Callback, IsEH); break; case Constant: OS << Offset; @@ -125,7 +127,7 @@ raw_ostream &llvm::dwarf::operator<<(raw_ostream &OS, const UnwindLocation &UL) { - UL.dump(OS, nullptr, false); + UL.dump(OS, false); return OS; } @@ -150,53 +152,59 @@ return false; } -void RegisterLocations::dump(raw_ostream &OS, const MCRegisterInfo *MRI, - bool IsEH) const { +void RegisterLocations::dump( + raw_ostream &OS, bool IsEH, + std::function(uint64_t RegNum, bool isEH)> Callback) + const { bool First = true; for (const auto &RegLocPair : Locations) { if (First) First = false; else OS << ", "; - printRegister(OS, MRI, IsEH, RegLocPair.first); + printRegister(OS, IsEH, RegLocPair.first, Callback); OS << '='; - RegLocPair.second.dump(OS, MRI, IsEH); + RegLocPair.second.dump(OS, IsEH, Callback); } } raw_ostream &llvm::dwarf::operator<<(raw_ostream &OS, const RegisterLocations &RL) { - RL.dump(OS, nullptr, false); + RL.dump(OS, false); return OS; } -void UnwindRow::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH, - unsigned IndentLevel) const { +void UnwindRow::dump( + raw_ostream &OS, bool IsEH, + std::function(uint64_t RegNum, bool isEH)> Callback, + unsigned IndentLevel) const { OS.indent(2 * IndentLevel); if (hasAddress()) OS << format("0x%" PRIx64 ": ", *Address); OS << "CFA="; - CFAValue.dump(OS, MRI, IsEH); + CFAValue.dump(OS, IsEH, Callback); if (RegLocs.hasLocations()) { OS << ": "; - RegLocs.dump(OS, MRI, IsEH); + RegLocs.dump(OS, IsEH, Callback); } OS << "\n"; } raw_ostream &llvm::dwarf::operator<<(raw_ostream &OS, const UnwindRow &Row) { - Row.dump(OS, nullptr, false, 0); + Row.dump(OS, false, nullptr, 0); return OS; } -void UnwindTable::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH, - unsigned IndentLevel) const { +void UnwindTable::dump( + raw_ostream &OS, bool IsEH, + std::function(uint64_t RegNum, bool isEH)> Callback, + unsigned IndentLevel) const { for (const UnwindRow &Row : Rows) - Row.dump(OS, MRI, IsEH, IndentLevel); + Row.dump(OS, IsEH, Callback, IndentLevel); } raw_ostream &llvm::dwarf::operator<<(raw_ostream &OS, const UnwindTable &Rows) { - Rows.dump(OS, nullptr, false, 0); + Rows.dump(OS, false, nullptr, 0); return OS; } @@ -852,10 +860,11 @@ } /// Print \p Opcode's operand number \p OperandIdx which has value \p Operand. -void CFIProgram::printOperand(raw_ostream &OS, DIDumpOptions DumpOpts, - const MCRegisterInfo *MRI, bool IsEH, - const Instruction &Instr, unsigned OperandIdx, - uint64_t Operand) const { +void CFIProgram::printOperand( + raw_ostream &OS, DIDumpOptions DumpOpts, bool IsEH, + const Instruction &Instr, unsigned OperandIdx, uint64_t Operand, + std::function(uint64_t RegNum, bool isEH)> Callback) + const { assert(OperandIdx < MaxOperands); uint8_t Opcode = Instr.Opcode; OperandType Type = getOperandTypes()[Opcode][OperandIdx]; @@ -901,7 +910,7 @@ break; case OT_Register: OS << ' '; - printRegister(OS, MRI, IsEH, Operand); + printRegister(OS, IsEH, Operand, Callback); break; case OT_AddressSpace: OS << format(" in addrspace%" PRId64, Operand); @@ -909,20 +918,21 @@ case OT_Expression: assert(Instr.Expression && "missing DWARFExpression object"); OS << " "; - Instr.Expression->print(OS, DumpOpts, MRI, nullptr, IsEH); + Instr.Expression->print(OS, DumpOpts, nullptr, Callback, IsEH); break; } } -void CFIProgram::dump(raw_ostream &OS, DIDumpOptions DumpOpts, - const MCRegisterInfo *MRI, bool IsEH, - unsigned IndentLevel) const { +void CFIProgram::dump( + raw_ostream &OS, DIDumpOptions DumpOpts, bool IsEH, + std::function(uint64_t RegNum, bool isEH)> Callback, + unsigned IndentLevel) const { for (const auto &Instr : Instructions) { uint8_t Opcode = Instr.Opcode; OS.indent(2 * IndentLevel); OS << callFrameString(Opcode) << ":"; for (unsigned i = 0; i < Instr.Ops.size(); ++i) - printOperand(OS, DumpOpts, MRI, IsEH, Instr, i, Instr.Ops[i]); + printOperand(OS, DumpOpts, IsEH, Instr, i, Instr.Ops[i], Callback); OS << '\n'; } } @@ -939,8 +949,9 @@ return DW_CIE_ID; } -void CIE::dump(raw_ostream &OS, DIDumpOptions DumpOpts, - const MCRegisterInfo *MRI, bool IsEH) const { +void CIE::dump(raw_ostream &OS, DIDumpOptions DumpOpts, bool IsEH, + std::function(uint64_t RegNum, bool isEH)> + Callback) const { // A CIE with a zero length is a terminator entry in the .eh_frame section. if (IsEH && Length == 0) { OS << format("%08" PRIx64, Offset) << " ZERO terminator\n"; @@ -974,11 +985,11 @@ OS << "\n"; } OS << "\n"; - CFIs.dump(OS, DumpOpts, MRI, IsEH); + CFIs.dump(OS, DumpOpts, IsEH, Callback); OS << "\n"; if (Expected RowsOrErr = UnwindTable::create(this)) - RowsOrErr->dump(OS, MRI, IsEH, 1); + RowsOrErr->dump(OS, IsEH, Callback, 1); else { DumpOpts.RecoverableErrorHandler(joinErrors( createStringError(errc::invalid_argument, @@ -988,8 +999,9 @@ OS << "\n"; } -void FDE::dump(raw_ostream &OS, DIDumpOptions DumpOpts, - const MCRegisterInfo *MRI, bool IsEH) const { +void FDE::dump(raw_ostream &OS, DIDumpOptions DumpOpts, bool IsEH, + std::function(uint64_t RegNum, bool isEH)> + Callback) const { OS << format("%08" PRIx64, Offset) << format(" %0*" PRIx64, IsDWARF64 ? 16 : 8, Length) << format(" %0*" PRIx64, IsDWARF64 && !IsEH ? 16 : 8, CIEPointer) @@ -1003,11 +1015,11 @@ OS << " Format: " << FormatString(IsDWARF64) << "\n"; if (LSDAAddress) OS << format(" LSDA Address: %016" PRIx64 "\n", *LSDAAddress); - CFIs.dump(OS, DumpOpts, MRI, IsEH); + CFIs.dump(OS, DumpOpts, IsEH, Callback); OS << "\n"; if (Expected RowsOrErr = UnwindTable::create(this)) - RowsOrErr->dump(OS, MRI, IsEH, 1); + RowsOrErr->dump(OS, IsEH, Callback, 1); else { DumpOpts.RecoverableErrorHandler(joinErrors( createStringError(errc::invalid_argument, @@ -1241,16 +1253,17 @@ return nullptr; } -void DWARFDebugFrame::dump(raw_ostream &OS, DIDumpOptions DumpOpts, - const MCRegisterInfo *MRI, - Optional Offset) const { +void DWARFDebugFrame::dump( + raw_ostream &OS, DIDumpOptions DumpOpts, Optional Offset, + std::function(uint64_t RegNum, bool isEH)> Callback) + const { if (Offset) { if (auto *Entry = getEntryAtOffset(*Offset)) - Entry->dump(OS, DumpOpts, MRI, IsEH); + Entry->dump(OS, DumpOpts, IsEH, Callback); return; } OS << "\n"; for (const auto &Entry : Entries) - Entry->dump(OS, DumpOpts, MRI, IsEH); + Entry->dump(OS, DumpOpts, IsEH, Callback); } Index: llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp =================================================================== --- llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp +++ llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp @@ -108,24 +108,25 @@ } } -static void dumpExpression(raw_ostream &OS, DIDumpOptions DumpOpts, - ArrayRef Data, bool IsLittleEndian, - unsigned AddressSize, const MCRegisterInfo *MRI, - DWARFUnit *U) { +static void dumpExpression( + raw_ostream &OS, DIDumpOptions DumpOpts, ArrayRef Data, + bool IsLittleEndian, unsigned AddressSize, DWARFUnit *U, + std::function(uint64_t RegNum, bool isEH)> Callback = + nullptr) { DWARFDataExtractor Extractor(Data, IsLittleEndian, AddressSize); // Note. We do not pass any format to DWARFExpression, even if the // corresponding unit is known. For now, there is only one operation, // DW_OP_call_ref, which depends on the format; it is rarely used, and // is unexpected in location tables. - DWARFExpression(Extractor, AddressSize).print(OS, DumpOpts, MRI, U); + DWARFExpression(Extractor, AddressSize).print(OS, DumpOpts, U, Callback); } -bool DWARFLocationTable::dumpLocationList(uint64_t *Offset, raw_ostream &OS, - Optional BaseAddr, - const MCRegisterInfo *MRI, - const DWARFObject &Obj, DWARFUnit *U, - DIDumpOptions DumpOpts, - unsigned Indent) const { +bool DWARFLocationTable::dumpLocationList( + uint64_t *Offset, raw_ostream &OS, Optional BaseAddr, + const DWARFObject &Obj, DWARFUnit *U, DIDumpOptions DumpOpts, + unsigned Indent, + std::function(uint64_t RegNum, bool isEH)> Callback) + const { DWARFLocationInterpreter Interp( BaseAddr, [U](uint32_t Index) -> Optional { if (U) @@ -158,7 +159,7 @@ E.Kind != dwarf::DW_LLE_end_of_list) { OS << ": "; dumpExpression(OS, DumpOpts, E.Loc, Data.isLittleEndian(), - Data.getAddressSize(), MRI, U); + Data.getAddressSize(), U, Callback); } return true; }); @@ -184,14 +185,16 @@ }); } -void DWARFDebugLoc::dump(raw_ostream &OS, const MCRegisterInfo *MRI, - const DWARFObject &Obj, DIDumpOptions DumpOpts, - Optional DumpOffset) const { +void DWARFDebugLoc::dump( + raw_ostream &OS, const DWARFObject &Obj, DIDumpOptions DumpOpts, + Optional DumpOffset, + std::function(uint64_t RegNum, bool isEH)> Callback) + const { auto BaseAddr = None; unsigned Indent = 12; if (DumpOffset) { - dumpLocationList(&*DumpOffset, OS, BaseAddr, MRI, Obj, nullptr, DumpOpts, - Indent); + dumpLocationList(&*DumpOffset, OS, BaseAddr, Obj, nullptr, DumpOpts, Indent, + Callback); } else { uint64_t Offset = 0; StringRef Separator; @@ -200,8 +203,8 @@ OS << Separator; Separator = "\n"; - CanContinue = dumpLocationList(&Offset, OS, BaseAddr, MRI, Obj, nullptr, - DumpOpts, Indent); + CanContinue = dumpLocationList(&Offset, OS, BaseAddr, Obj, nullptr, + DumpOpts, Indent, Callback); OS << '\n'; } } @@ -386,10 +389,10 @@ } } -void DWARFDebugLoclists::dumpRange(uint64_t StartOffset, uint64_t Size, - raw_ostream &OS, const MCRegisterInfo *MRI, - const DWARFObject &Obj, - DIDumpOptions DumpOpts) { +void DWARFDebugLoclists::dumpRange( + uint64_t StartOffset, uint64_t Size, raw_ostream &OS, + const DWARFObject &Obj, DIDumpOptions DumpOpts, + std::function(uint64_t RegNum, bool isEH)> Callback) { if (!Data.isValidOffsetForDataOfSize(StartOffset, Size)) { OS << "Invalid dump range\n"; return; @@ -401,8 +404,8 @@ OS << Separator; Separator = "\n"; - CanContinue = dumpLocationList(&Offset, OS, /*BaseAddr=*/None, MRI, Obj, - nullptr, DumpOpts, /*Indent=*/12); + CanContinue = dumpLocationList(&Offset, OS, /*BaseAddr=*/None, Obj, nullptr, + DumpOpts, /*Indent=*/12, Callback); OS << '\n'; } } Index: llvm/lib/DebugInfo/DWARF/DWARFDie.cpp =================================================================== --- llvm/lib/DebugInfo/DWARF/DWARFDie.cpp +++ llvm/lib/DebugInfo/DWARF/DWARFDie.cpp @@ -76,7 +76,6 @@ assert(FormValue.isFormClass(DWARFFormValue::FC_SectionOffset) && "bad FORM for location list"); DWARFContext &Ctx = U->getContext(); - const MCRegisterInfo *MRI = Ctx.getRegisterInfo(); uint64_t Offset = *FormValue.getAsSectionOffset(); if (FormValue.getForm() == DW_FORM_loclistx) { @@ -87,9 +86,9 @@ else return; } - U->getLocationTable().dumpLocationList(&Offset, OS, U->getBaseAddress(), MRI, - Ctx.getDWARFObj(), U, DumpOpts, - Indent); + U->getLocationTable().dumpLocationList(&Offset, OS, U->getBaseAddress(), + Ctx.getDWARFObj(), U, DumpOpts, Indent, + Ctx.Callback); } static void dumpLocationExpr(raw_ostream &OS, const DWARFFormValue &FormValue, @@ -99,12 +98,11 @@ FormValue.isFormClass(DWARFFormValue::FC_Exprloc)) && "bad FORM for location expression"); DWARFContext &Ctx = U->getContext(); - const MCRegisterInfo *MRI = Ctx.getRegisterInfo(); ArrayRef Expr = *FormValue.getAsBlock(); DataExtractor Data(StringRef((const char *)Expr.data(), Expr.size()), Ctx.isLittleEndian(), 0); DWARFExpression(Data, U->getAddressByteSize(), U->getFormParams().Format) - .print(OS, DumpOpts, MRI, U); + .print(OS, DumpOpts, U, Ctx.Callback); } static DWARFDie resolveReferencedType(DWARFDie D, DWARFFormValue F) { Index: llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp =================================================================== --- llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp +++ llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp @@ -8,7 +8,6 @@ #include "llvm/DebugInfo/DWARF/DWARFExpression.h" #include "llvm/DebugInfo/DWARF/DWARFUnit.h" -#include "llvm/MC/MCRegisterInfo.h" #include "llvm/Support/Format.h" #include #include @@ -225,11 +224,12 @@ } } -static bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS, - DIDumpOptions DumpOpts, uint8_t Opcode, - const uint64_t Operands[2], - const MCRegisterInfo *MRI, bool isEH) { - if (!MRI) +static bool prettyPrintRegisterOp( + DWARFUnit *U, raw_ostream &OS, DIDumpOptions DumpOpts, uint8_t Opcode, + const uint64_t Operands[2], bool isEH, + std::function(uint64_t RegNum, bool isEH)> Callback = + nullptr) { + if (!Callback) return false; uint64_t DwarfRegNum; @@ -243,27 +243,27 @@ else DwarfRegNum = Opcode - DW_OP_reg0; - if (Optional LLVMRegNum = MRI->getLLVMRegNum(DwarfRegNum, isEH)) { - if (const char *RegName = MRI->getName(*LLVMRegNum)) { - if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31) || - Opcode == DW_OP_bregx) - OS << format(" %s%+" PRId64, RegName, Operands[OpNum]); - else - OS << ' ' << RegName; - - if (Opcode == DW_OP_regval_type) - prettyPrintBaseTypeRef(U, OS, DumpOpts, Operands, 1); - return true; - } + auto RegName = Callback(DwarfRegNum, isEH); + if (RegName) { + if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31) || + Opcode == DW_OP_bregx) + OS << format(" %s%+" PRId64, RegName->data(), Operands[OpNum]); + else + OS << ' ' << RegName->data(); + + if (Opcode == DW_OP_regval_type) + prettyPrintBaseTypeRef(U, OS, DumpOpts, Operands, 1); + return true; } return false; } -bool DWARFExpression::Operation::print(raw_ostream &OS, DIDumpOptions DumpOpts, - const DWARFExpression *Expr, - const MCRegisterInfo *RegInfo, - DWARFUnit *U, bool isEH) const { +bool DWARFExpression::Operation::print( + raw_ostream &OS, DIDumpOptions DumpOpts, const DWARFExpression *Expr, + DWARFUnit *U, bool isEH, + std::function(uint64_t RegNum, bool isEH)> Callback) + const { if (Error) { OS << ""; return false; @@ -277,7 +277,8 @@ (Opcode >= DW_OP_reg0 && Opcode <= DW_OP_reg31) || Opcode == DW_OP_bregx || Opcode == DW_OP_regx || Opcode == DW_OP_regval_type) - if (prettyPrintRegisterOp(U, OS, DumpOpts, Opcode, Operands, RegInfo, isEH)) + if (prettyPrintRegisterOp(U, OS, DumpOpts, Opcode, Operands, isEH, + Callback)) return true; for (unsigned Operand = 0; Operand < 2; ++Operand) { @@ -322,16 +323,17 @@ return true; } -void DWARFExpression::print(raw_ostream &OS, DIDumpOptions DumpOpts, - const MCRegisterInfo *RegInfo, DWARFUnit *U, - bool IsEH) const { +void DWARFExpression::print( + raw_ostream &OS, DIDumpOptions DumpOpts, DWARFUnit *U, + std::function(uint64_t RegNum, bool isEH)> Callback, + bool IsEH) const { uint32_t EntryValExprSize = 0; uint64_t EntryValStartOffset = 0; if (Data.getData().empty()) OS << ""; for (auto &Op : *this) { - if (!Op.print(OS, DumpOpts, this, RegInfo, U, IsEH)) { + if (!Op.print(OS, DumpOpts, this, U, IsEH, Callback)) { uint64_t FailOffset = Op.getEndOffset(); while (FailOffset < Data.getData().size()) OS << format(" %02x", Data.getU8(&FailOffset)); @@ -402,9 +404,11 @@ PrintedExpr(ExprKind K = Address) : Kind(K) {} }; -static bool printCompactDWARFExpr(raw_ostream &OS, DWARFExpression::iterator I, - const DWARFExpression::iterator E, - const MCRegisterInfo &MRI) { +static bool printCompactDWARFExpr( + raw_ostream &OS, DWARFExpression::iterator I, + const DWARFExpression::iterator E, + std::function(uint64_t RegNum, bool isEH)> Callback = + nullptr) { SmallVector Stack; while (I != E) { @@ -415,25 +419,21 @@ // DW_OP_regx: A register, with the register num given as an operand. // Printed as the plain register name. uint64_t DwarfRegNum = Op.getRawOperand(0); - Optional LLVMRegNum = MRI.getLLVMRegNum(DwarfRegNum, false); - if (!LLVMRegNum) { - OS << ""; + auto RegName = Callback(DwarfRegNum, false); + if (!RegName) return false; - } raw_svector_ostream S(Stack.emplace_back(PrintedExpr::Value).String); - S << MRI.getName(*LLVMRegNum); + S << RegName; break; } case dwarf::DW_OP_bregx: { int DwarfRegNum = Op.getRawOperand(0); int64_t Offset = Op.getRawOperand(1); - Optional LLVMRegNum = MRI.getLLVMRegNum(DwarfRegNum, false); - if (!LLVMRegNum) { - OS << ""; + auto RegName = Callback(DwarfRegNum, false); + if (!RegName) return false; - } raw_svector_ostream S(Stack.emplace_back().String); - S << MRI.getName(*LLVMRegNum); + S << RegName; if (Offset) S << format("%+" PRId64, Offset); break; @@ -447,7 +447,7 @@ ++I; raw_svector_ostream S(Stack.emplace_back().String); S << "entry("; - printCompactDWARFExpr(S, I, SubExprEnd, MRI); + printCompactDWARFExpr(S, I, SubExprEnd, Callback); S << ")"; I = SubExprEnd; continue; @@ -464,24 +464,20 @@ // DW_OP_reg: A register, with the register num implied by the // opcode. Printed as the plain register name. uint64_t DwarfRegNum = Opcode - dwarf::DW_OP_reg0; - Optional LLVMRegNum = MRI.getLLVMRegNum(DwarfRegNum, false); - if (!LLVMRegNum) { - OS << ""; + auto RegName = Callback(DwarfRegNum, false); + if (!RegName) return false; - } raw_svector_ostream S(Stack.emplace_back(PrintedExpr::Value).String); - S << MRI.getName(*LLVMRegNum); + S << RegName; } else if (Opcode >= dwarf::DW_OP_breg0 && Opcode <= dwarf::DW_OP_breg31) { int DwarfRegNum = Opcode - dwarf::DW_OP_breg0; int64_t Offset = Op.getRawOperand(0); - Optional LLVMRegNum = MRI.getLLVMRegNum(DwarfRegNum, false); - if (!LLVMRegNum) { - OS << ""; + auto RegName = Callback(DwarfRegNum, false); + if (!RegName) return false; - } raw_svector_ostream S(Stack.emplace_back().String); - S << MRI.getName(*LLVMRegNum); + S << RegName; if (Offset) S << format("%+" PRId64, Offset); } else { @@ -506,8 +502,10 @@ return true; } -bool DWARFExpression::printCompact(raw_ostream &OS, const MCRegisterInfo &MRI) { - return printCompactDWARFExpr(OS, begin(), end(), MRI); +bool DWARFExpression::printCompact( + raw_ostream &OS, + std::function(uint64_t RegNum, bool isEH)> Callback) { + return printCompactDWARFExpr(OS, begin(), end(), Callback); } bool DWARFExpression::operator==(const DWARFExpression &RHS) const { Index: llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp =================================================================== --- llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp +++ llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp @@ -18,6 +18,8 @@ #include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h" #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h" #include "llvm/DebugInfo/DWARF/DWARFContext.h" +#include "llvm/MC/MCRegisterInfo.h" +#include "llvm/MC/TargetRegistry.h" #include "llvm/Object/Archive.h" #include "llvm/Object/MachOUniversal.h" #include "llvm/Object/ObjectFile.h" @@ -552,10 +554,43 @@ return Result; } +static Error createRegInfo(const object::ObjectFile &Obj, + std::unique_ptr &MCRegInfo) { + Triple TT; + TT.setArch(Triple::ArchType(Obj.getArch())); + TT.setVendor(Triple::UnknownVendor); + TT.setOS(Triple::UnknownOS); + std::string TargetLookupError; + const Target *TheTarget = + TargetRegistry::lookupTarget(TT.str(), TargetLookupError); + if (!TargetLookupError.empty()) + return createStringError(std::errc::invalid_argument, + TargetLookupError.c_str()); + MCRegInfo.reset(TheTarget->createMCRegInfo(TT.str())); + return Error::success(); +} + static bool dumpObjectFile(ObjectFile &Obj, DWARFContext &DICtx, const Twine &Filename, raw_ostream &OS) { - logAllUnhandledErrors(DICtx.loadRegisterInfo(Obj), errs(), - Filename.str() + ": "); + + std::unique_ptr MCRegInfo; + auto Err = createRegInfo(Obj, MCRegInfo); + if (Err) + logAllUnhandledErrors(std::move(Err), errs(), Filename.str() + ": "); + + auto GetRegName = [&MCRegInfo](uint64_t DwarfRegNum, + bool isEH) -> llvm::Optional { + if (!MCRegInfo) + return None; + if (llvm::Optional LLVMRegNum = + MCRegInfo->getLLVMRegNum(DwarfRegNum, isEH)) + if (const char *RegName = MCRegInfo->getName(*LLVMRegNum)) + return StringRef(RegName); + return None; + }; + + DICtx.Callback = GetRegName; + // The UUID dump already contains all the same information. if (!(DumpType & DIDT_UUID) || DumpType == DIDT_All) OS << Filename << ":\tfile format " << Obj.getFileFormatName() << '\n'; Index: llvm/tools/llvm-gsymutil/llvm-gsymutil.cpp =================================================================== --- llvm/tools/llvm-gsymutil/llvm-gsymutil.cpp +++ llvm/tools/llvm-gsymutil/llvm-gsymutil.cpp @@ -285,7 +285,6 @@ if (!DICtx) return createStringError(std::errc::invalid_argument, "unable to create DWARF context"); - logAllUnhandledErrors(DICtx->loadRegisterInfo(Obj), OS, "DwarfTransformer: "); // Make a DWARF transformer object and populate the ranges of the code // so we don't end up adding invalid functions to GSYM data. Index: llvm/tools/llvm-objdump/SourcePrinter.h =================================================================== --- llvm/tools/llvm-objdump/SourcePrinter.h +++ llvm/tools/llvm-objdump/SourcePrinter.h @@ -13,6 +13,7 @@ #include "llvm/ADT/StringSet.h" #include "llvm/DebugInfo/DWARF/DWARFContext.h" #include "llvm/DebugInfo/Symbolize/Symbolize.h" +#include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/Support/FormattedStream.h" #include Index: llvm/tools/llvm-objdump/SourcePrinter.cpp =================================================================== --- llvm/tools/llvm-objdump/SourcePrinter.cpp +++ llvm/tools/llvm-objdump/SourcePrinter.cpp @@ -42,7 +42,18 @@ DataExtractor Data({LocExpr.Expr.data(), LocExpr.Expr.size()}, Unit->getContext().isLittleEndian(), 0); DWARFExpression Expression(Data, Unit->getAddressByteSize()); - Expression.printCompact(OS, MRI); + + auto GetRegName = [&MRI, &OS](uint64_t DwarfRegNum, + bool isEH) -> Optional { + if (Optional LLVMRegNum = MRI.getLLVMRegNum(DwarfRegNum, isEH)) + if (const char *RegName = MRI.getName(*LLVMRegNum)) + return StringRef(RegName); + else + OS << ""; + return None; + }; + + Expression.printCompact(OS, GetRegName); } void LiveVariablePrinter::addVariable(DWARFDie FuncDie, DWARFDie VarDie) { Index: llvm/tools/llvm-readobj/DwarfCFIEHPrinter.h =================================================================== --- llvm/tools/llvm-readobj/DwarfCFIEHPrinter.h +++ llvm/tools/llvm-readobj/DwarfCFIEHPrinter.h @@ -226,7 +226,7 @@ W.getOStream() << "\n"; W.startLine() << "Program:\n"; W.indent(); - Entry.cfis().dump(W.getOStream(), DIDumpOptions(), nullptr, + Entry.cfis().dump(W.getOStream(), DIDumpOptions(), true, nullptr, W.getIndentLevel()); W.unindent(); W.unindent(); Index: llvm/unittests/DebugInfo/DWARF/DWARFDebugFrameTest.cpp =================================================================== --- llvm/unittests/DebugInfo/DWARF/DWARFDebugFrameTest.cpp +++ llvm/unittests/DebugInfo/DWARF/DWARFDebugFrameTest.cpp @@ -41,7 +41,7 @@ StringRef ExpectedFirstLine) { std::string Output; raw_string_ostream OS(Output); - TestCIE.dump(OS, DIDumpOptions(), /*MRI=*/nullptr, IsEH); + TestCIE.dump(OS, DIDumpOptions(), IsEH); OS.flush(); StringRef FirstLine = StringRef(Output).split('\n').first; EXPECT_EQ(FirstLine, ExpectedFirstLine); @@ -51,7 +51,7 @@ StringRef ExpectedFirstLine) { std::string Output; raw_string_ostream OS(Output); - TestFDE.dump(OS, DIDumpOptions(), /*MRI=*/nullptr, IsEH); + TestFDE.dump(OS, DIDumpOptions(), IsEH); OS.flush(); StringRef FirstLine = StringRef(Output).split('\n').first; EXPECT_EQ(FirstLine, ExpectedFirstLine); Index: llvm/unittests/DebugInfo/DWARF/DWARFExpressionCompactPrinterTest.cpp =================================================================== --- llvm/unittests/DebugInfo/DWARF/DWARFExpressionCompactPrinterTest.cpp +++ llvm/unittests/DebugInfo/DWARF/DWARFExpressionCompactPrinterTest.cpp @@ -60,7 +60,19 @@ raw_string_ostream OS(Result); DataExtractor DE(ExprData, true, 8); DWARFExpression Expr(DE, 8); - Expr.printCompact(OS, *MRI); + + auto GetRegName = [&](uint64_t DwarfRegNum, + bool isEH) -> Optional { + if (llvm::Optional LLVMRegNum = + this->MRI->getLLVMRegNum(DwarfRegNum, isEH)) + if (const char *RegName = this->MRI->getName(*LLVMRegNum)) + return llvm::StringRef(RegName); + else + OS << ""; + return None; + }; + + Expr.printCompact(OS, GetRegName); EXPECT_EQ(OS.str(), Expected); }