From: Mark Wielaard Date: Sat, 2 Apr 2011 15:33:41 +0000 (+0200) Subject: dwarflint: Add DW_LNE_set_discriminator check and clean unknown upcode warn. X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=976d70bad5c12cb8fdc672d91cc0c163e723054f;p=thirdparty%2Felfutils.git dwarflint: Add DW_LNE_set_discriminator check and clean unknown upcode warn. Print unknown (extended) opcodes has hex values. Add dwarf_line_extended_opcode_string. New simple DW_LNE_set_discriminator check (not zero). --- diff --git a/dwarflint/check_debug_line.cc b/dwarflint/check_debug_line.cc index b9d450f79..4a21125c3 100644 --- a/dwarflint/check_debug_line.cc +++ b/dwarflint/check_debug_line.cc @@ -459,6 +459,25 @@ check_debug_line::check_debug_line (checkstack &stack, dwarflint &lint) break; } + case DW_LNE_set_discriminator: + { + /* XXX Is there anything interesting we should + check here? */ + uint64_t disc; + if (!checked_read_uleb128 (&sub_ctx, &disc, &where, + "set_discriminator operand")) + goto skip; + + /* The discriminator is reset to zero on any + sequence change. So setting to zero is never + necessary. */ + if (disc == 0) + wr_message (where, mc_line | mc_impact_1) + << "DW_LNE_set_discriminator with zero operand." + << std::endl; + break; + } + case DW_LNE_define_file: { const char *name; @@ -490,7 +509,8 @@ check_debug_line::check_debug_line (checkstack &stack, dwarflint &lint) default: /* No we don't, emit a warning. */ wr_message (where, mc_impact_2 | mc_line) - << "unknown extended opcode #" << extended + << "unknown extended opcode 0x" + << std::hex << +extended << std::dec << '.' << std::endl; }; }; @@ -578,7 +598,8 @@ check_debug_line::check_debug_line (checkstack &stack, dwarflint &lint) default: if (opcode < opcode_base) wr_message (where, mc_impact_2 | mc_line) - << "unknown standard opcode #" << opcode + << "unknown standard opcode 0x" + << std::hex << +opcode << std::dec << '.' << std::endl; }; }; @@ -591,8 +612,8 @@ check_debug_line::check_debug_line (checkstack &stack, dwarflint &lint) sprintf (buf, "operand #%d of DW_LNS_%s", i, dwarf_line_standard_opcode_string (opcode)); else - sprintf (buf, "operand #%d of extended opcode %d", - i, extended); + sprintf (buf, "operand #%d of DW_LNE_%s", + i, dwarf_line_extended_opcode_string (extended)); if (!checked_read_uleb128 (&sub_ctx, &operand, &where, buf)) goto skip; } diff --git a/src/dwarfstrings.c b/src/dwarfstrings.c index 91933f013..9826cf30a 100644 --- a/src/dwarfstrings.c +++ b/src/dwarfstrings.c @@ -765,7 +765,6 @@ dwarf_locexpr_opcode_string (unsigned int code) return ret; } - const char * dwarf_line_standard_opcode_string (unsigned int code) { @@ -789,3 +788,27 @@ dwarf_line_standard_opcode_string (unsigned int code) return ret; } + +const char * +dwarf_line_extended_opcode_string (unsigned int code) +{ + static const char *const known[] = + { +#define ONE_KNOWN_DW_LNE(NAME, CODE) [CODE] = #NAME, + ALL_KNOWN_DW_LNE +#undef ONE_KNOWN_DW_LNE + }; + + const char *ret = NULL; + if (likely (code < sizeof (known) / sizeof (known[0]))) + ret = known[code]; + + if (ret == NULL) + { + static char buf[40]; + snprintf (buf, sizeof buf, gettext ("unknown opcode %x"), code); + ret = buf; + } + + return ret; +} diff --git a/src/dwarfstrings.h b/src/dwarfstrings.h index c77a19072..16180f199 100644 --- a/src/dwarfstrings.h +++ b/src/dwarfstrings.h @@ -61,6 +61,8 @@ const char *dwarf_locexpr_opcode_string (unsigned int code); const char *dwarf_line_standard_opcode_string (unsigned int code); +const char *dwarf_line_extended_opcode_string (unsigned int code); + #ifdef __cplusplus } #endif