This is the mail archive of the
elfutils-devel@sourceware.org
mailing list for the elfutils project.
Cleanup unknown line opcode printing and add set_discriminator check
- From: Mark Wielaard <mjw at redhat dot com>
- To: elfutils-devel at lists dot fedorahosted dot org
- Date: Sat, 02 Apr 2011 17:44:54 +0200
- Subject: Cleanup unknown line opcode printing and add set_discriminator check
Hi,
Richard Henderson noticed that unknown (extended) line opcodes were
printed strangely. This patch fixes that by explicitly converting to
numbers and printing as hex. It also adds a DW_LNE_set_discriminator
check. I don't know if there is much to check here, I don't fully
understand why they are needed in the first place. Commit pushed to the
dwarf branch.
But DW_LNE_set_discriminator should already have been recognized. I
assume Richard had an old checkout but didn't configure with
--enable-maintainer-mode which would have regenerated known-dwarf.h.
I have also forgot that in the past. Is there a reason for not just
generating known-dwarf.h always? It only needs awk, and I assume that is
available on all systems by default we care about, isn't it?
Cheers,
Mark
>From 976d70bad5c12cb8fdc672d91cc0c163e723054f Mon Sep 17 00:00:00 2001
From: Mark Wielaard <mjw@redhat.com>
Date: Sat, 2 Apr 2011 17:33:41 +0200
Subject: [PATCH] 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).
---
dwarflint/check_debug_line.cc | 29 +++++++++++++++++++++++++----
src/dwarfstrings.c | 25 ++++++++++++++++++++++++-
src/dwarfstrings.h | 2 ++
3 files changed, 51 insertions(+), 5 deletions(-)
diff --git a/dwarflint/check_debug_line.cc b/dwarflint/check_debug_line.cc
index b9d450f..4a21125 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 91933f0..9826cf3 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 c77a190..16180f1 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
--
1.7.4