+2014-12-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (elf_x86_64_relocate_section): Check
+ info->executable for symbols which need copy relocs.
+
+2014-12-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (elf_x86_64_check_relocs): Revert the last
+ change.
+ (elf_x86_64_adjust_dynamic_symbol): Don't check !info->shared
+ with ELIMINATE_COPY_RELOCS.
+ (elf_x86_64_allocate_dynrelocs): For PIE, discard space for
+ relocs against symbols which turn out to need copy relocs.
+
+2014-12-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf64-x86-64.c (elf_x86_64_create_dynamic_sections): Always
+ allow copy relocs for building executables.
+ (elf_x86_64_check_relocs): Allow copy relocs for non-GOT
+ pc-relative relocation in shared object.
+ (elf_x86_64_adjust_dynamic_symbol): Allocate copy relocs for
+ PIE.
+ (elf_x86_64_relocate_section): Don't copy a pc-relative
+ relocation into the output file if the symbol needs copy reloc.
+
2014-11-30 Alan Modra <amodra@gmail.com>
PR 16452, 16457
return FALSE;
htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
- if (!info->shared)
- htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss");
-
- if (!htab->sdynbss
- || (!info->shared && !htab->srelbss))
+ if (!htab->sdynbss)
abort ();
+ if (info->executable)
+ {
+ /* Always allow copy relocs for building executables. */
+ asection *s;
+ s = bfd_get_linker_section (dynobj, ".rela.bss");
+ if (s == NULL)
+ {
+ const struct elf_backend_data *bed = get_elf_backend_data (dynobj);
+ s = bfd_make_section_anyway_with_flags (dynobj,
+ ".rela.bss",
+ (bed->dynamic_sec_flags
+ | SEC_READONLY));
+ if (s == NULL
+ || ! bfd_set_section_alignment (dynobj, s,
+ bed->s->log_file_align))
+ return FALSE;
+ }
+ htab->srelbss = s;
+ }
+
if (!info->no_ld_generated_unwind_info
&& htab->plt_eh_frame == NULL
&& htab->elf.splt != NULL)
only references to the symbol are via the global offset table.
For such cases we need not do anything here; the relocations will
be handled correctly by relocate_section. */
- if (info->shared)
+ if (!info->executable)
return TRUE;
/* If there are no references to this symbol that do not use the
/* Also discard relocs on undefined weak syms with non-default
visibility. */
- if (eh->dyn_relocs != NULL
- && h->root.type == bfd_link_hash_undefweak)
+ if (eh->dyn_relocs != NULL)
{
- if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+ if (h->root.type == bfd_link_hash_undefweak)
+ {
+ if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+ eh->dyn_relocs = NULL;
+
+ /* Make sure undefined weak symbols are output as a dynamic
+ symbol in PIEs. */
+ else if (h->dynindx == -1
+ && ! h->forced_local
+ && ! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+ }
+ /* For PIE, discard space for relocs against symbols which
+ turn out to need copy relocs. */
+ else if (info->executable
+ && h->needs_copy
+ && h->def_dynamic
+ && !h->def_regular)
eh->dyn_relocs = NULL;
-
- /* Make sure undefined weak symbols are output as a dynamic
- symbol in PIEs. */
- else if (h->dynindx == -1
- && ! h->forced_local
- && ! bfd_elf_link_record_dynamic_symbol (info, h))
- return FALSE;
}
-
}
else if (ELIMINATE_COPY_RELOCS)
{
defined locally or for a branch. */
fail = !h->def_regular && !branch;
}
- else
+ else if (!(info->executable && h->needs_copy))
{
- /* Symbol isn't referenced locally. We only allow
- branch to symbol with non-default visibility. */
+ /* Symbol doesn't need copy reloc and isn't referenced
+ locally. We only allow branch to symbol with
+ non-default visibility. */
fail = (!branch
|| ELF_ST_VISIBILITY (h->other) == STV_DEFAULT);
}
if ((input_section->flags & SEC_ALLOC) == 0)
break;
+ /* Don't copy a pc-relative relocation into the output file
+ if the symbol needs copy reloc. */
if ((info->shared
+ && !(info->executable
+ && h != NULL
+ && h->needs_copy
+ && IS_X86_64_PCREL_TYPE (r_type))
&& (h == NULL
|| ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|| h->root.type != bfd_link_hash_undefweak)
"-shared -melf32_x86_64 tmpdir/simple-x32.o" "" "--x32"
{dummy.s} {{readelf {-s --wide} x86-64-x32.rd}} "x86-64-x32"}
}
+
+ run_cc_link_tests [list \
+ [list \
+ "Build copyreloc-lib.so" \
+ "-shared" \
+ "-fPIC" \
+ { copyreloc-lib.c } \
+ {} \
+ "copyreloc-lib.so" \
+ ] \
+ [list \
+ "Build copyreloc-main with PIE without -fPIE (1)" \
+ "tmpdir/copyreloc-lib.so -pie" \
+ "" \
+ { copyreloc-main.c } \
+ {{readelf {-Wr} copyreloc-main1.rd}} \
+ "copyreloc-main" \
+ ] \
+ [list \
+ "Build copyreloc-main with PIE without -fPIE (2)" \
+ "tmpdir/copyreloc-lib.so -pie" \
+ "" \
+ { copyreloc-main.c } \
+ {{readelf {-Wr} copyreloc-main2.rd}} \
+ "copyreloc-main" \
+ ] \
+ ]
+
+ run_ld_link_exec_tests [] [list \
+ [list \
+ "Run copyreloc-main with PIE without -fPIE" \
+ "tmpdir/copyreloc-lib.so -pie" \
+ "" \
+ { copyreloc-main.c } \
+ "copyreloc-main" \
+ "copyreloc-main.out" \
+ ] \
+ ]
}