Skip to content

Commit 53f8dd4

Browse files
anakryikoAlexei Starovoitov
authored and
Alexei Starovoitov
committed
libbpf: Fix global variable relocation
Similarly to a0d7da2 ("libbpf: Fix call relocation offset calculation bug"), relocations against global variables need to take into account referenced symbol's st_value, which holds offset into a corresponding data section (and, subsequently, offset into internal backing map). For static variables this offset is always zero and data offset is completely described by respective instruction's imm field. Convert a bunch of selftests to global variables. Previously they were relying on `static volatile` trick to ensure Clang doesn't inline static variables, which with global variables is not necessary anymore. Fixes: 393cdfb ("libbpf: Support initialized global variables") Signed-off-by: Andrii Nakryiko <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]> Acked-by: Yonghong Song <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent b568405 commit 53f8dd4

File tree

5 files changed

+36
-41
lines changed

5 files changed

+36
-41
lines changed

tools/lib/bpf/libbpf.c

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -171,10 +171,8 @@ struct bpf_program {
171171
RELO_DATA,
172172
} type;
173173
int insn_idx;
174-
union {
175-
int map_idx;
176-
int text_off;
177-
};
174+
int map_idx;
175+
int sym_off;
178176
} *reloc_desc;
179177
int nr_reloc;
180178
int log_level;
@@ -1824,7 +1822,7 @@ static int bpf_program__record_reloc(struct bpf_program *prog,
18241822
}
18251823
reloc_desc->type = RELO_CALL;
18261824
reloc_desc->insn_idx = insn_idx;
1827-
reloc_desc->text_off = sym->st_value / 8;
1825+
reloc_desc->sym_off = sym->st_value;
18281826
obj->has_pseudo_calls = true;
18291827
return 0;
18301828
}
@@ -1868,6 +1866,7 @@ static int bpf_program__record_reloc(struct bpf_program *prog,
18681866
reloc_desc->type = RELO_LD64;
18691867
reloc_desc->insn_idx = insn_idx;
18701868
reloc_desc->map_idx = map_idx;
1869+
reloc_desc->sym_off = 0; /* sym->st_value determines map_idx */
18711870
return 0;
18721871
}
18731872

@@ -1899,6 +1898,7 @@ static int bpf_program__record_reloc(struct bpf_program *prog,
18991898
reloc_desc->type = RELO_DATA;
19001899
reloc_desc->insn_idx = insn_idx;
19011900
reloc_desc->map_idx = map_idx;
1901+
reloc_desc->sym_off = sym->st_value;
19021902
return 0;
19031903
}
19041904

@@ -3563,8 +3563,8 @@ bpf_program__reloc_text(struct bpf_program *prog, struct bpf_object *obj,
35633563
return -LIBBPF_ERRNO__RELOC;
35643564

35653565
if (prog->idx == obj->efile.text_shndx) {
3566-
pr_warn("relo in .text insn %d into off %d\n",
3567-
relo->insn_idx, relo->text_off);
3566+
pr_warn("relo in .text insn %d into off %d (insn #%d)\n",
3567+
relo->insn_idx, relo->sym_off, relo->sym_off / 8);
35683568
return -LIBBPF_ERRNO__RELOC;
35693569
}
35703570

@@ -3599,7 +3599,7 @@ bpf_program__reloc_text(struct bpf_program *prog, struct bpf_object *obj,
35993599
prog->section_name);
36003600
}
36013601
insn = &prog->insns[relo->insn_idx];
3602-
insn->imm += relo->text_off + prog->main_prog_cnt - relo->insn_idx;
3602+
insn->imm += relo->sym_off / 8 + prog->main_prog_cnt - relo->insn_idx;
36033603
return 0;
36043604
}
36053605

@@ -3622,31 +3622,26 @@ bpf_program__relocate(struct bpf_program *prog, struct bpf_object *obj)
36223622
return 0;
36233623

36243624
for (i = 0; i < prog->nr_reloc; i++) {
3625-
if (prog->reloc_desc[i].type == RELO_LD64 ||
3626-
prog->reloc_desc[i].type == RELO_DATA) {
3627-
bool relo_data = prog->reloc_desc[i].type == RELO_DATA;
3628-
struct bpf_insn *insns = prog->insns;
3629-
int insn_idx, map_idx;
3625+
struct reloc_desc *relo = &prog->reloc_desc[i];
36303626

3631-
insn_idx = prog->reloc_desc[i].insn_idx;
3632-
map_idx = prog->reloc_desc[i].map_idx;
3627+
if (relo->type == RELO_LD64 || relo->type == RELO_DATA) {
3628+
struct bpf_insn *insn = &prog->insns[relo->insn_idx];
36333629

3634-
if (insn_idx + 1 >= (int)prog->insns_cnt) {
3630+
if (relo->insn_idx + 1 >= (int)prog->insns_cnt) {
36353631
pr_warn("relocation out of range: '%s'\n",
36363632
prog->section_name);
36373633
return -LIBBPF_ERRNO__RELOC;
36383634
}
36393635

3640-
if (!relo_data) {
3641-
insns[insn_idx].src_reg = BPF_PSEUDO_MAP_FD;
3636+
if (relo->type != RELO_DATA) {
3637+
insn[0].src_reg = BPF_PSEUDO_MAP_FD;
36423638
} else {
3643-
insns[insn_idx].src_reg = BPF_PSEUDO_MAP_VALUE;
3644-
insns[insn_idx + 1].imm = insns[insn_idx].imm;
3639+
insn[0].src_reg = BPF_PSEUDO_MAP_VALUE;
3640+
insn[1].imm = insn[0].imm + relo->sym_off;
36453641
}
3646-
insns[insn_idx].imm = obj->maps[map_idx].fd;
3647-
} else if (prog->reloc_desc[i].type == RELO_CALL) {
3648-
err = bpf_program__reloc_text(prog, obj,
3649-
&prog->reloc_desc[i]);
3642+
insn[0].imm = obj->maps[relo->map_idx].fd;
3643+
} else if (relo->type == RELO_CALL) {
3644+
err = bpf_program__reloc_text(prog, obj, relo);
36503645
if (err)
36513646
return err;
36523647
}

tools/testing/selftests/bpf/progs/fentry_test.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,36 +6,36 @@
66

77
char _license[] SEC("license") = "GPL";
88

9-
static volatile __u64 test1_result;
9+
__u64 test1_result = 0;
1010
BPF_TRACE_1("fentry/bpf_fentry_test1", test1, int, a)
1111
{
1212
test1_result = a == 1;
1313
return 0;
1414
}
1515

16-
static volatile __u64 test2_result;
16+
__u64 test2_result = 0;
1717
BPF_TRACE_2("fentry/bpf_fentry_test2", test2, int, a, __u64, b)
1818
{
1919
test2_result = a == 2 && b == 3;
2020
return 0;
2121
}
2222

23-
static volatile __u64 test3_result;
23+
__u64 test3_result = 0;
2424
BPF_TRACE_3("fentry/bpf_fentry_test3", test3, char, a, int, b, __u64, c)
2525
{
2626
test3_result = a == 4 && b == 5 && c == 6;
2727
return 0;
2828
}
2929

30-
static volatile __u64 test4_result;
30+
__u64 test4_result = 0;
3131
BPF_TRACE_4("fentry/bpf_fentry_test4", test4,
3232
void *, a, char, b, int, c, __u64, d)
3333
{
3434
test4_result = a == (void *)7 && b == 8 && c == 9 && d == 10;
3535
return 0;
3636
}
3737

38-
static volatile __u64 test5_result;
38+
__u64 test5_result = 0;
3939
BPF_TRACE_5("fentry/bpf_fentry_test5", test5,
4040
__u64, a, void *, b, short, c, int, d, __u64, e)
4141
{
@@ -44,7 +44,7 @@ BPF_TRACE_5("fentry/bpf_fentry_test5", test5,
4444
return 0;
4545
}
4646

47-
static volatile __u64 test6_result;
47+
__u64 test6_result = 0;
4848
BPF_TRACE_6("fentry/bpf_fentry_test6", test6,
4949
__u64, a, void *, b, short, c, int, d, void *, e, __u64, f)
5050
{

tools/testing/selftests/bpf/progs/fexit_bpf2bpf.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ struct sk_buff {
88
unsigned int len;
99
};
1010

11-
static volatile __u64 test_result;
11+
__u64 test_result = 0;
1212
BPF_TRACE_2("fexit/test_pkt_access", test_main,
1313
struct sk_buff *, skb, int, ret)
1414
{
@@ -23,7 +23,7 @@ BPF_TRACE_2("fexit/test_pkt_access", test_main,
2323
return 0;
2424
}
2525

26-
static volatile __u64 test_result_subprog1;
26+
__u64 test_result_subprog1 = 0;
2727
BPF_TRACE_2("fexit/test_pkt_access_subprog1", test_subprog1,
2828
struct sk_buff *, skb, int, ret)
2929
{
@@ -56,7 +56,7 @@ struct args_subprog2 {
5656
__u64 args[5];
5757
__u64 ret;
5858
};
59-
static volatile __u64 test_result_subprog2;
59+
__u64 test_result_subprog2 = 0;
6060
SEC("fexit/test_pkt_access_subprog2")
6161
int test_subprog2(struct args_subprog2 *ctx)
6262
{

tools/testing/selftests/bpf/progs/fexit_test.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,28 +6,28 @@
66

77
char _license[] SEC("license") = "GPL";
88

9-
static volatile __u64 test1_result;
9+
__u64 test1_result = 0;
1010
BPF_TRACE_2("fexit/bpf_fentry_test1", test1, int, a, int, ret)
1111
{
1212
test1_result = a == 1 && ret == 2;
1313
return 0;
1414
}
1515

16-
static volatile __u64 test2_result;
16+
__u64 test2_result = 0;
1717
BPF_TRACE_3("fexit/bpf_fentry_test2", test2, int, a, __u64, b, int, ret)
1818
{
1919
test2_result = a == 2 && b == 3 && ret == 5;
2020
return 0;
2121
}
2222

23-
static volatile __u64 test3_result;
23+
__u64 test3_result = 0;
2424
BPF_TRACE_4("fexit/bpf_fentry_test3", test3, char, a, int, b, __u64, c, int, ret)
2525
{
2626
test3_result = a == 4 && b == 5 && c == 6 && ret == 15;
2727
return 0;
2828
}
2929

30-
static volatile __u64 test4_result;
30+
__u64 test4_result = 0;
3131
BPF_TRACE_5("fexit/bpf_fentry_test4", test4,
3232
void *, a, char, b, int, c, __u64, d, int, ret)
3333
{
@@ -37,7 +37,7 @@ BPF_TRACE_5("fexit/bpf_fentry_test4", test4,
3737
return 0;
3838
}
3939

40-
static volatile __u64 test5_result;
40+
__u64 test5_result = 0;
4141
BPF_TRACE_6("fexit/bpf_fentry_test5", test5,
4242
__u64, a, void *, b, short, c, int, d, __u64, e, int, ret)
4343
{
@@ -46,7 +46,7 @@ BPF_TRACE_6("fexit/bpf_fentry_test5", test5,
4646
return 0;
4747
}
4848

49-
static volatile __u64 test6_result;
49+
__u64 test6_result = 0;
5050
BPF_TRACE_7("fexit/bpf_fentry_test6", test6,
5151
__u64, a, void *, b, short, c, int, d, void *, e, __u64, f,
5252
int, ret)

tools/testing/selftests/bpf/progs/test_mmap.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ struct {
1515
__type(value, __u64);
1616
} data_map SEC(".maps");
1717

18-
static volatile __u64 in_val;
19-
static volatile __u64 out_val;
18+
__u64 in_val = 0;
19+
__u64 out_val = 0;
2020

2121
SEC("raw_tracepoint/sys_enter")
2222
int test_mmap(void *ctx)

0 commit comments

Comments
 (0)