diff options
author | Mark Wielaard <mjw@redhat.com> | 2013-09-20 09:50:42 -0400 |
---|---|---|
committer | Mark Wielaard <mjw@redhat.com> | 2013-09-24 10:28:14 +0200 |
commit | 1b734df17fca9f89a887b85ffe74616a87388f51 (patch) | |
tree | 2dc0ba75b4c517261ad60a17f96b6f766722f9b5 /tests/run-allfcts.sh | |
parent | 21fc33fe191603b71e9e14d2d1a79a8aa48ad6e6 (diff) | |
download | elfutils-1b734df17fca9f89a887b85ffe74616a87388f51.tar.gz |
libdw: Make dwarf_getfuncs find all (defining) DW_TAG_subprogram DIEs.
dwarf_getfuncs used to return only the DW_TAG_subprogram DIEs that were
direct children of the given CU. This is normally how GCC outputs the
subprogram DIEs. But not always. For nested functions the subprogram DIE
is placed under the code construct DIE where it is nested. Other compilers
might output the defining subprogram DIE of a C++ class function under
the DW_TAG_namespace DIE where it was defined. Both such constructs seem
allowed by the DWARF specification. So just searching the CU DIE children
was wrong.
To find all (defining) subprogram DIEs in a CU dwarf_getfuncs should
use __libdw_visit_scopes to walk the tree for all DIEs that can contain
subprograms as children. The only tricky part is making sure the offset
returned and used when the callback returns DWARF_CB_ABORT is correct
and the search continues at the right spot in the CU DIE tree. This
operation now needs to rewalk the whole tree.
Two new testcases were added that fail without this patch. And the
allfcts test was tweaked so that it always returns DWARF_CB_ABORT
from its callback to make sure the offset handling is correct.
Signed-off-by: Mark Wielaard <mjw@redhat.com>
Diffstat (limited to 'tests/run-allfcts.sh')
-rwxr-xr-x | tests/run-allfcts.sh | 56 |
1 files changed, 55 insertions, 1 deletions
diff --git a/tests/run-allfcts.sh b/tests/run-allfcts.sh index 30f7dd4d..6eaf13c8 100755 --- a/tests/run-allfcts.sh +++ b/tests/run-allfcts.sh @@ -1,5 +1,5 @@ #! /bin/sh -# Copyright (C) 2005 Red Hat, Inc. +# Copyright (C) 2005, 2013 Red Hat, Inc. # This file is part of elfutils. # Written by Ulrich Drepper <drepper@redhat.com>, 2005. # @@ -37,4 +37,58 @@ testrun_compare ${abs_builddir}/allfcts testfile testfile2 testfile8 <<\EOF /home/drepper/gnu/elfutils/build/src/../../src/strip.c:313:handle_elf EOF +# = nested_funcs.c = +# +# static int +# foo (int x) +# { +# int bar (int y) +# { +# return x - y; +# } +# +# return bar (x * 2); +# } +# +# int +# main (int argc, char ** argv) +# { +# return foo (argc); +# } +# +# gcc -g -o nested_funcs nested_funcs.c + +# = class_func.cxx = +# +# namespace foobar +# { +# class Foo +# { +# public: +# int bar(int x); +# }; +# +# int Foo::bar(int x) { return x - 42; } +# }; +# +# int +# main (int argc, char **argv) +# { +# foobar::Foo foo; +# +# return foo.bar (42); +# } +# +# clang++ -g -o class_func class_func.cxx + +testfiles testfile_nested_funcs testfile_class_func + +testrun_compare ${abs_builddir}/allfcts testfile_nested_funcs testfile_class_func <<\EOF +/home/mark/src/tests/nested/nested_funcs.c:2:foo +/home/mark/src/tests/nested/nested_funcs.c:4:bar +/home/mark/src/tests/nested/nested_funcs.c:13:main +/home/mark/src/tests/nested/class_func.cxx:6:bar +/home/mark/src/tests/nested/class_func.cxx:13:main +EOF + exit 0 |