public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: Indu Bhagat <indu.bhagat@oracle.com>
To: binutils@sourceware.org
Subject: [PATCH,V6 09/10] unwinder: Add CTF Frame unwinder tests
Date: Tue,  2 Aug 2022 01:04:51 -0700	[thread overview]
Message-ID: <20220802080452.1143351-10-indu.bhagat@oracle.com> (raw)
In-Reply-To: <20220802080452.1143351-1-indu.bhagat@oracle.com>

From: Weimin Pan <weimin.pan@oracle.com>

[Changes in V6]
 - fixed testcases with more precise checks on the expected number of
   frames in each backtrace.
 - Consistent use of __noinline__+__noclone__ attributes to prevent the
   functions from getting optimized away.
 - Create/delete shared objects in $objdir, instead of $srcdir, and
   changed "expect { -re" to make it run faster for the solib test.
 - Disable unwinder tests from getting run when cross builds are
   performed.
 - Cleaned up CFLAGS_FOR_TARGET when unused.
[End of changes in V6]

[Added new in V5]

Add tests for backtracing using CTF Frame sections.

PS: libctfframe/configure has NOT been included in the patch.  Please
regenerate.

ChangeLog:

	* libctfframe/Makefile.in: Regenerated.
	* libctfframe/configure: Regenerated.  <-- [REMOVED FROM THE
	  PATCH. PLEASE REGENERATE.]
	* libctfframe/configure.ac: Check for cross compilation.
	* libctfframe/testsuite/Makefile.in: Regenerated.
	* libctfframe/testsuite/config/default.exp: Load
	  ctfframe-lib.exp.
	* libctfframe/testsuite/libctfframe.decode/Makefile.in:
	  Regenerated.
	* libctfframe/testsuite/libctfframe.encode/Makefile.in:
	  Regenerated.
	* libctfframe/testsuite/lib/ctfframe-lib.exp: New file.  Add
	  procedures for handling unwinder tests.
	* libctfframe/testsuite/libctfframe.unwind/backtrace.c: New test.
	* libctfframe/testsuite/libctfframe.unwind/backtrace.lk: New test.
	* libctfframe/testsuite/libctfframe.unwind/inline-cmds.c: New test.
	* libctfframe/testsuite/libctfframe.unwind/inline-cmds.lk: New test.
	* libctfframe/testsuite/libctfframe.unwind/inline.c: New test.
	* libctfframe/testsuite/libctfframe.unwind/inline.lk: New test.
	* libctfframe/testsuite/libctfframe.unwind/solib-lib1.c: New test.
	* libctfframe/testsuite/libctfframe.unwind/solib-lib2.c: New test.
	* libctfframe/testsuite/libctfframe.unwind/solib-main.c: New test.
	* libctfframe/testsuite/libctfframe.unwind/solib-main.d: New test.
	* libctfframe/testsuite/libctfframe.unwind/solib.exp: New file.
	* libctfframe/testsuite/libctfframe.unwind/solib_lib1.h: New test.
	* libctfframe/testsuite/libctfframe.unwind/solib_lib2.h: New test.
	* libctfframe/testsuite/libctfframe.unwind/tailcall.c: New test.
	* libctfframe/testsuite/libctfframe.unwind/tailcall.lk: New test.
	* libctfframe/testsuite/libctfframe.unwind/ttest.c: New test.
	* libctfframe/testsuite/libctfframe.unwind/ttest.lk: New test.
	* libctfframe/testsuite/libctfframe.unwind/unwind.exp: New file.
---
 libctfframe/Makefile.in                       |   1 +
 libctfframe/configure.ac                      |  12 ++
 libctfframe/testsuite/Makefile.in             |   1 +
 libctfframe/testsuite/config/default.exp      |   3 +
 libctfframe/testsuite/lib/ctfframe-lib.exp    | 180 ++++++++++++++++
 .../testsuite/libctfframe.decode/Makefile.in  |   1 +
 .../testsuite/libctfframe.encode/Makefile.in  |   1 +
 .../testsuite/libctfframe.unwind/backtrace.c  | 145 +++++++++++++
 .../testsuite/libctfframe.unwind/backtrace.lk |   3 +
 .../libctfframe.unwind/inline-cmds.c          | 135 ++++++++++++
 .../libctfframe.unwind/inline-cmds.lk         |   3 +
 .../testsuite/libctfframe.unwind/inline.c     |  97 +++++++++
 .../testsuite/libctfframe.unwind/inline.lk    |   3 +
 .../testsuite/libctfframe.unwind/solib-lib1.c |   8 +
 .../testsuite/libctfframe.unwind/solib-lib2.c |  51 +++++
 .../testsuite/libctfframe.unwind/solib-main.c |  47 ++++
 .../testsuite/libctfframe.unwind/solib-main.d |   3 +
 .../testsuite/libctfframe.unwind/solib.exp    |  75 +++++++
 .../testsuite/libctfframe.unwind/solib_lib1.h |   3 +
 .../testsuite/libctfframe.unwind/solib_lib2.h |   3 +
 .../testsuite/libctfframe.unwind/tailcall.c   | 103 +++++++++
 .../testsuite/libctfframe.unwind/tailcall.lk  |   3 +
 .../testsuite/libctfframe.unwind/ttest.c      | 127 +++++++++++
 .../testsuite/libctfframe.unwind/ttest.lk     |   3 +
 .../testsuite/libctfframe.unwind/unwind.exp   | 200 ++++++++++++++++++
 25 files changed, 1211 insertions(+)
 create mode 100644 libctfframe/testsuite/lib/ctfframe-lib.exp
 create mode 100644 libctfframe/testsuite/libctfframe.unwind/backtrace.c
 create mode 100644 libctfframe/testsuite/libctfframe.unwind/backtrace.lk
 create mode 100644 libctfframe/testsuite/libctfframe.unwind/inline-cmds.c
 create mode 100644 libctfframe/testsuite/libctfframe.unwind/inline-cmds.lk
 create mode 100644 libctfframe/testsuite/libctfframe.unwind/inline.c
 create mode 100644 libctfframe/testsuite/libctfframe.unwind/inline.lk
 create mode 100644 libctfframe/testsuite/libctfframe.unwind/solib-lib1.c
 create mode 100644 libctfframe/testsuite/libctfframe.unwind/solib-lib2.c
 create mode 100644 libctfframe/testsuite/libctfframe.unwind/solib-main.c
 create mode 100644 libctfframe/testsuite/libctfframe.unwind/solib-main.d
 create mode 100644 libctfframe/testsuite/libctfframe.unwind/solib.exp
 create mode 100644 libctfframe/testsuite/libctfframe.unwind/solib_lib1.h
 create mode 100644 libctfframe/testsuite/libctfframe.unwind/solib_lib2.h
 create mode 100644 libctfframe/testsuite/libctfframe.unwind/tailcall.c
 create mode 100644 libctfframe/testsuite/libctfframe.unwind/tailcall.lk
 create mode 100644 libctfframe/testsuite/libctfframe.unwind/ttest.c
 create mode 100644 libctfframe/testsuite/libctfframe.unwind/ttest.lk
 create mode 100644 libctfframe/testsuite/libctfframe.unwind/unwind.exp

diff --git a/libctfframe/Makefile.in b/libctfframe/Makefile.in
index c344067d961..c709c12de47 100644
--- a/libctfframe/Makefile.in
+++ b/libctfframe/Makefile.in
@@ -332,6 +332,7 @@ CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CROSS_COMPILE = @CROSS_COMPILE@
 CYGPATH_W = @CYGPATH_W@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
diff --git a/libctfframe/configure.ac b/libctfframe/configure.ac
index a35bce4d142..e831ac7b466 100644
--- a/libctfframe/configure.ac
+++ b/libctfframe/configure.ac
@@ -57,6 +57,18 @@ ACX_PROG_CC_WARNING_ALMOST_PEDANTIC([-Wno-long-long])
 # corrected.
 ACX_PROG_CC_WARNINGS_ARE_ERRORS([manual])
 
+# Determine if we are cross compiling
+AC_CANONICAL_HOST
+is_cross_compiler=
+if test x"${host}" = x"${target}" ; then
+  is_cross_compiler=no
+else
+  is_cross_compiler=yes
+fi
+CROSS_COMPILE=$is_cross_compiler
+AC_SUBST([CROSS_COMPILE])
+
+
 dnl The libctfbacktrace library needs to be built with CTF Frame info.
 dnl If the build assembler is not capable of generate CTF Frame then
 dnl the library is not built.
diff --git a/libctfframe/testsuite/Makefile.in b/libctfframe/testsuite/Makefile.in
index ec9ba703268..70513337d72 100644
--- a/libctfframe/testsuite/Makefile.in
+++ b/libctfframe/testsuite/Makefile.in
@@ -204,6 +204,7 @@ CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CROSS_COMPILE = @CROSS_COMPILE@
 CYGPATH_W = @CYGPATH_W@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
diff --git a/libctfframe/testsuite/config/default.exp b/libctfframe/testsuite/config/default.exp
index c91c01b2265..58d0e1d2cec 100644
--- a/libctfframe/testsuite/config/default.exp
+++ b/libctfframe/testsuite/config/default.exp
@@ -52,3 +52,6 @@ if {![info exists CFLAGS]} {
 if {![info exists CFLAGS_FOR_TARGET]} {
     set CFLAGS_FOR_TARGET $CFLAGS
 }
+
+# load the utility procedures
+load_lib ctfframe-lib.exp
diff --git a/libctfframe/testsuite/lib/ctfframe-lib.exp b/libctfframe/testsuite/lib/ctfframe-lib.exp
new file mode 100644
index 00000000000..bcde1f78983
--- /dev/null
+++ b/libctfframe/testsuite/lib/ctfframe-lib.exp
@@ -0,0 +1,180 @@
+# Support routines for libctfframe testsuite.
+#   Copyright (C) 2022 Free Software Foundation, Inc.
+#
+# This file is part of the GNU Binutils.
+#
+# 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.
+#
+# This program 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+# MA 02110-1301, USA.
+
+load_file $srcdir/../../ld/testsuite/lib/ld-lib.exp
+
+set unwind_test_file_name ""
+
+proc run_native_host_cmd { command } {
+    global link_output
+    global ld
+
+    verbose -log "$command"
+    set run_output ""
+    try {
+	set run_output [exec "sh" "-c" "$command" "2>@1"]
+	set status 0
+    } trap CHILDSTATUS {results options} {
+	set status [lindex [dict get $options -errorcode] 2]
+	set run_output $results
+    }
+    regsub "\n$" $run_output "" run_output
+    if { [lindex $status 0] != 0 && [string match "" $run_output] } then {
+	append run_output "child process exited abnormally"
+    }
+
+    if [string match "" $run_output] then {
+	return ""
+    }
+
+    verbose -log "$run_output"
+    return "$run_output"
+}
+
+# Compile and link a C source file for execution on the host.
+proc compile_link_one_host_cc { src output additional_args } {
+    global CC
+    global CFLAGS
+
+    return [run_native_host_cmd "../libtool --quiet --tag=CC --mode=link $CC $CFLAGS $src -o $output $additional_args" ]
+}
+
+proc make_unwind_parallel_path { args } {
+    global objdir
+    set joiner [list "file" "join" $objdir]
+    set joiner [concat $joiner $args]
+    return [eval $joiner]
+}
+
+proc standard_output_file {basename} {
+    global objdir subdir unwind_test_file_name
+
+    set dir [make_unwind_parallel_path outputs $subdir $unwind_test_file_name]
+    file mkdir $dir
+    return [file join $dir $basename]
+}
+
+proc standard_testfile {args} {
+    global unwind_test_file_name
+    global subdir
+    global unwind_test_file_last_vars
+
+    # Outputs.
+    global testfile binfile
+
+    set testfile $unwind_test_file_name
+    set binfile [standard_output_file ${testfile}]
+
+    if {[llength $args] == 0} {
+	set args .c
+    }
+
+    # Unset our previous output variables.
+    # This can help catch hidden bugs.
+    if {[info exists unwind_test_file_last_vars]} {
+	foreach varname $unwind_test_file_last_vars {
+	    global $varname
+	    catch {unset $varname}
+	}
+    }
+    # 'executable' is often set by tests.
+    set unwind_test_file_last_vars {executable}
+
+    set suffix ""
+    foreach arg $args {
+	set varname srcfile$suffix
+	global $varname
+
+	# Handle an extension.
+	if {$arg == ""} {
+	    set arg $testfile.c
+	} else {
+	    set first [string range $arg 0 0]
+	    if { $first == "." || $first == "-" } {
+		set arg $testfile$arg
+	    }
+	}
+
+	set $varname $arg
+	lappend unwind_test_file_last_vars $varname
+
+	if {$suffix == ""} {
+	    set suffix 2
+	} else {
+	    incr suffix
+	}
+    }
+}
+
+# Build a shared object DEST from SOURCES.
+proc unwind_compile_so {sources dest} {
+    global CFLAGS
+    set obj_options $CFLAGS
+    lappend obj_options "additional_flags=-fPIC -Wa,--gctf-frame"
+
+    set outdir [file dirname $dest]
+    set objects ""
+    foreach source $sources {
+	set sourcebase [file tail $source]
+	set object ${outdir}/${sourcebase}.o
+
+	if {[target_compile $source $object object \
+		  $obj_options] != ""} {
+	    return -1
+	}
+
+	lappend objects $object
+    }
+
+    set link_options "additional_flags=-shared"
+
+    set destbase [file tail $dest]
+    lappend link_options "additional_flags=-Wl,-soname,$destbase"
+
+    if {[target_compile "${objects}" "${dest}" executable $link_options] != ""} {
+	catch "exec rm ${objects}" status
+	return -1
+    }
+    catch "exec rm ${objects}" status
+    return ""
+}
+
+# Build a binary of TYPE from SOURCE at path DEST.
+proc unwind_compile {source dest type options} {
+    set new_options ""
+
+    foreach opt $options {
+	if {[regexp {^shlib=(.*)} $opt dummy_var shlib_name]
+	    && $type == "executable"} {
+	    lappend source "-Wl,$shlib_name"
+	} else {
+	    lappend new_options $opt
+	}
+    }
+    set options $new_options
+
+    verbose "options are $options"
+    verbose "source is $source $dest $type $options"
+
+    lappend options "additional_flags=-rdynamic -Wa,--gctf-frame ./../.libs/libctfbacktrace.a ./../.libs/libctfframe.a"
+    set result [target_compile $source $dest $type $options]
+
+    return $result
+}
diff --git a/libctfframe/testsuite/libctfframe.decode/Makefile.in b/libctfframe/testsuite/libctfframe.decode/Makefile.in
index f8f84fc7b89..dc6b2e7cb5c 100644
--- a/libctfframe/testsuite/libctfframe.decode/Makefile.in
+++ b/libctfframe/testsuite/libctfframe.decode/Makefile.in
@@ -200,6 +200,7 @@ CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CROSS_COMPILE = @CROSS_COMPILE@
 CYGPATH_W = @CYGPATH_W@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
diff --git a/libctfframe/testsuite/libctfframe.encode/Makefile.in b/libctfframe/testsuite/libctfframe.encode/Makefile.in
index 06b4052cb70..b0700146fa1 100644
--- a/libctfframe/testsuite/libctfframe.encode/Makefile.in
+++ b/libctfframe/testsuite/libctfframe.encode/Makefile.in
@@ -191,6 +191,7 @@ CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CROSS_COMPILE = @CROSS_COMPILE@
 CYGPATH_W = @CYGPATH_W@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
diff --git a/libctfframe/testsuite/libctfframe.unwind/backtrace.c b/libctfframe/testsuite/libctfframe.unwind/backtrace.c
new file mode 100644
index 00000000000..2411153c54c
--- /dev/null
+++ b/libctfframe/testsuite/libctfframe.unwind/backtrace.c
@@ -0,0 +1,145 @@
+/* Copyright (C) 2022 Free Software Foundation, Inc.
+
+   This program 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.
+
+   This program 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/>.  */
+
+/* This is a revised version of gdb/testsuite/gdb.base/backtrace.c.  */
+
+#ifdef __has_attribute
+# if !__has_attribute (noclone)
+#  define ATTRIBUTE_NOCLONE
+# endif
+#endif
+#ifndef ATTRIBUTE_NOCLONE
+# define ATTRIBUTE_NOCLONE __attribute__((noclone))
+#endif
+
+#include <execinfo.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "ctf-backtrace-api.h"
+
+#define BT_BUF_SIZE 100
+
+/* Expected funclist.  */
+static const char *const func_list[] =
+{
+  "show_bt",
+  "baz",
+  "bar",
+  "foo",
+  "main"
+};
+
+void __attribute__((__noinline__,__noclone__))
+show_bt ()
+{
+  void *buffer[BT_BUF_SIZE];
+  int j, nptrs, err;
+  char **strings;
+
+  /* Call the unwinder to get an array of return addresses.  */
+  nptrs = ctf_backtrace (buffer, BT_BUF_SIZE, &err);
+  if (nptrs != 5)
+    {
+      printf ("CTF error: %s (%d)\n", ctf_bt_errmsg (err), nptrs);
+      return;
+    }
+
+  /* Get these addresses symbolically.  */
+  strings = backtrace_symbols (buffer, nptrs);
+  if (strings == NULL) {
+      perror("backtrace_symbols");
+      exit(EXIT_FAILURE);
+  }
+
+  /* Verify the results.  */
+  for (j = 0; j < nptrs; j++)
+    if (!strstr (strings[j], func_list[j]))
+      break;
+
+  free(strings);
+
+  printf ("%s: backtrace test\n", j == nptrs ? "PASS" : "FAIL");
+}
+
+int __attribute__((__noinline__,__noclone__))
+baz ()
+{
+  void *buffer[BT_BUF_SIZE];
+  int nptrs, err;
+
+  /* Call the unwinder to get an array of return addresses.  */
+  nptrs = ctf_backtrace (buffer, BT_BUF_SIZE, &err);
+  if (nptrs == -1)
+    {
+      printf ("CTF error: %s (%d)\n", ctf_bt_errmsg (err), nptrs);
+      return -1;
+    }
+
+  show_bt ();
+  return 0;
+}
+
+int __attribute__((__noinline__,__noclone__))
+bar ()
+{
+  void *buffer[BT_BUF_SIZE];
+  int nptrs, err;
+
+  /* Call the unwinder to get an array of return addresses.  */
+  nptrs = ctf_backtrace (buffer, BT_BUF_SIZE, &err);
+  if (nptrs == -1)
+    {
+      printf ("CTF error: %s (%d)\n", ctf_bt_errmsg (err), nptrs);
+      return -1;
+    }
+
+  return baz ();
+}
+
+int __attribute__((__noinline__,__noclone__))
+foo ()
+{
+  void *buffer[BT_BUF_SIZE];
+  int nptrs, err;
+
+  /* Call the unwinder to get an array of return addresses.  */
+  nptrs = ctf_backtrace (buffer, BT_BUF_SIZE, &err);
+  if (nptrs == -1)
+    {
+      printf ("CTF error: %s (%d)\n", ctf_bt_errmsg (err), nptrs);
+      return -1;
+    }
+
+  return bar ();
+}
+
+int __attribute__((__noinline__,__noclone__))
+main ()
+{
+  void *buffer[BT_BUF_SIZE];
+  int nptrs, err;
+
+  /* Call the unwinder to get an array of return addresses.  */
+  nptrs = ctf_backtrace (buffer, BT_BUF_SIZE, &err);
+  if (nptrs == -1)
+    {
+      printf ("CTF error: %s (%d)\n", ctf_bt_errmsg (err), nptrs);
+      return -1;
+    }
+
+  return foo ();
+}
diff --git a/libctfframe/testsuite/libctfframe.unwind/backtrace.lk b/libctfframe/testsuite/libctfframe.unwind/backtrace.lk
new file mode 100644
index 00000000000..fdc78ebe34d
--- /dev/null
+++ b/libctfframe/testsuite/libctfframe.unwind/backtrace.lk
@@ -0,0 +1,3 @@
+# source: backtrace.c
+# link: on
+PASS: backtrace test
diff --git a/libctfframe/testsuite/libctfframe.unwind/inline-cmds.c b/libctfframe/testsuite/libctfframe.unwind/inline-cmds.c
new file mode 100644
index 00000000000..15850527a4f
--- /dev/null
+++ b/libctfframe/testsuite/libctfframe.unwind/inline-cmds.c
@@ -0,0 +1,135 @@
+/* Copyright (C) 2022 Free Software Foundation, Inc.
+
+   This program 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.
+
+   This program 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/>.  */
+
+/* This is only ever run if it is compiled with a new-enough GCC, but
+   we don't want the compilation to fail if compiled by some other
+   compiler.  */
+
+/* This is a revised version of gdb/testsuite/gdb.opt/inline-cmds.c.  */
+
+#ifdef __GNUC__
+#define ATTR __attribute__((always_inline))
+#else
+#define ATTR
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <execinfo.h>
+#include "ctf-backtrace-api.h"
+
+#define BT_BUF_SIZE 10
+
+int x, y;
+volatile int z = 0;
+volatile int result;
+
+void bar(void);
+void marker(void);
+void noinline(void);
+
+inline ATTR int func1(void)
+{
+  bar ();
+  return x * y;
+}
+
+inline ATTR int func2(void)
+{
+  return x * func1 ();
+}
+
+inline ATTR void func3(void)
+{
+  bar ();
+}
+
+inline ATTR void outer_inline1(void)
+{
+  noinline ();
+}
+
+inline ATTR void outer_inline2(void)
+{
+  outer_inline1 ();
+}
+
+int main (void)
+{ /* start of main */
+  int val;
+
+  x = 7;
+  y = 8;
+
+  outer_inline2 ();
+
+  return 0;
+}
+
+
+/* funclist for inline-cmds.  */
+const char *const func_list[] =
+{
+  "noinline",
+  "main"
+};
+
+void bar(void)
+{
+  x += y;
+}
+
+void marker(void)
+{
+  x += y - z;
+}
+
+inline ATTR void inlined_fn(void)
+{
+  x += y + z;
+
+  void *buffer[BT_BUF_SIZE];
+  char **strings;
+  /* Call the unwinder to get an array of return addresses.  */
+  int j, err;
+  int nptrs = ctf_backtrace (buffer, BT_BUF_SIZE, &err);
+  if (nptrs == -1 || nptrs != 2)
+    {
+      printf ("CTF error: %s (%d)\n", ctf_bt_errmsg (err), nptrs);
+      return;
+    }
+
+  /* Get these addresses symbolically.  */
+  strings = backtrace_symbols (buffer, nptrs);
+  if (strings == NULL) {
+        perror("backtrace_symbols");
+        exit(EXIT_FAILURE);
+  }
+
+  /* Verify the results.  */
+  for (j = 0; j < nptrs; j++)
+    if (!strstr (strings[j], func_list[j]))
+      break;
+
+    free(strings);
+    printf ("%s: inline-cmds test\n", j == nptrs ? "PASS" : "FAIL");
+}
+
+void noinline(void)
+{
+  inlined_fn (); /* inlined */
+}
diff --git a/libctfframe/testsuite/libctfframe.unwind/inline-cmds.lk b/libctfframe/testsuite/libctfframe.unwind/inline-cmds.lk
new file mode 100644
index 00000000000..053b66bd683
--- /dev/null
+++ b/libctfframe/testsuite/libctfframe.unwind/inline-cmds.lk
@@ -0,0 +1,3 @@
+# source: inline-cmds.c
+# link: on
+PASS: inline-cmds test
diff --git a/libctfframe/testsuite/libctfframe.unwind/inline.c b/libctfframe/testsuite/libctfframe.unwind/inline.c
new file mode 100644
index 00000000000..f7054bf8a9f
--- /dev/null
+++ b/libctfframe/testsuite/libctfframe.unwind/inline.c
@@ -0,0 +1,97 @@
+/* Copyright (C) 2022 Free Software Foundation, Inc.
+
+   This program 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.
+
+   This program 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/>.  */
+
+/* This is a revised version of gdb/testsuite/gdb.opt/inline-bt.c.  */
+
+#include <execinfo.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include "ctf-backtrace-api.h"
+
+#define ATTR __attribute__((always_inline))
+
+#define BT_BUF_SIZE 32
+
+int x, y;
+volatile int z = 0;
+volatile int result;
+
+/* funclist.  */
+const char *const flist[] =
+{
+  "main"
+};
+
+void bar(void)
+{
+  x += y;
+}
+
+inline ATTR int func1(void)
+{
+  bar ();
+  return x * y;
+}
+
+inline ATTR int func2(void)
+{
+  void *buffer[BT_BUF_SIZE];
+  int ok = 0, nptrs, err;
+  char **strings;
+
+  /* Call the unwinder to get an array of return addresses.  */
+  nptrs = ctf_backtrace (buffer, BT_BUF_SIZE, &err);
+  if (nptrs == -1)
+    {
+      printf ("CTF error: %s\n", ctf_bt_errmsg (err));
+      return -1;
+    }
+
+  /* Get these addresses symbolically.  */
+  strings = backtrace_symbols (buffer, nptrs);
+  if (strings == NULL) {
+      perror("backtrace_symbols");
+      exit(EXIT_FAILURE);
+  }
+
+  /* Verify the results.  */
+  if (nptrs == 1 && strstr (strings[0], flist[0]))
+    ok = 1;
+
+  free(strings);
+
+  printf ("%s: unwind test\n", ok == 1 ? "PASS" : "FAIL");
+
+  return x * func1 ();
+}
+
+int main (void)
+{
+  int val;
+
+  x = 7;
+  y = 8;
+  bar ();
+
+  val = func1 ();
+  result = val;
+
+  val = func2 ();
+  result = val;
+
+  return 0;
+}
diff --git a/libctfframe/testsuite/libctfframe.unwind/inline.lk b/libctfframe/testsuite/libctfframe.unwind/inline.lk
new file mode 100644
index 00000000000..88f846b0fce
--- /dev/null
+++ b/libctfframe/testsuite/libctfframe.unwind/inline.lk
@@ -0,0 +1,3 @@
+# source: inline.c
+# link: on
+PASS: unwind test
diff --git a/libctfframe/testsuite/libctfframe.unwind/solib-lib1.c b/libctfframe/testsuite/libctfframe.unwind/solib-lib1.c
new file mode 100644
index 00000000000..f4eebf927d9
--- /dev/null
+++ b/libctfframe/testsuite/libctfframe.unwind/solib-lib1.c
@@ -0,0 +1,8 @@
+#include "solib_lib1.h"
+
+unsigned int
+adder(unsigned int a, unsigned int b, int (*call)(int))
+{
+  (void)(*call)(a+b);
+  return (a+b);
+}
diff --git a/libctfframe/testsuite/libctfframe.unwind/solib-lib2.c b/libctfframe/testsuite/libctfframe.unwind/solib-lib2.c
new file mode 100644
index 00000000000..16f1fa9f968
--- /dev/null
+++ b/libctfframe/testsuite/libctfframe.unwind/solib-lib2.c
@@ -0,0 +1,51 @@
+#include <execinfo.h>
+#include <stdlib.h>
+#include <string.h>
+#include "ctf-backtrace-api.h"
+#include "solib_lib2.h"
+
+#define BT_BUF_SIZE 100
+
+/* funclist for running "ttest.x 3".  */
+static const char *const bt_list[] =
+{
+  "adder2",
+  "bar",
+  "adder",
+  "main"
+};
+
+unsigned int
+adder2 (unsigned int a, unsigned int b, int (*call)(int))
+{
+  void *buffer[BT_BUF_SIZE];
+  int i, nptrs, err;
+  char **strings;
+
+  nptrs = ctf_backtrace (buffer, BT_BUF_SIZE, &err);
+  if (nptrs == -1 || nptrs != 4)
+    {
+/* printf ("bcktrace failed: %d %d\n", nptrs, err); */
+      printf ("CTF error: %s\n", ctf_bt_errmsg (err));
+      return(-1);
+    }
+
+  strings = backtrace_symbols (buffer, nptrs);
+  if (strings == NULL)
+    {
+       perror("backtrace_symbols");
+       return(-1);
+    }
+
+  /* Verify the results.  */
+  for (i = 0; i < nptrs; i++)
+    if (!strstr (strings[i], bt_list[i]))
+      break;
+
+  free (strings);
+
+  printf ("%s: unwind solib test\n", i == nptrs ? "PASS" : "FAIL");
+
+  (void)(*call) (a+b);
+  return (a+b);
+}
diff --git a/libctfframe/testsuite/libctfframe.unwind/solib-main.c b/libctfframe/testsuite/libctfframe.unwind/solib-main.c
new file mode 100644
index 00000000000..3b9ca175073
--- /dev/null
+++ b/libctfframe/testsuite/libctfframe.unwind/solib-main.c
@@ -0,0 +1,47 @@
+/* Copyright (C) 2022 Free Software Foundation, Inc.
+
+   This program 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.
+
+   This program 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/>.  */
+
+#include <execinfo.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "ctf-backtrace-api.h"
+#include "solib_lib1.h"
+#include "solib_lib2.h"
+
+#define BT_BUF_SIZE 100
+
+int foo (int x)
+{
+  return ++x;
+}
+
+int bar (int x)
+{
+  x = adder2 (x, x+1, foo);
+
+  return ++x;
+}
+
+int main (void)
+{
+  unsigned int a = 1;
+  unsigned int b = 2;
+  unsigned int result = 0;
+
+  result = adder (a,b, bar);
+
+  return 0;
+}
diff --git a/libctfframe/testsuite/libctfframe.unwind/solib-main.d b/libctfframe/testsuite/libctfframe.unwind/solib-main.d
new file mode 100644
index 00000000000..483ded5a1e5
--- /dev/null
+++ b/libctfframe/testsuite/libctfframe.unwind/solib-main.d
@@ -0,0 +1,3 @@
+# source: solib-main.c
+# link: on
+PASS: unwind solib test
diff --git a/libctfframe/testsuite/libctfframe.unwind/solib.exp b/libctfframe/testsuite/libctfframe.unwind/solib.exp
new file mode 100644
index 00000000000..3136fdba3e7
--- /dev/null
+++ b/libctfframe/testsuite/libctfframe.unwind/solib.exp
@@ -0,0 +1,75 @@
+# Copyright 2022 Free Software Foundation, Inc.
+
+# This program 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.
+#
+# This program 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/>.
+
+# Run the test only if ctfbacktrace library exists.
+if [catch "exec ls $objdir/../.libs/libctfbacktrace.la" status] then {
+  return;
+}
+
+# Run the tests only if we are not cross compiling.
+if [string equal $CROSS_COMPILE "yes"] {
+    return;
+}
+
+set experimental ""
+
+# Shared object files.
+set libname1 "solib-lib1"
+set srcfile_lib1 ${srcdir}/${subdir}/${libname1}.c
+set binfile_lib1 ${objdir}/${libname1}.so
+set libname2 "solib-lib2"
+set srcfile_lib2 ${srcdir}/${subdir}/${libname2}.c
+set binfile_lib2 ${objdir}/${libname2}.so
+
+# Binary file.
+set testfile "solib-main"
+set srcfile ${srcdir}/${subdir}/${testfile}.c
+set binfile [standard_output_file ${testfile}]
+set bin_flags [list debug shlib=${binfile_lib1} shlib=${binfile_lib2}]
+
+if { [unwind_compile_so ${srcfile_lib1} ${binfile_lib1}] != ""
+     || [unwind_compile_so ${srcfile_lib2} ${binfile_lib2}] != ""
+     || [unwind_compile ${srcfile} ${binfile} executable $bin_flags] != "" } {
+    untested "failed to compile"
+    return -1
+}
+
+if {[info exists env(LD_LIBRARY_PATH)]} {
+    set old_ld_lib $env(LD_LIBRARY_PATH)
+}
+set env(LD_LIBRARY_PATH) "${objdir}"
+
+set solib_output "${binfile} ${binfile_lib1} ${binfile_lib2}"
+set results [run_host_cmd ${binfile} $solib_output]
+
+set f [open "tmpdir/solib.out" "w"]
+puts $f $results
+close $f
+
+if { [regexp_diff "tmpdir/solib.out" "${srcdir}/${subdir}/${testfile}.d"] } then {
+    fail "$test_name"
+} else {
+    pass "$test_name"
+}
+
+catch "exec rm ${binfile_lib1}" status
+catch "exec rm ${binfile_lib2}" status
+catch "exec rm tmpdir/solib.out" status
+
+if {[info exists old_ld_lib]} {
+    set env(LD_LIBRARY_PATH) $old_ld_lib
+} else {
+    unset env(LD_LIBRARY_PATH)
+}
diff --git a/libctfframe/testsuite/libctfframe.unwind/solib_lib1.h b/libctfframe/testsuite/libctfframe.unwind/solib_lib1.h
new file mode 100644
index 00000000000..d40eac0769c
--- /dev/null
+++ b/libctfframe/testsuite/libctfframe.unwind/solib_lib1.h
@@ -0,0 +1,3 @@
+#include<stdio.h>
+
+extern unsigned int adder(unsigned int a, unsigned int b, int (*call)(int));
diff --git a/libctfframe/testsuite/libctfframe.unwind/solib_lib2.h b/libctfframe/testsuite/libctfframe.unwind/solib_lib2.h
new file mode 100644
index 00000000000..61b72122771
--- /dev/null
+++ b/libctfframe/testsuite/libctfframe.unwind/solib_lib2.h
@@ -0,0 +1,3 @@
+#include<stdio.h>
+
+extern unsigned int adder2(unsigned int a, unsigned int b, int (*call)(int));
diff --git a/libctfframe/testsuite/libctfframe.unwind/tailcall.c b/libctfframe/testsuite/libctfframe.unwind/tailcall.c
new file mode 100644
index 00000000000..1052cb76bcf
--- /dev/null
+++ b/libctfframe/testsuite/libctfframe.unwind/tailcall.c
@@ -0,0 +1,103 @@
+/* Copyright (C) 2022 Free Software Foundation, Inc.
+
+   This program 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.
+
+   This program 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/>.  */
+
+#include <execinfo.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "ctf-backtrace-api.h"
+
+#ifdef __has_attribute
+# if !__has_attribute (noclone)
+#  define ATTRIBUTE_NOCLONE
+# endif
+#endif
+#ifndef ATTRIBUTE_NOCLONE
+# define ATTRIBUTE_NOCLONE __attribute__((noclone))
+#endif
+
+#define BT_BUF_SIZE 16
+
+/* funclist for running tailcall.  */
+const char *const func_list[] =
+{
+  "show_bt",
+  "dec",
+  "dec",
+  "main"
+};
+
+void show_bt ()
+{
+  void *buffer[BT_BUF_SIZE];
+  int j, nptrs, err;
+  char **strings;
+
+  /* Call the unwinder to get an array of return addresses.  */
+  nptrs = ctf_backtrace (buffer, BT_BUF_SIZE, &err);
+  if (nptrs == -1 || nptrs != 4)
+    {
+      printf ("CTF error: %s (%d)\n", ctf_bt_errmsg (err), nptrs);
+      return;
+    }
+
+  /* Get these addresses symbolically.  */
+  strings = backtrace_symbols (buffer, nptrs);
+  if (strings == NULL) {
+      perror("backtrace_symbols");
+      exit(EXIT_FAILURE);
+  }
+
+  /* Verify the results.  */
+  for (j = 0; j < nptrs; j++)
+    if (!strstr (strings[j], func_list[j]))
+      break;
+
+  free(strings);
+
+  printf ("%s: tailcall test\n", j == nptrs ? "PASS" : "FAIL");
+}
+
+/* An example of tail recursive function.  */
+void __attribute__((__noinline__,__noclone__))
+dec (int n)
+{
+  void *buffer[BT_BUF_SIZE];
+  int nptrs, err;
+
+  /* Call the unwinder to get an array of return addresses.  */
+  nptrs = ctf_backtrace (buffer, BT_BUF_SIZE, &err);
+  if (nptrs == -1)
+    {
+      printf ("CTF error: %s (%d)\n", ctf_bt_errmsg (err), nptrs);
+      return;
+    }
+
+  if (n < 0)
+     return;
+
+  if (n == 2)
+    show_bt ();
+
+  /* The last executed statement is recursive call.  */
+  dec (n-1);
+}
+
+int
+main (void)
+{
+  dec (3);
+}
diff --git a/libctfframe/testsuite/libctfframe.unwind/tailcall.lk b/libctfframe/testsuite/libctfframe.unwind/tailcall.lk
new file mode 100644
index 00000000000..3d7ab98ddba
--- /dev/null
+++ b/libctfframe/testsuite/libctfframe.unwind/tailcall.lk
@@ -0,0 +1,3 @@
+# source: tailcall.c
+# link: on
+PASS: tailcall test
diff --git a/libctfframe/testsuite/libctfframe.unwind/ttest.c b/libctfframe/testsuite/libctfframe.unwind/ttest.c
new file mode 100644
index 00000000000..1bf3dd5d0f8
--- /dev/null
+++ b/libctfframe/testsuite/libctfframe.unwind/ttest.c
@@ -0,0 +1,127 @@
+/* Copyright (C) 2022 Free Software Foundation, Inc.
+
+   This program 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.
+
+   This program 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/>.  */
+
+/* This is the revised version of the example in "man backtrace".  */
+
+#include <execinfo.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include "ctf-backtrace-api.h"
+
+#ifdef __has_attribute
+# if !__has_attribute (noclone)
+#  define ATTRIBUTE_NOCLONE
+# endif
+#endif
+#ifndef ATTRIBUTE_NOCLONE
+# define ATTRIBUTE_NOCLONE __attribute__((noclone))
+#endif
+
+#define BT_BUF_SIZE 100
+
+/* funclist  */
+static const char *const func_list[] =
+{
+  "myfunc3",
+  "()",
+  "myfunc",
+  "myfunc",
+  "myfunc",
+  "main"
+};
+
+void myfunc3 (void)
+{
+  void *buffer[BT_BUF_SIZE];
+  int j, nptrs, err;
+  char **strings;
+
+  /* Call the unwinder to get an array of return addresses.  */
+  nptrs = ctf_backtrace (buffer, BT_BUF_SIZE, &err);
+  if (nptrs == -1 || nptrs != 6)
+    {
+      printf ("CTF error: %s (%d)\n", ctf_bt_errmsg (err), nptrs);
+      return;
+    }
+
+  /* Get these addresses symbolically.  */
+  strings = backtrace_symbols (buffer, nptrs);
+  if (strings == NULL) {
+    perror("backtrace_symbols");
+    exit(EXIT_FAILURE);
+  }
+
+  /* Verify the results.  */
+  for (j = 0; j < nptrs; j++)
+    if (!strstr (strings[j], func_list[j]))
+      break;
+
+  free(strings);
+
+  printf ("%s: unwind test\n", j == nptrs ? "PASS" : "FAIL");
+}
+
+static void __attribute__((__noinline__,__noclone__))
+/* "static" means don't export the symbol.  */
+myfunc2 (void)
+{
+  void *buffer[BT_BUF_SIZE];
+  int nptrs, err;
+
+  /* Call the unwinder to get an array of return addresses.  */
+  nptrs = ctf_backtrace (buffer, BT_BUF_SIZE, &err);
+  if (nptrs == -1)
+    {
+      printf ("CTF error: %s (%d)\n", ctf_bt_errmsg (err), nptrs);
+      return;
+    }
+
+  myfunc3 ();
+}
+
+void __attribute__((__noinline__,__noclone__))
+myfunc (int ncalls)
+{
+  void *buffer[BT_BUF_SIZE];
+  int nptrs, err;
+
+  /* Call the unwinder to get an array of return addresses.  */
+  nptrs = ctf_backtrace (buffer, BT_BUF_SIZE, &err);
+  if (nptrs == -1)
+    {
+      printf ("CTF error: %s (%d)\n", ctf_bt_errmsg (err), nptrs);
+      return;
+    }
+
+  if (ncalls > 1)
+    myfunc (ncalls - 1);
+  else
+    myfunc2 ();
+}
+
+int
+main (int argc, char *argv[])
+{
+  int cnt;
+  if (argc != 2) {
+    cnt = 3;
+  }
+  else
+    cnt = atoi(argv[1]);
+  myfunc (cnt);
+  exit (EXIT_SUCCESS);
+}
diff --git a/libctfframe/testsuite/libctfframe.unwind/ttest.lk b/libctfframe/testsuite/libctfframe.unwind/ttest.lk
new file mode 100644
index 00000000000..80aa2241402
--- /dev/null
+++ b/libctfframe/testsuite/libctfframe.unwind/ttest.lk
@@ -0,0 +1,3 @@
+# source: ttest.c
+# link: on
+PASS: unwind test
diff --git a/libctfframe/testsuite/libctfframe.unwind/unwind.exp b/libctfframe/testsuite/libctfframe.unwind/unwind.exp
new file mode 100644
index 00000000000..d58a18c8852
--- /dev/null
+++ b/libctfframe/testsuite/libctfframe.unwind/unwind.exp
@@ -0,0 +1,200 @@
+# Copyright (C) 2022 Free Software Foundation, Inc.
+#
+# This file is part of the GNU Binutils.
+#
+# This program 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.
+#
+# This program 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+# MA 02110-1301, USA.
+#
+
+# Run the tests only if ctfbacktrace library exists.
+
+if [catch "exec ls $objdir/../.libs/libctfbacktrace.la" status] then {
+  verbose -log "$objdir/../.libs/libctfbacktrace.la not found.";
+  verbose -log "Skipping CTF Frame unwind tests";
+  return;
+}
+
+# Run the tests only if we are not cross compiling.
+if [string equal $CROSS_COMPILE "yes"] {
+    return;
+}
+
+if {[info exists env(LC_ALL)]} {
+    set old_lc_all $env(LC_ALL)
+}
+set env(LC_ALL) "C"
+
+proc run_unwind_test { name } {
+    global CC
+    global CFLAGS
+    global copyfile env runtests srcdir subdir verbose
+
+    # Append additional flags for unwinder to work properly
+    set unwind_cflags "-Wa,--gctf-frame -rdynamic"
+
+    if ![runtest_file_p $runtests $name] then {
+	return
+    }
+
+    if [string match "*/*" $name] {
+	set file $name
+	set name [file tail $name]
+    } else {
+	set file "$srcdir/$subdir/$name"
+    }
+
+    set opt_array [slurp_options "${file}.lk"]
+    if { $opt_array == -1 } {
+	perror "error reading options from $file.lk"
+	unresolved $subdir/$name
+	return
+    }
+    set run_ld 0
+    set shared "-shared"
+    set opts(link) {}
+    set opts(link_flags) {}
+    set opts(nonshared) {}
+    set opts(unwind) {}
+    set opts(name) {}
+    set opts(source) {}
+    set opts(xfail) {}
+
+    foreach i $opt_array {
+	set opt_name [lindex $i 0]
+	set opt_val [lindex $i 1]
+	if { $opt_name == "" } {
+	    set in_extra 1
+	    continue
+	}
+	if ![info exists opts($opt_name)] {
+	    perror "unknown option $opt_name in file $file.lk"
+	    unresolved $subdir/$name
+	    return
+	}
+
+	set opts($opt_name) [concat $opts($opt_name) $opt_val]
+    }
+
+    if { [llength $opts(unwind)] == 0 } {
+	set opts(unwind) "$file.c"
+    } else {
+	set opts(unwind) "[file dirname $file]/$opts(unwind)"
+    }
+
+    if { [llength $opts(name)] == 0 } {
+	set opts(name) $opts(unwind)
+    }
+
+    if { [llength $opts(link)] != 0
+	 || [llength $opts(source)] > 1 } {
+	set run_ld 1
+    }
+
+    if { [llength $opts(nonshared)] != 0 } {
+	set shared ""
+    }
+
+    set testname $opts(name)
+    if { $opts(name) == "" } {
+	set testname "$subdir/$name"
+    }
+
+    # Compile and link the unwind program.
+    set comp_output [compile_link_one_host_cc $opts(unwind) "tmpdir/test_x" "./../.libs/libctfbacktrace.la ./../.libs/libctfframe.la"]
+
+    if { $comp_output != ""} {
+	send_log "compilation of unwind program $opts(unwind) failed with <$comp_output>"
+	perror "compilation of unwind program $opts(unwind) failed"
+	fail $testname
+	return 0
+    }
+
+    # Compile the inputs and posibly link them together.
+
+    set unwind ""
+    if { [llength $opts(source)] > 0 } {
+	set unwind ""
+	if { $run_ld } {
+	    set unwind_output "tmpdir/test_x ./../.libs/libctfbacktrace.a ./../.libs/libctfframe.a"
+	    # set unwind_output "tmpdir/out.so"
+	    # set unwind_flags "-fPIC $shared $opts(link_flags)"
+	} else {
+	    set unwind_output "tmpdir/out.o"
+	    # set unwind_flags "-fPIC -c"
+	}
+	if [board_info [target_info name] exists cflags] {
+	    append unwind_flags " [board_info [target_info name] cflags]"
+	}
+	if [board_info [target_info name] exists ldflags] {
+	    append unwind_flags " [board_info [target_info name] ldflags]"
+	}
+	set src {}
+	foreach sfile $opts(source) {
+	    if [is_remote host] {
+		lappend src [remote_download host [file join [file dirname $file] $sfile]]
+	    } else {
+		lappend src [file join [file dirname $file] $sfile]
+	    }
+	}
+
+	set comp_output [run_host_cmd "$CC" "$CFLAGS $unwind_cflags [concat $src] -o $unwind_output"]
+
+	if { $comp_output != ""} {
+	    send_log "compilation of CTF program [concat $src] failed with <$comp_output>"
+	    fail $testname
+	    return 0
+	}
+    }
+
+    # Time to setup xfailures.
+    foreach targ $opts(xfail) {
+	if [match_target $targ] {
+	    setup_xfail "*-*-*"
+	    break
+	}
+    }
+
+    # Invoke the unwind program on the outputs.
+
+    verbose -log "$srcdir"
+    set results [run_host_cmd tmpdir/test_x $unwind_output]
+
+    set f [open "tmpdir/test_x.out" "w"]
+    puts $f $results
+    close $f
+
+    if { [regexp_diff "tmpdir/test_x.out" "${file}.lk"] } then {
+	fail $testname
+	if { $verbose == 2 } then { verbose "output is [file_contents tmpdir/test_x.out]" 2 }
+	return 0
+    }
+
+    pass $testname
+    return 0
+}
+
+set ctf_test_list [lsort [glob -nocomplain $srcdir/$subdir/*.lk]]
+
+foreach ctf_test $ctf_test_list {
+    verbose [file rootname $ctf_test]
+    verbose running unwind test on $ctf_test
+    run_unwind_test [file rootname $ctf_test]
+}
+
+if {[info exists old_lc_all]} {
+    set env(LC_ALL) $old_lc_all
+} else {
+    unset env(LC_ALL)
+}
-- 
2.37.1


  parent reply	other threads:[~2022-08-02  8:07 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-02  8:04 [PATCH,V6 00/10] Definition and Implementation of CTF Frame format Indu Bhagat
2022-08-02  8:04 ` [PATCH,V6 01/10] ctf-frame.h: Add CTF Frame format definition Indu Bhagat
2022-08-15 12:04   ` Nick Clifton
2022-08-02  8:04 ` [PATCH,V6 02/10] gas: add new command line option --gctf-frame Indu Bhagat
2022-08-15 12:07   ` Nick Clifton
2022-08-02  8:04 ` [PATCH,V6 03/10] gas: generate .ctf_frame Indu Bhagat
2022-08-15 12:22   ` Nick Clifton
2022-08-02  8:04 ` [PATCH,V6 04/10] libctfframe: add the CTF Frame library Indu Bhagat
2022-08-15 12:46   ` Nick Clifton
2022-08-02  8:04 ` [PATCH,V6 05/10] libctfframe: add GNU poke pickles for CTF Frame Indu Bhagat
2022-08-15 12:50   ` Nick Clifton
2022-08-02  8:04 ` [PATCH,V6 06/10] bfd: linker: merge .ctf_frame sections Indu Bhagat
2022-08-15 13:02   ` Nick Clifton
2022-08-18  2:11     ` Indu Bhagat
2022-08-02  8:04 ` [PATCH,V6 07/10] readelf/objdump: support for CTF Frame section Indu Bhagat
2022-08-15 13:11   ` Nick Clifton
2022-08-02  8:04 ` [PATCH,V6 08/10] unwinder: generate backtrace using CTF Frame format Indu Bhagat
2022-08-15 13:16   ` Nick Clifton
2022-08-02  8:04 ` Indu Bhagat [this message]
2022-08-15 13:27   ` [PATCH,V6 09/10] unwinder: Add CTF Frame unwinder tests Nick Clifton
2022-08-02  8:04 ` [PATCH, V6 10/10] gdb: sim: buildsystem changes to accommodate libctfframe Indu Bhagat
2022-08-05 14:43   ` Tom Tromey
2022-08-15 12:18 ` [PATCH,V6 00/10] Definition and Implementation of CTF Frame format Nick Clifton
2022-08-18  1:38   ` Indu Bhagat
2022-08-15 14:25 ` Nick Clifton
2022-09-30  0:04   ` [PATCH,V1 00/14] Definition and support for SFrame unwind format Indu Bhagat
2022-09-30  0:04     ` [PATCH,V1 01/14] sframe.h: Add SFrame format definition Indu Bhagat
2022-09-30  0:04     ` [PATCH,V1 02/14] gas: add new command line option --gsframe Indu Bhagat
2022-09-30  0:04     ` [PATCH,V1 03/14] gas: generate .sframe from CFI directives Indu Bhagat
2022-09-30  0:04     ` [PATCH,V1 04/14] gas: testsuite: add new tests for SFrame unwind info Indu Bhagat
2022-09-30  0:04     ` [PATCH,V1 05/14] libsframe: add the SFrame library Indu Bhagat
2022-09-30  0:04     ` [PATCH,V1 06/14] bfd: linker: merge .sframe sections Indu Bhagat
2022-09-30 10:51       ` Nick Clifton
2022-09-30  0:04     ` [PATCH,V1 07/14] readelf/objdump: support for SFrame section Indu Bhagat
2022-09-30 11:08       ` Nick Clifton
2022-09-30  0:04     ` [PATCH,V1 08/14] unwinder: generate backtrace using SFrame format Indu Bhagat
2022-09-30  0:04     ` [PATCH,V1 09/14] unwinder: Add SFrame unwinder tests Indu Bhagat
2022-09-30  0:04     ` [PATCH,V1 10/14] gdb: sim: buildsystem changes to accommodate libsframe Indu Bhagat
2022-10-11 16:08       ` [PATCH, V1 " Tom Tromey
2022-09-30  0:04     ` [PATCH,V1 11/14] libctf: add libsframe to LDFLAGS and LIBS Indu Bhagat
2022-09-30  0:04     ` [PATCH,V1 12/14] src-release.sh: Add libsframe Indu Bhagat
2022-09-30  0:04     ` [PATCH,V1 13/14] binutils/NEWS: add text for SFrame support Indu Bhagat
2022-09-30  0:04     ` [PATCH,V1 14/14] gas/NEWS: add text about new command line option and " Indu Bhagat
2022-09-30  8:09     ` [PATCH,V1 00/14] Definition and support for SFrame unwind format Jan Beulich
2022-10-04  5:16       ` Indu Bhagat
2022-10-04  6:53         ` Jan Beulich
2022-09-30  8:24     ` Fangrui Song
2022-10-01  0:15       ` Indu Bhagat
2022-09-30  9:12     ` Nick Clifton
2022-10-01  0:29       ` Indu Bhagat
2022-10-01  9:51       ` Jose E. Marchesi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220802080452.1143351-10-indu.bhagat@oracle.com \
    --to=indu.bhagat@oracle.com \
    --cc=binutils@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).