* dwarf2read.c (dwarf2_get_pc_bounds): Check DW_AT_high_pc form to
authorMark Wielaard <mjw@redhat.com>
Fri, 27 Apr 2012 18:55:19 +0000 (18:55 +0000)
committerMark Wielaard <mjw@redhat.com>
Fri, 27 Apr 2012 18:55:19 +0000 (18:55 +0000)
       see whether it is an address or a constant offset from DW_AT_low_pc.
       (dwarf2_record_block_ranges): Likewise.
       (read_partial_die): Likewise.

gdb/ChangeLog
gdb/dwarf2read.c

index a4dfd85252520c785e663ccc7550f9cefa064ada..e6b04dd790b86d49f0b6d2f21df048b1fc612f6a 100644 (file)
@@ -1,3 +1,10 @@
+2012-04-27  Mark Wielaard  <mjw@redhat.com>
+
+       * dwarf2read.c (dwarf2_get_pc_bounds): Check DW_AT_high_pc form to
+       see whether it is an address or a constant offset from DW_AT_low_pc.
+       (dwarf2_record_block_ranges): Likewise.
+       (read_partial_die): Likewise.
+
 2012-04-26  Mark Wielaard  <mjw@redhat.com>
 
        * MAINTAINERS (Write After Approval): Add myself to the list.
index 99bba9f8b979afa6d1c886140d0aa8b021869250..7ae3b8616cd5a079fd6429acd4ae91d9b8e9c78a 100644 (file)
@@ -6706,17 +6706,23 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
                      struct partial_symtab *pst)
 {
   struct attribute *attr;
+  struct attribute *attr_high;
   CORE_ADDR low = 0;
   CORE_ADDR high = 0;
   int ret = 0;
 
-  attr = dwarf2_attr (die, DW_AT_high_pc, cu);
-  if (attr)
+  attr_high = dwarf2_attr (die, DW_AT_high_pc, cu);
+  if (attr_high)
     {
-      high = DW_ADDR (attr);
       attr = dwarf2_attr (die, DW_AT_low_pc, cu);
       if (attr)
-       low = DW_ADDR (attr);
+        {
+         low = DW_ADDR (attr);
+         if (attr_high->form == DW_FORM_addr)
+           high = DW_ADDR (attr_high);
+         else
+           high = low + DW_UNSND (attr_high);
+       }
       else
        /* Found high w/o low attribute.  */
        return 0;
@@ -6864,16 +6870,20 @@ dwarf2_record_block_ranges (struct die_info *die, struct block *block,
 {
   struct objfile *objfile = cu->objfile;
   struct attribute *attr;
+  struct attribute *attr_high;
 
-  attr = dwarf2_attr (die, DW_AT_high_pc, cu);
-  if (attr)
+  attr_high = dwarf2_attr (die, DW_AT_high_pc, cu);
+  if (attr_high)
     {
-      CORE_ADDR high = DW_ADDR (attr);
-
       attr = dwarf2_attr (die, DW_AT_low_pc, cu);
       if (attr)
         {
           CORE_ADDR low = DW_ADDR (attr);
+         CORE_ADDR high;
+         if (attr_high->form == DW_FORM_addr)
+           high = DW_ADDR (attr_high);
+         else
+           high = low + DW_UNSND (attr_high);
 
           record_block_range (block, baseaddr + low, baseaddr + high - 1);
         }
@@ -9925,6 +9935,7 @@ read_partial_die (struct partial_die_info *part_die,
   struct attribute attr;
   int has_low_pc_attr = 0;
   int has_high_pc_attr = 0;
+  int high_pc_relative = 0;
 
   memset (part_die, 0, sizeof (struct partial_die_info));
 
@@ -9981,7 +9992,13 @@ read_partial_die (struct partial_die_info *part_die,
          break;
        case DW_AT_high_pc:
          has_high_pc_attr = 1;
-         part_die->highpc = DW_ADDR (&attr);
+         if (attr.form == DW_FORM_addr)
+           part_die->highpc = DW_ADDR (&attr);
+         else
+           {
+             high_pc_relative = 1;
+             part_die->highpc = DW_UNSND (&attr);
+           }
          break;
        case DW_AT_location:
           /* Support the .debug_loc offsets.  */
@@ -10061,6 +10078,9 @@ read_partial_die (struct partial_die_info *part_die,
        }
     }
 
+  if (high_pc_relative)
+    part_die->highpc += part_die->lowpc;
+
   if (has_low_pc_attr && has_high_pc_attr)
     {
       /* When using the GNU linker, .gnu.linkonce. sections are used to