diff options
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 16 | ||||
-rw-r--r-- | bfd/elf32-ppc.c | 3 | ||||
-rw-r--r-- | bfd/elf64-ppc.c | 3 | ||||
-rw-r--r-- | bfd/elflink.c | 64 |
4 files changed, 45 insertions, 41 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 0cd8bbd..44fc2bb 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,19 @@ +2015-02-17 Alan Modra <amodra@gmail.com> + + PR ld/17975 + * elflink.c (struct elf_outext_info): Remove need_second_pass + and second_pass. + (elf_link_output_extsym): Delete code handling second forced + local pass. Move code emitting NULL STT_FILE symbol later, so + that it can be omitted if forced local is stripped. Don't + emit the NULL STT_FILE if no file symbols have been output. + (bfd_elf_final_link): Remove second forced local pass. + * elf32-ppc.c (add_stub_sym): Set linker_def on linker syms. + (ppc_elf_size_dynamic_sections): Likewise. + * elf64-ppc.c (ppc_build_one_stub): Likewise. + (build_global_entry_stubs): Likewise. + (ppc64_elf_build_stubs): Likewise. + 2015-02-16 H.J. Lu <hongjiu.lu@intel.com> PR ld/17975 diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index 8d8167a..33f59c8 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -5685,6 +5685,7 @@ add_stub_sym (struct plt_entry *ent, sh->ref_regular_nonweak = 1; sh->forced_local = 1; sh->non_elf = 0; + sh->root.linker_def = 1; } return TRUE; } @@ -6366,6 +6367,7 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd, sh->ref_regular_nonweak = 1; sh->forced_local = 1; sh->non_elf = 0; + sh->root.linker_def = 1; } sh = elf_link_hash_lookup (&htab->elf, "__glink_PLTresolve", TRUE, FALSE, FALSE); @@ -6381,6 +6383,7 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd, sh->ref_regular_nonweak = 1; sh->forced_local = 1; sh->non_elf = 0; + sh->root.linker_def = 1; } } } diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index 38bc3fb..a2ddb41 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -10950,6 +10950,7 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg) h->ref_regular_nonweak = 1; h->forced_local = 1; h->non_elf = 0; + h->root.linker_def = 1; } } @@ -12653,6 +12654,7 @@ build_global_entry_stubs (struct elf_link_hash_entry *h, void *inf) h->ref_regular_nonweak = 1; h->forced_local = 1; h->non_elf = 0; + h->root.linker_def = 1; } } @@ -12726,6 +12728,7 @@ ppc64_elf_build_stubs (struct bfd_link_info *info, h->ref_regular_nonweak = 1; h->forced_local = 1; h->non_elf = 0; + h->root.linker_def = 1; } } plt0 = (htab->elf.splt->output_section->vma diff --git a/bfd/elflink.c b/bfd/elflink.c index 541129a..038e43d 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -7441,8 +7441,6 @@ struct elf_outext_info { bfd_boolean failed; bfd_boolean localsyms; - bfd_boolean need_second_pass; - bfd_boolean second_pass; bfd_boolean file_sym_done; struct elf_final_link_info *flinfo; }; @@ -8821,25 +8819,6 @@ elf_link_output_extsym (struct bfd_hash_entry *bh, void *data) { if (!h->forced_local) return TRUE; - if (eoinfo->second_pass - && !((h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - && h->root.u.def.section->output_section != NULL)) - return TRUE; - - if (!eoinfo->file_sym_done && eoinfo->flinfo->filesym_count) - { - /* Output a FILE symbol so that following locals are not associated - with the wrong input file. */ - memset (&sym, 0, sizeof (sym)); - sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FILE); - sym.st_shndx = SHN_ABS; - if (!elf_link_output_sym (eoinfo->flinfo, NULL, &sym, - bfd_und_section_ptr, NULL)) - return FALSE; - - eoinfo->file_sym_done = TRUE; - } } else { @@ -9001,16 +8980,6 @@ elf_link_output_extsym (struct bfd_hash_entry *bh, void *data) input_sec = h->root.u.def.section; if (input_sec->output_section != NULL) { - if (eoinfo->localsyms && flinfo->filesym_count == 1) - { - bfd_boolean second_pass_sym - = h->forced_local && !h->root.linker_def; - - eoinfo->need_second_pass |= second_pass_sym; - if (eoinfo->second_pass != second_pass_sym) - return TRUE; - } - sym.st_shndx = _bfd_elf_section_from_bfd_section (flinfo->output_bfd, input_sec->output_section); @@ -9241,6 +9210,29 @@ elf_link_output_extsym (struct bfd_hash_entry *bh, void *data) if (strip || (input_sec->flags & SEC_EXCLUDE) != 0) return TRUE; + /* Output a FILE symbol so that following locals are not associated + with the wrong input file. We need one for forced local symbols + if we've seen more than one FILE symbol or when we have exactly + one FILE symbol but global symbols are present in a file other + than the one with the FILE symbol. We also need one if linker + defined symbols are present. In practice these conditions are + always met, so just emit the FILE symbol unconditionally. */ + if (eoinfo->localsyms + && !eoinfo->file_sym_done + && eoinfo->flinfo->filesym_count != 0) + { + Elf_Internal_Sym fsym; + + memset (&fsym, 0, sizeof (fsym)); + fsym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FILE); + fsym.st_shndx = SHN_ABS; + if (!elf_link_output_sym (eoinfo->flinfo, NULL, &fsym, + bfd_und_section_ptr, NULL)) + return FALSE; + + eoinfo->file_sym_done = TRUE; + } + indx = bfd_get_symcount (flinfo->output_bfd); ret = elf_link_output_sym (flinfo, h->root.root.string, &sym, input_sec, h); if (ret == 0) @@ -11153,21 +11145,11 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) eoinfo.failed = FALSE; eoinfo.flinfo = &flinfo; eoinfo.localsyms = TRUE; - eoinfo.need_second_pass = FALSE; - eoinfo.second_pass = FALSE; eoinfo.file_sym_done = FALSE; bfd_hash_traverse (&info->hash->table, elf_link_output_extsym, &eoinfo); if (eoinfo.failed) return FALSE; - if (eoinfo.need_second_pass) - { - eoinfo.second_pass = TRUE; - bfd_hash_traverse (&info->hash->table, elf_link_output_extsym, &eoinfo); - if (eoinfo.failed) - return FALSE; - } - /* If backend needs to output some local symbols not present in the hash table, do it now. */ if (bed->elf_backend_output_arch_local_syms |