backends,bpf: add proper relocation support
authorYonghong Song <yhs@fb.com>
Sat, 16 Jun 2018 20:02:43 +0000 (13:02 -0700)
committerMark Wielaard <mark@klomp.org>
Thu, 21 Jun 2018 18:33:32 +0000 (20:33 +0200)
Due to libdw does not have proper BPF relocation support,
the pahole cannot display filenames correctly for objects
with default llvm options. So we have to invent
a special option "llc -march=bpf -mattr=dwarfris" to
prevent llvm from generating cross-section dwarf relocation
records (https://reviews.llvm.org/rL326505).
The pahole related discussion is in linux netdev
mailing list (http://lists.openwall.net/netdev/2018/06/15/38, etc.)

We would like to add proper BPF relocation support
to libdw so eventually we could retire the special llc bpf
flag "-mattr=dwarfris".

The bpf relocations are defined in
llvm_repo:include/llvm/BinaryFormat/ELFRelocs/BPF.def:
  ELF_RELOC(R_BPF_NONE,        0)
  ELF_RELOC(R_BPF_64_64,       1)
  ELF_RELOC(R_BPF_64_32,      10)

Removed the relocation type R_BPF_MAP_FD whoes name does not
confirm to llvm definition and replaced it with R_BPF_64_64.
The BPF object is just a relocatible object, not an executable or
a shared library, so assign ELF type to REL only in bpf_reloc.def.

Signed-off-by: Yonghong Song <yhs@fb.com>
backends/ChangeLog
backends/Makefile.am
backends/bpf_init.c
backends/bpf_reloc.def
backends/bpf_symbol.c [new file with mode: 0644]
tests/ChangeLog
tests/Makefile.am
tests/run-reloc-bpf.sh [new file with mode: 0755]
tests/testfile-bpf-reloc.expect.bz2 [new file with mode: 0644]
tests/testfile-bpf-reloc.o.bz2 [new file with mode: 0644]

index e97e33d..3fa0f19 100644 (file)
@@ -1,3 +1,10 @@
+2018-06-16  Yonghong Song  <yhs@fb.com>
+
+       * Makefile.am (bpf_SRCS): Add bpf_symbol.c.
+       * bpf_init.c (bpf_init): Add reloc_simple_type HOOK.
+       * bpf_reloc.def: Add RELOC_TYPE 64_64 and 64_32.
+       * bpf_symbol.c: New file.
+
 2018-06-21  Mark Wielaard  <mark@klomp.org>
 
        * bpf_reloc.def: Remove MAP_FD.
index 0c14ec8..e42d674 100644 (file)
@@ -126,7 +126,7 @@ am_libebl_m68k_pic_a_OBJECTS = $(m68k_SRCS:.c=.os)
 # an issue.
 m68k_corenote_no_Wpacked_not_aligned = yes
 
-bpf_SRCS = bpf_init.c bpf_regs.c
+bpf_SRCS = bpf_init.c bpf_regs.c bpf_symbol.c
 cpu_bpf = ../libcpu/libcpu_bpf.a
 libebl_bpf_pic_a_SOURCES = $(bpf_SRCS)
 am_libebl_bpf_pic_a_OBJECTS = $(bpf_SRCS:.c=.os)
index 8ea1bc1..a046e06 100644 (file)
@@ -53,6 +53,7 @@ bpf_init (Elf *elf __attribute__ ((unused)),
   bpf_init_reloc (eh);
   HOOK (eh, register_info);
   HOOK (eh, disasm);
+  HOOK (eh, reloc_simple_type);
 
   return MODVERSION;
 }
index 09ac3a6..59f519b 100644 (file)
@@ -28,3 +28,5 @@
 /*         NAME,               REL|EXEC|DYN    */
 
 RELOC_TYPE (NONE,              EXEC|DYN)
+RELOC_TYPE (64_64,             REL)
+RELOC_TYPE (64_32,             REL)
diff --git a/backends/bpf_symbol.c b/backends/bpf_symbol.c
new file mode 100644 (file)
index 0000000..c9856f2
--- /dev/null
@@ -0,0 +1,54 @@
+/* BPF specific symbolic name handling.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <elf.h>
+#include <stddef.h>
+#include <string.h>
+
+#define BACKEND bpf_
+#include "libebl_CPU.h"
+
+
+/* Check for the simple reloc types.  */
+Elf_Type
+bpf_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+{
+  switch (type)
+    {
+    case R_BPF_64_64:
+      return ELF_T_XWORD;
+    case R_BPF_64_32:
+      return ELF_T_WORD;
+    default:
+      return ELF_T_NUM;
+    }
+}
index 4abbd12..c494286 100644 (file)
@@ -1,3 +1,12 @@
+2018-06-16  Yonghong Song  <yhs@fb.com>
+
+       * run-reloc-bpf.sh: New test.
+       * testfile-bpf-reloc.o.bz2: New test file.
+       * testfile-bpf-reloc.expect.bz2: New test file.
+       * Makefile.am (TESTS): Add run-reloc-bpf.sh.
+       (EXTRA_DIST): Add run-reloc-bpf.sh, testfile-bpf-reloc.o.bz2 and
+       testfile-bpf-reloc.expect.bz2.
+
 2018-06-13  Mark Wielaard  <mark@klomp.org>
 
        * run-readelf-const-values.sh: New test.
index 2d63da6..bdb82fc 100644 (file)
@@ -146,7 +146,8 @@ TESTS = run-arextract.sh run-arsymtest.sh run-ar.sh newfile test-nlist \
        run-dwarf-die-addr-die.sh \
        run-get-units-invalid.sh run-get-units-split.sh \
        run-attr-integrate-skel.sh \
-       run-all-dwarf-ranges.sh run-unit-info.sh
+       run-all-dwarf-ranges.sh run-unit-info.sh \
+       run-reloc-bpf.sh
 
 if !BIARCH
 export ELFUTILS_DISABLE_BIARCH = 1
@@ -376,6 +377,8 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \
             run-zstrptr.sh run-compress-test.sh \
             run-disasm-bpf.sh \
             testfile-bpf-dis1.expect.bz2 testfile-bpf-dis1.o.bz2 \
+            run-reloc-bpf.sh \
+            testfile-bpf-reloc.expect.bz2 testfile-bpf-reloc.o.bz2 \
             testfile-m68k-core.bz2 testfile-m68k.bz2 testfile-m68k-s.bz2 \
             run-dwarf-die-addr-die.sh \
             run-get-units-invalid.sh run-get-units-split.sh \
diff --git a/tests/run-reloc-bpf.sh b/tests/run-reloc-bpf.sh
new file mode 100755 (executable)
index 0000000..feb7557
--- /dev/null
@@ -0,0 +1,33 @@
+#! /bin/sh
+# Copyright (C) 2018 Facebook, Inc.
+# This file is part of elfutils.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# This test file is created with
+# $ cat t.c
+# struct tt {
+#   int a;
+#   char b;
+# };
+# int test(struct tt *t) {
+#    return t->a;
+# }
+# $ clang -O2 -g -emit-llvm -c t.c -o - | llc -march=bpf -filetype=obj -o t.o
+# $ mv t.o testfile-bpf-reloc.o
+
+testfiles testfile-bpf-reloc.o testfile-bpf-reloc.expect
+testrun_compare ${abs_top_builddir}/src/objdump -r testfile-bpf-reloc.o < testfile-bpf-reloc.expect
diff --git a/tests/testfile-bpf-reloc.expect.bz2 b/tests/testfile-bpf-reloc.expect.bz2
new file mode 100644 (file)
index 0000000..0ff8cc4
Binary files /dev/null and b/tests/testfile-bpf-reloc.expect.bz2 differ
diff --git a/tests/testfile-bpf-reloc.o.bz2 b/tests/testfile-bpf-reloc.o.bz2
new file mode 100644 (file)
index 0000000..295634f
Binary files /dev/null and b/tests/testfile-bpf-reloc.o.bz2 differ