Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/gnu/dist/ld/emultempl a.out shared lib support.



details:   https://anonhg.NetBSD.org/src/rev/aaf0bd97eca3
branches:  trunk
changeset: 485754:aaf0bd97eca3
user:      kristerw <kristerw%NetBSD.org@localhost>
date:      Thu May 04 19:09:55 2000 +0000

description:
a.out shared lib support.

Note: it uses libbfd functionality that have not been committed yet.

diffstat:

 gnu/dist/ld/emultempl/netbsdaout.em |  974 ++++++++++++++++++++++++++++++++++++
 1 files changed, 974 insertions(+), 0 deletions(-)

diffs (truncated from 978 to 300 lines):

diff -r b412f2de6ea4 -r aaf0bd97eca3 gnu/dist/ld/emultempl/netbsdaout.em
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/gnu/dist/ld/emultempl/netbsdaout.em       Thu May 04 19:09:55 2000 +0000
@@ -0,0 +1,974 @@
+# This shell script emits a C file. -*- C -*-
+# It does some substitutions.
+cat >e${EMULATION_NAME}.c <<EOF
+/* This file is is generated by a shell script.  DO NOT EDIT! */
+
+/* NetBSD emulation code for ${EMULATION_NAME}
+   Copyright (C) 1991, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
+   Written by Steve Chamberlain <sac%cygnus.com@localhost>
+   SunOS shared library support by Ian Lance Taylor <ian%cygnus.com@localhost>
+   NetBSD changes by Krister Walfridsson <cato%df.lth.se@localhost>
+
+This file is part of GLD, the Gnu Linker.
+
+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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#define TARGET_IS_${EMULATION_NAME}
+
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "bfdlink.h"
+#include "libiberty.h"
+
+#include "ld.h"
+#include "ldmain.h"
+#include "ldemul.h"
+#include "ldfile.h"
+#include "ldmisc.h"
+#include "ldexp.h"
+#include "ldlang.h"
+
+#ifdef HAVE_DIRENT_H
+# include <dirent.h>
+#else
+# define dirent direct
+# ifdef HAVE_SYS_NDIR_H
+#  include <sys/ndir.h>
+# endif
+# ifdef HAVE_SYS_DIR_H
+#  include <sys/dir.h>
+# endif
+# ifdef HAVE_NDIR_H
+#  include <ndir.h>
+# endif
+#endif
+
+static void gld${EMULATION_NAME}_before_parse PARAMS ((void));
+static void gld${EMULATION_NAME}_set_symbols PARAMS ((void));
+static void gld${EMULATION_NAME}_create_output_section_statements
+  PARAMS ((void));
+static void gld${EMULATION_NAME}_find_so
+  PARAMS ((lang_input_statement_type *));
+static char *gld${EMULATION_NAME}_search_dir
+  PARAMS ((const char *, const char *, boolean *));
+static void gld${EMULATION_NAME}_after_open PARAMS ((void));
+static void gld${EMULATION_NAME}_check_needed
+  PARAMS ((lang_input_statement_type *));
+static boolean gld${EMULATION_NAME}_search_needed
+  PARAMS ((const char *, const char *));
+static boolean gld${EMULATION_NAME}_try_needed
+  PARAMS ((const char *, const char *));
+static void gld${EMULATION_NAME}_before_allocation PARAMS ((void));
+static void gld${EMULATION_NAME}_find_assignment
+  PARAMS ((lang_statement_union_type *));
+static void gld${EMULATION_NAME}_find_exp_assignment PARAMS ((etree_type *));
+static void gld${EMULATION_NAME}_count_need
+  PARAMS ((lang_input_statement_type *));
+static void gld${EMULATION_NAME}_set_need
+  PARAMS ((lang_input_statement_type *));
+static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
+
+static void
+gld${EMULATION_NAME}_before_parse()
+{
+  ldfile_output_architecture = bfd_arch_${ARCH};
+  config.dynamic_link = true;
+}
+
+/* This is called after the command line arguments have been parsed,
+   but before the linker script has been read.  If this is a native
+   linker, we add the directories in LD_LIBRARY_PATH to the search
+   list.  */
+
+static void
+gld${EMULATION_NAME}_set_symbols ()
+{
+EOF
+if [ "x${host}" = "x${target}" ] ; then
+  if [ "x${DEFAULT_EMULATION}" = "x${EMULATION_NAME}" ] ; then
+cat >>e${EMULATION_NAME}.c <<EOF
+  const char *env;
+
+  env = (const char *) getenv ("LD_LIBRARY_PATH");
+  if (env != NULL)
+    {
+      char *l;
+
+      l = xstrdup (env);
+      while (1)
+       {
+         char *c;
+
+         c = strchr (l, ':');
+         if (c != NULL)
+           *c++ = '\0';
+         if (*l != '\0')
+           ldfile_add_library_path (l, false);
+         if (c == NULL)
+           break;
+         l = c;
+       }
+    }
+EOF
+  fi
+fi
+cat >>e${EMULATION_NAME}.c <<EOF
+}
+
+/* Despite the name, we use this routine to search for dynamic
+   libraries.  On NetBSD this requires a directory search.  We need to
+   find the .so file with the highest version number.  The user may
+   restrict the major version by saying, e.g., -lc.1.  */
+
+static void
+gld${EMULATION_NAME}_create_output_section_statements ()
+{
+  lang_for_each_input_file (gld${EMULATION_NAME}_find_so);
+}
+
+/* Search the directory for a .so file for each library search.  */
+
+static void
+gld${EMULATION_NAME}_find_so (inp)
+     lang_input_statement_type *inp;
+{
+  search_dirs_type *search;
+  char *found;
+  char *alc;
+  struct stat st;
+
+  if (! inp->search_dirs_flag
+      || ! inp->is_archive
+      || ! inp->dynamic)
+    return;
+
+  ASSERT (strncmp (inp->local_sym_name, "-l", 2) == 0);
+
+  for (search = search_head; search != NULL; search = search->next)
+    {
+      boolean found_static;
+
+      found = gld${EMULATION_NAME}_search_dir (search->name, inp->filename,
+                                              &found_static);
+      if (found != NULL || found_static)
+       break;
+    }
+
+  if (found == NULL)
+    {
+      /* We did not find a matching .so file.  This isn't an error,
+        since there might still be a matching .a file, which will be
+        found by the usual search.  */
+      return;
+    }
+
+  /* Replace the filename with the one we have found.  */
+  alc = (char *) xmalloc (strlen (search->name) + strlen (found) + 2);
+  sprintf (alc, "%s/%s", search->name, found);
+  inp->filename = alc;
+
+  /* We are only interested in the symbols. */
+  inp->just_syms_flag = true;
+
+  /* Turn off the search_dirs_flag to prevent ldfile_open_file from
+     searching for this file again.  */
+  inp->search_dirs_flag = false;
+
+  free (found);
+}
+
+/* Search a directory for a .so file.  */
+
+static char *
+gld${EMULATION_NAME}_search_dir (dirname, filename, found_static)
+     const char *dirname;
+     const char *filename;
+     boolean *found_static;
+{
+  int force_maj, force_min;
+  const char *dot;
+  unsigned int len;
+  char *alc;
+  char *found;
+  int max_maj, max_min;
+  DIR *dir;
+  struct dirent *entry;
+
+  *found_static = false;
+
+  force_maj = -1;
+  force_min = -1;
+  dot = strchr (filename, '.');
+  if (dot == NULL)
+    {
+      len = strlen (filename);
+      alc = NULL;
+    }
+  else
+    {
+      force_maj = atoi (dot + 1);
+
+      len = dot - filename;
+      alc = (char *) xmalloc (len + 1);
+      strncpy (alc, filename, len);
+      alc[len] = '\0';
+      filename = alc;
+
+      dot = strchr (dot + 1, '.');
+      if (dot != NULL)
+       force_min = atoi (dot + 1);
+    }
+
+  found = NULL;
+  max_maj = max_min = 0;
+
+  dir = opendir (dirname);
+  if (dir == NULL)
+    return NULL;
+  
+  while ((entry = readdir (dir)) != NULL)
+    {
+      const char *s;
+      int found_maj, found_min;
+
+      if (strncmp (entry->d_name, "lib", 3) != 0
+         || strncmp (entry->d_name + 3, filename, len) != 0)
+       continue;
+
+      if (dot == NULL
+         && strcmp (entry->d_name + 3 + len, ".a") == 0)
+       {
+         *found_static = true;
+         continue;
+       }
+
+      /* We accept libfoo.so without a version number, even though the
+         native linker does not.  This is more convenient for packages
+         which just generate .so files for shared libraries, as on ELF
+         systems.  */
+      if (strncmp (entry->d_name + 3 + len, ".so", 3) != 0)
+       continue;
+      if (entry->d_name[6 + len] == '\0')
+       ;
+      else if (entry->d_name[6 + len] == '.'
+              && isdigit (entry->d_name[7 + len]))
+       ;
+      else
+       continue;
+
+      for (s = entry->d_name + 6 + len; *s != '\0'; s++)
+       if (*s != '.' && ! isdigit (*s))
+         break;
+      if (*s != '\0')
+       continue;
+
+      /* We've found a .so file.  Work out the major and minor
+        version numbers.  */
+      found_maj = 0;
+      found_min = 0;
+      sscanf (entry->d_name + 3 + len, ".so.%d.%d",
+             &found_maj, &found_min);
+
+      if ((force_maj != -1 && force_maj != found_maj)
+         || (force_min != -1 && force_min != found_min))
+       continue;
+
+      /* We've found a match for the name we are searching for.  See
+        if this is the version we should use.  If the major and minor
+        versions match, we use the last entry in alphabetical order.  */
+      if (found == NULL
+         || (found_maj > max_maj)



Home | Main Index | Thread Index | Old Index