# This file is now misnamed, because it supports both 32 bit and 64 bit
# ELF emulations.
test -z "${ELFSIZE}" && ELFSIZE=32
+if [ -z "$MACHINE" ]; then
+ OUTPUT_ARCH=${ARCH}
+else
+ OUTPUT_ARCH=${ARCH}:${MACHINE}
+fi
cat >e${EMULATION_NAME}.c <<EOF
/* This file is is generated by a shell script. DO NOT EDIT! */
/* ${ELFSIZE} bit ELF emulation code for ${EMULATION_NAME}
- Copyright (C) 1991, 93, 94, 95, 96, 97, 98, 99, 2000
+ Copyright 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
Written by Steve Chamberlain <sac@cygnus.com>
ELF support by Ian Lance Taylor <ian@cygnus.com>
#include "bfd.h"
#include "sysdep.h"
+#include "libiberty.h"
#include <ctype.h>
. ${srcdir}/emultempl/${EXTRA_EM_FILE}.em
fi
-# Functions in this file can be overriden by setting the LDEMUL_* shell
+# Functions in this file can be overridden by setting the LDEMUL_* shell
# variables. If the name of the overriding function is the same as is
# defined in this file, then don't output this file's version.
# If a different overriding name is given then output the standard function
static void
gld${EMULATION_NAME}_before_parse ()
{
- ldfile_output_architecture = bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`;
+ const bfd_arch_info_type *arch = bfd_scan_arch ("${OUTPUT_ARCH}");
+ if (arch)
+ {
+ ldfile_output_architecture = arch->arch;
+ ldfile_output_machine = arch->mach;
+ ldfile_output_machine_name = arch->printable_name;
+ }
+ else
+ ldfile_output_architecture = bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`;
config.dynamic_link = ${DYNAMIC_LINK-true};
config.has_shared = `if test -n "$GENERATE_SHLIB_SCRIPT" ; then echo true ; else echo false ; fi`;
}
This is called via lang_for_each_input_file.
GLOBAL_VERCHECK_NEEDED is the list of objects needed by the object
- which we ar checking. This sets GLOBAL_VERCHECK_FAILED if we find
+ which we are checking. This sets GLOBAL_VERCHECK_FAILED if we find
a conflicting version. */
static void
gld${EMULATION_NAME}_vercheck (s)
lang_input_statement_type *s;
{
- const char *soname, *f;
+ const char *soname;
struct bfd_link_needed_list *l;
if (global_vercheck_failed)
soname = bfd_elf_get_dt_soname (s->the_bfd);
if (soname == NULL)
- soname = bfd_get_filename (s->the_bfd);
-
- f = strrchr (soname, '/');
- if (f != NULL)
- ++f;
- else
- f = soname;
+ soname = basename (bfd_get_filename (s->the_bfd));
for (l = global_vercheck_needed; l != NULL; l = l->next)
{
const char *suffix;
- if (strcmp (f, l->name) == 0)
+ if (strcmp (soname, l->name) == 0)
{
/* Probably can't happen, but it's an easy check. */
continue;
suffix += sizeof ".so." - 1;
- if (strncmp (f, l->name, suffix - l->name) == 0)
+ if (strncmp (soname, l->name, suffix - l->name) == 0)
{
/* Here we know that S is a dynamic object FOO.SO.VER1, and
the object we are considering needs a dynamic object
struct stat st;
const char *suffix;
const char *soname;
- const char *f;
if (global_found)
return;
different versions of the same shared library. For example,
there may be a problem if -lc picks up libc.so.6 but some other
shared library has a DT_NEEDED entry of libc.so.5. This is a
- hueristic test, and it will only work if the name looks like
+ heuristic test, and it will only work if the name looks like
NAME.so.VERSION. FIXME: Depending on file names is error-prone.
If we really want to issue warnings about mixing version numbers
of shared libraries, we need to find a better way. */
soname = bfd_elf_get_dt_soname (s->the_bfd);
if (soname == NULL)
- soname = s->filename;
+ soname = basename (s->filename);
- f = strrchr (soname, '/');
- if (f != NULL)
- ++f;
- else
- f = soname;
-
- if (strncmp (f, global_needed->name, suffix - global_needed->name) == 0)
+ if (strncmp (soname, global_needed->name,
+ suffix - global_needed->name) == 0)
einfo ("%P: warning: %s, needed by %B, may conflict with %s\n",
- global_needed->name, global_needed->by, f);
+ global_needed->name, global_needed->by, soname);
}
einfo ("%F%P:%B: bfd_stat failed: %E\n", abfd);
/* First strip off everything before the last '/'. */
- soname = strrchr (abfd->filename, '/');
- if (soname)
- soname++;
- else
- soname = abfd->filename;
+ soname = basename (abfd->filename);
if (trace_file_tries)
info_msg (_("found %s at %s\n"), soname, name);
DT_NEEDED entry for this file. */
bfd_elf_set_dt_needed_name (abfd, "");
+ /* Previos basename call was clobbered in lang_for_each_input_file. */
+ soname = basename (abfd->filename);
+
/* Tell the ELF backend that the output file needs a DT_NEEDED
entry for this file if it is used to resolve the reference in
a regular object. */
const char *s;
size_t len;
+ if (name[0] == '/')
+ return gld${EMULATION_NAME}_try_needed (name, force);
+
if (path == NULL || *path == '\0')
return false;
len = strlen (name);
if [ "x${host}" = "x${target}" ] ; then
case " ${EMULATION_LIBPATH} " in
*" ${EMULATION_NAME} "*)
-cat >>e${EMULATION_NAME}.c <<EOF
+ case ${target} in
+ *-*-linux-gnu*)
+ cat >>e${EMULATION_NAME}.c <<EOF
/* For a native linker, check the file /etc/ld.so.conf for directories
in which we may find shared libraries. /etc/ld.so.conf is really
- only meaningful on Linux, but we check it on other systems anyhow. */
+ only meaningful on Linux. */
static boolean gld${EMULATION_NAME}_check_ld_so_conf
PARAMS ((const char *, int));
}
EOF
- ;;
+ # Linux
+ ;;
+ esac
esac
fi
cat >>e${EMULATION_NAME}.c <<EOF
if (global_found)
return;
- if (s->filename != NULL
- && strcmp (s->filename, global_needed->name) == 0)
+ if (s->filename != NULL)
{
- global_found = true;
- return;
+ const char *f;
+
+ if (strcmp (s->filename, global_needed->name) == 0)
+ {
+ global_found = true;
+ return;
+ }
+
+ if (s->search_dirs_flag)
+ {
+ f = strrchr (s->filename, '/');
+ if (f != NULL
+ && strcmp (f + 1, global_needed->name) == 0)
+ {
+ global_found = true;
+ return;
+ }
+ }
}
if (s->the_bfd != NULL)
return;
}
}
-
- 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;
- return;
- }
- }
}
EOF
if [ "x${host}" = "x${target}" ] ; then
case " ${EMULATION_LIBPATH} " in
*" ${EMULATION_NAME} "*)
-cat >>e${EMULATION_NAME}.c <<EOF
+ case ${target} in
+ *-*-linux-gnu*)
+ cat >>e${EMULATION_NAME}.c <<EOF
if (gld${EMULATION_NAME}_check_ld_so_conf (l->name, force))
break;
EOF
+ # Linux
+ ;;
+ esac
;;
esac
fi
EOF
if test x"$LDEMUL_BEFORE_ALLOCATION" != xgld"$EMULATION_NAME"_before_allocation; then
+ if test x"${ELF_INTERPRETER_NAME+set}" = xset; then
+ ELF_INTERPRETER_SET_DEFAULT="
+ if (sinterp != NULL)
+ {
+ sinterp->contents = ${ELF_INTERPRETER_NAME};
+ sinterp->_raw_size = strlen (sinterp->contents) + 1;
+ }
+
+"
+ else
+ ELF_INTERPRETER_SET_DEFAULT=
+ fi
cat >>e${EMULATION_NAME}.c <<EOF
/* This is called after the sections have been attached to output
rpath = (const char *) getenv ("LD_RUN_PATH");
if (! (bfd_elf${ELFSIZE}_size_dynamic_sections
(output_bfd, command_line.soname, rpath,
- command_line.export_dynamic, command_line.filter_shlib,
+ command_line.filter_shlib,
(const char * const *) command_line.auxiliary_filters,
&link_info, &sinterp, lang_elf_version_info)))
einfo ("%P%F: failed to set dynamic section sizes: %E\n");
-
+${ELF_INTERPRETER_SET_DEFAULT}
/* Let the user override the dynamic linker we are using. */
if (command_line.interpreter != NULL
&& sinterp != NULL)
if (bfd_check_format (entry->the_bfd, bfd_object)
&& (entry->the_bfd->flags & DYNAMIC) != 0)
{
- char *needed_name;
-
ASSERT (entry->is_archive && entry->search_dirs_flag);
/* Rather than duplicating the logic above. Just use the
- filename we recorded earlier.
-
- First strip off everything before the last '/'. */
- filename = strrchr (entry->filename, '/');
- filename++;
+ filename we recorded earlier. */
- needed_name = (char *) xmalloc (strlen (filename) + 1);
- strcpy (needed_name, filename);
- bfd_elf_set_dt_needed_name (entry->the_bfd, needed_name);
+ filename = xstrdup (basename (entry->filename));
+ bfd_elf_set_dt_needed_name (entry->the_bfd, filename);
}
return true;
if test x"$LDEMUL_PLACE_ORPHAN" != xgld"$EMULATION_NAME"_place_orphan; then
cat >>e${EMULATION_NAME}.c <<EOF
+/* Find the last output section before given output statement.
+ Used by place_orphan. */
+
+static asection *
+output_prev_sec_find (os)
+ lang_output_section_statement_type *os;
+{
+ asection *s = (asection *) NULL;
+ lang_statement_union_type *u;
+ lang_output_section_statement_type *lookup;
+
+ for (u = lang_output_section_statement.head;
+ u != (lang_statement_union_type *) NULL;
+ u = lookup->next)
+ {
+ lookup = &u->output_section_statement;
+ if (lookup == os)
+ break;
+ if (lookup->bfd_section != NULL)
+ s = lookup->bfd_section;
+ }
+
+ if (u == NULL)
+ return NULL;
+
+ return s;
+}
+
+
/* Place an orphan section. We use this to put random SHF_ALLOC
sections in the right segment. */
static struct orphan_save hold_bss;
static struct orphan_save hold_rel;
static struct orphan_save hold_interp;
+ static struct orphan_save hold_sdata;
static int count = 1;
struct orphan_save *place;
lang_statement_list_type *old;
secname = bfd_get_section_name (s->owner, s);
- if (! config.unique_orphan_sections)
+ if (! config.unique_orphan_sections && ! unique_section_p (secname))
{
- /* Look through the script to see where to place this section. */
+ /* Look through the script to see where to place this section. */
os = lang_output_section_find (secname);
if (os != NULL
if ((s->flags & SEC_ALLOC) == 0)
;
else if ((s->flags & SEC_LOAD) != 0
- && strncmp (secname, ".note", 4) == 0
+ && strncmp (secname, ".note", 5) == 0
&& HAVE_SECTION (hold_interp, ".interp"))
place = &hold_interp;
else if ((s->flags & SEC_HAS_CONTENTS) == 0
&& HAVE_SECTION (hold_bss, ".bss"))
place = &hold_bss;
+ else if ((s->flags & SEC_SMALL_DATA) != 0
+ && HAVE_SECTION (hold_sdata, ".sdata"))
+ place = &hold_sdata;
else if ((s->flags & SEC_READONLY) == 0
&& HAVE_SECTION (hold_data, ".data"))
place = &hold_data;
/* Choose a unique name for the section. This will be needed if the
same section name appears in the input file with different
- loadable or allocateable characteristics. */
+ loadable or allocatable characteristics. */
outsecname = secname;
if (bfd_get_section_by_name (output_bfd, outsecname) != NULL)
- outsecname = bfd_get_unique_section_name (output_bfd,
- outsecname,
- &count);
+ {
+ outsecname = bfd_get_unique_section_name (output_bfd,
+ outsecname,
+ &count);
+ if (outsecname == NULL)
+ einfo ("%F%P: place_orphan failed: %E\n");
+ }
/* Start building a list of statements for this section.
First save the current statement pointer. */
if (place != NULL)
{
- asection *snew, **pps;
+ asection *snew, **pps, *bfd_section;
snew = os->bfd_section;
+ bfd_section = place->os->bfd_section;
+ if (place->section == NULL && bfd_section == NULL)
+ bfd_section = output_prev_sec_find (place->os);
+
if (place->section != NULL
- || (place->os->bfd_section != NULL
- && place->os->bfd_section != snew))
+ || (bfd_section != NULL
+ && bfd_section != snew))
{
/* Shuffle the section to make the output file look neater.
This is really only cosmetic. */
#if 0
/* Finding the end of the list is a little tricky. We
make a wild stab at it by comparing section flags. */
- flagword first_flags = place->os->bfd_section->flags;
- for (pps = &place->os->bfd_section->next;
+ flagword first_flags = bfd_section->flags;
+ for (pps = &bfd_section->next;
*pps != NULL && (*pps)->flags == first_flags;
pps = &(*pps)->next)
;
place->section = pps;
#else
/* Put orphans after the first section on the list. */
- place->section = &place->os->bfd_section->next;
+ place->section = &bfd_section->next;
#endif
}
#define OPTION_DISABLE_NEW_DTAGS (400)
#define OPTION_ENABLE_NEW_DTAGS (OPTION_DISABLE_NEW_DTAGS + 1)
+#define OPTION_GROUP (OPTION_ENABLE_NEW_DTAGS + 1)
static struct option longopts[] =
{
{"disable-new-dtags", no_argument, NULL, OPTION_DISABLE_NEW_DTAGS},
{"enable-new-dtags", no_argument, NULL, OPTION_ENABLE_NEW_DTAGS},
{"enable-new-dtags", no_argument, NULL, OPTION_ENABLE_NEW_DTAGS},
+ {"Bgroup", no_argument, NULL, OPTION_GROUP},
+ {"Bgroup", no_argument, NULL, OPTION_GROUP},
EOF
fi
link_info.new_dtags = true;
break;
+ case OPTION_GROUP:
+ link_info.flags_1 |= (bfd_vma) DF_1_GROUP;
+ /* Groups must be self-contained. */
+ link_info.no_undefined = true;
+ break;
+
case 'z':
if (strcmp (optarg, "initfirst") == 0)
link_info.flags_1 |= (bfd_vma) DF_1_INITFIRST;
link_info.flags |= (bfd_vma) DF_ORIGIN;
link_info.flags_1 |= (bfd_vma) DF_1_ORIGIN;
}
+ else if (strcmp (optarg, "defs") == 0)
+ link_info.no_undefined = true;
/* What about the other Solaris -z options? FIXME. */
break;
EOF
if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
cat >>e${EMULATION_NAME}.c <<EOF
+ fprintf (file, _(" -Bgroup\t\tSelects group name lookup rules for DSO\n"));
fprintf (file, _(" --disable-new-dtags\tDisable new dynamic tags\n"));
fprintf (file, _(" --enable-new-dtags\tEnable new dynamic tags\n"));
- fprintf (file, _(" -z initfirst\t\tMark DSO to be initialized first at rutime\n"));
- fprintf (file, _(" -z interpose\t\tMark object to interpose all DSOs but execuable\n"));
+ fprintf (file, _(" -z defs\t\tDisallows undefined symbols\n"));
+ fprintf (file, _(" -z initfirst\t\tMark DSO to be initialized first at runtime\n"));
+ fprintf (file, _(" -z interpose\t\tMark object to interpose all DSOs but executable\n"));
fprintf (file, _(" -z loadfltr\t\tMark object requiring immediate process\n"));
fprintf (file, _(" -z nodefaultlib\tMark object not to use default search paths\n"));
fprintf (file, _(" -z nodelete\t\tMark DSO non-deletable at runtime\n"));
- fprintf (file, _(" -z nodlopen\t\tMark DSO not availale to dlopen\n"));
- fprintf (file, _(" -z nodump\t\tMark DSO not availale to dldump\n"));
+ fprintf (file, _(" -z nodlopen\t\tMark DSO not available to dlopen\n"));
+ fprintf (file, _(" -z nodump\t\tMark DSO not available to dldump\n"));
fprintf (file, _(" -z now\t\tMark object non-lazy runtime binding\n"));
fprintf (file, _(" -z origin\t\tMark object requiring immediate \$ORIGIN processing\n"));
fprintf (file, _("\t\t\t at runtime\n"));