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]

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


On Monday 20 February 2006 21:13, Daniel Jacobowitz wrote:
> What's supposed to happen is that we have a sysroot for the target
> FreeBSD system, possibly including a hints file. ?See /etc/ld.so.conf
> handling for GNU/Linux for a parallel; as far as I can tell this is
> the same behavior you want.
Okay I hope i got this right this time. Unfortunately being a binary file, it 
will fail if the endianness of the sysroot's hints file is different from the 
endianness of the building system.

By the way, seems to me that ld.so.conf is ignored on GNU/Linux, at least if I 
try to link to a non-existant libfoo, ld --verbose shows me only checks 
inside the paths defined at compile time (SEARCH_DIRS) and the ones given by 
command line (-L...), not for the paths defined in ld.so.conf (while it shows 
them on FreeBSD with this patch).

-- 
Diego "Flameeyes" Pettenò - http://dev.gentoo.org/~flameeyes/
Gentoo/ALT lead, Gentoo/FreeBSD, Video, AMD64, Sound, PAM, KDE
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,95 @@ 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.
+ */
+#ifdef HAVE_ELF_HINTS_H
+#include <elf-hints.h>
+#else
+ /*
+  * Fallback code took from FreeBSD's libc
+  * Copyright (c) 1997 John D. Polstra.
+  *
+  * This works only if the hints file is generated with a compatible version
+  * of ldconfig (most FreeBSD up to 6.1 and DragonFly at least up to 1.4),
+  * and with the same endianness.
+  */
+
+  struct elfhints_hdr {
+        u_int32_t       magic;          /* Magic number */
+        u_int32_t       version;        /* File version (1) */
+        u_int32_t       strtab;         /* Offset of string table in file */
+        u_int32_t       strsize;        /* Size of string table */
+        u_int32_t       dirlist;        /* Offset of directory list in
+                                           string table */
+        u_int32_t       dirlistlen;     /* strlen(dirlist) */
+        u_int32_t       spare[26];      /* Room for expansion */
+  };
+
+  #define ELFHINTS_MAGIC  0x746e6845
+
+  #define _PATH_ELF_HINTS "/var/run/ld-elf.so.hints"
+#endif
+
+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 +1010,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
Index: binutils-2.16.91.0.6/ld/configure.in
===================================================================
--- binutils-2.16.91.0.6.orig/ld/configure.in
+++ binutils-2.16.91.0.6/ld/configure.in
@@ -99,7 +99,7 @@ AC_SUBST(HOSTING_CRT0)
 AC_SUBST(HOSTING_LIBS)
 AC_SUBST(NATIVE_LIB_DIRS)
 
-AC_CHECK_HEADERS(string.h strings.h stdlib.h unistd.h)
+AC_CHECK_HEADERS(string.h strings.h stdlib.h unistd.h elf-hints.h)
 AC_CHECK_FUNCS(sbrk realpath glob)
 AC_HEADER_DIRENT
 
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,95 @@ 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.
+ */
+#ifdef HAVE_ELF_HINTS_H
+#include <elf-hints.h>
+#else
+ /*
+  * Fallback code took from FreeBSD's libc
+  * Copyright (c) 1997 John D. Polstra.
+  *
+  * This works only if the hints file is generated with a compatible version
+  * of ldconfig (most FreeBSD up to 6.1 and DragonFly at least up to 1.4),
+  * and with the same endianness.
+  */
+
+  struct elfhints_hdr {
+        u_int32_t       magic;          /* Magic number */
+        u_int32_t       version;        /* File version (1) */
+        u_int32_t       strtab;         /* Offset of string table in file */
+        u_int32_t       strsize;        /* Size of string table */
+        u_int32_t       dirlist;        /* Offset of directory list in
+                                           string table */
+        u_int32_t       dirlistlen;     /* strlen(dirlist) */
+        u_int32_t       spare[26];      /* Room for expansion */
+  };
+
+  #define ELFHINTS_MAGIC  0x746e6845
+
+  #define _PATH_ELF_HINTS "/var/run/ld-elf.so.hints"
+#endif
+
+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 +1021,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.1/ld/configure.in
===================================================================
--- binutils-2.16.1.orig/ld/configure.in
+++ binutils-2.16.1/ld/configure.in
@@ -118,7 +118,7 @@ AC_SUBST(HOSTING_CRT0)
 AC_SUBST(HOSTING_LIBS)
 AC_SUBST(NATIVE_LIB_DIRS)
 
-AC_CHECK_HEADERS(string.h strings.h stdlib.h unistd.h)
+AC_CHECK_HEADERS(string.h strings.h stdlib.h unistd.h elf-hints.h)
 AC_CHECK_FUNCS(sbrk realpath glob)
 AC_HEADER_DIRENT
 

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]