summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libdw/ChangeLog6
-rw-r--r--libdw/dwarf_getscopes.c18
-rw-r--r--tests/ChangeLog6
-rw-r--r--tests/Makefile.am1
-rwxr-xr-xtests/run-addr2line-i-test.sh43
-rwxr-xr-xtests/testfile-inlines-lto.bz2bin0 -> 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
new file mode 100755
index 00000000..7e2e2bfd
--- /dev/null
+++ b/tests/testfile-inlines-lto.bz2
Binary files differ