]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
libdw: dwarf_begin_elf should use elf_getshdrstrndx to get section names.
authorMark Wielaard <mark@klomp.org>
Sat, 4 Aug 2018 20:34:32 +0000 (22:34 +0200)
committerMark Wielaard <mark@klomp.org>
Thu, 13 Sep 2018 22:20:49 +0000 (00:20 +0200)
dwarf_begin_elf used the Ehdr e_shstrndx to get the shdr string table
section. This does not work for ELF files with more than SHN_LORESERVE
sections. Use elf_getshdrstrndx, and don't pass around the ehdr.

Add a simple testcase that fails before the patch because dwarf_begin
return an error.

Signed-off-by: Mark Wielaard <mark@klomp.org>
libdw/ChangeLog
libdw/dwarf_begin_elf.c
tests/ChangeLog
tests/Makefile.am
tests/run-typeiter-many.sh [new file with mode: 0755]

index 7cb2592354bcae3ab749a10ccff539338a6c4394..ebe002cdcdaa3693f4e61d7156623875feba5f58 100644 (file)
@@ -1,3 +1,12 @@
+2018-09-13  Mark Wielaard  <mark@klomp.org>
+
+       * dwarf_begin_elf.c (check_section): Drop ehdr argument, add and
+       use shstrndx argument.
+       (global_read): Likewise.
+       (scngrp_read): Likewise.
+       (dwarf_begin_elf): Call elf_getshdrstrndx. Pass shstrndx to
+       global_read or scngrp_read.
+
 2018-08-18  Mark Wielaard  <mark@klomp.org>
 
        * dwarf_getabbrev.c (__libdw_getabbrev): Continue until both name
index 184a6dc953a4c8f9961dc92786e4c816b18473d6..38c8f5c605041720fd2d295c0103a72d30730a49 100644 (file)
@@ -71,7 +71,7 @@ static const char dwarf_scnnames[IDX_last][19] =
 #define ndwarf_scnnames (sizeof (dwarf_scnnames) / sizeof (dwarf_scnnames[0]))
 
 static Dwarf *
-check_section (Dwarf *result, GElf_Ehdr *ehdr, Elf_Scn *scn, bool inscngrp)
+check_section (Dwarf *result, size_t shstrndx, Elf_Scn *scn, bool inscngrp)
 {
   GElf_Shdr shdr_mem;
   GElf_Shdr *shdr;
@@ -101,7 +101,7 @@ check_section (Dwarf *result, GElf_Ehdr *ehdr, Elf_Scn *scn, bool inscngrp)
 
   /* We recognize the DWARF section by their names.  This is not very
      safe and stable but the best we can do.  */
-  const char *scnname = elf_strptr (result->elf, ehdr->e_shstrndx,
+  const char *scnname = elf_strptr (result->elf, shstrndx,
                                    shdr->sh_name);
   if (scnname == NULL)
     {
@@ -302,19 +302,19 @@ valid_p (Dwarf *result)
 
 
 static Dwarf *
-global_read (Dwarf *result, Elf *elf, GElf_Ehdr *ehdr)
+global_read (Dwarf *result, Elf *elf, size_t shstrndx)
 {
   Elf_Scn *scn = NULL;
 
   while (result != NULL && (scn = elf_nextscn (elf, scn)) != NULL)
-    result = check_section (result, ehdr, scn, false);
+    result = check_section (result, shstrndx, scn, false);
 
   return valid_p (result);
 }
 
 
 static Dwarf *
-scngrp_read (Dwarf *result, Elf *elf, GElf_Ehdr *ehdr, Elf_Scn *scngrp)
+scngrp_read (Dwarf *result, Elf *elf, size_t shstrndx, Elf_Scn *scngrp)
 {
   GElf_Shdr shdr_mem;
   GElf_Shdr *shdr = gelf_getshdr (scngrp, &shdr_mem);
@@ -363,7 +363,7 @@ scngrp_read (Dwarf *result, Elf *elf, GElf_Ehdr *ehdr, Elf_Scn *scngrp)
          return NULL;
        }
 
-      result = check_section (result, ehdr, scn, true);
+      result = check_section (result, shstrndx, scn, true);
       if (result == NULL)
        break;
     }
@@ -425,15 +425,26 @@ dwarf_begin_elf (Elf *elf, Dwarf_Cmd cmd, Elf_Scn *scngrp)
 
   if (cmd == DWARF_C_READ || cmd == DWARF_C_RDWR)
     {
+      /* All sections are recognized by name, so pass the section header
+        string index along to easily get the section names.  */
+      size_t shstrndx;
+      if (elf_getshdrstrndx (elf, &shstrndx) != 0)
+       {
+         Dwarf_Sig8_Hash_free (&result->sig8_hash);
+         __libdw_seterrno (DWARF_E_INVALID_ELF);
+         free (result);
+         return NULL;
+       }
+
       /* If the caller provides a section group we get the DWARF
         sections only from this setion group.  Otherwise we search
         for the first section with the required name.  Further
         sections with the name are ignored.  The DWARF specification
         does not really say this is allowed.  */
       if (scngrp == NULL)
-       return global_read (result, elf, ehdr);
+       return global_read (result, elf, shstrndx);
       else
-       return scngrp_read (result, elf, ehdr, scngrp);
+       return scngrp_read (result, elf, shstrndx, scngrp);
     }
   else if (cmd == DWARF_C_WRITE)
     {
index 7668a661affea5738580d46463c9c054608798a7..33fee35d44922f41817a1f09587bb2e30b4ce1a8 100644 (file)
@@ -1,3 +1,9 @@
+2018-09-13  Mark Wielaard  <mark@klomp.org>
+
+       * run-typeiter-many.sh: New test.
+       * Makefile.am (TESTS): Add run-typeiter-many.sh.
+       (EXTRA_DIST): Likewise.
+
 2018-09-13  Mark Wielaard  <mark@klomp.org>
 
        * run-copymany-sections.sh: New test.
index fc7d7bc6897bd54bd88f3d9a077398c5e3006c76..d8ebd035224ba77753dcb5e63f012ca7d0f102d8 100644 (file)
@@ -155,7 +155,8 @@ TESTS = run-arextract.sh run-arsymtest.sh run-ar.sh newfile test-nlist \
        run-all-dwarf-ranges.sh run-unit-info.sh \
        run-reloc-bpf.sh \
        run-next-cfi.sh run-next-cfi-self.sh \
-       run-copyadd-sections.sh run-copymany-sections.sh
+       run-copyadd-sections.sh run-copymany-sections.sh \
+       run-typeiter-many.sh
 
 if !BIARCH
 export ELFUTILS_DISABLE_BIARCH = 1
@@ -406,7 +407,8 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \
             run-unit-info.sh run-next-cfi.sh run-next-cfi-self.sh \
             testfile-riscv64.bz2 testfile-riscv64-s.bz2 \
             testfile-riscv64-core.bz2 \
-            run-copyadd-sections.sh run-copymany-sections.sh
+            run-copyadd-sections.sh run-copymany-sections.sh \
+            run-typeiter-many.sh
 
 if USE_VALGRIND
 valgrind_cmd='valgrind -q --leak-check=full --error-exitcode=1'
diff --git a/tests/run-typeiter-many.sh b/tests/run-typeiter-many.sh
new file mode 100755 (executable)
index 0000000..39168f2
--- /dev/null
@@ -0,0 +1,31 @@
+#! /bin/sh
+# Copyright (C) 2018 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
+
+
+# Like run-typeiter.sh but we first add many sections to make sure
+# dwarf_begin actually recognizes the debug section names.
+testfiles testfile-debug-types
+
+testrun ${abs_builddir}/addsections 65535 testfile-debug-types
+testrun_compare ${abs_builddir}/typeiter2 testfile-debug-types <<\EOF
+ok A [68]
+ok B [38]
+EOF
+
+exit 0