x86-64: Restore PIC check for PCREL reloc against protected symbol
commit bd7ab16b45
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Tue Feb 13 07:34:22 2018 -0800
x86-64: Generate branch with PLT32 relocation
removed check R_X86_64_PC32 relocation against protected symbols in
shared objects. Since elf_x86_64_check_relocs is called after we
have seen all input files, we can check for PC-relative relocations in
elf_x86_64_check_relocs. We should not allow PC-relative relocations
against protected symbols since address of protected function and
location of protected data may not be in the shared object.
bfd/
PR ld/24151
* elf64-x86-64.c (elf_x86_64_need_pic): Check
SYMBOL_DEFINED_NON_SHARED_P instead of def_regular.
(elf_x86_64_relocate_section): Move PIC check for PC-relative
relocations to ...
(elf_x86_64_check_relocs): Here.
(elf_x86_64_finish_dynamic_symbol): Use SYMBOL_DEFINED_NON_SHARED_P
to check if a symbol is defined in a non-shared object.
* elfxx-x86.h (SYMBOL_DEFINED_NON_SHARED_P): New.
ld/
PR ld/24151
* testsuite/ld-x86-64/pr24151a-x32.d: New file.
* testsuite/ld-x86-64/pr24151a.d: Likewise.
* testsuite/ld-x86-64/pr24151a.s: Likewise.
* testsuite/ld-x86-64/x86-64.exp: Run pr24151a and pr24151a-x32.
This commit is contained in:
parent
4e9ac437aa
commit
83924b3846
@ -1,3 +1,15 @@
|
||||
2019-02-05 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR ld/24151
|
||||
* elf64-x86-64.c (elf_x86_64_need_pic): Check
|
||||
SYMBOL_DEFINED_NON_SHARED_P instead of def_regular.
|
||||
(elf_x86_64_relocate_section): Move PIC check for PC-relative
|
||||
relocations to ...
|
||||
(elf_x86_64_check_relocs): Here.
|
||||
(elf_x86_64_finish_dynamic_symbol): Use SYMBOL_DEFINED_NON_SHARED_P
|
||||
to check if a symbol is defined in a non-shared object.
|
||||
* elfxx-x86.h (SYMBOL_DEFINED_NON_SHARED_P): New.
|
||||
|
||||
2019-01-21 Sergio Durigan Junior <sergiodj@redhat.com>
|
||||
|
||||
* elf32-arm.c (elf32_arm_final_link_relocate): Use 'llabs' instead
|
||||
|
@ -1426,7 +1426,7 @@ elf_x86_64_need_pic (struct bfd_link_info *info,
|
||||
break;
|
||||
}
|
||||
|
||||
if (!h->def_regular && !h->def_dynamic)
|
||||
if (!SYMBOL_DEFINED_NON_SHARED_P (h) && !h->def_dynamic)
|
||||
und = _("undefined ");
|
||||
}
|
||||
else
|
||||
@ -1855,6 +1855,7 @@ 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);
|
||||
@ -2130,6 +2131,13 @@ 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;
|
||||
@ -2153,13 +2161,11 @@ 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
|
||||
@ -2223,6 +2229,67 @@ pointer:
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
&& 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,
|
||||
@ -3065,56 +3132,14 @@ 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. */
|
||||
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
|
||||
&& !resolved_to_zero)
|
||||
|| (bfd_link_pie (info)
|
||||
&& !h->def_regular
|
||||
&& h->def_dynamic)
|
||||
|| ((info->nocopyreloc
|
||||
|| (eh->def_protected
|
||||
&& elf_has_no_copy_on_protected (h->root.u.def.section->owner)))
|
||||
&& 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 = !(h->def_regular || ELF_COMMON_DEF_P (h));
|
||||
}
|
||||
else if (!(bfd_link_pie (info)
|
||||
&& (h->needs_copy || eh->needs_copy)))
|
||||
{
|
||||
/* Symbol doesn't need copy reloc and isn't referenced
|
||||
locally. Address of protected function may not be
|
||||
reachable at run-time. */
|
||||
fail = (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|
||||
|| (ELF_ST_VISIBILITY (h->other) == STV_PROTECTED
|
||||
&& h->type == STT_FUNC));
|
||||
}
|
||||
|
||||
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. */
|
||||
else if (h != NULL
|
||||
&& (input_section->flags & SEC_CODE) == 0
|
||||
&& bfd_link_pie (info)
|
||||
&& h->type == STT_FUNC
|
||||
&& !h->def_regular
|
||||
&& h->def_dynamic)
|
||||
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. */
|
||||
|
||||
@ -4271,7 +4296,7 @@ elf_x86_64_finish_dynamic_symbol (bfd *output_bfd,
|
||||
else if (bfd_link_pic (info)
|
||||
&& SYMBOL_REFERENCES_LOCAL_P (info, h))
|
||||
{
|
||||
if (!(h->def_regular || ELF_COMMON_DEF_P (h)))
|
||||
if (!SYMBOL_DEFINED_NON_SHARED_P (h))
|
||||
return FALSE;
|
||||
BFD_ASSERT((h->got.offset & 1) != 0);
|
||||
rela.r_info = htab->r_info (0, R_X86_64_RELATIVE);
|
||||
|
@ -161,6 +161,13 @@
|
||||
|| (ELF_ST_VISIBILITY ((H)->other) \
|
||||
&& (H)->root.type == bfd_link_hash_undefweak))
|
||||
|
||||
/* TRUE if this symbol isn't defined by a shared object. */
|
||||
#define SYMBOL_DEFINED_NON_SHARED_P(H) \
|
||||
((H)->def_regular \
|
||||
|| (H)->root.linker_def \
|
||||
|| (H)->root.ldscript_def \
|
||||
|| ELF_COMMON_DEF_P (H))
|
||||
|
||||
/* TRUE if relative relocation should be generated. GOT reference to
|
||||
global symbol in PIC will lead to dynamic symbol. It becomes a
|
||||
problem when "time" or "times" is defined as a variable in an
|
||||
|
@ -1,3 +1,11 @@
|
||||
2019-02-05 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR ld/24151
|
||||
* testsuite/ld-x86-64/pr24151a-x32.d: New file.
|
||||
* testsuite/ld-x86-64/pr24151a.d: Likewise.
|
||||
* testsuite/ld-x86-64/pr24151a.s: Likewise.
|
||||
* testsuite/ld-x86-64/x86-64.exp: Run pr24151a and pr24151a-x32.
|
||||
|
||||
2019-01-31 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* NEWS: Mention -t change.
|
||||
|
4
ld/testsuite/ld-x86-64/pr24151a-x32.d
Normal file
4
ld/testsuite/ld-x86-64/pr24151a-x32.d
Normal file
@ -0,0 +1,4 @@
|
||||
#source: pr24151a.s
|
||||
#as: --x32
|
||||
#ld: -shared -melf32_x86_64
|
||||
#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
|
3
ld/testsuite/ld-x86-64/pr24151a.d
Normal file
3
ld/testsuite/ld-x86-64/pr24151a.d
Normal file
@ -0,0 +1,3 @@
|
||||
#as: --64
|
||||
#ld: -shared -melf_x86_64
|
||||
#error: .*relocation R_X86_64_PC32 against protected symbol `foo' can not be used when making a shared object
|
9
ld/testsuite/ld-x86-64/pr24151a.s
Normal file
9
ld/testsuite/ld-x86-64/pr24151a.s
Normal file
@ -0,0 +1,9 @@
|
||||
.text
|
||||
.globl bar
|
||||
.type bar,@function
|
||||
bar:
|
||||
movl $30, foo(%rip)
|
||||
.size bar, .-bar
|
||||
.protected foo
|
||||
.type foo,@object
|
||||
.comm foo,4,4
|
@ -424,6 +424,8 @@ run_dump_test "pr23486d-x32"
|
||||
run_dump_test "pr23854"
|
||||
run_dump_test "pr23930"
|
||||
run_dump_test "pr23930-x32"
|
||||
run_dump_test "pr24151a"
|
||||
run_dump_test "pr24151a-x32"
|
||||
|
||||
if { ![istarget "x86_64-*-linux*"] && ![istarget "x86_64-*-nacl*"]} {
|
||||
return
|
||||
|
Loading…
Reference in New Issue
Block a user