]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
Rejigger relocatable libdw interface.
authorRoland McGrath <roland@redhat.com>
Tue, 22 Jun 2010 23:51:53 +0000 (16:51 -0700)
committerRoland McGrath <roland@redhat.com>
Tue, 22 Jun 2010 23:51:53 +0000 (16:51 -0700)
libdw/ChangeLog
libdw/Makefile.am
libdw/dwarf_form_relocatable.c
libdw/dwarf_line_relocatable.c [moved from libdw/dwarf_lineaddr_relocatable.c with 87% similarity]
libdw/dwarf_relocatable_info.c [new file with mode: 0644]
libdw/libdw.h
libdw/libdw.map
libdw/relocate.c

index 2fdc8bd90336fbad9e708be8cdf31f3ef960ba37..18afa68253608a53226f17391f4a5a979f0f3c0c 100644 (file)
@@ -1,5 +1,15 @@
 2010-06-22  Roland McGrath  <roland@redhat.com>
 
+       * libdw.h (Dwarf_Relocatable): New type.  Declare three new functions.
+       * dwarf_relocatable_info.c: New file.
+       * dwarf_form_relocatable.c: New file.
+       * dwarf_line_relocatable.c: New file.
+       * Makefile.am (libdw_a_SOURCES): Add them.
+       * libdw.map (ELFUTILS_0.149): New set; add those.
+
+       * relocate.c (__libdw_relocatable): New function.
+       * libdwP.h: Declare it.
+
        * dwarf_getsrclines.c: Fix signed comparison warning in extended
        opcode parsing.
 
 
 2010-06-21  Roland McGrath  <roland@redhat.com>
 
-       * relocate.c (__libdw_relocatable): New function.
-       * libdwP.h: Declare it.
-       * dwarf_form_relocatable.c: New file.
-       * dwarf_lineaddr_relocatable.c: New file.
-       * Makefile.am (libdw_a_SOURCES): Add them.
-       * libdw.map (ELFUTILS_0.149): New set; add those.
-       * libdw.h: Declare them.
-
        * libdwP.h (struct Dwarf_Line_s): Replace files with cu.
        (struct Dwarf_Lines_s): New member reloc.
        * dwarf_linesrc.c: Update usage.
index 067eec0d1ceb951b9c94f23c710edc7fca019a24..146d7f4428d8ed257a1c2d541f639a1c0f380c21 100644 (file)
@@ -85,8 +85,8 @@ libdw_a_SOURCES = dwarf_begin.c dwarf_begin_elf.c dwarf_end.c dwarf_getelf.c \
                  dwarf_cfi_addrframe.c \
                  dwarf_getcfi.c dwarf_getcfi_elf.c dwarf_cfi_end.c \
                  dwarf_aggregate_size.c \
-                 relocate.c \
-                 dwarf_form_relocatable.c dwarf_lineaddr_relocatable.c
+                 relocate.c dwarf_relocatable_info.c \
+                 dwarf_form_relocatable.c dwarf_line_relocatable.c
 
 if MAINTAINER_MODE
 BUILT_SOURCES = $(srcdir)/known-dwarf.h
index 588694c3cd89c2ff1a316375c4070d3b68f11186..3b2dc9c2d3285d1a4ad5df56e1b6d79d2314dcd0 100644 (file)
 
 
 int
-dwarf_form_relocatable (attr, sym, name, addend, secname)
+dwarf_form_relocatable (attr, reloc)
      Dwarf_Attribute *attr;
-     GElf_Sym *sym;
-     const char **name;
-     GElf_Sxword *addend;
-     const char **secname;
+     Dwarf_Relocatable *reloc;
 {
   if (attr == NULL)
     return -1;
 
-  int width;
-  switch (attr->form)
+  *reloc = (Dwarf_Relocatable)
     {
-    default:
-      return ((addend != NULL && INTUSE(dwarf_formsdata) (attr, addend)) ? -1
-             : __libdw_relocatable (attr->cu->dbg, IDX_last, NULL, 0,
-                                    sym, name, addend, 0, secname));
+      .sec = cu_sec_idx (attr->cu), .form = attr->form,
+      .cu = attr->cu, .valp = attr->valp,
+    };
 
-    case DW_FORM_addr:
-      width = attr->cu->address_size;
-      break;
-
-    case DW_FORM_data4:
-      width = 4;
-      break;
-
-    case DW_FORM_data8:
-      width = 8;
-      break;
-    }
-
-  return __libdw_relocatable (attr->cu->dbg, cu_sec_idx (attr->cu),
-                             attr->valp, width, sym, name, addend, 0, secname);
+  return 0;
 }
similarity index 87%
rename from libdw/dwarf_lineaddr_relocatable.c
rename to libdw/dwarf_line_relocatable.c
index c47ac6ef45fcc0de08922b67adc0a08075b8265c..a57422e96fd23891f23953cd9f5ad563a73e10f6 100644 (file)
 #endif
 
 #include "libdwP.h"
+#include <dwarf.h>
 
 
 int
-dwarf_lineaddr_relocatable (line, sym, name, addend, secname)
+dwarf_line_relocatable (line, reloc)
      Dwarf_Line *line;
-     GElf_Sym *sym;
-     const char **name;
-     GElf_Sxword *addend;
-     const char **secname;
+     Dwarf_Relocatable *reloc;
 {
   if (line == NULL)
     return -1;
 
-  return __libdw_relocatable (line->cu->dbg, IDX_debug_line,
-                             line->cu->lines->reloc == NULL ? NULL
-                             : line->cu->lines->reloc[line
-                                                      - line->cu->lines->info],
-                             line->cu->address_size, sym, name, addend,
-                             line->addr, secname);
+  *reloc = (Dwarf_Relocatable)
+    {
+      .sec = IDX_debug_line, .form = DW_FORM_addr,
+      .cu = line->cu,
+      .valp = (line->cu->lines->reloc == NULL ? NULL
+              : line->cu->lines->reloc[line - line->cu->lines->info]),
+      .adjust = line->addr
+    };
+
+  return 0;
 }
diff --git a/libdw/dwarf_relocatable_info.c b/libdw/dwarf_relocatable_info.c
new file mode 100644 (file)
index 0000000..67b28f5
--- /dev/null
@@ -0,0 +1,140 @@
+/* Return relocatable address from attribute.
+   Copyright (C) 2010 Red Hat, Inc.
+   This file is part of Red Hat elfutils.
+
+   Red Hat elfutils is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by the
+   Free Software Foundation; version 2 of the License.
+
+   Red Hat elfutils is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along
+   with Red Hat elfutils; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
+
+   In addition, as a special exception, Red Hat, Inc. gives You the
+   additional right to link the code of Red Hat elfutils with code licensed
+   under any Open Source Initiative certified open source license
+   (http://www.opensource.org/licenses/index.php) which requires the
+   distribution of source code with any binary distribution and to
+   distribute linked combinations of the two.  Non-GPL Code permitted under
+   this exception must only link to the code of Red Hat elfutils through
+   those well defined interfaces identified in the file named EXCEPTION
+   found in the source code files (the "Approved Interfaces").  The files
+   of Non-GPL Code may instantiate templates or use macros or inline
+   functions from the Approved Interfaces without causing the resulting
+   work to be covered by the GNU General Public License.  Only Red Hat,
+   Inc. may make changes or additions to the list of Approved Interfaces.
+   Red Hat's grant of this exception is conditioned upon your not adding
+   any new exceptions.  If you wish to add a new Approved Interface or
+   exception, please contact Red Hat.  You must obey the GNU General Public
+   License in all respects for all of the Red Hat elfutils code and other
+   code used in conjunction with Red Hat elfutils except the Non-GPL Code
+   covered by this exception.  If you modify this file, you may extend this
+   exception to your version of the file, but you are not obligated to do
+   so.  If you do not wish to provide this exception without modification,
+   you must delete this exception statement from your version and license
+   this file solely under the GPL without exception.
+
+   Red Hat elfutils is an included package of the Open Invention Network.
+   An included package of the Open Invention Network is a package for which
+   Open Invention Network licensees cross-license their patents.  No patent
+   license is granted, either expressly or impliedly, by designation as an
+   included package.  Should you wish to participate in the Open Invention
+   Network licensing program, please visit www.openinventionnetwork.com
+   <http://www.openinventionnetwork.com>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+#include <dwarf.h>
+
+static int
+relocatable_form (struct Dwarf_CU *cu,
+                 unsigned int sec_idx,
+                 unsigned int form,
+                 const unsigned char *valp,
+                 Dwarf_Addr adjust,
+                 GElf_Sym *sym, const char **name,
+                 GElf_Sxword *addend, const char **secname)
+{
+  int width;
+  switch (form)
+    {
+    default:
+      /* This can't be relocatable.  We'll let __libdw_relocatable
+        fill in the SHN_ABS indicator for the constant 0 base.  */
+      if (addend != NULL)
+       {
+         Dwarf_Attribute attr =
+           {
+             .cu = cu,
+             .form = form,
+             .valp = (unsigned char *) valp
+           };
+         if (INTUSE(dwarf_formsdata) (&attr, addend))
+           return -1;
+         *addend += adjust;
+         addend = NULL;
+       }
+      width = 0;
+      valp = NULL;
+      break;
+
+    case DW_FORM_addr:
+      width = cu->address_size;
+      break;
+
+    case DW_FORM_data4:
+      width = 4;
+      break;
+
+    case DW_FORM_data8:
+      width = 8;
+      break;
+    }
+
+  return __libdw_relocatable (cu->dbg, sec_idx, valp, width,
+                             sym, name, addend, adjust, secname);
+}
+
+int
+dwarf_relocatable_info (reloc, sym, name, addend, secname)
+     Dwarf_Relocatable *reloc;
+     GElf_Sym *sym;
+     const char **name;
+     GElf_Sxword *addend;
+     const char **secname;
+{
+  if (reloc == NULL)
+    return -1;
+
+  return relocatable_form (reloc->cu, reloc->sec,
+                          reloc->form, reloc->valp, reloc->adjust,
+                          sym, name, addend, secname);
+}
+
+#if 0
+/* Shorthand for dwarf_relocatable_info(dwarf_form_relocatable).  */
+
+int
+dwarf_form_relocatable_info (attr, sym, name, addend, secname)
+     Dwarf_Attribute *attr;
+     GElf_Sym *sym;
+     const char **name;
+     GElf_Sxword *addend;
+     const char **secname;
+{
+  if (attr == NULL)
+    return -1;
+
+  return relocatable_form (attr->cu, cu_sec_idx (attr->cu),
+                          attr->form, attr->valp, 0,
+                          sym, name, addend, secname);
+}
+#endif
index 2726fac437129198d100f557ea59a7a532fa1678..f55be48a419c31bd9605cc255b2e2dc7c2180155 100644 (file)
@@ -137,6 +137,7 @@ struct Dwarf_CU;
 /* Macro information.  */
 typedef struct Dwarf_Macro_s Dwarf_Macro;
 
+
 /* Attribute representation.  */
 typedef struct
 {
@@ -147,6 +148,17 @@ typedef struct
 } Dwarf_Attribute;
 
 
+/* Relocatable address representation.  */
+typedef struct
+{
+  unsigned int sec;
+  unsigned int form;
+  const unsigned char *valp;
+  struct Dwarf_CU *cu;
+  Dwarf_Addr adjust;
+} Dwarf_Relocatable;
+
+
 /* Data block representation.  */
 typedef struct
 {
@@ -445,6 +457,11 @@ extern int dwarf_formsdata (Dwarf_Attribute *attr, Dwarf_Sword *return_uval)
 extern int dwarf_formaddr (Dwarf_Attribute *attr, Dwarf_Addr *return_addr)
      __nonnull_attribute__ (2);
 
+/* Return relocatable address represented by attribute.  */
+extern int dwarf_form_relocatable (Dwarf_Attribute *attr,
+                                  Dwarf_Relocatable *return_reloc)
+     __nonnull_attribute__ (2);
+
 /* This function is deprecated.  Always use dwarf_formref_die instead.
    Return reference offset represented by attribute.  */
 extern int dwarf_formref (Dwarf_Attribute *attr, Dwarf_Off *return_offset)
@@ -512,38 +529,32 @@ extern int dwarf_arrayorder (Dwarf_Die *die);
 extern int dwarf_srclang (Dwarf_Die *die);
 
 
-/* Relocatable address access functions.
+/* Relocatable address access functions.  */
 
-   These retrieve an address that might require relocation in an ET_REL
-   file.  They return -1 for errors.  If successful, they fill in SYM
+/* A Dwarf_Relocatable represents an address that might require
+   relocation in an ET_REL file.  Return the relocation details for
+   that address.  Returns -1 for errors.  If successful, fills in SYM
    (if not null) with the ELF symbol describing the address fetched.
 
    If the symbol refers to a normal section, the return value is that
    section index (which might be above SHN_LORESERVE).  If the symbol
    does not refer to a normal section, the return value is zero and
-   SYM->st_shndx has a special SHN_* value.  If SECNAME is not null, it
-   is filled with the name of the symbol's section if available, or NULL
-   if not available (or for a special st_shndx).
+   SYM->st_shndx has a special SHN_* value.  If SECNAME is not null,
+   it is filled with the name of the symbol's section if available, or
+   NULL if not available (or for a special st_shndx).
 
-   If NAME is not null, it is filled with the symbol name, or with NULL
-   if there is no named symbol involved.  If ADDEND is not null, it is
-   filled with the offset relative to that symbol.
+   If NAME is not null, it is filled with the symbol name, or with
+   NULL if there is no named symbol involved.  If ADDEND is not null,
+   it is filled with the offset relative to that symbol.
 
    An address that required no relocation appears as a SHN_ABS symbol
    with st_value 0 and the whole address in the addend.  */
 
-/* Like dwarf_formaddr, but as described above.  */
-extern int dwarf_form_relocatable (Dwarf_Attribute *attr,
+extern int dwarf_relocatable_info (Dwarf_Relocatable *reloc,
                                   GElf_Sym *sym, const char **name,
                                   GElf_Sxword *addend,
                                   const char **secname);
 
-/* Like dwarf_lineaddr, but as described above.  */
-extern int dwarf_lineaddr_relocatable (Dwarf_Line *line,
-                                      GElf_Sym *sym, const char **name,
-                                      GElf_Sxword *addend,
-                                      const char **secname);
-
 
 /* Get abbreviation at given offset for given DIE.  */
 extern Dwarf_Abbrev *dwarf_getabbrev (Dwarf_Die *die, Dwarf_Off offset,
@@ -611,6 +622,9 @@ extern int dwarf_getsrc_file (Dwarf *dbg, const char *fname, int line, int col,
 /* Return line address.  */
 extern int dwarf_lineaddr (Dwarf_Line *line, Dwarf_Addr *addrp);
 
+/* Return line address in relocatable form.  */
+extern int dwarf_line_relocatable (Dwarf_Line *line, Dwarf_Relocatable *relocp);
+
 /* Return line VLIW operation index.  */
 extern int dwarf_lineop_index (Dwarf_Line *line, unsigned int *op_indexp);
 
index d3d51af3e0b9dbcde1846bb1648135c6e7282f4d..ff530702ebf167d9c109b78b12a35258134f7f18 100644 (file)
@@ -253,5 +253,6 @@ ELFUTILS_0.148 {
 ELFUTILS_0.149 {
   global:
     dwarf_form_relocatable;
-    dwarf_lineaddr_relocatable;
+    dwarf_line_relocatable;
+    dwarf_relocatable_info;
 } ELFUTILS_0.148;
index 1a27a71aada7c9d89a80a35339ce47925bfee268..195687390d9540af018cf8433da5b539d6231e65 100644 (file)
@@ -552,8 +552,9 @@ __libdw_relocatable (Dwarf *dbg, int sec_idx,
                     GElf_Sym *sym, const char **name, GElf_Sxword *addend,
                     GElf_Sxword offset, const char **secname)
 {
-  struct dwarf_section_reloc *const r
-    = dbg->relocate != NULL ? dbg->relocate->sectionrel[sec_idx] : NULL;
+  struct dwarf_section_reloc *const r = ((valp != NULL && dbg->relocate != NULL)
+                                        ? dbg->relocate->sectionrel[sec_idx]
+                                        : NULL);
   int symndx;
   int result = relocatable_datum (dbg, sec_idx, r, valp, width,
                                  &symndx, addend);