diff options
Diffstat (limited to 'llvm/lib/DebugInfo')
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp | 11 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFDie.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp | 52 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp | 2 |
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()) { |