/* This file is is generated by a shell script. DO NOT EDIT! */
/* ${ELFSIZE} bit ELF emulation code for ${EMULATION_NAME}
- Copyright (C) 1991-2014 Free Software Foundation, Inc.
+ Copyright (C) 1991-2018 Free Software Foundation, Inc.
Written by Steve Chamberlain <sac@cygnus.com>
ELF support by Ian Lance Taylor <ian@cygnus.com>
/* Declare functions used by various EXTRA_EM_FILEs. */
static void gld${EMULATION_NAME}_before_parse (void);
+static void gld${EMULATION_NAME}_after_parse (void);
static void gld${EMULATION_NAME}_after_open (void);
static void gld${EMULATION_NAME}_before_allocation (void);
static void gld${EMULATION_NAME}_after_allocation (void);
input_flags.dynamic = ${DYNAMIC_LINK-TRUE};
config.has_shared = `if test -n "$GENERATE_SHLIB_SCRIPT" ; then echo TRUE ; else echo FALSE ; fi`;
config.separate_code = `if test "x${SEPARATE_CODE}" = xyes ; then echo TRUE ; else echo FALSE ; fi`;
+ `if test -n "$CALL_NOP_BYTE" ; then echo link_info.call_nop_byte = $CALL_NOP_BYTE; fi`;
+ link_info.check_relocs_after_open_input = TRUE;
+ link_info.relro = DEFAULT_LD_Z_RELRO;
+ link_info.separate_code = DEFAULT_LD_Z_SEPARATE_CODE;
+}
+
+EOF
+fi
+
+if test x"$LDEMUL_AFTER_PARSE" != xgld"$EMULATION_NAME"_after_parse; then
+fragment <<EOF
+
+static void
+gld${EMULATION_NAME}_after_parse (void)
+{
+ if (bfd_link_pie (&link_info))
+ link_info.flags_1 |= (bfd_vma) DF_1_PIE;
+
+ if (bfd_link_executable (&link_info)
+ && link_info.nointerp)
+ {
+ if (link_info.dynamic_undefined_weak > 0)
+ einfo (_("%P: warning: -z dynamic-undefined-weak ignored\n"));
+ link_info.dynamic_undefined_weak = 0;
+ }
+ after_parse_default ();
}
EOF
if (entry->flags.just_syms
&& (bfd_get_file_flags (entry->the_bfd) & DYNAMIC) != 0)
- einfo (_("%P%F: --just-symbols may not be used on DSO: %B\n"),
+ einfo (_("%F%P: %pB: --just-symbols may not be used on DSO\n"),
entry->the_bfd);
if (link_class == 0
if (bfd_stat (s->the_bfd, &st) != 0)
{
- einfo ("%P:%B: bfd_stat failed: %E\n", s->the_bfd);
+ einfo (_("%P: %pB: bfd_stat failed: %E\n"), s->the_bfd);
return;
}
soname = lbasename (s->filename);
if (filename_ncmp (soname, global_needed->name, suffix - global_needed->name) == 0)
- einfo ("%P: warning: %s, needed by %B, may conflict with %s\n",
+ einfo (_("%P: warning: %s, needed by %pB, may conflict with %s\n"),
global_needed->name, global_needed->by, soname);
}
abfd = bfd_openr (name, bfd_get_target (link_info.output_bfd));
if (abfd == NULL)
- return FALSE;
+ {
+ if (verbose)
+ info_msg (_("attempt to open %s failed\n"), name);
+ return FALSE;
+ }
/* Linker needs to decompress sections. */
abfd->flags |= BFD_DECOMPRESS;
struct bfd_link_needed_list *needs;
if (! bfd_elf_get_bfd_needed_list (abfd, &needs))
- einfo ("%F%P:%B: bfd_elf_get_bfd_needed_list failed: %E\n", abfd);
+ einfo (_("%F%P: %pB: bfd_elf_get_bfd_needed_list failed: %E\n"), abfd);
if (needs != NULL)
{
can only check that using stat. */
if (bfd_stat (abfd, &global_stat) != 0)
- einfo ("%F%P:%B: bfd_stat failed: %E\n", abfd);
+ einfo (_("%F%P: %pB: bfd_stat failed: %E\n"), abfd);
/* First strip off everything before the last '/'. */
soname = lbasename (abfd->filename);
/* Add this file into the symbol table. */
if (! bfd_link_add_symbols (abfd, &link_info))
- einfo ("%F%B: error adding symbols: %E\n", abfd);
+ einfo (_("%F%P: %pB: error adding symbols: %E\n"), abfd);
return TRUE;
}
-
/* Search for a needed file in a path. */
static bfd_boolean
len = strlen (name);
while (1)
{
+ unsigned offset = 0;
+ char * var;
char *filename, *sset;
s = strchr (path, config.rpath_separator);
}
strcpy (sset, name);
+ /* PR 20535: Support the same pseudo-environment variables that
+ are supported by ld.so. Namely, $ORIGIN, $LIB and $PLATFORM.
+ Since there can be more than one occurrence of these tokens in
+ the path we loop until no more are found. Since we might not
+ be able to substitute some of the tokens we maintain an offset
+ into the filename for where we should begin our scan. */
+ while ((var = strchr (filename + offset, '$')) != NULL)
+ {
+ /* The ld.so manual page does not say, but I am going to assume that
+ these tokens are terminated by a directory separator character
+ (/) or the end of the string. There is also an implication that
+ $ORIGIN should only be used at the start of a path, but that is
+ not enforced here.
+
+ The ld.so manual page also states that it allows ${ORIGIN},
+ ${LIB} and ${PLATFORM}, so these are supported as well.
+
+ FIXME: The code could be a lot cleverer about allocating space
+ for the processed string. */
+ char * end = strchr (var, '/');
+ char * replacement = NULL;
+ char * v = var + 1;
+ char * freeme = NULL;
+ unsigned flen = strlen (filename);
+
+ if (end != NULL)
+ /* Temporarily terminate the filename at the end of the token. */
+ * end = 0;
+
+ if (*v == '{')
+ ++ v;
+ switch (*v++)
+ {
+ case 'O':
+ if (strcmp (v, "RIGIN") == 0 || strcmp (v, "RIGIN}") == 0)
+ {
+ /* ORIGIN - replace with the full path to the directory
+ containing the program or shared object. */
+ if (needed.by == NULL)
+ {
+ if (link_info.output_bfd == NULL)
+ {
+ break;
+ }
+ else
+ replacement = bfd_get_filename (link_info.output_bfd);
+ }
+ else
+ replacement = bfd_get_filename (needed.by);
+
+ if (replacement)
+ {
+ char * slash;
+
+ if (replacement[0] == '/')
+ freeme = xstrdup (replacement);
+ else
+ {
+ char * current_dir = getpwd ();
+
+ freeme = xmalloc (strlen (replacement) + strlen (current_dir) + 2);
+ sprintf (freeme, "%s/%s", current_dir, replacement);
+ }
+
+ replacement = freeme;
+ if ((slash = strrchr (replacement, '/')) != NULL)
+ * slash = 0;
+ }
+ }
+ break;
+
+ case 'L':
+ if (strcmp (v, "IB") == 0 || strcmp (v, "IB}") == 0)
+ {
+ /* LIB - replace with "lib" in 32-bit environments
+ and "lib64" in 64-bit environments. */
+
+ /* Note - we could replace this switch statement by
+ conditional fragments of shell script, but that is messy.
+ Any compiler worth its salt is going to optimize away
+ all but one of these case statements anyway. */
+ switch ($ELFSIZE)
+ {
+ case 32: replacement = "lib"; break;
+ case 64: replacement = "lib64"; break;
+ default:
+ /* $ELFSIZE is not 32 or 64 ... */
+ abort ();
+ }
+ }
+ break;
+
+ case 'P':
+ /* Supporting $PLATFORM in a cross-hosted environment is not
+ possible. Supporting it in a native environment involves
+ loading the <sys/auxv.h> header file which loads the
+ system <elf.h> header file, which conflicts with the
+ "include/elf/mips.h" header file. */
+ /* Fall through. */
+ default:
+ break;
+ }
+
+ if (replacement)
+ {
+ char * filename2 = xmalloc (flen + strlen (replacement));
+
+ if (end)
+ {
+ sprintf (filename2, "%.*s%s/%s",
+ (int)(var - filename), filename,
+ replacement, end + 1);
+ offset = (var - filename) + 1 + strlen (replacement);
+ }
+ else
+ {
+ sprintf (filename2, "%.*s%s",
+ (int)(var - filename), filename,
+ replacement);
+ offset = var - filename + strlen (replacement);
+ }
+
+ free (filename);
+ filename = filename2;
+ /* There is no need to restore the path separator (when
+ end != NULL) as we have replaced the entire string. */
+ }
+ else
+ {
+ if (verbose)
+ /* We only issue an "unrecognised" message in verbose mode
+ as the $<foo> token might be a legitimate component of
+ a path name in the target's file system. */
+ info_msg (_("unrecognised or unsupported token '%s' in search path\n"), var);
+
+ if (end)
+ /* Restore the path separator. */
+ * end = '/';
+
+ /* PR 20784: Make sure that we resume the scan *after*
+ the token that we could not replace. */
+ offset = (var + 1) - filename;
+ }
+
+ free (freeme);
+ }
+
needed.name = filename;
+
if (gld${EMULATION_NAME}_try_needed (&needed, force))
return TRUE;
if [ "x${USE_LIBPATH}" = xyes ] ; then
fragment <<EOF
-/* Add the sysroot to every entry in a path separated by
- config.rpath_separator. */
+/* Prefix the sysroot to absolute paths in PATH, a string containing
+ paths separated by config.rpath_separator. If running on a DOS
+ file system, paths containing a drive spec won't have the sysroot
+ prefix added, unless the sysroot also specifies the same drive. */
-static char *
+static const char *
gld${EMULATION_NAME}_add_sysroot (const char *path)
{
- int len, colons, i;
- char *ret, *p;
-
- len = strlen (path);
- colons = 0;
- i = 0;
- while (path[i])
- if (path[i++] == config.rpath_separator)
- colons++;
-
- if (path[i])
- colons++;
-
- len = len + (colons + 1) * strlen (ld_sysroot);
- ret = xmalloc (len + 1);
- strcpy (ret, ld_sysroot);
- p = ret + strlen (ret);
- i = 0;
- while (path[i])
- if (path[i] == config.rpath_separator)
- {
- *p++ = path[i++];
- strcpy (p, ld_sysroot);
- p = p + strlen (p);
- }
- else
- *p++ = path[i++];
+ size_t len, extra;
+ const char *p;
+ char *ret, *q;
+ int dos_drive_sysroot = HAS_DRIVE_SPEC (ld_sysroot);
+
+ len = strlen (ld_sysroot);
+ for (extra = 0, p = path; ; )
+ {
+ int dos_drive = HAS_DRIVE_SPEC (p);
+
+ if (dos_drive)
+ p += 2;
+ if (IS_DIR_SEPARATOR (*p)
+ && (!dos_drive
+ || (dos_drive_sysroot
+ && ld_sysroot[0] == p[-2])))
+ {
+ if (dos_drive && dos_drive_sysroot)
+ extra += len - 2;
+ else
+ extra += len;
+ }
+ p = strchr (p, config.rpath_separator);
+ if (!p)
+ break;
+ ++p;
+ }
+
+ ret = xmalloc (strlen (path) + extra + 1);
+
+ for (q = ret, p = path; ; )
+ {
+ const char *end;
+ int dos_drive = HAS_DRIVE_SPEC (p);
+
+ if (dos_drive)
+ {
+ *q++ = *p++;
+ *q++ = *p++;
+ }
+ if (IS_DIR_SEPARATOR (*p)
+ && (!dos_drive
+ || (dos_drive_sysroot
+ && ld_sysroot[0] == p[-2])))
+ {
+ if (dos_drive && dos_drive_sysroot)
+ {
+ strcpy (q, ld_sysroot + 2);
+ q += len - 2;
+ }
+ else
+ {
+ strcpy (q, ld_sysroot);
+ q += len;
+ }
+ }
+ end = strchr (p, config.rpath_separator);
+ if (end)
+ {
+ size_t n = end - p + 1;
+ strncpy (q, p, n);
+ q += n;
+ p += n;
+ }
+ else
+ {
+ strcpy (q, p);
+ break;
+ }
+ }
- *p = 0;
return ret;
}
int force)
{
static bfd_boolean initialized;
- static char *ld_elf_hints;
+ static const char *ld_elf_hints;
struct dt_needed needed;
if (!initialized)
int force)
{
static bfd_boolean initialized;
- static char *ld_so_conf;
+ static const char *ld_so_conf;
struct dt_needed needed;
if (! initialized)
if (info.path)
{
- char *d = gld${EMULATION_NAME}_add_sysroot (info.path);
+ ld_so_conf = gld${EMULATION_NAME}_add_sysroot (info.path);
free (info.path);
- ld_so_conf = d;
}
initialized = TRUE;
}
if (bfd_is_abs_section (asec->output_section))
{
einfo (_("%P: warning: .note.gnu.build-id section discarded,"
- " --build-id ignored.\n"));
+ " --build-id ignored\n"));
return TRUE;
}
i_shdr = &elf_section_data (asec->output_section)->this_hdr;
size = id_note_section_size (ibfd);
if (size == 0)
{
- einfo ("%P: warning: unrecognized --build-id style ignored.\n");
+ einfo (_("%P: warning: unrecognized --build-id style ignored\n"));
return FALSE;
}
return TRUE;
}
- einfo ("%P: warning: Cannot create .note.gnu.build-id section,"
- " --build-id ignored.\n");
+ einfo (_("%P: warning: cannot create .note.gnu.build-id section,"
+ " --build-id ignored\n"));
return FALSE;
}
{
struct bfd_link_needed_list *needed, *l;
struct elf_link_hash_table *htab;
+ asection *s;
+ bfd *abfd;
after_open_default ();
if (!is_elf_hash_table (htab))
return;
- if (emit_note_gnu_build_id != NULL)
+ if (command_line.out_implib_filename)
{
- bfd *abfd;
+ unlink_if_ordinary (command_line.out_implib_filename);
+ link_info.out_implib_bfd
+ = bfd_openw (command_line.out_implib_filename,
+ bfd_get_target (link_info.output_bfd));
+ if (link_info.out_implib_bfd == NULL)
+ {
+ einfo (_("%F%P: %s: can't open for writing: %E\n"),
+ command_line.out_implib_filename);
+ }
+ }
+
+ if (emit_note_gnu_build_id != NULL)
+ {
/* Find an ELF input. */
for (abfd = link_info.input_bfds;
abfd != (bfd *) NULL; abfd = abfd->link.next)
- if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
+ if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
+ && bfd_count_sections (abfd) != 0
+ && !((lang_input_statement_type *) abfd->usrdata)->flags.just_syms)
break;
/* PR 10555: If there are no ELF input files do not try to
}
}
- if (link_info.relocatable)
+ get_elf_backend_data (link_info.output_bfd)->setup_gnu_properties (&link_info);
+
+ if (bfd_link_relocatable (&link_info))
{
if (link_info.execstack == ! link_info.noexecstack)
/* PR ld/16744: If "-z [no]execstack" has been specified on the
return;
}
- if (link_info.eh_frame_hdr
- && !link_info.traditional_format)
+ if (!link_info.traditional_format)
{
- bfd *abfd, *elfbfd = NULL;
+ bfd *elfbfd = NULL;
bfd_boolean warn_eh_frame = FALSE;
- asection *s;
+ int seen_type = 0;
for (abfd = link_info.input_bfds; abfd; abfd = abfd->link.next)
{
- if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
- elfbfd = abfd;
- if (!warn_eh_frame)
+ int type = 0;
+
+ if (((lang_input_statement_type *) abfd->usrdata)->flags.just_syms)
+ continue;
+
+ for (s = abfd->sections; s && type < COMPACT_EH_HDR; s = s->next)
{
- s = bfd_get_section_by_name (abfd, ".eh_frame");
- while (s != NULL
- && (s->size <= 8
- || bfd_is_abs_section (s->output_section)))
- s = bfd_get_next_section_by_name (s);
- warn_eh_frame = s != NULL;
+ const char *name = bfd_get_section_name (abfd, s);
+
+ if (bfd_is_abs_section (s->output_section))
+ continue;
+ if (CONST_STRNEQ (name, ".eh_frame_entry"))
+ type = COMPACT_EH_HDR;
+ else if (strcmp (name, ".eh_frame") == 0 && s->size > 8)
+ type = DWARF2_EH_HDR;
}
- if (elfbfd && warn_eh_frame)
- break;
+
+ if (type != 0)
+ {
+ if (seen_type == 0)
+ {
+ seen_type = type;
+ }
+ else if (seen_type != type)
+ {
+ einfo (_("%F%P: compact frame descriptions incompatible with"
+ " DWARF2 .eh_frame from %pB\n"),
+ type == DWARF2_EH_HDR ? abfd : elfbfd);
+ break;
+ }
+
+ if (!elfbfd
+ && (type == COMPACT_EH_HDR || link_info.eh_frame_hdr_type != 0))
+ {
+ if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
+ elfbfd = abfd;
+
+ warn_eh_frame = TRUE;
+ }
+ }
+
+ if (seen_type == COMPACT_EH_HDR)
+ link_info.eh_frame_hdr_type = COMPACT_EH_HDR;
}
if (elfbfd)
{
}
}
if (warn_eh_frame)
- einfo ("%P: warning: Cannot create .eh_frame_hdr section,"
- " --eh-frame-hdr ignored.\n");
+ 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
n.name = l->name;
nn.by = l->by;
if (verbose)
- info_msg (_("%s needed by %B\n"), l->name, l->by);
+ info_msg (_("%s needed by %pB\n"), l->name, l->by);
/* As-needed libs specified on the command line (or linker script)
take priority over libs found in search dirs. */
size_t len;
search_dirs_type *search;
EOF
-if [ "x${NATIVE}" = xyes ] ; then
+if [ "x${NATIVE}" = xyes ] || [ "x${USE_LIBPATH}" = xyes ] ; then
fragment <<EOF
- const char *lib_path;
+ const char *path;
EOF
fi
if [ "x${USE_LIBPATH}" = xyes ] ; then
EOF
if [ "x${USE_LIBPATH}" = xyes ] ; then
fragment <<EOF
- if (gld${EMULATION_NAME}_search_needed (command_line.rpath,
- &n, force))
- break;
+ path = command_line.rpath;
+ if (path)
+ {
+ path = gld${EMULATION_NAME}_add_sysroot (path);
+ found = gld${EMULATION_NAME}_search_needed (path, &n, force);
+ free ((char *) path);
+ if (found)
+ break;
+ }
EOF
fi
if [ "x${NATIVE}" = xyes ] ; then
if (command_line.rpath_link == NULL
&& command_line.rpath == NULL)
{
- lib_path = (const char *) getenv ("LD_RUN_PATH");
- if (gld${EMULATION_NAME}_search_needed (lib_path, &n,
- force))
+ path = (const char *) getenv ("LD_RUN_PATH");
+ if (path
+ && gld${EMULATION_NAME}_search_needed (path, &n, force))
break;
}
- lib_path = (const char *) getenv ("LD_LIBRARY_PATH");
- if (gld${EMULATION_NAME}_search_needed (lib_path, &n, force))
+ path = (const char *) getenv ("LD_LIBRARY_PATH");
+ if (path
+ && gld${EMULATION_NAME}_search_needed (path, &n, force))
break;
EOF
fi
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);
+ path = gld${EMULATION_NAME}_add_sysroot (rp->name);
found = (rp->by == l->by
- && gld${EMULATION_NAME}_search_needed (tmpname,
- &n,
+ && gld${EMULATION_NAME}_search_needed (path, &n,
force));
- free (tmpname);
+ free ((char *) path);
}
if (found)
break;
if (force < 2)
continue;
- einfo ("%P: warning: %s, needed by %B, not found (try using -rpath or -rpath-link)\n",
+ einfo (_("%P: warning: %s, needed by %pB, not found "
+ "(try using -rpath or -rpath-link)\n"),
l->name, l->by);
}
+
+ if (link_info.eh_frame_hdr_type == COMPACT_EH_HDR)
+ if (!bfd_elf_parse_eh_frame_entries (NULL, &link_info))
+ einfo (_("%F%P: failed to parse EH frame entries\n"));
}
EOF
case etree_provide:
case etree_provided:
provide = TRUE;
- /* Fall thru */
+ /* Fallthru */
case etree_assign:
/* We call record_link_assignment even if the symbol is defined.
This is because if it is defined by a dynamic object, we
&link_info,
exp->assign.dst, provide,
exp->assign.hidden))
- einfo ("%P%F: failed to record assignment to %s: %E\n",
+ einfo (_("%F%P: failed to record assignment to %s: %E\n"),
exp->assign.dst);
}
gld${EMULATION_NAME}_find_exp_assignment (exp->assign.src);
}
}
+#if defined(__GNUC__) && GCC_VERSION < 4006
+ /* Work around a GCC uninitialized warning bug fixed in GCC 4.6. */
+static struct bfd_link_hash_entry ehdr_start_empty;
+#endif
+
/* This is called after the sections have been attached to output
sections, but before any sizes or addresses have been set. */
asection *sinterp;
bfd *abfd;
struct elf_link_hash_entry *ehdr_start = NULL;
- struct bfd_link_hash_entry ehdr_start_save = ehdr_start_save;
+#if defined(__GNUC__) && GCC_VERSION < 4006
+ /* Work around a GCC uninitialized warning bug fixed in GCC 4.6. */
+ struct bfd_link_hash_entry ehdr_start_save = ehdr_start_empty;
+#else
+ struct bfd_link_hash_entry ehdr_start_save;
+#endif
if (is_elf_hash_table (link_info.hash))
{
/* Make __ehdr_start hidden if it has been referenced, to
prevent the symbol from being dynamic. */
- if (!link_info.relocatable)
- {
- struct elf_link_hash_entry *h
- = elf_link_hash_lookup (elf_hash_table (&link_info), "__ehdr_start",
- FALSE, FALSE, TRUE);
-
- /* Only adjust the export class if the symbol was referenced
- and not defined, otherwise leave it alone. */
- if (h != NULL
- && (h->root.type == bfd_link_hash_new
- || h->root.type == bfd_link_hash_undefined
- || h->root.type == bfd_link_hash_undefweak
- || h->root.type == bfd_link_hash_common))
- {
- _bfd_elf_link_hash_hide_symbol (&link_info, h, TRUE);
- if (ELF_ST_VISIBILITY (h->other) != STV_INTERNAL)
- h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN;
- /* Don't leave the symbol undefined. Undefined hidden
- symbols typically won't have dynamic relocations, but
- we most likely will need dynamic relocations for
- __ehdr_start if we are building a PIE or shared
- library. */
- ehdr_start = h;
- ehdr_start_save = h->root;
- h->root.type = bfd_link_hash_defined;
- h->root.u.def.section = bfd_abs_section_ptr;
- h->root.u.def.value = 0;
- }
- }
+ if (!bfd_link_relocatable (&link_info))
+ {
+ struct elf_link_hash_table *htab = elf_hash_table (&link_info);
+ struct elf_link_hash_entry *h
+ = elf_link_hash_lookup (htab, "__ehdr_start", FALSE, FALSE, TRUE);
+
+ /* Only adjust the export class if the symbol was referenced
+ and not defined, otherwise leave it alone. */
+ if (h != NULL
+ && (h->root.type == bfd_link_hash_new
+ || h->root.type == bfd_link_hash_undefined
+ || h->root.type == bfd_link_hash_undefweak
+ || h->root.type == bfd_link_hash_common))
+ {
+ const struct elf_backend_data *bed;
+ bed = get_elf_backend_data (link_info.output_bfd);
+ (*bed->elf_backend_hide_symbol) (&link_info, h, TRUE);
+ if (ELF_ST_VISIBILITY (h->other) != STV_INTERNAL)
+ h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN;
+ /* Don't leave the symbol undefined. Undefined hidden
+ symbols typically won't have dynamic relocations, but
+ we most likely will need dynamic relocations for
+ __ehdr_start if we are building a PIE or shared
+ library. */
+ ehdr_start = h;
+ ehdr_start_save = h->root;
+ h->root.type = bfd_link_hash_defined;
+ h->root.u.def.section = bfd_abs_section_ptr;
+ h->root.u.def.value = 0;
+ }
+ }
/* If we are going to make any variable assignments, we need to
let the ELF backend know about them in case the variables are
command_line.filter_shlib, audit, depaudit,
(const char * const *) command_line.auxiliary_filters,
&link_info, &sinterp)))
- einfo ("%P%F: failed to set dynamic section sizes: %E\n");
+ einfo (_("%F%P: failed to set dynamic section sizes: %E\n"));
${ELF_INTERPRETER_SET_DEFAULT}
/* Let the user override the dynamic linker we are using. */
asection *s;
bfd_size_type sz;
char *msg;
- bfd_boolean ret;
if (is->flags.just_syms)
continue;
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",
+ einfo (_("%F%P: %pB: can't read contents of section .gnu.warning: %E\n"),
is->the_bfd);
msg[sz] = '\0';
- ret = link_info.callbacks->warning (&link_info, msg,
- (const char *) NULL,
- is->the_bfd, (asection *) NULL,
- (bfd_vma) 0);
- ASSERT (ret);
+ (*link_info.callbacks->warning) (&link_info, msg,
+ (const char *) NULL, is->the_bfd,
+ (asection *) NULL, (bfd_vma) 0);
free (msg);
/* Clobber the section size, so that we don't waste space
before_allocation_default ();
if (!bfd_elf_size_dynsym_hash_dynstr (link_info.output_bfd, &link_info))
- einfo ("%P%F: failed to set dynamic section sizes: %E\n");
+ einfo (_("%F%P: failed to set dynamic section sizes: %E\n"));
if (ehdr_start != NULL)
{
filename we recorded earlier. */
if (!entry->flags.full_name_provided)
- filename = lbasename (entry->filename);
+ filename = lbasename (entry->filename);
bfd_elf_set_dt_needed_name (entry->the_bfd, filename);
}
return last;
}
+/* Return whether IN is suitable to be part of OUT. */
+
+static bfd_boolean
+elf_orphan_compatible (asection *in, asection *out)
+{
+ /* Non-zero sh_info implies a section with SHF_INFO_LINK with
+ unknown semantics for the generic linker, or a SHT_REL/SHT_RELA
+ section where sh_info specifies a symbol table. (We won't see
+ SHT_GROUP, SHT_SYMTAB or SHT_DYNSYM sections here.) We clearly
+ can't merge SHT_REL/SHT_RELA using differing symbol tables, and
+ shouldn't merge sections with differing unknown semantics. */
+ if (elf_section_data (out)->this_hdr.sh_info
+ != elf_section_data (in)->this_hdr.sh_info)
+ return FALSE;
+ /* We can't merge two sections with differing SHF_EXCLUDE when doing
+ a relocatable link. */
+ if (bfd_link_relocatable (&link_info)
+ && ((elf_section_flags (out) ^ elf_section_flags (in)) & SHF_EXCLUDE) != 0)
+ return FALSE;
+ return _bfd_elf_match_sections_by_type (link_info.output_bfd, out,
+ in->owner, in);
+}
+
/* Place an orphan section. We use this to put random SHF_ALLOC
sections in the right segment. */
lang_output_section_statement_type *os;
lang_output_section_statement_type *match_by_name = NULL;
int isdyn = 0;
- int iself = s->owner->xvec->flavour == bfd_target_elf_flavour;
- unsigned int sh_type = iself ? elf_section_type (s) : SHT_NULL;
+ int elfinput = s->owner->xvec->flavour == bfd_target_elf_flavour;
+ int elfoutput = link_info.output_bfd->xvec->flavour == bfd_target_elf_flavour;
+ unsigned int sh_type = elfinput ? elf_section_type (s) : SHT_NULL;
+ flagword flags;
+ asection *nexts;
- if (! link_info.relocatable
+ if (!bfd_link_relocatable (&link_info)
&& link_info.combreloc
&& (s->flags & SEC_ALLOC))
{
- if (iself)
+ if (elfinput)
switch (sh_type)
{
case SHT_RELA:
}
}
- /* Look through the script to see where to place this section. */
+ if (!bfd_link_relocatable (&link_info)
+ && elfinput
+ && elfoutput
+ && (s->flags & SEC_ALLOC) != 0
+ && (elf_section_flags (s) & SHF_GNU_MBIND) != 0)
+ {
+ /* Find the output mbind section with the same type, attributes
+ and sh_info field. */
+ for (os = &lang_output_section_statement.head->output_section_statement;
+ os != NULL;
+ os = os->next)
+ if (os->bfd_section != NULL
+ && !bfd_is_abs_section (os->bfd_section)
+ && (elf_section_flags (os->bfd_section) & SHF_GNU_MBIND) != 0
+ && ((s->flags & (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_READONLY
+ | SEC_CODE))
+ == (os->bfd_section->flags & (SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS
+ | SEC_READONLY
+ | SEC_CODE)))
+ && (elf_section_data (os->bfd_section)->this_hdr.sh_info
+ == elf_section_data (s)->this_hdr.sh_info))
+ {
+ lang_add_section (&os->children, s, NULL, os);
+ return os;
+ }
+
+ /* Create the output mbind section with the ".mbind." prefix
+ in section name. */
+ if ((s->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
+ secname = ".mbind.bss";
+ else if ((s->flags & SEC_READONLY) == 0)
+ secname = ".mbind.data";
+ else if ((s->flags & SEC_CODE) == 0)
+ secname = ".mbind.rodata";
+ else
+ secname = ".mbind.text";
+ }
+
+ /* Look through the script to see where to place this section. The
+ script includes entries added by previous lang_insert_orphan
+ calls, so this loop puts multiple compatible orphans of the same
+ name into a single output section. */
if (constraint == 0)
for (os = lang_output_section_find (secname);
os != NULL;
lang_insert_orphan to create a new output section. */
constraint = SPECIAL;
+ /* Check to see if 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, possibly as a
+ result of a --section-start command line switch. */
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)))
+ || (((s->flags ^ os->bfd_section->flags)
+ & (SEC_LOAD | SEC_ALLOC)) == 0
+ && (!elfinput
+ || !elfoutput
+ || elf_orphan_compatible (s, os->bfd_section)))))
{
- /* 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, NULL, os);
return os;
}
/* 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.executable
- && ! link_info.relocatable
+ if (bfd_link_executable (&link_info)
&& CONST_STRNEQ (s->name, ".gnu.warning.")
&& hold[orphan_text].os != NULL)
{
return os;
}
+ flags = s->flags;
+ if (!bfd_link_relocatable (&link_info))
+ {
+ nexts = s;
+ while ((nexts = bfd_get_next_section_by_name (nexts->owner, nexts))
+ != NULL)
+ if (nexts->output_section == NULL
+ && (nexts->flags & SEC_EXCLUDE) == 0
+ && ((nexts->flags ^ flags) & (SEC_LOAD | SEC_ALLOC)) == 0
+ && (nexts->owner->flags & DYNAMIC) == 0
+ && nexts->owner->usrdata != NULL
+ && !(((lang_input_statement_type *) nexts->owner->usrdata)
+ ->flags.just_syms)
+ && _bfd_elf_match_sections_by_type (nexts->owner, nexts,
+ s->owner, s))
+ flags = (((flags ^ SEC_READONLY)
+ | (nexts->flags ^ SEC_READONLY))
+ ^ SEC_READONLY);
+ }
+
/* Decide which segment the section should go in based on the
section name and section flags. We put loadable .note sections
right after the .interp section, so that the PT_NOTE segment is
in the first page. */
place = NULL;
- if ((s->flags & (SEC_ALLOC | SEC_DEBUGGING)) == 0)
+ if ((flags & (SEC_ALLOC | SEC_DEBUGGING)) == 0)
place = &hold[orphan_nonalloc];
- else if ((s->flags & SEC_ALLOC) == 0)
+ else if ((flags & SEC_ALLOC) == 0)
;
- else if ((s->flags & SEC_LOAD) != 0
- && ((iself && sh_type == SHT_NOTE)
- || (!iself && CONST_STRNEQ (secname, ".note"))))
+ else if ((flags & SEC_LOAD) != 0
+ && ((elfinput && sh_type == SHT_NOTE)
+ || (!elfinput && CONST_STRNEQ (secname, ".note"))))
place = &hold[orphan_interp];
- else if ((s->flags & (SEC_LOAD | SEC_HAS_CONTENTS | SEC_THREAD_LOCAL)) == 0)
+ else if ((flags & (SEC_LOAD | SEC_HAS_CONTENTS | SEC_THREAD_LOCAL)) == 0)
place = &hold[orphan_bss];
- else if ((s->flags & SEC_SMALL_DATA) != 0)
+ else if ((flags & SEC_SMALL_DATA) != 0)
place = &hold[orphan_sdata];
- else if ((s->flags & SEC_THREAD_LOCAL) != 0)
+ else if ((flags & SEC_THREAD_LOCAL) != 0)
place = &hold[orphan_tdata];
- else if ((s->flags & SEC_READONLY) == 0)
+ else if ((flags & SEC_READONLY) == 0)
place = &hold[orphan_data];
- else if (((iself && (sh_type == SHT_RELA || sh_type == SHT_REL))
- || (!iself && CONST_STRNEQ (secname, ".rel")))
- && (s->flags & SEC_LOAD) != 0)
+ else if (((elfinput && (sh_type == SHT_RELA || sh_type == SHT_REL))
+ || (!elfinput && CONST_STRNEQ (secname, ".rel")))
+ && (flags & SEC_LOAD) != 0)
place = &hold[orphan_rel];
- else if ((s->flags & SEC_CODE) == 0)
+ else if ((flags & SEC_CODE) == 0)
place = &hold[orphan_rodata];
else
place = &hold[orphan_text];
}
after = place->os;
if (after == NULL)
- after = lang_output_section_find_by_flags
- (s, &place->os, _bfd_elf_match_sections_by_type);
+ after
+ = lang_output_section_find_by_flags (s, flags, &place->os,
+ _bfd_elf_match_sections_by_type);
if (after == NULL)
/* *ABS* is always the first output section statement. */
after = &lang_output_section_statement.head->output_section_statement;
static void
gld${EMULATION_NAME}_after_allocation (void)
{
- bfd_boolean need_layout = bfd_elf_discard_info (link_info.output_bfd,
- &link_info);
- gld${EMULATION_NAME}_map_segments (need_layout);
+ int need_layout = bfd_elf_discard_info (link_info.output_bfd, &link_info);
+
+ if (need_layout < 0)
+ einfo (_("%X%P: .eh_frame/.stab edit: %E\n"));
+ else
+ gld${EMULATION_NAME}_map_segments (need_layout);
}
EOF
fi
{
*isfile = 0;
- if (link_info.relocatable && config.build_constructors)
+ if (bfd_link_relocatable (&link_info) && config.build_constructors)
return
EOF
sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c
-echo ' ; else if (link_info.relocatable) return' >> e${EMULATION_NAME}.c
+echo ' ; else if (bfd_link_relocatable (&link_info)) return' >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c
echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c
fi
if test -n "$GENERATE_PIE_SCRIPT" ; then
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 ' ; else if (bfd_link_pie (&link_info)' >> e${EMULATION_NAME}.c
+echo ' && link_info.combreloc' >> e${EMULATION_NAME}.c
+echo ' && link_info.separate_code' >> e${EMULATION_NAME}.c
+echo ' && (link_info.flags & DF_BIND_NOW)) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xdwe >> e${EMULATION_NAME}.c
+echo ' ; else if (bfd_link_pie (&link_info)' >> e${EMULATION_NAME}.c
+echo ' && link_info.combreloc' >> e${EMULATION_NAME}.c
+echo ' && link_info.relro' >> 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
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
+echo ' ; else if (bfd_link_pie (&link_info)' >> e${EMULATION_NAME}.c
+echo ' && link_info.combreloc' >> e${EMULATION_NAME}.c
+echo ' && link_info.separate_code' >> e${EMULATION_NAME}.c
+echo ' && link_info.relro) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xdceo >> e${EMULATION_NAME}.c
+fi
+echo ' ; else if (bfd_link_pie (&link_info)' >> e${EMULATION_NAME}.c
+echo ' && link_info.separate_code' >> e${EMULATION_NAME}.c
+echo ' && link_info.combreloc) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xdce >> e${EMULATION_NAME}.c
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
+echo ' ; else if (bfd_link_pie (&link_info)' >> e${EMULATION_NAME}.c
+echo ' && link_info.combreloc' >> e${EMULATION_NAME}.c
+echo ' && link_info.relro) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xdco >> e${EMULATION_NAME}.c
+fi
+echo ' ; else if (bfd_link_pie (&link_info)' >> e${EMULATION_NAME}.c
+echo ' && link_info.combreloc) return' >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xdc >> e${EMULATION_NAME}.c
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
+echo ' ; else if (bfd_link_pie (&link_info)' >> e${EMULATION_NAME}.c
+echo ' && link_info.separate_code' >> e${EMULATION_NAME}.c
+echo ' && link_info.relro) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xdeo >> e${EMULATION_NAME}.c
fi
-echo ' ; else if (link_info.pie) return' >> e${EMULATION_NAME}.c
+fi
+echo ' ; else if (bfd_link_pie (&link_info)' >> e${EMULATION_NAME}.c
+echo ' && link_info.separate_code) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xde >> e${EMULATION_NAME}.c
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
+echo ' ; else if (bfd_link_pie (&link_info)' >> e${EMULATION_NAME}.c
+echo ' && link_info.relro) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xdo >> e${EMULATION_NAME}.c
+fi
+echo ' ; else if (bfd_link_pie (&link_info)) return' >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xd >> e${EMULATION_NAME}.c
fi
if test -n "$GENERATE_SHLIB_SCRIPT" ; then
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 ' ; else if (bfd_link_dll (&link_info)' >> e${EMULATION_NAME}.c
+echo ' && link_info.combreloc' >> e${EMULATION_NAME}.c
+echo ' && link_info.separate_code' >> e${EMULATION_NAME}.c
+echo ' && (link_info.flags & DF_BIND_NOW)) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xswe >> e${EMULATION_NAME}.c
+echo ' ; else if (bfd_link_dll (&link_info)' >> e${EMULATION_NAME}.c
+echo ' && link_info.combreloc' >> e${EMULATION_NAME}.c
+echo ' && link_info.relro' >> 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
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
+echo ' ; else if (bfd_link_dll (&link_info)' >> e${EMULATION_NAME}.c
+echo ' && link_info.combreloc' >> e${EMULATION_NAME}.c
+echo ' && link_info.separate_code' >> e${EMULATION_NAME}.c
+echo ' && link_info.relro) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xsceo >> e${EMULATION_NAME}.c
+fi
+echo ' ; else if (bfd_link_dll (&link_info)' >> e${EMULATION_NAME}.c
+echo ' && link_info.combreloc' >> e${EMULATION_NAME}.c
+echo ' && link_info.separate_code) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xsce >> e${EMULATION_NAME}.c
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
+echo ' ; else if (bfd_link_dll (&link_info)' >> e${EMULATION_NAME}.c
+echo ' && link_info.combreloc' >> e${EMULATION_NAME}.c
+echo ' && link_info.relro) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xsco >> e${EMULATION_NAME}.c
+fi
+echo ' ; else if (bfd_link_dll (&link_info)' >> e${EMULATION_NAME}.c
+echo ' && link_info.combreloc) return' >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xsc >> e${EMULATION_NAME}.c
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
+echo ' ; else if (bfd_link_dll (&link_info)' >> e${EMULATION_NAME}.c
+echo ' && link_info.separate_code' >> e${EMULATION_NAME}.c
+echo ' && link_info.relro) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xseo >> e${EMULATION_NAME}.c
+fi
fi
-echo ' ; else if (link_info.shared) return' >> e${EMULATION_NAME}.c
+echo ' ; else if (bfd_link_dll (&link_info)' >> e${EMULATION_NAME}.c
+echo ' && link_info.separate_code) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xse >> e${EMULATION_NAME}.c
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
+echo ' ; else if (bfd_link_dll (&link_info)' >> e${EMULATION_NAME}.c
+echo ' && link_info.relro) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xso >> e${EMULATION_NAME}.c
+fi
+echo ' ; else if (bfd_link_dll (&link_info)) return' >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xs >> 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 ' ; else if (link_info.combreloc' >> e${EMULATION_NAME}.c
+echo ' && link_info.separate_code' >> e${EMULATION_NAME}.c
+echo ' && (link_info.flags & DF_BIND_NOW)) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xwe >> e${EMULATION_NAME}.c
+echo ' ; else if (link_info.combreloc' >> e${EMULATION_NAME}.c
+echo ' && link_info.relro' >> 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
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
+echo ' ; else if (link_info.combreloc' >> e${EMULATION_NAME}.c
+echo ' && link_info.separate_code' >> e${EMULATION_NAME}.c
+echo ' && link_info.relro) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xceo >> e${EMULATION_NAME}.c
+fi
+echo ' ; else if (link_info.combreloc' >> e${EMULATION_NAME}.c
+echo ' && link_info.separate_code) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xce >> e${EMULATION_NAME}.c
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
+echo ' ; else if (link_info.combreloc' >> e${EMULATION_NAME}.c
+echo ' && link_info.relro) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xco >> e${EMULATION_NAME}.c
+fi
echo ' ; else if (link_info.combreloc) return' >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xc >> e${EMULATION_NAME}.c
fi
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
+echo ' ; else if (link_info.separate_code' >> e${EMULATION_NAME}.c
+echo ' && link_info.relro) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xeo >> e${EMULATION_NAME}.c
+fi
+echo ' ; else if (link_info.separate_code) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xe >> e${EMULATION_NAME}.c
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
+echo ' ; else if (link_info.relro) return' >> e${EMULATION_NAME}.c
+sed $sc ldscripts/${EMULATION_NAME}.xo >> e${EMULATION_NAME}.c
+fi
echo ' ; else return' >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c
echo '; }' >> e${EMULATION_NAME}.c
{
*isfile = 1;
- if (link_info.relocatable && config.build_constructors)
+ if (bfd_link_relocatable (&link_info) && config.build_constructors)
return "ldscripts/${EMULATION_NAME}.xu";
- else if (link_info.relocatable)
+ else if (bfd_link_relocatable (&link_info))
return "ldscripts/${EMULATION_NAME}.xr";
else if (!config.text_read_only)
return "ldscripts/${EMULATION_NAME}.xbn";
if test -n "$GENERATE_PIE_SCRIPT" ; then
if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
fragment <<EOF
- else if (link_info.pie && link_info.combreloc
- && 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";
+ else if (bfd_link_pie (&link_info)
+ && link_info.combreloc
+ && link_info.relro
+ && (link_info.flags & DF_BIND_NOW))
+ {
+ if (link_info.separate_code)
+ return "ldscripts/${EMULATION_NAME}.xdwe";
+ else
+ return "ldscripts/${EMULATION_NAME}.xdw";
+ }
+EOF
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
+fragment <<EOF
+ else if (bfd_link_pie (&link_info)
+ && link_info.combreloc
+ && link_info.relro)
+ {
+ if (link_info.separate_code)
+ return "ldscripts/${EMULATION_NAME}.xdceo";
+ else
+ return "ldscripts/${EMULATION_NAME}.xdco";
+ }
+EOF
+fi
+fragment <<EOF
+ else if (bfd_link_pie (&link_info)
+ && link_info.combreloc)
+ {
+ if (link_info.separate_code)
+ return "ldscripts/${EMULATION_NAME}.xdce";
+ else
+ return "ldscripts/${EMULATION_NAME}.xdc";
+ }
+EOF
+fi
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
+fragment <<EOF
+ else if (bfd_link_pie (&link_info)
+ && link_info.relro)
+ {
+ if (link_info.separate_code)
+ return "ldscripts/${EMULATION_NAME}.xdeo";
+ else
+ return "ldscripts/${EMULATION_NAME}.xdo";
+ }
EOF
fi
fragment <<EOF
- else if (link_info.pie)
- return "ldscripts/${EMULATION_NAME}.xd";
+ else if (bfd_link_pie (&link_info))
+ {
+ if (link_info.separate_code)
+ return "ldscripts/${EMULATION_NAME}.xde";
+ else
+ return "ldscripts/${EMULATION_NAME}.xd";
+ }
EOF
fi
if test -n "$GENERATE_SHLIB_SCRIPT" ; then
if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
fragment <<EOF
- else if (link_info.shared && link_info.combreloc
+ else if (bfd_link_dll (&link_info) && link_info.combreloc
&& 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";
+ {
+ if (link_info.separate_code)
+ return "ldscripts/${EMULATION_NAME}.xswe";
+ else
+ return "ldscripts/${EMULATION_NAME}.xsw";
+ }
+EOF
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
+fragment <<EOF
+ else if (bfd_link_dll (&link_info)
+ && link_info.combreloc
+ && link_info.relro)
+ {
+ if (link_info.separate_code)
+ return "ldscripts/${EMULATION_NAME}.xsceo";
+ else
+ return "ldscripts/${EMULATION_NAME}.xsco";
+ }
+EOF
+fi
+fragment <<EOF
+ else if (bfd_link_dll (&link_info) && link_info.combreloc)
+ {
+ if (link_info.separate_code)
+ return "ldscripts/${EMULATION_NAME}.xsce";
+ else
+ return "ldscripts/${EMULATION_NAME}.xsc";
+ }
EOF
fi
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
fragment <<EOF
- else if (link_info.shared)
- return "ldscripts/${EMULATION_NAME}.xs";
+ else if (bfd_link_dll (&link_info)
+ && link_info.relro)
+ {
+ if (link_info.separate_code)
+ return "ldscripts/${EMULATION_NAME}.xseo";
+ else
+ return "ldscripts/${EMULATION_NAME}.xso";
+ }
+EOF
+fi
+fragment <<EOF
+ else if (bfd_link_dll (&link_info))
+ {
+ if (link_info.separate_code)
+ return "ldscripts/${EMULATION_NAME}.xse";
+ else
+ return "ldscripts/${EMULATION_NAME}.xs";
+ }
EOF
fi
if test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
fragment <<EOF
else if (link_info.combreloc && link_info.relro
&& (link_info.flags & DF_BIND_NOW))
- return "ldscripts/${EMULATION_NAME}.xw";
+ {
+ if (link_info.separate_code)
+ return "ldscripts/${EMULATION_NAME}.xwe";
+ else
+ return "ldscripts/${EMULATION_NAME}.xw";
+ }
+EOF
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
+fragment <<EOF
+ else if (link_info.combreloc
+ && link_info.relro)
+ {
+ if (link_info.separate_code)
+ return "ldscripts/${EMULATION_NAME}.xceo";
+ else
+ return "ldscripts/${EMULATION_NAME}.xco";
+ }
+EOF
+fi
+fragment <<EOF
else if (link_info.combreloc)
- return "ldscripts/${EMULATION_NAME}.xc";
+ {
+ if (link_info.separate_code)
+ return "ldscripts/${EMULATION_NAME}.xce";
+ else
+ return "ldscripts/${EMULATION_NAME}.xc";
+ }
+EOF
+fi
+if test -n "$GENERATE_RELRO_SCRIPT" ; then
+fragment <<EOF
+ else if (link_info.relro)
+ {
+ if (link_info.separate_code)
+ return "ldscripts/${EMULATION_NAME}.xeo";
+ else
+ return "ldscripts/${EMULATION_NAME}.xo";
+ }
EOF
fi
fragment <<EOF
else
- return "ldscripts/${EMULATION_NAME}.x";
+ {
+ if (link_info.separate_code)
+ return "ldscripts/${EMULATION_NAME}.xe";
+ else
+ return "ldscripts/${EMULATION_NAME}.x";
+ }
}
EOF
fragment <<EOF
-#define OPTION_DISABLE_NEW_DTAGS (400)
-#define OPTION_ENABLE_NEW_DTAGS (OPTION_DISABLE_NEW_DTAGS + 1)
-#define OPTION_GROUP (OPTION_ENABLE_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)
+enum elf_options
+{
+ OPTION_DISABLE_NEW_DTAGS = 400,
+ OPTION_ENABLE_NEW_DTAGS,
+ OPTION_GROUP,
+ OPTION_EH_FRAME_HDR,
+ OPTION_NO_EH_FRAME_HDR,
+ OPTION_EXCLUDE_LIBS,
+ OPTION_HASH_STYLE,
+ OPTION_BUILD_ID,
+ OPTION_AUDIT,
+ OPTION_COMPRESS_DEBUG
+};
static void
gld${EMULATION_NAME}_add_options
fi
fragment <<EOF
{"build-id", optional_argument, NULL, OPTION_BUILD_ID},
+ {"compress-debug-sections", required_argument, NULL, OPTION_COMPRESS_DEBUG},
EOF
if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
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},
+ {"no-eh-frame-hdr", no_argument, NULL, OPTION_NO_EH_FRAME_HDR},
{"exclude-libs", required_argument, NULL, OPTION_EXCLUDE_LIBS},
{"hash-style", required_argument, NULL, OPTION_HASH_STYLE},
EOF
emit_note_gnu_build_id = xstrdup (optarg);
break;
+ case OPTION_COMPRESS_DEBUG:
+ if (strcasecmp (optarg, "none") == 0)
+ link_info.compress_debug = COMPRESS_DEBUG_NONE;
+ else if (strcasecmp (optarg, "zlib") == 0)
+ link_info.compress_debug = COMPRESS_DEBUG_GABI_ZLIB;
+ else if (strcasecmp (optarg, "zlib-gnu") == 0)
+ link_info.compress_debug = COMPRESS_DEBUG_GNU_ZLIB;
+ else if (strcasecmp (optarg, "zlib-gabi") == 0)
+ link_info.compress_debug = COMPRESS_DEBUG_GABI_ZLIB;
+ else
+ einfo (_("%F%P: invalid --compress-debug-sections option: \`%s'\n"),
+ optarg);
+ break;
EOF
if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
break;
case OPTION_EH_FRAME_HDR:
- link_info.eh_frame_hdr = TRUE;
+ link_info.eh_frame_hdr_type = DWARF2_EH_HDR;
+ break;
+
+ case OPTION_NO_EH_FRAME_HDR:
+ link_info.eh_frame_hdr_type = 0;
break;
case OPTION_GROUP:
link_info.emit_gnu_hash = TRUE;
}
else
- einfo (_("%P%F: invalid hash style \`%s'\n"), optarg);
+ einfo (_("%F%P: invalid hash style \`%s'\n"), optarg);
break;
EOF
case 'z':
if (strcmp (optarg, "defs") == 0)
link_info.unresolved_syms_in_objects = RM_GENERATE_ERROR;
+ else if (strcmp (optarg, "undefs") == 0)
+ link_info.unresolved_syms_in_objects = RM_IGNORE;
else if (strcmp (optarg, "muldefs") == 0)
link_info.allow_multiple_definition = TRUE;
else if (CONST_STRNEQ (optarg, "max-page-size="))
config.maxpagesize = strtoul (optarg + 14, &end, 0);
if (*end || (config.maxpagesize & (config.maxpagesize - 1)) != 0)
- einfo (_("%P%F: invalid maxium page size \`%s'\n"),
+ einfo (_("%F%P: invalid maximum page size \`%s'\n"),
optarg + 14);
}
else if (CONST_STRNEQ (optarg, "common-page-size="))
config.commonpagesize = strtoul (optarg + 17, &end, 0);
if (*end
|| (config.commonpagesize & (config.commonpagesize - 1)) != 0)
- einfo (_("%P%F: invalid common page size \`%s'\n"),
+ einfo (_("%F%P: invalid common page size \`%s'\n"),
optarg + 17);
}
else if (CONST_STRNEQ (optarg, "stack-size="))
char *end;
link_info.stacksize = strtoul (optarg + 11, &end, 0);
if (*end || link_info.stacksize < 0)
- einfo (_("%P%F: invalid stack size \`%s'\n"), optarg + 11);
+ einfo (_("%F%P: invalid stack size \`%s'\n"), optarg + 11);
if (!link_info.stacksize)
/* Use -1 for explicit no-stack, because zero means
'default'. */
link_info.noexecstack = TRUE;
link_info.execstack = FALSE;
}
+ else if (strcmp (optarg, "globalaudit") == 0)
+ {
+ link_info.flags_1 |= DF_1_GLOBAUDIT;
+ }
EOF
+
if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
fragment <<EOF
else if (strcmp (optarg, "global") == 0)
link_info.relro = TRUE;
else if (strcmp (optarg, "norelro") == 0)
link_info.relro = FALSE;
+ else if (strcmp (optarg, "separate-code") == 0)
+ link_info.separate_code = TRUE;
+ else if (strcmp (optarg, "noseparate-code") == 0)
+ link_info.separate_code = FALSE;
+ else if (strcmp (optarg, "common") == 0)
+ link_info.elf_stt_common = elf_stt_common;
+ else if (strcmp (optarg, "nocommon") == 0)
+ link_info.elf_stt_common = no_elf_stt_common;
else if (strcmp (optarg, "text") == 0)
link_info.error_textrel = TRUE;
else if (strcmp (optarg, "notext") == 0)
EOF
fi
+if test -n "$PARSE_AND_LIST_ARGS_CASE_Z" ; then
+fragment <<EOF
+ $PARSE_AND_LIST_ARGS_CASE_Z
+EOF
+fi
+
fragment <<EOF
else
- einfo (_("%P: warning: -z %s ignored.\n"), optarg);
+ einfo (_("%P: warning: -z %s ignored\n"), optarg);
break;
EOF
EOF
if test x"$LDEMUL_LIST_OPTIONS" != xgld"$EMULATION_NAME"_list_options; then
+gld_list_options="gld${EMULATION_NAME}_list_options"
+if test -n "$PARSE_AND_LIST_OPTIONS"; then
fragment <<EOF
static void
gld${EMULATION_NAME}_list_options (FILE * file)
{
EOF
-if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
-fragment <<EOF
- fprintf (file, _("\
- --audit=AUDITLIB Specify a library to use for auditing\n"));
- fprintf (file, _("\
- -Bgroup Selects group name lookup rules for DSO\n"));
-EOF
-fi
-fragment <<EOF
- fprintf (file, _("\
- --build-id[=STYLE] Generate build ID note\n"));
-EOF
-if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
-fragment <<EOF
- fprintf (file, _("\
- -P AUDITLIB, --depaudit=AUDITLIB\n" "\
- Specify a library to use for auditing dependencies\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, _("\
- --exclude-libs=LIBS Make all symbols in LIBS hidden\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"));
-EOF
-fi
-
-fragment <<EOF
- fprintf (file, _("\
- -z common-page-size=SIZE Set common page size to SIZE\n"));
- fprintf (file, _("\
- -z defs Report unresolved symbols in object files.\n"));
- fprintf (file, _("\
- -z execstack Mark executable as requiring executable stack\n"));
-EOF
-
-if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
-fragment <<EOF
- fprintf (file, _("\
- -z global Make symbols in DSO available for subsequently\n\
- loaded objects\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"));
-EOF
-fi
-
-fragment <<EOF
- fprintf (file, _("\
- -z max-page-size=SIZE Set maximum page size to SIZE\n"));
- fprintf (file, _("\
- -z muldefs Allow multiple definitions\n"));
-EOF
-
-if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
-fragment <<EOF
- 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"));
-EOF
-fi
-fragment <<EOF
- fprintf (file, _("\
- -z noexecstack Mark executable as not requiring executable stack\n"));
-EOF
-if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
-fragment <<EOF
- fprintf (file, _("\
- -z norelro Don't create RELRO program header\n"));
- 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"));
- fprintf (file, _("\
- -z relro Create RELRO program header\n"));
- fprintf (file, _("\
- -z stacksize=SIZE Set size of stack segment\n"));
-EOF
-fi
if test -n "$PARSE_AND_LIST_OPTIONS" ; then
fragment <<EOF
fragment <<EOF
}
EOF
+else
+ gld_list_options="NULL"
+fi
if test -n "$PARSE_AND_LIST_EPILOGUE" ; then
fragment <<EOF
${LDEMUL_BEFORE_PARSE-gld${EMULATION_NAME}_before_parse},
${LDEMUL_SYSLIB-syslib_default},
${LDEMUL_HLL-hll_default},
- ${LDEMUL_AFTER_PARSE-after_parse_default},
+ ${LDEMUL_AFTER_PARSE-gld${EMULATION_NAME}_after_parse},
${LDEMUL_AFTER_OPEN-gld${EMULATION_NAME}_after_open},
+ ${LDEMUL_AFTER_CHECK_RELOCS-after_check_relocs_default},
${LDEMUL_AFTER_ALLOCATION-gld${EMULATION_NAME}_after_allocation},
${LDEMUL_SET_OUTPUT_ARCH-set_output_arch_default},
${LDEMUL_CHOOSE_TARGET-ldemul_default_target},
gld${EMULATION_NAME}_add_options,
gld${EMULATION_NAME}_handle_option,
${LDEMUL_UNRECOGNIZED_FILE-NULL},
- ${LDEMUL_LIST_OPTIONS-gld${EMULATION_NAME}_list_options},
+ ${LDEMUL_LIST_OPTIONS-${gld_list_options}},
${LDEMUL_RECOGNIZED_FILE-gld${EMULATION_NAME}_load_symbols},
${LDEMUL_FIND_POTENTIAL_LIBRARIES-NULL},
${LDEMUL_NEW_VERS_PATTERN-NULL},