summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoland McGrath <roland@redhat.com>2009-04-21 15:44:07 -0700
committerRoland McGrath <roland@redhat.com>2009-04-21 15:44:07 -0700
commit19a8e4dbd8268b8f0add9803d80d0266eac1aaa9 (patch)
tree195a4ca16cf17038bd1be18220a569c88747ed56
parent1036157150672569a79d30c9b59cc7623e3e8e60 (diff)
downloadelfutils-19a8e4dbd8268b8f0add9803d80d0266eac1aaa9.tar.gz
Fix derelocate crash for non-ET_REL file with some sh_addr at 0.
-rw-r--r--libdwfl/ChangeLog9
-rw-r--r--libdwfl/derelocate.c5
-rw-r--r--libdwfl/dwfl_module_build_id.c5
-rw-r--r--libdwfl/dwfl_module_getsym.c30
-rw-r--r--libdwfl/relocate.c2
-rw-r--r--tests/ChangeLog6
-rw-r--r--tests/Makefile.am4
-rwxr-xr-xtests/run-addrname-test.sh1
-rwxr-xr-xtests/run-dwfl-addr-sect.sh8
-rw-r--r--tests/testfile50.bz2bin0 -> 229 bytes
10 files changed, 47 insertions, 23 deletions
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index c2eb39d9..bc4344c3 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,12 @@
+2009-04-21 Roland McGrath <roland@redhat.com>
+
+ * dwfl_module_getsym.c: Apply non-ET_REL bias only if SHF_ALLOC.
+
+ * relocate.c (__libdwfl_relocate_value): Assert that MOD is ET_REL.
+ * derelocate.c (cache_sections): Call __libdwfl_relocate_value only
+ for ET_REL.
+ * dwfl_module_build_id.c (__libdwfl_find_build_id): Likewise.
+
2009-04-20 Roland McGrath <roland@redhat.com>
* dwfl_module_getdwarf.c (__libdwfl_getelf): Add internal_function.
diff --git a/libdwfl/derelocate.c b/libdwfl/derelocate.c
index f2a64675..c300f84b 100644
--- a/libdwfl/derelocate.c
+++ b/libdwfl/derelocate.c
@@ -1,5 +1,5 @@
/* Recover relocatibility for addresses computed from debug information.
- Copyright (C) 2005, 2006, 2007, 2008 Red Hat, Inc.
+ Copyright (C) 2005-2009 Red Hat, Inc.
This file is part of Red Hat elfutils.
Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -110,7 +110,8 @@ cache_sections (Dwfl_Module *mod)
if (shdr == NULL)
goto elf_error;
- if ((shdr->sh_flags & SHF_ALLOC) && shdr->sh_addr == 0)
+ if ((shdr->sh_flags & SHF_ALLOC) && shdr->sh_addr == 0
+ && mod->e_type == ET_REL)
{
/* This section might not yet have been looked at. */
if (__libdwfl_relocate_value (mod, mod->main.elf, &shstrndx,
diff --git a/libdwfl/dwfl_module_build_id.c b/libdwfl/dwfl_module_build_id.c
index f3fcc190..a3797a5a 100644
--- a/libdwfl/dwfl_module_build_id.c
+++ b/libdwfl/dwfl_module_build_id.c
@@ -135,8 +135,9 @@ __libdwfl_find_build_id (Dwfl_Module *mod, bool set, Elf *elf)
/* Determine the right sh_addr in this module. */
GElf_Addr vaddr = 0;
if (!(shdr->sh_flags & SHF_ALLOC)
- || __libdwfl_relocate_value (mod, elf, &shstrndx,
- elf_ndxscn (scn), &vaddr))
+ || (mod->e_type == ET_REL
+ && __libdwfl_relocate_value (mod, elf, &shstrndx,
+ elf_ndxscn (scn), &vaddr)))
vaddr = NO_VADDR;
result = check_notes (mod, set, elf_getdata (scn, NULL), vaddr);
}
diff --git a/libdwfl/dwfl_module_getsym.c b/libdwfl/dwfl_module_getsym.c
index 816d2143..f78e6ec0 100644
--- a/libdwfl/dwfl_module_getsym.c
+++ b/libdwfl/dwfl_module_getsym.c
@@ -74,25 +74,25 @@ dwfl_module_getsym (Dwfl_Module *mod, int ndx,
if (sym->st_shndx != SHN_XINDEX)
shndx = sym->st_shndx;
- if (shndxp != NULL)
+ /* Figure out whether this symbol points into an SHF_ALLOC section. */
+ bool alloc = true;
+ if ((shndxp != NULL || mod->e_type != ET_REL)
+ && (sym->st_shndx == SHN_XINDEX
+ || (sym->st_shndx < SHN_LORESERVE && sym->st_shndx != SHN_UNDEF)))
{
- *shndxp = shndx;
-
- /* Yield -1 in case of a non-SHF_ALLOC section. */
- if (sym->st_shndx == SHN_XINDEX
- || (sym->st_shndx < SHN_LORESERVE && sym->st_shndx != SHN_UNDEF))
- {
- GElf_Shdr shdr_mem;
- GElf_Shdr *shdr = gelf_getshdr (elf_getscn (mod->symfile->elf, shndx),
- &shdr_mem);
- if (unlikely (shdr == NULL) || !(shdr->sh_flags & SHF_ALLOC))
- *shndxp = (GElf_Word) -1;
- }
+ GElf_Shdr shdr_mem;
+ GElf_Shdr *shdr = gelf_getshdr (elf_getscn (mod->symfile->elf, shndx),
+ &shdr_mem);
+ alloc = unlikely (shdr == NULL) || (shdr->sh_flags & SHF_ALLOC);
}
+ if (shndxp != NULL)
+ /* Yield -1 in case of a non-SHF_ALLOC section. */
+ *shndxp = alloc ? shndx : (GElf_Word) -1;
+
switch (sym->st_shndx)
{
- case SHN_ABS:
+ case SHN_ABS: /* XXX sometimes should use bias?? */
case SHN_UNDEF:
case SHN_COMMON:
break;
@@ -112,7 +112,7 @@ dwfl_module_getsym (Dwfl_Module *mod, int ndx,
return NULL;
}
}
- else
+ else if (alloc)
/* Apply the bias to the symbol value. */
sym->st_value += mod->symfile->bias;
break;
diff --git a/libdwfl/relocate.c b/libdwfl/relocate.c
index e809a979..b236ca50 100644
--- a/libdwfl/relocate.c
+++ b/libdwfl/relocate.c
@@ -59,6 +59,8 @@ internal_function
__libdwfl_relocate_value (Dwfl_Module *mod, Elf *elf, size_t *shstrndx,
Elf32_Word shndx, GElf_Addr *value)
{
+ assert (mod->e_type == ET_REL);
+
Elf_Scn *refscn = elf_getscn (elf, shndx);
GElf_Shdr refshdr_mem, *refshdr = gelf_getshdr (refscn, &refshdr_mem);
if (refshdr == NULL)
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 25f271f1..70e9c027 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,9 @@
+2009-04-21 Roland McGrath <roland@redhat.com>
+
+ * testfile50.bz2: New data file.
+ * Makefile.am (EXTRA_DIST): Add it.
+ * run-dwfl-addr-sect.sh: Add a case using it.
+
2008-12-31 Ulrich Drepper <drepper@redhat.com>
* testfile44.S.bz2: Add tests for dppd, dpps, insertps, movntdqa,
diff --git a/tests/Makefile.am b/tests/Makefile.am
index b533521c..81c1ab76 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,6 +1,6 @@
## Process this file with automake to create Makefile.in
##
-## Copyright (C) 1996-2002, 2003, 2004, 2005, 2006, 2007, 2008 Red Hat, Inc.
+## Copyright (C) 1996-2009 Red Hat, Inc.
## This file is part of Red Hat elfutils.
##
## Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -141,7 +141,7 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \
testfile44.S.bz2 testfile44.expect.bz2 run-disasm-x86.sh \
testfile45.S.bz2 testfile45.expect.bz2 run-disasm-x86-64.sh \
testfile46.bz2 testfile47.bz2 testfile48.bz2 testfile48.debug.bz2 \
- testfile49.bz2
+ testfile49.bz2 testfile50.bz2
installed_TESTS_ENVIRONMENT = libdir=$(DESTDIR)$(libdir) \
bindir=$(DESTDIR)$(bindir) \
diff --git a/tests/run-addrname-test.sh b/tests/run-addrname-test.sh
index d525523d..2a188915 100755
--- a/tests/run-addrname-test.sh
+++ b/tests/run-addrname-test.sh
@@ -64,6 +64,7 @@ EOF
testfiles testfile12 testfile14
tempfiles testmaps
+remove_files=
cat > testmaps <<EOF
00400000-00401000 r-xp 00000000 fd:01 4006812 `pwd`/testfile14
diff --git a/tests/run-dwfl-addr-sect.sh b/tests/run-dwfl-addr-sect.sh
index 98666f37..f33a6e42 100755
--- a/tests/run-dwfl-addr-sect.sh
+++ b/tests/run-dwfl-addr-sect.sh
@@ -1,5 +1,5 @@
#! /bin/sh
-# Copyright (C) 2007, 2008 Red Hat, Inc.
+# Copyright (C) 2007-2009 Red Hat, Inc.
# This file is part of Red Hat elfutils.
#
# Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -25,7 +25,7 @@
. $srcdir/test-subr.sh
-testfiles testfile43
+testfiles testfile43 testfile50
testrun_compare ./dwfl-addr-sect -e testfile43 0x64 0x8 0x98 <<\EOF
address 0x64 => module "" section 4 + 0
@@ -33,4 +33,8 @@ address 0x8 => module "" section 1 + 0x8
address 0x98 => module "" section 7 + 0
EOF
+testrun_compare ./dwfl-addr-sect -e testfile50 0x1 <<\EOF
+address 0x1 => module "" section 1 + 0x1
+EOF
+
exit 0
diff --git a/tests/testfile50.bz2 b/tests/testfile50.bz2
new file mode 100644
index 00000000..fce43321
--- /dev/null
+++ b/tests/testfile50.bz2
Binary files differ