Add Linux style directory searching.
* configure.tgt: Add i386lelf to targ_extra_emuls for i[345]86-*-linuxaout* and i[345]86-*-linuxoldld. For i[345]86-*-linux*, set targ_emul to i386lelf, and add elf_i386 to targ_extra_emuls. * emulparams/i386lelf.sh: New file, a copy of elf_i386.sh. * emultempl/elf32.em: If TARGET_IS_i386lelf, use autoconf recommended mechanism to define DIR and struct dirent. (libcmp): New static function use only when TARGET_IS_i386lelf. (gld${EMULATION_NAME}_open_dynamic_archive): Likewise. * Makefile.in (ALL_EMULATIONS): Add ei386lelf.o (ei386lelf.c): New target.
This commit is contained in:
parent
2b71e1e4d7
commit
ed753c2049
15
ld/ChangeLog
15
ld/ChangeLog
|
@ -1,5 +1,20 @@
|
|||
Fri Sep 8 16:32:43 1995 Ian Lance Taylor <ian@cygnus.com>
|
||||
|
||||
Add Linux style directory searching.
|
||||
* configure.tgt: Add i386lelf to targ_extra_emuls for
|
||||
i[345]86-*-linuxaout* and i[345]86-*-linuxoldld. For
|
||||
i[345]86-*-linux*, set targ_emul to i386lelf, and add elf_i386 to
|
||||
targ_extra_emuls.
|
||||
* emulparams/i386lelf.sh: New file, a copy of elf_i386.sh.
|
||||
* emultempl/elf32.em: If TARGET_IS_i386lelf, use autoconf
|
||||
recommended mechanism to define DIR and struct dirent.
|
||||
(libcmp): New static function use only when TARGET_IS_i386lelf.
|
||||
(gld${EMULATION_NAME}_open_dynamic_archive): Likewise.
|
||||
* Makefile.in (ALL_EMULATIONS): Add ei386lelf.o
|
||||
(ei386lelf.c): New target.
|
||||
|
||||
* Makefile.in (config.status): Depend upon configure.tgt.
|
||||
|
||||
* ldemul.h (ldemul_set_symbols): Declare.
|
||||
(ldemul_parse_args): Declare.
|
||||
* ldemul.c (ldemul_parse_args): Fix indentation.
|
||||
|
|
|
@ -202,7 +202,8 @@ ALL_EMULATIONS = ea29k.o ealpha.o earmaoutl.o earmaoutb.o \
|
|||
emipsidt.o emipsidtl.o emipslit.o enews.o ens32knbsd.o eppcnw.o \
|
||||
eriscix.o esa29200.o eshl.o esh.o esparclynx.o esparcnbsd.o \
|
||||
est2000.o esun3.o esun4.o evanilla.o evax.o evsta.o \
|
||||
ez8001.o ez8002.o ei386pe.o earmpe.o eelf32vr4300.o eelf32vr4300el.o
|
||||
ez8001.o ez8002.o ei386pe.o earmpe.o eelf32vr4300.o \
|
||||
eelf32vr4300el.o ei386lelf.o
|
||||
|
||||
CFILES = ldctor.c ldemul.c ldexp.c ldfile.c ldlang.c \
|
||||
ldmain.c ldmisc.c ldver.c ldwrite.c lexsup.c \
|
||||
|
@ -441,6 +442,9 @@ em68kaout.c: $(srcdir)/emulparams/m68kaout.sh \
|
|||
ei386linux.c: $(srcdir)/emulparams/i386linux.sh \
|
||||
$(srcdir)/emultempl/linux.em $(srcdir)/scripttempl/aout.sc ${GEN_DEPENDS}
|
||||
${GENSCRIPTS} i386linux
|
||||
ei386lelf.c: $(srcdir)/emulparams/i386lelf.sh \
|
||||
$(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
|
||||
${GENSCRIPTS} i386lelf
|
||||
eelf32_sparc.c: $(srcdir)/emulparams/elf32_sparc.sh \
|
||||
$(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
|
||||
${GENSCRIPTS} elf32_sparc
|
||||
|
@ -859,7 +863,7 @@ config.h: stamp-h ; @true
|
|||
stamp-h: config.in config.status
|
||||
CONFIG_FILES= CONFIG_HEADERS=config.h:config.in $(SHELL) ./config.status
|
||||
|
||||
config.status: configure configure.host
|
||||
config.status: configure configure.host configure.tgt
|
||||
$(SHELL) ./config.status --recheck
|
||||
|
||||
# What appears below is generated by a hacked mkdep using gcc -MM.
|
||||
|
|
|
@ -46,9 +46,15 @@ i[345]86-*-bsd) targ_emul=i386bsd ;;
|
|||
i[345]86-*-bsd386) targ_emul=i386bsd ;;
|
||||
i[345]86-*-bsdi*) targ_emul=i386bsd ;;
|
||||
i[345]86-*-aout) targ_emul=i386aout ;;
|
||||
i[345]86-*-linuxaout*) targ_emul=i386linux; targ_extra_emuls=elf_i386 ;;
|
||||
i[345]86-*-linuxoldld) targ_emul=i386linux; targ_extra_emuls=elf_i386 ;;
|
||||
i[345]86-*-linux*) targ_emul=elf_i386; targ_extra_emuls=i386linux ;;
|
||||
i[345]86-*-linuxaout*) targ_emul=i386linux
|
||||
targ_extra_emuls="i386lelf elf_i386"
|
||||
;;
|
||||
i[345]86-*-linuxoldld) targ_emul=i386linux
|
||||
targ_extra_emuls="i386lelf elf_i386"
|
||||
;;
|
||||
i[345]86-*-linux*) targ_emul=i386lelf
|
||||
targ_extra_emuls="elf_i386 i386linux"
|
||||
;;
|
||||
i[345]86-*-sysv4*) targ_emul=elf_i386 ;;
|
||||
i[345]86-*-unixware) targ_emul=elf_i386 ;;
|
||||
i[345]86-*-netbsd*) targ_emul=i386nbsd ;;
|
||||
|
|
|
@ -74,6 +74,7 @@ i386bsd.sh
|
|||
i386coff.sh
|
||||
i386go32.sh
|
||||
i386linux.sh
|
||||
i386lelf.sh
|
||||
i386lynx.sh
|
||||
i386mach.sh
|
||||
i386moss.sh
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
SCRIPT_NAME=elf
|
||||
OUTPUT_FORMAT="elf32-i386"
|
||||
TEXT_START_ADDR=0x08000000
|
||||
MAXPAGESIZE=0x1000
|
||||
NONPAGED_TEXT_START_ADDR=0x08000000
|
||||
ARCH=i386
|
||||
NOP=0x9090
|
||||
TEMPLATE_NAME=elf32
|
||||
GENERATE_SHLIB_SCRIPT=yes
|
|
@ -34,7 +34,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|||
#include "bfdlink.h"
|
||||
|
||||
#include "ld.h"
|
||||
#include "config.h"
|
||||
#include "ldmain.h"
|
||||
#include "ldemul.h"
|
||||
#include "ldfile.h"
|
||||
|
@ -43,9 +42,26 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|||
#include "ldlang.h"
|
||||
#include "ldgram.h"
|
||||
|
||||
#ifdef TARGET_IS_i386lelf
|
||||
#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
|
||||
#endif
|
||||
|
||||
static void gld${EMULATION_NAME}_before_parse PARAMS ((void));
|
||||
static boolean gld${EMULATION_NAME}_open_dynamic_archive
|
||||
PARAMS ((const char *, lang_input_statement_type *));
|
||||
PARAMS ((const char *, search_dirs_type *, lang_input_statement_type *));
|
||||
static void gld${EMULATION_NAME}_after_open PARAMS ((void));
|
||||
static void gld${EMULATION_NAME}_check_needed
|
||||
PARAMS ((lang_input_statement_type *));
|
||||
|
@ -69,20 +85,39 @@ gld${EMULATION_NAME}_before_parse()
|
|||
config.dynamic_link = ${DYNAMIC_LINK-true};
|
||||
}
|
||||
|
||||
#ifndef TARGET_IS_i386lelf
|
||||
|
||||
/* Try to open a dynamic archive. This is where we know that ELF
|
||||
dynamic libraries have an extension of .so. */
|
||||
|
||||
static boolean
|
||||
gld${EMULATION_NAME}_open_dynamic_archive (arch, entry)
|
||||
gld${EMULATION_NAME}_open_dynamic_archive (arch, search, entry)
|
||||
const char *arch;
|
||||
search_dirs_type *search;
|
||||
lang_input_statement_type *entry;
|
||||
{
|
||||
const char *filename;
|
||||
char *string;
|
||||
|
||||
if (! entry->is_archive)
|
||||
return false;
|
||||
|
||||
filename = entry->filename;
|
||||
|
||||
if (! ldfile_open_file_search (arch, entry, "lib", ".so"))
|
||||
return false;
|
||||
string = (char *) xmalloc (strlen (search->name)
|
||||
+ strlen (filename)
|
||||
+ strlen (arch)
|
||||
+ sizeof "/lib.so");
|
||||
|
||||
sprintf (string, "%s/lib%s%s.so", search->name, filename, arch);
|
||||
|
||||
if (! ldfile_try_open_bfd (string, entry))
|
||||
{
|
||||
free (string);
|
||||
return false;
|
||||
}
|
||||
|
||||
entry->filename = string;
|
||||
|
||||
/* We have found a dynamic object to include in the link. The ELF
|
||||
backend linker will create a DT_NEEDED entry in the .dynamic
|
||||
|
@ -113,6 +148,121 @@ gld${EMULATION_NAME}_open_dynamic_archive (arch, entry)
|
|||
return true;
|
||||
}
|
||||
|
||||
#else /* TARGET_IS_i386lelf */
|
||||
|
||||
/* Linux deviates from the SVR4 standard in that its archives use
|
||||
version numbers in the file name. I think this is bogus, but
|
||||
H.J. Lu insists that it be done this way. */
|
||||
|
||||
static int libcmp PARAMS ((const char *, const char *));
|
||||
|
||||
/* Choose between two library names. This is like a string
|
||||
comparison, except that numbers are compared by value. */
|
||||
|
||||
static int
|
||||
libcmp (p1, p2)
|
||||
const char *p1;
|
||||
const char *p2;
|
||||
{
|
||||
while (*p1 != '\0')
|
||||
{
|
||||
if (isdigit (*p1) && isdigit (*p2))
|
||||
{
|
||||
unsigned long v1, v2;
|
||||
|
||||
v1 = strtoul (p1, (char **) &p1, 10);
|
||||
v2 = strtoul (p2, (char **) &p2, 10);
|
||||
if (v1 < v2)
|
||||
return -1;
|
||||
else if (v1 > v2)
|
||||
return 1;
|
||||
}
|
||||
else if (*p1 < *p2)
|
||||
return -1;
|
||||
else if (*p1 > *p2)
|
||||
return 1;
|
||||
else
|
||||
{
|
||||
++p1;
|
||||
++p2;
|
||||
}
|
||||
}
|
||||
|
||||
if (*p2 != '\0')
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Search for the library to open. */
|
||||
|
||||
/*ARGSUSED*/
|
||||
static boolean
|
||||
gld${EMULATION_NAME}_open_dynamic_archive (arch, search, entry)
|
||||
const char *arch;
|
||||
search_dirs_type *search;
|
||||
lang_input_statement_type *entry;
|
||||
{
|
||||
size_t len;
|
||||
char *found;
|
||||
DIR *dir;
|
||||
struct dirent *ent;
|
||||
char *string;
|
||||
|
||||
len = strlen (entry->filename);
|
||||
|
||||
found = NULL;
|
||||
|
||||
dir = opendir (search->name);
|
||||
if (dir == NULL)
|
||||
return false;
|
||||
|
||||
while ((ent = readdir (dir)) != NULL)
|
||||
{
|
||||
if (strncmp (ent->d_name, "lib", 3) != 0
|
||||
|| strncmp (ent->d_name + 3, entry->filename, len) != 0
|
||||
|| strncmp (ent->d_name + len + 3, ".so", 3) != 0)
|
||||
continue;
|
||||
|
||||
if (found != NULL)
|
||||
{
|
||||
if (libcmp (ent->d_name + len + 6, found + len + 6) < 0)
|
||||
continue;
|
||||
free (found);
|
||||
}
|
||||
|
||||
found = (char *) xmalloc (strlen (ent->d_name) + 1);
|
||||
strcpy (found, ent->d_name);
|
||||
}
|
||||
|
||||
closedir (dir);
|
||||
|
||||
if (found == NULL)
|
||||
return false;
|
||||
|
||||
string = (char *) xmalloc (strlen (search->name) + strlen (found) + 2);
|
||||
sprintf (string, "%s/%s", search->name, found);
|
||||
if (! ldfile_try_open_bfd (string, entry))
|
||||
{
|
||||
free (found);
|
||||
return false;
|
||||
}
|
||||
|
||||
entry->filename = string;
|
||||
|
||||
if (bfd_check_format (entry->the_bfd, bfd_object)
|
||||
&& (entry->the_bfd->flags & DYNAMIC) != 0)
|
||||
{
|
||||
ASSERT (entry->is_archive && entry->search_dirs_flag);
|
||||
bfd_elf_set_dt_needed_name (entry->the_bfd, found);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
#endif /* TARGET_IS_i386lelf */
|
||||
|
||||
/* These variables are required to pass information back and forth
|
||||
between after_open and check_needed. */
|
||||
|
||||
|
@ -279,6 +429,17 @@ gld${EMULATION_NAME}_check_needed (s)
|
|||
if (s->filename != NULL
|
||||
&& strcmp (s->filename, global_needed->name) == 0)
|
||||
global_found = true;
|
||||
else if (s->search_dirs_flag
|
||||
&& s->filename != NULL
|
||||
&& strchr (global_needed->name, '/') == NULL)
|
||||
{
|
||||
const char *f;
|
||||
|
||||
f = strrchr (s->filename, '/');
|
||||
if (f != NULL
|
||||
&& strcmp (f + 1, global_needed->name) == 0)
|
||||
global_found = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* This is called after the sections have been attached to output
|
||||
|
@ -338,7 +499,8 @@ gld${EMULATION_NAME}_before_allocation ()
|
|||
einfo ("%F%B: Can't read contents of section .gnu.warning: %E\n",
|
||||
is->the_bfd);
|
||||
msg[sz] = '\0';
|
||||
ret = link_info.callbacks->warning (&link_info, msg);
|
||||
ret = link_info.callbacks->warning (&link_info, msg, is->the_bfd,
|
||||
(asection *) NULL, (bfd_vma) 0);
|
||||
ASSERT (ret);
|
||||
free (msg);
|
||||
|
||||
|
@ -491,6 +653,17 @@ gld${EMULATION_NAME}_place_orphan (file, s)
|
|||
|
||||
secname = bfd_get_section_name (s->owner, s);
|
||||
|
||||
/* If this is a final link, then always put .gnu.warning.SYMBOL
|
||||
sections into the .text section to get them out of the way. */
|
||||
if (! link_info.shared
|
||||
&& ! link_info.relocateable
|
||||
&& strncmp (secname, ".gnu.warning.", sizeof ".gnu.warning." - 1) == 0
|
||||
&& hold_text != NULL)
|
||||
{
|
||||
wild_doit (&hold_text->children, s, hold_text, file);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Decide which segment the section should go in based on the
|
||||
section name and section flags. */
|
||||
place = NULL;
|
||||
|
|
Loading…
Reference in New Issue