提交 cc789266 编写于 作者: A Andrii Nakryiko 提交者: Zheng Zengkai

libbpf: Preserve empty DATASEC BTFs during static linking

mainline inclusion
from mainline-5.13-rc1
commit 36e79851
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I5EUVD
CVE: NA

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=36e7985160782bc683001afe09e33a288435def0

-------------------------------------------------

Ensure that BPF static linker preserves all DATASEC BTF types, even if some of
them might not have any variable information at all. This may happen if the
compiler promotes local initialized variable contents into .rodata section and
there are no global or static functions in the program.

For example,

  $ cat t.c
  struct t { char a; char b; char c; };
  void bar(struct t*);
  void find() {
     struct t tmp = {1, 2, 3};
     bar(&tmp);
  }

  $ clang -target bpf -O2 -g -S t.c
         .long   104                             # BTF_KIND_DATASEC(id = 8)
         .long   251658240                       # 0xf000000
         .long   0

         .ascii  ".rodata"                       # string offset=104

  $ clang -target bpf -O2 -g -c t.c
  $ readelf -S t.o | grep data
     [ 4] .rodata           PROGBITS         0000000000000000  00000090

Fixes: 8fd27bf6 ("libbpf: Add BPF static linker BTF and BTF.ext support")
Reported-by: NAlexei Starovoitov <ast@kernel.org>
Signed-off-by: NAndrii Nakryiko <andrii@kernel.org>
Signed-off-by: NDaniel Borkmann <daniel@iogearbox.net>
Acked-by: NYonghong Song <yhs@fb.com>
Link: https://lore.kernel.org/bpf/20210326043036.3081011-1-andrii@kernel.org
(cherry picked from commit 36e79851)
Signed-off-by: NWang Yufen <wangyufen@huawei.com>
上级 ad0de89b
...@@ -94,6 +94,7 @@ struct dst_sec { ...@@ -94,6 +94,7 @@ struct dst_sec {
int sec_sym_idx; int sec_sym_idx;
/* section's DATASEC variable info, emitted on BTF finalization */ /* section's DATASEC variable info, emitted on BTF finalization */
bool has_btf;
int sec_var_cnt; int sec_var_cnt;
struct btf_var_secinfo *sec_vars; struct btf_var_secinfo *sec_vars;
...@@ -1436,6 +1437,16 @@ static int linker_append_btf(struct bpf_linker *linker, struct src_obj *obj) ...@@ -1436,6 +1437,16 @@ static int linker_append_btf(struct bpf_linker *linker, struct src_obj *obj)
continue; continue;
dst_sec = &linker->secs[src_sec->dst_id]; dst_sec = &linker->secs[src_sec->dst_id];
/* Mark section as having BTF regardless of the presence of
* variables. In some cases compiler might generate empty BTF
* with no variables information. E.g., when promoting local
* array/structure variable initial values and BPF object
* file otherwise has no read-only static variables in
* .rodata. We need to preserve such empty BTF and just set
* correct section size.
*/
dst_sec->has_btf = true;
t = btf__type_by_id(obj->btf, src_sec->sec_type_id); t = btf__type_by_id(obj->btf, src_sec->sec_type_id);
src_var = btf_var_secinfos(t); src_var = btf_var_secinfos(t);
n = btf_vlen(t); n = btf_vlen(t);
...@@ -1717,7 +1728,7 @@ static int finalize_btf(struct bpf_linker *linker) ...@@ -1717,7 +1728,7 @@ static int finalize_btf(struct bpf_linker *linker)
for (i = 1; i < linker->sec_cnt; i++) { for (i = 1; i < linker->sec_cnt; i++) {
struct dst_sec *sec = &linker->secs[i]; struct dst_sec *sec = &linker->secs[i];
if (!sec->sec_var_cnt) if (!sec->has_btf)
continue; continue;
id = btf__add_datasec(btf, sec->sec_name, sec->sec_sz); id = btf__add_datasec(btf, sec->sec_name, sec->sec_sz);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册