diff options
author | Alan Modra <amodra@gmail.com> | 2015-02-17 09:14:59 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2015-02-18 00:31:52 +1030 |
commit | 2ec55de302e4a6c49a06c673c8262a119fa6226f (patch) | |
tree | f70feefc1fc7d5694f3f3b702e2e05cd68b35e1d /bfd/elflink.c | |
parent | 69efdff130b843838e791065335b44d5f91f7075 (diff) | |
download | gdb-2ec55de302e4a6c49a06c673c8262a119fa6226f.zip gdb-2ec55de302e4a6c49a06c673c8262a119fa6226f.tar.gz gdb-2ec55de302e4a6c49a06c673c8262a119fa6226f.tar.bz2 |
Properly place the NULL STT_FILE symbol revistited
I was having a little closer look at what is going on here and noticed
that HJ unconditionally emits a NULL STT_FILE symbol before emitting
forced local symbols. That means we really don't need a second pass
over forced local symbols. The only reason for two passes is when
some forced local symbol can be emitted before the NULL STT_FILE. So
I set about removing the second pass, updating the testsuite all over
again. It's also unnecessary to emit the NULL STT_FILE when no
previous file symbol has been emitted.
bfd/
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.
ld/testsuite/
PR ld/17975
* ld-aarch64/gc-tls-relocs.d, * ld-alpha/tlspic.rd,
* ld-cris/libdso-2.d, * ld-i386/tlsdesc-nacl.rd, * ld-i386/tlsdesc.rd,
* ld-i386/tlsnopic-nacl.rd, * ld-i386/tlsnopic.rd,
* ld-i386/tlspic-nacl.rd, * ld-i386/tlspic.rd, * ld-ia64/tlspic.rd,
* ld-powerpc/tlsexe.r, * ld-powerpc/tlsexetoc.r,
* ld-powerpc/tlsso.r, * ld-powerpc/tlstocso.r,
* ld-s390/tlspic.rd, * ld-s390/tlspic_64.rd,
* ld-sparc/tlssunnopic32.rd, * ld-sparc/tlssunnopic64.rd,
* ld-sparc/tlssunpic32.rd, * ld-sparc/tlssunpic64.rd,
* ld-tic6x/shlib-1.rd, * ld-tic6x/shlib-1b.rd, * ld-tic6x/shlib-1r.rd,
* ld-tic6x/shlib-1rb.rd, * ld-tic6x/shlib-noindex.rd,
* ld-x86-64/tlsdesc-nacl.rd, * ld-x86-64/tlsdesc.rd,
* ld-x86-64/tlspic-nacl.rd, * ld-x86-64/tlspic.rd: Update.
Diffstat (limited to 'bfd/elflink.c')
-rw-r--r-- | bfd/elflink.c | 64 |
1 files changed, 23 insertions, 41 deletions
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 |