]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
Introduce __libdw_read_udata_address
authorPetr Machata <pmachata@redhat.com>
Tue, 5 May 2009 00:53:40 +0000 (02:53 +0200)
committerPetr Machata <pmachata@redhat.com>
Tue, 5 May 2009 00:53:40 +0000 (02:53 +0200)
* the use in dwarf_ranges is iffy, there's a functionality mismatch.
  Need to find some better way

libdw/ChangeLog
libdw/dwarf_formudata.c
libdw/dwarf_getlocation.c
libdw/dwarf_getsrclines.c
libdw/dwarf_ranges.c
libdw/libdwP.h

index 39b190f1724dae30cd9a1f533a6f9281485c9e67..abea245a0b16d72ae12b84ebc53160200cf2e5e1 100644 (file)
@@ -1,3 +1,12 @@
+2009-05-05  Petr Machata  <pmachata@redhat.com>
+
+       * libdwP.h (__libdw_read_udata_addr): Declare new function.
+       * dwarf_formudata.c: Implement it here.
+       * dwarf_getlocation.c (dwarf_getlocation_addr):
+       Call it instead of hand-rolled offset handling code.
+       * dwarf_getsrclines.c (dwarf_getsrclines): Likewise.
+       * dwarf_ranges.c (dwarf_ranges): Likewise.
+
 2009-05-04  Petr Machata  <pmachata@redhat.com>
 
        * libdwP.h (__libdw_read_begin_end_pair_inc): Declare new function.
index b346afb388e80d4aaf0e3014eae8886fe101aba2..71a5e967fc9464f3ba51dae76acd28345011b5fc 100644 (file)
 #include <dwarf.h>
 #include "libdwP.h"
 
+internal_function unsigned char *
+__libdw_read_udata_addr (Dwarf_Attribute *attr, int sec_index,
+                        int err_nodata, unsigned char **endpp)
+{
+  if (attr == NULL)
+    return NULL;
+
+  Dwarf_Word offset;
+  switch (attr->form)
+    {
+    case DW_FORM_data4:
+    case DW_FORM_data8:
+      if (__libdw_read_address (attr->cu->dbg, IDX_debug_info, attr->valp,
+                               attr->form == DW_FORM_data4 ? 4 : 8,
+                               &offset))
+       return NULL;
+      break;
+
+    default:
+      __libdw_seterrno (DWARF_E_INVALID_DWARF);
+      return NULL;
+    };
+
+  const Elf_Data *d = attr->cu->dbg->sectiondata[sec_index];
+  if (unlikely (d == NULL))
+    {
+    invalid:
+      __libdw_seterrno (err_nodata);
+      return NULL;
+    }
+
+  unsigned char *readp = d->d_buf + offset;
+  unsigned char *endp = d->d_buf + d->d_size;
+  if (readp >= endp)
+    goto invalid;
+
+  *endpp = endp;
+  return readp;
+}
 
 int
 dwarf_formudata (attr, return_uval)
@@ -77,11 +116,11 @@ dwarf_formudata (attr, return_uval)
       break;
 
     case DW_FORM_data4:
+      *return_uval = read_4ubyte_unaligned (attr->cu->dbg, attr->valp);
+      break;
+
     case DW_FORM_data8:
-      if (__libdw_read_address (attr->cu->dbg, IDX_debug_info, attr->valp,
-                               attr->form == DW_FORM_data4 ? 4 : 8,
-                               return_uval))
-       return -1;
+      *return_uval = read_8ubyte_unaligned (attr->cu->dbg, attr->valp);
       break;
 
     case DW_FORM_sdata:
index 95ad5259c14f2a2711db2629d75b8695a2500f13..3480f3ddcf7205289fa9d276e96068ee2dc3ba5e 100644 (file)
@@ -378,25 +378,17 @@ dwarf_getlocation_addr (attr, address, llbufs, listlens, maxlocs)
       return -1;
     }
 
-  /* Must have the form data4 or data8 which act as an offset.  */
-  Dwarf_Word offset;
-  if (unlikely (INTUSE(dwarf_formudata) (attr, &offset) != 0))
+  unsigned char *endp, *readp
+    = __libdw_read_udata_addr (attr, IDX_debug_loc,
+                              DWARF_E_NO_LOCLIST, &endp);
+  if (readp == NULL)
     return -1;
 
-  const Elf_Data *d = attr->cu->dbg->sectiondata[IDX_debug_loc];
-  if (unlikely (d == NULL))
-    {
-      __libdw_seterrno (DWARF_E_NO_LOCLIST);
-      return -1;
-    }
-
   Dwarf_Addr base = (Dwarf_Addr) -1;
-  unsigned char *readp = d->d_buf + offset;
   size_t got = 0;
   while (got < maxlocs)
     {
-      if ((unsigned char *) d->d_buf + d->d_size - readp
-         < attr->cu->address_size * 2)
+      if (endp - readp < attr->cu->address_size * 2)
        {
        invalid:
          __libdw_seterrno (DWARF_E_INVALID_DWARF);
@@ -417,14 +409,13 @@ dwarf_getlocation_addr (attr, address, llbufs, listlens, maxlocs)
       else if (status < 0)
        return status;
 
-      if ((unsigned char *) d->d_buf + d->d_size - readp < 2)
+      if (endp - readp < 2)
        goto invalid;
 
       /* We have a location expression.  */
       block.length = read_2ubyte_unaligned_inc (attr->cu->dbg, readp);
       block.data = readp;
-      if ((unsigned char *) d->d_buf + d->d_size - readp
-         < (ptrdiff_t) block.length)
+      if (endp - readp < (ptrdiff_t) block.length)
        goto invalid;
       readp += block.length;
 
index 67b62aacf9df968e87b9aac23166dee1e4525857..df510e1dd8d3a7bb4c9c565d46f796644bca1c73 100644 (file)
@@ -135,20 +135,13 @@ dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines)
 
       /* Get the offset into the .debug_line section.  NB: this call
         also checks whether the previous dwarf_attr call failed.  */
-      Dwarf_Word offset;
-      if (INTUSE(dwarf_formudata) (stmt_list, &offset) != 0)
+      const unsigned char *lineendp, *linep
+       = __libdw_read_udata_addr (stmt_list, IDX_debug_line,
+                                  DWARF_E_NO_DEBUG_LINE,
+                                  (unsigned char **) &lineendp);
+      if (linep == NULL)
        goto out;
 
-      Dwarf *dbg = cu->dbg;
-      if (dbg->sectiondata[IDX_debug_line] == NULL)
-       {
-         __libdw_seterrno (DWARF_E_NO_DEBUG_LINE);
-         goto out;
-       }
-      const uint8_t *linep = dbg->sectiondata[IDX_debug_line]->d_buf + offset;
-      const uint8_t *lineendp = (dbg->sectiondata[IDX_debug_line]->d_buf
-                                + dbg->sectiondata[IDX_debug_line]->d_size);
-
       /* Get the compilation directory.  */
       Dwarf_Attribute compdir_attr_mem;
       Dwarf_Attribute *compdir_attr = INTUSE(dwarf_attr) (cudie,
@@ -162,6 +155,8 @@ dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines)
          __libdw_seterrno (DWARF_E_INVALID_DEBUG_LINE);
          goto out;
        }
+
+      Dwarf *dbg = cu->dbg;
       Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep);
       unsigned int length = 4;
       if (unlikely (unit_length == DWARF3_LENGTH_64_BIT))
index ccb4f6b7c53f00fc462b63ee228846d050d66f42..875068cb4c474b041f8323aff61e6fb4a92f8302 100644 (file)
@@ -125,11 +125,11 @@ dwarf_ranges (Dwarf_Die *die, ptrdiff_t offset, Dwarf_Addr *basep,
   const Elf_Data *d = die->cu->dbg->sectiondata[IDX_debug_ranges];
   if (d == NULL && offset != 0)
     {
-    no_ranges:
       __libdw_seterrno (DWARF_E_NO_DEBUG_RANGES);
       return -1;
     }
 
+  unsigned char *readp, *readendp;
   if (offset == 0)
     {
       Dwarf_Attribute attr_mem;
@@ -139,13 +139,12 @@ dwarf_ranges (Dwarf_Die *die, ptrdiff_t offset, Dwarf_Addr *basep,
        /* No PC attributes in this DIE at all, so an empty range list.  */
        return 0;
 
-      /* Must have the form data4 or data8 which act as an offset.  */
-      Dwarf_Word start_offset;
-      if (INTUSE(dwarf_formudata) (attr, &start_offset) != 0)
+      if ((readp = __libdw_read_udata_addr (attr, IDX_debug_ranges,
+                                           DWARF_E_NO_DEBUG_RANGES,
+                                           &readendp)) == NULL)
        return -1;
 
-      if (d == NULL)
-       goto no_ranges;
+      Dwarf_Word start_offset = (void *) readp - d->d_buf;
 
       offset = start_offset;
       assert ((Dwarf_Word) offset == start_offset);
@@ -172,17 +171,20 @@ dwarf_ranges (Dwarf_Die *die, ptrdiff_t offset, Dwarf_Addr *basep,
          return -1;
        }
     }
-  else if (offset < 0 || (size_t) offset >= d->d_size)
+  else
     {
-      __libdw_seterrno (DWARF_E_INVALID_OFFSET);
-      return -1l;
-    }
+      if (offset < 0 || (size_t) offset >= d->d_size)
+       {
+         __libdw_seterrno (DWARF_E_INVALID_OFFSET);
+         return -1l;
+       }
 
-  unsigned char *readp = d->d_buf + offset;
+      readp = d->d_buf + offset;
+      readendp = d->d_buf + d->d_size;
+    }
 
  next:
-  if ((unsigned char *) d->d_buf + d->d_size - readp
-      < die->cu->address_size * 2)
+  if (readendp - readp < die->cu->address_size * 2)
     goto invalid;
 
   Dwarf_Addr begin;
index be0b99a8e2961cbda7fa94654867852361747a7d..16b19c6f7751a357f1228bda4e85508f8fc58bbb 100644 (file)
@@ -510,6 +510,11 @@ __libdw_read_begin_end_pair_inc (Dwarf *dbg, int sec_index,
                                 Dwarf_Addr *basep)
   internal_function;
 
+unsigned char *
+__libdw_read_udata_addr (Dwarf_Attribute *attr, int sec_index,
+                        int err_nodata, unsigned char **endpp)
+  internal_function;
+
 static inline int
 __libdw_read_address (Dwarf *dbg,
                      int sec_index, const unsigned char *addr,