diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2018-12-19 12:21:56 -0800 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2018-12-19 12:22:12 -0800 |
commit | b9519cfe9828b9ee5a73e74b4be83d46f33e6886 (patch) | |
tree | aecea8a8890eb3cc814a80abdf7c0a976a889f01 /gas/config/tc-i386.c | |
parent | fc999e8020ffe8e1136da70f275bceafaa62a588 (diff) | |
download | fsf-binutils-gdb-b9519cfe9828b9ee5a73e74b4be83d46f33e6886.zip fsf-binutils-gdb-b9519cfe9828b9ee5a73e74b4be83d46f33e6886.tar.gz fsf-binutils-gdb-b9519cfe9828b9ee5a73e74b4be83d46f33e6886.tar.bz2 |
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.
Diffstat (limited to 'gas/config/tc-i386.c')
-rw-r--r-- | gas/config/tc-i386.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 8e25e6c..7640631 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: |