mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-26 22:07:58 +08:00
x86-64: Check relocations with -z nocopyreloc
On x86-64, when -z nocopyreloc is used to build executable, relocations may overflow at run-time or may not be resolved without PIC. This patch checks these conditions and issues an error with suggestion for -fPIC. bfd/ PR ld/22001 * elf64-x86-64.c (elf_x86_64_relocate_section): Check for R_X86_64_PC32 relocation run-time overflow and unresolvable R_X86_64_32S relocation with -z nocopyreloc. ld/ PR ld/22001 * testsuite/ld-i386/i386.exp: Run -z nocopyreloc tests. * testsuite/ld-x86-64/x86-64.exp: Likewise. * ld/testsuite/ld-i386/pr22001-1a.c: New file. * ld/testsuite/ld-i386/pr22001-1b.c: Likewise. * ld/testsuite/ld-i386/pr22001-1c.S: Likewise. * ld/testsuite/ld-x86-64/pr22001-1a.c: Likewise. * ld/testsuite/ld-x86-64/pr22001-1a.err: Likewise. * ld/testsuite/ld-x86-64/pr22001-1b.c: Likewise. * ld/testsuite/ld-x86-64/pr22001-1b.err: Likewise. * ld/testsuite/ld-x86-64/pr22001-1c.c: Likewise.
This commit is contained in:
@ -1,3 +1,10 @@
|
|||||||
|
2017-08-24 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
|
PR ld/22001
|
||||||
|
* elf64-x86-64.c (elf_x86_64_relocate_section): Check for
|
||||||
|
R_X86_64_PC32 relocation run-time overflow and unresolvable
|
||||||
|
R_X86_64_32S relocation with -z nocopyreloc.
|
||||||
|
|
||||||
2017-08-24 H.J. Lu <hongjiu.lu@intel.com>
|
2017-08-24 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
* elf32-i386.c (elf_i386_check_relocs): Revert the last change.
|
* elf32-i386.c (elf_i386_check_relocs): Revert the last change.
|
||||||
|
@ -4942,13 +4942,17 @@ do_ifunc_pointer:
|
|||||||
case R_X86_64_PC32:
|
case R_X86_64_PC32:
|
||||||
case R_X86_64_PC32_BND:
|
case R_X86_64_PC32_BND:
|
||||||
/* Don't complain about -fPIC if the symbol is undefined when
|
/* Don't complain about -fPIC if the symbol is undefined when
|
||||||
building executable unless it is unresolved weak symbol. */
|
building executable unless it is unresolved weak symbol or
|
||||||
|
-z nocopyreloc is used. */
|
||||||
if ((input_section->flags & SEC_ALLOC) != 0
|
if ((input_section->flags & SEC_ALLOC) != 0
|
||||||
&& (input_section->flags & SEC_READONLY) != 0
|
&& (input_section->flags & SEC_READONLY) != 0
|
||||||
&& h != NULL
|
&& h != NULL
|
||||||
&& ((bfd_link_executable (info)
|
&& ((bfd_link_executable (info)
|
||||||
&& h->root.type == bfd_link_hash_undefweak
|
&& ((h->root.type == bfd_link_hash_undefweak
|
||||||
&& !resolved_to_zero)
|
&& !resolved_to_zero)
|
||||||
|
|| (info->nocopyreloc
|
||||||
|
&& h->def_dynamic
|
||||||
|
&& !(h->root.u.def.section->flags & SEC_CODE))))
|
||||||
|| bfd_link_dll (info)))
|
|| bfd_link_dll (info)))
|
||||||
{
|
{
|
||||||
bfd_boolean fail = FALSE;
|
bfd_boolean fail = FALSE;
|
||||||
@ -5717,15 +5721,26 @@ direct:
|
|||||||
&& _bfd_elf_section_offset (output_bfd, info, input_section,
|
&& _bfd_elf_section_offset (output_bfd, info, input_section,
|
||||||
rel->r_offset) != (bfd_vma) -1)
|
rel->r_offset) != (bfd_vma) -1)
|
||||||
{
|
{
|
||||||
_bfd_error_handler
|
switch (r_type)
|
||||||
/* xgettext:c-format */
|
{
|
||||||
(_("%B(%A+%#Lx): unresolvable %s relocation against symbol `%s'"),
|
case R_X86_64_32S:
|
||||||
input_bfd,
|
if (info->nocopyreloc
|
||||||
input_section,
|
&& !(h->root.u.def.section->flags & SEC_CODE))
|
||||||
rel->r_offset,
|
return elf_x86_64_need_pic (info, input_bfd, input_section,
|
||||||
howto->name,
|
h, NULL, NULL, howto);
|
||||||
h->root.root.string);
|
/* Fall through. */
|
||||||
return FALSE;
|
|
||||||
|
default:
|
||||||
|
_bfd_error_handler
|
||||||
|
/* xgettext:c-format */
|
||||||
|
(_("%B(%A+%#Lx): unresolvable %s relocation against symbol `%s'"),
|
||||||
|
input_bfd,
|
||||||
|
input_section,
|
||||||
|
rel->r_offset,
|
||||||
|
howto->name,
|
||||||
|
h->root.root.string);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
do_relocation:
|
do_relocation:
|
||||||
|
14
ld/ChangeLog
14
ld/ChangeLog
@ -1,3 +1,17 @@
|
|||||||
|
2017-08-24 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
|
PR ld/22001
|
||||||
|
* testsuite/ld-i386/i386.exp: Run -z nocopyreloc tests.
|
||||||
|
* testsuite/ld-x86-64/x86-64.exp: Likewise.
|
||||||
|
* ld/testsuite/ld-i386/pr22001-1a.c: New file.
|
||||||
|
* ld/testsuite/ld-i386/pr22001-1b.c: Likewise.
|
||||||
|
* ld/testsuite/ld-i386/pr22001-1c.S: Likewise.
|
||||||
|
* ld/testsuite/ld-x86-64/pr22001-1a.c: Likewise.
|
||||||
|
* ld/testsuite/ld-x86-64/pr22001-1a.err: Likewise.
|
||||||
|
* ld/testsuite/ld-x86-64/pr22001-1b.c: Likewise.
|
||||||
|
* ld/testsuite/ld-x86-64/pr22001-1b.err: Likewise.
|
||||||
|
* ld/testsuite/ld-x86-64/pr22001-1c.c: Likewise.
|
||||||
|
|
||||||
2017-08-17 Andrew Burgess <andrew.burgess@embecosm.com>
|
2017-08-17 Andrew Burgess <andrew.burgess@embecosm.com>
|
||||||
|
|
||||||
PR 21961
|
PR 21961
|
||||||
|
@ -1245,6 +1245,17 @@ if { [isnative]
|
|||||||
if { [isnative]
|
if { [isnative]
|
||||||
&& [istarget "i?86-*-*"]
|
&& [istarget "i?86-*-*"]
|
||||||
&& [which $CC] != 0 } {
|
&& [which $CC] != 0 } {
|
||||||
|
run_cc_link_tests [list \
|
||||||
|
[list \
|
||||||
|
"Build pr22001-1.so" \
|
||||||
|
"-shared" \
|
||||||
|
"" \
|
||||||
|
{ pr22001-1a.c } \
|
||||||
|
{} \
|
||||||
|
"pr22001-1.so" \
|
||||||
|
] \
|
||||||
|
]
|
||||||
|
|
||||||
run_ld_link_exec_tests [list \
|
run_ld_link_exec_tests [list \
|
||||||
[list \
|
[list \
|
||||||
"Run weakundef1 without PIE" \
|
"Run weakundef1 without PIE" \
|
||||||
@ -1255,7 +1266,51 @@ if { [isnative]
|
|||||||
"pass.out" \
|
"pass.out" \
|
||||||
"$NOPIE_CFLAGS" \
|
"$NOPIE_CFLAGS" \
|
||||||
] \
|
] \
|
||||||
|
[list \
|
||||||
|
"Run pr22001-1" \
|
||||||
|
"$NOPIE_LDFLAGS -Wl,-z,nocopyreloc,--no-as-needed tmpdir/pr22001-1.so" \
|
||||||
|
"" \
|
||||||
|
{ pr22001-1b.c } \
|
||||||
|
"pr22001-1" \
|
||||||
|
"pass.out" \
|
||||||
|
"$NOPIE_CFLAGS" \
|
||||||
|
] \
|
||||||
|
[list \
|
||||||
|
"Run pr22001-1 (PIE 1)" \
|
||||||
|
"$NOPIE_LDFLAGS -Wl,-z,nocopyreloc,--no-as-needed tmpdir/pr22001-1.so" \
|
||||||
|
"" \
|
||||||
|
{ pr22001-1c.S } \
|
||||||
|
"pr22001-1-pie-1" \
|
||||||
|
"pass.out" \
|
||||||
|
] \
|
||||||
|
[list \
|
||||||
|
"Run pr22001-1 (PIE 2)" \
|
||||||
|
"-pie -Wl,-z,nocopyreloc,--no-as-needed tmpdir/pr22001-1.so" \
|
||||||
|
"" \
|
||||||
|
{ pr22001-1c.S } \
|
||||||
|
"pr22001-1-pie-2" \
|
||||||
|
"pass.out" \
|
||||||
|
] \
|
||||||
|
[list \
|
||||||
|
"Run pr22001-1 (PIC 1)" \
|
||||||
|
"$NOPIE_LDFLAGS -Wl,-z,nocopyreloc,--no-as-needed tmpdir/pr22001-1.so" \
|
||||||
|
"" \
|
||||||
|
{ pr22001-1b.c } \
|
||||||
|
"pr22001-1-pic-1" \
|
||||||
|
"pass.out" \
|
||||||
|
"-fPIC" \
|
||||||
|
] \
|
||||||
|
[list \
|
||||||
|
"Run pr22001-1 (PIC 2)" \
|
||||||
|
"-pie -Wl,-z,nocopyreloc,--no-as-needed tmpdir/pr22001-1.so" \
|
||||||
|
"" \
|
||||||
|
{ pr22001-1b.c } \
|
||||||
|
"pr22001-1-pic-2" \
|
||||||
|
"pass.out" \
|
||||||
|
"-fPIC" \
|
||||||
|
] \
|
||||||
]
|
]
|
||||||
|
|
||||||
if { [at_least_gcc_version 5 0] } {
|
if { [at_least_gcc_version 5 0] } {
|
||||||
run_ld_link_exec_tests [list \
|
run_ld_link_exec_tests [list \
|
||||||
[list \
|
[list \
|
||||||
|
13
ld/testsuite/ld-i386/pr22001-1a.c
Normal file
13
ld/testsuite/ld-i386/pr22001-1a.c
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
int copy = 1;
|
||||||
|
|
||||||
|
int
|
||||||
|
get_copy ()
|
||||||
|
{
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
int *
|
||||||
|
get_copy_p ()
|
||||||
|
{
|
||||||
|
return ©
|
||||||
|
}
|
14
ld/testsuite/ld-i386/pr22001-1b.c
Normal file
14
ld/testsuite/ld-i386/pr22001-1b.c
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
extern int copy;
|
||||||
|
extern int get_copy (void);
|
||||||
|
extern int* get_copy_p (void);
|
||||||
|
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
if (copy == get_copy () && © == get_copy_p ())
|
||||||
|
printf ("PASS\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
51
ld/testsuite/ld-i386/pr22001-1c.S
Normal file
51
ld/testsuite/ld-i386/pr22001-1c.S
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
.section .rodata.str1.1,"aMS",@progbits,1
|
||||||
|
.LC0:
|
||||||
|
.string "PASS"
|
||||||
|
.section .text.startup,"ax",@progbits
|
||||||
|
.p2align 4,,15
|
||||||
|
.globl main
|
||||||
|
.type main, @function
|
||||||
|
main:
|
||||||
|
leal 4(%esp), %ecx
|
||||||
|
andl $-16, %esp
|
||||||
|
pushl -4(%ecx)
|
||||||
|
pushl %ebp
|
||||||
|
movl %esp, %ebp
|
||||||
|
pushl %esi
|
||||||
|
pushl %ebx
|
||||||
|
pushl %ecx
|
||||||
|
call __x86.get_pc_thunk.bx
|
||||||
|
addl $_GLOBAL_OFFSET_TABLE_, %ebx
|
||||||
|
subl $12, %esp
|
||||||
|
call get_copy@PLT
|
||||||
|
movl copy@GOT(%ebx), %esi
|
||||||
|
cmpl (%esi), %eax
|
||||||
|
je .L7
|
||||||
|
.L3:
|
||||||
|
leal -12(%ebp), %esp
|
||||||
|
xorl %eax, %eax
|
||||||
|
popl %ecx
|
||||||
|
popl %ebx
|
||||||
|
popl %esi
|
||||||
|
popl %ebp
|
||||||
|
leal -4(%ecx), %esp
|
||||||
|
ret
|
||||||
|
.L7:
|
||||||
|
call get_copy_p@PLT
|
||||||
|
cmpl %esi, %eax
|
||||||
|
jne .L3
|
||||||
|
leal .LC0@GOTOFF(%ebx), %eax
|
||||||
|
subl $12, %esp
|
||||||
|
pushl %eax
|
||||||
|
call puts@PLT
|
||||||
|
addl $16, %esp
|
||||||
|
jmp .L3
|
||||||
|
.size main, .-main
|
||||||
|
.section .text.__x86.get_pc_thunk.bx,"axG",@progbits,__x86.get_pc_thunk.bx,comdat
|
||||||
|
.globl __x86.get_pc_thunk.bx
|
||||||
|
.hidden __x86.get_pc_thunk.bx
|
||||||
|
.type __x86.get_pc_thunk.bx, @function
|
||||||
|
__x86.get_pc_thunk.bx:
|
||||||
|
movl (%esp), %ebx
|
||||||
|
ret
|
||||||
|
.section .note.GNU-stack,"",@progbits
|
13
ld/testsuite/ld-x86-64/pr22001-1a.c
Normal file
13
ld/testsuite/ld-x86-64/pr22001-1a.c
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
int copy = 1;
|
||||||
|
|
||||||
|
int
|
||||||
|
get_copy ()
|
||||||
|
{
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
int *
|
||||||
|
get_copy_p ()
|
||||||
|
{
|
||||||
|
return ©
|
||||||
|
}
|
2
ld/testsuite/ld-x86-64/pr22001-1a.err
Normal file
2
ld/testsuite/ld-x86-64/pr22001-1a.err
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
.*relocation R_X86_64_PC32 against symbol `copy' can not be used when making a P(D|I)E object; recompile with -fPIC
|
||||||
|
#...
|
13
ld/testsuite/ld-x86-64/pr22001-1b.c
Normal file
13
ld/testsuite/ld-x86-64/pr22001-1b.c
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
extern int copy;
|
||||||
|
extern int get_copy (void);
|
||||||
|
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
if (copy == get_copy ())
|
||||||
|
printf ("PASS\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
2
ld/testsuite/ld-x86-64/pr22001-1b.err
Normal file
2
ld/testsuite/ld-x86-64/pr22001-1b.err
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
.*relocation R_X86_64_32S against symbol `copy' can not be used when making a P(D|I)E object; recompile with -fPIC
|
||||||
|
#...
|
12
ld/testsuite/ld-x86-64/pr22001-1c.c
Normal file
12
ld/testsuite/ld-x86-64/pr22001-1c.c
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
extern int copy;
|
||||||
|
extern int* get_copy_p (void);
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
if (© == get_copy_p ())
|
||||||
|
printf ("PASS\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -1040,6 +1040,30 @@ if { [isnative] && [which $CC] != 0 } {
|
|||||||
{{readelf {-n} property-7.r}} \
|
{{readelf {-n} property-7.r}} \
|
||||||
"property-7b.o" \
|
"property-7b.o" \
|
||||||
] \
|
] \
|
||||||
|
[list \
|
||||||
|
"Build pr22001-1.so" \
|
||||||
|
"-shared" \
|
||||||
|
"-fPIC" \
|
||||||
|
{ pr22001-1a.c } \
|
||||||
|
{} \
|
||||||
|
"pr22001-1.so" \
|
||||||
|
] \
|
||||||
|
[list \
|
||||||
|
"Build pr22001-1a" \
|
||||||
|
"$NOPIE_LDFLAGS -Wl,-z,nocopyreloc,--no-as-needed tmpdir/pr22001-1.so" \
|
||||||
|
"$NOPIE_CFLAGS" \
|
||||||
|
{ pr22001-1b.c } \
|
||||||
|
{{error_output "pr22001-1a.err"}} \
|
||||||
|
"pr22001-1a" \
|
||||||
|
] \
|
||||||
|
[list \
|
||||||
|
"Build pr22001-1b" \
|
||||||
|
"$NOPIE_LDFLAGS -Wl,-z,nocopyreloc,--no-as-needed tmpdir/pr22001-1.so" \
|
||||||
|
"$NOPIE_CFLAGS" \
|
||||||
|
{ pr22001-1c.c } \
|
||||||
|
{{error_output "pr22001-1b.err"}} \
|
||||||
|
"pr22001-1b" \
|
||||||
|
] \
|
||||||
]
|
]
|
||||||
|
|
||||||
run_ld_link_exec_tests [list \
|
run_ld_link_exec_tests [list \
|
||||||
@ -1216,6 +1240,42 @@ if { [isnative] && [which $CC] != 0 } {
|
|||||||
{property-x86-2.S property-x86-1.S pass.c property-stack.S} \
|
{property-x86-2.S property-x86-1.S pass.c property-stack.S} \
|
||||||
"property-5-static" "pass.out" \
|
"property-5-static" "pass.out" \
|
||||||
] \
|
] \
|
||||||
|
[list \
|
||||||
|
"Run pr22001-1a (PIC 1)" \
|
||||||
|
"$NOPIE_LDFLAGS -Wl,-z,nocopyreloc,--no-as-needed tmpdir/pr22001-1.so" \
|
||||||
|
"" \
|
||||||
|
{ pr22001-1b.c } \
|
||||||
|
"pr22001-1a-pic-1" \
|
||||||
|
"pass.out" \
|
||||||
|
"-fPIC" \
|
||||||
|
] \
|
||||||
|
[list \
|
||||||
|
"Run pr22001-1a (PIC 2)" \
|
||||||
|
"-pie -Wl,-z,nocopyreloc,--no-as-needed tmpdir/pr22001-1.so" \
|
||||||
|
"" \
|
||||||
|
{ pr22001-1b.c } \
|
||||||
|
"pr22001-1a-pic-2" \
|
||||||
|
"pass.out" \
|
||||||
|
"-fPIC" \
|
||||||
|
] \
|
||||||
|
[list \
|
||||||
|
"Run pr22001-1b (PIC 1)" \
|
||||||
|
"$NOPIE_LDFLAGS -Wl,-z,nocopyreloc,--no-as-needed tmpdir/pr22001-1.so" \
|
||||||
|
"" \
|
||||||
|
{ pr22001-1c.c } \
|
||||||
|
"pr22001-1b-pic-1" \
|
||||||
|
"pass.out" \
|
||||||
|
"-fPIC" \
|
||||||
|
] \
|
||||||
|
[list \
|
||||||
|
"Run pr22001-1b (PIC 2)" \
|
||||||
|
"-pie -Wl,-z,nocopyreloc,--no-as-needed tmpdir/pr22001-1.so" \
|
||||||
|
"" \
|
||||||
|
{ pr22001-1c.c } \
|
||||||
|
"pr22001-1b-pic-2" \
|
||||||
|
"pass.out" \
|
||||||
|
"-fPIC" \
|
||||||
|
] \
|
||||||
]
|
]
|
||||||
|
|
||||||
# Run-time tests which require working ifunc attribute support.
|
# Run-time tests which require working ifunc attribute support.
|
||||||
|
Reference in New Issue
Block a user