From 8376927b2cc8b80cd5aa1e48aabafc85c0ad4f3e Mon Sep 17 00:00:00 2001 From: "Jose E. Marchesi" Date: Thu, 23 May 2019 19:05:42 +0200 Subject: [PATCH] ld: add support for eBPF This patch adds support to the linker for the Linux eBPF architecture. A minimal testsuite is included. ld/ChangeLog: 2019-05-23 Jose E. Marchesi * 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/ChangeLog b/ld/ChangeLog index d46fd95818..0965cd79b5 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,18 @@ +2019-05-23 Jose E. Marchesi + + * 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. + 2019-05-23 Alan Modra PR 24576 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]+ : + *[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]+ : + *[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.34.1