[PATCH 7/9] ld: add support for eBPF

Jose E. Marchesi jose.marchesi@oracle.com
Mon May 20 16:45:00 GMT 2019


This patch adds support to the linker for the Linux eBPF architecture.
A minimal testsuite is included.

ld/ChangeLog:

2019-05-20  Jose E. Marchesi  <jose.marchesi@oracle.com>

	* Makefile.am (ALL_64_EMULATION_SOURCES): Add eelf64bpf.c.
	* Makefile.in (prefix): Regenerate.
	* configure.tgt (targ_extra_ofiles): Add case for bpf-*-* targets.
	* emulparams/elf64bpf.sh: New file.
	* testsuite/lib/ld-lib.exp (check_gc_sections_available): Add
	bpf-*-* to the list of targets not supporting gc-sections.
	* testsuite/ld-bpf/bar.s: New file.
	* testsuite/ld-bpf/jump-1.d: Likewise.
	* testsuite/ld-bpf/foo.s: Likewise.
	* testsuite/ld-bpf/call-1.d: Likewise.
	* testsuite/ld-bpf/bpf.exp: Likewise.
	* testsuite/ld-bpf/baz.s: Likewise.
---
 ld/ChangeLog                 | 15 +++++++++++++++
 ld/Makefile.am               |  2 ++
 ld/Makefile.in               |  4 ++++
 ld/configure                 | 28 ++++++++++++++++++++--------
 ld/configure.tgt             |  1 +
 ld/emulparams/elf64bpf.sh    | 10 ++++++++++
 ld/testsuite/ld-bpf/bar.s    |  5 +++++
 ld/testsuite/ld-bpf/baz.s    |  5 +++++
 ld/testsuite/ld-bpf/bpf.exp  | 29 +++++++++++++++++++++++++++++
 ld/testsuite/ld-bpf/call-1.d | 23 +++++++++++++++++++++++
 ld/testsuite/ld-bpf/foo.s    |  5 +++++
 ld/testsuite/ld-bpf/jump-1.d | 23 +++++++++++++++++++++++
 ld/testsuite/lib/ld-lib.exp  |  1 +
 13 files changed, 143 insertions(+), 8 deletions(-)
 create mode 100644 ld/emulparams/elf64bpf.sh
 create mode 100644 ld/testsuite/ld-bpf/bar.s
 create mode 100644 ld/testsuite/ld-bpf/baz.s
 create mode 100644 ld/testsuite/ld-bpf/bpf.exp
 create mode 100644 ld/testsuite/ld-bpf/call-1.d
 create mode 100644 ld/testsuite/ld-bpf/foo.s
 create mode 100644 ld/testsuite/ld-bpf/jump-1.d

diff --git a/ld/Makefile.am b/ld/Makefile.am
index 4a0bb15227..0509c2e50f 100644
--- a/ld/Makefile.am
+++ b/ld/Makefile.am
@@ -423,6 +423,7 @@ ALL_64_EMULATION_SOURCES = \
 	eelf32ltsmipn32_fbsd.c \
 	eelf32mipswindiss.c \
 	eelf64_aix.c \
+	eelf64bpf.c \
 	eelf64_ia64.c \
 	eelf64_ia64_fbsd.c \
 	eelf64_ia64_vms.c \
@@ -907,6 +908,7 @@ $(ALL_EMULATION_SOURCES) $(ALL_64_EMULATION_SOURCES): $(GEN_DEPENDS)
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ltsmipn32_fbsd.Pc@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32mipswindiss.Pc@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_aix.Pc@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64bpf.Pc@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_ia64.Pc@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_ia64_fbsd.Pc@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_ia64_vms.Pc@am__quote@
diff --git a/ld/Makefile.in b/ld/Makefile.in
index fbccfbc9d7..9bc14f76c8 100644
--- a/ld/Makefile.in
+++ b/ld/Makefile.in
@@ -521,6 +521,7 @@ pdfdir = @pdfdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
+runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -909,6 +910,7 @@ ALL_64_EMULATION_SOURCES = \
 	eelf32ltsmipn32_fbsd.c \
 	eelf32mipswindiss.c \
 	eelf64_aix.c \
+	eelf64bpf.c \
 	eelf64_ia64.c \
 	eelf64_ia64_fbsd.c \
 	eelf64_ia64_vms.c \
@@ -1359,6 +1361,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64alpha_fbsd.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64alpha_nbsd.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64bmip.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64bpf.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64btsmip.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64btsmip_fbsd.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64hppa.Po@am__quote@
@@ -2507,6 +2510,7 @@ $(ALL_EMULATION_SOURCES) $(ALL_64_EMULATION_SOURCES): $(GEN_DEPENDS)
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ltsmipn32_fbsd.Pc@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32mipswindiss.Pc@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_aix.Pc@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64bpf.Pc@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_ia64.Pc@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_ia64_fbsd.Pc@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64_ia64_vms.Pc@am__quote@
diff --git a/ld/configure b/ld/configure
index 3b50f5db8e..9952489f8c 100755
--- a/ld/configure
+++ b/ld/configure
@@ -786,6 +786,7 @@ infodir
 docdir
 oldincludedir
 includedir
+runstatedir
 localstatedir
 sharedstatedir
 sysconfdir
@@ -888,6 +889,7 @@ datadir='${datarootdir}'
 sysconfdir='${prefix}/etc'
 sharedstatedir='${prefix}/com'
 localstatedir='${prefix}/var'
+runstatedir='${localstatedir}/run'
 includedir='${prefix}/include'
 oldincludedir='/usr/include'
 docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@@ -1140,6 +1142,15 @@ do
   | -silent | --silent | --silen | --sile | --sil)
     silent=yes ;;
 
+  -runstatedir | --runstatedir | --runstatedi | --runstated \
+  | --runstate | --runstat | --runsta | --runst | --runs \
+  | --run | --ru | --r)
+    ac_prev=runstatedir ;;
+  -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
+  | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
+  | --run=* | --ru=* | --r=*)
+    runstatedir=$ac_optarg ;;
+
   -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
     ac_prev=sbindir ;;
   -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@@ -1277,7 +1288,7 @@ fi
 for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
 		datadir sysconfdir sharedstatedir localstatedir includedir \
 		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
-		libdir localedir mandir
+		libdir localedir mandir runstatedir
 do
   eval ac_val=\$$ac_var
   # Remove trailing slashes.
@@ -1430,6 +1441,7 @@ Fine tuning of the installation directories:
   --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
   --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
   --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]
   --libdir=DIR            object code libraries [EPREFIX/lib]
   --includedir=DIR        C header files [PREFIX/include]
   --oldincludedir=DIR     C header files for non-gcc [/usr/include]
@@ -12027,7 +12039,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 12030 "configure"
+#line 12042 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -12133,7 +12145,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 12136 "configure"
+#line 12148 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -15536,7 +15548,7 @@ else
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
 		       && LARGE_OFF_T % 2147483647 == 1)
 		      ? 1 : -1];
@@ -15582,7 +15594,7 @@ else
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
 		       && LARGE_OFF_T % 2147483647 == 1)
 		      ? 1 : -1];
@@ -15606,7 +15618,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
 		       && LARGE_OFF_T % 2147483647 == 1)
 		      ? 1 : -1];
@@ -15651,7 +15663,7 @@ else
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
 		       && LARGE_OFF_T % 2147483647 == 1)
 		      ? 1 : -1];
@@ -15675,7 +15687,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
     incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
 		       && LARGE_OFF_T % 2147483647 == 1)
 		      ? 1 : -1];
diff --git a/ld/configure.tgt b/ld/configure.tgt
index e92d4484b4..c81bc8a7d8 100644
--- a/ld/configure.tgt
+++ b/ld/configure.tgt
@@ -182,6 +182,7 @@ bfin-*-linux-uclibc*)	targ_emul=elf32bfinfd;
 			targ_extra_emuls="elf32bfin"
 			targ_extra_libpath=$targ_extra_emuls
 			;;
+bpf-*-*)		targ_emul=elf64bpf ;;
 cr16-*-elf*)		targ_emul=elf32cr16 ;;
 cr16c-*-elf*)		targ_emul=elf32cr16c
 			;;
diff --git a/ld/emulparams/elf64bpf.sh b/ld/emulparams/elf64bpf.sh
new file mode 100644
index 0000000000..39b23f0451
--- /dev/null
+++ b/ld/emulparams/elf64bpf.sh
@@ -0,0 +1,10 @@
+TEMPLATE_NAME=elf32
+SCRIPT_NAME=elf
+BIG_OUTPUT_FORMAT="elf64-bpfbe"
+LITTLE_OUTPUT_FORMAT="elf64-bpfle"
+OUTPUT_FORMAT="$LITTLE_OUTPUT_FORMAT"
+ARCH=bpf
+MACHINE=
+TARGET_PAGE_SIZE=0x1000
+# XXX this is arbitrary, for now
+TEXT_START_ADDR=0x00400000
diff --git a/ld/testsuite/ld-bpf/bar.s b/ld/testsuite/ld-bpf/bar.s
new file mode 100644
index 0000000000..b577d87d74
--- /dev/null
+++ b/ld/testsuite/ld-bpf/bar.s
@@ -0,0 +1,5 @@
+        .global bar
+bar:
+        mov	%r1,%r2
+        mov	%r3,%r1
+        exit
diff --git a/ld/testsuite/ld-bpf/baz.s b/ld/testsuite/ld-bpf/baz.s
new file mode 100644
index 0000000000..2e159a8829
--- /dev/null
+++ b/ld/testsuite/ld-bpf/baz.s
@@ -0,0 +1,5 @@
+        mov %r1,1
+        mov %r2,2
+        mov %r3,3
+        ja bar
+        exit
diff --git a/ld/testsuite/ld-bpf/bpf.exp b/ld/testsuite/ld-bpf/bpf.exp
new file mode 100644
index 0000000000..02b2e03021
--- /dev/null
+++ b/ld/testsuite/ld-bpf/bpf.exp
@@ -0,0 +1,29 @@
+# Copyright (C) 2019 Free Software Foundation, Inc.
+#
+# This file is part of the GNU Binutils.
+#
+# This program 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.
+#
+# This program 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+# MA 02110-1301, USA.
+#
+
+if { ![istarget bpf*-*-*] } {
+    return
+}
+
+set bpf_test_list [lsort [glob -nocomplain $srcdir/$subdir/*.d]]
+foreach bpf_test $bpf_test_list {
+    verbose [file rootname $bpf_test]
+    run_dump_test [file rootname $bpf_test]
+}
diff --git a/ld/testsuite/ld-bpf/call-1.d b/ld/testsuite/ld-bpf/call-1.d
new file mode 100644
index 0000000000..f408cd4db9
--- /dev/null
+++ b/ld/testsuite/ld-bpf/call-1.d
@@ -0,0 +1,23 @@
+#as: --EL
+#source: foo.s
+#source: bar.s
+#objdump: -dr
+#ld: -EL
+#warning: .*cannot find entry symbol _start.*
+#name: CALL with disp32 reloc
+
+.*: +file format .*bpf.*
+
+Disassembly of section .text:
+
+[0-9a-f]+ <.*>:
+ *[0-9a-f]+:	b7 01 00 00 01 00 00 00 	mov %r1,1
+ *[0-9a-f]+:	b7 02 00 00 02 00 00 00 	mov %r2,2
+ *[0-9a-f]+:	b7 03 00 00 03 00 00 00 	mov %r3,3
+ *[0-9a-f]+:	85 10 00 00 01 00 00 00 	call 1
+ *[0-9a-f]+:	95 00 00 00 00 00 00 00 	exit
+
+[0-9a-f]+ <bar>:
+ *[0-9a-f]+:	bf 21 00 00 00 00 00 00 	mov %r1,%r2
+ *[0-9a-f]+:	bf 13 00 00 00 00 00 00 	mov %r3,%r1
+ *[0-9a-f]+:	95 00 00 00 00 00 00 00 	exit
diff --git a/ld/testsuite/ld-bpf/foo.s b/ld/testsuite/ld-bpf/foo.s
new file mode 100644
index 0000000000..0958bbf67c
--- /dev/null
+++ b/ld/testsuite/ld-bpf/foo.s
@@ -0,0 +1,5 @@
+        mov %r1,1
+        mov %r2,2
+        mov %r3,3
+        call bar
+        exit
diff --git a/ld/testsuite/ld-bpf/jump-1.d b/ld/testsuite/ld-bpf/jump-1.d
new file mode 100644
index 0000000000..b57bcf1f40
--- /dev/null
+++ b/ld/testsuite/ld-bpf/jump-1.d
@@ -0,0 +1,23 @@
+#as: --EL
+#source: baz.s
+#source: bar.s
+#objdump: -dr
+#ld: -EL
+#warning: .*cannot find entry symbol _start.*
+#name: jump with disp16 reloc
+
+.*: +file format .*bpf.*
+
+Disassembly of section .text:
+
+[0-9a-f]+ <.*>:
+ *[0-9a-f]+:	b7 01 00 00 01 00 00 00 	mov %r1,1
+ *[0-9a-f]+:	b7 02 00 00 02 00 00 00 	mov %r2,2
+ *[0-9a-f]+:	b7 03 00 00 03 00 00 00 	mov %r3,3
+ *[0-9a-f]+:	05 00 01 00 00 00 00 00 	ja 1
+ *[0-9a-f]+:	95 00 00 00 00 00 00 00 	exit
+
+[0-9a-f]+ <bar>:
+ *[0-9a-f]+:	bf 21 00 00 00 00 00 00 	mov %r1,%r2
+ *[0-9a-f]+:	bf 13 00 00 00 00 00 00 	mov %r3,%r1
+ *[0-9a-f]+:	95 00 00 00 00 00 00 00 	exit
diff --git a/ld/testsuite/lib/ld-lib.exp b/ld/testsuite/lib/ld-lib.exp
index 0ff51c9526..5ebb7fa35f 100644
--- a/ld/testsuite/lib/ld-lib.exp
+++ b/ld/testsuite/lib/ld-lib.exp
@@ -1045,6 +1045,7 @@ proc check_gc_sections_available { } {
 	# Some targets don't support gc-sections despite whatever's
 	# advertised by ld's options.
 	if {   [istarget alpha-*-*]
+            || [istarget bpf-*-*]
 	    || [istarget d30v-*-*]
 	    || [istarget dlx-*-*]
 	    || [istarget hppa*64-*-*]
-- 
2.11.0



More information about the Binutils mailing list