]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
Rewrites in read hooks
authorPetr Machata <pmachata@redhat.com>
Mon, 27 Apr 2009 16:53:06 +0000 (18:53 +0200)
committerPetr Machata <pmachata@redhat.com>
Mon, 27 Apr 2009 16:53:06 +0000 (18:53 +0200)
* Have the checking and reading logic itself in the header so that it gets
  optimized out/inlined.  Call external relocating hook from there, there
  will presumably be more work to do, and we presumably don't want to keep
  this in the header.

libdw/Makefile.am
libdw/dwarf_formaddr.c
libdw/dwarf_formref_die.c
libdw/dwarf_getlocation.c
libdw/dwarf_getpubnames.c
libdw/libdwP.h
libdw/libdw_readhooks.c [moved from libdw/dwarf_readhooks.c with 73% similarity]

index 6d8d533f73fdb89b896add3fdf164009182273d1..3ccd41e3630e0f9904a8adb60a61f71188f154d1 100644 (file)
@@ -83,7 +83,7 @@ libdw_a_SOURCES = dwarf_begin.c dwarf_begin_elf.c dwarf_end.c dwarf_getelf.c \
                  dwarf_func_inline.c dwarf_getsrc_file.c \
                  libdw_findcu.c libdw_form.c libdw_alloc.c memory-access.c \
                  libdw_visit_scopes.c \
-                 dwarf_entry_breakpoints.c dwarf_readhooks.c
+                 dwarf_entry_breakpoints.c libdw_readhooks.c
 
 if MAINTAINER_MODE
 BUILT_SOURCES = $(srcdir)/known-dwarf.h
index aff549155b006aa9cd70c9ba3de37090a370654b..9938be7e2d5621dc214f0ca80c82aee00d195dfc 100644 (file)
@@ -70,9 +70,10 @@ dwarf_formaddr (attr, return_addr)
       return -1;
     }
 
-  if (__libdw_read_addr (attr->cu->dbg, return_addr, attr->valp,
-                        attr->cu->address_size == 8))
-    return -1l;
+  if (__libdw_read_address (attr->cu->dbg,
+                           IDX_debug_info, attr->valp,
+                           attr->cu->address_size, return_addr))
+    return -1;
 
   return 0;
 }
index 3bd89fc1396f4f80836c83c0f3f94eaa599a2887..128ee137d08b3423f12018ada3785b114895f1df 100644 (file)
@@ -72,8 +72,9 @@ dwarf_formref_die (attr, die_mem)
                          ? attr->cu->address_size
                          : attr->cu->offset_size);
 
-      if (__libdw_read_addr (attr->cu->dbg, &offset,
-                            attr->valp, ref_size == 8))
+      if (__libdw_read_address (attr->cu->dbg,
+                               IDX_debug_info, attr->valp,
+                               ref_size, &offset))
        return NULL;
     }
   else
index 5df8cc6f1501b1b66b0ed96570e24ef63cf3b2e4..77f70ab96809216e4cd2c68fb48c78a1484978f2 100644 (file)
@@ -415,11 +415,14 @@ dwarf_getlocation_addr (attr, address, llbufs, listlens, maxlocs)
 
       Dwarf_Addr begin;
       Dwarf_Addr end;
-      bool addr64 = attr->cu->address_size == 8;
-      Dwarf_Addr escape = addr64 ? (Elf64_Addr)-1 : (Elf64_Addr)(Elf32_Addr)-1;
-
-      if (__libdw_read_addr_inc (attr->cu->dbg, &begin, &readp, addr64)
-         || __libdw_read_addr_inc (attr->cu->dbg, &end, &readp, addr64))
+      Dwarf_Addr escape = ADDR_ESCAPE (attr->cu->address_size);
+
+      if (__libdw_read_address_inc (attr->cu->dbg,
+                                   IDX_debug_line, &readp,
+                                   attr->cu->address_size, &begin)
+         || __libdw_read_address_inc (attr->cu->dbg,
+                                      IDX_debug_line, &readp,
+                                      attr->cu->address_size, &end))
        goto invalid;
 
       if (begin == escape)
index 2ad0e22cbaed56ed16556a271036286b42677e49..f8f34c50f4261992a855599ce5c7cc493989d5aa 100644 (file)
@@ -124,8 +124,8 @@ get_offsets (Dwarf *dbg)
        }
 
       /* Get the CU offset.  */
-      if (__libdw_read_addr (dbg, &mem[cnt].cu_offset,
-                            readp + 2, len_bytes == 8))
+      if (__libdw_read_address (dbg, IDX_debug_pubnames, readp + 2, len_bytes,
+                               &mem[cnt].cu_offset))
        /* Error has been already set in reader.  */
        goto err_return;
 
@@ -222,8 +222,9 @@ dwarf_getpubnames (dbg, callback, arg, offset)
       while (1)
        {
          /* READP points to the next offset/name pair.  */
-         if (__libdw_read_addr_inc (dbg, &gl.die_offset, &readp,
-                                    dbg->pubnames_sets[cnt].address_len == 8))
+         if (__libdw_read_address_inc (dbg, IDX_debug_pubnames, &readp,
+                                       dbg->pubnames_sets[cnt].address_len,
+                                       &gl.die_offset))
            return -1l;
 
          /* If the offset is zero we reached the end of the set.  */
index 79321343102cd9b83ad0f5b0805fdbd5b0fe65ec..fb9045f06748cfbd919723c2b12eb51ee57ab906 100644 (file)
@@ -53,6 +53,7 @@
 
 #include <libintl.h>
 #include <stdbool.h>
+#include <assert.h>
 
 #include <libdw.h>
 
@@ -421,27 +422,93 @@ extern int __dwarf_errno_internal (void);
 
 /* Reader hooks.  */
 
+static inline int
+__libdw_in_section (Dwarf *dbg, int sec_index,
+                   unsigned char *addr, int width)
+{
+  Elf_Data *data = dbg->sectiondata[sec_index];
 
-int __libdw_read_addr_inc (Dwarf *dbg, Dwarf_Word *ret,
-                          unsigned char **addr,
-                          bool addr64)
-  internal_function;
+  if ((void *)addr < data->d_buf
+      || (void *)addr + width > data->d_buf + data->d_size)
+    {
+      __libdw_seterrno (DWARF_E_INVALID_OFFSET);
+      return 1;
+    }
 
-int __libdw_read_off_inc (Dwarf *dbg, Dwarf_Word *ret,
-                         int sec_index, Dwarf_Word *offset,
-                         bool addr64)
-  internal_function;
+  return 0;
+}
 
-int __libdw_read_addr (Dwarf *dbg, Dwarf_Word *ret,
-                      unsigned char *addr,
-                      bool addr64)
+int __libdw_relocate_address (Dwarf *dbg,
+                             int sec_index, uintptr_t addr,
+                             int width, Dwarf_Addr *val)
   internal_function;
 
-int __libdw_read_off (Dwarf *dbg, Dwarf_Word *ret,
-                     int sec_index, Dwarf_Word offset,
-                     bool addr64)
+int __libdw_relocate_offset (Dwarf *dbg,
+                            int sec_index, uintptr_t addr,
+                            int width, Dwarf_Addr *val)
   internal_function;
 
+#define READ_AND_RELOCATE(RELOC_HOOK)                                  \
+  {                                                                    \
+    int status;                                                                \
+    if ((status = __libdw_in_section (dbg, sec_index, *addr, width)))  \
+      return status;                                                   \
+                                                                       \
+    uintptr_t addr0 = (uintptr_t)*addr;                                        \
+    Dwarf_Addr val;                                                    \
+                                                                       \
+    if (width == 4)                                                    \
+      val = read_4ubyte_unaligned_inc (dbg, *addr);                    \
+    else                                                               \
+      {                                                                        \
+       assert (width == 8);                                            \
+       val = read_8ubyte_unaligned_inc (dbg, *addr);                   \
+      }                                                                        \
+                                                                       \
+    if ((status = RELOC_HOOK (dbg, sec_index, addr0, width, &val)))    \
+      return status;                                                   \
+                                                                       \
+    *ret = val;                                                                \
+    return 0;                                                          \
+  }
+
+static inline int
+__libdw_read_address_inc (Dwarf *dbg,
+                         int sec_index, unsigned char **addr,
+                         int width, Dwarf_Addr *ret)
+{
+  READ_AND_RELOCATE (__libdw_relocate_address)
+}
+
+static inline int
+__libdw_read_offset_inc (Dwarf *dbg,
+                        int sec_index, unsigned char **addr,
+                        int width, Dwarf_Addr *ret)
+{
+  READ_AND_RELOCATE (__libdw_relocate_offset)
+}
+
+#undef READ_AND_RELOCATE
+
+static inline int
+__libdw_read_address (Dwarf *dbg,
+                     int sec_index, unsigned char *addr,
+                     int width, Dwarf_Addr *ret)
+{
+  return __libdw_read_address_inc (dbg, sec_index, &addr, width, ret);
+}
+
+static inline int
+__libdw_read_offset (Dwarf *dbg,
+                    int sec_index, unsigned char *addr,
+                    int width, Dwarf_Addr *ret)
+{
+  return __libdw_read_offset_inc (dbg, sec_index, &addr, width, ret);
+}
+
+#define ADDR_ESCAPE(width) \
+  (width == 8 ? (Elf64_Addr)-1 : (Elf64_Addr)(Elf32_Addr)-1)
+
 
 
 /* Aliases to avoid PLTs.  */
similarity index 73%
rename from libdw/dwarf_readhooks.c
rename to libdw/libdw_readhooks.c
index 705a97309ad45d6eedafc3a42d65d743aa869f65..20a5e1e88bb3537e1e1921c9eead03ecba9ef131 100644 (file)
 # include <config.h>
 #endif
 
-#include <dwarf.h>
 #include "libdwP.h"
 
-int
-__libdw_read_addr_inc (Dwarf *dbg, Dwarf_Word *ret,
-                      unsigned char **addr,
-                      bool addr64)
+internal_function int
+__libdw_relocate_address (Dwarf *dbg __attribute__ ((unused)),
+                         int sec_index __attribute__ ((unused)),
+                         uintptr_t addr __attribute__ ((unused)),
+                         int width __attribute__ ((unused)),
+                         Dwarf_Addr *val __attribute__ ((unused)))
 {
-  if (addr64)
-    *ret = read_8ubyte_unaligned_inc (dbg, *addr);
-  else
-    *ret = read_4ubyte_unaligned_inc (dbg, *addr);
   return 0;
 }
 
-int
-__libdw_read_off_inc (Dwarf *dbg, Dwarf_Word *ret,
-                     int sec_index, Dwarf_Word *offset,
-                     bool addr64)
+internal_function int
+__libdw_relocate_offset (Dwarf *dbg __attribute__ ((unused)),
+                        int sec_index __attribute__ ((unused)),
+                        uintptr_t addr __attribute__ ((unused)),
+                        int width __attribute__ ((unused)),
+                        Dwarf_Addr *val __attribute__ ((unused)))
 {
-  Elf_Data *data = dbg->sectiondata[sec_index];
-  if (*offset >= data->d_size
-      || *offset + addr64 ? 8 : 4 >= data->d_size)
-    {
-      __libdw_seterrno (DWARF_E_INVALID_OFFSET);
-      return 1;
-    }
-
-  unsigned char *buf = data->d_buf;
-  unsigned char *addr = buf + *offset;
-  int status = __libdw_read_addr_inc (dbg, ret, &addr, addr64);
-  *offset = addr - buf;
-  return status;
-}
-
-int
-__libdw_read_addr (Dwarf *dbg, Dwarf_Word *ret,
-                  unsigned char *addr,
-                  bool addr64)
-{
-  return __libdw_read_addr_inc (dbg, ret, &addr, addr64);
-}
-
-int
-__libdw_read_off (Dwarf *dbg, Dwarf_Word *ret,
-                 int sec_index, Dwarf_Word offset,
-                 bool addr64)
-{
-  return __libdw_read_off_inc (dbg, ret, sec_index, &offset, addr64);
+  return 0;
 }