From patchwork Thu Jan 19 09:53:18 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wang Nan X-Patchwork-Id: 91843 Delivered-To: patch@linaro.org Received: by 10.140.20.99 with SMTP id 90csp196310qgi; Thu, 19 Jan 2017 01:54:58 -0800 (PST) X-Received: by 10.99.114.19 with SMTP id n19mr9174376pgc.143.1484819698478; Thu, 19 Jan 2017 01:54:58 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r1si3067216pge.110.2017.01.19.01.54.58; Thu, 19 Jan 2017 01:54:58 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751630AbdASJyo (ORCPT + 25 others); Thu, 19 Jan 2017 04:54:44 -0500 Received: from szxga01-in.huawei.com ([58.251.152.64]:6071 "EHLO szxga01-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751367AbdASJym (ORCPT ); Thu, 19 Jan 2017 04:54:42 -0500 Received: from 172.24.1.60 (EHLO szxeml427-hub.china.huawei.com) ([172.24.1.60]) by szxrg01-dlp.huawei.com (MOS 4.3.7-GA FastPath queued) with ESMTP id DYD01912; Thu, 19 Jan 2017 17:53:35 +0800 (CST) Received: from linux-4hy3.site (10.107.193.248) by szxeml427-hub.china.huawei.com (10.82.67.182) with Microsoft SMTP Server id 14.3.235.1; Thu, 19 Jan 2017 17:53:28 +0800 From: Wang Nan To: , CC: , Wang Nan , "Alexei Starovoitov" , Daniel Borkmann , "Arnaldo Carvalho de Melo" Subject: [PATCH -improve] tools lib bpf: Fix map offsets in relocation Date: Thu, 19 Jan 2017 09:53:18 +0000 Message-ID: <20170119095318.12764-1-wangnan0@huawei.com> X-Mailer: git-send-email 2.10.1 In-Reply-To: <20170118235724.26103-2-joe@ovn.org> References: <20170118235724.26103-2-joe@ovn.org> MIME-Version: 1.0 X-Originating-IP: [10.107.193.248] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A020203.58808CA0.0304, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2013-06-18 04:22:30, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: 571d42d84857aad44414faa7d501f056 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Joe Stringer 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. Fixes: 4708bbda5cb2 ("tools lib bpf: Fix maps resolution") Signed-off-by: Joe Stringer Signed-off-by: Wang Nan [Allow different map size in an object] Cc: Alexei Starovoitov Cc: Daniel Borkmann Cc: Arnaldo Carvalho de Melo --- tools/lib/bpf/libbpf.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) -- 2.10.1 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; }