Skip to content

Commit eeda781

Browse files
committed
add verify userspace program
1 parent 1696b2b commit eeda781

37 files changed

+2686
-5
lines changed

src/38-btf-uprobe/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
uprobe
33
merge-btf
44
*.btf
5+
uprobe_failed

src/38-btf-uprobe/Makefile

+8-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,14 @@ $(call allow-override,CC,$(CROSS_COMPILE)cc)
6666
$(call allow-override,LD,$(CROSS_COMPILE)ld)
6767

6868
.PHONY: all
69-
all: $(APPS) merge-btf
69+
all: $(APPS) merge-btf all-btf
70+
71+
.PHONY: all-btf
72+
all-btf: merge-btf
73+
make -C examples
74+
./merge-btf /sys/kernel/btf/vmlinux examples/base-new.btf target-base-new.btf
75+
./merge-btf /sys/kernel/btf/vmlinux examples/base.btf target-base.btf
76+
./merge-btf /sys/kernel/btf/vmlinux examples/base-complete.btf target-base-complete.btf
7077

7178
.PHONY: clean
7279
clean:

src/38-btf-uprobe/README.zh.md

+22-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ int main(int argc, char **argv) {
112112
我们可以使用pahole和clang来生成每个版本的btf。制作示例并生成btf:
113113
114114
```sh
115-
make -C example # it's like: pahole --btf_encode_detached base.btf btf-base.o
115+
make -C examples # it's like: pahole --btf_encode_detached base.btf btf-base.o
116116
```
117117

118118
然后我们执行eBPF程序和用户空间程序。 对于 `btf-base`
@@ -197,6 +197,27 @@ char LICENSE[] SEC("license") = "Dual BSD/GPL";
197197
198198
`struct data`的记录在eBPF程序中被保留下来。然后,我们可以使用 `btf-base.btf`来编译eBPF程序。
199199
200+
这时,如果未提供用户态的 BTF 信息,会导致验证失败:
201+
202+
```console
203+
# ./uprobe examples/btf-base
204+
.....
205+
; int BPF_UPROBE(add_test, struct data *d) @ uprobe.bpf.c:23
206+
0: (79) r6 = *(u64 *)(r1 +112) ; R1=ctx() R6_w=scalar()
207+
1: (b7) r7 = 0 ; R7_w=0
208+
; int a = 0, c = 0; @ uprobe.bpf.c:25
209+
2: (63) *(u32 *)(r10 -4) = r7 ; R7_w=0 R10=fp0 fp-8=0000????
210+
3: (63) *(u32 *)(r10 -8) = r7 ; R7_w=0 R10=fp0 fp-8=00000
211+
4: <invalid CO-RE relocation>
212+
failed to resolve CO-RE relocation <byte_off> [17] struct data.a (0:0 @ offset 0)
213+
processed 5 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0
214+
-- END PROG LOAD LOG --
215+
libbpf: prog 'add_test': failed to load: -22
216+
libbpf: failed to load object 'uprobe_bpf'
217+
libbpf: failed to load BPF skeleton 'uprobe_bpf': -22
218+
Failed to load and verify BPF skeleton
219+
```
220+
200221
将用户btf与内核btf合并,这样我们就有了一个完整的内核和用户空间的btf:
201222

202223
```sh

src/38-btf-uprobe/examples/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
*.btf
33
btf-base
44
btf-base-new
5+
btf-base-complete

src/38-btf-uprobe/examples/Makefile

+11-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ BPF_SRCS = $(wildcard *.bpf.c)
77
# BPF object files
88
BPF_OBJS = $(BPF_SRCS:.c=.o)
99

10-
all: $(BPF_OBJS) base.btf btf-base btf-base-new base-new.btf
10+
all: $(BPF_OBJS) base.btf btf-base btf-base-new btf-base-complete base-new.btf base-complete.btf
1111

1212
%.bpf.o: %.bpf.c
1313
$(BPF_CC) $(BPF_CFLAGS) $< -o $@
@@ -18,9 +18,15 @@ btf-base.o: btf-base.c
1818
btf-base-new.o: btf-base-new.c
1919
clang -g -c btf-base-new.c -o btf-base-new.o
2020

21+
btf-base-complete.o: btf-base-complete.c
22+
clang -g -c btf-base-complete.c -o btf-base-complete.o
23+
2124
base.btf: btf-base.o
2225
pahole --btf_encode_detached base.btf btf-base.o
2326

27+
base-complete.btf: btf-base-complete.o
28+
pahole --btf_encode_detached base-complete.btf btf-base-complete.o
29+
2430
base-new.btf: btf-base-new.o
2531
pahole --btf_encode_detached base-new.btf btf-base-new.o
2632

@@ -29,7 +35,9 @@ btf-base: btf-base.o
2935

3036
btf-base-new: btf-base-new.o
3137
clang -g btf-base-new.o -o btf-base-new
32-
38+
39+
btf-base-complete: btf-base-complete.o
40+
clang -g btf-base-complete.o -o btf-base-complete
3341

3442
clean:
35-
rm -f *.o *.btf btf-base btf-base-new
43+
rm -f *.o *.btf btf-base btf-base-new btf-base-complete
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
4+
struct deep_memory_block {
5+
int a;
6+
char b[10];
7+
};
8+
9+
struct inner_memory_block {
10+
int a;
11+
char b[10];
12+
struct deep_memory_block *deep;
13+
};
14+
15+
struct data {
16+
int a;
17+
int b;
18+
int c;
19+
int d;
20+
// represent a pointer to a memory block
21+
struct inner_memory_block *inner;
22+
};
23+
24+
// hook function to be called by eBPF program
25+
int add_test(struct data *d) {
26+
return d->a + d->c;
27+
}
28+
29+
struct data* my_alloc_data() {
30+
printf("my_alloc_data\n");
31+
struct data *d = (struct data*)calloc(1, sizeof(struct data));
32+
d->inner = (struct inner_memory_block*)calloc(1, sizeof(struct inner_memory_block));
33+
d->inner->deep = (struct deep_memory_block*)calloc(1, sizeof(struct deep_memory_block));
34+
return d;
35+
}
36+
37+
void my_free_data(struct data *d) {
38+
printf("my_free_data\n");
39+
free(d->inner->deep);
40+
free(d->inner);
41+
free(d);
42+
}
43+
44+
int main(int argc, char **argv) {
45+
struct data *d = my_alloc_data();
46+
d->a = 1;
47+
d->c = 3;
48+
d->b = 5;
49+
d->d = 7;
50+
printf("add_test(&d) = %d\n", add_test(d));
51+
my_free_data(d);
52+
return 0;
53+
}
54+

0 commit comments

Comments
 (0)