1#!/bin/bash
2# test perf probe of function from different CU
3# SPDX-License-Identifier: GPL-2.0
4
5set -e
6
7# shellcheck source=lib/probe.sh
8. "$(dirname $0)"/lib/probe.sh
9
10skip_if_no_perf_probe || exit 2
11[ "$(id -u)" == 0 ] || exit 2
12
13# skip if there's no gcc
14if ! [ -x "$(command -v gcc)" ]; then
15        echo "failed: no gcc compiler"
16        exit 2
17fi
18
19temp_dir=$(mktemp -d /tmp/perf-uprobe-different-cu-sh.XXXXXXXXXX)
20
21cleanup()
22{
23	trap - EXIT TERM INT
24	if [[ "${temp_dir}" =~ ^/tmp/perf-uprobe-different-cu-sh.*$ ]]; then
25		echo "--- Cleaning up ---"
26		perf probe -x ${temp_dir}/testfile -d foo || true
27		rm -f "${temp_dir}/"*
28		rmdir "${temp_dir}"
29	fi
30}
31
32trap_cleanup()
33{
34        cleanup
35        exit 1
36}
37
38trap trap_cleanup EXIT TERM INT
39
40cat > ${temp_dir}/testfile-foo.h << EOF
41struct t
42{
43  int *p;
44  int c;
45};
46
47extern int foo (int i, struct t *t);
48EOF
49
50cat > ${temp_dir}/testfile-foo.c << EOF
51#include "testfile-foo.h"
52
53int
54foo (int i, struct t *t)
55{
56  int j, res = 0;
57  for (j = 0; j < i && j < t->c; j++)
58    res += t->p[j];
59
60  return res;
61}
62EOF
63
64cat > ${temp_dir}/testfile-main.c << EOF
65#include "testfile-foo.h"
66
67static struct t g;
68
69int
70main (int argc, char **argv)
71{
72  int i;
73  int j[argc];
74  g.c = argc;
75  g.p = j;
76  for (i = 0; i < argc; i++)
77    j[i] = (int) argv[i][0];
78  return foo (3, &g);
79}
80EOF
81
82gcc -g -Og -flto -c ${temp_dir}/testfile-foo.c -o ${temp_dir}/testfile-foo.o
83gcc -g -Og -c ${temp_dir}/testfile-main.c -o ${temp_dir}/testfile-main.o
84gcc -g -Og -o ${temp_dir}/testfile ${temp_dir}/testfile-foo.o ${temp_dir}/testfile-main.o
85
86perf probe -x ${temp_dir}/testfile --funcs foo | grep "foo"
87perf probe -x ${temp_dir}/testfile foo
88
89cleanup
90