diff options
| author | Mark Wielaard <[email protected]> | 2018-05-20 10:35:34 +0200 |
|---|---|---|
| committer | Mark Wielaard <[email protected]> | 2018-05-24 17:34:17 +0200 |
| commit | ac6960d6b8602df97b5964f66ffc7cd91fd16e5b (patch) | |
| tree | 24f79d3ddc8c412468d709b478a6d6976624157e /tests | |
| parent | c2d14cc492aa7fd28740d5789fede64ce81a063b (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/ChangeLog | 9 | ||||
| -rw-r--r-- | tests/Makefile.am | 8 | ||||
| -rwxr-xr-x | tests/run-unit-info.sh | 80 | ||||
| -rw-r--r-- | tests/unit-info.c | 323 |
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; +} |
