public inbox for gas2@sourceware.org
 help / color / mirror / Atom feed
* A new ld patch
@ 1995-05-02 21:23 H.J. Lu
  0 siblings, 0 replies; only message in thread
From: H.J. Lu @ 1995-05-02 21:23 UTC (permalink / raw)
  To: Ken Raeburn; +Cc: gas2

This patch added the support fo -Bstatic -lfoo -Bdynamic -lbar. It
also fixed the -Lxxxxx bug.


H.J.
------
Tue May  2 00:22:54 1995  H.J. Lu (hjl@nynexst.com)

	* Makefile.in: fix a typo in comments.
	  (NO_DEFAULT_WRITABLE_TEXT_SEGMENT): unset.
	  (GENSCRIPTS): add "${NO_DEFAULT_WRITABLE_TEXT_SEGMENT}"
	  and "${LIB_PATH}".

	* genscripts.sh (LIB_PATH): set to $7.
	  (NO_DEFAULT_WRITABLE_TEXT_SEGMENT): set to $8.
	  (EMULATION_NAME): set to $9.
	  don't include the native ${LIB_PATH} for non-native
	  emulation.

	* ldfile.c (try_open_bfd): make it global.
	  (ldfile_open_file): check entry->dynamic_link instead of
	  config.dynamic_link.

	* ldlang.h (lang_input_statement_type): add 

		boolean dynamic_link;

	* lexsup.c (parse_args): add

		boolean last_is_dynamic_link = config.dynamic_link;

	  (OPTION_CALL_SHARED): set

		last_is_dynamic_link = true;

	  (OPTION_NON_SHARED): set

		last_is_dynamic_link = false;

	  ('l'): set the dynamic_link field of the library entry
	  to last_is_dynamic_link.
	  Those changes add the -Bstaic -lfoo -Bdynamic -lbar support
	  to ld.

	* config/i386-linux.mt (NO_DEFAULT_WRITABLE_TEXT_SEGMENT): set
	  to y.

	* emultempl/elf32.em: add

		#include <dirent.h>.

	  (libcmp): new function, compare two shared libraries and
	  return the order.
	  (gld${EMULATION_NAME}_find_so): new, static. search for
	  open the .so file specified by ENTRY until a match .so or .a
	  file is found.
	  (gld${EMULATION_NAME}_open_dynamic_archive): call
	  gld${EMULATION_NAME}_find_so () to find the shared
	  library.
	  use entry->filename for needed_name.

	* scripttempl/elf.sc (DATA_ALIGN): if
	  NO_DEFAULT_WRITABLE_TEXT_SEGMENT is 'y' or 'Y', set to

		${DATA_ADDR-ALIGN(${MAXPAGESIZE}) + \
		((ALIGN(8) + ${MAXPAGESIZE} - \
		ALIGN(${MAXPAGESIZE})) & (${MAXPAGESIZE} - 1))}

	  or set to

		${DATA_ADDR- ALIGN(8) + ${MAXPAGESIZE}}

===================================================================
RCS file: /home/cvs/gnu/binutils/ld/Makefile.in,v
retrieving revision 1.1.1.3
diff -c -r1.1.1.3 Makefile.in
*** 1.1.1.3	1995/04/17 23:41:03
--- Makefile.in	1995/05/03 02:50:15
***************
*** 66,74 ****
  BISON = `if [ -f ../bison/bison ] ; then echo ../bison/bison -y -L../bison/bison ; else echo bison -y ; fi`
  LEX = `if [ -f ../flex/flex ] ; then echo ../flex/flex ;  else echo flex ; fi`
  
  # Seach path to override the default search path for -lfoo libraries.
  # If LIB_PATH is empty, the ones in the script (if any) are left alone.
! # (The default is usually /lib:usr/lib:/usr/local/lib, unless building
  # a cross-linker, in which case the default is empty.  See genscripts.sh.)
  # Otherwise, they are replaced with the ones given in LIB_PATH,
  # which may have the form: LIB_PATH=/lib:/usr/local/lib
--- 66,77 ----
  BISON = `if [ -f ../bison/bison ] ; then echo ../bison/bison -y -L../bison/bison ; else echo bison -y ; fi`
  LEX = `if [ -f ../flex/flex ] ; then echo ../flex/flex ;  else echo flex ; fi`
  
+ # This is for the ELF emulation scripts.
+ NO_DEFAULT_WRITABLE_TEXT_SEGMENT=
+ 
  # Seach path to override the default search path for -lfoo libraries.
  # If LIB_PATH is empty, the ones in the script (if any) are left alone.
! # (The default is usually /lib:/usr/lib:/usr/local/lib, unless building
  # a cross-linker, in which case the default is empty.  See genscripts.sh.)
  # Otherwise, they are replaced with the ones given in LIB_PATH,
  # which may have the form: LIB_PATH=/lib:/usr/local/lib
***************
*** 273,279 ****
  
  # These all start with e so 'make clean' can find them.
  
! GENSCRIPTS = $(SHELL) $(srcdir)/genscripts.sh ${srcdir} ${libdir} ${host_alias} ${target_alias} ${EMUL} "$(NATIVE_LIB_DIRS)"
  GEN_DEPENDS = $(srcdir)/genscripts.sh $(srcdir)/emultempl/stringify.sed
  
  esun4.c: $(srcdir)/emulparams/sun4.sh \
--- 276,282 ----
  
  # These all start with e so 'make clean' can find them.
  
! GENSCRIPTS = $(SHELL) $(srcdir)/genscripts.sh ${srcdir} ${libdir} ${host_alias} ${target_alias} ${EMUL} "$(NATIVE_LIB_DIRS)" "${LIB_PATH}" "${NO_DEFAULT_WRITABLE_TEXT_SEGMENT}"
  GEN_DEPENDS = $(srcdir)/genscripts.sh $(srcdir)/emultempl/stringify.sed
  
  esun4.c: $(srcdir)/emulparams/sun4.sh \
===================================================================
RCS file: /home/cvs/gnu/binutils/ld/genscripts.sh,v
retrieving revision 1.1.1.3
diff -c -r1.1.1.3 genscripts.sh
*** 1.1.1.3	1995/03/24 02:20:37
--- genscripts.sh	1995/05/03 02:50:15
***************
*** 15,21 ****
  target_alias=$4
  DEFAULT_EMULATION=$5
  NATIVE_LIB_DIRS=$6
! EMULATION_NAME=$7
  
  # Include the emulation-specific parameters:
  . ${srcdir}/emulparams/${EMULATION_NAME}.sh
--- 15,23 ----
  target_alias=$4
  DEFAULT_EMULATION=$5
  NATIVE_LIB_DIRS=$6
! LIB_PATH=$7
! NO_DEFAULT_WRITABLE_TEXT_SEGMENT=$8
! EMULATION_NAME=$9
  
  # Include the emulation-specific parameters:
  . ${srcdir}/emulparams/${EMULATION_NAME}.sh
***************
*** 52,58 ****
  fi
  
  # Always search $(tooldir)/lib, aka /usr/local/TARGET/lib.
! LIB_PATH=${LIB_PATH}:`echo ${libdir} | sed -e s'|/lib$||'`/${target_alias}/lib
  
  LIB_SEARCH_DIRS=`echo ${LIB_PATH} | tr ':' ' ' | sed -e 's/\([^ ][^ ]*\)/SEARCH_DIR(\1);/g'`
  
--- 54,65 ----
  fi
  
  # Always search $(tooldir)/lib, aka /usr/local/TARGET/lib.
! if [ $DEFAULT_EMULATION = $EMULATION_NAME ]; then
!   LIB_PATH=${LIB_PATH}:`echo ${libdir} | sed -e s'|/lib$||'`/${target_alias}/lib
! else
!   # This is not correct one since this is for a different target.
!   LIB_PATH=`echo ${libdir} | sed -e s'|/lib$||'`/${target_alias}/lib
! fi
  
  LIB_SEARCH_DIRS=`echo ${LIB_PATH} | tr ':' ' ' | sed -e 's/\([^ ][^ ]*\)/SEARCH_DIR(\1);/g'`
  
===================================================================
RCS file: /home/cvs/gnu/binutils/ld/ldfile.c,v
retrieving revision 1.1.1.3
diff -c -r1.1.1.3 ldfile.c
*** 1.1.1.3	1995/04/15 00:06:18
--- ldfile.c	1995/05/03 00:46:00
***************
*** 68,74 ****
  static search_arch_type *search_arch_head;
  static search_arch_type **search_arch_tail_ptr = &search_arch_head;
   
! static boolean try_open_bfd PARAMS ((const char *attempt,
  				     lang_input_statement_type *entry));
  static FILE *try_open PARAMS ((const char *name, const char *exten));
  
--- 68,74 ----
  static search_arch_type *search_arch_head;
  static search_arch_type **search_arch_tail_ptr = &search_arch_head;
   
! boolean try_open_bfd PARAMS ((const char *attempt,
  				     lang_input_statement_type *entry));
  static FILE *try_open PARAMS ((const char *name, const char *exten));
  
***************
*** 89,95 ****
  
  /* Try to open a BFD for a lang_input_statement.  */
  
! static boolean
  try_open_bfd (attempt, entry)
       const char *attempt;
       lang_input_statement_type *entry;
--- 89,95 ----
  
  /* Try to open a BFD for a lang_input_statement.  */
  
! boolean
  try_open_bfd (attempt, entry)
       const char *attempt;
       lang_input_statement_type *entry;
***************
*** 183,189 ****
  	   arch != (search_arch_type *) NULL;
  	   arch = arch->next)
  	{
! 	  if (config.dynamic_link)
  	    {
  	      if (ldemul_open_dynamic_archive (arch->name, entry))
  		return;
--- 183,189 ----
  	   arch != (search_arch_type *) NULL;
  	   arch = arch->next)
  	{
! 	  if (entry->dynamic_link)
  	    {
  	      if (ldemul_open_dynamic_archive (arch->name, entry))
  		return;
===================================================================
RCS file: /home/cvs/gnu/binutils/ld/ldlang.h,v
retrieving revision 1.1.1.2
diff -c -r1.1.1.2 ldlang.h
*** 1.1.1.2	1995/02/22 02:02:31
--- ldlang.h	1995/05/03 00:46:01
***************
*** 229,234 ****
--- 229,237 ----
    asection *common_section;
    asection *common_output_section;
    boolean complained;
+ 
+   /* This is used to overwrite the global one. */
+   boolean dynamic_link;
  } lang_input_statement_type;
  
  typedef struct
===================================================================
RCS file: /home/cvs/gnu/binutils/ld/lexsup.c,v
retrieving revision 1.1.1.3
diff -c -r1.1.1.3 lexsup.c
*** 1.1.1.3	1995/03/24 02:20:43
--- lexsup.c	1995/05/03 03:43:14
***************
*** 53,58 ****
--- 53,60 ----
  {
    int ingroup = 0;
  
+   boolean last_is_dynamic_link = config.dynamic_link;
+ 
    /* Starting the short option string with '-' is for programs that
       expect options and other ARGV-elements in any order and that care about
       the ordering of the two.  We describe each non-option ARGV-element
***************
*** 193,201 ****
--- 195,205 ----
  	  break;
  	case OPTION_CALL_SHARED:
  	  config.dynamic_link = true;
+ 	  last_is_dynamic_link = true;
  	  break;
  	case OPTION_NON_SHARED:
  	  config.dynamic_link = false;
+ 	  last_is_dynamic_link = false;
  	  break;
  	case 'd':
  	  command_line.force_common_definition = true;
***************
*** 246,252 ****
  	  break;
  	case 'l':
  	  lang_add_input_file (optarg, lang_input_file_is_l_enum,
! 			       (char *) NULL);
  	  break;
  	case 'M':
  	  config.map_filename = "-";
--- 250,257 ----
  	  break;
  	case 'l':
  	  lang_add_input_file (optarg, lang_input_file_is_l_enum,
! 			       (char *) NULL)->dynamic_link
! 			       = last_is_dynamic_link;
  	  break;
  	case 'M':
  	  config.map_filename = "-";
===================================================================
RCS file: /home/cvs/gnu/binutils/ld/config/i386-linux.mt,v
retrieving revision 1.1.1.2
diff -c -r1.1.1.2 i386-linux.mt
*** 1.1.1.2	1995/04/01 00:53:35
--- i386-linux.mt	1995/05/03 02:50:16
***************
*** 1,2 ****
--- 1,3 ----
  EMUL=elf_i386
  EMUL_EXTRA1=i386linux
+ NO_DEFAULT_WRITABLE_TEXT_SEGMENT=y
===================================================================
RCS file: /home/cvs/gnu/binutils/ld/emultempl/elf32.em,v
retrieving revision 1.1.1.3
diff -c -r1.1.1.3 elf32.em
*** 1.1.1.3	1995/03/04 19:23:54
--- elf32.em	1995/05/03 00:46:03
***************
*** 43,48 ****
--- 43,55 ----
  #include "ldlang.h"
  #include "ldgram.h"
  
+  
+ /* FIXME: On some hosts we will need to include a different file.
+    This is correct for ELF/SVR4, which is the only place this file will
+    typically be compiled.  However, if somebody configures the linker
+    for all targets, they will run into trouble here.  */
+ #include <dirent.h>
+ 
  static void gld${EMULATION_NAME}_before_parse PARAMS ((void));
  static boolean gld${EMULATION_NAME}_open_dynamic_archive
    PARAMS ((const char *, lang_input_statement_type *));
***************
*** 55,60 ****
--- 62,71 ----
  static void gld${EMULATION_NAME}_place_section
    PARAMS ((lang_statement_union_type *));
  static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
+ static boolean gld${EMULATION_NAME}_find_so PARAMS ((lang_input_statement_type *entry));
+ 
+ extern boolean try_open_bfd PARAMS ((const char *attempt,
+ 		lang_input_statement_type *entry));
  
  static void
  gld${EMULATION_NAME}_before_parse()
***************
*** 63,68 ****
--- 74,200 ----
    config.dynamic_link = ${DYNAMIC_LINK-true};
  }
  
+ /* figure out which library is greater */
+ static int libcmp(p1, p2)
+   char *p1, *p2;
+ {
+     while (*p1)
+     {
+ 	if (isdigit(*p1) && isdigit(*p2))
+ 	{
+ 	    /* must compare this numerically */
+ 	    int v1, v2;
+ 	    v1 = strtoul(p1, &p1, 10);
+ 	    v2 = strtoul(p2, &p2, 10);
+ 	    if (v1 != v2)
+ 		return v1 - v2;
+ 	}
+ 	else if (*p1 != *p2)
+ 	    return *p1 - *p2;
+ 	else
+ 	    p1++, p2++;
+     }
+ 
+     return *p1 - *p2;
+ }
+ 
+ /* Search for and open the .so file specified by ENTRY until
+    a match .so or .a file is found. H.J. */
+ static boolean
+ gld${EMULATION_NAME}_find_so (entry)
+      lang_input_statement_type *entry;
+ {
+   search_dirs_type *search;
+   char *filename;
+   unsigned int len;
+   char *found;
+   boolean found_static;
+ 
+   found_static = false;
+   found = NULL;
+   filename = (char *) entry->filename;
+   len = strlen (filename);
+   for (search = search_head;
+        search != (search_dirs_type *)NULL;
+        search = search->next) 
+   {
+     DIR *dir;
+     struct dirent *ent;
+ 
+     /* We try this directory. */
+     dir = opendir (search->name);
+     if (dir == NULL)
+       continue;
+ 
+     while ((ent = readdir (dir)) != NULL)
+     {
+       /* We are looking for libxxxx.*. */
+       if (ent->d_name [len + 3] != '.'
+ 	  || strncmp (ent->d_name, "lib", 3) != 0
+ 	  || strncmp (ent->d_name + 3, filename, len) != 0)
+ 	continue;
+ 
+       if (strncmp (ent->d_name + 3 + len, ".a", 2) == 0)
+       {
+ 	found_static = true;
+ 	continue;
+       }
+ 
+       if (strncmp (ent->d_name + 3 + len, ".so", 3) != 0)
+ 	continue;
+ 
+       /* We've found a lib*.so.x.x.x file. We compare it with the
+ 	 one we have found if there is one. */
+       if (found == NULL)
+       {
+ 	found = (char *) xmalloc (strlen (ent->d_name) + 1);
+ 	strcpy (found, ent->d_name);
+       }
+       else
+       {
+ 	if (libcmp (&ent->d_name [len + 6], &found [len + 6]) > 0)
+ 	{
+ 	  free (found);
+ 	  found = (char *) xmalloc (strlen (ent->d_name) + 1);
+ 	  strcpy (found, ent->d_name);
+ 	}
+       }
+     }
+ 
+     closedir (dir);
+ 
+     /* We find a shared or static library. */
+     if (found != NULL || found_static == true)
+       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 false;
+   }
+ 
+   filename = (char *) xmalloc (strlen (search->name)
+ 	+ strlen (found) + 2);
+   sprintf (filename, "%s/%s", search->name, found);
+ 
+   free (found);
+ 
+   /* Give it a try */
+   if (try_open_bfd (filename, entry)) 
+   {
+     entry->filename = filename;
+     return true;
+   }
+   else
+   {
+     free (filename);
+     return false;
+   }
+ }
+ 
  /* Try to open a dynamic archive.  This is where we know that ELF
     dynamic libraries have an extension of .so.  */
  
***************
*** 71,81 ****
       const char *arch;
       lang_input_statement_type *entry;
  {
!   const char *filename;
! 
!   filename = entry->filename;
! 
!   if (! ldfile_open_file_search (arch, entry, "lib", ".so"))
      return false;
  
    /* We have found a dynamic object to include in the link.  The ELF
--- 203,209 ----
       const char *arch;
       lang_input_statement_type *entry;
  {
!   if (gld${EMULATION_NAME}_find_so (entry) == false)
      return false;
  
    /* We have found a dynamic object to include in the link.  The ELF
***************
*** 95,106 ****
        && (entry->the_bfd->flags & DYNAMIC) != 0)
      {
        char *needed_name;
  
        ASSERT (entry->is_archive && entry->search_dirs_flag);
!       needed_name = (char *) xmalloc (strlen (filename)
! 				      + strlen (arch)
! 				      + sizeof "lib.so");
!       sprintf (needed_name, "lib%s%s.so", filename, arch);
        bfd_elf_set_dt_needed_name (entry->the_bfd, needed_name);
      }
  
--- 223,236 ----
        && (entry->the_bfd->flags & DYNAMIC) != 0)
      {
        char *needed_name;
+       char *shlib;
  
        ASSERT (entry->is_archive && entry->search_dirs_flag);
! 
!       /* We may have /xxxxx/libxxxx.so.x.x.x. We only want the
!        * libxxx.so.x.x.x part. */
!       shlib = strrchr (entry->filename, '/');
!       needed_name = strdup (shlib ? shlib + 1 : entry->filename);
        bfd_elf_set_dt_needed_name (entry->the_bfd, needed_name);
      }
  
===================================================================
RCS file: /home/cvs/gnu/binutils/ld/scripttempl/elf.sc,v
retrieving revision 1.1.1.3
diff -c -r1.1.1.3 elf.sc
*** 1.1.1.3	1995/03/04 19:23:56
--- elf.sc	1995/05/03 02:50:17
***************
*** 26,31 ****
--- 26,36 ----
  test "$LD_FLAG" = "N" && DATA_ADDR=.
  INTERP=".interp   ${RELOCATING-0} : { *(.interp) 	}"
  PLT=".plt    ${RELOCATING-0} : { *(.plt)	}"
+ if [ x"${NO_DEFAULT_WRITABLE_TEXT_SEGMENT}" = "xy" -o x"${NO_DEFAULT_WRITABLE_TEXT_SEGMENT}" = "xY" ]; then
+   DATA_ALIGN="${DATA_ADDR-ALIGN(${MAXPAGESIZE}) + ((ALIGN(8) + ${MAXPAGESIZE} - ALIGN(${MAXPAGESIZE})) & (${MAXPAGESIZE} - 1))}"
+ else
+   DATA_ALIGN="${DATA_ADDR- ALIGN(8) + ${MAXPAGESIZE}}"
+ fi
  cat <<EOF
  OUTPUT_FORMAT("${OUTPUT_FORMAT}", "${BIG_OUTPUT_FORMAT}",
  	      "${LITTLE_OUTPUT_FORMAT}")
***************
*** 101,107 ****
       important than losing a page of the virtual address space (note
       that no actual memory is lost; the page which is skipped can not
       be referenced).  */
!   ${RELOCATING+. = ${DATA_ADDR- ALIGN(8) + ${MAXPAGESIZE}};}
  
    .data  ${RELOCATING-0} :
    {
--- 106,112 ----
       important than losing a page of the virtual address space (note
       that no actual memory is lost; the page which is skipped can not
       be referenced).  */
!   ${RELOCATING+. = ${DATA_ALIGN};}
  
    .data  ${RELOCATING-0} :
    {


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~1995-05-02 21:23 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1995-05-02 21:23 A new ld patch H.J. Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).