From b9519cfe9828b9ee5a73e74b4be83d46f33e6886 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Wed, 19 Dec 2018 12:21:56 -0800 Subject: 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. --- gas/ChangeLog | 14 ++++++++++++++ gas/config/tc-i386.c | 17 ++++++++++++++--- gas/testsuite/gas/i386/ilp32/reloc64.l | 1 + gas/testsuite/gas/i386/ilp32/reloc64.s | 1 + gas/testsuite/gas/i386/reloc32.l | 1 + gas/testsuite/gas/i386/reloc32.s | 1 + gas/testsuite/gas/i386/reloc64.l | 1 + gas/testsuite/gas/i386/reloc64.s | 1 + 8 files changed, 34 insertions(+), 3 deletions(-) (limited to 'gas') diff --git a/gas/ChangeLog b/gas/ChangeLog index 00159202d1d..b21680a1589 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,17 @@ +2018-12-19 H.J. Lu + + 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 PR ld/23900 diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 8e25e6c7a04..764063119d1 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -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: diff --git a/gas/testsuite/gas/i386/ilp32/reloc64.l b/gas/testsuite/gas/i386/ilp32/reloc64.l index ff491945971..7a1808e4e96 100644 --- a/gas/testsuite/gas/i386/ilp32/reloc64.l +++ b/gas/testsuite/gas/i386/ilp32/reloc64.l @@ -51,3 +51,4 @@ .*:175: Error: .* .*:176: Error: .* .*:177: Error: .* +.*:189: Error: .* diff --git a/gas/testsuite/gas/i386/ilp32/reloc64.s b/gas/testsuite/gas/i386/ilp32/reloc64.s index 77764b3c625..3ab25eff6c0 100644 --- a/gas/testsuite/gas/i386/ilp32/reloc64.s +++ b/gas/testsuite/gas/i386/ilp32/reloc64.s @@ -186,3 +186,4 @@ bad .byte xtrn@tpoff .quad xtrn - 0x80000000 .long xtrn@got - 4 .long xtrn@got + 4 +bad .long xtrn@plt - . diff --git a/gas/testsuite/gas/i386/reloc32.l b/gas/testsuite/gas/i386/reloc32.l index 9299445851f..3fb3255fc89 100644 --- a/gas/testsuite/gas/i386/reloc32.l +++ b/gas/testsuite/gas/i386/reloc32.l @@ -65,4 +65,5 @@ .*:159: Error: .* .*:160: Error: .* .*:161: Error: .* +.*:164: Error: .* #pass diff --git a/gas/testsuite/gas/i386/reloc32.s b/gas/testsuite/gas/i386/reloc32.s index 855dcf578d9..e766a3dcc25 100644 --- a/gas/testsuite/gas/i386/reloc32.s +++ b/gas/testsuite/gas/i386/reloc32.s @@ -161,3 +161,4 @@ bad .byte xtrn@ntpoff bad .byte xtrn@tpoff .long xtrn@got + 4 .long xtrn@got - 4 +bad .long xtrn@plt - . diff --git a/gas/testsuite/gas/i386/reloc64.l b/gas/testsuite/gas/i386/reloc64.l index 5e970cb7b6d..6d7a3c70c4d 100644 --- a/gas/testsuite/gas/i386/reloc64.l +++ b/gas/testsuite/gas/i386/reloc64.l @@ -81,3 +81,4 @@ .*:218: Error: .* .*:219: Error: .* .*:220: Error: .* +.*:227: Error: .* diff --git a/gas/testsuite/gas/i386/reloc64.s b/gas/testsuite/gas/i386/reloc64.s index 0f9c51e4c8d..bc6f0fa6cc3 100644 --- a/gas/testsuite/gas/i386/reloc64.s +++ b/gas/testsuite/gas/i386/reloc64.s @@ -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 - . -- cgit v1.2.1