]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
2005-12-09 Roland McGrath <roland@redhat.com>
authorRoland McGrath <roland@redhat.com>
Fri, 9 Dec 2005 23:40:30 +0000 (23:40 +0000)
committerRoland McGrath <roland@redhat.com>
Fri, 9 Dec 2005 23:40:30 +0000 (23:40 +0000)
* dwarf_getlocation.c (dwarf_getlocation_addr): Add some unlikelys.
Delay CU base lookup until it's needed.
If CU base lookup fails with no error, flag invalid DWARF.

libdw/ChangeLog
libdw/dwarf_getlocation.c

index 91edce0d470e5aba4ea5ed0472967d30ee56dd44..77c18ce406a29044e2b3d56edf90457a0976549e 100644 (file)
@@ -1,3 +1,9 @@
+2005-12-09  Roland McGrath  <roland@redhat.com>
+
+       * dwarf_getlocation.c (dwarf_getlocation_addr): Add some unlikelys.
+       Delay CU base lookup until it's needed.
+       If CU base lookup fails with no error, flag invalid DWARF.
+
 2005-11-25  Roland McGrath  <roland@redhat.com>
 
        * libdw.map: Bump to 0.118; export dwfl_module_register_names.
index 4a75f97d8088241bafe56cb294753c6d249446be..e72913fffbaf117b7c8a3ad5c61d6a91eda477c7 100644 (file)
@@ -346,7 +346,7 @@ dwarf_getlocation_addr (attr, address, llbufs, listlens, maxlocs)
     }
 
   int error = INTUSE(dwarf_errno) ();
-  if (error != DWARF_E_NO_BLOCK)
+  if (unlikely (error != DWARF_E_NO_BLOCK))
     {
       __libdw_seterrno (error);
       return -1;
@@ -354,32 +354,17 @@ dwarf_getlocation_addr (attr, address, llbufs, listlens, maxlocs)
 
   /* Must have the form data4 or data8 which act as an offset.  */
   Dwarf_Word offset;
-  if (INTUSE(dwarf_formudata) (attr, &offset) != 0)
+  if (unlikely (INTUSE(dwarf_formudata) (attr, &offset) != 0))
     return -1;
 
   const Elf_Data *d = attr->cu->dbg->sectiondata[IDX_debug_loc];
-  if (d == NULL)
+  if (unlikely (d == NULL))
     {
       __libdw_seterrno (DWARF_E_NO_LOCLIST);
       return -1;
     }
 
-  /* Fetch the CU's base address.  */
-  Dwarf_Addr base;
-  Dwarf_Die cudie = CUDIE (attr->cu);
-
-  /* Find the base address of the compilation unit.  It will
-     normally be specified by DW_AT_low_pc.  In DWARF-3 draft 4,
-     the base address could be overridden by DW_AT_entry_pc.  It's
-     been removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc
-     for compilation units with discontinuous ranges.  */
-  Dwarf_Attribute attr_mem;
-  if (INTUSE(dwarf_lowpc) (&cudie, &base) != 0
-      && INTUSE(dwarf_formaddr) (INTUSE(dwarf_attr) (&cudie, DW_AT_entry_pc,
-                                                    &attr_mem),
-                                &base) != 0)
-    return -1;
-
+  Dwarf_Addr base = (Dwarf_Addr) -1;
   unsigned char *readp = d->d_buf + offset;
   size_t got = 0;
   while (got < maxlocs)
@@ -402,6 +387,8 @@ dwarf_getlocation_addr (attr, address, llbufs, listlens, maxlocs)
          if (begin == (Elf64_Addr) -1l) /* Base address entry.  */
            {
              base = end;
+             if (unlikely (base == (Dwarf_Addr) -1))
+               goto invalid;
              continue;
            }
        }
@@ -421,10 +408,7 @@ dwarf_getlocation_addr (attr, address, llbufs, listlens, maxlocs)
        break;
 
       if ((unsigned char *) d->d_buf + d->d_size - readp < 2)
-       {
-         __libdw_seterrno (DWARF_E_INVALID_DWARF);
-         return -1;
-       }
+       goto invalid;
 
       /* We have a location expression.  */
       block.length = read_2ubyte_unaligned_inc (attr->cu->dbg, readp);
@@ -434,12 +418,35 @@ dwarf_getlocation_addr (attr, address, llbufs, listlens, maxlocs)
        goto invalid;
       readp += block.length;
 
+      if (base == (Dwarf_Addr) -1)
+       {
+         /* Fetch the CU's base address.  */
+         Dwarf_Die cudie = CUDIE (attr->cu);
+
+         /* Find the base address of the compilation unit.  It will
+            normally be specified by DW_AT_low_pc.  In DWARF-3 draft 4,
+            the base address could be overridden by DW_AT_entry_pc.  It's
+            been removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc
+            for compilation units with discontinuous ranges.  */
+         Dwarf_Attribute attr_mem;
+         if (unlikely (INTUSE(dwarf_lowpc) (&cudie, &base) != 0)
+             && INTUSE(dwarf_formaddr) (INTUSE(dwarf_attr) (&cudie,
+                                                            DW_AT_entry_pc,
+                                                            &attr_mem),
+                                        &base) != 0)
+           {
+             if (INTUSE(dwarf_errno) () == 0)
+               goto invalid;
+             return -1;
+           }
+       }
+
       if (address >= base + begin && address < base + end)
        {
          /* This one matches the address.  */
          if (llbufs != NULL
-             && getlocation (attr->cu, &block,
-                             &llbufs[got], &listlens[got]) != 0)
+             && unlikely (getlocation (attr->cu, &block,
+                                       &llbufs[got], &listlens[got]) != 0))
            return -1;
          ++got;
        }