x86: Properly handle PLT expression in directive

For PLT expressions, we should subtract the PLT relocation size only for
jump instructions.  Since PLT relocations are PC relative, we only allow
"symbol@PLT" in PLT expression.

gas/

	PR gas/23997
	* config/tc-i386.c (x86_cons): Check for invalid PLT expression.
	(md_apply_fix): Subtract the PLT relocation size only for jump
	instructions.
	* testsuite/gas/i386/reloc32.s: Add test for invalid PLT
	expression.
	* testsuite/gas/i386/reloc64.s: Likewise.
	* testsuite/gas/i386/ilp32/reloc64.s: Likewise.
	* testsuite/gas/i386/reloc32.l: Updated.
	* testsuite/gas/i386/reloc64.l: Likewise.
	* testsuite/gas/i386/ilp32/reloc64.l: Likewise.

ld/

	PR gas/23997
	* testsuite/ld-i386/i386.exp: Run PR gas/23997 test.
	* testsuite/ld-x86-64/x86-64.exp: Likewise.
	* testsuite/ld-x86-64/pr23997a.s: New file.
	* testsuite/ld-x86-64/pr23997b.c: Likewise.
	* testsuite/ld-x86-64/pr23997c.c: Likewise.
This commit is contained in:
H.J. Lu 2018-12-19 12:21:56 -08:00
parent fc999e8020
commit b9519cfe98
14 changed files with 98 additions and 3 deletions

View File

@ -1,3 +1,17 @@
2018-12-19 H.J. Lu <hongjiu.lu@intel.com>
PR gas/23997
* config/tc-i386.c (x86_cons): Check for invalid PLT expression.
(md_apply_fix): Subtract the PLT relocation size only for jump
instructions.
* testsuite/gas/i386/reloc32.s: Add test for invalid PLT
expression.
* testsuite/gas/i386/reloc64.s: Likewise.
* testsuite/gas/i386/ilp32/reloc64.s: Likewise.
* testsuite/gas/i386/reloc32.l: Updated.
* testsuite/gas/i386/reloc64.l: Likewise.
* testsuite/gas/i386/ilp32/reloc64.l: Likewise.
2018-12-14 H.J. Lu <hongjiu.lu@intel.com>
PR ld/23900

View File

@ -8919,6 +8919,15 @@ x86_cons (expressionS *exp, int size)
as_bad (_("missing or invalid expression `%s'"), save);
*input_line_pointer = c;
}
else if ((got_reloc == BFD_RELOC_386_PLT32
|| got_reloc == BFD_RELOC_X86_64_PLT32)
&& exp->X_op != O_symbol)
{
char c = *input_line_pointer;
*input_line_pointer = 0;
as_bad (_("invalid PLT expression `%s'"), save);
*input_line_pointer = c;
}
}
}
else
@ -10533,9 +10542,11 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
{
case BFD_RELOC_386_PLT32:
case BFD_RELOC_X86_64_PLT32:
/* Make the jump instruction point to the address of the operand. At
runtime we merely add the offset to the actual PLT entry. */
value = -4;
/* Make the jump instruction point to the address of the operand.
At runtime we merely add the offset to the actual PLT entry.
NB: Subtract the offset size only for jump instructions. */
if (fixP->fx_pcrel)
value = -4;
break;
case BFD_RELOC_386_TLS_GD:

View File

@ -51,3 +51,4 @@
.*:175: Error: .*
.*:176: Error: .*
.*:177: Error: .*
.*:189: Error: .*

View File

@ -186,3 +186,4 @@ bad .byte xtrn@tpoff
.quad xtrn - 0x80000000
.long xtrn@got - 4
.long xtrn@got + 4
bad .long xtrn@plt - .

View File

@ -65,4 +65,5 @@
.*:159: Error: .*
.*:160: Error: .*
.*:161: Error: .*
.*:164: Error: .*
#pass

View File

@ -161,3 +161,4 @@ bad .byte xtrn@ntpoff
bad .byte xtrn@tpoff
.long xtrn@got + 4
.long xtrn@got - 4
bad .long xtrn@plt - .

View File

@ -81,3 +81,4 @@
.*:218: Error: .*
.*:219: Error: .*
.*:220: Error: .*
.*:227: Error: .*

View File

@ -224,3 +224,4 @@ bad .byte xtrn@gotplt
mov xtrn(,%ebx), %eax
vgatherdps %xmm2, xtrn(,%xmm1), %xmm0
addr32 vgatherdps %xmm2, xtrn(,%xmm1), %xmm0
bad .long xtrn@plt - .

View File

@ -1,3 +1,12 @@
2018-12-19 H.J. Lu <hongjiu.lu@intel.com>
PR gas/23997
* testsuite/ld-i386/i386.exp: Run PR gas/23997 test.
* testsuite/ld-x86-64/x86-64.exp: Likewise.
* testsuite/ld-x86-64/pr23997a.s: New file.
* testsuite/ld-x86-64/pr23997b.c: Likewise.
* testsuite/ld-x86-64/pr23997c.c: Likewise.
2018-12-19 H.J. Lu <hongjiu.lu@intel.com>
* testsuite/ld-x86-64/x86-64.exp: Rename PR ld/22842 run-time

View File

@ -1420,6 +1420,15 @@ if { [isnative]
"pr22842" \
"pass.out" \
] \
[list \
"Run pr23997" \
"" \
"" \
{ ../ld-x86-64/pr23997a.s ../ld-x86-64/pr23997b.c \
../ld-x86-64/pr23997c.c } \
"pr23997" \
"pass.out" \
] \
]
if { [at_least_gcc_version 5 0] } {

View File

@ -0,0 +1,6 @@
.text
.p2align 3
.globl foo_p
foo_p:
.long foo@plt
.section .note.GNU-stack,"",@progbits

View File

@ -0,0 +1,25 @@
#include <stdio.h>
typedef void (*func_t) (void);
extern func_t get_foo (void);
void
foo (void)
{
}
int
main ()
{
func_t p;
foo ();
p = get_foo ();
p ();
if (foo == p)
printf ("PASS\n");
return 0;
}

View File

@ -0,0 +1,7 @@
extern int foo_p;
void *
get_foo (void)
{
return (void *) ((long) &foo_p + foo_p);
}

View File

@ -1594,6 +1594,14 @@ if { [isnative] && [which $CC] != 0 } {
"pr22842" \
"pass.out" \
] \
[list \
"Run pr23997" \
"" \
"" \
{ pr23997a.s pr23997b.c pr23997c.c } \
"pr23997" \
"pass.out" \
] \
]
# Run-time tests which require working ifunc attribute support.