[PATCH] RISC-V: New emulations to make path searches follow glibc ABI.

Jim Wilson jimw@sifive.com
Fri May 4 21:45:00 GMT 2018


This is mostly RISC-V specific, but there is one non-RISC-V part where I
modified ld/genscripts.sh.

This is an attempt to fix the library path searching for RISC-V.  Glibc says
that RV64 LP64D libaries should be in /lib64/lp64d.  The ld port currently says
that they are in /lib64.  Since the library path searches appear to be hard
coded into the emulations, and we have 6 ABIs, that means we need 6 emulations.
I want to avoid breaking backward compatibililty for the existing support,
so I added 4 new emulations, and modified the two existing ones without
renaming them.

The current 64-bit port looks in /lib64 and /lib.  Again, I don't want to break
backward compatibility, so I need the new linker to look in /lib64/lp64d,
/lib64, and /lib.  To make that work, I extended LIBPATH_SUFFIX so that
it can contain more than one entry.  I added loops to genscripts.sh to make
this work.  This is the only non-RISC-V specific part of the patch.

The new emulations are only used for linux, as they don't affect the embedded
target, and I don't know yet if other targets like freebsd need or want them.
There is also a small gcc patch needed to make the new emulations work, but
it isn't necessary for the default RV64/LP64D linux target.

This was tested against multiple riscv{32,64}-{elf,linux} targets with
multiple ABIs with builds and testsuite runs.  I also tested it with x86_64
and --enable-target=all builds and checks.  There were no regressions.  I
haven't tested it with a linux distro toolchain build, as I don't have an
easy way to do that.

I'm holding off installing this for a bit in case anyone wants to comment on
the changes, and in the hope I can get some proper distro testing.

Jim

	ld/
	PR ld/22962
	* Makefile.am (ALL_EMULATION_SOURCES): Add eelf32lriscv_ilp32f.c,
	eelf32lriscv_ilp32.c, eelf64lriscv_lp64f.c, eelf64lriscv_lp64.c.
	(eelf32lriscv_ilp32f.c, eelf32lriscv_ilp32.c): New build rules.
	(eelf64lriscv_lp64f.c, eelf64lriscv_lp64.c): New build rules.
	* Makefile.in: Regenerated.
	* configure.tgt (riscv32*-*-linux*, riscv64*-*-linux*): New.
	* ld/emulparams/elf32lriscv.sh: Set LIBPATH_SUFFIX.
	* ld/emulparams/elf32lriscv_ilp32.sh: New.
	* ld/emulparams/elf32lriscv_ilp32f.sh: New.
	* ld/emulparams/elf64lriscv-defs.sh: Don't set LIBPATH_SUFFIX here.
	* ld/emulparams/elf64lriscv.sh: Set LIBPATH_SUFFIX.
	* ld/emulparams/elf64lriscv_lp64.sh: New.
	* ld/emulparams/elf64lriscv_lp64f.sh: New.
	* ld/genscripts.sh (append_to_lib_path): Change LIBPATH_SUFFIX test to
	a for.  Inside loop, change LIBPATH_SUFFIX uses to libpath_suffix.
	(LIB_PATH): In LIB_PATH if, add loop for LIBPATH_SUFFIX, changes uses
	inside loop to libpath_suffix.
---
 ld/Makefile.am                      | 26 ++++++++++++++++++++++++++
 ld/Makefile.in                      | 30 ++++++++++++++++++++++++++++++
 ld/configure.tgt                    |  6 ++++++
 ld/emulparams/elf32lriscv.sh        | 13 +++++++++++++
 ld/emulparams/elf32lriscv_ilp32.sh  | 14 ++++++++++++++
 ld/emulparams/elf32lriscv_ilp32f.sh | 14 ++++++++++++++
 ld/emulparams/elf64lriscv-defs.sh   | 11 -----------
 ld/emulparams/elf64lriscv.sh        | 13 +++++++++++++
 ld/emulparams/elf64lriscv_lp64.sh   | 14 ++++++++++++++
 ld/emulparams/elf64lriscv_lp64f.sh  | 14 ++++++++++++++
 ld/genscripts.sh                    | 22 ++++++++++++----------
 11 files changed, 156 insertions(+), 21 deletions(-)
 create mode 100644 ld/emulparams/elf32lriscv_ilp32.sh
 create mode 100644 ld/emulparams/elf32lriscv_ilp32f.sh
 create mode 100644 ld/emulparams/elf64lriscv_lp64.sh
 create mode 100644 ld/emulparams/elf64lriscv_lp64f.sh

diff --git a/ld/Makefile.am b/ld/Makefile.am
index 2d758b1ee3..8e4c8774d1 100644
--- a/ld/Makefile.am
+++ b/ld/Makefile.am
@@ -266,6 +266,8 @@ ALL_EMULATION_SOURCES = \
 	eelf32ppcvxworks.c \
 	eelf32ppcwindiss.c \
 	eelf32lriscv.c \
+	eelf32lriscv_ilp32f.c \
+	eelf32lriscv_ilp32.c \
 	eelf32rl78.c \
 	eelf32rx.c \
 	eelf32tilegx.c \
@@ -434,6 +436,8 @@ ALL_64_EMULATION_SOURCES = \
 	eelf64hppa.c \
 	eelf64lppc.c \
 	eelf64lriscv.c \
+	eelf64lriscv_lp64f.c \
+	eelf64lriscv_lp64.c \
 	eelf64ltsmip.c \
 	eelf64ltsmip_fbsd.c \
 	eelf64mmix.c \
@@ -1103,6 +1107,16 @@ eelf32lriscv.c: $(srcdir)/emulparams/elf32lriscv.sh \
   $(srcdir)/emultempl/riscvelf.em $(srcdir)/scripttempl/elf.sc \
   ${GEN_DEPENDS}
 
+eelf32lriscv_ilp32f.c: $(srcdir)/emulparams/elf32lriscv_ilp32f.sh \
+  $(srcdir)/emulparams/elf32lriscv-defs.sh $(ELF_DEPS) \
+  $(srcdir)/emultempl/riscvelf.em $(srcdir)/scripttempl/elf.sc \
+  ${GEN_DEPENDS}
+
+eelf32lriscv_ilp32.c: $(srcdir)/emulparams/elf32lriscv_ilp32.sh \
+  $(srcdir)/emulparams/elf32lriscv-defs.sh $(ELF_DEPS) \
+  $(srcdir)/emultempl/riscvelf.em $(srcdir)/scripttempl/elf.sc \
+  ${GEN_DEPENDS}
+
 eelf32lsmip.c: $(srcdir)/emulparams/elf32lsmip.sh \
   $(srcdir)/emulparams/elf32lmip.sh $(srcdir)/emulparams/elf32bmip.sh \
   $(ELF_DEPS) $(srcdir)/emultempl/mipself.em $(srcdir)/scripttempl/elf.sc \
@@ -1748,6 +1762,18 @@ eelf64lriscv.c: $(srcdir)/emulparams/elf64lriscv.sh \
   $(srcdir)/emultempl/riscvelf.em $(srcdir)/scripttempl/elf.sc \
   ${GEN_DEPENDS}
 
+eelf64lriscv_lp64f.c: $(srcdir)/emulparams/elf64lriscv_lp64f.sh \
+  $(srcdir)/emulparams/elf64lriscv-defs.sh \
+  $(srcdir)/emulparams/elf32lriscv-defs.sh $(ELF_DEPS) \
+  $(srcdir)/emultempl/riscvelf.em $(srcdir)/scripttempl/elf.sc \
+  ${GEN_DEPENDS}
+
+eelf64lriscv_lp64.c: $(srcdir)/emulparams/elf64lriscv_lp64.sh \
+  $(srcdir)/emulparams/elf64lriscv-defs.sh \
+  $(srcdir)/emulparams/elf32lriscv-defs.sh $(ELF_DEPS) \
+  $(srcdir)/emultempl/riscvelf.em $(srcdir)/scripttempl/elf.sc \
+  ${GEN_DEPENDS}
+
 eelf64ltsmip.c: $(srcdir)/emulparams/elf64ltsmip.sh \
   $(srcdir)/emulparams/elf64btsmip.sh $(srcdir)/emulparams/elf64bmip-defs.sh \
   $(srcdir)/emulparams/elf32bmipn32-defs.sh $(ELF_DEPS) \
diff --git a/ld/Makefile.in b/ld/Makefile.in
index 8e0122c855..afd2a4bb88 100644
--- a/ld/Makefile.in
+++ b/ld/Makefile.in
@@ -635,6 +635,8 @@ ALL_EMULATION_SOURCES = \
 	eelf32ppcvxworks.c \
 	eelf32ppcwindiss.c \
 	eelf32lriscv.c \
+	eelf32lriscv_ilp32f.c \
+	eelf32lriscv_ilp32.c \
 	eelf32rl78.c \
 	eelf32rx.c \
 	eelf32tilegx.c \
@@ -802,6 +804,8 @@ ALL_64_EMULATION_SOURCES = \
 	eelf64hppa.c \
 	eelf64lppc.c \
 	eelf64lriscv.c \
+	eelf64lriscv_lp64f.c \
+	eelf64lriscv_lp64.c \
 	eelf64ltsmip.c \
 	eelf64ltsmip_fbsd.c \
 	eelf64mmix.c \
@@ -1180,6 +1184,8 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lr5900.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lr5900n32.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lriscv.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lriscv_ilp32.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lriscv_ilp32f.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lsmip.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ltsmip.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ltsmip_fbsd.Po@am__quote@
@@ -1234,6 +1240,8 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64hppa.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lppc.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lriscv.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lriscv_lp64.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lriscv_lp64f.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64ltsmip.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64ltsmip_fbsd.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64mmix.Po@am__quote@
@@ -2604,6 +2612,16 @@ eelf32lriscv.c: $(srcdir)/emulparams/elf32lriscv.sh \
   $(srcdir)/emultempl/riscvelf.em $(srcdir)/scripttempl/elf.sc \
   ${GEN_DEPENDS}
 
+eelf32lriscv_ilp32f.c: $(srcdir)/emulparams/elf32lriscv_ilp32f.sh \
+  $(srcdir)/emulparams/elf32lriscv-defs.sh $(ELF_DEPS) \
+  $(srcdir)/emultempl/riscvelf.em $(srcdir)/scripttempl/elf.sc \
+  ${GEN_DEPENDS}
+
+eelf32lriscv_ilp32.c: $(srcdir)/emulparams/elf32lriscv_ilp32.sh \
+  $(srcdir)/emulparams/elf32lriscv-defs.sh $(ELF_DEPS) \
+  $(srcdir)/emultempl/riscvelf.em $(srcdir)/scripttempl/elf.sc \
+  ${GEN_DEPENDS}
+
 eelf32lsmip.c: $(srcdir)/emulparams/elf32lsmip.sh \
   $(srcdir)/emulparams/elf32lmip.sh $(srcdir)/emulparams/elf32bmip.sh \
   $(ELF_DEPS) $(srcdir)/emultempl/mipself.em $(srcdir)/scripttempl/elf.sc \
@@ -3249,6 +3267,18 @@ eelf64lriscv.c: $(srcdir)/emulparams/elf64lriscv.sh \
   $(srcdir)/emultempl/riscvelf.em $(srcdir)/scripttempl/elf.sc \
   ${GEN_DEPENDS}
 
+eelf64lriscv_lp64f.c: $(srcdir)/emulparams/elf64lriscv_lp64f.sh \
+  $(srcdir)/emulparams/elf64lriscv-defs.sh \
+  $(srcdir)/emulparams/elf32lriscv-defs.sh $(ELF_DEPS) \
+  $(srcdir)/emultempl/riscvelf.em $(srcdir)/scripttempl/elf.sc \
+  ${GEN_DEPENDS}
+
+eelf64lriscv_lp64.c: $(srcdir)/emulparams/elf64lriscv_lp64.sh \
+  $(srcdir)/emulparams/elf64lriscv-defs.sh \
+  $(srcdir)/emulparams/elf32lriscv-defs.sh $(ELF_DEPS) \
+  $(srcdir)/emultempl/riscvelf.em $(srcdir)/scripttempl/elf.sc \
+  ${GEN_DEPENDS}
+
 eelf64ltsmip.c: $(srcdir)/emulparams/elf64ltsmip.sh \
   $(srcdir)/emulparams/elf64btsmip.sh $(srcdir)/emulparams/elf64bmip-defs.sh \
   $(srcdir)/emulparams/elf32bmipn32-defs.sh $(ELF_DEPS) \
diff --git a/ld/configure.tgt b/ld/configure.tgt
index 1999010896..4c4ab850f2 100644
--- a/ld/configure.tgt
+++ b/ld/configure.tgt
@@ -627,9 +627,15 @@ powerpc-*-beos*)	targ_emul=aixppc ;;
 powerpc-*-windiss*)	targ_emul=elf32ppcwindiss ;;
 powerpc-*-lynxos*)	targ_emul=ppclynx ;;
 pru*-*-*)		targ_emul=pruelf ;;
+riscv32*-*-linux*)	targ_emul=elf32lriscv
+			targ_extra_emuls="elf32lriscv_ilp32f elf32lriscv_ilp32 elf64lriscv elf64lriscv_lp64f elf64lriscv_lp64"
+			targ_extra_libpath=$targ_extra_emuls ;;
 riscv32*-*-*)		targ_emul=elf32lriscv
 			targ_extra_emuls="elf64lriscv"
 			targ_extra_libpath=$targ_extra_emuls ;;
+riscv64*-*-linux*)	targ_emul=elf64lriscv
+			targ_extra_emuls="elf64lriscv_lp64f elf64lriscv_lp64 elf32lriscv elf32lriscv_ilp32f elf32lriscv_ilp32"
+			targ_extra_libpath=$targ_extra_emuls ;;
 riscv64*-*-*)		targ_emul=elf64lriscv
 			targ_extra_emuls="elf32lriscv"
 			targ_extra_libpath=$targ_extra_emuls ;;
diff --git a/ld/emulparams/elf32lriscv.sh b/ld/emulparams/elf32lriscv.sh
index aac08e78f1..e91f884cec 100644
--- a/ld/emulparams/elf32lriscv.sh
+++ b/ld/emulparams/elf32lriscv.sh
@@ -1,2 +1,15 @@
+# RV32 code using ILP32D ABI.
+# ABI not in emulation name to avoid breaking backward compatibility.
 . ${srcdir}/emulparams/elf32lriscv-defs.sh
 OUTPUT_FORMAT="elf32-littleriscv"
+
+# On Linux, first look for 32 bit ILP32D target libraries in /lib/ilp32d as per
+# the glibc ABI.
+case "$target" in
+  riscv32*-linux*)
+    case "$EMULATION_NAME" in
+      *32*)
+	LIBPATH_SUFFIX="/ilp32d" ;;
+    esac
+    ;;
+esac
diff --git a/ld/emulparams/elf32lriscv_ilp32.sh b/ld/emulparams/elf32lriscv_ilp32.sh
new file mode 100644
index 0000000000..ec676bcb1d
--- /dev/null
+++ b/ld/emulparams/elf32lriscv_ilp32.sh
@@ -0,0 +1,14 @@
+# RV32 code using ILP32 ABI.
+. ${srcdir}/emulparams/elf32lriscv-defs.sh
+OUTPUT_FORMAT="elf32-littleriscv"
+
+# On Linux, first look for 32 bit ILP32 target libraries in /lib/ilp32 as per
+# the glibc ABI.
+case "$target" in
+  riscv32*-linux*)
+    case "$EMULATION_NAME" in
+      *32*)
+	LIBPATH_SUFFIX="/ilp32" ;;
+    esac
+    ;;
+esac
diff --git a/ld/emulparams/elf32lriscv_ilp32f.sh b/ld/emulparams/elf32lriscv_ilp32f.sh
new file mode 100644
index 0000000000..63304f9ef9
--- /dev/null
+++ b/ld/emulparams/elf32lriscv_ilp32f.sh
@@ -0,0 +1,14 @@
+# RV32 code using ILP32F ABI.
+. ${srcdir}/emulparams/elf32lriscv-defs.sh
+OUTPUT_FORMAT="elf32-littleriscv"
+
+# On Linux, first look for 32 bit ILP32F target libraries in /lib/ilp32f as per
+# the glibc ABI.
+case "$target" in
+  riscv32*-linux*)
+    case "$EMULATION_NAME" in
+      *32*)
+	LIBPATH_SUFFIX="/ilp32f" ;;
+    esac
+    ;;
+esac
diff --git a/ld/emulparams/elf64lriscv-defs.sh b/ld/emulparams/elf64lriscv-defs.sh
index 6308714207..930f333979 100644
--- a/ld/emulparams/elf64lriscv-defs.sh
+++ b/ld/emulparams/elf64lriscv-defs.sh
@@ -1,13 +1,2 @@
 . ${srcdir}/emulparams/elf32lriscv-defs.sh
 ELFSIZE=64
-
-# Look for 64 bit target libraries in /lib64, /usr/lib64 etc., first
-# on Linux.
-case "$target" in
-  riscv64*-linux*)
-    case "$EMULATION_NAME" in
-      *64*)
-	LIBPATH_SUFFIX=64 ;;
-    esac
-    ;;
-esac
diff --git a/ld/emulparams/elf64lriscv.sh b/ld/emulparams/elf64lriscv.sh
index 3a6a652c9d..f0a10abec7 100644
--- a/ld/emulparams/elf64lriscv.sh
+++ b/ld/emulparams/elf64lriscv.sh
@@ -1,2 +1,15 @@
+# RV64 code using LP64D ABI.
+# ABI not in emulation name to avoid breaking backward compatibility.
 . ${srcdir}/emulparams/elf64lriscv-defs.sh
 OUTPUT_FORMAT="elf64-littleriscv"
+
+# On Linux, first look for 64 bit LP64D target libraries in /lib64/lp64d as per
+# the glibc ABI, and then /lib64 for backward compatility.
+case "$target" in
+  riscv64*-linux*)
+    case "$EMULATION_NAME" in
+      *64*)
+	LIBPATH_SUFFIX="64/lp64d 64";;
+    esac
+    ;;
+esac
diff --git a/ld/emulparams/elf64lriscv_lp64.sh b/ld/emulparams/elf64lriscv_lp64.sh
new file mode 100644
index 0000000000..80a8f826d1
--- /dev/null
+++ b/ld/emulparams/elf64lriscv_lp64.sh
@@ -0,0 +1,14 @@
+# RV64 code using LP64 ABI.
+. ${srcdir}/emulparams/elf64lriscv-defs.sh
+OUTPUT_FORMAT="elf64-littleriscv"
+
+# On Linux, first look for 64 bit LP64 target libraries in /lib64/lp64 as per
+# the glibc ABI, and then /lib64 for backward compatility.
+case "$target" in
+  riscv64*-linux*)
+    case "$EMULATION_NAME" in
+      *64*)
+	LIBPATH_SUFFIX="64/lp64 64";;
+    esac
+    ;;
+esac
diff --git a/ld/emulparams/elf64lriscv_lp64f.sh b/ld/emulparams/elf64lriscv_lp64f.sh
new file mode 100644
index 0000000000..8f86421feb
--- /dev/null
+++ b/ld/emulparams/elf64lriscv_lp64f.sh
@@ -0,0 +1,14 @@
+# RV64 code using LP64F ABI.
+. ${srcdir}/emulparams/elf64lriscv-defs.sh
+OUTPUT_FORMAT="elf64-littleriscv"
+
+# On Linux, first look for 64 bit LP64F target libraries in /lib64/lp64f as per
+# the glibc ABI, and then /lib64 for backward compatility.
+case "$target" in
+  riscv64*-linux*)
+    case "$EMULATION_NAME" in
+      *64*)
+	LIBPATH_SUFFIX="64/lp64f 64";;
+    esac
+    ;;
+esac
diff --git a/ld/genscripts.sh b/ld/genscripts.sh
index 8732422b3a..370b22269d 100755
--- a/ld/genscripts.sh
+++ b/ld/genscripts.sh
@@ -155,9 +155,9 @@ append_to_lib_path()
 	lib="=${lib}"
       fi
       skip_lib=no
-      if test -n "${LIBPATH_SUFFIX}"; then
+      for libpath_suffix in ${LIBPATH_SUFFIX}; do
 	case "${lib}" in
-	  *${LIBPATH_SUFFIX})
+	  *${libpath_suffix})
 	    case :${lib_path1}: in
 	      *:${lib}:*) ;;
 	      ::) lib_path1=${lib} ;;
@@ -171,13 +171,13 @@ append_to_lib_path()
 	    fi
 	    if test "${skip_lib}" = "no"; then
 	      case :${lib_path1}: in
-		*:${lib}${LIBPATH_SUFFIX}:*) ;;
-		::) lib_path1=${lib}${LIBPATH_SUFFIX} ;;
-	        *) lib_path1=${lib_path1}:${lib}${LIBPATH_SUFFIX} ;;
+		*:${lib}${libpath_suffix}:*) ;;
+		::) lib_path1=${lib}${libpath_suffix} ;;
+		*) lib_path1=${lib_path1}:${lib}${libpath_suffix} ;;
 	      esac
 	    fi ;;
 	esac
-      fi
+      done
       if test "${skip_lib}" = "no"; then
 	case :${lib_path1}:${lib_path2}: in
 	  *:${lib}:*) ;;
@@ -203,10 +203,12 @@ if [ "${LIB_PATH}" != ":" ] ; then
     # because 64bit libraries may be in both places, depending on
     # cross-development setup method (e.g.: /usr/s390x-linux/lib64
     # vs. /usr/s390-linux/lib64)
-    case "${NATIVE}:${LIBPATH_SUFFIX}:${TOOL_LIB}" in
-      :* | *::* | *:*:*${LIBPATH_SUFFIX}) ;;
-      *) libs="${exec_prefix}/${target_alias}/lib${LIBPATH_SUFFIX}" ;;
-    esac
+    for libpath_suffix in ${LIBPATH_SUFFIX}; do
+      case "${NATIVE}:${libpath_suffix}:${TOOL_LIB}" in
+	:* | *::* | *:*:*${libpath_suffix}) ;;
+	*) libs="${exec_prefix}/${target_alias}/lib${libpath_suffix}" ;;
+      esac
+    done
     libs="${exec_prefix}/${TOOL_LIB}/lib ${libs}"
   fi
   append_to_lib_path ${libs}
-- 
2.14.1



More information about the Binutils mailing list