x86-64: Move PIC check for PC-relative relocations back

commit 83924b3846
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Tue Feb 5 18:45:23 2019 -0800

    x86-64: Restore PIC check for PCREL reloc against protected symbol

moved PIC check for PC-relative relocations to elf_x86_64_check_relocs.
Since linker defined symbols may not be processed at the time, we need
to move the check back to elf_x86_64_relocate_section.

bfd/

	PR ld/24905
	* elf64-x86-64.c (elf_x86_64_check_relocs): Move PIC check for
	PC-relative relocations back to ...
	(elf_x86_64_relocate_section): Here.

ld/

	PR ld/24905
	* testsuite/ld-x86-64/pr24905-x32.d: New file.
	* testsuite/ld-x86-64/pr24905.d: Likewise.
	* testsuite/ld-x86-64/pr24905.s: Likewise.
	* testsuite/ld-x86-64/pr24905.t: Likewise.
	* testsuite/ld-x86-64/x86-64.exp: Run pr24905 and pr24905-x32.
This commit is contained in:
H.J. Lu 2019-08-16 14:25:15 -07:00
parent 398fdd6086
commit 81e8046dc0
8 changed files with 110 additions and 79 deletions

View File

@ -1,3 +1,10 @@
2019-08-16 H.J. Lu <hongjiu.lu@intel.com>
PR ld/24905
* elf64-x86-64.c (elf_x86_64_check_relocs): Move PIC check for
PC-relative relocations back to ...
(elf_x86_64_relocate_section): Here.
2019-08-16 Martin Liska <mliska@suse.cz>
PR ld/24912

View File

@ -1864,7 +1864,6 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
const char *name;
bfd_boolean size_reloc;
bfd_boolean converted_reloc;
bfd_boolean do_check_pic;
r_symndx = htab->r_sym (rel->r_info);
r_type = ELF32_R_TYPE (rel->r_info);
@ -2136,13 +2135,6 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
size_reloc = TRUE;
goto do_size;
case R_X86_64_PC8:
case R_X86_64_PC16:
case R_X86_64_PC32:
case R_X86_64_PC32_BND:
do_check_pic = TRUE;
goto check_pic;
case R_X86_64_32:
if (!ABI_64_P (abfd))
goto pointer;
@ -2166,11 +2158,13 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
&x86_64_elf_howto_table[r_type]);
/* Fall through. */
case R_X86_64_PC8:
case R_X86_64_PC16:
case R_X86_64_PC32:
case R_X86_64_PC32_BND:
case R_X86_64_PC64:
case R_X86_64_64:
pointer:
do_check_pic = FALSE;
check_pic:
if (eh != NULL && (sec->flags & SEC_CODE) != 0)
eh->zero_undefweak |= 0x2;
/* We are called after all symbols have been resolved. Only
@ -2234,69 +2228,6 @@ check_pic:
}
}
if (do_check_pic)
{
/* Don't complain about -fPIC if the symbol is undefined
when building executable unless it is unresolved weak
symbol, references a dynamic definition in PIE or
-z nocopyreloc is used. */
bfd_boolean no_copyreloc_p
= (info->nocopyreloc
|| (h != NULL
&& !h->root.linker_def
&& !h->root.ldscript_def
&& eh->def_protected
&& elf_has_no_copy_on_protected (h->root.u.def.section->owner)));
if ((sec->flags & SEC_ALLOC) != 0
&& (sec->flags & SEC_READONLY) != 0
&& h != NULL
&& ((bfd_link_executable (info)
&& ((h->root.type == bfd_link_hash_undefweak
&& (eh == NULL
|| !UNDEFINED_WEAK_RESOLVED_TO_ZERO (info,
eh)))
|| (bfd_link_pie (info)
&& !SYMBOL_DEFINED_NON_SHARED_P (h)
&& h->def_dynamic)
|| (no_copyreloc_p
&& h->def_dynamic
&& !(h->root.u.def.section->flags & SEC_CODE))))
|| bfd_link_dll (info)))
{
bfd_boolean fail = FALSE;
if (SYMBOL_REFERENCES_LOCAL_P (info, h))
{
/* Symbol is referenced locally. Make sure it is
defined locally. */
fail = !SYMBOL_DEFINED_NON_SHARED_P (h);
}
else if (bfd_link_pie (info))
{
/* We can only use PC-relative relocations in PIE
from non-code sections. */
if (h->type == STT_FUNC
&& (sec->flags & SEC_CODE) != 0)
fail = TRUE;
}
else if (no_copyreloc_p || bfd_link_dll (info))
{
/* Symbol doesn't need copy reloc and isn't
referenced locally. Don't allow PC-relative
relocations against default and protected
symbols since address of protected function
and location of protected data may not be in
the shared object. */
fail = (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|| ELF_ST_VISIBILITY (h->other) == STV_PROTECTED);
}
if (fail)
return elf_x86_64_need_pic (info, abfd, sec, h,
symtab_hdr, isym,
&x86_64_elf_howto_table[r_type]);
}
}
size_reloc = FALSE;
do_size:
if (NEED_DYNAMIC_RELOCATION_P (info, TRUE, h, sec, r_type,
@ -2497,6 +2428,7 @@ elf_x86_64_relocate_section (bfd *output_bfd,
bfd_boolean relative_reloc;
bfd_boolean converted_reloc;
bfd_boolean need_copy_reloc_in_pie;
bfd_boolean no_copyreloc_p;
r_type = ELF32_R_TYPE (rel->r_info);
if (r_type == (int) R_X86_64_GNU_VTINHERIT
@ -3137,14 +3069,73 @@ use_plt:
case R_X86_64_PC16:
case R_X86_64_PC32:
case R_X86_64_PC32_BND:
/* Don't complain about -fPIC if the symbol is undefined when
building executable unless it is unresolved weak symbol,
references a dynamic definition in PIE or -z nocopyreloc
is used. */
no_copyreloc_p
= (info->nocopyreloc
|| (h != NULL
&& !h->root.linker_def
&& !h->root.ldscript_def
&& eh->def_protected
&& elf_has_no_copy_on_protected (h->root.u.def.section->owner)));
if ((input_section->flags & SEC_ALLOC) != 0
&& (input_section->flags & SEC_READONLY) != 0
&& h != NULL
&& ((bfd_link_executable (info)
&& ((h->root.type == bfd_link_hash_undefweak
&& (eh == NULL
|| !UNDEFINED_WEAK_RESOLVED_TO_ZERO (info,
eh)))
|| (bfd_link_pie (info)
&& !SYMBOL_DEFINED_NON_SHARED_P (h)
&& h->def_dynamic)
|| (no_copyreloc_p
&& h->def_dynamic
&& !(h->root.u.def.section->flags & SEC_CODE))))
|| bfd_link_dll (info)))
{
bfd_boolean fail = FALSE;
if (SYMBOL_REFERENCES_LOCAL_P (info, h))
{
/* Symbol is referenced locally. Make sure it is
defined locally. */
fail = !SYMBOL_DEFINED_NON_SHARED_P (h);
}
else if (bfd_link_pie (info))
{
/* We can only use PC-relative relocations in PIE
from non-code sections. */
if (h->type == STT_FUNC
&& (sec->flags & SEC_CODE) != 0)
fail = TRUE;
}
else if (no_copyreloc_p || bfd_link_dll (info))
{
/* Symbol doesn't need copy reloc and isn't
referenced locally. Don't allow PC-relative
relocations against default and protected
symbols since address of protected function
and location of protected data may not be in
the shared object. */
fail = (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|| ELF_ST_VISIBILITY (h->other) == STV_PROTECTED);
}
if (fail)
return elf_x86_64_need_pic (info, input_bfd, input_section,
h, NULL, NULL, howto);
}
/* Since x86-64 has PC-relative PLT, we can use PLT in PIE
as function address. */
if (h != NULL
&& (input_section->flags & SEC_CODE) == 0
&& bfd_link_pie (info)
&& h->type == STT_FUNC
&& !h->def_regular
&& h->def_dynamic)
else if (h != NULL
&& (input_section->flags & SEC_CODE) == 0
&& bfd_link_pie (info)
&& h->type == STT_FUNC
&& !h->def_regular
&& h->def_dynamic)
goto use_plt;
/* Fall through. */

View File

@ -1,3 +1,12 @@
2019-08-16 H.J. Lu <hongjiu.lu@intel.com>
PR ld/24905
* testsuite/ld-x86-64/pr24905-x32.d: New file.
* testsuite/ld-x86-64/pr24905.d: Likewise.
* testsuite/ld-x86-64/pr24905.s: Likewise.
* testsuite/ld-x86-64/pr24905.t: Likewise.
* testsuite/ld-x86-64/x86-64.exp: Run pr24905 and pr24905-x32.
2019-08-16 Christophe Lyon <christophe.lyon@linaro.org>
* emulparams/armelf.sh (OTHER_SECTIONS): Add support for noinit

View File

@ -0,0 +1,8 @@
#source: pr24905.s
#as: --x32
#ld: -shared -melf32_x86_64 $srcdir/$subdir/pr24905.t
#nm: -n
#...
[0-9a-f]* t EXTERNAL_SYM
#pass

View File

@ -0,0 +1,7 @@
#as: --64
#ld: -shared -melf_x86_64 $srcdir/$subdir/pr24905.t
#nm: -n
#...
[0-9a-f]* t EXTERNAL_SYM
#pass

View File

@ -0,0 +1,6 @@
.text
.globl foo
.type foo, @function
foo:
leaq EXTERNAL_SYM(%rip), %rdi
.hidden EXTERNAL_SYM

View File

@ -0,0 +1 @@
PROVIDE_HIDDEN(EXTERNAL_SYM = ADDR(.text));

View File

@ -458,6 +458,8 @@ run_dump_test "pr24458c"
run_dump_test "pr24458c-x32"
run_dump_test "pr24721"
run_dump_test "pr24721-x32"
run_dump_test "pr24905"
run_dump_test "pr24905-x32"
if { ![istarget "x86_64-*-linux*"] && ![istarget "x86_64-*-nacl*"]} {
return