Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755224AbbFLFqN (ORCPT ); Fri, 12 Jun 2015 01:46:13 -0400 Received: from szxga01-in.huawei.com ([58.251.152.64]:26684 "EHLO szxga01-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750773AbbFLFg1 (ORCPT ); Fri, 12 Jun 2015 01:36:27 -0400 From: Wang Nan To: , , , , , , , , , , CC: , , , , Subject: [RFC PATCH v7 16/37] bpf tools: Relocate eBPF programs Date: Fri, 12 Jun 2015 05:35:24 +0000 Message-ID: <1434087345-127225-17-git-send-email-wangnan0@huawei.com> X-Mailer: git-send-email 1.8.3.4 In-Reply-To: <1434087345-127225-1-git-send-email-wangnan0@huawei.com> References: <1434087345-127225-1-git-send-email-wangnan0@huawei.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.107.197.200] X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2760 Lines: 101 If an eBPF program accesses a map, LLVM generates a load instruction which loads an absolute address into a register, like this: ld_64 r1, ... call 2 That ld_64 instruction will be recorded in relocation section. To enable the usage of that map, relocation must be done by replacing the immediate value by real map file descriptor so it can be found by eBPF map functions. This patch to the relocation work based on information collected by patch 'bpf tools: Collect relocation sections from SHT_REL sections'. For each instruction which needs relocation, it inject corresponding file descriptor to imm field. As a part of protocol, src_reg is set to BPF_PSEUDO_MAP_FD to notify kernel this is a map loading instruction. Signed-off-by: Wang Nan Acked-by: Alexei Starovoitov --- tools/lib/bpf/libbpf.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 814721a..dbec69f 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -622,6 +622,55 @@ bpf_object__create_maps(struct bpf_object *obj) return 0; } +static int +bpf_program__relocate(struct bpf_program *prog, int *map_fds) +{ + int i; + + if (!prog || !prog->reloc_desc) + return 0; + + for (i = 0; i < prog->nr_reloc; i++) { + int insn_idx, map_idx; + struct bpf_insn *insns = prog->insns; + + insn_idx = prog->reloc_desc[i].insn_idx; + map_idx = prog->reloc_desc[i].map_idx; + + if (insn_idx >= (int)prog->insns_cnt) { + pr_warning("relocation out of range: '%s'\n", + prog->section_name); + return -ERANGE; + } + insns[insn_idx].src_reg = BPF_PSEUDO_MAP_FD; + insns[insn_idx].imm = map_fds[map_idx]; + } + + zfree(&prog->reloc_desc); + prog->nr_reloc = 0; + return 0; +} + + +static int +bpf_object__relocate(struct bpf_object *obj) +{ + struct bpf_program *prog; + size_t i; + int err; + + for (i = 0; i < obj->nr_programs; i++) { + prog = &obj->programs[i]; + + if ((err = bpf_program__relocate(prog, obj->map_fds))) { + pr_warning("failed to relocate '%s'\n", + prog->section_name); + return err; + } + } + return 0; +} + static int bpf_object__collect_reloc(struct bpf_object *obj) { int i, err; @@ -753,6 +802,8 @@ int bpf_object__load(struct bpf_object *obj) obj->loaded = true; if (bpf_object__create_maps(obj)) goto out; + if (bpf_object__relocate(obj)) + goto out; return 0; out: -- 1.8.3.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/