Re: [PATCH bpf] libbpf: fix global variable relocation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On 11/26/19 10:01 PM, Andrii Nakryiko wrote:
> Similarly to a0d7da26ce86 ("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: 393cdfbee809 ("libbpf: Support initialized global variables")
> Signed-off-by: Andrii Nakryiko <andriin@xxxxxx>

LGTM with a few nits below.

Acked-by: Yonghong Song <yhs@xxxxxx>

> ---
>   tools/lib/bpf/libbpf.c                        | 40 +++++++++----------
>   .../testing/selftests/bpf/progs/fentry_test.c | 12 +++---
>   .../selftests/bpf/progs/fexit_bpf2bpf.c       |  6 +--
>   .../testing/selftests/bpf/progs/fexit_test.c  | 12 +++---
>   tools/testing/selftests/bpf/progs/test_mmap.c |  4 +-
>   5 files changed, 35 insertions(+), 39 deletions(-)
> 
> diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
> index b20f82e58989..4209b5a23a53 100644
> --- a/tools/lib/bpf/libbpf.c
> +++ b/tools/lib/bpf/libbpf.c
> @@ -171,10 +171,8 @@ struct bpf_program {
>   			RELO_DATA,
>   		} type;
>   		int insn_idx;
> -		union {
> -			int map_idx;
> -			int text_off;
> -		};
> +		int map_idx;
> +		int sym_off;
>   	} *reloc_desc;
>   	int nr_reloc;
>   	int log_level;
[...]
> @@ -3622,31 +3622,27 @@ bpf_program__relocate(struct bpf_program *prog, struct bpf_object *obj)
>   		return 0;
>   
>   	for (i = 0; i < prog->nr_reloc; i++) {
> +		struct reloc_desc *relo = &prog->reloc_desc[i];
> +
>   		if (prog->reloc_desc[i].type == RELO_LD64 ||
>   		    prog->reloc_desc[i].type == RELO_DATA) {

Using relo->type == RELO_LD64 or RELO_DATA?

> -			bool relo_data = prog->reloc_desc[i].type == RELO_DATA;
> -			struct bpf_insn *insns = prog->insns;
> -			int insn_idx, map_idx;
> -
> -			insn_idx = prog->reloc_desc[i].insn_idx;
> -			map_idx = prog->reloc_desc[i].map_idx;
> +			struct bpf_insn *insn = &prog->insns[relo->insn_idx];
>   
> -			if (insn_idx + 1 >= (int)prog->insns_cnt) {
> +			if (relo->insn_idx + 1 >= (int)prog->insns_cnt) {
>   				pr_warn("relocation out of range: '%s'\n",
>   					prog->section_name);
>   				return -LIBBPF_ERRNO__RELOC;
>   			}
>   
> -			if (!relo_data) {
> -				insns[insn_idx].src_reg = BPF_PSEUDO_MAP_FD;
> +			if (relo->type != RELO_DATA) {
> +				insn[0].src_reg = BPF_PSEUDO_MAP_FD;
>   			} else {
> -				insns[insn_idx].src_reg = BPF_PSEUDO_MAP_VALUE;
> -				insns[insn_idx + 1].imm = insns[insn_idx].imm;
> +				insn[0].src_reg = BPF_PSEUDO_MAP_VALUE;
> +				insn[1].imm = insn[0].imm + relo->sym_off;
>   			}
> -			insns[insn_idx].imm = obj->maps[map_idx].fd;
> +			insn[0].imm = obj->maps[relo->map_idx].fd;
>   		} else if (prog->reloc_desc[i].type == RELO_CALL) {

Using relo->type == RELO_CALL?

> -			err = bpf_program__reloc_text(prog, obj,
> -						      &prog->reloc_desc[i]);
> +			err = bpf_program__reloc_text(prog, obj, relo);
>   			if (err)
>   				return err;
>   		}
> diff --git a/tools/testing/selftests/bpf/progs/fentry_test.c b/tools/testing/selftests/bpf/progs/fentry_test.c
> index d2af9f039df5..615f7c6bca77 100644
> --- a/tools/testing/selftests/bpf/progs/fentry_test.c
> +++ b/tools/testing/selftests/bpf/progs/fentry_test.c
> @@ -6,28 +6,28 @@
[...]




[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux