This is an archive of the discontinued LLVM Phabricator instance.

lldb-dwarfdump -verify [-quiet]
AbandonedPublic

Authored by clayborg on Apr 27 2017, 4:25 PM.

Details

Summary

This patch add the framework for verifying DWARF using llvm-dwarfdump as the front end.

This patch currently verifies:

  • All DW_TAG_subprogram DIEs ranges have any child ranges (DW_AT_lexical_block and DW_AT_inlined_subroutine) verified to ensure that all ranges are in the parent ranges.
  • Make sure that no DW_TAG_subprogram address ranges overlap
  • If a DW_TAG_compile_unit has DW_AT_ranges, then ensure that all DW_TAG_subprogram ranges are in the CU ranges.
  • All DW_AT_ranges attributes have valid .debug_ranges offsets
  • All DW_AT_stmt_list attributes have valid .debug_line offsets
  • All DW_FORM_strp attributes have valid .debug_str offsets
  • All reference attributes (DW_FORM_ref1,DW_FORM_ref2, DW_FORM_ref4, DW_FORM_ref8, DW_FORM_ref_udata, DW_FORM_ref_addr) have values that point to actual valid DIE offsets.
  • If .debug_aranges is available, we parse only the information in there and verify that all function ranges are accounted for and point to the correct CU offset
  • Verifies all line table rows have valid increasing addresses within each sequence
  • Verifies all line table rows have valid file indexes

Diff Detail

Event Timeline

clayborg created this revision.Apr 27 2017, 4:25 PM

Forgot to add that the verifier respects the -debug-dump option! So you can currently do:

// Verify all sections
llvm-dwardump --verify a.out
// Verify only .debug_info
llvm-dwardump --verify -debug-dump=info a.out
// Verify only .debug_aranges
llvm-dwardump --verify -debug-dump=aranges a.out
// Verify only .debug_line
llvm-dwardump --verify -debug-dump=line a.out

And for Eric Christopher I added "--quiet":

llvm-dwardump --verify a.out --quiet

The program will return a non-zero exit status if verification fails, and zero if it succeeds
dblaikie edited edge metadata.Apr 27 2017, 4:38 PM

This'll need tests - and it's probably easier to review those and the code in smaller patches adding one kind of verification at a time.

aprantl edited edge metadata.Apr 28 2017, 1:10 PM

First off, thank you very much for getting this started!

I agree with David that it would be better to commit this check by check and with a testcase for each one.

Generating testcases shouldn't be too much work. We could just start with a correct C program, compile it with clang -S and then inject an error into the assembler output, and then create a .s test with a run-line like this:
llvm-mc -triple x86_64-unknown-linux test.s -filetype=obj -o - | llvm-dwarfdump --verify -
The only dwarfback to this approach is that it will not fly for any DWARF generated by the assembler itself, such as .loc directives.

include/llvm/DebugInfo/DIContext.h
165

// No verifier? Just say things went well.
return true;

lib/DebugInfo/DWARF/DWARFContext.cpp
298

Weird indentation here and later on, too.
Can you run the entire patch through clang-format?

298

/// Returns true if the two ranges intersect.

318

We should probably factor out the "error: " part so its consistently formatted everywhere (and so we can colorize it, etc.)

328

I would just remove this. That check will likely get inlined from std::sort anyway.

337

FYI: We had a discussion earlier this week about how to best format ranges:

http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20170424/448535.html

and decided to write a helper function that outputs them as [x,y) by default.

362

According to the LLVM style both elses here should be removed, since the if has an early exit on all paths.

367

I

397

This is bound to break when we add more kinds?

401

I

404

delete

407

This function should probably be split up into several static helpers.

lib/DebugInfo/DWARF/DWARFDebugLine.cpp
164

separate commit?

clayborg abandoned this revision.May 1 2017, 10:58 AM

I will split this up as requested.