]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
libdw: Search for abstract origin in the correct CU
authorMark Wielaard <mark@klomp.org>
Sat, 21 Jan 2023 23:31:57 +0000 (00:31 +0100)
committerMark Wielaard <mark@klomp.org>
Mon, 30 Jan 2023 21:05:41 +0000 (22:05 +0100)
With gcc -flto the abstract origin of an inlined subroutine
could be in a different CU. dwarf_getscopes might return an
empty scope if it cannot find the abstract origin scope. So
make sure to search in the

We also tried to add the origin match in pc_record directly
in the current inlined scope. This always failed, causing
to do a needless traversal, followed by the full CU scan in
dwarf_getscopes. Just always stop the pc_record search and
then do the CU origin_match in dwarf_getscopes.

Signed-off-by: Mark Wielaard <mark@klomp.org>
libdw/ChangeLog
libdw/dwarf_getscopes.c
tests/ChangeLog
tests/Makefile.am
tests/run-addr2line-i-test.sh
tests/testfile-inlines-lto.bz2 [new file with mode: 0755]

index 4c7af94eda70486ea1cb25ee3cee58aeb1064252..71e96c880b739549cbd5f5e166428ed58d786273 100644 (file)
@@ -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.
index 5662eecf131ca09051b0bbe84b18500ed8211814..833f1ac504d2608fa4ad4a3dc3566c5ed89178b8 100644 (file)
@@ -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;
index 14b901b98c22a9daffdb4fe3dd930e5ebd7967d9..6c51eb3b0364c1f5af6fc2d54a2d638f8388077a 100644 (file)
@@ -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.
index fa7c30ef202cbad9608bf7494186b3e26a43bb9c..36823d94c397d01fc2b7763ae0c6088f26fe202e 100644 (file)
@@ -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 \
index d08f3cba5ba9d906127d4f25931e0d2d6165f9c4..4f63e487cd3f92a846737b5ab0f3671c26c8083d 100755 (executable)
@@ -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 (executable)
index 0000000..7e2e2bf
Binary files /dev/null and b/tests/testfile-inlines-lto.bz2 differ