[PATCH] Note that .rela.debug* sections are debuginfo sections.
by Nick Alcock
Without this fix, strip -g misbehaves when stripping object files
and other ELF objects containing debuginfo relocation sections,
preserving all debuginfo sections in the output file because the
.rela.debug* sections reference them.
Signed-off-by: Nick Alcock <nick.alcock(a)oracle.com>
---
The selection of sections to RELAFY here is pretty much arbitrary,
covering everything I've seen .rela.* created for and anything else that
seems likely to need it.
Testing is trivial: try to strip -g a Linux kernel module (or any other
object file containing debug info) and observe the .debug* and
.rela.debug* sections turning up in the stripped output rather than (if
specified) the -f file. binutils behaves correctly in this area.
I haven't considered DWARF 1 sections not shared with DWARF 2+ at all
because I have no way to generate such sections for testing.
libebl/ChangeLog | 5 +++++
libebl/eblopenbackend.c | 36 +++++++++++++++++++-----------------
2 files changed, 24 insertions(+), 17 deletions(-)
diff --git a/libebl/ChangeLog b/libebl/ChangeLog
index af819a2..c6204c6 100644
--- a/libebl/ChangeLog
+++ b/libebl/ChangeLog
@@ -1,3 +1,8 @@
+2012-09-18 Nick Alcock <nick.alcock(a)oracle.com>
+
+ * eblopenbackend.c (default_debugscn_p): Add .rela.* versions of
+ many DWARF 2+ debuginfo sections.
+
2012-08-22 Jeff Kenton <jkenton(a)tilera.com>
* eblopenbackend.c (machines): Add tilegx.
diff --git a/libebl/eblopenbackend.c b/libebl/eblopenbackend.c
index 89e5da5..d10b0d0 100644
--- a/libebl/eblopenbackend.c
+++ b/libebl/eblopenbackend.c
@@ -619,6 +619,7 @@ default_object_note (const char *name __attribute__ ((unused)),
static bool
default_debugscn_p (const char *name)
{
+#define RELAFY(x) x, ".rela" x
/* We know by default only about the DWARF debug sections which have
fixed names. */
static const char *dwarf_scn_names[] =
@@ -630,31 +631,32 @@ default_debugscn_p (const char *name)
".debug_srcinfo",
".debug_sfnames",
/* DWARF 1.1 and DWARF 2 */
- ".debug_aranges",
- ".debug_pubnames",
+ RELAFY(".debug_aranges"),
+ RELAFY(".debug_pubnames"),
/* DWARF 2 */
- ".debug_info",
- ".debug_abbrev",
- ".debug_line",
- ".debug_frame",
- ".debug_str",
- ".debug_loc",
- ".debug_macinfo",
+ RELAFY(".debug_info"),
+ RELAFY(".debug_abbrev"),
+ RELAFY(".debug_line"),
+ RELAFY(".debug_frame"),
+ RELAFY(".debug_str"),
+ RELAFY(".debug_loc"),
+ RELAFY(".debug_macinfo"),
/* DWARF 3 */
- ".debug_ranges",
- ".debug_pubtypes",
+ RELAFY(".debug_ranges"),
+ RELAFY(".debug_pubtypes"),
/* DWARF 4 */
- ".debug_types",
+ RELAFY(".debug_types"),
/* GDB DWARF 4 extension */
".gdb_index",
/* GNU/DWARF 5 extension/proposal */
- ".debug_macro",
+ RELAFY(".debug_macro"),
/* SGI/MIPS DWARF 2 extensions */
- ".debug_weaknames",
- ".debug_funcnames",
- ".debug_typenames",
- ".debug_varnames"
+ RELAFY(".debug_weaknames"),
+ RELAFY(".debug_funcnames"),
+ RELAFY(".debug_typenames"),
+ RELAFY(".debug_varnames")
};
+#undef RELAFY
const size_t ndwarf_scn_names = (sizeof (dwarf_scn_names)
/ sizeof (dwarf_scn_names[0]));
for (size_t cnt = 0; cnt < ndwarf_scn_names; ++cnt)
--
1.7.12.156.gd7c4257
--
NULL && (void)
10 years
[patch] Fix 64-bit->32-bit vDSO reporting
by Jan Kratochvil
Hi Roland,
jankratochvil/auxv32
the problem is obvious I think. I do not see how to write an easy testcase.
It is tested on the jankratochvil/unwind branch but a more minimal testcase
would just be a partial duplication of that testcase also involving biarch
compilation and ptrace attachment.
FAIL->PASS
0xf7502000 0xf76b0000 /lib/libc-2.14.90.so
0xf76b3000 0xf76cc000 /lib/libpthread-2.14.90.so
0xf76ec000 0xf770f000 /lib/ld-2.14.90.so
0xf770f000 0xf7711000 /home/jkratoch/redhat/elfutils-clean/tests/backtrace-child-biarch
TID 29871:
# 0 0xf76eb430 (null)
No DWARF information found
[...]
->
0xf74ff000 0xf76ad000 /lib/libc-2.14.90.so
0xf76b0000 0xf76c9000 /lib/libpthread-2.14.90.so
0xf76e8000 0xf76e9000 [vdso: 29682]
0xf76e9000 0xf770c000 /lib/ld-2.14.90.so
0xf770c000 0xf770e000 /home/jkratoch/redhat/elfutils-clean/tests/backtrace-child-biarch
TID 29683:
# 0 0xf76e8430 __kernel_vsyscall
[...]
One can see [vdso: 29682] is not reported above at all.
Thanks,
Jan
commit 77d700999426dec7004ea41af89376580aab264c
Author: Jan Kratochvil <jan.kratochvil(a)redhat.com>
Date: Wed Oct 10 20:42:30 2012 +0200
libdwfl/
2012-10-10 Jan Kratochvil <jan.kratochvil(a)redhat.com>
* linux-proc-maps.c (PROCEXEFMT, get_pid_width): New.
(grovel_auxv): New parameter width. Use it.
(dwfl_linux_proc_report): New variable width, initialize it by
get_pid_width, use it for grovel_auxv.
Signed-off-by: Jan Kratochvil <jan.kratochvil(a)redhat.com>
diff --git a/libdwfl/linux-proc-maps.c b/libdwfl/linux-proc-maps.c
index 4fbe90d..327eb32 100644
--- a/libdwfl/linux-proc-maps.c
+++ b/libdwfl/linux-proc-maps.c
@@ -44,12 +44,39 @@
#define PROCMAPSFMT "/proc/%d/maps"
#define PROCMEMFMT "/proc/%d/mem"
#define PROCAUXVFMT "/proc/%d/auxv"
+#define PROCEXEFMT "/proc/%d/exe"
+/* Return 64 for 64-bit main ELF executable, 32 accordingly otherwise.
+ Return -1 for errors. */
+
+static int
+get_pid_width (pid_t pid)
+{
+ char *fname;
+ if (asprintf (&fname, PROCEXEFMT, pid) < 0)
+ return -1;
+
+ int fd = open64 (fname, O_RDONLY);
+ free (fname);
+ if (fd < 0)
+ return -1;
+
+ unsigned char buf[5];
+ ssize_t nread = read (fd, &buf, sizeof buf);
+ close (fd);
+ if (nread != sizeof (buf) || buf[0] != ELFMAG0 || buf[1] != ELFMAG1
+ || buf[2] != ELFMAG2 || buf[3] != ELFMAG3
+ || (buf[4] != ELFCLASS64 && buf[4] != ELFCLASS32))
+ return -1;
+
+ return buf[4] == ELFCLASS64 ? 64 : 32;
+}
+
/* Search /proc/PID/auxv for the AT_SYSINFO_EHDR tag. */
static int
-grovel_auxv (pid_t pid, Dwfl *dwfl, GElf_Addr *sysinfo_ehdr)
+grovel_auxv (pid_t pid, Dwfl *dwfl, int width, GElf_Addr *sysinfo_ehdr)
{
char *fname;
if (asprintf (&fname, PROCAUXVFMT, pid) < 0)
@@ -72,9 +99,9 @@ grovel_auxv (pid_t pid, Dwfl *dwfl, GElf_Addr *sysinfo_ehdr)
nread = read (fd, &d, sizeof d);
if (nread > 0)
{
- switch (sizeof (long int))
+ switch (width)
{
- case 4:
+ case 32:
for (size_t i = 0; (char *) &d.a32[i] < &d.buffer[nread]; ++i)
if (d.a32[i].a_type == AT_SYSINFO_EHDR)
{
@@ -89,7 +116,7 @@ grovel_auxv (pid_t pid, Dwfl *dwfl, GElf_Addr *sysinfo_ehdr)
&& dwfl->segment_align <= 1)
dwfl->segment_align = d.a32[i].a_un.a_val;
break;
- case 8:
+ case 64:
for (size_t i = 0; (char *) &d.a64[i] < &d.buffer[nread]; ++i)
if (d.a64[i].a_type == AT_SYSINFO_EHDR)
{
@@ -227,9 +254,13 @@ dwfl_linux_proc_report (Dwfl *dwfl, pid_t pid)
if (dwfl == NULL)
return -1;
+ int width = get_pid_width (pid);
+ if (width == -1)
+ return -1;
+
/* We'll notice the AT_SYSINFO_EHDR address specially when we hit it. */
GElf_Addr sysinfo_ehdr = 0;
- int result = grovel_auxv (pid, dwfl, &sysinfo_ehdr);
+ int result = grovel_auxv (pid, dwfl, width, &sysinfo_ehdr);
if (result != 0)
return result;
10 years, 8 months
[patch] Resolve ppc64 func descriptors as .func (via .opd)
by Jan Kratochvil
Hi,
patch has dependency on:
Re: [patch] Fix bias for vDSOs from core files
https://lists.fedorahosted.org/pipermail/elfutils-devel/2012-October/0026...
(gdb) info addr main
Symbol "main" is at 0x10556708 in a file compiled without debugging.
(gdb) info addr .main
Symbol ".main" is at 0x100562d0 in a file compiled without debugging.
Entry point address: 0x105566b8
Section Headers:
[Nr] Name Type Address Off Size ES Flg Lk Inf Al
[26] .opd PROGBITS 00000000105566b8 5566b8 024458 00 WA 0 0 8
[13] .text PROGBITS 00000000100526a8 0526a8 36c258 00 AX 0 0 8
$ eu-addr2line -e /usr/bin/gdb -S 0x10556708 0x100562d0
FAIL:
main
??:0
??
??:0
PASS:
main
??:0
.main
??:0
So far elfutils resolves addresses from function descriptors but not the real
code addresses.
It does not work universally like bfd artificial ELF symbols do, only
dwfl_module_addrsym is patched; but I find it good enough as I could not find
some easy enough way for elfutils first-class artificial ELF symbols.
I had to add all the INCLUDES entries because ebl-hooks.h declaration depends
on Dwfl_Module now.
In backends/ppc64_get_func_pc.c I was considering fixedsizehash.h instead of
qsort + bsearch but one needs to search by a block of bytes but
fixedsizehash.h can search only by strings.
Use there conversion by
+ val64 = (elf_getident (elf, NULL)[EI_DATA] == ELFDATA2MSB
+ ? be64toh (val64) : le64toh (val64));
While I used first src/readelf.c function "convert" I do not much understand
its purpose, it does not handle properly different sizes of indata / valuedata
anyway and it is more complicated than to just convert it by hand as above.
Thanks,
Jan
backends/
2012-10-09 Jan Kratochvil <jan.kratochvil(a)redhat.com>
* Makefile.am (INCLUDES): Add libdwfl.
(ppc64_SRCS): Add ppc64_get_func_pc.c.
* ppc64_get_func_pc.c: New file.
* ppc64_init.c (ppc64_init): Install get_func_pc and destr.
libasm/
2012-10-09 Jan Kratochvil <jan.kratochvil(a)redhat.com>
* Makefile.am (INCLUDES): Add libdwfl.
libcpu/
2012-10-09 Jan Kratochvil <jan.kratochvil(a)redhat.com>
* Makefile.am (INCLUDES): Add libdwfl.
libdw/
2012-10-09 Jan Kratochvil <jan.kratochvil(a)redhat.com>
* Makefile.am (INCLUDES): Add libdwfl.
libdwfl/
2012-10-09 Jan Kratochvil <jan.kratochvil(a)redhat.com>
* dwfl_module_addrsym.c (dwfl_module_addrsym) (get_section): New
function from ...
(dwfl_module_addrsym) (same_section): ... here. Call it.
(dwfl_module_addrsym) (found_sym): New function from ...
(dwfl_module_addrsym) (search_table): ... here. Call it. Try second
time with ebl_get_func_pc.
libebl/
2012-10-09 Jan Kratochvil <jan.kratochvil(a)redhat.com>
* Makefile.am (INCLUDES): Add libdwfl.
(gen_SOURCES): Add eblgetfuncpc.c.
* ebl-hooks.h (get_func_pc): New entry.
* eblgetfuncpc.c: New file.
* libebl.h: Include libdwfl.h.
(ebl_get_func_pc): New declaration.
* libeblP.h (struct ebl): New field backend.
tests/
2012-10-09 Jan Kratochvil <jan.kratochvil(a)redhat.com>
* run-addrname-test.sh: New testcase for ppc64 function descriptors.
* testfile66.bz2: New file.
diff --git a/backends/Makefile.am b/backends/Makefile.am
index 982ff2a..f52c493 100644
--- a/backends/Makefile.am
+++ b/backends/Makefile.am
@@ -29,7 +29,7 @@
## not, see <http://www.gnu.org/licenses/>.
include $(top_srcdir)/config/eu.am
INCLUDES += -I$(top_srcdir)/libebl -I$(top_srcdir)/libasm \
- -I$(top_srcdir)/libelf -I$(top_srcdir)/libdw
+ -I$(top_srcdir)/libelf -I$(top_srcdir)/libdw -I$(top_srcdir)/libdwfl
modules = i386 sh x86_64 ia64 alpha arm sparc ppc ppc64 s390 tilegx
@@ -90,7 +90,8 @@ libebl_ppc_pic_a_SOURCES = $(ppc_SRCS)
am_libebl_ppc_pic_a_OBJECTS = $(ppc_SRCS:.c=.os)
ppc64_SRCS = ppc64_init.c ppc64_symbol.c ppc64_retval.c \
- ppc64_corenote.c ppc_regs.c ppc_auxv.c ppc_attrs.c ppc_syscall.c
+ ppc64_corenote.c ppc_regs.c ppc_auxv.c ppc_attrs.c ppc_syscall.c \
+ ppc64_get_func_pc.c
libebl_ppc64_pic_a_SOURCES = $(ppc64_SRCS)
am_libebl_ppc64_pic_a_OBJECTS = $(ppc64_SRCS:.c=.os)
diff --git a/backends/ppc64_get_func_pc.c b/backends/ppc64_get_func_pc.c
new file mode 100644
index 0000000..f6df6e2
--- /dev/null
+++ b/backends/ppc64_get_func_pc.c
@@ -0,0 +1,195 @@
+/* Convert function descriptor SYM to the function PC value in-place.
+ Copyright (C) 2005-2010 Red Hat, Inc.
+ This file is part of elfutils.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ 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 copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include "../libdwfl/libdwflP.h"
+#include <endian.h>
+
+#define BACKEND ppc64_
+#include "libebl_CPU.h"
+
+struct pc_entry
+{
+ /* sym_from must be the very first element for the use in bsearch below. */
+ GElf_Sym sym_from;
+ Elf64_Addr st_value_to;
+ const char *name_to;
+};
+
+struct pc_table
+{
+ size_t nelem;
+ struct pc_entry a[];
+ /* Here follow strings allocated for pc_entry->name_to. */
+};
+
+static int
+compar (const void *a_voidp, const void *b_voidp)
+{
+ const struct pc_entry *a = a_voidp;
+ const struct pc_entry *b = b_voidp;
+
+ return memcmp (&a->sym_from, &b->sym_from, sizeof (a->sym_from));
+}
+
+static void
+init (Ebl *ebl, Dwfl_Module *mod)
+{
+ int syments = dwfl_module_getsymtab (mod);
+ assert (syments >= 0);
+ GElf_Sym sym;
+ size_t funcs = 0;
+ size_t names_size = 0;
+ Elf *elf = ebl->elf;
+ if (elf == NULL)
+ return;
+ GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (elf, &ehdr_mem);
+ if (ehdr == NULL)
+ return;
+ GElf_Word shndx, opd_shndx = 0;
+ /* Needless initialization for old GCCs. */
+ Elf_Data *opd_data = NULL;
+ /* Needless initialization for old GCCs. */
+ GElf_Shdr opd_shdr_mem, *opd_shdr = NULL;
+ for (int symi = 1; symi < syments; symi++)
+ {
+ if (dwfl_module_getsym (mod, symi, &sym, &shndx) == NULL
+ || GELF_ST_TYPE (sym.st_info) != STT_FUNC)
+ continue;
+ if (sym.st_shndx != SHN_XINDEX)
+ shndx = sym.st_shndx;
+ /* Zero is invalid value but it could crash this code. */
+ if (shndx == 0)
+ continue;
+ if (opd_shndx == 0)
+ {
+ Elf_Scn *scn = elf_getscn (elf, shndx);
+ if (scn == NULL)
+ continue;
+ opd_shdr = gelf_getshdr (scn, &opd_shdr_mem);
+ if (opd_shdr == NULL)
+ continue;
+ if (strcmp (elf_strptr (elf, ehdr->e_shstrndx, opd_shdr->sh_name),
+ ".opd") != 0)
+ continue;
+ opd_data = elf_getdata (scn, NULL);
+ /* SHT_NOBITS will produce NULL D_BUF. */
+ if (opd_data == NULL || opd_data->d_buf == NULL)
+ return;
+ assert (opd_data->d_size == opd_shdr->sh_size);
+ opd_shndx = shndx;
+ }
+ if (shndx != opd_shndx)
+ continue;
+ Elf64_Addr val;
+ if (sym.st_value < opd_shdr->sh_addr + mod->main_bias
+ || sym.st_value > (opd_shdr->sh_addr + mod->main_bias
+ + opd_shdr->sh_size - sizeof (val)))
+ continue;
+ if (unlikely (sym.st_name >= mod->symstrdata->d_size))
+ continue;
+ funcs++;
+ const char *name = mod->symstrdata->d_buf + sym.st_name;
+ names_size += 1 + strlen (name) + 1;
+ }
+ struct pc_table *pc_table;
+ pc_table = malloc (sizeof (*pc_table) + funcs * sizeof (*pc_table->a)
+ + names_size);
+ if (pc_table == NULL)
+ return;
+ ebl->backend = pc_table;
+ pc_table->nelem = 0;
+ if (funcs == 0)
+ return;
+ struct pc_entry *dest = pc_table->a;
+ char *names = (void *) (pc_table->a + funcs), *names_dest = names;
+ for (int symi = 1; symi < syments; symi++)
+ {
+ if (dwfl_module_getsym (mod, symi, &sym, &shndx) == NULL
+ || GELF_ST_TYPE (sym.st_info) != STT_FUNC)
+ continue;
+ if (sym.st_shndx != SHN_XINDEX)
+ shndx = sym.st_shndx;
+ if (shndx != opd_shndx)
+ continue;
+ uint64_t val64;
+ if (sym.st_value < opd_shdr->sh_addr + mod->main_bias
+ || sym.st_value > (opd_shdr->sh_addr + mod->main_bias
+ + opd_shdr->sh_size - sizeof (val64)))
+ continue;
+ val64 = *(const uint64_t *) (opd_data->d_buf + sym.st_value
+ - (opd_shdr->sh_addr + mod->main_bias));
+ val64 = (elf_getident (elf, NULL)[EI_DATA] == ELFDATA2MSB
+ ? be64toh (val64) : le64toh (val64));
+ assert (dest < pc_table->a + funcs);
+ dest->sym_from = sym;
+ dest->st_value_to = val64 + mod->main_bias;
+ assert (sym.st_name < mod->symstrdata->d_size);
+ const char *name = mod->symstrdata->d_buf + sym.st_name;
+ dest->name_to = names_dest;
+ *names_dest++ = '.';
+ names_dest = stpcpy (names_dest, name) + 1;
+ dest++;
+ pc_table->nelem++;
+ }
+ assert (pc_table->nelem == funcs);
+ assert (dest == pc_table->a + pc_table->nelem);
+ assert (names_dest == names + names_size);
+ qsort (pc_table->a, pc_table->nelem, sizeof (*pc_table->a), compar);
+}
+
+const char *
+ppc64_get_func_pc (Ebl *ebl, Dwfl_Module *mod, GElf_Sym *sym)
+{
+ if (ebl->backend == NULL)
+ init (ebl, mod);
+ if (ebl->backend == NULL)
+ return NULL;
+ const struct pc_table *pc_table = ebl->backend;
+ const struct pc_entry *found;
+ found = bsearch (sym, pc_table->a, pc_table->nelem, sizeof (*pc_table->a),
+ compar);
+ if (found == NULL)
+ return NULL;
+ sym->st_value = found->st_value_to;
+ return found->name_to;
+}
+
+void
+ppc64_destr (Ebl *ebl)
+{
+ if (ebl->backend == NULL)
+ return;
+ struct pc_table *pc_table = ebl->backend;
+ free (pc_table);
+ ebl->backend = NULL;
+}
diff --git a/backends/ppc64_init.c b/backends/ppc64_init.c
index 90d4f2b..da7d02c 100644
--- a/backends/ppc64_init.c
+++ b/backends/ppc64_init.c
@@ -64,6 +64,8 @@ ppc64_init (elf, machine, eh, ehlen)
HOOK (eh, syscall_abi);
HOOK (eh, core_note);
HOOK (eh, auxv_info);
+ HOOK (eh, get_func_pc);
+ HOOK (eh, destr);
return MODVERSION;
}
diff --git a/libasm/Makefile.am b/libasm/Makefile.am
index abe5468..0552a7e 100644
--- a/libasm/Makefile.am
+++ b/libasm/Makefile.am
@@ -28,7 +28,8 @@
## not, see <http://www.gnu.org/licenses/>.
##
include $(top_srcdir)/config/eu.am
-INCLUDES += -I$(top_srcdir)/libelf -I$(top_srcdir)/libebl -I$(top_srcdir)/libdw
+INCLUDES += -I$(top_srcdir)/libelf -I$(top_srcdir)/libebl \
+ -I$(top_srcdir)/libdw -I$(top_srcdir)/libdwfl
GCC_INCLUDE = -I$(shell $(CC) -print-file-name=include)
VERSION = 1
diff --git a/libcpu/Makefile.am b/libcpu/Makefile.am
index 8f62be2..4934c76 100644
--- a/libcpu/Makefile.am
+++ b/libcpu/Makefile.am
@@ -29,7 +29,7 @@
##
include $(top_srcdir)/config/eu.am
INCLUDES += -I$(srcdir)/../libelf -I$(srcdir)/../libebl \
- -I$(srcdir)/../libdw -I$(srcdir)/../libasm
+ -I$(srcdir)/../libdw -I$(srcdir)/../libdwfl -I$(srcdir)/../libasm
AM_CFLAGS += -fpic -fdollars-in-identifiers
LEXCOMPILE = $(LEX) $(LFLAGS) $(AM_LFLAGS) -P$(<F:lex.l=)
LEX_OUTPUT_ROOT = lex.$(<F:lex.l=)
diff --git a/libdw/Makefile.am b/libdw/Makefile.am
index c6ac264..7189e91 100644
--- a/libdw/Makefile.am
+++ b/libdw/Makefile.am
@@ -32,7 +32,7 @@ DEFS += -DIS_LIBDW
if BUILD_STATIC
AM_CFLAGS += -fpic
endif
-INCLUDES += -I$(srcdir)/../libelf
+INCLUDES += -I$(srcdir)/../libelf -I$(srcdir)/../libdwfl
VERSION = 1
lib_LIBRARIES = libdw.a
diff --git a/libdwfl/dwfl_module_addrsym.c b/libdwfl/dwfl_module_addrsym.c
index dcc2a7a..272b31e 100644
--- a/libdwfl/dwfl_module_addrsym.c
+++ b/libdwfl/dwfl_module_addrsym.c
@@ -39,6 +39,23 @@ dwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr addr,
if (syments < 0)
return NULL;
+ /* Return section where FIND_ADDR lies. Return SHN_ABS otherwise. */
+ inline GElf_Word get_section (GElf_Addr find_addr)
+ {
+ GElf_Addr mod_addr = dwfl_deadjust_st_value (mod, find_addr);
+ Elf_Scn *scn = NULL;
+ while ((scn = elf_nextscn (mod->symfile->elf, scn)) != NULL)
+ {
+ GElf_Shdr shdr_mem;
+ GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+ if (likely (shdr != NULL)
+ && mod_addr >= shdr->sh_addr
+ && mod_addr < shdr->sh_addr + shdr->sh_size)
+ return elf_ndxscn (scn);
+ }
+ return SHN_ABS;
+ }
+
/* Return true iff we consider ADDR to lie in the same section as SYM. */
GElf_Word addr_shndx = SHN_UNDEF;
inline bool same_section (const GElf_Sym *sym, GElf_Word shndx)
@@ -49,23 +66,7 @@ dwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr addr,
/* Figure out what section ADDR lies in. */
if (addr_shndx == SHN_UNDEF)
- {
- GElf_Addr mod_addr = dwfl_deadjust_st_value (mod, addr);
- Elf_Scn *scn = NULL;
- addr_shndx = SHN_ABS;
- while ((scn = elf_nextscn (mod->symfile->elf, scn)) != NULL)
- {
- GElf_Shdr shdr_mem;
- GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
- if (likely (shdr != NULL)
- && mod_addr >= shdr->sh_addr
- && mod_addr < shdr->sh_addr + shdr->sh_size)
- {
- addr_shndx = elf_ndxscn (scn);
- break;
- }
- }
- }
+ addr_shndx = get_section (addr);
return shndx == addr_shndx;
}
@@ -83,80 +84,95 @@ dwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr addr,
/* Keep track of the lowest address a relevant sizeless symbol could have. */
GElf_Addr min_label = 0;
- /* Look through the symbol table for a matching symbol. */
- inline void search_table (int start, int end)
+ /* Consider one symbol SYM. */
+ inline void found_sym (const GElf_Sym *sym, GElf_Word shndx, const char *name)
{
- for (int i = start; i < end; ++i)
+ if (name != NULL && name[0] != '\0'
+ && sym->st_shndx != SHN_UNDEF
+ && sym->st_value <= addr
+ && GELF_ST_TYPE (sym->st_info) != STT_SECTION
+ && GELF_ST_TYPE (sym->st_info) != STT_FILE
+ && GELF_ST_TYPE (sym->st_info) != STT_TLS)
{
- GElf_Sym sym;
- GElf_Word shndx;
- const char *name = INTUSE(dwfl_module_getsym) (mod, i, &sym, &shndx);
- if (name != NULL && name[0] != '\0'
- && sym.st_shndx != SHN_UNDEF
- && sym.st_value <= addr
- && GELF_ST_TYPE (sym.st_info) != STT_SECTION
- && GELF_ST_TYPE (sym.st_info) != STT_FILE
- && GELF_ST_TYPE (sym.st_info) != STT_TLS)
- {
- /* Even if we don't choose this symbol, its existence excludes
- any sizeless symbol (assembly label) that is below its upper
- bound. */
- if (sym.st_value + sym.st_size > min_label)
- min_label = sym.st_value + sym.st_size;
+ /* Even if we don't choose this symbol, its existence excludes
+ any sizeless symbol (assembly label) that is below its upper
+ bound. */
+ if (sym->st_value + sym->st_size > min_label)
+ min_label = sym->st_value + sym->st_size;
- if (sym.st_size == 0 || addr - sym.st_value < sym.st_size)
- {
+ if (sym->st_size == 0 || addr - sym->st_value < sym->st_size)
+ {
#define BIND_PREF(sym) \
- (GELF_ST_BIND ((sym).st_info) == STB_GLOBAL \
- ? 3 : (GELF_ST_BIND ((sym).st_info) == STB_WEAK \
- ? 2 : (GELF_ST_BIND ((sym).st_info) == STB_LOCAL ? 1 : 0)))
- /* This symbol is a better candidate than the current one
- if it's closer to ADDR or is global when it was local. */
- if (closest_name == NULL
- || closest_sym->st_value < sym.st_value
- || BIND_PREF (*closest_sym) < BIND_PREF (sym))
- {
- if (sym.st_size != 0)
- {
- *closest_sym = sym;
- closest_shndx = shndx;
- closest_name = name;
- }
- else if (closest_name == NULL
- && sym.st_value >= min_label
- && same_section (&sym, shndx))
- {
- /* Handwritten assembly symbols sometimes have no
- st_size. If no symbol with proper size includes
- the address, we'll use the closest one that is in
- the same section as ADDR. */
- sizeless_sym = sym;
- sizeless_shndx = shndx;
- sizeless_name = name;
- }
- }
- /* When the beginning of its range is no closer,
- the end of its range might be. Otherwise follow
- GELF_ST_BIND preference. If all are equal prefer
- the first symbol found. */
- else if (sym.st_size != 0
- && closest_sym->st_value == sym.st_value
- && ((closest_sym->st_size > sym.st_size
- && BIND_PREF (*closest_sym) <= BIND_PREF (sym))
- || (closest_sym->st_size >= sym.st_size
- && (BIND_PREF (*closest_sym)
- < BIND_PREF (sym)))))
+ (GELF_ST_BIND ((sym)->st_info) == STB_GLOBAL \
+ ? 3 : (GELF_ST_BIND ((sym)->st_info) == STB_WEAK \
+ ? 2 : (GELF_ST_BIND ((sym)->st_info) == STB_LOCAL ? 1 : 0)))
+ /* This symbol is a better candidate than the current one
+ if it's closer to ADDR or is global when it was local. */
+ if (closest_name == NULL
+ || closest_sym->st_value < sym->st_value
+ || BIND_PREF (closest_sym) < BIND_PREF (sym))
+ {
+ if (sym->st_size != 0)
{
- *closest_sym = sym;
+ *closest_sym = *sym;
closest_shndx = shndx;
closest_name = name;
}
-#undef BIND_PREF
+ else if (closest_name == NULL
+ && sym->st_value >= min_label
+ && same_section (sym, shndx))
+ {
+ /* Handwritten assembly symbols sometimes have no
+ st_size. If no symbol with proper size includes
+ the address, we'll use the closest one that is in
+ the same section as ADDR. */
+ sizeless_sym = *sym;
+ sizeless_shndx = shndx;
+ sizeless_name = name;
+ }
+ }
+ /* When the beginning of its range is no closer,
+ the end of its range might be. Otherwise follow
+ GELF_ST_BIND preference. If all are equal prefer
+ the first symbol found. */
+ else if (sym->st_size != 0
+ && closest_sym->st_value == sym->st_value
+ && ((closest_sym->st_size > sym->st_size
+ && BIND_PREF (closest_sym) <= BIND_PREF (sym))
+ || (closest_sym->st_size >= sym->st_size
+ && (BIND_PREF (closest_sym) < BIND_PREF (sym)))))
+ {
+ *closest_sym = *sym;
+ closest_shndx = shndx;
+ closest_name = name;
}
+#undef BIND_PREF
}
}
}
+ /* Look through the symbol table for a matching symbol. */
+ inline void search_table (int start, int end)
+ {
+ for (int i = start; i < end; ++i)
+ {
+ GElf_Sym sym;
+ GElf_Word shndx;
+ const char *name = INTUSE(dwfl_module_getsym) (mod, i, &sym, &shndx);
+ found_sym (&sym, shndx, name);
+ if (name == NULL || GELF_ST_TYPE (sym.st_info) != STT_FUNC)
+ continue;
+ Dwfl_Error error = __libdwfl_module_getebl (mod);
+ if (error != DWFL_E_NOERROR)
+ continue;
+ name = ebl_get_func_pc (mod->ebl, mod, &sym);
+ if (name == NULL)
+ continue;
+ shndx = get_section (sym.st_value);
+ found_sym (&sym, shndx, name);
+ }
+ }
+
/* First go through global symbols. mod->first_global is setup by
dwfl_module_getsymtab to the index of the first global symbol in
the module's symbol table, or -1 when unknown. All symbols with
diff --git a/libebl/Makefile.am b/libebl/Makefile.am
index 65e6b5b..db24518 100644
--- a/libebl/Makefile.am
+++ b/libebl/Makefile.am
@@ -29,7 +29,8 @@
##
include $(top_srcdir)/config/eu.am
AM_CFLAGS += -fpic
-INCLUDES += -I$(srcdir)/../libelf -I$(srcdir)/../libdw -I$(srcdir)/../libasm
+INCLUDES += -I$(srcdir)/../libelf -I$(srcdir)/../libdw -I$(srcdir)/../libdwfl \
+ -I$(srcdir)/../libasm
VERSION = 1
LIBEBL_SUBDIR = @LIBEBL_SUBDIR@
@@ -54,7 +55,7 @@ gen_SOURCES = eblopenbackend.c eblclosebackend.c eblstrtab.c \
eblreginfo.c eblnonerelocp.c eblrelativerelocp.c \
eblsysvhashentrysize.c eblauxvinfo.c eblcheckobjattr.c \
ebl_check_special_section.c ebl_syscall_abi.c eblabicfi.c \
- eblstother.c
+ eblstother.c eblgetfuncpc.c
libebl_a_SOURCES = $(gen_SOURCES)
diff --git a/libebl/ebl-hooks.h b/libebl/ebl-hooks.h
index f629bce..6510e98 100644
--- a/libebl/ebl-hooks.h
+++ b/libebl/ebl-hooks.h
@@ -154,5 +154,10 @@ int EBLHOOK(disasm) (const uint8_t **startp, const uint8_t *end,
/* Supply the machine-specific state of CFI before CIE initial programs. */
int EBLHOOK(abi_cfi) (Ebl *ebl, Dwarf_CIE *abi_info);
+/* *SYM must be STT_FUNC. Then if it describes a function descriptor (PPC64)
+ convert in-place its data and return a possibly different new name for it.
+ The name is valid as long as EBL is valid. */
+const char *EBLHOOK(get_func_pc) (Ebl *ebl, Dwfl_Module *mod, GElf_Sym *sym);
+
/* Destructor for ELF backend handle. */
void EBLHOOK(destr) (struct ebl *);
diff --git a/libebl/eblgetfuncpc.c b/libebl/eblgetfuncpc.c
new file mode 100644
index 0000000..f67c08f
--- /dev/null
+++ b/libebl/eblgetfuncpc.c
@@ -0,0 +1,46 @@
+/* Convert function descriptor SYM to the function PC value in-place.
+ Copyright (C) 2012 Red Hat, Inc.
+ This file is part of elfutils.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of either
+
+ * the GNU Lesser General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at
+ your option) any later version
+
+ or
+
+ * the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at
+ your option) any later version
+
+ or both in parallel, as here.
+
+ 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 copies of the GNU General Public License and
+ the GNU Lesser General Public License along with this program. If
+ not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+#include <assert.h>
+
+const char *
+ebl_get_func_pc (Ebl *ebl, Dwfl_Module *mod, GElf_Sym *sym)
+{
+ if (ebl == NULL)
+ return NULL;
+ assert (sym != NULL);
+ assert (GELF_ST_TYPE (sym->st_info) == STT_FUNC);
+ if (ebl->get_func_pc == NULL)
+ return NULL;
+ return ebl->get_func_pc (ebl, mod, sym);
+}
diff --git a/libebl/libebl.h b/libebl/libebl.h
index 0d5621d..6f67451 100644
--- a/libebl/libebl.h
+++ b/libebl/libebl.h
@@ -31,6 +31,7 @@
#include <gelf.h>
#include "libdw.h"
+#include "libdwfl.h"
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
@@ -375,6 +376,10 @@ extern int ebl_auxv_info (Ebl *ebl, GElf_Xword a_type,
const char **name, const char **format)
__nonnull_attribute__ (1, 3, 4);
+/* Convert function descriptor SYM to the function PC value in-place. */
+extern const char *ebl_get_func_pc (Ebl *ebl, Dwfl_Module *mod, GElf_Sym *sym)
+ __nonnull_attribute__ (1, 2, 3);
+
#ifdef __cplusplus
}
diff --git a/libebl/libeblP.h b/libebl/libeblP.h
index 5ec26a4..c8196bd 100644
--- a/libebl/libeblP.h
+++ b/libebl/libeblP.h
@@ -62,6 +62,9 @@ struct ebl
/* Internal data. */
void *dlhandle;
+
+ /* Data specific to the backend. */
+ void *backend;
};
diff --git a/tests/run-addrname-test.sh b/tests/run-addrname-test.sh
index 4feb193..4dd6018 100755
--- a/tests/run-addrname-test.sh
+++ b/tests/run-addrname-test.sh
@@ -298,4 +298,12 @@ __vdso_time
??:0
EOF
+testfiles testfile66
+testrun_compare ../src/addr2line -S -e testfile66 0x10340 0x250 <<\EOF
+func
+??:0
+.func
+??:0
+EOF
+
exit 0
diff --git a/tests/testfile66.bz2 b/tests/testfile66.bz2
new file mode 100755
index 0000000000000000000000000000000000000000..db07f25415729927f4e2b4985c5668c8e2ee10a2
GIT binary patch
literal 569
zcmV-90>=G9T4*^jL0KkKSrloeYybi*|NH;`Q+Gmd_t9I$azOv*{$$8R5dZ){00;sg
zN(3VzzyZ?W%~)z`O*V<ChK5r#X)zd>fu;fm0WvhiG}9)JQGyXYL8JhU5NHRe007X?
z$Qoh*0BMi_;L)Q%&}a;pfXL9u01Y(A003Zs0!0dH8USbj00000000000H3&^h5+h?
zHGH8oS#&k;tR%<0nFK6&-#1i4RnYl;-bpN9k2InZwNKHPIa5z$l?D9dtf^2;aFZ>;
z6H2`TaFp50B|IFU9;meM2nk4CXKdt!?6iqh`+DOs7204JFHHaexzT9oele)vNXcO|
z&aXz&bgUpHL5Q+$&J@iFQZPa%v>5P$Ld;?WwHgw?W$OZSUT)aw=i|cU?V{^+uO+T&
zsc1>77*MKpaR&z&l3<3FBTF`AA*kg!f+LXQdlF0z1|<OGVw|;E3MDuVYg}lF1kIB*
z2MO?2(vv|()kGjFhM>|aV;0;9Y&kKvJQ6|?q76u^Sl}`<LIO+NDfU1C1=+J>CXwR7
zvQ|1@iR(qMOPC<M!U)iAS_QSrP$be&teWK@Xh4y??kxH~E_K((z?!P4lv4z@9Y0sD
zK?cn^FLD~401iNn#iXf~Yy5H5(sqZpp=+#)n|DQ6r81NSyLB;KQD(6uE>?9m>Ok-8
z(YXp^O0BHJBpo)oV3bgUCvFNTfZoo@a?O8}_!iyT909f+z2<0!_i&kLzs1~<P81{s
H8flvV7_Id;
literal 0
HcmV?d00001
10 years, 9 months
[patch] Fix for PIE with both -e and --core in use
by Jan Kratochvil
Hi Roland,
jankratochvil/pie-core
it was already self-discussed at the bottom of "[API RFC] unwinder".
To load a PIE executable together with a core file one cannot relocate the
executable to the proper VMA.
Shared libraries are located by Dwfl_Callbacks->find_elf which will put them
proper displacement. But the main executable is only specified via
--executable and one cannot easily associate it to the proper core segment.
(It may get associated via build-id but build-id does not have to be available
etc.)
With --core=X --executable=Y order one gets:
0x7ff2cfe9b000 0x7ff2d009c000 [pie]
0x200000 0x400ac0
where the second entry is not relocated.
Similarly it looks for the order --executable=Y --core=X:
0x200000 0x400ac0
0x7ff2cfe9b000 0x7ff2d009c000 [pie]
In both cases the main executable symbols are based at address 0x200000 while
we need them at address 0x7ff2cfe9b000.
The parse_opt diff below has many whitespace changes, one can use -w:
git diff origin/master..origin/jankratochvil/pie-core -w libdwfl/argp-std.c
Thanks,
Jan
commit d01e339994eb1be65017eaf2f7fff8b77f3ff1f3
Author: Jan Kratochvil <jan.kratochvil(a)redhat.com>
Date: Thu Oct 18 00:11:30 2012 +0200
libdwfl/
2012-10-17 Jan Kratochvil <jan.kratochvil(a)redhat.com>
* argp-std.c (offline_find_elf): New function.
(offline_callbacks): Use it for FIND_ELF.
(struct parse_opt): New.
(parse_opt): New KEY ARGP_KEY_INIT. In other make HOOK struct
parse_opt pointer from former Dwfl pointer. Delay 'e and OPT_COREFILE
processing till ARGP_KEY_SUCCESS. Initialize state->INPUT already from
ARGP_KEY_SUCCESS. Modify the cleanup in ARGP_KEY_ERROR. Make the final state->INPUT initialization optional.
* libdwfl.h (dwfl_standard_argp): Extend the comment for USERDATA.
tests/
2012-10-17 Jan Kratochvil <jan.kratochvil(a)redhat.com>
* run-addrname-test.sh: New test for PIE relocation.
* testfile70.core.bz2: New file.
* testfile70.exec.bz2: New file.
Signed-off-by: Jan Kratochvil <jan.kratochvil(a)redhat.com>
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index bdd9440..3919973 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,5 +1,16 @@
2012-10-17 Jan Kratochvil <jan.kratochvil(a)redhat.com>
+ * argp-std.c (offline_find_elf): New function.
+ (offline_callbacks): Use it for FIND_ELF.
+ (struct parse_opt): New.
+ (parse_opt): New KEY ARGP_KEY_INIT. In other make HOOK struct
+ parse_opt pointer from former Dwfl pointer. Delay 'e and OPT_COREFILE
+ processing till ARGP_KEY_SUCCESS. Initialize state->INPUT already from
+ ARGP_KEY_SUCCESS. Modify the cleanup in ARGP_KEY_ERROR. Make the final state->INPUT initialization optional.
+ * libdwfl.h (dwfl_standard_argp): Extend the comment for USERDATA.
+
+2012-10-17 Jan Kratochvil <jan.kratochvil(a)redhat.com>
+
* dwfl_module_getdwarf.c (mod_verify_build_id): New function with code
from ...
(__libdwfl_getelf): ... here. Call it.
diff --git a/libdwfl/argp-std.c b/libdwfl/argp-std.c
index 2ef4555..f0c530f 100644
--- a/libdwfl/argp-std.c
+++ b/libdwfl/argp-std.c
@@ -60,6 +60,27 @@ static const struct argp_option options[] =
{ NULL, 0, NULL, 0, NULL, 0 }
};
+/* Wrapper to provide proper FILE_NAME for -e|--executable. */
+static int
+offline_find_elf (Dwfl_Module *mod, void **userdata, const char *modname,
+ Dwarf_Addr base, char **file_name, Elf **elfp)
+{
+ if (modname != NULL && (strcmp (modname, "[exe]") == 0
+ || strcmp (modname, "[pie]") == 0)
+ && *userdata)
+ {
+ char *e_dup = strdup (*userdata);
+ if (e_dup)
+ {
+ free (*file_name);
+ *file_name = e_dup;
+ return -1;
+ }
+ }
+ return INTUSE(dwfl_build_id_find_elf) (mod, userdata, modname, base,
+ file_name, elfp);
+}
+
static char *debuginfo_path;
static const Dwfl_Callbacks offline_callbacks =
@@ -70,7 +91,7 @@ static const Dwfl_Callbacks offline_callbacks =
.section_address = INTUSE(dwfl_offline_section_address),
/* We use this table for core files too. */
- .find_elf = INTUSE(dwfl_build_id_find_elf),
+ .find_elf = offline_find_elf,
};
static const Dwfl_Callbacks proc_callbacks =
@@ -90,6 +111,16 @@ static const Dwfl_Callbacks kernel_callbacks =
.section_address = INTUSE(dwfl_linux_kernel_module_section_address),
};
+/* Structure held at state->HOOK. */
+struct parse_opt
+{
+ Dwfl *dwfl;
+ /* The -e|--executable parameter. */
+ const char *e;
+ /* The --core parameter. */
+ const char *core;
+};
+
static error_t
parse_opt (int key, char *arg, struct argp_state *state)
{
@@ -111,152 +142,142 @@ parse_opt (int key, char *arg, struct argp_state *state)
switch (key)
{
+ case ARGP_KEY_INIT:
+ {
+ assert (state->hook == NULL);
+ struct parse_opt *opt = calloc (1, sizeof (*opt));
+ if (opt == NULL)
+ failure (NULL, DWFL_E_ERRNO, "calloc");
+ state->hook = opt;
+ }
+ break;
+
case OPT_DEBUGINFO:
debuginfo_path = arg;
break;
case 'e':
{
- Dwfl *dwfl = state->hook;
+ struct parse_opt *opt = state->hook;
+ Dwfl *dwfl = opt->dwfl;
if (dwfl == NULL)
{
dwfl = INTUSE(dwfl_begin) (&offline_callbacks);
if (dwfl == NULL)
return fail (dwfl, -1, arg);
- state->hook = dwfl;
+ opt->dwfl = dwfl;
/* Start at zero so if there is just one -e foo.so,
the DSO is shown without address bias. */
dwfl->offline_next_address = 0;
}
- if (dwfl->callbacks == &offline_callbacks)
- {
- if (INTUSE(dwfl_report_offline) (dwfl, "", arg, -1) == NULL)
- return fail (dwfl, -1, arg);
- state->hook = dwfl;
- }
- else
+ if (dwfl->callbacks != &offline_callbacks)
{
toomany:
argp_error (state, "%s",
_("only one of -e, -p, -k, -K, or --core allowed"));
return EINVAL;
}
+ opt->e = arg;
}
break;
case 'p':
- if (state->hook == NULL)
- {
- Dwfl *dwfl = INTUSE(dwfl_begin) (&proc_callbacks);
- int result = INTUSE(dwfl_linux_proc_report) (dwfl, atoi (arg));
- if (result != 0)
- return fail (dwfl, result, arg);
- state->hook = dwfl;
- }
- else
- goto toomany;
+ {
+ struct parse_opt *opt = state->hook;
+ if (opt->dwfl == NULL)
+ {
+ Dwfl *dwfl = INTUSE(dwfl_begin) (&proc_callbacks);
+ int result = INTUSE(dwfl_linux_proc_report) (dwfl, atoi (arg));
+ if (result != 0)
+ return fail (dwfl, result, arg);
+ opt->dwfl = dwfl;
+ }
+ else
+ goto toomany;
+ }
break;
case 'M':
- if (state->hook == NULL)
- {
- FILE *f = fopen (arg, "r");
- if (f == NULL)
- nofile:
- {
- int code = errno;
- argp_failure (state, EXIT_FAILURE, code,
- "cannot open '%s'", arg);
- return code;
- }
- Dwfl *dwfl = INTUSE(dwfl_begin) (&proc_callbacks);
- int result = INTUSE(dwfl_linux_proc_maps_report) (dwfl, f);
- fclose (f);
- if (result != 0)
- return fail (dwfl, result, arg);
- state->hook = dwfl;
- }
- else
- goto toomany;
+ {
+ struct parse_opt *opt = state->hook;
+ if (opt->dwfl == NULL)
+ {
+ FILE *f = fopen (arg, "r");
+ if (f == NULL)
+ nofile:
+ {
+ int code = errno;
+ argp_failure (state, EXIT_FAILURE, code,
+ "cannot open '%s'", arg);
+ return code;
+ }
+ Dwfl *dwfl = INTUSE(dwfl_begin) (&proc_callbacks);
+ int result = INTUSE(dwfl_linux_proc_maps_report) (dwfl, f);
+ fclose (f);
+ if (result != 0)
+ return fail (dwfl, result, arg);
+ opt->dwfl = dwfl;
+ }
+ else
+ goto toomany;
+ }
break;
case OPT_COREFILE:
{
- Dwfl *dwfl = state->hook;
+ struct parse_opt *opt = state->hook;
+ Dwfl *dwfl = opt->dwfl;
if (dwfl == NULL)
- state->hook = dwfl = INTUSE(dwfl_begin) (&offline_callbacks);
+ opt->dwfl = dwfl = INTUSE(dwfl_begin) (&offline_callbacks);
/* Permit -e and --core together. */
else if (dwfl->callbacks != &offline_callbacks)
goto toomany;
-
- int fd = open64 (arg, O_RDONLY);
- if (fd < 0)
- goto nofile;
-
- Elf *core;
- Dwfl_Error error = __libdw_open_file (&fd, &core, true, false);
- if (error != DWFL_E_NOERROR)
- {
- argp_failure (state, EXIT_FAILURE, 0,
- _("cannot read ELF core file: %s"),
- INTUSE(dwfl_errmsg) (error));
- return error == DWFL_E_ERRNO ? errno : EIO;
- }
-
- int result = INTUSE(dwfl_core_file_report) (dwfl, core);
- if (result < 0)
- {
- elf_end (core);
- close (fd);
- return fail (dwfl, result, arg);
- }
-
- /* From now we leak FD and CORE. */
-
- if (result == 0)
- {
- argp_failure (state, EXIT_FAILURE, 0,
- _("No modules recognized in core file"));
- return ENOENT;
- }
+ opt->core = arg;
}
break;
case 'k':
- if (state->hook == NULL)
- {
- Dwfl *dwfl = INTUSE(dwfl_begin) (&kernel_callbacks);
- int result = INTUSE(dwfl_linux_kernel_report_kernel) (dwfl);
- if (result != 0)
- return fail (dwfl, result, _("cannot load kernel symbols"));
- result = INTUSE(dwfl_linux_kernel_report_modules) (dwfl);
- if (result != 0)
- /* Non-fatal to have no modules since we do have the kernel. */
- failure (dwfl, result, _("cannot find kernel modules"));
- state->hook = dwfl;
- }
- else
- goto toomany;
+ {
+ struct parse_opt *opt = state->hook;
+ if (opt->dwfl == NULL)
+ {
+ Dwfl *dwfl = INTUSE(dwfl_begin) (&kernel_callbacks);
+ int result = INTUSE(dwfl_linux_kernel_report_kernel) (dwfl);
+ if (result != 0)
+ return fail (dwfl, result, _("cannot load kernel symbols"));
+ result = INTUSE(dwfl_linux_kernel_report_modules) (dwfl);
+ if (result != 0)
+ /* Non-fatal to have no modules since we do have the kernel. */
+ failure (dwfl, result, _("cannot find kernel modules"));
+ opt->dwfl = dwfl;
+ }
+ else
+ goto toomany;
+ }
break;
case 'K':
- if (state->hook == NULL)
- {
- Dwfl *dwfl = INTUSE(dwfl_begin) (&offline_callbacks);
- int result = INTUSE(dwfl_linux_kernel_report_offline) (dwfl, arg,
- NULL);
- if (result != 0)
- return fail (dwfl, result, _("cannot find kernel or modules"));
- state->hook = dwfl;
- }
- else
- goto toomany;
+ {
+ struct parse_opt *opt = state->hook;
+ if (opt->dwfl == NULL)
+ {
+ Dwfl *dwfl = INTUSE(dwfl_begin) (&offline_callbacks);
+ int result = INTUSE(dwfl_linux_kernel_report_offline) (dwfl, arg,
+ NULL);
+ if (result != 0)
+ return fail (dwfl, result, _("cannot find kernel or modules"));
+ opt->dwfl = dwfl;
+ }
+ else
+ goto toomany;
+ }
break;
case ARGP_KEY_SUCCESS:
{
- Dwfl *dwfl = state->hook;
+ struct parse_opt *opt = state->hook;
+ Dwfl *dwfl = opt->dwfl;
if (dwfl == NULL)
{
@@ -265,7 +286,56 @@ parse_opt (int key, char *arg, struct argp_state *state)
dwfl = INTUSE(dwfl_begin) (&offline_callbacks);
if (INTUSE(dwfl_report_offline) (dwfl, "", arg, -1) == NULL)
return fail (dwfl, -1, arg);
- state->hook = dwfl;
+ opt->dwfl = dwfl;
+ }
+
+ if (opt->core)
+ {
+ int fd = open64 (opt->core, O_RDONLY);
+ if (fd < 0)
+ goto nofile;
+
+ Elf *core;
+ Dwfl_Error error = __libdw_open_file (&fd, &core, true, false);
+ if (error != DWFL_E_NOERROR)
+ {
+ argp_failure (state, EXIT_FAILURE, 0,
+ _("cannot read ELF core file: %s"),
+ INTUSE(dwfl_errmsg) (error));
+ return error == DWFL_E_ERRNO ? errno : EIO;
+ }
+
+ int result = INTUSE(dwfl_core_file_report) (dwfl, core);
+ if (result < 0)
+ {
+ elf_end (core);
+ close (fd);
+ return fail (dwfl, result, opt->core);
+ }
+
+ /* From now we leak FD and CORE. */
+
+ if (result == 0)
+ {
+ argp_failure (state, EXIT_FAILURE, 0,
+ _("No modules recognized in core file"));
+ return ENOENT;
+ }
+
+ if (opt->e)
+ for (Dwfl_Module *mod = dwfl->modulelist; mod; mod = mod->next)
+ {
+ if (mod->name == NULL
+ || (strcmp (mod->name, "[exe]") != 0
+ && strcmp (mod->name, "[pie]") != 0))
+ continue;
+ mod->userdata = (void *) opt->e;
+ }
+ }
+ else if (opt->e)
+ {
+ if (INTUSE(dwfl_report_offline) (dwfl, "", opt->e, -1) == NULL)
+ return fail (dwfl, -1, arg);
}
/* One of the three flavors has done dwfl_begin and some reporting
@@ -274,12 +344,22 @@ parse_opt (int key, char *arg, struct argp_state *state)
int result = INTUSE(dwfl_report_end) (dwfl, NULL, NULL);
assert (result == 0);
+
+ /* Update the input all along, so a parent parser can see it.
+ As we free OPT the update below will be no longer active. */
+ *(Dwfl **) state->input = dwfl;
+ free (opt);
+ state->hook = NULL;
}
break;
case ARGP_KEY_ERROR:
- dwfl_end (state->hook);
- state->hook = NULL;
+ {
+ struct parse_opt *opt = state->hook;
+ dwfl_end (opt->dwfl);
+ free (opt);
+ state->hook = NULL;
+ }
break;
default:
@@ -287,7 +367,10 @@ parse_opt (int key, char *arg, struct argp_state *state)
}
/* Update the input all along, so a parent parser can see it. */
- *(Dwfl **) state->input = state->hook;
+ struct parse_opt *opt = state->hook;
+ if (opt)
+ *(Dwfl **) state->input = opt->dwfl;
+
return 0;
}
diff --git a/libdwfl/libdwfl.h b/libdwfl/libdwfl.h
index 000d582..8498c0c 100644
--- a/libdwfl/libdwfl.h
+++ b/libdwfl/libdwfl.h
@@ -364,7 +364,8 @@ extern int dwfl_linux_proc_find_elf (Dwfl_Module *mod, void **userdata,
const char *module_name, Dwarf_Addr base,
char **file_name, Elf **);
-/* Standard argument parsing for using a standard callback set. */
+/* Standard argument parsing for using a standard callback set.
+ Field Dwfl_Module->USERDATA is reserved for "[exe]" or "[pie]" modules. */
struct argp;
extern const struct argp *dwfl_standard_argp (void) __attribute__ ((const));
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 9e8ad2c..b9674cc 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,5 +1,11 @@
2012-10-17 Jan Kratochvil <jan.kratochvil(a)redhat.com>
+ * run-addrname-test.sh: New test for PIE relocation.
+ * testfile70.core.bz2: New file.
+ * testfile70.exec.bz2: New file.
+
+2012-10-17 Jan Kratochvil <jan.kratochvil(a)redhat.com>
+
* run-addrname-test.sh: New test for DSO with build-id bias.
* testfile69.core.bz2: New file.
* testfile69.so.bz2: New file.
diff --git a/tests/run-addrname-test.sh b/tests/run-addrname-test.sh
index cc8aa33..99abf9d 100755
--- a/tests/run-addrname-test.sh
+++ b/tests/run-addrname-test.sh
@@ -306,4 +306,14 @@ libglobal+0x9
??:0
EOF
+testfiles testfile70.exec testfile70.core
+testrun_compare ../src/addr2line -S -e testfile70.exec --core=testfile70.core 0x7ff2cfe9b6b5 <<\EOF
+main+0x9
+??:0
+EOF
+testrun_compare ../src/addr2line -S --core=testfile70.core -e testfile70.exec 0x7ff2cfe9b6b5 <<\EOF
+main+0x9
+??:0
+EOF
+
exit 0
diff --git a/tests/testfile70.core.bz2 b/tests/testfile70.core.bz2
new file mode 100644
index 0000000000000000000000000000000000000000..6c47c6d45b2ba29d6956cedc43d60c48e77e16be
GIT binary patch
literal 2739
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
literal 0
HcmV?d00001
diff --git a/tests/testfile70.exec.bz2 b/tests/testfile70.exec.bz2
new file mode 100644
index 0000000000000000000000000000000000000000..f1b969afa667b3166d8052481fad793990abd19f
GIT binary patch
literal 2567
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,KoM%$d1Xdb#tE4
z%wJ(yb%nC)EYr%nN~_0mxkipqL22BErQNf)d&QlRL7VH)1I%L*3{pS@R>(`rtj#4D
zq$w0mu>?Tkl|(5LX_^x9w@49a3T?g?-q&nNC%{68ZlID>RNtSK0)#R6r~2f%F0!(c
z-S%M4;e3c?b@*L|21ot>ldVQJ8dP)_XowsZcjllJW0`zTWH)nOYM^_7>g>FdAz0|b
zjnJnO9lZEXBX_oq9X?+63%dTByNWs8;+PAd;xgR8|1i3eU@&b`YIFFKSoW}RAm91A
dQ(%CARyC}#C++`O#!>&p+>uTcBo8B21%Ok5qx1j(
literal 0
HcmV?d00001
10 years, 10 months
[patch] Code cleanup: Simplify __libdwfl_report_elf
by Jan Kratochvil
Hi Roland,
jankratochvil/basecleanup
./libdwfl/dwfl_report_elf.c
__libdwfl_report_elf <ET_DYN>
vaddr = ph->p_vaddr & -ph->p_align;
address_sync = ph->p_vaddr + ph->p_memsz;
if ((base & (ph->p_align - 1)) != 0)
base = (base + ph->p_align - 1) & -ph->p_align;
- start = base + (ph->p_vaddr & -ph->p_align);
+ start = base + vaddr;
break;
}
}
- bias = start - vaddr;
+ bias = base;
This change has no functionality effect.
It is more interesting whether dwfl_report_elf and __libdwfl_report_elf
parameter BASE was intended to be "base address" or "bias".
Currently it works as bias and it is also documented so:
./libdwfl/libdwfl.h
/* Report a module with start and end addresses computed from the ELF
program headers in the given file, plus BASE. For an ET_REL file,
But this means an application cannot specify base address as application does
not know where the ELF is prelinked to. An application also cannot open an
ELF file beforehand to find out the prelinked address by hand as
__libdw_open_file is private. Application could only parse ELF completely on
its own which does not seem right to me. Therefore I will propose some new
API function for specifying the base address later; this paragraph is offtopic
here.
This base address <-> bias confusion may also come from:
./libdwfl/link_map.c
mod = INTUSE(dwfl_report_elf) (dwfl, basename (name),
name, -1, l_addr);
possibly due to:
glibc/elf/link.h
ElfW(Addr) l_addr; /* Base address shared object is loaded at. */
which is not "Base address" but it is BIAS; fix of the glibc comment failed
with Jakub Jelinek in:
[patch] Fix l_addr comment
http://sourceware.org/ml/libc-alpha/2011-09/msg00151.html
Also the current meaning of dwfl->offline_next_address is not clear to me:
./libdwfl/offline.c
process_elf
Dwfl_Module *mod = __libdwfl_report_elf (dwfl, name, file_name, fd, elf,
dwfl->offline_next_address, false);
as it means BIAS, not "next_address" here, which is for example correct for:
./src/readelf.c
process_file
/* Let 0 be the logical address of the file (or first in archive). */
dwfl->offline_next_address = 0;
./libdwfl/argp-std.c
parse_opt <'e'>
/* Start at zero so if there is just one -e foo.so,
the DSO is shown without address bias. */
dwfl->offline_next_address = 0;
but it seems incorrect to me for:
/* If this is an ET_EXEC file with fixed addresses, the address range
it consumed may or may not intersect with the arbitrary range we
will use for relocatable modules. Make sure we always use a free
range for the offline allocations. If this module did use
offline_next_address, it may have rounded it up for the module's
alignment requirements. */
if ((dwfl->offline_next_address >= mod->low_addr
|| mod->low_addr - dwfl->offline_next_address < OFFLINE_REDZONE)
&& dwfl->offline_next_address < mod->high_addr + OFFLINE_REDZONE)
dwfl->offline_next_address = mod->high_addr + OFFLINE_REDZONE;
where the code IMO expects an address and not a bias. Maybe it is in practice
"next_address" for ET_REL (which is never prelinked) and it is BIAS for ET_DYN.
I guess the current API/ABI should keep this BASE parameter to be BIAS, so
one/I can rather clarify more the code while keeping the functionality as is.
Thanks,
Jan
commit 10a94132fb2e669f4bc7adcce80844bd761ae3b0
Author: Jan Kratochvil <jan.kratochvil(a)redhat.com>
Date: Sat Oct 27 20:45:27 2012 +0200
libdwfl/
* dwfl_report_elf.c (__libdwfl_report_elf): Simplify START and BIAS
calculation.
Signed-off-by: Jan Kratochvil <jan.kratochvil(a)redhat.com>
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index bdd9440..83bdf46 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,8 @@
+2012-10-27 Jan Kratochvil <jan.kratochvil(a)redhat.com>
+
+ * dwfl_report_elf.c (__libdwfl_report_elf): Simplify START and BIAS
+ calculation.
+
2012-10-17 Jan Kratochvil <jan.kratochvil(a)redhat.com>
* dwfl_module_getdwarf.c (mod_verify_build_id): New function with code
diff --git a/libdwfl/dwfl_report_elf.c b/libdwfl/dwfl_report_elf.c
index 35d9f48..174ce7c 100644
--- a/libdwfl/dwfl_report_elf.c
+++ b/libdwfl/dwfl_report_elf.c
@@ -183,11 +183,11 @@ __libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name,
address_sync = ph->p_vaddr + ph->p_memsz;
if ((base & (ph->p_align - 1)) != 0)
base = (base + ph->p_align - 1) & -ph->p_align;
- start = base + (ph->p_vaddr & -ph->p_align);
+ start = base + vaddr;
break;
}
}
- bias = start - vaddr;
+ bias = base;
for (size_t i = phnum; i-- > 0;)
{
10 years, 10 months
[patch] Fix dwfl_report_elf BASE alignment
by Jan Kratochvil
Hi Roland,
jankratochvil/basecleanup-basealign
this patch has dependency on:
[patch] Code cleanup: Simplify __libdwfl_report_elf
https://lists.fedorahosted.org/pipermail/elfutils-devel/2012-October/0027...
elfutils code does:
if ((base & (ph->p_align - 1)) != 0)
base = (base + ph->p_align - 1) & -ph->p_align;
which conflicts with the p_align ELF spec definition:
Loadable process segments must have congruent values for p_vaddr and
p_offset, modulo the page size.This member gives the value to which
the segments are aligned in memory and in the file.
(I have always found its name "align" to be confusing.)
One can see in real world runtime this "alignment" 0x200000 really is not
applied - base address 0x...92000 is not 2MB-aligned.
7f3560c92000-7f3560c93000 r-xp 00000000 fd:02 25037063 testfile-dwfl-report-elf-align-shlib.so
7f3560c93000-7f3560e92000 ---p 00001000 fd:02 25037063 testfile-dwfl-report-elf-align-shlib.so
7f3560e92000-7f3560e93000 rw-p 00000000 fd:02 25037063 testfile-dwfl-report-elf-align-shlib.so
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x00065c 0x00065c R E 0x200000
LOAD 0x000660 0x0000000000200660 0x0000000000200660 0x0001f0 0x000200 RW 0x200000
Also I do not see why an alignment of BASE (to whatever value) is useful.
This bug does not affect elfutils as they use dwfl_report_segment internally
and neither dwfl_report_elf nor __libdwfl_report_elf. Also this code is never
executed by elfutils testsuite and I do not know hot so easilt execute it:
./libdwfl/link_map.c
mod = INTUSE(dwfl_report_elf) (dwfl, basename (name),
name, -1, l_addr);
Application cannot use dwfl_report_segment as its real use requires private
elfutils members/functions.
Thanks,
Jan
commit a7f0c7072e8a420f672b5a99ea85f3d15212ffac
Author: Jan Kratochvil <jan.kratochvil(a)redhat.com>
Date: Sat Oct 27 20:50:21 2012 +0200
libdwfl/
* dwfl_report_elf.c (__libdwfl_report_elf): Remove BASE aligning.
tests/
* Makefile.am (check_PROGRAMS): Add dwfl-report-elf-align.
(TESTS): Add run-dwfl-report-elf-align.sh.
(EXTRA_DIST): Add run-dwfl-report-elf-align.sh and
testfile-dwfl-report-elf-align-shlib.so.bz2 .
(dwfl_report_elf_align_LDADD): New.
* dwfl-report-elf-align.c: New file.
* run-dwfl-report-elf-align.sh: New file.
* testfile-dwfl-report-elf-align-shlib.so.bz2: New file.
Signed-off-by: Jan Kratochvil <jan.kratochvil(a)redhat.com>
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 83bdf46..cdf539e 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,5 +1,9 @@
2012-10-27 Jan Kratochvil <jan.kratochvil(a)redhat.com>
+ * dwfl_report_elf.c (__libdwfl_report_elf): Remove BASE aligning.
+
+2012-10-27 Jan Kratochvil <jan.kratochvil(a)redhat.com>
+
* dwfl_report_elf.c (__libdwfl_report_elf): Simplify START and BIAS
calculation.
diff --git a/libdwfl/dwfl_report_elf.c b/libdwfl/dwfl_report_elf.c
index 174ce7c..d706170 100644
--- a/libdwfl/dwfl_report_elf.c
+++ b/libdwfl/dwfl_report_elf.c
@@ -181,8 +181,6 @@ __libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name,
{
vaddr = ph->p_vaddr & -ph->p_align;
address_sync = ph->p_vaddr + ph->p_memsz;
- if ((base & (ph->p_align - 1)) != 0)
- base = (base + ph->p_align - 1) & -ph->p_align;
start = base + vaddr;
break;
}
diff --git a/tests/ChangeLog b/tests/ChangeLog
index edb82b4..896105d 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,5 +1,16 @@
2012-10-27 Jan Kratochvil <jan.kratochvil(a)redhat.com>
+ * Makefile.am (check_PROGRAMS): Add dwfl-report-elf-align.
+ (TESTS): Add run-dwfl-report-elf-align.sh.
+ (EXTRA_DIST): Add run-dwfl-report-elf-align.sh and
+ testfile-dwfl-report-elf-align-shlib.so.bz2 .
+ (dwfl_report_elf_align_LDADD): New.
+ * dwfl-report-elf-align.c: New file.
+ * run-dwfl-report-elf-align.sh: New file.
+ * testfile-dwfl-report-elf-align-shlib.so.bz2: New file.
+
+2012-10-27 Jan Kratochvil <jan.kratochvil(a)redhat.com>
+
* Makefile.am (EXTRA_DIST): Add testfile64.bz2, testfile65.bz2,
testfile69.core.bz2 and testfile69.so.bz2 .
diff --git a/tests/Makefile.am b/tests/Makefile.am
index f2d2484..a1ed284 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -51,7 +51,7 @@ check_PROGRAMS = arextract arsymtest newfile saridx scnnames sectiondump \
dwfl-bug-getmodules dwarf-getmacros addrcfi \
test-flag-nobits dwarf-getstring rerequest_tag \
alldts md5-sha1-test typeiter low_high_pc \
- test-elf_cntl_gelf_getshdr
+ test-elf_cntl_gelf_getshdr dwfl-report-elf-align
asm_TESTS = asm-tst1 asm-tst2 asm-tst3 asm-tst4 asm-tst5 \
asm-tst6 asm-tst7 asm-tst8 asm-tst9
@@ -85,7 +85,7 @@ TESTS = run-arextract.sh run-arsymtest.sh newfile test-nlist \
run-readelf-d.sh run-readelf-gdb_index.sh run-unstrip-n.sh \
run-low_high_pc.sh run-macro-test.sh run-elf_cntl_gelf_getshdr.sh \
run-test-archive64.sh run-readelf-vmcoreinfo.sh \
- run-readelf-mixed-corenote.sh
+ run-readelf-mixed-corenote.sh run-dwfl-report-elf-align.sh
if !STANDALONE
check_PROGRAMS += msg_tst md5-sha1-test
@@ -180,7 +180,9 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \
testfile60.bz2 testfile61.bz2 \
run-readelf-vmcoreinfo.sh testfile62.bz2 \
run-readelf-mixed-corenote.sh testfile63.bz2 testfile64.bz2 \
- testfile65.bz2 testfile69.core.bz2 testfile69.so.bz2
+ testfile65.bz2 testfile69.core.bz2 testfile69.so.bz2 \
+ run-dwfl-report-elf-align.sh \
+ testfile-dwfl-report-elf-align-shlib.so.bz2
if USE_VALGRIND
valgrind_cmd="valgrind -q --trace-children=yes --error-exitcode=1"
@@ -287,6 +289,7 @@ md5_sha1_test_LDADD = $(libeu)
typeiter_LDADD = $(libdw) $(libelf) $(libmudflap)
low_high_pc_LDADD = $(libdw) $(libelf) $(libmudflap)
test_elf_cntl_gelf_getshdr_LDADD = $(libelf) $(libmudflap)
+dwfl_report_elf_align_LDADD = $(libdw) $(libmudflap)
if GCOV
check: check-am coverage
diff --git a/tests/dwfl-report-elf-align.c b/tests/dwfl-report-elf-align.c
new file mode 100644
index 0000000..86297fa
--- /dev/null
+++ b/tests/dwfl-report-elf-align.c
@@ -0,0 +1,72 @@
+/* Test program for dwfl_report_elf incorrect BASE alignment.
+ Copyright (C) 2012 Red Hat, Inc.
+ This file is part of elfutils.
+
+ This file 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; either version 3 of the License, or
+ (at your option) any later version.
+
+ 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 this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+#include <assert.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <error.h>
+#include <locale.h>
+#include <string.h>
+#include <stdlib.h>
+#include ELFUTILS_HEADER(dwfl)
+
+
+static const Dwfl_Callbacks offline_callbacks =
+ {
+ .find_debuginfo = INTUSE(dwfl_standard_find_debuginfo),
+ .section_address = INTUSE(dwfl_offline_section_address),
+ };
+
+
+int
+main (int argc, char **argv)
+{
+ /* We use no threads here which can interfere with handling a stream. */
+ (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER);
+
+ /* Set locale. */
+ (void) setlocale (LC_ALL, "");
+
+ if (argc != 5)
+ error (1, 0, "dwfl-report-elf-align shlib.so base funcaddr funcname");
+
+ Dwfl *dwfl = dwfl_begin (&offline_callbacks);
+ assert (dwfl != NULL);
+
+ char *endptr;
+ uintptr_t base = strtol (argv[2], &endptr, 0);
+ assert (endptr && !*endptr);
+
+ Dwfl_Module *mod = dwfl_report_elf (dwfl, argv[1], argv[1], -1, base);
+ assert (mod != NULL);
+
+ uintptr_t funcaddr = strtol (argv[3], &endptr, 0);
+ assert (endptr && !*endptr);
+
+ Dwfl_Module *mod_found = dwfl_addrmodule (dwfl, funcaddr);
+ assert (mod_found == mod);
+
+ const char *symname = dwfl_module_addrname (mod, funcaddr);
+ assert (symname != NULL);
+ assert (strcmp (symname, argv[4]) == 0);
+
+ dwfl_end (dwfl);
+
+ return 0;
+}
diff --git a/tests/run-dwfl-report-elf-align.sh b/tests/run-dwfl-report-elf-align.sh
new file mode 100755
index 0000000..df2c583
--- /dev/null
+++ b/tests/run-dwfl-report-elf-align.sh
@@ -0,0 +1,34 @@
+#! /bin/sh
+# Copyright (C) 2012 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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; either version 3 of the License, or
+# (at your option) any later version.
+#
+# 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 this program. If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testfiles testfile-dwfl-report-elf-align-shlib.so
+
+# 7f3560c92000-7f3560c93000 r-xp 00000000 fd:02 25037063 testfile-dwfl-report-elf-align-shlib.so
+# 7f3560c93000-7f3560e92000 ---p 00001000 fd:02 25037063 testfile-dwfl-report-elf-align-shlib.so
+# 7f3560e92000-7f3560e93000 rw-p 00000000 fd:02 25037063 testfile-dwfl-report-elf-align-shlib.so
+# Program Headers:
+# Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
+# LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x00065c 0x00065c R E 0x200000
+# LOAD 0x000660 0x0000000000200660 0x0000000000200660 0x0001f0 0x000200 RW 0x200000
+# #1 0x00007f3560c92585 in shlib () from ./testfile-dwfl-report-elf-align-shlib.so
+
+./dwfl-report-elf-align ./testfile-dwfl-report-elf-align-shlib.so \
+ 0x7f3560c92000 0x7f3560c92585 shlib
+
+exit 0
diff --git a/tests/testfile-dwfl-report-elf-align-shlib.so.bz2 b/tests/testfile-dwfl-report-elf-align-shlib.so.bz2
new file mode 100755
index 0000000000000000000000000000000000000000..1f35df98ffa1dc5883acce9f3b567891f024e43e
GIT binary patch
literal 1546
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
literal 0
HcmV?d00001
10 years, 10 months
[obv] Fix missing tests/ EXTRA_DIST for files by me
by Jan Kratochvil
Hi,
sorry I forgot to add some recent test files to EXTRA_DIST. For make dist:
SKIP: run-addrname-test.sh
All 88 tests passed
(1 test was not run)
->
All 89 tests passed
Checked in as obvious.
Regards,
Jan
commit d7ed0254bcdeeed0ed2b69d864afcd9d5492d0a0
Author: Jan Kratochvil <jan.kratochvil(a)redhat.com>
Date: Sat Oct 27 21:31:58 2012 +0200
tests/
* Makefile.am (EXTRA_DIST): Add testfile64.bz2, testfile65.bz2,
testfile69.core.bz2 and testfile69.so.bz2 .
Signed-off-by: Jan Kratochvil <jan.kratochvil(a)redhat.com>
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 9e8ad2c..edb82b4 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,8 @@
+2012-10-27 Jan Kratochvil <jan.kratochvil(a)redhat.com>
+
+ * Makefile.am (EXTRA_DIST): Add testfile64.bz2, testfile65.bz2,
+ testfile69.core.bz2 and testfile69.so.bz2 .
+
2012-10-17 Jan Kratochvil <jan.kratochvil(a)redhat.com>
* run-addrname-test.sh: New test for DSO with build-id bias.
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 4775b37..f2d2484 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -179,7 +179,8 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \
run-test-archive64.sh testarchive64.a.bz2 \
testfile60.bz2 testfile61.bz2 \
run-readelf-vmcoreinfo.sh testfile62.bz2 \
- run-readelf-mixed-corenote.sh testfile63.bz2
+ run-readelf-mixed-corenote.sh testfile63.bz2 testfile64.bz2 \
+ testfile65.bz2 testfile69.core.bz2 testfile69.so.bz2
if USE_VALGRIND
valgrind_cmd="valgrind -q --trace-children=yes --error-exitcode=1"
10 years, 11 months
[API RFC] unwinder
by Jan Kratochvil
Hi,
git://git.jankratochvil.net/elfutils
branch jankratochvil/unwind
git clone -b jankratochvil/unwind git://git.jankratochvil.net/elfutils elfutils-unwind;cd elfutils-unwind;autoreconf -f -i;./configure --enable-maintainer-mode;make;cd tests;make backtrace backtrace-child;LD_LIBRARY_PATH=../backends:../libdw:../libelf ./backtrace
OR
git remote add jankratochvilgit git://git.jankratochvil.net/elfutils; git fetch jankratochvilgit; git checkout jankratochvil/unwind
TID 20043:
# 0 0x7fed6e187880 (null)
# 1 0x7fed6e187c86 - 1 sigusr2
# 2 0x7fed6d9c5300 __restore_rt
# 3 0x7fed6e187d80 jmp
# 4 0x7fed6e187d0a - 1 stdarg
# 5 0x7fed6e187d70 - 1 backtracegen
# 6 0x7fed6e187d79 - 1 start
# 7 0x7fed6dd4ed90 - 1 start_thread
# 8 0x7fed6da8019d - 1 clone
TID 20042:
# 0 0x7fed6dd563cb raise
# 1 0x7fed6e187a9d - 1 main
# 2 0x7fed6d9b069d - 1 __libc_start_main
# 3 0x7fed6e187b3d - 1 _start
It is 1.2MB due to non-x86* core file testcases, I can push it as
jankratochvil/unwind to the main repo upon request.
User API is to unwind PC, nothing more. It requires CFI now, no per-arch
frames unwinding possible now. Live PIDs and core files are supported.
Archs supported: i386 x86_64 ppc ppc64 s390 s390x (+planned arm)
New testcase: run-backtrace.sh
Going to post along some independent elfutils extensions (s390{,x} core notes,
ppc64 .opd support) and fixes (bias adjustments, uninitialized data).
I have some issues with the API, what is libdw vs. libdwfl etc. I have put
now mostly all to libdwfl, should I really keep it there? There is some mess
with libdw/cfi.h where are:
Dwarf_Frame_State -> Dwarf_Frame_State_Thread -> Dwarf_Frame_State_Process
User can see only opaque Dwarf_Frame_State. Current API for it follows.
Maybe there were already some ideas for elfutils unwinding API, I have no
problem to refactor it to some completely different model.
# /* Get innermost frame of first thread of live process PID. Returns NULL on
# failure. */
# extern Dwarf_Frame_State *dwfl_frame_state_pid (Dwfl *dwfl, pid_t pid);
#
# /* Get innermost frame of first thread of core file COREFILE. Returns NULL on
# failure. */
# extern Dwarf_Frame_State *dwfl_frame_state_core (Dwfl *dwfl,
# const char *corefile);
#
# /* Return TRUE and update *STATEP for the unwound frame for successful unwind.
# Return TRUE and set *STATEP to NULL for the outermost frame. Return FALSE
# (and call __libdwfl_seterrno) otherwise. */
# extern bool dwfl_frame_unwind (Dwarf_Frame_State **statep);
#
# /* Get return address register value for frame. Return TRUE if *PC set and
# optionally *MINUSONE is also set, if MINUSONE is not NULL. Return FALSE
# (and call __libdw_seterrno) otherwise. *MINUSONE is TRUE for normal calls
# where *PC should be decremented by one to get the call instruction, it is
# FALSE if this frame was interrupted by a signal handler. */
# extern bool dwfl_frame_state_pc (Dwarf_Frame_State *state, Dwarf_Addr *pc,
# bool *minusone);
#
# /* Get innermost frame of the next thread from STATE. STATE can be any frame
# of (the previous) thread. */
# extern Dwarf_Frame_State *dwfl_frame_thread_next (Dwarf_Frame_State *state);
#
# /* Get Task ID of the thread of STATE. This is PID for the thread started by
# function main and gettid () for the other threads. */
# extern pid_t dwfl_frame_tid_get (Dwarf_Frame_State *state);
Sample code for unwinding (without error checks) is:
# Initialize Dwfl *dwfl, including reporting PID process or a core file. This
# is a bit unclear to me whether dwfl_frame_state_pid / dwfl_frame_state_core
# should report it themselves or not. See also tests/backtrace.c report_core.
#
# Dwarf_Frame_State *state = dwfl_frame_state_pid (dwfl, pid);
# OR
# Dwarf_Frame_State *state = dwfl_frame_state_core (dwfl, corefile);
# do
# {
# Dwarf_Frame_State *thread = state;
# pid_t tid = dwfl_frame_tid_get (thread);
# # TID for printing.
# while (state)
# {
# Dwarf_Addr pc;
# bool minusone;
# dwfl_frame_state_pc (state, &pc, &minusone);
# Dwarf_Addr pc_adjusted = pc - (minusone ? 1 : 0);
# ### Print PC and dwfl_module_addrname (PC_ADJUSTED).
# dwfl_frame_unwind (&state);
# }
# state = dwfl_frame_thread_next (thread);
# }
# while (state);
The initial reporting is a bit problematic for me. For example
src/stack -e ~/t/sleep6000-32 --core=$HOME/t/sleep6000-32.core
# 1 0xf75e64f0 - 1 __nanosleep
# 2 0xf75e632f - 1 sleep
# 3 0x80483d9 - 1 (null)
^^^^^^ main is not resolved, we need to use:
src/stack --core=$HOME/t/sleep6000-32.core -e ~/t/sleep6000-32
- as otherwise dwfl_addrmodule will find the one from a core file without
symbols first which dwfl_module_addrname will not work for.
Still currently does not work after uncommenting run-backtrace.sh line:
# mytestrun ./backtrace ./$child ./$core
./backtrace ./backtrace-child ./core.20860
0x7fa68624b000 0x7fa68644d000 [pie]
0x7fffa49ff000 0x7fffa4a00000 linux-vdso.so.1
0x7fa685e0b000 0x7fa686027000 libpthread.so.0
0x7fa685a53000 0x7fa685e0b000 libc.so.6
0x7fa686027000 0x7fa68624b000 ld-linux-x86-64.so.2
0x200000 0x401558 <executable>
TID 20860:
# 0 0x7fa685e14080 pthread_join
# 1 0x7fa68624beba - 1 (null)
No DWARF information found
Because <executable> which is PIE is reported with different VMA than [pie].
I had this case working in the past but apparently the bias adjustments are
still not right, I will try more.
Thanks,
Jan
10 years, 11 months
Strip on mips
by Kurt Roeckx
Hi,
I'm trying to debug why strip on mips isn't working properly.
What I see is that for the debug sections, sh_type is not set to
SHT_PROGBITS but to SHT_MIPS_DWARF.
The stripped file still ends up with the debug information it it,
and the file that is supposed to have the debug symbols in it
has it set to SHT_NOBITS, and is rather small.
I'm assuming this is because of the SHT_MIPS_DWARF. I'm not sure
how to find where it's going wrong.
Kurt
10 years, 11 months
[patch] Fix bias for DSOs loaded from core file with build-id
by Jan Kratochvil
Hi Roland,
jankratochvil/buildid-bias
another missing initialization of module bias. If file is found in arbitrary
way but later the check the file matches is done via build-id the module bias
was not initialized.
Thanks,
Jan
commit 2972c2a989cfd1ccc69939d34bc44c612b742d47
Author: Jan Kratochvil <jan.kratochvil(a)redhat.com>
Date: Wed Oct 17 21:49:10 2012 +0200
libdwfl/
2012-10-17 Jan Kratochvil <jan.kratochvil(a)redhat.com>
* dwfl_module_getdwarf.c (__libdwfl_getelf): Do not return yet on
matching build-id. Check ELFERR before closing this MOD file.
tests/
2012-10-17 Jan Kratochvil <jan.kratochvil(a)redhat.com>
* run-addrname-test.sh: New test for DSO with build-id bias.
* testfile69.core.bz2: New file.
* testfile69.so.bz2: New file.
Signed-off-by: Jan Kratochvil <jan.kratochvil(a)redhat.com>
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 189d3b7..db3c9b7 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,8 @@
+2012-10-17 Jan Kratochvil <jan.kratochvil(a)redhat.com>
+
+ * dwfl_module_getdwarf.c (__libdwfl_getelf): Do not return yet on
+ matching build-id. Check ELFERR before closing this MOD file.
+
2012-10-10 Jan Kratochvil <jan.kratochvil(a)redhat.com>
* dwfl_segment_report_module.c (dwfl_segment_report_module):
diff --git a/libdwfl/dwfl_module_getdwarf.c b/libdwfl/dwfl_module_getdwarf.c
index bbf9ff3..fe0755b 100644
--- a/libdwfl/dwfl_module_getdwarf.c
+++ b/libdwfl/dwfl_module_getdwarf.c
@@ -176,8 +176,8 @@ __libdwfl_getelf (Dwfl_Module *mod)
mod->main.elf), 2))
{
case 2:
- /* Build ID matches as it should. */
- return;
+ /* Build ID matches as it should. But initialize MAIN_BIAS below. */
+ break;
case -1: /* ELF error. */
mod->elferr = INTUSE(dwfl_errno) ();
@@ -192,13 +192,16 @@ __libdwfl_getelf (Dwfl_Module *mod)
abort ();
}
- /* We get here when it was the right ELF file. Clear it out. */
- elf_end (mod->main.elf);
- mod->main.elf = NULL;
- if (mod->main.fd >= 0)
+ if (mod->elferr != DWFL_E_NOERROR)
{
- close (mod->main.fd);
- mod->main.fd = -1;
+ /* We get here when it was the right ELF file. Clear it out. */
+ elf_end (mod->main.elf);
+ mod->main.elf = NULL;
+ if (mod->main.fd >= 0)
+ {
+ close (mod->main.fd);
+ mod->main.fd = -1;
+ }
}
}
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 2495fb5..9e8ad2c 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,9 @@
+2012-10-17 Jan Kratochvil <jan.kratochvil(a)redhat.com>
+
+ * run-addrname-test.sh: New test for DSO with build-id bias.
+ * testfile69.core.bz2: New file.
+ * testfile69.so.bz2: New file.
+
2012-10-10 Jan Kratochvil <jan.kratochvil(a)redhat.com>
* run-addrname-test.sh: New test for core vDSO bias.
diff --git a/tests/run-addrname-test.sh b/tests/run-addrname-test.sh
index 4feb193..cc8aa33 100755
--- a/tests/run-addrname-test.sh
+++ b/tests/run-addrname-test.sh
@@ -298,4 +298,12 @@ __vdso_time
??:0
EOF
+testfiles testfile69.core testfile69.so
+testrun_compare ../src/addr2line --core=./testfile69.core -S 0x7f0bc6a33535 0x7f0bc6a33546 <<\EOF
+libstatic+0x9
+??:0
+libglobal+0x9
+??:0
+EOF
+
exit 0
diff --git a/tests/testfile69.core.bz2 b/tests/testfile69.core.bz2
new file mode 100644
index 0000000000000000000000000000000000000000..99553182aee0aa017d762e9a4fbbe2847eff7fa9
GIT binary patch
literal 4416
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
GKXTBtr0_5R
literal 0
HcmV?d00001
diff --git a/tests/testfile69.so.bz2 b/tests/testfile69.so.bz2
new file mode 100755
index 0000000000000000000000000000000000000000..fdddab98cffcaee843a2738b0b7e84faa5f22895
GIT binary patch
literal 2099
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
literal 0
HcmV?d00001
10 years, 11 months