]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
Fix derelocate crash for non-ET_REL file with some sh_addr at 0.
authorRoland McGrath <roland@redhat.com>
Tue, 21 Apr 2009 22:44:07 +0000 (15:44 -0700)
committerRoland McGrath <roland@redhat.com>
Tue, 21 Apr 2009 22:44:07 +0000 (15:44 -0700)
libdwfl/ChangeLog
libdwfl/derelocate.c
libdwfl/dwfl_module_build_id.c
libdwfl/dwfl_module_getsym.c
libdwfl/relocate.c
tests/ChangeLog
tests/Makefile.am
tests/run-addrname-test.sh
tests/run-dwfl-addr-sect.sh
tests/testfile50.bz2 [new file with mode: 0644]

index c2eb39d943eb7b3d02054646ce0de57ab2a34327..bc4344c3999ca073a65a80898e540ba04b2ad959 100644 (file)
@@ -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.
index f2a64675e80144ed4bfadd5bf9ace9e63c4e5ee1..c300f84ba9c774d76dd7ff55714b751ee3fb9962 100644 (file)
@@ -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,
index f3fcc190ee319c5e676ce211d387e42477fd346e..a3797a5ad716c869731cc65ea23a12d64181ec5b 100644 (file)
@@ -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);
          }
index 816d21433c0327ebb3b619350a8c68523f413b51..f78e6ec03fdcf3fc3296705d5bf319dbd8974b94 100644 (file)
@@ -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;
index e809a979db9c26fc7ca9aa7bf70559c20897b87e..b236ca50a6effed196cbc1e77159cd74b579d9a6 100644 (file)
@@ -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)
index 25f271f124bf01fae99ef2459edfb5cdc2742867..70e9c0270c1db6c615b5450cd8c520dbbecdbbde 100644 (file)
@@ -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,
index b533521c5988fdbd6aa19e4cb5f43fb62306d083..81c1ab76ba6f50446ba854e1dd5b8de502213b31 100644 (file)
@@ -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) \
index d525523d918808e1ffeaf82fa546e0b51c562918..2a188915e71ed45491b17508dfd1a2ea8dfe1367 100755 (executable)
@@ -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
index 98666f376ebae7ddcce7df724d7cf7b2a8290f08..f33a6e427bde9630fdfee11687fe1dd0d1f473c9 100755 (executable)
@@ -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 (file)
index 0000000..fce4332
Binary files /dev/null and b/tests/testfile50.bz2 differ