diff options
-rw-r--r-- | libdw/ChangeLog | 6 | ||||
-rw-r--r-- | libdw/dwarf_getscopes.c | 18 | ||||
-rw-r--r-- | tests/ChangeLog | 6 | ||||
-rw-r--r-- | tests/Makefile.am | 1 | ||||
-rwxr-xr-x | tests/run-addr2line-i-test.sh | 43 | ||||
-rwxr-xr-x | tests/testfile-inlines-lto.bz2 | bin | 0 -> 2838 bytes |
6 files changed, 66 insertions, 8 deletions
diff --git a/libdw/ChangeLog b/libdw/ChangeLog index 4c7af94e..71e96c88 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,9 @@ +2023-01-22 Mark Wielaard <mark@klomp.org> + + * dwarf_getscopes.c (pc_record): Return nscopes when done. + (dwarf_getscopes): Call __libdw_visit_scopes with + inlined_origin CU. + 2022-12-20 Mark Wielaard <mark@klomp.org> * Makefile.am (AM_CPPFLAGS): Add -I$(srcdir)/../libebl. diff --git a/libdw/dwarf_getscopes.c b/libdw/dwarf_getscopes.c index 5662eecf..833f1ac5 100644 --- a/libdw/dwarf_getscopes.c +++ b/libdw/dwarf_getscopes.c @@ -1,5 +1,6 @@ /* Return scope DIEs containing PC address. Copyright (C) 2005, 2007, 2015 Red Hat, Inc. + Copyright (C) 2023 Mark J. Wielaard <mark@klomp.org> This file is part of elfutils. This file is free software; you can redistribute it and/or modify @@ -173,12 +174,8 @@ pc_record (unsigned int depth, struct Dwarf_Die_Chain *die, void *arg) /* Not there yet. */ return 0; - /* Now we are in a scope that contains the concrete inlined instance. - Search it for the inline function's abstract definition. - If we don't find it, return to search the containing scope. - If we do find it, the nonzero return value will bail us out - of the postorder traversal. */ - return __libdw_visit_scopes (depth, die, NULL, &origin_match, NULL, a); + /* This is the innermost inline scope, we are done here. */ + return a->nscopes; } @@ -193,8 +190,13 @@ dwarf_getscopes (Dwarf_Die *cudie, Dwarf_Addr pc, Dwarf_Die **scopes) int result = __libdw_visit_scopes (0, &cu, NULL, &pc_match, &pc_record, &a); - if (result == 0 && a.scopes != NULL) - result = __libdw_visit_scopes (0, &cu, NULL, &origin_match, NULL, &a); + if (result >= 0 && a.scopes != NULL && a.inlined > 0) + { + /* We like the find the inline function's abstract definition + scope, but that might be in a different CU. */ + cu.die = CUDIE (a.inlined_origin.cu); + result = __libdw_visit_scopes (0, &cu, NULL, &origin_match, NULL, &a); + } if (result > 0) *scopes = a.scopes; diff --git a/tests/ChangeLog b/tests/ChangeLog index 14b901b9..6c51eb3b 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,9 @@ +2023-01-22 Mark Wielaard <mark@klomp.org> + + * testfile-inlines-lto.bz2: New testfile. + * run-addr2line-i-test.sh: Add new lto inlines test. + * Makefile.am (EXTRA_DIST): Add testfile-inlines-lto.bz2. + 2023-01-19 Mark Wielaard <mark@klomp.org> * run-addr2line-C-test.sh: New test. diff --git a/tests/Makefile.am b/tests/Makefile.am index fa7c30ef..36823d94 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -428,6 +428,7 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \ test-core.exec.bz2 run-addr2line-test.sh \ run-addr2line-C-test.sh \ run-addr2line-i-test.sh testfile-inlines.bz2 \ + testfile-inlines-lto.bz2 \ run-addr2line-i-lex-test.sh testfile-lex-inlines.bz2 \ run-addr2line-i-demangle-test.sh run-addr2line-alt-debugpath.sh \ testfileppc32.bz2 testfileppc64.bz2 \ diff --git a/tests/run-addr2line-i-test.sh b/tests/run-addr2line-i-test.sh index d08f3cba..4f63e487 100755 --- a/tests/run-addr2line-i-test.sh +++ b/tests/run-addr2line-i-test.sh @@ -220,4 +220,47 @@ testrun_compare ${abs_top_builddir}/src/addr2line --pretty-print -a -f -i -e tes (inlined by) _Z2fuv at /tmp/x.cpp:33 EOF +# == x.cpp == +# g++ x.cpp -g -fPIC -olibx.so -shared -O0 -flto +# +# __attribute__((always_inline)) inline +# int foobar(int i) +# { +# return i + 1; +# } +# +# __attribute__((always_inline)) inline +# int fubar(int i) +# { +# return i + 1; +# } +# +# __attribute__((always_inline)) inline +# int bar(int i) +# { +# return fubar(i++); +# } +# +# __attribute__((always_inline)) inline +# int foo(int i) +# { +# return foobar(i++); +# } +# +# int fu(int i) +# { +# return foo(i++) + bar(i++); +# } + +testfiles testfile-inlines-lto + +testrun_compare ${abs_top_builddir}/src/addr2line --pretty -fiC -e testfile-inlines-lto 0x1118 0x1137 <<\EOF +foobar(int) at /tmp/x.cpp:4:14 + (inlined by) foo(int) at /tmp/x.cpp:22:16 + (inlined by) fu(int) at /tmp/x.cpp:27:13 +fubar(int) at /tmp/x.cpp:10:14 + (inlined by) bar(int) at /tmp/x.cpp:16:15 + (inlined by) fu(int) at /tmp/x.cpp:27:24 +EOF + exit 0 diff --git a/tests/testfile-inlines-lto.bz2 b/tests/testfile-inlines-lto.bz2 Binary files differnew file mode 100755 index 00000000..7e2e2bfd --- /dev/null +++ b/tests/testfile-inlines-lto.bz2 |