From: H.J. Lu Date: Fri, 16 Aug 2019 21:25:15 +0000 (-0700) Subject: x86-64: Move PIC check for PC-relative relocations back X-Git-Tag: binutils-2_33~181 X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fbinutils-gdb.git;a=commitdiff_plain;h=81e8046dc0daaf56fb10b11931fc77600a4b5920 x86-64: Move PIC check for PC-relative relocations back commit 83924b3846361f2f76f9a6e7b5afa01c0eebbd4f Author: H.J. Lu 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. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 868796a8c10..962fc1f0375 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2019-08-16 H.J. Lu + + 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 PR ld/24912 diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 34180c7552a..e5c8003a68e 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -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. */ diff --git a/ld/ChangeLog b/ld/ChangeLog index 34d32408235..4837aac2203 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,12 @@ +2019-08-16 H.J. Lu + + 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 * emulparams/armelf.sh (OTHER_SECTIONS): Add support for noinit diff --git a/ld/testsuite/ld-x86-64/pr24905-x32.d b/ld/testsuite/ld-x86-64/pr24905-x32.d new file mode 100644 index 00000000000..e2c6a730766 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr24905-x32.d @@ -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 diff --git a/ld/testsuite/ld-x86-64/pr24905.d b/ld/testsuite/ld-x86-64/pr24905.d new file mode 100644 index 00000000000..f11834f12b9 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr24905.d @@ -0,0 +1,7 @@ +#as: --64 +#ld: -shared -melf_x86_64 $srcdir/$subdir/pr24905.t +#nm: -n + +#... +[0-9a-f]* t EXTERNAL_SYM +#pass diff --git a/ld/testsuite/ld-x86-64/pr24905.s b/ld/testsuite/ld-x86-64/pr24905.s new file mode 100644 index 00000000000..73a5d58032f --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr24905.s @@ -0,0 +1,6 @@ + .text + .globl foo + .type foo, @function +foo: + leaq EXTERNAL_SYM(%rip), %rdi + .hidden EXTERNAL_SYM diff --git a/ld/testsuite/ld-x86-64/pr24905.t b/ld/testsuite/ld-x86-64/pr24905.t new file mode 100644 index 00000000000..5e7dbd371f4 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr24905.t @@ -0,0 +1 @@ +PROVIDE_HIDDEN(EXTERNAL_SYM = ADDR(.text)); diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp index d815e5d633c..b13cc7df0e9 100644 --- a/ld/testsuite/ld-x86-64/x86-64.exp +++ b/ld/testsuite/ld-x86-64/x86-64.exp @@ -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