forked from Imagelibrary/binutils-gdb
Ignore 0x66 prefix for call/jmp/jcc in 64-bit mode
The operand size prefix (0x66) is ignored for 32-bit PC-relative call,
jmp and jcc in 64-bit mode.
gas/testsuite/
PR binutis/18386
* gas/i386/i386.exp: Run x86-64-jump.
* gas/i386/x86-64-branch.d: Updated.
* gas/i386/ilp32/x86-64-branch.d: Likewise.
* gas/i386/x86-64-branch.s: Add tests for the operand size prefix
with call, jmp and jb.
* gas/i386/x86-64-jump.d: New file.
* gas/i386/x86-64-jump.s: Likewise.
ld/testsuite/
PR binutis/18386
* ld-x86-64/tlsgdesc.dd: Updated.
* ld-x86-64/tlspic.dd: Likewise.
opcodes/
PR binutis/18386
* i386-dis.c (X86_64_E8): New.
(X86_64_E9): Likewise.
Update comments on 'T', 'U', 'V'. Add comments for '^'.
(dis386): Replace callT/jmpT with X86_64_E8/X86_64_E9.
(x86_64_table): Add X86_64_E8 and X86_64_E9.
(mod_table): Replace {T|} with ^ on Jcall/Jmp.
(putop): Handle '^'.
(OP_J): Ignore the operand size prefix in 64-bit. Don't check
REX_W.
This commit is contained in:
@@ -1632,6 +1632,8 @@ enum
|
||||
X86_64_CE,
|
||||
X86_64_D4,
|
||||
X86_64_D5,
|
||||
X86_64_E8,
|
||||
X86_64_E9,
|
||||
X86_64_EA,
|
||||
X86_64_0F01_REG_0,
|
||||
X86_64_0F01_REG_1,
|
||||
@@ -2401,9 +2403,12 @@ struct dis386 {
|
||||
is true
|
||||
'R' => print 'w', 'l' or 'q' ('d' for 'l' and 'e' in Intel mode)
|
||||
'S' => print 'w', 'l' or 'q' if suffix_always is true
|
||||
'T' => print 'q' in 64bit mode and behave as 'P' otherwise
|
||||
'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
|
||||
'V' => print 'q' in 64bit mode and behave as 'S' otherwise
|
||||
'T' => print 'q' in 64bit mode if instruction has no operand size
|
||||
prefix and behave as 'P' otherwise
|
||||
'U' => print 'q' in 64bit mode if instruction has no operand size
|
||||
prefix and behave as 'Q' otherwise
|
||||
'V' => print 'q' in 64bit mode if instruction has no operand size
|
||||
prefix and behave as 'S' otherwise
|
||||
'W' => print 'b', 'w' or 'l' ('d' in Intel mode)
|
||||
'X' => print 's', 'd' depending on data16 prefix (for XMM)
|
||||
'Y' => 'q' if instruction has an REX 64bit overwrite prefix and
|
||||
@@ -2411,6 +2416,8 @@ struct dis386 {
|
||||
'Z' => print 'q' in 64bit mode and behave as 'L' otherwise
|
||||
'!' => change condition from true to false or from false to true.
|
||||
'%' => add 1 upper case letter to the macro.
|
||||
'^' => print 'w' or 'l' depending on operand size prefix or
|
||||
suffix_always is true (lcall/ljmp).
|
||||
|
||||
2 upper case letter macros:
|
||||
"XY" => print 'x' or 'y' if suffix_always is true or no register
|
||||
@@ -2697,8 +2704,8 @@ static const struct dis386 dis386[] = {
|
||||
{ "outB", { Ib, AL }, 0 },
|
||||
{ "outG", { Ib, zAX }, 0 },
|
||||
/* e8 */
|
||||
{ "callT", { Jv, BND }, 0 },
|
||||
{ "jmpT", { Jv, BND }, 0 },
|
||||
{ X86_64_TABLE (X86_64_E8) },
|
||||
{ X86_64_TABLE (X86_64_E9) },
|
||||
{ X86_64_TABLE (X86_64_EA) },
|
||||
{ "jmp", { Jb, BND }, 0 },
|
||||
{ "inB", { AL, indirDX }, 0 },
|
||||
@@ -6834,6 +6841,18 @@ static const struct dis386 x86_64_table[][2] = {
|
||||
{ "aad", { Ib }, 0 },
|
||||
},
|
||||
|
||||
/* X86_64_E8 */
|
||||
{
|
||||
{ "callP", { Jv, BND }, 0 },
|
||||
{ "callq", { Jv, BND }, 0 }
|
||||
},
|
||||
|
||||
/* X86_64_E9 */
|
||||
{
|
||||
{ "jmpP", { Jv, BND }, 0 },
|
||||
{ "jmpq", { Jv, BND }, 0 }
|
||||
},
|
||||
|
||||
/* X86_64_EA */
|
||||
{
|
||||
{ "Jjmp{T|}", { Ap }, 0 },
|
||||
@@ -11576,11 +11595,11 @@ static const struct dis386 mod_table[][2] = {
|
||||
},
|
||||
{
|
||||
/* MOD_FF_REG_3 */
|
||||
{ "Jcall{T|}", { indirEp }, 0 },
|
||||
{ "Jcall^", { indirEp }, 0 },
|
||||
},
|
||||
{
|
||||
/* MOD_FF_REG_5 */
|
||||
{ "Jjmp{T|}", { indirEp }, 0 },
|
||||
{ "Jjmp^", { indirEp }, 0 },
|
||||
},
|
||||
{
|
||||
/* MOD_0F01_REG_0 */
|
||||
@@ -14177,6 +14196,18 @@ case_S:
|
||||
*obufp++ = vex.w ? 'q': 'd';
|
||||
}
|
||||
break;
|
||||
case '^':
|
||||
if (intel_syntax)
|
||||
break;
|
||||
if ((prefixes & PREFIX_DATA) || (sizeflag & SUFFIX_ALWAYS))
|
||||
{
|
||||
if (sizeflag & DFLAG)
|
||||
*obufp++ = 'l';
|
||||
else
|
||||
*obufp++ = 'w';
|
||||
used_prefixes |= (prefixes & PREFIX_DATA);
|
||||
}
|
||||
break;
|
||||
}
|
||||
alt = 0;
|
||||
}
|
||||
@@ -15693,8 +15724,7 @@ OP_J (int bytemode, int sizeflag)
|
||||
disp -= 0x100;
|
||||
break;
|
||||
case v_mode:
|
||||
USED_REX (REX_W);
|
||||
if ((sizeflag & DFLAG) || (rex & REX_W))
|
||||
if (address_mode == mode_64bit || (sizeflag & DFLAG))
|
||||
disp = get32s ();
|
||||
else
|
||||
{
|
||||
@@ -15710,7 +15740,7 @@ OP_J (int bytemode, int sizeflag)
|
||||
segment = ((start_pc + codep - start_codep)
|
||||
& ~((bfd_vma) 0xffff));
|
||||
}
|
||||
if (!(rex & REX_W))
|
||||
if (address_mode != mode_64bit)
|
||||
used_prefixes |= (prefixes & PREFIX_DATA);
|
||||
break;
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user