From: Roland McGrath Date: Tue, 21 Apr 2009 22:44:07 +0000 (-0700) Subject: Fix derelocate crash for non-ET_REL file with some sh_addr at 0. X-Git-Tag: elfutils-0.141~8 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=19a8e4dbd8268b8f0add9803d80d0266eac1aaa9;p=thirdparty%2Felfutils.git Fix derelocate crash for non-ET_REL file with some sh_addr at 0. --- diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog index c2eb39d94..bc4344c39 100644 --- a/libdwfl/ChangeLog +++ b/libdwfl/ChangeLog @@ -1,3 +1,12 @@ +2009-04-21 Roland McGrath + + * 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 * dwfl_module_getdwarf.c (__libdwfl_getelf): Add internal_function. diff --git a/libdwfl/derelocate.c b/libdwfl/derelocate.c index f2a64675e..c300f84ba 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 f3fcc190e..a3797a5ad 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 816d21433..f78e6ec03 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 e809a979d..b236ca50a 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 25f271f12..70e9c0270 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,9 @@ +2009-04-21 Roland McGrath + + * 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 * testfile44.S.bz2: Add tests for dppd, dpps, insertps, movntdqa, diff --git a/tests/Makefile.am b/tests/Makefile.am index b533521c5..81c1ab76b 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 d525523d9..2a188915e 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 < 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 000000000..fce433215 Binary files /dev/null and b/tests/testfile50.bz2 differ