summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorMark Wielaard <[email protected]>2018-05-20 10:35:34 +0200
committerMark Wielaard <[email protected]>2018-05-24 17:34:17 +0200
commitac6960d6b8602df97b5964f66ffc7cd91fd16e5b (patch)
tree24f79d3ddc8c412468d709b478a6d6976624157e /tests
parentc2d14cc492aa7fd28740d5789fede64ce81a063b (diff)
libdw: Add new dwarf_cu_info function.
This allows getting a (split) subdie lazily, only when needed. All arguments to dwarf_get_units are optional. When not given then unit DIE and sub DIE are not looked up. This new function allows them to be looked up when not immediately retrieved with dwarf_get_units, or for a Dwarf_CU gotten through some other way. Add a new testcase to make sure the results of calling dwarf_cu_info and dwarf_get_units are consistent. Signed-off-by: Mark Wielaard <[email protected]>
Diffstat (limited to 'tests')
-rw-r--r--tests/ChangeLog9
-rw-r--r--tests/Makefile.am8
-rwxr-xr-xtests/run-unit-info.sh80
-rw-r--r--tests/unit-info.c323
4 files changed, 417 insertions, 3 deletions
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 86bcf9db..a93b0e98 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,12 @@
+2018-05-20 Mark Wielaard <[email protected]>
+
+ * unit-info.c: New test.
+ * run-unit-info.sh: New test runner.
+ * Makefile.am (check_PROGRAMS): Add unit-info.
+ (TESTS): Add run-unit-info.sh
+ (EXTRA_INFO): Likewise.
+ (unit_info_LDADD): New variable.
+
2018-05-24 Mark Wielaard <[email protected]>
* get-units-invalid.c (main): Add check for invalid dwarf_ranges.
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 08d84649..9beae140 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -57,7 +57,7 @@ check_PROGRAMS = arextract arsymtest newfile saridx scnnames sectiondump \
elfgetzdata elfputzdata zstrptr emptyfile vendorelf \
fillfile dwarf_default_lower_bound dwarf-die-addr-die \
get-units-invalid get-units-split attr-integrate-skel \
- all-dwarf-ranges
+ all-dwarf-ranges unit-info
asm_TESTS = asm-tst1 asm-tst2 asm-tst3 asm-tst4 asm-tst5 \
asm-tst6 asm-tst7 asm-tst8 asm-tst9
@@ -143,7 +143,7 @@ TESTS = run-arextract.sh run-arsymtest.sh run-ar.sh newfile test-nlist \
run-dwarf-die-addr-die.sh \
run-get-units-invalid.sh run-get-units-split.sh \
run-attr-integrate-skel.sh \
- run-all-dwarf-ranges.sh
+ run-all-dwarf-ranges.sh run-unit-info.sh
if !BIARCH
export ELFUTILS_DISABLE_BIARCH = 1
@@ -370,7 +370,8 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \
testfile-world5.dwo.bz2 testfile-world4.dwo.bz2 \
run-attr-integrate-skel.sh \
run-all-dwarf-ranges.sh testfilesplitranges4.debug.bz2 \
- testfile-ranges-hello.dwo.bz2 testfile-ranges-world.dwo.bz2
+ testfile-ranges-hello.dwo.bz2 testfile-ranges-world.dwo.bz2 \
+ run-unit-info.sh
if USE_VALGRIND
valgrind_cmd='valgrind -q --leak-check=full --error-exitcode=1'
@@ -533,6 +534,7 @@ get_units_invalid_LDADD = $(libdw)
get_units_split_LDADD = $(libdw)
attr_integrate_skel_LDADD = $(libdw)
all_dwarf_ranges_LDADD = $(libdw)
+unit_info_LDADD = $(libdw)
# We want to test the libelf header against the system elf.h header.
# Don't include any -I CPPFLAGS.
diff --git a/tests/run-unit-info.sh b/tests/run-unit-info.sh
new file mode 100755
index 00000000..f4ce427b
--- /dev/null
+++ b/tests/run-unit-info.sh
@@ -0,0 +1,80 @@
+#! /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
+
+# See run-typeiter.sh
+testfiles testfile-debug-types
+
+testrun ${abs_builddir}/unit-info testfile-debug-types
+
+# see run-readelf-dwz-multi.sh
+testfiles testfile_multi_main testfile_multi.dwz
+
+testrun ${abs_builddir}/unit-info testfile_multi_main
+
+# see tests/run-dwflsyms.sh
+testfiles testfilebazdbgppc64.debug
+
+testrun ${abs_builddir}/unit-info testfilebazdbgppc64.debug
+
+# see tests/testfile-dwarf-45.source
+testfiles testfile-dwarf-4 testfile-dwarf-5
+testfiles testfile-splitdwarf-4 testfile-splitdwarf-5
+testfiles testfile-hello4.dwo testfile-hello5.dwo
+testfiles testfile-world4.dwo testfile-world5.dwo
+
+testrun ${abs_builddir}/unit-info testfile-dwarf-4
+testrun ${abs_builddir}/unit-info testfile-dwarf-5
+
+# The consistency checks should find most issue, but make sure the
+# output is also what we expect in case we break dwarf_get_units and
+# dwarf_cu_info at the same time.
+testrun_compare ${abs_builddir}/unit-info \
+ testfile-splitdwarf-4 testfile-splitdwarf-5 <<\EOF
+file: testfile-splitdwarf-4
+Iterate getting all info, compare with dwarf_cu_info.
+0 cu dietag: 11, subtag: 11, version 4, unit_type 4
+0 subdietag: 11, subtag: 0, version 4, unit_type 5
+1 cu dietag: 11, subtag: 11, version 4, unit_type 4
+1 subdietag: 11, subtag: 0, version 4, unit_type 5
+rechecking: testfile-splitdwarf-4
+Iterate no info, compare recorded info with dwarf_cu_info.
+0 re dietag: 11, subtag: 11, version 4, unit_type 4
+0 subdietag: 11, subtag: 0, version 4, unit_type 5
+1 re dietag: 11, subtag: 11, version 4, unit_type 4
+1 subdietag: 11, subtag: 0, version 4, unit_type 5
+
+file: testfile-splitdwarf-5
+Iterate getting all info, compare with dwarf_cu_info.
+0 cu dietag: 4a, subtag: 11, version 5, unit_type 4
+0 subdietag: 11, subtag: 0, version 5, unit_type 5
+1 cu dietag: 4a, subtag: 11, version 5, unit_type 4
+1 subdietag: 11, subtag: 0, version 5, unit_type 5
+rechecking: testfile-splitdwarf-5
+Iterate no info, compare recorded info with dwarf_cu_info.
+0 re dietag: 4a, subtag: 11, version 5, unit_type 4
+0 subdietag: 11, subtag: 0, version 5, unit_type 5
+1 re dietag: 4a, subtag: 11, version 5, unit_type 4
+1 subdietag: 11, subtag: 0, version 5, unit_type 5
+
+EOF
+
+# Self test
+testrun_on_self ${abs_builddir}/unit-info
+
+exit 0
diff --git a/tests/unit-info.c b/tests/unit-info.c
new file mode 100644
index 00000000..4fb9a984
--- /dev/null
+++ b/tests/unit-info.c
@@ -0,0 +1,323 @@
+/* Test dwarf_cu_info properties.
+ 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/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include ELFUTILS_HEADER(dw)
+#include <stdio.h>
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+/* Yeah, lazy, 16K CUs should be enough for everybody... */
+#define MAX_UNITS 16384
+struct info
+{
+ int dietag;
+ int subtag;
+ Dwarf_Half version;
+ uint8_t unit_type;
+ uint64_t id;
+ uint8_t addr_size;
+ uint8_t off_size;
+};
+static struct info unit_info[MAX_UNITS];
+
+int
+main (int argc, char *argv[])
+{
+ for (int i = 1; i < argc; i++)
+ {
+ printf ("file: %s\n", argv[i]);
+ int fd = open (argv[i], O_RDONLY);
+ Dwarf *dbg = dwarf_begin (fd, DWARF_C_READ);
+ if (dbg == NULL)
+ {
+ printf ("%s not usable: %s\n", argv[i], dwarf_errmsg (-1));
+ return -1;
+ }
+
+ Dwarf_CU *cu = NULL;
+ Dwarf_Half version;
+ Dwarf_Die cudie, subdie;
+ uint8_t unit_type;
+ size_t u, units;
+ u = units = 0;
+ printf ("Iterate getting all info, compare with dwarf_cu_info.\n");
+ while (dwarf_get_units (dbg, cu, &cu, &version,
+ &unit_type, &cudie, &subdie) == 0)
+ {
+ int dietag = dwarf_tag (&cudie);
+ int subtag = dwarf_tag (&subdie);
+
+ unit_info[u].dietag = dietag;
+ unit_info[u].subtag = subtag;
+ unit_info[u].version = version;
+ unit_info[u].unit_type = unit_type;
+
+ printf ("%zu cu dietag: %x, subtag: %x, version %" PRIx32
+ ", unit_type %" PRIx8 "\n",
+ u, dietag, subtag, version, unit_type);
+
+ uint64_t unit_id;
+ uint8_t addr_size, off_size;
+ if (dwarf_cu_info (cu,
+ &version, &unit_type, &cudie, &subdie,
+ &unit_id, &addr_size, &off_size) != 0)
+ {
+ printf ("Invalid dwarf_cu_info: %s\n", dwarf_errmsg (-1));
+ return -1;
+ }
+
+ dietag = dwarf_tag (&cudie);
+ subtag = dwarf_tag (&subdie);
+
+ if (unit_info[u].dietag != dietag)
+ {
+ printf("Unequal dietags\n");
+ return -1;
+ }
+
+ if (unit_info[u].subtag != subtag)
+ {
+ printf("Unequal subtags\n");
+ return -1;
+ }
+
+ if (unit_info[u].version != version)
+ {
+ printf("Unequal versions\n");
+ return -1;
+ }
+
+ if (unit_info[u].unit_type != unit_type)
+ {
+ printf("Unequal unit_types\n");
+ return -1;
+ }
+
+ unit_info[u].id = unit_id;
+ unit_info[u].addr_size = addr_size;
+ unit_info[u].off_size = off_size;
+
+ if (unit_type == DW_UT_skeleton)
+ {
+ if (dwarf_cu_info (subdie.cu,
+ &version, &unit_type, &cudie, &subdie,
+ &unit_id, &addr_size, &off_size) != 0)
+ {
+ printf ("Invalid subdie dwarf_cu_info: %s\n",
+ dwarf_errmsg (-1));
+ return -1;
+ }
+
+ dietag = dwarf_tag (&cudie);
+ subtag = dwarf_tag (&subdie);
+
+ printf ("%zu subdietag: %x, subtag: %x, version %" PRIx32
+ ", unit_type %" PRIx8 "\n",
+ u, dietag, subtag, version, unit_type);
+
+ /* subdie is now cudie. */
+ if (unit_info[u].subtag != dietag)
+ {
+ printf ("Inconsistent subdie tag\n");
+ return -1;
+ }
+
+ if (unit_info[u].id != unit_id)
+ {
+ printf ("Unequal subdie ids\n");
+ return -1;
+ }
+
+ if (unit_info[u].addr_size != addr_size)
+ {
+ printf ("Unequal subdie addr_size\n");
+ return -1;
+ }
+
+ if (unit_info[u].off_size != off_size)
+ {
+ printf ("Unequal subdie off_size\n");
+ return -1;
+ }
+ }
+
+ if (u >= MAX_UNITS)
+ {
+ printf ("Oops, more than 16K units...\n");
+ return -1;
+ }
+ u = ++units;
+ }
+
+ dwarf_end (dbg);
+ close (fd);
+
+ /* And again... */
+ printf ("rechecking: %s\n", argv[i]);
+ fd = open (argv[i], O_RDONLY);
+ dbg = dwarf_begin (fd, DWARF_C_READ);
+ if (dbg == NULL)
+ {
+ printf ("%s not usable: %s\n", argv[i], dwarf_errmsg (-1));
+ return -1;
+ }
+
+ cu = NULL;
+ u = 0;
+ printf ("Iterate no info, compare recorded info with dwarf_cu_info.\n");
+ while (dwarf_get_units (dbg, cu, &cu, NULL, NULL, NULL, NULL) == 0)
+ {
+ if (u > units)
+ {
+ printf ("Got too many units???\n");
+ return -1;
+ }
+
+ uint64_t unit_id;
+ uint8_t addr_size, off_size;
+ if (dwarf_cu_info (cu,
+ &version, &unit_type, &cudie, &subdie,
+ &unit_id, &addr_size, &off_size) != 0)
+ {
+ printf ("Invalid dwarf_cu_info: %s\n", dwarf_errmsg (-1));
+ return -1;
+ }
+
+ int dietag = dwarf_tag (&cudie);
+ int subtag = dwarf_tag (&subdie);
+
+ printf ("%zu re dietag: %x, subtag: %x, version %" PRIx32
+ ", unit_type %" PRIx8 "\n",
+ u, dietag, subtag, version, unit_type);
+
+ if (unit_info[u].dietag != dietag)
+ {
+ printf("Unequal dietags %x != %x\n", unit_info[u].dietag, dietag);
+ return -1;
+ }
+
+ if (unit_info[u].subtag != subtag)
+ {
+ printf("Unequal subtags\n");
+ return -1;
+ }
+
+ if (unit_info[u].version != version)
+ {
+ printf("Unequal versions\n");
+ return -1;
+ }
+
+ if (unit_info[u].unit_type != unit_type)
+ {
+ printf("Unequal unit_types\n");
+ return -1;
+ }
+
+ if (unit_info[u].id != unit_id)
+ {
+ printf ("Unequal subdie ids\n");
+ return -1;
+ }
+
+ if (unit_info[u].addr_size != addr_size)
+ {
+ printf ("Unequal subdie addr_size\n");
+ return -1;
+ }
+
+ if (unit_info[u].off_size != off_size)
+ {
+ printf ("Unequal subdie off_size\n");
+ return -1;
+ }
+
+ if (unit_type == DW_UT_skeleton)
+ {
+ if (dwarf_cu_info (subdie.cu,
+ &version, &unit_type, &cudie, &subdie,
+ &unit_id, &addr_size, &off_size) != 0)
+ {
+ printf ("Invalid subdie dwarf_cu_info: %s\n",
+ dwarf_errmsg (-1));
+ return -1;
+ }
+
+ dietag = dwarf_tag (&cudie);
+ subtag = dwarf_tag (&subdie);
+
+ printf ("%zu subdietag: %x, subtag: %x, version %" PRIx32
+ ", unit_type %" PRIx8 "\n",
+ u, dietag, subtag, version, unit_type);
+
+ /* subdie is now cudie. */
+ subtag = dwarf_tag (&cudie);
+ if (unit_info[u].subtag != subtag)
+ {
+ printf ("Inconsistent subdie tag\n");
+ return -1;
+ }
+
+ if (unit_info[u].id != unit_id)
+ {
+ printf ("Unequal subdie ids\n");
+ return -1;
+ }
+
+ if (unit_info[u].addr_size != addr_size)
+ {
+ printf ("Unequal subdie addr_size\n");
+ return -1;
+ }
+
+ if (unit_info[u].off_size != off_size)
+ {
+ printf ("Unequal subdie off_size\n");
+ return -1;
+ }
+ }
+
+ if (u >= MAX_UNITS)
+ {
+ printf ("Oops, more than 16K units...\n");
+ return -1;
+ }
+ u++;
+ }
+
+ if (u != units)
+ {
+ printf ("Got not enough units???\n");
+ return -1;
+ }
+
+ dwarf_end (dbg);
+ close (fd);
+
+ printf ("\n");
+ }
+
+ return 0;
+}