lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <1334957394-12086-4-git-send-email-jason.wessel@windriver.com>
Date:	Fri, 20 Apr 2012 16:29:49 -0500
From:	Jason Wessel <jason.wessel@...driver.com>
To:	<linux-kernel@...r.kernel.org>
CC:	<mingo@...hat.com>, <masami.hiramatsu.pt@...achi.com>,
	<rusty@...tcorp.com.au>
Subject: [RFC PATCH 3/8] readelf: emit simple to parse line .debug_line data

A quiet option was added so as to emit only the following data when
running readelf.  Example:

scripts/readelf -q --debug-dump=line vmlinux
[...]
sched.c:45 0xffffffff81011e79
sched.c:49 0xffffffff81011e80

It is important to leave the original printfs behind as they are
required in order to debug problems related to parsing the debug line
data.

Signed-off-by: Jason Wessel <jason.wessel@...driver.com>
---
 scripts/readelf.c |  218 ++++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 164 insertions(+), 54 deletions(-)

diff --git a/scripts/readelf.c b/scripts/readelf.c
index 6ed944f..228de30 100644
--- a/scripts/readelf.c
+++ b/scripts/readelf.c
@@ -236,6 +236,7 @@ Elf_Internal_Shdr *section_headers;
 Elf_Internal_Shdr *symtab_shndx_hdr;
 int show_name;
 int do_dump;
+int do_quiet;
 int do_wide;
 int do_debug_lines;
 int is_32bit_elf;
@@ -605,6 +606,7 @@ usage ()
   fprintf (stdout, " Options are:\n\
   --debug-dump=line      Display the contents of DWARF2 debug sections\n");
   fprintf (stdout, "\
+  -q                     Only emit line number data\n\
   -W --wide              Allow output width to exceed 80 characters\n\
   -H --help              Display this information\n");
 
@@ -653,7 +655,7 @@ parse_args (argc, argv)
     usage ();
 
   while ((c = getopt_long
-	  (argc, argv, "WH", options, NULL)) != EOF)
+	  (argc, argv, "qWH", options, NULL)) != EOF)
     {
 
       switch (c)
@@ -665,6 +667,10 @@ parse_args (argc, argv)
 	  usage ();
 	  break;
 
+	case 'q':
+	  do_quiet = 1;
+	  break;
+
 	case OPTION_DEBUG_DUMP:
 	  do_dump++;
 	    {
@@ -1006,6 +1012,7 @@ process_extended_line_op (data, is_stmt, pointer_size)
   unsigned int len;
   unsigned char *name;
   unsigned long adr;
+  unsigned long val;
 
   len = read_leb128 (data, & bytes_read, 0);
   data += bytes_read;
@@ -1019,38 +1026,55 @@ process_extended_line_op (data, is_stmt, pointer_size)
   len += bytes_read;
   op_code = *data++;
 
-  printf ("  Extended opcode %d: ", op_code);
+  if (!do_quiet)
+    printf ("  Extended opcode %d: ", op_code);
 
   switch (op_code)
     {
     case DW_LNE_end_sequence:
-      printf ("End of Sequence\n\n");
+	  if (!do_quiet)
+		printf ("End of Sequence\n\n");
       reset_state_machine (is_stmt);
       break;
 
     case DW_LNE_set_address:
       adr = byte_get (data, pointer_size);
-      printf ("set Address to 0x%lx\n", adr);
+	  if (!do_quiet)
+		printf ("set Address to 0x%lx\n", adr);
       state_machine_regs.address = adr;
       break;
 
     case DW_LNE_define_file:
-      printf ("  define new File Table entry\n");
-      printf ("  Entry\tDir\tTime\tSize\tName\n");
+	  if (!do_quiet)
+	    {
+		  printf ("  define new File Table entry\n");
+		  printf ("  Entry\tDir\tTime\tSize\tName\n");
+		}
 
-      printf ("   %d\t", ++state_machine_regs.last_file_entry);
+	  ++state_machine_regs.last_file_entry;
+	  if (!do_quiet)
+		printf ("   %d\t", state_machine_regs.last_file_entry);
       name = data;
       data += strlen ((char *) data) + 1;
-      printf ("%lu\t", read_leb128 (data, & bytes_read, 0));
+	  val = read_leb128 (data, & bytes_read, 0);
+	  if (!do_quiet)
+		printf ("%lu\t", val);
       data += bytes_read;
-      printf ("%lu\t", read_leb128 (data, & bytes_read, 0));
+	  val = read_leb128 (data, & bytes_read, 0);
+	  if (!do_quiet)
+		printf ("%lu\t", val);
       data += bytes_read;
-      printf ("%lu\t", read_leb128 (data, & bytes_read, 0));
-      printf ("%s\n\n", name);
+	  val = read_leb128 (data, & bytes_read, 0);
+	  if (!do_quiet)
+	    {
+		  printf ("%lu\t", val);
+		  printf ("%s\n\n", name);
+		}
       break;
 
     default:
-      printf ("UNKNOWN: length %d\n", len - bytes_read);
+	  if (!do_quiet)
+		printf ("UNKNOWN: length %d\n", len - bytes_read);
       break;
     }
 
@@ -1074,11 +1098,15 @@ display_debug_lines (section, start, file)
   unsigned char *data = start;
   unsigned char *end = start + section->sh_size;
   unsigned char *end_of_sequence;
+  unsigned int max_ftable = 0;
+  unsigned char **ftable = NULL;
+
   int i;
   int offset_size;
   int initial_length_size;
 
-  printf ("\nDump of debug contents of section %s:\n\n",
+  if (!do_quiet)
+    printf ("\nDump of debug contents of section %s:\n\n",
 	  SECTION_NAME (section));
 
   while (data < end)
@@ -1136,14 +1164,17 @@ display_debug_lines (section, start, file)
       info.li_line_base <<= 24;
       info.li_line_base >>= 24;
 
-      printf ("  Length:                      %ld\n", info.li_length);
-      printf ("  DWARF Version:               %d\n", info.li_version);
-      printf ("  Prologue Length:             %d\n", info.li_prologue_length);
-      printf ("  Minimum Instruction Length:  %d\n", info.li_min_insn_length);
-      printf ("  Initial value of 'is_stmt':  %d\n", info.li_default_is_stmt);
-      printf ("  Line Base:                   %d\n", info.li_line_base);
-      printf ("  Line Range:                  %d\n", info.li_line_range);
-      printf ("  Opcode Base:                 %d\n", info.li_opcode_base);
+      if (!do_quiet)
+        {
+	  printf ("  Length:                      %ld\n", info.li_length);
+	  printf ("  DWARF Version:               %d\n", info.li_version);
+	  printf ("  Prologue Length:             %d\n", info.li_prologue_length);
+	  printf ("  Minimum Instruction Length:  %d\n", info.li_min_insn_length);
+	  printf ("  Initial value of 'is_stmt':  %d\n", info.li_default_is_stmt);
+	  printf ("  Line Base:                   %d\n", info.li_line_base);
+	  printf ("  Line Range:                  %d\n", info.li_line_range);
+	  printf ("  Opcode Base:                 %d\n", info.li_opcode_base);
+	}
 
       end_of_sequence = data + info.li_length + initial_length_size;
 
@@ -1152,23 +1183,30 @@ display_debug_lines (section, start, file)
       /* Display the contents of the Opcodes table.  */
       standard_opcodes = hdrptr;
 
-      printf ("\n Opcodes:\n");
+      if (!do_quiet) {
+	printf ("\n Opcodes:\n");
 
-      for (i = 1; i < info.li_opcode_base; i++)
-	printf ("  Opcode %d has %d args\n", i, standard_opcodes[i - 1]);
+        for (i = 1; i < info.li_opcode_base; i++)
+	  printf ("  Opcode %d has %d args\n", i, standard_opcodes[i - 1]);
+      }
 
       /* Display the contents of the Directory table.  */
       data = standard_opcodes + info.li_opcode_base - 1;
 
       if (*data == 0)
-	printf ("\n The Directory Table is empty.\n");
+        {
+	  if (!do_quiet)
+	    printf ("\n The Directory Table is empty.\n");
+        }
       else
 	{
-	  printf ("\n The Directory Table:\n");
+	  if (!do_quiet)
+	    printf ("\n The Directory Table:\n");
 
 	  while (*data != 0)
 	    {
-	      printf ("  %s\n", data);
+	      if (!do_quiet)
+	        printf ("  %s\n", data);
 
 	      data += strlen ((char *) data) + 1;
 	    }
@@ -1177,31 +1215,81 @@ display_debug_lines (section, start, file)
       /* Skip the NUL at the end of the table.  */
       data++;
 
+      if (ftable)
+        {
+	  while (max_ftable)
+	    {
+	      max_ftable--;
+	      free(ftable[max_ftable]);
+	    }
+	  free(ftable);
+	  ftable = NULL;
+	}
+      max_ftable = 0;
       /* Display the contents of the File Name table.  */
       if (*data == 0)
-	printf ("\n The File Name Table is empty.\n");
+        {
+	  if (!do_quiet)
+	    printf ("\n The File Name Table is empty.\n");
+	}
       else
 	{
-	  printf ("\n The File Name Table:\n");
-	  printf ("  Entry\tDir\tTime\tSize\tName\n");
+	  unsigned char *data_reset = data;
+	  if (!do_quiet)
+	    {
+	      printf ("\n The File Name Table:\n");
+	      printf ("  Entry\tDir\tTime\tSize\tName\n");
+	    }
 
 	  while (*data != 0)
 	    {
 	      unsigned char *name;
 	      int bytes_read;
+	      unsigned long ret;
 
-	      printf ("  %d\t", ++state_machine_regs.last_file_entry);
+	      max_ftable++;
+	      if (!do_quiet)
+	        printf ("  %d\t", ++state_machine_regs.last_file_entry);
 	      name = data;
 
 	      data += strlen ((char *) data) + 1;
 
-	      printf ("%lu\t", read_leb128 (data, & bytes_read, 0));
+	      ret =  read_leb128 (data, & bytes_read, 0);
+	      if (!do_quiet)
+	        printf ("%lu\t", ret);
+	      data += bytes_read;
+	      ret =  read_leb128 (data, & bytes_read, 0);
+	      if (!do_quiet)
+	        printf ("%lu\t", ret);
+	      data += bytes_read;
+	      ret =  read_leb128 (data, & bytes_read, 0);
+	      if (!do_quiet)
+	        printf ("%lu\t", ret);
+	      data += bytes_read;
+	      if (!do_quiet)
+	        printf ("%s\n", name);
+	    }
+	  /* Allocate file table array */
+	  ftable = malloc(sizeof(char *) * max_ftable);
+	  data = data_reset;
+	  max_ftable = 0;
+	  while (*data != 0)
+	    {
+	      int bytes_read;
+
+	      ftable[max_ftable] = (unsigned char *)strdup((char *)data);
+	      if (!ftable[max_ftable])
+		abort();
+	      max_ftable++;
+
+	      data += strlen ((char *) data) + 1;
+
+	      read_leb128 (data, & bytes_read, 0);
 	      data += bytes_read;
-	      printf ("%lu\t", read_leb128 (data, & bytes_read, 0));
+	      read_leb128 (data, & bytes_read, 0);
 	      data += bytes_read;
-	      printf ("%lu\t", read_leb128 (data, & bytes_read, 0));
+	      read_leb128 (data, & bytes_read, 0);
 	      data += bytes_read;
-	      printf ("%s\n", name);
 	    }
 	}
 
@@ -1209,7 +1297,8 @@ display_debug_lines (section, start, file)
       data++;
 
       /* Now display the statements.  */
-      printf ("\n Line Number Statements:\n");
+      if (!do_quiet)
+        printf ("\n Line Number Statements:\n");
 
 
       while (data < end_of_sequence)
@@ -1225,12 +1314,17 @@ display_debug_lines (section, start, file)
 	      op_code -= info.li_opcode_base;
 	      adv      = (op_code / info.li_line_range) * info.li_min_insn_length;
 	      state_machine_regs.address += adv;
-	      printf ("  Special opcode %d: advance Address by %d to 0x%lx",
+	      if (!do_quiet)
+	        printf ("  Special opcode %d: advance Address by %d to 0x%lx",
 		      op_code, adv, state_machine_regs.address);
 	      adv = (op_code % info.li_line_range) + info.li_line_base;
 	      state_machine_regs.line += adv;
-	      printf (" and Line by %d to %d\n",
+	      if (!do_quiet)
+	        printf (" and Line by %d to %d\n",
 		      adv, state_machine_regs.line);
+	      if (do_quiet)
+		printf("%s:%u 0x%lx\n", ftable[state_machine_regs.file - 1],
+state_machine_regs.line, state_machine_regs.address);
 	    }
 	  else switch (op_code)
 	    {
@@ -1240,14 +1334,16 @@ display_debug_lines (section, start, file)
 	      break;
 
 	    case DW_LNS_copy:
-	      printf ("  Copy\n");
+	      if (!do_quiet)
+	        printf ("  Copy\n");
 	      break;
 
 	    case DW_LNS_advance_pc:
 	      adv = info.li_min_insn_length * read_leb128 (data, & bytes_read, 0);
 	      data += bytes_read;
 	      state_machine_regs.address += adv;
-	      printf ("  Advance PC by %d to %lx\n", adv,
+	      if (!do_quiet)
+	        printf ("  Advance PC by %d to %lx\n", adv,
 		      state_machine_regs.address);
 	      break;
 
@@ -1255,14 +1351,16 @@ display_debug_lines (section, start, file)
 	      adv = read_leb128 (data, & bytes_read, 1);
 	      data += bytes_read;
 	      state_machine_regs.line += adv;
-	      printf ("  Advance Line by %d to %d\n", adv,
+	      if (!do_quiet)
+	        printf ("  Advance Line by %d to %d\n", adv,
 		      state_machine_regs.line);
 	      break;
 
 	    case DW_LNS_set_file:
 	      adv = read_leb128 (data, & bytes_read, 0);
 	      data += bytes_read;
-	      printf ("  Set File Name to entry %d in the File Name Table\n",
+	      if (!do_quiet)
+	        printf ("  Set File Name to entry %d in the File Name Table\n",
 		      adv);
 	      state_machine_regs.file = adv;
 	      break;
@@ -1270,19 +1368,22 @@ display_debug_lines (section, start, file)
 	    case DW_LNS_set_column:
 	      adv = read_leb128 (data, & bytes_read, 0);
 	      data += bytes_read;
-	      printf ("  Set column to %d\n", adv);
+	      if (!do_quiet)
+	        printf ("  Set column to %d\n", adv);
 	      state_machine_regs.column = adv;
 	      break;
 
 	    case DW_LNS_negate_stmt:
 	      adv = state_machine_regs.is_stmt;
 	      adv = ! adv;
-	      printf ("  Set is_stmt to %d\n", adv);
+	      if (!do_quiet)
+	        printf ("  Set is_stmt to %d\n", adv);
 	      state_machine_regs.is_stmt = adv;
 	      break;
 
 	    case DW_LNS_set_basic_block:
-	      printf ("  Set basic block\n");
+	      if (!do_quiet)
+	        printf ("  Set basic block\n");
 	      state_machine_regs.basic_block = 1;
 	      break;
 
@@ -1290,7 +1391,8 @@ display_debug_lines (section, start, file)
 	      adv = (((255 - info.li_opcode_base) / info.li_line_range)
 		     * info.li_min_insn_length);
 	      state_machine_regs.address += adv;
-	      printf ("  Advance PC by constant %d to 0x%lx\n", adv,
+	      if (!do_quiet)
+	        printf ("  Advance PC by constant %d to 0x%lx\n", adv,
 		      state_machine_regs.address);
 	      break;
 
@@ -1298,40 +1400,48 @@ display_debug_lines (section, start, file)
 	      adv = byte_get (data, 2);
 	      data += 2;
 	      state_machine_regs.address += adv;
-	      printf ("  Advance PC by fixed size amount %d to 0x%lx\n",
+	      if (!do_quiet)
+	        printf ("  Advance PC by fixed size amount %d to 0x%lx\n",
 		      adv, state_machine_regs.address);
 	      break;
 
 	    case DW_LNS_set_prologue_end:
-	      printf ("  Set prologue_end to true\n");
+	      if (!do_quiet)
+	        printf ("  Set prologue_end to true\n");
 	      break;
 
 	    case DW_LNS_set_epilogue_begin:
-	      printf ("  Set epilogue_begin to true\n");
+	      if (!do_quiet)
+	        printf ("  Set epilogue_begin to true\n");
 	      break;
 
 	    case DW_LNS_set_isa:
 	      adv = read_leb128 (data, & bytes_read, 0);
 	      data += bytes_read;
-	      printf ("  Set ISA to %d\n", adv);
+	      if (!do_quiet)
+	        printf ("  Set ISA to %d\n", adv);
 	      break;
 
 	    default:
-	      printf ("  Unknown opcode %d with operands: ", op_code);
+	      if (!do_quiet)
+	        printf ("  Unknown opcode %d with operands: ", op_code);
 	      {
 		int i;
 		for (i = standard_opcodes[op_code - 1]; i > 0 ; --i)
 		  {
-		    printf ("0x%lx%s", read_leb128 (data, &bytes_read, 0),
+		    if (!do_quiet)
+		      printf ("0x%lx%s", read_leb128 (data, &bytes_read, 0),
 			    i == 1 ? "" : ", ");
 		    data += bytes_read;
 		  }
-		putchar ('\n');
+		if (!do_quiet)
+		  putchar ('\n');
 	      }
 	      break;
 	    }
 	}
-      putchar ('\n');
+      if (!do_quiet)
+        putchar ('\n');
     }
 
   return 1;
-- 
1.7.10

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ