FYI unwinder vDSO exception bugfix
by Jan Kratochvil
Hi Mark,
just updating the reviewed off-trunk branch jankratochvil/unwindx86 with this
fix. If vDSO happened to be first in the module list it failed to unwind.
Jan
--- a/libdwfl/dwfl_frame.c
+++ b/libdwfl/dwfl_frame.c
@@ -157,6 +157,12 @@ dwfl_attach_state (Dwfl *dwfl, int machine, pid_t pid,
ebl = NULL;
for (Dwfl_Module *mod = dwfl->modulelist; mod != NULL; mod = mod->next)
{
+ /* Reading of the vDSO module may fail as /proc/PID/mem is unreadable
+ without PTRACE_ATTACH and we may not be PTRACE_ATTACH-ed now.
+ MOD would not be re-read later to unwind it when we are already
+ PTRACE_ATTACH-ed to PID. */
+ if (strncmp (mod->name, "[vdso: ", 7) == 0)
+ continue;
Dwfl_Error error = __libdwfl_module_getebl (mod);
if (error != DWFL_E_NOERROR)
continue;
10 years, 5 months
[COMMITTED] Fix some (harmless) cppcheck warnings.
by Mark Wielaard
[dwarf_getaranges.c:149]: (warning) Ineffective statement similar to '*A++;'.
Did you intend to write '(*A)++;'?
There was already an XXX statement that we weren't using the result.
Explicitly read the segment_size and check it is zero. And report an
error if it isn't, since we aren't prepared to handle such a case.
[arlib.c:62]: (error) Uninitialized variable: tmpbuf
[arlib.c:124]: (error) Uninitialized variable: tmpbuf
cppcheck is wrong. tmpbuf is initialized in the snprintf call whose result
is use in the same memcpy call. It does make the code less readable and
harder to understand. So explicitly split the snprintf and memcpy calls.
[nm.c:766]: (warning) Assert statement modifies 'cnt'.
The cnt variable was only used for this assert sanity check.
But it is bad style to do have side effects inside an assert statement.
Increase cnt after the assert.
Reported-by: David Binderman <dcb314(a)hotmail.com>
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
libdw/ChangeLog | 5 +++++
libdw/dwarf_getaranges.c | 7 ++++---
src/ChangeLog | 7 +++++++
src/arlib.c | 12 ++++++------
src/nm.c | 3 ++-
5 files changed, 24 insertions(+), 10 deletions(-)
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index c355c30..dc0c4c9 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,8 @@
+2013-11-09 Mark Wielaard <mjw(a)redhat.com>
+
+ * dwarf_getaranges.c (dwarf_getaranges): Read segment_size and
+ check that it is zero.
+
2013-11-07 Jan Kratochvil <jan.kratochvil(a)redhat.com>
* cfi.h (struct Dwarf_Frame_s): Make the comment more specific.
diff --git a/libdw/dwarf_getaranges.c b/libdw/dwarf_getaranges.c
index cc70cb2..20ac7ec 100644
--- a/libdw/dwarf_getaranges.c
+++ b/libdw/dwarf_getaranges.c
@@ -144,9 +144,10 @@ dwarf_getaranges (dbg, aranges, naranges)
if (address_size != 4 && address_size != 8)
goto invalid;
- /* Ignore the segment size value. */
- // XXX Really?
- (void) *readp++;
+ /* We don't actually support segment selectors. */
+ unsigned int segment_size = *readp++;
+ if (segment_size != 0)
+ goto invalid;
/* Round the address to the next multiple of 2*address_size. */
readp += ((2 * address_size - ((readp - hdrstart) % (2 * address_size)))
diff --git a/src/ChangeLog b/src/ChangeLog
index aebcb2f..94bc27a 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,10 @@
+2013-11-09 Mark Wielaard <mjw(a)redhat.com>
+
+ * arlib.c (arlib_init): Call snprintf before using the result
+ with memcpy.
+ (arlib_finalize): Likewise.
+ * nm.c (show_symbols_sysv): Don't modify cnt inside assert.
+
2013-11-07 Jan Kratochvil <jan.kratochvil(a)redhat.com>
* Makefile.am (bin_PROGRAMS): Add stack.
diff --git a/src/arlib.c b/src/arlib.c
index 62c517c..43a9145 100644
--- a/src/arlib.c
+++ b/src/arlib.c
@@ -59,11 +59,11 @@ arlib_init (void)
_FORTIFY_SOURCE=2 would not let us play these games. Therefore
we play it safe. */
char tmpbuf[sizeof (ar_hdr.ar_date) + 1];
- memcpy (ar_hdr.ar_date, tmpbuf,
- snprintf (tmpbuf, sizeof (tmpbuf), "%-*lld",
+ int s = snprintf (tmpbuf, sizeof (tmpbuf), "%-*lld",
(int) sizeof (ar_hdr.ar_date),
(arlib_deterministic_output ? 0
- : (long long int) time (NULL))));
+ : (long long int) time (NULL)));
+ memcpy (ar_hdr.ar_date, tmpbuf, s);
assert ((sizeof (struct ar_hdr) % sizeof (uint32_t)) == 0);
/* Note the string for the ar_uid and ar_gid cases is longer than
@@ -121,10 +121,10 @@ arlib_finalize (void)
symtab.longnames = obstack_finish (&symtab.longnamesob);
- memcpy (&((struct ar_hdr *) symtab.longnames)->ar_size, tmpbuf,
- snprintf (tmpbuf, sizeof (tmpbuf), "%-*zu",
+ int s = snprintf (tmpbuf, sizeof (tmpbuf), "%-*zu",
(int) sizeof (((struct ar_hdr *) NULL)->ar_size),
- symtab.longnameslen - sizeof (struct ar_hdr)));
+ symtab.longnameslen - sizeof (struct ar_hdr));
+ memcpy (&((struct ar_hdr *) symtab.longnames)->ar_size, tmpbuf, s);
}
symtab.symsofflen = obstack_object_size (&symtab.symsoffob);
diff --git a/src/nm.c b/src/nm.c
index 7aae84b..d434f44 100644
--- a/src/nm.c
+++ b/src/nm.c
@@ -763,7 +763,8 @@ show_symbols_sysv (Ebl *ebl, GElf_Word strndx, const char *fullname,
{
GElf_Shdr shdr_mem;
- assert (elf_ndxscn (scn) == cnt++);
+ assert (elf_ndxscn (scn) == cnt);
+ cnt++;
char *name = elf_strptr (ebl->elf, shstrndx,
gelf_getshdr (scn, &shdr_mem)->sh_name);
--
1.8.3.1
10 years, 5 months
[patch] Fix a regression of dwfl_core_file_report retval
by Jan Kratochvil
Hi Mark,
the patch
commit 596d430f23f85f3cd019bd0ac560ecd5371fc7e0
Author: Jan Kratochvil <jan.kratochvil(a)redhat.com>
Date: Tue Jul 23 16:30:01 2013 +0200
Fix false match of non-build-id disk library to build-id memory library.
regressed the return value of dwfl_core_file_report as now some modules may be
successfully reported by the function will still return 0.
Moreover the sniffed vs. listed logic no longer applies as all the modules are
reported reliably, if reported at all.
The problem occurs during jankratochvil/unwindx86 make check if there is no
vDSO to report - other modules did not count and the function returned 0.
But I have not provided a specific testcase for it.
Thanks,
Jan
libdwf/
2013-11-01 Jan Kratochvil <jan.kratochvil(a)redhat.com>
* core-file.c (dwfl_core_file_report): Replaced variable sniffed by
retval. Fix one forgotten LISTED increase.
diff --git a/libdwfl/core-file.c b/libdwfl/core-file.c
index 37613b8..b8087dd 100644
--- a/libdwfl/core-file.c
+++ b/libdwfl/core-file.c
@@ -462,14 +462,14 @@ dwfl_core_file_report (Dwfl *dwfl, Elf *elf, const char *executable)
struct r_debug_info r_debug_info;
memset (&r_debug_info, 0, sizeof r_debug_info);
- int listed = dwfl_link_map_report (dwfl, auxv, auxv_size,
+ int retval = dwfl_link_map_report (dwfl, auxv, auxv_size,
dwfl_elf_phdr_memory_callback, elf,
&r_debug_info);
+ int listed = MAX (0, retval);
/* Now sniff segment contents for modules hinted by information gathered
from DT_DEBUG. */
- int sniffed = 0;
ndx = 0;
do
{
@@ -485,7 +485,7 @@ dwfl_core_file_report (Dwfl *dwfl, Elf *elf, const char *executable)
if (seg > ndx)
{
ndx = seg;
- ++sniffed;
+ ++listed;
}
else
++ndx;
@@ -508,6 +508,7 @@ dwfl_core_file_report (Dwfl *dwfl, Elf *elf, const char *executable)
true, true);
if (mod == NULL)
continue;
+ ++listed;
module->elf = NULL;
module->fd = -1;
/* Move this module to the end of the list, so that we end
@@ -534,7 +535,7 @@ dwfl_core_file_report (Dwfl *dwfl, Elf *elf, const char *executable)
/* We return the number of modules we found if we found any.
If we found none, we return -1 instead of 0 if there was an
error rather than just nothing found. */
- return sniffed || listed >= 0 ? listed + sniffed : listed;
+ return listed > 0 ? listed : retval;
}
INTDEF (dwfl_core_file_report)
NEW_VERSION (dwfl_core_file_report, ELFUTILS_0.158)
10 years, 5 months
[patch 2/2] Fix core files for re-prelink-ed files
by Jan Kratochvil
Hi Mark,
this problem happens on RHEL-5 as it has no build-id. On build-id system the
files get re-aligned correctly.
That is if you generate core file, re-prelink you system (which happens
nightly) and try to load the core file some shared libraries may no longer
load at their right place.
It happens even during "make check" for jankratochvil/unwindx86 which I am not
sure why now. But the code was clearly wrong wrt prelink anyway.
Fortunately link_map->l_ld is absolute address so one can recompute new l_addr
according to it, ignoring former link_map->l_addr.
There is no test case, though.
Thanks,
Jan
libdwfl/
2013-11-01 Jan Kratochvil <jan.kratochvil(a)redhat.com>
Fix core files for re-prelink-ed files.
* core-file.c (dynamic_vaddr_get): New function.
(dwfl_core_file_report): New variable file_dynamic_vaddr. Call
dynamic_vaddr_get instead of using L_ADDR.
* libdwflP.h (struct r_debug_info_module): Remove field l_addr.
* link_map.c (report_r_debug): Do not initialize l_addr.
--- a/libdwfl/core-file.c
+++ b/libdwfl/core-file.c
@@ -397,6 +397,27 @@ clear_r_debug_info (struct r_debug_info *r_debug_info)
}
}
+static bool
+dynamic_vaddr_get (Elf *elf, GElf_Addr *vaddrp)
+{
+ size_t phnum;
+ if (unlikely (elf_getphdrnum (elf, &phnum) != 0))
+ return false;
+ for (size_t i = 0; i < phnum; ++i)
+ {
+ GElf_Phdr phdr_mem;
+ GElf_Phdr *phdr = gelf_getphdr (elf, i, &phdr_mem);
+ if (unlikely (phdr == NULL))
+ return false;
+ if (phdr->p_type == PT_DYNAMIC)
+ {
+ *vaddrp = phdr->p_vaddr;
+ return true;
+ }
+ }
+ return false;
+}
+
int
dwfl_core_file_report (Dwfl *dwfl, Elf *elf, const char *executable)
{
@@ -503,9 +524,13 @@ dwfl_core_file_report (Dwfl *dwfl, Elf *elf, const char *executable)
{
if (module->elf == NULL)
continue;
+ GElf_Addr file_dynamic_vaddr;
+ if (! dynamic_vaddr_get (module->elf, &file_dynamic_vaddr))
+ continue;
Dwfl_Module *mod;
mod = __libdwfl_report_elf (dwfl, basename (module->name), module->name,
- module->fd, module->elf, module->l_addr,
+ module->fd, module->elf,
+ module->l_ld - file_dynamic_vaddr,
true, true);
if (mod == NULL)
continue;
--- a/libdwfl/libdwflP.h
+++ b/libdwfl/libdwflP.h
@@ -467,7 +467,7 @@ struct r_debug_info_module
/* FD is -1 iff ELF is NULL. */
int fd;
Elf *elf;
- GElf_Addr l_addr, l_ld;
+ GElf_Addr l_ld;
/* START and END are both zero if not valid. */
GElf_Addr start, end;
bool disk_file_has_build_id;
--- a/libdwfl/link_map.c
+++ b/libdwfl/link_map.c
@@ -369,7 +369,6 @@ report_r_debug (uint_fast8_t elfclass, uint_fast8_t elfdata,
return release_buffer (result);
r_debug_info_module->fd = -1;
r_debug_info_module->elf = NULL;
- r_debug_info_module->l_addr = l_addr;
r_debug_info_module->l_ld = l_ld;
r_debug_info_module->start = 0;
r_debug_info_module->end = 0;
10 years, 5 months
[COMMITTED] configure.ac: Warn when --enable-dwz=no, but /usr/lib/debug/.dwz exists.
by Mark Wielaard
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
ChangeLog | 5 +++++
configure.ac | 2 ++
2 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index f808413..0ef4416 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
2013-11-06 Mark Wielaard <mjw(a)redhat.com>
+ * configure.ac (--enable-dwz): Add AC_MSG_WARN when disabled but
+ local system does have /usr/lib/debug/.dwz.
+
+2013-11-06 Mark Wielaard <mjw(a)redhat.com>
+
* configure.ac (--enable-thread-safety): Add AC_MSG_WARN experimental
option.
diff --git a/configure.ac b/configure.ac
index 4023f31..03d5756 100644
--- a/configure.ac
+++ b/configure.ac
@@ -75,6 +75,8 @@ AS_HELP_STRING([--enable-dwz], [enable experimental GNU ref_alt FORM, dwz multi
enable_dwz=$enableval, enable_dwz=no)
AM_CONDITIONAL(ENABLE_DWZ, test "$enable_dwz" = yes)
AS_IF([test "$enable_dwz" = yes], [AC_DEFINE(ENABLE_DWZ)])
+AS_IF([test "$enable_dwz" = no -a -d /usr/lib/debug/.dwz],
+ [AC_MSG_WARN([--enable-dwz disabled and /usr/lib/debug/.dwz exists, native tests might fail])])
AH_TEMPLATE([ENABLE_DWZ], [Defined if libdw should support GNU ref_alt FORM, dwz multi files.])
--
1.7.1
10 years, 5 months
run-elf_cntl_gelf_getshdr.sh: Resource deadlock avoided.
by Kurt Roeckx
Hi,
When running the test suite with --enable-thread-safety I get the
following error in the FDREAD case:
test-elf_cntl_gelf_getshdr: elf_readall.c:73: __libelf_readall: Unexpected error: Resource deadlock avoided.
Aborted
(READ and MMAP work without problems.)
Program received signal SIGABRT, Aborted.
0x00007ffff784b1e5 in raise () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) bt
#0 0x00007ffff784b1e5 in raise () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007ffff784e398 in abort () from /lib/x86_64-linux-gnu/libc.so.6
#2 0x00007ffff7844272 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#3 0x00007ffff7844382 in __assert_perror_fail () from /lib/x86_64-linux-gnu/libc.so.6
#4 0x00007ffff7bcb072 in __libelf_readall (elf=elf@entry=0x603010) at elf_readall.c:73
#5 0x00007ffff7bcb156 in elf_cntl (elf=elf@entry=0x603010, cmd=cmd@entry=ELF_C_FDREAD) at elf_cntl.c:61
#6 0x0000000000400ba8 in main (argc=<optimized out>, argv=0x7fffffffea88) at test-elf_cntl_gelf_getshdr.c:84
(gdb) frame 4
#4 0x00007ffff7bcb072 in __libelf_readall (elf=elf@entry=0x603010) at elf_readall.c:73
73 rwlock_wrlock (elf->lock);
elf_cntl() also already did a rwlock_wrlock (elf->lock); at elf_cntl.c:55
The only other caller of __libelf_readall() seems to be elf_rawfile()
which takes a lock just after the __libelf_readall() call.
Kurt
10 years, 5 months
libelf RDWR and elf_newscn do not work
by Jiri Slaby
Hi,
if I add a section using the code below, I obtain a section like this:
[29] NULL 0000000000000000
fff1000400000001 000000 00 0 0 281487861612544
The attached patch fixed it for me. Any ideas?
Code:
if (elf_version(EV_CURRENT) == EV_NONE)
errx(1, "elf_version: %s" , elf_errmsg(-1));
fd = open(argv[1], O_RDWR, 0);
if (fd < 0)
err(1, "open");
elf = elf_begin(fd, ELF_C_RDWR, NULL);
if (!elf)
errx(EXIT_FAILURE, "elf_begin: %s", elf_errmsg(-1));
data = elf_newdata(scn);
if (!data)
errx(1, "!elf_newdata: %s", elf_errmsg(-1));
GElf_Shdr shdr_data, *shdr;
shdr = gelf_getshdr(scn, &shdr_data);
if (!shdr)
errx(1, "gelf_getshdr: %s", elf_errmsg(-1));
shdr->sh_type = SHT_NOBITS;
if (!gelf_update_shdr(scn, shdr))
errx(EXIT_FAILURE, "gelf_update_shdr: %s", elf_errmsg(-1));
if (elf_update(elf, ELF_C_NULL) < 0)
errx(EXIT_FAILURE, "elf_update1: %s", elf_errmsg(-1));
if (elf_update(elf, ELF_C_WRITE) < 0)
errx(EXIT_FAILURE, "elf_update2: %s", elf_errmsg(-1));
if (elf_end(elf))
errx(EXIT_FAILURE, "elf_end: %s", elf_errmsg(-1));
close(fd);
thanks,
--
js
suse labs
10 years, 5 months
[PATCH] Check for prefixed ar, readelf, and nm
by Michael Forney
Sometimes with cross-compile toolchains, the tools are prefixed with the
target arch. Using AC_CHECK_TOOL looks for tools named like this.
---
I'm not entirely sure why the additional libdwfl_objects variable is necessary,
but was required on my system in order for automake to generate Makefile.in
correctly with regards to variable expansion. However, it seems innocent
enough.
config/eu.am | 2 +-
configure.ac | 3 +++
libasm/Makefile.am | 2 +-
libdw/Makefile.am | 5 +++--
libelf/Makefile.am | 2 +-
tests/Makefile.am | 6 ++++--
tests/run-arsymtest.sh | 2 +-
7 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/config/eu.am b/config/eu.am
index 86e5a4e..38718c7 100644
--- a/config/eu.am
+++ b/config/eu.am
@@ -61,4 +61,4 @@ endif
CLEANFILES = *.gcno *.gcda
-textrel_check = if readelf -d $@ | fgrep -q TEXTREL; then exit 1; fi
+textrel_check = if $(READELF) -d $@ | fgrep -q TEXTREL; then exit 1; fi
diff --git a/configure.ac b/configure.ac
index b4c249c..c69dd3e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -79,6 +79,9 @@ AC_PROG_CC
AC_PROG_RANLIB
AC_PROG_YACC
AM_PROG_LEX
+AM_PROG_AR
+AC_CHECK_TOOL([READELF], [readelf])
+AC_CHECK_TOOL([NM], [nm])
AC_CACHE_CHECK([for gcc with C99 support], ac_cv_c99, [dnl
old_CFLAGS="$CFLAGS"
diff --git a/libasm/Makefile.am b/libasm/Makefile.am
index e16d4be..4d81536 100644
--- a/libasm/Makefile.am
+++ b/libasm/Makefile.am
@@ -69,7 +69,7 @@ libasm.so: libasm_pic.a libasm.map
-Wl,--version-script,$(srcdir)/libasm.map,--no-undefined \
-Wl,--soname,$@.$(VERSION) \
../libebl/libebl.a ../libelf/libelf.so $(libasm_so_LDLIBS)
- if readelf -d $@ | fgrep -q TEXTREL; then exit 1; fi
+ if $(READELF) -d $@ | fgrep -q TEXTREL; then exit 1; fi
ln -fs $@ $@.$(VERSION)
install: install-am libasm.so
diff --git a/libdw/Makefile.am b/libdw/Makefile.am
index 5fef2e1..a22166a 100644
--- a/libdw/Makefile.am
+++ b/libdw/Makefile.am
@@ -113,7 +113,7 @@ libdw.so: $(srcdir)/libdw.map libdw_pic.a \
-Wl,--version-script,$<,--no-undefined \
-Wl,--whole-archive $(filter-out $<,$^) -Wl,--no-whole-archive\
-ldl $(zip_LIBS)
- if readelf -d $@ | fgrep -q TEXTREL; then exit 1; fi
+ if $(READELF) -d $@ | fgrep -q TEXTREL; then exit 1; fi
ln -fs $@ $@.$(VERSION)
install: install-am libdw.so
@@ -129,7 +129,8 @@ uninstall: uninstall-am
rmdir --ignore-fail-on-non-empty $(DESTDIR)$(includedir)/elfutils
endif
-libdw_a_LIBADD = $(addprefix ../libdwfl/,$(shell $(AR) t ../libdwfl/libdwfl.a))
+libdwfl_objects = $(shell $(AR) t ../libdwfl/libdwfl.a)
+libdw_a_LIBADD = $(addprefix ../libdwfl/,$(libdwfl_objects))
noinst_HEADERS = libdwP.h memory-access.h dwarf_abbrev_hash.h \
dwarf_sig8_hash.h cfi.h encoded-value.h
diff --git a/libelf/Makefile.am b/libelf/Makefile.am
index 5903ea8..4646fba 100644
--- a/libelf/Makefile.am
+++ b/libelf/Makefile.am
@@ -106,7 +106,7 @@ libelf.so: libelf_pic.a libelf.map
$(LINK) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \
-Wl,--version-script,$(srcdir)/libelf.map,--no-undefined \
-Wl,--soname,$@.$(VERSION),-z,defs,-z,relro $(libelf_so_LDLIBS)
- if readelf -d $@ | fgrep -q TEXTREL; then exit 1; fi
+ if $(READELF) -d $@ | fgrep -q TEXTREL; then exit 1; fi
ln -fs $@ $@.$(VERSION)
install: install-am libelf.so
diff --git a/tests/Makefile.am b/tests/Makefile.am
index d07cb0b..bc97523 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -231,7 +231,8 @@ installed_TESTS_ENVIRONMENT = libdir=$(DESTDIR)$(libdir); \
export abs_srcdir; export abs_builddir; \
export abs_top_builddir; \
export libdir; export bindir; \
- export LC_ALL; export LANG; export VALGRIND_CMD;
+ export LC_ALL; export LANG; export VALGRIND_CMD; \
+ NM=$(NM); export NM;
installed_LOG_COMPILER = $(abs_srcdir)/test-wrapper.sh \
installed $(tests_rpath) \
'$(program_transform_name)'
@@ -244,7 +245,8 @@ TESTS_ENVIRONMENT = LC_ALL=C; LANG=C; VALGRIND_CMD=$(valgrind_cmd); \
abs_top_builddir=$(abs_top_builddir); \
export abs_srcdir; export abs_builddir; \
export abs_top_builddir; \
- export LC_ALL; export LANG; export VALGRIND_CMD;
+ export LC_ALL; export LANG; export VALGRIND_CMD; \
+ NM=$(NM); export NM;
LOG_COMPILER = $(abs_srcdir)/test-wrapper.sh \
$(abs_top_builddir)/libdw:$(abs_top_builddir)/backends:$(abs_top_builddir)/libelf:$(abs_top_builddir)/libasm
diff --git a/tests/run-arsymtest.sh b/tests/run-arsymtest.sh
index dc016e1..b0fdfcd 100755
--- a/tests/run-arsymtest.sh
+++ b/tests/run-arsymtest.sh
@@ -28,7 +28,7 @@ tempfiles $okfile $tmpfile $testfile
result=77
if test -f $lib; then
# Generate list using `nm' we check against.
- nm -s $lib |
+ ${NM} -s $lib |
sed -e '1,/^Arch/d' -e '/^$/,$d' |
sort > $okfile
--
1.8.4.1
10 years, 5 months
[COMMITTED] readelf: Solve comparison between signed and unsigned compiler warning.
by Mark Wielaard
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
src/ChangeLog | 6 ++++++
src/readelf.c | 4 ++--
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/ChangeLog b/src/ChangeLog
index 72f9924..3012bf4 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,9 @@
+2013-11-05 Mark Wielaard <mjw(a)redhat.com>
+
+ * readelf.c (print_debug_ranges_section): Cast address to size_t
+ before comparison.
+ (print_debug_loc_section): Likewise.
+
2013-10-18 Mark Wielaard <mjw(a)redhat.com>
* ar.c (main): Correct operation check when instance_specifed is set.
diff --git a/src/readelf.c b/src/readelf.c
index d1a5b68..ac2f2b0 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -4638,7 +4638,7 @@ print_debug_ranges_section (Dwfl_Module *dwflmod,
offset, &readp, endp))
continue;
- if (unlikely (data->d_size - offset < address_size * 2))
+ if (unlikely (data->d_size - offset < (size_t) address_size * 2))
{
printf (gettext (" [%6tx] <INVALID DATA>\n"), offset);
break;
@@ -6554,7 +6554,7 @@ print_debug_loc_section (Dwfl_Module *dwflmod,
&cu, offset, &readp, endp))
continue;
- if (unlikely (data->d_size - offset < address_size * 2))
+ if (unlikely (data->d_size - offset < (size_t) address_size * 2))
{
printf (gettext (" [%6tx] <INVALID DATA>\n"), offset);
break;
--
1.7.1
10 years, 5 months
[PATCH] libdw: Make dwarf_getfuncs find all (defining) DW_TAG_subprogram DIEs.
by Mark Wielaard
dwarf_getfuncs used to return only the DW_TAG_subprogram DIEs that were
direct children of the given CU. This is normally how GCC outputs the
subprogram DIEs. But not always. For nested functions the subprogram DIE
is placed under the subprogram DIE where it is nested. Other compilers
might output the defining subprogram DIE of a C++ class function under
the DW_TAG_namespace DIE where it was defined. Both such constructs seem
allowed by the DWARF specification. So just searching the CU DIE children
was wrong.
To find all (defining) subprogram DIEs in a CU dwarf_getfuncs should
use __libdw_visit_scopes to walk the tree. The only tricky part is
making sure the offset returned and used when the callback returns
DWARF_CB_ABORT is correct and the search continues at the right spot
in the CU DIE tree.
Two new testcases were added that fail without this patch. And the
allfcts test was tweaked so that it always returns DWARF_CB_ABORT
from its callback to make sure the offset handling is correct.
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
libdw/ChangeLog | 6 +++
libdw/dwarf_getfuncs.c | 79 ++++++++++++++++++++++++++-------------
tests/ChangeLog | 10 +++++
tests/Makefile.am | 1 +
tests/allfcts.c | 12 ++++-
tests/run-allfcts.sh | 56 +++++++++++++++++++++++++++-
tests/testfile_class_func.bz2 | Bin 0 -> 2962 bytes
tests/testfile_nested_funcs.bz2 | Bin 0 -> 3045 bytes
8 files changed, 134 insertions(+), 30 deletions(-)
create mode 100755 tests/testfile_class_func.bz2
create mode 100755 tests/testfile_nested_funcs.bz2
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index c8398b2..07090ba 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,9 @@
+2013-09-18 Mark Wielaard <mjw(a)redhat.com>
+
+ * dwarf_getfuncs.c (visitor_info): New struct.
+ (tree_visitor): New function.
+ (dwarf_getfuncs): Use __libdw_visit_scopes with tree_visitor.
+
2013-08-24 Mark Wielaard <mjw(a)redhat.com>
* dwarf_getlocation.c (store_implicit_value): Don't take data
diff --git a/libdw/dwarf_getfuncs.c b/libdw/dwarf_getfuncs.c
index afc5b6e..c5a7618 100644
--- a/libdw/dwarf_getfuncs.c
+++ b/libdw/dwarf_getfuncs.c
@@ -1,5 +1,5 @@
/* Get function information.
- Copyright (C) 2005 Red Hat, Inc.
+ Copyright (C) 2005, 2013 Red Hat, Inc.
This file is part of elfutils.
Written by Ulrich Drepper <drepper(a)redhat.com>, 2005.
@@ -35,6 +35,51 @@
#include "libdwP.h"
+struct visitor_info
+{
+ /* The user callback of dwarf_getfuncs. */
+ int (*callback) (Dwarf_Die *, void *);
+
+ /* The user arg value to dwarf_getfuncs. */
+ void *arg;
+
+ /* The DIE offset where to (re)start the search. */
+ Dwarf_Off offset;
+};
+
+static int
+tree_visitor (unsigned int depth __attribute__ ((unused)),
+ struct Dwarf_Die_Chain *chain, void *arg)
+{
+ struct visitor_info *const v = arg;
+ Dwarf_Die *die = &chain->die;
+ Dwarf_Off offset = v->offset;
+ Dwarf_Off die_offset = INTUSE(dwarf_dieoffset) (die);
+
+ /* Skip any subtrees till we find the first DIE offset we are
+ interested in. */
+ if (die_offset < offset)
+ {
+ Dwarf_Die sibling;
+ if (INTUSE(dwarf_siblingof) (die, &sibling) == 0
+ && INTUSE(dwarf_dieoffset) (&sibling) <= offset)
+ {
+ chain->prune = true;
+ return DWARF_CB_OK;
+ }
+ }
+
+ /* If we aren't past the requested DIE offset or this isn't a
+ (defining) subprogram entity, skip DIE. */
+ if (die_offset <= offset
+ || INTUSE(dwarf_tag) (die) != DW_TAG_subprogram
+ || INTUSE(dwarf_hasattr) (die, DW_AT_declaration))
+ return DWARF_CB_OK;
+
+ v->offset = die_offset;
+ return (*v->callback) (die, v->arg);
+}
+
ptrdiff_t
dwarf_getfuncs (Dwarf_Die *cudie, int (*callback) (Dwarf_Die *, void *),
void *arg, ptrdiff_t offset)
@@ -43,31 +88,13 @@ dwarf_getfuncs (Dwarf_Die *cudie, int (*callback) (Dwarf_Die *, void *),
|| INTUSE(dwarf_tag) (cudie) != DW_TAG_compile_unit))
return -1;
- Dwarf_Die die_mem;
- Dwarf_Die *die;
+ struct visitor_info v = { callback, arg, offset };
+ struct Dwarf_Die_Chain chain = { .die = CUDIE (cudie->cu),
+ .parent = NULL };
+ int res = __libdw_visit_scopes (0, &chain, &tree_visitor, NULL, &v);
- int res;
- if (offset == 0)
- res = INTUSE(dwarf_child) (cudie, &die_mem);
+ if (res == DWARF_CB_ABORT)
+ return v.offset;
else
- {
- die = INTUSE(dwarf_offdie) (cudie->cu->dbg, offset, &die_mem);
- res = INTUSE(dwarf_siblingof) (die, &die_mem);
- }
- die = res != 0 ? NULL : &die_mem;
-
- while (die != NULL)
- {
- if (INTUSE(dwarf_tag) (die) == DW_TAG_subprogram)
- {
- if (callback (die, arg) != DWARF_CB_OK)
- return INTUSE(dwarf_dieoffset) (die);
- }
-
- if (INTUSE(dwarf_siblingof) (die, &die_mem) != 0)
- break;
- }
-
- /* That's all. */
- return 0;
+ return res;
}
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 9ea285f..810c89a 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,13 @@
+2013-09-18 Mark Wielaard <mjw(a)redhat.com>
+
+ * allfcts.c (cb): Return DWARF_CB_ABORT.
+ (main): Iterate over all offsets returned by dwarf_getfuncs.
+ * run-allfcts.sh: Add nested_funcs and class_func testcases.
+ * testfile_nested_funcs.bz2: New test file.
+ * testfile_class_func.bz2: Likewise.
+ * Makefile.am (EXTRA_DIST): Add testfile_class_func.bz2 and
+ testfile_nested_funcs.bz2.
+
2013-08-30 Mark Wielaard <mjw(a)redhat.com>
* Makefile.am (check_PROGRAMS): Add varlocs.
diff --git a/tests/Makefile.am b/tests/Makefile.am
index e06d914..58db6c3 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -119,6 +119,7 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \
testfile5.bz2 testfile6.bz2 testfile7.bz2 testfile8.bz2 \
testfile9.bz2 testfile10.bz2 testfile11.bz2 testfile12.bz2 \
testfile13.bz2 run-strip-test3.sh run-allfcts.sh \
+ testfile_class_func.bz2 testfile_nested_funcs.bz2 \
run-line2addr.sh run-elflint-test.sh testfile14.bz2 \
run-strip-test4.sh run-strip-test5.sh run-strip-test6.sh \
run-strip-test7.sh run-strip-test8.sh run-strip-groups.sh \
diff --git a/tests/allfcts.c b/tests/allfcts.c
index f14b493..7803722 100644
--- a/tests/allfcts.c
+++ b/tests/allfcts.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005 Red Hat, Inc.
+/* Copyright (C) 2005, 2013 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -34,7 +34,7 @@ cb (Dwarf_Die *func, void *arg __attribute__ ((unused)))
printf ("%s:%d:%s\n", file, line, fct);
- return DWARF_CB_OK;
+ return DWARF_CB_ABORT;
}
@@ -57,7 +57,13 @@ main (int argc, char *argv[])
Dwarf_Die die_mem;
Dwarf_Die *die = dwarf_offdie (dbg, off + cuhl, &die_mem);
- (void) dwarf_getfuncs (die, cb, NULL, 0);
+ /* Explicitly stop in the callback and then resume each time. */
+ ptrdiff_t doff = 0;
+ do
+ {
+ doff = dwarf_getfuncs (die, cb, NULL, doff);
+ }
+ while (doff > 0);
off = noff;
}
diff --git a/tests/run-allfcts.sh b/tests/run-allfcts.sh
index 30f7dd4..6eaf13c 100755
--- a/tests/run-allfcts.sh
+++ b/tests/run-allfcts.sh
@@ -1,5 +1,5 @@
#! /bin/sh
-# Copyright (C) 2005 Red Hat, Inc.
+# Copyright (C) 2005, 2013 Red Hat, Inc.
# This file is part of elfutils.
# Written by Ulrich Drepper <drepper(a)redhat.com>, 2005.
#
@@ -37,4 +37,58 @@ testrun_compare ${abs_builddir}/allfcts testfile testfile2 testfile8 <<\EOF
/home/drepper/gnu/elfutils/build/src/../../src/strip.c:313:handle_elf
EOF
+# = nested_funcs.c =
+#
+# static int
+# foo (int x)
+# {
+# int bar (int y)
+# {
+# return x - y;
+# }
+#
+# return bar (x * 2);
+# }
+#
+# int
+# main (int argc, char ** argv)
+# {
+# return foo (argc);
+# }
+#
+# gcc -g -o nested_funcs nested_funcs.c
+
+# = class_func.cxx =
+#
+# namespace foobar
+# {
+# class Foo
+# {
+# public:
+# int bar(int x);
+# };
+#
+# int Foo::bar(int x) { return x - 42; }
+# };
+#
+# int
+# main (int argc, char **argv)
+# {
+# foobar::Foo foo;
+#
+# return foo.bar (42);
+# }
+#
+# clang++ -g -o class_func class_func.cxx
+
+testfiles testfile_nested_funcs testfile_class_func
+
+testrun_compare ${abs_builddir}/allfcts testfile_nested_funcs testfile_class_func <<\EOF
+/home/mark/src/tests/nested/nested_funcs.c:2:foo
+/home/mark/src/tests/nested/nested_funcs.c:4:bar
+/home/mark/src/tests/nested/nested_funcs.c:13:main
+/home/mark/src/tests/nested/class_func.cxx:6:bar
+/home/mark/src/tests/nested/class_func.cxx:13:main
+EOF
+
exit 0
diff --git a/tests/testfile_class_func.bz2 b/tests/testfile_class_func.bz2
new file mode 100755
index 0000000000000000000000000000000000000000..e40dcf2623637a709110115e013273e3e8277eaa
GIT binary patch
literal 2962
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
I0;uKJAjNljEdT%j
literal 0
HcmV?d00001
diff --git a/tests/testfile_nested_funcs.bz2 b/tests/testfile_nested_funcs.bz2
new file mode 100755
index 0000000000000000000000000000000000000000..d36b603ebd25ddd53367909dc7512b05930fdd6b
GIT binary patch
literal 3045
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
literal 0
HcmV?d00001
--
1.7.1
10 years, 5 months