mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
llvm-dwarfdump: Support verbose printing DW_OP_convert to print the CU local offset before the resolved absolute offset
This commit is contained in:
parent
243bd8f652
commit
174725a4ae
@ -71,8 +71,8 @@ public:
|
|||||||
/// where a problem occurred in case an error is returned.
|
/// where a problem occurred in case an error is returned.
|
||||||
Error parse(DWARFDataExtractor Data, uint64_t *Offset, uint64_t EndOffset);
|
Error parse(DWARFDataExtractor Data, uint64_t *Offset, uint64_t EndOffset);
|
||||||
|
|
||||||
void dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH,
|
void dump(raw_ostream &OS, DIDumpOptions DumpOpts, const MCRegisterInfo *MRI,
|
||||||
unsigned IndentLevel = 1) const;
|
bool IsEH, unsigned IndentLevel = 1) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<Instruction> Instructions;
|
std::vector<Instruction> Instructions;
|
||||||
@ -121,7 +121,8 @@ private:
|
|||||||
static ArrayRef<OperandType[2]> getOperandTypes();
|
static ArrayRef<OperandType[2]> getOperandTypes();
|
||||||
|
|
||||||
/// Print \p Opcode's operand number \p OperandIdx which has value \p Operand.
|
/// Print \p Opcode's operand number \p OperandIdx which has value \p Operand.
|
||||||
void printOperand(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH,
|
void printOperand(raw_ostream &OS, DIDumpOptions DumpOpts,
|
||||||
|
const MCRegisterInfo *MRI, bool IsEH,
|
||||||
const Instruction &Instr, unsigned OperandIdx,
|
const Instruction &Instr, unsigned OperandIdx,
|
||||||
uint64_t Operand) const;
|
uint64_t Operand) const;
|
||||||
};
|
};
|
||||||
@ -146,8 +147,8 @@ public:
|
|||||||
CFIProgram &cfis() { return CFIs; }
|
CFIProgram &cfis() { return CFIs; }
|
||||||
|
|
||||||
/// Dump the instructions in this CFI fragment
|
/// Dump the instructions in this CFI fragment
|
||||||
virtual void dump(raw_ostream &OS, const MCRegisterInfo *MRI,
|
virtual void dump(raw_ostream &OS, DIDumpOptions DumpOpts,
|
||||||
bool IsEH) const = 0;
|
const MCRegisterInfo *MRI, bool IsEH) const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const FrameKind Kind;
|
const FrameKind Kind;
|
||||||
@ -201,7 +202,7 @@ public:
|
|||||||
|
|
||||||
uint32_t getLSDAPointerEncoding() const { return LSDAPointerEncoding; }
|
uint32_t getLSDAPointerEncoding() const { return LSDAPointerEncoding; }
|
||||||
|
|
||||||
void dump(raw_ostream &OS, const MCRegisterInfo *MRI,
|
void dump(raw_ostream &OS, DIDumpOptions DumpOpts, const MCRegisterInfo *MRI,
|
||||||
bool IsEH) const override;
|
bool IsEH) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -242,7 +243,7 @@ public:
|
|||||||
uint64_t getAddressRange() const { return AddressRange; }
|
uint64_t getAddressRange() const { return AddressRange; }
|
||||||
Optional<uint64_t> getLSDAAddress() const { return LSDAAddress; }
|
Optional<uint64_t> getLSDAAddress() const { return LSDAAddress; }
|
||||||
|
|
||||||
void dump(raw_ostream &OS, const MCRegisterInfo *MRI,
|
void dump(raw_ostream &OS, DIDumpOptions DumpOpts, const MCRegisterInfo *MRI,
|
||||||
bool IsEH) const override;
|
bool IsEH) const override;
|
||||||
|
|
||||||
static bool classof(const FrameEntry *FE) { return FE->getKind() == FK_FDE; }
|
static bool classof(const FrameEntry *FE) { return FE->getKind() == FK_FDE; }
|
||||||
@ -285,7 +286,7 @@ public:
|
|||||||
~DWARFDebugFrame();
|
~DWARFDebugFrame();
|
||||||
|
|
||||||
/// Dump the section data into the given stream.
|
/// Dump the section data into the given stream.
|
||||||
void dump(raw_ostream &OS, const MCRegisterInfo *MRI,
|
void dump(raw_ostream &OS, DIDumpOptions DumpOpts, const MCRegisterInfo *MRI,
|
||||||
Optional<uint64_t> Offset) const;
|
Optional<uint64_t> Offset) const;
|
||||||
|
|
||||||
/// Parse the section from raw data. \p Data is assumed to contain the whole
|
/// Parse the section from raw data. \p Data is assumed to contain the whole
|
||||||
|
@ -10,10 +10,11 @@
|
|||||||
#define LLVM_DEBUGINFO_DWARFEXPRESSION_H
|
#define LLVM_DEBUGINFO_DWARFEXPRESSION_H
|
||||||
|
|
||||||
#include "llvm/ADT/ArrayRef.h"
|
#include "llvm/ADT/ArrayRef.h"
|
||||||
|
#include "llvm/ADT/Optional.h"
|
||||||
#include "llvm/ADT/iterator.h"
|
#include "llvm/ADT/iterator.h"
|
||||||
#include "llvm/ADT/iterator_range.h"
|
#include "llvm/ADT/iterator_range.h"
|
||||||
#include "llvm/ADT/Optional.h"
|
|
||||||
#include "llvm/BinaryFormat/Dwarf.h"
|
#include "llvm/BinaryFormat/Dwarf.h"
|
||||||
|
#include "llvm/DebugInfo/DIContext.h"
|
||||||
#include "llvm/Support/DataExtractor.h"
|
#include "llvm/Support/DataExtractor.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
@ -93,8 +94,9 @@ public:
|
|||||||
bool extract(DataExtractor Data, uint8_t AddressSize, uint64_t Offset,
|
bool extract(DataExtractor Data, uint8_t AddressSize, uint64_t Offset,
|
||||||
Optional<dwarf::DwarfFormat> Format);
|
Optional<dwarf::DwarfFormat> Format);
|
||||||
bool isError() { return Error; }
|
bool isError() { return Error; }
|
||||||
bool print(raw_ostream &OS, const DWARFExpression *Expr,
|
bool print(raw_ostream &OS, DIDumpOptions DumpOpts,
|
||||||
const MCRegisterInfo *RegInfo, DWARFUnit *U, bool isEH);
|
const DWARFExpression *Expr, const MCRegisterInfo *RegInfo,
|
||||||
|
DWARFUnit *U, bool isEH);
|
||||||
bool verify(DWARFUnit *U);
|
bool verify(DWARFUnit *U);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -143,7 +145,8 @@ public:
|
|||||||
iterator begin() const { return iterator(this, 0); }
|
iterator begin() const { return iterator(this, 0); }
|
||||||
iterator end() const { return iterator(this, Data.getData().size()); }
|
iterator end() const { return iterator(this, Data.getData().size()); }
|
||||||
|
|
||||||
void print(raw_ostream &OS, const MCRegisterInfo *RegInfo, DWARFUnit *U,
|
void print(raw_ostream &OS, DIDumpOptions DumpOpts,
|
||||||
|
const MCRegisterInfo *RegInfo, DWARFUnit *U,
|
||||||
bool IsEH = false) const;
|
bool IsEH = false) const;
|
||||||
|
|
||||||
/// Print the expression in a format intended to be compact and useful to a
|
/// Print the expression in a format intended to be compact and useful to a
|
||||||
|
@ -457,7 +457,7 @@ void DWARFContext::dump(
|
|||||||
shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame,
|
shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame,
|
||||||
DObj->getFrameSection().Data)) {
|
DObj->getFrameSection().Data)) {
|
||||||
if (Expected<const DWARFDebugFrame *> DF = getDebugFrame())
|
if (Expected<const DWARFDebugFrame *> DF = getDebugFrame())
|
||||||
(*DF)->dump(OS, getRegisterInfo(), *Off);
|
(*DF)->dump(OS, DumpOpts, getRegisterInfo(), *Off);
|
||||||
else
|
else
|
||||||
RecoverableErrorHandler(DF.takeError());
|
RecoverableErrorHandler(DF.takeError());
|
||||||
}
|
}
|
||||||
@ -466,7 +466,7 @@ void DWARFContext::dump(
|
|||||||
shouldDump(Explicit, ".eh_frame", DIDT_ID_DebugFrame,
|
shouldDump(Explicit, ".eh_frame", DIDT_ID_DebugFrame,
|
||||||
DObj->getEHFrameSection().Data)) {
|
DObj->getEHFrameSection().Data)) {
|
||||||
if (Expected<const DWARFDebugFrame *> DF = getEHFrame())
|
if (Expected<const DWARFDebugFrame *> DF = getEHFrame())
|
||||||
(*DF)->dump(OS, getRegisterInfo(), *Off);
|
(*DF)->dump(OS, DumpOpts, getRegisterInfo(), *Off);
|
||||||
else
|
else
|
||||||
RecoverableErrorHandler(DF.takeError());
|
RecoverableErrorHandler(DF.takeError());
|
||||||
}
|
}
|
||||||
|
@ -234,9 +234,10 @@ ArrayRef<CFIProgram::OperandType[2]> CFIProgram::getOperandTypes() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Print \p Opcode's operand number \p OperandIdx which has value \p Operand.
|
/// Print \p Opcode's operand number \p OperandIdx which has value \p Operand.
|
||||||
void CFIProgram::printOperand(raw_ostream &OS, const MCRegisterInfo *MRI,
|
void CFIProgram::printOperand(raw_ostream &OS, DIDumpOptions DumpOpts,
|
||||||
bool IsEH, const Instruction &Instr,
|
const MCRegisterInfo *MRI, bool IsEH,
|
||||||
unsigned OperandIdx, uint64_t Operand) const {
|
const Instruction &Instr, unsigned OperandIdx,
|
||||||
|
uint64_t Operand) const {
|
||||||
assert(OperandIdx < 2);
|
assert(OperandIdx < 2);
|
||||||
uint8_t Opcode = Instr.Opcode;
|
uint8_t Opcode = Instr.Opcode;
|
||||||
OperandType Type = getOperandTypes()[Opcode][OperandIdx];
|
OperandType Type = getOperandTypes()[Opcode][OperandIdx];
|
||||||
@ -287,12 +288,13 @@ void CFIProgram::printOperand(raw_ostream &OS, const MCRegisterInfo *MRI,
|
|||||||
case OT_Expression:
|
case OT_Expression:
|
||||||
assert(Instr.Expression && "missing DWARFExpression object");
|
assert(Instr.Expression && "missing DWARFExpression object");
|
||||||
OS << " ";
|
OS << " ";
|
||||||
Instr.Expression->print(OS, MRI, nullptr, IsEH);
|
Instr.Expression->print(OS, DumpOpts, MRI, nullptr, IsEH);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFIProgram::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH,
|
void CFIProgram::dump(raw_ostream &OS, DIDumpOptions DumpOpts,
|
||||||
|
const MCRegisterInfo *MRI, bool IsEH,
|
||||||
unsigned IndentLevel) const {
|
unsigned IndentLevel) const {
|
||||||
for (const auto &Instr : Instructions) {
|
for (const auto &Instr : Instructions) {
|
||||||
uint8_t Opcode = Instr.Opcode;
|
uint8_t Opcode = Instr.Opcode;
|
||||||
@ -301,7 +303,7 @@ void CFIProgram::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH,
|
|||||||
OS.indent(2 * IndentLevel);
|
OS.indent(2 * IndentLevel);
|
||||||
OS << CallFrameString(Opcode, Arch) << ":";
|
OS << CallFrameString(Opcode, Arch) << ":";
|
||||||
for (unsigned i = 0; i < Instr.Ops.size(); ++i)
|
for (unsigned i = 0; i < Instr.Ops.size(); ++i)
|
||||||
printOperand(OS, MRI, IsEH, Instr, i, Instr.Ops[i]);
|
printOperand(OS, DumpOpts, MRI, IsEH, Instr, i, Instr.Ops[i]);
|
||||||
OS << '\n';
|
OS << '\n';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -318,7 +320,8 @@ constexpr uint64_t getCIEId(bool IsDWARF64, bool IsEH) {
|
|||||||
return DW_CIE_ID;
|
return DW_CIE_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CIE::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH) const {
|
void CIE::dump(raw_ostream &OS, DIDumpOptions DumpOpts,
|
||||||
|
const MCRegisterInfo *MRI, bool IsEH) const {
|
||||||
// A CIE with a zero length is a terminator entry in the .eh_frame section.
|
// A CIE with a zero length is a terminator entry in the .eh_frame section.
|
||||||
if (IsEH && Length == 0) {
|
if (IsEH && Length == 0) {
|
||||||
OS << format("%08" PRIx64, Offset) << " ZERO terminator\n";
|
OS << format("%08" PRIx64, Offset) << " ZERO terminator\n";
|
||||||
@ -350,11 +353,12 @@ void CIE::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH) const {
|
|||||||
OS << "\n";
|
OS << "\n";
|
||||||
}
|
}
|
||||||
OS << "\n";
|
OS << "\n";
|
||||||
CFIs.dump(OS, MRI, IsEH);
|
CFIs.dump(OS, DumpOpts, MRI, IsEH);
|
||||||
OS << "\n";
|
OS << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void FDE::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH) const {
|
void FDE::dump(raw_ostream &OS, DIDumpOptions DumpOpts,
|
||||||
|
const MCRegisterInfo *MRI, bool IsEH) const {
|
||||||
OS << format("%08" PRIx64, Offset)
|
OS << format("%08" PRIx64, Offset)
|
||||||
<< format(" %0*" PRIx64, IsDWARF64 ? 16 : 8, Length)
|
<< format(" %0*" PRIx64, IsDWARF64 ? 16 : 8, Length)
|
||||||
<< format(" %0*" PRIx64, IsDWARF64 && !IsEH ? 16 : 8, CIEPointer)
|
<< format(" %0*" PRIx64, IsDWARF64 && !IsEH ? 16 : 8, CIEPointer)
|
||||||
@ -368,7 +372,7 @@ void FDE::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH) const {
|
|||||||
OS << " Format: " << FormatString(IsDWARF64) << "\n";
|
OS << " Format: " << FormatString(IsDWARF64) << "\n";
|
||||||
if (LSDAAddress)
|
if (LSDAAddress)
|
||||||
OS << format(" LSDA Address: %016" PRIx64 "\n", *LSDAAddress);
|
OS << format(" LSDA Address: %016" PRIx64 "\n", *LSDAAddress);
|
||||||
CFIs.dump(OS, MRI, IsEH);
|
CFIs.dump(OS, DumpOpts, MRI, IsEH);
|
||||||
OS << "\n";
|
OS << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -597,15 +601,16 @@ FrameEntry *DWARFDebugFrame::getEntryAtOffset(uint64_t Offset) const {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DWARFDebugFrame::dump(raw_ostream &OS, const MCRegisterInfo *MRI,
|
void DWARFDebugFrame::dump(raw_ostream &OS, DIDumpOptions DumpOpts,
|
||||||
|
const MCRegisterInfo *MRI,
|
||||||
Optional<uint64_t> Offset) const {
|
Optional<uint64_t> Offset) const {
|
||||||
if (Offset) {
|
if (Offset) {
|
||||||
if (auto *Entry = getEntryAtOffset(*Offset))
|
if (auto *Entry = getEntryAtOffset(*Offset))
|
||||||
Entry->dump(OS, MRI, IsEH);
|
Entry->dump(OS, DumpOpts, MRI, IsEH);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
OS << "\n";
|
OS << "\n";
|
||||||
for (const auto &Entry : Entries)
|
for (const auto &Entry : Entries)
|
||||||
Entry->dump(OS, MRI, IsEH);
|
Entry->dump(OS, DumpOpts, MRI, IsEH);
|
||||||
}
|
}
|
||||||
|
@ -106,15 +106,16 @@ DWARFLocationInterpreter::Interpret(const DWARFLocationEntry &E) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dumpExpression(raw_ostream &OS, ArrayRef<uint8_t> Data,
|
static void dumpExpression(raw_ostream &OS, DIDumpOptions DumpOpts,
|
||||||
bool IsLittleEndian, unsigned AddressSize,
|
ArrayRef<uint8_t> Data, bool IsLittleEndian,
|
||||||
const MCRegisterInfo *MRI, DWARFUnit *U) {
|
unsigned AddressSize, const MCRegisterInfo *MRI,
|
||||||
|
DWARFUnit *U) {
|
||||||
DWARFDataExtractor Extractor(Data, IsLittleEndian, AddressSize);
|
DWARFDataExtractor Extractor(Data, IsLittleEndian, AddressSize);
|
||||||
// Note. We do not pass any format to DWARFExpression, even if the
|
// Note. We do not pass any format to DWARFExpression, even if the
|
||||||
// corresponding unit is known. For now, there is only one operation,
|
// 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
|
// DW_OP_call_ref, which depends on the format; it is rarely used, and
|
||||||
// is unexpected in location tables.
|
// is unexpected in location tables.
|
||||||
DWARFExpression(Extractor, AddressSize).print(OS, MRI, U);
|
DWARFExpression(Extractor, AddressSize).print(OS, DumpOpts, MRI, U);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DWARFLocationTable::dumpLocationList(uint64_t *Offset, raw_ostream &OS,
|
bool DWARFLocationTable::dumpLocationList(uint64_t *Offset, raw_ostream &OS,
|
||||||
@ -154,8 +155,8 @@ bool DWARFLocationTable::dumpLocationList(uint64_t *Offset, raw_ostream &OS,
|
|||||||
E.Kind != dwarf::DW_LLE_base_addressx &&
|
E.Kind != dwarf::DW_LLE_base_addressx &&
|
||||||
E.Kind != dwarf::DW_LLE_end_of_list) {
|
E.Kind != dwarf::DW_LLE_end_of_list) {
|
||||||
OS << ": ";
|
OS << ": ";
|
||||||
dumpExpression(OS, E.Loc, Data.isLittleEndian(), Data.getAddressSize(),
|
dumpExpression(OS, DumpOpts, E.Loc, Data.isLittleEndian(),
|
||||||
MRI, U);
|
Data.getAddressSize(), MRI, U);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
@ -80,7 +80,7 @@ static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue,
|
|||||||
DataExtractor Data(StringRef((const char *)Expr.data(), Expr.size()),
|
DataExtractor Data(StringRef((const char *)Expr.data(), Expr.size()),
|
||||||
Ctx.isLittleEndian(), 0);
|
Ctx.isLittleEndian(), 0);
|
||||||
DWARFExpression(Data, U->getAddressByteSize(), U->getFormParams().Format)
|
DWARFExpression(Data, U->getAddressByteSize(), U->getFormParams().Format)
|
||||||
.print(OS, MRI, U);
|
.print(OS, DumpOpts, MRI, U);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,11 +204,15 @@ bool DWARFExpression::Operation::extract(DataExtractor Data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void prettyPrintBaseTypeRef(DWARFUnit *U, raw_ostream &OS,
|
static void prettyPrintBaseTypeRef(DWARFUnit *U, raw_ostream &OS,
|
||||||
uint64_t Operands[2], unsigned Operand) {
|
DIDumpOptions DumpOpts, uint64_t Operands[2],
|
||||||
|
unsigned Operand) {
|
||||||
assert(Operand < 2 && "operand out of bounds");
|
assert(Operand < 2 && "operand out of bounds");
|
||||||
auto Die = U->getDIEForOffset(U->getOffset() + Operands[Operand]);
|
auto Die = U->getDIEForOffset(U->getOffset() + Operands[Operand]);
|
||||||
if (Die && Die.getTag() == dwarf::DW_TAG_base_type) {
|
if (Die && Die.getTag() == dwarf::DW_TAG_base_type) {
|
||||||
OS << format(" (0x%08" PRIx64 ")", U->getOffset() + Operands[Operand]);
|
OS << " (";
|
||||||
|
if (DumpOpts.Verbose)
|
||||||
|
OS << format("0x%08" PRIx64 " -> ", Operands[Operand]);
|
||||||
|
OS << format("0x%08" PRIx64 ")", U->getOffset() + Operands[Operand]);
|
||||||
if (auto Name = Die.find(dwarf::DW_AT_name))
|
if (auto Name = Die.find(dwarf::DW_AT_name))
|
||||||
OS << " \"" << Name->getAsCString() << "\"";
|
OS << " \"" << Name->getAsCString() << "\"";
|
||||||
} else {
|
} else {
|
||||||
@ -217,7 +221,8 @@ static void prettyPrintBaseTypeRef(DWARFUnit *U, raw_ostream &OS,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS, uint8_t Opcode,
|
static bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS,
|
||||||
|
DIDumpOptions DumpOpts, uint8_t Opcode,
|
||||||
uint64_t Operands[2],
|
uint64_t Operands[2],
|
||||||
const MCRegisterInfo *MRI, bool isEH) {
|
const MCRegisterInfo *MRI, bool isEH) {
|
||||||
if (!MRI)
|
if (!MRI)
|
||||||
@ -243,7 +248,7 @@ static bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS, uint8_t Opcode,
|
|||||||
OS << ' ' << RegName;
|
OS << ' ' << RegName;
|
||||||
|
|
||||||
if (Opcode == DW_OP_regval_type)
|
if (Opcode == DW_OP_regval_type)
|
||||||
prettyPrintBaseTypeRef(U, OS, Operands, 1);
|
prettyPrintBaseTypeRef(U, OS, DumpOpts, Operands, 1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -251,11 +256,10 @@ static bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS, uint8_t Opcode,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DWARFExpression::Operation::print(raw_ostream &OS,
|
bool DWARFExpression::Operation::print(raw_ostream &OS, DIDumpOptions DumpOpts,
|
||||||
const DWARFExpression *Expr,
|
const DWARFExpression *Expr,
|
||||||
const MCRegisterInfo *RegInfo,
|
const MCRegisterInfo *RegInfo,
|
||||||
DWARFUnit *U,
|
DWARFUnit *U, bool isEH) {
|
||||||
bool isEH) {
|
|
||||||
if (Error) {
|
if (Error) {
|
||||||
OS << "<decoding error>";
|
OS << "<decoding error>";
|
||||||
return false;
|
return false;
|
||||||
@ -269,7 +273,7 @@ bool DWARFExpression::Operation::print(raw_ostream &OS,
|
|||||||
(Opcode >= DW_OP_reg0 && Opcode <= DW_OP_reg31) ||
|
(Opcode >= DW_OP_reg0 && Opcode <= DW_OP_reg31) ||
|
||||||
Opcode == DW_OP_bregx || Opcode == DW_OP_regx ||
|
Opcode == DW_OP_bregx || Opcode == DW_OP_regx ||
|
||||||
Opcode == DW_OP_regval_type)
|
Opcode == DW_OP_regval_type)
|
||||||
if (prettyPrintRegisterOp(U, OS, Opcode, Operands, RegInfo, isEH))
|
if (prettyPrintRegisterOp(U, OS, DumpOpts, Opcode, Operands, RegInfo, isEH))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
for (unsigned Operand = 0; Operand < 2; ++Operand) {
|
for (unsigned Operand = 0; Operand < 2; ++Operand) {
|
||||||
@ -286,7 +290,7 @@ bool DWARFExpression::Operation::print(raw_ostream &OS,
|
|||||||
if (Opcode == DW_OP_convert && Operands[Operand] == 0)
|
if (Opcode == DW_OP_convert && Operands[Operand] == 0)
|
||||||
OS << " 0x0";
|
OS << " 0x0";
|
||||||
else
|
else
|
||||||
prettyPrintBaseTypeRef(U, OS, Operands, Operand);
|
prettyPrintBaseTypeRef(U, OS, DumpOpts, Operands, Operand);
|
||||||
} else if (Size == Operation::WasmLocationArg) {
|
} else if (Size == Operation::WasmLocationArg) {
|
||||||
assert(Operand == 1);
|
assert(Operand == 1);
|
||||||
switch (Operands[0]) {
|
switch (Operands[0]) {
|
||||||
@ -311,11 +315,12 @@ bool DWARFExpression::Operation::print(raw_ostream &OS,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DWARFExpression::print(raw_ostream &OS, const MCRegisterInfo *RegInfo,
|
void DWARFExpression::print(raw_ostream &OS, DIDumpOptions DumpOpts,
|
||||||
DWARFUnit *U, bool IsEH) const {
|
const MCRegisterInfo *RegInfo, DWARFUnit *U,
|
||||||
|
bool IsEH) const {
|
||||||
uint32_t EntryValExprSize = 0;
|
uint32_t EntryValExprSize = 0;
|
||||||
for (auto &Op : *this) {
|
for (auto &Op : *this) {
|
||||||
if (!Op.print(OS, this, RegInfo, U, IsEH)) {
|
if (!Op.print(OS, DumpOpts, this, RegInfo, U, IsEH)) {
|
||||||
uint64_t FailOffset = Op.getEndOffset();
|
uint64_t FailOffset = Op.getEndOffset();
|
||||||
while (FailOffset < Data.getData().size())
|
while (FailOffset < Data.getData().size())
|
||||||
OS << format(" %02x", Data.getU8(&FailOffset));
|
OS << format(" %02x", Data.getU8(&FailOffset));
|
||||||
|
@ -23,31 +23,38 @@
|
|||||||
; RUN: llc -mtriple=x86_64-pc-linux-gnu -dwarf-version=5 -filetype=obj -O0 < %s -debugger-tune=lldb -dwarf-op-convert=Enable -split-dwarf-file=baz.dwo | llvm-dwarfdump - \
|
; RUN: llc -mtriple=x86_64-pc-linux-gnu -dwarf-version=5 -filetype=obj -O0 < %s -debugger-tune=lldb -dwarf-op-convert=Enable -split-dwarf-file=baz.dwo | llvm-dwarfdump - \
|
||||||
; RUN: | FileCheck %s --check-prefix=CONV --check-prefix=SPLITCONV --check-prefix=SPLIT "--implicit-check-not={{DW_TAG|NULL}}"
|
; RUN: | FileCheck %s --check-prefix=CONV --check-prefix=SPLITCONV --check-prefix=SPLIT "--implicit-check-not={{DW_TAG|NULL}}"
|
||||||
|
|
||||||
|
; RUN: %llc_dwarf -dwarf-version=5 -filetype=obj -O0 < %s -debugger-tune=gdb | llvm-dwarfdump -v -debug-info - \
|
||||||
|
; RUN: | FileCheck %s --check-prefix=VERBOSE --check-prefix=CONV "--implicit-check-not={{DW_TAG|NULL}}"
|
||||||
|
|
||||||
|
|
||||||
; SPLITCONV: Compile Unit:{{.*}} DWO_id = 0xe91d8d1d7f9782c0
|
; SPLITCONV: Compile Unit:{{.*}} DWO_id = 0xe91d8d1d7f9782c0
|
||||||
; SPLIT: DW_TAG_skeleton_unit
|
; SPLIT: DW_TAG_skeleton_unit
|
||||||
|
|
||||||
; CONV: DW_TAG_compile_unit
|
; CONV: DW_TAG_compile_unit
|
||||||
; CONV:[[SIG8:.*]]: DW_TAG_base_type
|
; CONV:[[SIG8:.*]]: DW_TAG_base_type
|
||||||
; CONV-NEXT:DW_AT_name ("DW_ATE_signed_8")
|
; CONV-NEXT:DW_AT_name {{.*}}"DW_ATE_signed_8")
|
||||||
; CONV-NEXT:DW_AT_encoding (DW_ATE_signed)
|
; CONV-NEXT:DW_AT_encoding {{.*}}DW_ATE_signed)
|
||||||
; CONV-NEXT:DW_AT_byte_size (0x01)
|
; CONV-NEXT:DW_AT_byte_size {{.*}}0x01)
|
||||||
; CONV-NOT: DW_AT
|
; CONV-NOT: DW_AT
|
||||||
; CONV:[[SIG32:.*]]: DW_TAG_base_type
|
; CONV:[[SIG32:.*]]: DW_TAG_base_type
|
||||||
; CONV-NEXT:DW_AT_name ("DW_ATE_signed_32")
|
; CONV-NEXT:DW_AT_name {{.*}}"DW_ATE_signed_32")
|
||||||
; CONV-NEXT:DW_AT_encoding (DW_ATE_signed)
|
; CONV-NEXT:DW_AT_encoding {{.*}}DW_ATE_signed)
|
||||||
; CONV-NEXT:DW_AT_byte_size (0x04)
|
; CONV-NEXT:DW_AT_byte_size {{.*}}0x04)
|
||||||
; CONV-NOT: DW_AT
|
; CONV-NOT: DW_AT
|
||||||
; CONV: DW_TAG_subprogram
|
; CONV: DW_TAG_subprogram
|
||||||
; CONV: DW_TAG_formal_parameter
|
; CONV: DW_TAG_formal_parameter
|
||||||
; CONV: DW_TAG_variable
|
; CONV: DW_TAG_variable
|
||||||
; CONV: DW_AT_location (
|
; CONV: DW_AT_location {{.*}}DW_OP_constu 0x20, DW_OP_convert (
|
||||||
; CONV: {{.*}}, DW_OP_convert ([[SIG8]]) "DW_ATE_signed_8", DW_OP_convert ([[SIG32]]) "DW_ATE_signed_32", DW_OP_stack_value)
|
; VERBOSE-SAME: [[SIG8]] ->
|
||||||
; CONV: DW_AT_name ("y")
|
; CONV-SAME: [[SIG8]]) "DW_ATE_signed_8", DW_OP_convert (
|
||||||
|
; VERBOSE-SAME: [[SIG32]] ->
|
||||||
|
; CONV-SAME: [[SIG32]]) "DW_ATE_signed_32", DW_OP_stack_value)
|
||||||
|
; CONV: DW_AT_name {{.*}}"y")
|
||||||
; CONV: NULL
|
; CONV: NULL
|
||||||
; CONV: DW_TAG_base_type
|
; CONV: DW_TAG_base_type
|
||||||
; CONV: DW_AT_name ("signed char")
|
; CONV: DW_AT_name {{.*}}"signed char")
|
||||||
; CONV: DW_TAG_base_type
|
; CONV: DW_TAG_base_type
|
||||||
; CONV: DW_AT_name ("int")
|
; CONV: DW_AT_name {{.*}}"int")
|
||||||
; CONV: NULL
|
; CONV: NULL
|
||||||
|
|
||||||
; NOCONV: DW_TAG_compile_unit
|
; NOCONV: DW_TAG_compile_unit
|
||||||
|
@ -225,7 +225,8 @@ void PrinterContext<ELFT>::printEHFrame(const Elf_Shdr *EHFrameShdr) const {
|
|||||||
W.getOStream() << "\n";
|
W.getOStream() << "\n";
|
||||||
W.startLine() << "Program:\n";
|
W.startLine() << "Program:\n";
|
||||||
W.indent();
|
W.indent();
|
||||||
Entry.cfis().dump(W.getOStream(), nullptr, W.getIndentLevel());
|
Entry.cfis().dump(W.getOStream(), DIDumpOptions(), nullptr,
|
||||||
|
W.getIndentLevel());
|
||||||
W.unindent();
|
W.unindent();
|
||||||
W.unindent();
|
W.unindent();
|
||||||
W.getOStream() << "\n";
|
W.getOStream() << "\n";
|
||||||
|
@ -39,7 +39,7 @@ void expectDumpResult(const dwarf::CIE &TestCIE, bool IsEH,
|
|||||||
StringRef ExpectedFirstLine) {
|
StringRef ExpectedFirstLine) {
|
||||||
std::string Output;
|
std::string Output;
|
||||||
raw_string_ostream OS(Output);
|
raw_string_ostream OS(Output);
|
||||||
TestCIE.dump(OS, /*MRI=*/nullptr, IsEH);
|
TestCIE.dump(OS, DIDumpOptions(), /*MRI=*/nullptr, IsEH);
|
||||||
OS.flush();
|
OS.flush();
|
||||||
StringRef FirstLine = StringRef(Output).split('\n').first;
|
StringRef FirstLine = StringRef(Output).split('\n').first;
|
||||||
EXPECT_EQ(FirstLine, ExpectedFirstLine);
|
EXPECT_EQ(FirstLine, ExpectedFirstLine);
|
||||||
@ -49,7 +49,7 @@ void expectDumpResult(const dwarf::FDE &TestFDE, bool IsEH,
|
|||||||
StringRef ExpectedFirstLine) {
|
StringRef ExpectedFirstLine) {
|
||||||
std::string Output;
|
std::string Output;
|
||||||
raw_string_ostream OS(Output);
|
raw_string_ostream OS(Output);
|
||||||
TestFDE.dump(OS, /*MRI=*/nullptr, IsEH);
|
TestFDE.dump(OS, DIDumpOptions(), /*MRI=*/nullptr, IsEH);
|
||||||
OS.flush();
|
OS.flush();
|
||||||
StringRef FirstLine = StringRef(Output).split('\n').first;
|
StringRef FirstLine = StringRef(Output).split('\n').first;
|
||||||
EXPECT_EQ(FirstLine, ExpectedFirstLine);
|
EXPECT_EQ(FirstLine, ExpectedFirstLine);
|
||||||
|
Loading…
Reference in New Issue
Block a user