else
OUTPUT_ARCH=${ARCH}:${MACHINE}
fi
-cat >e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
/* This file is is generated by a shell script. DO NOT EDIT! */
/* ${ELFSIZE} bit ELF emulation code for ${EMULATION_NAME}
Copyright 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
- 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+ Free Software Foundation, Inc.
Written by Steve Chamberlain <sac@cygnus.com>
ELF support by Ian Lance Taylor <ian@cygnus.com>
#include "libiberty.h"
#include "safe-ctype.h"
#include "getopt.h"
+#include "md5.h"
+#include "sha1.h"
+#include <fcntl.h>
#include "bfdlink.h"
#include <ldgram.h>
#include "elf/common.h"
#include "elf-bfd.h"
+#include "filenames.h"
/* Declare functions used by various EXTRA_EM_FILEs. */
static void gld${EMULATION_NAME}_before_parse (void);
static void gld${EMULATION_NAME}_after_open (void);
static void gld${EMULATION_NAME}_before_allocation (void);
-static bfd_boolean gld${EMULATION_NAME}_place_orphan (asection *s);
-static void gld${EMULATION_NAME}_finish (void);
-
+static void gld${EMULATION_NAME}_after_allocation (void);
+static lang_output_section_statement_type *gld${EMULATION_NAME}_place_orphan
+ (asection *, const char *, int);
EOF
if [ "x${USE_LIBPATH}" = xyes ] ; then
case ${target} in
*-*-linux-* | *-*-k*bsd*-*)
- cat >>e${EMULATION_NAME}.c <<EOF
+ fragment <<EOF
#ifdef HAVE_GLOB
#include <glob.h>
#endif
# Import any needed special functions and/or overrides.
#
-. ${srcdir}/emultempl/elf-generic.em
+source_em ${srcdir}/emultempl/elf-generic.em
if test -n "$EXTRA_EM_FILE" ; then
-. ${srcdir}/emultempl/${EXTRA_EM_FILE}.em
+ source_em ${srcdir}/emultempl/${EXTRA_EM_FILE}.em
fi
# Functions in this file can be overridden by setting the LDEMUL_* shell
# as presumably it is called from the overriding function.
#
if test x"$LDEMUL_BEFORE_PARSE" != xgld"$EMULATION_NAME"_before_parse; then
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
static void
gld${EMULATION_NAME}_before_parse (void)
fi
if test x"$LDEMUL_RECOGNIZED_FILE" != xgld"${EMULATION_NAME}"_load_symbols; then
-cat >>e${EMULATION_NAME}.c <<EOF
-/* Handle as_needed DT_NEEDED. */
+fragment <<EOF
+/* Handle the generation of DT_NEEDED tags. */
static bfd_boolean
gld${EMULATION_NAME}_load_symbols (lang_input_statement_type *entry)
{
- int class = 0;
+ int link_class = 0;
/* Tell the ELF linker that we don't want the output file to have a
DT_NEEDED entry for this file, unless it is used to resolve
references in a regular object. */
- if (entry->as_needed)
- class = DYN_AS_NEEDED;
+ if (entry->add_DT_NEEDED_for_regular)
+ link_class = DYN_AS_NEEDED;
/* Tell the ELF linker that we don't want the output file to have a
DT_NEEDED entry for any dynamic library in DT_NEEDED tags from
this file at all. */
- if (!entry->add_needed)
- class |= DYN_NO_ADD_NEEDED;
+ if (!entry->add_DT_NEEDED_for_dynamic)
+ link_class |= DYN_NO_ADD_NEEDED;
if (entry->just_syms_flag
&& (bfd_get_file_flags (entry->the_bfd) & DYNAMIC) != 0)
einfo (_("%P%F: --just-symbols may not be used on DSO: %B\n"),
entry->the_bfd);
- if (!class
+ if (link_class == 0
|| (bfd_get_file_flags (entry->the_bfd) & DYNAMIC) == 0)
return FALSE;
- bfd_elf_set_dyn_lib_class (entry->the_bfd, class);
+ bfd_elf_set_dyn_lib_class (entry->the_bfd,
+ (enum dynamic_lib_link_class) link_class);
/* Continue on with normal load_symbols processing. */
return FALSE;
EOF
fi
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
/* These variables are required to pass information back and forth
between after_open and check_needed and stat_needed and vercheck. */
static struct bfd_link_needed_list *global_vercheck_needed;
static bfd_boolean global_vercheck_failed;
+/* These variables are used to implement target options */
+
+static char *audit; /* colon (typically) separated list of libs */
+static char *depaudit; /* colon (typically) separated list of libs */
/* On Linux, it's possible to have different versions of the same
shared library linked against different versions of libc. The
bfd *abfd;
const char *name = needed->name;
const char *soname;
- int class;
+ int link_class;
- abfd = bfd_openr (name, bfd_get_target (output_bfd));
+ abfd = bfd_openr (name, bfd_get_target (link_info.output_bfd));
if (abfd == NULL)
return FALSE;
if (! bfd_check_format (abfd, bfd_object))
}
/* For DT_NEEDED, they have to match. */
- if (abfd->xvec != output_bfd->xvec)
+ if (abfd->xvec != link_info.output_bfd->xvec)
{
bfd_close (abfd);
return FALSE;
if (! force)
{
- struct bfd_link_needed_list *needed;
+ struct bfd_link_needed_list *needs;
- if (! bfd_elf_get_bfd_needed_list (abfd, &needed))
+ if (! bfd_elf_get_bfd_needed_list (abfd, &needs))
einfo ("%F%P:%B: bfd_elf_get_bfd_needed_list failed: %E\n", abfd);
- if (needed != NULL)
+ if (needs != NULL)
{
- global_vercheck_needed = needed;
+ global_vercheck_needed = needs;
global_vercheck_failed = FALSE;
lang_for_each_input_file (gld${EMULATION_NAME}_vercheck);
if (global_vercheck_failed)
EOF
case ${target} in
*-*-linux-* | *-*-k*bsd*-*)
- cat >>e${EMULATION_NAME}.c <<EOF
+ fragment <<EOF
{
struct bfd_link_needed_list *l;
- for (l = needed; l != NULL; l = l->next)
+ for (l = needs; l != NULL; l = l->next)
if (CONST_STRNEQ (l->name, "libc.so"))
break;
if (l == NULL)
EOF
;;
esac
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
}
}
/* Tell the ELF linker that we don't want the output file to have a
DT_NEEDED entry for this file, unless it is used to resolve
references in a regular object. */
- class = DYN_DT_NEEDED;
+ link_class = DYN_DT_NEEDED;
/* Tell the ELF linker that we don't want the output file to have a
DT_NEEDED entry for this file at all if the entry is from a file
with DYN_NO_ADD_NEEDED. */
if (needed->by != NULL
&& (bfd_elf_get_dyn_lib_class (needed->by) & DYN_NO_ADD_NEEDED) != 0)
- class |= DYN_NO_NEEDED | DYN_NO_ADD_NEEDED;
+ link_class |= DYN_NO_NEEDED | DYN_NO_ADD_NEEDED;
- bfd_elf_set_dyn_lib_class (abfd, class);
+ bfd_elf_set_dyn_lib_class (abfd, (enum dynamic_lib_link_class) link_class);
/* Add this file into the symbol table. */
if (! bfd_link_add_symbols (abfd, &link_info))
if (s == NULL)
s = path + strlen (path);
+#if HAVE_DOS_BASED_FILE_SYSTEM
+ /* Assume a match on the second char is part of drive specifier. */
+ else if (config.rpath_separator == ':'
+ && s == path + 1
+ && ISALPHA (*path))
+ {
+ s = strchr (s + 1, config.rpath_separator);
+ if (s == NULL)
+ s = path + strlen (path);
+ }
+#endif
filename = (char *) xmalloc (s - path + len + 2);
if (s == path)
sset = filename;
EOF
if [ "x${USE_LIBPATH}" = xyes ] ; then
- cat >>e${EMULATION_NAME}.c <<EOF
+ fragment <<EOF
/* Add the sysroot to every entry in a path separated by
config.rpath_separator. */
EOF
case ${target} in
*-*-freebsd* | *-*-dragonfly*)
- cat >>e${EMULATION_NAME}.c <<EOF
+ fragment <<EOF
/* Read the system search path the FreeBSD way rather than the Linux way. */
#ifdef HAVE_ELF_HINTS_H
#include <elf-hints.h>
FILE *f;
char *tmppath;
- tmppath = concat (ld_sysroot, _PATH_ELF_HINTS, NULL);
+ tmppath = concat (ld_sysroot, _PATH_ELF_HINTS, (const char *) NULL);
f = fopen (tmppath, FOPEN_RB);
free (tmppath);
if (f != NULL)
;;
*-*-linux-* | *-*-k*bsd*-*)
- cat >>e${EMULATION_NAME}.c <<EOF
+ fragment <<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. */
info.path = NULL;
info.len = info.alloc = 0;
- tmppath = concat (ld_sysroot, "${prefix}/etc/ld.so.conf", NULL);
+ tmppath = concat (ld_sysroot, "${prefix}/etc/ld.so.conf",
+ (const char *) NULL);
if (!gld${EMULATION_NAME}_parse_ld_so_conf (&info, tmppath))
{
free (tmppath);
- tmppath = concat (ld_sysroot, "/etc/ld.so.conf", NULL);
+ tmppath = concat (ld_sysroot, "/etc/ld.so.conf",
+ (const char *) NULL);
gld${EMULATION_NAME}_parse_ld_so_conf (&info, tmppath);
}
free (tmppath);
;;
esac
fi
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
/* See if an input file matches a DT_NEEDED entry by name. */
EOF
if test x"$LDEMUL_AFTER_OPEN" != xgld"$EMULATION_NAME"_after_open; then
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
+
+static bfd_size_type
+gld${EMULATION_NAME}_id_note_section_size (bfd *abfd,
+ struct bfd_link_info *linfo)
+{
+ const char *style = linfo->emit_note_gnu_build_id;
+ bfd_size_type size;
+
+ abfd = abfd;
+
+ size = offsetof (Elf_External_Note, name[sizeof "GNU"]);
+ size = (size + 3) & -(bfd_size_type) 4;
+
+ if (!strcmp (style, "md5") || !strcmp (style, "uuid"))
+ size += 128 / 8;
+ else if (!strcmp (style, "sha1"))
+ size += 160 / 8;
+ else if (!strncmp (style, "0x", 2))
+ {
+ /* ID is in string form (hex). Convert to bits. */
+ const char *id = style + 2;
+ do
+ {
+ if (ISXDIGIT (id[0]) && ISXDIGIT (id[1]))
+ {
+ ++size;
+ id += 2;
+ }
+ else if (*id == '-' || *id == ':')
+ ++id;
+ else
+ {
+ size = 0;
+ break;
+ }
+ } while (*id != '\0');
+ }
+ else
+ size = 0;
+
+ return size;
+}
+
+static unsigned char
+read_hex (const char xdigit)
+{
+ if (ISDIGIT (xdigit))
+ return xdigit - '0';
+ if (ISUPPER (xdigit))
+ return xdigit - 'A' + 0xa;
+ if (ISLOWER (xdigit))
+ return xdigit - 'a' + 0xa;
+ abort ();
+ return 0;
+}
+
+struct build_id_info
+{
+ const char *style;
+ asection *sec;
+};
+
+static bfd_boolean
+gld${EMULATION_NAME}_write_build_id_section (bfd *abfd)
+{
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ struct build_id_info *info = (struct build_id_info *)
+ elf_tdata (abfd)->after_write_object_contents_info;
+ asection *asec;
+ Elf_Internal_Shdr *i_shdr;
+ unsigned char *contents, *id_bits;
+ bfd_size_type size;
+ Elf_External_Note *e_note;
+
+ asec = info->sec;
+ if (bfd_is_abs_section (asec->output_section))
+ {
+ einfo (_("%P: warning: .note.gnu.build-id section discarded,"
+ " --build-id ignored.\n"));
+ return TRUE;
+ }
+ i_shdr = &elf_section_data (asec->output_section)->this_hdr;
+
+ if (i_shdr->contents == NULL)
+ {
+ if (asec->contents == NULL)
+ asec->contents = (unsigned char *) xmalloc (asec->size);
+ contents = asec->contents;
+ }
+ else
+ contents = i_shdr->contents + asec->output_offset;
+
+ e_note = (Elf_External_Note *) contents;
+ size = offsetof (Elf_External_Note, name[sizeof "GNU"]);
+ size = (size + 3) & -(bfd_size_type) 4;
+ id_bits = contents + size;
+ size = asec->size - size;
+
+ bfd_h_put_32 (abfd, sizeof "GNU", &e_note->namesz);
+ bfd_h_put_32 (abfd, size, &e_note->descsz);
+ bfd_h_put_32 (abfd, NT_GNU_BUILD_ID, &e_note->type);
+ memcpy (e_note->name, "GNU", sizeof "GNU");
+
+ if (!strcmp (info->style, "md5"))
+ {
+ struct md5_ctx ctx;
+ md5_init_ctx (&ctx);
+ if (bed->s->checksum_contents (abfd,
+ (void (*) (const void *, size_t, void *))
+ &md5_process_bytes,
+ &ctx))
+ md5_finish_ctx (&ctx, id_bits);
+ else
+ return FALSE;
+ }
+ else if (!strcmp (info->style, "sha1"))
+ {
+ struct sha1_ctx ctx;
+ sha1_init_ctx (&ctx);
+ if (bed->s->checksum_contents (abfd,
+ (void (*) (const void *, size_t, void *))
+ &sha1_process_bytes,
+ &ctx))
+ sha1_finish_ctx (&ctx, id_bits);
+ else
+ return FALSE;
+ }
+ else if (!strcmp (info->style, "uuid"))
+ {
+ int n;
+ int fd = open ("/dev/urandom", O_RDONLY);
+ if (fd < 0)
+ return FALSE;
+ n = read (fd, id_bits, size);
+ close (fd);
+ if (n < (int) size)
+ return FALSE;
+ }
+ else if (!strncmp (info->style, "0x", 2))
+ {
+ /* ID is in string form (hex). Convert to bits. */
+ const char *id = info->style + 2;
+ size_t n = 0;
+ do
+ {
+ if (ISXDIGIT (id[0]) && ISXDIGIT (id[1]))
+ {
+ id_bits[n] = read_hex (*id++) << 4;
+ id_bits[n++] |= read_hex (*id++);
+ }
+ else if (*id == '-' || *id == ':')
+ ++id;
+ else
+ abort (); /* Should have been validated earlier. */
+ } while (*id != '\0');
+ }
+ else
+ abort (); /* Should have been validated earlier. */
+
+ size = asec->size;
+ return (bfd_seek (abfd,
+ i_shdr->sh_offset + asec->output_offset, SEEK_SET) == 0
+ && bfd_bwrite (contents, size, abfd) == size);
+}
+
/* This is called after all the input files have been opened. */
gld${EMULATION_NAME}_after_open (void)
{
struct bfd_link_needed_list *needed, *l;
+ struct elf_link_hash_table *htab;
- if (link_info.eh_frame_hdr
- && ! link_info.traditional_format
- && ! link_info.relocatable)
+ htab = elf_hash_table (&link_info);
+ if (!is_elf_hash_table (htab))
+ return;
+
+ if (link_info.emit_note_gnu_build_id)
{
- struct elf_link_hash_table *htab;
+ bfd *abfd;
+ asection *s;
+ bfd_size_type size;
- htab = elf_hash_table (&link_info);
- if (is_elf_hash_table (htab))
- {
- bfd *abfd;
- asection *s;
+ abfd = link_info.input_bfds;
- for (abfd = link_info.input_bfds; abfd; abfd = abfd->link_next)
+ if (abfd == NULL)
+ {
+ /* PR 10555: If there are no input files do not
+ try to create a .note.gnu-build-id section. */
+ free (link_info.emit_note_gnu_build_id);
+ link_info.emit_note_gnu_build_id = NULL;
+ }
+ else
+ {
+ size = gld${EMULATION_NAME}_id_note_section_size (abfd, &link_info);
+ if (size == 0)
{
- s = bfd_get_section_by_name (abfd, ".eh_frame");
- if (s && s->size > 8 && !bfd_is_abs_section (s->output_section))
- break;
+ einfo ("%P: warning: unrecognized --build-id style ignored.\n");
+ free (link_info.emit_note_gnu_build_id);
+ link_info.emit_note_gnu_build_id = NULL;
}
- if (abfd)
+ else
{
- const struct elf_backend_data *bed;
-
- bed = get_elf_backend_data (abfd);
- s = bfd_make_section_with_flags (abfd, ".eh_frame_hdr",
- bed->dynamic_sec_flags
- | SEC_READONLY);
- if (s != NULL
- && bfd_set_section_alignment (abfd, s, 2))
- htab->eh_info.hdr_sec = s;
+ s = bfd_make_section_with_flags (abfd, ".note.gnu.build-id",
+ SEC_ALLOC | SEC_LOAD
+ | SEC_IN_MEMORY | SEC_LINKER_CREATED
+ | SEC_READONLY | SEC_DATA);
+ if (s != NULL && bfd_set_section_alignment (abfd, s, 2))
+ {
+ struct elf_obj_tdata *t = elf_tdata (link_info.output_bfd);
+ struct build_id_info *b =
+ (struct build_id_info *) xmalloc (sizeof *b);
+
+ b->style = link_info.emit_note_gnu_build_id;
+ b->sec = s;
+ elf_section_type (s) = SHT_NOTE;
+ s->size = size;
+ t->after_write_object_contents
+ = &gld${EMULATION_NAME}_write_build_id_section;
+ t->after_write_object_contents_info = b;
+ }
else
- einfo ("%P: warning: Cannot create .eh_frame_hdr section,"
- " --eh-frame-hdr ignored.\n");
+ {
+ einfo ("%P: warning: Cannot create .note.gnu.build-id section,"
+ " --build-id ignored.\n");
+ free (link_info.emit_note_gnu_build_id);
+ link_info.emit_note_gnu_build_id = NULL;
+ }
}
}
}
- /* We only need to worry about this when doing a final link. */
- if (link_info.relocatable || !link_info.executable)
+ if (link_info.relocatable)
return;
+ if (link_info.eh_frame_hdr
+ && !link_info.traditional_format)
+ {
+ bfd *abfd;
+ asection *s;
+
+ for (abfd = link_info.input_bfds; abfd; abfd = abfd->link_next)
+ {
+ s = bfd_get_section_by_name (abfd, ".eh_frame");
+ if (s && s->size > 8 && !bfd_is_abs_section (s->output_section))
+ break;
+ }
+ if (abfd)
+ {
+ const struct elf_backend_data *bed;
+
+ bed = get_elf_backend_data (abfd);
+ s = bfd_make_section_with_flags (abfd, ".eh_frame_hdr",
+ bed->dynamic_sec_flags
+ | SEC_READONLY);
+ if (s != NULL
+ && bfd_set_section_alignment (abfd, s, 2))
+ htab->eh_info.hdr_sec = s;
+ else
+ einfo ("%P: warning: Cannot create .eh_frame_hdr section,"
+ " --eh-frame-hdr ignored.\n");
+ }
+ }
+
/* Get the list of files which appear in DT_NEEDED entries in
dynamic objects included in the link (often there will be none).
For each such file, we want to track down the corresponding
special action by the person doing the link. Note that the
needed list can actually grow while we are stepping through this
loop. */
- needed = bfd_elf_get_needed_list (output_bfd, &link_info);
+ if (!link_info.executable)
+ return;
+ needed = bfd_elf_get_needed_list (link_info.output_bfd, &link_info);
for (l = needed; l != NULL; l = l->next)
{
struct bfd_link_needed_list *ll;
search_dirs_type *search;
EOF
if [ "x${NATIVE}" = xyes ] ; then
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
const char *lib_path;
EOF
fi
if [ "x${USE_LIBPATH}" = xyes ] ; then
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
struct bfd_link_needed_list *rp;
int found;
EOF
fi
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
if (gld${EMULATION_NAME}_search_needed (command_line.rpath_link,
&n, force))
break;
EOF
if [ "x${USE_LIBPATH}" = xyes ] ; then
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
if (gld${EMULATION_NAME}_search_needed (command_line.rpath,
&n, force))
break;
EOF
fi
if [ "x${NATIVE}" = xyes ] ; then
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
if (command_line.rpath_link == NULL
&& command_line.rpath == NULL)
{
EOF
fi
if [ "x${USE_LIBPATH}" = xyes ] ; then
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
found = 0;
- rp = bfd_elf_get_runpath_list (output_bfd, &link_info);
+ rp = bfd_elf_get_runpath_list (link_info.output_bfd, &link_info);
for (; !found && rp != NULL; rp = rp->next)
{
char *tmpname = gld${EMULATION_NAME}_add_sysroot (rp->name);
if [ "x${USE_LIBPATH}" = xyes ] ; then
case ${target} in
*-*-freebsd* | *-*-dragonfly*)
- cat >>e${EMULATION_NAME}.c <<EOF
+ fragment <<EOF
if (gld${EMULATION_NAME}_check_ld_elf_hints (l->name, force))
break;
EOF
*-*-linux-* | *-*-k*bsd*-*)
# Linux
- cat >>e${EMULATION_NAME}.c <<EOF
+ fragment <<EOF
if (gld${EMULATION_NAME}_check_ld_so_conf (l->name, force))
break;
;;
esac
fi
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
len = strlen (l->name);
for (search = search_head; search != NULL; search = search->next)
{
if (search != NULL)
break;
EOF
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
}
if (force < 2)
EOF
fi
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
/* Look through an expression for an assignment statement. */
will do no harm. */
if (strcmp (exp->assign.dst, ".") != 0)
{
- if (!bfd_elf_record_link_assignment (output_bfd, &link_info,
+ if (!bfd_elf_record_link_assignment (link_info.output_bfd,
+ &link_info,
exp->assign.dst, provide,
exp->assign.hidden))
einfo ("%P%F: failed to record assignment to %s: %E\n",
else
ELF_INTERPRETER_SET_DEFAULT=
fi
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
+
+/* used by before_allocation and handle_option. */
+static void
+gld${EMULATION_NAME}_append_to_separated_string (char **to, char *op_arg)
+{
+ if (*to == NULL)
+ *to = xstrdup (op_arg);
+ else
+ {
+ size_t to_len = strlen (*to);
+ size_t op_arg_len = strlen (op_arg);
+ char *buf;
+ char *cp = *to;
+
+ /* First see whether OPTARG is already in the path. */
+ do
+ {
+ if (strncmp (op_arg, cp, op_arg_len) == 0
+ && (cp[op_arg_len] == 0
+ || cp[op_arg_len] == config.rpath_separator))
+ /* We found it. */
+ break;
+
+ /* Not yet found. */
+ cp = strchr (cp, config.rpath_separator);
+ if (cp != NULL)
+ ++cp;
+ }
+ while (cp != NULL);
+
+ if (cp == NULL)
+ {
+ buf = xmalloc (to_len + op_arg_len + 2);
+ sprintf (buf, "%s%c%s", *to,
+ config.rpath_separator, op_arg);
+ free (*to);
+ *to = buf;
+ }
+ }
+}
/* This is called after the sections have been attached to output
sections, but before any sizes or addresses have been set. */
{
const char *rpath;
asection *sinterp;
+ bfd *abfd;
if (link_info.hash->type == bfd_link_elf_hash_table)
- _bfd_elf_tls_setup (output_bfd, &link_info);
+ _bfd_elf_tls_setup (link_info.output_bfd, &link_info);
/* If we are going to make any variable assignments, we need to let
the ELF backend know about them in case the variables are
rpath = command_line.rpath;
if (rpath == NULL)
rpath = (const char *) getenv ("LD_RUN_PATH");
+
+ for (abfd = link_info.input_bfds; abfd; abfd = abfd->link_next)
+ {
+ const char *audit_libs = elf_dt_audit (abfd);
+
+ /* If the input bfd contains an audit entry, we need to add it as
+ a dep audit entry. */
+ if (audit_libs && *audit_libs != '\0')
+ {
+ char *cp = xstrdup (audit_libs);
+ do
+ {
+ int more = 0;
+ char *cp2 = strchr (cp, config.rpath_separator);
+
+ if (cp2)
+ {
+ *cp2 = '\0';
+ more = 1;
+ }
+
+ if (cp != NULL && *cp != '\0')
+ gld${EMULATION_NAME}_append_to_separated_string (&depaudit, cp);
+
+ cp = more ? ++cp2 : NULL;
+ }
+ while (cp != NULL);
+ }
+ }
+
if (! (bfd_elf_size_dynamic_sections
- (output_bfd, command_line.soname, rpath,
- command_line.filter_shlib,
+ (link_info.output_bfd, command_line.soname, rpath,
+ command_line.filter_shlib, audit, depaudit,
(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");
continue;
sz = s->size;
- msg = xmalloc ((size_t) (sz + 1));
+ msg = (char *) xmalloc ((size_t) (sz + 1));
if (! bfd_get_section_contents (is->the_bfd, s, msg,
(file_ptr) 0, sz))
einfo ("%F%B: Can't read contents of section .gnu.warning: %E\n",
before_allocation_default ();
- if (!bfd_elf_size_dynsym_hash_dynstr (output_bfd, &link_info))
+ if (!bfd_elf_size_dynsym_hash_dynstr (link_info.output_bfd, &link_info))
einfo ("%P%F: failed to set dynamic section sizes: %E\n");
}
fi
if test x"$LDEMUL_OPEN_DYNAMIC_ARCHIVE" != xgld"$EMULATION_NAME"_open_dynamic_archive; then
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
/* Try to open a dynamic archive. This is where we know that ELF
dynamic libraries have an extension of .so (or .sl on oddball systems
/* Try the .so extension first. If that fails build a new filename
using EXTRA_SHLIB_EXTENSION. */
if (! ldfile_try_open_bfd (string, entry))
- sprintf (string, "%s/lib%s%s%s", search->name,
- filename, arch, EXTRA_SHLIB_EXTENSION);
+ {
+ sprintf (string, "%s/lib%s%s%s", search->name,
+ filename, arch, EXTRA_SHLIB_EXTENSION);
#endif
if (! ldfile_try_open_bfd (string, entry))
free (string);
return FALSE;
}
+#ifdef EXTRA_SHLIB_EXTENSION
+ }
+#endif
entry->filename = string;
fi
if test x"$LDEMUL_PLACE_ORPHAN" != xgld"$EMULATION_NAME"_place_orphan; then
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
/* A variant of lang_output_section_find used by place_orphan. */
lang_output_section_statement_type *lookup;
lang_output_section_statement_type *last = NULL;
lang_output_section_statement_type *last_alloc = NULL;
+ lang_output_section_statement_type *last_ro_alloc = NULL;
lang_output_section_statement_type *last_rel = NULL;
lang_output_section_statement_type *last_rel_alloc = NULL;
int rela = sec->name[4] == 'a';
lookup != NULL;
lookup = lookup->next)
{
- if (lookup->constraint != -1
+ if (lookup->constraint >= 0
&& CONST_STRNEQ (lookup->name, ".rel"))
{
int lookrela = lookup->name[4] == 'a';
last = lookup;
if (lookup->bfd_section != NULL
&& (lookup->bfd_section->flags & SEC_ALLOC) != 0)
- last_alloc = lookup;
+ {
+ last_alloc = lookup;
+ if ((lookup->bfd_section->flags & SEC_READONLY) != 0)
+ last_ro_alloc = lookup;
+ }
}
if (last_rel_alloc)
if (last_rel)
return last_rel;
+ if (last_ro_alloc)
+ return last_ro_alloc;
+
if (last_alloc)
return last_alloc;
/* Place an orphan section. We use this to put random SHF_ALLOC
sections in the right segment. */
-static bfd_boolean
-gld${EMULATION_NAME}_place_orphan (asection *s)
+static lang_output_section_statement_type *
+gld${EMULATION_NAME}_place_orphan (asection *s,
+ const char *secname,
+ int constraint)
{
static struct orphan_save hold[] =
{
0, 0, 0, 0 },
{ ".sdata",
SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_SMALL_DATA,
- 0, 0, 0, 0 }
+ 0, 0, 0, 0 },
+ { 0,
+ SEC_HAS_CONTENTS,
+ 0, 0, 0, 0 },
};
enum orphan_save_index
{
orphan_bss,
orphan_rel,
orphan_interp,
- orphan_sdata
+ orphan_sdata,
+ orphan_nonalloc
};
static int orphan_init_done = 0;
struct orphan_save *place;
- const char *secname;
lang_output_section_statement_type *after;
lang_output_section_statement_type *os;
int isdyn = 0;
int iself = s->owner->xvec->flavour == bfd_target_elf_flavour;
unsigned int sh_type = iself ? elf_section_type (s) : SHT_NULL;
- secname = bfd_get_section_name (s->owner, s);
-
if (! link_info.relocatable
&& link_info.combreloc
&& (s->flags & SEC_ALLOC))
}
}
- if (isdyn || (!config.unique_orphan_sections && !unique_section_p (s)))
- {
- /* Look through the script to see where to place this section. */
- os = lang_output_section_find (secname);
-
- if (os != NULL
- && (os->bfd_section == NULL
- || os->bfd_section->flags == 0
- || (_bfd_elf_match_sections_by_type (output_bfd,
- os->bfd_section,
- s->owner, s)
- && ((s->flags ^ os->bfd_section->flags)
- & (SEC_LOAD | SEC_ALLOC)) == 0)))
- {
- /* We already have an output section statement with this
- name, and its bfd section, if any, has compatible flags.
- If the section already exists but does not have any flags
- set, then it has been created by the linker, probably as a
- result of a --section-start command line switch. */
- lang_add_section (&os->children, s, os);
- return TRUE;
- }
- }
+ /* Look through the script to see where to place this section. */
+ if (constraint == 0)
+ for (os = lang_output_section_find (secname);
+ os != NULL;
+ os = next_matching_output_section_statement (os, 0))
+ {
+ /* If we don't match an existing output section, tell
+ lang_insert_orphan to create a new output section. */
+ constraint = SPECIAL;
+
+ if (os->bfd_section != NULL
+ && (os->bfd_section->flags == 0
+ || (_bfd_elf_match_sections_by_type (link_info.output_bfd,
+ os->bfd_section,
+ s->owner, s)
+ && ((s->flags ^ os->bfd_section->flags)
+ & (SEC_LOAD | SEC_ALLOC)) == 0)))
+ {
+ /* We already have an output section statement with this
+ name, and its bfd section has compatible flags.
+ If the section already exists but does not have any flags
+ set, then it has been created by the linker, probably as a
+ result of a --section-start command line switch. */
+ lang_add_section (&os->children, s, os);
+ return os;
+ }
+ }
if (!orphan_init_done)
{
+ lang_output_section_statement_type *lookup;
struct orphan_save *ho;
+
for (ho = hold; ho < hold + sizeof (hold) / sizeof (hold[0]); ++ho)
if (ho->name != NULL)
{
if (ho->os != NULL && ho->os->flags == 0)
ho->os->flags = ho->flags;
}
+ lookup = hold[orphan_bss].os;
+ if (lookup == NULL)
+ lookup = &lang_output_section_statement.head->output_section_statement;
+ for (; lookup != NULL; lookup = lookup->next)
+ if ((lookup->bfd_section != NULL
+ && (lookup->bfd_section->flags & SEC_DEBUGGING) != 0)
+ || strcmp (lookup->name, ".comment") == 0)
+ break;
+ hold[orphan_nonalloc].os = lookup ? lookup->prev : NULL;
+ hold[orphan_nonalloc].name = ".comment";
orphan_init_done = 1;
}
sections into the .text section to get them out of the way. */
if (link_info.executable
&& ! link_info.relocatable
- && CONST_STRNEQ (secname, ".gnu.warning.")
+ && CONST_STRNEQ (s->name, ".gnu.warning.")
&& hold[orphan_text].os != NULL)
{
- lang_add_section (&hold[orphan_text].os->children, s,
- hold[orphan_text].os);
- return TRUE;
+ os = hold[orphan_text].os;
+ lang_add_section (&os->children, s, os);
+ return os;
}
/* Decide which segment the section should go in based on the
in the first page. */
place = NULL;
- if ((s->flags & SEC_ALLOC) == 0)
+ if ((s->flags & (SEC_ALLOC | SEC_DEBUGGING)) == 0)
+ place = &hold[orphan_nonalloc];
+ else if ((s->flags & SEC_ALLOC) == 0)
;
else if ((s->flags & SEC_LOAD) != 0
&& ((iself && sh_type == SHT_NOTE)
after = &lang_output_section_statement.head->output_section_statement;
}
- /* 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 allocatable characteristics. */
- if (bfd_get_section_by_name (output_bfd, secname) != NULL)
- {
- static int count = 1;
- secname = bfd_get_unique_section_name (output_bfd, secname, &count);
- if (secname == NULL)
- einfo ("%F%P: place_orphan failed: %E\n");
- }
-
- lang_insert_orphan (s, secname, after, place, NULL, NULL);
-
- return TRUE;
+ return lang_insert_orphan (s, secname, constraint, after, place, NULL, NULL);
}
EOF
fi
-if test x"$LDEMUL_FINISH" != xgld"$EMULATION_NAME"_finish; then
-cat >>e${EMULATION_NAME}.c <<EOF
+if test x"$LDEMUL_AFTER_ALLOCATION" != xgld"$EMULATION_NAME"_after_allocation; then
+fragment <<EOF
static void
-gld${EMULATION_NAME}_finish (void)
+gld${EMULATION_NAME}_after_allocation (void)
{
- bfd_boolean need_layout = bfd_elf_discard_info (output_bfd, &link_info);
-
+ bfd_boolean need_layout = bfd_elf_discard_info (link_info.output_bfd,
+ &link_info);
gld${EMULATION_NAME}_map_segments (need_layout);
- finish_default ();
}
EOF
fi
if test x"$LDEMUL_GET_SCRIPT" != xgld"$EMULATION_NAME"_get_script; then
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
static char *
gld${EMULATION_NAME}_get_script (int *isfile)
# sed commands to quote an ld script as a C string.
sc="-f stringify.sed"
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
{
*isfile = 0;
if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
echo ' ; else if (link_info.pie && link_info.combreloc' >> e${EMULATION_NAME}.c
echo ' && link_info.relro' >> e${EMULATION_NAME}.c
-echo ' && (link_info.flags & DT_BIND_NOW)) return' >> e${EMULATION_NAME}.c
+echo ' && (link_info.flags & DF_BIND_NOW)) return' >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xdw >> e${EMULATION_NAME}.c
echo ' ; else if (link_info.pie && link_info.combreloc) return' >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xdc >> e${EMULATION_NAME}.c
if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
echo ' ; else if (link_info.shared && link_info.combreloc' >> e${EMULATION_NAME}.c
echo ' && link_info.relro' >> e${EMULATION_NAME}.c
-echo ' && (link_info.flags & DT_BIND_NOW)) return' >> e${EMULATION_NAME}.c
+echo ' && (link_info.flags & DF_BIND_NOW)) return' >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xsw >> e${EMULATION_NAME}.c
echo ' ; else if (link_info.shared && link_info.combreloc) return' >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xsc >> e${EMULATION_NAME}.c
fi
if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
echo ' ; else if (link_info.combreloc && link_info.relro' >> e${EMULATION_NAME}.c
-echo ' && (link_info.flags & DT_BIND_NOW)) return' >> e${EMULATION_NAME}.c
+echo ' && (link_info.flags & DF_BIND_NOW)) return' >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xw >> e${EMULATION_NAME}.c
echo ' ; else if (link_info.combreloc) return' >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xc >> e${EMULATION_NAME}.c
else
# Scripts read from the filesystem.
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
{
*isfile = 1;
EOF
if cmp -s ldscripts/${EMULATION_NAME}.x ldscripts/${EMULATION_NAME}.xn; then :
else
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
else if (!config.magic_demand_paged)
return "ldscripts/${EMULATION_NAME}.xn";
EOF
fi
if test -n "$GENERATE_PIE_SCRIPT" ; then
if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
else if (link_info.pie && link_info.combreloc
- && link_info.relro && (link_info.flags & DT_BIND_NOW))
+ && link_info.relro && (link_info.flags & DF_BIND_NOW))
return "ldscripts/${EMULATION_NAME}.xdw";
else if (link_info.pie && link_info.combreloc)
return "ldscripts/${EMULATION_NAME}.xdc";
EOF
fi
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
else if (link_info.pie)
return "ldscripts/${EMULATION_NAME}.xd";
EOF
fi
if test -n "$GENERATE_SHLIB_SCRIPT" ; then
if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
else if (link_info.shared && link_info.combreloc
- && link_info.relro && (link_info.flags & DT_BIND_NOW))
+ && link_info.relro && (link_info.flags & DF_BIND_NOW))
return "ldscripts/${EMULATION_NAME}.xsw";
else if (link_info.shared && link_info.combreloc)
return "ldscripts/${EMULATION_NAME}.xsc";
EOF
fi
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
else if (link_info.shared)
return "ldscripts/${EMULATION_NAME}.xs";
EOF
fi
if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
else if (link_info.combreloc && link_info.relro
- && (link_info.flags & DT_BIND_NOW))
+ && (link_info.flags & DF_BIND_NOW))
return "ldscripts/${EMULATION_NAME}.xw";
else if (link_info.combreloc)
return "ldscripts/${EMULATION_NAME}.xc";
EOF
fi
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
else
return "ldscripts/${EMULATION_NAME}.x";
}
if test -n "$PARSE_AND_LIST_ARGS_CASES" -o x"$GENERATE_SHLIB_SCRIPT" = xyes; then
if test -n "$PARSE_AND_LIST_PROLOGUE" ; then
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
$PARSE_AND_LIST_PROLOGUE
EOF
fi
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
#define OPTION_DISABLE_NEW_DTAGS (400)
#define OPTION_ENABLE_NEW_DTAGS (OPTION_DISABLE_NEW_DTAGS + 1)
#define OPTION_EH_FRAME_HDR (OPTION_GROUP + 1)
#define OPTION_EXCLUDE_LIBS (OPTION_EH_FRAME_HDR + 1)
#define OPTION_HASH_STYLE (OPTION_EXCLUDE_LIBS + 1)
+#define OPTION_BUILD_ID (OPTION_HASH_STYLE + 1)
+#define OPTION_AUDIT (OPTION_BUILD_ID + 1)
static void
gld${EMULATION_NAME}_add_options
(int ns, char **shortopts, int nl, struct option **longopts,
int nrl ATTRIBUTE_UNUSED, struct option **really_longopts ATTRIBUTE_UNUSED)
{
- static const char xtra_short[] = "${PARSE_AND_LIST_SHORTOPTS}z:";
+ static const char xtra_short[] = "${PARSE_AND_LIST_SHORTOPTS}z:P:";
static const struct option xtra_long[] = {
+ {"build-id", optional_argument, NULL, OPTION_BUILD_ID},
+ {"audit", required_argument, NULL, OPTION_AUDIT},
+ {"depaudit", required_argument, NULL, 'P'},
EOF
if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
{"disable-new-dtags", no_argument, NULL, OPTION_DISABLE_NEW_DTAGS},
{"enable-new-dtags", no_argument, NULL, OPTION_ENABLE_NEW_DTAGS},
{"eh-frame-hdr", no_argument, NULL, OPTION_EH_FRAME_HDR},
fi
if test -n "$PARSE_AND_LIST_LONGOPTS" ; then
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
$PARSE_AND_LIST_LONGOPTS
EOF
fi
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
{NULL, no_argument, NULL, 0}
};
memcpy (*longopts + nl, &xtra_long, sizeof (xtra_long));
}
+#define DEFAULT_BUILD_ID_STYLE "sha1"
+
static bfd_boolean
gld${EMULATION_NAME}_handle_option (int optc)
{
default:
return FALSE;
+ case OPTION_BUILD_ID:
+ if (link_info.emit_note_gnu_build_id != NULL)
+ {
+ free (link_info.emit_note_gnu_build_id);
+ link_info.emit_note_gnu_build_id = NULL;
+ }
+ if (optarg == NULL)
+ optarg = DEFAULT_BUILD_ID_STYLE;
+ if (strcmp (optarg, "none"))
+ link_info.emit_note_gnu_build_id = xstrdup (optarg);
+ break;
+ case OPTION_AUDIT:
+ gld${EMULATION_NAME}_append_to_separated_string (&audit, optarg);
+ break;
+ case 'P':
+ gld${EMULATION_NAME}_append_to_separated_string (&depaudit, optarg);
+ break;
+
EOF
if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
case OPTION_DISABLE_NEW_DTAGS:
link_info.new_dtags = FALSE;
break;
EOF
if test -n "$COMMONPAGESIZE"; then
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
else if (strcmp (optarg, "relro") == 0)
link_info.relro = TRUE;
else if (strcmp (optarg, "norelro") == 0)
EOF
fi
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
else if (CONST_STRNEQ (optarg, "max-page-size="))
{
char *end;
if (*end || (config.maxpagesize & (config.maxpagesize - 1)) != 0)
einfo (_("%P%F: invalid maxium page size \`%s'\n"),
optarg + 14);
- ASSERT (default_target != NULL);
- bfd_emul_set_maxpagesize (default_target, config.maxpagesize);
}
else if (CONST_STRNEQ (optarg, "common-page-size="))
{
|| (config.commonpagesize & (config.commonpagesize - 1)) != 0)
einfo (_("%P%F: invalid common page size \`%s'\n"),
optarg + 17);
- ASSERT (default_target != NULL);
- bfd_emul_set_commonpagesize (default_target,
- config.commonpagesize);
}
/* What about the other Solaris -z options? FIXME. */
break;
fi
if test -n "$PARSE_AND_LIST_ARGS_CASES" ; then
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
$PARSE_AND_LIST_ARGS_CASES
EOF
fi
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
}
return TRUE;
EOF
if test x"$LDEMUL_LIST_OPTIONS" != xgld"$EMULATION_NAME"_list_options; then
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
static void
gld${EMULATION_NAME}_list_options (FILE * file)
{
+ fprintf (file, _("\
+ --build-id[=STYLE] Generate build ID note\n"));
+ fprintf (file, _("\
+ --audit=AUDITLIB Specify a library to use for auditing\n"));
+ fprintf (file, _("\
+ -P AUDITLIB, --depaudit=AUDITLIB\n" "\
+ Specify a library to use for auditing dependencies\n"));
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, _(" --eh-frame-hdr\tCreate .eh_frame_hdr section\n"));
- fprintf (file, _(" --hash-style=STYLE\tSet hash style to sysv, gnu or both\n"));
- fprintf (file, _(" -z combreloc\t\tMerge dynamic relocs into one section and sort\n"));
- fprintf (file, _(" -z defs\t\tReport unresolved symbols in object files.\n"));
- fprintf (file, _(" -z execstack\t\tMark executable as requiring executable stack\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 lazy\t\tMark object lazy runtime binding (default)\n"));
- fprintf (file, _(" -z loadfltr\t\tMark object requiring immediate process\n"));
- fprintf (file, _(" -z muldefs\t\tAllow multiple definitions\n"));
- fprintf (file, _(" -z nocombreloc\tDon't merge dynamic relocs into one section\n"));
- fprintf (file, _(" -z nocopyreloc\tDon't create copy relocs\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 available to dlopen\n"));
- fprintf (file, _(" -z nodump\t\tMark DSO not available to dldump\n"));
- fprintf (file, _(" -z noexecstack\tMark executable as not requiring executable stack\n"));
+fragment <<EOF
+ fprintf (file, _("\
+ -Bgroup Selects group name lookup rules for DSO\n"));
+ fprintf (file, _("\
+ --disable-new-dtags Disable new dynamic tags\n"));
+ fprintf (file, _("\
+ --enable-new-dtags Enable new dynamic tags\n"));
+ fprintf (file, _("\
+ --eh-frame-hdr Create .eh_frame_hdr section\n"));
+ fprintf (file, _("\
+ --hash-style=STYLE Set hash style to sysv, gnu or both\n"));
+ fprintf (file, _("\
+ -z combreloc Merge dynamic relocs into one section and sort\n"));
+ fprintf (file, _("\
+ -z defs Report unresolved symbols in object files.\n"));
+ fprintf (file, _("\
+ -z execstack Mark executable as requiring executable stack\n"));
+ fprintf (file, _("\
+ -z initfirst Mark DSO to be initialized first at runtime\n"));
+ fprintf (file, _("\
+ -z interpose Mark object to interpose all DSOs but executable\n"));
+ fprintf (file, _("\
+ -z lazy Mark object lazy runtime binding (default)\n"));
+ fprintf (file, _("\
+ -z loadfltr Mark object requiring immediate process\n"));
+ fprintf (file, _("\
+ -z muldefs Allow multiple definitions\n"));
+ fprintf (file, _("\
+ -z nocombreloc Don't merge dynamic relocs into one section\n"));
+ fprintf (file, _("\
+ -z nocopyreloc Don't create copy relocs\n"));
+ fprintf (file, _("\
+ -z nodefaultlib Mark object not to use default search paths\n"));
+ fprintf (file, _("\
+ -z nodelete Mark DSO non-deletable at runtime\n"));
+ fprintf (file, _("\
+ -z nodlopen Mark DSO not available to dlopen\n"));
+ fprintf (file, _("\
+ -z nodump Mark DSO not available to dldump\n"));
+ fprintf (file, _("\
+ -z noexecstack Mark executable as not requiring executable stack\n"));
EOF
if test -n "$COMMONPAGESIZE"; then
-cat >>e${EMULATION_NAME}.c <<EOF
- fprintf (file, _(" -z norelro\t\tDon't create RELRO program header\n"));
+fragment <<EOF
+ fprintf (file, _("\
+ -z norelro Don't create RELRO program header\n"));
EOF
fi
-cat >>e${EMULATION_NAME}.c <<EOF
- fprintf (file, _(" -z now\t\tMark object non-lazy runtime binding\n"));
- fprintf (file, _(" -z origin\t\tMark object requiring immediate \$ORIGIN processing\n\t\t\t at runtime\n"));
+fragment <<EOF
+ fprintf (file, _("\
+ -z now Mark object non-lazy runtime binding\n"));
+ fprintf (file, _("\
+ -z origin Mark object requiring immediate \$ORIGIN\n\
+ processing at runtime\n"));
EOF
if test -n "$COMMONPAGESIZE"; then
-cat >>e${EMULATION_NAME}.c <<EOF
- fprintf (file, _(" -z relro\t\tCreate RELRO program header\n"));
+fragment <<EOF
+ fprintf (file, _("\
+ -z relro Create RELRO program header\n"));
EOF
fi
-cat >>e${EMULATION_NAME}.c <<EOF
- fprintf (file, _(" -z max-page-size=SIZE\tSet maximum page size to SIZE\n"));
- fprintf (file, _(" -z common-page-size=SIZE\n\t\t\tSet common page size to SIZE\n"));
- fprintf (file, _(" -z KEYWORD\t\tIgnored for Solaris compatibility\n"));
+fragment <<EOF
+ fprintf (file, _("\
+ -z max-page-size=SIZE Set maximum page size to SIZE\n"));
+ fprintf (file, _("\
+ -z common-page-size=SIZE Set common page size to SIZE\n"));
+ fprintf (file, _("\
+ -z KEYWORD Ignored for Solaris compatibility\n"));
EOF
fi
if test -n "$PARSE_AND_LIST_OPTIONS" ; then
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
$PARSE_AND_LIST_OPTIONS
EOF
fi
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
}
EOF
if test -n "$PARSE_AND_LIST_EPILOGUE" ; then
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
$PARSE_AND_LIST_EPILOGUE
EOF
fi
fi
else
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
#define gld${EMULATION_NAME}_add_options NULL
#define gld${EMULATION_NAME}_handle_option NULL
EOF
if test x"$LDEMUL_LIST_OPTIONS" != xgld"$EMULATION_NAME"_list_options; then
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
#define gld${EMULATION_NAME}_list_options NULL
EOF
fi
fi
-cat >>e${EMULATION_NAME}.c <<EOF
+fragment <<EOF
struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
{
${LDEMUL_HLL-hll_default},
${LDEMUL_AFTER_PARSE-after_parse_default},
${LDEMUL_AFTER_OPEN-gld${EMULATION_NAME}_after_open},
- ${LDEMUL_AFTER_ALLOCATION-after_allocation_default},
+ ${LDEMUL_AFTER_ALLOCATION-gld${EMULATION_NAME}_after_allocation},
${LDEMUL_SET_OUTPUT_ARCH-set_output_arch_default},
${LDEMUL_CHOOSE_TARGET-ldemul_default_target},
${LDEMUL_BEFORE_ALLOCATION-gld${EMULATION_NAME}_before_allocation},
${LDEMUL_GET_SCRIPT-gld${EMULATION_NAME}_get_script},
"${EMULATION_NAME}",
"${OUTPUT_FORMAT}",
- ${LDEMUL_FINISH-gld${EMULATION_NAME}_finish},
+ ${LDEMUL_FINISH-finish_default},
${LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS-NULL},
${LDEMUL_OPEN_DYNAMIC_ARCHIVE-gld${EMULATION_NAME}_open_dynamic_archive},
${LDEMUL_PLACE_ORPHAN-gld${EMULATION_NAME}_place_orphan},