This is the mail archive of the elfutils-devel@sourceware.org mailing list for the elfutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]