This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Add support for ld-elf.so.hints on FreeBSD


While working on Gentoo/FreeBSD I had quite a few problems with linking, as 
binutils shipped with FreeBSD base system are patched to get the search paths 
(when using a native ld) from the ld-elf.so hints file.

The two attached patches are forward ports of the original patch (a bit 
reworked as there were changes in the API it seems, before it was passing the 
library name, now a dt_needed struct pointer), applying to version 2.16.1 and 
2.16.91.0.6 (it's a refresh of the other, after fixing the change between 
*-linux-gnu* and the new check for uclibc/glibc targets).

This is not the only change between "vanilla" binutils and freebsd's ones, but 
it's for sure the most important to use them as system binutils. The other 
changes are bfd updates, but I haven't forward ported them yet.

This is the first time that I spend time on binutils sources so I'm not sure 
if I'm doing it right (both wrt sources patch and sending it here).
Sorry if I'm doing something wrong.

-- 
Diego "Flameeyes" Pettenò - http://dev.gentoo.org/~flameeyes/
Gentoo/ALT lead, Gentoo/FreeBSD, Video, AMD64, Sound, PAM, KDE
Index: binutils-2.16.1/ld/Makefile.in
===================================================================
--- binutils-2.16.1.orig/ld/Makefile.in
+++ binutils-2.16.1/ld/Makefile.in
@@ -347,6 +347,7 @@ ALL_EMULATIONS = \
 	ei386beos.o \
 	ei386bsd.o \
 	ei386coff.o \
+	ei386freebsd.o \
 	ei386go32.o \
 	ei386linux.o \
 	ei386lynx.o \
@@ -1711,6 +1712,9 @@ ei386bsd.c: $(srcdir)/emulparams/i386bsd
 ei386coff.c: $(srcdir)/emulparams/i386coff.sh \
   $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/i386coff.sc ${GEN_DEPENDS}
 	${GENSCRIPTS} i386coff "$(tdir_i386coff)"
+ei386freebsd.c: $(srcdir)/emulparams/i386freebsd.sh \
+  $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+	${GENSCRIPTS} i386freebsd "$(tdir_i386freebsd)"
 ei386go32.c: $(srcdir)/emulparams/i386go32.sh \
   $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/i386go32.sc ${GEN_DEPENDS}
 	${GENSCRIPTS} i386go32 "$(tdir_i386go32)"
Index: binutils-2.16.1/ld/emulparams/i386freebsd.sh
===================================================================
--- /dev/null
+++ binutils-2.16.1/ld/emulparams/i386freebsd.sh
@@ -0,0 +1,6 @@
+SCRIPT_NAME=aout
+TEXT_START_ADDR=0x1020
+OUTPUT_FORMAT="a.out-i386-freebsd"
+TARGET_PAGE_SIZE=0x1000
+ARCH=i386
+EXECUTABLE_SYMBOLS='__DYNAMIC = 0;'
Index: binutils-2.16.1/ld/emultempl/elf32.em
===================================================================
--- binutils-2.16.1.orig/ld/emultempl/elf32.em
+++ binutils-2.16.1/ld/emultempl/elf32.em
@@ -522,6 +522,69 @@ gld${EMULATION_NAME}_add_sysroot (const 
 
 EOF
   case ${target} in
+    *-*-freebsd*)
+      cat >>e${EMULATION_NAME}.c <<EOF
+/*
+ * Read the system search path the FreeBSD way rather than like Linux.
+ */
+#include <elf-hints.h>
+
+static bfd_boolean
+gld${EMULATION_NAME}_check_ld_elf_hints (struct dt_needed *n, int force)
+{
+  const char *name = n->name;
+  static bfd_boolean initialized;
+  static char *ld_elf_hints;
+
+  if (! initialized)
+    {
+      FILE *f;
+      char *tmppath;
+
+      tmppath = concat (ld_sysroot, _PATH_ELF_HINTS, NULL);
+      f = fopen (tmppath, FOPEN_RB);
+      free (tmppath);
+      if (f != NULL)
+	{
+	  struct elfhints_hdr hdr;
+
+	  if (fread(&hdr, 1, sizeof(hdr), f) == sizeof(hdr) &&
+	      hdr.magic == ELFHINTS_MAGIC &&
+	      hdr.version == 1)
+	    {
+	      if (fseek(f, hdr.strtab + hdr.dirlist, SEEK_SET) != -1)
+		{
+		  char *b;
+
+		  b = (char *) xmalloc (hdr.dirlistlen + 1);
+		  if (fread(b, 1, hdr.dirlistlen + 1, f) !=
+		      hdr.dirlistlen + 1)
+		    {
+		      free(b);
+		      b = NULL;
+		    }
+		  else
+		    {
+		      ld_elf_hints = gld${EMULATION_NAME}_add_sysroot (b);
+		      free (b);
+		    }
+		}
+	    }
+	  fclose (f);
+	}
+
+      initialized = TRUE;
+    }
+
+  if (ld_elf_hints == NULL)
+    return FALSE;
+
+  return gld${EMULATION_NAME}_search_needed (ld_elf_hints, n, force);
+}
+EOF
+    # FreeBSD
+    ;;
+
     *-*-linux-gnu*)
       cat >>e${EMULATION_NAME}.c <<EOF
 /* For a native linker, check the file /etc/ld.so.conf for directories
@@ -932,6 +995,14 @@ cat >>e${EMULATION_NAME}.c <<EOF
 EOF
 if [ "x${USE_LIBPATH}" = xyes ] ; then
   case ${target} in
+    *-*-freebsd*)
+      cat >>e${EMULATION_NAME}.c <<EOF
+	  if (gld${EMULATION_NAME}_check_ld_elf_hints (&n, force))
+	    break;
+EOF
+    # FreeBSD
+    ;;
+
     *-*-linux-gnu*)
       cat >>e${EMULATION_NAME}.c <<EOF
 	  if (gld${EMULATION_NAME}_check_ld_so_conf (l->name, force))
Index: binutils-2.16.91.0.6/ld/Makefile.in
===================================================================
--- binutils-2.16.91.0.6.orig/ld/Makefile.in
+++ binutils-2.16.91.0.6/ld/Makefile.in
@@ -446,6 +446,7 @@ ALL_EMULATIONS = \
 	ei386beos.o \
 	ei386bsd.o \
 	ei386coff.o \
+	ei386freebsd.o \
 	ei386go32.o \
 	ei386linux.o \
 	ei386lynx.o \
@@ -1795,6 +1796,9 @@ ei386bsd.c: $(srcdir)/emulparams/i386bsd
 ei386coff.c: $(srcdir)/emulparams/i386coff.sh \
   $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/i386coff.sc ${GEN_DEPENDS}
 	${GENSCRIPTS} i386coff "$(tdir_i386coff)"
+ei386freebsd.c: $(srcdir)/emulparams/i386freebsd.sh \
+  $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
+	${GENSCRIPTS} i386freebsd "$(tdir_i386freebsd)"
 ei386go32.c: $(srcdir)/emulparams/i386go32.sh \
   $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/i386go32.sc ${GEN_DEPENDS}
 	${GENSCRIPTS} i386go32 "$(tdir_i386go32)"
Index: binutils-2.16.91.0.6/ld/emulparams/i386freebsd.sh
===================================================================
--- /dev/null
+++ binutils-2.16.91.0.6/ld/emulparams/i386freebsd.sh
@@ -0,0 +1,6 @@
+SCRIPT_NAME=aout
+TEXT_START_ADDR=0x1020
+OUTPUT_FORMAT="a.out-i386-freebsd"
+TARGET_PAGE_SIZE=0x1000
+ARCH=i386
+EXECUTABLE_SYMBOLS='__DYNAMIC = 0;'
Index: binutils-2.16.91.0.6/ld/emultempl/elf32.em
===================================================================
--- binutils-2.16.91.0.6.orig/ld/emultempl/elf32.em
+++ binutils-2.16.91.0.6/ld/emultempl/elf32.em
@@ -529,6 +529,69 @@ gld${EMULATION_NAME}_add_sysroot (const 
 
 EOF
   case ${target} in
+    *-*-freebsd*)
+      cat >>e${EMULATION_NAME}.c <<EOF
+/*
+ * Read the system search path the FreeBSD way rather than like Linux.
+ */
+#include <elf-hints.h>
+
+static bfd_boolean
+gld${EMULATION_NAME}_check_ld_elf_hints (struct dt_needed *n, int force)
+{
+  const char *name = n->name;
+  static bfd_boolean initialized;
+  static char *ld_elf_hints;
+
+  if (! initialized)
+    {
+      FILE *f;
+      char *tmppath;
+
+      tmppath = concat (ld_sysroot, _PATH_ELF_HINTS, NULL);
+      f = fopen (tmppath, FOPEN_RB);
+      free (tmppath);
+      if (f != NULL)
+	{
+	  struct elfhints_hdr hdr;
+
+	  if (fread(&hdr, 1, sizeof(hdr), f) == sizeof(hdr) &&
+	      hdr.magic == ELFHINTS_MAGIC &&
+	      hdr.version == 1)
+	    {
+	      if (fseek(f, hdr.strtab + hdr.dirlist, SEEK_SET) != -1)
+		{
+		  char *b;
+
+		  b = (char *) xmalloc (hdr.dirlistlen + 1);
+		  if (fread(b, 1, hdr.dirlistlen + 1, f) !=
+		      hdr.dirlistlen + 1)
+		    {
+		      free(b);
+		      b = NULL;
+		    }
+		  else
+		    {
+		      ld_elf_hints = gld${EMULATION_NAME}_add_sysroot (b);
+		      free (b);
+		    }
+		}
+	    }
+	  fclose (f);
+	}
+
+      initialized = TRUE;
+    }
+
+  if (ld_elf_hints == NULL)
+    return FALSE;
+
+  return gld${EMULATION_NAME}_search_needed (ld_elf_hints, n, force);
+}
+EOF
+    # FreeBSD
+    ;;
+
     *-*-linux-* | *-*-k*bsd*-*)
       cat >>e${EMULATION_NAME}.c <<EOF
 /* For a native linker, check the file /etc/ld.so.conf for directories
@@ -921,6 +984,14 @@ EOF
 fi
 if [ "x${USE_LIBPATH}" = xyes ] ; then
   case ${target} in
+    *-*-freebsd*)
+      cat >>e${EMULATION_NAME}.c <<EOF
+	  if (gld${EMULATION_NAME}_check_ld_elf_hints (&n, force))
+	    break;
+EOF
+    # FreeBSD
+    ;;
+
     *-*-linux-* | *-*-k*bsd*-*)
     # Linux
       cat >>e${EMULATION_NAME}.c <<EOF

Attachment: pgp00000.pgp
Description: PGP signature


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]