]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
libdw: set address size, offset size and version on fake CUs
authorMark Wielaard <mark@klomp.org>
Thu, 26 Aug 2021 17:05:45 +0000 (19:05 +0200)
committerMark Wielaard <mark@klomp.org>
Sun, 12 Sep 2021 19:37:31 +0000 (21:37 +0200)
There are three "fake CUs" that are associated with .debug_loc,
.debug_loclist and .debug_addr.  These fake CUs are used for "fake
attributes" to provide values that are stored in these sections
instead of in the .debug_info section. These fake CUs didn't have the
address size, offset size and DWARF version set. This meant that
values that depended on those properties might not be interpreted
correctly. One example was the value associated with a DW_OP_addrx
(which comes from the .debug_addr section).

Add a testcase using varlocs to test that addresses can correctly be
retrieved for gcc/clang, DWARF4/5 and 32/64 bits objects.

https://sourceware.org/bugzilla/show_bug.cgi?id=28220

Signed-off-by: Mark Wielaard <mark@klomp.org>
13 files changed:
libdw/ChangeLog
libdw/dwarf_begin_elf.c
tests/ChangeLog
tests/Makefile.am
tests/run-varlocs-vars.sh [new file with mode: 0755]
tests/testfile-vars-clang-dwarf4-32.o.bz2 [new file with mode: 0644]
tests/testfile-vars-clang-dwarf4-64.o.bz2 [new file with mode: 0644]
tests/testfile-vars-clang-dwarf5-32.o.bz2 [new file with mode: 0644]
tests/testfile-vars-clang-dwarf5-64.o.bz2 [new file with mode: 0644]
tests/testfile-vars-gcc-dwarf4-32.o.bz2 [new file with mode: 0644]
tests/testfile-vars-gcc-dwarf4-64.o.bz2 [new file with mode: 0644]
tests/testfile-vars-gcc-dwarf5-32.o.bz2 [new file with mode: 0644]
tests/testfile-vars-gcc-dwarf5-64.o.bz2 [new file with mode: 0644]

index 768d5c25c22a0d860baa17a53025dded7d7799a4..b707bbfe63b7e659f57622c050a3befa5cd24dca 100644 (file)
@@ -1,3 +1,8 @@
+2021-09-08  Mark Wielaard  <mark@klomp.org>
+
+       * dwarf_begin_elf.c (valid_p): Identify ELF class and use this to set
+       address_size of the fake CUs. Also set offset_size and DWARF version.
+
 2021-09-06  Dmitry V. Levin  <ldv@altlinux.org>
 
        * dwarf_begin_elf.c (valid_p): Remove casts of malloc return values.
index 7bde61b3de2593b514c8dc259d88adca6ad8def4..53b44cd43073fb15466a42ed88088aabbec0a01f 100644 (file)
@@ -224,6 +224,23 @@ valid_p (Dwarf *result)
       result = NULL;
     }
 
+  /* We are setting up some "fake" CUs, which need an address size.
+     Check the ELF class to come up with something reasonable.  */
+  int elf_addr_size = 8;
+  if (result != NULL)
+    {
+      GElf_Ehdr ehdr;
+      if (gelf_getehdr (result->elf, &ehdr) == NULL)
+       {
+         Dwarf_Sig8_Hash_free (&result->sig8_hash);
+         __libdw_seterrno (DWARF_E_INVALID_ELF);
+         free (result);
+         result = NULL;
+       }
+      else if (ehdr.e_ident[EI_CLASS] == ELFCLASS32)
+       elf_addr_size = 4;
+    }
+
   /* For dwarf_location_attr () we need a "fake" CU to indicate
      where the "fake" attribute data comes from.  This is a block
      inside the .debug_loc or .debug_loclists section.  */
@@ -247,8 +264,9 @@ valid_p (Dwarf *result)
            = (result->sectiondata[IDX_debug_loc]->d_buf
               + result->sectiondata[IDX_debug_loc]->d_size);
          result->fake_loc_cu->locs = NULL;
-         result->fake_loc_cu->address_size = 0;
-         result->fake_loc_cu->version = 0;
+         result->fake_loc_cu->address_size = elf_addr_size;
+         result->fake_loc_cu->offset_size = 4;
+         result->fake_loc_cu->version = 4;
          result->fake_loc_cu->split = NULL;
        }
     }
@@ -274,8 +292,9 @@ valid_p (Dwarf *result)
            = (result->sectiondata[IDX_debug_loclists]->d_buf
               + result->sectiondata[IDX_debug_loclists]->d_size);
          result->fake_loclists_cu->locs = NULL;
-         result->fake_loclists_cu->address_size = 0;
-         result->fake_loclists_cu->version = 0;
+         result->fake_loclists_cu->address_size = elf_addr_size;
+         result->fake_loclists_cu->offset_size = 4;
+         result->fake_loclists_cu->version = 5;
          result->fake_loclists_cu->split = NULL;
        }
     }
@@ -306,8 +325,9 @@ valid_p (Dwarf *result)
            = (result->sectiondata[IDX_debug_addr]->d_buf
               + result->sectiondata[IDX_debug_addr]->d_size);
          result->fake_addr_cu->locs = NULL;
-         result->fake_addr_cu->address_size = 0;
-         result->fake_addr_cu->version = 0;
+         result->fake_addr_cu->address_size = elf_addr_size;
+         result->fake_addr_cu->offset_size = 4;
+         result->fake_addr_cu->version = 5;
          result->fake_addr_cu->split = NULL;
        }
     }
index caee93d394afe3475f7344290f73ec62f065c239..1154686a8e388ae51605c9acbbe33d38daab66dc 100644 (file)
@@ -1,3 +1,17 @@
+2021-09-08  Mark Wielaard  <mark@klomp.org>
+
+       * run-varlocs-vars.sh: New test.
+       * testfile-vars-clang-dwarf4-32.o.bz2: New test file.
+       * testfile-vars-clang-dwarf4-64.o.bz2: Likewise.
+       * testfile-vars-clang-dwarf5-32.o.bz2: Likewise.
+       * testfile-vars-clang-dwarf5-64.o.bz2: Likewise.
+       * testfile-vars-gcc-dwarf4-32.o.bz2: Likewise.
+       * testfile-vars-gcc-dwarf4-64.o.bz2: Likewise.
+       * testfile-vars-gcc-dwarf5-32.o.bz2: Likewise.
+       * testfile-vars-gcc-dwarf5-64.o.bz2: Likewise.
+       * Makefile.am (EXTRA_DIST): Add new test and test files.
+       (TESTS): Add run-varlocs-vars.sh.
+
 2021-09-09  Mark Wielaard  <mark@klomp.org>
 
        * debuginfod-subr.sh: set -o functrace.
index c586422e213b2f46447ddb50c3f89ecc6fa5da59..2294273365ef8a6f290879f0b50d77275f5b6440 100644 (file)
@@ -143,7 +143,7 @@ TESTS = run-arextract.sh run-arsymtest.sh run-ar.sh newfile test-nlist \
        run-dwfl-report-elf-align.sh run-addr2line-test.sh \
        run-addr2line-i-test.sh run-addr2line-i-lex-test.sh \
        run-addr2line-i-demangle-test.sh run-addr2line-alt-debugpath.sh \
-       run-varlocs.sh run-exprlocs.sh run-funcretval.sh \
+       run-varlocs.sh run-exprlocs.sh run-varlocs-vars.sh run-funcretval.sh \
        run-backtrace-native.sh run-backtrace-data.sh run-backtrace-dwarf.sh \
        run-backtrace-native-biarch.sh run-backtrace-native-core.sh \
        run-backtrace-native-core-biarch.sh run-backtrace-core-x86_64.sh \
@@ -399,7 +399,16 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \
             testfileppc32.bz2 testfileppc64.bz2 \
             testfiles390.bz2 testfiles390x.bz2 \
             testfilearm.bz2 testfileaarch64.bz2 \
-            run-varlocs.sh run-exprlocs.sh testfile-stridex.bz2 \
+            run-varlocs.sh run-exprlocs.sh run-varlocs-vars.sh \
+            testfile-vars-clang-dwarf4-32.o.bz2 \
+            testfile-vars-clang-dwarf4-64.o.bz2 \
+            testfile-vars-clang-dwarf5-32.o.bz2 \
+            testfile-vars-clang-dwarf5-64.o.bz2 \
+            testfile-vars-gcc-dwarf4-32.o.bz2 \
+            testfile-vars-gcc-dwarf4-64.o.bz2 \
+            testfile-vars-gcc-dwarf5-32.o.bz2 \
+            testfile-vars-gcc-dwarf5-64.o.bz2 \
+            testfile-stridex.bz2 \
             testfile_const_type.c testfile_const_type.bz2 \
             testfile_implicit_pointer.c testfile_implicit_pointer.bz2 \
             testfile_parameter_ref.c testfile_parameter_ref.bz2 \
diff --git a/tests/run-varlocs-vars.sh b/tests/run-varlocs-vars.sh
new file mode 100755 (executable)
index 0000000..e7598bf
--- /dev/null
@@ -0,0 +1,93 @@
+#! /bin/sh
+# Copyright (C) 2013, 2021 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
+
+# Testfiles generated with:
+#
+# $ cat foo.c
+# int x = 1;
+# int y = 2;
+#
+# for cc in gcc clang; do
+#   for v in 4 5; do
+#     for w in 32 64; do
+#       out="testfile-vars-$cc-dwarf$v-$w.o"
+#       "$cc" -m"$w" -Wall -Wextra -gdwarf-"$v" -c foo.c -o "$out"
+#     done
+#   done
+# done
+
+testfiles testfile-vars-clang-dwarf4-32.o
+testfiles testfile-vars-clang-dwarf4-64.o
+testfiles testfile-vars-clang-dwarf5-32.o
+testfiles testfile-vars-clang-dwarf5-64.o
+testfiles testfile-vars-gcc-dwarf4-32.o
+testfiles testfile-vars-gcc-dwarf4-64.o
+testfiles testfile-vars-gcc-dwarf5-32.o
+testfiles testfile-vars-gcc-dwarf5-64.o
+
+tempfiles varlocs.out
+testrun ${abs_top_builddir}/tests/varlocs --debug --exprlocs -e testfile-vars-clang-dwarf4-32.o | grep exprloc > varlocs.out
+diff -u varlocs.out - <<EOF
+    location (exprloc) {addr(0x0)}
+    location (exprloc) {addr(0x4)}
+EOF
+
+testrun ${abs_top_builddir}/tests/varlocs --debug --exprlocs -e testfile-vars-clang-dwarf4-64.o | grep exprloc > varlocs.out
+diff -u varlocs.out - <<EOF
+    location (exprloc) {addr(0x0)}
+    location (exprloc) {addr(0x4)}
+EOF
+
+testrun ${abs_top_builddir}/tests/varlocs --debug --exprlocs -e testfile-vars-clang-dwarf5-32.o | grep exprloc > varlocs.out
+diff -u varlocs.out - <<EOF
+    location (exprloc) {addr: 0x0}
+    location (exprloc) {addr: 0x4}
+EOF
+
+testrun ${abs_top_builddir}/tests/varlocs --debug --exprlocs -e testfile-vars-clang-dwarf5-32.o | grep exprloc > varlocs.out
+diff -u varlocs.out - <<EOF
+    location (exprloc) {addr: 0x0}
+    location (exprloc) {addr: 0x4}
+EOF
+
+testrun ${abs_top_builddir}/tests/varlocs --debug --exprlocs -e testfile-vars-gcc-dwarf4-32.o | grep exprloc > varlocs.out
+diff -u varlocs.out - <<EOF
+    location (exprloc) {addr(0x0)}
+    location (exprloc) {addr(0x4)}
+EOF
+
+testrun ${abs_top_builddir}/tests/varlocs --debug --exprlocs -e testfile-vars-gcc-dwarf4-64.o | grep exprloc > varlocs.out
+diff -u varlocs.out - <<EOF
+    location (exprloc) {addr(0x0)}
+    location (exprloc) {addr(0x4)}
+EOF
+
+testrun ${abs_top_builddir}/tests/varlocs --debug --exprlocs -e testfile-vars-gcc-dwarf5-32.o | grep exprloc > varlocs.out
+diff -u varlocs.out - <<EOF
+    location (exprloc) {addr(0x0)}
+    location (exprloc) {addr(0x4)}
+EOF
+
+testrun ${abs_top_builddir}/tests/varlocs --debug --exprlocs -e testfile-vars-gcc-dwarf5-64.o | grep exprloc > varlocs.out
+diff -u varlocs.out - <<EOF
+    location (exprloc) {addr(0x0)}
+    location (exprloc) {addr(0x4)}
+EOF
+
+exit 0
diff --git a/tests/testfile-vars-clang-dwarf4-32.o.bz2 b/tests/testfile-vars-clang-dwarf4-32.o.bz2
new file mode 100644 (file)
index 0000000..c1ddf81
Binary files /dev/null and b/tests/testfile-vars-clang-dwarf4-32.o.bz2 differ
diff --git a/tests/testfile-vars-clang-dwarf4-64.o.bz2 b/tests/testfile-vars-clang-dwarf4-64.o.bz2
new file mode 100644 (file)
index 0000000..df33299
Binary files /dev/null and b/tests/testfile-vars-clang-dwarf4-64.o.bz2 differ
diff --git a/tests/testfile-vars-clang-dwarf5-32.o.bz2 b/tests/testfile-vars-clang-dwarf5-32.o.bz2
new file mode 100644 (file)
index 0000000..b1d6b6c
Binary files /dev/null and b/tests/testfile-vars-clang-dwarf5-32.o.bz2 differ
diff --git a/tests/testfile-vars-clang-dwarf5-64.o.bz2 b/tests/testfile-vars-clang-dwarf5-64.o.bz2
new file mode 100644 (file)
index 0000000..adf6c6a
Binary files /dev/null and b/tests/testfile-vars-clang-dwarf5-64.o.bz2 differ
diff --git a/tests/testfile-vars-gcc-dwarf4-32.o.bz2 b/tests/testfile-vars-gcc-dwarf4-32.o.bz2
new file mode 100644 (file)
index 0000000..da9aac7
Binary files /dev/null and b/tests/testfile-vars-gcc-dwarf4-32.o.bz2 differ
diff --git a/tests/testfile-vars-gcc-dwarf4-64.o.bz2 b/tests/testfile-vars-gcc-dwarf4-64.o.bz2
new file mode 100644 (file)
index 0000000..2642164
Binary files /dev/null and b/tests/testfile-vars-gcc-dwarf4-64.o.bz2 differ
diff --git a/tests/testfile-vars-gcc-dwarf5-32.o.bz2 b/tests/testfile-vars-gcc-dwarf5-32.o.bz2
new file mode 100644 (file)
index 0000000..cb1c705
Binary files /dev/null and b/tests/testfile-vars-gcc-dwarf5-32.o.bz2 differ
diff --git a/tests/testfile-vars-gcc-dwarf5-64.o.bz2 b/tests/testfile-vars-gcc-dwarf5-64.o.bz2
new file mode 100644 (file)
index 0000000..e286f8f
Binary files /dev/null and b/tests/testfile-vars-gcc-dwarf5-64.o.bz2 differ