Blob Blame History Raw
From 9783e8b3de077c2e6399a9aa83f93237690bd744 Mon Sep 17 00:00:00 2001
From: Andrea Claudi <aclaudi@redhat.com>
Date: Thu, 13 Jun 2019 14:37:57 +0200
Subject: [PATCH] bpf: check map symbol type properly with newer llvm compiler

Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1716361
Upstream Status: iproute2.git commit 7a04dd84a7f93

commit 7a04dd84a7f938f72fcef9efe8383314b0a66274
Author: Yonghong Song <yhs@fb.com>
Date:   Mon Oct 29 15:32:03 2018 -0700

    bpf: check map symbol type properly with newer llvm compiler

    With llvm 7.0 or earlier, the map symbol type is STT_NOTYPE.
      -bash-4.4$ cat t.c
      __attribute__((section("maps"))) int g;
      -bash-4.4$ clang -target bpf -O2 -c t.c
      -bash-4.4$ readelf -s t.o

      Symbol table '.symtab' contains 2 entries:
         Num:    Value          Size Type    Bind   Vis      Ndx Name
           0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
           1: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT    3 g

    The following llvm commit enables BPF target to generate
    proper symbol type and size.
      commit bf6ec206615b9718869d48b4e5400d0c6e3638dd
      Author: Yonghong Song <yhs@fb.com>
      Date:   Wed Sep 19 16:04:13 2018 +0000

          [bpf] Symbol sizes and types in object file

          Clang-compiled object files currently don't include the symbol sizes and
          types.  Some tools however need that information.  For example, ctfconvert
          uses that information to generate FreeBSD's CTF representation from ELF
          files.
          With this patch, symbol sizes and types are included in object files.

          Signed-off-by: Paul Chaignon <paul.chaignon@orange.com>
          Reported-by: Yutaro Hayakawa <yhayakawa3720@gmail.com>

    Hence, for llvm 8.0.0 (currently trunk), symbol type will be not NOTYPE, but OBJECT.
      -bash-4.4$ clang -target bpf -O2 -c t.c
      -bash-4.4$ readelf -s t.o

      Symbol table '.symtab' contains 3 entries:
         Num:    Value          Size Type    Bind   Vis      Ndx Name
           0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
           1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS t.c
           2: 0000000000000000     4 OBJECT  GLOBAL DEFAULT    3 g

    This patch makes sure bpf library accepts both NOTYPE and OBJECT types
    of global map symbols.

    Signed-off-by: Yonghong Song <yhs@fb.com>
    Acked-by: Daniel Borkmann <daniel@iogearbox.net>
    Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 lib/bpf.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/lib/bpf.c b/lib/bpf.c
index d093d0bd86eae..45f279fa4a416 100644
--- a/lib/bpf.c
+++ b/lib/bpf.c
@@ -1758,11 +1758,13 @@ static const char *bpf_map_fetch_name(struct bpf_elf_ctx *ctx, int which)
 	int i;
 
 	for (i = 0; i < ctx->sym_num; i++) {
+		int type = GELF_ST_TYPE(sym.st_info);
+
 		if (gelf_getsym(ctx->sym_tab, i, &sym) != &sym)
 			continue;
 
 		if (GELF_ST_BIND(sym.st_info) != STB_GLOBAL ||
-		    GELF_ST_TYPE(sym.st_info) != STT_NOTYPE ||
+		    (type != STT_NOTYPE && type != STT_OBJECT) ||
 		    sym.st_shndx != ctx->sec_maps ||
 		    sym.st_value / ctx->map_len != which)
 			continue;
@@ -1849,11 +1851,13 @@ static int bpf_map_num_sym(struct bpf_elf_ctx *ctx)
 	GElf_Sym sym;
 
 	for (i = 0; i < ctx->sym_num; i++) {
+		int type = GELF_ST_TYPE(sym.st_info);
+
 		if (gelf_getsym(ctx->sym_tab, i, &sym) != &sym)
 			continue;
 
 		if (GELF_ST_BIND(sym.st_info) != STB_GLOBAL ||
-		    GELF_ST_TYPE(sym.st_info) != STT_NOTYPE ||
+		    (type != STT_NOTYPE && type != STT_OBJECT) ||
 		    sym.st_shndx != ctx->sec_maps)
 			continue;
 		num++;
@@ -1927,10 +1931,12 @@ static int bpf_map_verify_all_offs(struct bpf_elf_ctx *ctx, int end)
 		 * the table again.
 		 */
 		for (i = 0; i < ctx->sym_num; i++) {
+			int type = GELF_ST_TYPE(sym.st_info);
+
 			if (gelf_getsym(ctx->sym_tab, i, &sym) != &sym)
 				continue;
 			if (GELF_ST_BIND(sym.st_info) != STB_GLOBAL ||
-			    GELF_ST_TYPE(sym.st_info) != STT_NOTYPE ||
+			    (type != STT_NOTYPE && type != STT_OBJECT) ||
 			    sym.st_shndx != ctx->sec_maps)
 				continue;
 			if (sym.st_value == off)
-- 
2.20.1