BPF Archive on lore.kernel.org
 help / color / Atom feed
* [RFC] dwarves/pahole: Add test scripts
@ 2021-02-23 13:23 Jiri Olsa
  2021-02-24 17:30 ` Nathan Chancellor
  0 siblings, 1 reply; 2+ messages in thread
From: Jiri Olsa @ 2021-02-23 13:23 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo, Andrii Nakryiko
  Cc: dwarves, netdev, bpf, Alexei Starovoitov, Yonghong Song, Hao Luo,
	Martin KaFai Lau, Song Liu, John Fastabend, KP Singh,
	Nathan Chancellor, Sedat Dilek

hi,
I cleaned up a bit my testing scripts, that I'm using for testing
btf encoding changes. It's far from ideal and convoluted, but let's
have discussion if this could be kicked into something useful for
everybody.

There are 2 scripts:
  kernel-objects-build.sh - compiles kernel for several archs and
                            stores vmlinux and kernel modules

  kernel-objects-test.sh  - goes through objects stored by ^^^
                            and runs tests on each of them

The general idea is that all objects are compiled already with
BTF debuginfo with available pahole. The test script then:
  - takes each objects and dumps its current BTF data
  - then create new BTF data with given pahole binary
  - dumps the new BTF data and makes the comparison

I was thinking about support for comparing 2 pahole binaries,
but so far that did not fit into my workflow. Normally I have
latest globally available pahole, which is used to build the
kernel binaries and then I'm playing with new pahole binary,
which I'm putting to the test.

Example.. prepare vmlinux and modules for all archs:

        $ ./kernel-objects-build.sh
        output:  /tmp/pahole.test.nsQ
        kdir:    /home/jolsa/linux
        pahole:  /opt/dwarves/bin/pahole
        objects: /home/jolsa/.pahole_test_objects

        cleanup /home/jolsa/linux
        ...

All objects are stored under ~/pahole_test_objects/ directories:

        $ ls ~/.pahole_test_objects/
        aarch64-clang
        aarch64-gcc
        powerpc-gcc
        powerpcle-gcc
        s390x-gcc
        x86-clang
        x86-gcc

Each containing vmlinux and modules:

	$ ls ~/.pahole_test_objects/x86-gcc/
	efivarfs.ko  iptable_nat.ko  nf_log_arp.ko  nf_log_common.ko  nf_log_ipv4.ko  nf_log_ipv6.ko
	vmlinux  x86_pkg_temp_thermal.ko  xt_addrtype.ko  xt_LOG.ko  xt_mark.ko  xt_MASQUERADE.ko  xt_nat.ko

Run test on all of them with new './pahole' binary:

        $ ./kernel-objects-test.sh -B ~/linux/tools/bpf/bpftool/bpftool -P ./pahole
        pahole:  /home/jolsa/pahole/build/pahole
        bpftool: /home/jolsa/linux/tools/bpf/bpftool/bpftool
        base:    /tmp/pahole.test.oxv
        objects: /home/jolsa/.pahole_test_objects
        fail:    no
        cleanup: yes

        test_funcs      on /home/jolsa/.pahole_test_objects/aarch64-clang/vmlinux ... OK
        test_format_c   on /home/jolsa/.pahole_test_objects/aarch64-clang/vmlinux ... OK
        test_btfdiff    on /home/jolsa/.pahole_test_objects/aarch64-clang/vmlinux ... FAIL
        test_funcs      on /home/jolsa/.pahole_test_objects/aarch64-clang/8021q.ko ... OK
        test_format_c   on /home/jolsa/.pahole_test_objects/aarch64-clang/8021q.ko ... OK
        test_funcs      on /home/jolsa/.pahole_test_objects/aarch64-clang/act_gact.ko ... OK
        test_format_c   on /home/jolsa/.pahole_test_objects/aarch64-clang/act_gact.ko ... OK
        ...

There are several options that helps to set other binaries/dirs
or stop and debug issues.

thoughts?

thanks,
jirka


---
 kernel-objects-build.sh | 132 +++++++++++++++++++
 kernel-objects-test.sh  | 282 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 414 insertions(+)
 create mode 100755 kernel-objects-build.sh
 create mode 100755 kernel-objects-test.sh

diff --git a/kernel-objects-build.sh b/kernel-objects-build.sh
new file mode 100755
index 000000000000..b92729994ded
--- /dev/null
+++ b/kernel-objects-build.sh
@@ -0,0 +1,132 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+
+set -u
+set -e
+
+exec 2>&1
+
+OBJECTS="${HOME}/.pahole_test_objects"
+KDIR=${HOME}/linux
+PAHOLE=$(which pahole)
+OUTPUT=
+
+usage()
+{
+	cat <<EOF
+Usage: $0 [-k KERNEL] [-O OUTPUT] [-o OBJECTS]
+
+The script prepares vmlinux and kernel modules for different archs/C:
+
+  - x86 gcc/clang
+  - arm64 gcc/clang
+  - powerpc gcc
+  - s390x gcc
+
+Options:
+  -k) Update kernel tree directory (default HOME/linux)
+  -O) Update temp output directory (default mktemp /tmp/pahole.test.XXX)
+  -o) Update final objects directory (default HOME/.pahole.test.XXX)
+
+Make images under '/tmp/build', and place it under 'objects':
+
+  $ $0 -o objects -O /tmp/build/
+
+EOF
+}
+
+build()
+{
+	local name=$1
+	local opts=$2
+
+	echo "build ${name} (${OUTPUT}/output)"
+
+	mkdir -p ${OBJECTS}/${name}
+	mkdir -p ${OUTPUT}
+
+	pushd ${KDIR}
+	make ${opts} -j"$(nproc)" O=${OUTPUT} olddefconfig > ${OUTPUT}/output 2>&1
+	scripts/config \
+		--file ${OUTPUT}/.config \
+		-e BPF_SYSCALL \
+		-e DEBUG_INFO \
+		-e DEBUG_INFO_BTF \
+		-e FTRACE \
+		-e FUNCTION_TRACER \
+		>> ${OUTPUT}/output 2>&1
+	make ${opts} -j"$(nproc)" O=${OUTPUT} PAHOLE=${PAHOLE} olddefconfig all >> ${OUTPUT}/output 2>&1
+
+	cp ${OUTPUT}/vmlinux ${OBJECTS}/${name}
+	find ${OUTPUT} -name '*.ko' | xargs cp -t ${OBJECTS}/${name}
+
+	rm -rf ${OUTPUT}
+	popd
+}
+
+main()
+{
+	while getopts 'k:o:O:' opt; do
+		case ${opt} in
+		k)
+			KDIR="$OPTARG"
+			;;
+		O)
+			OUTPUT="$OPTARG"
+			;;
+		o)
+			OBJECTS="$OPTARG"
+			;;
+		esac
+	done
+	shift $((OPTIND -1))
+
+	if [[ $# -ne 0 ]]; then
+		usage
+		exit 1
+	fi
+
+        if [[ "${OUTPUT}" == "" ]]; then
+                OUTPUT=$(mktemp -d /tmp/pahole.test.XXX)
+        fi
+
+	PAHOLE=$(realpath ${PAHOLE})
+	OBJECTS=$(realpath ${OBJECTS})
+
+	echo "output:  ${OUTPUT}"
+	echo "kdir:    ${KDIR}"
+	echo "pahole:  ${PAHOLE}"
+	echo "objects: ${OBJECTS}"
+	echo
+
+	mkdir -p ${OBJECTS}
+
+	echo "cleanup ${KDIR}"
+	make -C ${KDIR} mrproper
+
+
+	build x86-clang     "LLVM=1"
+	build x86-gcc       ""
+
+	build aarch64-clang "ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- LLVM=1"
+	build aarch64-gcc   "ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-"
+
+#	build powerpc-clang "ARCH=powerpc CROSS_COMPILE=powerpc64-linux-gnu- LLVM=1"
+	build powerpc-gcc   "ARCH=powerpc CROSS_COMPILE=powerpc64-linux-gnu-"
+
+#	build powerpcle-clang "ARCH=powerpc CROSS_COMPILE=powerpc64le-linux-gnu- LLVM=1"
+	build powerpcle-gcc   "ARCH=powerpc CROSS_COMPILE=powerpc64le-linux-gnu-"
+
+#	build s390x-clang   "ARCH=s390 CROSS_COMPILE=s390x-linux-gnu- LLVM=1"
+	build s390x-gcc     "ARCH=s390 CROSS_COMPILE=s390x-linux-gnu-"
+}
+
+catch()
+{
+	local exit_code=$1
+	exit ${exit_code}
+}
+
+trap 'catch "$?"' EXIT
+
+main "$@"
diff --git a/kernel-objects-test.sh b/kernel-objects-test.sh
new file mode 100755
index 000000000000..a34c22c2eb09
--- /dev/null
+++ b/kernel-objects-test.sh
@@ -0,0 +1,282 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+
+set -u
+
+exec 2>&1
+
+PAHOLE=$(which pahole)
+BPFTOOL=$(which bpftool)
+BTFDIFF=$(which btfdiff)
+
+OBJECTS="$HOME/.pahole_test_objects"
+CLEANUP="yes"
+BASE=
+FAIL="no"
+
+function test_funcs()
+{
+	local vmlinux=$1
+	local obj=$2
+	local err=0
+
+	cp ${obj} ${BASE}/object
+
+	if [[ ${obj} == *.ko ]]; then
+		${BPFTOOL} --base ${vmlinux} btf dump file ${BASE}/object > ${BASE}/btf.old
+		${PAHOLE} -V -J --btf_base ${vmlinux} ${BASE}/object > ${BASE}/output
+		${BPFTOOL} --base ${vmlinux} btf dump file ${BASE}/object > ${BASE}/btf.new
+	else
+		${BPFTOOL} btf dump file ${BASE}/object > ${BASE}/btf.old
+		${PAHOLE} -V -J ${BASE}/object > ${BASE}/output
+		${BPFTOOL} btf dump file ${BASE}/object > ${BASE}/btf.new
+	fi
+
+	diff -puw ${BASE}/btf.old ${BASE}/btf.new > ${BASE}/diff.all
+	if [ $? -ne 0 ]; then
+		funcs_old=${BASE}/funcs.old
+		funcs_new=${BASE}/funcs.new
+
+		cat ${BASE}/btf.old | grep 'FUNC ' | awk '{ print $3 }' | sort | uniq > ${funcs_old}
+		cat ${BASE}/btf.new | grep 'FUNC ' | awk '{ print $3 }' | sort | uniq > ${funcs_new}
+
+		diff -puw ${funcs_old} ${funcs_new} > ${BASE}/diff.funcs
+	fi
+
+	if [[ $? -ne 0 ]]; then
+		err=1
+	fi
+
+	return ${err};
+}
+
+function test_format_c()
+{
+	local vmlinux=$1
+	local obj=$2
+	local err=0
+
+	cp ${obj} ${BASE}/object
+
+	if [[ ${obj} == *.ko ]]; then
+		${BPFTOOL} --base ${vmlinux} btf dump file ${BASE}/object format c > ${BASE}/c.old
+		${PAHOLE} -V -J --btf_base ${vmlinux} ${BASE}/object > ${BASE}/output
+		${BPFTOOL} --base ${vmlinux} btf dump file ${BASE}/object format c > ${BASE}/c.new
+	else
+		${BPFTOOL} btf dump file ${BASE}/object format c > ${BASE}/c.old
+		${PAHOLE} -V -J ${BASE}/object > ${BASE}/output
+		${BPFTOOL} btf dump file ${BASE}/object format c > ${BASE}/c.new
+	fi
+
+	diff -puw ${BASE}/c.old ${BASE}/c.new > ${BASE}/diff.all
+	if [[ $? -ne 0 ]]; then
+		err=1
+	fi
+
+	return ${err};
+}
+
+function test_btfdiff()
+{
+	local vmlinux=$1
+	local obj=$2
+	local err=0
+
+	if [[ -x ${BTFDIFF} ]]; then
+		${BTFDIFF} ${obj} > ${BASE}/output
+		if [[ -s "${BASE}/output" ]]; then
+			err=1
+		fi
+	else
+		err=2
+	fi
+
+	return ${err}
+}
+
+usage()
+{
+	cat <<EOF
+Usage: $0 [-f] [-o object] [-O objects] [-b BASE] [-P PAHOLE] [-B BPFTOOL] -- [test]
+
+The script runs tests on objects with BTF data.
+
+Options:
+  -f) Stop on failure
+  -o) Run tests on specific objects
+  -O) Update the root objects directory (default HOME/.pahole_test_objects)
+  -b) Update work base/temporary directory (default mktemp -d /tmp/pahole.test.XXX)
+  -P) Update pahole path (default which pahole)
+  -B) Update bpftool path (default which bpftool)
+
+Test image under 'objects':
+
+  $ $0 -O objects/
+
+Test specific image (objects/aarch64-clang) and stop on failure:
+
+  $ $0 -o o objects/aarch64-clang -f
+
+Run specific test (test_format_c):
+
+  $ $0 -o o objects/aarch64-clang -f test_format_c
+EOF
+}
+
+do_test()
+{
+	local test_name=$1
+	local vmlinux=$2
+	local obj=$3
+
+	printf "%-15s on %s ... " "${test_name}"  "${obj}"
+
+	eval ${test_name} ${vmlinux} ${obj}
+	local err=$?
+
+	case ${err} in
+	0)
+		echo "OK"
+		;;
+	1)
+		echo "FAIL"
+		;;
+	2)
+		echo "SKIP"
+		;;
+	esac
+
+	if [[ ${err} -eq 1 && "${FAIL}" == "yes" ]]; then
+		exit 1
+	fi
+
+	return ${err}
+}
+
+run_tests()
+{
+	local vmlinux=$1
+	local obj=$2
+	local test_name=$3
+
+	if [[ "${test_name}" != "all" ]]; then
+		do_test ${test_name} ${vmlinux} ${obj}
+	else
+		do_test test_funcs ${vmlinux} ${obj}
+		do_test test_format_c ${vmlinux} ${obj}
+
+		# btfdiff is only for vmlinux
+		if [[ ${obj} != *.ko ]]; then
+			do_test test_btfdiff ${vmlinux} ${obj}
+		fi
+	fi
+}
+
+do_obj()
+{
+	local obj=$1
+	local test_name=$2
+	local vmlinux=${obj}/vmlinux
+
+	run_tests ${vmlinux} ${vmlinux} ${test_name}
+
+	for kmod in $(ls ${obj}/*.ko); do
+		run_tests ${vmlinux} ${kmod} ${test_name}
+	done
+}
+
+main()
+{
+	local test_name="all"
+
+	while getopts 'b:o:dhP:B:fO:' opt; do
+		case ${opt} in
+		f)
+			FAIL="yes"
+			CLEANUP="no"
+			;;
+		o)
+			obj="$OPTARG"
+			;;
+		O)
+			OBJECTS="$OPTARG"
+			;;
+		b)
+			BASE="$OPTARG"
+			;;
+		P)
+			PAHOLE="$OPTARG"
+			;;
+		B)
+			BPFTOOL="$OPTARG"
+			;;
+		h)
+			usage
+			exit 0
+			;;
+		\? )
+			echo "Invalid Option: -$OPTARG"
+			usage
+			exit 1
+			;;
+		: )
+			echo "Invalid Option: -$OPTARG requires an argument"
+			usage
+			exit 1
+			;;
+		esac
+	done
+	shift $((OPTIND -1))
+
+	if [[ $# -gt 1 ]]; then
+		echo "Invalid test: $@"
+		usage
+		exit 1
+	fi
+
+	if [[ $# -eq 1 ]]; then
+		test_name="$@"
+	fi
+
+	if [[ "${BASE}" == "" ]]; then
+		BASE=$(mktemp -d /tmp/pahole.test.XXX)
+	else
+		mkdir -p ${BASE}
+	fi
+
+	PAHOLE=$(realpath ${PAHOLE})
+	BPFTOOL=$(realpath ${BPFTOOL})
+	OBJECTS=$(realpath ${OBJECTS})
+
+	echo "pahole:  ${PAHOLE}"
+	echo "bpftool: ${BPFTOOL}"
+	echo "base:    ${BASE}"
+	echo "objects: ${obj:-${OBJECTS}}"
+	echo "fail:    ${FAIL}"
+	echo "cleanup: ${CLEANUP}"
+	echo
+
+	if [[ "${obj:=""}" != "" ]]; then
+		do_obj ${obj} ${test_name}
+	else
+		for obj in $(ls ${OBJECTS}); do
+			do_obj ${OBJECTS}/${obj} ${test_name}
+		done
+	fi
+}
+
+catch()
+{
+	local exit_code=$1
+	if [[ "${BASE:=""}" != "" && "${CLEANUP}" == "yes" ]]; then
+		rm -rf ${BASE}
+	else
+		echo
+		echo "Keeping test data in: ${BASE}"
+	fi
+	exit ${exit_code}
+}
+
+trap 'catch "$?"' EXIT
+
+main "$@"
-- 
2.29.2


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [RFC] dwarves/pahole: Add test scripts
  2021-02-23 13:23 [RFC] dwarves/pahole: Add test scripts Jiri Olsa
@ 2021-02-24 17:30 ` Nathan Chancellor
  0 siblings, 0 replies; 2+ messages in thread
From: Nathan Chancellor @ 2021-02-24 17:30 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Arnaldo Carvalho de Melo, Andrii Nakryiko, dwarves, netdev, bpf,
	Alexei Starovoitov, Yonghong Song, Hao Luo, Martin KaFai Lau,
	Song Liu, John Fastabend, KP Singh, Sedat Dilek

Hi Jiri,

Just some drive by comments. I think the idea is neat, I am always a fan
of automating more things :)

On Tue, Feb 23, 2021 at 02:23:21PM +0100, Jiri Olsa wrote:
> hi,
> I cleaned up a bit my testing scripts, that I'm using for testing
> btf encoding changes. It's far from ideal and convoluted, but let's
> have discussion if this could be kicked into something useful for
> everybody.
> 
> There are 2 scripts:
>   kernel-objects-build.sh - compiles kernel for several archs and
>                             stores vmlinux and kernel modules
> 
>   kernel-objects-test.sh  - goes through objects stored by ^^^
>                             and runs tests on each of them
> 
> The general idea is that all objects are compiled already with
> BTF debuginfo with available pahole. The test script then:
>   - takes each objects and dumps its current BTF data
>   - then create new BTF data with given pahole binary
>   - dumps the new BTF data and makes the comparison
> 
> I was thinking about support for comparing 2 pahole binaries,
> but so far that did not fit into my workflow. Normally I have
> latest globally available pahole, which is used to build the
> kernel binaries and then I'm playing with new pahole binary,
> which I'm putting to the test.
> 
> Example.. prepare vmlinux and modules for all archs:
> 
>         $ ./kernel-objects-build.sh
>         output:  /tmp/pahole.test.nsQ
>         kdir:    /home/jolsa/linux
>         pahole:  /opt/dwarves/bin/pahole
>         objects: /home/jolsa/.pahole_test_objects
> 
>         cleanup /home/jolsa/linux
>         ...
> 
> All objects are stored under ~/pahole_test_objects/ directories:
> 
>         $ ls ~/.pahole_test_objects/
>         aarch64-clang
>         aarch64-gcc
>         powerpc-gcc
>         powerpcle-gcc
>         s390x-gcc
>         x86-clang
>         x86-gcc
> 
> Each containing vmlinux and modules:
> 
> 	$ ls ~/.pahole_test_objects/x86-gcc/
> 	efivarfs.ko  iptable_nat.ko  nf_log_arp.ko  nf_log_common.ko  nf_log_ipv4.ko  nf_log_ipv6.ko
> 	vmlinux  x86_pkg_temp_thermal.ko  xt_addrtype.ko  xt_LOG.ko  xt_mark.ko  xt_MASQUERADE.ko  xt_nat.ko
> 
> Run test on all of them with new './pahole' binary:
> 
>         $ ./kernel-objects-test.sh -B ~/linux/tools/bpf/bpftool/bpftool -P ./pahole
>         pahole:  /home/jolsa/pahole/build/pahole
>         bpftool: /home/jolsa/linux/tools/bpf/bpftool/bpftool
>         base:    /tmp/pahole.test.oxv
>         objects: /home/jolsa/.pahole_test_objects
>         fail:    no
>         cleanup: yes
> 
>         test_funcs      on /home/jolsa/.pahole_test_objects/aarch64-clang/vmlinux ... OK
>         test_format_c   on /home/jolsa/.pahole_test_objects/aarch64-clang/vmlinux ... OK
>         test_btfdiff    on /home/jolsa/.pahole_test_objects/aarch64-clang/vmlinux ... FAIL
>         test_funcs      on /home/jolsa/.pahole_test_objects/aarch64-clang/8021q.ko ... OK
>         test_format_c   on /home/jolsa/.pahole_test_objects/aarch64-clang/8021q.ko ... OK
>         test_funcs      on /home/jolsa/.pahole_test_objects/aarch64-clang/act_gact.ko ... OK
>         test_format_c   on /home/jolsa/.pahole_test_objects/aarch64-clang/act_gact.ko ... OK
>         ...
> 
> There are several options that helps to set other binaries/dirs
> or stop and debug issues.
> 
> thoughts?
> 
> thanks,
> jirka
> 
> 
> ---
>  kernel-objects-build.sh | 132 +++++++++++++++++++
>  kernel-objects-test.sh  | 282 ++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 414 insertions(+)
>  create mode 100755 kernel-objects-build.sh
>  create mode 100755 kernel-objects-test.sh
> 
> diff --git a/kernel-objects-build.sh b/kernel-objects-build.sh
> new file mode 100755
> index 000000000000..b92729994ded
> --- /dev/null
> +++ b/kernel-objects-build.sh
> @@ -0,0 +1,132 @@
> +#!/bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +
> +set -u
> +set -e
> +
> +exec 2>&1
> +
> +OBJECTS="${HOME}/.pahole_test_objects"
> +KDIR=${HOME}/linux
> +PAHOLE=$(which pahole)
> +OUTPUT=
> +
> +usage()
> +{
> +	cat <<EOF
> +Usage: $0 [-k KERNEL] [-O OUTPUT] [-o OBJECTS]
> +
> +The script prepares vmlinux and kernel modules for different archs/C:
> +
> +  - x86 gcc/clang
> +  - arm64 gcc/clang
> +  - powerpc gcc
> +  - s390x gcc
> +
> +Options:
> +  -k) Update kernel tree directory (default HOME/linux)
> +  -O) Update temp output directory (default mktemp /tmp/pahole.test.XXX)
> +  -o) Update final objects directory (default HOME/.pahole.test.XXX)
> +
> +Make images under '/tmp/build', and place it under 'objects':
> +
> +  $ $0 -o objects -O /tmp/build/
> +
> +EOF
> +}
> +
> +build()
> +{
> +	local name=$1
> +	local opts=$2

A more robust way to handle this might be

shift
local opts=$@

> +
> +	echo "build ${name} (${OUTPUT}/output)"
> +
> +	mkdir -p ${OBJECTS}/${name}
> +	mkdir -p ${OUTPUT}
> +
> +	pushd ${KDIR}
> +	make ${opts} -j"$(nproc)" O=${OUTPUT} olddefconfig > ${OUTPUT}/output 2>&1

Then change this to

make "${opts[@]}"

shellcheck complains about implicit word splitting (and finds some other
things in the other script).

> +	scripts/config \
> +		--file ${OUTPUT}/.config \
> +		-e BPF_SYSCALL \
> +		-e DEBUG_INFO \
> +		-e DEBUG_INFO_BTF \
> +		-e FTRACE \
> +		-e FUNCTION_TRACER \
> +		>> ${OUTPUT}/output 2>&1
> +	make ${opts} -j"$(nproc)" O=${OUTPUT} PAHOLE=${PAHOLE} olddefconfig all >> ${OUTPUT}/output 2>&1
> +
> +	cp ${OUTPUT}/vmlinux ${OBJECTS}/${name}
> +	find ${OUTPUT} -name '*.ko' | xargs cp -t ${OBJECTS}/${name}
> +
> +	rm -rf ${OUTPUT}
> +	popd
> +}
> +
> +main()
> +{
> +	while getopts 'k:o:O:' opt; do
> +		case ${opt} in
> +		k)
> +			KDIR="$OPTARG"
> +			;;
> +		O)
> +			OUTPUT="$OPTARG"
> +			;;
> +		o)
> +			OBJECTS="$OPTARG"
> +			;;
> +		esac
> +	done
> +	shift $((OPTIND -1))
> +
> +	if [[ $# -ne 0 ]]; then
> +		usage
> +		exit 1
> +	fi
> +
> +        if [[ "${OUTPUT}" == "" ]]; then
> +                OUTPUT=$(mktemp -d /tmp/pahole.test.XXX)
> +        fi
> +
> +	PAHOLE=$(realpath ${PAHOLE})
> +	OBJECTS=$(realpath ${OBJECTS})
> +
> +	echo "output:  ${OUTPUT}"
> +	echo "kdir:    ${KDIR}"
> +	echo "pahole:  ${PAHOLE}"
> +	echo "objects: ${OBJECTS}"
> +	echo
> +
> +	mkdir -p ${OBJECTS}
> +
> +	echo "cleanup ${KDIR}"
> +	make -C ${KDIR} mrproper
> +
> +
> +	build x86-clang     "LLVM=1"

With that change above, you could unquote these options and just pass
them in as regular parameters.

> +	build x86-gcc       ""
> +
> +	build aarch64-clang "ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- LLVM=1"
> +	build aarch64-gcc   "ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-"
> +
> +#	build powerpc-clang "ARCH=powerpc CROSS_COMPILE=powerpc64-linux-gnu- LLVM=1"
> +	build powerpc-gcc   "ARCH=powerpc CROSS_COMPILE=powerpc64-linux-gnu-"
> +
> +#	build powerpcle-clang "ARCH=powerpc CROSS_COMPILE=powerpc64le-linux-gnu- LLVM=1"
> +	build powerpcle-gcc   "ARCH=powerpc CROSS_COMPILE=powerpc64le-linux-gnu-"
> +
> +#	build s390x-clang   "ARCH=s390 CROSS_COMPILE=s390x-linux-gnu- LLVM=1"

powerpc64le and s390 can build with CC=clang, instead of LLVM=1.

I will see if I can give this a run locally over the next week or so.

Cheers,
Nathan

> +	build s390x-gcc     "ARCH=s390 CROSS_COMPILE=s390x-linux-gnu-"
> +}
> +
> +catch()
> +{
> +	local exit_code=$1
> +	exit ${exit_code}
> +}
> +
> +trap 'catch "$?"' EXIT
> +
> +main "$@"
> diff --git a/kernel-objects-test.sh b/kernel-objects-test.sh
> new file mode 100755
> index 000000000000..a34c22c2eb09
> --- /dev/null
> +++ b/kernel-objects-test.sh
> @@ -0,0 +1,282 @@
> +#!/bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +
> +set -u
> +
> +exec 2>&1
> +
> +PAHOLE=$(which pahole)
> +BPFTOOL=$(which bpftool)
> +BTFDIFF=$(which btfdiff)
> +
> +OBJECTS="$HOME/.pahole_test_objects"
> +CLEANUP="yes"
> +BASE=
> +FAIL="no"
> +
> +function test_funcs()
> +{
> +	local vmlinux=$1
> +	local obj=$2
> +	local err=0
> +
> +	cp ${obj} ${BASE}/object
> +
> +	if [[ ${obj} == *.ko ]]; then
> +		${BPFTOOL} --base ${vmlinux} btf dump file ${BASE}/object > ${BASE}/btf.old
> +		${PAHOLE} -V -J --btf_base ${vmlinux} ${BASE}/object > ${BASE}/output
> +		${BPFTOOL} --base ${vmlinux} btf dump file ${BASE}/object > ${BASE}/btf.new
> +	else
> +		${BPFTOOL} btf dump file ${BASE}/object > ${BASE}/btf.old
> +		${PAHOLE} -V -J ${BASE}/object > ${BASE}/output
> +		${BPFTOOL} btf dump file ${BASE}/object > ${BASE}/btf.new
> +	fi
> +
> +	diff -puw ${BASE}/btf.old ${BASE}/btf.new > ${BASE}/diff.all
> +	if [ $? -ne 0 ]; then
> +		funcs_old=${BASE}/funcs.old
> +		funcs_new=${BASE}/funcs.new
> +
> +		cat ${BASE}/btf.old | grep 'FUNC ' | awk '{ print $3 }' | sort | uniq > ${funcs_old}
> +		cat ${BASE}/btf.new | grep 'FUNC ' | awk '{ print $3 }' | sort | uniq > ${funcs_new}
> +
> +		diff -puw ${funcs_old} ${funcs_new} > ${BASE}/diff.funcs
> +	fi
> +
> +	if [[ $? -ne 0 ]]; then
> +		err=1
> +	fi
> +
> +	return ${err};
> +}
> +
> +function test_format_c()
> +{
> +	local vmlinux=$1
> +	local obj=$2
> +	local err=0
> +
> +	cp ${obj} ${BASE}/object
> +
> +	if [[ ${obj} == *.ko ]]; then
> +		${BPFTOOL} --base ${vmlinux} btf dump file ${BASE}/object format c > ${BASE}/c.old
> +		${PAHOLE} -V -J --btf_base ${vmlinux} ${BASE}/object > ${BASE}/output
> +		${BPFTOOL} --base ${vmlinux} btf dump file ${BASE}/object format c > ${BASE}/c.new
> +	else
> +		${BPFTOOL} btf dump file ${BASE}/object format c > ${BASE}/c.old
> +		${PAHOLE} -V -J ${BASE}/object > ${BASE}/output
> +		${BPFTOOL} btf dump file ${BASE}/object format c > ${BASE}/c.new
> +	fi
> +
> +	diff -puw ${BASE}/c.old ${BASE}/c.new > ${BASE}/diff.all
> +	if [[ $? -ne 0 ]]; then
> +		err=1
> +	fi
> +
> +	return ${err};
> +}
> +
> +function test_btfdiff()
> +{
> +	local vmlinux=$1
> +	local obj=$2
> +	local err=0
> +
> +	if [[ -x ${BTFDIFF} ]]; then
> +		${BTFDIFF} ${obj} > ${BASE}/output
> +		if [[ -s "${BASE}/output" ]]; then
> +			err=1
> +		fi
> +	else
> +		err=2
> +	fi
> +
> +	return ${err}
> +}
> +
> +usage()
> +{
> +	cat <<EOF
> +Usage: $0 [-f] [-o object] [-O objects] [-b BASE] [-P PAHOLE] [-B BPFTOOL] -- [test]
> +
> +The script runs tests on objects with BTF data.
> +
> +Options:
> +  -f) Stop on failure
> +  -o) Run tests on specific objects
> +  -O) Update the root objects directory (default HOME/.pahole_test_objects)
> +  -b) Update work base/temporary directory (default mktemp -d /tmp/pahole.test.XXX)
> +  -P) Update pahole path (default which pahole)
> +  -B) Update bpftool path (default which bpftool)
> +
> +Test image under 'objects':
> +
> +  $ $0 -O objects/
> +
> +Test specific image (objects/aarch64-clang) and stop on failure:
> +
> +  $ $0 -o o objects/aarch64-clang -f
> +
> +Run specific test (test_format_c):
> +
> +  $ $0 -o o objects/aarch64-clang -f test_format_c
> +EOF
> +}
> +
> +do_test()
> +{
> +	local test_name=$1
> +	local vmlinux=$2
> +	local obj=$3
> +
> +	printf "%-15s on %s ... " "${test_name}"  "${obj}"
> +
> +	eval ${test_name} ${vmlinux} ${obj}
> +	local err=$?
> +
> +	case ${err} in
> +	0)
> +		echo "OK"
> +		;;
> +	1)
> +		echo "FAIL"
> +		;;
> +	2)
> +		echo "SKIP"
> +		;;
> +	esac
> +
> +	if [[ ${err} -eq 1 && "${FAIL}" == "yes" ]]; then
> +		exit 1
> +	fi
> +
> +	return ${err}
> +}
> +
> +run_tests()
> +{
> +	local vmlinux=$1
> +	local obj=$2
> +	local test_name=$3
> +
> +	if [[ "${test_name}" != "all" ]]; then
> +		do_test ${test_name} ${vmlinux} ${obj}
> +	else
> +		do_test test_funcs ${vmlinux} ${obj}
> +		do_test test_format_c ${vmlinux} ${obj}
> +
> +		# btfdiff is only for vmlinux
> +		if [[ ${obj} != *.ko ]]; then
> +			do_test test_btfdiff ${vmlinux} ${obj}
> +		fi
> +	fi
> +}
> +
> +do_obj()
> +{
> +	local obj=$1
> +	local test_name=$2
> +	local vmlinux=${obj}/vmlinux
> +
> +	run_tests ${vmlinux} ${vmlinux} ${test_name}
> +
> +	for kmod in $(ls ${obj}/*.ko); do
> +		run_tests ${vmlinux} ${kmod} ${test_name}
> +	done
> +}
> +
> +main()
> +{
> +	local test_name="all"
> +
> +	while getopts 'b:o:dhP:B:fO:' opt; do
> +		case ${opt} in
> +		f)
> +			FAIL="yes"
> +			CLEANUP="no"
> +			;;
> +		o)
> +			obj="$OPTARG"
> +			;;
> +		O)
> +			OBJECTS="$OPTARG"
> +			;;
> +		b)
> +			BASE="$OPTARG"
> +			;;
> +		P)
> +			PAHOLE="$OPTARG"
> +			;;
> +		B)
> +			BPFTOOL="$OPTARG"
> +			;;
> +		h)
> +			usage
> +			exit 0
> +			;;
> +		\? )
> +			echo "Invalid Option: -$OPTARG"
> +			usage
> +			exit 1
> +			;;
> +		: )
> +			echo "Invalid Option: -$OPTARG requires an argument"
> +			usage
> +			exit 1
> +			;;
> +		esac
> +	done
> +	shift $((OPTIND -1))
> +
> +	if [[ $# -gt 1 ]]; then
> +		echo "Invalid test: $@"
> +		usage
> +		exit 1
> +	fi
> +
> +	if [[ $# -eq 1 ]]; then
> +		test_name="$@"
> +	fi
> +
> +	if [[ "${BASE}" == "" ]]; then
> +		BASE=$(mktemp -d /tmp/pahole.test.XXX)
> +	else
> +		mkdir -p ${BASE}
> +	fi
> +
> +	PAHOLE=$(realpath ${PAHOLE})
> +	BPFTOOL=$(realpath ${BPFTOOL})
> +	OBJECTS=$(realpath ${OBJECTS})
> +
> +	echo "pahole:  ${PAHOLE}"
> +	echo "bpftool: ${BPFTOOL}"
> +	echo "base:    ${BASE}"
> +	echo "objects: ${obj:-${OBJECTS}}"
> +	echo "fail:    ${FAIL}"
> +	echo "cleanup: ${CLEANUP}"
> +	echo
> +
> +	if [[ "${obj:=""}" != "" ]]; then
> +		do_obj ${obj} ${test_name}
> +	else
> +		for obj in $(ls ${OBJECTS}); do
> +			do_obj ${OBJECTS}/${obj} ${test_name}
> +		done
> +	fi
> +}
> +
> +catch()
> +{
> +	local exit_code=$1
> +	if [[ "${BASE:=""}" != "" && "${CLEANUP}" == "yes" ]]; then
> +		rm -rf ${BASE}
> +	else
> +		echo
> +		echo "Keeping test data in: ${BASE}"
> +	fi
> +	exit ${exit_code}
> +}
> +
> +trap 'catch "$?"' EXIT
> +
> +main "$@"
> -- 
> 2.29.2
> 

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, back to index

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-23 13:23 [RFC] dwarves/pahole: Add test scripts Jiri Olsa
2021-02-24 17:30 ` Nathan Chancellor

BPF Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/bpf/0 bpf/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 bpf bpf/ https://lore.kernel.org/bpf \
		bpf@vger.kernel.org
	public-inbox-index bpf

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.bpf


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git