]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
propagate from branch 'com.redhat.elfutils.roland.pending' (head 1ac619debea0e3ecfd27...
authorUlrich Drepper <drepper@redhat.com>
Wed, 12 Jul 2006 07:46:03 +0000 (07:46 +0000)
committerUlrich Drepper <drepper@redhat.com>
Wed, 12 Jul 2006 07:46:03 +0000 (07:46 +0000)
            to branch 'com.redhat.elfutils' (head 830d38d0a2ce24911160a871963f093209e69d9e)

18 files changed:
NEWS
libdw/ChangeLog
libdw/libdw.map
libdwfl/ChangeLog
libdwfl/Makefile.am
libdwfl/dwfl_line_comp_dir.c [new file with mode: 0644]
libdwfl/dwfl_linecu.c [new file with mode: 0644]
libdwfl/dwfl_lineinfo.c
libdwfl/dwfl_module.c
libdwfl/dwfl_module_addrname.c [new file with mode: 0644]
libdwfl/dwfl_module_getdwarf.c
libdwfl/dwfl_module_getsym.c [new file with mode: 0644]
libdwfl/dwfl_module_return_value_location.c
libdwfl/libdwfl.h
libdwfl/libdwflP.h
libdwfl/relocate.c
src/ChangeLog
src/addr2line.c

diff --git a/NEWS b/NEWS
index 2edfbb30bcc9dd2e011db4ca5ed53028bcf9e50b..a4d7c98812af0069908d98a4e7a9ad9534715c58 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,7 @@
 Version 0.122:
 
+libdwfl: New functions dwfl_module_getsymtab, dwfl_module_getsym.
+
 libebl:add function to test for relative relocation
 
 elflint: fix and extend DT_RELCOUNT/DT_RELACOUNT checks
index 95312497d8d4337b5983376bbe0d923cfe8eb832..d1b2dc6dbd0dd737bfda0a625c5468374d4e139e 100644 (file)
@@ -1,3 +1,10 @@
+2006-06-28  Roland McGrath  <roland@redhat.com>
+
+       * libdw.map: Export dwfl_linecu, dwfl_line_comp_dir.
+
+       * libdw.map: Bump to 0.122; export dwfl_module_getsymtab and
+       dwfl_module_getsym.
+
 2006-05-27  Ulrich Drepper  <drepper@redhat.com>
 
        * libdw.h: Add extern "C".
index 08b01982fa8dd4bbd58cf7cbcbaf4ce4c8061c6a..6ee42ece5d3c278e650913092bd2368d78ced73a 100644 (file)
@@ -1,5 +1,5 @@
 ELFUTILS_0 { };
-ELFUTILS_0.120 {
+ELFUTILS_0.122 {
   global:
     dwarf_abbrevhaschildren;
     dwarf_addrdie;
@@ -104,6 +104,8 @@ ELFUTILS_0.120 {
     dwfl_getmodules;
     dwfl_getsrc;
     dwfl_getsrclines;
+    dwfl_line_comp_dir;
+    dwfl_linecu;
     dwfl_lineinfo;
     dwfl_linemodule;
     dwfl_linux_kernel_find_elf;
@@ -112,14 +114,16 @@ ELFUTILS_0.120 {
     dwfl_linux_kernel_report_modules;
     dwfl_linux_kernel_report_offline;
     dwfl_linux_proc_find_elf;
-    dwfl_linux_proc_report;
     dwfl_linux_proc_maps_report;
+    dwfl_linux_proc_report;
     dwfl_module_addrdie;
     dwfl_module_addrname;
     dwfl_module_getdwarf;
     dwfl_module_getelf;
     dwfl_module_getsrc;
     dwfl_module_getsrc_file;
+    dwfl_module_getsym;
+    dwfl_module_getsymtab;
     dwfl_module_info;
     dwfl_module_nextcu;
     dwfl_module_register_names;
index bdfd12c248c33ae5fc44656491b4a564b1896170..dd0b9b69eecfcfe2d9da1924dfdd4a0a474c0531 100644 (file)
@@ -4,11 +4,47 @@
        it can overflow the return value type.
        Patch by Tim Moore <timoore@redhat.com>.
 
+2006-06-28  Roland McGrath  <roland@redhat.com>
+
+       * libdwfl.h: Cosmetic changes.
+
+       * dwfl_line_comp_dir.c: New file.
+       * Makefile.am (libdwfl_a_SOURCES): Add it.
+       * libdwfl.h: Declare dwfl_line_comp_dir.
+
+       * dwfl_lineinfo.c (dwfl_lineinfo): Remove stray extern in defn.
+
+       * dwfl_linecu.c: New file.
+       * Makefile.am (libdwfl_a_SOURCES): Add it.
+       * libdwfl.h: Declare dwfl_linecu.
+
+       * libdwflP.h (dwfl_linecu_inline): Function renamed from dwfl_linecu.
+       (dwfl_linecu): Define as macro.
+
+       * relocate.c (__libdwfl_relocate): Use dwfl_module_getsym.
+
+       * dwfl_module_getdwarf.c (dwfl_module_getsymtab): New function.
+       (dwfl_module_addrname): Function moved ...
+       * dwfl_module_addrname.c: ... here, new file.
+       * dwfl_module_getsym.c: New file.
+       * Makefile.am (libdwfl_a_SOURCES): Add them.
+       * libdwfl.h: Declare dwfl_module_getsymtab, dwfl_module_getsym.
+       * libdwflP.h: Add INTDECLs.
+
+2006-06-27  Roland McGrath  <roland@redhat.com>
+
+       * dwfl_module.c (dwfl_report_end): Whitespace fix.
+
 2006-06-13  Roland McGrath  <roland@redhat.com>
 
        * elf-from-memory.c (elf_from_remote_memory): Fix 32/64 typo.
        Use __libdwfl_seterrno for elf_memory failure.
 
+2006-05-22  Roland McGrath  <roland@redhat.com>
+
+       * dwfl_module_return_value_location.c
+       (dwfl_module_return_value_location): Use __libdwfl_module_getebl.
+
 2006-05-27  Ulrich Drepper  <drepper@redhat.com>
 
        * libdwfl.h: Add extern "C".
index 4583ed63705510fd22dead1f4ee6bc883111bdea..ee9efec93cdcc712a791e29da5114b3602e5e780 100644 (file)
@@ -59,12 +59,14 @@ libdwfl_a_SOURCES = dwfl_begin.c dwfl_end.c dwfl_error.c dwfl_version.c \
                    dwfl_addrmodule.c dwfl_addrdwarf.c \
                    cu.c dwfl_module_nextcu.c dwfl_nextcu.c dwfl_cumodule.c \
                    dwfl_module_addrdie.c dwfl_addrdie.c \
-                   lines.c dwfl_lineinfo.c dwfl_linemodule.c \
+                   lines.c dwfl_lineinfo.c dwfl_line_comp_dir.c \
+                   dwfl_linemodule.c dwfl_linecu.c \
                    dwfl_getsrclines.c dwfl_onesrcline.c \
                    dwfl_module_getsrc.c dwfl_getsrc.c \
                    dwfl_module_getsrc_file.c \
                    libdwfl_crc32.c libdwfl_crc32_file.c \
                    elf-from-memory.c \
+                   dwfl_module_getsym.c dwfl_module_addrname.c \
                    dwfl_module_return_value_location.c \
                    dwfl_module_register_names.c
 
diff --git a/libdwfl/dwfl_line_comp_dir.c b/libdwfl/dwfl_line_comp_dir.c
new file mode 100644 (file)
index 0000000..a755524
--- /dev/null
@@ -0,0 +1,64 @@
+/* Get information from a source line record returned by libdwfl.
+   Copyright (C) 2005, 2006 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>.  */
+
+#include "libdwflP.h"
+#include <dwarf.h>
+
+const char *
+dwfl_line_comp_dir (Dwfl_Line *line)
+{
+  if (line == NULL)
+    return NULL;
+
+  struct dwfl_cu *cu = dwfl_linecu (line);
+  Dwarf_Attribute attr_mem;
+  return INTUSE(dwarf_formstring) (INTUSE(dwarf_attr) (&cu->die,
+                                                      DW_AT_comp_dir,
+                                                      &attr_mem));
+}
diff --git a/libdwfl/dwfl_linecu.c b/libdwfl/dwfl_linecu.c
new file mode 100644 (file)
index 0000000..34f5bb1
--- /dev/null
@@ -0,0 +1,62 @@
+/* Fetch the module containing a source line record returned by libdwfl.
+   Copyright (C) 2006 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>.  */
+
+#include "libdwflP.h"
+
+#undef dwfl_linecu
+
+Dwarf_Die *
+dwfl_linecu (Dwfl_Line *line)
+{
+  if (line == NULL)
+    return NULL;
+
+  struct dwfl_cu *cu = dwfl_linecu_inline (line);
+  return &cu->die;
+}
index 9fd343b626a4df70a4f15ac06998c17d038ef853..0d8a6887ee40f0e5c7d10a44f64afb07527d0709 100644 (file)
@@ -1,5 +1,5 @@
 /* Get information from a source line record returned by libdwfl.
-   Copyright (C) 2005 Red Hat, Inc.
+   Copyright (C) 2005, 2006 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -50,7 +50,7 @@
 #include "libdwflP.h"
 #include "../libdw/libdwP.h"
 
-extern const char *
+const char *
 dwfl_lineinfo (Dwfl_Line *line, Dwarf_Addr *addr, int *linep, int *colp,
               Dwarf_Word *mtime, Dwarf_Word *length)
 {
index 6f3aa849c077c5e3e795c4540eac54d215012e4c..e3db1e061f0e1e8679551e6f2438268172ee35c7 100644 (file)
@@ -186,11 +186,12 @@ compare_modules (const void *a, const void *b)
    existed before but was not included in the current report.
    Returns a nonzero return value from the callback.
    DWFL cannot be used until this function has returned zero.  */
-int dwfl_report_end (Dwfl *dwfl,
-                    int (*removed) (Dwfl_Module *, void *,
-                                    const char *, Dwarf_Addr,
-                                    void *arg),
-                    void *arg)
+int
+dwfl_report_end (Dwfl *dwfl,
+                int (*removed) (Dwfl_Module *, void *,
+                                const char *, Dwarf_Addr,
+                                void *arg),
+                void *arg)
 {
   assert (dwfl->modules == NULL);
 
diff --git a/libdwfl/dwfl_module_addrname.c b/libdwfl/dwfl_module_addrname.c
new file mode 100644 (file)
index 0000000..19b4c2d
--- /dev/null
@@ -0,0 +1,70 @@
+/* Find debugging and symbol information for a module in libdwfl.
+   Copyright (C) 2005, 2006 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>.  */
+
+#include "libdwflP.h"
+
+const char *
+dwfl_module_addrname (Dwfl_Module *mod, GElf_Addr addr)
+{
+  int syments = INTUSE(dwfl_module_getsymtab) (mod);
+  if (syments < 0)
+    return NULL;
+
+  /* Look through the symbol table for a matching symbol.  */
+  for (int i = 1; i < syments; ++i)
+    {
+      GElf_Sym sym;
+      const char *name = INTUSE(dwfl_module_getsym) (mod, i, &sym, NULL);
+      if (name != NULL
+         && sym.st_value <= addr && addr < sym.st_value + sym.st_size)
+       return name;
+    }
+
+  return NULL;
+}
index 56a40fa6de2652ba30c6b5953f5e5c038ed694cc..1688f1e4cc9828f8115f6fe9f72173b4b1f9616e 100644 (file)
@@ -1,5 +1,5 @@
 /* Find debugging and symbol information for a module in libdwfl.
-   Copyright (C) 2005 Red Hat, Inc.
+   Copyright (C) 2005, 2006 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -471,77 +471,17 @@ dwfl_module_getdwarf (Dwfl_Module *mod, Dwarf_Addr *bias)
 }
 INTDEF (dwfl_module_getdwarf)
 
-
-const char *
-dwfl_module_addrname (Dwfl_Module *mod, GElf_Addr addr)
+int
+dwfl_module_getsymtab (Dwfl_Module *mod)
 {
   if (mod == NULL)
-    return NULL;
+    return -1;
 
   find_symtab (mod);
-  if (mod->symerr != DWFL_E_NOERROR)
-    {
-      __libdwfl_seterrno (mod->symerr);
-      return NULL;
-    }
-
-  addr -= mod->symfile->bias;
+  if (mod->symerr == DWFL_E_NOERROR)
+    return mod->syments;
 
-  /* Look through the symbol table for a matching symbol.  */
-  size_t symshstrndx = SHN_UNDEF;
-  for (size_t i = 1; i < mod->syments; ++i)
-    {
-      GElf_Sym sym_mem;
-      GElf_Word shndx;
-      GElf_Sym *sym = gelf_getsymshndx (mod->symdata, mod->symxndxdata,
-                                       i, &sym_mem, &shndx);
-      if (sym != NULL)
-       {
-         GElf_Addr symaddr = sym->st_value;
-
-         if (sym->st_shndx != SHN_XINDEX)
-           shndx = sym->st_shndx;
-
-         if (mod->e_type == ET_REL)
-           /* In an ET_REL file, the symbol table values are relative
-              to the section, not to the module's load base.  */
-           switch (shndx)
-             {
-             case SHN_UNDEF:   /* Undefined symbol can't match an address.  */
-             case SHN_COMMON:  /* Nor can a common defn.  */
-               continue;
-
-             case SHN_ABS:     /* Symbol value is already absolute.  */
-               break;
-
-             default:
-               {
-                 Dwfl_Error result = DWFL_E_LIBELF;
-                 if (likely (symshstrndx != SHN_UNDEF)
-                     || elf_getshstrndx (mod->symfile->elf,
-                                         &symshstrndx) == 0)
-                   result = __libdwfl_relocate_value (mod, symshstrndx,
-                                                      shndx, &symaddr);
-                 if (unlikely (result != DWFL_E_NOERROR))
-                   {
-                     __libdwfl_seterrno (result);
-                     return NULL;
-                   }
-                 break;
-               }
-             }
-
-         if (symaddr <= addr && addr < symaddr + sym->st_size)
-           {
-             if (unlikely (sym->st_name >= mod->symstrdata->d_size))
-               {
-                 __libdwfl_seterrno (DWFL_E_BADSTROFF);
-                 return NULL;
-               }
-             return (const char *) mod->symstrdata->d_buf + sym->st_name;
-           }
-       }
-    }
-
-  return NULL;
+  __libdwfl_seterrno (mod->symerr);
+  return -1;
 }
+INTDEF (dwfl_module_getsymtab)
diff --git a/libdwfl/dwfl_module_getsym.c b/libdwfl/dwfl_module_getsym.c
new file mode 100644 (file)
index 0000000..0c076e8
--- /dev/null
@@ -0,0 +1,116 @@
+/* Find debugging and symbol information for a module in libdwfl.
+   Copyright (C) 2006 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>.  */
+
+#include "libdwflP.h"
+
+const char *
+dwfl_module_getsym (Dwfl_Module *mod, int ndx,
+                   GElf_Sym *sym, GElf_Word *shndxp)
+{
+  if (unlikely (mod == NULL))
+    return NULL;
+
+  if (unlikely (mod->symdata == NULL))
+    {
+      int result = INTUSE(dwfl_module_getsymtab) (mod);
+      if (result < 0)
+       return NULL;
+    }
+
+  GElf_Word shndx;
+  sym = gelf_getsymshndx (mod->symdata, mod->symxndxdata, ndx, sym, &shndx);
+  if (unlikely (sym == NULL))
+    {
+      __libdwfl_seterrno (DWFL_E_LIBELF);
+      return NULL;
+    }
+
+  if (sym->st_shndx != SHN_XINDEX)
+    shndx = sym->st_shndx;
+
+  if (shndxp != NULL)
+    *shndxp = shndx;
+
+  switch (shndx)
+    {
+    case SHN_ABS:
+    case SHN_UNDEF:
+    case SHN_COMMON:
+      break;
+
+    default:
+      if (mod->e_type != ET_REL)
+       /* Apply the bias to the symbol value.  */
+       sym->st_value += mod->symfile->bias;
+      else
+       {
+         /* In an ET_REL file, the symbol table values are relative
+            to the section, not to the module's load base.  */
+         size_t symshstrndx;
+         Dwfl_Error result = DWFL_E_LIBELF;
+         if (elf_getshstrndx (mod->symfile->elf, &symshstrndx) == 0)
+           result = __libdwfl_relocate_value (mod, symshstrndx,
+                                              shndx, &sym->st_value);
+         if (unlikely (result != DWFL_E_NOERROR))
+           {
+             __libdwfl_seterrno (result);
+             return NULL;
+           }
+       }
+      break;
+    }
+
+  if (unlikely (sym->st_name >= mod->symstrdata->d_size))
+    {
+      __libdwfl_seterrno (DWFL_E_BADSTROFF);
+      return NULL;
+    }
+  return (const char *) mod->symstrdata->d_buf + sym->st_name;
+}
+INTDEF (dwfl_module_getsym)
index 914933517be1d35cfe13edb9ed344ef2bebf4907..3d5154e21499bb969b1dc48af399c580a2e87a62 100644 (file)
@@ -1,5 +1,5 @@
 /* Return location expression to find return value given a function type DIE.
-   Copyright (C) 2005 Red Hat, Inc.
+   Copyright (C) 2005, 2006 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -61,10 +61,10 @@ dwfl_module_return_value_location (mod, functypedie, locops)
 
   if (mod->ebl == NULL)
     {
-      mod->ebl = ebl_openbackend (mod->main.elf);
-      if (mod->ebl == NULL)
+      Dwfl_Error error = __libdwfl_module_getebl (mod);
+      if (error != DWFL_E_NOERROR)
        {
-         __libdwfl_seterrno (DWFL_E_LIBEBL);
+         __libdwfl_seterrno (error);
          return -1;
        }
     }
index 170ba3e0213168fe56ba6573c025892cdf642d08..ce85a6bb865c6ccb7adb9615e4496e6240ded9e1 100644 (file)
@@ -82,7 +82,7 @@ typedef struct
   int (*section_address) (Dwfl_Module *mod, void **userdata,
                          const char *modname, Dwarf_Addr base,
                          const char *secname,
-                         Elf32_Word shndx, const GElf_Shdr *shdr,
+                         GElf_Word shndx, const GElf_Shdr *shdr,
                          Dwarf_Addr *addr);
 
   char **debuginfo_path;       /* See dwfl_standard_find_debuginfo.  */
@@ -179,6 +179,9 @@ extern ptrdiff_t dwfl_getmodules (Dwfl *dwfl,
                                  void *arg,
                                  ptrdiff_t offset);
 
+/* Find the module containing the given address.  */
+extern Dwfl_Module *dwfl_addrmodule (Dwfl *dwfl, Dwarf_Addr address);
+
 
 /*** Standard callbacks ***/
 
@@ -211,7 +214,7 @@ extern int dwfl_standard_find_debuginfo (Dwfl_Module *, void **,
    if ET_REL is to be supported.  */
 extern int dwfl_offline_section_address (Dwfl_Module *, void **,
                                         const char *, Dwarf_Addr,
-                                        const char *, Elf32_Word,
+                                        const char *, GElf_Word,
                                         const GElf_Shdr *,
                                         Dwarf_Addr *addr);
 
@@ -222,7 +225,7 @@ extern int dwfl_linux_kernel_find_elf (Dwfl_Module *, void **,
                                       char **, Elf **);
 extern int dwfl_linux_kernel_module_section_address (Dwfl_Module *, void **,
                                                     const char *, Dwarf_Addr,
-                                                    const char *, Elf32_Word,
+                                                    const char *, GElf_Word,
                                                     const GElf_Shdr *,
                                                     Dwarf_Addr *addr);
 
@@ -292,7 +295,7 @@ extern int dwfl_module_relocate_address (Dwfl_Module *mod,
    Returns null for errors.  */
 extern const char *dwfl_module_relocation_info (Dwfl_Module *mod,
                                                unsigned int idx,
-                                               Elf32_Word *shndxp);
+                                               GElf_Word *shndxp);
 
 /* Validate that ADDRESS and ADDRESS+OFFSET lie in a known module
    and both within the same contiguous region for relocation purposes.
@@ -301,10 +304,7 @@ extern int dwfl_validate_address (Dwfl *dwfl,
                                  Dwarf_Addr address, Dwarf_Sword offset);
 
 
-/*** Dwarf access functions ***/
-
-/* Find the module containing the given address.  */
-extern Dwfl_Module *dwfl_addrmodule (Dwfl *dwfl, Dwarf_Addr address);
+/*** ELF access functions ***/
 
 /* Fetch the module main ELF file (where the allocated sections
    are found) for use with libelf.  If successful, fills in *BIAS
@@ -312,6 +312,26 @@ extern Dwfl_Module *dwfl_addrmodule (Dwfl *dwfl, Dwarf_Addr address);
    and those in symbol tables or Dwarf information referring to it.  */
 extern Elf *dwfl_module_getelf (Dwfl_Module *, GElf_Addr *bias);
 
+/* Return the number of symbols in the module's symbol table,
+   or -1 for errors.  */
+extern int dwfl_module_getsymtab (Dwfl_Module *mod);
+
+/* Fetch one entry from the module's symbol table.  On errors, returns
+   NULL.  If successful, fills in *SYM and returns the string for st_name.
+   This works like gelf_getsym except that st_value is always adjusted
+   to an absolute value based on the module's location.  If SHNDXP is
+   non-null, it's set with the section index (whether from st_shndx or
+   extended index table).  */
+extern const char *dwfl_module_getsym (Dwfl_Module *mod, int ndx,
+                                      GElf_Sym *sym, GElf_Word *shndxp)
+  __nonnull_attribute__ (3);
+
+/* Find the symbol that ADDRESS lies inside, and return its name.  */
+extern const char *dwfl_module_addrname (Dwfl_Module *mod, GElf_Addr address);
+
+
+/*** Dwarf access functions ***/
+
 /* Fetch the module's debug information for use with libdw.
    If successful, fills in *BIAS with the difference between
    addresses within the loaded module and those  to use with libdw.  */
@@ -368,17 +388,20 @@ extern int dwfl_module_getsrc_file (Dwfl_Module *mod,
 /* Return the module containing this line record.  */
 extern Dwfl_Module *dwfl_linemodule (Dwfl_Line *line);
 
+/* Return the CU containing this line record.  */
+extern Dwarf_Die *dwfl_linecu (Dwfl_Line *line);
+
 /* Return the source file name and fill in other information.
    Arguments may be null for unneeded fields.  */
 extern const char *dwfl_lineinfo (Dwfl_Line *line, Dwarf_Addr *addr,
                                  int *linep, int *colp,
                                  Dwarf_Word *mtime, Dwarf_Word *length);
 
-
-/* Find the symbol that ADDRESS lies inside, and return its name.  */
-extern const char *dwfl_module_addrname (Dwfl_Module *mod, GElf_Addr address);
+/* Return the compilation directory (AT_comp_dir) from this line's CU.  */
+extern const char *dwfl_line_comp_dir (Dwfl_Line *line);
 
 
+/*** Machine backend access functions ***/
 
 /* Return location expression to find return value given a
    DW_TAG_subprogram, DW_TAG_subroutine_type, or similar DIE describing
index bc798fa18ff41d9f99371c5834f4cd93c0d70730..949e0d7e199767fb6a9e8b9313fd48578e343f0e 100644 (file)
@@ -1,5 +1,5 @@
 /* Internal definitions for libdwfl.
-   Copyright (C) 2005 Red Hat, Inc.
+   Copyright (C) 2005, 2006 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -144,7 +144,7 @@ struct Dwfl_Module
   struct dwfl_file *symfile;   /* Either main or debug.  */
   Elf_Data *symdata;           /* Data in the ELF symbol table section.  */
   size_t syments;              /* sh_size / sh_entsize of that section.  */
-  const Elf_Data *symstrdata;  /* Data for its string table.  */
+  Elf_Data *symstrdata;                /* Data for its string table.  */
   Elf_Data *symxndxdata;       /* Data in the extended section index table. */
   Dwfl_Error symerr;           /* Previous failure to load symbols.  */
 
@@ -198,13 +198,14 @@ struct Dwfl_Lines
 };
 
 static inline struct dwfl_cu *
-dwfl_linecu (const Dwfl_Line *line)
+dwfl_linecu_inline (const Dwfl_Line *line)
 {
   const struct Dwfl_Lines *lines = ((const void *) line
                                    - offsetof (struct Dwfl_Lines,
                                                idx[line->idx]));
   return lines->cu;
 }
+#define dwfl_linecu dwfl_linecu_inline
 
 /* This describes a contiguous address range that lies in a single CU.
    We condense runs of Dwarf_Arange entries for the same CU into this.  */
@@ -270,6 +271,8 @@ INTDECL (dwfl_addrdie)
 INTDECL (dwfl_module_addrdie)
 INTDECL (dwfl_module_getdwarf)
 INTDECL (dwfl_module_getelf)
+INTDECL (dwfl_module_getsym)
+INTDECL (dwfl_module_getsymtab)
 INTDECL (dwfl_module_getsrc)
 INTDECL (dwfl_report_elf)
 INTDECL (dwfl_report_begin)
index 3431743b7566398591822d357c3cfd384eff2468..f0013e3b978f192204dfd48514505aa41d8dbf58 100644 (file)
@@ -1,5 +1,5 @@
 /* Relocate debug information.
-   Copyright (C) 2005 Red Hat, Inc.
+   Copyright (C) 2005, 2006 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -156,11 +156,6 @@ __libdwfl_relocate (Dwfl_Module *mod, Elf *debugfile)
            {
              /* First, resolve the symbol to an absolute value.  */
              GElf_Addr value;
-             inline Dwfl_Error adjust (GElf_Word shndx)
-               {
-                 return __libdwfl_relocate_value (mod, symshstrndx,
-                                                  shndx, &value);
-               }
 
              if (symndx == STN_UNDEF)
                /* When strip removes a section symbol referring to a
@@ -172,35 +167,17 @@ __libdwfl_relocate (Dwfl_Module *mod, Elf *debugfile)
                value = 0;
              else
                {
-                 GElf_Sym sym_mem;
+                 GElf_Sym sym;
                  GElf_Word shndx;
-                 GElf_Sym *sym = gelf_getsymshndx (mod->symdata,
-                                                   mod->symxndxdata,
-                                                   symndx, &sym_mem,
-                                                   &shndx);
-                 if (sym == NULL)
-                   return DWFL_E_LIBELF;
 
-                 value = sym->st_value;
-                 if (sym->st_shndx != SHN_XINDEX)
-                   shndx = sym->st_shndx;
-                 switch (shndx)
-                   {
-                   case SHN_ABS:
-                     break;
+                 if (INTUSE(dwfl_module_getsym) (mod, symndx,
+                                                 &sym, &shndx) == NULL)
+                   return dwfl_errno ();
 
-                   case SHN_UNDEF:
-                   case SHN_COMMON:
-                     return DWFL_E_RELUNDEF;
+                 if (shndx == SHN_UNDEF || shndx == SHN_COMMON)
+                   return DWFL_E_RELUNDEF;
 
-                   default:
-                     {
-                       Dwfl_Error error = adjust (shndx);
-                       if (error != DWFL_E_NOERROR)
-                         return error;
-                       break;
-                     }
-                   }
+                 value = sym.st_value;
                }
 
              /* These are the types we can relocate.  */
index 7ac7978550f026bd6f91e4ac5cf17855be2508cc..3432dce64bf5a848ac51cc6a465bd83cf4ed8a85 100644 (file)
        * Makefile.am: Add hacks to create dependency files for non-generic
        linker.
 
+2006-06-28  Roland McGrath  <roland@redhat.com>
+
+       * addr2line.c (use_comp_dir): New variable.
+       (options, parse_opt): Grok -A/--absolute to set it.
+       (handle_address): If set, prepend dwfl_line_comp_dir results to
+       relative file names.
+
 2006-06-12  Ulrich Drepper  <drepper@redhat.com>
 
        * ldgeneric.c (ld_generic_generate_sections): Don't create .interp
index 1729058e1aa925742ab23303452a9126800feb01..c849ec792f5701576ad0731416e763f2b4cbb052 100644 (file)
@@ -63,6 +63,8 @@ static const struct argp_option options[] =
 {
   { NULL, 0, NULL, 0, N_("Output Selection:"), 0 },
   { "basenames", 's', NULL, 0, N_("Show only base names of source files"), 0 },
+  { "absolute", 'A', NULL, 0,
+    N_("Show absolute file names using compilation directory"), 0 },
   { "functions", 'f', NULL, 0, N_("Additional show function names"), 0 },
 
   { NULL, 0, NULL, 0, N_("Miscellaneous:"), 0 },
@@ -99,6 +101,9 @@ static void handle_address (GElf_Addr addr, Dwfl *dwfl);
 /* True if only base names of files should be shown.  */
 static bool only_basenames;
 
+/* True if absolute file names based on DW_AT_comp_dir should be shown.  */
+static bool use_comp_dir;
+
 /* True if function names should be shown.  */
 static bool show_functions;
 
@@ -207,6 +212,10 @@ parse_opt (int key, char *arg __attribute__ ((unused)),
       only_basenames = true;
       break;
 
+    case 'A':
+      use_comp_dir = true;
+      break;
+
     case 'f':
       show_functions = true;
       break;
@@ -307,13 +316,24 @@ handle_address (GElf_Addr addr, Dwfl *dwfl)
   if (line != NULL && (src = dwfl_lineinfo (line, &addr, &lineno, &linecol,
                                            NULL, NULL)) != NULL)
     {
+      const char *comp_dir = "";
+      const char *comp_dir_sep = "";
+
       if (only_basenames)
        src = basename (src);
+      else if (use_comp_dir && src[0] != '/')
+       {
+         comp_dir = dwfl_line_comp_dir (line);
+         if (comp_dir != NULL)
+           comp_dir_sep = "/";
+       }
 
       if (linecol != 0)
-       printf ("%s:%d:%d\n", src, lineno, linecol);
+       printf ("%s%s%s:%d:%d\n",
+               comp_dir, comp_dir_sep, src, lineno, linecol);
       else
-       printf ("%s:%d\n", src, lineno);
+       printf ("%s%s%s:%d\n",
+               comp_dir, comp_dir_sep, src, lineno);
     }
   else
     puts ("??:0");