aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2015-05-15 05:49:00 -0700
committerH.J. Lu <hjl.tools@gmail.com>2015-05-15 05:49:00 -0700
commitc8302360003ed1d956167b9ab6576b326fbe798a (patch)
tree9dff445c75c119a1053c1a6cbc379af75857cfe8
parent95d04eda574137ba56b39ac233a690e219432a22 (diff)
downloadgdb-c8302360003ed1d956167b9ab6576b326fbe798a.zip
gdb-c8302360003ed1d956167b9ab6576b326fbe798a.tar.gz
gdb-c8302360003ed1d956167b9ab6576b326fbe798a.tar.bz2
Add AMD64 call/jmp
-rw-r--r--opcodes/i386-dis.c43
-rw-r--r--opcodes/i386-opc.tbl2
-rw-r--r--opcodes/i386-tbl.h26
3 files changed, 66 insertions, 5 deletions
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c
index 941f699..978a948 100644
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -2418,6 +2418,8 @@ struct dis386 {
'%' => add 1 upper case letter to the macro.
'^' => print 'w' or 'l' depending on operand size prefix or
suffix_always is true (lcall/ljmp).
+ '@' => print 'q' for Intel64 ISA, 'w' or 'q' for AMD64 ISA depending
+ on operand size prefix.
2 upper case letter macros:
"XY" => print 'x' or 'y' if suffix_always is true or no register
@@ -6844,13 +6846,13 @@ static const struct dis386 x86_64_table[][2] = {
/* X86_64_E8 */
{
{ "callP", { Jv, BND }, 0 },
- { "callq", { Jv, BND }, 0 }
+ { "call@", { Jv, BND }, 0 }
},
/* X86_64_E9 */
{
{ "jmpP", { Jv, BND }, 0 },
- { "jmpq", { Jv, BND }, 0 }
+ { "jmp@", { Jv, BND }, 0 }
},
/* X86_64_EA */
@@ -12342,6 +12344,14 @@ static char close_char;
static char separator_char;
static char scale_char;
+enum x86_64_isa
+{
+ amd64,
+ intel64
+};
+
+static enum x86_64_isa isa64 = amd64;
+
/* Here for backwards compatibility. When gdb stops using
print_insn_i386_att and print_insn_i386_intel these functions can
disappear, and print_insn_i386 be merged into print_insn. */
@@ -12391,6 +12401,8 @@ with the -M switch (multiple options should be separated by commas):\n"));
fprintf (stream, _(" data32 Assume 32bit data size\n"));
fprintf (stream, _(" data16 Assume 16bit data size\n"));
fprintf (stream, _(" suffix Always display instruction suffix in AT&T syntax\n"));
+ fprintf (stream, _(" AMD64 Display instruction in AMD64 ISA\n"));
+ fprintf (stream, _(" Intel64 Display instruction in Intel64 ISA\n"));
}
/* Bad opcode. */
@@ -12874,7 +12886,11 @@ print_insn (bfd_vma pc, disassemble_info *info)
for (p = info->disassembler_options; p != NULL; )
{
- if (CONST_STRNEQ (p, "x86-64"))
+ if (!strncasecmp (p, "amd64", sizeof "amd64"))
+ isa64 = amd64;
+ else if (!strncasecmp (p, "intel64", sizeof "intel64"))
+ isa64 = intel64;
+ else if (CONST_STRNEQ (p, "x86-64"))
{
address_mode = mode_64bit;
priv.orig_sizeflag = AFLAG | DFLAG;
@@ -14208,6 +14224,18 @@ case_S:
used_prefixes |= (prefixes & PREFIX_DATA);
}
break;
+ case '@':
+ if (isa64 == intel64)
+ *obufp++ = 'q';
+ else if ((prefixes & PREFIX_DATA))
+ {
+ if (sizeflag & DFLAG)
+ *obufp++ = 'q';
+ else
+ *obufp++ = 'w';
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ }
+ break;
}
alt = 0;
}
@@ -15724,7 +15752,11 @@ OP_J (int bytemode, int sizeflag)
disp -= 0x100;
break;
case v_mode:
- if (address_mode == mode_64bit || (sizeflag & DFLAG))
+ if (isa64 == amd64)
+ USED_REX (REX_W);
+ if ((sizeflag & DFLAG)
+ || (address_mode == mode_64bit
+ && (isa64 != amd64 || (rex & REX_W))))
disp = get32s ();
else
{
@@ -15740,7 +15772,8 @@ OP_J (int bytemode, int sizeflag)
segment = ((start_pc + codep - start_codep)
& ~((bfd_vma) 0xffff));
}
- if (address_mode != mode_64bit)
+ if (address_mode != mode_64bit
+ || (isa64 == amd64 && !(rex & REX_W)))
used_prefixes |= (prefixes & PREFIX_DATA);
break;
default:
diff --git a/opcodes/i386-opc.tbl b/opcodes/i386-opc.tbl
index ca629c4..64108f7 100644
--- a/opcodes/i386-opc.tbl
+++ b/opcodes/i386-opc.tbl
@@ -319,6 +319,7 @@ shrd, 2, 0xfad, None, 2, Cpu386, Modrm|CheckRegSize|No_bSuf|No_sSuf|No_ldSuf, {
// Control transfer instructions.
call, 1, 0xe8, None, 1, CpuNo64, JumpDword|DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk, { Disp16|Disp32 }
+call, 1, 0xe8, None, 1, Cpu64|CpuAMD64, JumpDword|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk, { Disp16|Disp32|Disp32S }
call, 1, 0xe8, None, 1, Cpu64, JumpDword|DefaultSize|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk, { Disp32S }
call, 1, 0xff, 0x2, 1, CpuNo64, Modrm|DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk, { Reg16|Reg32|Word|Dword|Unspecified|BaseIndex|Disp8|Disp16|Disp32|JumpAbsolute }
call, 1, 0xff, 0x2, 1, Cpu64, Modrm|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk, { Reg16|Reg64|Word|Qword|Unspecified|BaseIndex|Disp8|Disp32|Disp32S|JumpAbsolute }
@@ -330,6 +331,7 @@ lcall, 2, 0x9a, None, 1, CpuNo64, JumpInterSegment|DefaultSize|No_bSuf|No_sSuf|N
lcall, 1, 0xff, 0x3, 1, 0, Modrm|DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { Unspecified|BaseIndex|Disp8|Disp16|Disp32|Disp32S|JumpAbsolute }
jmp, 1, 0xeb, None, 1, CpuNo64, Jump|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk, { Disp8|Disp16|Disp32|Disp32S }
+jmp, 1, 0xeb, None, 1, Cpu64|CpuAMD64, Jump|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk, { Disp8|Disp16|Disp32|Disp32S }
jmp, 1, 0xeb, None, 1, Cpu64, Jump|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk, { Disp8|Disp32S }
jmp, 1, 0xff, 0x4, 1, CpuNo64, Modrm|No_bSuf|No_sSuf|No_qSuf|No_ldSuf|BNDPrefixOk, { Reg16|Reg32|Word|Dword|Unspecified|BaseIndex|Disp8|Disp16|Disp32|JumpAbsolute }
jmp, 1, 0xff, 0x4, 1, Cpu64, Modrm|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|BNDPrefixOk, { Reg16|Reg64|Word|Qword|Unspecified|BaseIndex|Disp8|Disp32|Disp32S|JumpAbsolute }
diff --git a/opcodes/i386-tbl.h b/opcodes/i386-tbl.h
index de3f5f0..e252977 100644
--- a/opcodes/i386-tbl.h
+++ b/opcodes/i386-tbl.h
@@ -3187,6 +3187,19 @@ const insn_template i386_optab[] =
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 1, 0, 0 } },
+ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
+ 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0 },
+ { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } } } },
+ { "call", 1, 0xe8, None, 1,
+ { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0 } },
{ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
@@ -3297,6 +3310,19 @@ const insn_template i386_optab[] =
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 1, 0, 0 } },
+ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
+ 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0 },
+ { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } } } },
+ { "jmp", 1, 0xeb, None, 1,
+ { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0 } },
{ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,