X86-64: Allow copy relocs for building PIE
This patch allows copy relocs for non-GOT pc-relative relocation in PIE. bfd/ * 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. ld/testsuite/ * ld-x86-64/copyreloc-lib.c: New file. * ld-x86-64/copyreloc-main.c: Likewise. * ld-x86-64/copyreloc-main.out: Likewise. * ld-x86-64/copyreloc-main1.rd: Likewise. * ld-x86-64/copyreloc-main2.rd: Likewise. * ld-x86-64/x86-64.exp: Run copyreloc tests.
This commit is contained in:
parent
5da3ffc99d
commit
9a926d55ab
9 changed files with 103 additions and 11 deletions
|
@ -1,3 +1,14 @@
|
|||
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-12-02 Andrew Bennett <andrew.bennett@imgtec.com>
|
||||
|
||||
* elfxx-mips.c (mips_elf_calculate_relocation): Only check for
|
||||
|
|
|
@ -1060,13 +1060,29 @@ elf_x86_64_create_dynamic_sections (bfd *dynobj,
|
|||
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)
|
||||
|
@ -1939,7 +1955,8 @@ do_size:
|
|||
storing information in the relocs_copied field of the hash
|
||||
table entry. A similar situation occurs when creating
|
||||
shared libraries and symbol visibility changes render the
|
||||
symbol local.
|
||||
symbol local. We allow copy relocs for non-GOT pc-relative
|
||||
relocation.
|
||||
|
||||
If on the other hand, we are creating an executable, we
|
||||
may need to keep relocations for symbols satisfied by a
|
||||
|
@ -1949,6 +1966,7 @@ do_size:
|
|||
&& (sec->flags & SEC_ALLOC) != 0
|
||||
&& (! IS_X86_64_PCREL_TYPE (r_type)
|
||||
|| (h != NULL
|
||||
&& !h->non_got_ref
|
||||
&& (! SYMBOLIC_BIND (info, h)
|
||||
|| h->root.type == bfd_link_hash_defweak
|
||||
|| !h->def_regular))))
|
||||
|
@ -2369,7 +2387,7 @@ elf_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info,
|
|||
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
|
||||
|
@ -2384,7 +2402,7 @@ elf_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
if (ELIMINATE_COPY_RELOCS)
|
||||
if (ELIMINATE_COPY_RELOCS && !info->shared)
|
||||
{
|
||||
eh = (struct elf_x86_64_link_hash_entry *) h;
|
||||
for (p = eh->dyn_relocs; p != NULL; p = p->next)
|
||||
|
@ -4035,10 +4053,11 @@ elf_x86_64_relocate_section (bfd *output_bfd,
|
|||
defined locally or for a branch. */
|
||||
fail = !h->def_regular && !branch;
|
||||
}
|
||||
else
|
||||
else if (!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);
|
||||
}
|
||||
|
@ -4092,7 +4111,12 @@ direct:
|
|||
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
|
||||
&& !(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)
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
2014-12-02 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
* ld-x86-64/copyreloc-lib.c: New file.
|
||||
* ld-x86-64/copyreloc-main.c: Likewise.
|
||||
* ld-x86-64/copyreloc-main.out: Likewise.
|
||||
* ld-x86-64/copyreloc-main1.rd: Likewise.
|
||||
* ld-x86-64/copyreloc-main2.rd: Likewise.
|
||||
|
||||
* ld-x86-64/x86-64.exp: Run copyreloc tests.
|
||||
|
||||
2014-12-02 Andrew Bennett <andrew.bennett@imgtec.com>
|
||||
|
||||
* ld-mips-elf/mips-elf.exp: Add undefined weak overflow
|
||||
|
|
1
ld/testsuite/ld-x86-64/copyreloc-lib.c
Normal file
1
ld/testsuite/ld-x86-64/copyreloc-lib.c
Normal file
|
@ -0,0 +1 @@
|
|||
int a_glob = 2;
|
7
ld/testsuite/ld-x86-64/copyreloc-main.c
Normal file
7
ld/testsuite/ld-x86-64/copyreloc-main.c
Normal file
|
@ -0,0 +1,7 @@
|
|||
extern int a_glob;
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
return a_glob != 2;
|
||||
}
|
0
ld/testsuite/ld-x86-64/copyreloc-main.out
Normal file
0
ld/testsuite/ld-x86-64/copyreloc-main.out
Normal file
3
ld/testsuite/ld-x86-64/copyreloc-main1.rd
Normal file
3
ld/testsuite/ld-x86-64/copyreloc-main1.rd
Normal file
|
@ -0,0 +1,3 @@
|
|||
#...
|
||||
[0-9a-f ]+R_X86_64_COPY+[0-9a-f ]+ +a_glob \+ 0
|
||||
#...
|
4
ld/testsuite/ld-x86-64/copyreloc-main2.rd
Normal file
4
ld/testsuite/ld-x86-64/copyreloc-main2.rd
Normal file
|
@ -0,0 +1,4 @@
|
|||
#failif
|
||||
#...
|
||||
[0-9a-f ]+R_X86_64_NONE.*
|
||||
#...
|
|
@ -392,6 +392,30 @@ if { [isnative] && [which $CC] != 0 } {
|
|||
{{readelf {-Wr} plt-main.rd}} \
|
||||
"plt-main" \
|
||||
] \
|
||||
[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 \
|
||||
|
@ -414,6 +438,14 @@ if { [isnative] && [which $CC] != 0 } {
|
|||
"plt-main.out" \
|
||||
"-fPIC" \
|
||||
] \
|
||||
[list \
|
||||
"Run copyreloc-main with PIE without -fPIE" \
|
||||
"tmpdir/copyreloc-lib.so -pie" \
|
||||
"" \
|
||||
{ copyreloc-main.c } \
|
||||
"copyreloc-main" \
|
||||
"copyreloc-main.out" \
|
||||
] \
|
||||
]
|
||||
|
||||
if { [istarget "x86_64-*-linux*"] \
|
||||
|
|
Loading…
Reference in a new issue