* 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).