/* 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, 2008, 2009, 2010, 2011, 2012, 2013
- Free Software Foundation, Inc.
+ Copyright (C) 1991-2015 Free Software Foundation, Inc.
Written by Steve Chamberlain <sac@cygnus.com>
ELF support by Ian Lance Taylor <ian@cygnus.com>
#include "sysdep.h"
#include "bfd.h"
#include "libiberty.h"
-#include "filenames.h"
#include "safe-ctype.h"
+#include "filenames.h"
#include "getopt.h"
-#include "md5.h"
-#include "sha1.h"
#include <fcntl.h>
#include "bfdlink.h"
#include "ldlang.h"
#include "ldfile.h"
#include "ldemul.h"
+#include "ldbuildid.h"
#include <ldgram.h>
#include "elf/common.h"
#include "elf-bfd.h"
{
const char *style = emit_note_gnu_build_id;
bfd_size_type size;
+ bfd_size_type build_id_size;
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');
- }
+ build_id_size = compute_build_id_size (style);
+ if (build_id_size)
+ size += build_id_size;
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;
-}
-
static bfd_boolean
write_build_id (bfd *abfd)
{
bfd_size_type size;
file_ptr position;
Elf_External_Note *e_note;
- typedef void (*sum_fn) (const void *, size_t, void *);
style = t->o->build_id.style;
asec = t->o->build_id.sec;
bfd_h_put_32 (abfd, NT_GNU_BUILD_ID, &e_note->type);
memcpy (e_note->name, "GNU", sizeof "GNU");
- if (strcmp (style, "md5") == 0)
- {
- struct md5_ctx ctx;
-
- md5_init_ctx (&ctx);
- if (!bed->s->checksum_contents (abfd, (sum_fn) &md5_process_bytes, &ctx))
- return FALSE;
- md5_finish_ctx (&ctx, id_bits);
- }
- else if (strcmp (style, "sha1") == 0)
- {
- struct sha1_ctx ctx;
-
- sha1_init_ctx (&ctx);
- if (!bed->s->checksum_contents (abfd, (sum_fn) &sha1_process_bytes, &ctx))
- return FALSE;
- sha1_finish_ctx (&ctx, id_bits);
- }
- else if (strcmp (style, "uuid") == 0)
- {
- 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 (style, "0x", 2) == 0)
- {
- /* ID is in string form (hex). Convert to bits. */
- const char *id = 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. */
+ generate_build_id (abfd, style, bed->s->checksum_contents, id_bits, size);
position = i_shdr->sh_offset + asec->output_offset;
size = asec->size;
/* 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)
+ abfd != (bfd *) NULL; abfd = abfd->link.next)
+ if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
+ && bfd_count_sections (abfd) != 0)
break;
/* PR 10555: If there are no ELF input files do not try to
}
if (link_info.relocatable)
- return;
+ {
+ if (link_info.execstack == ! link_info.noexecstack)
+ /* PR ld/16744: If "-z [no]execstack" has been specified on the
+ command line and we are perfoming a relocatable link then no
+ PT_GNU_STACK segment will be created and so the
+ linkinfo.[no]execstack values set in _handle_option() will have no
+ effect. Instead we create a .note.GNU-stack section in much the
+ same way as the assembler does with its --[no]execstack option. */
+ (void) bfd_make_section_with_flags (link_info.input_bfds,
+ ".note.GNU-stack",
+ SEC_READONLY | (link_info.execstack ? SEC_CODE : 0));
- if (link_info.eh_frame_hdr
- && !link_info.traditional_format)
+ return;
+ }
+
+ if (!link_info.traditional_format)
{
bfd *abfd, *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)
+ 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;
+ 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 (_("%P%F: compact frame descriptions incompatible with"
+ " DWARF2 .eh_frame from %B\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 (bfd_count_sections (abfd) == 0)
+ continue;
}
if (elfbfd)
{
einfo ("%P: warning: %s, needed by %B, 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) == FALSE)
+ einfo (_("%P%F: Failed to parse EH frame entries.\n"));
}
EOF
const char *rpath;
asection *sinterp;
bfd *abfd;
+ struct elf_link_hash_entry *ehdr_start = NULL;
+#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_save;
+#else
+ struct bfd_link_hash_entry ehdr_start_save;
+#endif
if (is_elf_hash_table (link_info.hash))
{
_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 (rpath == NULL)
rpath = (const char *) getenv ("LD_RUN_PATH");
- for (abfd = link_info.input_bfds; abfd; abfd = abfd->link_next)
+ for (abfd = link_info.input_bfds; abfd; abfd = abfd->link.next)
if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
{
const char *audit_libs = elf_dt_audit (abfd);
if (!bfd_elf_size_dynsym_hash_dynstr (link_info.output_bfd, &link_info))
einfo ("%P%F: failed to set dynamic section sizes: %E\n");
+
+ if (ehdr_start != NULL)
+ {
+ /* If we twiddled __ehdr_start to defined earlier, put it back
+ as it was. */
+ ehdr_start->root.type = ehdr_start_save.type;
+ ehdr_start->root.u = ehdr_start_save.u;
+ }
}
EOF
{
const char *filename;
char *string;
+ size_t len;
+ bfd_boolean opened = FALSE;
if (! entry->flags.maybe_archive)
return FALSE;
filename = entry->filename;
+ len = strlen (search->name) + strlen (filename);
+ if (entry->flags.full_name_provided)
+ {
+ len += sizeof "/";
+ string = (char *) xmalloc (len);
+ sprintf (string, "%s/%s", search->name, filename);
+ }
+ else
+ {
+ size_t xlen = 0;
- /* This allocates a few bytes too many when EXTRA_SHLIB_EXTENSION
- is defined, but it does not seem worth the headache to optimize
- away those two bytes of space. */
- string = (char *) xmalloc (strlen (search->name)
- + strlen (filename)
- + strlen (arch)
+ len += strlen (arch) + sizeof "/lib.so";
#ifdef EXTRA_SHLIB_EXTENSION
- + strlen (EXTRA_SHLIB_EXTENSION)
+ xlen = (strlen (EXTRA_SHLIB_EXTENSION) > 3
+ ? strlen (EXTRA_SHLIB_EXTENSION) - 3
+ : 0);
#endif
- + sizeof "/lib.so");
-
- sprintf (string, "%s/lib%s%s.so", search->name, filename, arch);
-
+ string = (char *) xmalloc (len + xlen);
+ sprintf (string, "%s/lib%s%s.so", search->name, filename, arch);
#ifdef EXTRA_SHLIB_EXTENSION
- /* 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);
+ /* Try the .so extension first. If that fails build a new filename
+ using EXTRA_SHLIB_EXTENSION. */
+ opened = ldfile_try_open_bfd (string, entry);
+ if (!opened)
+ strcpy (string + len - 4, EXTRA_SHLIB_EXTENSION);
#endif
+ }
- if (! ldfile_try_open_bfd (string, entry))
+ if (!opened && !ldfile_try_open_bfd (string, entry))
{
free (string);
return FALSE;
}
-#ifdef EXTRA_SHLIB_EXTENSION
- }
-#endif
entry->filename = string;
/* Rather than duplicating the logic above. Just use the
filename we recorded earlier. */
- filename = lbasename (entry->filename);
+ if (!entry->flags.full_name_provided)
+ filename = lbasename (entry->filename);
bfd_elf_set_dt_needed_name (entry->the_bfd, filename);
}
{ ".rodata",
SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA,
0, 0, 0, 0 },
+ { ".tdata",
+ SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_THREAD_LOCAL,
+ 0, 0, 0, 0 },
{ ".data",
SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_DATA,
0, 0, 0, 0 },
{
orphan_text = 0,
orphan_rodata,
+ orphan_tdata,
orphan_data,
orphan_bss,
orphan_rel,
place = &hold[orphan_bss];
else if ((s->flags & SEC_SMALL_DATA) != 0)
place = &hold[orphan_sdata];
+ else if ((s->flags & SEC_THREAD_LOCAL) != 0)
+ place = &hold[orphan_tdata];
else if ((s->flags & SEC_READONLY) == 0)
place = &hold[orphan_data];
else if (((iself && (sh_type == SHT_RELA || sh_type == SHT_REL))
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
gld${EMULATION_NAME}_get_script (int *isfile)
EOF
-if test -n "$COMPILE_IN"
+if test x"$COMPILE_IN" = xyes
then
# Scripts compiled in.
#define OPTION_HASH_STYLE (OPTION_EXCLUDE_LIBS + 1)
#define OPTION_BUILD_ID (OPTION_HASH_STYLE + 1)
#define OPTION_AUDIT (OPTION_BUILD_ID + 1)
+#define OPTION_COMPRESS_DEBUG (OPTION_AUDIT + 1)
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
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 (_("%P%F: 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_GROUP:
link_info.execstack = FALSE;
}
EOF
+
if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
fragment <<EOF
else if (strcmp (optarg, "global") == 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);
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
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}
+ ${LDEMUL_NEW_VERS_PATTERN-NULL},
+ ${LDEMUL_EXTRA_MAP_FILE_TEXT-NULL}
};
EOF