= DWARF lint tool = This will be a new tool analogous to elflint, to check DWARF formats for correctness and consistency. The initial version can operate on a single DWARF file only. In future if we do advanced size reduction techniques via interobject references, it would also have modes to check those references and the composite DWARF trees in whole. dwarflint is being developed on "dwarf" branch of elfutils GIT repository. dwarflint discovered a couple SuspiciousDebuginfoCases. == What it should do in future == ... can be found in [source:dwarflint/TODO@dwarf TODO file]. == What it can do now == What follows is a list of checks that dwarflint executes on DWARF files. You can always get the accurate list of checks by launching {{{dwarflint --list-checks --verbose}}} That will generate an output quite similar to what you see below. If you drop the `--verbose` option, the list will be more concise. === check_debug_aranges === Checks for low-level structure of .debug_aranges. In addition it checks: - that relocations are valid. In ET_REL files that certain fields are relocated - for dangling and duplicate CU references - for garbage inside padding - for zero-length ranges - that the ranges cover all the address range covered by CUs === check_debug_ranges === Checks for low-level structure of .debug_ranges. In addition it checks: - for overlapping and dangling references from .debug_info - that base address is set and that it actually changes the address - that ranges have a positive size - that there are no unreferenced holes in the section - that relocations are valid. In ET_REL files that certain fields are relocated - neither or both of range start and range end are expected to be relocated. It's expected that they are both relocated against the same section. === check_debug_loc === Checks for low-level structure of .debug_loc. In addition it makes the same checks as .debug_ranges. For location expressions it further checks: - that DW_OP_bra and DW_OP_skip argument is non-zero and doesn't escape the expression. In addition it is required that the jump ends on another instruction, not arbitrarily in the middle of the byte stream, even if that position happened to be interpretable as another well-defined instruction stream. - on 32-bit machines it rejects DW_OP_const8u and DW_OP_const8s - on 32-bit machines it checks that ULEB128-encoded arguments aren't quantities that don't fit into 32 bits === check_debug_pubnames === Checks for low-level structure of .debug_pubnames. In addition it checks: - for garbage inside padding - that relocations are valid. In ET_REL files that certain fields are relocated Furthermore, if .debug_info is valid, it is checked: - that references point to actual CUs and DIEs - that there's only one pub section per CU === check_debug_pubtypes === Checks for low-level structure of .debug_pubtypes. In addition it makes the same checks as check_debug_pubnames. === check_debug_line === Checks for low-level structure of .debug_line. In addition it checks: - for normalized values of certain attributes (such as that default_is_stmt is 0 or 1, even though technically any non-zero value is allowed). - for valid setting of opcode base (i.e. non-zero) and any file indices - that all include directories and all files are used - that files with absolute paths don't refer to include directories, and otherwise that the directory reference is valid - that each used standard or extended opcode is known (note that this assumes that elfutils know about all opcodes used in practice. Be sure to build against recent-enough version). - that the line number program is properly terminated with the DW_LNE_end_sequence instruction and that it contains at least one other instruction - that relocations are valid. In ET_REL files that certain fields are relocated Furthermore, if .debug_info is valid, it is checked: - that each line table is used by some CU - that the line table references at CUs point to actual line tables TODOs: - overlaps in defined addresses are probably OK, one instruction can be derived from several statements. But certain flags in table should be consistent in that case, namely is_stmt, basic_block, end_sequence, prologue_end, epilogue_begin, isa. === check_debug_info === Checks for low-level structure of .debug_info. In addition it checks: - for dangling reference to .debug_abbrev section - that reported CU address sizes are consistent - that rangeptr values are aligned to CU address size - it is checked that DW_AT_low_pc and DW_AT_high_pc are relocated consistently - that DIE references are well formed (both intra-CU and inter-CU) and that local reference isn't needlessly formed as global - that .debug_string references are well formed and referred strings are properly NUL-terminated - that referenced abbreviations actually exist - that DIEs with children have the DW_AT_sibling attribute and that the sibling actually is at the address reported at that attribute - that the DIE chain is terminated - that the last sibling in chain has no DW_AT_sibling attribute - that the DIE with children actually has children (i.e. that the chain is not empty) - for format constraints (such as that there are no 64-bit CUs inside DWARF 2 file) - in 32-bit CUs, that location attributes are not formed with DW_FORM_data8 - all the attribute checks done by check_debug_abbrev are done here for attributes with DW_FORM_indirect. Indirect form is forbidden to be again indirect - that all abbreviations are used - that relocations are valid. In ET_REL files that certain fields are relocated === check_debug_abbrev === Checks for low-level structure of .debug_abbrev. In addition it checks: - that all abbreviation tables are non-empty - that certain attribute forms match expectations (mainly those that we have to work with in subsequent check passes. For example we check that DW_AT_low_pc has a form of DW_FORM_{,ref_}addr) - that all CUs that share an abbrev table are of the same DWARF version - that each abbrev table is used - that abbrevs don't share abbrev codes - that abbrev tags, attribute names and attribute forms are all known (note that this assumes that elfutils know about all tags used in practice. Be sure to build against recent-enough version) - that the value of has_children is either 0 or 1 - that DW_AT_sibling isn't formed as DW_FORM_ref_addr, and that it isn't present at childless abbrevs - that attributes are not duplicated at abbrev - that DW_AT_high_pc is never used without DW_AT_low_pc. If both are used, that DW_AT_ranges isn't also used This check generally requires CU headers to be readable, i.e. that the .debug_info section is roughly well-defined. If that isn't the case, many checks will still be done, operating under assumption that what we see is the latest DWARF format. This may render some checks inaccurate. === check_duplicate_DW_tag_variable === Implements a check for two full DW_TAG_variable DIEs with the same DW_AT_name value. This covers duplicate declaration, duplicate definition and declaration with definition. https://lists.fedorahosted.org/pipermail/elfutils-devel/2010-July/001497.html http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39524 === check_dups_abstract_origin === If a given attribute name is present on a DIE, it is suspicious if that attribute name appears on the DIE that's the first DIE's DW_AT_abstract_origin or DW_AT_specification. https://bugzilla.redhat.com/show_bug.cgi?id=527430 === check_expected_trees === Checks whether all DIEs have the right attributes and the right children. Currently this is very much a work in progress. === check_range_out_of_scope === Check whether PC ranges reported at DIEs fall into the containing scope. === check_matching_ranges === Check that the ranges in .debug_aranges and .debug_ranges match. === check_nodebug === Checks that there are at least essential debuginfo sections present in the ELF file. === locstats === Computes a location info coverage statistics. Goes through the whole DIE graph, looking at each variable and formal parameter, and determining scope coverage of its location information. In other words for how big a part of scope we know, where the variable "lives". https://lists.fedorahosted.org/pipermail/elfutils-devel/2010-July/001498.html https://lists.fedorahosted.org/pipermail/elfutils-devel/2010-September/001602.html