From 5e8c1cf25beccac1d22d10dc866912394f42771b Mon Sep 17 00:00:00 2001 From: Andrew Hsieh Date: Tue, 9 Dec 2014 17:57:18 +0800 Subject: [2.25] sync to a30720e3e633f275250e26f85ccae5dbdddfb6c6 local patches will be re-applied later commit a30720e3e633f275250e26f85ccae5dbdddfb6c6 Author: Alan Modra Date: Wed Nov 19 10:30:16 2014 +1030 daily update Change-Id: Ieb2a3f4dd2ecb289ac5305ff08d428b2847494ab --- binutils-2.25/ld/emultempl/elf32.em | 249 ++++++++++++++++++------------------ 1 file changed, 121 insertions(+), 128 deletions(-) (limited to 'binutils-2.25/ld/emultempl/elf32.em') diff --git a/binutils-2.25/ld/emultempl/elf32.em b/binutils-2.25/ld/emultempl/elf32.em index 682f5e5..137446f 100644 --- a/binutils-2.25/ld/emultempl/elf32.em +++ b/binutils-2.25/ld/emultempl/elf32.em @@ -12,9 +12,7 @@ fragment < ELF support by Ian Lance Taylor @@ -40,11 +38,9 @@ fragment < #include "bfdlink.h" @@ -56,6 +52,7 @@ fragment < #include "elf/common.h" #include "elf-bfd.h" @@ -897,53 +894,20 @@ id_note_section_size (bfd *abfd ATTRIBUTE_UNUSED) { 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) { @@ -956,7 +920,6 @@ 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; @@ -988,55 +951,7 @@ write_build_id (bfd *abfd) 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; @@ -1099,7 +1014,7 @@ gld${EMULATION_NAME}_after_open (void) /* Find an ELF input. */ for (abfd = link_info.input_bfds; - abfd != (bfd *) NULL; abfd = abfd->link_next) + abfd != (bfd *) NULL; abfd = abfd->link.next) if (bfd_get_flavour (abfd) == bfd_target_elf_flavour) break; @@ -1114,7 +1029,20 @@ gld${EMULATION_NAME}_after_open (void) } 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)); + + return; + } if (link_info.eh_frame_hdr && !link_info.traditional_format) @@ -1123,7 +1051,7 @@ gld${EMULATION_NAME}_after_open (void) bfd_boolean warn_eh_frame = FALSE; asection *s; - 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; @@ -1480,6 +1408,8 @@ gld${EMULATION_NAME}_before_allocation (void) const char *rpath; asection *sinterp; bfd *abfd; + struct elf_link_hash_entry *ehdr_start = NULL; + struct bfd_link_hash_entry ehdr_start_save = ehdr_start_save; if (is_elf_hash_table (link_info.hash)) { @@ -1487,10 +1417,35 @@ gld${EMULATION_NAME}_before_allocation (void) /* Make __ehdr_start hidden if it has been referenced, to prevent the symbol from being dynamic. */ - if (!bfd_elf_record_link_assignment (link_info.output_bfd, &link_info, - "__ehdr_start", TRUE, TRUE)) - einfo ("%P%F: failed to record assignment to %s: %E\n", - "__ehdr_start"); + 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 we are going to make any variable assignments, we need to let the ELF backend know about them in case the variables are @@ -1504,7 +1459,7 @@ gld${EMULATION_NAME}_before_allocation (void) 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); @@ -1605,6 +1560,14 @@ ${ELF_INTERPRETER_SET_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"); + + 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 @@ -1623,42 +1586,46 @@ gld${EMULATION_NAME}_open_dynamic_archive { 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; @@ -1683,7 +1650,8 @@ gld${EMULATION_NAME}_open_dynamic_archive /* 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); } @@ -1777,6 +1745,9 @@ gld${EMULATION_NAME}_place_orphan (asection *s, { ".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 }, @@ -1800,6 +1771,7 @@ gld${EMULATION_NAME}_place_orphan (asection *s, { orphan_text = 0, orphan_rodata, + orphan_tdata, orphan_data, orphan_bss, orphan_rel, @@ -1927,6 +1899,8 @@ gld${EMULATION_NAME}_place_orphan (asection *s, 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)) @@ -1968,9 +1942,12 @@ fragment <