summaryrefslogtreecommitdiffstats
path: root/llvm/lib/DebugInfo/DWARF
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/DebugInfo/DWARF')
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp2
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp11
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDie.cpp6
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp52
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp2
5 files changed, 60 insertions, 13 deletions
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
index 154e466e911..c112d2be12a 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
@@ -266,7 +266,7 @@ void CFIProgram::printOperand(raw_ostream &OS, const MCRegisterInfo *MRI,
case OT_Expression:
assert(Instr.Expression && "missing DWARFExpression object");
OS << " ";
- Instr.Expression->print(OS, MRI, IsEH);
+ Instr.Expression->print(OS, MRI, nullptr, IsEH);
break;
}
}
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
index 54e0e8e18fa..366b4df6657 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
@@ -30,15 +30,16 @@ using namespace llvm;
// non-LLVM tools.
static void dumpExpression(raw_ostream &OS, ArrayRef<char> Data,
bool IsLittleEndian, unsigned AddressSize,
- const MCRegisterInfo *MRI) {
+ const MCRegisterInfo *MRI, DWARFUnit *U) {
DWARFDataExtractor Extractor(StringRef(Data.data(), Data.size()),
IsLittleEndian, AddressSize);
- DWARFExpression(Extractor, dwarf::DWARF_VERSION, AddressSize).print(OS, MRI);
+ DWARFExpression(Extractor, dwarf::DWARF_VERSION, AddressSize).print(OS, MRI, U);
}
void DWARFDebugLoc::LocationList::dump(raw_ostream &OS, bool IsLittleEndian,
unsigned AddressSize,
const MCRegisterInfo *MRI,
+ DWARFUnit *U,
uint64_t BaseAddress,
unsigned Indent) const {
for (const Entry &E : Entries) {
@@ -50,7 +51,7 @@ void DWARFDebugLoc::LocationList::dump(raw_ostream &OS, bool IsLittleEndian,
BaseAddress + E.End);
OS << ": ";
- dumpExpression(OS, E.Loc, IsLittleEndian, AddressSize, MRI);
+ dumpExpression(OS, E.Loc, IsLittleEndian, AddressSize, MRI, U);
}
}
@@ -68,7 +69,7 @@ void DWARFDebugLoc::dump(raw_ostream &OS, const MCRegisterInfo *MRI,
Optional<uint64_t> Offset) const {
auto DumpLocationList = [&](const LocationList &L) {
OS << format("0x%8.8x: ", L.Offset);
- L.dump(OS, IsLittleEndian, AddressSize, MRI, 0, 12);
+ L.dump(OS, IsLittleEndian, AddressSize, MRI, nullptr, 0, 12);
OS << "\n\n";
};
@@ -253,7 +254,7 @@ void DWARFDebugLoclists::LocationList::dump(raw_ostream &OS, uint64_t BaseAddr,
llvm_unreachable("unreachable locations list kind");
}
- dumpExpression(OS, E.Loc, IsLittleEndian, AddressSize, MRI);
+ dumpExpression(OS, E.Loc, IsLittleEndian, AddressSize, MRI, nullptr);
}
}
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
index b1aa77d1f23..e8887780767 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
@@ -86,7 +86,7 @@ static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue,
DataExtractor Data(StringRef((const char *)Expr.data(), Expr.size()),
Ctx.isLittleEndian(), 0);
DWARFExpression(Data, U->getVersion(), U->getAddressByteSize())
- .print(OS, MRI);
+ .print(OS, MRI, U);
return;
}
@@ -102,8 +102,8 @@ static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue,
uint64_t BaseAddr = 0;
if (Optional<SectionedAddress> BA = U->getBaseAddress())
BaseAddr = BA->Address;
- LL->dump(OS, Ctx.isLittleEndian(), Obj.getAddressSize(), MRI, BaseAddr,
- Indent);
+ LL->dump(OS, Ctx.isLittleEndian(), Obj.getAddressSize(), MRI, U,
+ BaseAddr, Indent);
} else
OS << "error extracting location list.";
return;
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp b/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp
index 920fa183e45..24400ff89c6 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Support/Format.h"
@@ -96,6 +97,9 @@ static DescVector getDescriptions() {
Descriptions[DW_OP_addrx] = Desc(Op::Dwarf4, Op::SizeLEB);
Descriptions[DW_OP_GNU_addr_index] = Desc(Op::Dwarf4, Op::SizeLEB);
Descriptions[DW_OP_GNU_const_index] = Desc(Op::Dwarf4, Op::SizeLEB);
+
+ Descriptions[DW_OP_convert] = Desc(Op::Dwarf5, Op::BaseTypeRef);
+
return Descriptions;
}
@@ -170,6 +174,9 @@ bool DWARFExpression::Operation::extract(DataExtractor Data, uint16_t Version,
else
Operands[Operand] = Data.getULEB128(&Offset);
break;
+ case Operation::BaseTypeRef:
+ Operands[Operand] = Data.getULEB128(&Offset);
+ break;
case Operation::SizeBlock:
// We need a size, so this cannot be the first operand
if (Operand == 0)
@@ -221,6 +228,7 @@ static bool prettyPrintRegisterOp(raw_ostream &OS, uint8_t Opcode,
bool DWARFExpression::Operation::print(raw_ostream &OS,
const DWARFExpression *Expr,
const MCRegisterInfo *RegInfo,
+ DWARFUnit *U,
bool isEH) {
if (Error) {
OS << "<decoding error>";
@@ -244,7 +252,17 @@ bool DWARFExpression::Operation::print(raw_ostream &OS,
if (Size == Operation::SizeNA)
break;
- if (Size == Operation::SizeBlock) {
+ if (Size == Operation::BaseTypeRef && U) {
+ auto Die = U->getDIEForOffset(U->getOffset() + Operands[Operand]);
+ if (Die && Die.getTag() == dwarf::DW_TAG_base_type) {
+ OS << format(" (0x%08x)", U->getOffset() + Operands[Operand]);
+ if (auto Name = Die.find(dwarf::DW_AT_name))
+ OS << " \"" << Name->getAsCString() << "\"";
+ } else {
+ OS << format(" <invalid base_type ref: 0x%" PRIx64 ">",
+ Operands[Operand]);
+ }
+ } else if (Size == Operation::SizeBlock) {
uint32_t Offset = Operands[Operand];
for (unsigned i = 0; i < Operands[Operand - 1]; ++i)
OS << format(" 0x%02x", Expr->Data.getU8(&Offset));
@@ -259,9 +277,9 @@ bool DWARFExpression::Operation::print(raw_ostream &OS,
}
void DWARFExpression::print(raw_ostream &OS, const MCRegisterInfo *RegInfo,
- bool IsEH) const {
+ DWARFUnit *U, bool IsEH) const {
for (auto &Op : *this) {
- if (!Op.print(OS, this, RegInfo, IsEH)) {
+ if (!Op.print(OS, this, RegInfo, U, IsEH)) {
uint32_t FailOffset = Op.getEndOffset();
while (FailOffset < Data.getData().size())
OS << format(" %02x", Data.getU8(&FailOffset));
@@ -272,4 +290,32 @@ void DWARFExpression::print(raw_ostream &OS, const MCRegisterInfo *RegInfo,
}
}
+bool DWARFExpression::Operation::verify(DWARFUnit *U) {
+
+ for (unsigned Operand = 0; Operand < 2; ++Operand) {
+ unsigned Size = Desc.Op[Operand];
+
+ if (Size == Operation::SizeNA)
+ break;
+
+ if (Size == Operation::BaseTypeRef) {
+ auto Die = U->getDIEForOffset(U->getOffset() + Operands[Operand]);
+ if (!Die || Die.getTag() != dwarf::DW_TAG_base_type) {
+ Error = true;
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+bool DWARFExpression::verify(DWARFUnit *U) {
+ for (auto &Op : *this)
+ if (!Op.verify(U))
+ return false;
+
+ return true;
+}
+
} // namespace llvm
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
index 0eef0f6a82b..2447708465a 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
@@ -502,7 +502,7 @@ unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die,
bool Error = llvm::any_of(Expression, [](DWARFExpression::Operation &Op) {
return Op.isError();
});
- if (Error)
+ if (Error || !Expression.verify(U))
ReportError("DIE contains invalid DWARF expression:");
};
if (Optional<ArrayRef<uint8_t>> Expr = AttrValue.Value.getAsBlock()) {
OpenPOWER on IntegriCloud