uint64_t DumpType = DIDT_All;
bool DumpEH = false;
bool SummarizeTypes = false;
- bool Brief = false;
+ bool Verbose = false;
};
class DIContext {
virtual void dump(raw_ostream &OS, DIDumpOptions DumpOpts) = 0;
- virtual bool verify(raw_ostream &OS, uint64_t DumpType = DIDT_All) {
+ virtual bool verify(raw_ostream &OS, uint64_t DumpType = DIDT_All,
+ DIDumpOptions DumpOpts = {}) {
// No verifier? Just say things went well.
return true;
}
void dump(raw_ostream &OS, DIDumpOptions DumpOpts) override;
- bool verify(raw_ostream &OS, uint64_t DumpType = DIDT_All) override;
+ bool verify(raw_ostream &OS, uint64_t DumpType = DIDT_All,
+ DIDumpOptions DumpOpts = {}) override;
using cu_iterator_range = DWARFUnitSection<DWARFCompileUnit>::iterator_range;
using tu_iterator_range = DWARFUnitSection<DWARFTypeUnit>::iterator_range;
return DWARFUnit::getHeaderSize() + 12;
}
- void dump(raw_ostream &OS, bool Brief = false);
+ void dump(raw_ostream &OS, DIDumpOptions DumpOpts = {});
static const DWARFSectionKind Section = DW_SECT_TYPES;
protected:
#ifndef LLVM_DEBUGINFO_DWARF_DWARFVERIFIER_H
#define LLVM_DEBUGINFO_DWARF_DWARFVERIFIER_H
+#include "llvm/DebugInfo/DIContext.h"
+
#include <cstdint>
#include <map>
#include <set>
class DWARFVerifier {
raw_ostream &OS;
DWARFContext &DCtx;
+ DIDumpOptions DumpOpts;
/// A map that tracks all references (converted absolute references) so we
/// can verify each reference points to a valid DIE and not an offset that
/// lies between to valid DIEs.
DataExtractor *StrData, const char *SectionName);
public:
- DWARFVerifier(raw_ostream &S, DWARFContext &D)
- : OS(S), DCtx(D) {}
+ DWARFVerifier(raw_ostream &S, DWARFContext &D, DIDumpOptions DumpOpts = {})
+ : OS(S), DCtx(D), DumpOpts(std::move(DumpOpts)) {}
/// Verify the information in any of the following sections, if available:
/// .debug_abbrev, debug_abbrev.dwo
///
void DWARFContext::dump(raw_ostream &OS, DIDumpOptions DumpOpts) {
uint64_t DumpType = DumpOpts.DumpType;
bool DumpEH = DumpOpts.DumpEH;
- bool SummarizeTypes = DumpOpts.SummarizeTypes;
if (DumpType & DIDT_DebugAbbrev) {
OS << ".debug_abbrev contents:\n";
OS << "\n.debug_types contents:\n";
for (const auto &TUS : type_unit_sections())
for (const auto &TU : TUS)
- TU->dump(OS, SummarizeTypes);
+ TU->dump(OS, DumpOpts);
}
if ((DumpType & DIDT_DebugTypesDwo) &&
OS << "\n.debug_types.dwo contents:\n";
for (const auto &DWOTUS : dwo_type_unit_sections())
for (const auto &DWOTU : DWOTUS)
- DWOTU->dump(OS, SummarizeTypes);
+ DWOTU->dump(OS, DumpOpts);
}
if (DumpType & DIDT_DebugLoc) {
return DWARFDie();
}
-bool DWARFContext::verify(raw_ostream &OS, uint64_t DumpType) {
+bool DWARFContext::verify(raw_ostream &OS, uint64_t DumpType,
+ DIDumpOptions DumpOpts) {
bool Success = true;
- DWARFVerifier verifier(OS, *this);
+ DWARFVerifier verifier(OS, *this, DumpOpts);
Success &= verifier.handleDebugAbbrev();
if (DumpType & DIDT_DebugInfo)
// Make sure the offset is good before we try to parse.
if (stmtOffset >= U->getLineSection().Data.size())
- return nullptr;
+ return nullptr;
// We have to parse it first.
DWARFDataExtractor lineData(*DObj, U->getLineSection(), isLittleEndian(),
unsigned AddressSize, unsigned Indent,
const DIDumpOptions &DumpOpts) {
ArrayRef<SectionName> SectionNames;
- if (!DumpOpts.Brief)
+ if (DumpOpts.Verbose)
SectionNames = Obj.getSectionNames();
for (size_t I = 0; I < Ranges.size(); ++I) {
}
static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue,
- DWARFUnit *U, unsigned Indent) {
+ DWARFUnit *U, unsigned Indent,
+ DIDumpOptions DumpOpts) {
DWARFContext &Ctx = U->getContext();
const DWARFObject &Obj = Ctx.getDWARFObj();
const MCRegisterInfo *MRI = Ctx.getRegisterInfo();
return;
}
- FormValue.dump(OS);
+ FormValue.dump(OS, DumpOpts);
if (FormValue.isFormClass(DWARFFormValue::FC_SectionOffset)) {
const DWARFSection &LocSection = Obj.getLocSection();
const DWARFSection &LocDWOSection = Obj.getLocDWOSection();
else
WithColor(OS, syntax::Attribute).get() << format("DW_AT_Unknown_%x", Attr);
- if (!DumpOpts.Brief) {
+ if (DumpOpts.Verbose) {
auto formString = FormEncodingString(Form);
if (!formString.empty())
OS << " [" << formString << ']';
OS << *formValue.getAsUnsignedConstant();
else if (Attr == DW_AT_location || Attr == DW_AT_frame_base ||
Attr == DW_AT_data_member_location)
- dumpLocation(OS, formValue, U, sizeof(BaseIndent) + Indent + 4);
+ dumpLocation(OS, formValue, U, sizeof(BaseIndent) + Indent + 4, DumpOpts);
else
formValue.dump(OS, DumpOpts);
WithColor(OS, syntax::Tag).get().indent(Indent)
<< format("DW_TAG_Unknown_%x", getTag());
- if (!DumpOpts.Brief)
+ if (DumpOpts.Verbose)
OS << format(" [%u] %c", abbrCode,
AbbrevDecl->hasChildren() ? '*' : ' ');
OS << '\n';
OS << Value.uval;
break;
case DW_FORM_strp:
- if (!DumpOpts.Brief)
+ if (DumpOpts.Verbose)
OS << format(" .debug_str[0x%8.8x] = ", (uint32_t)UValue);
dumpString(OS);
break;
break;
}
- if (CURelativeOffset && !DumpOpts.Brief) {
+ if (CURelativeOffset && DumpOpts.Verbose) {
OS << " => {";
WithColor(OS, syntax::Address).get()
<< format("0x%8.8" PRIx64, UValue + (U ? U->getOffset() : 0));
return TypeOffset < getLength() + SizeOfLength;
}
-void DWARFTypeUnit::dump(raw_ostream &OS, bool SummarizeTypes) {
+void DWARFTypeUnit::dump(raw_ostream &OS, DIDumpOptions DumpOpts) {
DWARFDie TD = getDIEForOffset(TypeOffset + getOffset());
const char *Name = TD.getName(DINameKind::ShortName);
- if (SummarizeTypes) {
+ if (DumpOpts.SummarizeTypes) {
OS << "name = '" << Name << "'"
<< " type_signature = " << format("0x%016" PRIx64, TypeHash)
<< " length = " << format("0x%08x", getLength()) << '\n';
<< " (next unit at " << format("0x%08x", getNextUnitOffset()) << ")\n";
if (DWARFDie TU = getUnitDIE(false))
- TU.dump(OS, -1U);
+ TU.dump(OS, -1U, 0, DumpOpts);
else
OS << "<type unit can't be parsed!>\n\n";
}
++NumErrors;
OS << "error: DW_AT_ranges offset is beyond .debug_ranges "
"bounds:\n";
- Die.dump(OS, 0);
+ Die.dump(OS, 0, 0, DumpOpts);
OS << "\n";
}
} else {
++NumErrors;
OS << "error: DIE has invalid DW_AT_ranges encoding:\n";
- Die.dump(OS, 0);
+ Die.dump(OS, 0, 0, DumpOpts);
OS << "\n";
}
break;
OS << "error: DW_AT_stmt_list offset is beyond .debug_line "
"bounds: "
<< format("0x%08" PRIx64, *SectionOffset) << "\n";
- Die.dump(OS, 0);
+ Die.dump(OS, 0, 0, DumpOpts);
OS << "\n";
}
} else {
++NumErrors;
OS << "error: DIE has invalid DW_AT_stmt_list encoding:\n";
- Die.dump(OS, 0);
+ Die.dump(OS, 0, 0, DumpOpts);
OS << "\n";
}
break;
<< format("0x%08" PRIx64, CUOffset)
<< " is invalid (must be less than CU size of "
<< format("0x%08" PRIx32, CUSize) << "):\n";
- Die.dump(OS, 0);
+ Die.dump(OS, 0, 0, DumpOpts);
OS << "\n";
} else {
// Valid reference, but we will verify it points to an actual
++NumErrors;
OS << "error: DW_FORM_ref_addr offset beyond .debug_info "
"bounds:\n";
- Die.dump(OS, 0);
+ Die.dump(OS, 0, 0, DumpOpts);
OS << "\n";
} else {
// Valid reference, but we will verify it points to an actual
if (SecOffset && *SecOffset >= DObj.getStringSection().size()) {
++NumErrors;
OS << "error: DW_FORM_strp offset beyond .debug_str bounds:\n";
- Die.dump(OS, 0);
+ Die.dump(OS, 0, 0, DumpOpts);
OS << "\n";
}
break;
<< ". Offset is in between DIEs:\n";
for (auto Offset : Pair.second) {
auto ReferencingDie = DCtx.getDIEForOffset(Offset);
- ReferencingDie.dump(OS, 0);
+ ReferencingDie.dump(OS, 0, 0, DumpOpts);
OS << "\n";
}
OS << "\n";
++NumDebugLineErrors;
OS << "error: .debug_line[" << format("0x%08" PRIx32, LineTableOffset)
<< "] was not able to be parsed for CU:\n";
- Die.dump(OS, 0);
+ Die.dump(OS, 0, 0, DumpOpts);
OS << '\n';
continue;
}
<< format("0x%08" PRIx32, Iter->second.getOffset()) << " and "
<< format("0x%08" PRIx32, Die.getOffset())
<< ", have the same DW_AT_stmt_list section offset:\n";
- Iter->second.dump(OS, 0);
- Die.dump(OS, 0);
+ Iter->second.dump(OS, 0, 0, DumpOpts);
+ Die.dump(OS, 0, 0, DumpOpts);
OS << '\n';
// Already verified this line table before, no need to do it again.
continue;
# RUN: llvm-mc %s -filetype obj -triple x86_64-apple-darwin -o - \
-# RUN: | not llvm-dwarfdump -verify - \
+# RUN: | not llvm-dwarfdump -v -verify - \
# RUN: | FileCheck %s
# CHECK: error: DIE has invalid DW_AT_stmt_list encoding:{{[[:space:]]}}
# CHECK-NEXT: DW_AT_comp_dir [DW_FORM_strp] ( .debug_str[0x0000003f] = "/Users/sgravani/Development/tests")
# CHECK-NEXT: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000000)
# CHECK-NEXT: DW_AT_high_pc [DW_FORM_data4] (0x00000016){{[[:space:]]}}
-# CHECK-NEXT: Units[2] - start offset: 0x00000068
+# CHECK-NEXT: Units[2] - start offset: 0x00000068
# CHECK-NEXT: Error: The length for this unit is too large for the .debug_info provided.
# CHECK-NEXT: Error: The unit type encoding is not valid.
.byte 1 ## DWARF Unit Type
.byte 4 ## Address Size (in bytes)
.long 0 ## Abbrev offset
- .byte 0
+ .byte 0
Ltu_begin0:
.long 26 ## Length of Unit -- Error: The length for this unit is too large for the .debug_info provided.
.short 5 ## DWARF version number
.long 0
.quad 0
.long 0
- .byte 0
+ .byte 0
.subsections_via_symbols
.section __DWARF,__debug_line,regular,debug
if (!Options.Verbose || !DIE)
return;
+ DIDumpOptions DumpOpts;
+ DumpOpts.Verbose = Options.Verbose;
+
errs() << " in DIE:\n";
- DIE->dump(errs(), 0 /* RecurseDepth */, 6 /* Indent */);
+ DIE->dump(errs(), 0 /* RecurseDepth */, 6 /* Indent */, DumpOpts);
}
bool DwarfLinker::createStreamer(const Triple &TheTriple,
(Flags & TF_InFunctionScope))
return Flags;
- if (Options.Verbose)
- DIE.dump(outs(), 0, 8 /* Indent */);
+ if (Options.Verbose) {
+ DIDumpOptions DumpOpts;
+ DumpOpts.Verbose = Options.Verbose;
+ DIE.dump(outs(), 0, 8 /* Indent */, DumpOpts);
+ }
return Flags | TF_Keep;
}
!RelocMgr.hasValidRelocation(LowPcOffset, LowPcEndOffset, MyInfo))
return Flags;
- if (Options.Verbose)
- DIE.dump(outs(), 0, 8 /* Indent */);
+ if (Options.Verbose) {
+ DIDumpOptions DumpOpts;
+ DumpOpts.Verbose = Options.Verbose;
+ DIE.dump(outs(), 0, 8 /* Indent */, DumpOpts);
+ }
Flags |= TF_Keep;
auto CUDie = CU->getUnitDIE(false);
if (Options.Verbose) {
outs() << "Input compilation unit:";
- CUDie.dump(outs(), 0);
+ DIDumpOptions DumpOpts;
+ DumpOpts.Verbose = Options.Verbose;
+ CUDie.dump(outs(), 0, 0, DumpOpts);
}
if (!registerModuleReference(CUDie, *CU, ModuleMap)) {
exit(1);
}
+static DIDumpOptions GetDumpOpts() {
+ DIDumpOptions DumpOpts;
+ DumpOpts.DumpType = DumpType;
+ DumpOpts.SummarizeTypes = SummarizeTypes;
+ DumpOpts.Verbose = Verbose;
+ return DumpOpts;
+}
+
static void DumpObjectFile(ObjectFile &Obj, Twine Filename) {
std::unique_ptr<DWARFContext> DICtx = DWARFContext::create(Obj);
logAllUnhandledErrors(DICtx->loadRegisterInfo(Obj), errs(),
// Dump the complete DWARF structure.
- DIDumpOptions DumpOpts;
- DumpOpts.DumpType = DumpType;
- DumpOpts.SummarizeTypes = SummarizeTypes;
- DumpOpts.Brief = !Verbose;
- DICtx->dump(outs(), DumpOpts);
+ DICtx->dump(outs(), GetDumpOpts());
}
static void DumpInput(StringRef Filename) {
raw_ostream &stream = Quiet ? nulls() : outs();
stream << "Verifying " << Filename.str() << ":\tfile format "
<< Obj.getFileFormatName() << "\n";
- bool Result = DICtx->verify(stream, DumpType);
+ bool Result = DICtx->verify(stream, DumpType, GetDumpOpts());
if (Result)
stream << "No errors.\n";
else