* dwarf.h (debug_info): Add offset_info and dwarf_version fields.
authorJakub Jelinek <jakub@redhat.com>
Thu, 9 Sep 2010 10:18:12 +0000 (10:18 +0000)
committerJakub Jelinek <jakub@redhat.com>
Thu, 9 Sep 2010 10:18:12 +0000 (10:18 +0000)
* 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.

binutils/ChangeLog
binutils/dwarf.c
binutils/dwarf.h
include/ChangeLog
include/dwarf2.h

index d42141eadb29a04fcbd5723af88983f0f32dc98f..dcbf00b04b802d733f913f788d0a00f524b9fbc0 100644 (file)
@@ -1,3 +1,16 @@
+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.
+
 2010-09-07  Nick Clifton  <nickc@redhat.com>
 
        * readelf.c (process_section_headers): Mention meaning of 'l'
index 599c0d2ba81d03863c5f4018f65ba550312519af..17a608c9fa0a0877b337f43efd700ea34f22c780 100644 (file)
@@ -712,6 +712,8 @@ display_block (unsigned char *data, unsigned long length)
 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 char * data,
        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 char * data,
            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 long attribute,
          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 *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 *section, void *file)
       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 *section, void *file)
 
       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 *section, void *file)
              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_section *section,
              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_section *section,
                {
                  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_section *section,
                {
                  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')
index a9b501f3e7ea460dc369c3aecda86af2995f7541..df90ae0c33754199bc837bbf29b90a0a9cad2a32 100644 (file)
@@ -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 debug_displays [];
 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.  */
index 91b2edbed0f2b742d0b0540f5cb75d10d871c29d..7f3682c26472b39d8adc38645c1c376dd9c51df9 100644 (file)
@@ -1,3 +1,7 @@
+2010-09-09  Jakub Jelinek  <jakub@redhat.com>
+
+       * dwarf2.h (DW_OP_GNU_implicit_pointer): New.
+
 2010-07-06  Ken Werner  <ken.werner@de.ibm.com>
 
        * floatformat.h (floatformat_ieee_half_big): Add declaration.
index 03c25812d09a498d94172d8f97d6aabcb79335b7..fea23ad61e493c81bb8a3951e2669313baa3aafb 100644 (file)
@@ -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,