aboutsummaryrefslogtreecommitdiff
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/DWARFExpressionPrinter.cpp163
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp22
2 files changed, 118 insertions, 67 deletions
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFExpressionPrinter.cpp b/llvm/lib/DebugInfo/DWARF/DWARFExpressionPrinter.cpp
index ebcd4dd..078ebf4 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFExpressionPrinter.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFExpressionPrinter.cpp
@@ -48,13 +48,52 @@ static bool printOp(const DWARFExpression::Operation *Op, raw_ostream &OS,
DIDumpOptions DumpOpts, const DWARFExpression *Expr,
DWARFUnit *U) {
if (Op->isError()) {
- OS << "<decoding error>";
+ if (!DumpOpts.PrintRegisterOnly)
+ OS << "<decoding error>";
return false;
}
- StringRef Name = OperationEncodingString(Op->getCode());
- assert(!Name.empty() && "DW_OP has no name!");
- OS << Name;
+ // In "register-only" mode, still show simple constant-valued locations.
+ // This lets clients print annotations like "i = 0" when the location is
+ // a constant (e.g. DW_OP_constu/consts ... DW_OP_stack_value).
+ // We continue to suppress all other non-register ops in this mode.
+ if (DumpOpts.PrintRegisterOnly) {
+ // First, try pretty-printing registers (existing behavior below also does
+ // this, but we need to short-circuit here to avoid printing opcode names).
+ if ((Op->getCode() >= DW_OP_breg0 && Op->getCode() <= DW_OP_breg31) ||
+ (Op->getCode() >= DW_OP_reg0 && Op->getCode() <= DW_OP_reg31) ||
+ Op->getCode() == DW_OP_bregx || Op->getCode() == DW_OP_regx ||
+ Op->getCode() == DW_OP_regval_type) {
+ if (prettyPrintRegisterOp(U, OS, DumpOpts, Op->getCode(),
+ Op->getRawOperands()))
+ return true;
+ // If we couldn't pretty-print, fall through and suppress.
+ }
+
+ // Show constants (decimal), suppress everything else.
+ if (Op->getCode() == DW_OP_constu) {
+ OS << (uint64_t)Op->getRawOperand(0);
+ return true;
+ }
+ if (Op->getCode() == DW_OP_consts) {
+ OS << (int64_t)Op->getRawOperand(0);
+ return true;
+ }
+ if (Op->getCode() >= DW_OP_lit0 && Op->getCode() <= DW_OP_lit31) {
+ OS << (unsigned)(Op->getCode() - DW_OP_lit0);
+ return true;
+ }
+ if (Op->getCode() == DW_OP_stack_value)
+ return true; // metadata; don't print a token
+
+ return true; // suppress other opcodes silently in register-only mode
+ }
+
+ if (!DumpOpts.PrintRegisterOnly) {
+ StringRef Name = OperationEncodingString(Op->getCode());
+ assert(!Name.empty() && "DW_OP has no name!");
+ OS << Name;
+ }
if ((Op->getCode() >= DW_OP_breg0 && Op->getCode() <= DW_OP_breg31) ||
(Op->getCode() >= DW_OP_reg0 && Op->getCode() <= DW_OP_reg31) ||
@@ -64,48 +103,51 @@ static bool printOp(const DWARFExpression::Operation *Op, raw_ostream &OS,
Op->getRawOperands()))
return true;
- for (unsigned Operand = 0; Operand < Op->getDescription().Op.size();
- ++Operand) {
- unsigned Size = Op->getDescription().Op[Operand];
- unsigned Signed = Size & DWARFExpression::Operation::SignBit;
-
- if (Size == DWARFExpression::Operation::SizeSubOpLEB) {
- StringRef SubName =
- SubOperationEncodingString(Op->getCode(), Op->getRawOperand(Operand));
- assert(!SubName.empty() && "DW_OP SubOp has no name!");
- OS << " " << SubName;
- } else if (Size == DWARFExpression::Operation::BaseTypeRef && U) {
- // For DW_OP_convert the operand may be 0 to indicate that conversion to
- // the generic type should be done. The same holds for DW_OP_reinterpret,
- // which is currently not supported.
- if (Op->getCode() == DW_OP_convert && Op->getRawOperand(Operand) == 0)
- OS << " 0x0";
- else
- prettyPrintBaseTypeRef(U, OS, DumpOpts, Op->getRawOperands(), Operand);
- } else if (Size == DWARFExpression::Operation::WasmLocationArg) {
- assert(Operand == 1);
- switch (Op->getRawOperand(0)) {
- case 0:
- case 1:
- case 2:
- case 3: // global as uint32
- case 4:
- OS << format(" 0x%" PRIx64, Op->getRawOperand(Operand));
- break;
- default:
- assert(false);
+ if (!DumpOpts.PrintRegisterOnly) {
+ for (unsigned Operand = 0; Operand < Op->getDescription().Op.size();
+ ++Operand) {
+ unsigned Size = Op->getDescription().Op[Operand];
+ unsigned Signed = Size & DWARFExpression::Operation::SignBit;
+
+ if (Size == DWARFExpression::Operation::SizeSubOpLEB) {
+ StringRef SubName = SubOperationEncodingString(
+ Op->getCode(), Op->getRawOperand(Operand));
+ assert(!SubName.empty() && "DW_OP SubOp has no name!");
+ OS << " " << SubName;
+ } else if (Size == DWARFExpression::Operation::BaseTypeRef && U) {
+ // For DW_OP_convert the operand may be 0 to indicate that conversion to
+ // the generic type should be done. The same holds for
+ // DW_OP_reinterpret, which is currently not supported.
+ if (Op->getCode() == DW_OP_convert && Op->getRawOperand(Operand) == 0)
+ OS << " 0x0";
+ else
+ prettyPrintBaseTypeRef(U, OS, DumpOpts, Op->getRawOperands(),
+ Operand);
+ } else if (Size == DWARFExpression::Operation::WasmLocationArg) {
+ assert(Operand == 1);
+ switch (Op->getRawOperand(0)) {
+ case 0:
+ case 1:
+ case 2:
+ case 3: // global as uint32
+ case 4:
+ OS << format(" 0x%" PRIx64, Op->getRawOperand(Operand));
+ break;
+ default:
+ assert(false);
+ }
+ } else if (Size == DWARFExpression::Operation::SizeBlock) {
+ uint64_t Offset = Op->getRawOperand(Operand);
+ for (unsigned i = 0; i < Op->getRawOperand(Operand - 1); ++i)
+ OS << format(" 0x%02x",
+ static_cast<uint8_t>(Expr->getData()[Offset++]));
+ } else {
+ if (Signed)
+ OS << format(" %+" PRId64, (int64_t)Op->getRawOperand(Operand));
+ else if (Op->getCode() != DW_OP_entry_value &&
+ Op->getCode() != DW_OP_GNU_entry_value)
+ OS << format(" 0x%" PRIx64, Op->getRawOperand(Operand));
}
- } else if (Size == DWARFExpression::Operation::SizeBlock) {
- uint64_t Offset = Op->getRawOperand(Operand);
- for (unsigned i = 0; i < Op->getRawOperand(Operand - 1); ++i)
- OS << format(" 0x%02x",
- static_cast<uint8_t>(Expr->getData()[Offset++]));
- } else {
- if (Signed)
- OS << format(" %+" PRId64, (int64_t)Op->getRawOperand(Operand));
- else if (Op->getCode() != DW_OP_entry_value &&
- Op->getCode() != DW_OP_GNU_entry_value)
- OS << format(" 0x%" PRIx64, Op->getRawOperand(Operand));
}
}
return true;
@@ -120,29 +162,30 @@ void printDwarfExpression(const DWARFExpression *E, raw_ostream &OS,
for (auto &Op : *E) {
DumpOpts.IsEH = IsEH;
- if (!printOp(&Op, OS, DumpOpts, E, U)) {
+ if (!printOp(&Op, OS, DumpOpts, E, U) && !DumpOpts.PrintRegisterOnly) {
uint64_t FailOffset = Op.getEndOffset();
while (FailOffset < E->getData().size())
OS << format(" %02x", static_cast<uint8_t>(E->getData()[FailOffset++]));
return;
}
+ if (!DumpOpts.PrintRegisterOnly) {
+ if (Op.getCode() == DW_OP_entry_value ||
+ Op.getCode() == DW_OP_GNU_entry_value) {
+ OS << "(";
+ EntryValExprSize = Op.getRawOperand(0);
+ EntryValStartOffset = Op.getEndOffset();
+ continue;
+ }
- if (Op.getCode() == DW_OP_entry_value ||
- Op.getCode() == DW_OP_GNU_entry_value) {
- OS << "(";
- EntryValExprSize = Op.getRawOperand(0);
- EntryValStartOffset = Op.getEndOffset();
- continue;
- }
+ if (EntryValExprSize) {
+ EntryValExprSize -= Op.getEndOffset() - EntryValStartOffset;
+ if (EntryValExprSize == 0)
+ OS << ")";
+ }
- if (EntryValExprSize) {
- EntryValExprSize -= Op.getEndOffset() - EntryValStartOffset;
- if (EntryValExprSize == 0)
- OS << ")";
+ if (Op.getEndOffset() < E->getData().size())
+ OS << ", ";
}
-
- if (Op.getEndOffset() < E->getData().size())
- OS << ", ";
}
}
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp b/llvm/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp
index 987e639..a201fae 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp
@@ -60,6 +60,20 @@ void DWARFGdbIndex::dumpSymbolTable(raw_ostream &OS) const {
", filled slots:",
SymbolTableOffset, (uint64_t)SymbolTable.size())
<< '\n';
+
+ const auto FindCuVectorId = [&](uint32_t VecOffset) {
+ // Entries in ConstantPoolVectors are sorted by their offset in constant
+ // pool, see how ConstantPoolVectors is populated in parseImpl.
+ const auto *It =
+ llvm::lower_bound(ConstantPoolVectors, VecOffset,
+ [](const auto &ConstantPoolEntry, uint32_t Offset) {
+ return ConstantPoolEntry.first < Offset;
+ });
+ assert(It != ConstantPoolVectors.end() && It->first == VecOffset &&
+ "Invalid symbol table");
+ return It - ConstantPoolVectors.begin();
+ };
+
uint32_t I = -1;
for (const SymTableEntry &E : SymbolTable) {
++I;
@@ -72,13 +86,7 @@ void DWARFGdbIndex::dumpSymbolTable(raw_ostream &OS) const {
StringRef Name = ConstantPoolStrings.substr(
ConstantPoolOffset - StringPoolOffset + E.NameOffset);
- auto CuVector = llvm::find_if(
- ConstantPoolVectors,
- [&](const std::pair<uint32_t, SmallVector<uint32_t, 0>> &V) {
- return V.first == E.VecOffset;
- });
- assert(CuVector != ConstantPoolVectors.end() && "Invalid symbol table");
- uint32_t CuVectorId = CuVector - ConstantPoolVectors.begin();
+ const uint32_t CuVectorId = FindCuVectorId(E.VecOffset);
OS << format(" String name: %s, CU vector index: %d\n", Name.data(),
CuVectorId);
}