When creating distilled BTF, BTF_KIND_FUNC, _LOC_PARAM and _LOC_PROTO
should be added to split BTF.  This means potentially some duplication
of location information, but only for out-of-tree modules that use
distilled base/split BTF.

Signed-off-by: Alan Maguire <[email protected]>
---
 .../selftests/bpf/prog_tests/btf_distill.c    | 76 +++++++++++++++++++
 1 file changed, 76 insertions(+)

diff --git a/tools/testing/selftests/bpf/prog_tests/btf_distill.c 
b/tools/testing/selftests/bpf/prog_tests/btf_distill.c
index fb67ae195a73..f433b29ffce9 100644
--- a/tools/testing/selftests/bpf/prog_tests/btf_distill.c
+++ b/tools/testing/selftests/bpf/prog_tests/btf_distill.c
@@ -671,6 +671,80 @@ static void test_distilled_base_embedded_err(void)
        btf__free(btf1);
 }
 
+/* LOC_PARAM, LOC_PROTO should be added to split BTF. */
+static void test_distilled_loc(void)
+{
+       struct btf *btf1 = NULL, *btf2 = NULL, *btf3 = NULL, *btf4 = NULL;
+
+       btf1 = btf__new_empty();
+       if (!ASSERT_OK_PTR(btf1, "empty_main_btf"))
+               return;
+
+       btf__add_int(btf1, "int", 4, BTF_INT_SIGNED);   /* [1] int */
+       btf__add_func_proto(btf1, 1);                   /* [2] int (*)(int); */
+       btf__add_func_param(btf1, "p1", 1);
+       btf__add_func(btf1, "foo", BTF_FUNC_STATIC, 2); /* [3] int foo(int); */
+       btf__add_loc_param(btf1, 4, BTF_LOC_PARAM_SIGNED | BTF_LOC_PARAM_CONST);
+       btf__add_loc_param_value(btf1, -1);             /* [4] loc value */
+
+       VALIDATE_RAW_BTF(
+               btf1,
+               "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
+               "[2] FUNC_PROTO '(anon)' ret_type_id=1 vlen=1\n"
+               "\t'p1' type_id=1",
+               "[3] FUNC 'foo' type_id=2 linkage=static",
+               "[4] LOC_PARAM '(anon)' size=4 flags=0x3 vlen=1\n"
+               "\tvalue=-1");
+
+       btf2 = btf__new_empty_split(btf1);
+       if (!ASSERT_OK_PTR(btf2, "empty_split_btf"))
+               goto cleanup;
+
+       btf__add_loc_proto(btf2);                       /* [5] loc proto */
+       btf__add_loc_proto_param(btf2, 4);              /*  param value */
+
+       btf__add_locsec(btf2, ".locs");                 /* [6] locsec */
+       btf__add_locsec_loc(btf2, 3, 5, 256);           /* "foo" offset 256 */
+       VALIDATE_RAW_BTF(
+               btf2,
+               "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
+               "[2] FUNC_PROTO '(anon)' ret_type_id=1 vlen=1\n"
+               "\t'p1' type_id=1",
+               "[3] FUNC 'foo' type_id=2 linkage=static",
+               "[4] LOC_PARAM '(anon)' size=4 flags=0x3 vlen=1\n"
+               "\tvalue=-1",
+               "[5] LOC_PROTO '(anon)' vlen=1\n"
+               "\ttype_id=4",
+               "[6] LOCSEC '.locs' vlen=1\n"
+               "\tfunc_type_id=3 loc_proto_type_id=5 offset=256");
+
+       if (!ASSERT_EQ(0, btf__distill_base(btf2, &btf3, &btf4),
+                      "distilled_base") ||
+           !ASSERT_OK_PTR(btf3, "distilled_base") ||
+           !ASSERT_OK_PTR(btf4, "distilled_split") ||
+           !ASSERT_EQ(2, btf__type_cnt(btf3), "distilled_base_type_cnt"))
+               goto cleanup;
+
+       VALIDATE_RAW_BTF(
+               btf4,
+               "[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
+               /* remainder is split BTF */
+               "[2] LOC_PROTO '(anon)' vlen=1\n"
+               "\ttype_id=6",
+               "[3] LOCSEC '.locs' vlen=1\n"
+               "\tfunc_type_id=5 loc_proto_type_id=2 offset=256",
+               "[4] FUNC_PROTO '(anon)' ret_type_id=1 vlen=1\n"
+               "\t'p1' type_id=1",
+               "[5] FUNC 'foo' type_id=4 linkage=static",
+               "[6] LOC_PARAM '(anon)' size=4 flags=0x3 vlen=1\n"
+               "\tvalue=-1");
+cleanup:
+       btf__free(btf4);
+       btf__free(btf3);
+       btf__free(btf2);
+       btf__free(btf1);
+}
+
 void test_btf_distill(void)
 {
        if (test__start_subtest("distilled_base"))
@@ -689,4 +763,6 @@ void test_btf_distill(void)
                test_distilled_base_vmlinux();
        if (test__start_subtest("distilled_endianness"))
                test_distilled_endianness();
+       if (test__start_subtest("distilled_loc"))
+               test_distilled_loc();
 }
-- 
2.43.5


Reply via email to