From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753490AbdAZPbT (ORCPT ); Thu, 26 Jan 2017 10:31:19 -0500 Received: from terminus.zytor.com ([65.50.211.136]:47708 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752564AbdAZPbQ (ORCPT ); Thu, 26 Jan 2017 10:31:16 -0500 Date: Thu, 26 Jan 2017 07:29:42 -0800 From: tip-bot for Joe Stringer Message-ID: Cc: linux-kernel@vger.kernel.org, wangnan0@huawei.com, daniel@iogearbox.net, ast@fb.com, acme@redhat.com, hpa@zytor.com, joe@ovn.org, mingo@kernel.org, tglx@linutronix.de Reply-To: acme@redhat.com, hpa@zytor.com, tglx@linutronix.de, mingo@kernel.org, joe@ovn.org, daniel@iogearbox.net, wangnan0@huawei.com, ast@fb.com, linux-kernel@vger.kernel.org In-Reply-To: <20170123011128.26534-2-joe@ovn.org> References: <20170123011128.26534-2-joe@ovn.org> To: linux-tip-commits@vger.kernel.org Subject: [tip:perf/core] tools lib bpf: Fix map offsets in relocation Git-Commit-ID: 94e5adece8b37a23d99fb1f8a5de94b23194f387 X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit-ID: 94e5adece8b37a23d99fb1f8a5de94b23194f387 Gitweb: http://git.kernel.org/tip/94e5adece8b37a23d99fb1f8a5de94b23194f387 Author: Joe Stringer AuthorDate: Sun, 22 Jan 2017 17:11:22 -0800 Committer: Arnaldo Carvalho de Melo CommitDate: Thu, 26 Jan 2017 11:42:56 -0300 tools lib bpf: Fix map offsets in relocation Commit 4708bbda5cb2 ("tools lib bpf: Fix maps resolution") attempted to fix map resolution by identifying the number of symbols that point to maps, and using this number to resolve each of the maps. However, during relocation the original definition of the map size was still in use. For up to two maps, the calculation was correct if there was a small difference in size between the map definition in libbpf and the one that the client library uses. However if the difference was large, particularly if more than two maps were used in the BPF program, the relocation would fail. For example, when using a map definition with size 28, with three maps, map relocation would count: (sym_offset / sizeof(struct bpf_map_def) => map_idx) (0 / 16 => 0), ie map_idx = 0 (28 / 16 => 1), ie map_idx = 1 (56 / 16 => 3), ie map_idx = 3 So, libbpf reports: libbpf: bpf relocation: map_idx 3 large than 2 Fix map relocation by checking the exact offset of maps when doing relocation. Signed-off-by: Joe Stringer [Allow different map size in an object] Signed-off-by: Wang Nan Cc: Alexei Starovoitov Cc: Daniel Borkmann Cc: netdev@vger.kernel.org Fixes: 4708bbda5cb2 ("tools lib bpf: Fix maps resolution") Link: http://lkml.kernel.org/r/20170123011128.26534-2-joe@ovn.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/bpf/libbpf.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 84e6b35..671d5ad 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -779,7 +779,7 @@ static int bpf_program__collect_reloc(struct bpf_program *prog, size_t nr_maps, GElf_Shdr *shdr, Elf_Data *data, Elf_Data *symbols, - int maps_shndx) + int maps_shndx, struct bpf_map *maps) { int i, nrels; @@ -829,7 +829,15 @@ bpf_program__collect_reloc(struct bpf_program *prog, return -LIBBPF_ERRNO__RELOC; } - map_idx = sym.st_value / sizeof(struct bpf_map_def); + /* TODO: 'maps' is sorted. We can use bsearch to make it faster. */ + for (map_idx = 0; map_idx < nr_maps; map_idx++) { + if (maps[map_idx].offset == sym.st_value) { + pr_debug("relocation: find map %zd (%s) for insn %u\n", + map_idx, maps[map_idx].name, insn_idx); + break; + } + } + if (map_idx >= nr_maps) { pr_warning("bpf relocation: map_idx %d large than %d\n", (int)map_idx, (int)nr_maps - 1); @@ -953,7 +961,8 @@ static int bpf_object__collect_reloc(struct bpf_object *obj) err = bpf_program__collect_reloc(prog, nr_maps, shdr, data, obj->efile.symbols, - obj->efile.maps_shndx); + obj->efile.maps_shndx, + obj->maps); if (err) return err; }