diff mbox series

[RFC] dwarves/pahole: Add test scripts

Message ID 20210223132321.220570-1-jolsa@kernel.org
State New
Headers show
Series [RFC] dwarves/pahole: Add test scripts | expand

Commit Message

Jiri Olsa Feb. 23, 2021, 1:23 p.m. UTC
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

Comments

Jiri Olsa Feb. 25, 2021, 10:15 p.m. UTC | #1
On Wed, Feb 24, 2021 at 10:30:45AM -0700, Nathan Chancellor wrote:

SNIP

> > +

> > +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).


I have no doutbs ;-) ok

SNIP

> > +

> > +	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.


ok I see, that'd be easier and better looking, I'll change this

> 

> > +	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 got some strange error when building ppc and s390 with LLVM=1,
but I did not check it deeply.. I'll try with CC=clang then, great

> 

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


thanks,
jirka
Arnaldo Carvalho de Melo Aug. 20, 2021, 8:39 p.m. UTC | #2
Em Tue, Feb 23, 2021 at 02:23:21PM +0100, Jiri Olsa escreveu:
> 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?


So far:

should look in other places for getting the kernel sources directory,
myne is at $(HOME)/git/linux/, kernel-objects-build.sh is looking at
$(HOME)/linux/

Maybe we can use this, if there is any locally built kernel:

[acme@quaco pahole]$ ls -la /lib/modules/5.10.0-rc5/source
lrwxrwxrwx. 1 root root 20 Nov 23  2020 /lib/modules/5.10.0-rc5/source -> /home/acme/git/linux
[acme@quaco pahole]$

Or look at $HOME/git/linux/ too if not finding it in $HOME/linux/

Also it is building in the source tree, would be better to create a temp
dir and use O=.

Trying it:

⬢[acme@toolbox pahole]$ ./kernel-objects-build.sh
output:  /tmp/pahole.test.0su
kdir:    /var/home/acme/git/linux
pahole:  /var/home/acme/git/pahole/build/pahole
objects: /var/home/acme/.pahole_test_objects

cleanup /var/home/acme/git/linux
make: Entering directory '/var/home/acme/git/linux'
make: Leaving directory '/var/home/acme/git/linux'
build x86-clang (/tmp/pahole.test.0su/output)
~/git/linux ~/git/pahole
~/git/pahole
build x86-gcc (/tmp/pahole.test.0su/output)
~/git/linux ~/git/pahole
rpm~/git/pahole
build aarch64-clang (/tmp/pahole.test.0su/output)
~/git/linux ~/git/pahole
⬢[acme@toolbox pahole]$

⬢[acme@toolbox pahole]$ ls -la ~/.pahole_test_objects/
total 0
drwxr-xr-x. 1 acme acme   58 Aug 20 17:24 .
drwx------. 1 acme acme 1346 Aug 20 17:31 ..
drwxr-xr-x. 1 acme acme    0 Aug 20 17:24 aarch64-clang
drwxr-xr-x. 1 acme acme  258 Aug 20 17:21 x86-clang
drwxr-xr-x. 1 acme acme  258 Aug 20 17:24 x86-gcc
⬢[acme@toolbox pahole]$

⬢[acme@toolbox pahole]$ ls -la ~/.pahole_test_objects/aarch64-clang/
total 0
drwxr-xr-x. 1 acme acme  0 Aug 20 17:24 .
drwxr-xr-x. 1 acme acme 58 Aug 20 17:24 ..
⬢[acme@toolbox pahole]$ ls -la ~/.pahole_test_objects/x86-clang/
total 592512
drwxr-xr-x. 1 acme acme       258 Aug 20 17:21 .
drwxr-xr-x. 1 acme acme        58 Aug 20 17:24 ..
-rw-r--r--. 1 acme acme    392920 Aug 20 17:21 efivarfs.ko
-rw-r--r--. 1 acme acme    388384 Aug 20 17:21 iptable_nat.ko
-rw-r--r--. 1 acme acme    471896 Aug 20 17:21 nf_log_syslog.ko
-rwxr-xr-x. 1 acme acme 603366392 Aug 20 17:21 vmlinux
-rw-r--r--. 1 acme acme    245272 Aug 20 17:21 x86_pkg_temp_thermal.ko
-rw-r--r--. 1 acme acme    397128 Aug 20 17:21 xt_addrtype.ko
-rw-r--r--. 1 acme acme    375536 Aug 20 17:21 xt_LOG.ko
-rw-r--r--. 1 acme acme    292320 Aug 20 17:21 xt_mark.ko
-rw-r--r--. 1 acme acme    383824 Aug 20 17:21 xt_MASQUERADE.ko
-rw-r--r--. 1 acme acme    401672 Aug 20 17:21 xt_nat.ko
⬢[acme@toolbox pahole]$ ls -la ~/.pahole_test_objects/x86-gcc/
total 699988
drwxr-xr-x. 1 acme acme       258 Aug 20 17:24 .
drwxr-xr-x. 1 acme acme        58 Aug 20 17:24 ..
-rw-r--r--. 1 acme acme    485112 Aug 20 17:24 efivarfs.ko
-rw-r--r--. 1 acme acme    419520 Aug 20 17:24 iptable_nat.ko
-rw-r--r--. 1 acme acme    514512 Aug 20 17:24 nf_log_syslog.ko
-rwxr-xr-x. 1 acme acme 713044328 Aug 20 17:24 vmlinux
-rw-r--r--. 1 acme acme    301256 Aug 20 17:24 x86_pkg_temp_thermal.ko
-rw-r--r--. 1 acme acme    431712 Aug 20 17:24 xt_addrtype.ko
-rw-r--r--. 1 acme acme    403384 Aug 20 17:24 xt_LOG.ko
-rw-r--r--. 1 acme acme    316528 Aug 20 17:24 xt_mark.ko
-rw-r--r--. 1 acme acme    411992 Aug 20 17:24 xt_MASQUERADE.ko
-rw-r--r--. 1 acme acme    435312 Aug 20 17:24 xt_nat.ko
⬢[acme@toolbox pahole]$

It didn't build bpftool so I have to do it now:


⬢[acme@toolbox pahole]$ cd ../linux
⬢[acme@toolbox linux]$ make -C tools/bpf/bpftool/
make: Entering directory '/var/home/acme/git/linux/tools/bpf/bpftool'

Auto-detecting system features:
...                        libbfd: [ on  ]
...        disassembler-four-args: [ on  ]
...                          zlib: [ on  ]
...                        libcap: [ on  ]
...               clang-bpf-co-re: [ on  ]


  CC      btf.o
<SNIP>
  CC      struct_ops.o
  CC      tracelog.o
  CC      xlated_dumper.o
  CC      jit_disasm.o
  CC      disasm.o
  LINK    bpftool
make: Leaving directory '/var/home/acme/git/linux/tools/bpf/bpftool'
⬢[acme@toolbox linux]$

⬢[acme@toolbox linux]$ cd -
/var/home/acme/git/pahole
⬢[acme@toolbox pahole]$

⬢[acme@toolbox pahole]$ ./kernel-objects-test.sh -B ~/git/linux/tools/bpf/bpftool/bpftool -P build/pahole
/usr/bin/which: no bpftool in (/var/home/acme/.local/bin:/var/home/acme/bin:/usr/lib64/ccache:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin)
pahole:  /var/home/acme/git/pahole/build/pahole
bpftool: /var/home/acme/git/linux/tools/bpf/bpftool/bpftool
base:    /tmp/pahole.test.4of
objects: /var/home/acme/.pahole_test_objects
fail:    no
cleanup: yes

test_funcs      on /var/home/acme/.pahole_test_objects/aarch64-clang/vmlinux ... cp: cannot stat '/var/home/acme/.pahole_test_objects/aarch64-clang/vmlinux': No such file or directory
Error: failed to load BTF from /tmp/pahole.test.4of/object: No such file or directory
pahole: /tmp/pahole.test.4of/object: No such file or directory
Error: failed to load BTF from /tmp/pahole.test.4of/object: No such file or directory
OK
test_format_c   on /var/home/acme/.pahole_test_objects/aarch64-clang/vmlinux ... cp: cannot stat '/var/home/acme/.pahole_test_objects/aarch64-clang/vmlinux': No such file or directory
Error: failed to load BTF from /tmp/pahole.test.4of/object: No such file or directory
pahole: /tmp/pahole.test.4of/object: No such file or directory
Error: failed to load BTF from /tmp/pahole.test.4of/object: No such file or directory
OK
test_btfdiff    on /var/home/acme/.pahole_test_objects/aarch64-clang/vmlinux ... OK
ls: cannot access '/var/home/acme/.pahole_test_objects/aarch64-clang/*.ko': No such file or directory
test_funcs      on /var/home/acme/.pahole_test_objects/x86-clang/vmlinux ... OK
test_format_c   on /var/home/acme/.pahole_test_objects/x86-clang/vmlinux ... OK
test_btfdiff    on /var/home/acme/.pahole_test_objects/x86-clang/vmlinux ... FAIL
test_funcs      on /var/home/acme/.pahole_test_objects/x86-clang/efivarfs.ko ... OK
test_format_c   on /var/home/acme/.pahole_test_objects/x86-clang/efivarfs.ko ... OK
test_funcs      on /var/home/acme/.pahole_test_objects/x86-clang/iptable_nat.ko ... OK
test_format_c   on /var/home/acme/.pahole_test_objects/x86-clang/iptable_nat.ko ... OK
test_funcs      on /var/home/acme/.pahole_test_objects/x86-clang/nf_log_syslog.ko ... OK
test_format_c   on /var/home/acme/.pahole_test_objects/x86-clang/nf_log_syslog.ko ... OK
test_funcs      on /var/home/acme/.pahole_test_objects/x86-clang/x86_pkg_temp_thermal.ko ... OK
test_format_c   on /var/home/acme/.pahole_test_objects/x86-clang/x86_pkg_temp_thermal.ko ... OK
test_funcs      on /var/home/acme/.pahole_test_objects/x86-clang/xt_addrtype.ko ... OK
test_format_c   on /var/home/acme/.pahole_test_objects/x86-clang/xt_addrtype.ko ... OK
test_funcs      on /var/home/acme/.pahole_test_objects/x86-clang/xt_LOG.ko ... OK
test_format_c   on /var/home/acme/.pahole_test_objects/x86-clang/xt_LOG.ko ... OK
test_funcs      on /var/home/acme/.pahole_test_objects/x86-clang/xt_mark.ko ... OK
test_format_c   on /var/home/acme/.pahole_test_objects/x86-clang/xt_mark.ko ... OK
test_funcs      on /var/home/acme/.pahole_test_objects/x86-clang/xt_MASQUERADE.ko ... OK
test_format_c   on /var/home/acme/.pahole_test_objects/x86-clang/xt_MASQUERADE.ko ... OK
test_funcs      on /var/home/acme/.pahole_test_objects/x86-clang/xt_nat.ko ... OK
test_format_c   on /var/home/acme/.pahole_test_objects/x86-clang/xt_nat.ko ... OK
test_funcs      on /var/home/acme/.pahole_test_objects/x86-gcc/vmlinux ... Ignoring zero-sized per-CPU variable 'pagesets'...
OK
test_format_c   on /var/home/acme/.pahole_test_objects/x86-gcc/vmlinux ... Ignoring zero-sized per-CPU variable 'pagesets'...
OK
test_btfdiff    on /var/home/acme/.pahole_test_objects/x86-gcc/vmlinux ... FAIL
test_funcs      on /var/home/acme/.pahole_test_objects/x86-gcc/efivarfs.ko ... OK
test_format_c   on /var/home/acme/.pahole_test_objects/x86-gcc/efivarfs.ko ... OK
test_funcs      on /var/home/acme/.pahole_test_objects/x86-gcc/iptable_nat.ko ... OK
test_format_c   on /var/home/acme/.pahole_test_objects/x86-gcc/iptable_nat.ko ... OK
test_funcs      on /var/home/acme/.pahole_test_objects/x86-gcc/nf_log_syslog.ko ... OK
test_format_c   on /var/home/acme/.pahole_test_objects/x86-gcc/nf_log_syslog.ko ... OK
test_funcs      on /var/home/acme/.pahole_test_objects/x86-gcc/x86_pkg_temp_thermal.ko ... OK
test_format_c   on /var/home/acme/.pahole_test_objects/x86-gcc/x86_pkg_temp_thermal.ko ... OK
test_funcs      on /var/home/acme/.pahole_test_objects/x86-gcc/xt_addrtype.ko ... OK
test_format_c   on /var/home/acme/.pahole_test_objects/x86-gcc/xt_addrtype.ko ... OK
test_funcs      on /var/home/acme/.pahole_test_objects/x86-gcc/xt_LOG.ko ... OK
test_format_c   on /var/home/acme/.pahole_test_objects/x86-gcc/xt_LOG.ko ... OK
test_funcs      on /var/home/acme/.pahole_test_objects/x86-gcc/xt_mark.ko ... OK
test_format_c   on /var/home/acme/.pahole_test_objects/x86-gcc/xt_mark.ko ... OK
test_funcs      on /var/home/acme/.pahole_test_objects/x86-gcc/xt_MASQUERADE.ko ... OK
test_format_c   on /var/home/acme/.pahole_test_objects/x86-gcc/xt_MASQUERADE.ko ... OK
test_funcs      on /var/home/acme/.pahole_test_objects/x86-gcc/xt_nat.ko ... OK
test_format_c   on /var/home/acme/.pahole_test_objects/x86-gcc/xt_nat.ko ... OK
⬢[acme@toolbox pahole]$

So, now looking at:

test_btfdiff    on /var/home/acme/.pahole_test_objects/x86-gcc/vmlinux ... FAIL

Overall, I like it, will add also the 'fullcircle' test for some of the
single CU kernel objects and add detached BTF tests.

- Arnaldo
Arnaldo Carvalho de Melo Aug. 20, 2021, 9:02 p.m. UTC | #3
Em Fri, Aug 20, 2021 at 05:39:22PM -0300, Arnaldo Carvalho de Melo escreveu:
> So, now looking at:

 
> test_btfdiff    on /var/home/acme/.pahole_test_objects/x86-gcc/vmlinux ... FAIL


Minor stuff, why would BTF get that const and DWARF not?

⬢[acme@toolbox pahole]$ btfdiff /var/home/acme/.pahole_test_objects/x86-gcc/vmlinux
--- /tmp/btfdiff.dwarf.j8SZhr	2021-08-20 17:40:52.052186096 -0300
+++ /tmp/btfdiff.btf.5QMi8C	2021-08-20 17:40:52.298191569 -0300
@@ -33719,7 +33719,7 @@ struct e1000_option {

 			/* XXX 4 bytes hole, try to pack */

-			struct e1000_opt_list * p;       /*    40     8 */
+			const struct e1000_opt_list  * p; /*    40     8 */
 		} l;                                     /*    32    16 */
 	} arg;                                           /*    32    16 */

⬢[acme@toolbox pahole]$ btfdiff /var/home/acme/.pahole_test_objects/x86-clang/vmlinux
--- /tmp/btfdiff.dwarf.1TAWtj	2021-08-20 17:41:18.821781610 -0300
+++ /tmp/btfdiff.btf.FMLZRt	2021-08-20 17:41:19.058786883 -0300
@@ -21584,7 +21584,7 @@ struct cpu_rmap {
 	struct {
 		u16                index;                /*    16     2 */
 		u16                dist;                 /*    18     2 */
-	} near[0]; /*    16     0 */
+	} near[]; /*    16     0 */

 	/* size: 16, cachelines: 1, members: 5 */
 	/* last cacheline: 16 bytes */
@@ -65743,7 +65743,7 @@ struct linux_efi_memreserve {
 	struct {
 		phys_addr_t        base;                 /*    16     8 */
 		phys_addr_t        size;                 /*    24     8 */
-	} entry[0]; /*    16     0 */
+	} entry[]; /*    16     0 */

 	/* size: 16, cachelines: 1, members: 4 */
 	/* last cacheline: 16 bytes */
@@ -72814,7 +72814,7 @@ struct netlink_policy_dump_state {
 	struct {
 		const struct nla_policy  * policy;       /*    16     8 */
 		unsigned int       maxtype;              /*    24     4 */
-	} policies[0]; /*    16     0 */
+	} policies[]; /*    16     0 */

 	/* size: 16, cachelines: 1, members: 4 */
 	/* sum members: 12, holes: 1, sum holes: 4 */
⬢[acme@toolbox pahole]$o

I see, there are two declarations for this struct, one at:

drivers/net/ethernet/intel/e1000/e1000_param.c

166 struct e1000_option {
167         enum { enable_option, range_option, list_option } type;
168         const char *name;
169         const char *err;
170         int def;
171         union {
172                 struct { /* range_option info */
173                         int min;
174                         int max;
175                 } r;
176                 struct { /* list_option info */
177                         int nr;
178                         const struct e1000_opt_list { int i; char *str; } *p;
179                 } l;
180         } arg;
181 };

and the other at (note that extra 'e' after 1000 :) ):

drivers/net/ethernet/intel/e1000e/param.c

141 struct e1000_option {
142         enum { enable_option, range_option, list_option } type;
143         const char *name;
144         const char *err;
145         int def;
146         union {
147                 /* range_option info */
148                 struct {
149                         int min;
150                         int max;
151                 } r;
152                 /* list_option info */
153                 struct {
154                         int nr;
155                         struct e1000_opt_list {
156                                 int i;
157                                 char *str;
158                         } *p;
159                 } l;
160         } arg;
161 };

The only difference is that 'const'.

I _guess_ that the BTF deduplicator is picking the one with the 'const'
while pahole's (which is just used when pretty printing, not when BTF
encoding) with the other (it shouldn't as per my intention, I'm not
arguing about if both should appear as different types).

I tested it with:

  pahole -j -F dwarf -C e1000_option /var/home/acme/.pahole_test_objects/x86-gcc/vmlinux

to use the new DWARF multithreaded loading, like 'btfdiff' now does, and
its related to which of these types get loaded first, but its just
related to pahole pretty printing, not for the BTF encoding, where all
types will be passed to BTF for deduplication.

Same thing happens with clang, its just that when pretty printing in
this test run the clang multithreaded DWARF loading saw the type that
BTF picked (the one with 'const').

When I re-run it with:

⬢[acme@toolbox pahole]$ git diff
diff --git a/btfdiff b/btfdiff
index 77543630d1965b5e..71d3dbf5fc861e16 100755
--- a/btfdiff
+++ b/btfdiff
@@ -26,7 +26,6 @@ pahole_bin=${PAHOLE-"pahole"}
 ${pahole_bin} -F dwarf \
              --flat_arrays \
              --sort \
-             --jobs \
              --suppress_aligned_attribute \
              --suppress_force_paddings \
              --suppress_packed \
⬢[acme@toolbox pahole]$ git diff

I get:

test_btfdiff    on /var/home/acme/.pahole_test_objects/aarch64-clang/vmlinux ... OK
test_btfdiff    on /var/home/acme/.pahole_test_objects/x86-clang/vmlinux ... FAIL

clang's is just that zero entries array diff again.

I'll get 1.22 out of the door tomorrow as it passed these tests and also
the ones at libbpf github CI and my local ones and get these scripts merged
in 1.23, will check the clang output as well.

Thanks for the scripts!

- Arnaldo
diff mbox series

Patch

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 "$@"