aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog16
-rw-r--r--bfd/elf32-ppc.c3
-rw-r--r--bfd/elf64-ppc.c3
-rw-r--r--bfd/elflink.c64
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