Skip to content

Commit 4263cc0

Browse files
olsajiriqmonnet
authored andcommitted
bpftool: Display cookie for kprobe multi link
Displaying cookies for kprobe multi link, in plain mode: # bpftool link ... 1397: kprobe_multi prog 47532 kretprobe.multi func_cnt 3 addr cookie func [module] ffffffff82b370c0 3 bpf_fentry_test1 ffffffff82b39780 1 bpf_fentry_test2 ffffffff82b397a0 2 bpf_fentry_test3 And in json mode: # bpftool link -j | jq ... { "id": 1397, "type": "kprobe_multi", "prog_id": 47532, "retprobe": true, "func_cnt": 3, "missed": 0, "funcs": [ { "addr": 18446744071607382208, "func": "bpf_fentry_test1", "module": null, "cookie": 3 }, { "addr": 18446744071607392128, "func": "bpf_fentry_test2", "module": null, "cookie": 1 }, { "addr": 18446744071607392160, "func": "bpf_fentry_test3", "module": null, "cookie": 2 } ] } Cookie is attached to specific address, and because we sort addresses before printing, we need to sort cookies the same way, hence adding the struct addr_cookie to keep and sort them together. Also adding missing dd.sym_count check to show_kprobe_multi_json. Signed-off-by: Jiri Olsa <[email protected]> Acked-by: Song Liu <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 25df69b commit 4263cc0

File tree

1 file changed

+63
-15
lines changed

1 file changed

+63
-15
lines changed

src/link.c

Lines changed: 63 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -249,33 +249,65 @@ static int get_prog_info(int prog_id, struct bpf_prog_info *info)
249249
return err;
250250
}
251251

252-
static int cmp_u64(const void *A, const void *B)
252+
struct addr_cookie {
253+
__u64 addr;
254+
__u64 cookie;
255+
};
256+
257+
static int cmp_addr_cookie(const void *A, const void *B)
258+
{
259+
const struct addr_cookie *a = A, *b = B;
260+
261+
if (a->addr == b->addr)
262+
return 0;
263+
return a->addr < b->addr ? -1 : 1;
264+
}
265+
266+
static struct addr_cookie *
267+
get_addr_cookie_array(__u64 *addrs, __u64 *cookies, __u32 count)
253268
{
254-
const __u64 *a = A, *b = B;
269+
struct addr_cookie *data;
270+
__u32 i;
255271

256-
return *a - *b;
272+
data = calloc(count, sizeof(data[0]));
273+
if (!data) {
274+
p_err("mem alloc failed");
275+
return NULL;
276+
}
277+
for (i = 0; i < count; i++) {
278+
data[i].addr = addrs[i];
279+
data[i].cookie = cookies[i];
280+
}
281+
qsort(data, count, sizeof(data[0]), cmp_addr_cookie);
282+
return data;
257283
}
258284

259285
static void
260286
show_kprobe_multi_json(struct bpf_link_info *info, json_writer_t *wtr)
261287
{
288+
struct addr_cookie *data;
262289
__u32 i, j = 0;
263-
__u64 *addrs;
264290

265291
jsonw_bool_field(json_wtr, "retprobe",
266292
info->kprobe_multi.flags & BPF_F_KPROBE_MULTI_RETURN);
267293
jsonw_uint_field(json_wtr, "func_cnt", info->kprobe_multi.count);
268294
jsonw_uint_field(json_wtr, "missed", info->kprobe_multi.missed);
269295
jsonw_name(json_wtr, "funcs");
270296
jsonw_start_array(json_wtr);
271-
addrs = u64_to_ptr(info->kprobe_multi.addrs);
272-
qsort(addrs, info->kprobe_multi.count, sizeof(addrs[0]), cmp_u64);
297+
data = get_addr_cookie_array(u64_to_ptr(info->kprobe_multi.addrs),
298+
u64_to_ptr(info->kprobe_multi.cookies),
299+
info->kprobe_multi.count);
300+
if (!data)
301+
return;
273302

274303
/* Load it once for all. */
275304
if (!dd.sym_count)
276305
kernel_syms_load(&dd);
306+
if (!dd.sym_count)
307+
goto error;
308+
277309
for (i = 0; i < dd.sym_count; i++) {
278-
if (dd.sym_mapping[i].address != addrs[j])
310+
if (dd.sym_mapping[i].address != data[j].addr)
279311
continue;
280312
jsonw_start_object(json_wtr);
281313
jsonw_uint_field(json_wtr, "addr", dd.sym_mapping[i].address);
@@ -287,11 +319,14 @@ show_kprobe_multi_json(struct bpf_link_info *info, json_writer_t *wtr)
287319
} else {
288320
jsonw_string_field(json_wtr, "module", dd.sym_mapping[i].module);
289321
}
322+
jsonw_uint_field(json_wtr, "cookie", data[j].cookie);
290323
jsonw_end_object(json_wtr);
291324
if (j++ == info->kprobe_multi.count)
292325
break;
293326
}
294327
jsonw_end_array(json_wtr);
328+
error:
329+
free(data);
295330
}
296331

297332
static __u64 *u64_to_arr(__u64 val)
@@ -675,8 +710,8 @@ void netfilter_dump_plain(const struct bpf_link_info *info)
675710

676711
static void show_kprobe_multi_plain(struct bpf_link_info *info)
677712
{
713+
struct addr_cookie *data;
678714
__u32 i, j = 0;
679-
__u64 *addrs;
680715

681716
if (!info->kprobe_multi.count)
682717
return;
@@ -688,21 +723,24 @@ static void show_kprobe_multi_plain(struct bpf_link_info *info)
688723
printf("func_cnt %u ", info->kprobe_multi.count);
689724
if (info->kprobe_multi.missed)
690725
printf("missed %llu ", info->kprobe_multi.missed);
691-
addrs = (__u64 *)u64_to_ptr(info->kprobe_multi.addrs);
692-
qsort(addrs, info->kprobe_multi.count, sizeof(__u64), cmp_u64);
726+
data = get_addr_cookie_array(u64_to_ptr(info->kprobe_multi.addrs),
727+
u64_to_ptr(info->kprobe_multi.cookies),
728+
info->kprobe_multi.count);
729+
if (!data)
730+
return;
693731

694732
/* Load it once for all. */
695733
if (!dd.sym_count)
696734
kernel_syms_load(&dd);
697735
if (!dd.sym_count)
698-
return;
736+
goto error;
699737

700-
printf("\n\t%-16s %s", "addr", "func [module]");
738+
printf("\n\t%-16s %-16s %s", "addr", "cookie", "func [module]");
701739
for (i = 0; i < dd.sym_count; i++) {
702-
if (dd.sym_mapping[i].address != addrs[j])
740+
if (dd.sym_mapping[i].address != data[j].addr)
703741
continue;
704-
printf("\n\t%016lx %s",
705-
dd.sym_mapping[i].address, dd.sym_mapping[i].name);
742+
printf("\n\t%016lx %-16llx %s",
743+
dd.sym_mapping[i].address, data[j].cookie, dd.sym_mapping[i].name);
706744
if (dd.sym_mapping[i].module[0] != '\0')
707745
printf(" [%s] ", dd.sym_mapping[i].module);
708746
else
@@ -711,6 +749,8 @@ static void show_kprobe_multi_plain(struct bpf_link_info *info)
711749
if (j++ == info->kprobe_multi.count)
712750
break;
713751
}
752+
error:
753+
free(data);
714754
}
715755

716756
static void show_uprobe_multi_plain(struct bpf_link_info *info)
@@ -966,6 +1006,14 @@ static int do_show_link(int fd)
9661006
return -ENOMEM;
9671007
}
9681008
info.kprobe_multi.addrs = ptr_to_u64(addrs);
1009+
cookies = calloc(count, sizeof(__u64));
1010+
if (!cookies) {
1011+
p_err("mem alloc failed");
1012+
free(addrs);
1013+
close(fd);
1014+
return -ENOMEM;
1015+
}
1016+
info.kprobe_multi.cookies = ptr_to_u64(cookies);
9691017
goto again;
9701018
}
9711019
}

0 commit comments

Comments
 (0)