libdw: Handle all address FORMs for dwarf_highpc, handle errors better.
authorMark Wielaard <mark@klomp.org>
Tue, 22 May 2018 12:34:06 +0000 (14:34 +0200)
committerMark Wielaard <mark@klomp.org>
Fri, 25 May 2018 13:10:40 +0000 (15:10 +0200)
dwarf_highpc can use any address FORM, not just DW_FORM_addr. Just try
whether the address can be resolved as address. Always set error when
attribute couldn't be found or resolved. When calculating the base
address for a CU don't try to second guess the error code, just treat
an error the same as the attribute not being there.

Signed-off-by: Mark Wielaard <mark@klomp.org>
libdw/ChangeLog
libdw/dwarf_getlocation.c
libdw/dwarf_highpc.c

index f568963..526c91f 100644 (file)
@@ -1,3 +1,10 @@
+2018-05-22  Mark Wielaard  <mark@klomp.org>
+
+       * dwarf_getlocation.c (__libdw_cu_base_address): Treat errors of
+       getting lowpc or entrypc the same as missing base address (zero).
+       * dwarf_highpc (dwarf_highpc): Handle any address form. Always set
+       error when attribute could not be found.
+
 2018-05-21  Mark Wielaard  <mark@klomp.org>
 
        * dwarf_begin_elf.c (valid_p): Add a fake_addr_cu to the result.
index 116fa71..ade3e6c 100644 (file)
@@ -682,19 +682,10 @@ __libdw_cu_base_address (Dwarf_CU *cu)
                                                         &attr_mem),
                                     &base) != 0)
        {
-         int err = INTUSE(dwarf_errno) ();
-         if (err != 0)
-           {
-             __libdw_seterrno (err);
-             base = (Dwarf_Addr) -1;
-           }
-         else
-           {
-             /* The compiler provided no base address when it should
-                have.  Buggy GCC does this when it used absolute
-                addresses in the location list and no DW_AT_ranges.  */
-             base = 0;
-           }
+         /* The compiler provided no base address when it should
+            have.  Buggy GCC does this when it used absolute
+            addresses in the location list and no DW_AT_ranges.  */
+          base = 0;
        }
       cu->base_address = base;
     }
index 1baffa7..5b2f0fd 100644 (file)
@@ -47,10 +47,10 @@ dwarf_highpc (Dwarf_Die *die, Dwarf_Addr *return_addr)
     attr_high = INTUSE(dwarf_attr) (die, DW_AT_high_pc, &attr_high_mem);
 
   if (attr_high == NULL)
-    return -1;
+    goto no_addr;
 
-  if (attr_high->form == DW_FORM_addr)
-    return INTUSE(dwarf_formaddr) (attr_high, return_addr);
+  if (INTUSE(dwarf_formaddr) (attr_high, return_addr) == 0)
+    return 0;
 
   /* DWARF 4 allows high_pc to be a constant offset from low_pc. */
   if (INTUSE(dwarf_lowpc) (die, return_addr) == 0)
@@ -61,8 +61,10 @@ dwarf_highpc (Dwarf_Die *die, Dwarf_Addr *return_addr)
          *return_addr += uval;
          return 0;
        }
-      __libdw_seterrno (DWARF_E_NO_ADDR);
     }
+
+no_addr:
+  __libdw_seterrno (DWARF_E_NO_ADDR);
   return -1;
 }
 INTDEF(dwarf_highpc)