]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
Add dwarf_getsrc_relocatable.
authorRoland McGrath <roland@redhat.com>
Tue, 29 Jun 2010 07:21:10 +0000 (00:21 -0700)
committerRoland McGrath <roland@redhat.com>
Tue, 29 Jun 2010 07:21:10 +0000 (00:21 -0700)
libdw/ChangeLog
libdw/Makefile.am
libdw/dwarf_getsrc_die.c
libdw/dwarf_relocatable_info.c
libdw/libdw.h
libdw/libdw.map
libdw/libdwP.h

index 70e46a16e9b90385ab0fe475ff6ce4c8b4e8c4f1..023621f49b89cfd1d33ff8138d925ae0081ca459 100644 (file)
@@ -1,4 +1,12 @@
-2010-06-28  Roland McGrath  <roland@redhat.com>
+2010-06-29  Roland McGrath  <roland@redhat.com>
+
+       * dwarf_getsrc_relocatable.c: New file.
+       * Makefile.am (libdw_a_SOURCES): Add it.
+       * libdw.h: Declare it.
+       * libdw.map (ELFUTILS_0.149): Add it.
+
+       * dwarf_getsrc_die.c: Add INTDEF.
+       * libdwP.h: Add INTDECL.
 
        * libdwP.h (struct Dwarf_Lines_s): Change reloc member to int pointer.
        * dwarf_getsrclines.c (struct linelist): Add reloc/symndx/shndx members.
@@ -15,9 +23,9 @@
 
        * libdw.h (Dwarf_Relocatable): Use uint8_t for sec and form members.
        Add symndx member.
-       * dwarf_relocatable_info.c (relocatable_form): Take new arg SYMNDX.
-       If VALP is null, use SYMNDX instead of looking for a reloc.
-       (dwarf_relocatable_info): Update caller.
+       * dwarf_relocatable_info.c: Update RELOC with non-null valp to
+       one with a null valp, symndx set, and adjust section-relative.
+       If RELOC->valp is already null, use cached symndx.
 
 2010-06-24  Roland McGrath  <roland@redhat.com>
 
index e77ea5f4cb2adf42e274bec6933dade466c0bde2..719d1d5804b51d0595679337674aaddb6ed5c3f4 100644 (file)
@@ -88,7 +88,7 @@ libdw_a_SOURCES = dwarf_begin.c dwarf_begin_elf.c dwarf_end.c dwarf_getelf.c \
                  relocate.c dwarf_relocatable_info.c \
                  dwarf_form_relocatable.c dwarf_line_relocatable.c \
                  dwarf_ranges_relocatable.c dwarf_getlocation_relocatable.c \
-                 dwarf_haspc_relocatable.c
+                 dwarf_haspc_relocatable.c dwarf_getsrc_relocatable.c
 
 if MAINTAINER_MODE
 BUILT_SOURCES = $(srcdir)/known-dwarf.h
index 96aa41fdc9badf18e2bec3a569fef91851d1f4bf..f82ed5bfdd74e23f49f452759ea80782a64efa6e 100644 (file)
@@ -1,5 +1,5 @@
 /* Find line information for address.
-   Copyright (C) 2004, 2005 Red Hat, Inc.
+   Copyright (C) 2004-2010 Red Hat, Inc.
    This file is part of Red Hat elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2004.
 
@@ -97,3 +97,4 @@ dwarf_getsrc_die (Dwarf_Die *cudie, Dwarf_Addr addr)
   __libdw_seterrno (DWARF_E_ADDR_OUTOFRANGE);
   return NULL;
 }
+INTDEF (dwarf_getsrc_die)
index f4260e7729ba5b96d733967cf70a9b70d5c8be98..37868f62734cc8cdaebbeddaba63246c53cc6915 100644 (file)
 #include <dwarf.h>
 
 
-static int
-relocatable_form (struct Dwarf_CU *cu,
-                 uint_fast8_t sec_idx,
-                 uint_fast8_t form,
-                 const unsigned char *valp,
-                 int symndx,
-                 Dwarf_Addr adjust,
-                 GElf_Sym *sym, const char **name,
-                 GElf_Sxword *addend, const char **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;
+
   int width;
-  switch (form)
+  switch (reloc->form)
     {
     default:
       /* This can't be relocatable.  */
       if (addend != NULL)
        {
-         if (valp == NULL)
+         if (reloc->valp == NULL)
            *addend = 0;
          else
            {
              Dwarf_Attribute attr =
                {
-                 .cu = cu,
-                 .form = form,
-                 .valp = (unsigned char *) valp
+                 .cu = reloc->cu,
+                 .form = reloc->form,
+                 .valp = (unsigned char *) reloc->valp
                };
              if (INTUSE(dwarf_formsdata) (&attr, addend))
                return -1;
@@ -88,7 +89,7 @@ relocatable_form (struct Dwarf_CU *cu,
        }
     noreloc:
       if (addend != NULL)
-       *addend += adjust;
+       *addend += reloc->adjust;
       if (sym != NULL)
        *sym = (GElf_Sym) { .st_shndx = SHN_ABS };
       if (name != NULL)
@@ -98,7 +99,7 @@ relocatable_form (struct Dwarf_CU *cu,
       return 0;
 
     case DW_FORM_addr:
-      width = cu->address_size;
+      width = reloc->cu->address_size;
       break;
 
     case DW_FORM_data4:
@@ -110,29 +111,43 @@ relocatable_form (struct Dwarf_CU *cu,
       break;
     }
 
-  if (valp != NULL)
+  GElf_Sxword adjust = 0;
+  if (reloc->valp != NULL)
     {
-      int result = __libdw_relocatable (cu->dbg, sec_idx, valp, width,
-                                       &symndx, addend);
+      int result = __libdw_relocatable (reloc->cu->dbg, reloc->sec,
+                                       reloc->valp, width,
+                                       &reloc->symndx, &adjust);
       if (unlikely (result < 0))
        return result;
       if (result == 0)
-       goto noreloc;
+       {
+         reloc->valp = NULL;
+         reloc->adjust += adjust;
+         goto noreloc;
+       }
     }
 
-  struct dwarf_section_reloc *r = cu->dbg->relocate->sectionrel[sec_idx];
+  struct dwarf_section_reloc *const r
+    = reloc->cu->dbg->relocate->sectionrel[reloc->sec];
   GElf_Sym sym_mem;
   GElf_Word shndx;
   if (sym == NULL)
     sym = &sym_mem;
 
   if (unlikely (gelf_getsymshndx (r->symdata, r->symxndxdata,
-                                 symndx, sym, &shndx) == NULL))
+                                 reloc->symndx, sym, &shndx) == NULL))
     {
       __libdw_seterrno (DWARF_E_RELBADSYM);
       return -1;
     }
 
+  if (reloc->valp != NULL)
+    {
+      /* Turn the adjustment into a section-relative address.  */
+      reloc->valp = NULL;
+      reloc->adjust += sym->st_value + adjust;
+    }
+
   if (name != NULL)
     {
       if (sym->st_name == 0)
@@ -147,14 +162,9 @@ relocatable_form (struct Dwarf_CU *cu,
     }
 
   if (addend != NULL)
-    {
-      if (valp == NULL)
-       /* The ADJUST value was already section-relative, so we have to
-          remove the st_value portion of it.  */
-       *addend = adjust - sym->st_value;
-      else
-       *addend += adjust;
-    }
+    /* The adjustment is already section-relative, so we have to
+       remove the st_value portion of it.  */
+    *addend = reloc->adjust - sym->st_value;
 
   int result = (sym->st_shndx < SHN_LORESERVE ? sym->st_shndx
                : sym->st_shndx == SHN_XINDEX ? shndx : SHN_UNDEF);
@@ -174,41 +184,4 @@ relocatable_form (struct Dwarf_CU *cu,
 
   return result;
 }
-
-
-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->symndx, reloc->adjust,
-                          sym, name, addend, secname);
-}
 INTDEF (dwarf_relocatable_info)
-
-#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 c359e10f2c59cd76997ce9f445042c99a602cc13..2eaf95a27de613a98d1c2d88604624c5e82da60b 100644 (file)
@@ -626,6 +626,11 @@ extern int dwarf_getsrcfiles (Dwarf_Die *cudie, Dwarf_Files **files,
 /* Get source for address in CU.  */
 extern Dwarf_Line *dwarf_getsrc_die (Dwarf_Die *cudie, Dwarf_Addr addr);
 
+/* Get source for relocatable address in CU.  */
+extern Dwarf_Line *dwarf_getsrc_relocatable (Dwarf_Die *cudie,
+                                            Dwarf_Relocatable *reloc)
+     __nonnull_attribute__ (2);
+
 /* Get source for file and line number.  */
 extern int dwarf_getsrc_file (Dwarf *dbg, const char *fname, int line, int col,
                              Dwarf_Line ***srcsp, size_t *nsrcs)
index ff3638ea98c73b49f37838d41a680a5805fc1be8..86505b4bd6925bd49c567eb5a149302c5a93f9ed 100644 (file)
@@ -251,6 +251,7 @@ ELFUTILS_0.148 {
 ELFUTILS_0.149 {
   global:
     dwarf_form_relocatable;
+    dwarf_getsrc_relocatable;
     dwarf_line_relocatable;
     dwarf_getlocation_relocatable;
     dwarf_haspc_relocatable;
index f2886028c8f73ce309c6aa632c1a07c33c81be1c..3633a28afa63d7f2e7f16bff7f8a3ef282b4a8d2 100644 (file)
@@ -679,6 +679,7 @@ INTDECL (dwarf_getarangeinfo)
 INTDECL (dwarf_getaranges)
 INTDECL (dwarf_getsrcfiles)
 INTDECL (dwarf_getsrclines)
+INTDECL (dwarf_getsrc_die)
 INTDECL (dwarf_hasattr)
 INTDECL (dwarf_haschildren)
 INTDECL (dwarf_haspc)