This is the mail archive of the binutils@sourceware.org mailing list for the binutils 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]

[PATCH] DW_OP_GNU_implicit_pointer binutils support, fix up DW_OP_call_ref


Hi!

This patch adds DW_OP_GNU_implicit_pointer printing support for
readelf -wi and fixes up DW_OP_call_ref printing (both the operand size was
wrong and cu_offset incorrectly added to it).
Tested on x86_64-linux, ok for trunk?

2010-09-09  Jakub Jelinek  <jakub@redhat.com>

	* dwarf.h (debug_info): Add offset_info and dwarf_version fields.
	* dwarf.c (decode_location_expression): Add offset_size and
	dwarf_version arguments.  Prefix DIE offset with 0x for
	DW_OP_call{2,4,_ref}.  Fix up DW_OP_call_ref operand size,
	complain if in frame info section.  Handle
	DW_OP_GNU_implicit_pointer.
	(read_and_display_attr_value, display_debug_loc,
	display_debug_frames): Adjust decode_location_expression callers.
	(process_debug_info): Save offset_size and dwarf_version values
	into debug_information array.

	* dwarf2.h (DW_OP_GNU_implicit_pointer): New.

--- include/dwarf2.h.jj	2010-06-21 18:38:33.000000000 +0200
+++ include/dwarf2.h	2010-09-09 10:41:52.000000000 +0200
@@ -622,6 +622,7 @@ enum dwarf_location_atom
     /* The following is for marking variables that are uninitialized.  */
     DW_OP_GNU_uninit     = 0xf0,
     DW_OP_GNU_encoded_addr = 0xf1,
+    DW_OP_GNU_implicit_pointer = 0xf2,
     /* HP extensions.  */
     DW_OP_HP_unknown     = 0xe0, /* Ouch, the same as GNU_push_tls_address.  */
     DW_OP_HP_is_value    = 0xe1,
--- binutils/dwarf.c.jj	2010-09-09 10:11:47.000000000 +0200
+++ binutils/dwarf.c	2010-09-09 11:21:19.000000000 +0200
@@ -712,6 +712,8 @@ display_block (unsigned char *data, unsi
 static int
 decode_location_expression (unsigned char * data,
 			    unsigned int pointer_size,
+			    unsigned int offset_size,
+			    int dwarf_version,
 			    unsigned long length,
 			    unsigned long cu_offset,
 			    struct dwarf_section * section)
@@ -1018,20 +1020,36 @@ decode_location_expression (unsigned cha
 	case DW_OP_call2:
 	  /* XXX: Strictly speaking for 64-bit DWARF3 files
 	     this ought to be an 8-byte wide computation.  */
-	  printf ("DW_OP_call2: <%lx>", (long) byte_get (data, 2) + cu_offset);
+	  printf ("DW_OP_call2: <0x%lx>", (long) byte_get (data, 2) + cu_offset);
 	  data += 2;
 	  break;
 	case DW_OP_call4:
 	  /* XXX: Strictly speaking for 64-bit DWARF3 files
 	     this ought to be an 8-byte wide computation.  */
-	  printf ("DW_OP_call4: <%lx>", (long) byte_get (data, 4) + cu_offset);
+	  printf ("DW_OP_call4: <0x%lx>", (long) byte_get (data, 4) + cu_offset);
 	  data += 4;
 	  break;
 	case DW_OP_call_ref:
 	  /* XXX: Strictly speaking for 64-bit DWARF3 files
 	     this ought to be an 8-byte wide computation.  */
-	  printf ("DW_OP_call_ref: <%lx>", (long) byte_get (data, 4) + cu_offset);
-	  data += 4;
+	  if (dwarf_version == -1)
+	    {
+	      printf (_("(DW_OP_call_ref in frame info)"));
+	      /* No way to tell where the next op is, so just bail.  */
+	      return need_frame_base;
+	    }
+	  if (dwarf_version == 2)
+	    {
+	      printf ("DW_OP_call_ref: <0x%lx>",
+		      (long) byte_get (data, pointer_size));
+	      data += pointer_size;
+	    }
+	  else
+	    {
+	      printf ("DW_OP_call_ref: <0x%lx>",
+		      (long) byte_get (data, offset_size));
+	      data += offset_size;
+	    }
 	  break;
 	case DW_OP_form_tls_address:
 	  printf ("DW_OP_form_tls_address");
@@ -1083,6 +1101,30 @@ decode_location_expression (unsigned cha
 	    print_dwarf_vma (addr, pointer_size);
 	  }
 	  break;
+	case DW_OP_GNU_implicit_pointer:
+	  /* XXX: Strictly speaking for 64-bit DWARF3 files
+	     this ought to be an 8-byte wide computation.  */
+	  if (dwarf_version == -1)
+	    {
+	      printf (_("(DW_OP_GNU_implicit_pointer in frame info)"));
+	      /* No way to tell where the next op is, so just bail.  */
+	      return need_frame_base;
+	    }
+	  if (dwarf_version == 2)
+	    {
+	      printf ("DW_OP_GNU_implicit_pointer: <0x%lx> %ld",
+		      (long) byte_get (data, pointer_size),
+		      read_leb128 (data + pointer_size, &bytes_read, 1));
+	      data += pointer_size + bytes_read;
+	    }
+	  else
+	    {
+	      printf ("DW_OP_GNU_implicit_pointer: <0x%lx> %ld",
+		      (long) byte_get (data, offset_size),
+		      read_leb128 (data + offset_size, &bytes_read, 1));
+	      data += offset_size;
+	    }
+	  break;
 
 	  /* HP extensions.  */
 	case DW_OP_HP_is_value:
@@ -1632,6 +1674,8 @@ read_and_display_attr_value (unsigned lo
 	  printf ("(");
 	  need_frame_base = decode_location_expression (block_start,
 							pointer_size,
+							offset_size,
+							dwarf_version,
 							uvalue,
 							cu_offset, section);
 	  printf (")");
@@ -2023,6 +2067,8 @@ process_debug_info (struct dwarf_section
 	  debug_information [unit].cu_offset = cu_offset;
 	  debug_information [unit].pointer_size
 	    = compunit.cu_pointer_size;
+	  debug_information [unit].offset_size = offset_size;
+	  debug_information [unit].dwarf_version = compunit.cu_version;
 	  debug_information [unit].base_address = 0;
 	  debug_information [unit].loc_offsets = NULL;
 	  debug_information [unit].have_frame_base = NULL;
@@ -3405,6 +3451,8 @@ display_debug_loc (struct dwarf_section 
       unsigned short length;
       unsigned long offset;
       unsigned int pointer_size;
+      unsigned int offset_size;
+      int dwarf_version;
       unsigned long cu_offset;
       unsigned long base_address;
       int need_frame_base;
@@ -3412,6 +3460,8 @@ display_debug_loc (struct dwarf_section 
 
       pointer_size = debug_information [i].pointer_size;
       cu_offset = debug_information [i].cu_offset;
+      offset_size = debug_information [i].offset_size;
+      dwarf_version = debug_information [i].dwarf_version;
 
       for (j = 0; j < debug_information [i].num_loc_offsets; j++)
 	{
@@ -3503,6 +3553,8 @@ display_debug_loc (struct dwarf_section 
 	      putchar ('(');
 	      need_frame_base = decode_location_expression (start,
 							    pointer_size,
+							    offset_size,
+							    dwarf_version,
 							    length,
 							    cu_offset, section);
 	      putchar (')');
@@ -4774,8 +4826,8 @@ display_debug_frames (struct dwarf_secti
 	      if (! do_debug_frames_interp)
 		{
 		  printf ("  DW_CFA_def_cfa_expression (");
-		  decode_location_expression (start, eh_addr_size, ul, 0,
-					      section);
+		  decode_location_expression (start, eh_addr_size, 0, -1,
+					      ul, 0, section);
 		  printf (")\n");
 		}
 	      fc->cfa_exp = 1;
@@ -4791,7 +4843,7 @@ display_debug_frames (struct dwarf_secti
 		{
 		  printf ("  DW_CFA_expression: %s%s (",
 			  reg_prefix, regname (reg, 0));
-		  decode_location_expression (start, eh_addr_size,
+		  decode_location_expression (start, eh_addr_size, 0, -1,
 					      ul, 0, section);
 		  printf (")\n");
 		}
@@ -4809,8 +4861,8 @@ display_debug_frames (struct dwarf_secti
 		{
 		  printf ("  DW_CFA_val_expression: %s%s (",
 			  reg_prefix, regname (reg, 0));
-		  decode_location_expression (start, eh_addr_size, ul, 0,
-					      section);
+		  decode_location_expression (start, eh_addr_size, 0, -1,
+					      ul, 0, section);
 		  printf (")\n");
 		}
 	      if (*reg_prefix == '\0')
--- binutils/dwarf.h.jj	2010-09-09 10:11:47.000000000 +0200
+++ binutils/dwarf.h	2010-09-09 11:08:44.000000000 +0200
@@ -1,5 +1,5 @@
 /* dwarf.h - DWARF support header file
-   Copyright 2005, 2007, 2008, 2009
+   Copyright 2005, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
 
    This file is part of GNU Binutils.
@@ -84,6 +84,8 @@ extern struct dwarf_section_display debu
 typedef struct
 {
   unsigned int   pointer_size;
+  unsigned int   offset_size;
+  int            dwarf_version;
   unsigned long  cu_offset;
   unsigned long	 base_address;
   /* This is an array of offsets to the location list table.  */

	Jakub


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