summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS2
-rw-r--r--libdw/ChangeLog7
-rw-r--r--libdw/libdw.map8
-rw-r--r--libdwfl/ChangeLog36
-rw-r--r--libdwfl/Makefile.am4
-rw-r--r--libdwfl/dwfl_line_comp_dir.c64
-rw-r--r--libdwfl/dwfl_linecu.c62
-rw-r--r--libdwfl/dwfl_lineinfo.c4
-rw-r--r--libdwfl/dwfl_module.c11
-rw-r--r--libdwfl/dwfl_module_addrname.c70
-rw-r--r--libdwfl/dwfl_module_getdwarf.c78
-rw-r--r--libdwfl/dwfl_module_getsym.c116
-rw-r--r--libdwfl/dwfl_module_return_value_location.c8
-rw-r--r--libdwfl/libdwfl.h45
-rw-r--r--libdwfl/libdwflP.h9
-rw-r--r--libdwfl/relocate.c39
-rw-r--r--src/ChangeLog7
-rw-r--r--src/addr2line.c24
18 files changed, 464 insertions, 130 deletions
diff --git a/NEWS b/NEWS
index 2edfbb30..a4d7c988 100644
--- 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
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 95312497..d1b2dc6d 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -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".
diff --git a/libdw/libdw.map b/libdw/libdw.map
index 08b01982..6ee42ece 100644
--- a/libdw/libdw.map
+++ b/libdw/libdw.map
@@ -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;
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index bdfd12c2..dd0b9b69 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -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".
diff --git a/libdwfl/Makefile.am b/libdwfl/Makefile.am
index 4583ed63..ee9efec9 100644
--- a/libdwfl/Makefile.am
+++ b/libdwfl/Makefile.am
@@ -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
index 00000000..a755524d
--- /dev/null
+++ b/libdwfl/dwfl_line_comp_dir.c
@@ -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
index 00000000..34f5bb10
--- /dev/null
+++ b/libdwfl/dwfl_linecu.c
@@ -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;
+}
diff --git a/libdwfl/dwfl_lineinfo.c b/libdwfl/dwfl_lineinfo.c
index 9fd343b6..0d8a6887 100644
--- a/libdwfl/dwfl_lineinfo.c
+++ b/libdwfl/dwfl_lineinfo.c
@@ -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)
{
diff --git a/libdwfl/dwfl_module.c b/libdwfl/dwfl_module.c
index 6f3aa849..e3db1e06 100644
--- a/libdwfl/dwfl_module.c
+++ b/libdwfl/dwfl_module.c
@@ -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
index 00000000..19b4c2d3
--- /dev/null
+++ b/libdwfl/dwfl_module_addrname.c
@@ -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;
+}
diff --git a/libdwfl/dwfl_module_getdwarf.c b/libdwfl/dwfl_module_getdwarf.c
index 56a40fa6..1688f1e4 100644
--- a/libdwfl/dwfl_module_getdwarf.c
+++ b/libdwfl/dwfl_module_getdwarf.c
@@ -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
index 00000000..0c076e87
--- /dev/null
+++ b/libdwfl/dwfl_module_getsym.c
@@ -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)
diff --git a/libdwfl/dwfl_module_return_value_location.c b/libdwfl/dwfl_module_return_value_location.c
index 91493351..3d5154e2 100644
--- a/libdwfl/dwfl_module_return_value_location.c
+++ b/libdwfl/dwfl_module_return_value_location.c
@@ -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;
}
}
diff --git a/libdwfl/libdwfl.h b/libdwfl/libdwfl.h
index 170ba3e0..ce85a6bb 100644
--- a/libdwfl/libdwfl.h
+++ b/libdwfl/libdwfl.h
@@ -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
diff --git a/libdwfl/libdwflP.h b/libdwfl/libdwflP.h
index bc798fa1..949e0d7e 100644
--- a/libdwfl/libdwflP.h
+++ b/libdwfl/libdwflP.h
@@ -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)
diff --git a/libdwfl/relocate.c b/libdwfl/relocate.c
index 3431743b..f0013e3b 100644
--- a/libdwfl/relocate.c
+++ b/libdwfl/relocate.c
@@ -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. */
diff --git a/src/ChangeLog b/src/ChangeLog
index 7ac79785..3432dce6 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -45,6 +45,13 @@
* 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
diff --git a/src/addr2line.c b/src/addr2line.c
index 1729058e..c849ec79 100644
--- a/src/addr2line.c
+++ b/src/addr2line.c
@@ -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");