Create a PLT entry for R_X86_64_PC32 in non-code sections

Since something like ".long foo - ." may be used as pointer, we make
sure that PLT is used if foo is a function defined in a shared library.

bfd/

	PR ld/19031
	* elf64-x86-64.c (elf_x86_64_check_relocs): Set
	pointer_equality_needed for R_X86_64_PC32 reloc in non-code
	sections.

ld/testsuite/

	PR ld/19031
	* ld-x86-64/x86-64.exp: Run PR ld/19031 test.
	* ld-x86-64/pr19031.out: New file.
	* ld-x86-64/pr19031a.c: Likewise.
	* ld-x86-64/pr19031b.S: Likewise.
	* ld-x86-64/pr19031c.c: Likewise.
This commit is contained in:
H.J. Lu 2015-10-01 10:49:33 -07:00
parent dd0a637a3d
commit 5db4f0d383
8 changed files with 83 additions and 7 deletions

View File

@ -1,3 +1,10 @@
2015-10-01 H.J. Lu <hongjiu.lu@intel.com>
PR ld/19031
* elf64-x86-64.c (elf_x86_64_check_relocs): Set
pointer_equality_needed for R_X86_64_PC32 reloc in non-code
sections.
2015-10-01 Renlin Li <renlin.li@arm.com>
* elfnn-aarch64.c (elfNN_aarch64_output_plt_map): Remove.

View File

@ -1961,9 +1961,16 @@ pointer:
/* We may need a .plt entry if the function this reloc
refers to is in a shared lib. */
h->plt.refcount += 1;
if (r_type != R_X86_64_PC32
&& r_type != R_X86_64_PC32_BND
&& r_type != R_X86_64_PC64)
if (r_type == R_X86_64_PC32)
{
/* Since something like ".long foo - ." may be used
as pointer, make sure that PLT is used if foo is
a function defined in a shared library. */
if ((sec->flags & SEC_CODE) == 0)
h->pointer_equality_needed = 1;
}
else if (r_type != R_X86_64_PC32_BND
&& r_type != R_X86_64_PC64)
{
h->pointer_equality_needed = 1;
/* At run-time, R_X86_64_64 can be resolved for both

View File

@ -1,3 +1,12 @@
2015-10-01 H.J. Lu <hongjiu.lu@intel.com>
PR ld/19031
* ld-x86-64/x86-64.exp: Run PR ld/19031 test.
* ld-x86-64/pr19031.out: New file.
* ld-x86-64/pr19031a.c: Likewise.
* ld-x86-64/pr19031b.S: Likewise.
* ld-x86-64/pr19031c.c: Likewise.
2015-10-01 Renlin Li <renlin.li@arm.com>
* ld-aarch64/aarch64-elf.exp: Run the new test.
@ -17,10 +26,10 @@
PR ld/19031
* ld-i386/i386.exp: Run PR ld/19031 test.
* ld/testsuite/ld-i386/pr19031.out: New file.
* ld/testsuite/ld-i386/pr19031a.c: Likewise.
* ld/testsuite/ld-i386/pr19031b.S: Likewise.
* ld/testsuite/ld-i386/pr19031c.c: Likewise.
* ld-i386/pr19031.out: New file.
* ld-i386/pr19031a.c: Likewise.
* ld-i386/pr19031b.S: Likewise.
* ld-i386/pr19031c.c: Likewise.
2015-09-30 H.J. Lu <hongjiu.lu@intel.com>

View File

@ -0,0 +1 @@
OK

View File

@ -0,0 +1,4 @@
void
f (void)
{
}

View File

@ -0,0 +1,18 @@
.text
.globl g
.type g, @function
g:
movq f@GOTPCREL(%rip), %rax
retq
.globl h
.type h, @function
h:
leaq zed, %rax
movslq zed, %rbx
addq %rbx, %rax
retq
.data
zed:
.long f - .

View File

@ -0,0 +1,14 @@
#include <stdio.h>
extern void *h (void);
extern void *g (void);
int
main (void)
{
if (h () == g ())
printf ("OK\n");
return 0;
}

View File

@ -503,6 +503,14 @@ if { [isnative] && [which $CC] != 0 } {
{{readelf {-Wrd} pr18900b.rd}} \
"pr18900b" \
] \
[list \
"Build pr19031.so" \
"-shared" \
"-fPIC" \
{ pr19031a.c } \
"" \
"pr19031.so" \
] \
]
run_ld_link_exec_tests [] [list \
@ -557,6 +565,14 @@ if { [isnative] && [which $CC] != 0 } {
"pr18900" \
"pr18900.out" \
] \
[list \
"Run pr19031" \
"tmpdir/pr19031.so" \
"" \
{ pr19031b.S pr19031c.c } \
"pr19031" \
"pr19031.out" \
] \
]
if { [istarget "x86_64-*-linux*"] \