diff mbox series

[bpf-next] selftests/bpf: merge most of test_btf into test_progs

Message ID 20200910011404.2519355-1-andriin@fb.com
State New
Headers show
Series [bpf-next] selftests/bpf: merge most of test_btf into test_progs | expand

Commit Message

Andrii Nakryiko Sept. 10, 2020, 1:14 a.m. UTC
Move almost 200 tests from test_btf into test_progs framework to be exercised
regularly. Pretty-printing tests were left alone in test_btf because they are
very slow and were not even executed by default with test_btf. Also, they seem
to break when moved under test_progs and I didn't want to spend more time on
figuring out why they broke, given we don't want to execute them all the time
anyway.

All the test_btf tests that were moved are modeled as proper sub-tests in
test_progs framework for ease of debugging and reporting.

No functional or behavioral changes were intended, I tried to preserve
original behavior as close to the original as possible. `test_progs -v` will
activate "always_log" flag to emit BTF validation log.

Signed-off-by: Andrii Nakryiko <andriin@fb.com>
---
 tools/testing/selftests/bpf/prog_tests/btf.c | 6124 ++++++++++++++
 tools/testing/selftests/bpf/test_btf.c       | 7442 ++----------------
 2 files changed, 6796 insertions(+), 6770 deletions(-)
 create mode 100644 tools/testing/selftests/bpf/prog_tests/btf.c

Comments

Alexei Starovoitov Sept. 15, 2020, 1:31 a.m. UTC | #1
On Wed, Sep 9, 2020 at 7:51 PM Andrii Nakryiko <andriin@fb.com> wrote:
>

> Move almost 200 tests from test_btf into test_progs framework to be exercised

> regularly. Pretty-printing tests were left alone in test_btf because they are

> very slow and were not even executed by default with test_btf. Also, they seem

> to break when moved under test_progs and I didn't want to spend more time on

> figuring out why they broke, given we don't want to execute them all the time

> anyway.

>

> All the test_btf tests that were moved are modeled as proper sub-tests in

> test_progs framework for ease of debugging and reporting.

>

> No functional or behavioral changes were intended, I tried to preserve

> original behavior as close to the original as possible. `test_progs -v` will

> activate "always_log" flag to emit BTF validation log.

>

> Signed-off-by: Andrii Nakryiko <andriin@fb.com>

> ---

>  tools/testing/selftests/bpf/prog_tests/btf.c | 6124 ++++++++++++++

>  tools/testing/selftests/bpf/test_btf.c       | 7442 ++----------------

>  2 files changed, 6796 insertions(+), 6770 deletions(-)


Thanks for consolidating, but it's impossible to realistically review such diff.
gmail web ui is super slow to even reply to such email.
Could you split it into 'git mv' patch and other patches?
The first move will break the selftests build, but I think that's ok.
I'd rather live with such bisecting issue than no review.
Also just noticed doing
./test_btf -p
BTF pretty print array(#0)......OK
BTF pretty print hash(#0)......[   83.134228] ------------[ cut here
]------------
[   83.134907] WARNING: CPU: 3 PID: 2006 at kernel/bpf/hashtab.c:717
htab_map_get_next_key+0x7fc/0xab0
[   83.135962] Modules linked in: bpf_preload
[   83.136403] CPU: 3 PID: 2006 Comm: test_btf Not tainted
5.9.0-rc1-00870-g2bab48c5bef0 #2930
[   83.137328] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996),
BIOS 1.11.0-2.el7 04/01/2014
[   83.138337] RIP: 0010:htab_map_get_next_key+0x7fc/0xab0
[   83.138947] Code: c0 45 31 e4 e9 0b ff ff ff 48 8b 7c 24 10 48 8d
70 30 89 ca e8 d5 8d 21 00 31 c0 48 83 c4 40 5b 5d 41 5c 41 5d 41 5e
41 5f c3 <0f> 0b e9 30 f8 ff ff 4c 8b 34 24 89 ca 41 89 dc 41 89 dd e9
70 fa
[   83.140997] RSP: 0018:ffff8881df5b7d30 EFLAGS: 00010246
[   83.141577] RAX: 0000000000000000 RBX: ffff8881eb537a98 RCX: 1ffff1103d6a6f58
[   83.142345] RDX: dffffc0000000000 RSI: ffffffff84b180a0 RDI: ffff8881f05008c8
[   83.143153] RBP: ffff8881e6cf8000 R08: 0000000000000000 R09: ffff8881e6cf8000
[   83.143953] R10: ffff8881e793405a R11: ffffed103cf2680b R12: ffff8881f1d96898
[   83.144739] R13: ffffffff83cdf8a0 R14: ffff8881eb537b78 R15: 000000000000005b
[   83.145571] FS:  00007ff4f1d0a700(0000) GS:ffff8881f6f80000(0000)
knlGS:0000000000000000
[   83.146433] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   83.147076] CR2: 0000000000436ef1 CR3: 00000001dfc8e001 CR4: 00000000003706e0
[   83.147842] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[   83.148679] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[   83.149474] Call Trace:
[   83.149779]  ? memcpy+0x39/0x60
[   83.150136]  map_seq_next+0x176/0x300
[   83.150571]  ? map_seq_show+0x150/0x220
[   83.151054]  seq_read+0x6ed/0xd70
[   83.151423]  vfs_read+0x150/0x4a0
[   83.151830]  ksys_read+0xe9/0x1b0
[   83.152196]  ? vfs_write+0x620/0x620
[   83.152644]  ? trace_hardirqs_on+0x20/0x170
[   83.153133]  do_syscall_64+0x2d/0x40
[   83.153542]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[   83.154110] RIP: 0033:0x7ff4f0dd7bf0
[   83.154498] Code: 0b 31 c0 48 83 c4 08 e9 ae fe ff ff 48 8d 3d 7f
ed 08 00 e8 02 d4 01 00 66 90 83 3d 59 5b 2c 00 00 75 10 b8 00 00 00
00 0f 05 <48> 3d 01 f0 ff ff 73 31 c3 48 83 ec 08 e8 ae 96 01 00 48 89
04 24
[   83.156514] RSP: 002b:00007fffb93aeee8 EFLAGS: 00000246 ORIG_RAX:
0000000000000000
[   83.157340] RAX: ffffffffffffffda RBX: 0000000000543040 RCX: 00007ff4f0dd7bf0
[   83.158155] RDX: 0000000000001000 RSI: 0000000000543520 RDI: 0000000000000005
[   83.158981] RBP: 0000000000543040 R08: 0000000000000003 R09: 0000000000001011
[   83.159757] R10: 0000000000000000 R11: 0000000000000246 R12: 00007fffb93aefd8
[   83.160538] R13: 0000000000000001 R14: 0000000000000000 R15: 0000000000000004
[   83.161323] irq event stamp: 3514803
[   83.161762] hardirqs last  enabled at (3514813):
[<ffffffff81275931>] console_unlock+0x611/0x9d0
[   83.162818] hardirqs last disabled at (3514822):
[<ffffffff81275400>] console_unlock+0xe0/0x9d0
[   83.163900] softirqs last  enabled at (3308060):
[<ffffffff83a005a3>] __do_softirq+0x5a3/0x883
[   83.164851] softirqs last disabled at (3308055):
[<ffffffff83800ebf>] asm_call_on_stack+0xf/0x20
[   83.165883] ---[ end trace 518a74dd5d67d50c ]---
OK
BTF pretty print lru hash(#0)......[   86.149427] perf: interrupt took
too long (2577 > 2500), lowering kernel.perf_event_max_sample_rate to
77000
OK
BTF pretty print percpu array(#0)......[   89.952685] perf: interrupt
took too long (3249 > 3221), lowering
kernel.perf_event_max_sample_rate to 61000
OK
BTF pretty print percpu hash(#0)......OK
BTF pretty print lru percpu hash(#0)......[  100.798017] perf:
interrupt took too long (4160 > 4061), lowering
kernel.perf_event_max_sample_rate to 48000
OK
BTF pretty print array(#1)......OK
BTF pretty print array(#2)......OK
BTF pretty print array(#3)......OK
PASS:9 SKIP:0 FAIL:0

They are slow, but they pass and clearly useful, since they caught above bug.
Andrii Nakryiko Sept. 15, 2020, 1:53 a.m. UTC | #2
On Mon, Sep 14, 2020 at 6:31 PM Alexei Starovoitov
<alexei.starovoitov@gmail.com> wrote:
>
> On Wed, Sep 9, 2020 at 7:51 PM Andrii Nakryiko <andriin@fb.com> wrote:
> >
> > Move almost 200 tests from test_btf into test_progs framework to be exercised
> > regularly. Pretty-printing tests were left alone in test_btf because they are
> > very slow and were not even executed by default with test_btf. Also, they seem
> > to break when moved under test_progs and I didn't want to spend more time on
> > figuring out why they broke, given we don't want to execute them all the time
> > anyway.
> >
> > All the test_btf tests that were moved are modeled as proper sub-tests in
> > test_progs framework for ease of debugging and reporting.
> >
> > No functional or behavioral changes were intended, I tried to preserve
> > original behavior as close to the original as possible. `test_progs -v` will
> > activate "always_log" flag to emit BTF validation log.
> >
> > Signed-off-by: Andrii Nakryiko <andriin@fb.com>
> > ---
> >  tools/testing/selftests/bpf/prog_tests/btf.c | 6124 ++++++++++++++
> >  tools/testing/selftests/bpf/test_btf.c       | 7442 ++----------------
> >  2 files changed, 6796 insertions(+), 6770 deletions(-)
>
> Thanks for consolidating, but it's impossible to realistically review such diff.
> gmail web ui is super slow to even reply to such email.
> Could you split it into 'git mv' patch and other patches?
> The first move will break the selftests build, but I think that's ok.
> I'd rather live with such bisecting issue than no review.

Didn't see your email, when I just sent v2. I renamed test_btf into
test_btf_pprint and GIT properly detected a rename. It's now += 1000
lines and Gmail seem to be handling reply quite well.



> Also just noticed doing
> ./test_btf -p
> BTF pretty print array(#0)......OK
> BTF pretty print hash(#0)......[   83.134228] ------------[ cut here
> ]------------
> [   83.134907] WARNING: CPU: 3 PID: 2006 at kernel/bpf/hashtab.c:717
> htab_map_get_next_key+0x7fc/0xab0
> [   83.135962] Modules linked in: bpf_preload
> [   83.136403] CPU: 3 PID: 2006 Comm: test_btf Not tainted
> 5.9.0-rc1-00870-g2bab48c5bef0 #2930
> [   83.137328] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996),
> BIOS 1.11.0-2.el7 04/01/2014
> [   83.138337] RIP: 0010:htab_map_get_next_key+0x7fc/0xab0
> [   83.138947] Code: c0 45 31 e4 e9 0b ff ff ff 48 8b 7c 24 10 48 8d
> 70 30 89 ca e8 d5 8d 21 00 31 c0 48 83 c4 40 5b 5d 41 5c 41 5d 41 5e
> 41 5f c3 <0f> 0b e9 30 f8 ff ff 4c 8b 34 24 89 ca 41 89 dc 41 89 dd e9
> 70 fa
> [   83.140997] RSP: 0018:ffff8881df5b7d30 EFLAGS: 00010246
> [   83.141577] RAX: 0000000000000000 RBX: ffff8881eb537a98 RCX: 1ffff1103d6a6f58
> [   83.142345] RDX: dffffc0000000000 RSI: ffffffff84b180a0 RDI: ffff8881f05008c8
> [   83.143153] RBP: ffff8881e6cf8000 R08: 0000000000000000 R09: ffff8881e6cf8000
> [   83.143953] R10: ffff8881e793405a R11: ffffed103cf2680b R12: ffff8881f1d96898
> [   83.144739] R13: ffffffff83cdf8a0 R14: ffff8881eb537b78 R15: 000000000000005b
> [   83.145571] FS:  00007ff4f1d0a700(0000) GS:ffff8881f6f80000(0000)
> knlGS:0000000000000000
> [   83.146433] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [   83.147076] CR2: 0000000000436ef1 CR3: 00000001dfc8e001 CR4: 00000000003706e0
> [   83.147842] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> [   83.148679] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
> [   83.149474] Call Trace:
> [   83.149779]  ? memcpy+0x39/0x60
> [   83.150136]  map_seq_next+0x176/0x300
> [   83.150571]  ? map_seq_show+0x150/0x220
> [   83.151054]  seq_read+0x6ed/0xd70
> [   83.151423]  vfs_read+0x150/0x4a0
> [   83.151830]  ksys_read+0xe9/0x1b0
> [   83.152196]  ? vfs_write+0x620/0x620
> [   83.152644]  ? trace_hardirqs_on+0x20/0x170
> [   83.153133]  do_syscall_64+0x2d/0x40
> [   83.153542]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
> [   83.154110] RIP: 0033:0x7ff4f0dd7bf0
> [   83.154498] Code: 0b 31 c0 48 83 c4 08 e9 ae fe ff ff 48 8d 3d 7f
> ed 08 00 e8 02 d4 01 00 66 90 83 3d 59 5b 2c 00 00 75 10 b8 00 00 00
> 00 0f 05 <48> 3d 01 f0 ff ff 73 31 c3 48 83 ec 08 e8 ae 96 01 00 48 89
> 04 24
> [   83.156514] RSP: 002b:00007fffb93aeee8 EFLAGS: 00000246 ORIG_RAX:
> 0000000000000000
> [   83.157340] RAX: ffffffffffffffda RBX: 0000000000543040 RCX: 00007ff4f0dd7bf0
> [   83.158155] RDX: 0000000000001000 RSI: 0000000000543520 RDI: 0000000000000005
> [   83.158981] RBP: 0000000000543040 R08: 0000000000000003 R09: 0000000000001011
> [   83.159757] R10: 0000000000000000 R11: 0000000000000246 R12: 00007fffb93aefd8
> [   83.160538] R13: 0000000000000001 R14: 0000000000000000 R15: 0000000000000004
> [   83.161323] irq event stamp: 3514803
> [   83.161762] hardirqs last  enabled at (3514813):
> [<ffffffff81275931>] console_unlock+0x611/0x9d0
> [   83.162818] hardirqs last disabled at (3514822):
> [<ffffffff81275400>] console_unlock+0xe0/0x9d0
> [   83.163900] softirqs last  enabled at (3308060):
> [<ffffffff83a005a3>] __do_softirq+0x5a3/0x883
> [   83.164851] softirqs last disabled at (3308055):
> [<ffffffff83800ebf>] asm_call_on_stack+0xf/0x20
> [   83.165883] ---[ end trace 518a74dd5d67d50c ]---
> OK
> BTF pretty print lru hash(#0)......[   86.149427] perf: interrupt took
> too long (2577 > 2500), lowering kernel.perf_event_max_sample_rate to
> 77000
> OK
> BTF pretty print percpu array(#0)......[   89.952685] perf: interrupt
> took too long (3249 > 3221), lowering
> kernel.perf_event_max_sample_rate to 61000
> OK
> BTF pretty print percpu hash(#0)......OK
> BTF pretty print lru percpu hash(#0)......[  100.798017] perf:
> interrupt took too long (4160 > 4061), lowering
> kernel.perf_event_max_sample_rate to 48000
> OK
> BTF pretty print array(#1)......OK
> BTF pretty print array(#2)......OK
> BTF pretty print array(#3)......OK
> PASS:9 SKIP:0 FAIL:0
>
> They are slow, but they pass and clearly useful, since they caught above bug.

So are you suggesting to move them into test_progs as well? They do
pass for me when run standalone, but when I initially converted them
into test_progs they started failing and the perspective of figuring
out why wasn't very exciting. But besides that, having guaranteed very
slow tests running all the time is really demotivating. I'm already
quite often tempted to skip bpf_verif_scale due to how long they run,
having another set of even slower tests is just depressing. Unless we
introduce a default fast test subset vs opt-in slow full test suite,
it's just detrimental to a development process, IMO:

$ time sudo ./test_btf_pprint
BTF pretty print array(#0)......OK
BTF pretty print hash(#0)......OK
BTF pretty print lru hash(#0)......OK
BTF pretty print percpu array(#0)......OK
BTF pretty print percpu hash(#0)......OK
BTF pretty print lru percpu hash(#0)......OK
BTF pretty print array(#1)......OK
BTF pretty print array(#2)......OK
BTF pretty print array(#3)......OK
PASS:9 SKIP:0 FAIL:0
sudo ./test_btf_pprint  26.21s user 47.69s system 99% cpu 1:13.92 total
diff mbox series

Patch

diff --git a/tools/testing/selftests/bpf/prog_tests/btf.c b/tools/testing/selftests/bpf/prog_tests/btf.c
new file mode 100644
index 000000000000..94719b692a1b
--- /dev/null
+++ b/tools/testing/selftests/bpf/prog_tests/btf.c
@@ -0,0 +1,6124 @@ 
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (c) 2018 Facebook */
+
+#include <linux/bpf.h>
+#include <linux/btf.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/filter.h>
+#include <linux/unistd.h>
+#include <bpf/bpf.h>
+#include <sys/resource.h>
+#include <libelf.h>
+#include <gelf.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <assert.h>
+#include <bpf/libbpf.h>
+#include <bpf/btf.h>
+
+#include "bpf_rlimit.h"
+#include "bpf_util.h"
+#include "../test_btf.h"
+#include "test_progs.h"
+
+#define MAX_INSNS	512
+#define MAX_SUBPROGS	16
+
+static int duration = 0;
+static bool always_log;
+
+#undef CHECK
+#define CHECK(condition, format...) _CHECK(condition, "check", duration, format)
+
+#define BTF_END_RAW 0xdeadbeef
+#define NAME_TBD 0xdeadb33f
+
+#define NAME_NTH(N) (0xffff0000 | N)
+#define IS_NAME_NTH(X) ((X & 0xffff0000) == 0xffff0000)
+#define GET_NAME_NTH_IDX(X) (X & 0x0000ffff)
+
+#define MAX_NR_RAW_U32 1024
+#define BTF_LOG_BUF_SIZE 65535
+
+static char btf_log_buf[BTF_LOG_BUF_SIZE];
+
+static struct btf_header hdr_tmpl = {
+	.magic = BTF_MAGIC,
+	.version = BTF_VERSION,
+	.hdr_len = sizeof(struct btf_header),
+};
+
+/* several different mapv kinds(types) supported by pprint */
+enum pprint_mapv_kind_t {
+	PPRINT_MAPV_KIND_BASIC = 0,
+	PPRINT_MAPV_KIND_INT128,
+};
+
+struct btf_raw_test {
+	const char *descr;
+	const char *str_sec;
+	const char *map_name;
+	const char *err_str;
+	__u32 raw_types[MAX_NR_RAW_U32];
+	__u32 str_sec_size;
+	enum bpf_map_type map_type;
+	__u32 key_size;
+	__u32 value_size;
+	__u32 key_type_id;
+	__u32 value_type_id;
+	__u32 max_entries;
+	bool btf_load_err;
+	bool map_create_err;
+	bool ordered_map;
+	bool lossless_map;
+	bool percpu_map;
+	int hdr_len_delta;
+	int type_off_delta;
+	int str_off_delta;
+	int str_len_delta;
+	enum pprint_mapv_kind_t mapv_kind;
+};
+
+#define BTF_STR_SEC(str) \
+	.str_sec = str, .str_sec_size = sizeof(str)
+
+static struct btf_raw_test raw_tests[] = {
+/* enum E {
+ *     E0,
+ *     E1,
+ * };
+ *
+ * struct A {
+ *	unsigned long long m;
+ *	int n;
+ *	char o;
+ *	[3 bytes hole]
+ *	int p[8];
+ *	int q[4][8];
+ *	enum E r;
+ * };
+ */
+{
+	.descr = "struct test #1",
+	.raw_types = {
+		/* int */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		/* unsigned long long */
+		BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),		/* [2] */
+		/* char */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),	/* [3] */
+		/* int[8] */
+		BTF_TYPE_ARRAY_ENC(1, 1, 8),			/* [4] */
+		/* struct A { */				/* [5] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 6), 180),
+		BTF_MEMBER_ENC(NAME_TBD, 2, 0),	/* unsigned long long m;*/
+		BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;		*/
+		BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;		*/
+		BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]		*/
+		BTF_MEMBER_ENC(NAME_TBD, 6, 384),/* int q[4][8]		*/
+		BTF_MEMBER_ENC(NAME_TBD, 7, 1408), /* enum E r		*/
+		/* } */
+		/* int[4][8] */
+		BTF_TYPE_ARRAY_ENC(4, 1, 4),			/* [6] */
+		/* enum E */					/* [7] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), sizeof(int)),
+		BTF_ENUM_ENC(NAME_TBD, 0),
+		BTF_ENUM_ENC(NAME_TBD, 1),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0A\0m\0n\0o\0p\0q\0r\0E\0E0\0E1",
+	.str_sec_size = sizeof("\0A\0m\0n\0o\0p\0q\0r\0E\0E0\0E1"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "struct_test1_map",
+	.key_size = sizeof(int),
+	.value_size = 180,
+	.key_type_id = 1,
+	.value_type_id = 5,
+	.max_entries = 4,
+},
+
+/* typedef struct b Struct_B;
+ *
+ * struct A {
+ *     int m;
+ *     struct b n[4];
+ *     const Struct_B o[4];
+ * };
+ *
+ * struct B {
+ *     int m;
+ *     int n;
+ * };
+ */
+{
+	.descr = "struct test #2",
+	.raw_types = {
+		/* int */					/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
+		/* struct b [4] */				/* [2] */
+		BTF_TYPE_ARRAY_ENC(4, 1, 4),
+
+		/* struct A { */				/* [3] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 3), 68),
+		BTF_MEMBER_ENC(NAME_TBD, 1, 0),	/* int m;		*/
+		BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* struct B n[4]	*/
+		BTF_MEMBER_ENC(NAME_TBD, 8, 288),/* const Struct_B o[4];*/
+		/* } */
+
+		/* struct B { */				/* [4] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
+		BTF_MEMBER_ENC(NAME_TBD, 1, 0),	/* int m; */
+		BTF_MEMBER_ENC(NAME_TBD, 1, 32),/* int n; */
+		/* } */
+
+		/* const int */					/* [5] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 1),
+		/* typedef struct b Struct_B */	/* [6] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_TYPEDEF, 0, 0), 4),
+		/* const Struct_B */				/* [7] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 6),
+		/* const Struct_B [4] */			/* [8] */
+		BTF_TYPE_ARRAY_ENC(7, 1, 4),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0A\0m\0n\0o\0B\0m\0n\0Struct_B",
+	.str_sec_size = sizeof("\0A\0m\0n\0o\0B\0m\0n\0Struct_B"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "struct_test2_map",
+	.key_size = sizeof(int),
+	.value_size = 68,
+	.key_type_id = 1,
+	.value_type_id = 3,
+	.max_entries = 4,
+},
+{
+	.descr = "struct test #3 Invalid member offset",
+	.raw_types = {
+		/* int */					/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
+		/* int64 */					/* [2] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 64, 8),
+
+		/* struct A { */				/* [3] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 16),
+		BTF_MEMBER_ENC(NAME_TBD, 1, 64),	/* int m;		*/
+		BTF_MEMBER_ENC(NAME_TBD, 2, 0),		/* int64 n; */
+		/* } */
+		BTF_END_RAW,
+	},
+	.str_sec = "\0A\0m\0n\0",
+	.str_sec_size = sizeof("\0A\0m\0n\0"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "struct_test3_map",
+	.key_size = sizeof(int),
+	.value_size = 16,
+	.key_type_id = 1,
+	.value_type_id = 3,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid member bits_offset",
+},
+/*
+ * struct A {
+ *	unsigned long long m;
+ *	int n;
+ *	char o;
+ *	[3 bytes hole]
+ *	int p[8];
+ * };
+ */
+{
+	.descr = "global data test #1",
+	.raw_types = {
+		/* int */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		/* unsigned long long */
+		BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),		/* [2] */
+		/* char */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),	/* [3] */
+		/* int[8] */
+		BTF_TYPE_ARRAY_ENC(1, 1, 8),			/* [4] */
+		/* struct A { */				/* [5] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
+		BTF_MEMBER_ENC(NAME_TBD, 2, 0),	/* unsigned long long m;*/
+		BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;		*/
+		BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;		*/
+		BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]		*/
+		/* } */
+		BTF_END_RAW,
+	},
+	.str_sec = "\0A\0m\0n\0o\0p",
+	.str_sec_size = sizeof("\0A\0m\0n\0o\0p"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "struct_test1_map",
+	.key_size = sizeof(int),
+	.value_size = 48,
+	.key_type_id = 1,
+	.value_type_id = 5,
+	.max_entries = 4,
+},
+/*
+ * struct A {
+ *	unsigned long long m;
+ *	int n;
+ *	char o;
+ *	[3 bytes hole]
+ *	int p[8];
+ * };
+ * static struct A t; <- in .bss
+ */
+{
+	.descr = "global data test #2",
+	.raw_types = {
+		/* int */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		/* unsigned long long */
+		BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),		/* [2] */
+		/* char */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),	/* [3] */
+		/* int[8] */
+		BTF_TYPE_ARRAY_ENC(1, 1, 8),			/* [4] */
+		/* struct A { */				/* [5] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
+		BTF_MEMBER_ENC(NAME_TBD, 2, 0),	/* unsigned long long m;*/
+		BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;		*/
+		BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;		*/
+		BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]		*/
+		/* } */
+		/* static struct A t */
+		BTF_VAR_ENC(NAME_TBD, 5, 0),			/* [6] */
+		/* .bss section */				/* [7] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 48),
+		BTF_VAR_SECINFO_ENC(6, 0, 48),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0A\0m\0n\0o\0p\0t\0.bss",
+	.str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0.bss"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = ".bss",
+	.key_size = sizeof(int),
+	.value_size = 48,
+	.key_type_id = 0,
+	.value_type_id = 7,
+	.max_entries = 1,
+},
+{
+	.descr = "global data test #3",
+	.raw_types = {
+		/* int */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		/* static int t */
+		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [2] */
+		/* .bss section */				/* [3] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
+		BTF_VAR_SECINFO_ENC(2, 0, 4),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0t\0.bss",
+	.str_sec_size = sizeof("\0t\0.bss"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = ".bss",
+	.key_size = sizeof(int),
+	.value_size = 4,
+	.key_type_id = 0,
+	.value_type_id = 3,
+	.max_entries = 1,
+},
+{
+	.descr = "global data test #4, unsupported linkage",
+	.raw_types = {
+		/* int */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		/* static int t */
+		BTF_VAR_ENC(NAME_TBD, 1, 2),			/* [2] */
+		/* .bss section */				/* [3] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
+		BTF_VAR_SECINFO_ENC(2, 0, 4),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0t\0.bss",
+	.str_sec_size = sizeof("\0t\0.bss"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = ".bss",
+	.key_size = sizeof(int),
+	.value_size = 4,
+	.key_type_id = 0,
+	.value_type_id = 3,
+	.max_entries = 1,
+	.btf_load_err = true,
+	.err_str = "Linkage not supported",
+},
+{
+	.descr = "global data test #5, invalid var type",
+	.raw_types = {
+		/* static void t */
+		BTF_VAR_ENC(NAME_TBD, 0, 0),			/* [1] */
+		/* .bss section */				/* [2] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
+		BTF_VAR_SECINFO_ENC(1, 0, 4),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0t\0.bss",
+	.str_sec_size = sizeof("\0t\0.bss"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = ".bss",
+	.key_size = sizeof(int),
+	.value_size = 4,
+	.key_type_id = 0,
+	.value_type_id = 2,
+	.max_entries = 1,
+	.btf_load_err = true,
+	.err_str = "Invalid type_id",
+},
+{
+	.descr = "global data test #6, invalid var type (fwd type)",
+	.raw_types = {
+		/* union A */
+		BTF_TYPE_ENC(NAME_TBD,
+			     BTF_INFO_ENC(BTF_KIND_FWD, 1, 0), 0), /* [1] */
+		/* static union A t */
+		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [2] */
+		/* .bss section */				/* [3] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
+		BTF_VAR_SECINFO_ENC(2, 0, 4),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0A\0t\0.bss",
+	.str_sec_size = sizeof("\0A\0t\0.bss"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = ".bss",
+	.key_size = sizeof(int),
+	.value_size = 4,
+	.key_type_id = 0,
+	.value_type_id = 2,
+	.max_entries = 1,
+	.btf_load_err = true,
+	.err_str = "Invalid type",
+},
+{
+	.descr = "global data test #7, invalid var type (fwd type)",
+	.raw_types = {
+		/* union A */
+		BTF_TYPE_ENC(NAME_TBD,
+			     BTF_INFO_ENC(BTF_KIND_FWD, 1, 0), 0), /* [1] */
+		/* static union A t */
+		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [2] */
+		/* .bss section */				/* [3] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
+		BTF_VAR_SECINFO_ENC(1, 0, 4),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0A\0t\0.bss",
+	.str_sec_size = sizeof("\0A\0t\0.bss"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = ".bss",
+	.key_size = sizeof(int),
+	.value_size = 4,
+	.key_type_id = 0,
+	.value_type_id = 2,
+	.max_entries = 1,
+	.btf_load_err = true,
+	.err_str = "Invalid type",
+},
+{
+	.descr = "global data test #8, invalid var size",
+	.raw_types = {
+		/* int */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		/* unsigned long long */
+		BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),		/* [2] */
+		/* char */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),	/* [3] */
+		/* int[8] */
+		BTF_TYPE_ARRAY_ENC(1, 1, 8),			/* [4] */
+		/* struct A { */				/* [5] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
+		BTF_MEMBER_ENC(NAME_TBD, 2, 0),	/* unsigned long long m;*/
+		BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;		*/
+		BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;		*/
+		BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]		*/
+		/* } */
+		/* static struct A t */
+		BTF_VAR_ENC(NAME_TBD, 5, 0),			/* [6] */
+		/* .bss section */				/* [7] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 48),
+		BTF_VAR_SECINFO_ENC(6, 0, 47),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0A\0m\0n\0o\0p\0t\0.bss",
+	.str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0.bss"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = ".bss",
+	.key_size = sizeof(int),
+	.value_size = 48,
+	.key_type_id = 0,
+	.value_type_id = 7,
+	.max_entries = 1,
+	.btf_load_err = true,
+	.err_str = "Invalid size",
+},
+{
+	.descr = "global data test #9, invalid var size",
+	.raw_types = {
+		/* int */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		/* unsigned long long */
+		BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),		/* [2] */
+		/* char */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),	/* [3] */
+		/* int[8] */
+		BTF_TYPE_ARRAY_ENC(1, 1, 8),			/* [4] */
+		/* struct A { */				/* [5] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
+		BTF_MEMBER_ENC(NAME_TBD, 2, 0),	/* unsigned long long m;*/
+		BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;		*/
+		BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;		*/
+		BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]		*/
+		/* } */
+		/* static struct A t */
+		BTF_VAR_ENC(NAME_TBD, 5, 0),			/* [6] */
+		/* .bss section */				/* [7] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 46),
+		BTF_VAR_SECINFO_ENC(6, 0, 48),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0A\0m\0n\0o\0p\0t\0.bss",
+	.str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0.bss"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = ".bss",
+	.key_size = sizeof(int),
+	.value_size = 48,
+	.key_type_id = 0,
+	.value_type_id = 7,
+	.max_entries = 1,
+	.btf_load_err = true,
+	.err_str = "Invalid size",
+},
+{
+	.descr = "global data test #10, invalid var size",
+	.raw_types = {
+		/* int */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		/* unsigned long long */
+		BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),		/* [2] */
+		/* char */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),	/* [3] */
+		/* int[8] */
+		BTF_TYPE_ARRAY_ENC(1, 1, 8),			/* [4] */
+		/* struct A { */				/* [5] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
+		BTF_MEMBER_ENC(NAME_TBD, 2, 0),	/* unsigned long long m;*/
+		BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;		*/
+		BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;		*/
+		BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]		*/
+		/* } */
+		/* static struct A t */
+		BTF_VAR_ENC(NAME_TBD, 5, 0),			/* [6] */
+		/* .bss section */				/* [7] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 46),
+		BTF_VAR_SECINFO_ENC(6, 0, 46),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0A\0m\0n\0o\0p\0t\0.bss",
+	.str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0.bss"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = ".bss",
+	.key_size = sizeof(int),
+	.value_size = 48,
+	.key_type_id = 0,
+	.value_type_id = 7,
+	.max_entries = 1,
+	.btf_load_err = true,
+	.err_str = "Invalid size",
+},
+{
+	.descr = "global data test #11, multiple section members",
+	.raw_types = {
+		/* int */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		/* unsigned long long */
+		BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),		/* [2] */
+		/* char */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),	/* [3] */
+		/* int[8] */
+		BTF_TYPE_ARRAY_ENC(1, 1, 8),			/* [4] */
+		/* struct A { */				/* [5] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
+		BTF_MEMBER_ENC(NAME_TBD, 2, 0),	/* unsigned long long m;*/
+		BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;		*/
+		BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;		*/
+		BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]		*/
+		/* } */
+		/* static struct A t */
+		BTF_VAR_ENC(NAME_TBD, 5, 0),			/* [6] */
+		/* static int u */
+		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [7] */
+		/* .bss section */				/* [8] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 2), 62),
+		BTF_VAR_SECINFO_ENC(6, 10, 48),
+		BTF_VAR_SECINFO_ENC(7, 58, 4),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0A\0m\0n\0o\0p\0t\0u\0.bss",
+	.str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0u\0.bss"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = ".bss",
+	.key_size = sizeof(int),
+	.value_size = 62,
+	.key_type_id = 0,
+	.value_type_id = 8,
+	.max_entries = 1,
+},
+{
+	.descr = "global data test #12, invalid offset",
+	.raw_types = {
+		/* int */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		/* unsigned long long */
+		BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),		/* [2] */
+		/* char */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),	/* [3] */
+		/* int[8] */
+		BTF_TYPE_ARRAY_ENC(1, 1, 8),			/* [4] */
+		/* struct A { */				/* [5] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
+		BTF_MEMBER_ENC(NAME_TBD, 2, 0),	/* unsigned long long m;*/
+		BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;		*/
+		BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;		*/
+		BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]		*/
+		/* } */
+		/* static struct A t */
+		BTF_VAR_ENC(NAME_TBD, 5, 0),			/* [6] */
+		/* static int u */
+		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [7] */
+		/* .bss section */				/* [8] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 2), 62),
+		BTF_VAR_SECINFO_ENC(6, 10, 48),
+		BTF_VAR_SECINFO_ENC(7, 60, 4),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0A\0m\0n\0o\0p\0t\0u\0.bss",
+	.str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0u\0.bss"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = ".bss",
+	.key_size = sizeof(int),
+	.value_size = 62,
+	.key_type_id = 0,
+	.value_type_id = 8,
+	.max_entries = 1,
+	.btf_load_err = true,
+	.err_str = "Invalid offset+size",
+},
+{
+	.descr = "global data test #13, invalid offset",
+	.raw_types = {
+		/* int */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		/* unsigned long long */
+		BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),		/* [2] */
+		/* char */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),	/* [3] */
+		/* int[8] */
+		BTF_TYPE_ARRAY_ENC(1, 1, 8),			/* [4] */
+		/* struct A { */				/* [5] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
+		BTF_MEMBER_ENC(NAME_TBD, 2, 0),	/* unsigned long long m;*/
+		BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;		*/
+		BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;		*/
+		BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]		*/
+		/* } */
+		/* static struct A t */
+		BTF_VAR_ENC(NAME_TBD, 5, 0),			/* [6] */
+		/* static int u */
+		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [7] */
+		/* .bss section */				/* [8] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 2), 62),
+		BTF_VAR_SECINFO_ENC(6, 10, 48),
+		BTF_VAR_SECINFO_ENC(7, 12, 4),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0A\0m\0n\0o\0p\0t\0u\0.bss",
+	.str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0u\0.bss"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = ".bss",
+	.key_size = sizeof(int),
+	.value_size = 62,
+	.key_type_id = 0,
+	.value_type_id = 8,
+	.max_entries = 1,
+	.btf_load_err = true,
+	.err_str = "Invalid offset",
+},
+{
+	.descr = "global data test #14, invalid offset",
+	.raw_types = {
+		/* int */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		/* unsigned long long */
+		BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),		/* [2] */
+		/* char */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),	/* [3] */
+		/* int[8] */
+		BTF_TYPE_ARRAY_ENC(1, 1, 8),			/* [4] */
+		/* struct A { */				/* [5] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
+		BTF_MEMBER_ENC(NAME_TBD, 2, 0),	/* unsigned long long m;*/
+		BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;		*/
+		BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;		*/
+		BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]		*/
+		/* } */
+		/* static struct A t */
+		BTF_VAR_ENC(NAME_TBD, 5, 0),			/* [6] */
+		/* static int u */
+		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [7] */
+		/* .bss section */				/* [8] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 2), 62),
+		BTF_VAR_SECINFO_ENC(7, 58, 4),
+		BTF_VAR_SECINFO_ENC(6, 10, 48),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0A\0m\0n\0o\0p\0t\0u\0.bss",
+	.str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0u\0.bss"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = ".bss",
+	.key_size = sizeof(int),
+	.value_size = 62,
+	.key_type_id = 0,
+	.value_type_id = 8,
+	.max_entries = 1,
+	.btf_load_err = true,
+	.err_str = "Invalid offset",
+},
+{
+	.descr = "global data test #15, not var kind",
+	.raw_types = {
+		/* int */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [2] */
+		/* .bss section */				/* [3] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
+		BTF_VAR_SECINFO_ENC(1, 0, 4),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0A\0t\0.bss",
+	.str_sec_size = sizeof("\0A\0t\0.bss"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = ".bss",
+	.key_size = sizeof(int),
+	.value_size = 4,
+	.key_type_id = 0,
+	.value_type_id = 3,
+	.max_entries = 1,
+	.btf_load_err = true,
+	.err_str = "Not a VAR kind member",
+},
+{
+	.descr = "global data test #16, invalid var referencing sec",
+	.raw_types = {
+		/* int */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_VAR_ENC(NAME_TBD, 5, 0),			/* [2] */
+		BTF_VAR_ENC(NAME_TBD, 2, 0),			/* [3] */
+		/* a section */					/* [4] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
+		BTF_VAR_SECINFO_ENC(3, 0, 4),
+		/* a section */					/* [5] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
+		BTF_VAR_SECINFO_ENC(6, 0, 4),
+		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [6] */
+		BTF_END_RAW,
+	},
+	.str_sec = "\0A\0t\0s\0a\0a",
+	.str_sec_size = sizeof("\0A\0t\0s\0a\0a"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = ".bss",
+	.key_size = sizeof(int),
+	.value_size = 4,
+	.key_type_id = 0,
+	.value_type_id = 4,
+	.max_entries = 1,
+	.btf_load_err = true,
+	.err_str = "Invalid type_id",
+},
+{
+	.descr = "global data test #17, invalid var referencing var",
+	.raw_types = {
+		/* int */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [2] */
+		BTF_VAR_ENC(NAME_TBD, 2, 0),			/* [3] */
+		/* a section */					/* [4] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
+		BTF_VAR_SECINFO_ENC(3, 0, 4),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0A\0t\0s\0a\0a",
+	.str_sec_size = sizeof("\0A\0t\0s\0a\0a"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = ".bss",
+	.key_size = sizeof(int),
+	.value_size = 4,
+	.key_type_id = 0,
+	.value_type_id = 4,
+	.max_entries = 1,
+	.btf_load_err = true,
+	.err_str = "Invalid type_id",
+},
+{
+	.descr = "global data test #18, invalid var loop",
+	.raw_types = {
+		/* int */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_VAR_ENC(NAME_TBD, 2, 0),			/* [2] */
+		/* .bss section */				/* [3] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
+		BTF_VAR_SECINFO_ENC(2, 0, 4),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0A\0t\0aaa",
+	.str_sec_size = sizeof("\0A\0t\0aaa"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = ".bss",
+	.key_size = sizeof(int),
+	.value_size = 4,
+	.key_type_id = 0,
+	.value_type_id = 4,
+	.max_entries = 1,
+	.btf_load_err = true,
+	.err_str = "Invalid type_id",
+},
+{
+	.descr = "global data test #19, invalid var referencing var",
+	.raw_types = {
+		/* int */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_VAR_ENC(NAME_TBD, 3, 0),			/* [2] */
+		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [3] */
+		BTF_END_RAW,
+	},
+	.str_sec = "\0A\0t\0s\0a\0a",
+	.str_sec_size = sizeof("\0A\0t\0s\0a\0a"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = ".bss",
+	.key_size = sizeof(int),
+	.value_size = 4,
+	.key_type_id = 0,
+	.value_type_id = 4,
+	.max_entries = 1,
+	.btf_load_err = true,
+	.err_str = "Invalid type_id",
+},
+{
+	.descr = "global data test #20, invalid ptr referencing var",
+	.raw_types = {
+		/* int */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		/* PTR type_id=3	*/			/* [2] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 3),
+		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [3] */
+		BTF_END_RAW,
+	},
+	.str_sec = "\0A\0t\0s\0a\0a",
+	.str_sec_size = sizeof("\0A\0t\0s\0a\0a"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = ".bss",
+	.key_size = sizeof(int),
+	.value_size = 4,
+	.key_type_id = 0,
+	.value_type_id = 4,
+	.max_entries = 1,
+	.btf_load_err = true,
+	.err_str = "Invalid type_id",
+},
+{
+	.descr = "global data test #21, var included in struct",
+	.raw_types = {
+		/* int */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		/* struct A { */				/* [2] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 2),
+		BTF_MEMBER_ENC(NAME_TBD, 1, 0),	/* int m; */
+		BTF_MEMBER_ENC(NAME_TBD, 3, 32),/* VAR type_id=3; */
+		/* } */
+		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [3] */
+		BTF_END_RAW,
+	},
+	.str_sec = "\0A\0t\0s\0a\0a",
+	.str_sec_size = sizeof("\0A\0t\0s\0a\0a"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = ".bss",
+	.key_size = sizeof(int),
+	.value_size = 4,
+	.key_type_id = 0,
+	.value_type_id = 4,
+	.max_entries = 1,
+	.btf_load_err = true,
+	.err_str = "Invalid member",
+},
+{
+	.descr = "global data test #22, array of var",
+	.raw_types = {
+		/* int */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_TYPE_ARRAY_ENC(3, 1, 4),			/* [2] */
+		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [3] */
+		BTF_END_RAW,
+	},
+	.str_sec = "\0A\0t\0s\0a\0a",
+	.str_sec_size = sizeof("\0A\0t\0s\0a\0a"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = ".bss",
+	.key_size = sizeof(int),
+	.value_size = 4,
+	.key_type_id = 0,
+	.value_type_id = 4,
+	.max_entries = 1,
+	.btf_load_err = true,
+	.err_str = "Invalid elem",
+},
+/* Test member exceeds the size of struct.
+ *
+ * struct A {
+ *     int m;
+ *     int n;
+ * };
+ */
+{
+	.descr = "size check test #1",
+	.raw_types = {
+		/* int */					/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
+		/* struct A { */				/* [2] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 2 -  1),
+		BTF_MEMBER_ENC(NAME_TBD, 1, 0),	/* int m; */
+		BTF_MEMBER_ENC(NAME_TBD, 1, 32),/* int n; */
+		/* } */
+		BTF_END_RAW,
+	},
+	.str_sec = "\0A\0m\0n",
+	.str_sec_size = sizeof("\0A\0m\0n"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "size_check1_map",
+	.key_size = sizeof(int),
+	.value_size = 1,
+	.key_type_id = 1,
+	.value_type_id = 2,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Member exceeds struct_size",
+},
+
+/* Test member exeeds the size of struct
+ *
+ * struct A {
+ *     int m;
+ *     int n[2];
+ * };
+ */
+{
+	.descr = "size check test #2",
+	.raw_types = {
+		/* int */					/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)),
+		/* int[2] */					/* [2] */
+		BTF_TYPE_ARRAY_ENC(1, 1, 2),
+		/* struct A { */				/* [3] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 3 - 1),
+		BTF_MEMBER_ENC(NAME_TBD, 1, 0),	/* int m; */
+		BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* int n[2]; */
+		/* } */
+		BTF_END_RAW,
+	},
+	.str_sec = "\0A\0m\0n",
+	.str_sec_size = sizeof("\0A\0m\0n"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "size_check2_map",
+	.key_size = sizeof(int),
+	.value_size = 1,
+	.key_type_id = 1,
+	.value_type_id = 3,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Member exceeds struct_size",
+},
+
+/* Test member exeeds the size of struct
+ *
+ * struct A {
+ *     int m;
+ *     void *n;
+ * };
+ */
+{
+	.descr = "size check test #3",
+	.raw_types = {
+		/* int */					/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)),
+		/* void* */					/* [2] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0),
+		/* struct A { */				/* [3] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) + sizeof(void *) - 1),
+		BTF_MEMBER_ENC(NAME_TBD, 1, 0),	/* int m; */
+		BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* void *n; */
+		/* } */
+		BTF_END_RAW,
+	},
+	.str_sec = "\0A\0m\0n",
+	.str_sec_size = sizeof("\0A\0m\0n"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "size_check3_map",
+	.key_size = sizeof(int),
+	.value_size = 1,
+	.key_type_id = 1,
+	.value_type_id = 3,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Member exceeds struct_size",
+},
+
+/* Test member exceeds the size of struct
+ *
+ * enum E {
+ *     E0,
+ *     E1,
+ * };
+ *
+ * struct A {
+ *     int m;
+ *     enum E n;
+ * };
+ */
+{
+	.descr = "size check test #4",
+	.raw_types = {
+		/* int */			/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)),
+		/* enum E { */			/* [2] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), sizeof(int)),
+		BTF_ENUM_ENC(NAME_TBD, 0),
+		BTF_ENUM_ENC(NAME_TBD, 1),
+		/* } */
+		/* struct A { */		/* [3] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 2 - 1),
+		BTF_MEMBER_ENC(NAME_TBD, 1, 0),	/* int m; */
+		BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* enum E n; */
+		/* } */
+		BTF_END_RAW,
+	},
+	.str_sec = "\0E\0E0\0E1\0A\0m\0n",
+	.str_sec_size = sizeof("\0E\0E0\0E1\0A\0m\0n"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "size_check4_map",
+	.key_size = sizeof(int),
+	.value_size = 1,
+	.key_type_id = 1,
+	.value_type_id = 3,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Member exceeds struct_size",
+},
+
+/* Test member unexceeds the size of struct
+ *
+ * enum E {
+ *     E0,
+ *     E1,
+ * };
+ *
+ * struct A {
+ *     char m;
+ *     enum E __attribute__((packed)) n;
+ * };
+ */
+{
+	.descr = "size check test #5",
+	.raw_types = {
+		/* int */			/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)),
+		/* char */			/* [2] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),
+		/* enum E { */			/* [3] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), 1),
+		BTF_ENUM_ENC(NAME_TBD, 0),
+		BTF_ENUM_ENC(NAME_TBD, 1),
+		/* } */
+		/* struct A { */		/* [4] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 2),
+		BTF_MEMBER_ENC(NAME_TBD, 2, 0),	/* char m; */
+		BTF_MEMBER_ENC(NAME_TBD, 3, 8),/* enum E __attribute__((packed)) n; */
+		/* } */
+		BTF_END_RAW,
+	},
+	.str_sec = "\0E\0E0\0E1\0A\0m\0n",
+	.str_sec_size = sizeof("\0E\0E0\0E1\0A\0m\0n"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "size_check5_map",
+	.key_size = sizeof(int),
+	.value_size = 2,
+	.key_type_id = 1,
+	.value_type_id = 4,
+	.max_entries = 4,
+},
+
+/* typedef const void * const_void_ptr;
+ * struct A {
+ *	const_void_ptr m;
+ * };
+ */
+{
+	.descr = "void test #1",
+	.raw_types = {
+		/* int */		/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
+		/* const void */	/* [2] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
+		/* const void* */	/* [3] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 2),
+		/* typedef const void * const_void_ptr */
+		BTF_TYPEDEF_ENC(NAME_TBD, 3),	/* [4] */
+		/* struct A { */	/* [5] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
+		/* const_void_ptr m; */
+		BTF_MEMBER_ENC(NAME_TBD, 4, 0),
+		/* } */
+		BTF_END_RAW,
+	},
+	.str_sec = "\0const_void_ptr\0A\0m",
+	.str_sec_size = sizeof("\0const_void_ptr\0A\0m"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "void_test1_map",
+	.key_size = sizeof(int),
+	.value_size = sizeof(void *),
+	.key_type_id = 1,
+	.value_type_id = 4,
+	.max_entries = 4,
+},
+
+/* struct A {
+ *     const void m;
+ * };
+ */
+{
+	.descr = "void test #2",
+	.raw_types = {
+		/* int */		/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
+		/* const void */	/* [2] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
+		/* struct A { */	/* [3] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 8),
+		/* const void m; */
+		BTF_MEMBER_ENC(NAME_TBD, 2, 0),
+		/* } */
+		BTF_END_RAW,
+	},
+	.str_sec = "\0A\0m",
+	.str_sec_size = sizeof("\0A\0m"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "void_test2_map",
+	.key_size = sizeof(int),
+	.value_size = sizeof(void *),
+	.key_type_id = 1,
+	.value_type_id = 3,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid member",
+},
+
+/* typedef const void * const_void_ptr;
+ * const_void_ptr[4]
+ */
+{
+	.descr = "void test #3",
+	.raw_types = {
+		/* int */		/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
+		/* const void */	/* [2] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
+		/* const void* */	/* [3] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 2),
+		/* typedef const void * const_void_ptr */
+		BTF_TYPEDEF_ENC(NAME_TBD, 3),	/* [4] */
+		/* const_void_ptr[4] */
+		BTF_TYPE_ARRAY_ENC(4, 1, 4),	/* [5] */
+		BTF_END_RAW,
+	},
+	.str_sec = "\0const_void_ptr",
+	.str_sec_size = sizeof("\0const_void_ptr"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "void_test3_map",
+	.key_size = sizeof(int),
+	.value_size = sizeof(void *) * 4,
+	.key_type_id = 1,
+	.value_type_id = 5,
+	.max_entries = 4,
+},
+
+/* const void[4]  */
+{
+	.descr = "void test #4",
+	.raw_types = {
+		/* int */		/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
+		/* const void */	/* [2] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
+		/* const void[4] */	/* [3] */
+		BTF_TYPE_ARRAY_ENC(2, 1, 4),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0A\0m",
+	.str_sec_size = sizeof("\0A\0m"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "void_test4_map",
+	.key_size = sizeof(int),
+	.value_size = sizeof(void *) * 4,
+	.key_type_id = 1,
+	.value_type_id = 3,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid elem",
+},
+
+/* Array_A  <------------------+
+ *     elem_type == Array_B    |
+ *                    |        |
+ *                    |        |
+ * Array_B  <-------- +        |
+ *      elem_type == Array A --+
+ */
+{
+	.descr = "loop test #1",
+	.raw_types = {
+		/* int */			/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
+		/* Array_A */			/* [2] */
+		BTF_TYPE_ARRAY_ENC(3, 1, 8),
+		/* Array_B */			/* [3] */
+		BTF_TYPE_ARRAY_ENC(2, 1, 8),
+		BTF_END_RAW,
+	},
+	.str_sec = "",
+	.str_sec_size = sizeof(""),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "loop_test1_map",
+	.key_size = sizeof(int),
+	.value_size = sizeof(sizeof(int) * 8),
+	.key_type_id = 1,
+	.value_type_id = 2,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Loop detected",
+},
+
+/* typedef is _before_ the BTF type of Array_A and Array_B
+ *
+ * typedef Array_B int_array;
+ *
+ * Array_A  <------------------+
+ *     elem_type == int_array  |
+ *                    |        |
+ *                    |        |
+ * Array_B  <-------- +        |
+ *      elem_type == Array_A --+
+ */
+{
+	.descr = "loop test #2",
+	.raw_types = {
+		/* int */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		/* typedef Array_B int_array */
+		BTF_TYPEDEF_ENC(1, 4),				/* [2] */
+		/* Array_A */
+		BTF_TYPE_ARRAY_ENC(2, 1, 8),			/* [3] */
+		/* Array_B */
+		BTF_TYPE_ARRAY_ENC(3, 1, 8),			/* [4] */
+		BTF_END_RAW,
+	},
+	.str_sec = "\0int_array\0",
+	.str_sec_size = sizeof("\0int_array"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "loop_test2_map",
+	.key_size = sizeof(int),
+	.value_size = sizeof(sizeof(int) * 8),
+	.key_type_id = 1,
+	.value_type_id = 2,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Loop detected",
+},
+
+/* Array_A  <------------------+
+ *     elem_type == Array_B    |
+ *                    |        |
+ *                    |        |
+ * Array_B  <-------- +        |
+ *      elem_type == Array_A --+
+ */
+{
+	.descr = "loop test #3",
+	.raw_types = {
+		/* int */				/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
+		/* Array_A */				/* [2] */
+		BTF_TYPE_ARRAY_ENC(3, 1, 8),
+		/* Array_B */				/* [3] */
+		BTF_TYPE_ARRAY_ENC(2, 1, 8),
+		BTF_END_RAW,
+	},
+	.str_sec = "",
+	.str_sec_size = sizeof(""),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "loop_test3_map",
+	.key_size = sizeof(int),
+	.value_size = sizeof(sizeof(int) * 8),
+	.key_type_id = 1,
+	.value_type_id = 2,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Loop detected",
+},
+
+/* typedef is _between_ the BTF type of Array_A and Array_B
+ *
+ * typedef Array_B int_array;
+ *
+ * Array_A  <------------------+
+ *     elem_type == int_array  |
+ *                    |        |
+ *                    |        |
+ * Array_B  <-------- +        |
+ *      elem_type == Array_A --+
+ */
+{
+	.descr = "loop test #4",
+	.raw_types = {
+		/* int */				/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
+		/* Array_A */				/* [2] */
+		BTF_TYPE_ARRAY_ENC(3, 1, 8),
+		/* typedef Array_B int_array */		/* [3] */
+		BTF_TYPEDEF_ENC(NAME_TBD, 4),
+		/* Array_B */				/* [4] */
+		BTF_TYPE_ARRAY_ENC(2, 1, 8),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0int_array\0",
+	.str_sec_size = sizeof("\0int_array"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "loop_test4_map",
+	.key_size = sizeof(int),
+	.value_size = sizeof(sizeof(int) * 8),
+	.key_type_id = 1,
+	.value_type_id = 2,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Loop detected",
+},
+
+/* typedef struct B Struct_B
+ *
+ * struct A {
+ *     int x;
+ *     Struct_B y;
+ * };
+ *
+ * struct B {
+ *     int x;
+ *     struct A y;
+ * };
+ */
+{
+	.descr = "loop test #5",
+	.raw_types = {
+		/* int */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		/* struct A */					/* [2] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
+		BTF_MEMBER_ENC(NAME_TBD, 1, 0),	/* int x;	*/
+		BTF_MEMBER_ENC(NAME_TBD, 3, 32),/* Struct_B y;	*/
+		/* typedef struct B Struct_B */
+		BTF_TYPEDEF_ENC(NAME_TBD, 4),			/* [3] */
+		/* struct B */					/* [4] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
+		BTF_MEMBER_ENC(NAME_TBD, 1, 0),	/* int x;	*/
+		BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* struct A y;	*/
+		BTF_END_RAW,
+	},
+	.str_sec = "\0A\0x\0y\0Struct_B\0B\0x\0y",
+	.str_sec_size = sizeof("\0A\0x\0y\0Struct_B\0B\0x\0y"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "loop_test5_map",
+	.key_size = sizeof(int),
+	.value_size = 8,
+	.key_type_id = 1,
+	.value_type_id = 2,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Loop detected",
+},
+
+/* struct A {
+ *     int x;
+ *     struct A array_a[4];
+ * };
+ */
+{
+	.descr = "loop test #6",
+	.raw_types = {
+		/* int */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_TYPE_ARRAY_ENC(3, 1, 4),			/* [2] */
+		/* struct A */					/* [3] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
+		BTF_MEMBER_ENC(NAME_TBD, 1, 0),	/* int x;		*/
+		BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* struct A array_a[4];	*/
+		BTF_END_RAW,
+	},
+	.str_sec = "\0A\0x\0y",
+	.str_sec_size = sizeof("\0A\0x\0y"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "loop_test6_map",
+	.key_size = sizeof(int),
+	.value_size = 8,
+	.key_type_id = 1,
+	.value_type_id = 2,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Loop detected",
+},
+
+{
+	.descr = "loop test #7",
+	.raw_types = {
+		/* int */				/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
+		/* struct A { */			/* [2] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
+		/*     const void *m;	*/
+		BTF_MEMBER_ENC(NAME_TBD, 3, 0),
+		/* CONST type_id=3	*/		/* [3] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 4),
+		/* PTR type_id=2	*/		/* [4] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 3),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0A\0m",
+	.str_sec_size = sizeof("\0A\0m"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "loop_test7_map",
+	.key_size = sizeof(int),
+	.value_size = sizeof(void *),
+	.key_type_id = 1,
+	.value_type_id = 2,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Loop detected",
+},
+
+{
+	.descr = "loop test #8",
+	.raw_types = {
+		/* int */				/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
+		/* struct A { */			/* [2] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
+		/*     const void *m;	*/
+		BTF_MEMBER_ENC(NAME_TBD, 4, 0),
+		/* struct B { */			/* [3] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
+		/*     const void *n;	*/
+		BTF_MEMBER_ENC(NAME_TBD, 6, 0),
+		/* CONST type_id=5	*/		/* [4] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 5),
+		/* PTR type_id=6	*/		/* [5] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 6),
+		/* CONST type_id=7	*/		/* [6] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 7),
+		/* PTR type_id=4	*/		/* [7] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 4),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0A\0m\0B\0n",
+	.str_sec_size = sizeof("\0A\0m\0B\0n"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "loop_test8_map",
+	.key_size = sizeof(int),
+	.value_size = sizeof(void *),
+	.key_type_id = 1,
+	.value_type_id = 2,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Loop detected",
+},
+
+{
+	.descr = "string section does not end with null",
+	.raw_types = {
+		/* int */				/* [1] */
+		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0int",
+	.str_sec_size = sizeof("\0int") - 1,
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "hdr_test_map",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid string section",
+},
+
+{
+	.descr = "empty string section",
+	.raw_types = {
+		/* int */				/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
+		BTF_END_RAW,
+	},
+	.str_sec = "",
+	.str_sec_size = 0,
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "hdr_test_map",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid string section",
+},
+
+{
+	.descr = "empty type section",
+	.raw_types = {
+		BTF_END_RAW,
+	},
+	.str_sec = "\0int",
+	.str_sec_size = sizeof("\0int"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "hdr_test_map",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "No type found",
+},
+
+{
+	.descr = "btf_header test. Longer hdr_len",
+	.raw_types = {
+		/* int */				/* [1] */
+		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0int",
+	.str_sec_size = sizeof("\0int"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "hdr_test_map",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.hdr_len_delta = 4,
+	.err_str = "Unsupported btf_header",
+},
+
+{
+	.descr = "btf_header test. Gap between hdr and type",
+	.raw_types = {
+		/* int */				/* [1] */
+		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0int",
+	.str_sec_size = sizeof("\0int"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "hdr_test_map",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.type_off_delta = 4,
+	.err_str = "Unsupported section found",
+},
+
+{
+	.descr = "btf_header test. Gap between type and str",
+	.raw_types = {
+		/* int */				/* [1] */
+		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0int",
+	.str_sec_size = sizeof("\0int"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "hdr_test_map",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.str_off_delta = 4,
+	.err_str = "Unsupported section found",
+},
+
+{
+	.descr = "btf_header test. Overlap between type and str",
+	.raw_types = {
+		/* int */				/* [1] */
+		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0int",
+	.str_sec_size = sizeof("\0int"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "hdr_test_map",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.str_off_delta = -4,
+	.err_str = "Section overlap found",
+},
+
+{
+	.descr = "btf_header test. Larger BTF size",
+	.raw_types = {
+		/* int */				/* [1] */
+		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0int",
+	.str_sec_size = sizeof("\0int"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "hdr_test_map",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.str_len_delta = -4,
+	.err_str = "Unsupported section found",
+},
+
+{
+	.descr = "btf_header test. Smaller BTF size",
+	.raw_types = {
+		/* int */				/* [1] */
+		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0int",
+	.str_sec_size = sizeof("\0int"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "hdr_test_map",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.str_len_delta = 4,
+	.err_str = "Total section length too long",
+},
+
+{
+	.descr = "array test. index_type/elem_type \"int\"",
+	.raw_types = {
+		/* int */				/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
+		/* int[16] */				/* [2] */
+		BTF_TYPE_ARRAY_ENC(1, 1, 16),
+		BTF_END_RAW,
+	},
+	.str_sec = "",
+	.str_sec_size = sizeof(""),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "array_test_map",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+},
+
+{
+	.descr = "array test. index_type/elem_type \"const int\"",
+	.raw_types = {
+		/* int */				/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
+		/* int[16] */				/* [2] */
+		BTF_TYPE_ARRAY_ENC(3, 3, 16),
+		/* CONST type_id=1 */			/* [3] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 1),
+		BTF_END_RAW,
+	},
+	.str_sec = "",
+	.str_sec_size = sizeof(""),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "array_test_map",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+},
+
+{
+	.descr = "array test. index_type \"const int:31\"",
+	.raw_types = {
+		/* int */				/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
+		/* int:31 */				/* [2] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 31, 4),
+		/* int[16] */				/* [3] */
+		BTF_TYPE_ARRAY_ENC(1, 4, 16),
+		/* CONST type_id=2 */			/* [4] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 2),
+		BTF_END_RAW,
+	},
+	.str_sec = "",
+	.str_sec_size = sizeof(""),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "array_test_map",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid index",
+},
+
+{
+	.descr = "array test. elem_type \"const int:31\"",
+	.raw_types = {
+		/* int */				/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
+		/* int:31 */				/* [2] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 31, 4),
+		/* int[16] */				/* [3] */
+		BTF_TYPE_ARRAY_ENC(4, 1, 16),
+		/* CONST type_id=2 */			/* [4] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 2),
+		BTF_END_RAW,
+	},
+	.str_sec = "",
+	.str_sec_size = sizeof(""),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "array_test_map",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid array of int",
+},
+
+{
+	.descr = "array test. index_type \"void\"",
+	.raw_types = {
+		/* int */				/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
+		/* int[16] */				/* [2] */
+		BTF_TYPE_ARRAY_ENC(1, 0, 16),
+		BTF_END_RAW,
+	},
+	.str_sec = "",
+	.str_sec_size = sizeof(""),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "array_test_map",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid index",
+},
+
+{
+	.descr = "array test. index_type \"const void\"",
+	.raw_types = {
+		/* int */				/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
+		/* int[16] */				/* [2] */
+		BTF_TYPE_ARRAY_ENC(1, 3, 16),
+		/* CONST type_id=0 (void) */		/* [3] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
+		BTF_END_RAW,
+	},
+	.str_sec = "",
+	.str_sec_size = sizeof(""),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "array_test_map",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid index",
+},
+
+{
+	.descr = "array test. elem_type \"const void\"",
+	.raw_types = {
+		/* int */				/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
+		/* int[16] */				/* [2] */
+		BTF_TYPE_ARRAY_ENC(3, 1, 16),
+		/* CONST type_id=0 (void) */		/* [3] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
+		BTF_END_RAW,
+	},
+	.str_sec = "",
+	.str_sec_size = sizeof(""),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "array_test_map",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid elem",
+},
+
+{
+	.descr = "array test. elem_type \"const void *\"",
+	.raw_types = {
+		/* int */				/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
+		/* const void *[16] */			/* [2] */
+		BTF_TYPE_ARRAY_ENC(3, 1, 16),
+		/* CONST type_id=4 */			/* [3] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 4),
+		/* void* */				/* [4] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0),
+		BTF_END_RAW,
+	},
+	.str_sec = "",
+	.str_sec_size = sizeof(""),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "array_test_map",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+},
+
+{
+	.descr = "array test. index_type \"const void *\"",
+	.raw_types = {
+		/* int */				/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
+		/* const void *[16] */			/* [2] */
+		BTF_TYPE_ARRAY_ENC(3, 3, 16),
+		/* CONST type_id=4 */			/* [3] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 4),
+		/* void* */				/* [4] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0),
+		BTF_END_RAW,
+	},
+	.str_sec = "",
+	.str_sec_size = sizeof(""),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "array_test_map",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid index",
+},
+
+{
+	.descr = "array test. t->size != 0\"",
+	.raw_types = {
+		/* int */				/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
+		/* int[16] */				/* [2] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ARRAY, 0, 0), 1),
+		BTF_ARRAY_ENC(1, 1, 16),
+		BTF_END_RAW,
+	},
+	.str_sec = "",
+	.str_sec_size = sizeof(""),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "array_test_map",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "size != 0",
+},
+
+{
+	.descr = "int test. invalid int_data",
+	.raw_types = {
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_INT, 0, 0), 4),
+		0x10000000,
+		BTF_END_RAW,
+	},
+	.str_sec = "",
+	.str_sec_size = sizeof(""),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "array_test_map",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid int_data",
+},
+
+{
+	.descr = "invalid BTF_INFO",
+	.raw_types = {
+		/* int */				/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
+		BTF_TYPE_ENC(0, 0x10000000, 4),
+		BTF_END_RAW,
+	},
+	.str_sec = "",
+	.str_sec_size = sizeof(""),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "array_test_map",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid btf_info",
+},
+
+{
+	.descr = "fwd test. t->type != 0\"",
+	.raw_types = {
+		/* int */				/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
+		/* fwd type */				/* [2] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FWD, 0, 0), 1),
+		BTF_END_RAW,
+	},
+	.str_sec = "",
+	.str_sec_size = sizeof(""),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "fwd_test_map",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "type != 0",
+},
+
+{
+	.descr = "typedef (invalid name, name_off = 0)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_TYPEDEF_ENC(0, 1),				/* [2] */
+		BTF_END_RAW,
+	},
+	.str_sec = "\0__int",
+	.str_sec_size = sizeof("\0__int"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "typedef_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid name",
+},
+
+{
+	.descr = "typedef (invalid name, invalid identifier)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_TYPEDEF_ENC(NAME_TBD, 1),			/* [2] */
+		BTF_END_RAW,
+	},
+	.str_sec = "\0__!int",
+	.str_sec_size = sizeof("\0__!int"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "typedef_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid name",
+},
+
+{
+	.descr = "ptr type (invalid name, name_off <> 0)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
+		BTF_TYPE_ENC(NAME_TBD,
+			     BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 1),	/* [2] */
+		BTF_END_RAW,
+	},
+	.str_sec = "\0__int",
+	.str_sec_size = sizeof("\0__int"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "ptr_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid name",
+},
+
+{
+	.descr = "volatile type (invalid name, name_off <> 0)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
+		BTF_TYPE_ENC(NAME_TBD,
+			     BTF_INFO_ENC(BTF_KIND_VOLATILE, 0, 0), 1),	/* [2] */
+		BTF_END_RAW,
+	},
+	.str_sec = "\0__int",
+	.str_sec_size = sizeof("\0__int"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "volatile_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid name",
+},
+
+{
+	.descr = "const type (invalid name, name_off <> 0)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
+		BTF_TYPE_ENC(NAME_TBD,
+			     BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 1),	/* [2] */
+		BTF_END_RAW,
+	},
+	.str_sec = "\0__int",
+	.str_sec_size = sizeof("\0__int"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "const_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid name",
+},
+
+{
+	.descr = "restrict type (invalid name, name_off <> 0)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 1),	/* [2] */
+		BTF_TYPE_ENC(NAME_TBD,
+			     BTF_INFO_ENC(BTF_KIND_RESTRICT, 0, 0), 2),	/* [3] */
+		BTF_END_RAW,
+	},
+	.str_sec = "\0__int",
+	.str_sec_size = sizeof("\0__int"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "restrict_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid name",
+},
+
+{
+	.descr = "fwd type (invalid name, name_off = 0)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FWD, 0, 0), 0),	/* [2] */
+		BTF_END_RAW,
+	},
+	.str_sec = "\0__skb",
+	.str_sec_size = sizeof("\0__skb"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "fwd_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid name",
+},
+
+{
+	.descr = "fwd type (invalid name, invalid identifier)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
+		BTF_TYPE_ENC(NAME_TBD,
+			     BTF_INFO_ENC(BTF_KIND_FWD, 0, 0), 0),	/* [2] */
+		BTF_END_RAW,
+	},
+	.str_sec = "\0__!skb",
+	.str_sec_size = sizeof("\0__!skb"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "fwd_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid name",
+},
+
+{
+	.descr = "array type (invalid name, name_off <> 0)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
+		BTF_TYPE_ENC(NAME_TBD,
+			     BTF_INFO_ENC(BTF_KIND_ARRAY, 0, 0), 0),	/* [2] */
+		BTF_ARRAY_ENC(1, 1, 4),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0__skb",
+	.str_sec_size = sizeof("\0__skb"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "array_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid name",
+},
+
+{
+	.descr = "struct type (name_off = 0)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
+		BTF_TYPE_ENC(0,
+			     BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4),	/* [2] */
+		BTF_MEMBER_ENC(NAME_TBD, 1, 0),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0A",
+	.str_sec_size = sizeof("\0A"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "struct_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+},
+
+{
+	.descr = "struct type (invalid name, invalid identifier)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
+		BTF_TYPE_ENC(NAME_TBD,
+			     BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4),	/* [2] */
+		BTF_MEMBER_ENC(NAME_TBD, 1, 0),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0A!\0B",
+	.str_sec_size = sizeof("\0A!\0B"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "struct_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid name",
+},
+
+{
+	.descr = "struct member (name_off = 0)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
+		BTF_TYPE_ENC(0,
+			     BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4),	/* [2] */
+		BTF_MEMBER_ENC(NAME_TBD, 1, 0),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0A",
+	.str_sec_size = sizeof("\0A"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "struct_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+},
+
+{
+	.descr = "struct member (invalid name, invalid identifier)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
+		BTF_TYPE_ENC(NAME_TBD,
+			     BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4),	/* [2] */
+		BTF_MEMBER_ENC(NAME_TBD, 1, 0),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0A\0B*",
+	.str_sec_size = sizeof("\0A\0B*"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "struct_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid name",
+},
+
+{
+	.descr = "enum type (name_off = 0)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
+		BTF_TYPE_ENC(0,
+			     BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1),
+			     sizeof(int)),				/* [2] */
+		BTF_ENUM_ENC(NAME_TBD, 0),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0A\0B",
+	.str_sec_size = sizeof("\0A\0B"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "enum_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+},
+
+{
+	.descr = "enum type (invalid name, invalid identifier)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
+		BTF_TYPE_ENC(NAME_TBD,
+			     BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1),
+			     sizeof(int)),				/* [2] */
+		BTF_ENUM_ENC(NAME_TBD, 0),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0A!\0B",
+	.str_sec_size = sizeof("\0A!\0B"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "enum_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid name",
+},
+
+{
+	.descr = "enum member (invalid name, name_off = 0)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
+		BTF_TYPE_ENC(0,
+			     BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1),
+			     sizeof(int)),				/* [2] */
+		BTF_ENUM_ENC(0, 0),
+		BTF_END_RAW,
+	},
+	.str_sec = "",
+	.str_sec_size = sizeof(""),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "enum_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid name",
+},
+
+{
+	.descr = "enum member (invalid name, invalid identifier)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
+		BTF_TYPE_ENC(0,
+			     BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1),
+			     sizeof(int)),				/* [2] */
+		BTF_ENUM_ENC(NAME_TBD, 0),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0A!",
+	.str_sec_size = sizeof("\0A!"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "enum_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid name",
+},
+{
+	.descr = "arraymap invalid btf key (a bit field)",
+	.raw_types = {
+		/* int */				/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
+		/* 32 bit int with 32 bit offset */	/* [2] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 32, 32, 8),
+		BTF_END_RAW,
+	},
+	.str_sec = "",
+	.str_sec_size = sizeof(""),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "array_map_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 2,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.map_create_err = true,
+},
+
+{
+	.descr = "arraymap invalid btf key (!= 32 bits)",
+	.raw_types = {
+		/* int */				/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
+		/* 16 bit int with 0 bit offset */	/* [2] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 16, 2),
+		BTF_END_RAW,
+	},
+	.str_sec = "",
+	.str_sec_size = sizeof(""),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "array_map_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 2,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.map_create_err = true,
+},
+
+{
+	.descr = "arraymap invalid btf value (too small)",
+	.raw_types = {
+		/* int */				/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
+		BTF_END_RAW,
+	},
+	.str_sec = "",
+	.str_sec_size = sizeof(""),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "array_map_check_btf",
+	.key_size = sizeof(int),
+	/* btf_value_size < map->value_size */
+	.value_size = sizeof(__u64),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.map_create_err = true,
+},
+
+{
+	.descr = "arraymap invalid btf value (too big)",
+	.raw_types = {
+		/* int */				/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
+		BTF_END_RAW,
+	},
+	.str_sec = "",
+	.str_sec_size = sizeof(""),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "array_map_check_btf",
+	.key_size = sizeof(int),
+	/* btf_value_size > map->value_size */
+	.value_size = sizeof(__u16),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.map_create_err = true,
+},
+
+{
+	.descr = "func proto (int (*)(int, unsigned int))",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
+		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
+		/* int (*)(int, unsigned int) */
+		BTF_FUNC_PROTO_ENC(1, 2),			/* [3] */
+			BTF_FUNC_PROTO_ARG_ENC(0, 1),
+			BTF_FUNC_PROTO_ARG_ENC(0, 2),
+		BTF_END_RAW,
+	},
+	.str_sec = "",
+	.str_sec_size = sizeof(""),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "func_proto_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+},
+
+{
+	.descr = "func proto (vararg)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
+		/* void (*)(int, unsigned int, ...) */
+		BTF_FUNC_PROTO_ENC(0, 3),			/* [3] */
+			BTF_FUNC_PROTO_ARG_ENC(0, 1),
+			BTF_FUNC_PROTO_ARG_ENC(0, 2),
+			BTF_FUNC_PROTO_ARG_ENC(0, 0),
+		BTF_END_RAW,
+	},
+	.str_sec = "",
+	.str_sec_size = sizeof(""),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "func_proto_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+},
+
+{
+	.descr = "func proto (vararg with name)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
+		/* void (*)(int a, unsigned int b, ... c) */
+		BTF_FUNC_PROTO_ENC(0, 3),			/* [3] */
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 0),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0a\0b\0c",
+	.str_sec_size = sizeof("\0a\0b\0c"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "func_proto_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid arg#3",
+},
+
+{
+	.descr = "func proto (arg after vararg)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
+		/* void (*)(int a, ..., unsigned int b) */
+		BTF_FUNC_PROTO_ENC(0, 3),			/* [3] */
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
+			BTF_FUNC_PROTO_ARG_ENC(0, 0),
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0a\0b",
+	.str_sec_size = sizeof("\0a\0b"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "func_proto_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid arg#2",
+},
+
+{
+	.descr = "func proto (CONST=>TYPEDEF=>PTR=>FUNC_PROTO)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
+		/* typedef void (*func_ptr)(int, unsigned int) */
+		BTF_TYPEDEF_ENC(NAME_TBD, 5),			/* [3] */
+		/* const func_ptr */
+		BTF_CONST_ENC(3),				/* [4] */
+		BTF_PTR_ENC(6),					/* [5] */
+		BTF_FUNC_PROTO_ENC(0, 2),			/* [6] */
+			BTF_FUNC_PROTO_ARG_ENC(0, 1),
+			BTF_FUNC_PROTO_ARG_ENC(0, 2),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0func_ptr",
+	.str_sec_size = sizeof("\0func_ptr"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "func_proto_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+},
+
+{
+	.descr = "func proto (TYPEDEF=>FUNC_PROTO)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
+		BTF_TYPEDEF_ENC(NAME_TBD, 4),			/* [3] */
+		BTF_FUNC_PROTO_ENC(0, 2),			/* [4] */
+			BTF_FUNC_PROTO_ARG_ENC(0, 1),
+			BTF_FUNC_PROTO_ARG_ENC(0, 2),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0func_typedef",
+	.str_sec_size = sizeof("\0func_typedef"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "func_proto_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+},
+
+{
+	.descr = "func proto (btf_resolve(arg))",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		/* void (*)(const void *) */
+		BTF_FUNC_PROTO_ENC(0, 1),			/* [2] */
+			BTF_FUNC_PROTO_ARG_ENC(0, 3),
+		BTF_CONST_ENC(4),				/* [3] */
+		BTF_PTR_ENC(0),					/* [4] */
+		BTF_END_RAW,
+	},
+	.str_sec = "",
+	.str_sec_size = sizeof(""),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "func_proto_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+},
+
+{
+	.descr = "func proto (Not all arg has name)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
+		/* void (*)(int, unsigned int b) */
+		BTF_FUNC_PROTO_ENC(0, 2),			/* [3] */
+			BTF_FUNC_PROTO_ARG_ENC(0, 1),
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0b",
+	.str_sec_size = sizeof("\0b"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "func_proto_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+},
+
+{
+	.descr = "func proto (Bad arg name_off)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
+		/* void (*)(int a, unsigned int <bad_name_off>) */
+		BTF_FUNC_PROTO_ENC(0, 2),			/* [3] */
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
+			BTF_FUNC_PROTO_ARG_ENC(0x0fffffff, 2),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0a",
+	.str_sec_size = sizeof("\0a"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "func_proto_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid arg#2",
+},
+
+{
+	.descr = "func proto (Bad arg name)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
+		/* void (*)(int a, unsigned int !!!) */
+		BTF_FUNC_PROTO_ENC(0, 2),			/* [3] */
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0a\0!!!",
+	.str_sec_size = sizeof("\0a\0!!!"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "func_proto_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid arg#2",
+},
+
+{
+	.descr = "func proto (Invalid return type)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
+		/* <bad_ret_type> (*)(int, unsigned int) */
+		BTF_FUNC_PROTO_ENC(100, 2),			/* [3] */
+			BTF_FUNC_PROTO_ARG_ENC(0, 1),
+			BTF_FUNC_PROTO_ARG_ENC(0, 2),
+		BTF_END_RAW,
+	},
+	.str_sec = "",
+	.str_sec_size = sizeof(""),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "func_proto_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid return type",
+},
+
+{
+	.descr = "func proto (with func name)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
+		/* void func_proto(int, unsigned int) */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 2), 0),	/* [3] */
+			BTF_FUNC_PROTO_ARG_ENC(0, 1),
+			BTF_FUNC_PROTO_ARG_ENC(0, 2),
+		BTF_END_RAW,
+	},
+	.str_sec = "\0func_proto",
+	.str_sec_size = sizeof("\0func_proto"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "func_proto_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid name",
+},
+
+{
+	.descr = "func proto (const void arg)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
+		/* void (*)(const void) */
+		BTF_FUNC_PROTO_ENC(0, 1),			/* [3] */
+			BTF_FUNC_PROTO_ARG_ENC(0, 4),
+		BTF_CONST_ENC(0),				/* [4] */
+		BTF_END_RAW,
+	},
+	.str_sec = "",
+	.str_sec_size = sizeof(""),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "func_proto_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid arg#1",
+},
+
+{
+	.descr = "func (void func(int a, unsigned int b))",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
+		/* void (*)(int a, unsigned int b) */
+		BTF_FUNC_PROTO_ENC(0, 2),			/* [3] */
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
+		/* void func(int a, unsigned int b) */
+		BTF_FUNC_ENC(NAME_TBD, 3),			/* [4] */
+		BTF_END_RAW,
+	},
+	.str_sec = "\0a\0b\0func",
+	.str_sec_size = sizeof("\0a\0b\0func"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "func_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+},
+
+{
+	.descr = "func (No func name)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
+		/* void (*)(int a, unsigned int b) */
+		BTF_FUNC_PROTO_ENC(0, 2),			/* [3] */
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
+		/* void <no_name>(int a, unsigned int b) */
+		BTF_FUNC_ENC(0, 3),				/* [4] */
+		BTF_END_RAW,
+	},
+	.str_sec = "\0a\0b",
+	.str_sec_size = sizeof("\0a\0b"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "func_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid name",
+},
+
+{
+	.descr = "func (Invalid func name)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
+		/* void (*)(int a, unsigned int b) */
+		BTF_FUNC_PROTO_ENC(0, 2),			/* [3] */
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
+		/* void !!!(int a, unsigned int b) */
+		BTF_FUNC_ENC(NAME_TBD, 3),			/* [4] */
+		BTF_END_RAW,
+	},
+	.str_sec = "\0a\0b\0!!!",
+	.str_sec_size = sizeof("\0a\0b\0!!!"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "func_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid name",
+},
+
+{
+	.descr = "func (Some arg has no name)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
+		/* void (*)(int a, unsigned int) */
+		BTF_FUNC_PROTO_ENC(0, 2),			/* [3] */
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
+			BTF_FUNC_PROTO_ARG_ENC(0, 2),
+		/* void func(int a, unsigned int) */
+		BTF_FUNC_ENC(NAME_TBD, 3),			/* [4] */
+		BTF_END_RAW,
+	},
+	.str_sec = "\0a\0func",
+	.str_sec_size = sizeof("\0a\0func"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "func_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid arg#2",
+},
+
+{
+	.descr = "func (Non zero vlen)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
+		/* void (*)(int a, unsigned int b) */
+		BTF_FUNC_PROTO_ENC(0, 2),			/* [3] */
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
+		/* void func(int a, unsigned int b) */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FUNC, 0, 2), 3), 	/* [4] */
+		BTF_END_RAW,
+	},
+	.str_sec = "\0a\0b\0func",
+	.str_sec_size = sizeof("\0a\0b\0func"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "func_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid func linkage",
+},
+
+{
+	.descr = "func (Not referring to FUNC_PROTO)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_FUNC_ENC(NAME_TBD, 1),			/* [2] */
+		BTF_END_RAW,
+	},
+	.str_sec = "\0func",
+	.str_sec_size = sizeof("\0func"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "func_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid type_id",
+},
+
+{
+	.descr = "invalid int kind_flag",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_INT, 1, 0), 4),	/* [2] */
+		BTF_INT_ENC(0, 0, 32),
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC(""),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "int_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid btf_info kind_flag",
+},
+
+{
+	.descr = "invalid ptr kind_flag",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 1, 0), 1),	/* [2] */
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC(""),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "ptr_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid btf_info kind_flag",
+},
+
+{
+	.descr = "invalid array kind_flag",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ARRAY, 1, 0), 0),	/* [2] */
+		BTF_ARRAY_ENC(1, 1, 1),
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC(""),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "array_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid btf_info kind_flag",
+},
+
+{
+	.descr = "invalid enum kind_flag",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 1, 1), 4),	/* [2] */
+		BTF_ENUM_ENC(NAME_TBD, 0),
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0A"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "enum_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid btf_info kind_flag",
+},
+
+{
+	.descr = "valid fwd kind_flag",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
+		BTF_TYPE_ENC(NAME_TBD,
+			     BTF_INFO_ENC(BTF_KIND_FWD, 1, 0), 0),	/* [2] */
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0A"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "fwd_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+},
+
+{
+	.descr = "invalid typedef kind_flag",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
+		BTF_TYPE_ENC(NAME_TBD,
+			     BTF_INFO_ENC(BTF_KIND_TYPEDEF, 1, 0), 1),	/* [2] */
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0A"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "typedef_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid btf_info kind_flag",
+},
+
+{
+	.descr = "invalid volatile kind_flag",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_VOLATILE, 1, 0), 1),	/* [2] */
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC(""),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "volatile_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid btf_info kind_flag",
+},
+
+{
+	.descr = "invalid const kind_flag",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 1, 0), 1),	/* [2] */
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC(""),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "const_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid btf_info kind_flag",
+},
+
+{
+	.descr = "invalid restrict kind_flag",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_RESTRICT, 1, 0), 1),	/* [2] */
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC(""),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "restrict_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid btf_info kind_flag",
+},
+
+{
+	.descr = "invalid func kind_flag",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 0), 0),	/* [2] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FUNC, 1, 0), 2),	/* [3] */
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0A"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "func_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid btf_info kind_flag",
+},
+
+{
+	.descr = "invalid func_proto kind_flag",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 1, 0), 0),	/* [2] */
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC(""),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "func_proto_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid btf_info kind_flag",
+},
+
+{
+	.descr = "valid struct, kind_flag, bitfield_size = 0",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 8),	/* [2] */
+		BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(0, 0)),
+		BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(0, 32)),
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0A\0B"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "struct_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+},
+
+{
+	.descr = "valid struct, kind_flag, int member, bitfield_size != 0",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),	/* [2] */
+		BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 0)),
+		BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 4)),
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0A\0B"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "struct_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+},
+
+{
+	.descr = "valid union, kind_flag, int member, bitfield_size != 0",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 4),	/* [2] */
+		BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 0)),
+		BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 0)),
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0A\0B"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "union_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+},
+
+{
+	.descr = "valid struct, kind_flag, enum member, bitfield_size != 0",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),	/* [2] */
+		BTF_ENUM_ENC(NAME_TBD, 0),
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),/* [3] */
+		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 0)),
+		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 4)),
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0A\0B\0C"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "struct_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+},
+
+{
+	.descr = "valid union, kind_flag, enum member, bitfield_size != 0",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),	/* [2] */
+		BTF_ENUM_ENC(NAME_TBD, 0),
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 4),	/* [3] */
+		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 0)),
+		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 0)),
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0A\0B\0C"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "union_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+},
+
+{
+	.descr = "valid struct, kind_flag, typedef member, bitfield_size != 0",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),	/* [2] */
+		BTF_ENUM_ENC(NAME_TBD, 0),
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),/* [3] */
+		BTF_MEMBER_ENC(NAME_TBD, 4, BTF_MEMBER_OFFSET(4, 0)),
+		BTF_MEMBER_ENC(NAME_TBD, 5, BTF_MEMBER_OFFSET(4, 4)),
+		BTF_TYPEDEF_ENC(NAME_TBD, 1),				/* [4] */
+		BTF_TYPEDEF_ENC(NAME_TBD, 2),				/* [5] */
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0A\0B\0C\0D\0E"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "struct_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+},
+
+{
+	.descr = "valid union, kind_flag, typedef member, bitfield_size != 0",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),	/* [2] */
+		BTF_ENUM_ENC(NAME_TBD, 0),
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 4),	/* [3] */
+		BTF_MEMBER_ENC(NAME_TBD, 4, BTF_MEMBER_OFFSET(4, 0)),
+		BTF_MEMBER_ENC(NAME_TBD, 5, BTF_MEMBER_OFFSET(4, 0)),
+		BTF_TYPEDEF_ENC(NAME_TBD, 1),				/* [4] */
+		BTF_TYPEDEF_ENC(NAME_TBD, 2),				/* [5] */
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0A\0B\0C\0D\0E"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "union_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+},
+
+{
+	.descr = "invalid struct, kind_flag, bitfield_size greater than struct size",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),	/* [2] */
+		BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(20, 0)),
+		BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(20, 20)),
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0A\0B"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "struct_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Member exceeds struct_size",
+},
+
+{
+	.descr = "invalid struct, kind_flag, bitfield base_type int not regular",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 20, 4),			/* [2] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),	/* [3] */
+		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(20, 0)),
+		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(20, 20)),
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0A\0B"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "struct_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid member base type",
+},
+
+{
+	.descr = "invalid struct, kind_flag, base_type int not regular",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 12, 4),			/* [2] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),	/* [3] */
+		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(8, 0)),
+		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(8, 8)),
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0A\0B"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "struct_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid member base type",
+},
+
+{
+	.descr = "invalid union, kind_flag, bitfield_size greater than struct size",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 2),	/* [2] */
+		BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(8, 0)),
+		BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(20, 0)),
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0A\0B"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "union_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Member exceeds struct_size",
+},
+
+{
+	.descr = "invalid struct, kind_flag, int member, bitfield_size = 0, wrong byte alignment",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [2] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 12),	/* [3] */
+		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)),
+		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 36)),
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0A\0B"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "struct_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid member offset",
+},
+
+{
+	.descr = "invalid struct, kind_flag, enum member, bitfield_size = 0, wrong byte alignment",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [2] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),	/* [2] */
+		BTF_ENUM_ENC(NAME_TBD, 0),
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 12),	/* [3] */
+		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)),
+		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 36)),
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0A\0B\0C"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "struct_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+	.btf_load_err = true,
+	.err_str = "Invalid member offset",
+},
+
+{
+	.descr = "128-bit int",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 128, 16),		/* [2] */
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0A"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "int_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+},
+
+{
+	.descr = "struct, 128-bit int member",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 128, 16),		/* [2] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 16),	/* [3] */
+		BTF_MEMBER_ENC(NAME_TBD, 2, 0),
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0A"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "struct_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+},
+
+{
+	.descr = "struct, 120-bit int member bitfield",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 120, 16),		/* [2] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 16),	/* [3] */
+		BTF_MEMBER_ENC(NAME_TBD, 2, 0),
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0A"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "struct_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+},
+
+{
+	.descr = "struct, kind_flag, 128-bit int member",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 128, 16),		/* [2] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 1), 16),	/* [3] */
+		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)),
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0A"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "struct_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+},
+
+{
+	.descr = "struct, kind_flag, 120-bit int member bitfield",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 128, 16),		/* [2] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 1), 16),	/* [3] */
+		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(120, 0)),
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0A"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "struct_type_check_btf",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int),
+	.key_type_id = 1,
+	.value_type_id = 1,
+	.max_entries = 4,
+},
+/*
+ * typedef int arr_t[16];
+ * struct s {
+ *	arr_t *a;
+ * };
+ */
+{
+	.descr = "struct->ptr->typedef->array->int size resolution",
+	.raw_types = {
+		BTF_STRUCT_ENC(NAME_TBD, 1, 8),			/* [1] */
+		BTF_MEMBER_ENC(NAME_TBD, 2, 0),
+		BTF_PTR_ENC(3),					/* [2] */
+		BTF_TYPEDEF_ENC(NAME_TBD, 4),			/* [3] */
+		BTF_TYPE_ARRAY_ENC(5, 5, 16),			/* [4] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [5] */
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0s\0a\0arr_t"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "ptr_mod_chain_size_resolve_map",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int) * 16,
+	.key_type_id = 5 /* int */,
+	.value_type_id = 3 /* arr_t */,
+	.max_entries = 4,
+},
+/*
+ * typedef int arr_t[16][8][4];
+ * struct s {
+ *	arr_t *a;
+ * };
+ */
+{
+	.descr = "struct->ptr->typedef->multi-array->int size resolution",
+	.raw_types = {
+		BTF_STRUCT_ENC(NAME_TBD, 1, 8),			/* [1] */
+		BTF_MEMBER_ENC(NAME_TBD, 2, 0),
+		BTF_PTR_ENC(3),					/* [2] */
+		BTF_TYPEDEF_ENC(NAME_TBD, 4),			/* [3] */
+		BTF_TYPE_ARRAY_ENC(5, 7, 16),			/* [4] */
+		BTF_TYPE_ARRAY_ENC(6, 7, 8),			/* [5] */
+		BTF_TYPE_ARRAY_ENC(7, 7, 4),			/* [6] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [7] */
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0s\0a\0arr_t"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "multi_arr_size_resolve_map",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int) * 16 * 8 * 4,
+	.key_type_id = 7 /* int */,
+	.value_type_id = 3 /* arr_t */,
+	.max_entries = 4,
+},
+/*
+ * typedef int int_t;
+ * typedef int_t arr3_t[4];
+ * typedef arr3_t arr2_t[8];
+ * typedef arr2_t arr1_t[16];
+ * struct s {
+ *	arr1_t *a;
+ * };
+ */
+{
+	.descr = "typedef/multi-arr mix size resolution",
+	.raw_types = {
+		BTF_STRUCT_ENC(NAME_TBD, 1, 8),			/* [1] */
+		BTF_MEMBER_ENC(NAME_TBD, 2, 0),
+		BTF_PTR_ENC(3),					/* [2] */
+		BTF_TYPEDEF_ENC(NAME_TBD, 4),			/* [3] */
+		BTF_TYPE_ARRAY_ENC(5, 10, 16),			/* [4] */
+		BTF_TYPEDEF_ENC(NAME_TBD, 6),			/* [5] */
+		BTF_TYPE_ARRAY_ENC(7, 10, 8),			/* [6] */
+		BTF_TYPEDEF_ENC(NAME_TBD, 8),			/* [7] */
+		BTF_TYPE_ARRAY_ENC(9, 10, 4),			/* [8] */
+		BTF_TYPEDEF_ENC(NAME_TBD, 10),			/* [9] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [10] */
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0s\0a\0arr1_t\0arr2_t\0arr3_t\0int_t"),
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "typedef_arra_mix_size_resolve_map",
+	.key_size = sizeof(int),
+	.value_size = sizeof(int) * 16 * 8 * 4,
+	.key_type_id = 10 /* int */,
+	.value_type_id = 3 /* arr_t */,
+	.max_entries = 4,
+},
+
+}; /* struct btf_raw_test raw_tests[] */
+
+static const char *get_next_str(const char *start, const char *end)
+{
+	return start < end - 1 ? start + 1 : NULL;
+}
+
+static int get_raw_sec_size(const __u32 *raw_types)
+{
+	int i;
+
+	for (i = MAX_NR_RAW_U32 - 1;
+	     i >= 0 && raw_types[i] != BTF_END_RAW;
+	     i--)
+		;
+
+	return i < 0 ? i : i * sizeof(raw_types[0]);
+}
+
+static void *btf_raw_create(const struct btf_header *hdr,
+			    const __u32 *raw_types,
+			    const char *str,
+			    unsigned int str_sec_size,
+			    unsigned int *btf_size,
+			    const char **ret_next_str)
+{
+	const char *next_str = str, *end_str = str + str_sec_size;
+	const char **strs_idx = NULL, **tmp_strs_idx;
+	int strs_cap = 0, strs_cnt = 0, next_str_idx = 0;
+	unsigned int size_needed, offset;
+	struct btf_header *ret_hdr;
+	int i, type_sec_size, err = 0;
+	uint32_t *ret_types;
+	void *raw_btf = NULL;
+
+	type_sec_size = get_raw_sec_size(raw_types);
+	if (CHECK(type_sec_size < 0, "Cannot get nr_raw_types"))
+		return NULL;
+
+	size_needed = sizeof(*hdr) + type_sec_size + str_sec_size;
+	raw_btf = malloc(size_needed);
+	if (CHECK(!raw_btf, "Cannot allocate memory for raw_btf"))
+		return NULL;
+
+	/* Copy header */
+	memcpy(raw_btf, hdr, sizeof(*hdr));
+	offset = sizeof(*hdr);
+
+	/* Index strings */
+	while ((next_str = get_next_str(next_str, end_str))) {
+		if (strs_cnt == strs_cap) {
+			strs_cap += max(16, strs_cap / 2);
+			tmp_strs_idx = realloc(strs_idx,
+					       sizeof(*strs_idx) * strs_cap);
+			if (CHECK(!tmp_strs_idx,
+				  "Cannot allocate memory for strs_idx")) {
+				err = -1;
+				goto done;
+			}
+			strs_idx = tmp_strs_idx;
+		}
+		strs_idx[strs_cnt++] = next_str;
+		next_str += strlen(next_str);
+	}
+
+	/* Copy type section */
+	ret_types = raw_btf + offset;
+	for (i = 0; i < type_sec_size / sizeof(raw_types[0]); i++) {
+		if (raw_types[i] == NAME_TBD) {
+			if (CHECK(next_str_idx == strs_cnt,
+				  "Error in getting next_str #%d",
+				  next_str_idx)) {
+				err = -1;
+				goto done;
+			}
+			ret_types[i] = strs_idx[next_str_idx++] - str;
+		} else if (IS_NAME_NTH(raw_types[i])) {
+			int idx = GET_NAME_NTH_IDX(raw_types[i]);
+
+			if (CHECK(idx <= 0 || idx > strs_cnt,
+				  "Error getting string #%d, strs_cnt:%d",
+				  idx, strs_cnt)) {
+				err = -1;
+				goto done;
+			}
+			ret_types[i] = strs_idx[idx-1] - str;
+		} else {
+			ret_types[i] = raw_types[i];
+		}
+	}
+	offset += type_sec_size;
+
+	/* Copy string section */
+	memcpy(raw_btf + offset, str, str_sec_size);
+
+	ret_hdr = (struct btf_header *)raw_btf;
+	ret_hdr->type_len = type_sec_size;
+	ret_hdr->str_off = type_sec_size;
+	ret_hdr->str_len = str_sec_size;
+
+	*btf_size = size_needed;
+	if (ret_next_str)
+		*ret_next_str =
+			next_str_idx < strs_cnt ? strs_idx[next_str_idx] : NULL;
+
+done:
+	if (err) {
+		if (raw_btf)
+			free(raw_btf);
+		if (strs_idx)
+			free(strs_idx);
+		return NULL;
+	}
+	return raw_btf;
+}
+
+static void do_test_raw(unsigned int test_num)
+{
+	struct btf_raw_test *test = &raw_tests[test_num - 1];
+	struct bpf_create_map_attr create_attr = {};
+	int map_fd = -1, btf_fd = -1;
+	unsigned int raw_btf_size;
+	struct btf_header *hdr;
+	void *raw_btf;
+	int err;
+
+	if (!test__start_subtest(test->descr))
+		return;
+
+	raw_btf = btf_raw_create(&hdr_tmpl,
+				 test->raw_types,
+				 test->str_sec,
+				 test->str_sec_size,
+				 &raw_btf_size, NULL);
+	if (!raw_btf)
+		return;
+
+	hdr = raw_btf;
+
+	hdr->hdr_len = (int)hdr->hdr_len + test->hdr_len_delta;
+	hdr->type_off = (int)hdr->type_off + test->type_off_delta;
+	hdr->str_off = (int)hdr->str_off + test->str_off_delta;
+	hdr->str_len = (int)hdr->str_len + test->str_len_delta;
+
+	*btf_log_buf = '\0';
+	btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
+			      btf_log_buf, BTF_LOG_BUF_SIZE,
+			      always_log);
+	free(raw_btf);
+
+	err = ((btf_fd == -1) != test->btf_load_err);
+	if (CHECK(err, "btf_fd:%d test->btf_load_err:%u",
+		  btf_fd, test->btf_load_err) ||
+	    CHECK(test->err_str && !strstr(btf_log_buf, test->err_str),
+		  "expected err_str:%s", test->err_str)) {
+		err = -1;
+		goto done;
+	}
+
+	if (err || btf_fd == -1)
+		goto done;
+
+	create_attr.name = test->map_name;
+	create_attr.map_type = test->map_type;
+	create_attr.key_size = test->key_size;
+	create_attr.value_size = test->value_size;
+	create_attr.max_entries = test->max_entries;
+	create_attr.btf_fd = btf_fd;
+	create_attr.btf_key_type_id = test->key_type_id;
+	create_attr.btf_value_type_id = test->value_type_id;
+
+	map_fd = bpf_create_map_xattr(&create_attr);
+
+	err = ((map_fd == -1) != test->map_create_err);
+	CHECK(err, "map_fd:%d test->map_create_err:%u",
+	      map_fd, test->map_create_err);
+
+done:
+	if (*btf_log_buf && (err || always_log))
+		fprintf(stderr, "\n%s", btf_log_buf);
+	if (btf_fd != -1)
+		close(btf_fd);
+	if (map_fd != -1)
+		close(map_fd);
+}
+
+struct btf_get_info_test {
+	const char *descr;
+	const char *str_sec;
+	__u32 raw_types[MAX_NR_RAW_U32];
+	__u32 str_sec_size;
+	int btf_size_delta;
+	int (*special_test)(unsigned int test_num);
+};
+
+static int test_big_btf_info(unsigned int test_num);
+static int test_btf_id(unsigned int test_num);
+
+const struct btf_get_info_test get_info_tests[] = {
+{
+	.descr = "== raw_btf_size+1",
+	.raw_types = {
+		/* int */				/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
+		BTF_END_RAW,
+	},
+	.str_sec = "",
+	.str_sec_size = sizeof(""),
+	.btf_size_delta = 1,
+},
+{
+	.descr = "== raw_btf_size-3",
+	.raw_types = {
+		/* int */				/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
+		BTF_END_RAW,
+	},
+	.str_sec = "",
+	.str_sec_size = sizeof(""),
+	.btf_size_delta = -3,
+},
+{
+	.descr = "Large bpf_btf_info",
+	.raw_types = {
+		/* int */				/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
+		BTF_END_RAW,
+	},
+	.str_sec = "",
+	.str_sec_size = sizeof(""),
+	.special_test = test_big_btf_info,
+},
+{
+	.descr = "BTF ID",
+	.raw_types = {
+		/* int */				/* [1] */
+		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
+		/* unsigned int */			/* [2] */
+		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),
+		BTF_END_RAW,
+	},
+	.str_sec = "",
+	.str_sec_size = sizeof(""),
+	.special_test = test_btf_id,
+},
+};
+
+static int test_big_btf_info(unsigned int test_num)
+{
+	const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
+	uint8_t *raw_btf = NULL, *user_btf = NULL;
+	unsigned int raw_btf_size;
+	struct {
+		struct bpf_btf_info info;
+		uint64_t garbage;
+	} info_garbage;
+	struct bpf_btf_info *info;
+	int btf_fd = -1, err;
+	uint32_t info_len;
+
+	raw_btf = btf_raw_create(&hdr_tmpl,
+				 test->raw_types,
+				 test->str_sec,
+				 test->str_sec_size,
+				 &raw_btf_size, NULL);
+
+	if (!raw_btf)
+		return -1;
+
+	*btf_log_buf = '\0';
+
+	user_btf = malloc(raw_btf_size);
+	if (CHECK(!user_btf, "!user_btf")) {
+		err = -1;
+		goto done;
+	}
+
+	btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
+			      btf_log_buf, BTF_LOG_BUF_SIZE,
+			      always_log);
+	if (CHECK(btf_fd == -1, "errno:%d", errno)) {
+		err = -1;
+		goto done;
+	}
+
+	/*
+	 * GET_INFO should error out if the userspace info
+	 * has non zero tailing bytes.
+	 */
+	info = &info_garbage.info;
+	memset(info, 0, sizeof(*info));
+	info_garbage.garbage = 0xdeadbeef;
+	info_len = sizeof(info_garbage);
+	info->btf = ptr_to_u64(user_btf);
+	info->btf_size = raw_btf_size;
+
+	err = bpf_obj_get_info_by_fd(btf_fd, info, &info_len);
+	if (CHECK(!err, "!err")) {
+		err = -1;
+		goto done;
+	}
+
+	/*
+	 * GET_INFO should succeed even info_len is larger than
+	 * the kernel supported as long as tailing bytes are zero.
+	 * The kernel supported info len should also be returned
+	 * to userspace.
+	 */
+	info_garbage.garbage = 0;
+	err = bpf_obj_get_info_by_fd(btf_fd, info, &info_len);
+	if (CHECK(err || info_len != sizeof(*info),
+		  "err:%d errno:%d info_len:%u sizeof(*info):%zu",
+		  err, errno, info_len, sizeof(*info))) {
+		err = -1;
+		goto done;
+	}
+
+	fprintf(stderr, "OK");
+
+done:
+	if (*btf_log_buf && (err || always_log))
+		fprintf(stderr, "\n%s", btf_log_buf);
+
+	free(raw_btf);
+	free(user_btf);
+
+	if (btf_fd != -1)
+		close(btf_fd);
+
+	return err;
+}
+
+static int test_btf_id(unsigned int test_num)
+{
+	const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
+	struct bpf_create_map_attr create_attr = {};
+	uint8_t *raw_btf = NULL, *user_btf[2] = {};
+	int btf_fd[2] = {-1, -1}, map_fd = -1;
+	struct bpf_map_info map_info = {};
+	struct bpf_btf_info info[2] = {};
+	unsigned int raw_btf_size;
+	uint32_t info_len;
+	int err, i, ret;
+
+	raw_btf = btf_raw_create(&hdr_tmpl,
+				 test->raw_types,
+				 test->str_sec,
+				 test->str_sec_size,
+				 &raw_btf_size, NULL);
+
+	if (!raw_btf)
+		return -1;
+
+	*btf_log_buf = '\0';
+
+	for (i = 0; i < 2; i++) {
+		user_btf[i] = malloc(raw_btf_size);
+		if (CHECK(!user_btf[i], "!user_btf[%d]", i)) {
+			err = -1;
+			goto done;
+		}
+		info[i].btf = ptr_to_u64(user_btf[i]);
+		info[i].btf_size = raw_btf_size;
+	}
+
+	btf_fd[0] = bpf_load_btf(raw_btf, raw_btf_size,
+				 btf_log_buf, BTF_LOG_BUF_SIZE,
+				 always_log);
+	if (CHECK(btf_fd[0] == -1, "errno:%d", errno)) {
+		err = -1;
+		goto done;
+	}
+
+	/* Test BPF_OBJ_GET_INFO_BY_ID on btf_id */
+	info_len = sizeof(info[0]);
+	err = bpf_obj_get_info_by_fd(btf_fd[0], &info[0], &info_len);
+	if (CHECK(err, "errno:%d", errno)) {
+		err = -1;
+		goto done;
+	}
+
+	btf_fd[1] = bpf_btf_get_fd_by_id(info[0].id);
+	if (CHECK(btf_fd[1] == -1, "errno:%d", errno)) {
+		err = -1;
+		goto done;
+	}
+
+	ret = 0;
+	err = bpf_obj_get_info_by_fd(btf_fd[1], &info[1], &info_len);
+	if (CHECK(err || info[0].id != info[1].id ||
+		  info[0].btf_size != info[1].btf_size ||
+		  (ret = memcmp(user_btf[0], user_btf[1], info[0].btf_size)),
+		  "err:%d errno:%d id0:%u id1:%u btf_size0:%u btf_size1:%u memcmp:%d",
+		  err, errno, info[0].id, info[1].id,
+		  info[0].btf_size, info[1].btf_size, ret)) {
+		err = -1;
+		goto done;
+	}
+
+	/* Test btf members in struct bpf_map_info */
+	create_attr.name = "test_btf_id";
+	create_attr.map_type = BPF_MAP_TYPE_ARRAY;
+	create_attr.key_size = sizeof(int);
+	create_attr.value_size = sizeof(unsigned int);
+	create_attr.max_entries = 4;
+	create_attr.btf_fd = btf_fd[0];
+	create_attr.btf_key_type_id = 1;
+	create_attr.btf_value_type_id = 2;
+
+	map_fd = bpf_create_map_xattr(&create_attr);
+	if (CHECK(map_fd == -1, "errno:%d", errno)) {
+		err = -1;
+		goto done;
+	}
+
+	info_len = sizeof(map_info);
+	err = bpf_obj_get_info_by_fd(map_fd, &map_info, &info_len);
+	if (CHECK(err || map_info.btf_id != info[0].id ||
+		  map_info.btf_key_type_id != 1 || map_info.btf_value_type_id != 2,
+		  "err:%d errno:%d info.id:%u btf_id:%u btf_key_type_id:%u btf_value_type_id:%u",
+		  err, errno, info[0].id, map_info.btf_id, map_info.btf_key_type_id,
+		  map_info.btf_value_type_id)) {
+		err = -1;
+		goto done;
+	}
+
+	for (i = 0; i < 2; i++) {
+		close(btf_fd[i]);
+		btf_fd[i] = -1;
+	}
+
+	/* Test BTF ID is removed from the kernel */
+	btf_fd[0] = bpf_btf_get_fd_by_id(map_info.btf_id);
+	if (CHECK(btf_fd[0] == -1, "errno:%d", errno)) {
+		err = -1;
+		goto done;
+	}
+	close(btf_fd[0]);
+	btf_fd[0] = -1;
+
+	/* The map holds the last ref to BTF and its btf_id */
+	close(map_fd);
+	map_fd = -1;
+	btf_fd[0] = bpf_btf_get_fd_by_id(map_info.btf_id);
+	if (CHECK(btf_fd[0] != -1, "BTF lingers")) {
+		err = -1;
+		goto done;
+	}
+
+	fprintf(stderr, "OK");
+
+done:
+	if (*btf_log_buf && (err || always_log))
+		fprintf(stderr, "\n%s", btf_log_buf);
+
+	free(raw_btf);
+	if (map_fd != -1)
+		close(map_fd);
+	for (i = 0; i < 2; i++) {
+		free(user_btf[i]);
+		if (btf_fd[i] != -1)
+			close(btf_fd[i]);
+	}
+
+	return err;
+}
+
+static void do_test_get_info(unsigned int test_num)
+{
+	const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
+	unsigned int raw_btf_size, user_btf_size, expected_nbytes;
+	uint8_t *raw_btf = NULL, *user_btf = NULL;
+	struct bpf_btf_info info = {};
+	int btf_fd = -1, err, ret;
+	uint32_t info_len;
+
+	if (!test__start_subtest(test->descr))
+		return;
+
+	if (test->special_test) {
+		err = test->special_test(test_num);
+		if (CHECK(err, "failed: %d\n", err))
+			return;
+	}
+
+	raw_btf = btf_raw_create(&hdr_tmpl,
+				 test->raw_types,
+				 test->str_sec,
+				 test->str_sec_size,
+				 &raw_btf_size, NULL);
+
+	if (!raw_btf)
+		return;
+
+	*btf_log_buf = '\0';
+
+	user_btf = malloc(raw_btf_size);
+	if (CHECK(!user_btf, "!user_btf")) {
+		err = -1;
+		goto done;
+	}
+
+	btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
+			      btf_log_buf, BTF_LOG_BUF_SIZE,
+			      always_log);
+	if (CHECK(btf_fd == -1, "errno:%d", errno)) {
+		err = -1;
+		goto done;
+	}
+
+	user_btf_size = (int)raw_btf_size + test->btf_size_delta;
+	expected_nbytes = min(raw_btf_size, user_btf_size);
+	if (raw_btf_size > expected_nbytes)
+		memset(user_btf + expected_nbytes, 0xff,
+		       raw_btf_size - expected_nbytes);
+
+	info_len = sizeof(info);
+	info.btf = ptr_to_u64(user_btf);
+	info.btf_size = user_btf_size;
+
+	ret = 0;
+	err = bpf_obj_get_info_by_fd(btf_fd, &info, &info_len);
+	if (CHECK(err || !info.id || info_len != sizeof(info) ||
+		  info.btf_size != raw_btf_size ||
+		  (ret = memcmp(raw_btf, user_btf, expected_nbytes)),
+		  "err:%d errno:%d info.id:%u info_len:%u sizeof(info):%zu raw_btf_size:%u info.btf_size:%u expected_nbytes:%u memcmp:%d",
+		  err, errno, info.id, info_len, sizeof(info),
+		  raw_btf_size, info.btf_size, expected_nbytes, ret)) {
+		err = -1;
+		goto done;
+	}
+
+	while (expected_nbytes < raw_btf_size) {
+		fprintf(stderr, "%u...", expected_nbytes);
+		if (CHECK(user_btf[expected_nbytes++] != 0xff,
+			  "user_btf[%u]:%x != 0xff", expected_nbytes - 1,
+			  user_btf[expected_nbytes - 1])) {
+			err = -1;
+			goto done;
+		}
+	}
+
+	fprintf(stderr, "OK");
+
+done:
+	if (*btf_log_buf && (err || always_log))
+		fprintf(stderr, "\n%s", btf_log_buf);
+
+	free(raw_btf);
+	free(user_btf);
+
+	if (btf_fd != -1)
+		close(btf_fd);
+}
+
+struct btf_file_test {
+	const char *file;
+	bool btf_kv_notfound;
+};
+
+static struct btf_file_test file_tests[] = {
+	{ .file = "test_btf_haskv.o", },
+	{ .file = "test_btf_newkv.o", },
+	{ .file = "test_btf_nokv.o", .btf_kv_notfound = true, },
+};
+
+static void do_test_file(unsigned int test_num)
+{
+	const struct btf_file_test *test = &file_tests[test_num - 1];
+	const char *expected_fnames[] = {"_dummy_tracepoint",
+					 "test_long_fname_1",
+					 "test_long_fname_2"};
+	struct btf_ext *btf_ext = NULL;
+	struct bpf_prog_info info = {};
+	struct bpf_object *obj = NULL;
+	struct bpf_func_info *finfo;
+	struct bpf_program *prog;
+	__u32 info_len, rec_size;
+	bool has_btf_ext = false;
+	struct btf *btf = NULL;
+	void *func_info = NULL;
+	struct bpf_map *map;
+	int i, err, prog_fd;
+
+	if (!test__start_subtest(test->file))
+		return;
+
+	btf = btf__parse_elf(test->file, &btf_ext);
+	if (IS_ERR(btf)) {
+		if (PTR_ERR(btf) == -ENOENT) {
+			printf("%s:SKIP: No ELF %s found", __func__, BTF_ELF_SEC);
+			test__skip();
+			return;
+		}
+		return;
+	}
+	btf__free(btf);
+
+	has_btf_ext = btf_ext != NULL;
+	btf_ext__free(btf_ext);
+
+	obj = bpf_object__open(test->file);
+	if (CHECK(IS_ERR(obj), "obj: %ld", PTR_ERR(obj)))
+		return;
+
+	prog = bpf_program__next(NULL, obj);
+	if (CHECK(!prog, "Cannot find bpf_prog")) {
+		err = -1;
+		goto done;
+	}
+
+	bpf_program__set_type(prog, BPF_PROG_TYPE_TRACEPOINT);
+	err = bpf_object__load(obj);
+	if (CHECK(err < 0, "bpf_object__load: %d", err))
+		goto done;
+	prog_fd = bpf_program__fd(prog);
+
+	map = bpf_object__find_map_by_name(obj, "btf_map");
+	if (CHECK(!map, "btf_map not found")) {
+		err = -1;
+		goto done;
+	}
+
+	err = (bpf_map__btf_key_type_id(map) == 0 || bpf_map__btf_value_type_id(map) == 0)
+		!= test->btf_kv_notfound;
+	if (CHECK(err, "btf_key_type_id:%u btf_value_type_id:%u test->btf_kv_notfound:%u",
+		  bpf_map__btf_key_type_id(map), bpf_map__btf_value_type_id(map),
+		  test->btf_kv_notfound))
+		goto done;
+
+	if (!has_btf_ext)
+		goto skip;
+
+	/* get necessary program info */
+	info_len = sizeof(struct bpf_prog_info);
+	err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
+
+	if (CHECK(err == -1, "invalid get info (1st) errno:%d", errno)) {
+		fprintf(stderr, "%s\n", btf_log_buf);
+		err = -1;
+		goto done;
+	}
+	if (CHECK(info.nr_func_info != 3,
+		  "incorrect info.nr_func_info (1st) %d",
+		  info.nr_func_info)) {
+		err = -1;
+		goto done;
+	}
+	rec_size = info.func_info_rec_size;
+	if (CHECK(rec_size != sizeof(struct bpf_func_info),
+		  "incorrect info.func_info_rec_size (1st) %d\n", rec_size)) {
+		err = -1;
+		goto done;
+	}
+
+	func_info = malloc(info.nr_func_info * rec_size);
+	if (CHECK(!func_info, "out of memory")) {
+		err = -1;
+		goto done;
+	}
+
+	/* reset info to only retrieve func_info related data */
+	memset(&info, 0, sizeof(info));
+	info.nr_func_info = 3;
+	info.func_info_rec_size = rec_size;
+	info.func_info = ptr_to_u64(func_info);
+
+	err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
+
+	if (CHECK(err == -1, "invalid get info (2nd) errno:%d", errno)) {
+		fprintf(stderr, "%s\n", btf_log_buf);
+		err = -1;
+		goto done;
+	}
+	if (CHECK(info.nr_func_info != 3,
+		  "incorrect info.nr_func_info (2nd) %d",
+		  info.nr_func_info)) {
+		err = -1;
+		goto done;
+	}
+	if (CHECK(info.func_info_rec_size != rec_size,
+		  "incorrect info.func_info_rec_size (2nd) %d",
+		  info.func_info_rec_size)) {
+		err = -1;
+		goto done;
+	}
+
+	err = btf__get_from_id(info.btf_id, &btf);
+	if (CHECK(err, "cannot get btf from kernel, err: %d", err))
+		goto done;
+
+	/* check three functions */
+	finfo = func_info;
+	for (i = 0; i < 3; i++) {
+		const struct btf_type *t;
+		const char *fname;
+
+		t = btf__type_by_id(btf, finfo->type_id);
+		if (CHECK(!t, "btf__type_by_id failure: id %u",
+			  finfo->type_id)) {
+			err = -1;
+			goto done;
+		}
+
+		fname = btf__name_by_offset(btf, t->name_off);
+		err = strcmp(fname, expected_fnames[i]);
+		/* for the second and third functions in .text section,
+		 * the compiler may order them either way.
+		 */
+		if (i && err)
+			err = strcmp(fname, expected_fnames[3 - i]);
+		if (CHECK(err, "incorrect fname %s", fname ? : "")) {
+			err = -1;
+			goto done;
+		}
+
+		finfo = (void *)finfo + rec_size;
+	}
+
+skip:
+	return;
+
+done:
+	free(func_info);
+	bpf_object__close(obj);
+}
+
+#define BPF_LINE_INFO_ENC(insn_off, file_off, line_off, line_num, line_col) \
+	(insn_off), (file_off), (line_off), ((line_num) << 10 | ((line_col) & 0x3ff))
+
+static struct prog_info_raw_test {
+	const char *descr;
+	const char *str_sec;
+	const char *err_str;
+	__u32 raw_types[MAX_NR_RAW_U32];
+	__u32 str_sec_size;
+	struct bpf_insn insns[MAX_INSNS];
+	__u32 prog_type;
+	__u32 func_info[MAX_SUBPROGS][2];
+	__u32 func_info_rec_size;
+	__u32 func_info_cnt;
+	__u32 line_info[MAX_NR_RAW_U32];
+	__u32 line_info_rec_size;
+	__u32 nr_jited_ksyms;
+	bool expected_prog_load_failure;
+	__u32 dead_code_cnt;
+	__u32 dead_code_mask;
+	__u32 dead_func_cnt;
+	__u32 dead_func_mask;
+} info_raw_tests[] = {
+{
+	.descr = "func_type (main func + one sub)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),	/* [2] */
+		BTF_FUNC_PROTO_ENC(1, 2),			/* [3] */
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
+		BTF_FUNC_PROTO_ENC(1, 2),			/* [4] */
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
+		BTF_FUNC_ENC(NAME_TBD, 3),			/* [5] */
+		BTF_FUNC_ENC(NAME_TBD, 4),			/* [6] */
+		BTF_END_RAW,
+	},
+	.str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
+	.str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
+	.insns = {
+		BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
+		BPF_MOV64_IMM(BPF_REG_0, 1),
+		BPF_EXIT_INSN(),
+		BPF_MOV64_IMM(BPF_REG_0, 2),
+		BPF_EXIT_INSN(),
+	},
+	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
+	.func_info = { {0, 5}, {3, 6} },
+	.func_info_rec_size = 8,
+	.func_info_cnt = 2,
+	.line_info = { BTF_END_RAW },
+},
+
+{
+	.descr = "func_type (Incorrect func_info_rec_size)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),	/* [2] */
+		BTF_FUNC_PROTO_ENC(1, 2),			/* [3] */
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
+		BTF_FUNC_PROTO_ENC(1, 2),			/* [4] */
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
+		BTF_FUNC_ENC(NAME_TBD, 3),			/* [5] */
+		BTF_FUNC_ENC(NAME_TBD, 4),			/* [6] */
+		BTF_END_RAW,
+	},
+	.str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
+	.str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
+	.insns = {
+		BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
+		BPF_MOV64_IMM(BPF_REG_0, 1),
+		BPF_EXIT_INSN(),
+		BPF_MOV64_IMM(BPF_REG_0, 2),
+		BPF_EXIT_INSN(),
+	},
+	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
+	.func_info = { {0, 5}, {3, 6} },
+	.func_info_rec_size = 4,
+	.func_info_cnt = 2,
+	.line_info = { BTF_END_RAW },
+	.expected_prog_load_failure = true,
+},
+
+{
+	.descr = "func_type (Incorrect func_info_cnt)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),	/* [2] */
+		BTF_FUNC_PROTO_ENC(1, 2),			/* [3] */
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
+		BTF_FUNC_PROTO_ENC(1, 2),			/* [4] */
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
+		BTF_FUNC_ENC(NAME_TBD, 3),			/* [5] */
+		BTF_FUNC_ENC(NAME_TBD, 4),			/* [6] */
+		BTF_END_RAW,
+	},
+	.str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
+	.str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
+	.insns = {
+		BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
+		BPF_MOV64_IMM(BPF_REG_0, 1),
+		BPF_EXIT_INSN(),
+		BPF_MOV64_IMM(BPF_REG_0, 2),
+		BPF_EXIT_INSN(),
+	},
+	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
+	.func_info = { {0, 5}, {3, 6} },
+	.func_info_rec_size = 8,
+	.func_info_cnt = 1,
+	.line_info = { BTF_END_RAW },
+	.expected_prog_load_failure = true,
+},
+
+{
+	.descr = "func_type (Incorrect bpf_func_info.insn_off)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),	/* [2] */
+		BTF_FUNC_PROTO_ENC(1, 2),			/* [3] */
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
+		BTF_FUNC_PROTO_ENC(1, 2),			/* [4] */
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
+		BTF_FUNC_ENC(NAME_TBD, 3),			/* [5] */
+		BTF_FUNC_ENC(NAME_TBD, 4),			/* [6] */
+		BTF_END_RAW,
+	},
+	.str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
+	.str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
+	.insns = {
+		BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
+		BPF_MOV64_IMM(BPF_REG_0, 1),
+		BPF_EXIT_INSN(),
+		BPF_MOV64_IMM(BPF_REG_0, 2),
+		BPF_EXIT_INSN(),
+	},
+	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
+	.func_info = { {0, 5}, {2, 6} },
+	.func_info_rec_size = 8,
+	.func_info_cnt = 2,
+	.line_info = { BTF_END_RAW },
+	.expected_prog_load_failure = true,
+},
+
+{
+	.descr = "line_info (No subprog)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
+	.insns = {
+		BPF_MOV64_IMM(BPF_REG_0, 1),
+		BPF_MOV64_IMM(BPF_REG_1, 2),
+		BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
+		BPF_EXIT_INSN(),
+	},
+	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
+	.func_info_cnt = 0,
+	.line_info = {
+		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9),
+		BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
+		BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7),
+		BTF_END_RAW,
+	},
+	.line_info_rec_size = sizeof(struct bpf_line_info),
+	.nr_jited_ksyms = 1,
+},
+
+{
+	.descr = "line_info (No subprog. insn_off >= prog->len)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
+	.insns = {
+		BPF_MOV64_IMM(BPF_REG_0, 1),
+		BPF_MOV64_IMM(BPF_REG_1, 2),
+		BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
+		BPF_EXIT_INSN(),
+	},
+	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
+	.func_info_cnt = 0,
+	.line_info = {
+		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9),
+		BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
+		BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7),
+		BPF_LINE_INFO_ENC(4, 0, 0, 5, 6),
+		BTF_END_RAW,
+	},
+	.line_info_rec_size = sizeof(struct bpf_line_info),
+	.nr_jited_ksyms = 1,
+	.err_str = "line_info[4].insn_off",
+	.expected_prog_load_failure = true,
+},
+
+{
+	.descr = "line_info (Zero bpf insn code)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),	/* [2] */
+		BTF_TYPEDEF_ENC(NAME_TBD, 2),			/* [3] */
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0int\0unsigned long\0u64\0u64 a=1;\0return a;"),
+	.insns = {
+		BPF_LD_IMM64(BPF_REG_0, 1),
+		BPF_EXIT_INSN(),
+	},
+	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
+	.func_info_cnt = 0,
+	.line_info = {
+		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(1, 0, 0, 2, 9),
+		BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
+		BTF_END_RAW,
+	},
+	.line_info_rec_size = sizeof(struct bpf_line_info),
+	.nr_jited_ksyms = 1,
+	.err_str = "Invalid insn code at line_info[1]",
+	.expected_prog_load_failure = true,
+},
+
+{
+	.descr = "line_info (No subprog. zero tailing line_info",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
+	.insns = {
+		BPF_MOV64_IMM(BPF_REG_0, 1),
+		BPF_MOV64_IMM(BPF_REG_1, 2),
+		BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
+		BPF_EXIT_INSN(),
+	},
+	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
+	.func_info_cnt = 0,
+	.line_info = {
+		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 0,
+		BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9), 0,
+		BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8), 0,
+		BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7), 0,
+		BTF_END_RAW,
+	},
+	.line_info_rec_size = sizeof(struct bpf_line_info) + sizeof(__u32),
+	.nr_jited_ksyms = 1,
+},
+
+{
+	.descr = "line_info (No subprog. nonzero tailing line_info)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
+	.insns = {
+		BPF_MOV64_IMM(BPF_REG_0, 1),
+		BPF_MOV64_IMM(BPF_REG_1, 2),
+		BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
+		BPF_EXIT_INSN(),
+	},
+	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
+	.func_info_cnt = 0,
+	.line_info = {
+		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 0,
+		BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9), 0,
+		BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8), 0,
+		BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7), 1,
+		BTF_END_RAW,
+	},
+	.line_info_rec_size = sizeof(struct bpf_line_info) + sizeof(__u32),
+	.nr_jited_ksyms = 1,
+	.err_str = "nonzero tailing record in line_info",
+	.expected_prog_load_failure = true,
+},
+
+{
+	.descr = "line_info (subprog)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
+	.insns = {
+		BPF_MOV64_IMM(BPF_REG_2, 1),
+		BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
+		BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
+		BPF_CALL_REL(1),
+		BPF_EXIT_INSN(),
+		BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
+		BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
+		BPF_EXIT_INSN(),
+	},
+	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
+	.func_info_cnt = 0,
+	.line_info = {
+		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
+		BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8),
+		BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
+		BTF_END_RAW,
+	},
+	.line_info_rec_size = sizeof(struct bpf_line_info),
+	.nr_jited_ksyms = 2,
+},
+
+{
+	.descr = "line_info (subprog + func_info)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_FUNC_PROTO_ENC(1, 1),			/* [2] */
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
+		BTF_FUNC_ENC(NAME_TBD, 2),			/* [3] */
+		BTF_FUNC_ENC(NAME_TBD, 2),			/* [4] */
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0int\0x\0sub\0main\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
+	.insns = {
+		BPF_MOV64_IMM(BPF_REG_2, 1),
+		BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
+		BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
+		BPF_CALL_REL(1),
+		BPF_EXIT_INSN(),
+		BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
+		BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
+		BPF_EXIT_INSN(),
+	},
+	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
+	.func_info_cnt = 2,
+	.func_info_rec_size = 8,
+	.func_info = { {0, 4}, {5, 3} },
+	.line_info = {
+		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
+		BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8),
+		BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
+		BTF_END_RAW,
+	},
+	.line_info_rec_size = sizeof(struct bpf_line_info),
+	.nr_jited_ksyms = 2,
+},
+
+{
+	.descr = "line_info (subprog. missing 1st func line info)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
+	.insns = {
+		BPF_MOV64_IMM(BPF_REG_2, 1),
+		BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
+		BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
+		BPF_CALL_REL(1),
+		BPF_EXIT_INSN(),
+		BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
+		BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
+		BPF_EXIT_INSN(),
+	},
+	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
+	.func_info_cnt = 0,
+	.line_info = {
+		BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
+		BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8),
+		BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
+		BTF_END_RAW,
+	},
+	.line_info_rec_size = sizeof(struct bpf_line_info),
+	.nr_jited_ksyms = 2,
+	.err_str = "missing bpf_line_info for func#0",
+	.expected_prog_load_failure = true,
+},
+
+{
+	.descr = "line_info (subprog. missing 2nd func line info)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
+	.insns = {
+		BPF_MOV64_IMM(BPF_REG_2, 1),
+		BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
+		BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
+		BPF_CALL_REL(1),
+		BPF_EXIT_INSN(),
+		BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
+		BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
+		BPF_EXIT_INSN(),
+	},
+	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
+	.func_info_cnt = 0,
+	.line_info = {
+		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
+		BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 3, 8),
+		BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
+		BTF_END_RAW,
+	},
+	.line_info_rec_size = sizeof(struct bpf_line_info),
+	.nr_jited_ksyms = 2,
+	.err_str = "missing bpf_line_info for func#1",
+	.expected_prog_load_failure = true,
+},
+
+{
+	.descr = "line_info (subprog. unordered insn offset)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
+	.insns = {
+		BPF_MOV64_IMM(BPF_REG_2, 1),
+		BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
+		BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
+		BPF_CALL_REL(1),
+		BPF_EXIT_INSN(),
+		BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
+		BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
+		BPF_EXIT_INSN(),
+	},
+	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
+	.func_info_cnt = 0,
+	.line_info = {
+		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 2, 9),
+		BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
+		BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
+		BTF_END_RAW,
+	},
+	.line_info_rec_size = sizeof(struct bpf_line_info),
+	.nr_jited_ksyms = 2,
+	.err_str = "Invalid line_info[2].insn_off",
+	.expected_prog_load_failure = true,
+},
+
+{
+	.descr = "line_info (dead start)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0int\0/* dead jmp */\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
+	.insns = {
+		BPF_JMP_IMM(BPF_JA, 0, 0, 0),
+		BPF_MOV64_IMM(BPF_REG_0, 1),
+		BPF_MOV64_IMM(BPF_REG_1, 2),
+		BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
+		BPF_EXIT_INSN(),
+	},
+	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
+	.func_info_cnt = 0,
+	.line_info = {
+		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9),
+		BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
+		BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7),
+		BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 5, 6),
+		BTF_END_RAW,
+	},
+	.line_info_rec_size = sizeof(struct bpf_line_info),
+	.nr_jited_ksyms = 1,
+	.dead_code_cnt = 1,
+	.dead_code_mask = 0x01,
+},
+
+{
+	.descr = "line_info (dead end)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0/* dead jmp */\0return a + b;\0/* dead exit */"),
+	.insns = {
+		BPF_MOV64_IMM(BPF_REG_0, 1),
+		BPF_MOV64_IMM(BPF_REG_1, 2),
+		BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
+		BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 10, 1),
+		BPF_EXIT_INSN(),
+		BPF_EXIT_INSN(),
+	},
+	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
+	.func_info_cnt = 0,
+	.line_info = {
+		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 12),
+		BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 11),
+		BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 10),
+		BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 9),
+		BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 5, 8),
+		BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 6, 7),
+		BTF_END_RAW,
+	},
+	.line_info_rec_size = sizeof(struct bpf_line_info),
+	.nr_jited_ksyms = 1,
+	.dead_code_cnt = 2,
+	.dead_code_mask = 0x28,
+},
+
+{
+	.descr = "line_info (dead code + subprog + func_info)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_FUNC_PROTO_ENC(1, 1),			/* [2] */
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
+		BTF_FUNC_ENC(NAME_TBD, 2),			/* [3] */
+		BTF_FUNC_ENC(NAME_TBD, 2),			/* [4] */
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0int\0x\0sub\0main\0int a=1+1;\0/* dead jmp */"
+		    "\0/* dead */\0/* dead */\0/* dead */\0/* dead */"
+		    "\0/* dead */\0/* dead */\0/* dead */\0/* dead */"
+		    "\0return func(a);\0b+=1;\0return b;"),
+	.insns = {
+		BPF_MOV64_IMM(BPF_REG_2, 1),
+		BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
+		BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
+		BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 8),
+		BPF_MOV64_IMM(BPF_REG_2, 1),
+		BPF_MOV64_IMM(BPF_REG_2, 1),
+		BPF_MOV64_IMM(BPF_REG_2, 1),
+		BPF_MOV64_IMM(BPF_REG_2, 1),
+		BPF_MOV64_IMM(BPF_REG_2, 1),
+		BPF_MOV64_IMM(BPF_REG_2, 1),
+		BPF_MOV64_IMM(BPF_REG_2, 1),
+		BPF_MOV64_IMM(BPF_REG_2, 1),
+		BPF_CALL_REL(1),
+		BPF_EXIT_INSN(),
+		BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
+		BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
+		BPF_EXIT_INSN(),
+	},
+	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
+	.func_info_cnt = 2,
+	.func_info_rec_size = 8,
+	.func_info = { {0, 4}, {14, 3} },
+	.line_info = {
+		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(8, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(9, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(10, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(11, 0, NAME_TBD, 2, 9),
+		BPF_LINE_INFO_ENC(12, 0, NAME_TBD, 2, 9),
+		BPF_LINE_INFO_ENC(14, 0, NAME_TBD, 3, 8),
+		BPF_LINE_INFO_ENC(16, 0, NAME_TBD, 4, 7),
+		BTF_END_RAW,
+	},
+	.line_info_rec_size = sizeof(struct bpf_line_info),
+	.nr_jited_ksyms = 2,
+	.dead_code_cnt = 9,
+	.dead_code_mask = 0x3fe,
+},
+
+{
+	.descr = "line_info (dead subprog)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_FUNC_PROTO_ENC(1, 1),			/* [2] */
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
+		BTF_FUNC_ENC(NAME_TBD, 2),			/* [3] */
+		BTF_FUNC_ENC(NAME_TBD, 2),			/* [4] */
+		BTF_FUNC_ENC(NAME_TBD, 2),			/* [5] */
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0int\0x\0dead\0main\0func\0int a=1+1;\0/* live call */"
+		    "\0return 0;\0return 0;\0/* dead */\0/* dead */"
+		    "\0/* dead */\0return bla + 1;\0return bla + 1;"
+		    "\0return bla + 1;\0return func(a);\0b+=1;\0return b;"),
+	.insns = {
+		BPF_MOV64_IMM(BPF_REG_2, 1),
+		BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
+		BPF_CALL_REL(3),
+		BPF_CALL_REL(5),
+		BPF_MOV64_IMM(BPF_REG_0, 0),
+		BPF_EXIT_INSN(),
+		BPF_MOV64_IMM(BPF_REG_0, 0),
+		BPF_CALL_REL(1),
+		BPF_EXIT_INSN(),
+		BPF_MOV64_REG(BPF_REG_0, 2),
+		BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
+		BPF_EXIT_INSN(),
+	},
+	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
+	.func_info_cnt = 3,
+	.func_info_rec_size = 8,
+		.func_info = { {0, 4}, {6, 3}, {9, 5} },
+	.line_info = {
+		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(8, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(9, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(10, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(11, 0, NAME_TBD, 2, 9),
+		BTF_END_RAW,
+	},
+	.line_info_rec_size = sizeof(struct bpf_line_info),
+	.nr_jited_ksyms = 2,
+	.dead_code_cnt = 3,
+	.dead_code_mask = 0x70,
+	.dead_func_cnt = 1,
+	.dead_func_mask = 0x2,
+},
+
+{
+	.descr = "line_info (dead last subprog)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_FUNC_PROTO_ENC(1, 1),			/* [2] */
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
+		BTF_FUNC_ENC(NAME_TBD, 2),			/* [3] */
+		BTF_FUNC_ENC(NAME_TBD, 2),			/* [5] */
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0int\0x\0dead\0main\0int a=1+1;\0/* live call */"
+		    "\0return 0;\0/* dead */\0/* dead */"),
+	.insns = {
+		BPF_MOV64_IMM(BPF_REG_2, 1),
+		BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
+		BPF_CALL_REL(2),
+		BPF_MOV64_IMM(BPF_REG_0, 0),
+		BPF_EXIT_INSN(),
+		BPF_MOV64_IMM(BPF_REG_0, 0),
+		BPF_EXIT_INSN(),
+	},
+	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
+	.func_info_cnt = 2,
+	.func_info_rec_size = 8,
+		.func_info = { {0, 4}, {5, 3} },
+	.line_info = {
+		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
+		BTF_END_RAW,
+	},
+	.line_info_rec_size = sizeof(struct bpf_line_info),
+	.nr_jited_ksyms = 1,
+	.dead_code_cnt = 2,
+	.dead_code_mask = 0x18,
+	.dead_func_cnt = 1,
+	.dead_func_mask = 0x2,
+},
+
+{
+	.descr = "line_info (dead subprog + dead start)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_FUNC_PROTO_ENC(1, 1),			/* [2] */
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
+		BTF_FUNC_ENC(NAME_TBD, 2),			/* [3] */
+		BTF_FUNC_ENC(NAME_TBD, 2),			/* [4] */
+		BTF_FUNC_ENC(NAME_TBD, 2),			/* [5] */
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0int\0x\0dead\0main\0func\0int a=1+1;\0/* dead */"
+		    "\0return 0;\0return 0;\0return 0;"
+		    "\0/* dead */\0/* dead */\0/* dead */\0/* dead */"
+		    "\0return b + 1;\0return b + 1;\0return b + 1;"),
+	.insns = {
+		BPF_JMP_IMM(BPF_JA, 0, 0, 0),
+		BPF_MOV64_IMM(BPF_REG_2, 1),
+		BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
+		BPF_CALL_REL(3),
+		BPF_CALL_REL(5),
+		BPF_MOV64_IMM(BPF_REG_0, 0),
+		BPF_EXIT_INSN(),
+		BPF_MOV64_IMM(BPF_REG_0, 0),
+		BPF_CALL_REL(1),
+		BPF_EXIT_INSN(),
+		BPF_JMP_IMM(BPF_JA, 0, 0, 0),
+		BPF_MOV64_REG(BPF_REG_0, 2),
+		BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
+		BPF_EXIT_INSN(),
+	},
+	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
+	.func_info_cnt = 3,
+	.func_info_rec_size = 8,
+		.func_info = { {0, 4}, {7, 3}, {10, 5} },
+	.line_info = {
+		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(8, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(9, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(10, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(11, 0, NAME_TBD, 2, 9),
+		BPF_LINE_INFO_ENC(12, 0, NAME_TBD, 2, 9),
+		BPF_LINE_INFO_ENC(13, 0, NAME_TBD, 2, 9),
+		BTF_END_RAW,
+	},
+	.line_info_rec_size = sizeof(struct bpf_line_info),
+	.nr_jited_ksyms = 2,
+	.dead_code_cnt = 5,
+	.dead_code_mask = 0x1e2,
+	.dead_func_cnt = 1,
+	.dead_func_mask = 0x2,
+},
+
+{
+	.descr = "line_info (dead subprog + dead start w/ move)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_FUNC_PROTO_ENC(1, 1),			/* [2] */
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
+		BTF_FUNC_ENC(NAME_TBD, 2),			/* [3] */
+		BTF_FUNC_ENC(NAME_TBD, 2),			/* [4] */
+		BTF_FUNC_ENC(NAME_TBD, 2),			/* [5] */
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0int\0x\0dead\0main\0func\0int a=1+1;\0/* live call */"
+		    "\0return 0;\0return 0;\0/* dead */\0/* dead */"
+		    "\0/* dead */\0return bla + 1;\0return bla + 1;"
+		    "\0return bla + 1;\0return func(a);\0b+=1;\0return b;"),
+	.insns = {
+		BPF_MOV64_IMM(BPF_REG_2, 1),
+		BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
+		BPF_CALL_REL(3),
+		BPF_CALL_REL(5),
+		BPF_MOV64_IMM(BPF_REG_0, 0),
+		BPF_EXIT_INSN(),
+		BPF_MOV64_IMM(BPF_REG_0, 0),
+		BPF_CALL_REL(1),
+		BPF_EXIT_INSN(),
+		BPF_JMP_IMM(BPF_JA, 0, 0, 0),
+		BPF_MOV64_REG(BPF_REG_0, 2),
+		BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
+		BPF_EXIT_INSN(),
+	},
+	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
+	.func_info_cnt = 3,
+	.func_info_rec_size = 8,
+		.func_info = { {0, 4}, {6, 3}, {9, 5} },
+	.line_info = {
+		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(8, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(9, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(11, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(12, 0, NAME_TBD, 2, 9),
+		BTF_END_RAW,
+	},
+	.line_info_rec_size = sizeof(struct bpf_line_info),
+	.nr_jited_ksyms = 2,
+	.dead_code_cnt = 3,
+	.dead_code_mask = 0x70,
+	.dead_func_cnt = 1,
+	.dead_func_mask = 0x2,
+},
+
+{
+	.descr = "line_info (dead end + subprog start w/ no linfo)",
+	.raw_types = {
+		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+		BTF_FUNC_PROTO_ENC(1, 1),			/* [2] */
+			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
+		BTF_FUNC_ENC(NAME_TBD, 2),			/* [3] */
+		BTF_FUNC_ENC(NAME_TBD, 2),			/* [4] */
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0int\0x\0main\0func\0/* main linfo */\0/* func linfo */"),
+	.insns = {
+		BPF_MOV64_IMM(BPF_REG_0, 0),
+		BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 1, 3),
+		BPF_CALL_REL(3),
+		BPF_MOV64_IMM(BPF_REG_0, 0),
+		BPF_EXIT_INSN(),
+		BPF_EXIT_INSN(),
+		BPF_JMP_IMM(BPF_JA, 0, 0, 0),
+		BPF_EXIT_INSN(),
+	},
+	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
+	.func_info_cnt = 2,
+	.func_info_rec_size = 8,
+	.func_info = { {0, 3}, {6, 4}, },
+	.line_info = {
+		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
+		BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
+		BTF_END_RAW,
+	},
+	.line_info_rec_size = sizeof(struct bpf_line_info),
+	.nr_jited_ksyms = 2,
+},
+
+};
+
+static size_t probe_prog_length(const struct bpf_insn *fp)
+{
+	size_t len;
+
+	for (len = MAX_INSNS - 1; len > 0; --len)
+		if (fp[len].code != 0 || fp[len].imm != 0)
+			break;
+	return len + 1;
+}
+
+static __u32 *patch_name_tbd(const __u32 *raw_u32,
+			     const char *str, __u32 str_off,
+			     unsigned int str_sec_size,
+			     unsigned int *ret_size)
+{
+	int i, raw_u32_size = get_raw_sec_size(raw_u32);
+	const char *end_str = str + str_sec_size;
+	const char *next_str = str + str_off;
+	__u32 *new_u32 = NULL;
+
+	if (raw_u32_size == -1)
+		return ERR_PTR(-EINVAL);
+
+	if (!raw_u32_size) {
+		*ret_size = 0;
+		return NULL;
+	}
+
+	new_u32 = malloc(raw_u32_size);
+	if (!new_u32)
+		return ERR_PTR(-ENOMEM);
+
+	for (i = 0; i < raw_u32_size / sizeof(raw_u32[0]); i++) {
+		if (raw_u32[i] == NAME_TBD) {
+			next_str = get_next_str(next_str, end_str);
+			if (CHECK(!next_str, "Error in getting next_str\n")) {
+				free(new_u32);
+				return ERR_PTR(-EINVAL);
+			}
+			new_u32[i] = next_str - str;
+			next_str += strlen(next_str);
+		} else {
+			new_u32[i] = raw_u32[i];
+		}
+	}
+
+	*ret_size = raw_u32_size;
+	return new_u32;
+}
+
+static int test_get_finfo(const struct prog_info_raw_test *test,
+			  int prog_fd)
+{
+	struct bpf_prog_info info = {};
+	struct bpf_func_info *finfo;
+	__u32 info_len, rec_size, i;
+	void *func_info = NULL;
+	__u32 nr_func_info;
+	int err;
+
+	/* get necessary lens */
+	info_len = sizeof(struct bpf_prog_info);
+	err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
+	if (CHECK(err == -1, "invalid get info (1st) errno:%d", errno)) {
+		fprintf(stderr, "%s\n", btf_log_buf);
+		return -1;
+	}
+	nr_func_info = test->func_info_cnt - test->dead_func_cnt;
+	if (CHECK(info.nr_func_info != nr_func_info,
+		  "incorrect info.nr_func_info (1st) %d",
+		  info.nr_func_info)) {
+		return -1;
+	}
+
+	rec_size = info.func_info_rec_size;
+	if (CHECK(rec_size != sizeof(struct bpf_func_info),
+		  "incorrect info.func_info_rec_size (1st) %d", rec_size)) {
+		return -1;
+	}
+
+	if (!info.nr_func_info)
+		return 0;
+
+	func_info = malloc(info.nr_func_info * rec_size);
+	if (CHECK(!func_info, "out of memory"))
+		return -1;
+
+	/* reset info to only retrieve func_info related data */
+	memset(&info, 0, sizeof(info));
+	info.nr_func_info = nr_func_info;
+	info.func_info_rec_size = rec_size;
+	info.func_info = ptr_to_u64(func_info);
+	err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
+	if (CHECK(err == -1, "invalid get info (2nd) errno:%d", errno)) {
+		fprintf(stderr, "%s\n", btf_log_buf);
+		err = -1;
+		goto done;
+	}
+	if (CHECK(info.nr_func_info != nr_func_info,
+		  "incorrect info.nr_func_info (2nd) %d",
+		  info.nr_func_info)) {
+		err = -1;
+		goto done;
+	}
+	if (CHECK(info.func_info_rec_size != rec_size,
+		  "incorrect info.func_info_rec_size (2nd) %d",
+		  info.func_info_rec_size)) {
+		err = -1;
+		goto done;
+	}
+
+	finfo = func_info;
+	for (i = 0; i < nr_func_info; i++) {
+		if (test->dead_func_mask & (1 << i))
+			continue;
+		if (CHECK(finfo->type_id != test->func_info[i][1],
+			  "incorrect func_type %u expected %u",
+			  finfo->type_id, test->func_info[i][1])) {
+			err = -1;
+			goto done;
+		}
+		finfo = (void *)finfo + rec_size;
+	}
+
+	err = 0;
+
+done:
+	free(func_info);
+	return err;
+}
+
+static int test_get_linfo(const struct prog_info_raw_test *test,
+			  const void *patched_linfo,
+			  __u32 cnt, int prog_fd)
+{
+	__u32 i, info_len, nr_jited_ksyms, nr_jited_func_lens;
+	__u64 *jited_linfo = NULL, *jited_ksyms = NULL;
+	__u32 rec_size, jited_rec_size, jited_cnt;
+	struct bpf_line_info *linfo = NULL;
+	__u32 cur_func_len, ksyms_found;
+	struct bpf_prog_info info = {};
+	__u32 *jited_func_lens = NULL;
+	__u64 cur_func_ksyms;
+	__u32 dead_insns;
+	int err;
+
+	jited_cnt = cnt;
+	rec_size = sizeof(*linfo);
+	jited_rec_size = sizeof(*jited_linfo);
+	if (test->nr_jited_ksyms)
+		nr_jited_ksyms = test->nr_jited_ksyms;
+	else
+		nr_jited_ksyms = test->func_info_cnt - test->dead_func_cnt;
+	nr_jited_func_lens = nr_jited_ksyms;
+
+	info_len = sizeof(struct bpf_prog_info);
+	err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
+	if (CHECK(err == -1, "err:%d errno:%d", err, errno)) {
+		err = -1;
+		goto done;
+	}
+
+	if (!info.jited_prog_len) {
+		/* prog is not jited */
+		jited_cnt = 0;
+		nr_jited_ksyms = 1;
+		nr_jited_func_lens = 1;
+	}
+
+	if (CHECK(info.nr_line_info != cnt ||
+		  info.nr_jited_line_info != jited_cnt ||
+		  info.nr_jited_ksyms != nr_jited_ksyms ||
+		  info.nr_jited_func_lens != nr_jited_func_lens ||
+		  (!info.nr_line_info && info.nr_jited_line_info),
+		  "info: nr_line_info:%u(expected:%u) nr_jited_line_info:%u(expected:%u) nr_jited_ksyms:%u(expected:%u) nr_jited_func_lens:%u(expected:%u)",
+		  info.nr_line_info, cnt,
+		  info.nr_jited_line_info, jited_cnt,
+		  info.nr_jited_ksyms, nr_jited_ksyms,
+		  info.nr_jited_func_lens, nr_jited_func_lens)) {
+		err = -1;
+		goto done;
+	}
+
+	if (CHECK(info.line_info_rec_size != sizeof(struct bpf_line_info) ||
+		  info.jited_line_info_rec_size != sizeof(__u64),
+		  "info: line_info_rec_size:%u(userspace expected:%u) jited_line_info_rec_size:%u(userspace expected:%u)",
+		  info.line_info_rec_size, rec_size,
+		  info.jited_line_info_rec_size, jited_rec_size)) {
+		err = -1;
+		goto done;
+	}
+
+	if (!cnt)
+		return 0;
+
+	rec_size = info.line_info_rec_size;
+	jited_rec_size = info.jited_line_info_rec_size;
+
+	memset(&info, 0, sizeof(info));
+
+	linfo = calloc(cnt, rec_size);
+	if (CHECK(!linfo, "!linfo")) {
+		err = -1;
+		goto done;
+	}
+	info.nr_line_info = cnt;
+	info.line_info_rec_size = rec_size;
+	info.line_info = ptr_to_u64(linfo);
+
+	if (jited_cnt) {
+		jited_linfo = calloc(jited_cnt, jited_rec_size);
+		jited_ksyms = calloc(nr_jited_ksyms, sizeof(*jited_ksyms));
+		jited_func_lens = calloc(nr_jited_func_lens,
+					 sizeof(*jited_func_lens));
+		if (CHECK(!jited_linfo || !jited_ksyms || !jited_func_lens,
+			  "jited_linfo:%p jited_ksyms:%p jited_func_lens:%p",
+			  jited_linfo, jited_ksyms, jited_func_lens)) {
+			err = -1;
+			goto done;
+		}
+
+		info.nr_jited_line_info = jited_cnt;
+		info.jited_line_info_rec_size = jited_rec_size;
+		info.jited_line_info = ptr_to_u64(jited_linfo);
+		info.nr_jited_ksyms = nr_jited_ksyms;
+		info.jited_ksyms = ptr_to_u64(jited_ksyms);
+		info.nr_jited_func_lens = nr_jited_func_lens;
+		info.jited_func_lens = ptr_to_u64(jited_func_lens);
+	}
+
+	err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
+
+	/*
+	 * Only recheck the info.*line_info* fields.
+	 * Other fields are not the concern of this test.
+	 */
+	if (CHECK(err == -1 ||
+		  info.nr_line_info != cnt ||
+		  (jited_cnt && !info.jited_line_info) ||
+		  info.nr_jited_line_info != jited_cnt ||
+		  info.line_info_rec_size != rec_size ||
+		  info.jited_line_info_rec_size != jited_rec_size,
+		  "err:%d errno:%d info: nr_line_info:%u(expected:%u) nr_jited_line_info:%u(expected:%u) line_info_rec_size:%u(expected:%u) jited_linfo_rec_size:%u(expected:%u) line_info:%p jited_line_info:%p",
+		  err, errno,
+		  info.nr_line_info, cnt,
+		  info.nr_jited_line_info, jited_cnt,
+		  info.line_info_rec_size, rec_size,
+		  info.jited_line_info_rec_size, jited_rec_size,
+		  (void *)(long)info.line_info,
+		  (void *)(long)info.jited_line_info)) {
+		err = -1;
+		goto done;
+	}
+
+	dead_insns = 0;
+	while (test->dead_code_mask & (1 << dead_insns))
+		dead_insns++;
+
+	CHECK(linfo[0].insn_off, "linfo[0].insn_off:%u",
+	      linfo[0].insn_off);
+	for (i = 1; i < cnt; i++) {
+		const struct bpf_line_info *expected_linfo;
+
+		while (test->dead_code_mask & (1 << (i + dead_insns)))
+			dead_insns++;
+
+		expected_linfo = patched_linfo +
+			((i + dead_insns) * test->line_info_rec_size);
+		if (CHECK(linfo[i].insn_off <= linfo[i - 1].insn_off,
+			  "linfo[%u].insn_off:%u <= linfo[%u].insn_off:%u",
+			  i, linfo[i].insn_off,
+			  i - 1, linfo[i - 1].insn_off)) {
+			err = -1;
+			goto done;
+		}
+		if (CHECK(linfo[i].file_name_off != expected_linfo->file_name_off ||
+			  linfo[i].line_off != expected_linfo->line_off ||
+			  linfo[i].line_col != expected_linfo->line_col,
+			  "linfo[%u] (%u, %u, %u) != (%u, %u, %u)", i,
+			  linfo[i].file_name_off,
+			  linfo[i].line_off,
+			  linfo[i].line_col,
+			  expected_linfo->file_name_off,
+			  expected_linfo->line_off,
+			  expected_linfo->line_col)) {
+			err = -1;
+			goto done;
+		}
+	}
+
+	if (!jited_cnt) {
+		fprintf(stderr, "not jited. skipping jited_line_info check. ");
+		err = 0;
+		goto done;
+	}
+
+	if (CHECK(jited_linfo[0] != jited_ksyms[0],
+		  "jited_linfo[0]:%lx != jited_ksyms[0]:%lx",
+		  (long)(jited_linfo[0]), (long)(jited_ksyms[0]))) {
+		err = -1;
+		goto done;
+	}
+
+	ksyms_found = 1;
+	cur_func_len = jited_func_lens[0];
+	cur_func_ksyms = jited_ksyms[0];
+	for (i = 1; i < jited_cnt; i++) {
+		if (ksyms_found < nr_jited_ksyms &&
+		    jited_linfo[i] == jited_ksyms[ksyms_found]) {
+			cur_func_ksyms = jited_ksyms[ksyms_found];
+			cur_func_len = jited_ksyms[ksyms_found];
+			ksyms_found++;
+			continue;
+		}
+
+		if (CHECK(jited_linfo[i] <= jited_linfo[i - 1],
+			  "jited_linfo[%u]:%lx <= jited_linfo[%u]:%lx",
+			  i, (long)jited_linfo[i],
+			  i - 1, (long)(jited_linfo[i - 1]))) {
+			err = -1;
+			goto done;
+		}
+
+		if (CHECK(jited_linfo[i] - cur_func_ksyms > cur_func_len,
+			  "jited_linfo[%u]:%lx - %lx > %u",
+			  i, (long)jited_linfo[i], (long)cur_func_ksyms,
+			  cur_func_len)) {
+			err = -1;
+			goto done;
+		}
+	}
+
+	if (CHECK(ksyms_found != nr_jited_ksyms,
+		  "ksyms_found:%u != nr_jited_ksyms:%u",
+		  ksyms_found, nr_jited_ksyms)) {
+		err = -1;
+		goto done;
+	}
+
+	err = 0;
+
+done:
+	free(linfo);
+	free(jited_linfo);
+	free(jited_ksyms);
+	free(jited_func_lens);
+	return err;
+}
+
+static void do_test_info_raw(unsigned int test_num)
+{
+	const struct prog_info_raw_test *test = &info_raw_tests[test_num - 1];
+	unsigned int raw_btf_size, linfo_str_off, linfo_size;
+	int btf_fd = -1, prog_fd = -1, err = 0;
+	void *raw_btf, *patched_linfo = NULL;
+	const char *ret_next_str;
+	union bpf_attr attr = {};
+
+	if (!test__start_subtest(test->descr))
+		return;
+
+	raw_btf = btf_raw_create(&hdr_tmpl, test->raw_types,
+				 test->str_sec, test->str_sec_size,
+				 &raw_btf_size, &ret_next_str);
+	if (!raw_btf)
+		return;
+
+	*btf_log_buf = '\0';
+	btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
+			      btf_log_buf, BTF_LOG_BUF_SIZE,
+			      always_log);
+	free(raw_btf);
+
+	if (CHECK(btf_fd == -1, "invalid btf_fd errno:%d", errno)) {
+		err = -1;
+		goto done;
+	}
+
+	if (*btf_log_buf && always_log)
+		fprintf(stderr, "\n%s", btf_log_buf);
+	*btf_log_buf = '\0';
+
+	linfo_str_off = ret_next_str - test->str_sec;
+	patched_linfo = patch_name_tbd(test->line_info,
+				       test->str_sec, linfo_str_off,
+				       test->str_sec_size, &linfo_size);
+	if (IS_ERR(patched_linfo)) {
+		fprintf(stderr, "error in creating raw bpf_line_info");
+		err = -1;
+		goto done;
+	}
+
+	attr.prog_type = test->prog_type;
+	attr.insns = ptr_to_u64(test->insns);
+	attr.insn_cnt = probe_prog_length(test->insns);
+	attr.license = ptr_to_u64("GPL");
+	attr.prog_btf_fd = btf_fd;
+	attr.func_info_rec_size = test->func_info_rec_size;
+	attr.func_info_cnt = test->func_info_cnt;
+	attr.func_info = ptr_to_u64(test->func_info);
+	attr.log_buf = ptr_to_u64(btf_log_buf);
+	attr.log_size = BTF_LOG_BUF_SIZE;
+	attr.log_level = 1;
+	if (linfo_size) {
+		attr.line_info_rec_size = test->line_info_rec_size;
+		attr.line_info = ptr_to_u64(patched_linfo);
+		attr.line_info_cnt = linfo_size / attr.line_info_rec_size;
+	}
+
+	prog_fd = syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr));
+	err = ((prog_fd == -1) != test->expected_prog_load_failure);
+	if (CHECK(err, "prog_fd:%d expected_prog_load_failure:%u errno:%d",
+		  prog_fd, test->expected_prog_load_failure, errno) ||
+	    CHECK(test->err_str && !strstr(btf_log_buf, test->err_str),
+		  "expected err_str:%s", test->err_str)) {
+		err = -1;
+		goto done;
+	}
+
+	if (prog_fd == -1)
+		goto done;
+
+	err = test_get_finfo(test, prog_fd);
+	if (err)
+		goto done;
+
+	err = test_get_linfo(test, patched_linfo,
+			     attr.line_info_cnt - test->dead_code_cnt,
+			     prog_fd);
+	if (err)
+		goto done;
+
+done:
+	if (*btf_log_buf && (err || always_log))
+		fprintf(stderr, "\n%s", btf_log_buf);
+
+	if (btf_fd != -1)
+		close(btf_fd);
+	if (prog_fd != -1)
+		close(prog_fd);
+
+	if (!IS_ERR(patched_linfo))
+		free(patched_linfo);
+}
+
+struct btf_raw_data {
+	__u32 raw_types[MAX_NR_RAW_U32];
+	const char *str_sec;
+	__u32 str_sec_size;
+};
+
+struct btf_dedup_test {
+	const char *descr;
+	struct btf_raw_data input;
+	struct btf_raw_data expect;
+	struct btf_dedup_opts opts;
+};
+
+const struct btf_dedup_test dedup_tests[] = {
+
+{
+	.descr = "dedup: unused strings filtering",
+	.input = {
+		.raw_types = {
+			BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 32, 4),
+			BTF_TYPE_INT_ENC(NAME_NTH(5), BTF_INT_SIGNED, 0, 64, 8),
+			BTF_END_RAW,
+		},
+		BTF_STR_SEC("\0unused\0int\0foo\0bar\0long"),
+	},
+	.expect = {
+		.raw_types = {
+			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
+			BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 64, 8),
+			BTF_END_RAW,
+		},
+		BTF_STR_SEC("\0int\0long"),
+	},
+	.opts = {
+		.dont_resolve_fwds = false,
+	},
+},
+{
+	.descr = "dedup: strings deduplication",
+	.input = {
+		.raw_types = {
+			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
+			BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 64, 8),
+			BTF_TYPE_INT_ENC(NAME_NTH(3), BTF_INT_SIGNED, 0, 32, 4),
+			BTF_TYPE_INT_ENC(NAME_NTH(4), BTF_INT_SIGNED, 0, 64, 8),
+			BTF_TYPE_INT_ENC(NAME_NTH(5), BTF_INT_SIGNED, 0, 32, 4),
+			BTF_END_RAW,
+		},
+		BTF_STR_SEC("\0int\0long int\0int\0long int\0int"),
+	},
+	.expect = {
+		.raw_types = {
+			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
+			BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 64, 8),
+			BTF_END_RAW,
+		},
+		BTF_STR_SEC("\0int\0long int"),
+	},
+	.opts = {
+		.dont_resolve_fwds = false,
+	},
+},
+{
+	.descr = "dedup: struct example #1",
+	/*
+	 * struct s {
+	 *	struct s *next;
+	 *	const int *a;
+	 *	int b[16];
+	 *	int c;
+	 * }
+	 */
+	.input = {
+		.raw_types = {
+			/* int */
+			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+			/* int[16] */
+			BTF_TYPE_ARRAY_ENC(1, 1, 16),					/* [2] */
+			/* struct s { */
+			BTF_STRUCT_ENC(NAME_NTH(2), 4, 84),				/* [3] */
+				BTF_MEMBER_ENC(NAME_NTH(3), 4, 0),	/* struct s *next;	*/
+				BTF_MEMBER_ENC(NAME_NTH(4), 5, 64),	/* const int *a;	*/
+				BTF_MEMBER_ENC(NAME_NTH(5), 2, 128),	/* int b[16];		*/
+				BTF_MEMBER_ENC(NAME_NTH(6), 1, 640),	/* int c;		*/
+			/* ptr -> [3] struct s */
+			BTF_PTR_ENC(3),							/* [4] */
+			/* ptr -> [6] const int */
+			BTF_PTR_ENC(6),							/* [5] */
+			/* const -> [1] int */
+			BTF_CONST_ENC(1),						/* [6] */
+
+			/* full copy of the above */
+			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),	/* [7] */
+			BTF_TYPE_ARRAY_ENC(7, 7, 16),					/* [8] */
+			BTF_STRUCT_ENC(NAME_NTH(2), 4, 84),				/* [9] */
+				BTF_MEMBER_ENC(NAME_NTH(3), 10, 0),
+				BTF_MEMBER_ENC(NAME_NTH(4), 11, 64),
+				BTF_MEMBER_ENC(NAME_NTH(5), 8, 128),
+				BTF_MEMBER_ENC(NAME_NTH(6), 7, 640),
+			BTF_PTR_ENC(9),							/* [10] */
+			BTF_PTR_ENC(12),						/* [11] */
+			BTF_CONST_ENC(7),						/* [12] */
+			BTF_END_RAW,
+		},
+		BTF_STR_SEC("\0int\0s\0next\0a\0b\0c\0"),
+	},
+	.expect = {
+		.raw_types = {
+			/* int */
+			BTF_TYPE_INT_ENC(NAME_NTH(4), BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+			/* int[16] */
+			BTF_TYPE_ARRAY_ENC(1, 1, 16),					/* [2] */
+			/* struct s { */
+			BTF_STRUCT_ENC(NAME_NTH(6), 4, 84),				/* [3] */
+				BTF_MEMBER_ENC(NAME_NTH(5), 4, 0),	/* struct s *next;	*/
+				BTF_MEMBER_ENC(NAME_NTH(1), 5, 64),	/* const int *a;	*/
+				BTF_MEMBER_ENC(NAME_NTH(2), 2, 128),	/* int b[16];		*/
+				BTF_MEMBER_ENC(NAME_NTH(3), 1, 640),	/* int c;		*/
+			/* ptr -> [3] struct s */
+			BTF_PTR_ENC(3),							/* [4] */
+			/* ptr -> [6] const int */
+			BTF_PTR_ENC(6),							/* [5] */
+			/* const -> [1] int */
+			BTF_CONST_ENC(1),						/* [6] */
+			BTF_END_RAW,
+		},
+		BTF_STR_SEC("\0a\0b\0c\0int\0next\0s"),
+	},
+	.opts = {
+		.dont_resolve_fwds = false,
+	},
+},
+{
+	.descr = "dedup: struct <-> fwd resolution w/ hash collision",
+	/*
+	 * // CU 1:
+	 * struct x;
+	 * struct s {
+	 *	struct x *x;
+	 * };
+	 * // CU 2:
+	 * struct x {};
+	 * struct s {
+	 *	struct x *x;
+	 * };
+	 */
+	.input = {
+		.raw_types = {
+			/* CU 1 */
+			BTF_FWD_ENC(NAME_TBD, 0 /* struct fwd */),	/* [1] fwd x      */
+			BTF_PTR_ENC(1),					/* [2] ptr -> [1] */
+			BTF_STRUCT_ENC(NAME_TBD, 1, 8),			/* [3] struct s   */
+				BTF_MEMBER_ENC(NAME_TBD, 2, 0),
+			/* CU 2 */
+			BTF_STRUCT_ENC(NAME_TBD, 0, 0),			/* [4] struct x   */
+			BTF_PTR_ENC(4),					/* [5] ptr -> [4] */
+			BTF_STRUCT_ENC(NAME_TBD, 1, 8),			/* [6] struct s   */
+				BTF_MEMBER_ENC(NAME_TBD, 5, 0),
+			BTF_END_RAW,
+		},
+		BTF_STR_SEC("\0x\0s\0x\0x\0s\0x\0"),
+	},
+	.expect = {
+		.raw_types = {
+			BTF_PTR_ENC(3),					/* [1] ptr -> [3] */
+			BTF_STRUCT_ENC(NAME_TBD, 1, 8),			/* [2] struct s   */
+				BTF_MEMBER_ENC(NAME_TBD, 1, 0),
+			BTF_STRUCT_ENC(NAME_NTH(2), 0, 0),		/* [3] struct x   */
+			BTF_END_RAW,
+		},
+		BTF_STR_SEC("\0s\0x"),
+	},
+	.opts = {
+		.dont_resolve_fwds = false,
+		.dedup_table_size = 1, /* force hash collisions */
+	},
+},
+{
+	.descr = "dedup: void equiv check",
+	/*
+	 * // CU 1:
+	 * struct s {
+	 *	struct {} *x;
+	 * };
+	 * // CU 2:
+	 * struct s {
+	 *	int *x;
+	 * };
+	 */
+	.input = {
+		.raw_types = {
+			/* CU 1 */
+			BTF_STRUCT_ENC(0, 0, 1),				/* [1] struct {}  */
+			BTF_PTR_ENC(1),						/* [2] ptr -> [1] */
+			BTF_STRUCT_ENC(NAME_NTH(1), 1, 8),			/* [3] struct s   */
+				BTF_MEMBER_ENC(NAME_NTH(2), 2, 0),
+			/* CU 2 */
+			BTF_PTR_ENC(0),						/* [4] ptr -> void */
+			BTF_STRUCT_ENC(NAME_NTH(1), 1, 8),			/* [5] struct s   */
+				BTF_MEMBER_ENC(NAME_NTH(2), 4, 0),
+			BTF_END_RAW,
+		},
+		BTF_STR_SEC("\0s\0x"),
+	},
+	.expect = {
+		.raw_types = {
+			/* CU 1 */
+			BTF_STRUCT_ENC(0, 0, 1),				/* [1] struct {}  */
+			BTF_PTR_ENC(1),						/* [2] ptr -> [1] */
+			BTF_STRUCT_ENC(NAME_NTH(1), 1, 8),			/* [3] struct s   */
+				BTF_MEMBER_ENC(NAME_NTH(2), 2, 0),
+			/* CU 2 */
+			BTF_PTR_ENC(0),						/* [4] ptr -> void */
+			BTF_STRUCT_ENC(NAME_NTH(1), 1, 8),			/* [5] struct s   */
+				BTF_MEMBER_ENC(NAME_NTH(2), 4, 0),
+			BTF_END_RAW,
+		},
+		BTF_STR_SEC("\0s\0x"),
+	},
+	.opts = {
+		.dont_resolve_fwds = false,
+		.dedup_table_size = 1, /* force hash collisions */
+	},
+},
+{
+	.descr = "dedup: all possible kinds (no duplicates)",
+	.input = {
+		.raw_types = {
+			BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 8),		/* [1] int */
+			BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), 4),	/* [2] enum */
+				BTF_ENUM_ENC(NAME_TBD, 0),
+				BTF_ENUM_ENC(NAME_TBD, 1),
+			BTF_FWD_ENC(NAME_TBD, 1 /* union kind_flag */),			/* [3] fwd */
+			BTF_TYPE_ARRAY_ENC(2, 1, 7),					/* [4] array */
+			BTF_STRUCT_ENC(NAME_TBD, 1, 4),					/* [5] struct */
+				BTF_MEMBER_ENC(NAME_TBD, 1, 0),
+			BTF_UNION_ENC(NAME_TBD, 1, 4),					/* [6] union */
+				BTF_MEMBER_ENC(NAME_TBD, 1, 0),
+			BTF_TYPEDEF_ENC(NAME_TBD, 1),					/* [7] typedef */
+			BTF_PTR_ENC(0),							/* [8] ptr */
+			BTF_CONST_ENC(8),						/* [9] const */
+			BTF_VOLATILE_ENC(8),						/* [10] volatile */
+			BTF_RESTRICT_ENC(8),						/* [11] restrict */
+			BTF_FUNC_PROTO_ENC(1, 2),					/* [12] func_proto */
+				BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
+				BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 8),
+			BTF_FUNC_ENC(NAME_TBD, 12),					/* [13] func */
+			BTF_END_RAW,
+		},
+		BTF_STR_SEC("\0A\0B\0C\0D\0E\0F\0G\0H\0I\0J\0K\0L\0M"),
+	},
+	.expect = {
+		.raw_types = {
+			BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 8),		/* [1] int */
+			BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), 4),	/* [2] enum */
+				BTF_ENUM_ENC(NAME_TBD, 0),
+				BTF_ENUM_ENC(NAME_TBD, 1),
+			BTF_FWD_ENC(NAME_TBD, 1 /* union kind_flag */),			/* [3] fwd */
+			BTF_TYPE_ARRAY_ENC(2, 1, 7),					/* [4] array */
+			BTF_STRUCT_ENC(NAME_TBD, 1, 4),					/* [5] struct */
+				BTF_MEMBER_ENC(NAME_TBD, 1, 0),
+			BTF_UNION_ENC(NAME_TBD, 1, 4),					/* [6] union */
+				BTF_MEMBER_ENC(NAME_TBD, 1, 0),
+			BTF_TYPEDEF_ENC(NAME_TBD, 1),					/* [7] typedef */
+			BTF_PTR_ENC(0),							/* [8] ptr */
+			BTF_CONST_ENC(8),						/* [9] const */
+			BTF_VOLATILE_ENC(8),						/* [10] volatile */
+			BTF_RESTRICT_ENC(8),						/* [11] restrict */
+			BTF_FUNC_PROTO_ENC(1, 2),					/* [12] func_proto */
+				BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
+				BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 8),
+			BTF_FUNC_ENC(NAME_TBD, 12),					/* [13] func */
+			BTF_END_RAW,
+		},
+		BTF_STR_SEC("\0A\0B\0C\0D\0E\0F\0G\0H\0I\0J\0K\0L\0M"),
+	},
+	.opts = {
+		.dont_resolve_fwds = false,
+	},
+},
+{
+	.descr = "dedup: no int duplicates",
+	.input = {
+		.raw_types = {
+			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 8),
+			/* different name */
+			BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 32, 8),
+			/* different encoding */
+			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_CHAR, 0, 32, 8),
+			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_BOOL, 0, 32, 8),
+			/* different bit offset */
+			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 8, 32, 8),
+			/* different bit size */
+			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 27, 8),
+			/* different byte size */
+			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
+			BTF_END_RAW,
+		},
+		BTF_STR_SEC("\0int\0some other int"),
+	},
+	.expect = {
+		.raw_types = {
+			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 8),
+			/* different name */
+			BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 32, 8),
+			/* different encoding */
+			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_CHAR, 0, 32, 8),
+			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_BOOL, 0, 32, 8),
+			/* different bit offset */
+			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 8, 32, 8),
+			/* different bit size */
+			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 27, 8),
+			/* different byte size */
+			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
+			BTF_END_RAW,
+		},
+		BTF_STR_SEC("\0int\0some other int"),
+	},
+	.opts = {
+		.dont_resolve_fwds = false,
+	},
+},
+{
+	.descr = "dedup: enum fwd resolution",
+	.input = {
+		.raw_types = {
+			/* [1] fwd enum 'e1' before full enum */
+			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 4),
+			/* [2] full enum 'e1' after fwd */
+			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
+				BTF_ENUM_ENC(NAME_NTH(2), 123),
+			/* [3] full enum 'e2' before fwd */
+			BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
+				BTF_ENUM_ENC(NAME_NTH(4), 456),
+			/* [4] fwd enum 'e2' after full enum */
+			BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 4),
+			/* [5] incompatible fwd enum with different size */
+			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 1),
+			/* [6] incompatible full enum with different value */
+			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
+				BTF_ENUM_ENC(NAME_NTH(2), 321),
+			BTF_END_RAW,
+		},
+		BTF_STR_SEC("\0e1\0e1_val\0e2\0e2_val"),
+	},
+	.expect = {
+		.raw_types = {
+			/* [1] full enum 'e1' */
+			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
+				BTF_ENUM_ENC(NAME_NTH(2), 123),
+			/* [2] full enum 'e2' */
+			BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
+				BTF_ENUM_ENC(NAME_NTH(4), 456),
+			/* [3] incompatible fwd enum with different size */
+			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 1),
+			/* [4] incompatible full enum with different value */
+			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
+				BTF_ENUM_ENC(NAME_NTH(2), 321),
+			BTF_END_RAW,
+		},
+		BTF_STR_SEC("\0e1\0e1_val\0e2\0e2_val"),
+	},
+	.opts = {
+		.dont_resolve_fwds = false,
+	},
+},
+{
+	.descr = "dedup: datasec and vars pass-through",
+	.input = {
+		.raw_types = {
+			/* int */
+			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+			/* static int t */
+			BTF_VAR_ENC(NAME_NTH(2), 1, 0),			/* [2] */
+			/* .bss section */				/* [3] */
+			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
+			BTF_VAR_SECINFO_ENC(2, 0, 4),
+			/* int, referenced from [5] */
+			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [4] */
+			/* another static int t */
+			BTF_VAR_ENC(NAME_NTH(2), 4, 0),			/* [5] */
+			/* another .bss section */			/* [6] */
+			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
+			BTF_VAR_SECINFO_ENC(5, 0, 4),
+			BTF_END_RAW,
+		},
+		BTF_STR_SEC("\0.bss\0t"),
+	},
+	.expect = {
+		.raw_types = {
+			/* int */
+			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
+			/* static int t */
+			BTF_VAR_ENC(NAME_NTH(2), 1, 0),			/* [2] */
+			/* .bss section */				/* [3] */
+			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
+			BTF_VAR_SECINFO_ENC(2, 0, 4),
+			/* another static int t */
+			BTF_VAR_ENC(NAME_NTH(2), 1, 0),			/* [4] */
+			/* another .bss section */			/* [5] */
+			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
+			BTF_VAR_SECINFO_ENC(4, 0, 4),
+			BTF_END_RAW,
+		},
+		BTF_STR_SEC("\0.bss\0t"),
+	},
+	.opts = {
+		.dont_resolve_fwds = false,
+		.dedup_table_size = 1
+	},
+},
+
+};
+
+static int btf_type_size(const struct btf_type *t)
+{
+	int base_size = sizeof(struct btf_type);
+	__u16 vlen = BTF_INFO_VLEN(t->info);
+	__u16 kind = BTF_INFO_KIND(t->info);
+
+	switch (kind) {
+	case BTF_KIND_FWD:
+	case BTF_KIND_CONST:
+	case BTF_KIND_VOLATILE:
+	case BTF_KIND_RESTRICT:
+	case BTF_KIND_PTR:
+	case BTF_KIND_TYPEDEF:
+	case BTF_KIND_FUNC:
+		return base_size;
+	case BTF_KIND_INT:
+		return base_size + sizeof(__u32);
+	case BTF_KIND_ENUM:
+		return base_size + vlen * sizeof(struct btf_enum);
+	case BTF_KIND_ARRAY:
+		return base_size + sizeof(struct btf_array);
+	case BTF_KIND_STRUCT:
+	case BTF_KIND_UNION:
+		return base_size + vlen * sizeof(struct btf_member);
+	case BTF_KIND_FUNC_PROTO:
+		return base_size + vlen * sizeof(struct btf_param);
+	case BTF_KIND_VAR:
+		return base_size + sizeof(struct btf_var);
+	case BTF_KIND_DATASEC:
+		return base_size + vlen * sizeof(struct btf_var_secinfo);
+	default:
+		fprintf(stderr, "Unsupported BTF_KIND:%u\n", kind);
+		return -EINVAL;
+	}
+}
+
+static void dump_btf_strings(const char *strs, __u32 len)
+{
+	const char *cur = strs;
+	int i = 0;
+
+	while (cur < strs + len) {
+		fprintf(stderr, "string #%d: '%s'\n", i, cur);
+		cur += strlen(cur) + 1;
+		i++;
+	}
+}
+
+static void do_test_dedup(unsigned int test_num)
+{
+	const struct btf_dedup_test *test = &dedup_tests[test_num - 1];
+	__u32 test_nr_types, expect_nr_types, test_btf_size, expect_btf_size;
+	const struct btf_header *test_hdr, *expect_hdr;
+	struct btf *test_btf = NULL, *expect_btf = NULL;
+	const void *test_btf_data, *expect_btf_data;
+	const char *ret_test_next_str, *ret_expect_next_str;
+	const char *test_strs, *expect_strs;
+	const char *test_str_cur, *test_str_end;
+	const char *expect_str_cur, *expect_str_end;
+	unsigned int raw_btf_size;
+	void *raw_btf;
+	int err = 0, i;
+
+	if (!test__start_subtest(test->descr))
+		return;
+
+	raw_btf = btf_raw_create(&hdr_tmpl, test->input.raw_types,
+				 test->input.str_sec, test->input.str_sec_size,
+				 &raw_btf_size, &ret_test_next_str);
+	if (!raw_btf)
+		return;
+
+	test_btf = btf__new((__u8 *)raw_btf, raw_btf_size);
+	free(raw_btf);
+	if (CHECK(IS_ERR(test_btf), "invalid test_btf errno:%ld",
+		  PTR_ERR(test_btf))) {
+		err = -1;
+		goto done;
+	}
+
+	raw_btf = btf_raw_create(&hdr_tmpl, test->expect.raw_types,
+				 test->expect.str_sec,
+				 test->expect.str_sec_size,
+				 &raw_btf_size, &ret_expect_next_str);
+	if (!raw_btf)
+		return;
+	expect_btf = btf__new((__u8 *)raw_btf, raw_btf_size);
+	free(raw_btf);
+	if (CHECK(IS_ERR(expect_btf), "invalid expect_btf errno:%ld",
+		  PTR_ERR(expect_btf))) {
+		err = -1;
+		goto done;
+	}
+
+	err = btf__dedup(test_btf, NULL, &test->opts);
+	if (CHECK(err, "btf_dedup failed errno:%d", err)) {
+		err = -1;
+		goto done;
+	}
+
+	test_btf_data = btf__get_raw_data(test_btf, &test_btf_size);
+	expect_btf_data = btf__get_raw_data(expect_btf, &expect_btf_size);
+	if (CHECK(test_btf_size != expect_btf_size,
+		  "test_btf_size:%u != expect_btf_size:%u",
+		  test_btf_size, expect_btf_size)) {
+		err = -1;
+		goto done;
+	}
+
+	test_hdr = test_btf_data;
+	test_strs = test_btf_data + sizeof(*test_hdr) + test_hdr->str_off;
+	expect_hdr = expect_btf_data;
+	expect_strs = expect_btf_data + sizeof(*test_hdr) + expect_hdr->str_off;
+	if (CHECK(test_hdr->str_len != expect_hdr->str_len,
+		  "test_hdr->str_len:%u != expect_hdr->str_len:%u",
+		  test_hdr->str_len, expect_hdr->str_len)) {
+		fprintf(stderr, "\ntest strings:\n");
+		dump_btf_strings(test_strs, test_hdr->str_len);
+		fprintf(stderr, "\nexpected strings:\n");
+		dump_btf_strings(expect_strs, expect_hdr->str_len);
+		err = -1;
+		goto done;
+	}
+
+	test_str_cur = test_strs;
+	test_str_end = test_strs + test_hdr->str_len;
+	expect_str_cur = expect_strs;
+	expect_str_end = expect_strs + expect_hdr->str_len;
+	while (test_str_cur < test_str_end && expect_str_cur < expect_str_end) {
+		size_t test_len, expect_len;
+
+		test_len = strlen(test_str_cur);
+		expect_len = strlen(expect_str_cur);
+		if (CHECK(test_len != expect_len,
+			  "test_len:%zu != expect_len:%zu "
+			  "(test_str:%s, expect_str:%s)",
+			  test_len, expect_len, test_str_cur, expect_str_cur)) {
+			err = -1;
+			goto done;
+		}
+		if (CHECK(strcmp(test_str_cur, expect_str_cur),
+			  "test_str:%s != expect_str:%s",
+			  test_str_cur, expect_str_cur)) {
+			err = -1;
+			goto done;
+		}
+		test_str_cur += test_len + 1;
+		expect_str_cur += expect_len + 1;
+	}
+	if (CHECK(test_str_cur != test_str_end,
+		  "test_str_cur:%p != test_str_end:%p",
+		  test_str_cur, test_str_end)) {
+		err = -1;
+		goto done;
+	}
+
+	test_nr_types = btf__get_nr_types(test_btf);
+	expect_nr_types = btf__get_nr_types(expect_btf);
+	if (CHECK(test_nr_types != expect_nr_types,
+		  "test_nr_types:%u != expect_nr_types:%u",
+		  test_nr_types, expect_nr_types)) {
+		err = -1;
+		goto done;
+	}
+
+	for (i = 1; i <= test_nr_types; i++) {
+		const struct btf_type *test_type, *expect_type;
+		int test_size, expect_size;
+
+		test_type = btf__type_by_id(test_btf, i);
+		expect_type = btf__type_by_id(expect_btf, i);
+		test_size = btf_type_size(test_type);
+		expect_size = btf_type_size(expect_type);
+
+		if (CHECK(test_size != expect_size,
+			  "type #%d: test_size:%d != expect_size:%u",
+			  i, test_size, expect_size)) {
+			err = -1;
+			goto done;
+		}
+		if (CHECK(memcmp((void *)test_type,
+				 (void *)expect_type,
+				 test_size),
+			  "type #%d: contents differ", i)) {
+			err = -1;
+			goto done;
+		}
+	}
+
+done:
+	if (!IS_ERR(test_btf))
+		btf__free(test_btf);
+	if (!IS_ERR(expect_btf))
+		btf__free(expect_btf);
+}
+
+void test_btf(void)
+{
+	int i;
+
+	always_log = env.verbosity > VERBOSE_NONE;
+
+	for (i = 1; i <= ARRAY_SIZE(raw_tests); i++)
+		do_test_raw(i);
+	for (i = 1; i <= ARRAY_SIZE(get_info_tests); i++)
+		do_test_get_info(i);
+	for (i = 1; i <= ARRAY_SIZE(file_tests); i++)
+		do_test_file(i);
+	for (i = 1; i <= ARRAY_SIZE(info_raw_tests); i++)
+		do_test_info_raw(i);
+	for (i = 1; i <= ARRAY_SIZE(dedup_tests); i++)
+		do_test_dedup(i);
+}
diff --git a/tools/testing/selftests/bpf/test_btf.c b/tools/testing/selftests/bpf/test_btf.c
index c75fc6447186..2108c1ada14b 100644
--- a/tools/testing/selftests/bpf/test_btf.c
+++ b/tools/testing/selftests/bpf/test_btf.c
@@ -70,18 +70,7 @@  static int __base_pr(enum libbpf_print_level level __attribute__((unused)),
 #define BTF_LOG_BUF_SIZE 65535
 
 static struct args {
-	unsigned int raw_test_num;
-	unsigned int file_test_num;
-	unsigned int get_info_test_num;
-	unsigned int info_raw_test_num;
-	unsigned int dedup_test_num;
-	bool raw_test;
-	bool file_test;
-	bool get_info_test;
-	bool pprint_test;
 	bool always_log;
-	bool info_raw_test;
-	bool dedup_test;
 } args;
 
 static char btf_log_buf[BTF_LOG_BUF_SIZE];
@@ -126,6809 +115,812 @@  struct btf_raw_test {
 #define BTF_STR_SEC(str) \
 	.str_sec = str, .str_sec_size = sizeof(str)
 
-static struct btf_raw_test raw_tests[] = {
-/* enum E {
- *     E0,
- *     E1,
- * };
- *
- * struct A {
- *	unsigned long long m;
- *	int n;
- *	char o;
- *	[3 bytes hole]
- *	int p[8];
- *	int q[4][8];
- *	enum E r;
- * };
- */
-{
-	.descr = "struct test #1",
-	.raw_types = {
-		/* int */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		/* unsigned long long */
-		BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),		/* [2] */
-		/* char */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),	/* [3] */
-		/* int[8] */
-		BTF_TYPE_ARRAY_ENC(1, 1, 8),			/* [4] */
-		/* struct A { */				/* [5] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 6), 180),
-		BTF_MEMBER_ENC(NAME_TBD, 2, 0),	/* unsigned long long m;*/
-		BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;		*/
-		BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;		*/
-		BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]		*/
-		BTF_MEMBER_ENC(NAME_TBD, 6, 384),/* int q[4][8]		*/
-		BTF_MEMBER_ENC(NAME_TBD, 7, 1408), /* enum E r		*/
-		/* } */
-		/* int[4][8] */
-		BTF_TYPE_ARRAY_ENC(4, 1, 4),			/* [6] */
-		/* enum E */					/* [7] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), sizeof(int)),
-		BTF_ENUM_ENC(NAME_TBD, 0),
-		BTF_ENUM_ENC(NAME_TBD, 1),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0A\0m\0n\0o\0p\0q\0r\0E\0E0\0E1",
-	.str_sec_size = sizeof("\0A\0m\0n\0o\0p\0q\0r\0E\0E0\0E1"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "struct_test1_map",
-	.key_size = sizeof(int),
-	.value_size = 180,
-	.key_type_id = 1,
-	.value_type_id = 5,
-	.max_entries = 4,
-},
-
-/* typedef struct b Struct_B;
- *
- * struct A {
- *     int m;
- *     struct b n[4];
- *     const Struct_B o[4];
- * };
- *
- * struct B {
- *     int m;
- *     int n;
- * };
- */
-{
-	.descr = "struct test #2",
-	.raw_types = {
-		/* int */					/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
-		/* struct b [4] */				/* [2] */
-		BTF_TYPE_ARRAY_ENC(4, 1, 4),
-
-		/* struct A { */				/* [3] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 3), 68),
-		BTF_MEMBER_ENC(NAME_TBD, 1, 0),	/* int m;		*/
-		BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* struct B n[4]	*/
-		BTF_MEMBER_ENC(NAME_TBD, 8, 288),/* const Struct_B o[4];*/
-		/* } */
-
-		/* struct B { */				/* [4] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
-		BTF_MEMBER_ENC(NAME_TBD, 1, 0),	/* int m; */
-		BTF_MEMBER_ENC(NAME_TBD, 1, 32),/* int n; */
-		/* } */
-
-		/* const int */					/* [5] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 1),
-		/* typedef struct b Struct_B */	/* [6] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_TYPEDEF, 0, 0), 4),
-		/* const Struct_B */				/* [7] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 6),
-		/* const Struct_B [4] */			/* [8] */
-		BTF_TYPE_ARRAY_ENC(7, 1, 4),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0A\0m\0n\0o\0B\0m\0n\0Struct_B",
-	.str_sec_size = sizeof("\0A\0m\0n\0o\0B\0m\0n\0Struct_B"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "struct_test2_map",
-	.key_size = sizeof(int),
-	.value_size = 68,
-	.key_type_id = 1,
-	.value_type_id = 3,
-	.max_entries = 4,
-},
-{
-	.descr = "struct test #3 Invalid member offset",
-	.raw_types = {
-		/* int */					/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
-		/* int64 */					/* [2] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 64, 8),
-
-		/* struct A { */				/* [3] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 16),
-		BTF_MEMBER_ENC(NAME_TBD, 1, 64),	/* int m;		*/
-		BTF_MEMBER_ENC(NAME_TBD, 2, 0),		/* int64 n; */
-		/* } */
-		BTF_END_RAW,
-	},
-	.str_sec = "\0A\0m\0n\0",
-	.str_sec_size = sizeof("\0A\0m\0n\0"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "struct_test3_map",
-	.key_size = sizeof(int),
-	.value_size = 16,
-	.key_type_id = 1,
-	.value_type_id = 3,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid member bits_offset",
-},
-/*
- * struct A {
- *	unsigned long long m;
- *	int n;
- *	char o;
- *	[3 bytes hole]
- *	int p[8];
- * };
- */
-{
-	.descr = "global data test #1",
-	.raw_types = {
-		/* int */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		/* unsigned long long */
-		BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),		/* [2] */
-		/* char */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),	/* [3] */
-		/* int[8] */
-		BTF_TYPE_ARRAY_ENC(1, 1, 8),			/* [4] */
-		/* struct A { */				/* [5] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
-		BTF_MEMBER_ENC(NAME_TBD, 2, 0),	/* unsigned long long m;*/
-		BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;		*/
-		BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;		*/
-		BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]		*/
-		/* } */
-		BTF_END_RAW,
-	},
-	.str_sec = "\0A\0m\0n\0o\0p",
-	.str_sec_size = sizeof("\0A\0m\0n\0o\0p"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "struct_test1_map",
-	.key_size = sizeof(int),
-	.value_size = 48,
-	.key_type_id = 1,
-	.value_type_id = 5,
-	.max_entries = 4,
-},
-/*
- * struct A {
- *	unsigned long long m;
- *	int n;
- *	char o;
- *	[3 bytes hole]
- *	int p[8];
- * };
- * static struct A t; <- in .bss
- */
-{
-	.descr = "global data test #2",
-	.raw_types = {
-		/* int */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		/* unsigned long long */
-		BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),		/* [2] */
-		/* char */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),	/* [3] */
-		/* int[8] */
-		BTF_TYPE_ARRAY_ENC(1, 1, 8),			/* [4] */
-		/* struct A { */				/* [5] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
-		BTF_MEMBER_ENC(NAME_TBD, 2, 0),	/* unsigned long long m;*/
-		BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;		*/
-		BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;		*/
-		BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]		*/
-		/* } */
-		/* static struct A t */
-		BTF_VAR_ENC(NAME_TBD, 5, 0),			/* [6] */
-		/* .bss section */				/* [7] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 48),
-		BTF_VAR_SECINFO_ENC(6, 0, 48),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0A\0m\0n\0o\0p\0t\0.bss",
-	.str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0.bss"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = ".bss",
-	.key_size = sizeof(int),
-	.value_size = 48,
-	.key_type_id = 0,
-	.value_type_id = 7,
-	.max_entries = 1,
-},
-{
-	.descr = "global data test #3",
-	.raw_types = {
-		/* int */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		/* static int t */
-		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [2] */
-		/* .bss section */				/* [3] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
-		BTF_VAR_SECINFO_ENC(2, 0, 4),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0t\0.bss",
-	.str_sec_size = sizeof("\0t\0.bss"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = ".bss",
-	.key_size = sizeof(int),
-	.value_size = 4,
-	.key_type_id = 0,
-	.value_type_id = 3,
-	.max_entries = 1,
-},
-{
-	.descr = "global data test #4, unsupported linkage",
-	.raw_types = {
-		/* int */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		/* static int t */
-		BTF_VAR_ENC(NAME_TBD, 1, 2),			/* [2] */
-		/* .bss section */				/* [3] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
-		BTF_VAR_SECINFO_ENC(2, 0, 4),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0t\0.bss",
-	.str_sec_size = sizeof("\0t\0.bss"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = ".bss",
-	.key_size = sizeof(int),
-	.value_size = 4,
-	.key_type_id = 0,
-	.value_type_id = 3,
-	.max_entries = 1,
-	.btf_load_err = true,
-	.err_str = "Linkage not supported",
-},
-{
-	.descr = "global data test #5, invalid var type",
-	.raw_types = {
-		/* static void t */
-		BTF_VAR_ENC(NAME_TBD, 0, 0),			/* [1] */
-		/* .bss section */				/* [2] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
-		BTF_VAR_SECINFO_ENC(1, 0, 4),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0t\0.bss",
-	.str_sec_size = sizeof("\0t\0.bss"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = ".bss",
-	.key_size = sizeof(int),
-	.value_size = 4,
-	.key_type_id = 0,
-	.value_type_id = 2,
-	.max_entries = 1,
-	.btf_load_err = true,
-	.err_str = "Invalid type_id",
-},
-{
-	.descr = "global data test #6, invalid var type (fwd type)",
-	.raw_types = {
-		/* union A */
-		BTF_TYPE_ENC(NAME_TBD,
-			     BTF_INFO_ENC(BTF_KIND_FWD, 1, 0), 0), /* [1] */
-		/* static union A t */
-		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [2] */
-		/* .bss section */				/* [3] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
-		BTF_VAR_SECINFO_ENC(2, 0, 4),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0A\0t\0.bss",
-	.str_sec_size = sizeof("\0A\0t\0.bss"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = ".bss",
-	.key_size = sizeof(int),
-	.value_size = 4,
-	.key_type_id = 0,
-	.value_type_id = 2,
-	.max_entries = 1,
-	.btf_load_err = true,
-	.err_str = "Invalid type",
-},
-{
-	.descr = "global data test #7, invalid var type (fwd type)",
-	.raw_types = {
-		/* union A */
-		BTF_TYPE_ENC(NAME_TBD,
-			     BTF_INFO_ENC(BTF_KIND_FWD, 1, 0), 0), /* [1] */
-		/* static union A t */
-		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [2] */
-		/* .bss section */				/* [3] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
-		BTF_VAR_SECINFO_ENC(1, 0, 4),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0A\0t\0.bss",
-	.str_sec_size = sizeof("\0A\0t\0.bss"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = ".bss",
-	.key_size = sizeof(int),
-	.value_size = 4,
-	.key_type_id = 0,
-	.value_type_id = 2,
-	.max_entries = 1,
-	.btf_load_err = true,
-	.err_str = "Invalid type",
-},
-{
-	.descr = "global data test #8, invalid var size",
-	.raw_types = {
-		/* int */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		/* unsigned long long */
-		BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),		/* [2] */
-		/* char */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),	/* [3] */
-		/* int[8] */
-		BTF_TYPE_ARRAY_ENC(1, 1, 8),			/* [4] */
-		/* struct A { */				/* [5] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
-		BTF_MEMBER_ENC(NAME_TBD, 2, 0),	/* unsigned long long m;*/
-		BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;		*/
-		BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;		*/
-		BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]		*/
-		/* } */
-		/* static struct A t */
-		BTF_VAR_ENC(NAME_TBD, 5, 0),			/* [6] */
-		/* .bss section */				/* [7] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 48),
-		BTF_VAR_SECINFO_ENC(6, 0, 47),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0A\0m\0n\0o\0p\0t\0.bss",
-	.str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0.bss"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = ".bss",
-	.key_size = sizeof(int),
-	.value_size = 48,
-	.key_type_id = 0,
-	.value_type_id = 7,
-	.max_entries = 1,
-	.btf_load_err = true,
-	.err_str = "Invalid size",
-},
-{
-	.descr = "global data test #9, invalid var size",
-	.raw_types = {
-		/* int */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		/* unsigned long long */
-		BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),		/* [2] */
-		/* char */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),	/* [3] */
-		/* int[8] */
-		BTF_TYPE_ARRAY_ENC(1, 1, 8),			/* [4] */
-		/* struct A { */				/* [5] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
-		BTF_MEMBER_ENC(NAME_TBD, 2, 0),	/* unsigned long long m;*/
-		BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;		*/
-		BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;		*/
-		BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]		*/
-		/* } */
-		/* static struct A t */
-		BTF_VAR_ENC(NAME_TBD, 5, 0),			/* [6] */
-		/* .bss section */				/* [7] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 46),
-		BTF_VAR_SECINFO_ENC(6, 0, 48),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0A\0m\0n\0o\0p\0t\0.bss",
-	.str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0.bss"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = ".bss",
-	.key_size = sizeof(int),
-	.value_size = 48,
-	.key_type_id = 0,
-	.value_type_id = 7,
-	.max_entries = 1,
-	.btf_load_err = true,
-	.err_str = "Invalid size",
-},
-{
-	.descr = "global data test #10, invalid var size",
-	.raw_types = {
-		/* int */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		/* unsigned long long */
-		BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),		/* [2] */
-		/* char */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),	/* [3] */
-		/* int[8] */
-		BTF_TYPE_ARRAY_ENC(1, 1, 8),			/* [4] */
-		/* struct A { */				/* [5] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
-		BTF_MEMBER_ENC(NAME_TBD, 2, 0),	/* unsigned long long m;*/
-		BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;		*/
-		BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;		*/
-		BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]		*/
-		/* } */
-		/* static struct A t */
-		BTF_VAR_ENC(NAME_TBD, 5, 0),			/* [6] */
-		/* .bss section */				/* [7] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 46),
-		BTF_VAR_SECINFO_ENC(6, 0, 46),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0A\0m\0n\0o\0p\0t\0.bss",
-	.str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0.bss"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = ".bss",
-	.key_size = sizeof(int),
-	.value_size = 48,
-	.key_type_id = 0,
-	.value_type_id = 7,
-	.max_entries = 1,
-	.btf_load_err = true,
-	.err_str = "Invalid size",
-},
-{
-	.descr = "global data test #11, multiple section members",
-	.raw_types = {
-		/* int */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		/* unsigned long long */
-		BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),		/* [2] */
-		/* char */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),	/* [3] */
-		/* int[8] */
-		BTF_TYPE_ARRAY_ENC(1, 1, 8),			/* [4] */
-		/* struct A { */				/* [5] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
-		BTF_MEMBER_ENC(NAME_TBD, 2, 0),	/* unsigned long long m;*/
-		BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;		*/
-		BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;		*/
-		BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]		*/
-		/* } */
-		/* static struct A t */
-		BTF_VAR_ENC(NAME_TBD, 5, 0),			/* [6] */
-		/* static int u */
-		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [7] */
-		/* .bss section */				/* [8] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 2), 62),
-		BTF_VAR_SECINFO_ENC(6, 10, 48),
-		BTF_VAR_SECINFO_ENC(7, 58, 4),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0A\0m\0n\0o\0p\0t\0u\0.bss",
-	.str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0u\0.bss"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = ".bss",
-	.key_size = sizeof(int),
-	.value_size = 62,
-	.key_type_id = 0,
-	.value_type_id = 8,
-	.max_entries = 1,
-},
-{
-	.descr = "global data test #12, invalid offset",
-	.raw_types = {
-		/* int */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		/* unsigned long long */
-		BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),		/* [2] */
-		/* char */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),	/* [3] */
-		/* int[8] */
-		BTF_TYPE_ARRAY_ENC(1, 1, 8),			/* [4] */
-		/* struct A { */				/* [5] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
-		BTF_MEMBER_ENC(NAME_TBD, 2, 0),	/* unsigned long long m;*/
-		BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;		*/
-		BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;		*/
-		BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]		*/
-		/* } */
-		/* static struct A t */
-		BTF_VAR_ENC(NAME_TBD, 5, 0),			/* [6] */
-		/* static int u */
-		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [7] */
-		/* .bss section */				/* [8] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 2), 62),
-		BTF_VAR_SECINFO_ENC(6, 10, 48),
-		BTF_VAR_SECINFO_ENC(7, 60, 4),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0A\0m\0n\0o\0p\0t\0u\0.bss",
-	.str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0u\0.bss"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = ".bss",
-	.key_size = sizeof(int),
-	.value_size = 62,
-	.key_type_id = 0,
-	.value_type_id = 8,
-	.max_entries = 1,
-	.btf_load_err = true,
-	.err_str = "Invalid offset+size",
-},
-{
-	.descr = "global data test #13, invalid offset",
-	.raw_types = {
-		/* int */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		/* unsigned long long */
-		BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),		/* [2] */
-		/* char */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),	/* [3] */
-		/* int[8] */
-		BTF_TYPE_ARRAY_ENC(1, 1, 8),			/* [4] */
-		/* struct A { */				/* [5] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
-		BTF_MEMBER_ENC(NAME_TBD, 2, 0),	/* unsigned long long m;*/
-		BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;		*/
-		BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;		*/
-		BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]		*/
-		/* } */
-		/* static struct A t */
-		BTF_VAR_ENC(NAME_TBD, 5, 0),			/* [6] */
-		/* static int u */
-		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [7] */
-		/* .bss section */				/* [8] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 2), 62),
-		BTF_VAR_SECINFO_ENC(6, 10, 48),
-		BTF_VAR_SECINFO_ENC(7, 12, 4),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0A\0m\0n\0o\0p\0t\0u\0.bss",
-	.str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0u\0.bss"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = ".bss",
-	.key_size = sizeof(int),
-	.value_size = 62,
-	.key_type_id = 0,
-	.value_type_id = 8,
-	.max_entries = 1,
-	.btf_load_err = true,
-	.err_str = "Invalid offset",
-},
-{
-	.descr = "global data test #14, invalid offset",
-	.raw_types = {
-		/* int */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		/* unsigned long long */
-		BTF_TYPE_INT_ENC(0, 0, 0, 64, 8),		/* [2] */
-		/* char */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),	/* [3] */
-		/* int[8] */
-		BTF_TYPE_ARRAY_ENC(1, 1, 8),			/* [4] */
-		/* struct A { */				/* [5] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 4), 48),
-		BTF_MEMBER_ENC(NAME_TBD, 2, 0),	/* unsigned long long m;*/
-		BTF_MEMBER_ENC(NAME_TBD, 1, 64),/* int n;		*/
-		BTF_MEMBER_ENC(NAME_TBD, 3, 96),/* char o;		*/
-		BTF_MEMBER_ENC(NAME_TBD, 4, 128),/* int p[8]		*/
-		/* } */
-		/* static struct A t */
-		BTF_VAR_ENC(NAME_TBD, 5, 0),			/* [6] */
-		/* static int u */
-		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [7] */
-		/* .bss section */				/* [8] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 2), 62),
-		BTF_VAR_SECINFO_ENC(7, 58, 4),
-		BTF_VAR_SECINFO_ENC(6, 10, 48),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0A\0m\0n\0o\0p\0t\0u\0.bss",
-	.str_sec_size = sizeof("\0A\0m\0n\0o\0p\0t\0u\0.bss"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = ".bss",
-	.key_size = sizeof(int),
-	.value_size = 62,
-	.key_type_id = 0,
-	.value_type_id = 8,
-	.max_entries = 1,
-	.btf_load_err = true,
-	.err_str = "Invalid offset",
-},
-{
-	.descr = "global data test #15, not var kind",
-	.raw_types = {
-		/* int */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [2] */
-		/* .bss section */				/* [3] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
-		BTF_VAR_SECINFO_ENC(1, 0, 4),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0A\0t\0.bss",
-	.str_sec_size = sizeof("\0A\0t\0.bss"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = ".bss",
-	.key_size = sizeof(int),
-	.value_size = 4,
-	.key_type_id = 0,
-	.value_type_id = 3,
-	.max_entries = 1,
-	.btf_load_err = true,
-	.err_str = "Not a VAR kind member",
-},
-{
-	.descr = "global data test #16, invalid var referencing sec",
-	.raw_types = {
-		/* int */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_VAR_ENC(NAME_TBD, 5, 0),			/* [2] */
-		BTF_VAR_ENC(NAME_TBD, 2, 0),			/* [3] */
-		/* a section */					/* [4] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
-		BTF_VAR_SECINFO_ENC(3, 0, 4),
-		/* a section */					/* [5] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
-		BTF_VAR_SECINFO_ENC(6, 0, 4),
-		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [6] */
-		BTF_END_RAW,
-	},
-	.str_sec = "\0A\0t\0s\0a\0a",
-	.str_sec_size = sizeof("\0A\0t\0s\0a\0a"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = ".bss",
-	.key_size = sizeof(int),
-	.value_size = 4,
-	.key_type_id = 0,
-	.value_type_id = 4,
-	.max_entries = 1,
-	.btf_load_err = true,
-	.err_str = "Invalid type_id",
-},
-{
-	.descr = "global data test #17, invalid var referencing var",
-	.raw_types = {
-		/* int */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [2] */
-		BTF_VAR_ENC(NAME_TBD, 2, 0),			/* [3] */
-		/* a section */					/* [4] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
-		BTF_VAR_SECINFO_ENC(3, 0, 4),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0A\0t\0s\0a\0a",
-	.str_sec_size = sizeof("\0A\0t\0s\0a\0a"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = ".bss",
-	.key_size = sizeof(int),
-	.value_size = 4,
-	.key_type_id = 0,
-	.value_type_id = 4,
-	.max_entries = 1,
-	.btf_load_err = true,
-	.err_str = "Invalid type_id",
-},
-{
-	.descr = "global data test #18, invalid var loop",
-	.raw_types = {
-		/* int */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_VAR_ENC(NAME_TBD, 2, 0),			/* [2] */
-		/* .bss section */				/* [3] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
-		BTF_VAR_SECINFO_ENC(2, 0, 4),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0A\0t\0aaa",
-	.str_sec_size = sizeof("\0A\0t\0aaa"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = ".bss",
-	.key_size = sizeof(int),
-	.value_size = 4,
-	.key_type_id = 0,
-	.value_type_id = 4,
-	.max_entries = 1,
-	.btf_load_err = true,
-	.err_str = "Invalid type_id",
-},
-{
-	.descr = "global data test #19, invalid var referencing var",
-	.raw_types = {
-		/* int */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_VAR_ENC(NAME_TBD, 3, 0),			/* [2] */
-		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [3] */
-		BTF_END_RAW,
-	},
-	.str_sec = "\0A\0t\0s\0a\0a",
-	.str_sec_size = sizeof("\0A\0t\0s\0a\0a"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = ".bss",
-	.key_size = sizeof(int),
-	.value_size = 4,
-	.key_type_id = 0,
-	.value_type_id = 4,
-	.max_entries = 1,
-	.btf_load_err = true,
-	.err_str = "Invalid type_id",
-},
-{
-	.descr = "global data test #20, invalid ptr referencing var",
-	.raw_types = {
-		/* int */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		/* PTR type_id=3	*/			/* [2] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 3),
-		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [3] */
-		BTF_END_RAW,
-	},
-	.str_sec = "\0A\0t\0s\0a\0a",
-	.str_sec_size = sizeof("\0A\0t\0s\0a\0a"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = ".bss",
-	.key_size = sizeof(int),
-	.value_size = 4,
-	.key_type_id = 0,
-	.value_type_id = 4,
-	.max_entries = 1,
-	.btf_load_err = true,
-	.err_str = "Invalid type_id",
-},
-{
-	.descr = "global data test #21, var included in struct",
-	.raw_types = {
-		/* int */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		/* struct A { */				/* [2] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 2),
-		BTF_MEMBER_ENC(NAME_TBD, 1, 0),	/* int m; */
-		BTF_MEMBER_ENC(NAME_TBD, 3, 32),/* VAR type_id=3; */
-		/* } */
-		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [3] */
-		BTF_END_RAW,
-	},
-	.str_sec = "\0A\0t\0s\0a\0a",
-	.str_sec_size = sizeof("\0A\0t\0s\0a\0a"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = ".bss",
-	.key_size = sizeof(int),
-	.value_size = 4,
-	.key_type_id = 0,
-	.value_type_id = 4,
-	.max_entries = 1,
-	.btf_load_err = true,
-	.err_str = "Invalid member",
-},
-{
-	.descr = "global data test #22, array of var",
-	.raw_types = {
-		/* int */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_TYPE_ARRAY_ENC(3, 1, 4),			/* [2] */
-		BTF_VAR_ENC(NAME_TBD, 1, 0),			/* [3] */
-		BTF_END_RAW,
-	},
-	.str_sec = "\0A\0t\0s\0a\0a",
-	.str_sec_size = sizeof("\0A\0t\0s\0a\0a"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = ".bss",
-	.key_size = sizeof(int),
-	.value_size = 4,
-	.key_type_id = 0,
-	.value_type_id = 4,
-	.max_entries = 1,
-	.btf_load_err = true,
-	.err_str = "Invalid elem",
-},
-/* Test member exceeds the size of struct.
- *
- * struct A {
- *     int m;
- *     int n;
- * };
- */
-{
-	.descr = "size check test #1",
-	.raw_types = {
-		/* int */					/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
-		/* struct A { */				/* [2] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 2 -  1),
-		BTF_MEMBER_ENC(NAME_TBD, 1, 0),	/* int m; */
-		BTF_MEMBER_ENC(NAME_TBD, 1, 32),/* int n; */
-		/* } */
-		BTF_END_RAW,
-	},
-	.str_sec = "\0A\0m\0n",
-	.str_sec_size = sizeof("\0A\0m\0n"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "size_check1_map",
-	.key_size = sizeof(int),
-	.value_size = 1,
-	.key_type_id = 1,
-	.value_type_id = 2,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Member exceeds struct_size",
-},
-
-/* Test member exeeds the size of struct
- *
- * struct A {
- *     int m;
- *     int n[2];
- * };
- */
-{
-	.descr = "size check test #2",
-	.raw_types = {
-		/* int */					/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)),
-		/* int[2] */					/* [2] */
-		BTF_TYPE_ARRAY_ENC(1, 1, 2),
-		/* struct A { */				/* [3] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 3 - 1),
-		BTF_MEMBER_ENC(NAME_TBD, 1, 0),	/* int m; */
-		BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* int n[2]; */
-		/* } */
-		BTF_END_RAW,
-	},
-	.str_sec = "\0A\0m\0n",
-	.str_sec_size = sizeof("\0A\0m\0n"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "size_check2_map",
-	.key_size = sizeof(int),
-	.value_size = 1,
-	.key_type_id = 1,
-	.value_type_id = 3,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Member exceeds struct_size",
-},
-
-/* Test member exeeds the size of struct
- *
- * struct A {
- *     int m;
- *     void *n;
- * };
- */
-{
-	.descr = "size check test #3",
-	.raw_types = {
-		/* int */					/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)),
-		/* void* */					/* [2] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0),
-		/* struct A { */				/* [3] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) + sizeof(void *) - 1),
-		BTF_MEMBER_ENC(NAME_TBD, 1, 0),	/* int m; */
-		BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* void *n; */
-		/* } */
-		BTF_END_RAW,
-	},
-	.str_sec = "\0A\0m\0n",
-	.str_sec_size = sizeof("\0A\0m\0n"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "size_check3_map",
-	.key_size = sizeof(int),
-	.value_size = 1,
-	.key_type_id = 1,
-	.value_type_id = 3,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Member exceeds struct_size",
-},
-
-/* Test member exceeds the size of struct
- *
- * enum E {
- *     E0,
- *     E1,
- * };
- *
- * struct A {
- *     int m;
- *     enum E n;
- * };
- */
-{
-	.descr = "size check test #4",
-	.raw_types = {
-		/* int */			/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)),
-		/* enum E { */			/* [2] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), sizeof(int)),
-		BTF_ENUM_ENC(NAME_TBD, 0),
-		BTF_ENUM_ENC(NAME_TBD, 1),
-		/* } */
-		/* struct A { */		/* [3] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), sizeof(int) * 2 - 1),
-		BTF_MEMBER_ENC(NAME_TBD, 1, 0),	/* int m; */
-		BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* enum E n; */
-		/* } */
-		BTF_END_RAW,
-	},
-	.str_sec = "\0E\0E0\0E1\0A\0m\0n",
-	.str_sec_size = sizeof("\0E\0E0\0E1\0A\0m\0n"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "size_check4_map",
-	.key_size = sizeof(int),
-	.value_size = 1,
-	.key_type_id = 1,
-	.value_type_id = 3,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Member exceeds struct_size",
-},
-
-/* Test member unexceeds the size of struct
- *
- * enum E {
- *     E0,
- *     E1,
- * };
- *
- * struct A {
- *     char m;
- *     enum E __attribute__((packed)) n;
- * };
- */
-{
-	.descr = "size check test #5",
-	.raw_types = {
-		/* int */			/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, sizeof(int)),
-		/* char */			/* [2] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 8, 1),
-		/* enum E { */			/* [3] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), 1),
-		BTF_ENUM_ENC(NAME_TBD, 0),
-		BTF_ENUM_ENC(NAME_TBD, 1),
-		/* } */
-		/* struct A { */		/* [4] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 2),
-		BTF_MEMBER_ENC(NAME_TBD, 2, 0),	/* char m; */
-		BTF_MEMBER_ENC(NAME_TBD, 3, 8),/* enum E __attribute__((packed)) n; */
-		/* } */
-		BTF_END_RAW,
-	},
-	.str_sec = "\0E\0E0\0E1\0A\0m\0n",
-	.str_sec_size = sizeof("\0E\0E0\0E1\0A\0m\0n"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "size_check5_map",
-	.key_size = sizeof(int),
-	.value_size = 2,
-	.key_type_id = 1,
-	.value_type_id = 4,
-	.max_entries = 4,
-},
-
-/* typedef const void * const_void_ptr;
- * struct A {
- *	const_void_ptr m;
- * };
- */
-{
-	.descr = "void test #1",
-	.raw_types = {
-		/* int */		/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
-		/* const void */	/* [2] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
-		/* const void* */	/* [3] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 2),
-		/* typedef const void * const_void_ptr */
-		BTF_TYPEDEF_ENC(NAME_TBD, 3),	/* [4] */
-		/* struct A { */	/* [5] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
-		/* const_void_ptr m; */
-		BTF_MEMBER_ENC(NAME_TBD, 4, 0),
-		/* } */
-		BTF_END_RAW,
-	},
-	.str_sec = "\0const_void_ptr\0A\0m",
-	.str_sec_size = sizeof("\0const_void_ptr\0A\0m"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "void_test1_map",
-	.key_size = sizeof(int),
-	.value_size = sizeof(void *),
-	.key_type_id = 1,
-	.value_type_id = 4,
-	.max_entries = 4,
-},
-
-/* struct A {
- *     const void m;
- * };
- */
-{
-	.descr = "void test #2",
-	.raw_types = {
-		/* int */		/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
-		/* const void */	/* [2] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
-		/* struct A { */	/* [3] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 8),
-		/* const void m; */
-		BTF_MEMBER_ENC(NAME_TBD, 2, 0),
-		/* } */
-		BTF_END_RAW,
-	},
-	.str_sec = "\0A\0m",
-	.str_sec_size = sizeof("\0A\0m"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "void_test2_map",
-	.key_size = sizeof(int),
-	.value_size = sizeof(void *),
-	.key_type_id = 1,
-	.value_type_id = 3,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid member",
-},
-
-/* typedef const void * const_void_ptr;
- * const_void_ptr[4]
- */
-{
-	.descr = "void test #3",
-	.raw_types = {
-		/* int */		/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
-		/* const void */	/* [2] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
-		/* const void* */	/* [3] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 2),
-		/* typedef const void * const_void_ptr */
-		BTF_TYPEDEF_ENC(NAME_TBD, 3),	/* [4] */
-		/* const_void_ptr[4] */
-		BTF_TYPE_ARRAY_ENC(4, 1, 4),	/* [5] */
-		BTF_END_RAW,
-	},
-	.str_sec = "\0const_void_ptr",
-	.str_sec_size = sizeof("\0const_void_ptr"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "void_test3_map",
-	.key_size = sizeof(int),
-	.value_size = sizeof(void *) * 4,
-	.key_type_id = 1,
-	.value_type_id = 5,
-	.max_entries = 4,
-},
-
-/* const void[4]  */
-{
-	.descr = "void test #4",
-	.raw_types = {
-		/* int */		/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
-		/* const void */	/* [2] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
-		/* const void[4] */	/* [3] */
-		BTF_TYPE_ARRAY_ENC(2, 1, 4),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0A\0m",
-	.str_sec_size = sizeof("\0A\0m"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "void_test4_map",
-	.key_size = sizeof(int),
-	.value_size = sizeof(void *) * 4,
-	.key_type_id = 1,
-	.value_type_id = 3,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid elem",
-},
-
-/* Array_A  <------------------+
- *     elem_type == Array_B    |
- *                    |        |
- *                    |        |
- * Array_B  <-------- +        |
- *      elem_type == Array A --+
- */
-{
-	.descr = "loop test #1",
-	.raw_types = {
-		/* int */			/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
-		/* Array_A */			/* [2] */
-		BTF_TYPE_ARRAY_ENC(3, 1, 8),
-		/* Array_B */			/* [3] */
-		BTF_TYPE_ARRAY_ENC(2, 1, 8),
-		BTF_END_RAW,
-	},
-	.str_sec = "",
-	.str_sec_size = sizeof(""),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "loop_test1_map",
-	.key_size = sizeof(int),
-	.value_size = sizeof(sizeof(int) * 8),
-	.key_type_id = 1,
-	.value_type_id = 2,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Loop detected",
-},
-
-/* typedef is _before_ the BTF type of Array_A and Array_B
- *
- * typedef Array_B int_array;
- *
- * Array_A  <------------------+
- *     elem_type == int_array  |
- *                    |        |
- *                    |        |
- * Array_B  <-------- +        |
- *      elem_type == Array_A --+
- */
-{
-	.descr = "loop test #2",
-	.raw_types = {
-		/* int */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		/* typedef Array_B int_array */
-		BTF_TYPEDEF_ENC(1, 4),				/* [2] */
-		/* Array_A */
-		BTF_TYPE_ARRAY_ENC(2, 1, 8),			/* [3] */
-		/* Array_B */
-		BTF_TYPE_ARRAY_ENC(3, 1, 8),			/* [4] */
-		BTF_END_RAW,
-	},
-	.str_sec = "\0int_array\0",
-	.str_sec_size = sizeof("\0int_array"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "loop_test2_map",
-	.key_size = sizeof(int),
-	.value_size = sizeof(sizeof(int) * 8),
-	.key_type_id = 1,
-	.value_type_id = 2,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Loop detected",
-},
-
-/* Array_A  <------------------+
- *     elem_type == Array_B    |
- *                    |        |
- *                    |        |
- * Array_B  <-------- +        |
- *      elem_type == Array_A --+
- */
-{
-	.descr = "loop test #3",
-	.raw_types = {
-		/* int */				/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
-		/* Array_A */				/* [2] */
-		BTF_TYPE_ARRAY_ENC(3, 1, 8),
-		/* Array_B */				/* [3] */
-		BTF_TYPE_ARRAY_ENC(2, 1, 8),
-		BTF_END_RAW,
-	},
-	.str_sec = "",
-	.str_sec_size = sizeof(""),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "loop_test3_map",
-	.key_size = sizeof(int),
-	.value_size = sizeof(sizeof(int) * 8),
-	.key_type_id = 1,
-	.value_type_id = 2,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Loop detected",
-},
-
-/* typedef is _between_ the BTF type of Array_A and Array_B
- *
- * typedef Array_B int_array;
- *
- * Array_A  <------------------+
- *     elem_type == int_array  |
- *                    |        |
- *                    |        |
- * Array_B  <-------- +        |
- *      elem_type == Array_A --+
- */
-{
-	.descr = "loop test #4",
-	.raw_types = {
-		/* int */				/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
-		/* Array_A */				/* [2] */
-		BTF_TYPE_ARRAY_ENC(3, 1, 8),
-		/* typedef Array_B int_array */		/* [3] */
-		BTF_TYPEDEF_ENC(NAME_TBD, 4),
-		/* Array_B */				/* [4] */
-		BTF_TYPE_ARRAY_ENC(2, 1, 8),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0int_array\0",
-	.str_sec_size = sizeof("\0int_array"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "loop_test4_map",
-	.key_size = sizeof(int),
-	.value_size = sizeof(sizeof(int) * 8),
-	.key_type_id = 1,
-	.value_type_id = 2,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Loop detected",
-},
-
-/* typedef struct B Struct_B
- *
- * struct A {
- *     int x;
- *     Struct_B y;
- * };
- *
- * struct B {
- *     int x;
- *     struct A y;
- * };
- */
-{
-	.descr = "loop test #5",
-	.raw_types = {
-		/* int */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		/* struct A */					/* [2] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
-		BTF_MEMBER_ENC(NAME_TBD, 1, 0),	/* int x;	*/
-		BTF_MEMBER_ENC(NAME_TBD, 3, 32),/* Struct_B y;	*/
-		/* typedef struct B Struct_B */
-		BTF_TYPEDEF_ENC(NAME_TBD, 4),			/* [3] */
-		/* struct B */					/* [4] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
-		BTF_MEMBER_ENC(NAME_TBD, 1, 0),	/* int x;	*/
-		BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* struct A y;	*/
-		BTF_END_RAW,
-	},
-	.str_sec = "\0A\0x\0y\0Struct_B\0B\0x\0y",
-	.str_sec_size = sizeof("\0A\0x\0y\0Struct_B\0B\0x\0y"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "loop_test5_map",
-	.key_size = sizeof(int),
-	.value_size = 8,
-	.key_type_id = 1,
-	.value_type_id = 2,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Loop detected",
-},
-
-/* struct A {
- *     int x;
- *     struct A array_a[4];
- * };
- */
-{
-	.descr = "loop test #6",
-	.raw_types = {
-		/* int */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_TYPE_ARRAY_ENC(3, 1, 4),			/* [2] */
-		/* struct A */					/* [3] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 8),
-		BTF_MEMBER_ENC(NAME_TBD, 1, 0),	/* int x;		*/
-		BTF_MEMBER_ENC(NAME_TBD, 2, 32),/* struct A array_a[4];	*/
-		BTF_END_RAW,
-	},
-	.str_sec = "\0A\0x\0y",
-	.str_sec_size = sizeof("\0A\0x\0y"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "loop_test6_map",
-	.key_size = sizeof(int),
-	.value_size = 8,
-	.key_type_id = 1,
-	.value_type_id = 2,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Loop detected",
-},
-
-{
-	.descr = "loop test #7",
-	.raw_types = {
-		/* int */				/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
-		/* struct A { */			/* [2] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
-		/*     const void *m;	*/
-		BTF_MEMBER_ENC(NAME_TBD, 3, 0),
-		/* CONST type_id=3	*/		/* [3] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 4),
-		/* PTR type_id=2	*/		/* [4] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 3),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0A\0m",
-	.str_sec_size = sizeof("\0A\0m"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "loop_test7_map",
-	.key_size = sizeof(int),
-	.value_size = sizeof(void *),
-	.key_type_id = 1,
-	.value_type_id = 2,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Loop detected",
-},
-
-{
-	.descr = "loop test #8",
-	.raw_types = {
-		/* int */				/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
-		/* struct A { */			/* [2] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
-		/*     const void *m;	*/
-		BTF_MEMBER_ENC(NAME_TBD, 4, 0),
-		/* struct B { */			/* [3] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), sizeof(void *)),
-		/*     const void *n;	*/
-		BTF_MEMBER_ENC(NAME_TBD, 6, 0),
-		/* CONST type_id=5	*/		/* [4] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 5),
-		/* PTR type_id=6	*/		/* [5] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 6),
-		/* CONST type_id=7	*/		/* [6] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 7),
-		/* PTR type_id=4	*/		/* [7] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 4),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0A\0m\0B\0n",
-	.str_sec_size = sizeof("\0A\0m\0B\0n"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "loop_test8_map",
-	.key_size = sizeof(int),
-	.value_size = sizeof(void *),
-	.key_type_id = 1,
-	.value_type_id = 2,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Loop detected",
-},
-
-{
-	.descr = "string section does not end with null",
-	.raw_types = {
-		/* int */				/* [1] */
-		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0int",
-	.str_sec_size = sizeof("\0int") - 1,
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "hdr_test_map",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid string section",
-},
-
-{
-	.descr = "empty string section",
-	.raw_types = {
-		/* int */				/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
-		BTF_END_RAW,
-	},
-	.str_sec = "",
-	.str_sec_size = 0,
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "hdr_test_map",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid string section",
-},
-
-{
-	.descr = "empty type section",
-	.raw_types = {
-		BTF_END_RAW,
-	},
-	.str_sec = "\0int",
-	.str_sec_size = sizeof("\0int"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "hdr_test_map",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "No type found",
-},
-
-{
-	.descr = "btf_header test. Longer hdr_len",
-	.raw_types = {
-		/* int */				/* [1] */
-		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0int",
-	.str_sec_size = sizeof("\0int"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "hdr_test_map",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.hdr_len_delta = 4,
-	.err_str = "Unsupported btf_header",
-},
-
-{
-	.descr = "btf_header test. Gap between hdr and type",
-	.raw_types = {
-		/* int */				/* [1] */
-		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0int",
-	.str_sec_size = sizeof("\0int"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "hdr_test_map",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.type_off_delta = 4,
-	.err_str = "Unsupported section found",
-},
-
-{
-	.descr = "btf_header test. Gap between type and str",
-	.raw_types = {
-		/* int */				/* [1] */
-		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0int",
-	.str_sec_size = sizeof("\0int"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "hdr_test_map",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.str_off_delta = 4,
-	.err_str = "Unsupported section found",
-},
-
-{
-	.descr = "btf_header test. Overlap between type and str",
-	.raw_types = {
-		/* int */				/* [1] */
-		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0int",
-	.str_sec_size = sizeof("\0int"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "hdr_test_map",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.str_off_delta = -4,
-	.err_str = "Section overlap found",
-},
-
-{
-	.descr = "btf_header test. Larger BTF size",
-	.raw_types = {
-		/* int */				/* [1] */
-		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0int",
-	.str_sec_size = sizeof("\0int"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "hdr_test_map",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.str_len_delta = -4,
-	.err_str = "Unsupported section found",
-},
-
-{
-	.descr = "btf_header test. Smaller BTF size",
-	.raw_types = {
-		/* int */				/* [1] */
-		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0int",
-	.str_sec_size = sizeof("\0int"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "hdr_test_map",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.str_len_delta = 4,
-	.err_str = "Total section length too long",
-},
-
-{
-	.descr = "array test. index_type/elem_type \"int\"",
-	.raw_types = {
-		/* int */				/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
-		/* int[16] */				/* [2] */
-		BTF_TYPE_ARRAY_ENC(1, 1, 16),
-		BTF_END_RAW,
-	},
-	.str_sec = "",
-	.str_sec_size = sizeof(""),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "array_test_map",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-},
-
-{
-	.descr = "array test. index_type/elem_type \"const int\"",
-	.raw_types = {
-		/* int */				/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
-		/* int[16] */				/* [2] */
-		BTF_TYPE_ARRAY_ENC(3, 3, 16),
-		/* CONST type_id=1 */			/* [3] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 1),
-		BTF_END_RAW,
-	},
-	.str_sec = "",
-	.str_sec_size = sizeof(""),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "array_test_map",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-},
-
-{
-	.descr = "array test. index_type \"const int:31\"",
-	.raw_types = {
-		/* int */				/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
-		/* int:31 */				/* [2] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 31, 4),
-		/* int[16] */				/* [3] */
-		BTF_TYPE_ARRAY_ENC(1, 4, 16),
-		/* CONST type_id=2 */			/* [4] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 2),
-		BTF_END_RAW,
-	},
-	.str_sec = "",
-	.str_sec_size = sizeof(""),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "array_test_map",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid index",
-},
-
-{
-	.descr = "array test. elem_type \"const int:31\"",
-	.raw_types = {
-		/* int */				/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
-		/* int:31 */				/* [2] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 31, 4),
-		/* int[16] */				/* [3] */
-		BTF_TYPE_ARRAY_ENC(4, 1, 16),
-		/* CONST type_id=2 */			/* [4] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 2),
-		BTF_END_RAW,
-	},
-	.str_sec = "",
-	.str_sec_size = sizeof(""),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "array_test_map",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid array of int",
-},
-
-{
-	.descr = "array test. index_type \"void\"",
-	.raw_types = {
-		/* int */				/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
-		/* int[16] */				/* [2] */
-		BTF_TYPE_ARRAY_ENC(1, 0, 16),
-		BTF_END_RAW,
-	},
-	.str_sec = "",
-	.str_sec_size = sizeof(""),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "array_test_map",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid index",
-},
-
-{
-	.descr = "array test. index_type \"const void\"",
-	.raw_types = {
-		/* int */				/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
-		/* int[16] */				/* [2] */
-		BTF_TYPE_ARRAY_ENC(1, 3, 16),
-		/* CONST type_id=0 (void) */		/* [3] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
-		BTF_END_RAW,
-	},
-	.str_sec = "",
-	.str_sec_size = sizeof(""),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "array_test_map",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid index",
-},
-
-{
-	.descr = "array test. elem_type \"const void\"",
-	.raw_types = {
-		/* int */				/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
-		/* int[16] */				/* [2] */
-		BTF_TYPE_ARRAY_ENC(3, 1, 16),
-		/* CONST type_id=0 (void) */		/* [3] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 0),
-		BTF_END_RAW,
-	},
-	.str_sec = "",
-	.str_sec_size = sizeof(""),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "array_test_map",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid elem",
-},
-
-{
-	.descr = "array test. elem_type \"const void *\"",
-	.raw_types = {
-		/* int */				/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
-		/* const void *[16] */			/* [2] */
-		BTF_TYPE_ARRAY_ENC(3, 1, 16),
-		/* CONST type_id=4 */			/* [3] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 4),
-		/* void* */				/* [4] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0),
-		BTF_END_RAW,
-	},
-	.str_sec = "",
-	.str_sec_size = sizeof(""),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "array_test_map",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-},
-
-{
-	.descr = "array test. index_type \"const void *\"",
-	.raw_types = {
-		/* int */				/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
-		/* const void *[16] */			/* [2] */
-		BTF_TYPE_ARRAY_ENC(3, 3, 16),
-		/* CONST type_id=4 */			/* [3] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 4),
-		/* void* */				/* [4] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0),
-		BTF_END_RAW,
-	},
-	.str_sec = "",
-	.str_sec_size = sizeof(""),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "array_test_map",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid index",
-},
-
-{
-	.descr = "array test. t->size != 0\"",
-	.raw_types = {
-		/* int */				/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
-		/* int[16] */				/* [2] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ARRAY, 0, 0), 1),
-		BTF_ARRAY_ENC(1, 1, 16),
-		BTF_END_RAW,
-	},
-	.str_sec = "",
-	.str_sec_size = sizeof(""),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "array_test_map",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "size != 0",
-},
-
-{
-	.descr = "int test. invalid int_data",
-	.raw_types = {
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_INT, 0, 0), 4),
-		0x10000000,
-		BTF_END_RAW,
-	},
-	.str_sec = "",
-	.str_sec_size = sizeof(""),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "array_test_map",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid int_data",
-},
-
-{
-	.descr = "invalid BTF_INFO",
-	.raw_types = {
-		/* int */				/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
-		BTF_TYPE_ENC(0, 0x10000000, 4),
-		BTF_END_RAW,
-	},
-	.str_sec = "",
-	.str_sec_size = sizeof(""),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "array_test_map",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid btf_info",
-},
-
-{
-	.descr = "fwd test. t->type != 0\"",
-	.raw_types = {
-		/* int */				/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
-		/* fwd type */				/* [2] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FWD, 0, 0), 1),
-		BTF_END_RAW,
-	},
-	.str_sec = "",
-	.str_sec_size = sizeof(""),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "fwd_test_map",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "type != 0",
-},
-
-{
-	.descr = "typedef (invalid name, name_off = 0)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_TYPEDEF_ENC(0, 1),				/* [2] */
-		BTF_END_RAW,
-	},
-	.str_sec = "\0__int",
-	.str_sec_size = sizeof("\0__int"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "typedef_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid name",
-},
-
-{
-	.descr = "typedef (invalid name, invalid identifier)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_TYPEDEF_ENC(NAME_TBD, 1),			/* [2] */
-		BTF_END_RAW,
-	},
-	.str_sec = "\0__!int",
-	.str_sec_size = sizeof("\0__!int"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "typedef_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid name",
-},
-
-{
-	.descr = "ptr type (invalid name, name_off <> 0)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
-		BTF_TYPE_ENC(NAME_TBD,
-			     BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 1),	/* [2] */
-		BTF_END_RAW,
-	},
-	.str_sec = "\0__int",
-	.str_sec_size = sizeof("\0__int"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "ptr_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid name",
-},
-
-{
-	.descr = "volatile type (invalid name, name_off <> 0)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
-		BTF_TYPE_ENC(NAME_TBD,
-			     BTF_INFO_ENC(BTF_KIND_VOLATILE, 0, 0), 1),	/* [2] */
-		BTF_END_RAW,
-	},
-	.str_sec = "\0__int",
-	.str_sec_size = sizeof("\0__int"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "volatile_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid name",
-},
-
-{
-	.descr = "const type (invalid name, name_off <> 0)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
-		BTF_TYPE_ENC(NAME_TBD,
-			     BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 1),	/* [2] */
-		BTF_END_RAW,
-	},
-	.str_sec = "\0__int",
-	.str_sec_size = sizeof("\0__int"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "const_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid name",
-},
-
-{
-	.descr = "restrict type (invalid name, name_off <> 0)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 1),	/* [2] */
-		BTF_TYPE_ENC(NAME_TBD,
-			     BTF_INFO_ENC(BTF_KIND_RESTRICT, 0, 0), 2),	/* [3] */
-		BTF_END_RAW,
-	},
-	.str_sec = "\0__int",
-	.str_sec_size = sizeof("\0__int"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "restrict_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid name",
-},
-
-{
-	.descr = "fwd type (invalid name, name_off = 0)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FWD, 0, 0), 0),	/* [2] */
-		BTF_END_RAW,
-	},
-	.str_sec = "\0__skb",
-	.str_sec_size = sizeof("\0__skb"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "fwd_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid name",
-},
-
-{
-	.descr = "fwd type (invalid name, invalid identifier)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
-		BTF_TYPE_ENC(NAME_TBD,
-			     BTF_INFO_ENC(BTF_KIND_FWD, 0, 0), 0),	/* [2] */
-		BTF_END_RAW,
-	},
-	.str_sec = "\0__!skb",
-	.str_sec_size = sizeof("\0__!skb"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "fwd_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid name",
-},
-
-{
-	.descr = "array type (invalid name, name_off <> 0)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
-		BTF_TYPE_ENC(NAME_TBD,
-			     BTF_INFO_ENC(BTF_KIND_ARRAY, 0, 0), 0),	/* [2] */
-		BTF_ARRAY_ENC(1, 1, 4),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0__skb",
-	.str_sec_size = sizeof("\0__skb"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "array_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid name",
-},
-
-{
-	.descr = "struct type (name_off = 0)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
-		BTF_TYPE_ENC(0,
-			     BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4),	/* [2] */
-		BTF_MEMBER_ENC(NAME_TBD, 1, 0),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0A",
-	.str_sec_size = sizeof("\0A"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "struct_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-},
-
-{
-	.descr = "struct type (invalid name, invalid identifier)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
-		BTF_TYPE_ENC(NAME_TBD,
-			     BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4),	/* [2] */
-		BTF_MEMBER_ENC(NAME_TBD, 1, 0),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0A!\0B",
-	.str_sec_size = sizeof("\0A!\0B"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "struct_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid name",
-},
-
-{
-	.descr = "struct member (name_off = 0)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
-		BTF_TYPE_ENC(0,
-			     BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4),	/* [2] */
-		BTF_MEMBER_ENC(NAME_TBD, 1, 0),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0A",
-	.str_sec_size = sizeof("\0A"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "struct_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-},
-
-{
-	.descr = "struct member (invalid name, invalid identifier)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
-		BTF_TYPE_ENC(NAME_TBD,
-			     BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 4),	/* [2] */
-		BTF_MEMBER_ENC(NAME_TBD, 1, 0),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0A\0B*",
-	.str_sec_size = sizeof("\0A\0B*"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "struct_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid name",
-},
-
-{
-	.descr = "enum type (name_off = 0)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
-		BTF_TYPE_ENC(0,
-			     BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1),
-			     sizeof(int)),				/* [2] */
-		BTF_ENUM_ENC(NAME_TBD, 0),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0A\0B",
-	.str_sec_size = sizeof("\0A\0B"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "enum_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-},
-
-{
-	.descr = "enum type (invalid name, invalid identifier)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
-		BTF_TYPE_ENC(NAME_TBD,
-			     BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1),
-			     sizeof(int)),				/* [2] */
-		BTF_ENUM_ENC(NAME_TBD, 0),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0A!\0B",
-	.str_sec_size = sizeof("\0A!\0B"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "enum_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid name",
-},
-
-{
-	.descr = "enum member (invalid name, name_off = 0)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
-		BTF_TYPE_ENC(0,
-			     BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1),
-			     sizeof(int)),				/* [2] */
-		BTF_ENUM_ENC(0, 0),
-		BTF_END_RAW,
-	},
-	.str_sec = "",
-	.str_sec_size = sizeof(""),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "enum_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid name",
-},
-
-{
-	.descr = "enum member (invalid name, invalid identifier)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
-		BTF_TYPE_ENC(0,
-			     BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1),
-			     sizeof(int)),				/* [2] */
-		BTF_ENUM_ENC(NAME_TBD, 0),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0A!",
-	.str_sec_size = sizeof("\0A!"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "enum_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid name",
-},
-{
-	.descr = "arraymap invalid btf key (a bit field)",
-	.raw_types = {
-		/* int */				/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
-		/* 32 bit int with 32 bit offset */	/* [2] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 32, 32, 8),
-		BTF_END_RAW,
-	},
-	.str_sec = "",
-	.str_sec_size = sizeof(""),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "array_map_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 2,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.map_create_err = true,
-},
-
-{
-	.descr = "arraymap invalid btf key (!= 32 bits)",
-	.raw_types = {
-		/* int */				/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
-		/* 16 bit int with 0 bit offset */	/* [2] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 16, 2),
-		BTF_END_RAW,
-	},
-	.str_sec = "",
-	.str_sec_size = sizeof(""),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "array_map_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 2,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.map_create_err = true,
-},
-
-{
-	.descr = "arraymap invalid btf value (too small)",
-	.raw_types = {
-		/* int */				/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
-		BTF_END_RAW,
-	},
-	.str_sec = "",
-	.str_sec_size = sizeof(""),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "array_map_check_btf",
-	.key_size = sizeof(int),
-	/* btf_value_size < map->value_size */
-	.value_size = sizeof(__u64),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.map_create_err = true,
-},
-
-{
-	.descr = "arraymap invalid btf value (too big)",
-	.raw_types = {
-		/* int */				/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
-		BTF_END_RAW,
-	},
-	.str_sec = "",
-	.str_sec_size = sizeof(""),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "array_map_check_btf",
-	.key_size = sizeof(int),
-	/* btf_value_size > map->value_size */
-	.value_size = sizeof(__u16),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.map_create_err = true,
-},
-
-{
-	.descr = "func proto (int (*)(int, unsigned int))",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
-		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
-		/* int (*)(int, unsigned int) */
-		BTF_FUNC_PROTO_ENC(1, 2),			/* [3] */
-			BTF_FUNC_PROTO_ARG_ENC(0, 1),
-			BTF_FUNC_PROTO_ARG_ENC(0, 2),
-		BTF_END_RAW,
-	},
-	.str_sec = "",
-	.str_sec_size = sizeof(""),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "func_proto_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-},
-
-{
-	.descr = "func proto (vararg)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
-		/* void (*)(int, unsigned int, ...) */
-		BTF_FUNC_PROTO_ENC(0, 3),			/* [3] */
-			BTF_FUNC_PROTO_ARG_ENC(0, 1),
-			BTF_FUNC_PROTO_ARG_ENC(0, 2),
-			BTF_FUNC_PROTO_ARG_ENC(0, 0),
-		BTF_END_RAW,
-	},
-	.str_sec = "",
-	.str_sec_size = sizeof(""),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "func_proto_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-},
-
-{
-	.descr = "func proto (vararg with name)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
-		/* void (*)(int a, unsigned int b, ... c) */
-		BTF_FUNC_PROTO_ENC(0, 3),			/* [3] */
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 0),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0a\0b\0c",
-	.str_sec_size = sizeof("\0a\0b\0c"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "func_proto_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid arg#3",
-},
-
-{
-	.descr = "func proto (arg after vararg)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
-		/* void (*)(int a, ..., unsigned int b) */
-		BTF_FUNC_PROTO_ENC(0, 3),			/* [3] */
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
-			BTF_FUNC_PROTO_ARG_ENC(0, 0),
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0a\0b",
-	.str_sec_size = sizeof("\0a\0b"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "func_proto_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid arg#2",
-},
-
-{
-	.descr = "func proto (CONST=>TYPEDEF=>PTR=>FUNC_PROTO)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
-		/* typedef void (*func_ptr)(int, unsigned int) */
-		BTF_TYPEDEF_ENC(NAME_TBD, 5),			/* [3] */
-		/* const func_ptr */
-		BTF_CONST_ENC(3),				/* [4] */
-		BTF_PTR_ENC(6),					/* [5] */
-		BTF_FUNC_PROTO_ENC(0, 2),			/* [6] */
-			BTF_FUNC_PROTO_ARG_ENC(0, 1),
-			BTF_FUNC_PROTO_ARG_ENC(0, 2),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0func_ptr",
-	.str_sec_size = sizeof("\0func_ptr"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "func_proto_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-},
-
-{
-	.descr = "func proto (TYPEDEF=>FUNC_PROTO)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
-		BTF_TYPEDEF_ENC(NAME_TBD, 4),			/* [3] */
-		BTF_FUNC_PROTO_ENC(0, 2),			/* [4] */
-			BTF_FUNC_PROTO_ARG_ENC(0, 1),
-			BTF_FUNC_PROTO_ARG_ENC(0, 2),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0func_typedef",
-	.str_sec_size = sizeof("\0func_typedef"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "func_proto_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-},
-
-{
-	.descr = "func proto (btf_resolve(arg))",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		/* void (*)(const void *) */
-		BTF_FUNC_PROTO_ENC(0, 1),			/* [2] */
-			BTF_FUNC_PROTO_ARG_ENC(0, 3),
-		BTF_CONST_ENC(4),				/* [3] */
-		BTF_PTR_ENC(0),					/* [4] */
-		BTF_END_RAW,
-	},
-	.str_sec = "",
-	.str_sec_size = sizeof(""),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "func_proto_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-},
-
-{
-	.descr = "func proto (Not all arg has name)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
-		/* void (*)(int, unsigned int b) */
-		BTF_FUNC_PROTO_ENC(0, 2),			/* [3] */
-			BTF_FUNC_PROTO_ARG_ENC(0, 1),
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0b",
-	.str_sec_size = sizeof("\0b"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "func_proto_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-},
-
-{
-	.descr = "func proto (Bad arg name_off)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
-		/* void (*)(int a, unsigned int <bad_name_off>) */
-		BTF_FUNC_PROTO_ENC(0, 2),			/* [3] */
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
-			BTF_FUNC_PROTO_ARG_ENC(0x0fffffff, 2),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0a",
-	.str_sec_size = sizeof("\0a"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "func_proto_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid arg#2",
-},
-
-{
-	.descr = "func proto (Bad arg name)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
-		/* void (*)(int a, unsigned int !!!) */
-		BTF_FUNC_PROTO_ENC(0, 2),			/* [3] */
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0a\0!!!",
-	.str_sec_size = sizeof("\0a\0!!!"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "func_proto_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid arg#2",
-},
-
-{
-	.descr = "func proto (Invalid return type)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
-		/* <bad_ret_type> (*)(int, unsigned int) */
-		BTF_FUNC_PROTO_ENC(100, 2),			/* [3] */
-			BTF_FUNC_PROTO_ARG_ENC(0, 1),
-			BTF_FUNC_PROTO_ARG_ENC(0, 2),
-		BTF_END_RAW,
-	},
-	.str_sec = "",
-	.str_sec_size = sizeof(""),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "func_proto_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid return type",
-},
-
-{
-	.descr = "func proto (with func name)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
-		/* void func_proto(int, unsigned int) */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 2), 0),	/* [3] */
-			BTF_FUNC_PROTO_ARG_ENC(0, 1),
-			BTF_FUNC_PROTO_ARG_ENC(0, 2),
-		BTF_END_RAW,
-	},
-	.str_sec = "\0func_proto",
-	.str_sec_size = sizeof("\0func_proto"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "func_proto_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid name",
-},
-
-{
-	.descr = "func proto (const void arg)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
-		/* void (*)(const void) */
-		BTF_FUNC_PROTO_ENC(0, 1),			/* [3] */
-			BTF_FUNC_PROTO_ARG_ENC(0, 4),
-		BTF_CONST_ENC(0),				/* [4] */
-		BTF_END_RAW,
-	},
-	.str_sec = "",
-	.str_sec_size = sizeof(""),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "func_proto_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid arg#1",
-},
-
-{
-	.descr = "func (void func(int a, unsigned int b))",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
-		/* void (*)(int a, unsigned int b) */
-		BTF_FUNC_PROTO_ENC(0, 2),			/* [3] */
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
-		/* void func(int a, unsigned int b) */
-		BTF_FUNC_ENC(NAME_TBD, 3),			/* [4] */
-		BTF_END_RAW,
-	},
-	.str_sec = "\0a\0b\0func",
-	.str_sec_size = sizeof("\0a\0b\0func"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "func_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-},
-
-{
-	.descr = "func (No func name)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
-		/* void (*)(int a, unsigned int b) */
-		BTF_FUNC_PROTO_ENC(0, 2),			/* [3] */
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
-		/* void <no_name>(int a, unsigned int b) */
-		BTF_FUNC_ENC(0, 3),				/* [4] */
-		BTF_END_RAW,
-	},
-	.str_sec = "\0a\0b",
-	.str_sec_size = sizeof("\0a\0b"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "func_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid name",
-},
-
-{
-	.descr = "func (Invalid func name)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
-		/* void (*)(int a, unsigned int b) */
-		BTF_FUNC_PROTO_ENC(0, 2),			/* [3] */
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
-		/* void !!!(int a, unsigned int b) */
-		BTF_FUNC_ENC(NAME_TBD, 3),			/* [4] */
-		BTF_END_RAW,
-	},
-	.str_sec = "\0a\0b\0!!!",
-	.str_sec_size = sizeof("\0a\0b\0!!!"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "func_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid name",
-},
-
-{
-	.descr = "func (Some arg has no name)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
-		/* void (*)(int a, unsigned int) */
-		BTF_FUNC_PROTO_ENC(0, 2),			/* [3] */
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
-			BTF_FUNC_PROTO_ARG_ENC(0, 2),
-		/* void func(int a, unsigned int) */
-		BTF_FUNC_ENC(NAME_TBD, 3),			/* [4] */
-		BTF_END_RAW,
-	},
-	.str_sec = "\0a\0func",
-	.str_sec_size = sizeof("\0a\0func"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "func_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid arg#2",
-},
-
-{
-	.descr = "func (Non zero vlen)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),		/* [2] */
-		/* void (*)(int a, unsigned int b) */
-		BTF_FUNC_PROTO_ENC(0, 2),			/* [3] */
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
-		/* void func(int a, unsigned int b) */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FUNC, 0, 2), 3), 	/* [4] */
-		BTF_END_RAW,
-	},
-	.str_sec = "\0a\0b\0func",
-	.str_sec_size = sizeof("\0a\0b\0func"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "func_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid func linkage",
-},
-
-{
-	.descr = "func (Not referring to FUNC_PROTO)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_FUNC_ENC(NAME_TBD, 1),			/* [2] */
-		BTF_END_RAW,
-	},
-	.str_sec = "\0func",
-	.str_sec_size = sizeof("\0func"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "func_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid type_id",
-},
-
-{
-	.descr = "invalid int kind_flag",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_INT, 1, 0), 4),	/* [2] */
-		BTF_INT_ENC(0, 0, 32),
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC(""),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "int_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid btf_info kind_flag",
-},
-
-{
-	.descr = "invalid ptr kind_flag",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 1, 0), 1),	/* [2] */
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC(""),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "ptr_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid btf_info kind_flag",
-},
-
-{
-	.descr = "invalid array kind_flag",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ARRAY, 1, 0), 0),	/* [2] */
-		BTF_ARRAY_ENC(1, 1, 1),
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC(""),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "array_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid btf_info kind_flag",
-},
-
-{
-	.descr = "invalid enum kind_flag",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 1, 1), 4),	/* [2] */
-		BTF_ENUM_ENC(NAME_TBD, 0),
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0A"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "enum_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid btf_info kind_flag",
-},
-
-{
-	.descr = "valid fwd kind_flag",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
-		BTF_TYPE_ENC(NAME_TBD,
-			     BTF_INFO_ENC(BTF_KIND_FWD, 1, 0), 0),	/* [2] */
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0A"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "fwd_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-},
-
-{
-	.descr = "invalid typedef kind_flag",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
-		BTF_TYPE_ENC(NAME_TBD,
-			     BTF_INFO_ENC(BTF_KIND_TYPEDEF, 1, 0), 1),	/* [2] */
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0A"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "typedef_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid btf_info kind_flag",
-},
-
-{
-	.descr = "invalid volatile kind_flag",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_VOLATILE, 1, 0), 1),	/* [2] */
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC(""),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "volatile_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid btf_info kind_flag",
-},
-
-{
-	.descr = "invalid const kind_flag",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 1, 0), 1),	/* [2] */
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC(""),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "const_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid btf_info kind_flag",
-},
-
-{
-	.descr = "invalid restrict kind_flag",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_RESTRICT, 1, 0), 1),	/* [2] */
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC(""),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "restrict_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid btf_info kind_flag",
-},
-
-{
-	.descr = "invalid func kind_flag",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 0), 0),	/* [2] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FUNC, 1, 0), 2),	/* [3] */
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0A"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "func_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid btf_info kind_flag",
-},
-
-{
-	.descr = "invalid func_proto kind_flag",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 1, 0), 0),	/* [2] */
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC(""),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "func_proto_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid btf_info kind_flag",
-},
-
-{
-	.descr = "valid struct, kind_flag, bitfield_size = 0",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 8),	/* [2] */
-		BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(0, 0)),
-		BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(0, 32)),
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0A\0B"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "struct_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-},
-
-{
-	.descr = "valid struct, kind_flag, int member, bitfield_size != 0",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),	/* [2] */
-		BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 0)),
-		BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 4)),
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0A\0B"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "struct_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-},
-
-{
-	.descr = "valid union, kind_flag, int member, bitfield_size != 0",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 4),	/* [2] */
-		BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 0)),
-		BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 0)),
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0A\0B"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "union_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-},
-
-{
-	.descr = "valid struct, kind_flag, enum member, bitfield_size != 0",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),	/* [2] */
-		BTF_ENUM_ENC(NAME_TBD, 0),
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),/* [3] */
-		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 0)),
-		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 4)),
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0A\0B\0C"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "struct_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-},
-
-{
-	.descr = "valid union, kind_flag, enum member, bitfield_size != 0",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),	/* [2] */
-		BTF_ENUM_ENC(NAME_TBD, 0),
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 4),	/* [3] */
-		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 0)),
-		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 0)),
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0A\0B\0C"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "union_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-},
-
-{
-	.descr = "valid struct, kind_flag, typedef member, bitfield_size != 0",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),	/* [2] */
-		BTF_ENUM_ENC(NAME_TBD, 0),
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),/* [3] */
-		BTF_MEMBER_ENC(NAME_TBD, 4, BTF_MEMBER_OFFSET(4, 0)),
-		BTF_MEMBER_ENC(NAME_TBD, 5, BTF_MEMBER_OFFSET(4, 4)),
-		BTF_TYPEDEF_ENC(NAME_TBD, 1),				/* [4] */
-		BTF_TYPEDEF_ENC(NAME_TBD, 2),				/* [5] */
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0A\0B\0C\0D\0E"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "struct_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-},
-
-{
-	.descr = "valid union, kind_flag, typedef member, bitfield_size != 0",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),	/* [2] */
-		BTF_ENUM_ENC(NAME_TBD, 0),
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 4),	/* [3] */
-		BTF_MEMBER_ENC(NAME_TBD, 4, BTF_MEMBER_OFFSET(4, 0)),
-		BTF_MEMBER_ENC(NAME_TBD, 5, BTF_MEMBER_OFFSET(4, 0)),
-		BTF_TYPEDEF_ENC(NAME_TBD, 1),				/* [4] */
-		BTF_TYPEDEF_ENC(NAME_TBD, 2),				/* [5] */
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0A\0B\0C\0D\0E"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "union_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-},
-
-{
-	.descr = "invalid struct, kind_flag, bitfield_size greater than struct size",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),	/* [2] */
-		BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(20, 0)),
-		BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(20, 20)),
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0A\0B"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "struct_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Member exceeds struct_size",
-},
-
-{
-	.descr = "invalid struct, kind_flag, bitfield base_type int not regular",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 20, 4),			/* [2] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),	/* [3] */
-		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(20, 0)),
-		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(20, 20)),
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0A\0B"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "struct_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid member base type",
-},
-
-{
-	.descr = "invalid struct, kind_flag, base_type int not regular",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 12, 4),			/* [2] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),	/* [3] */
-		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(8, 0)),
-		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(8, 8)),
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0A\0B"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "struct_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid member base type",
-},
-
-{
-	.descr = "invalid union, kind_flag, bitfield_size greater than struct size",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),		/* [1] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 2),	/* [2] */
-		BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(8, 0)),
-		BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(20, 0)),
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0A\0B"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "union_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Member exceeds struct_size",
-},
-
-{
-	.descr = "invalid struct, kind_flag, int member, bitfield_size = 0, wrong byte alignment",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [2] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 12),	/* [3] */
-		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)),
-		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 36)),
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0A\0B"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "struct_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid member offset",
-},
-
-{
-	.descr = "invalid struct, kind_flag, enum member, bitfield_size = 0, wrong byte alignment",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [2] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),	/* [2] */
-		BTF_ENUM_ENC(NAME_TBD, 0),
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 12),	/* [3] */
-		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)),
-		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 36)),
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0A\0B\0C"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "struct_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-	.btf_load_err = true,
-	.err_str = "Invalid member offset",
-},
-
-{
-	.descr = "128-bit int",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 128, 16),		/* [2] */
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0A"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "int_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-},
-
-{
-	.descr = "struct, 128-bit int member",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 128, 16),		/* [2] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 16),	/* [3] */
-		BTF_MEMBER_ENC(NAME_TBD, 2, 0),
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0A"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "struct_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-},
-
-{
-	.descr = "struct, 120-bit int member bitfield",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 120, 16),		/* [2] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 1), 16),	/* [3] */
-		BTF_MEMBER_ENC(NAME_TBD, 2, 0),
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0A"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "struct_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-},
-
-{
-	.descr = "struct, kind_flag, 128-bit int member",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 128, 16),		/* [2] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 1), 16),	/* [3] */
-		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)),
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0A"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "struct_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-},
-
-{
-	.descr = "struct, kind_flag, 120-bit int member bitfield",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),			/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 128, 16),		/* [2] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 1), 16),	/* [3] */
-		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(120, 0)),
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0A"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "struct_type_check_btf",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int),
-	.key_type_id = 1,
-	.value_type_id = 1,
-	.max_entries = 4,
-},
-/*
- * typedef int arr_t[16];
- * struct s {
- *	arr_t *a;
- * };
- */
-{
-	.descr = "struct->ptr->typedef->array->int size resolution",
-	.raw_types = {
-		BTF_STRUCT_ENC(NAME_TBD, 1, 8),			/* [1] */
-		BTF_MEMBER_ENC(NAME_TBD, 2, 0),
-		BTF_PTR_ENC(3),					/* [2] */
-		BTF_TYPEDEF_ENC(NAME_TBD, 4),			/* [3] */
-		BTF_TYPE_ARRAY_ENC(5, 5, 16),			/* [4] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [5] */
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0s\0a\0arr_t"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "ptr_mod_chain_size_resolve_map",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int) * 16,
-	.key_type_id = 5 /* int */,
-	.value_type_id = 3 /* arr_t */,
-	.max_entries = 4,
-},
-/*
- * typedef int arr_t[16][8][4];
- * struct s {
- *	arr_t *a;
- * };
- */
-{
-	.descr = "struct->ptr->typedef->multi-array->int size resolution",
-	.raw_types = {
-		BTF_STRUCT_ENC(NAME_TBD, 1, 8),			/* [1] */
-		BTF_MEMBER_ENC(NAME_TBD, 2, 0),
-		BTF_PTR_ENC(3),					/* [2] */
-		BTF_TYPEDEF_ENC(NAME_TBD, 4),			/* [3] */
-		BTF_TYPE_ARRAY_ENC(5, 7, 16),			/* [4] */
-		BTF_TYPE_ARRAY_ENC(6, 7, 8),			/* [5] */
-		BTF_TYPE_ARRAY_ENC(7, 7, 4),			/* [6] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [7] */
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0s\0a\0arr_t"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "multi_arr_size_resolve_map",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int) * 16 * 8 * 4,
-	.key_type_id = 7 /* int */,
-	.value_type_id = 3 /* arr_t */,
-	.max_entries = 4,
-},
-/*
- * typedef int int_t;
- * typedef int_t arr3_t[4];
- * typedef arr3_t arr2_t[8];
- * typedef arr2_t arr1_t[16];
- * struct s {
- *	arr1_t *a;
- * };
- */
-{
-	.descr = "typedef/multi-arr mix size resolution",
-	.raw_types = {
-		BTF_STRUCT_ENC(NAME_TBD, 1, 8),			/* [1] */
-		BTF_MEMBER_ENC(NAME_TBD, 2, 0),
-		BTF_PTR_ENC(3),					/* [2] */
-		BTF_TYPEDEF_ENC(NAME_TBD, 4),			/* [3] */
-		BTF_TYPE_ARRAY_ENC(5, 10, 16),			/* [4] */
-		BTF_TYPEDEF_ENC(NAME_TBD, 6),			/* [5] */
-		BTF_TYPE_ARRAY_ENC(7, 10, 8),			/* [6] */
-		BTF_TYPEDEF_ENC(NAME_TBD, 8),			/* [7] */
-		BTF_TYPE_ARRAY_ENC(9, 10, 4),			/* [8] */
-		BTF_TYPEDEF_ENC(NAME_TBD, 10),			/* [9] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [10] */
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0s\0a\0arr1_t\0arr2_t\0arr3_t\0int_t"),
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "typedef_arra_mix_size_resolve_map",
-	.key_size = sizeof(int),
-	.value_size = sizeof(int) * 16 * 8 * 4,
-	.key_type_id = 10 /* int */,
-	.value_type_id = 3 /* arr_t */,
-	.max_entries = 4,
-},
-
-}; /* struct btf_raw_test raw_tests[] */
-
-static const char *get_next_str(const char *start, const char *end)
-{
-	return start < end - 1 ? start + 1 : NULL;
-}
-
-static int get_raw_sec_size(const __u32 *raw_types)
-{
-	int i;
-
-	for (i = MAX_NR_RAW_U32 - 1;
-	     i >= 0 && raw_types[i] != BTF_END_RAW;
-	     i--)
-		;
-
-	return i < 0 ? i : i * sizeof(raw_types[0]);
-}
-
-static void *btf_raw_create(const struct btf_header *hdr,
-			    const __u32 *raw_types,
-			    const char *str,
-			    unsigned int str_sec_size,
-			    unsigned int *btf_size,
-			    const char **ret_next_str)
-{
-	const char *next_str = str, *end_str = str + str_sec_size;
-	const char **strs_idx = NULL, **tmp_strs_idx;
-	int strs_cap = 0, strs_cnt = 0, next_str_idx = 0;
-	unsigned int size_needed, offset;
-	struct btf_header *ret_hdr;
-	int i, type_sec_size, err = 0;
-	uint32_t *ret_types;
-	void *raw_btf = NULL;
-
-	type_sec_size = get_raw_sec_size(raw_types);
-	if (CHECK(type_sec_size < 0, "Cannot get nr_raw_types"))
-		return NULL;
-
-	size_needed = sizeof(*hdr) + type_sec_size + str_sec_size;
-	raw_btf = malloc(size_needed);
-	if (CHECK(!raw_btf, "Cannot allocate memory for raw_btf"))
-		return NULL;
-
-	/* Copy header */
-	memcpy(raw_btf, hdr, sizeof(*hdr));
-	offset = sizeof(*hdr);
-
-	/* Index strings */
-	while ((next_str = get_next_str(next_str, end_str))) {
-		if (strs_cnt == strs_cap) {
-			strs_cap += max(16, strs_cap / 2);
-			tmp_strs_idx = realloc(strs_idx,
-					       sizeof(*strs_idx) * strs_cap);
-			if (CHECK(!tmp_strs_idx,
-				  "Cannot allocate memory for strs_idx")) {
-				err = -1;
-				goto done;
-			}
-			strs_idx = tmp_strs_idx;
-		}
-		strs_idx[strs_cnt++] = next_str;
-		next_str += strlen(next_str);
-	}
-
-	/* Copy type section */
-	ret_types = raw_btf + offset;
-	for (i = 0; i < type_sec_size / sizeof(raw_types[0]); i++) {
-		if (raw_types[i] == NAME_TBD) {
-			if (CHECK(next_str_idx == strs_cnt,
-				  "Error in getting next_str #%d",
-				  next_str_idx)) {
-				err = -1;
-				goto done;
-			}
-			ret_types[i] = strs_idx[next_str_idx++] - str;
-		} else if (IS_NAME_NTH(raw_types[i])) {
-			int idx = GET_NAME_NTH_IDX(raw_types[i]);
-
-			if (CHECK(idx <= 0 || idx > strs_cnt,
-				  "Error getting string #%d, strs_cnt:%d",
-				  idx, strs_cnt)) {
-				err = -1;
-				goto done;
-			}
-			ret_types[i] = strs_idx[idx-1] - str;
-		} else {
-			ret_types[i] = raw_types[i];
-		}
-	}
-	offset += type_sec_size;
-
-	/* Copy string section */
-	memcpy(raw_btf + offset, str, str_sec_size);
-
-	ret_hdr = (struct btf_header *)raw_btf;
-	ret_hdr->type_len = type_sec_size;
-	ret_hdr->str_off = type_sec_size;
-	ret_hdr->str_len = str_sec_size;
-
-	*btf_size = size_needed;
-	if (ret_next_str)
-		*ret_next_str =
-			next_str_idx < strs_cnt ? strs_idx[next_str_idx] : NULL;
-
-done:
-	if (err) {
-		if (raw_btf)
-			free(raw_btf);
-		if (strs_idx)
-			free(strs_idx);
-		return NULL;
-	}
-	return raw_btf;
-}
-
-static int do_test_raw(unsigned int test_num)
-{
-	struct btf_raw_test *test = &raw_tests[test_num - 1];
-	struct bpf_create_map_attr create_attr = {};
-	int map_fd = -1, btf_fd = -1;
-	unsigned int raw_btf_size;
-	struct btf_header *hdr;
-	void *raw_btf;
-	int err;
-
-	fprintf(stderr, "BTF raw test[%u] (%s): ", test_num, test->descr);
-	raw_btf = btf_raw_create(&hdr_tmpl,
-				 test->raw_types,
-				 test->str_sec,
-				 test->str_sec_size,
-				 &raw_btf_size, NULL);
-
-	if (!raw_btf)
-		return -1;
-
-	hdr = raw_btf;
-
-	hdr->hdr_len = (int)hdr->hdr_len + test->hdr_len_delta;
-	hdr->type_off = (int)hdr->type_off + test->type_off_delta;
-	hdr->str_off = (int)hdr->str_off + test->str_off_delta;
-	hdr->str_len = (int)hdr->str_len + test->str_len_delta;
-
-	*btf_log_buf = '\0';
-	btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
-			      btf_log_buf, BTF_LOG_BUF_SIZE,
-			      args.always_log);
-	free(raw_btf);
-
-	err = ((btf_fd == -1) != test->btf_load_err);
-	if (CHECK(err, "btf_fd:%d test->btf_load_err:%u",
-		  btf_fd, test->btf_load_err) ||
-	    CHECK(test->err_str && !strstr(btf_log_buf, test->err_str),
-		  "expected err_str:%s", test->err_str)) {
-		err = -1;
-		goto done;
-	}
-
-	if (err || btf_fd == -1)
-		goto done;
-
-	create_attr.name = test->map_name;
-	create_attr.map_type = test->map_type;
-	create_attr.key_size = test->key_size;
-	create_attr.value_size = test->value_size;
-	create_attr.max_entries = test->max_entries;
-	create_attr.btf_fd = btf_fd;
-	create_attr.btf_key_type_id = test->key_type_id;
-	create_attr.btf_value_type_id = test->value_type_id;
-
-	map_fd = bpf_create_map_xattr(&create_attr);
-
-	err = ((map_fd == -1) != test->map_create_err);
-	CHECK(err, "map_fd:%d test->map_create_err:%u",
-	      map_fd, test->map_create_err);
-
-done:
-	if (!err)
-		fprintf(stderr, "OK");
-
-	if (*btf_log_buf && (err || args.always_log))
-		fprintf(stderr, "\n%s", btf_log_buf);
-
-	if (btf_fd != -1)
-		close(btf_fd);
-	if (map_fd != -1)
-		close(map_fd);
-
-	return err;
-}
-
-static int test_raw(void)
-{
-	unsigned int i;
-	int err = 0;
-
-	if (args.raw_test_num)
-		return count_result(do_test_raw(args.raw_test_num));
-
-	for (i = 1; i <= ARRAY_SIZE(raw_tests); i++)
-		err |= count_result(do_test_raw(i));
-
-	return err;
-}
-
-struct btf_get_info_test {
-	const char *descr;
-	const char *str_sec;
-	__u32 raw_types[MAX_NR_RAW_U32];
-	__u32 str_sec_size;
-	int btf_size_delta;
-	int (*special_test)(unsigned int test_num);
-};
-
-static int test_big_btf_info(unsigned int test_num);
-static int test_btf_id(unsigned int test_num);
-
-const struct btf_get_info_test get_info_tests[] = {
-{
-	.descr = "== raw_btf_size+1",
-	.raw_types = {
-		/* int */				/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
-		BTF_END_RAW,
-	},
-	.str_sec = "",
-	.str_sec_size = sizeof(""),
-	.btf_size_delta = 1,
-},
-{
-	.descr = "== raw_btf_size-3",
-	.raw_types = {
-		/* int */				/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
-		BTF_END_RAW,
-	},
-	.str_sec = "",
-	.str_sec_size = sizeof(""),
-	.btf_size_delta = -3,
-},
-{
-	.descr = "Large bpf_btf_info",
-	.raw_types = {
-		/* int */				/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
-		BTF_END_RAW,
-	},
-	.str_sec = "",
-	.str_sec_size = sizeof(""),
-	.special_test = test_big_btf_info,
-},
-{
-	.descr = "BTF ID",
-	.raw_types = {
-		/* int */				/* [1] */
-		BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),
-		/* unsigned int */			/* [2] */
-		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),
-		BTF_END_RAW,
-	},
-	.str_sec = "",
-	.str_sec_size = sizeof(""),
-	.special_test = test_btf_id,
-},
-};
-
-static inline __u64 ptr_to_u64(const void *ptr)
-{
-	return (__u64)(unsigned long)ptr;
-}
-
-static int test_big_btf_info(unsigned int test_num)
-{
-	const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
-	uint8_t *raw_btf = NULL, *user_btf = NULL;
-	unsigned int raw_btf_size;
-	struct {
-		struct bpf_btf_info info;
-		uint64_t garbage;
-	} info_garbage;
-	struct bpf_btf_info *info;
-	int btf_fd = -1, err;
-	uint32_t info_len;
-
-	raw_btf = btf_raw_create(&hdr_tmpl,
-				 test->raw_types,
-				 test->str_sec,
-				 test->str_sec_size,
-				 &raw_btf_size, NULL);
-
-	if (!raw_btf)
-		return -1;
-
-	*btf_log_buf = '\0';
-
-	user_btf = malloc(raw_btf_size);
-	if (CHECK(!user_btf, "!user_btf")) {
-		err = -1;
-		goto done;
-	}
-
-	btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
-			      btf_log_buf, BTF_LOG_BUF_SIZE,
-			      args.always_log);
-	if (CHECK(btf_fd == -1, "errno:%d", errno)) {
-		err = -1;
-		goto done;
-	}
-
-	/*
-	 * GET_INFO should error out if the userspace info
-	 * has non zero tailing bytes.
-	 */
-	info = &info_garbage.info;
-	memset(info, 0, sizeof(*info));
-	info_garbage.garbage = 0xdeadbeef;
-	info_len = sizeof(info_garbage);
-	info->btf = ptr_to_u64(user_btf);
-	info->btf_size = raw_btf_size;
-
-	err = bpf_obj_get_info_by_fd(btf_fd, info, &info_len);
-	if (CHECK(!err, "!err")) {
-		err = -1;
-		goto done;
-	}
-
-	/*
-	 * GET_INFO should succeed even info_len is larger than
-	 * the kernel supported as long as tailing bytes are zero.
-	 * The kernel supported info len should also be returned
-	 * to userspace.
-	 */
-	info_garbage.garbage = 0;
-	err = bpf_obj_get_info_by_fd(btf_fd, info, &info_len);
-	if (CHECK(err || info_len != sizeof(*info),
-		  "err:%d errno:%d info_len:%u sizeof(*info):%zu",
-		  err, errno, info_len, sizeof(*info))) {
-		err = -1;
-		goto done;
-	}
-
-	fprintf(stderr, "OK");
-
-done:
-	if (*btf_log_buf && (err || args.always_log))
-		fprintf(stderr, "\n%s", btf_log_buf);
-
-	free(raw_btf);
-	free(user_btf);
-
-	if (btf_fd != -1)
-		close(btf_fd);
-
-	return err;
-}
-
-static int test_btf_id(unsigned int test_num)
-{
-	const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
-	struct bpf_create_map_attr create_attr = {};
-	uint8_t *raw_btf = NULL, *user_btf[2] = {};
-	int btf_fd[2] = {-1, -1}, map_fd = -1;
-	struct bpf_map_info map_info = {};
-	struct bpf_btf_info info[2] = {};
-	unsigned int raw_btf_size;
-	uint32_t info_len;
-	int err, i, ret;
-
-	raw_btf = btf_raw_create(&hdr_tmpl,
-				 test->raw_types,
-				 test->str_sec,
-				 test->str_sec_size,
-				 &raw_btf_size, NULL);
-
-	if (!raw_btf)
-		return -1;
-
-	*btf_log_buf = '\0';
-
-	for (i = 0; i < 2; i++) {
-		user_btf[i] = malloc(raw_btf_size);
-		if (CHECK(!user_btf[i], "!user_btf[%d]", i)) {
-			err = -1;
-			goto done;
-		}
-		info[i].btf = ptr_to_u64(user_btf[i]);
-		info[i].btf_size = raw_btf_size;
-	}
-
-	btf_fd[0] = bpf_load_btf(raw_btf, raw_btf_size,
-				 btf_log_buf, BTF_LOG_BUF_SIZE,
-				 args.always_log);
-	if (CHECK(btf_fd[0] == -1, "errno:%d", errno)) {
-		err = -1;
-		goto done;
-	}
-
-	/* Test BPF_OBJ_GET_INFO_BY_ID on btf_id */
-	info_len = sizeof(info[0]);
-	err = bpf_obj_get_info_by_fd(btf_fd[0], &info[0], &info_len);
-	if (CHECK(err, "errno:%d", errno)) {
-		err = -1;
-		goto done;
-	}
-
-	btf_fd[1] = bpf_btf_get_fd_by_id(info[0].id);
-	if (CHECK(btf_fd[1] == -1, "errno:%d", errno)) {
-		err = -1;
-		goto done;
-	}
-
-	ret = 0;
-	err = bpf_obj_get_info_by_fd(btf_fd[1], &info[1], &info_len);
-	if (CHECK(err || info[0].id != info[1].id ||
-		  info[0].btf_size != info[1].btf_size ||
-		  (ret = memcmp(user_btf[0], user_btf[1], info[0].btf_size)),
-		  "err:%d errno:%d id0:%u id1:%u btf_size0:%u btf_size1:%u memcmp:%d",
-		  err, errno, info[0].id, info[1].id,
-		  info[0].btf_size, info[1].btf_size, ret)) {
-		err = -1;
-		goto done;
-	}
-
-	/* Test btf members in struct bpf_map_info */
-	create_attr.name = "test_btf_id";
-	create_attr.map_type = BPF_MAP_TYPE_ARRAY;
-	create_attr.key_size = sizeof(int);
-	create_attr.value_size = sizeof(unsigned int);
-	create_attr.max_entries = 4;
-	create_attr.btf_fd = btf_fd[0];
-	create_attr.btf_key_type_id = 1;
-	create_attr.btf_value_type_id = 2;
-
-	map_fd = bpf_create_map_xattr(&create_attr);
-	if (CHECK(map_fd == -1, "errno:%d", errno)) {
-		err = -1;
-		goto done;
-	}
-
-	info_len = sizeof(map_info);
-	err = bpf_obj_get_info_by_fd(map_fd, &map_info, &info_len);
-	if (CHECK(err || map_info.btf_id != info[0].id ||
-		  map_info.btf_key_type_id != 1 || map_info.btf_value_type_id != 2,
-		  "err:%d errno:%d info.id:%u btf_id:%u btf_key_type_id:%u btf_value_type_id:%u",
-		  err, errno, info[0].id, map_info.btf_id, map_info.btf_key_type_id,
-		  map_info.btf_value_type_id)) {
-		err = -1;
-		goto done;
-	}
-
-	for (i = 0; i < 2; i++) {
-		close(btf_fd[i]);
-		btf_fd[i] = -1;
-	}
-
-	/* Test BTF ID is removed from the kernel */
-	btf_fd[0] = bpf_btf_get_fd_by_id(map_info.btf_id);
-	if (CHECK(btf_fd[0] == -1, "errno:%d", errno)) {
-		err = -1;
-		goto done;
-	}
-	close(btf_fd[0]);
-	btf_fd[0] = -1;
-
-	/* The map holds the last ref to BTF and its btf_id */
-	close(map_fd);
-	map_fd = -1;
-	btf_fd[0] = bpf_btf_get_fd_by_id(map_info.btf_id);
-	if (CHECK(btf_fd[0] != -1, "BTF lingers")) {
-		err = -1;
-		goto done;
-	}
-
-	fprintf(stderr, "OK");
-
-done:
-	if (*btf_log_buf && (err || args.always_log))
-		fprintf(stderr, "\n%s", btf_log_buf);
-
-	free(raw_btf);
-	if (map_fd != -1)
-		close(map_fd);
-	for (i = 0; i < 2; i++) {
-		free(user_btf[i]);
-		if (btf_fd[i] != -1)
-			close(btf_fd[i]);
-	}
-
-	return err;
-}
-
-static int do_test_get_info(unsigned int test_num)
-{
-	const struct btf_get_info_test *test = &get_info_tests[test_num - 1];
-	unsigned int raw_btf_size, user_btf_size, expected_nbytes;
-	uint8_t *raw_btf = NULL, *user_btf = NULL;
-	struct bpf_btf_info info = {};
-	int btf_fd = -1, err, ret;
-	uint32_t info_len;
-
-	fprintf(stderr, "BTF GET_INFO test[%u] (%s): ",
-		test_num, test->descr);
-
-	if (test->special_test)
-		return test->special_test(test_num);
-
-	raw_btf = btf_raw_create(&hdr_tmpl,
-				 test->raw_types,
-				 test->str_sec,
-				 test->str_sec_size,
-				 &raw_btf_size, NULL);
-
-	if (!raw_btf)
-		return -1;
-
-	*btf_log_buf = '\0';
-
-	user_btf = malloc(raw_btf_size);
-	if (CHECK(!user_btf, "!user_btf")) {
-		err = -1;
-		goto done;
-	}
-
-	btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
-			      btf_log_buf, BTF_LOG_BUF_SIZE,
-			      args.always_log);
-	if (CHECK(btf_fd == -1, "errno:%d", errno)) {
-		err = -1;
-		goto done;
-	}
-
-	user_btf_size = (int)raw_btf_size + test->btf_size_delta;
-	expected_nbytes = min(raw_btf_size, user_btf_size);
-	if (raw_btf_size > expected_nbytes)
-		memset(user_btf + expected_nbytes, 0xff,
-		       raw_btf_size - expected_nbytes);
-
-	info_len = sizeof(info);
-	info.btf = ptr_to_u64(user_btf);
-	info.btf_size = user_btf_size;
-
-	ret = 0;
-	err = bpf_obj_get_info_by_fd(btf_fd, &info, &info_len);
-	if (CHECK(err || !info.id || info_len != sizeof(info) ||
-		  info.btf_size != raw_btf_size ||
-		  (ret = memcmp(raw_btf, user_btf, expected_nbytes)),
-		  "err:%d errno:%d info.id:%u info_len:%u sizeof(info):%zu raw_btf_size:%u info.btf_size:%u expected_nbytes:%u memcmp:%d",
-		  err, errno, info.id, info_len, sizeof(info),
-		  raw_btf_size, info.btf_size, expected_nbytes, ret)) {
-		err = -1;
-		goto done;
-	}
-
-	while (expected_nbytes < raw_btf_size) {
-		fprintf(stderr, "%u...", expected_nbytes);
-		if (CHECK(user_btf[expected_nbytes++] != 0xff,
-			  "user_btf[%u]:%x != 0xff", expected_nbytes - 1,
-			  user_btf[expected_nbytes - 1])) {
-			err = -1;
-			goto done;
-		}
-	}
-
-	fprintf(stderr, "OK");
-
-done:
-	if (*btf_log_buf && (err || args.always_log))
-		fprintf(stderr, "\n%s", btf_log_buf);
-
-	free(raw_btf);
-	free(user_btf);
-
-	if (btf_fd != -1)
-		close(btf_fd);
-
-	return err;
-}
-
-static int test_get_info(void)
-{
-	unsigned int i;
-	int err = 0;
-
-	if (args.get_info_test_num)
-		return count_result(do_test_get_info(args.get_info_test_num));
-
-	for (i = 1; i <= ARRAY_SIZE(get_info_tests); i++)
-		err |= count_result(do_test_get_info(i));
-
-	return err;
-}
-
-struct btf_file_test {
-	const char *file;
-	bool btf_kv_notfound;
-};
-
-static struct btf_file_test file_tests[] = {
-	{ .file = "test_btf_haskv.o", },
-	{ .file = "test_btf_newkv.o", },
-	{ .file = "test_btf_nokv.o", .btf_kv_notfound = true, },
-};
-
-static int do_test_file(unsigned int test_num)
-{
-	const struct btf_file_test *test = &file_tests[test_num - 1];
-	const char *expected_fnames[] = {"_dummy_tracepoint",
-					 "test_long_fname_1",
-					 "test_long_fname_2"};
-	struct btf_ext *btf_ext = NULL;
-	struct bpf_prog_info info = {};
-	struct bpf_object *obj = NULL;
-	struct bpf_func_info *finfo;
-	struct bpf_program *prog;
-	__u32 info_len, rec_size;
-	bool has_btf_ext = false;
-	struct btf *btf = NULL;
-	void *func_info = NULL;
-	struct bpf_map *map;
-	int i, err, prog_fd;
-
-	fprintf(stderr, "BTF libbpf test[%u] (%s): ", test_num,
-		test->file);
-
-	btf = btf__parse_elf(test->file, &btf_ext);
-	if (IS_ERR(btf)) {
-		if (PTR_ERR(btf) == -ENOENT) {
-			fprintf(stderr, "SKIP. No ELF %s found", BTF_ELF_SEC);
-			skip_cnt++;
-			return 0;
-		}
-		return PTR_ERR(btf);
-	}
-	btf__free(btf);
-
-	has_btf_ext = btf_ext != NULL;
-	btf_ext__free(btf_ext);
-
-	obj = bpf_object__open(test->file);
-	if (CHECK(IS_ERR(obj), "obj: %ld", PTR_ERR(obj)))
-		return PTR_ERR(obj);
-
-	prog = bpf_program__next(NULL, obj);
-	if (CHECK(!prog, "Cannot find bpf_prog")) {
-		err = -1;
-		goto done;
-	}
-
-	bpf_program__set_type(prog, BPF_PROG_TYPE_TRACEPOINT);
-	err = bpf_object__load(obj);
-	if (CHECK(err < 0, "bpf_object__load: %d", err))
-		goto done;
-	prog_fd = bpf_program__fd(prog);
-
-	map = bpf_object__find_map_by_name(obj, "btf_map");
-	if (CHECK(!map, "btf_map not found")) {
-		err = -1;
-		goto done;
-	}
-
-	err = (bpf_map__btf_key_type_id(map) == 0 || bpf_map__btf_value_type_id(map) == 0)
-		!= test->btf_kv_notfound;
-	if (CHECK(err, "btf_key_type_id:%u btf_value_type_id:%u test->btf_kv_notfound:%u",
-		  bpf_map__btf_key_type_id(map), bpf_map__btf_value_type_id(map),
-		  test->btf_kv_notfound))
-		goto done;
-
-	if (!has_btf_ext)
-		goto skip;
-
-	/* get necessary program info */
-	info_len = sizeof(struct bpf_prog_info);
-	err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
-
-	if (CHECK(err == -1, "invalid get info (1st) errno:%d", errno)) {
-		fprintf(stderr, "%s\n", btf_log_buf);
-		err = -1;
-		goto done;
-	}
-	if (CHECK(info.nr_func_info != 3,
-		  "incorrect info.nr_func_info (1st) %d",
-		  info.nr_func_info)) {
-		err = -1;
-		goto done;
-	}
-	rec_size = info.func_info_rec_size;
-	if (CHECK(rec_size != sizeof(struct bpf_func_info),
-		  "incorrect info.func_info_rec_size (1st) %d\n", rec_size)) {
-		err = -1;
-		goto done;
-	}
-
-	func_info = malloc(info.nr_func_info * rec_size);
-	if (CHECK(!func_info, "out of memory")) {
-		err = -1;
-		goto done;
-	}
-
-	/* reset info to only retrieve func_info related data */
-	memset(&info, 0, sizeof(info));
-	info.nr_func_info = 3;
-	info.func_info_rec_size = rec_size;
-	info.func_info = ptr_to_u64(func_info);
-
-	err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
-
-	if (CHECK(err == -1, "invalid get info (2nd) errno:%d", errno)) {
-		fprintf(stderr, "%s\n", btf_log_buf);
-		err = -1;
-		goto done;
-	}
-	if (CHECK(info.nr_func_info != 3,
-		  "incorrect info.nr_func_info (2nd) %d",
-		  info.nr_func_info)) {
-		err = -1;
-		goto done;
-	}
-	if (CHECK(info.func_info_rec_size != rec_size,
-		  "incorrect info.func_info_rec_size (2nd) %d",
-		  info.func_info_rec_size)) {
-		err = -1;
-		goto done;
-	}
-
-	err = btf__get_from_id(info.btf_id, &btf);
-	if (CHECK(err, "cannot get btf from kernel, err: %d", err))
-		goto done;
-
-	/* check three functions */
-	finfo = func_info;
-	for (i = 0; i < 3; i++) {
-		const struct btf_type *t;
-		const char *fname;
-
-		t = btf__type_by_id(btf, finfo->type_id);
-		if (CHECK(!t, "btf__type_by_id failure: id %u",
-			  finfo->type_id)) {
-			err = -1;
-			goto done;
-		}
-
-		fname = btf__name_by_offset(btf, t->name_off);
-		err = strcmp(fname, expected_fnames[i]);
-		/* for the second and third functions in .text section,
-		 * the compiler may order them either way.
-		 */
-		if (i && err)
-			err = strcmp(fname, expected_fnames[3 - i]);
-		if (CHECK(err, "incorrect fname %s", fname ? : "")) {
-			err = -1;
-			goto done;
-		}
-
-		finfo = (void *)finfo + rec_size;
-	}
-
-skip:
-	fprintf(stderr, "OK");
-
-done:
-	free(func_info);
-	bpf_object__close(obj);
-	return err;
-}
-
-static int test_file(void)
-{
-	unsigned int i;
-	int err = 0;
-
-	if (args.file_test_num)
-		return count_result(do_test_file(args.file_test_num));
-
-	for (i = 1; i <= ARRAY_SIZE(file_tests); i++)
-		err |= count_result(do_test_file(i));
-
-	return err;
-}
-
-const char *pprint_enum_str[] = {
-	"ENUM_ZERO",
-	"ENUM_ONE",
-	"ENUM_TWO",
-	"ENUM_THREE",
-};
-
-struct pprint_mapv {
-	uint32_t ui32;
-	uint16_t ui16;
-	/* 2 bytes hole */
-	int32_t si32;
-	uint32_t unused_bits2a:2,
-		bits28:28,
-		unused_bits2b:2;
-	union {
-		uint64_t ui64;
-		uint8_t ui8a[8];
-	};
-	enum {
-		ENUM_ZERO,
-		ENUM_ONE,
-		ENUM_TWO,
-		ENUM_THREE,
-	} aenum;
-	uint32_t ui32b;
-	uint32_t bits2c:2;
-	uint8_t si8_4[2][2];
-};
-
-#ifdef __SIZEOF_INT128__
-struct pprint_mapv_int128 {
-	__int128 si128a;
-	__int128 si128b;
-	unsigned __int128 bits3:3;
-	unsigned __int128 bits80:80;
-	unsigned __int128 ui128;
-};
-#endif
-
-static struct btf_raw_test pprint_test_template[] = {
-{
-	.raw_types = {
-		/* unsighed char */			/* [1] */
-		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
-		/* unsigned short */			/* [2] */
-		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
-		/* unsigned int */			/* [3] */
-		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
-		/* int */				/* [4] */
-		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
-		/* unsigned long long */		/* [5] */
-		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
-		/* 2 bits */				/* [6] */
-		BTF_TYPE_INT_ENC(0, 0, 0, 2, 2),
-		/* 28 bits */				/* [7] */
-		BTF_TYPE_INT_ENC(0, 0, 0, 28, 4),
-		/* uint8_t[8] */			/* [8] */
-		BTF_TYPE_ARRAY_ENC(9, 1, 8),
-		/* typedef unsigned char uint8_t */	/* [9] */
-		BTF_TYPEDEF_ENC(NAME_TBD, 1),
-		/* typedef unsigned short uint16_t */	/* [10] */
-		BTF_TYPEDEF_ENC(NAME_TBD, 2),
-		/* typedef unsigned int uint32_t */	/* [11] */
-		BTF_TYPEDEF_ENC(NAME_TBD, 3),
-		/* typedef int int32_t */		/* [12] */
-		BTF_TYPEDEF_ENC(NAME_TBD, 4),
-		/* typedef unsigned long long uint64_t *//* [13] */
-		BTF_TYPEDEF_ENC(NAME_TBD, 5),
-		/* union (anon) */			/* [14] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
-		BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
-		BTF_MEMBER_ENC(NAME_TBD, 8, 0),	/* uint8_t ui8a[8]; */
-		/* enum (anon) */			/* [15] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
-		BTF_ENUM_ENC(NAME_TBD, 0),
-		BTF_ENUM_ENC(NAME_TBD, 1),
-		BTF_ENUM_ENC(NAME_TBD, 2),
-		BTF_ENUM_ENC(NAME_TBD, 3),
-		/* struct pprint_mapv */		/* [16] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 11), 40),
-		BTF_MEMBER_ENC(NAME_TBD, 11, 0),	/* uint32_t ui32 */
-		BTF_MEMBER_ENC(NAME_TBD, 10, 32),	/* uint16_t ui16 */
-		BTF_MEMBER_ENC(NAME_TBD, 12, 64),	/* int32_t si32 */
-		BTF_MEMBER_ENC(NAME_TBD, 6, 96),	/* unused_bits2a */
-		BTF_MEMBER_ENC(NAME_TBD, 7, 98),	/* bits28 */
-		BTF_MEMBER_ENC(NAME_TBD, 6, 126),	/* unused_bits2b */
-		BTF_MEMBER_ENC(0, 14, 128),		/* union (anon) */
-		BTF_MEMBER_ENC(NAME_TBD, 15, 192),	/* aenum */
-		BTF_MEMBER_ENC(NAME_TBD, 11, 224),	/* uint32_t ui32b */
-		BTF_MEMBER_ENC(NAME_TBD, 6, 256),	/* bits2c */
-		BTF_MEMBER_ENC(NAME_TBD, 17, 264),	/* si8_4 */
-		BTF_TYPE_ARRAY_ENC(18, 1, 2),		/* [17] */
-		BTF_TYPE_ARRAY_ENC(1, 1, 2),		/* [18] */
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum\0ui32b\0bits2c\0si8_4"),
-	.key_size = sizeof(unsigned int),
-	.value_size = sizeof(struct pprint_mapv),
-	.key_type_id = 3,	/* unsigned int */
-	.value_type_id = 16,	/* struct pprint_mapv */
-	.max_entries = 128 * 1024,
-},
-
-{
-	/* this type will have the same type as the
-	 * first .raw_types definition, but struct type will
-	 * be encoded with kind_flag set.
-	 */
-	.raw_types = {
-		/* unsighed char */			/* [1] */
-		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
-		/* unsigned short */			/* [2] */
-		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
-		/* unsigned int */			/* [3] */
-		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
-		/* int */				/* [4] */
-		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
-		/* unsigned long long */		/* [5] */
-		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
-		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),	/* [6] */
-		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),	/* [7] */
-		/* uint8_t[8] */			/* [8] */
-		BTF_TYPE_ARRAY_ENC(9, 1, 8),
-		/* typedef unsigned char uint8_t */	/* [9] */
-		BTF_TYPEDEF_ENC(NAME_TBD, 1),
-		/* typedef unsigned short uint16_t */	/* [10] */
-		BTF_TYPEDEF_ENC(NAME_TBD, 2),
-		/* typedef unsigned int uint32_t */	/* [11] */
-		BTF_TYPEDEF_ENC(NAME_TBD, 3),
-		/* typedef int int32_t */		/* [12] */
-		BTF_TYPEDEF_ENC(NAME_TBD, 4),
-		/* typedef unsigned long long uint64_t *//* [13] */
-		BTF_TYPEDEF_ENC(NAME_TBD, 5),
-		/* union (anon) */			/* [14] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
-		BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
-		BTF_MEMBER_ENC(NAME_TBD, 8, 0),	/* uint8_t ui8a[8]; */
-		/* enum (anon) */			/* [15] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
-		BTF_ENUM_ENC(NAME_TBD, 0),
-		BTF_ENUM_ENC(NAME_TBD, 1),
-		BTF_ENUM_ENC(NAME_TBD, 2),
-		BTF_ENUM_ENC(NAME_TBD, 3),
-		/* struct pprint_mapv */		/* [16] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 11), 40),
-		BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 0)),	/* uint32_t ui32 */
-		BTF_MEMBER_ENC(NAME_TBD, 10, BTF_MEMBER_OFFSET(0, 32)),	/* uint16_t ui16 */
-		BTF_MEMBER_ENC(NAME_TBD, 12, BTF_MEMBER_OFFSET(0, 64)),	/* int32_t si32 */
-		BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 96)),	/* unused_bits2a */
-		BTF_MEMBER_ENC(NAME_TBD, 7, BTF_MEMBER_OFFSET(28, 98)),	/* bits28 */
-		BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 126)),	/* unused_bits2b */
-		BTF_MEMBER_ENC(0, 14, BTF_MEMBER_OFFSET(0, 128)),	/* union (anon) */
-		BTF_MEMBER_ENC(NAME_TBD, 15, BTF_MEMBER_OFFSET(0, 192)),	/* aenum */
-		BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 224)),	/* uint32_t ui32b */
-		BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 256)),	/* bits2c */
-		BTF_MEMBER_ENC(NAME_TBD, 17, 264),	/* si8_4 */
-		BTF_TYPE_ARRAY_ENC(18, 1, 2),		/* [17] */
-		BTF_TYPE_ARRAY_ENC(1, 1, 2),		/* [18] */
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum\0ui32b\0bits2c\0si8_4"),
-	.key_size = sizeof(unsigned int),
-	.value_size = sizeof(struct pprint_mapv),
-	.key_type_id = 3,	/* unsigned int */
-	.value_type_id = 16,	/* struct pprint_mapv */
-	.max_entries = 128 * 1024,
-},
-
-{
-	/* this type will have the same layout as the
-	 * first .raw_types definition. The struct type will
-	 * be encoded with kind_flag set, bitfield members
-	 * are added typedef/const/volatile, and bitfield members
-	 * will have both int and enum types.
-	 */
-	.raw_types = {
-		/* unsighed char */			/* [1] */
-		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
-		/* unsigned short */			/* [2] */
-		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
-		/* unsigned int */			/* [3] */
-		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
-		/* int */				/* [4] */
-		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
-		/* unsigned long long */		/* [5] */
-		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
-		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),	/* [6] */
-		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),	/* [7] */
-		/* uint8_t[8] */			/* [8] */
-		BTF_TYPE_ARRAY_ENC(9, 1, 8),
-		/* typedef unsigned char uint8_t */	/* [9] */
-		BTF_TYPEDEF_ENC(NAME_TBD, 1),
-		/* typedef unsigned short uint16_t */	/* [10] */
-		BTF_TYPEDEF_ENC(NAME_TBD, 2),
-		/* typedef unsigned int uint32_t */	/* [11] */
-		BTF_TYPEDEF_ENC(NAME_TBD, 3),
-		/* typedef int int32_t */		/* [12] */
-		BTF_TYPEDEF_ENC(NAME_TBD, 4),
-		/* typedef unsigned long long uint64_t *//* [13] */
-		BTF_TYPEDEF_ENC(NAME_TBD, 5),
-		/* union (anon) */			/* [14] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
-		BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
-		BTF_MEMBER_ENC(NAME_TBD, 8, 0),	/* uint8_t ui8a[8]; */
-		/* enum (anon) */			/* [15] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
-		BTF_ENUM_ENC(NAME_TBD, 0),
-		BTF_ENUM_ENC(NAME_TBD, 1),
-		BTF_ENUM_ENC(NAME_TBD, 2),
-		BTF_ENUM_ENC(NAME_TBD, 3),
-		/* struct pprint_mapv */		/* [16] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 11), 40),
-		BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 0)),	/* uint32_t ui32 */
-		BTF_MEMBER_ENC(NAME_TBD, 10, BTF_MEMBER_OFFSET(0, 32)),	/* uint16_t ui16 */
-		BTF_MEMBER_ENC(NAME_TBD, 12, BTF_MEMBER_OFFSET(0, 64)),	/* int32_t si32 */
-		BTF_MEMBER_ENC(NAME_TBD, 17, BTF_MEMBER_OFFSET(2, 96)),	/* unused_bits2a */
-		BTF_MEMBER_ENC(NAME_TBD, 7, BTF_MEMBER_OFFSET(28, 98)),	/* bits28 */
-		BTF_MEMBER_ENC(NAME_TBD, 19, BTF_MEMBER_OFFSET(2, 126)),/* unused_bits2b */
-		BTF_MEMBER_ENC(0, 14, BTF_MEMBER_OFFSET(0, 128)),	/* union (anon) */
-		BTF_MEMBER_ENC(NAME_TBD, 15, BTF_MEMBER_OFFSET(0, 192)),	/* aenum */
-		BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 224)),	/* uint32_t ui32b */
-		BTF_MEMBER_ENC(NAME_TBD, 17, BTF_MEMBER_OFFSET(2, 256)),	/* bits2c */
-		BTF_MEMBER_ENC(NAME_TBD, 20, BTF_MEMBER_OFFSET(0, 264)),	/* si8_4 */
-		/* typedef unsigned int ___int */	/* [17] */
-		BTF_TYPEDEF_ENC(NAME_TBD, 18),
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_VOLATILE, 0, 0), 6),	/* [18] */
-		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 15),	/* [19] */
-		BTF_TYPE_ARRAY_ENC(21, 1, 2),					/* [20] */
-		BTF_TYPE_ARRAY_ENC(1, 1, 2),					/* [21] */
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum\0ui32b\0bits2c\0___int\0si8_4"),
-	.key_size = sizeof(unsigned int),
-	.value_size = sizeof(struct pprint_mapv),
-	.key_type_id = 3,	/* unsigned int */
-	.value_type_id = 16,	/* struct pprint_mapv */
-	.max_entries = 128 * 1024,
-},
-
-#ifdef __SIZEOF_INT128__
-{
-	/* test int128 */
-	.raw_types = {
-		/* unsigned int */				/* [1] */
-		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
-		/* __int128 */					/* [2] */
-		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 128, 16),
-		/* unsigned __int128 */				/* [3] */
-		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 128, 16),
-		/* struct pprint_mapv_int128 */			/* [4] */
-		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 5), 64),
-		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)),		/* si128a */
-		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 128)),		/* si128b */
-		BTF_MEMBER_ENC(NAME_TBD, 3, BTF_MEMBER_OFFSET(3, 256)),		/* bits3 */
-		BTF_MEMBER_ENC(NAME_TBD, 3, BTF_MEMBER_OFFSET(80, 259)),	/* bits80 */
-		BTF_MEMBER_ENC(NAME_TBD, 3, BTF_MEMBER_OFFSET(0, 384)),		/* ui128 */
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0unsigned int\0__int128\0unsigned __int128\0pprint_mapv_int128\0si128a\0si128b\0bits3\0bits80\0ui128"),
-	.key_size = sizeof(unsigned int),
-	.value_size = sizeof(struct pprint_mapv_int128),
-	.key_type_id = 1,
-	.value_type_id = 4,
-	.max_entries = 128 * 1024,
-	.mapv_kind = PPRINT_MAPV_KIND_INT128,
-},
-#endif
-
-};
-
-static struct btf_pprint_test_meta {
-	const char *descr;
-	enum bpf_map_type map_type;
-	const char *map_name;
-	bool ordered_map;
-	bool lossless_map;
-	bool percpu_map;
-} pprint_tests_meta[] = {
-{
-	.descr = "BTF pretty print array",
-	.map_type = BPF_MAP_TYPE_ARRAY,
-	.map_name = "pprint_test_array",
-	.ordered_map = true,
-	.lossless_map = true,
-	.percpu_map = false,
-},
-
-{
-	.descr = "BTF pretty print hash",
-	.map_type = BPF_MAP_TYPE_HASH,
-	.map_name = "pprint_test_hash",
-	.ordered_map = false,
-	.lossless_map = true,
-	.percpu_map = false,
-},
-
-{
-	.descr = "BTF pretty print lru hash",
-	.map_type = BPF_MAP_TYPE_LRU_HASH,
-	.map_name = "pprint_test_lru_hash",
-	.ordered_map = false,
-	.lossless_map = false,
-	.percpu_map = false,
-},
-
-{
-	.descr = "BTF pretty print percpu array",
-	.map_type = BPF_MAP_TYPE_PERCPU_ARRAY,
-	.map_name = "pprint_test_percpu_array",
-	.ordered_map = true,
-	.lossless_map = true,
-	.percpu_map = true,
-},
-
-{
-	.descr = "BTF pretty print percpu hash",
-	.map_type = BPF_MAP_TYPE_PERCPU_HASH,
-	.map_name = "pprint_test_percpu_hash",
-	.ordered_map = false,
-	.lossless_map = true,
-	.percpu_map = true,
-},
-
-{
-	.descr = "BTF pretty print lru percpu hash",
-	.map_type = BPF_MAP_TYPE_LRU_PERCPU_HASH,
-	.map_name = "pprint_test_lru_percpu_hash",
-	.ordered_map = false,
-	.lossless_map = false,
-	.percpu_map = true,
-},
-
-};
-
-static size_t get_pprint_mapv_size(enum pprint_mapv_kind_t mapv_kind)
-{
-	if (mapv_kind == PPRINT_MAPV_KIND_BASIC)
-		return sizeof(struct pprint_mapv);
-
-#ifdef __SIZEOF_INT128__
-	if (mapv_kind == PPRINT_MAPV_KIND_INT128)
-		return sizeof(struct pprint_mapv_int128);
-#endif
-
-	assert(0);
-}
-
-static void set_pprint_mapv(enum pprint_mapv_kind_t mapv_kind,
-			    void *mapv, uint32_t i,
-			    int num_cpus, int rounded_value_size)
-{
-	int cpu;
-
-	if (mapv_kind == PPRINT_MAPV_KIND_BASIC) {
-		struct pprint_mapv *v = mapv;
-
-		for (cpu = 0; cpu < num_cpus; cpu++) {
-			v->ui32 = i + cpu;
-			v->si32 = -i;
-			v->unused_bits2a = 3;
-			v->bits28 = i;
-			v->unused_bits2b = 3;
-			v->ui64 = i;
-			v->aenum = i & 0x03;
-			v->ui32b = 4;
-			v->bits2c = 1;
-			v->si8_4[0][0] = (cpu + i) & 0xff;
-			v->si8_4[0][1] = (cpu + i + 1) & 0xff;
-			v->si8_4[1][0] = (cpu + i + 2) & 0xff;
-			v->si8_4[1][1] = (cpu + i + 3) & 0xff;
-			v = (void *)v + rounded_value_size;
-		}
-	}
-
-#ifdef __SIZEOF_INT128__
-	if (mapv_kind == PPRINT_MAPV_KIND_INT128) {
-		struct pprint_mapv_int128 *v = mapv;
-
-		for (cpu = 0; cpu < num_cpus; cpu++) {
-			v->si128a = i;
-			v->si128b = -i;
-			v->bits3 = i & 0x07;
-			v->bits80 = (((unsigned __int128)1) << 64) + i;
-			v->ui128 = (((unsigned __int128)2) << 64) + i;
-			v = (void *)v + rounded_value_size;
-		}
-	}
-#endif
-}
-
-ssize_t get_pprint_expected_line(enum pprint_mapv_kind_t mapv_kind,
-				 char *expected_line, ssize_t line_size,
-				 bool percpu_map, unsigned int next_key,
-				 int cpu, void *mapv)
-{
-	ssize_t nexpected_line = -1;
-
-	if (mapv_kind == PPRINT_MAPV_KIND_BASIC) {
-		struct pprint_mapv *v = mapv;
-
-		nexpected_line = snprintf(expected_line, line_size,
-					  "%s%u: {%u,0,%d,0x%x,0x%x,0x%x,"
-					  "{%llu|[%u,%u,%u,%u,%u,%u,%u,%u]},%s,"
-					  "%u,0x%x,[[%d,%d],[%d,%d]]}\n",
-					  percpu_map ? "\tcpu" : "",
-					  percpu_map ? cpu : next_key,
-					  v->ui32, v->si32,
-					  v->unused_bits2a,
-					  v->bits28,
-					  v->unused_bits2b,
-					  (__u64)v->ui64,
-					  v->ui8a[0], v->ui8a[1],
-					  v->ui8a[2], v->ui8a[3],
-					  v->ui8a[4], v->ui8a[5],
-					  v->ui8a[6], v->ui8a[7],
-					  pprint_enum_str[v->aenum],
-					  v->ui32b,
-					  v->bits2c,
-					  v->si8_4[0][0], v->si8_4[0][1],
-					  v->si8_4[1][0], v->si8_4[1][1]);
-	}
-
-#ifdef __SIZEOF_INT128__
-	if (mapv_kind == PPRINT_MAPV_KIND_INT128) {
-		struct pprint_mapv_int128 *v = mapv;
-
-		nexpected_line = snprintf(expected_line, line_size,
-					  "%s%u: {0x%lx,0x%lx,0x%lx,"
-					  "0x%lx%016lx,0x%lx%016lx}\n",
-					  percpu_map ? "\tcpu" : "",
-					  percpu_map ? cpu : next_key,
-					  (uint64_t)v->si128a,
-					  (uint64_t)v->si128b,
-					  (uint64_t)v->bits3,
-					  (uint64_t)(v->bits80 >> 64),
-					  (uint64_t)v->bits80,
-					  (uint64_t)(v->ui128 >> 64),
-					  (uint64_t)v->ui128);
-	}
-#endif
-
-	return nexpected_line;
-}
-
-static int check_line(const char *expected_line, int nexpected_line,
-		      int expected_line_len, const char *line)
-{
-	if (CHECK(nexpected_line == expected_line_len,
-		  "expected_line is too long"))
-		return -1;
-
-	if (strcmp(expected_line, line)) {
-		fprintf(stderr, "unexpected pprint output\n");
-		fprintf(stderr, "expected: %s", expected_line);
-		fprintf(stderr, "    read: %s", line);
-		return -1;
-	}
-
-	return 0;
-}
-
-
-static int do_test_pprint(int test_num)
-{
-	const struct btf_raw_test *test = &pprint_test_template[test_num];
-	enum pprint_mapv_kind_t mapv_kind = test->mapv_kind;
-	struct bpf_create_map_attr create_attr = {};
-	bool ordered_map, lossless_map, percpu_map;
-	int err, ret, num_cpus, rounded_value_size;
-	unsigned int key, nr_read_elems;
-	int map_fd = -1, btf_fd = -1;
-	unsigned int raw_btf_size;
-	char expected_line[255];
-	FILE *pin_file = NULL;
-	char pin_path[255];
-	size_t line_len = 0;
-	char *line = NULL;
-	void *mapv = NULL;
-	uint8_t *raw_btf;
-	ssize_t nread;
-
-	fprintf(stderr, "%s(#%d)......", test->descr, test_num);
-	raw_btf = btf_raw_create(&hdr_tmpl, test->raw_types,
-				 test->str_sec, test->str_sec_size,
-				 &raw_btf_size, NULL);
-
-	if (!raw_btf)
-		return -1;
-
-	*btf_log_buf = '\0';
-	btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
-			      btf_log_buf, BTF_LOG_BUF_SIZE,
-			      args.always_log);
-	free(raw_btf);
-
-	if (CHECK(btf_fd == -1, "errno:%d", errno)) {
-		err = -1;
-		goto done;
-	}
-
-	create_attr.name = test->map_name;
-	create_attr.map_type = test->map_type;
-	create_attr.key_size = test->key_size;
-	create_attr.value_size = test->value_size;
-	create_attr.max_entries = test->max_entries;
-	create_attr.btf_fd = btf_fd;
-	create_attr.btf_key_type_id = test->key_type_id;
-	create_attr.btf_value_type_id = test->value_type_id;
-
-	map_fd = bpf_create_map_xattr(&create_attr);
-	if (CHECK(map_fd == -1, "errno:%d", errno)) {
-		err = -1;
-		goto done;
-	}
-
-	ret = snprintf(pin_path, sizeof(pin_path), "%s/%s",
-		       "/sys/fs/bpf", test->map_name);
-
-	if (CHECK(ret == sizeof(pin_path), "pin_path %s/%s is too long",
-		  "/sys/fs/bpf", test->map_name)) {
-		err = -1;
-		goto done;
-	}
-
-	err = bpf_obj_pin(map_fd, pin_path);
-	if (CHECK(err, "bpf_obj_pin(%s): errno:%d.", pin_path, errno))
-		goto done;
-
-	percpu_map = test->percpu_map;
-	num_cpus = percpu_map ? bpf_num_possible_cpus() : 1;
-	rounded_value_size = round_up(get_pprint_mapv_size(mapv_kind), 8);
-	mapv = calloc(num_cpus, rounded_value_size);
-	if (CHECK(!mapv, "mapv allocation failure")) {
-		err = -1;
-		goto done;
-	}
-
-	for (key = 0; key < test->max_entries; key++) {
-		set_pprint_mapv(mapv_kind, mapv, key, num_cpus, rounded_value_size);
-		bpf_map_update_elem(map_fd, &key, mapv, 0);
-	}
-
-	pin_file = fopen(pin_path, "r");
-	if (CHECK(!pin_file, "fopen(%s): errno:%d", pin_path, errno)) {
-		err = -1;
-		goto done;
-	}
-
-	/* Skip lines start with '#' */
-	while ((nread = getline(&line, &line_len, pin_file)) > 0 &&
-	       *line == '#')
-		;
-
-	if (CHECK(nread <= 0, "Unexpected EOF")) {
-		err = -1;
-		goto done;
-	}
-
-	nr_read_elems = 0;
-	ordered_map = test->ordered_map;
-	lossless_map = test->lossless_map;
-	do {
-		ssize_t nexpected_line;
-		unsigned int next_key;
-		void *cmapv;
-		int cpu;
-
-		next_key = ordered_map ? nr_read_elems : atoi(line);
-		set_pprint_mapv(mapv_kind, mapv, next_key, num_cpus, rounded_value_size);
-		cmapv = mapv;
-
-		for (cpu = 0; cpu < num_cpus; cpu++) {
-			if (percpu_map) {
-				/* for percpu map, the format looks like:
-				 * <key>: {
-				 *	cpu0: <value_on_cpu0>
-				 *	cpu1: <value_on_cpu1>
-				 *	...
-				 *	cpun: <value_on_cpun>
-				 * }
-				 *
-				 * let us verify the line containing the key here.
-				 */
-				if (cpu == 0) {
-					nexpected_line = snprintf(expected_line,
-								  sizeof(expected_line),
-								  "%u: {\n",
-								  next_key);
-
-					err = check_line(expected_line, nexpected_line,
-							 sizeof(expected_line), line);
-					if (err == -1)
-						goto done;
-				}
-
-				/* read value@cpu */
-				nread = getline(&line, &line_len, pin_file);
-				if (nread < 0)
-					break;
-			}
-
-			nexpected_line = get_pprint_expected_line(mapv_kind, expected_line,
-								  sizeof(expected_line),
-								  percpu_map, next_key,
-								  cpu, cmapv);
-			err = check_line(expected_line, nexpected_line,
-					 sizeof(expected_line), line);
-			if (err == -1)
-				goto done;
-
-			cmapv = cmapv + rounded_value_size;
-		}
-
-		if (percpu_map) {
-			/* skip the last bracket for the percpu map */
-			nread = getline(&line, &line_len, pin_file);
-			if (nread < 0)
-				break;
-		}
-
-		nread = getline(&line, &line_len, pin_file);
-	} while (++nr_read_elems < test->max_entries && nread > 0);
-
-	if (lossless_map &&
-	    CHECK(nr_read_elems < test->max_entries,
-		  "Unexpected EOF. nr_read_elems:%u test->max_entries:%u",
-		  nr_read_elems, test->max_entries)) {
-		err = -1;
-		goto done;
-	}
-
-	if (CHECK(nread > 0, "Unexpected extra pprint output: %s", line)) {
-		err = -1;
-		goto done;
-	}
-
-	err = 0;
-
-done:
-	if (mapv)
-		free(mapv);
-	if (!err)
-		fprintf(stderr, "OK");
-	if (*btf_log_buf && (err || args.always_log))
-		fprintf(stderr, "\n%s", btf_log_buf);
-	if (btf_fd != -1)
-		close(btf_fd);
-	if (map_fd != -1)
-		close(map_fd);
-	if (pin_file)
-		fclose(pin_file);
-	unlink(pin_path);
-	free(line);
-
-	return err;
-}
-
-static int test_pprint(void)
+static const char *get_next_str(const char *start, const char *end)
 {
-	unsigned int i;
-	int err = 0;
-
-	/* test various maps with the first test template */
-	for (i = 0; i < ARRAY_SIZE(pprint_tests_meta); i++) {
-		pprint_test_template[0].descr = pprint_tests_meta[i].descr;
-		pprint_test_template[0].map_type = pprint_tests_meta[i].map_type;
-		pprint_test_template[0].map_name = pprint_tests_meta[i].map_name;
-		pprint_test_template[0].ordered_map = pprint_tests_meta[i].ordered_map;
-		pprint_test_template[0].lossless_map = pprint_tests_meta[i].lossless_map;
-		pprint_test_template[0].percpu_map = pprint_tests_meta[i].percpu_map;
-
-		err |= count_result(do_test_pprint(0));
-	}
-
-	/* test rest test templates with the first map */
-	for (i = 1; i < ARRAY_SIZE(pprint_test_template); i++) {
-		pprint_test_template[i].descr = pprint_tests_meta[0].descr;
-		pprint_test_template[i].map_type = pprint_tests_meta[0].map_type;
-		pprint_test_template[i].map_name = pprint_tests_meta[0].map_name;
-		pprint_test_template[i].ordered_map = pprint_tests_meta[0].ordered_map;
-		pprint_test_template[i].lossless_map = pprint_tests_meta[0].lossless_map;
-		pprint_test_template[i].percpu_map = pprint_tests_meta[0].percpu_map;
-		err |= count_result(do_test_pprint(i));
-	}
-
-	return err;
+	return start < end - 1 ? start + 1 : NULL;
 }
 
-#define BPF_LINE_INFO_ENC(insn_off, file_off, line_off, line_num, line_col) \
-	(insn_off), (file_off), (line_off), ((line_num) << 10 | ((line_col) & 0x3ff))
-
-static struct prog_info_raw_test {
-	const char *descr;
-	const char *str_sec;
-	const char *err_str;
-	__u32 raw_types[MAX_NR_RAW_U32];
-	__u32 str_sec_size;
-	struct bpf_insn insns[MAX_INSNS];
-	__u32 prog_type;
-	__u32 func_info[MAX_SUBPROGS][2];
-	__u32 func_info_rec_size;
-	__u32 func_info_cnt;
-	__u32 line_info[MAX_NR_RAW_U32];
-	__u32 line_info_rec_size;
-	__u32 nr_jited_ksyms;
-	bool expected_prog_load_failure;
-	__u32 dead_code_cnt;
-	__u32 dead_code_mask;
-	__u32 dead_func_cnt;
-	__u32 dead_func_mask;
-} info_raw_tests[] = {
-{
-	.descr = "func_type (main func + one sub)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),	/* [2] */
-		BTF_FUNC_PROTO_ENC(1, 2),			/* [3] */
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
-		BTF_FUNC_PROTO_ENC(1, 2),			/* [4] */
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
-		BTF_FUNC_ENC(NAME_TBD, 3),			/* [5] */
-		BTF_FUNC_ENC(NAME_TBD, 4),			/* [6] */
-		BTF_END_RAW,
-	},
-	.str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
-	.str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
-	.insns = {
-		BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
-		BPF_MOV64_IMM(BPF_REG_0, 1),
-		BPF_EXIT_INSN(),
-		BPF_MOV64_IMM(BPF_REG_0, 2),
-		BPF_EXIT_INSN(),
-	},
-	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
-	.func_info = { {0, 5}, {3, 6} },
-	.func_info_rec_size = 8,
-	.func_info_cnt = 2,
-	.line_info = { BTF_END_RAW },
-},
-
+static int get_raw_sec_size(const __u32 *raw_types)
 {
-	.descr = "func_type (Incorrect func_info_rec_size)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),	/* [2] */
-		BTF_FUNC_PROTO_ENC(1, 2),			/* [3] */
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
-		BTF_FUNC_PROTO_ENC(1, 2),			/* [4] */
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
-		BTF_FUNC_ENC(NAME_TBD, 3),			/* [5] */
-		BTF_FUNC_ENC(NAME_TBD, 4),			/* [6] */
-		BTF_END_RAW,
-	},
-	.str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
-	.str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
-	.insns = {
-		BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
-		BPF_MOV64_IMM(BPF_REG_0, 1),
-		BPF_EXIT_INSN(),
-		BPF_MOV64_IMM(BPF_REG_0, 2),
-		BPF_EXIT_INSN(),
-	},
-	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
-	.func_info = { {0, 5}, {3, 6} },
-	.func_info_rec_size = 4,
-	.func_info_cnt = 2,
-	.line_info = { BTF_END_RAW },
-	.expected_prog_load_failure = true,
-},
+	int i;
 
-{
-	.descr = "func_type (Incorrect func_info_cnt)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),	/* [2] */
-		BTF_FUNC_PROTO_ENC(1, 2),			/* [3] */
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
-		BTF_FUNC_PROTO_ENC(1, 2),			/* [4] */
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
-		BTF_FUNC_ENC(NAME_TBD, 3),			/* [5] */
-		BTF_FUNC_ENC(NAME_TBD, 4),			/* [6] */
-		BTF_END_RAW,
-	},
-	.str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
-	.str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
-	.insns = {
-		BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
-		BPF_MOV64_IMM(BPF_REG_0, 1),
-		BPF_EXIT_INSN(),
-		BPF_MOV64_IMM(BPF_REG_0, 2),
-		BPF_EXIT_INSN(),
-	},
-	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
-	.func_info = { {0, 5}, {3, 6} },
-	.func_info_rec_size = 8,
-	.func_info_cnt = 1,
-	.line_info = { BTF_END_RAW },
-	.expected_prog_load_failure = true,
-},
+	for (i = MAX_NR_RAW_U32 - 1;
+	     i >= 0 && raw_types[i] != BTF_END_RAW;
+	     i--)
+		;
 
-{
-	.descr = "func_type (Incorrect bpf_func_info.insn_off)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),	/* [2] */
-		BTF_FUNC_PROTO_ENC(1, 2),			/* [3] */
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
-		BTF_FUNC_PROTO_ENC(1, 2),			/* [4] */
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 2),
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
-		BTF_FUNC_ENC(NAME_TBD, 3),			/* [5] */
-		BTF_FUNC_ENC(NAME_TBD, 4),			/* [6] */
-		BTF_END_RAW,
-	},
-	.str_sec = "\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB",
-	.str_sec_size = sizeof("\0int\0unsigned int\0a\0b\0c\0d\0funcA\0funcB"),
-	.insns = {
-		BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
-		BPF_MOV64_IMM(BPF_REG_0, 1),
-		BPF_EXIT_INSN(),
-		BPF_MOV64_IMM(BPF_REG_0, 2),
-		BPF_EXIT_INSN(),
-	},
-	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
-	.func_info = { {0, 5}, {2, 6} },
-	.func_info_rec_size = 8,
-	.func_info_cnt = 2,
-	.line_info = { BTF_END_RAW },
-	.expected_prog_load_failure = true,
-},
+	return i < 0 ? i : i * sizeof(raw_types[0]);
+}
 
+static void *btf_raw_create(const struct btf_header *hdr,
+			    const __u32 *raw_types,
+			    const char *str,
+			    unsigned int str_sec_size,
+			    unsigned int *btf_size,
+			    const char **ret_next_str)
 {
-	.descr = "line_info (No subprog)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
-	.insns = {
-		BPF_MOV64_IMM(BPF_REG_0, 1),
-		BPF_MOV64_IMM(BPF_REG_1, 2),
-		BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
-		BPF_EXIT_INSN(),
-	},
-	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
-	.func_info_cnt = 0,
-	.line_info = {
-		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9),
-		BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
-		BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7),
-		BTF_END_RAW,
-	},
-	.line_info_rec_size = sizeof(struct bpf_line_info),
-	.nr_jited_ksyms = 1,
-},
+	const char *next_str = str, *end_str = str + str_sec_size;
+	const char **strs_idx = NULL, **tmp_strs_idx;
+	int strs_cap = 0, strs_cnt = 0, next_str_idx = 0;
+	unsigned int size_needed, offset;
+	struct btf_header *ret_hdr;
+	int i, type_sec_size, err = 0;
+	uint32_t *ret_types;
+	void *raw_btf = NULL;
 
-{
-	.descr = "line_info (No subprog. insn_off >= prog->len)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
-	.insns = {
-		BPF_MOV64_IMM(BPF_REG_0, 1),
-		BPF_MOV64_IMM(BPF_REG_1, 2),
-		BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
-		BPF_EXIT_INSN(),
-	},
-	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
-	.func_info_cnt = 0,
-	.line_info = {
-		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9),
-		BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
-		BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7),
-		BPF_LINE_INFO_ENC(4, 0, 0, 5, 6),
-		BTF_END_RAW,
-	},
-	.line_info_rec_size = sizeof(struct bpf_line_info),
-	.nr_jited_ksyms = 1,
-	.err_str = "line_info[4].insn_off",
-	.expected_prog_load_failure = true,
-},
+	type_sec_size = get_raw_sec_size(raw_types);
+	if (CHECK(type_sec_size < 0, "Cannot get nr_raw_types"))
+		return NULL;
 
-{
-	.descr = "line_info (Zero bpf insn code)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),	/* [2] */
-		BTF_TYPEDEF_ENC(NAME_TBD, 2),			/* [3] */
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0int\0unsigned long\0u64\0u64 a=1;\0return a;"),
-	.insns = {
-		BPF_LD_IMM64(BPF_REG_0, 1),
-		BPF_EXIT_INSN(),
-	},
-	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
-	.func_info_cnt = 0,
-	.line_info = {
-		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(1, 0, 0, 2, 9),
-		BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
-		BTF_END_RAW,
-	},
-	.line_info_rec_size = sizeof(struct bpf_line_info),
-	.nr_jited_ksyms = 1,
-	.err_str = "Invalid insn code at line_info[1]",
-	.expected_prog_load_failure = true,
-},
+	size_needed = sizeof(*hdr) + type_sec_size + str_sec_size;
+	raw_btf = malloc(size_needed);
+	if (CHECK(!raw_btf, "Cannot allocate memory for raw_btf"))
+		return NULL;
 
-{
-	.descr = "line_info (No subprog. zero tailing line_info",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
-	.insns = {
-		BPF_MOV64_IMM(BPF_REG_0, 1),
-		BPF_MOV64_IMM(BPF_REG_1, 2),
-		BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
-		BPF_EXIT_INSN(),
-	},
-	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
-	.func_info_cnt = 0,
-	.line_info = {
-		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 0,
-		BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9), 0,
-		BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8), 0,
-		BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7), 0,
-		BTF_END_RAW,
-	},
-	.line_info_rec_size = sizeof(struct bpf_line_info) + sizeof(__u32),
-	.nr_jited_ksyms = 1,
-},
+	/* Copy header */
+	memcpy(raw_btf, hdr, sizeof(*hdr));
+	offset = sizeof(*hdr);
 
-{
-	.descr = "line_info (No subprog. nonzero tailing line_info)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
-	.insns = {
-		BPF_MOV64_IMM(BPF_REG_0, 1),
-		BPF_MOV64_IMM(BPF_REG_1, 2),
-		BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
-		BPF_EXIT_INSN(),
-	},
-	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
-	.func_info_cnt = 0,
-	.line_info = {
-		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10), 0,
-		BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9), 0,
-		BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8), 0,
-		BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7), 1,
-		BTF_END_RAW,
-	},
-	.line_info_rec_size = sizeof(struct bpf_line_info) + sizeof(__u32),
-	.nr_jited_ksyms = 1,
-	.err_str = "nonzero tailing record in line_info",
-	.expected_prog_load_failure = true,
-},
+	/* Index strings */
+	while ((next_str = get_next_str(next_str, end_str))) {
+		if (strs_cnt == strs_cap) {
+			strs_cap += max(16, strs_cap / 2);
+			tmp_strs_idx = realloc(strs_idx,
+					       sizeof(*strs_idx) * strs_cap);
+			if (CHECK(!tmp_strs_idx,
+				  "Cannot allocate memory for strs_idx")) {
+				err = -1;
+				goto done;
+			}
+			strs_idx = tmp_strs_idx;
+		}
+		strs_idx[strs_cnt++] = next_str;
+		next_str += strlen(next_str);
+	}
 
-{
-	.descr = "line_info (subprog)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
-	.insns = {
-		BPF_MOV64_IMM(BPF_REG_2, 1),
-		BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
-		BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
-		BPF_CALL_REL(1),
-		BPF_EXIT_INSN(),
-		BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
-		BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
-		BPF_EXIT_INSN(),
-	},
-	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
-	.func_info_cnt = 0,
-	.line_info = {
-		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
-		BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8),
-		BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
-		BTF_END_RAW,
-	},
-	.line_info_rec_size = sizeof(struct bpf_line_info),
-	.nr_jited_ksyms = 2,
-},
+	/* Copy type section */
+	ret_types = raw_btf + offset;
+	for (i = 0; i < type_sec_size / sizeof(raw_types[0]); i++) {
+		if (raw_types[i] == NAME_TBD) {
+			if (CHECK(next_str_idx == strs_cnt,
+				  "Error in getting next_str #%d",
+				  next_str_idx)) {
+				err = -1;
+				goto done;
+			}
+			ret_types[i] = strs_idx[next_str_idx++] - str;
+		} else if (IS_NAME_NTH(raw_types[i])) {
+			int idx = GET_NAME_NTH_IDX(raw_types[i]);
 
-{
-	.descr = "line_info (subprog + func_info)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_FUNC_PROTO_ENC(1, 1),			/* [2] */
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
-		BTF_FUNC_ENC(NAME_TBD, 2),			/* [3] */
-		BTF_FUNC_ENC(NAME_TBD, 2),			/* [4] */
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0int\0x\0sub\0main\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
-	.insns = {
-		BPF_MOV64_IMM(BPF_REG_2, 1),
-		BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
-		BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
-		BPF_CALL_REL(1),
-		BPF_EXIT_INSN(),
-		BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
-		BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
-		BPF_EXIT_INSN(),
-	},
-	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
-	.func_info_cnt = 2,
-	.func_info_rec_size = 8,
-	.func_info = { {0, 4}, {5, 3} },
-	.line_info = {
-		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
-		BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8),
-		BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
-		BTF_END_RAW,
-	},
-	.line_info_rec_size = sizeof(struct bpf_line_info),
-	.nr_jited_ksyms = 2,
-},
+			if (CHECK(idx <= 0 || idx > strs_cnt,
+				  "Error getting string #%d, strs_cnt:%d",
+				  idx, strs_cnt)) {
+				err = -1;
+				goto done;
+			}
+			ret_types[i] = strs_idx[idx-1] - str;
+		} else {
+			ret_types[i] = raw_types[i];
+		}
+	}
+	offset += type_sec_size;
 
-{
-	.descr = "line_info (subprog. missing 1st func line info)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
-	.insns = {
-		BPF_MOV64_IMM(BPF_REG_2, 1),
-		BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
-		BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
-		BPF_CALL_REL(1),
-		BPF_EXIT_INSN(),
-		BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
-		BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
-		BPF_EXIT_INSN(),
-	},
-	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
-	.func_info_cnt = 0,
-	.line_info = {
-		BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
-		BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 3, 8),
-		BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
-		BTF_END_RAW,
-	},
-	.line_info_rec_size = sizeof(struct bpf_line_info),
-	.nr_jited_ksyms = 2,
-	.err_str = "missing bpf_line_info for func#0",
-	.expected_prog_load_failure = true,
-},
+	/* Copy string section */
+	memcpy(raw_btf + offset, str, str_sec_size);
 
-{
-	.descr = "line_info (subprog. missing 2nd func line info)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
-	.insns = {
-		BPF_MOV64_IMM(BPF_REG_2, 1),
-		BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
-		BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
-		BPF_CALL_REL(1),
-		BPF_EXIT_INSN(),
-		BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
-		BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
-		BPF_EXIT_INSN(),
-	},
-	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
-	.func_info_cnt = 0,
-	.line_info = {
-		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 2, 9),
-		BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 3, 8),
-		BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
-		BTF_END_RAW,
-	},
-	.line_info_rec_size = sizeof(struct bpf_line_info),
-	.nr_jited_ksyms = 2,
-	.err_str = "missing bpf_line_info for func#1",
-	.expected_prog_load_failure = true,
-},
+	ret_hdr = (struct btf_header *)raw_btf;
+	ret_hdr->type_len = type_sec_size;
+	ret_hdr->str_off = type_sec_size;
+	ret_hdr->str_len = str_sec_size;
 
-{
-	.descr = "line_info (subprog. unordered insn offset)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0int\0int a=1+1;\0return func(a);\0b+=1;\0return b;"),
-	.insns = {
-		BPF_MOV64_IMM(BPF_REG_2, 1),
-		BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
-		BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
-		BPF_CALL_REL(1),
-		BPF_EXIT_INSN(),
-		BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
-		BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
-		BPF_EXIT_INSN(),
-	},
-	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
-	.func_info_cnt = 0,
-	.line_info = {
-		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 2, 9),
-		BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
-		BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 4, 7),
-		BTF_END_RAW,
-	},
-	.line_info_rec_size = sizeof(struct bpf_line_info),
-	.nr_jited_ksyms = 2,
-	.err_str = "Invalid line_info[2].insn_off",
-	.expected_prog_load_failure = true,
-},
+	*btf_size = size_needed;
+	if (ret_next_str)
+		*ret_next_str =
+			next_str_idx < strs_cnt ? strs_idx[next_str_idx] : NULL;
 
-{
-	.descr = "line_info (dead start)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0int\0/* dead jmp */\0int a=1;\0int b=2;\0return a + b;\0return a + b;"),
-	.insns = {
-		BPF_JMP_IMM(BPF_JA, 0, 0, 0),
-		BPF_MOV64_IMM(BPF_REG_0, 1),
-		BPF_MOV64_IMM(BPF_REG_1, 2),
-		BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
-		BPF_EXIT_INSN(),
-	},
-	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
-	.func_info_cnt = 0,
-	.line_info = {
-		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 9),
-		BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
-		BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 7),
-		BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 5, 6),
-		BTF_END_RAW,
-	},
-	.line_info_rec_size = sizeof(struct bpf_line_info),
-	.nr_jited_ksyms = 1,
-	.dead_code_cnt = 1,
-	.dead_code_mask = 0x01,
-},
+done:
+	if (err) {
+		if (raw_btf)
+			free(raw_btf);
+		if (strs_idx)
+			free(strs_idx);
+		return NULL;
+	}
+	return raw_btf;
+}
 
-{
-	.descr = "line_info (dead end)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0int\0int a=1;\0int b=2;\0return a + b;\0/* dead jmp */\0return a + b;\0/* dead exit */"),
-	.insns = {
-		BPF_MOV64_IMM(BPF_REG_0, 1),
-		BPF_MOV64_IMM(BPF_REG_1, 2),
-		BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
-		BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 10, 1),
-		BPF_EXIT_INSN(),
-		BPF_EXIT_INSN(),
-	},
-	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
-	.func_info_cnt = 0,
-	.line_info = {
-		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 12),
-		BPF_LINE_INFO_ENC(1, 0, NAME_TBD, 2, 11),
-		BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 10),
-		BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 4, 9),
-		BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 5, 8),
-		BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 6, 7),
-		BTF_END_RAW,
-	},
-	.line_info_rec_size = sizeof(struct bpf_line_info),
-	.nr_jited_ksyms = 1,
-	.dead_code_cnt = 2,
-	.dead_code_mask = 0x28,
-},
+const char *pprint_enum_str[] = {
+	"ENUM_ZERO",
+	"ENUM_ONE",
+	"ENUM_TWO",
+	"ENUM_THREE",
+};
 
-{
-	.descr = "line_info (dead code + subprog + func_info)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_FUNC_PROTO_ENC(1, 1),			/* [2] */
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
-		BTF_FUNC_ENC(NAME_TBD, 2),			/* [3] */
-		BTF_FUNC_ENC(NAME_TBD, 2),			/* [4] */
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0int\0x\0sub\0main\0int a=1+1;\0/* dead jmp */"
-		    "\0/* dead */\0/* dead */\0/* dead */\0/* dead */"
-		    "\0/* dead */\0/* dead */\0/* dead */\0/* dead */"
-		    "\0return func(a);\0b+=1;\0return b;"),
-	.insns = {
-		BPF_MOV64_IMM(BPF_REG_2, 1),
-		BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1),
-		BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
-		BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 8),
-		BPF_MOV64_IMM(BPF_REG_2, 1),
-		BPF_MOV64_IMM(BPF_REG_2, 1),
-		BPF_MOV64_IMM(BPF_REG_2, 1),
-		BPF_MOV64_IMM(BPF_REG_2, 1),
-		BPF_MOV64_IMM(BPF_REG_2, 1),
-		BPF_MOV64_IMM(BPF_REG_2, 1),
-		BPF_MOV64_IMM(BPF_REG_2, 1),
-		BPF_MOV64_IMM(BPF_REG_2, 1),
-		BPF_CALL_REL(1),
-		BPF_EXIT_INSN(),
-		BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
-		BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
-		BPF_EXIT_INSN(),
-	},
-	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
-	.func_info_cnt = 2,
-	.func_info_rec_size = 8,
-	.func_info = { {0, 4}, {14, 3} },
-	.line_info = {
-		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(8, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(9, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(10, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(11, 0, NAME_TBD, 2, 9),
-		BPF_LINE_INFO_ENC(12, 0, NAME_TBD, 2, 9),
-		BPF_LINE_INFO_ENC(14, 0, NAME_TBD, 3, 8),
-		BPF_LINE_INFO_ENC(16, 0, NAME_TBD, 4, 7),
-		BTF_END_RAW,
-	},
-	.line_info_rec_size = sizeof(struct bpf_line_info),
-	.nr_jited_ksyms = 2,
-	.dead_code_cnt = 9,
-	.dead_code_mask = 0x3fe,
-},
+struct pprint_mapv {
+	uint32_t ui32;
+	uint16_t ui16;
+	/* 2 bytes hole */
+	int32_t si32;
+	uint32_t unused_bits2a:2,
+		bits28:28,
+		unused_bits2b:2;
+	union {
+		uint64_t ui64;
+		uint8_t ui8a[8];
+	};
+	enum {
+		ENUM_ZERO,
+		ENUM_ONE,
+		ENUM_TWO,
+		ENUM_THREE,
+	} aenum;
+	uint32_t ui32b;
+	uint32_t bits2c:2;
+	uint8_t si8_4[2][2];
+};
 
-{
-	.descr = "line_info (dead subprog)",
-	.raw_types = {
-		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_FUNC_PROTO_ENC(1, 1),			/* [2] */
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
-		BTF_FUNC_ENC(NAME_TBD, 2),			/* [3] */
-		BTF_FUNC_ENC(NAME_TBD, 2),			/* [4] */
-		BTF_FUNC_ENC(NAME_TBD, 2),			/* [5] */
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0int\0x\0dead\0main\0func\0int a=1+1;\0/* live call */"
-		    "\0return 0;\0return 0;\0/* dead */\0/* dead */"
-		    "\0/* dead */\0return bla + 1;\0return bla + 1;"
-		    "\0return bla + 1;\0return func(a);\0b+=1;\0return b;"),
-	.insns = {
-		BPF_MOV64_IMM(BPF_REG_2, 1),
-		BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
-		BPF_CALL_REL(3),
-		BPF_CALL_REL(5),
-		BPF_MOV64_IMM(BPF_REG_0, 0),
-		BPF_EXIT_INSN(),
-		BPF_MOV64_IMM(BPF_REG_0, 0),
-		BPF_CALL_REL(1),
-		BPF_EXIT_INSN(),
-		BPF_MOV64_REG(BPF_REG_0, 2),
-		BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
-		BPF_EXIT_INSN(),
-	},
-	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
-	.func_info_cnt = 3,
-	.func_info_rec_size = 8,
-		.func_info = { {0, 4}, {6, 3}, {9, 5} },
-	.line_info = {
-		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(8, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(9, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(10, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(11, 0, NAME_TBD, 2, 9),
-		BTF_END_RAW,
-	},
-	.line_info_rec_size = sizeof(struct bpf_line_info),
-	.nr_jited_ksyms = 2,
-	.dead_code_cnt = 3,
-	.dead_code_mask = 0x70,
-	.dead_func_cnt = 1,
-	.dead_func_mask = 0x2,
-},
+#ifdef __SIZEOF_INT128__
+struct pprint_mapv_int128 {
+	__int128 si128a;
+	__int128 si128b;
+	unsigned __int128 bits3:3;
+	unsigned __int128 bits80:80;
+	unsigned __int128 ui128;
+};
+#endif
 
+static struct btf_raw_test pprint_test_template[] = {
 {
-	.descr = "line_info (dead last subprog)",
 	.raw_types = {
-		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_FUNC_PROTO_ENC(1, 1),			/* [2] */
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
-		BTF_FUNC_ENC(NAME_TBD, 2),			/* [3] */
-		BTF_FUNC_ENC(NAME_TBD, 2),			/* [5] */
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0int\0x\0dead\0main\0int a=1+1;\0/* live call */"
-		    "\0return 0;\0/* dead */\0/* dead */"),
-	.insns = {
-		BPF_MOV64_IMM(BPF_REG_2, 1),
-		BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
-		BPF_CALL_REL(2),
-		BPF_MOV64_IMM(BPF_REG_0, 0),
-		BPF_EXIT_INSN(),
-		BPF_MOV64_IMM(BPF_REG_0, 0),
-		BPF_EXIT_INSN(),
-	},
-	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
-	.func_info_cnt = 2,
-	.func_info_rec_size = 8,
-		.func_info = { {0, 4}, {5, 3} },
-	.line_info = {
-		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
+		/* unsighed char */			/* [1] */
+		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
+		/* unsigned short */			/* [2] */
+		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
+		/* unsigned int */			/* [3] */
+		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
+		/* int */				/* [4] */
+		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
+		/* unsigned long long */		/* [5] */
+		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
+		/* 2 bits */				/* [6] */
+		BTF_TYPE_INT_ENC(0, 0, 0, 2, 2),
+		/* 28 bits */				/* [7] */
+		BTF_TYPE_INT_ENC(0, 0, 0, 28, 4),
+		/* uint8_t[8] */			/* [8] */
+		BTF_TYPE_ARRAY_ENC(9, 1, 8),
+		/* typedef unsigned char uint8_t */	/* [9] */
+		BTF_TYPEDEF_ENC(NAME_TBD, 1),
+		/* typedef unsigned short uint16_t */	/* [10] */
+		BTF_TYPEDEF_ENC(NAME_TBD, 2),
+		/* typedef unsigned int uint32_t */	/* [11] */
+		BTF_TYPEDEF_ENC(NAME_TBD, 3),
+		/* typedef int int32_t */		/* [12] */
+		BTF_TYPEDEF_ENC(NAME_TBD, 4),
+		/* typedef unsigned long long uint64_t *//* [13] */
+		BTF_TYPEDEF_ENC(NAME_TBD, 5),
+		/* union (anon) */			/* [14] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
+		BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
+		BTF_MEMBER_ENC(NAME_TBD, 8, 0),	/* uint8_t ui8a[8]; */
+		/* enum (anon) */			/* [15] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
+		BTF_ENUM_ENC(NAME_TBD, 0),
+		BTF_ENUM_ENC(NAME_TBD, 1),
+		BTF_ENUM_ENC(NAME_TBD, 2),
+		BTF_ENUM_ENC(NAME_TBD, 3),
+		/* struct pprint_mapv */		/* [16] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 11), 40),
+		BTF_MEMBER_ENC(NAME_TBD, 11, 0),	/* uint32_t ui32 */
+		BTF_MEMBER_ENC(NAME_TBD, 10, 32),	/* uint16_t ui16 */
+		BTF_MEMBER_ENC(NAME_TBD, 12, 64),	/* int32_t si32 */
+		BTF_MEMBER_ENC(NAME_TBD, 6, 96),	/* unused_bits2a */
+		BTF_MEMBER_ENC(NAME_TBD, 7, 98),	/* bits28 */
+		BTF_MEMBER_ENC(NAME_TBD, 6, 126),	/* unused_bits2b */
+		BTF_MEMBER_ENC(0, 14, 128),		/* union (anon) */
+		BTF_MEMBER_ENC(NAME_TBD, 15, 192),	/* aenum */
+		BTF_MEMBER_ENC(NAME_TBD, 11, 224),	/* uint32_t ui32b */
+		BTF_MEMBER_ENC(NAME_TBD, 6, 256),	/* bits2c */
+		BTF_MEMBER_ENC(NAME_TBD, 17, 264),	/* si8_4 */
+		BTF_TYPE_ARRAY_ENC(18, 1, 2),		/* [17] */
+		BTF_TYPE_ARRAY_ENC(1, 1, 2),		/* [18] */
 		BTF_END_RAW,
 	},
-	.line_info_rec_size = sizeof(struct bpf_line_info),
-	.nr_jited_ksyms = 1,
-	.dead_code_cnt = 2,
-	.dead_code_mask = 0x18,
-	.dead_func_cnt = 1,
-	.dead_func_mask = 0x2,
+	BTF_STR_SEC("\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum\0ui32b\0bits2c\0si8_4"),
+	.key_size = sizeof(unsigned int),
+	.value_size = sizeof(struct pprint_mapv),
+	.key_type_id = 3,	/* unsigned int */
+	.value_type_id = 16,	/* struct pprint_mapv */
+	.max_entries = 128 * 1024,
 },
 
 {
-	.descr = "line_info (dead subprog + dead start)",
+	/* this type will have the same type as the
+	 * first .raw_types definition, but struct type will
+	 * be encoded with kind_flag set.
+	 */
 	.raw_types = {
-		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_FUNC_PROTO_ENC(1, 1),			/* [2] */
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
-		BTF_FUNC_ENC(NAME_TBD, 2),			/* [3] */
-		BTF_FUNC_ENC(NAME_TBD, 2),			/* [4] */
-		BTF_FUNC_ENC(NAME_TBD, 2),			/* [5] */
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0int\0x\0dead\0main\0func\0int a=1+1;\0/* dead */"
-		    "\0return 0;\0return 0;\0return 0;"
-		    "\0/* dead */\0/* dead */\0/* dead */\0/* dead */"
-		    "\0return b + 1;\0return b + 1;\0return b + 1;"),
-	.insns = {
-		BPF_JMP_IMM(BPF_JA, 0, 0, 0),
-		BPF_MOV64_IMM(BPF_REG_2, 1),
-		BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
-		BPF_CALL_REL(3),
-		BPF_CALL_REL(5),
-		BPF_MOV64_IMM(BPF_REG_0, 0),
-		BPF_EXIT_INSN(),
-		BPF_MOV64_IMM(BPF_REG_0, 0),
-		BPF_CALL_REL(1),
-		BPF_EXIT_INSN(),
-		BPF_JMP_IMM(BPF_JA, 0, 0, 0),
-		BPF_MOV64_REG(BPF_REG_0, 2),
-		BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
-		BPF_EXIT_INSN(),
-	},
-	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
-	.func_info_cnt = 3,
-	.func_info_rec_size = 8,
-		.func_info = { {0, 4}, {7, 3}, {10, 5} },
-	.line_info = {
-		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(8, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(9, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(10, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(11, 0, NAME_TBD, 2, 9),
-		BPF_LINE_INFO_ENC(12, 0, NAME_TBD, 2, 9),
-		BPF_LINE_INFO_ENC(13, 0, NAME_TBD, 2, 9),
+		/* unsighed char */			/* [1] */
+		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
+		/* unsigned short */			/* [2] */
+		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
+		/* unsigned int */			/* [3] */
+		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
+		/* int */				/* [4] */
+		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
+		/* unsigned long long */		/* [5] */
+		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
+		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),	/* [6] */
+		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),	/* [7] */
+		/* uint8_t[8] */			/* [8] */
+		BTF_TYPE_ARRAY_ENC(9, 1, 8),
+		/* typedef unsigned char uint8_t */	/* [9] */
+		BTF_TYPEDEF_ENC(NAME_TBD, 1),
+		/* typedef unsigned short uint16_t */	/* [10] */
+		BTF_TYPEDEF_ENC(NAME_TBD, 2),
+		/* typedef unsigned int uint32_t */	/* [11] */
+		BTF_TYPEDEF_ENC(NAME_TBD, 3),
+		/* typedef int int32_t */		/* [12] */
+		BTF_TYPEDEF_ENC(NAME_TBD, 4),
+		/* typedef unsigned long long uint64_t *//* [13] */
+		BTF_TYPEDEF_ENC(NAME_TBD, 5),
+		/* union (anon) */			/* [14] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
+		BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
+		BTF_MEMBER_ENC(NAME_TBD, 8, 0),	/* uint8_t ui8a[8]; */
+		/* enum (anon) */			/* [15] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
+		BTF_ENUM_ENC(NAME_TBD, 0),
+		BTF_ENUM_ENC(NAME_TBD, 1),
+		BTF_ENUM_ENC(NAME_TBD, 2),
+		BTF_ENUM_ENC(NAME_TBD, 3),
+		/* struct pprint_mapv */		/* [16] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 11), 40),
+		BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 0)),	/* uint32_t ui32 */
+		BTF_MEMBER_ENC(NAME_TBD, 10, BTF_MEMBER_OFFSET(0, 32)),	/* uint16_t ui16 */
+		BTF_MEMBER_ENC(NAME_TBD, 12, BTF_MEMBER_OFFSET(0, 64)),	/* int32_t si32 */
+		BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 96)),	/* unused_bits2a */
+		BTF_MEMBER_ENC(NAME_TBD, 7, BTF_MEMBER_OFFSET(28, 98)),	/* bits28 */
+		BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 126)),	/* unused_bits2b */
+		BTF_MEMBER_ENC(0, 14, BTF_MEMBER_OFFSET(0, 128)),	/* union (anon) */
+		BTF_MEMBER_ENC(NAME_TBD, 15, BTF_MEMBER_OFFSET(0, 192)),	/* aenum */
+		BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 224)),	/* uint32_t ui32b */
+		BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 256)),	/* bits2c */
+		BTF_MEMBER_ENC(NAME_TBD, 17, 264),	/* si8_4 */
+		BTF_TYPE_ARRAY_ENC(18, 1, 2),		/* [17] */
+		BTF_TYPE_ARRAY_ENC(1, 1, 2),		/* [18] */
 		BTF_END_RAW,
 	},
-	.line_info_rec_size = sizeof(struct bpf_line_info),
-	.nr_jited_ksyms = 2,
-	.dead_code_cnt = 5,
-	.dead_code_mask = 0x1e2,
-	.dead_func_cnt = 1,
-	.dead_func_mask = 0x2,
+	BTF_STR_SEC("\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum\0ui32b\0bits2c\0si8_4"),
+	.key_size = sizeof(unsigned int),
+	.value_size = sizeof(struct pprint_mapv),
+	.key_type_id = 3,	/* unsigned int */
+	.value_type_id = 16,	/* struct pprint_mapv */
+	.max_entries = 128 * 1024,
 },
 
 {
-	.descr = "line_info (dead subprog + dead start w/ move)",
+	/* this type will have the same layout as the
+	 * first .raw_types definition. The struct type will
+	 * be encoded with kind_flag set, bitfield members
+	 * are added typedef/const/volatile, and bitfield members
+	 * will have both int and enum types.
+	 */
 	.raw_types = {
-		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_FUNC_PROTO_ENC(1, 1),			/* [2] */
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
-		BTF_FUNC_ENC(NAME_TBD, 2),			/* [3] */
-		BTF_FUNC_ENC(NAME_TBD, 2),			/* [4] */
-		BTF_FUNC_ENC(NAME_TBD, 2),			/* [5] */
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0int\0x\0dead\0main\0func\0int a=1+1;\0/* live call */"
-		    "\0return 0;\0return 0;\0/* dead */\0/* dead */"
-		    "\0/* dead */\0return bla + 1;\0return bla + 1;"
-		    "\0return bla + 1;\0return func(a);\0b+=1;\0return b;"),
-	.insns = {
-		BPF_MOV64_IMM(BPF_REG_2, 1),
-		BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
-		BPF_CALL_REL(3),
-		BPF_CALL_REL(5),
-		BPF_MOV64_IMM(BPF_REG_0, 0),
-		BPF_EXIT_INSN(),
-		BPF_MOV64_IMM(BPF_REG_0, 0),
-		BPF_CALL_REL(1),
-		BPF_EXIT_INSN(),
-		BPF_JMP_IMM(BPF_JA, 0, 0, 0),
-		BPF_MOV64_REG(BPF_REG_0, 2),
-		BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
-		BPF_EXIT_INSN(),
-	},
-	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
-	.func_info_cnt = 3,
-	.func_info_rec_size = 8,
-		.func_info = { {0, 4}, {6, 3}, {9, 5} },
-	.line_info = {
-		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(3, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(4, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(5, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(7, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(8, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(9, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(11, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(12, 0, NAME_TBD, 2, 9),
+		/* unsighed char */			/* [1] */
+		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
+		/* unsigned short */			/* [2] */
+		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
+		/* unsigned int */			/* [3] */
+		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
+		/* int */				/* [4] */
+		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
+		/* unsigned long long */		/* [5] */
+		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
+		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),	/* [6] */
+		BTF_TYPE_INT_ENC(0, 0, 0, 32, 4),	/* [7] */
+		/* uint8_t[8] */			/* [8] */
+		BTF_TYPE_ARRAY_ENC(9, 1, 8),
+		/* typedef unsigned char uint8_t */	/* [9] */
+		BTF_TYPEDEF_ENC(NAME_TBD, 1),
+		/* typedef unsigned short uint16_t */	/* [10] */
+		BTF_TYPEDEF_ENC(NAME_TBD, 2),
+		/* typedef unsigned int uint32_t */	/* [11] */
+		BTF_TYPEDEF_ENC(NAME_TBD, 3),
+		/* typedef int int32_t */		/* [12] */
+		BTF_TYPEDEF_ENC(NAME_TBD, 4),
+		/* typedef unsigned long long uint64_t *//* [13] */
+		BTF_TYPEDEF_ENC(NAME_TBD, 5),
+		/* union (anon) */			/* [14] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
+		BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
+		BTF_MEMBER_ENC(NAME_TBD, 8, 0),	/* uint8_t ui8a[8]; */
+		/* enum (anon) */			/* [15] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
+		BTF_ENUM_ENC(NAME_TBD, 0),
+		BTF_ENUM_ENC(NAME_TBD, 1),
+		BTF_ENUM_ENC(NAME_TBD, 2),
+		BTF_ENUM_ENC(NAME_TBD, 3),
+		/* struct pprint_mapv */		/* [16] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 11), 40),
+		BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 0)),	/* uint32_t ui32 */
+		BTF_MEMBER_ENC(NAME_TBD, 10, BTF_MEMBER_OFFSET(0, 32)),	/* uint16_t ui16 */
+		BTF_MEMBER_ENC(NAME_TBD, 12, BTF_MEMBER_OFFSET(0, 64)),	/* int32_t si32 */
+		BTF_MEMBER_ENC(NAME_TBD, 17, BTF_MEMBER_OFFSET(2, 96)),	/* unused_bits2a */
+		BTF_MEMBER_ENC(NAME_TBD, 7, BTF_MEMBER_OFFSET(28, 98)),	/* bits28 */
+		BTF_MEMBER_ENC(NAME_TBD, 19, BTF_MEMBER_OFFSET(2, 126)),/* unused_bits2b */
+		BTF_MEMBER_ENC(0, 14, BTF_MEMBER_OFFSET(0, 128)),	/* union (anon) */
+		BTF_MEMBER_ENC(NAME_TBD, 15, BTF_MEMBER_OFFSET(0, 192)),	/* aenum */
+		BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 224)),	/* uint32_t ui32b */
+		BTF_MEMBER_ENC(NAME_TBD, 17, BTF_MEMBER_OFFSET(2, 256)),	/* bits2c */
+		BTF_MEMBER_ENC(NAME_TBD, 20, BTF_MEMBER_OFFSET(0, 264)),	/* si8_4 */
+		/* typedef unsigned int ___int */	/* [17] */
+		BTF_TYPEDEF_ENC(NAME_TBD, 18),
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_VOLATILE, 0, 0), 6),	/* [18] */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 15),	/* [19] */
+		BTF_TYPE_ARRAY_ENC(21, 1, 2),					/* [20] */
+		BTF_TYPE_ARRAY_ENC(1, 1, 2),					/* [21] */
 		BTF_END_RAW,
 	},
-	.line_info_rec_size = sizeof(struct bpf_line_info),
-	.nr_jited_ksyms = 2,
-	.dead_code_cnt = 3,
-	.dead_code_mask = 0x70,
-	.dead_func_cnt = 1,
-	.dead_func_mask = 0x2,
+	BTF_STR_SEC("\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum\0ui32b\0bits2c\0___int\0si8_4"),
+	.key_size = sizeof(unsigned int),
+	.value_size = sizeof(struct pprint_mapv),
+	.key_type_id = 3,	/* unsigned int */
+	.value_type_id = 16,	/* struct pprint_mapv */
+	.max_entries = 128 * 1024,
 },
 
+#ifdef __SIZEOF_INT128__
 {
-	.descr = "line_info (dead end + subprog start w/ no linfo)",
+	/* test int128 */
 	.raw_types = {
-		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-		BTF_FUNC_PROTO_ENC(1, 1),			/* [2] */
-			BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
-		BTF_FUNC_ENC(NAME_TBD, 2),			/* [3] */
-		BTF_FUNC_ENC(NAME_TBD, 2),			/* [4] */
-		BTF_END_RAW,
-	},
-	BTF_STR_SEC("\0int\0x\0main\0func\0/* main linfo */\0/* func linfo */"),
-	.insns = {
-		BPF_MOV64_IMM(BPF_REG_0, 0),
-		BPF_JMP_IMM(BPF_JGE, BPF_REG_0, 1, 3),
-		BPF_CALL_REL(3),
-		BPF_MOV64_IMM(BPF_REG_0, 0),
-		BPF_EXIT_INSN(),
-		BPF_EXIT_INSN(),
-		BPF_JMP_IMM(BPF_JA, 0, 0, 0),
-		BPF_EXIT_INSN(),
-	},
-	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
-	.func_info_cnt = 2,
-	.func_info_rec_size = 8,
-	.func_info = { {0, 3}, {6, 4}, },
-	.line_info = {
-		BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
-		BPF_LINE_INFO_ENC(6, 0, NAME_TBD, 1, 10),
-		BTF_END_RAW,
-	},
-	.line_info_rec_size = sizeof(struct bpf_line_info),
-	.nr_jited_ksyms = 2,
-},
-
-};
-
-static size_t probe_prog_length(const struct bpf_insn *fp)
-{
-	size_t len;
-
-	for (len = MAX_INSNS - 1; len > 0; --len)
-		if (fp[len].code != 0 || fp[len].imm != 0)
-			break;
-	return len + 1;
-}
-
-static __u32 *patch_name_tbd(const __u32 *raw_u32,
-			     const char *str, __u32 str_off,
-			     unsigned int str_sec_size,
-			     unsigned int *ret_size)
-{
-	int i, raw_u32_size = get_raw_sec_size(raw_u32);
-	const char *end_str = str + str_sec_size;
-	const char *next_str = str + str_off;
-	__u32 *new_u32 = NULL;
-
-	if (raw_u32_size == -1)
-		return ERR_PTR(-EINVAL);
-
-	if (!raw_u32_size) {
-		*ret_size = 0;
-		return NULL;
-	}
-
-	new_u32 = malloc(raw_u32_size);
-	if (!new_u32)
-		return ERR_PTR(-ENOMEM);
-
-	for (i = 0; i < raw_u32_size / sizeof(raw_u32[0]); i++) {
-		if (raw_u32[i] == NAME_TBD) {
-			next_str = get_next_str(next_str, end_str);
-			if (CHECK(!next_str, "Error in getting next_str\n")) {
-				free(new_u32);
-				return ERR_PTR(-EINVAL);
-			}
-			new_u32[i] = next_str - str;
-			next_str += strlen(next_str);
-		} else {
-			new_u32[i] = raw_u32[i];
-		}
-	}
-
-	*ret_size = raw_u32_size;
-	return new_u32;
-}
-
-static int test_get_finfo(const struct prog_info_raw_test *test,
-			  int prog_fd)
-{
-	struct bpf_prog_info info = {};
-	struct bpf_func_info *finfo;
-	__u32 info_len, rec_size, i;
-	void *func_info = NULL;
-	__u32 nr_func_info;
-	int err;
-
-	/* get necessary lens */
-	info_len = sizeof(struct bpf_prog_info);
-	err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
-	if (CHECK(err == -1, "invalid get info (1st) errno:%d", errno)) {
-		fprintf(stderr, "%s\n", btf_log_buf);
-		return -1;
-	}
-	nr_func_info = test->func_info_cnt - test->dead_func_cnt;
-	if (CHECK(info.nr_func_info != nr_func_info,
-		  "incorrect info.nr_func_info (1st) %d",
-		  info.nr_func_info)) {
-		return -1;
-	}
-
-	rec_size = info.func_info_rec_size;
-	if (CHECK(rec_size != sizeof(struct bpf_func_info),
-		  "incorrect info.func_info_rec_size (1st) %d", rec_size)) {
-		return -1;
-	}
-
-	if (!info.nr_func_info)
-		return 0;
-
-	func_info = malloc(info.nr_func_info * rec_size);
-	if (CHECK(!func_info, "out of memory"))
-		return -1;
-
-	/* reset info to only retrieve func_info related data */
-	memset(&info, 0, sizeof(info));
-	info.nr_func_info = nr_func_info;
-	info.func_info_rec_size = rec_size;
-	info.func_info = ptr_to_u64(func_info);
-	err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
-	if (CHECK(err == -1, "invalid get info (2nd) errno:%d", errno)) {
-		fprintf(stderr, "%s\n", btf_log_buf);
-		err = -1;
-		goto done;
-	}
-	if (CHECK(info.nr_func_info != nr_func_info,
-		  "incorrect info.nr_func_info (2nd) %d",
-		  info.nr_func_info)) {
-		err = -1;
-		goto done;
-	}
-	if (CHECK(info.func_info_rec_size != rec_size,
-		  "incorrect info.func_info_rec_size (2nd) %d",
-		  info.func_info_rec_size)) {
-		err = -1;
-		goto done;
-	}
-
-	finfo = func_info;
-	for (i = 0; i < nr_func_info; i++) {
-		if (test->dead_func_mask & (1 << i))
-			continue;
-		if (CHECK(finfo->type_id != test->func_info[i][1],
-			  "incorrect func_type %u expected %u",
-			  finfo->type_id, test->func_info[i][1])) {
-			err = -1;
-			goto done;
-		}
-		finfo = (void *)finfo + rec_size;
-	}
-
-	err = 0;
-
-done:
-	free(func_info);
-	return err;
-}
-
-static int test_get_linfo(const struct prog_info_raw_test *test,
-			  const void *patched_linfo,
-			  __u32 cnt, int prog_fd)
-{
-	__u32 i, info_len, nr_jited_ksyms, nr_jited_func_lens;
-	__u64 *jited_linfo = NULL, *jited_ksyms = NULL;
-	__u32 rec_size, jited_rec_size, jited_cnt;
-	struct bpf_line_info *linfo = NULL;
-	__u32 cur_func_len, ksyms_found;
-	struct bpf_prog_info info = {};
-	__u32 *jited_func_lens = NULL;
-	__u64 cur_func_ksyms;
-	__u32 dead_insns;
-	int err;
-
-	jited_cnt = cnt;
-	rec_size = sizeof(*linfo);
-	jited_rec_size = sizeof(*jited_linfo);
-	if (test->nr_jited_ksyms)
-		nr_jited_ksyms = test->nr_jited_ksyms;
-	else
-		nr_jited_ksyms = test->func_info_cnt - test->dead_func_cnt;
-	nr_jited_func_lens = nr_jited_ksyms;
-
-	info_len = sizeof(struct bpf_prog_info);
-	err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
-	if (CHECK(err == -1, "err:%d errno:%d", err, errno)) {
-		err = -1;
-		goto done;
-	}
-
-	if (!info.jited_prog_len) {
-		/* prog is not jited */
-		jited_cnt = 0;
-		nr_jited_ksyms = 1;
-		nr_jited_func_lens = 1;
-	}
-
-	if (CHECK(info.nr_line_info != cnt ||
-		  info.nr_jited_line_info != jited_cnt ||
-		  info.nr_jited_ksyms != nr_jited_ksyms ||
-		  info.nr_jited_func_lens != nr_jited_func_lens ||
-		  (!info.nr_line_info && info.nr_jited_line_info),
-		  "info: nr_line_info:%u(expected:%u) nr_jited_line_info:%u(expected:%u) nr_jited_ksyms:%u(expected:%u) nr_jited_func_lens:%u(expected:%u)",
-		  info.nr_line_info, cnt,
-		  info.nr_jited_line_info, jited_cnt,
-		  info.nr_jited_ksyms, nr_jited_ksyms,
-		  info.nr_jited_func_lens, nr_jited_func_lens)) {
-		err = -1;
-		goto done;
-	}
-
-	if (CHECK(info.line_info_rec_size != sizeof(struct bpf_line_info) ||
-		  info.jited_line_info_rec_size != sizeof(__u64),
-		  "info: line_info_rec_size:%u(userspace expected:%u) jited_line_info_rec_size:%u(userspace expected:%u)",
-		  info.line_info_rec_size, rec_size,
-		  info.jited_line_info_rec_size, jited_rec_size)) {
-		err = -1;
-		goto done;
-	}
-
-	if (!cnt)
-		return 0;
-
-	rec_size = info.line_info_rec_size;
-	jited_rec_size = info.jited_line_info_rec_size;
-
-	memset(&info, 0, sizeof(info));
-
-	linfo = calloc(cnt, rec_size);
-	if (CHECK(!linfo, "!linfo")) {
-		err = -1;
-		goto done;
-	}
-	info.nr_line_info = cnt;
-	info.line_info_rec_size = rec_size;
-	info.line_info = ptr_to_u64(linfo);
-
-	if (jited_cnt) {
-		jited_linfo = calloc(jited_cnt, jited_rec_size);
-		jited_ksyms = calloc(nr_jited_ksyms, sizeof(*jited_ksyms));
-		jited_func_lens = calloc(nr_jited_func_lens,
-					 sizeof(*jited_func_lens));
-		if (CHECK(!jited_linfo || !jited_ksyms || !jited_func_lens,
-			  "jited_linfo:%p jited_ksyms:%p jited_func_lens:%p",
-			  jited_linfo, jited_ksyms, jited_func_lens)) {
-			err = -1;
-			goto done;
-		}
-
-		info.nr_jited_line_info = jited_cnt;
-		info.jited_line_info_rec_size = jited_rec_size;
-		info.jited_line_info = ptr_to_u64(jited_linfo);
-		info.nr_jited_ksyms = nr_jited_ksyms;
-		info.jited_ksyms = ptr_to_u64(jited_ksyms);
-		info.nr_jited_func_lens = nr_jited_func_lens;
-		info.jited_func_lens = ptr_to_u64(jited_func_lens);
-	}
-
-	err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
-
-	/*
-	 * Only recheck the info.*line_info* fields.
-	 * Other fields are not the concern of this test.
-	 */
-	if (CHECK(err == -1 ||
-		  info.nr_line_info != cnt ||
-		  (jited_cnt && !info.jited_line_info) ||
-		  info.nr_jited_line_info != jited_cnt ||
-		  info.line_info_rec_size != rec_size ||
-		  info.jited_line_info_rec_size != jited_rec_size,
-		  "err:%d errno:%d info: nr_line_info:%u(expected:%u) nr_jited_line_info:%u(expected:%u) line_info_rec_size:%u(expected:%u) jited_linfo_rec_size:%u(expected:%u) line_info:%p jited_line_info:%p",
-		  err, errno,
-		  info.nr_line_info, cnt,
-		  info.nr_jited_line_info, jited_cnt,
-		  info.line_info_rec_size, rec_size,
-		  info.jited_line_info_rec_size, jited_rec_size,
-		  (void *)(long)info.line_info,
-		  (void *)(long)info.jited_line_info)) {
-		err = -1;
-		goto done;
-	}
-
-	dead_insns = 0;
-	while (test->dead_code_mask & (1 << dead_insns))
-		dead_insns++;
+		/* unsigned int */				/* [1] */
+		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
+		/* __int128 */					/* [2] */
+		BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 128, 16),
+		/* unsigned __int128 */				/* [3] */
+		BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 128, 16),
+		/* struct pprint_mapv_int128 */			/* [4] */
+		BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 5), 64),
+		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)),		/* si128a */
+		BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 128)),		/* si128b */
+		BTF_MEMBER_ENC(NAME_TBD, 3, BTF_MEMBER_OFFSET(3, 256)),		/* bits3 */
+		BTF_MEMBER_ENC(NAME_TBD, 3, BTF_MEMBER_OFFSET(80, 259)),	/* bits80 */
+		BTF_MEMBER_ENC(NAME_TBD, 3, BTF_MEMBER_OFFSET(0, 384)),		/* ui128 */
+		BTF_END_RAW,
+	},
+	BTF_STR_SEC("\0unsigned int\0__int128\0unsigned __int128\0pprint_mapv_int128\0si128a\0si128b\0bits3\0bits80\0ui128"),
+	.key_size = sizeof(unsigned int),
+	.value_size = sizeof(struct pprint_mapv_int128),
+	.key_type_id = 1,
+	.value_type_id = 4,
+	.max_entries = 128 * 1024,
+	.mapv_kind = PPRINT_MAPV_KIND_INT128,
+},
+#endif
 
-	CHECK(linfo[0].insn_off, "linfo[0].insn_off:%u",
-	      linfo[0].insn_off);
-	for (i = 1; i < cnt; i++) {
-		const struct bpf_line_info *expected_linfo;
+};
 
-		while (test->dead_code_mask & (1 << (i + dead_insns)))
-			dead_insns++;
+static struct btf_pprint_test_meta {
+	const char *descr;
+	enum bpf_map_type map_type;
+	const char *map_name;
+	bool ordered_map;
+	bool lossless_map;
+	bool percpu_map;
+} pprint_tests_meta[] = {
+{
+	.descr = "BTF pretty print array",
+	.map_type = BPF_MAP_TYPE_ARRAY,
+	.map_name = "pprint_test_array",
+	.ordered_map = true,
+	.lossless_map = true,
+	.percpu_map = false,
+},
 
-		expected_linfo = patched_linfo +
-			((i + dead_insns) * test->line_info_rec_size);
-		if (CHECK(linfo[i].insn_off <= linfo[i - 1].insn_off,
-			  "linfo[%u].insn_off:%u <= linfo[%u].insn_off:%u",
-			  i, linfo[i].insn_off,
-			  i - 1, linfo[i - 1].insn_off)) {
-			err = -1;
-			goto done;
-		}
-		if (CHECK(linfo[i].file_name_off != expected_linfo->file_name_off ||
-			  linfo[i].line_off != expected_linfo->line_off ||
-			  linfo[i].line_col != expected_linfo->line_col,
-			  "linfo[%u] (%u, %u, %u) != (%u, %u, %u)", i,
-			  linfo[i].file_name_off,
-			  linfo[i].line_off,
-			  linfo[i].line_col,
-			  expected_linfo->file_name_off,
-			  expected_linfo->line_off,
-			  expected_linfo->line_col)) {
-			err = -1;
-			goto done;
-		}
-	}
+{
+	.descr = "BTF pretty print hash",
+	.map_type = BPF_MAP_TYPE_HASH,
+	.map_name = "pprint_test_hash",
+	.ordered_map = false,
+	.lossless_map = true,
+	.percpu_map = false,
+},
 
-	if (!jited_cnt) {
-		fprintf(stderr, "not jited. skipping jited_line_info check. ");
-		err = 0;
-		goto done;
-	}
+{
+	.descr = "BTF pretty print lru hash",
+	.map_type = BPF_MAP_TYPE_LRU_HASH,
+	.map_name = "pprint_test_lru_hash",
+	.ordered_map = false,
+	.lossless_map = false,
+	.percpu_map = false,
+},
 
-	if (CHECK(jited_linfo[0] != jited_ksyms[0],
-		  "jited_linfo[0]:%lx != jited_ksyms[0]:%lx",
-		  (long)(jited_linfo[0]), (long)(jited_ksyms[0]))) {
-		err = -1;
-		goto done;
-	}
+{
+	.descr = "BTF pretty print percpu array",
+	.map_type = BPF_MAP_TYPE_PERCPU_ARRAY,
+	.map_name = "pprint_test_percpu_array",
+	.ordered_map = true,
+	.lossless_map = true,
+	.percpu_map = true,
+},
 
-	ksyms_found = 1;
-	cur_func_len = jited_func_lens[0];
-	cur_func_ksyms = jited_ksyms[0];
-	for (i = 1; i < jited_cnt; i++) {
-		if (ksyms_found < nr_jited_ksyms &&
-		    jited_linfo[i] == jited_ksyms[ksyms_found]) {
-			cur_func_ksyms = jited_ksyms[ksyms_found];
-			cur_func_len = jited_ksyms[ksyms_found];
-			ksyms_found++;
-			continue;
-		}
+{
+	.descr = "BTF pretty print percpu hash",
+	.map_type = BPF_MAP_TYPE_PERCPU_HASH,
+	.map_name = "pprint_test_percpu_hash",
+	.ordered_map = false,
+	.lossless_map = true,
+	.percpu_map = true,
+},
 
-		if (CHECK(jited_linfo[i] <= jited_linfo[i - 1],
-			  "jited_linfo[%u]:%lx <= jited_linfo[%u]:%lx",
-			  i, (long)jited_linfo[i],
-			  i - 1, (long)(jited_linfo[i - 1]))) {
-			err = -1;
-			goto done;
-		}
+{
+	.descr = "BTF pretty print lru percpu hash",
+	.map_type = BPF_MAP_TYPE_LRU_PERCPU_HASH,
+	.map_name = "pprint_test_lru_percpu_hash",
+	.ordered_map = false,
+	.lossless_map = false,
+	.percpu_map = true,
+},
 
-		if (CHECK(jited_linfo[i] - cur_func_ksyms > cur_func_len,
-			  "jited_linfo[%u]:%lx - %lx > %u",
-			  i, (long)jited_linfo[i], (long)cur_func_ksyms,
-			  cur_func_len)) {
-			err = -1;
-			goto done;
-		}
-	}
+};
 
-	if (CHECK(ksyms_found != nr_jited_ksyms,
-		  "ksyms_found:%u != nr_jited_ksyms:%u",
-		  ksyms_found, nr_jited_ksyms)) {
-		err = -1;
-		goto done;
-	}
+static size_t get_pprint_mapv_size(enum pprint_mapv_kind_t mapv_kind)
+{
+	if (mapv_kind == PPRINT_MAPV_KIND_BASIC)
+		return sizeof(struct pprint_mapv);
 
-	err = 0;
+#ifdef __SIZEOF_INT128__
+	if (mapv_kind == PPRINT_MAPV_KIND_INT128)
+		return sizeof(struct pprint_mapv_int128);
+#endif
 
-done:
-	free(linfo);
-	free(jited_linfo);
-	free(jited_ksyms);
-	free(jited_func_lens);
-	return err;
+	assert(0);
 }
 
-static int do_test_info_raw(unsigned int test_num)
+static void set_pprint_mapv(enum pprint_mapv_kind_t mapv_kind,
+			    void *mapv, uint32_t i,
+			    int num_cpus, int rounded_value_size)
 {
-	const struct prog_info_raw_test *test = &info_raw_tests[test_num - 1];
-	unsigned int raw_btf_size, linfo_str_off, linfo_size;
-	int btf_fd = -1, prog_fd = -1, err = 0;
-	void *raw_btf, *patched_linfo = NULL;
-	const char *ret_next_str;
-	union bpf_attr attr = {};
-
-	fprintf(stderr, "BTF prog info raw test[%u] (%s): ", test_num, test->descr);
-	raw_btf = btf_raw_create(&hdr_tmpl, test->raw_types,
-				 test->str_sec, test->str_sec_size,
-				 &raw_btf_size, &ret_next_str);
-
-	if (!raw_btf)
-		return -1;
-
-	*btf_log_buf = '\0';
-	btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
-			      btf_log_buf, BTF_LOG_BUF_SIZE,
-			      args.always_log);
-	free(raw_btf);
-
-	if (CHECK(btf_fd == -1, "invalid btf_fd errno:%d", errno)) {
-		err = -1;
-		goto done;
-	}
+	int cpu;
 
-	if (*btf_log_buf && args.always_log)
-		fprintf(stderr, "\n%s", btf_log_buf);
-	*btf_log_buf = '\0';
+	if (mapv_kind == PPRINT_MAPV_KIND_BASIC) {
+		struct pprint_mapv *v = mapv;
 
-	linfo_str_off = ret_next_str - test->str_sec;
-	patched_linfo = patch_name_tbd(test->line_info,
-				       test->str_sec, linfo_str_off,
-				       test->str_sec_size, &linfo_size);
-	if (IS_ERR(patched_linfo)) {
-		fprintf(stderr, "error in creating raw bpf_line_info");
-		err = -1;
-		goto done;
+		for (cpu = 0; cpu < num_cpus; cpu++) {
+			v->ui32 = i + cpu;
+			v->si32 = -i;
+			v->unused_bits2a = 3;
+			v->bits28 = i;
+			v->unused_bits2b = 3;
+			v->ui64 = i;
+			v->aenum = i & 0x03;
+			v->ui32b = 4;
+			v->bits2c = 1;
+			v->si8_4[0][0] = (cpu + i) & 0xff;
+			v->si8_4[0][1] = (cpu + i + 1) & 0xff;
+			v->si8_4[1][0] = (cpu + i + 2) & 0xff;
+			v->si8_4[1][1] = (cpu + i + 3) & 0xff;
+			v = (void *)v + rounded_value_size;
+		}
 	}
 
-	attr.prog_type = test->prog_type;
-	attr.insns = ptr_to_u64(test->insns);
-	attr.insn_cnt = probe_prog_length(test->insns);
-	attr.license = ptr_to_u64("GPL");
-	attr.prog_btf_fd = btf_fd;
-	attr.func_info_rec_size = test->func_info_rec_size;
-	attr.func_info_cnt = test->func_info_cnt;
-	attr.func_info = ptr_to_u64(test->func_info);
-	attr.log_buf = ptr_to_u64(btf_log_buf);
-	attr.log_size = BTF_LOG_BUF_SIZE;
-	attr.log_level = 1;
-	if (linfo_size) {
-		attr.line_info_rec_size = test->line_info_rec_size;
-		attr.line_info = ptr_to_u64(patched_linfo);
-		attr.line_info_cnt = linfo_size / attr.line_info_rec_size;
-	}
+#ifdef __SIZEOF_INT128__
+	if (mapv_kind == PPRINT_MAPV_KIND_INT128) {
+		struct pprint_mapv_int128 *v = mapv;
 
-	prog_fd = syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr));
-	err = ((prog_fd == -1) != test->expected_prog_load_failure);
-	if (CHECK(err, "prog_fd:%d expected_prog_load_failure:%u errno:%d",
-		  prog_fd, test->expected_prog_load_failure, errno) ||
-	    CHECK(test->err_str && !strstr(btf_log_buf, test->err_str),
-		  "expected err_str:%s", test->err_str)) {
-		err = -1;
-		goto done;
+		for (cpu = 0; cpu < num_cpus; cpu++) {
+			v->si128a = i;
+			v->si128b = -i;
+			v->bits3 = i & 0x07;
+			v->bits80 = (((unsigned __int128)1) << 64) + i;
+			v->ui128 = (((unsigned __int128)2) << 64) + i;
+			v = (void *)v + rounded_value_size;
+		}
 	}
-
-	if (prog_fd == -1)
-		goto done;
-
-	err = test_get_finfo(test, prog_fd);
-	if (err)
-		goto done;
-
-	err = test_get_linfo(test, patched_linfo,
-			     attr.line_info_cnt - test->dead_code_cnt,
-			     prog_fd);
-	if (err)
-		goto done;
-
-done:
-	if (!err)
-		fprintf(stderr, "OK");
-
-	if (*btf_log_buf && (err || args.always_log))
-		fprintf(stderr, "\n%s", btf_log_buf);
-
-	if (btf_fd != -1)
-		close(btf_fd);
-	if (prog_fd != -1)
-		close(prog_fd);
-
-	if (!IS_ERR(patched_linfo))
-		free(patched_linfo);
-
-	return err;
-}
-
-static int test_info_raw(void)
-{
-	unsigned int i;
-	int err = 0;
-
-	if (args.info_raw_test_num)
-		return count_result(do_test_info_raw(args.info_raw_test_num));
-
-	for (i = 1; i <= ARRAY_SIZE(info_raw_tests); i++)
-		err |= count_result(do_test_info_raw(i));
-
-	return err;
+#endif
 }
 
-struct btf_raw_data {
-	__u32 raw_types[MAX_NR_RAW_U32];
-	const char *str_sec;
-	__u32 str_sec_size;
-};
-
-struct btf_dedup_test {
-	const char *descr;
-	struct btf_raw_data input;
-	struct btf_raw_data expect;
-	struct btf_dedup_opts opts;
-};
-
-const struct btf_dedup_test dedup_tests[] = {
-
-{
-	.descr = "dedup: unused strings filtering",
-	.input = {
-		.raw_types = {
-			BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 32, 4),
-			BTF_TYPE_INT_ENC(NAME_NTH(5), BTF_INT_SIGNED, 0, 64, 8),
-			BTF_END_RAW,
-		},
-		BTF_STR_SEC("\0unused\0int\0foo\0bar\0long"),
-	},
-	.expect = {
-		.raw_types = {
-			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
-			BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 64, 8),
-			BTF_END_RAW,
-		},
-		BTF_STR_SEC("\0int\0long"),
-	},
-	.opts = {
-		.dont_resolve_fwds = false,
-	},
-},
-{
-	.descr = "dedup: strings deduplication",
-	.input = {
-		.raw_types = {
-			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
-			BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 64, 8),
-			BTF_TYPE_INT_ENC(NAME_NTH(3), BTF_INT_SIGNED, 0, 32, 4),
-			BTF_TYPE_INT_ENC(NAME_NTH(4), BTF_INT_SIGNED, 0, 64, 8),
-			BTF_TYPE_INT_ENC(NAME_NTH(5), BTF_INT_SIGNED, 0, 32, 4),
-			BTF_END_RAW,
-		},
-		BTF_STR_SEC("\0int\0long int\0int\0long int\0int"),
-	},
-	.expect = {
-		.raw_types = {
-			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
-			BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 64, 8),
-			BTF_END_RAW,
-		},
-		BTF_STR_SEC("\0int\0long int"),
-	},
-	.opts = {
-		.dont_resolve_fwds = false,
-	},
-},
+ssize_t get_pprint_expected_line(enum pprint_mapv_kind_t mapv_kind,
+				 char *expected_line, ssize_t line_size,
+				 bool percpu_map, unsigned int next_key,
+				 int cpu, void *mapv)
 {
-	.descr = "dedup: struct example #1",
-	/*
-	 * struct s {
-	 *	struct s *next;
-	 *	const int *a;
-	 *	int b[16];
-	 *	int c;
-	 * }
-	 */
-	.input = {
-		.raw_types = {
-			/* int */
-			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-			/* int[16] */
-			BTF_TYPE_ARRAY_ENC(1, 1, 16),					/* [2] */
-			/* struct s { */
-			BTF_STRUCT_ENC(NAME_NTH(2), 4, 84),				/* [3] */
-				BTF_MEMBER_ENC(NAME_NTH(3), 4, 0),	/* struct s *next;	*/
-				BTF_MEMBER_ENC(NAME_NTH(4), 5, 64),	/* const int *a;	*/
-				BTF_MEMBER_ENC(NAME_NTH(5), 2, 128),	/* int b[16];		*/
-				BTF_MEMBER_ENC(NAME_NTH(6), 1, 640),	/* int c;		*/
-			/* ptr -> [3] struct s */
-			BTF_PTR_ENC(3),							/* [4] */
-			/* ptr -> [6] const int */
-			BTF_PTR_ENC(6),							/* [5] */
-			/* const -> [1] int */
-			BTF_CONST_ENC(1),						/* [6] */
+	ssize_t nexpected_line = -1;
 
-			/* full copy of the above */
-			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),	/* [7] */
-			BTF_TYPE_ARRAY_ENC(7, 7, 16),					/* [8] */
-			BTF_STRUCT_ENC(NAME_NTH(2), 4, 84),				/* [9] */
-				BTF_MEMBER_ENC(NAME_NTH(3), 10, 0),
-				BTF_MEMBER_ENC(NAME_NTH(4), 11, 64),
-				BTF_MEMBER_ENC(NAME_NTH(5), 8, 128),
-				BTF_MEMBER_ENC(NAME_NTH(6), 7, 640),
-			BTF_PTR_ENC(9),							/* [10] */
-			BTF_PTR_ENC(12),						/* [11] */
-			BTF_CONST_ENC(7),						/* [12] */
-			BTF_END_RAW,
-		},
-		BTF_STR_SEC("\0int\0s\0next\0a\0b\0c\0"),
-	},
-	.expect = {
-		.raw_types = {
-			/* int */
-			BTF_TYPE_INT_ENC(NAME_NTH(4), BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-			/* int[16] */
-			BTF_TYPE_ARRAY_ENC(1, 1, 16),					/* [2] */
-			/* struct s { */
-			BTF_STRUCT_ENC(NAME_NTH(6), 4, 84),				/* [3] */
-				BTF_MEMBER_ENC(NAME_NTH(5), 4, 0),	/* struct s *next;	*/
-				BTF_MEMBER_ENC(NAME_NTH(1), 5, 64),	/* const int *a;	*/
-				BTF_MEMBER_ENC(NAME_NTH(2), 2, 128),	/* int b[16];		*/
-				BTF_MEMBER_ENC(NAME_NTH(3), 1, 640),	/* int c;		*/
-			/* ptr -> [3] struct s */
-			BTF_PTR_ENC(3),							/* [4] */
-			/* ptr -> [6] const int */
-			BTF_PTR_ENC(6),							/* [5] */
-			/* const -> [1] int */
-			BTF_CONST_ENC(1),						/* [6] */
-			BTF_END_RAW,
-		},
-		BTF_STR_SEC("\0a\0b\0c\0int\0next\0s"),
-	},
-	.opts = {
-		.dont_resolve_fwds = false,
-	},
-},
-{
-	.descr = "dedup: struct <-> fwd resolution w/ hash collision",
-	/*
-	 * // CU 1:
-	 * struct x;
-	 * struct s {
-	 *	struct x *x;
-	 * };
-	 * // CU 2:
-	 * struct x {};
-	 * struct s {
-	 *	struct x *x;
-	 * };
-	 */
-	.input = {
-		.raw_types = {
-			/* CU 1 */
-			BTF_FWD_ENC(NAME_TBD, 0 /* struct fwd */),	/* [1] fwd x      */
-			BTF_PTR_ENC(1),					/* [2] ptr -> [1] */
-			BTF_STRUCT_ENC(NAME_TBD, 1, 8),			/* [3] struct s   */
-				BTF_MEMBER_ENC(NAME_TBD, 2, 0),
-			/* CU 2 */
-			BTF_STRUCT_ENC(NAME_TBD, 0, 0),			/* [4] struct x   */
-			BTF_PTR_ENC(4),					/* [5] ptr -> [4] */
-			BTF_STRUCT_ENC(NAME_TBD, 1, 8),			/* [6] struct s   */
-				BTF_MEMBER_ENC(NAME_TBD, 5, 0),
-			BTF_END_RAW,
-		},
-		BTF_STR_SEC("\0x\0s\0x\0x\0s\0x\0"),
-	},
-	.expect = {
-		.raw_types = {
-			BTF_PTR_ENC(3),					/* [1] ptr -> [3] */
-			BTF_STRUCT_ENC(NAME_TBD, 1, 8),			/* [2] struct s   */
-				BTF_MEMBER_ENC(NAME_TBD, 1, 0),
-			BTF_STRUCT_ENC(NAME_NTH(2), 0, 0),		/* [3] struct x   */
-			BTF_END_RAW,
-		},
-		BTF_STR_SEC("\0s\0x"),
-	},
-	.opts = {
-		.dont_resolve_fwds = false,
-		.dedup_table_size = 1, /* force hash collisions */
-	},
-},
-{
-	.descr = "dedup: void equiv check",
-	/*
-	 * // CU 1:
-	 * struct s {
-	 *	struct {} *x;
-	 * };
-	 * // CU 2:
-	 * struct s {
-	 *	int *x;
-	 * };
-	 */
-	.input = {
-		.raw_types = {
-			/* CU 1 */
-			BTF_STRUCT_ENC(0, 0, 1),				/* [1] struct {}  */
-			BTF_PTR_ENC(1),						/* [2] ptr -> [1] */
-			BTF_STRUCT_ENC(NAME_NTH(1), 1, 8),			/* [3] struct s   */
-				BTF_MEMBER_ENC(NAME_NTH(2), 2, 0),
-			/* CU 2 */
-			BTF_PTR_ENC(0),						/* [4] ptr -> void */
-			BTF_STRUCT_ENC(NAME_NTH(1), 1, 8),			/* [5] struct s   */
-				BTF_MEMBER_ENC(NAME_NTH(2), 4, 0),
-			BTF_END_RAW,
-		},
-		BTF_STR_SEC("\0s\0x"),
-	},
-	.expect = {
-		.raw_types = {
-			/* CU 1 */
-			BTF_STRUCT_ENC(0, 0, 1),				/* [1] struct {}  */
-			BTF_PTR_ENC(1),						/* [2] ptr -> [1] */
-			BTF_STRUCT_ENC(NAME_NTH(1), 1, 8),			/* [3] struct s   */
-				BTF_MEMBER_ENC(NAME_NTH(2), 2, 0),
-			/* CU 2 */
-			BTF_PTR_ENC(0),						/* [4] ptr -> void */
-			BTF_STRUCT_ENC(NAME_NTH(1), 1, 8),			/* [5] struct s   */
-				BTF_MEMBER_ENC(NAME_NTH(2), 4, 0),
-			BTF_END_RAW,
-		},
-		BTF_STR_SEC("\0s\0x"),
-	},
-	.opts = {
-		.dont_resolve_fwds = false,
-		.dedup_table_size = 1, /* force hash collisions */
-	},
-},
-{
-	.descr = "dedup: all possible kinds (no duplicates)",
-	.input = {
-		.raw_types = {
-			BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 8),		/* [1] int */
-			BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), 4),	/* [2] enum */
-				BTF_ENUM_ENC(NAME_TBD, 0),
-				BTF_ENUM_ENC(NAME_TBD, 1),
-			BTF_FWD_ENC(NAME_TBD, 1 /* union kind_flag */),			/* [3] fwd */
-			BTF_TYPE_ARRAY_ENC(2, 1, 7),					/* [4] array */
-			BTF_STRUCT_ENC(NAME_TBD, 1, 4),					/* [5] struct */
-				BTF_MEMBER_ENC(NAME_TBD, 1, 0),
-			BTF_UNION_ENC(NAME_TBD, 1, 4),					/* [6] union */
-				BTF_MEMBER_ENC(NAME_TBD, 1, 0),
-			BTF_TYPEDEF_ENC(NAME_TBD, 1),					/* [7] typedef */
-			BTF_PTR_ENC(0),							/* [8] ptr */
-			BTF_CONST_ENC(8),						/* [9] const */
-			BTF_VOLATILE_ENC(8),						/* [10] volatile */
-			BTF_RESTRICT_ENC(8),						/* [11] restrict */
-			BTF_FUNC_PROTO_ENC(1, 2),					/* [12] func_proto */
-				BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
-				BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 8),
-			BTF_FUNC_ENC(NAME_TBD, 12),					/* [13] func */
-			BTF_END_RAW,
-		},
-		BTF_STR_SEC("\0A\0B\0C\0D\0E\0F\0G\0H\0I\0J\0K\0L\0M"),
-	},
-	.expect = {
-		.raw_types = {
-			BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 8),		/* [1] int */
-			BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 2), 4),	/* [2] enum */
-				BTF_ENUM_ENC(NAME_TBD, 0),
-				BTF_ENUM_ENC(NAME_TBD, 1),
-			BTF_FWD_ENC(NAME_TBD, 1 /* union kind_flag */),			/* [3] fwd */
-			BTF_TYPE_ARRAY_ENC(2, 1, 7),					/* [4] array */
-			BTF_STRUCT_ENC(NAME_TBD, 1, 4),					/* [5] struct */
-				BTF_MEMBER_ENC(NAME_TBD, 1, 0),
-			BTF_UNION_ENC(NAME_TBD, 1, 4),					/* [6] union */
-				BTF_MEMBER_ENC(NAME_TBD, 1, 0),
-			BTF_TYPEDEF_ENC(NAME_TBD, 1),					/* [7] typedef */
-			BTF_PTR_ENC(0),							/* [8] ptr */
-			BTF_CONST_ENC(8),						/* [9] const */
-			BTF_VOLATILE_ENC(8),						/* [10] volatile */
-			BTF_RESTRICT_ENC(8),						/* [11] restrict */
-			BTF_FUNC_PROTO_ENC(1, 2),					/* [12] func_proto */
-				BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 1),
-				BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 8),
-			BTF_FUNC_ENC(NAME_TBD, 12),					/* [13] func */
-			BTF_END_RAW,
-		},
-		BTF_STR_SEC("\0A\0B\0C\0D\0E\0F\0G\0H\0I\0J\0K\0L\0M"),
-	},
-	.opts = {
-		.dont_resolve_fwds = false,
-	},
-},
-{
-	.descr = "dedup: no int duplicates",
-	.input = {
-		.raw_types = {
-			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 8),
-			/* different name */
-			BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 32, 8),
-			/* different encoding */
-			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_CHAR, 0, 32, 8),
-			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_BOOL, 0, 32, 8),
-			/* different bit offset */
-			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 8, 32, 8),
-			/* different bit size */
-			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 27, 8),
-			/* different byte size */
-			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
-			BTF_END_RAW,
-		},
-		BTF_STR_SEC("\0int\0some other int"),
-	},
-	.expect = {
-		.raw_types = {
-			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 8),
-			/* different name */
-			BTF_TYPE_INT_ENC(NAME_NTH(2), BTF_INT_SIGNED, 0, 32, 8),
-			/* different encoding */
-			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_CHAR, 0, 32, 8),
-			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_BOOL, 0, 32, 8),
-			/* different bit offset */
-			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 8, 32, 8),
-			/* different bit size */
-			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 27, 8),
-			/* different byte size */
-			BTF_TYPE_INT_ENC(NAME_NTH(1), BTF_INT_SIGNED, 0, 32, 4),
-			BTF_END_RAW,
-		},
-		BTF_STR_SEC("\0int\0some other int"),
-	},
-	.opts = {
-		.dont_resolve_fwds = false,
-	},
-},
-{
-	.descr = "dedup: enum fwd resolution",
-	.input = {
-		.raw_types = {
-			/* [1] fwd enum 'e1' before full enum */
-			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 4),
-			/* [2] full enum 'e1' after fwd */
-			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
-				BTF_ENUM_ENC(NAME_NTH(2), 123),
-			/* [3] full enum 'e2' before fwd */
-			BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
-				BTF_ENUM_ENC(NAME_NTH(4), 456),
-			/* [4] fwd enum 'e2' after full enum */
-			BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 4),
-			/* [5] incompatible fwd enum with different size */
-			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 1),
-			/* [6] incompatible full enum with different value */
-			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
-				BTF_ENUM_ENC(NAME_NTH(2), 321),
-			BTF_END_RAW,
-		},
-		BTF_STR_SEC("\0e1\0e1_val\0e2\0e2_val"),
-	},
-	.expect = {
-		.raw_types = {
-			/* [1] full enum 'e1' */
-			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
-				BTF_ENUM_ENC(NAME_NTH(2), 123),
-			/* [2] full enum 'e2' */
-			BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
-				BTF_ENUM_ENC(NAME_NTH(4), 456),
-			/* [3] incompatible fwd enum with different size */
-			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 1),
-			/* [4] incompatible full enum with different value */
-			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4),
-				BTF_ENUM_ENC(NAME_NTH(2), 321),
-			BTF_END_RAW,
-		},
-		BTF_STR_SEC("\0e1\0e1_val\0e2\0e2_val"),
-	},
-	.opts = {
-		.dont_resolve_fwds = false,
-	},
-},
-{
-	.descr = "dedup: datasec and vars pass-through",
-	.input = {
-		.raw_types = {
-			/* int */
-			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-			/* static int t */
-			BTF_VAR_ENC(NAME_NTH(2), 1, 0),			/* [2] */
-			/* .bss section */				/* [3] */
-			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
-			BTF_VAR_SECINFO_ENC(2, 0, 4),
-			/* int, referenced from [5] */
-			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [4] */
-			/* another static int t */
-			BTF_VAR_ENC(NAME_NTH(2), 4, 0),			/* [5] */
-			/* another .bss section */			/* [6] */
-			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
-			BTF_VAR_SECINFO_ENC(5, 0, 4),
-			BTF_END_RAW,
-		},
-		BTF_STR_SEC("\0.bss\0t"),
-	},
-	.expect = {
-		.raw_types = {
-			/* int */
-			BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4),	/* [1] */
-			/* static int t */
-			BTF_VAR_ENC(NAME_NTH(2), 1, 0),			/* [2] */
-			/* .bss section */				/* [3] */
-			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
-			BTF_VAR_SECINFO_ENC(2, 0, 4),
-			/* another static int t */
-			BTF_VAR_ENC(NAME_NTH(2), 1, 0),			/* [4] */
-			/* another .bss section */			/* [5] */
-			BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
-			BTF_VAR_SECINFO_ENC(4, 0, 4),
-			BTF_END_RAW,
-		},
-		BTF_STR_SEC("\0.bss\0t"),
-	},
-	.opts = {
-		.dont_resolve_fwds = false,
-		.dedup_table_size = 1
-	},
-},
+	if (mapv_kind == PPRINT_MAPV_KIND_BASIC) {
+		struct pprint_mapv *v = mapv;
 
-};
+		nexpected_line = snprintf(expected_line, line_size,
+					  "%s%u: {%u,0,%d,0x%x,0x%x,0x%x,"
+					  "{%llu|[%u,%u,%u,%u,%u,%u,%u,%u]},%s,"
+					  "%u,0x%x,[[%d,%d],[%d,%d]]}\n",
+					  percpu_map ? "\tcpu" : "",
+					  percpu_map ? cpu : next_key,
+					  v->ui32, v->si32,
+					  v->unused_bits2a,
+					  v->bits28,
+					  v->unused_bits2b,
+					  (__u64)v->ui64,
+					  v->ui8a[0], v->ui8a[1],
+					  v->ui8a[2], v->ui8a[3],
+					  v->ui8a[4], v->ui8a[5],
+					  v->ui8a[6], v->ui8a[7],
+					  pprint_enum_str[v->aenum],
+					  v->ui32b,
+					  v->bits2c,
+					  v->si8_4[0][0], v->si8_4[0][1],
+					  v->si8_4[1][0], v->si8_4[1][1]);
+	}
 
-static int btf_type_size(const struct btf_type *t)
-{
-	int base_size = sizeof(struct btf_type);
-	__u16 vlen = BTF_INFO_VLEN(t->info);
-	__u16 kind = BTF_INFO_KIND(t->info);
+#ifdef __SIZEOF_INT128__
+	if (mapv_kind == PPRINT_MAPV_KIND_INT128) {
+		struct pprint_mapv_int128 *v = mapv;
 
-	switch (kind) {
-	case BTF_KIND_FWD:
-	case BTF_KIND_CONST:
-	case BTF_KIND_VOLATILE:
-	case BTF_KIND_RESTRICT:
-	case BTF_KIND_PTR:
-	case BTF_KIND_TYPEDEF:
-	case BTF_KIND_FUNC:
-		return base_size;
-	case BTF_KIND_INT:
-		return base_size + sizeof(__u32);
-	case BTF_KIND_ENUM:
-		return base_size + vlen * sizeof(struct btf_enum);
-	case BTF_KIND_ARRAY:
-		return base_size + sizeof(struct btf_array);
-	case BTF_KIND_STRUCT:
-	case BTF_KIND_UNION:
-		return base_size + vlen * sizeof(struct btf_member);
-	case BTF_KIND_FUNC_PROTO:
-		return base_size + vlen * sizeof(struct btf_param);
-	case BTF_KIND_VAR:
-		return base_size + sizeof(struct btf_var);
-	case BTF_KIND_DATASEC:
-		return base_size + vlen * sizeof(struct btf_var_secinfo);
-	default:
-		fprintf(stderr, "Unsupported BTF_KIND:%u\n", kind);
-		return -EINVAL;
+		nexpected_line = snprintf(expected_line, line_size,
+					  "%s%u: {0x%lx,0x%lx,0x%lx,"
+					  "0x%lx%016lx,0x%lx%016lx}\n",
+					  percpu_map ? "\tcpu" : "",
+					  percpu_map ? cpu : next_key,
+					  (uint64_t)v->si128a,
+					  (uint64_t)v->si128b,
+					  (uint64_t)v->bits3,
+					  (uint64_t)(v->bits80 >> 64),
+					  (uint64_t)v->bits80,
+					  (uint64_t)(v->ui128 >> 64),
+					  (uint64_t)v->ui128);
 	}
+#endif
+
+	return nexpected_line;
 }
 
-static void dump_btf_strings(const char *strs, __u32 len)
+static int check_line(const char *expected_line, int nexpected_line,
+		      int expected_line_len, const char *line)
 {
-	const char *cur = strs;
-	int i = 0;
+	if (CHECK(nexpected_line == expected_line_len,
+		  "expected_line is too long"))
+		return -1;
 
-	while (cur < strs + len) {
-		fprintf(stderr, "string #%d: '%s'\n", i, cur);
-		cur += strlen(cur) + 1;
-		i++;
+	if (strcmp(expected_line, line)) {
+		fprintf(stderr, "unexpected pprint output\n");
+		fprintf(stderr, "expected: %s", expected_line);
+		fprintf(stderr, "    read: %s", line);
+		return -1;
 	}
+
+	return 0;
 }
 
-static int do_test_dedup(unsigned int test_num)
+
+static int do_test_pprint(int test_num)
 {
-	const struct btf_dedup_test *test = &dedup_tests[test_num - 1];
-	__u32 test_nr_types, expect_nr_types, test_btf_size, expect_btf_size;
-	const struct btf_header *test_hdr, *expect_hdr;
-	struct btf *test_btf = NULL, *expect_btf = NULL;
-	const void *test_btf_data, *expect_btf_data;
-	const char *ret_test_next_str, *ret_expect_next_str;
-	const char *test_strs, *expect_strs;
-	const char *test_str_cur, *test_str_end;
-	const char *expect_str_cur, *expect_str_end;
+	const struct btf_raw_test *test = &pprint_test_template[test_num];
+	enum pprint_mapv_kind_t mapv_kind = test->mapv_kind;
+	struct bpf_create_map_attr create_attr = {};
+	bool ordered_map, lossless_map, percpu_map;
+	int err, ret, num_cpus, rounded_value_size;
+	unsigned int key, nr_read_elems;
+	int map_fd = -1, btf_fd = -1;
 	unsigned int raw_btf_size;
-	void *raw_btf;
-	int err = 0, i;
+	char expected_line[255];
+	FILE *pin_file = NULL;
+	char pin_path[255];
+	size_t line_len = 0;
+	char *line = NULL;
+	void *mapv = NULL;
+	uint8_t *raw_btf;
+	ssize_t nread;
 
-	fprintf(stderr, "BTF dedup test[%u] (%s):", test_num, test->descr);
+	fprintf(stderr, "%s(#%d)......", test->descr, test_num);
+	raw_btf = btf_raw_create(&hdr_tmpl, test->raw_types,
+				 test->str_sec, test->str_sec_size,
+				 &raw_btf_size, NULL);
 
-	raw_btf = btf_raw_create(&hdr_tmpl, test->input.raw_types,
-				 test->input.str_sec, test->input.str_sec_size,
-				 &raw_btf_size, &ret_test_next_str);
 	if (!raw_btf)
 		return -1;
-	test_btf = btf__new((__u8 *)raw_btf, raw_btf_size);
+
+	*btf_log_buf = '\0';
+	btf_fd = bpf_load_btf(raw_btf, raw_btf_size,
+			      btf_log_buf, BTF_LOG_BUF_SIZE,
+			      args.always_log);
 	free(raw_btf);
-	if (CHECK(IS_ERR(test_btf), "invalid test_btf errno:%ld",
-		  PTR_ERR(test_btf))) {
+
+	if (CHECK(btf_fd == -1, "errno:%d", errno)) {
 		err = -1;
 		goto done;
 	}
 
-	raw_btf = btf_raw_create(&hdr_tmpl, test->expect.raw_types,
-				 test->expect.str_sec,
-				 test->expect.str_sec_size,
-				 &raw_btf_size, &ret_expect_next_str);
-	if (!raw_btf)
-		return -1;
-	expect_btf = btf__new((__u8 *)raw_btf, raw_btf_size);
-	free(raw_btf);
-	if (CHECK(IS_ERR(expect_btf), "invalid expect_btf errno:%ld",
-		  PTR_ERR(expect_btf))) {
+	create_attr.name = test->map_name;
+	create_attr.map_type = test->map_type;
+	create_attr.key_size = test->key_size;
+	create_attr.value_size = test->value_size;
+	create_attr.max_entries = test->max_entries;
+	create_attr.btf_fd = btf_fd;
+	create_attr.btf_key_type_id = test->key_type_id;
+	create_attr.btf_value_type_id = test->value_type_id;
+
+	map_fd = bpf_create_map_xattr(&create_attr);
+	if (CHECK(map_fd == -1, "errno:%d", errno)) {
 		err = -1;
 		goto done;
 	}
 
-	err = btf__dedup(test_btf, NULL, &test->opts);
-	if (CHECK(err, "btf_dedup failed errno:%d", err)) {
+	ret = snprintf(pin_path, sizeof(pin_path), "%s/%s",
+		       "/sys/fs/bpf", test->map_name);
+
+	if (CHECK(ret == sizeof(pin_path), "pin_path %s/%s is too long",
+		  "/sys/fs/bpf", test->map_name)) {
 		err = -1;
 		goto done;
 	}
 
-	test_btf_data = btf__get_raw_data(test_btf, &test_btf_size);
-	expect_btf_data = btf__get_raw_data(expect_btf, &expect_btf_size);
-	if (CHECK(test_btf_size != expect_btf_size,
-		  "test_btf_size:%u != expect_btf_size:%u",
-		  test_btf_size, expect_btf_size)) {
-		err = -1;
+	err = bpf_obj_pin(map_fd, pin_path);
+	if (CHECK(err, "bpf_obj_pin(%s): errno:%d.", pin_path, errno))
 		goto done;
-	}
 
-	test_hdr = test_btf_data;
-	test_strs = test_btf_data + sizeof(*test_hdr) + test_hdr->str_off;
-	expect_hdr = expect_btf_data;
-	expect_strs = expect_btf_data + sizeof(*test_hdr) + expect_hdr->str_off;
-	if (CHECK(test_hdr->str_len != expect_hdr->str_len,
-		  "test_hdr->str_len:%u != expect_hdr->str_len:%u",
-		  test_hdr->str_len, expect_hdr->str_len)) {
-		fprintf(stderr, "\ntest strings:\n");
-		dump_btf_strings(test_strs, test_hdr->str_len);
-		fprintf(stderr, "\nexpected strings:\n");
-		dump_btf_strings(expect_strs, expect_hdr->str_len);
+	percpu_map = test->percpu_map;
+	num_cpus = percpu_map ? bpf_num_possible_cpus() : 1;
+	rounded_value_size = round_up(get_pprint_mapv_size(mapv_kind), 8);
+	mapv = calloc(num_cpus, rounded_value_size);
+	if (CHECK(!mapv, "mapv allocation failure")) {
 		err = -1;
 		goto done;
 	}
 
-	test_str_cur = test_strs;
-	test_str_end = test_strs + test_hdr->str_len;
-	expect_str_cur = expect_strs;
-	expect_str_end = expect_strs + expect_hdr->str_len;
-	while (test_str_cur < test_str_end && expect_str_cur < expect_str_end) {
-		size_t test_len, expect_len;
-
-		test_len = strlen(test_str_cur);
-		expect_len = strlen(expect_str_cur);
-		if (CHECK(test_len != expect_len,
-			  "test_len:%zu != expect_len:%zu "
-			  "(test_str:%s, expect_str:%s)",
-			  test_len, expect_len, test_str_cur, expect_str_cur)) {
-			err = -1;
-			goto done;
-		}
-		if (CHECK(strcmp(test_str_cur, expect_str_cur),
-			  "test_str:%s != expect_str:%s",
-			  test_str_cur, expect_str_cur)) {
-			err = -1;
-			goto done;
-		}
-		test_str_cur += test_len + 1;
-		expect_str_cur += expect_len + 1;
+	for (key = 0; key < test->max_entries; key++) {
+		set_pprint_mapv(mapv_kind, mapv, key, num_cpus, rounded_value_size);
+		bpf_map_update_elem(map_fd, &key, mapv, 0);
 	}
-	if (CHECK(test_str_cur != test_str_end,
-		  "test_str_cur:%p != test_str_end:%p",
-		  test_str_cur, test_str_end)) {
+
+	pin_file = fopen(pin_path, "r");
+	if (CHECK(!pin_file, "fopen(%s): errno:%d", pin_path, errno)) {
 		err = -1;
 		goto done;
 	}
 
-	test_nr_types = btf__get_nr_types(test_btf);
-	expect_nr_types = btf__get_nr_types(expect_btf);
-	if (CHECK(test_nr_types != expect_nr_types,
-		  "test_nr_types:%u != expect_nr_types:%u",
-		  test_nr_types, expect_nr_types)) {
+	/* Skip lines start with '#' */
+	while ((nread = getline(&line, &line_len, pin_file)) > 0 &&
+	       *line == '#')
+		;
+
+	if (CHECK(nread <= 0, "Unexpected EOF")) {
 		err = -1;
 		goto done;
 	}
 
-	for (i = 1; i <= test_nr_types; i++) {
-		const struct btf_type *test_type, *expect_type;
-		int test_size, expect_size;
+	nr_read_elems = 0;
+	ordered_map = test->ordered_map;
+	lossless_map = test->lossless_map;
+	do {
+		ssize_t nexpected_line;
+		unsigned int next_key;
+		void *cmapv;
+		int cpu;
+
+		next_key = ordered_map ? nr_read_elems : atoi(line);
+		set_pprint_mapv(mapv_kind, mapv, next_key, num_cpus, rounded_value_size);
+		cmapv = mapv;
+
+		for (cpu = 0; cpu < num_cpus; cpu++) {
+			if (percpu_map) {
+				/* for percpu map, the format looks like:
+				 * <key>: {
+				 *	cpu0: <value_on_cpu0>
+				 *	cpu1: <value_on_cpu1>
+				 *	...
+				 *	cpun: <value_on_cpun>
+				 * }
+				 *
+				 * let us verify the line containing the key here.
+				 */
+				if (cpu == 0) {
+					nexpected_line = snprintf(expected_line,
+								  sizeof(expected_line),
+								  "%u: {\n",
+								  next_key);
+
+					err = check_line(expected_line, nexpected_line,
+							 sizeof(expected_line), line);
+					if (err == -1)
+						goto done;
+				}
+
+				/* read value@cpu */
+				nread = getline(&line, &line_len, pin_file);
+				if (nread < 0)
+					break;
+			}
 
-		test_type = btf__type_by_id(test_btf, i);
-		expect_type = btf__type_by_id(expect_btf, i);
-		test_size = btf_type_size(test_type);
-		expect_size = btf_type_size(expect_type);
+			nexpected_line = get_pprint_expected_line(mapv_kind, expected_line,
+								  sizeof(expected_line),
+								  percpu_map, next_key,
+								  cpu, cmapv);
+			err = check_line(expected_line, nexpected_line,
+					 sizeof(expected_line), line);
+			if (err == -1)
+				goto done;
 
-		if (CHECK(test_size != expect_size,
-			  "type #%d: test_size:%d != expect_size:%u",
-			  i, test_size, expect_size)) {
-			err = -1;
-			goto done;
+			cmapv = cmapv + rounded_value_size;
 		}
-		if (CHECK(memcmp((void *)test_type,
-				 (void *)expect_type,
-				 test_size),
-			  "type #%d: contents differ", i)) {
-			err = -1;
-			goto done;
+
+		if (percpu_map) {
+			/* skip the last bracket for the percpu map */
+			nread = getline(&line, &line_len, pin_file);
+			if (nread < 0)
+				break;
 		}
+
+		nread = getline(&line, &line_len, pin_file);
+	} while (++nr_read_elems < test->max_entries && nread > 0);
+
+	if (lossless_map &&
+	    CHECK(nr_read_elems < test->max_entries,
+		  "Unexpected EOF. nr_read_elems:%u test->max_entries:%u",
+		  nr_read_elems, test->max_entries)) {
+		err = -1;
+		goto done;
+	}
+
+	if (CHECK(nread > 0, "Unexpected extra pprint output: %s", line)) {
+		err = -1;
+		goto done;
 	}
 
+	err = 0;
+
 done:
+	if (mapv)
+		free(mapv);
 	if (!err)
 		fprintf(stderr, "OK");
-	if (!IS_ERR(test_btf))
-		btf__free(test_btf);
-	if (!IS_ERR(expect_btf))
-		btf__free(expect_btf);
+	if (*btf_log_buf && (err || args.always_log))
+		fprintf(stderr, "\n%s", btf_log_buf);
+	if (btf_fd != -1)
+		close(btf_fd);
+	if (map_fd != -1)
+		close(map_fd);
+	if (pin_file)
+		fclose(pin_file);
+	unlink(pin_path);
+	free(line);
 
 	return err;
 }
 
-static int test_dedup(void)
+static int test_pprint(void)
 {
 	unsigned int i;
 	int err = 0;
 
-	if (args.dedup_test_num)
-		return count_result(do_test_dedup(args.dedup_test_num));
+	/* test various maps with the first test template */
+	for (i = 0; i < ARRAY_SIZE(pprint_tests_meta); i++) {
+		pprint_test_template[0].descr = pprint_tests_meta[i].descr;
+		pprint_test_template[0].map_type = pprint_tests_meta[i].map_type;
+		pprint_test_template[0].map_name = pprint_tests_meta[i].map_name;
+		pprint_test_template[0].ordered_map = pprint_tests_meta[i].ordered_map;
+		pprint_test_template[0].lossless_map = pprint_tests_meta[i].lossless_map;
+		pprint_test_template[0].percpu_map = pprint_tests_meta[i].percpu_map;
+
+		err |= count_result(do_test_pprint(0));
+	}
 
-	for (i = 1; i <= ARRAY_SIZE(dedup_tests); i++)
-		err |= count_result(do_test_dedup(i));
+	/* test rest test templates with the first map */
+	for (i = 1; i < ARRAY_SIZE(pprint_test_template); i++) {
+		pprint_test_template[i].descr = pprint_tests_meta[0].descr;
+		pprint_test_template[i].map_type = pprint_tests_meta[0].map_type;
+		pprint_test_template[i].map_name = pprint_tests_meta[0].map_name;
+		pprint_test_template[i].ordered_map = pprint_tests_meta[0].ordered_map;
+		pprint_test_template[i].lossless_map = pprint_tests_meta[0].lossless_map;
+		pprint_test_template[i].percpu_map = pprint_tests_meta[0].percpu_map;
+		err |= count_result(do_test_pprint(i));
+	}
 
 	return err;
 }
 
 static void usage(const char *cmd)
 {
-	fprintf(stderr, "Usage: %s [-l] [[-r btf_raw_test_num (1 - %zu)] |\n"
-			"\t[-g btf_get_info_test_num (1 - %zu)] |\n"
-			"\t[-f btf_file_test_num (1 - %zu)] |\n"
-			"\t[-k btf_prog_info_raw_test_num (1 - %zu)] |\n"
-			"\t[-p (pretty print test)] |\n"
-			"\t[-d btf_dedup_test_num (1 - %zu)]]\n",
-		cmd, ARRAY_SIZE(raw_tests), ARRAY_SIZE(get_info_tests),
-		ARRAY_SIZE(file_tests), ARRAY_SIZE(info_raw_tests),
-		ARRAY_SIZE(dedup_tests));
+	fprintf(stderr, "Usage: %s [-l]\n", cmd);
 }
 
 static int parse_args(int argc, char **argv)
@@ -6941,29 +933,6 @@  static int parse_args(int argc, char **argv)
 		case 'l':
 			args.always_log = true;
 			break;
-		case 'f':
-			args.file_test_num = atoi(optarg);
-			args.file_test = true;
-			break;
-		case 'r':
-			args.raw_test_num = atoi(optarg);
-			args.raw_test = true;
-			break;
-		case 'g':
-			args.get_info_test_num = atoi(optarg);
-			args.get_info_test = true;
-			break;
-		case 'p':
-			args.pprint_test = true;
-			break;
-		case 'k':
-			args.info_raw_test_num = atoi(optarg);
-			args.info_raw_test = true;
-			break;
-		case 'd':
-			args.dedup_test_num = atoi(optarg);
-			args.dedup_test = true;
-			break;
 		case 'h':
 			usage(argv[0]);
 			exit(0);
@@ -6973,46 +942,6 @@  static int parse_args(int argc, char **argv)
 		}
 	}
 
-	if (args.raw_test_num &&
-	    (args.raw_test_num < 1 ||
-	     args.raw_test_num > ARRAY_SIZE(raw_tests))) {
-		fprintf(stderr, "BTF raw test number must be [1 - %zu]\n",
-			ARRAY_SIZE(raw_tests));
-		return -1;
-	}
-
-	if (args.file_test_num &&
-	    (args.file_test_num < 1 ||
-	     args.file_test_num > ARRAY_SIZE(file_tests))) {
-		fprintf(stderr, "BTF file test number must be [1 - %zu]\n",
-			ARRAY_SIZE(file_tests));
-		return -1;
-	}
-
-	if (args.get_info_test_num &&
-	    (args.get_info_test_num < 1 ||
-	     args.get_info_test_num > ARRAY_SIZE(get_info_tests))) {
-		fprintf(stderr, "BTF get info test number must be [1 - %zu]\n",
-			ARRAY_SIZE(get_info_tests));
-		return -1;
-	}
-
-	if (args.info_raw_test_num &&
-	    (args.info_raw_test_num < 1 ||
-	     args.info_raw_test_num > ARRAY_SIZE(info_raw_tests))) {
-		fprintf(stderr, "BTF prog info raw test number must be [1 - %zu]\n",
-			ARRAY_SIZE(info_raw_tests));
-		return -1;
-	}
-
-	if (args.dedup_test_num &&
-	    (args.dedup_test_num < 1 ||
-	     args.dedup_test_num > ARRAY_SIZE(dedup_tests))) {
-		fprintf(stderr, "BTF dedup test number must be [1 - %zu]\n",
-			ARRAY_SIZE(dedup_tests));
-		return -1;
-	}
-
 	return 0;
 }
 
@@ -7033,35 +962,8 @@  int main(int argc, char **argv)
 	if (args.always_log)
 		libbpf_set_print(__base_pr);
 
-	if (args.raw_test)
-		err |= test_raw();
-
-	if (args.get_info_test)
-		err |= test_get_info();
+	test_pprint();
 
-	if (args.file_test)
-		err |= test_file();
-
-	if (args.pprint_test)
-		err |= test_pprint();
-
-	if (args.info_raw_test)
-		err |= test_info_raw();
-
-	if (args.dedup_test)
-		err |= test_dedup();
-
-	if (args.raw_test || args.get_info_test || args.file_test ||
-	    args.pprint_test || args.info_raw_test || args.dedup_test)
-		goto done;
-
-	err |= test_raw();
-	err |= test_get_info();
-	err |= test_file();
-	err |= test_info_raw();
-	err |= test_dedup();
-
-done:
 	print_summary();
 	return err;
 }