Re: [RFA/RFC Prec] Add Linux AMD64 process record support second version, (instruction set support) 1/3

Hui Zhu
2009-07-17T08:47:05Z

[-- Attachment #1: Type: text/plain, Size: 78309 bytes --]

On Mon, Jul 13, 2009 at 08:34, Michael Snyder<msnyder@vmware.com> wrote:
> Hui Zhu wrote:
>>
>> Because AMD64 instruction set is the extend of I386 instruction set.
>> So I update the function i386_process_record to make it support AMD64
>> instruction set.  some of other software do something like it.
>> 2009-07-07  Hui Zhu  <teawater@gmail.com>
>>
>>        Add AMD64 process record instruction set support.
>>
>>        * i386-tdep.h (gdbarch_tdep): Add record_regmap for registers
>>        because the AMD64's registers order in GDB is not same with
>>        I386 instructions.
>>        Add i386_syscall_record to be the syscall function handle
>>        interface.
>>        (record_i386_regnum): Number for record_regmap.
>>        * i386-tdep.c (OT_QUAD): For 64 bits.
>>        (i386_record_s): Add rex_x, rex_b, rip_offset and
>>        popl_esp_hack for AMD64 instruction set. And regmap for
>>        record_regmap.
>>        (i386_record_lea_modrm_addr): Support AMD64 instruction set
>>        64 bits lea.
>>        (i386_record_lea_modrm): Ditto.
>>        (i386_record_push): New function.  Record the execution log
>>        of push.
>>        (I386_RECORD_ARCH_LIST_ADD_REG): New macro to record the
>>        register.
>>        (i386_process_record): Support AMD64 instruction set.
>>        amd64-tdep.c (amd64_record_regmap): For record_regmap.
>>        (amd64_init_abi): Set amd64_record_regmap to record_regmap.
>
> OK, this is kind of preliminary -- mostly concerned with
> whitespace / formatting.  I'll try to do more later.
>
>
>> @@ -2859,7 +2868,7 @@ i386_record_lea_modrm_addr (struct i386_
>>          if ((base & 7) == 5)
>>            {
>>              base = 0xff;
>> -             if (target_read_memory (irp->addr, (gdb_byte *) addr, 4))
>> +             if (target_read_memory (irp->addr, (gdb_byte *)&tmpi32, 4))
>
> Space after a cast, please.  There are many instances of this,
> I won't try to note them all.
>
>> @@ -2884,10 +2896,10 @@ i386_record_lea_modrm_addr (struct i386_
>>              return -1;
>>            }
>>          irp->addr++;
>> -         *addr = (int8_t) tmpu8;
>> +         *addr = (int8_t)tmpu8;
>
> Space after cast
>
>> @@ -2949,10 +2974,10 @@ i386_record_lea_modrm_addr (struct i386_
>>              return -1;
>>            }
>>          irp->addr++;
>> -         *addr = (int8_t) tmpu8;
>> +         *addr = (int8_t)tmpu8;
>>          break;
>>        case 2:
>> -         if (target_read_memory (irp->addr, (gdb_byte *) & tmpu16, 2))
>> +         if (target_read_memory (irp->addr, (gdb_byte *) & tmpi16, 2))
>
> No space after '&' operator.  In general, we use a space
> both before and after a binary operator (such as 'plus'),
> but no space after a unary operator such as '&', '*' or '-'.
>
>> +         if (ir.aflag == 2)
>> +           {
>> +              if (target_read_memory
>> +                 (ir.addr, (gdb_byte *)&addr, 8))
>
> Please try to avoid doing this (putting the left-paren of a
> function call on the next line).  Occasionally when a line gets
> really long I tend to overlook it, but in this case it would
> be really easy to divide the line up like this:
>
>               if (target_read_memory (ir.addr,
>                                       (gdb_byte *) &addr, 8))
>
>> +          if (ir.mod ==3)
>
> Space after ==
>
>> +          switch (ir.dflag)
>> +            {
>> +            case 0:
>> +              tmpu64 += ((int16_t)tmpulongest >> 4)<< 4;
>
> Space before <<, space after cast.
>
>> +              break;
>> +            case 1:
>> +              tmpu64 += ((int32_t)tmpulongest >> 5)<< 5;
>
> Ditto
>
>> +              break;
>> +            case 2:
>> +              tmpu64 += ((int64_t)tmpulongest >> 6)<< 6;
>
> Ditto
>
>> +  /* The map for registers because the AMD64's registers order in GDB is
>> not
>> +     same with I386 instructions.  */
>
> "same as".  And could you shorten the first line please?
>
>
>

Thanks Michael,

I updated all the AMD64 patches. Please help me review it.

Thanks,
Hui

2009-07-17 Hui Zhu <teawater@gmail.com>

Add AMD64 process record instruction set support.

* i386-tdep.h (gdbarch_tdep): Add record_regmap for registers
because the AMD64's registers order in GDB is not same with
I386 instructions.
Add i386_syscall_record to be the syscall function handle
interface.
(record_i386_regnum): Number for record_regmap.
* i386-tdep.c (OT_QUAD): For 64 bits.
(i386_record_s): Add rex_x, rex_b, rip_offset and
popl_esp_hack for AMD64 instruction set. And regmap for
record_regmap.
(i386_record_lea_modrm_addr): Support AMD64 instruction set
64 bits lea.
(i386_record_lea_modrm): Ditto.
(i386_record_push): New function. Record the execution log
of push.
(I386_RECORD_ARCH_LIST_ADD_REG): New macro to record the
register.
(i386_process_record): Support AMD64 instruction set.
amd64-tdep.c (amd64_record_regmap): For record_regmap.
(amd64_init_abi): Set amd64_record_regmap to record_regmap.

---
amd64-tdep.c | 12
i386-tdep.c | 1437 +++++++++++++++++++++++++++++++----------------------------
i386-tdep.h | 35 +
3 files changed, 825 insertions(+), 659 deletions(-)

--- a/amd64-tdep.c
+++ b/amd64-tdep.c
@@ -1989,6 +1989,16 @@ amd64_get_longjmp_target (struct frame_i
return 1;
}

+static const int amd64_record_regmap[] =
+{
+ AMD64_RAX_REGNUM, AMD64_RCX_REGNUM, AMD64_RDX_REGNUM, AMD64_RBX_REGNUM,
+ AMD64_RSP_REGNUM, AMD64_RBP_REGNUM, AMD64_RSI_REGNUM, AMD64_RDI_REGNUM,
+ AMD64_R8_REGNUM, AMD64_R9_REGNUM, AMD64_R10_REGNUM, AMD64_R11_REGNUM,
+ AMD64_R12_REGNUM, AMD64_R13_REGNUM, AMD64_R14_REGNUM, AMD64_R15_REGNUM,
+ AMD64_RIP_REGNUM, AMD64_EFLAGS_REGNUM, AMD64_CS_REGNUM, AMD64_SS_REGNUM,
+ AMD64_DS_REGNUM, AMD64_ES_REGNUM, AMD64_FS_REGNUM, AMD64_GS_REGNUM
+};
+
void
amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
@@ -2051,6 +2061,8 @@ amd64_init_abi (struct gdbarch_info info
set_gdbarch_num_pseudo_regs (gdbarch, 0);
tdep->mm0_regnum = -1;

+ tdep->record_regmap = amd64_record_regmap;
+
set_gdbarch_dummy_id (gdbarch, amd64_dummy_id);

frame_unwind_append_unwinder (gdbarch, &amd64_sigtramp_frame_unwind);
--- a/i386-tdep.c
+++ b/i386-tdep.c
@@ -2847,6 +2847,7 @@ enum
OT_BYTE = 0,
OT_WORD,
OT_LONG,
+ OT_QUAD,
};

/* i386 arith/logic operations */
@@ -2864,6 +2865,7 @@ enum

struct i386_record_s
{
+ struct gdbarch *gdbarch;
struct regcache *regcache;
CORE_ADDR addr;
int aflag;
@@ -2872,6 +2874,11 @@ struct i386_record_s
uint8_t modrm;
uint8_t mod, reg, rm;
int ot;
+ uint8_t rex_x;
+ uint8_t rex_b;
+ int rip_offset;
+ int popl_esp_hack;
+ const int *regmap;
};

/* Parse "modrm" part in current memory address that irp->addr point to
@@ -2880,7 +2887,7 @@ struct i386_record_s
static int
i386_record_modrm (struct i386_record_s *irp)
{
- struct gdbarch *gdbarch = get_regcache_arch (irp->regcache);
+ struct gdbarch *gdbarch = irp->gdbarch;

if (target_read_memory (irp->addr, &irp->modrm, 1))
{
@@ -2903,12 +2910,13 @@ i386_record_modrm (struct i386_record_s
Return -1 if something wrong. */

static int
-i386_record_lea_modrm_addr (struct i386_record_s *irp, uint32_t * addr)
+i386_record_lea_modrm_addr (struct i386_record_s *irp, uint64_t *addr)
{
- struct gdbarch *gdbarch = get_regcache_arch (irp->regcache);
+ struct gdbarch *gdbarch = irp->gdbarch;
uint8_t tmpu8;
- uint16_t tmpu16;
- uint32_t tmpu32;
+ int16_t tmpi16;
+ int32_t tmpi32;
+ ULONGEST tmpulongest;

*addr = 0;
if (irp->aflag)
@@ -2932,9 +2940,10 @@ i386_record_lea_modrm_addr (struct i386_
}
irp->addr++;
scale = (tmpu8 >> 6) & 3;
- index = ((tmpu8 >> 3) & 7);
+ index = ((tmpu8 >> 3) & 7) | irp->rex_x;
base = (tmpu8 & 7);
}
+ base |= irp->rex_b;

switch (irp->mod)
{
@@ -2942,7 +2951,7 @@ i386_record_lea_modrm_addr (struct i386_
if ((base & 7) == 5)
{
base = 0xff;
- if (target_read_memory (irp->addr, (gdb_byte *) addr, 4))
+ if (target_read_memory (irp->addr, (gdb_byte *) &tmpi32, 4))
{
if (record_debug)
printf_unfiltered (_("Process record: error reading "
@@ -2951,6 +2960,9 @@ i386_record_lea_modrm_addr (struct i386_
return -1;
}
irp->addr += 4;
+ *addr = tmpi32;
+ if (irp->regmap[X86_RECORD_R8_REGNUM] && !havesib)
+ *addr += irp->addr + irp->rip_offset;
}
else
{
@@ -2970,7 +2982,7 @@ i386_record_lea_modrm_addr (struct i386_
*addr = (int8_t) tmpu8;
break;
case 2:
- if (target_read_memory (irp->addr, (gdb_byte *) addr, 4))
+ if (target_read_memory (irp->addr, (gdb_byte *) &tmpi32, 4))
{
if (record_debug)
printf_unfiltered (_("Process record: error reading memory "
@@ -2978,21 +2990,34 @@ i386_record_lea_modrm_addr (struct i386_
paddress (gdbarch, irp->addr));
return -1;
}
+ *addr = tmpi32;
irp->addr += 4;
break;
}

+ tmpulongest = 0;
if (base != 0xff)
- {
- regcache_raw_read (irp->regcache, base, (gdb_byte *) & tmpu32);
- *addr += tmpu32;
+ {
+ if (base == 4 && irp->popl_esp_hack)
+ *addr += irp->popl_esp_hack;
+ regcache_raw_read_unsigned (irp->regcache, irp->regmap[base],
+ &tmpulongest);
}
+ if (irp->aflag == 2)
+ {
+ *addr += tmpulongest;
+ }
+ else
+ *addr = (uint32_t) (tmpulongest + *addr);

- /* XXX: index == 4 is always invalid */
if (havesib && (index != 4 || scale != 0))
{
- regcache_raw_read (irp->regcache, index, (gdb_byte *) & tmpu32);
- *addr += tmpu32 << scale;
+ regcache_raw_read_unsigned (irp->regcache, irp->regmap[index],
+ &tmpulongest);
+ if (irp->aflag == 2)
+ *addr += tmpulongest << scale;
+ else
+ *addr = (uint32_t) (*addr + (tmpulongest << scale));
}
}
else
@@ -3004,7 +3029,7 @@ i386_record_lea_modrm_addr (struct i386_
if (irp->rm == 6)
{
if (target_read_memory
- (irp->addr, (gdb_byte *) & tmpu16, 2))
+ (irp->addr, (gdb_byte *) &tmpi16, 2))
{
if (record_debug)
printf_unfiltered (_("Process record: error reading "
@@ -3013,7 +3038,7 @@ i386_record_lea_modrm_addr (struct i386_
return -1;
}
irp->addr += 2;
- *addr = (int16_t) tmpu16;
+ *addr = tmpi16;
irp->rm = 0;
goto no_rm;
}
@@ -3035,7 +3060,7 @@ i386_record_lea_modrm_addr (struct i386_
*addr = (int8_t) tmpu8;
break;
case 2:
- if (target_read_memory (irp->addr, (gdb_byte *) & tmpu16, 2))
+ if (target_read_memory (irp->addr, (gdb_byte *) &tmpi16, 2))
{
if (record_debug)
printf_unfiltered (_("Process record: error reading memory "
@@ -3044,63 +3069,75 @@ i386_record_lea_modrm_addr (struct i386_
return -1;
}
irp->addr += 2;
- *addr = (int16_t) tmpu16;
+ *addr = tmpi16;
break;
}

switch (irp->rm)
{
case 0:
- regcache_raw_read (irp->regcache, I386_EBX_REGNUM,
- (gdb_byte *) & tmpu32);
- *addr += tmpu32;
- regcache_raw_read (irp->regcache, I386_ESI_REGNUM,
- (gdb_byte *) & tmpu32);
- *addr += tmpu32;
+ regcache_raw_read_unsigned (irp->regcache,
+ irp->regmap[X86_RECORD_REBX_REGNUM],
+ &tmpulongest);
+ *addr = (uint32_t) (*addr + tmpulongest);
+ regcache_raw_read_unsigned (irp->regcache,
+ irp->regmap[X86_RECORD_RESI_REGNUM],
+ &tmpulongest);
+ *addr = (uint32_t) (*addr + tmpulongest);
break;
case 1:
- regcache_raw_read (irp->regcache, I386_EBX_REGNUM,
- (gdb_byte *) & tmpu32);
- *addr += tmpu32;
- regcache_raw_read (irp->regcache, I386_EDI_REGNUM,
- (gdb_byte *) & tmpu32);
- *addr += tmpu32;
+ regcache_raw_read_unsigned (irp->regcache,
+ irp->regmap[X86_RECORD_REBX_REGNUM],
+ &tmpulongest);
+ *addr = (uint32_t) (*addr + tmpulongest);
+ regcache_raw_read_unsigned (irp->regcache,
+ irp->regmap[X86_RECORD_REDI_REGNUM],
+ &tmpulongest);
+ *addr = (uint32_t) (*addr + tmpulongest);
break;
case 2:
- regcache_raw_read (irp->regcache, I386_EBP_REGNUM,
- (gdb_byte *) & tmpu32);
- *addr += tmpu32;
- regcache_raw_read (irp->regcache, I386_ESI_REGNUM,
- (gdb_byte *) & tmpu32);
- *addr += tmpu32;
+ regcache_raw_read_unsigned (irp->regcache,
+ irp->regmap[X86_RECORD_REBP_REGNUM],
+ &tmpulongest);
+ *addr = (uint32_t) (*addr + tmpulongest);
+ regcache_raw_read_unsigned (irp->regcache,
+ irp->regmap[X86_RECORD_RESI_REGNUM],
+ &tmpulongest);
+ *addr = (uint32_t) (*addr + tmpulongest);
break;
case 3:
- regcache_raw_read (irp->regcache, I386_EBP_REGNUM,
- (gdb_byte *) & tmpu32);
- *addr += tmpu32;
- regcache_raw_read (irp->regcache, I386_EDI_REGNUM,
- (gdb_byte *) & tmpu32);
- *addr += tmpu32;
+ regcache_raw_read_unsigned (irp->regcache,
+ irp->regmap[X86_RECORD_REBP_REGNUM],
+ &tmpulongest);
+ *addr = (uint32_t) (*addr + tmpulongest);
+ regcache_raw_read_unsigned (irp->regcache,
+ irp->regmap[X86_RECORD_REDI_REGNUM],
+ &tmpulongest);
+ *addr = (uint32_t) (*addr + tmpulongest);
break;
case 4:
- regcache_raw_read (irp->regcache, I386_ESI_REGNUM,
- (gdb_byte *) & tmpu32);
- *addr += tmpu32;
+ regcache_raw_read_unsigned (irp->regcache,
+ irp->regmap[X86_RECORD_RESI_REGNUM],
+ &tmpulongest);
+ *addr = (uint32_t) (*addr + tmpulongest);
break;
case 5:
- regcache_raw_read (irp->regcache, I386_EDI_REGNUM,
- (gdb_byte *) & tmpu32);
- *addr += tmpu32;
+ regcache_raw_read_unsigned (irp->regcache,
+ irp->regmap[X86_RECORD_REDI_REGNUM],
+ &tmpulongest);
+ *addr = (uint32_t) (*addr + tmpulongest);
break;
case 6:
- regcache_raw_read (irp->regcache, I386_EBP_REGNUM,
- (gdb_byte *) & tmpu32);
- *addr += tmpu32;
+ regcache_raw_read_unsigned (irp->regcache,
+ irp->regmap[X86_RECORD_REBP_REGNUM],
+ &tmpulongest);
+ *addr = (uint32_t) (*addr + tmpulongest);
break;
case 7:
- regcache_raw_read (irp->regcache, I386_EBX_REGNUM,
- (gdb_byte *) & tmpu32);
- *addr += tmpu32;
+ regcache_raw_read_unsigned (irp->regcache,
+ irp->regmap[X86_RECORD_REBX_REGNUM],
+ &tmpulongest);
+ *addr = (uint32_t) (*addr + tmpulongest);
break;
}
*addr &= 0xffff;
@@ -3117,10 +3154,10 @@ no_rm:
static int
i386_record_lea_modrm (struct i386_record_s *irp)
{
- struct gdbarch *gdbarch = get_regcache_arch (irp->regcache);
- uint32_t addr;
+ struct gdbarch *gdbarch = irp->gdbarch;
+ uint64_t addr;

- if (irp->override)
+ if (irp->override >= 0)
{
if (record_debug)
printf_unfiltered (_("Process record ignores the memory change "
@@ -3139,10 +3176,36 @@ i386_record_lea_modrm (struct i386_recor
return 0;
}

+/* Record the push operation to "record_arch_list".
+ Return -1 if something wrong. */
+
+static int
+i386_record_push (struct i386_record_s *irp, int size)
+{
+ ULONGEST tmpulongest;
+
+ if (record_arch_list_add_reg (irp->regcache,
+ irp->regmap[X86_RECORD_RESP_REGNUM]))
+ return -1;
+ regcache_raw_read_unsigned (irp->regcache,
+ irp->regmap[X86_RECORD_RESP_REGNUM],
+ &tmpulongest);
+ if (record_arch_list_add_mem ((CORE_ADDR) tmpulongest - size, size))
+ return -1;
+
+ return 0;
+}
+
/* Parse the current instruction and record the values of the registers and
memory that will be changed in current instruction to "record_arch_list".
Return -1 if something wrong. */

+#define I386_RECORD_ARCH_LIST_ADD_REG(regnum) \
+ do { \
+ if (record_arch_list_add_reg (ir.regcache, ir.regmap[(regnum)])) \
+ return -1; \
+ } while (0)
+
int
i386_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
CORE_ADDR addr)
@@ -3151,14 +3214,21 @@ i386_process_record (struct gdbarch *gdb
uint8_t tmpu8;
uint16_t tmpu16;
uint32_t tmpu32;
+ ULONGEST tmpulongest;
uint32_t opcode;
struct i386_record_s ir;
+ int rex = 0;
+ uint8_t rex_w = -1;
+ uint8_t rex_r = 0;

memset (&ir, 0, sizeof (struct i386_record_s));
ir.regcache = regcache;
ir.addr = addr;
ir.aflag = 1;
ir.dflag = 1;
+ ir.override = -1;
+ ir.regmap = gdbarch_tdep (gdbarch)->record_regmap;
+ ir.gdbarch = gdbarch;

if (record_debug > 1)
fprintf_unfiltered (gdb_stdlog, "Process record: i386_process_record "
@@ -3189,22 +3259,22 @@ i386_process_record (struct gdbarch *gdb
prefixes |= PREFIX_LOCK;
break;
case 0x2e:
- ir.override = I386_CS_REGNUM;
+ ir.override = X86_RECORD_CS_REGNUM;
break;
case 0x36:
- ir.override = I386_SS_REGNUM;
+ ir.override = X86_RECORD_SS_REGNUM;
break;
case 0x3e:
- ir.override = I386_DS_REGNUM;
+ ir.override = X86_RECORD_DS_REGNUM;
break;
case 0x26:
- ir.override = I386_ES_REGNUM;
+ ir.override = X86_RECORD_ES_REGNUM;
break;
case 0x64:
- ir.override = I386_FS_REGNUM;
+ ir.override = X86_RECORD_FS_REGNUM;
break;
case 0x65:
- ir.override = I386_GS_REGNUM;
+ ir.override = X86_RECORD_GS_REGNUM;
break;
case 0x66:
prefixes |= PREFIX_DATA;
@@ -3212,16 +3282,51 @@ i386_process_record (struct gdbarch *gdb
case 0x67:
prefixes |= PREFIX_ADDR;
break;
+ case 0x40:
+ case 0x41:
+ case 0x42:
+ case 0x43:
+ case 0x44:
+ case 0x45:
+ case 0x46:
+ case 0x47:
+ case 0x48:
+ case 0x49:
+ case 0x4a:
+ case 0x4b:
+ case 0x4c:
+ case 0x4d:
+ case 0x4e:
+ case 0x4f:
+ if (ir.regmap[X86_RECORD_R8_REGNUM])
+ {
+ /* REX */
+ rex = 1;
+ rex_w = (tmpu8 >> 3) & 1;
+ rex_r = (tmpu8 & 0x4) << 1;
+ ir.rex_x = (tmpu8 & 0x2) << 2;
+ ir.rex_b = (tmpu8 & 0x1) << 3;
+ }
+ break;
default:
goto out_prefixes;
break;
}
}
out_prefixes:
- if (prefixes & PREFIX_DATA)
- ir.dflag ^= 1;
+ if (ir.regmap[X86_RECORD_R8_REGNUM] && rex_w == 1)
+ {
+ ir.dflag = 2;
+ }
+ else
+ {
+ if (prefixes & PREFIX_DATA)
+ ir.dflag ^= 1;
+ }
if (prefixes & PREFIX_ADDR)
ir.aflag ^= 1;
+ else if (ir.regmap[X86_RECORD_R8_REGNUM])
+ ir.aflag = 2;

/* now check op code */
opcode = (uint32_t) tmpu8;
@@ -3311,30 +3416,28 @@ reswitch:
}
else
{
- if (ir.ot == OT_BYTE)
+ ir.rm |= ir.rex_b;
+ if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
ir.rm &= 0x3;
- if (record_arch_list_add_reg (ir.regcache, ir.rm))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
}
break;
/* OP Gv, Ev */
case 1:
if (i386_record_modrm (&ir))
return -1;
- if (ir.ot == OT_BYTE)
+ ir.reg |= rex_r;
+ if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
ir.reg &= 0x3;
- if (record_arch_list_add_reg (ir.regcache, ir.reg))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
break;
/* OP A, Iv */
case 2:
- if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
break;
}
}
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* GRP1 */
@@ -3354,17 +3457,17 @@ reswitch:

if (ir.mod != 3)
{
+ if (opcode == 0x83)
+ ir.rip_offset = 1;
+ else
+ ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
if (i386_record_lea_modrm (&ir))
return -1;
}
else
- {
- if (record_arch_list_add_reg (ir.regcache, ir.rm))
- return -1;
- }
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
}
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* inv */
@@ -3385,10 +3488,8 @@ reswitch:
case 0x4d:
case 0x4e:
case 0x4f:
- if (record_arch_list_add_reg (ir.regcache, opcode & 7))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (opcode & 7);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* GRP3 */
@@ -3401,28 +3502,17 @@ reswitch:
if (i386_record_modrm (&ir))
return -1;

+ if (ir.mod != 3 && ir.reg == 0)
+ ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
+
switch (ir.reg)
{
/* test */
case 0:
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;
/* not */
case 2:
- if (ir.mod != 3)
- {
- if (i386_record_lea_modrm (&ir))
- return -1;
- }
- else
- {
- if (ir.ot == OT_BYTE)
- ir.rm &= 0x3;
- if (record_arch_list_add_reg (ir.regcache, ir.rm))
- return -1;
- }
- break;
/* neg */
case 3:
if (ir.mod != 3)
@@ -3432,13 +3522,14 @@ reswitch:
}
else
{
- if (ir.ot == OT_BYTE)
+ ir.rm |= ir.rex_b;
+ if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
ir.rm &= 0x3;
- if (record_arch_list_add_reg (ir.regcache, ir.rm))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
}
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ /* neg */
+ if (ir.reg == 3)
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;
/* mul */
case 4:
@@ -3448,15 +3539,10 @@ reswitch:
case 6:
/* idiv */
case 7:
- if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
if (ir.ot != OT_BYTE)
- {
- if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
- return -1;
- }
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;
default:
ir.addr -= 2;
@@ -3470,10 +3556,6 @@ reswitch:
case 0xfe:
/* GRP5 */
case 0xff:
- if ((opcode & 1) == 0)
- ir.ot = OT_BYTE;
- else
- ir.ot = ir.dflag + OT_WORD;
if (i386_record_modrm (&ir))
return -1;
if (ir.reg >= 2 && opcode == 0xfe)
@@ -3482,13 +3564,16 @@ reswitch:
opcode = opcode << 8 | ir.modrm;
goto no_support;
}
-
switch (ir.reg)
{
/* inc */
case 0:
/* dec */
case 1:
+ if ((opcode & 1) == 0)
+ ir.ot = OT_BYTE;
+ else
+ ir.ot = ir.dflag + OT_WORD;
if (ir.mod != 3)
{
if (i386_record_lea_modrm (&ir))
@@ -3496,42 +3581,40 @@ reswitch:
}
else
{
- if (ir.ot == OT_BYTE)
+ ir.rm |= ir.rex_b;
+ if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
ir.rm &= 0x3;
- if (record_arch_list_add_reg (ir.regcache, ir.rm))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
}
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;
/* call */
case 2:
- /* push */
- case 6:
- if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
- return -1;
- regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
- (gdb_byte *) & tmpu32);
- if (record_arch_list_add_mem
- ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
+ if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+ ir.dflag = 2;
+ if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;
/* lcall */
case 3:
- if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
- return -1;
- regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
- (gdb_byte *) & tmpu32);
- if (record_arch_list_add_mem
- ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 2)), (1 << (ir.dflag + 2))))
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_CS_REGNUM);
+ if (i386_record_push (&ir, 1 << (ir.dflag + 2)))
return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;
/* jmp */
case 4:
/* ljmp */
case 5:
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+ break;
+ /* push */
+ case 6:
+ if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+ ir.dflag = 2;
+ if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+ return -1;
break;
default:
ir.addr -= 2;
@@ -3546,22 +3629,18 @@ reswitch:
case 0x85:
case 0xa8:
case 0xa9:
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* CWDE/CBW */
case 0x98:
- if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
break;

/* CDQ/CWD */
case 0x99:
- if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM);
break;

/* imul */
@@ -3571,12 +3650,15 @@ reswitch:
ir.ot = ir.dflag + OT_WORD;
if (i386_record_modrm (&ir))
return -1;
- if (ir.ot == OT_BYTE)
+ if (opcode == 0x69)
+ ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
+ else if (opcode == 0x6b)
+ ir.rip_offset = 1;
+ ir.reg |= rex_r;
+ if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
ir.reg &= 0x3;
- if (record_arch_list_add_reg (ir.regcache, ir.reg))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* xadd */
@@ -3588,28 +3670,25 @@ reswitch:
ir.ot = ir.dflag + OT_WORD;
if (i386_record_modrm (&ir))
return -1;
+ ir.reg |= rex_r;
if (ir.mod == 3)
{
- if (ir.ot == OT_BYTE)
+ if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
ir.reg &= 0x3;
- if (record_arch_list_add_reg (ir.regcache, ir.reg))
- return -1;
- if (ir.ot == OT_BYTE)
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
+ if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
ir.rm &= 0x3;
- if (record_arch_list_add_reg (ir.regcache, ir.rm))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
}
else
{
if (i386_record_lea_modrm (&ir))
return -1;
- if (ir.ot == OT_BYTE)
+ if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
ir.reg &= 0x3;
- if (record_arch_list_add_reg (ir.regcache, ir.reg))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
}
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* cmpxchg */
@@ -3623,22 +3702,19 @@ reswitch:
return -1;
if (ir.mod == 3)
{
- if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
- return -1;
- if (ir.ot == OT_BYTE)
+ ir.reg |= rex_r;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+ if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
ir.reg &= 0x3;
- if (record_arch_list_add_reg (ir.regcache, ir.reg))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
}
else
{
- if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
if (i386_record_lea_modrm (&ir))
return -1;
}
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* cmpxchg8b */
@@ -3651,14 +3727,11 @@ reswitch:
opcode = opcode << 8 | ir.modrm;
goto no_support;
}
- if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM);
if (i386_record_lea_modrm (&ir))
return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* push */
@@ -3672,6 +3745,12 @@ reswitch:
case 0x57:
case 0x68:
case 0x6a:
+ if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+ ir.dflag = 2;
+ if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+ return -1;
+ break;
+
/* push es */
case 0x06:
/* push cs */
@@ -3680,16 +3759,36 @@ reswitch:
case 0x16:
/* push ds */
case 0x1e:
+ if (ir.regmap[X86_RECORD_R8_REGNUM])
+ {
+ ir.addr -= 1;
+ goto no_support;
+ }
+ if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+ return -1;
+ break;
+
/* push fs */
case 0x0fa0:
/* push gs */
case 0x0fa8:
- if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
+ if (ir.regmap[X86_RECORD_R8_REGNUM])
+ {
+ ir.addr -= 2;
+ goto no_support;
+ }
+ if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
return -1;
- regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
- (gdb_byte *) & tmpu32);
- if (record_arch_list_add_mem
- ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
+ break;
+
+ /* pusha */
+ case 0x60:
+ if (ir.regmap[X86_RECORD_R8_REGNUM])
+ {
+ ir.addr -= 1;
+ goto no_support;
+ }
+ if (i386_record_push (&ir, 1 << (ir.dflag + 4)))
return -1;
break;

@@ -3702,113 +3801,103 @@ reswitch:
case 0x5d:
case 0x5e:
case 0x5f:
- ir.ot = ir.dflag + OT_WORD;
- if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
- return -1;
- if (ir.ot == OT_BYTE)
- opcode &= 0x3;
- if (record_arch_list_add_reg (ir.regcache, opcode & 0x7))
- return -1;
- break;
-
- /* pusha */
- case 0x60:
- if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
- return -1;
- regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
- (gdb_byte *) & tmpu32);
- if (record_arch_list_add_mem
- ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 4)), (1 << (ir.dflag + 4))))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG ((opcode & 0x7) | ir.rex_b);
break;

/* popa */
case 0x61:
- for (tmpu8 = I386_EAX_REGNUM; tmpu8 <= I386_EDI_REGNUM; tmpu8++)
- {
- if (record_arch_list_add_reg (ir.regcache, tmpu8))
- return -1;
+ if (ir.regmap[X86_RECORD_R8_REGNUM])
+ {
+ ir.addr -= 1;
+ goto no_support;
}
+ for (tmpu8 = X86_RECORD_REAX_REGNUM; tmpu8 <= X86_RECORD_REDI_REGNUM;
+ tmpu8++)
+ I386_RECORD_ARCH_LIST_ADD_REG (tmpu8);
break;

/* pop */
case 0x8f:
- ir.ot = ir.dflag + OT_WORD;
+ if (ir.regmap[X86_RECORD_R8_REGNUM])
+ ir.ot = ir.dflag ? OT_QUAD : OT_WORD;
+ else
+ ir.ot = ir.dflag + OT_WORD;
if (i386_record_modrm (&ir))
return -1;
if (ir.mod == 3)
- {
- if (record_arch_list_add_reg (ir.regcache, ir.rm))
- return -1;
- }
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
else
{
if (i386_record_lea_modrm (&ir))
return -1;
}
- if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
break;

/* enter */
case 0xc8:
- if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_EBP_REGNUM))
- return -1;
- regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
- (gdb_byte *) & tmpu32);
- if (record_arch_list_add_mem
- ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REBP_REGNUM);
+ if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+ ir.dflag = 2;
+ if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
return -1;
break;

/* leave */
case 0xc9:
- if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_EBP_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REBP_REGNUM);
break;

/* pop es */
case 0x07:
- if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_ES_REGNUM))
- return -1;
+ if (ir.regmap[X86_RECORD_R8_REGNUM])
+ {
+ ir.addr -= 1;
+ goto no_support;
+ }
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_ES_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* pop ss */
case 0x17:
- if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_SS_REGNUM))
- return -1;
+ if (ir.regmap[X86_RECORD_R8_REGNUM])
+ {
+ ir.addr -= 1;
+ goto no_support;
+ }
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_SS_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* pop ds */
case 0x1f:
- if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_DS_REGNUM))
- return -1;
+ if (ir.regmap[X86_RECORD_R8_REGNUM])
+ {
+ ir.addr -= 1;
+ goto no_support;
+ }
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_DS_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* pop fs */
case 0x0fa1:
- if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_FS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_FS_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* pop gs */
case 0x0fa9:
- if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_GS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_GS_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* mov */
@@ -3826,19 +3915,21 @@ reswitch:

if (ir.mod != 3)
{
+ if (opcode == 0xc6 || opcode == 0xc7)
+ ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
if (i386_record_lea_modrm (&ir))
return -1;
}
else
{
- if (ir.ot == OT_BYTE)
+ if (opcode == 0xc6 || opcode == 0xc7)
+ ir.rm |= ir.rex_b;
+ if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
ir.rm &= 0x3;
- if (record_arch_list_add_reg (ir.regcache, ir.rm))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
}
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
break;
+
/* mov */
case 0x8a:
case 0x8b:
@@ -3846,40 +3937,55 @@ reswitch:
ir.ot = OT_BYTE;
else
ir.ot = ir.dflag + OT_WORD;
-
if (i386_record_modrm (&ir))
return -1;
-
- if (ir.ot == OT_BYTE)
+ ir.reg |= rex_r;
+ if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
ir.reg &= 0x3;
- if (record_arch_list_add_reg (ir.regcache, ir.reg))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
+ break;

- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
+ /* mov seg */
+ case 0x8c:
+ if (i386_record_modrm (&ir))
return -1;
+ if (ir.reg > 5)
+ {
+ ir.addr -= 2;
+ opcode = opcode << 8 | ir.modrm;
+ goto no_support;
+ }
+
+ if (ir.mod == 3)
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
+ else
+ {
+ ir.ot = OT_WORD;
+ if (i386_record_lea_modrm (&ir))
+ return -1;
+ }
break;

/* mov seg */
case 0x8e:
if (i386_record_modrm (&ir))
return -1;
-
switch (ir.reg)
{
case 0:
- tmpu8 = I386_ES_REGNUM;
+ tmpu8 = X86_RECORD_ES_REGNUM;
break;
case 2:
- tmpu8 = I386_SS_REGNUM;
+ tmpu8 = X86_RECORD_SS_REGNUM;
break;
case 3:
- tmpu8 = I386_DS_REGNUM;
+ tmpu8 = X86_RECORD_DS_REGNUM;
break;
case 4:
- tmpu8 = I386_FS_REGNUM;
+ tmpu8 = X86_RECORD_FS_REGNUM;
break;
case 5:
- tmpu8 = I386_GS_REGNUM;
+ tmpu8 = X86_RECORD_GS_REGNUM;
break;
default:
ir.addr -= 2;
@@ -3887,38 +3993,8 @@ reswitch:
goto no_support;
break;
}
- if (record_arch_list_add_reg (ir.regcache, tmpu8))
- return -1;
-
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
- break;
-
- /* mov seg */
- case 0x8c:
- if (i386_record_modrm (&ir))
- return -1;
- if (ir.reg > 5)
- {
- ir.addr -= 2;
- opcode = opcode << 8 | ir.modrm;
- goto no_support;
- }
-
- if (ir.mod == 3)
- {
- if (record_arch_list_add_reg (ir.regcache, ir.rm))
- return -1;
- }
- else
- {
- ir.ot = OT_WORD;
- if (i386_record_lea_modrm (&ir))
- return -1;
- }
-
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (tmpu8);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* movzbS */
@@ -3931,8 +4007,7 @@ reswitch:
case 0x0fbf:
if (i386_record_modrm (&ir))
return -1;
- if (record_arch_list_add_reg (ir.regcache, ir.reg))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
break;

/* lea */
@@ -3945,12 +4020,11 @@ reswitch:
opcode = opcode << 8 | ir.modrm;
goto no_support;
}
-
ir.ot = ir.dflag;
- if (ir.ot == OT_BYTE)
+ ir.reg |= rex_r;
+ if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
ir.reg &= 0x3;
- if (record_arch_list_add_reg (ir.regcache, ir.reg))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
break;

/* mov EAX */
@@ -3958,62 +4032,68 @@ reswitch:
case 0xa1:
/* xlat */
case 0xd7:
- if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
break;

/* mov EAX */
case 0xa2:
case 0xa3:
- {
- uint32_t addr;
-
- if (ir.override)
- {
- if (record_debug)
- printf_unfiltered (_("Process record ignores the memory change "
- "of instruction at address %s because "
- "it can't get the value of the segment "
- "register.\n"),
- paddress (gdbarch, ir.addr));
- }
- else
- {
- if ((opcode & 1) == 0)
- ir.ot = OT_BYTE;
- else
- ir.ot = ir.dflag + OT_WORD;
- if (ir.aflag)
- {
- if (target_read_memory
- (ir.addr, (gdb_byte *) & addr, 4))
- {
- if (record_debug)
- printf_unfiltered (_("Process record: error reading "
- "memory at addr %s len = 4.\n"),
- paddress (gdbarch, ir.addr));
- return -1;
- }
- ir.addr += 4;
- }
- else
- {
- if (target_read_memory
- (ir.addr, (gdb_byte *) & tmpu16, 4))
- {
- if (record_debug)
- printf_unfiltered (_("Process record: error reading "
- "memory at addr %s len = 4.\n"),
- paddress (gdbarch, ir.addr));
- return -1;
- }
- ir.addr += 2;
- addr = tmpu16;
- }
- if (record_arch_list_add_mem (addr, 1 << ir.ot))
- return -1;
- }
- }
+ if (ir.override >= 0)
+ {
+ if (record_debug)
+ printf_unfiltered (_("Process record ignores the memory change "
+ "of instruction at address 0x%s because "
+ "it can't get the value of the segment "
+ "register.\n"),
+ paddress (gdbarch, ir.addr));
+ }
+ else
+ {
+ if ((opcode & 1) == 0)
+ ir.ot = OT_BYTE;
+ else
+ ir.ot = ir.dflag + OT_WORD;
+ if (ir.aflag == 2)
+ {
+ if (target_read_memory (ir.addr, (gdb_byte *) &addr, 8))
+ {
+ if (record_debug)
+ printf_unfiltered (_("Process record: error reading "
+ "memory at addr 0x%s len = 8.\n"),
+ paddress (gdbarch, ir.addr));
+ return -1;
+ }
+ ir.addr += 8;
+ }
+ else if (ir.aflag)
+ {
+ if (target_read_memory (ir.addr, (gdb_byte *) &tmpu32, 4))
+ {
+ if (record_debug)
+ printf_unfiltered (_("Process record: error reading "
+ "memory at addr 0x%s len = 4.\n"),
+ paddress (gdbarch, ir.addr));
+ return -1;
+ }
+ ir.addr += 4;
+ addr = tmpu32;
+ }
+ else
+ {
+ if (target_read_memory (ir.addr, (gdb_byte *) &tmpu16, 2))
+ {
+ if (record_debug)
+ printf_unfiltered (_("Process record: error reading "
+ "memory at addr 0x%s len = 2.\n"),
+ paddress (gdbarch, ir.addr));
+ return -1;
+ }
+ ir.addr += 2;
+ addr = tmpu16;
+ }
+ if (record_arch_list_add_mem (addr, 1 << ir.ot))
+ return -1;
+ }
break;

/* mov R, Ib */
@@ -4025,8 +4105,9 @@ reswitch:
case 0xb5:
case 0xb6:
case 0xb7:
- if (record_arch_list_add_reg (ir.regcache, (opcode & 0x7) & 0x3))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG ((ir.regmap[X86_RECORD_R8_REGNUM]) ?
+ ((opcode & 0x7) | ir.rex_b) :
+ ((opcode & 0x7) & 0x3));
break;

/* mov R, Iv */
@@ -4038,8 +4119,7 @@ reswitch:
case 0xbd:
case 0xbe:
case 0xbf:
- if (record_arch_list_add_reg (ir.regcache, opcode & 0x7))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG ((opcode & 0x7) | ir.rex_b);
break;

/* xchg R, EAX */
@@ -4050,10 +4130,8 @@ reswitch:
case 0x95:
case 0x96:
case 0x97:
- if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, opcode & 0x7))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (opcode & 0x7);
break;

/* xchg Ev, Gv */
@@ -4063,33 +4141,35 @@ reswitch:
ir.ot = OT_BYTE;
else
ir.ot = ir.dflag + OT_WORD;
-
if (i386_record_modrm (&ir))
return -1;
-
if (ir.mod == 3)
{
- if (ir.ot == OT_BYTE)
+ ir.rm != ir.rex_b;
+ if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
ir.rm &= 0x3;
- if (record_arch_list_add_reg (ir.regcache, ir.rm))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
}
else
{
if (i386_record_lea_modrm (&ir))
return -1;
}
-
- if (ir.ot == OT_BYTE)
+ ir.reg |= rex_r;
+ if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
ir.reg &= 0x3;
- if (record_arch_list_add_reg (ir.regcache, ir.reg))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
break;

/* les Gv */
case 0xc4:
/* lds Gv */
case 0xc5:
+ if (ir.regmap[X86_RECORD_R8_REGNUM])
+ {
+ ir.addr -= 1;
+ goto no_support;
+ }
/* lss Gv */
case 0x0fb2:
/* lfs Gv */
@@ -4107,35 +4187,32 @@ reswitch:
opcode = opcode << 8 | ir.modrm;
goto no_support;
}
-
switch (opcode)
{
/* les Gv */
case 0xc4:
- tmpu8 = I386_ES_REGNUM;
+ tmpu8 = X86_RECORD_ES_REGNUM;
break;
/* lds Gv */
case 0xc5:
- tmpu8 = I386_DS_REGNUM;
+ tmpu8 = X86_RECORD_DS_REGNUM;
break;
/* lss Gv */
case 0x0fb2:
- tmpu8 = I386_SS_REGNUM;
+ tmpu8 = X86_RECORD_SS_REGNUM;
break;
/* lfs Gv */
case 0x0fb4:
- tmpu8 = I386_FS_REGNUM;
+ tmpu8 = X86_RECORD_FS_REGNUM;
break;
/* lgs Gv */
case 0x0fb5:
- tmpu8 = I386_GS_REGNUM;
+ tmpu8 = X86_RECORD_GS_REGNUM;
break;
}
- if (record_arch_list_add_reg (ir.regcache, tmpu8))
- return -1;
-
- if (record_arch_list_add_reg (ir.regcache, ir.reg))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (tmpu8);
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* shifts */
@@ -4149,10 +4226,8 @@ reswitch:
ir.ot = OT_BYTE;
else
ir.ot = ir.dflag + OT_WORD;
-
if (i386_record_modrm (&ir))
return -1;
-
if (ir.mod != 3 && (opcode == 0xd2 || opcode == 0xd3))
{
if (i386_record_lea_modrm (&ir))
@@ -4160,14 +4235,12 @@ reswitch:
}
else
{
- if (ir.ot == OT_BYTE)
+ ir.rm |= ir.rex_b;
+ if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
ir.rm &= 0x3;
- if (record_arch_list_add_reg (ir.regcache, ir.rm))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
}
-
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

case 0x0fa4:
@@ -4204,9 +4277,9 @@ reswitch:
if (ir.mod != 3)
{
/* memory */
- uint32_t addr;
+ uint64_t tmpu64;

- if (i386_record_lea_modrm_addr (&ir, &addr))
+ if (i386_record_lea_modrm_addr (&ir, &tmpu64))
return -1;
switch (ir.reg)
{
@@ -4266,16 +4339,16 @@ reswitch:
switch (ir.reg >> 4)
{
case 0:
- if (record_arch_list_add_mem (addr, 4))
+ if (record_arch_list_add_mem (tmpu64, 4))
return -1;
break;
case 2:
- if (record_arch_list_add_mem (addr, 8))
+ if (record_arch_list_add_mem (tmpu64, 8))
return -1;
break;
case 3:
default:
- if (record_arch_list_add_mem (addr, 2))
+ if (record_arch_list_add_mem (tmpu64, 2))
return -1;
break;
}
@@ -4285,16 +4358,16 @@ reswitch:
{
case 0:
case 1:
- if (record_arch_list_add_mem (addr, 4))
+ if (record_arch_list_add_mem (tmpu64, 4))
return -1;
break;
case 2:
- if (record_arch_list_add_mem (addr, 8))
+ if (record_arch_list_add_mem (tmpu64, 8))
return -1;
break;
case 3:
default:
- if (record_arch_list_add_mem (addr, 2))
+ if (record_arch_list_add_mem (tmpu64, 2))
return -1;
break;
}
@@ -4311,43 +4384,43 @@ reswitch:
case 0x0e:
if (ir.dflag)
{
- if (record_arch_list_add_mem (addr, 28))
+ if (record_arch_list_add_mem (tmpu64, 28))
return -1;
}
else
{
- if (record_arch_list_add_mem (addr, 14))
+ if (record_arch_list_add_mem (tmpu64, 14))
return -1;
}
break;
case 0x0f:
case 0x2f:
- if (record_arch_list_add_mem (addr, 2))
+ if (record_arch_list_add_mem (tmpu64, 2))
return -1;
break;
case 0x1f:
case 0x3e:
- if (record_arch_list_add_mem (addr, 10))
+ if (record_arch_list_add_mem (tmpu64, 10))
return -1;
break;
case 0x2e:
if (ir.dflag)
{
- if (record_arch_list_add_mem (addr, 28))
+ if (record_arch_list_add_mem (tmpu64, 28))
return -1;
- addr += 28;
+ tmpu64 += 28;
}
else
{
- if (record_arch_list_add_mem (addr, 14))
+ if (record_arch_list_add_mem (tmpu64, 14))
return -1;
- addr += 14;
+ tmpu64 += 14;
}
- if (record_arch_list_add_mem (addr, 80))
+ if (record_arch_list_add_mem (tmpu64, 80))
return -1;
break;
case 0x3f:
- if (record_arch_list_add_mem (addr, 8))
+ if (record_arch_list_add_mem (tmpu64, 8))
return -1;
break;
default:
@@ -4369,123 +4442,88 @@ reswitch:
/* insS */
case 0x6c:
case 0x6d:
- {
- uint32_t addr;
-
- if ((opcode & 1) == 0)
- ir.ot = OT_BYTE;
- else
- ir.ot = ir.dflag + OT_WORD;
- if (opcode == 0xa4 || opcode == 0xa5)
- {
- if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
- return -1;
- }
- if (record_arch_list_add_reg (ir.regcache, I386_EDI_REGNUM))
- return -1;
-
- regcache_raw_read (ir.regcache, I386_EDI_REGNUM,
- (gdb_byte *) & addr);
- if (!ir.aflag)
- {
- addr &= 0xffff;
- /* addr += ((uint32_t)read_register (I386_ES_REGNUM)) << 4; */
- if (record_debug)
- printf_unfiltered (_("Process record ignores the memory change "
- "of instruction at address %s because "
- "it can't get the value of the segment "
- "register.\n"),
- paddress (gdbarch, ir.addr));
- }
-
- if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
- {
- uint32_t count;
-
- regcache_raw_read (ir.regcache, I386_ECX_REGNUM,
- (gdb_byte *) & count);
- if (!ir.aflag)
- count &= 0xffff;
-
- regcache_raw_read (ir.regcache, I386_EFLAGS_REGNUM,
- (gdb_byte *) & tmpu32);
- if ((tmpu32 >> 10) & 0x1)
- addr -= (count - 1) * (1 << ir.ot);
-
- if (ir.aflag)
- {
- if (record_arch_list_add_mem (addr, count * (1 << ir.ot)))
- return -1;
- }
+ if ((opcode & 1) == 0)
+ ir.ot = OT_BYTE;
+ else
+ ir.ot = ir.dflag + OT_WORD;
+ regcache_raw_read_unsigned (ir.regcache,
+ ir.regmap[X86_RECORD_REDI_REGNUM],
+ &tmpulongest);
+ if (!ir.aflag)
+ {
+ tmpulongest &= 0xffff;
+ /* addr += ((uint32_t) read_register (I386_ES_REGNUM)) << 4; */
+ if (record_debug)
+ printf_unfiltered (_("Process record ignores the memory change "
+ "of instruction at address 0x%s because "
+ "it can't get the value of the segment "
+ "register.\n"),
+ paddress (gdbarch, ir.addr));
+ }
+ if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
+ {
+ ULONGEST count, eflags;
+ regcache_raw_read_unsigned (ir.regcache,
+ ir.regmap[X86_RECORD_REDI_REGNUM],
+ &count);
+ if (!ir.aflag)
+ count &= 0xffff;
+ regcache_raw_read_unsigned (ir.regcache,
+ ir.regmap[X86_RECORD_EFLAGS_REGNUM],
+ &eflags);
+ if ((eflags >> 10) & 0x1)
+ tmpulongest -= (count - 1) * (1 << ir.ot);
+ if (record_arch_list_add_mem (tmpulongest, count * (1 << ir.ot)))
+ return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+ }
+ else
+ {
+ if (record_arch_list_add_mem (tmpulongest, 1 << ir.ot))
+ return -1;
+ }
+ if (opcode == 0xa4 || opcode == 0xa5)
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDI_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+ break;

- if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
- return -1;
- }
- else
- {
- if (ir.aflag)
- {
- if (record_arch_list_add_mem (addr, 1 << ir.ot))
- return -1;
- }
- }
- }
+ /* cmpsS */
+ case 0xa6:
+ case 0xa7:
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDI_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
+ if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* lodsS */
case 0xac:
case 0xad:
- if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
- return -1;
- if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
- {
- if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
- return -1;
- }
- break;
-
- /* outsS */
- case 0x6e:
- case 0x6f:
- if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
- {
- if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
- return -1;
- }
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* scasS */
case 0xae:
case 0xaf:
- if (record_arch_list_add_reg (ir.regcache, I386_EDI_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDI_REGNUM);
if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
- {
- if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
- return -1;
- }
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

- /* cmpsS */
- case 0xa6:
- case 0xa7:
- if (record_arch_list_add_reg (ir.regcache, I386_EDI_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
- return -1;
+ /* outsS */
+ case 0x6e:
+ case 0x6f:
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
- {
- if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
- return -1;
- }
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* port I/O */
@@ -4493,8 +4531,8 @@ reswitch:
case 0xe5:
case 0xec:
case 0xed:
- if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
break;

case 0xe6:
@@ -4508,48 +4546,32 @@ reswitch:
case 0xc2:
/* ret */
case 0xc3:
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+ break;
+
/* lret im */
case 0xca:
/* lret */
case 0xcb:
- if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
- return -1;
- break;
-
/* iret */
case 0xcf:
- if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_CS_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* call im */
case 0xe8:
- if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
- return -1;
- regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
- (gdb_byte *) & tmpu32);
- if (record_arch_list_add_mem
- ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
- return -1;
+ if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+ return -1;
break;

/* lcall im */
case 0x9a:
- if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
- return -1;
- regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
- (gdb_byte *) & tmpu32);
- if (record_arch_list_add_mem
- ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 2)), (1 << (ir.dflag + 2))))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_CS_REGNUM);
+ if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+ return -1;
break;

/* jmp im */
@@ -4611,14 +4633,13 @@ reswitch:
case 0x0f9d:
case 0x0f9e:
case 0x0f9f:
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
ir.ot = OT_BYTE;
if (i386_record_modrm (&ir))
return -1;
if (ir.mod == 3)
- {
- if (record_arch_list_add_reg (ir.regcache, ir.rm & 0x3))
- return -1;
- }
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.rex_b ? (ir.rm | ir.rex_b):
+ (ir.rm & 0x3));
else
{
if (i386_record_lea_modrm (&ir))
@@ -4645,34 +4666,33 @@ reswitch:
case 0x0f4f:
if (i386_record_modrm (&ir))
return -1;
+ ir.reg |= rex_r;
if (ir.dflag == OT_BYTE)
ir.reg &= 0x3;
- if (record_arch_list_add_reg (ir.regcache, ir.reg & 0x3))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
break;

/* flags */
/* pushf */
case 0x9c:
- if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
- return -1;
- regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
- (gdb_byte *) & tmpu32);
- if (record_arch_list_add_mem
- ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+ if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+ return -1;
break;

/* popf */
case 0x9d:
- if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* sahf */
case 0x9e:
+ if (ir.regmap[X86_RECORD_R8_REGNUM])
+ {
+ ir.addr -= 1;
+ goto no_support;
+ }
/* cmc */
case 0xf5:
/* clc */
@@ -4683,66 +4703,95 @@ reswitch:
case 0xfc:
/* std */
case 0xfd:
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* lahf */
case 0x9f:
- if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
- return -1;
+ if (ir.regmap[X86_RECORD_R8_REGNUM])
+ {
+ ir.addr -= 1;
+ goto no_support;
+ }
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
break;

/* bit operations */
/* bt/bts/btr/btc Gv, im */
case 0x0fba:
- /* bts */
- case 0x0fab:
- /* btr */
- case 0x0fb3:
- /* btc */
- case 0x0fbb:
ir.ot = ir.dflag + OT_WORD;
if (i386_record_modrm (&ir))
return -1;
if (ir.reg < 4)
{
- ir.addr -= 3;
+ ir.addr -= 2;
opcode = opcode << 8 | ir.modrm;
goto no_support;
}
- ir.reg -= 4;
- if (ir.reg != 0)
+ if (ir.reg != 4)
{
- if (ir.mod != 3)
- {
- if (i386_record_lea_modrm (&ir))
- return -1;
- }
+ if (ir.mod == 3)
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
else
{
- if (record_arch_list_add_reg (ir.regcache, ir.rm))
+ if (i386_record_lea_modrm (&ir))
return -1;
}
}
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* bt Gv, Ev */
case 0x0fa3:
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+ break;
+
+ /* bts */
+ case 0x0fab:
+ /* btr */
+ case 0x0fb3:
+ /* btc */
+ case 0x0fbb:
+ ir.ot = ir.dflag + OT_WORD;
+ if (i386_record_modrm (&ir))
+ return -1;
+ if (ir.mod == 3)
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
+ else
+ {
+ uint64_t tmpu64;
+ if (i386_record_lea_modrm_addr (&ir, &tmpu64))
+ return -1;
+ regcache_raw_read_unsigned (ir.regcache,
+ ir.regmap[ir.reg | rex_r],
+ &tmpulongest);
+ switch (ir.dflag)
+ {
+ case 0:
+ tmpu64 += ((int16_t) tmpulongest >> 4) << 4;
+ break;
+ case 1:
+ tmpu64 += ((int32_t) tmpulongest >> 5) << 5;
+ break;
+ case 2:
+ tmpu64 += ((int64_t) tmpulongest >> 6) << 6;
+ break;
+ }
+ if (record_arch_list_add_mem (tmpu64, 1 << ir.ot))
+ return -1;
+ if (i386_record_lea_modrm (&ir))
+ return -1;
+ }
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* bsf */
case 0x0fbc:
/* bsr */
case 0x0fbd:
- if (record_arch_list_add_reg (ir.regcache, ir.reg))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* bcd */
@@ -4758,10 +4807,13 @@ reswitch:
case 0xd4:
/* aad */
case 0xd5:
- if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ if (ir.regmap[X86_RECORD_R8_REGNUM])
+ {
+ ir.addr -= 1;
+ goto no_support;
+ }
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* misc */
@@ -4853,16 +4905,18 @@ reswitch:
case 0x0fcd:
case 0x0fce:
case 0x0fcf:
- if (record_arch_list_add_reg (ir.regcache, opcode & 7))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG ((opcode & 7) | ir.rex_b);
break;

/* salc */
case 0xd6:
- if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ if (ir.regmap[X86_RECORD_R8_REGNUM])
+ {
+ ir.addr -= 1;
+ goto no_support;
+ }
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* loopnz */
@@ -4873,8 +4927,8 @@ reswitch:
case 0xe2:
/* jecxz */
case 0xe3:
- if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* wrmsr */
@@ -4905,6 +4959,11 @@ reswitch:
case 0x0f34:
{
int ret;
+ if (ir.regmap[X86_RECORD_R8_REGNUM])
+ {
+ ir.addr -= 2;
+ goto no_support;
+ }
if (gdbarch_tdep (gdbarch)->i386_sysenter_record == NULL)
{
printf_unfiltered (_("Process record doesn't support "
@@ -4926,16 +4985,37 @@ reswitch:
goto no_support;
break;

+ /* syscall */
+ case 0x0f05:
+ {
+ int ret;
+ if (gdbarch_tdep (gdbarch)->i386_syscall_record == NULL)
+ {
+ printf_unfiltered (_("Process record doesn't support "
+ "instruction syscall.\n"));
+ ir.addr -= 2;
+ goto no_support;
+ }
+ ret = gdbarch_tdep (gdbarch)->i386_syscall_record (ir.regcache);
+ if (ret)
+ return ret;
+ }
+ break;
+
+ /* sysret */
+ case 0x0f07:
+ printf_unfiltered (_("Process record doesn't support "
+ "instruction sysret.\n"));
+ ir.addr -= 2;
+ goto no_support;
+ break;
+
/* cpuid */
case 0x0fa2:
- if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_EBX_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REBX_REGNUM);
break;

/* hlt */
@@ -4956,10 +5036,7 @@ reswitch:
/* str */
case 1:
if (ir.mod == 3)
- {
- if (record_arch_list_add_reg (ir.regcache, ir.rm))
- return -1;
- }
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
else
{
ir.ot = OT_WORD;
@@ -4976,8 +5053,7 @@ reswitch:
case 4:
/* verw */
case 5:
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;
default:
ir.addr -= 3;
@@ -4995,7 +5071,7 @@ reswitch:
/* sgdt */
case 0:
{
- uint32_t addr;
+ uint64_t tmpu64;

if (ir.mod == 3)
{
@@ -5003,8 +5079,7 @@ reswitch:
opcode = opcode << 8 | ir.modrm;
goto no_support;
}
-
- if (ir.override)
+ if (ir.override >= 0)
{
if (record_debug)
printf_unfiltered (_("Process record ignores the memory "
@@ -5016,13 +5091,21 @@ reswitch:
}
else
{
- if (i386_record_lea_modrm_addr (&ir, &addr))
- return -1;
- if (record_arch_list_add_mem (addr, 2))
+ if (i386_record_lea_modrm_addr (&ir, &tmpu64))
return -1;
- addr += 2;
- if (record_arch_list_add_mem (addr, 4))
+ if (record_arch_list_add_mem (tmpu64, 2))
return -1;
+ tmpu64 += 2;
+ if (ir.regmap[X86_RECORD_R8_REGNUM])
+ {
+ if (record_arch_list_add_mem (tmpu64, 8))
+ return -1;
+ }
+ else
+ {
+ if (record_arch_list_add_mem (tmpu64, 4))
+ return -1;
+ }
}
}
break;
@@ -5036,8 +5119,7 @@ reswitch:
break;
/* mwait */
case 1:
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;
default:
ir.addr -= 3;
@@ -5049,7 +5131,7 @@ reswitch:
else
{
/* sidt */
- if (ir.override)
+ if (ir.override >= 0)
{
if (record_debug)
printf_unfiltered (_("Process record ignores the memory "
@@ -5061,15 +5143,23 @@ reswitch:
}
else
{
- uint32_t addr;
+ uint64_t tmpu64;

- if (i386_record_lea_modrm_addr (&ir, &addr))
+ if (i386_record_lea_modrm_addr (&ir, &tmpu64))
return -1;
- if (record_arch_list_add_mem (addr, 2))
+ if (record_arch_list_add_mem (tmpu64, 2))
return -1;
addr += 2;
- if (record_arch_list_add_mem (addr, 4))
- return -1;
+ if (ir.regmap[X86_RECORD_R8_REGNUM])
+ {
+ if (record_arch_list_add_mem (tmpu64, 8))
+ return -1;
+ }
+ else
+ {
+ if (record_arch_list_add_mem (tmpu64, 4))
+ return -1;
+ }
}
}
break;
@@ -5077,9 +5167,6 @@ reswitch:
case 2:
/* lidt */
case 3:
- /* invlpg */
- case 7:
- default:
if (ir.mod == 3)
{
ir.addr -= 3;
@@ -5091,7 +5178,7 @@ reswitch:
case 4:
if (ir.mod == 3)
{
- if (record_arch_list_add_reg (ir.regcache, ir.rm))
+ if (record_arch_list_add_reg (ir.regcache, ir.rm | ir.rex_b))
return -1;
}
else
@@ -5100,9 +5187,32 @@ reswitch:
if (i386_record_lea_modrm (&ir))
return -1;
}
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;
/* lmsw */
case 6:
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+ break;
+ /* invlpg */
+ case 7:
+ if (ir.mod == 3)
+ {
+ if (ir.rm == 0 && ir.regmap[X86_RECORD_R8_REGNUM])
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_GS_REGNUM);
+ else
+ {
+ ir.addr -= 3;
+ opcode = opcode << 8 | ir.modrm;
+ goto no_support;
+ }
+ }
+ else
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+ break;
+ default:
+ ir.addr -= 3;
+ opcode = opcode << 8 | ir.modrm;
+ goto no_support;
break;
}
break;
@@ -5115,21 +5225,21 @@ reswitch:

/* arpl */
case 0x63:
- ir.ot = ir.dflag ? OT_LONG : OT_WORD;
if (i386_record_modrm (&ir))
return -1;
- if (ir.mod != 3)
- {
- if (i386_record_lea_modrm (&ir))
- return -1;
- }
+ if (ir.mod == 3 || ir.regmap[X86_RECORD_R8_REGNUM])
+ {
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.regmap[X86_RECORD_R8_REGNUM]?
+ (ir.reg | rex_r) : ir.rm);
+ }
else
- {
- if (record_arch_list_add_reg (ir.regcache, ir.rm))
- return -1;
- }
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ {
+ ir.ot = ir.dflag ? OT_LONG : OT_WORD;
+ if (i386_record_lea_modrm (&ir))
+ return -1;
+ }
+ if (!ir.regmap[X86_RECORD_R8_REGNUM])
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* lar */
@@ -5138,13 +5248,19 @@ reswitch:
case 0x0f03:
if (i386_record_modrm (&ir))
return -1;
- if (record_arch_list_add_reg (ir.regcache, ir.reg))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

case 0x0f18:
+ if (i386_record_modrm (&ir))
+ return -1;
+ if (ir.mod == 3 && ir.reg == 3)
+ {
+ ir.addr -= 3;
+ opcode = opcode << 8 | ir.modrm;
+ goto no_support;
+ }
break;

/* nop (multi byte) */
@@ -5165,7 +5281,7 @@ reswitch:
return -1;
if ((ir.modrm & 0xc0) != 0xc0)
{
- ir.addr -= 2;
+ ir.addr -= 3;
opcode = opcode << 8 | ir.modrm;
goto no_support;
}
@@ -5177,16 +5293,12 @@ reswitch:
case 4:
case 8:
if (opcode & 2)
- {
- }
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
else
- {
- if (record_arch_list_add_reg (ir.regcache, ir.rm))
- return -1;
- }
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
break;
default:
- ir.addr -= 2;
+ ir.addr -= 3;
opcode = opcode << 8 | ir.modrm;
goto no_support;
break;
@@ -5202,22 +5314,19 @@ reswitch:
if ((ir.modrm & 0xc0) != 0xc0 || ir.reg == 4
|| ir.reg == 5 || ir.reg >= 8)
{
- ir.addr -= 2;
+ ir.addr -= 3;
opcode = opcode << 8 | ir.modrm;
goto no_support;
}
if (opcode & 2)
- {
- }
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
else
- {
- if (record_arch_list_add_reg (ir.regcache, ir.rm))
- return -1;
- }
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
break;

/* clts */
case 0x0f06:
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* MMX/SSE/SSE2/PNI support */
@@ -5232,9 +5341,8 @@ reswitch:
break;
}

-/* In the future, Maybe still need to deal with need_dasm */
- if (record_arch_list_add_reg (ir.regcache, I386_EIP_REGNUM))
- return -1;
+ /* In the future, Maybe still need to deal with need_dasm */
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REIP_REGNUM);
if (record_arch_list_add_end ())
return -1;

@@ -5247,6 +5355,15 @@ no_support:
return -1;
}

+static const int i386_record_regmap[] =
+{
+ I386_EAX_REGNUM, I386_ECX_REGNUM, I386_EDX_REGNUM, I386_EBX_REGNUM,
+ I386_ESP_REGNUM, I386_EBP_REGNUM, I386_ESI_REGNUM, I386_EDI_REGNUM,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ I386_EIP_REGNUM, I386_EFLAGS_REGNUM, I386_CS_REGNUM, I386_SS_REGNUM,
+ I386_DS_REGNUM, I386_ES_REGNUM, I386_FS_REGNUM, I386_GS_REGNUM
+};
+

static struct gdbarch *
i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
@@ -5307,6 +5424,8 @@ i386_gdbarch_init (struct gdbarch_info i
tdep->sc_pc_offset = -1;
tdep->sc_sp_offset = -1;

+ tdep->record_regmap = i386_record_regmap;
+
/* The format used for `long double' on almost all i386 targets is
the i387 extended floating-point format. In fact, of all targets
in the GCC 2.95 tree, only OSF/1 does it different, and insists
--- a/i386-tdep.h
+++ b/i386-tdep.h
@@ -111,10 +111,15 @@ struct gdbarch_tdep
struct type *i387_ext_type;

/* Process record/replay target. */
+ /* The map for registers because the AMD64's registers order
+ in GDB is not same as I386 instructions. */
+ const int *record_regmap;
/* Parse intx80 args. */
int (*i386_intx80_record) (struct regcache *regcache);
/* Parse sysenter args. */
int (*i386_sysenter_record) (struct regcache *regcache);
+ /* Parse syscall args. */
+ int (*i386_syscall_record) (struct regcache *regcache);
};

/* Floating-point registers. */
@@ -151,6 +156,36 @@ enum i386_regnum
I386_ST0_REGNUM /* %st(0) */
};

+/* Register numbers of RECORD_REGMAP. */
+
+enum record_i386_regnum
+{
+ X86_RECORD_REAX_REGNUM,
+ X86_RECORD_RECX_REGNUM,
+ X86_RECORD_REDX_REGNUM,
+ X86_RECORD_REBX_REGNUM,
+ X86_RECORD_RESP_REGNUM,
+ X86_RECORD_REBP_REGNUM,
+ X86_RECORD_RESI_REGNUM,
+ X86_RECORD_REDI_REGNUM,
+ X86_RECORD_R8_REGNUM,
+ X86_RECORD_R9_REGNUM,
+ X86_RECORD_R10_REGNUM,
+ X86_RECORD_R11_REGNUM,
+ X86_RECORD_R12_REGNUM,
+ X86_RECORD_R13_REGNUM,
+ X86_RECORD_R14_REGNUM,
+ X86_RECORD_R15_REGNUM,
+ X86_RECORD_REIP_REGNUM,
+ X86_RECORD_EFLAGS_REGNUM,
+ X86_RECORD_CS_REGNUM,
+ X86_RECORD_SS_REGNUM,
+ X86_RECORD_DS_REGNUM,
+ X86_RECORD_ES_REGNUM,
+ X86_RECORD_FS_REGNUM,
+ X86_RECORD_GS_REGNUM,
+};
+
#define I386_NUM_GREGS 16
#define I386_NUM_FREGS 16
#define I386_NUM_XREGS 9

[-- Attachment #2: prec_amd64_tdep.txt --]
[-- Type: text/plain, Size: 70749 bytes --]

---
amd64-tdep.c | 12
i386-tdep.c | 1437 +++++++++++++++++++++++++++++++----------------------------
i386-tdep.h | 35 +
3 files changed, 825 insertions(+), 659 deletions(-)

--- a/amd64-tdep.c
+++ b/amd64-tdep.c
@@ -1989,6 +1989,16 @@ amd64_get_longjmp_target (struct frame_i
return 1;
}

+static const int amd64_record_regmap[] =
+{
+ AMD64_RAX_REGNUM, AMD64_RCX_REGNUM, AMD64_RDX_REGNUM, AMD64_RBX_REGNUM,
+ AMD64_RSP_REGNUM, AMD64_RBP_REGNUM, AMD64_RSI_REGNUM, AMD64_RDI_REGNUM,
+ AMD64_R8_REGNUM, AMD64_R9_REGNUM, AMD64_R10_REGNUM, AMD64_R11_REGNUM,
+ AMD64_R12_REGNUM, AMD64_R13_REGNUM, AMD64_R14_REGNUM, AMD64_R15_REGNUM,
+ AMD64_RIP_REGNUM, AMD64_EFLAGS_REGNUM, AMD64_CS_REGNUM, AMD64_SS_REGNUM,
+ AMD64_DS_REGNUM, AMD64_ES_REGNUM, AMD64_FS_REGNUM, AMD64_GS_REGNUM
+};
+
void
amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
@@ -2051,6 +2061,8 @@ amd64_init_abi (struct gdbarch_info info
set_gdbarch_num_pseudo_regs (gdbarch, 0);
tdep->mm0_regnum = -1;

+ tdep->record_regmap = amd64_record_regmap;
+
set_gdbarch_dummy_id (gdbarch, amd64_dummy_id);

frame_unwind_append_unwinder (gdbarch, &amd64_sigtramp_frame_unwind);
--- a/i386-tdep.c
+++ b/i386-tdep.c
@@ -2847,6 +2847,7 @@ enum
OT_BYTE = 0,
OT_WORD,
OT_LONG,
+ OT_QUAD,
};

/* i386 arith/logic operations */
@@ -2864,6 +2865,7 @@ enum

struct i386_record_s
{
+ struct gdbarch *gdbarch;
struct regcache *regcache;
CORE_ADDR addr;
int aflag;
@@ -2872,6 +2874,11 @@ struct i386_record_s
uint8_t modrm;
uint8_t mod, reg, rm;
int ot;
+ uint8_t rex_x;
+ uint8_t rex_b;
+ int rip_offset;
+ int popl_esp_hack;
+ const int *regmap;
};

/* Parse "modrm" part in current memory address that irp->addr point to
@@ -2880,7 +2887,7 @@ struct i386_record_s
static int
i386_record_modrm (struct i386_record_s *irp)
{
- struct gdbarch *gdbarch = get_regcache_arch (irp->regcache);
+ struct gdbarch *gdbarch = irp->gdbarch;

if (target_read_memory (irp->addr, &irp->modrm, 1))
{
@@ -2903,12 +2910,13 @@ i386_record_modrm (struct i386_record_s
Return -1 if something wrong. */

static int
-i386_record_lea_modrm_addr (struct i386_record_s *irp, uint32_t * addr)
+i386_record_lea_modrm_addr (struct i386_record_s *irp, uint64_t *addr)
{
- struct gdbarch *gdbarch = get_regcache_arch (irp->regcache);
+ struct gdbarch *gdbarch = irp->gdbarch;
uint8_t tmpu8;
- uint16_t tmpu16;
- uint32_t tmpu32;
+ int16_t tmpi16;
+ int32_t tmpi32;
+ ULONGEST tmpulongest;

*addr = 0;
if (irp->aflag)
@@ -2932,9 +2940,10 @@ i386_record_lea_modrm_addr (struct i386_
}
irp->addr++;
scale = (tmpu8 >> 6) & 3;
- index = ((tmpu8 >> 3) & 7);
+ index = ((tmpu8 >> 3) & 7) | irp->rex_x;
base = (tmpu8 & 7);
}
+ base |= irp->rex_b;

switch (irp->mod)
{
@@ -2942,7 +2951,7 @@ i386_record_lea_modrm_addr (struct i386_
if ((base & 7) == 5)
{
base = 0xff;
- if (target_read_memory (irp->addr, (gdb_byte *) addr, 4))
+ if (target_read_memory (irp->addr, (gdb_byte *) &tmpi32, 4))
{
if (record_debug)
printf_unfiltered (_("Process record: error reading "
@@ -2951,6 +2960,9 @@ i386_record_lea_modrm_addr (struct i386_
return -1;
}
irp->addr += 4;
+ *addr = tmpi32;
+ if (irp->regmap[X86_RECORD_R8_REGNUM] && !havesib)
+ *addr += irp->addr + irp->rip_offset;
}
else
{
@@ -2970,7 +2982,7 @@ i386_record_lea_modrm_addr (struct i386_
*addr = (int8_t) tmpu8;
break;
case 2:
- if (target_read_memory (irp->addr, (gdb_byte *) addr, 4))
+ if (target_read_memory (irp->addr, (gdb_byte *) &tmpi32, 4))
{
if (record_debug)
printf_unfiltered (_("Process record: error reading memory "
@@ -2978,21 +2990,34 @@ i386_record_lea_modrm_addr (struct i386_
paddress (gdbarch, irp->addr));
return -1;
}
+ *addr = tmpi32;
irp->addr += 4;
break;
}

+ tmpulongest = 0;
if (base != 0xff)
- {
- regcache_raw_read (irp->regcache, base, (gdb_byte *) & tmpu32);
- *addr += tmpu32;
+ {
+ if (base == 4 && irp->popl_esp_hack)
+ *addr += irp->popl_esp_hack;
+ regcache_raw_read_unsigned (irp->regcache, irp->regmap[base],
+ &tmpulongest);
}
+ if (irp->aflag == 2)
+ {
+ *addr += tmpulongest;
+ }
+ else
+ *addr = (uint32_t) (tmpulongest + *addr);

- /* XXX: index == 4 is always invalid */
if (havesib && (index != 4 || scale != 0))
{
- regcache_raw_read (irp->regcache, index, (gdb_byte *) & tmpu32);
- *addr += tmpu32 << scale;
+ regcache_raw_read_unsigned (irp->regcache, irp->regmap[index],
+ &tmpulongest);
+ if (irp->aflag == 2)
+ *addr += tmpulongest << scale;
+ else
+ *addr = (uint32_t) (*addr + (tmpulongest << scale));
}
}
else
@@ -3004,7 +3029,7 @@ i386_record_lea_modrm_addr (struct i386_
if (irp->rm == 6)
{
if (target_read_memory
- (irp->addr, (gdb_byte *) & tmpu16, 2))
+ (irp->addr, (gdb_byte *) &tmpi16, 2))
{
if (record_debug)
printf_unfiltered (_("Process record: error reading "
@@ -3013,7 +3038,7 @@ i386_record_lea_modrm_addr (struct i386_
return -1;
}
irp->addr += 2;
- *addr = (int16_t) tmpu16;
+ *addr = tmpi16;
irp->rm = 0;
goto no_rm;
}
@@ -3035,7 +3060,7 @@ i386_record_lea_modrm_addr (struct i386_
*addr = (int8_t) tmpu8;
break;
case 2:
- if (target_read_memory (irp->addr, (gdb_byte *) & tmpu16, 2))
+ if (target_read_memory (irp->addr, (gdb_byte *) &tmpi16, 2))
{
if (record_debug)
printf_unfiltered (_("Process record: error reading memory "
@@ -3044,63 +3069,75 @@ i386_record_lea_modrm_addr (struct i386_
return -1;
}
irp->addr += 2;
- *addr = (int16_t) tmpu16;
+ *addr = tmpi16;
break;
}

switch (irp->rm)
{
case 0:
- regcache_raw_read (irp->regcache, I386_EBX_REGNUM,
- (gdb_byte *) & tmpu32);
- *addr += tmpu32;
- regcache_raw_read (irp->regcache, I386_ESI_REGNUM,
- (gdb_byte *) & tmpu32);
- *addr += tmpu32;
+ regcache_raw_read_unsigned (irp->regcache,
+ irp->regmap[X86_RECORD_REBX_REGNUM],
+ &tmpulongest);
+ *addr = (uint32_t) (*addr + tmpulongest);
+ regcache_raw_read_unsigned (irp->regcache,
+ irp->regmap[X86_RECORD_RESI_REGNUM],
+ &tmpulongest);
+ *addr = (uint32_t) (*addr + tmpulongest);
break;
case 1:
- regcache_raw_read (irp->regcache, I386_EBX_REGNUM,
- (gdb_byte *) & tmpu32);
- *addr += tmpu32;
- regcache_raw_read (irp->regcache, I386_EDI_REGNUM,
- (gdb_byte *) & tmpu32);
- *addr += tmpu32;
+ regcache_raw_read_unsigned (irp->regcache,
+ irp->regmap[X86_RECORD_REBX_REGNUM],
+ &tmpulongest);
+ *addr = (uint32_t) (*addr + tmpulongest);
+ regcache_raw_read_unsigned (irp->regcache,
+ irp->regmap[X86_RECORD_REDI_REGNUM],
+ &tmpulongest);
+ *addr = (uint32_t) (*addr + tmpulongest);
break;
case 2:
- regcache_raw_read (irp->regcache, I386_EBP_REGNUM,
- (gdb_byte *) & tmpu32);
- *addr += tmpu32;
- regcache_raw_read (irp->regcache, I386_ESI_REGNUM,
- (gdb_byte *) & tmpu32);
- *addr += tmpu32;
+ regcache_raw_read_unsigned (irp->regcache,
+ irp->regmap[X86_RECORD_REBP_REGNUM],
+ &tmpulongest);
+ *addr = (uint32_t) (*addr + tmpulongest);
+ regcache_raw_read_unsigned (irp->regcache,
+ irp->regmap[X86_RECORD_RESI_REGNUM],
+ &tmpulongest);
+ *addr = (uint32_t) (*addr + tmpulongest);
break;
case 3:
- regcache_raw_read (irp->regcache, I386_EBP_REGNUM,
- (gdb_byte *) & tmpu32);
- *addr += tmpu32;
- regcache_raw_read (irp->regcache, I386_EDI_REGNUM,
- (gdb_byte *) & tmpu32);
- *addr += tmpu32;
+ regcache_raw_read_unsigned (irp->regcache,
+ irp->regmap[X86_RECORD_REBP_REGNUM],
+ &tmpulongest);
+ *addr = (uint32_t) (*addr + tmpulongest);
+ regcache_raw_read_unsigned (irp->regcache,
+ irp->regmap[X86_RECORD_REDI_REGNUM],
+ &tmpulongest);
+ *addr = (uint32_t) (*addr + tmpulongest);
break;
case 4:
- regcache_raw_read (irp->regcache, I386_ESI_REGNUM,
- (gdb_byte *) & tmpu32);
- *addr += tmpu32;
+ regcache_raw_read_unsigned (irp->regcache,
+ irp->regmap[X86_RECORD_RESI_REGNUM],
+ &tmpulongest);
+ *addr = (uint32_t) (*addr + tmpulongest);
break;
case 5:
- regcache_raw_read (irp->regcache, I386_EDI_REGNUM,
- (gdb_byte *) & tmpu32);
- *addr += tmpu32;
+ regcache_raw_read_unsigned (irp->regcache,
+ irp->regmap[X86_RECORD_REDI_REGNUM],
+ &tmpulongest);
+ *addr = (uint32_t) (*addr + tmpulongest);
break;
case 6:
- regcache_raw_read (irp->regcache, I386_EBP_REGNUM,
- (gdb_byte *) & tmpu32);
- *addr += tmpu32;
+ regcache_raw_read_unsigned (irp->regcache,
+ irp->regmap[X86_RECORD_REBP_REGNUM],
+ &tmpulongest);
+ *addr = (uint32_t) (*addr + tmpulongest);
break;
case 7:
- regcache_raw_read (irp->regcache, I386_EBX_REGNUM,
- (gdb_byte *) & tmpu32);
- *addr += tmpu32;
+ regcache_raw_read_unsigned (irp->regcache,
+ irp->regmap[X86_RECORD_REBX_REGNUM],
+ &tmpulongest);
+ *addr = (uint32_t) (*addr + tmpulongest);
break;
}
*addr &= 0xffff;
@@ -3117,10 +3154,10 @@ no_rm:
static int
i386_record_lea_modrm (struct i386_record_s *irp)
{
- struct gdbarch *gdbarch = get_regcache_arch (irp->regcache);
- uint32_t addr;
+ struct gdbarch *gdbarch = irp->gdbarch;
+ uint64_t addr;

- if (irp->override)
+ if (irp->override >= 0)
{
if (record_debug)
printf_unfiltered (_("Process record ignores the memory change "
@@ -3139,10 +3176,36 @@ i386_record_lea_modrm (struct i386_recor
return 0;
}

+/* Record the push operation to "record_arch_list".
+ Return -1 if something wrong. */
+
+static int
+i386_record_push (struct i386_record_s *irp, int size)
+{
+ ULONGEST tmpulongest;
+
+ if (record_arch_list_add_reg (irp->regcache,
+ irp->regmap[X86_RECORD_RESP_REGNUM]))
+ return -1;
+ regcache_raw_read_unsigned (irp->regcache,
+ irp->regmap[X86_RECORD_RESP_REGNUM],
+ &tmpulongest);
+ if (record_arch_list_add_mem ((CORE_ADDR) tmpulongest - size, size))
+ return -1;
+
+ return 0;
+}
+
/* Parse the current instruction and record the values of the registers and
memory that will be changed in current instruction to "record_arch_list".
Return -1 if something wrong. */

+#define I386_RECORD_ARCH_LIST_ADD_REG(regnum) \
+ do { \
+ if (record_arch_list_add_reg (ir.regcache, ir.regmap[(regnum)])) \
+ return -1; \
+ } while (0)
+
int
i386_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
CORE_ADDR addr)
@@ -3151,14 +3214,21 @@ i386_process_record (struct gdbarch *gdb
uint8_t tmpu8;
uint16_t tmpu16;
uint32_t tmpu32;
+ ULONGEST tmpulongest;
uint32_t opcode;
struct i386_record_s ir;
+ int rex = 0;
+ uint8_t rex_w = -1;
+ uint8_t rex_r = 0;

memset (&ir, 0, sizeof (struct i386_record_s));
ir.regcache = regcache;
ir.addr = addr;
ir.aflag = 1;
ir.dflag = 1;
+ ir.override = -1;
+ ir.regmap = gdbarch_tdep (gdbarch)->record_regmap;
+ ir.gdbarch = gdbarch;

if (record_debug > 1)
fprintf_unfiltered (gdb_stdlog, "Process record: i386_process_record "
@@ -3189,22 +3259,22 @@ i386_process_record (struct gdbarch *gdb
prefixes |= PREFIX_LOCK;
break;
case 0x2e:
- ir.override = I386_CS_REGNUM;
+ ir.override = X86_RECORD_CS_REGNUM;
break;
case 0x36:
- ir.override = I386_SS_REGNUM;
+ ir.override = X86_RECORD_SS_REGNUM;
break;
case 0x3e:
- ir.override = I386_DS_REGNUM;
+ ir.override = X86_RECORD_DS_REGNUM;
break;
case 0x26:
- ir.override = I386_ES_REGNUM;
+ ir.override = X86_RECORD_ES_REGNUM;
break;
case 0x64:
- ir.override = I386_FS_REGNUM;
+ ir.override = X86_RECORD_FS_REGNUM;
break;
case 0x65:
- ir.override = I386_GS_REGNUM;
+ ir.override = X86_RECORD_GS_REGNUM;
break;
case 0x66:
prefixes |= PREFIX_DATA;
@@ -3212,16 +3282,51 @@ i386_process_record (struct gdbarch *gdb
case 0x67:
prefixes |= PREFIX_ADDR;
break;
+ case 0x40:
+ case 0x41:
+ case 0x42:
+ case 0x43:
+ case 0x44:
+ case 0x45:
+ case 0x46:
+ case 0x47:
+ case 0x48:
+ case 0x49:
+ case 0x4a:
+ case 0x4b:
+ case 0x4c:
+ case 0x4d:
+ case 0x4e:
+ case 0x4f:
+ if (ir.regmap[X86_RECORD_R8_REGNUM])
+ {
+ /* REX */
+ rex = 1;
+ rex_w = (tmpu8 >> 3) & 1;
+ rex_r = (tmpu8 & 0x4) << 1;
+ ir.rex_x = (tmpu8 & 0x2) << 2;
+ ir.rex_b = (tmpu8 & 0x1) << 3;
+ }
+ break;
default:
goto out_prefixes;
break;
}
}
out_prefixes:
- if (prefixes & PREFIX_DATA)
- ir.dflag ^= 1;
+ if (ir.regmap[X86_RECORD_R8_REGNUM] && rex_w == 1)
+ {
+ ir.dflag = 2;
+ }
+ else
+ {
+ if (prefixes & PREFIX_DATA)
+ ir.dflag ^= 1;
+ }
if (prefixes & PREFIX_ADDR)
ir.aflag ^= 1;
+ else if (ir.regmap[X86_RECORD_R8_REGNUM])
+ ir.aflag = 2;

/* now check op code */
opcode = (uint32_t) tmpu8;
@@ -3311,30 +3416,28 @@ reswitch:
}
else
{
- if (ir.ot == OT_BYTE)
+ ir.rm |= ir.rex_b;
+ if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
ir.rm &= 0x3;
- if (record_arch_list_add_reg (ir.regcache, ir.rm))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
}
break;
/* OP Gv, Ev */
case 1:
if (i386_record_modrm (&ir))
return -1;
- if (ir.ot == OT_BYTE)
+ ir.reg |= rex_r;
+ if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
ir.reg &= 0x3;
- if (record_arch_list_add_reg (ir.regcache, ir.reg))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
break;
/* OP A, Iv */
case 2:
- if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
break;
}
}
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* GRP1 */
@@ -3354,17 +3457,17 @@ reswitch:

if (ir.mod != 3)
{
+ if (opcode == 0x83)
+ ir.rip_offset = 1;
+ else
+ ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
if (i386_record_lea_modrm (&ir))
return -1;
}
else
- {
- if (record_arch_list_add_reg (ir.regcache, ir.rm))
- return -1;
- }
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
}
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* inv */
@@ -3385,10 +3488,8 @@ reswitch:
case 0x4d:
case 0x4e:
case 0x4f:
- if (record_arch_list_add_reg (ir.regcache, opcode & 7))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (opcode & 7);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* GRP3 */
@@ -3401,28 +3502,17 @@ reswitch:
if (i386_record_modrm (&ir))
return -1;

+ if (ir.mod != 3 && ir.reg == 0)
+ ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
+
switch (ir.reg)
{
/* test */
case 0:
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;
/* not */
case 2:
- if (ir.mod != 3)
- {
- if (i386_record_lea_modrm (&ir))
- return -1;
- }
- else
- {
- if (ir.ot == OT_BYTE)
- ir.rm &= 0x3;
- if (record_arch_list_add_reg (ir.regcache, ir.rm))
- return -1;
- }
- break;
/* neg */
case 3:
if (ir.mod != 3)
@@ -3432,13 +3522,14 @@ reswitch:
}
else
{
- if (ir.ot == OT_BYTE)
+ ir.rm |= ir.rex_b;
+ if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
ir.rm &= 0x3;
- if (record_arch_list_add_reg (ir.regcache, ir.rm))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
}
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ /* neg */
+ if (ir.reg == 3)
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;
/* mul */
case 4:
@@ -3448,15 +3539,10 @@ reswitch:
case 6:
/* idiv */
case 7:
- if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
if (ir.ot != OT_BYTE)
- {
- if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
- return -1;
- }
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;
default:
ir.addr -= 2;
@@ -3470,10 +3556,6 @@ reswitch:
case 0xfe:
/* GRP5 */
case 0xff:
- if ((opcode & 1) == 0)
- ir.ot = OT_BYTE;
- else
- ir.ot = ir.dflag + OT_WORD;
if (i386_record_modrm (&ir))
return -1;
if (ir.reg >= 2 && opcode == 0xfe)
@@ -3482,13 +3564,16 @@ reswitch:
opcode = opcode << 8 | ir.modrm;
goto no_support;
}
-
switch (ir.reg)
{
/* inc */
case 0:
/* dec */
case 1:
+ if ((opcode & 1) == 0)
+ ir.ot = OT_BYTE;
+ else
+ ir.ot = ir.dflag + OT_WORD;
if (ir.mod != 3)
{
if (i386_record_lea_modrm (&ir))
@@ -3496,42 +3581,40 @@ reswitch:
}
else
{
- if (ir.ot == OT_BYTE)
+ ir.rm |= ir.rex_b;
+ if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
ir.rm &= 0x3;
- if (record_arch_list_add_reg (ir.regcache, ir.rm))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
}
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;
/* call */
case 2:
- /* push */
- case 6:
- if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
- return -1;
- regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
- (gdb_byte *) & tmpu32);
- if (record_arch_list_add_mem
- ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
+ if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+ ir.dflag = 2;
+ if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;
/* lcall */
case 3:
- if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
- return -1;
- regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
- (gdb_byte *) & tmpu32);
- if (record_arch_list_add_mem
- ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 2)), (1 << (ir.dflag + 2))))
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_CS_REGNUM);
+ if (i386_record_push (&ir, 1 << (ir.dflag + 2)))
return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;
/* jmp */
case 4:
/* ljmp */
case 5:
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+ break;
+ /* push */
+ case 6:
+ if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+ ir.dflag = 2;
+ if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+ return -1;
break;
default:
ir.addr -= 2;
@@ -3546,22 +3629,18 @@ reswitch:
case 0x85:
case 0xa8:
case 0xa9:
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* CWDE/CBW */
case 0x98:
- if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
break;

/* CDQ/CWD */
case 0x99:
- if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM);
break;

/* imul */
@@ -3571,12 +3650,15 @@ reswitch:
ir.ot = ir.dflag + OT_WORD;
if (i386_record_modrm (&ir))
return -1;
- if (ir.ot == OT_BYTE)
+ if (opcode == 0x69)
+ ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
+ else if (opcode == 0x6b)
+ ir.rip_offset = 1;
+ ir.reg |= rex_r;
+ if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
ir.reg &= 0x3;
- if (record_arch_list_add_reg (ir.regcache, ir.reg))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* xadd */
@@ -3588,28 +3670,25 @@ reswitch:
ir.ot = ir.dflag + OT_WORD;
if (i386_record_modrm (&ir))
return -1;
+ ir.reg |= rex_r;
if (ir.mod == 3)
{
- if (ir.ot == OT_BYTE)
+ if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
ir.reg &= 0x3;
- if (record_arch_list_add_reg (ir.regcache, ir.reg))
- return -1;
- if (ir.ot == OT_BYTE)
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
+ if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
ir.rm &= 0x3;
- if (record_arch_list_add_reg (ir.regcache, ir.rm))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
}
else
{
if (i386_record_lea_modrm (&ir))
return -1;
- if (ir.ot == OT_BYTE)
+ if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
ir.reg &= 0x3;
- if (record_arch_list_add_reg (ir.regcache, ir.reg))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
}
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* cmpxchg */
@@ -3623,22 +3702,19 @@ reswitch:
return -1;
if (ir.mod == 3)
{
- if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
- return -1;
- if (ir.ot == OT_BYTE)
+ ir.reg |= rex_r;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+ if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
ir.reg &= 0x3;
- if (record_arch_list_add_reg (ir.regcache, ir.reg))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
}
else
{
- if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
if (i386_record_lea_modrm (&ir))
return -1;
}
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* cmpxchg8b */
@@ -3651,14 +3727,11 @@ reswitch:
opcode = opcode << 8 | ir.modrm;
goto no_support;
}
- if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM);
if (i386_record_lea_modrm (&ir))
return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* push */
@@ -3672,6 +3745,12 @@ reswitch:
case 0x57:
case 0x68:
case 0x6a:
+ if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+ ir.dflag = 2;
+ if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+ return -1;
+ break;
+
/* push es */
case 0x06:
/* push cs */
@@ -3680,16 +3759,36 @@ reswitch:
case 0x16:
/* push ds */
case 0x1e:
+ if (ir.regmap[X86_RECORD_R8_REGNUM])
+ {
+ ir.addr -= 1;
+ goto no_support;
+ }
+ if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+ return -1;
+ break;
+
/* push fs */
case 0x0fa0:
/* push gs */
case 0x0fa8:
- if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
+ if (ir.regmap[X86_RECORD_R8_REGNUM])
+ {
+ ir.addr -= 2;
+ goto no_support;
+ }
+ if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
return -1;
- regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
- (gdb_byte *) & tmpu32);
- if (record_arch_list_add_mem
- ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
+ break;
+
+ /* pusha */
+ case 0x60:
+ if (ir.regmap[X86_RECORD_R8_REGNUM])
+ {
+ ir.addr -= 1;
+ goto no_support;
+ }
+ if (i386_record_push (&ir, 1 << (ir.dflag + 4)))
return -1;
break;

@@ -3702,113 +3801,103 @@ reswitch:
case 0x5d:
case 0x5e:
case 0x5f:
- ir.ot = ir.dflag + OT_WORD;
- if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
- return -1;
- if (ir.ot == OT_BYTE)
- opcode &= 0x3;
- if (record_arch_list_add_reg (ir.regcache, opcode & 0x7))
- return -1;
- break;
-
- /* pusha */
- case 0x60:
- if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
- return -1;
- regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
- (gdb_byte *) & tmpu32);
- if (record_arch_list_add_mem
- ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 4)), (1 << (ir.dflag + 4))))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG ((opcode & 0x7) | ir.rex_b);
break;

/* popa */
case 0x61:
- for (tmpu8 = I386_EAX_REGNUM; tmpu8 <= I386_EDI_REGNUM; tmpu8++)
- {
- if (record_arch_list_add_reg (ir.regcache, tmpu8))
- return -1;
+ if (ir.regmap[X86_RECORD_R8_REGNUM])
+ {
+ ir.addr -= 1;
+ goto no_support;
}
+ for (tmpu8 = X86_RECORD_REAX_REGNUM; tmpu8 <= X86_RECORD_REDI_REGNUM;
+ tmpu8++)
+ I386_RECORD_ARCH_LIST_ADD_REG (tmpu8);
break;

/* pop */
case 0x8f:
- ir.ot = ir.dflag + OT_WORD;
+ if (ir.regmap[X86_RECORD_R8_REGNUM])
+ ir.ot = ir.dflag ? OT_QUAD : OT_WORD;
+ else
+ ir.ot = ir.dflag + OT_WORD;
if (i386_record_modrm (&ir))
return -1;
if (ir.mod == 3)
- {
- if (record_arch_list_add_reg (ir.regcache, ir.rm))
- return -1;
- }
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
else
{
if (i386_record_lea_modrm (&ir))
return -1;
}
- if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
break;

/* enter */
case 0xc8:
- if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_EBP_REGNUM))
- return -1;
- regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
- (gdb_byte *) & tmpu32);
- if (record_arch_list_add_mem
- ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REBP_REGNUM);
+ if (ir.regmap[X86_RECORD_R8_REGNUM] && ir.dflag)
+ ir.dflag = 2;
+ if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
return -1;
break;

/* leave */
case 0xc9:
- if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_EBP_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REBP_REGNUM);
break;

/* pop es */
case 0x07:
- if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_ES_REGNUM))
- return -1;
+ if (ir.regmap[X86_RECORD_R8_REGNUM])
+ {
+ ir.addr -= 1;
+ goto no_support;
+ }
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_ES_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* pop ss */
case 0x17:
- if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_SS_REGNUM))
- return -1;
+ if (ir.regmap[X86_RECORD_R8_REGNUM])
+ {
+ ir.addr -= 1;
+ goto no_support;
+ }
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_SS_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* pop ds */
case 0x1f:
- if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_DS_REGNUM))
- return -1;
+ if (ir.regmap[X86_RECORD_R8_REGNUM])
+ {
+ ir.addr -= 1;
+ goto no_support;
+ }
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_DS_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* pop fs */
case 0x0fa1:
- if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_FS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_FS_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* pop gs */
case 0x0fa9:
- if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_GS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_GS_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* mov */
@@ -3826,19 +3915,21 @@ reswitch:

if (ir.mod != 3)
{
+ if (opcode == 0xc6 || opcode == 0xc7)
+ ir.rip_offset = (ir.ot > OT_LONG) ? 4 : (1 << ir.ot);
if (i386_record_lea_modrm (&ir))
return -1;
}
else
{
- if (ir.ot == OT_BYTE)
+ if (opcode == 0xc6 || opcode == 0xc7)
+ ir.rm |= ir.rex_b;
+ if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
ir.rm &= 0x3;
- if (record_arch_list_add_reg (ir.regcache, ir.rm))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
}
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
break;
+
/* mov */
case 0x8a:
case 0x8b:
@@ -3846,40 +3937,55 @@ reswitch:
ir.ot = OT_BYTE;
else
ir.ot = ir.dflag + OT_WORD;
-
if (i386_record_modrm (&ir))
return -1;
-
- if (ir.ot == OT_BYTE)
+ ir.reg |= rex_r;
+ if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
ir.reg &= 0x3;
- if (record_arch_list_add_reg (ir.regcache, ir.reg))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
+ break;

- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
+ /* mov seg */
+ case 0x8c:
+ if (i386_record_modrm (&ir))
return -1;
+ if (ir.reg > 5)
+ {
+ ir.addr -= 2;
+ opcode = opcode << 8 | ir.modrm;
+ goto no_support;
+ }
+
+ if (ir.mod == 3)
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
+ else
+ {
+ ir.ot = OT_WORD;
+ if (i386_record_lea_modrm (&ir))
+ return -1;
+ }
break;

/* mov seg */
case 0x8e:
if (i386_record_modrm (&ir))
return -1;
-
switch (ir.reg)
{
case 0:
- tmpu8 = I386_ES_REGNUM;
+ tmpu8 = X86_RECORD_ES_REGNUM;
break;
case 2:
- tmpu8 = I386_SS_REGNUM;
+ tmpu8 = X86_RECORD_SS_REGNUM;
break;
case 3:
- tmpu8 = I386_DS_REGNUM;
+ tmpu8 = X86_RECORD_DS_REGNUM;
break;
case 4:
- tmpu8 = I386_FS_REGNUM;
+ tmpu8 = X86_RECORD_FS_REGNUM;
break;
case 5:
- tmpu8 = I386_GS_REGNUM;
+ tmpu8 = X86_RECORD_GS_REGNUM;
break;
default:
ir.addr -= 2;
@@ -3887,38 +3993,8 @@ reswitch:
goto no_support;
break;
}
- if (record_arch_list_add_reg (ir.regcache, tmpu8))
- return -1;
-
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
- break;
-
- /* mov seg */
- case 0x8c:
- if (i386_record_modrm (&ir))
- return -1;
- if (ir.reg > 5)
- {
- ir.addr -= 2;
- opcode = opcode << 8 | ir.modrm;
- goto no_support;
- }
-
- if (ir.mod == 3)
- {
- if (record_arch_list_add_reg (ir.regcache, ir.rm))
- return -1;
- }
- else
- {
- ir.ot = OT_WORD;
- if (i386_record_lea_modrm (&ir))
- return -1;
- }
-
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (tmpu8);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* movzbS */
@@ -3931,8 +4007,7 @@ reswitch:
case 0x0fbf:
if (i386_record_modrm (&ir))
return -1;
- if (record_arch_list_add_reg (ir.regcache, ir.reg))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
break;

/* lea */
@@ -3945,12 +4020,11 @@ reswitch:
opcode = opcode << 8 | ir.modrm;
goto no_support;
}
-
ir.ot = ir.dflag;
- if (ir.ot == OT_BYTE)
+ ir.reg |= rex_r;
+ if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
ir.reg &= 0x3;
- if (record_arch_list_add_reg (ir.regcache, ir.reg))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
break;

/* mov EAX */
@@ -3958,62 +4032,68 @@ reswitch:
case 0xa1:
/* xlat */
case 0xd7:
- if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
break;

/* mov EAX */
case 0xa2:
case 0xa3:
- {
- uint32_t addr;
-
- if (ir.override)
- {
- if (record_debug)
- printf_unfiltered (_("Process record ignores the memory change "
- "of instruction at address %s because "
- "it can't get the value of the segment "
- "register.\n"),
- paddress (gdbarch, ir.addr));
- }
- else
- {
- if ((opcode & 1) == 0)
- ir.ot = OT_BYTE;
- else
- ir.ot = ir.dflag + OT_WORD;
- if (ir.aflag)
- {
- if (target_read_memory
- (ir.addr, (gdb_byte *) & addr, 4))
- {
- if (record_debug)
- printf_unfiltered (_("Process record: error reading "
- "memory at addr %s len = 4.\n"),
- paddress (gdbarch, ir.addr));
- return -1;
- }
- ir.addr += 4;
- }
- else
- {
- if (target_read_memory
- (ir.addr, (gdb_byte *) & tmpu16, 4))
- {
- if (record_debug)
- printf_unfiltered (_("Process record: error reading "
- "memory at addr %s len = 4.\n"),
- paddress (gdbarch, ir.addr));
- return -1;
- }
- ir.addr += 2;
- addr = tmpu16;
- }
- if (record_arch_list_add_mem (addr, 1 << ir.ot))
- return -1;
- }
- }
+ if (ir.override >= 0)
+ {
+ if (record_debug)
+ printf_unfiltered (_("Process record ignores the memory change "
+ "of instruction at address 0x%s because "
+ "it can't get the value of the segment "
+ "register.\n"),
+ paddress (gdbarch, ir.addr));
+ }
+ else
+ {
+ if ((opcode & 1) == 0)
+ ir.ot = OT_BYTE;
+ else
+ ir.ot = ir.dflag + OT_WORD;
+ if (ir.aflag == 2)
+ {
+ if (target_read_memory (ir.addr, (gdb_byte *) &addr, 8))
+ {
+ if (record_debug)
+ printf_unfiltered (_("Process record: error reading "
+ "memory at addr 0x%s len = 8.\n"),
+ paddress (gdbarch, ir.addr));
+ return -1;
+ }
+ ir.addr += 8;
+ }
+ else if (ir.aflag)
+ {
+ if (target_read_memory (ir.addr, (gdb_byte *) &tmpu32, 4))
+ {
+ if (record_debug)
+ printf_unfiltered (_("Process record: error reading "
+ "memory at addr 0x%s len = 4.\n"),
+ paddress (gdbarch, ir.addr));
+ return -1;
+ }
+ ir.addr += 4;
+ addr = tmpu32;
+ }
+ else
+ {
+ if (target_read_memory (ir.addr, (gdb_byte *) &tmpu16, 2))
+ {
+ if (record_debug)
+ printf_unfiltered (_("Process record: error reading "
+ "memory at addr 0x%s len = 2.\n"),
+ paddress (gdbarch, ir.addr));
+ return -1;
+ }
+ ir.addr += 2;
+ addr = tmpu16;
+ }
+ if (record_arch_list_add_mem (addr, 1 << ir.ot))
+ return -1;
+ }
break;

/* mov R, Ib */
@@ -4025,8 +4105,9 @@ reswitch:
case 0xb5:
case 0xb6:
case 0xb7:
- if (record_arch_list_add_reg (ir.regcache, (opcode & 0x7) & 0x3))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG ((ir.regmap[X86_RECORD_R8_REGNUM]) ?
+ ((opcode & 0x7) | ir.rex_b) :
+ ((opcode & 0x7) & 0x3));
break;

/* mov R, Iv */
@@ -4038,8 +4119,7 @@ reswitch:
case 0xbd:
case 0xbe:
case 0xbf:
- if (record_arch_list_add_reg (ir.regcache, opcode & 0x7))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG ((opcode & 0x7) | ir.rex_b);
break;

/* xchg R, EAX */
@@ -4050,10 +4130,8 @@ reswitch:
case 0x95:
case 0x96:
case 0x97:
- if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, opcode & 0x7))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (opcode & 0x7);
break;

/* xchg Ev, Gv */
@@ -4063,33 +4141,35 @@ reswitch:
ir.ot = OT_BYTE;
else
ir.ot = ir.dflag + OT_WORD;
-
if (i386_record_modrm (&ir))
return -1;
-
if (ir.mod == 3)
{
- if (ir.ot == OT_BYTE)
+ ir.rm != ir.rex_b;
+ if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
ir.rm &= 0x3;
- if (record_arch_list_add_reg (ir.regcache, ir.rm))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
}
else
{
if (i386_record_lea_modrm (&ir))
return -1;
}
-
- if (ir.ot == OT_BYTE)
+ ir.reg |= rex_r;
+ if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
ir.reg &= 0x3;
- if (record_arch_list_add_reg (ir.regcache, ir.reg))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
break;

/* les Gv */
case 0xc4:
/* lds Gv */
case 0xc5:
+ if (ir.regmap[X86_RECORD_R8_REGNUM])
+ {
+ ir.addr -= 1;
+ goto no_support;
+ }
/* lss Gv */
case 0x0fb2:
/* lfs Gv */
@@ -4107,35 +4187,32 @@ reswitch:
opcode = opcode << 8 | ir.modrm;
goto no_support;
}
-
switch (opcode)
{
/* les Gv */
case 0xc4:
- tmpu8 = I386_ES_REGNUM;
+ tmpu8 = X86_RECORD_ES_REGNUM;
break;
/* lds Gv */
case 0xc5:
- tmpu8 = I386_DS_REGNUM;
+ tmpu8 = X86_RECORD_DS_REGNUM;
break;
/* lss Gv */
case 0x0fb2:
- tmpu8 = I386_SS_REGNUM;
+ tmpu8 = X86_RECORD_SS_REGNUM;
break;
/* lfs Gv */
case 0x0fb4:
- tmpu8 = I386_FS_REGNUM;
+ tmpu8 = X86_RECORD_FS_REGNUM;
break;
/* lgs Gv */
case 0x0fb5:
- tmpu8 = I386_GS_REGNUM;
+ tmpu8 = X86_RECORD_GS_REGNUM;
break;
}
- if (record_arch_list_add_reg (ir.regcache, tmpu8))
- return -1;
-
- if (record_arch_list_add_reg (ir.regcache, ir.reg))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (tmpu8);
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* shifts */
@@ -4149,10 +4226,8 @@ reswitch:
ir.ot = OT_BYTE;
else
ir.ot = ir.dflag + OT_WORD;
-
if (i386_record_modrm (&ir))
return -1;
-
if (ir.mod != 3 && (opcode == 0xd2 || opcode == 0xd3))
{
if (i386_record_lea_modrm (&ir))
@@ -4160,14 +4235,12 @@ reswitch:
}
else
{
- if (ir.ot == OT_BYTE)
+ ir.rm |= ir.rex_b;
+ if (ir.ot == OT_BYTE && !ir.regmap[X86_RECORD_R8_REGNUM])
ir.rm &= 0x3;
- if (record_arch_list_add_reg (ir.regcache, ir.rm))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.rm);
}
-
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

case 0x0fa4:
@@ -4204,9 +4277,9 @@ reswitch:
if (ir.mod != 3)
{
/* memory */
- uint32_t addr;
+ uint64_t tmpu64;

- if (i386_record_lea_modrm_addr (&ir, &addr))
+ if (i386_record_lea_modrm_addr (&ir, &tmpu64))
return -1;
switch (ir.reg)
{
@@ -4266,16 +4339,16 @@ reswitch:
switch (ir.reg >> 4)
{
case 0:
- if (record_arch_list_add_mem (addr, 4))
+ if (record_arch_list_add_mem (tmpu64, 4))
return -1;
break;
case 2:
- if (record_arch_list_add_mem (addr, 8))
+ if (record_arch_list_add_mem (tmpu64, 8))
return -1;
break;
case 3:
default:
- if (record_arch_list_add_mem (addr, 2))
+ if (record_arch_list_add_mem (tmpu64, 2))
return -1;
break;
}
@@ -4285,16 +4358,16 @@ reswitch:
{
case 0:
case 1:
- if (record_arch_list_add_mem (addr, 4))
+ if (record_arch_list_add_mem (tmpu64, 4))
return -1;
break;
case 2:
- if (record_arch_list_add_mem (addr, 8))
+ if (record_arch_list_add_mem (tmpu64, 8))
return -1;
break;
case 3:
default:
- if (record_arch_list_add_mem (addr, 2))
+ if (record_arch_list_add_mem (tmpu64, 2))
return -1;
break;
}
@@ -4311,43 +4384,43 @@ reswitch:
case 0x0e:
if (ir.dflag)
{
- if (record_arch_list_add_mem (addr, 28))
+ if (record_arch_list_add_mem (tmpu64, 28))
return -1;
}
else
{
- if (record_arch_list_add_mem (addr, 14))
+ if (record_arch_list_add_mem (tmpu64, 14))
return -1;
}
break;
case 0x0f:
case 0x2f:
- if (record_arch_list_add_mem (addr, 2))
+ if (record_arch_list_add_mem (tmpu64, 2))
return -1;
break;
case 0x1f:
case 0x3e:
- if (record_arch_list_add_mem (addr, 10))
+ if (record_arch_list_add_mem (tmpu64, 10))
return -1;
break;
case 0x2e:
if (ir.dflag)
{
- if (record_arch_list_add_mem (addr, 28))
+ if (record_arch_list_add_mem (tmpu64, 28))
return -1;
- addr += 28;
+ tmpu64 += 28;
}
else
{
- if (record_arch_list_add_mem (addr, 14))
+ if (record_arch_list_add_mem (tmpu64, 14))
return -1;
- addr += 14;
+ tmpu64 += 14;
}
- if (record_arch_list_add_mem (addr, 80))
+ if (record_arch_list_add_mem (tmpu64, 80))
return -1;
break;
case 0x3f:
- if (record_arch_list_add_mem (addr, 8))
+ if (record_arch_list_add_mem (tmpu64, 8))
return -1;
break;
default:
@@ -4369,123 +4442,88 @@ reswitch:
/* insS */
case 0x6c:
case 0x6d:
- {
- uint32_t addr;
-
- if ((opcode & 1) == 0)
- ir.ot = OT_BYTE;
- else
- ir.ot = ir.dflag + OT_WORD;
- if (opcode == 0xa4 || opcode == 0xa5)
- {
- if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
- return -1;
- }
- if (record_arch_list_add_reg (ir.regcache, I386_EDI_REGNUM))
- return -1;
-
- regcache_raw_read (ir.regcache, I386_EDI_REGNUM,
- (gdb_byte *) & addr);
- if (!ir.aflag)
- {
- addr &= 0xffff;
- /* addr += ((uint32_t)read_register (I386_ES_REGNUM)) << 4; */
- if (record_debug)
- printf_unfiltered (_("Process record ignores the memory change "
- "of instruction at address %s because "
- "it can't get the value of the segment "
- "register.\n"),
- paddress (gdbarch, ir.addr));
- }
-
- if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
- {
- uint32_t count;
-
- regcache_raw_read (ir.regcache, I386_ECX_REGNUM,
- (gdb_byte *) & count);
- if (!ir.aflag)
- count &= 0xffff;
-
- regcache_raw_read (ir.regcache, I386_EFLAGS_REGNUM,
- (gdb_byte *) & tmpu32);
- if ((tmpu32 >> 10) & 0x1)
- addr -= (count - 1) * (1 << ir.ot);
-
- if (ir.aflag)
- {
- if (record_arch_list_add_mem (addr, count * (1 << ir.ot)))
- return -1;
- }
+ if ((opcode & 1) == 0)
+ ir.ot = OT_BYTE;
+ else
+ ir.ot = ir.dflag + OT_WORD;
+ regcache_raw_read_unsigned (ir.regcache,
+ ir.regmap[X86_RECORD_REDI_REGNUM],
+ &tmpulongest);
+ if (!ir.aflag)
+ {
+ tmpulongest &= 0xffff;
+ /* addr += ((uint32_t) read_register (I386_ES_REGNUM)) << 4; */
+ if (record_debug)
+ printf_unfiltered (_("Process record ignores the memory change "
+ "of instruction at address 0x%s because "
+ "it can't get the value of the segment "
+ "register.\n"),
+ paddress (gdbarch, ir.addr));
+ }
+ if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
+ {
+ ULONGEST count, eflags;
+ regcache_raw_read_unsigned (ir.regcache,
+ ir.regmap[X86_RECORD_REDI_REGNUM],
+ &count);
+ if (!ir.aflag)
+ count &= 0xffff;
+ regcache_raw_read_unsigned (ir.regcache,
+ ir.regmap[X86_RECORD_EFLAGS_REGNUM],
+ &eflags);
+ if ((eflags >> 10) & 0x1)
+ tmpulongest -= (count - 1) * (1 << ir.ot);
+ if (record_arch_list_add_mem (tmpulongest, count * (1 << ir.ot)))
+ return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+ }
+ else
+ {
+ if (record_arch_list_add_mem (tmpulongest, 1 << ir.ot))
+ return -1;
+ }
+ if (opcode == 0xa4 || opcode == 0xa5)
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDI_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+ break;

- if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
- return -1;
- }
- else
- {
- if (ir.aflag)
- {
- if (record_arch_list_add_mem (addr, 1 << ir.ot))
- return -1;
- }
- }
- }
+ /* cmpsS */
+ case 0xa6:
+ case 0xa7:
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDI_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
+ if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* lodsS */
case 0xac:
case 0xad:
- if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
- return -1;
- if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
- {
- if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
- return -1;
- }
- break;
-
- /* outsS */
- case 0x6e:
- case 0x6f:
- if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
- {
- if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
- return -1;
- }
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* scasS */
case 0xae:
case 0xaf:
- if (record_arch_list_add_reg (ir.regcache, I386_EDI_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDI_REGNUM);
if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
- {
- if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
- return -1;
- }
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

- /* cmpsS */
- case 0xa6:
- case 0xa7:
- if (record_arch_list_add_reg (ir.regcache, I386_EDI_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_ESI_REGNUM))
- return -1;
+ /* outsS */
+ case 0x6e:
+ case 0x6f:
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESI_REGNUM);
if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ))
- {
- if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
- return -1;
- }
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* port I/O */
@@ -4493,8 +4531,8 @@ reswitch:
case 0xe5:
case 0xec:
case 0xed:
- if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
break;

case 0xe6:
@@ -4508,48 +4546,32 @@ reswitch:
case 0xc2:
/* ret */
case 0xc3:
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+ break;
+
/* lret im */
case 0xca:
/* lret */
case 0xcb:
- if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
- return -1;
- break;
-
/* iret */
case 0xcf:
- if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_CS_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* call im */
case 0xe8:
- if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
- return -1;
- regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
- (gdb_byte *) & tmpu32);
- if (record_arch_list_add_mem
- ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
- return -1;
+ if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+ return -1;
break;

/* lcall im */
case 0x9a:
- if (record_arch_list_add_reg (ir.regcache, I386_CS_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
- return -1;
- regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
- (gdb_byte *) & tmpu32);
- if (record_arch_list_add_mem
- ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 2)), (1 << (ir.dflag + 2))))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_CS_REGNUM);
+ if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+ return -1;
break;

/* jmp im */
@@ -4611,14 +4633,13 @@ reswitch:
case 0x0f9d:
case 0x0f9e:
case 0x0f9f:
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
ir.ot = OT_BYTE;
if (i386_record_modrm (&ir))
return -1;
if (ir.mod == 3)
- {
- if (record_arch_list_add_reg (ir.regcache, ir.rm & 0x3))
- return -1;
- }
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.rex_b ? (ir.rm | ir.rex_b):
+ (ir.rm & 0x3));
else
{
if (i386_record_lea_modrm (&ir))
@@ -4645,34 +4666,33 @@ reswitch:
case 0x0f4f:
if (i386_record_modrm (&ir))
return -1;
+ ir.reg |= rex_r;
if (ir.dflag == OT_BYTE)
ir.reg &= 0x3;
- if (record_arch_list_add_reg (ir.regcache, ir.reg & 0x3))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.reg);
break;

/* flags */
/* pushf */
case 0x9c:
- if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
- return -1;
- regcache_raw_read (ir.regcache, I386_ESP_REGNUM,
- (gdb_byte *) & tmpu32);
- if (record_arch_list_add_mem
- ((CORE_ADDR) tmpu32 - (1 << (ir.dflag + 1)), (1 << (ir.dflag + 1))))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+ if (i386_record_push (&ir, 1 << (ir.dflag + 1)))
+ return -1;
break;

/* popf */
case 0x9d:
- if (record_arch_list_add_reg (ir.regcache, I386_ESP_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RESP_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* sahf */
case 0x9e:
+ if (ir.regmap[X86_RECORD_R8_REGNUM])
+ {
+ ir.addr -= 1;
+ goto no_support;
+ }
/* cmc */
case 0xf5:
/* clc */
@@ -4683,66 +4703,95 @@ reswitch:
case 0xfc:
/* std */
case 0xfd:
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* lahf */
case 0x9f:
- if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
- return -1;
+ if (ir.regmap[X86_RECORD_R8_REGNUM])
+ {
+ ir.addr -= 1;
+ goto no_support;
+ }
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
break;

/* bit operations */
/* bt/bts/btr/btc Gv, im */
case 0x0fba:
- /* bts */
- case 0x0fab:
- /* btr */
- case 0x0fb3:
- /* btc */
- case 0x0fbb:
ir.ot = ir.dflag + OT_WORD;
if (i386_record_modrm (&ir))
return -1;
if (ir.reg < 4)
{
- ir.addr -= 3;
+ ir.addr -= 2;
opcode = opcode << 8 | ir.modrm;
goto no_support;
}
- ir.reg -= 4;
- if (ir.reg != 0)
+ if (ir.reg != 4)
{
- if (ir.mod != 3)
- {
- if (i386_record_lea_modrm (&ir))
- return -1;
- }
+ if (ir.mod == 3)
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
else
{
- if (record_arch_list_add_reg (ir.regcache, ir.rm))
+ if (i386_record_lea_modrm (&ir))
return -1;
}
}
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* bt Gv, Ev */
case 0x0fa3:
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+ break;
+
+ /* bts */
+ case 0x0fab:
+ /* btr */
+ case 0x0fb3:
+ /* btc */
+ case 0x0fbb:
+ ir.ot = ir.dflag + OT_WORD;
+ if (i386_record_modrm (&ir))
+ return -1;
+ if (ir.mod == 3)
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
+ else
+ {
+ uint64_t tmpu64;
+ if (i386_record_lea_modrm_addr (&ir, &tmpu64))
+ return -1;
+ regcache_raw_read_unsigned (ir.regcache,
+ ir.regmap[ir.reg | rex_r],
+ &tmpulongest);
+ switch (ir.dflag)
+ {
+ case 0:
+ tmpu64 += ((int16_t) tmpulongest >> 4) << 4;
+ break;
+ case 1:
+ tmpu64 += ((int32_t) tmpulongest >> 5) << 5;
+ break;
+ case 2:
+ tmpu64 += ((int64_t) tmpulongest >> 6) << 6;
+ break;
+ }
+ if (record_arch_list_add_mem (tmpu64, 1 << ir.ot))
+ return -1;
+ if (i386_record_lea_modrm (&ir))
+ return -1;
+ }
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* bsf */
case 0x0fbc:
/* bsr */
case 0x0fbd:
- if (record_arch_list_add_reg (ir.regcache, ir.reg))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* bcd */
@@ -4758,10 +4807,13 @@ reswitch:
case 0xd4:
/* aad */
case 0xd5:
- if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ if (ir.regmap[X86_RECORD_R8_REGNUM])
+ {
+ ir.addr -= 1;
+ goto no_support;
+ }
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* misc */
@@ -4853,16 +4905,18 @@ reswitch:
case 0x0fcd:
case 0x0fce:
case 0x0fcf:
- if (record_arch_list_add_reg (ir.regcache, opcode & 7))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG ((opcode & 7) | ir.rex_b);
break;

/* salc */
case 0xd6:
- if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ if (ir.regmap[X86_RECORD_R8_REGNUM])
+ {
+ ir.addr -= 1;
+ goto no_support;
+ }
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* loopnz */
@@ -4873,8 +4927,8 @@ reswitch:
case 0xe2:
/* jecxz */
case 0xe3:
- if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* wrmsr */
@@ -4905,6 +4959,11 @@ reswitch:
case 0x0f34:
{
int ret;
+ if (ir.regmap[X86_RECORD_R8_REGNUM])
+ {
+ ir.addr -= 2;
+ goto no_support;
+ }
if (gdbarch_tdep (gdbarch)->i386_sysenter_record == NULL)
{
printf_unfiltered (_("Process record doesn't support "
@@ -4926,16 +4985,37 @@ reswitch:
goto no_support;
break;

+ /* syscall */
+ case 0x0f05:
+ {
+ int ret;
+ if (gdbarch_tdep (gdbarch)->i386_syscall_record == NULL)
+ {
+ printf_unfiltered (_("Process record doesn't support "
+ "instruction syscall.\n"));
+ ir.addr -= 2;
+ goto no_support;
+ }
+ ret = gdbarch_tdep (gdbarch)->i386_syscall_record (ir.regcache);
+ if (ret)
+ return ret;
+ }
+ break;
+
+ /* sysret */
+ case 0x0f07:
+ printf_unfiltered (_("Process record doesn't support "
+ "instruction sysret.\n"));
+ ir.addr -= 2;
+ goto no_support;
+ break;
+
/* cpuid */
case 0x0fa2:
- if (record_arch_list_add_reg (ir.regcache, I386_EAX_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_ECX_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_EDX_REGNUM))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_EBX_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REBX_REGNUM);
break;

/* hlt */
@@ -4956,10 +5036,7 @@ reswitch:
/* str */
case 1:
if (ir.mod == 3)
- {
- if (record_arch_list_add_reg (ir.regcache, ir.rm))
- return -1;
- }
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
else
{
ir.ot = OT_WORD;
@@ -4976,8 +5053,7 @@ reswitch:
case 4:
/* verw */
case 5:
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;
default:
ir.addr -= 3;
@@ -4995,7 +5071,7 @@ reswitch:
/* sgdt */
case 0:
{
- uint32_t addr;
+ uint64_t tmpu64;

if (ir.mod == 3)
{
@@ -5003,8 +5079,7 @@ reswitch:
opcode = opcode << 8 | ir.modrm;
goto no_support;
}
-
- if (ir.override)
+ if (ir.override >= 0)
{
if (record_debug)
printf_unfiltered (_("Process record ignores the memory "
@@ -5016,13 +5091,21 @@ reswitch:
}
else
{
- if (i386_record_lea_modrm_addr (&ir, &addr))
- return -1;
- if (record_arch_list_add_mem (addr, 2))
+ if (i386_record_lea_modrm_addr (&ir, &tmpu64))
return -1;
- addr += 2;
- if (record_arch_list_add_mem (addr, 4))
+ if (record_arch_list_add_mem (tmpu64, 2))
return -1;
+ tmpu64 += 2;
+ if (ir.regmap[X86_RECORD_R8_REGNUM])
+ {
+ if (record_arch_list_add_mem (tmpu64, 8))
+ return -1;
+ }
+ else
+ {
+ if (record_arch_list_add_mem (tmpu64, 4))
+ return -1;
+ }
}
}
break;
@@ -5036,8 +5119,7 @@ reswitch:
break;
/* mwait */
case 1:
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;
default:
ir.addr -= 3;
@@ -5049,7 +5131,7 @@ reswitch:
else
{
/* sidt */
- if (ir.override)
+ if (ir.override >= 0)
{
if (record_debug)
printf_unfiltered (_("Process record ignores the memory "
@@ -5061,15 +5143,23 @@ reswitch:
}
else
{
- uint32_t addr;
+ uint64_t tmpu64;

- if (i386_record_lea_modrm_addr (&ir, &addr))
+ if (i386_record_lea_modrm_addr (&ir, &tmpu64))
return -1;
- if (record_arch_list_add_mem (addr, 2))
+ if (record_arch_list_add_mem (tmpu64, 2))
return -1;
addr += 2;
- if (record_arch_list_add_mem (addr, 4))
- return -1;
+ if (ir.regmap[X86_RECORD_R8_REGNUM])
+ {
+ if (record_arch_list_add_mem (tmpu64, 8))
+ return -1;
+ }
+ else
+ {
+ if (record_arch_list_add_mem (tmpu64, 4))
+ return -1;
+ }
}
}
break;
@@ -5077,9 +5167,6 @@ reswitch:
case 2:
/* lidt */
case 3:
- /* invlpg */
- case 7:
- default:
if (ir.mod == 3)
{
ir.addr -= 3;
@@ -5091,7 +5178,7 @@ reswitch:
case 4:
if (ir.mod == 3)
{
- if (record_arch_list_add_reg (ir.regcache, ir.rm))
+ if (record_arch_list_add_reg (ir.regcache, ir.rm | ir.rex_b))
return -1;
}
else
@@ -5100,9 +5187,32 @@ reswitch:
if (i386_record_lea_modrm (&ir))
return -1;
}
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;
/* lmsw */
case 6:
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+ break;
+ /* invlpg */
+ case 7:
+ if (ir.mod == 3)
+ {
+ if (ir.rm == 0 && ir.regmap[X86_RECORD_R8_REGNUM])
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_GS_REGNUM);
+ else
+ {
+ ir.addr -= 3;
+ opcode = opcode << 8 | ir.modrm;
+ goto no_support;
+ }
+ }
+ else
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
+ break;
+ default:
+ ir.addr -= 3;
+ opcode = opcode << 8 | ir.modrm;
+ goto no_support;
break;
}
break;
@@ -5115,21 +5225,21 @@ reswitch:

/* arpl */
case 0x63:
- ir.ot = ir.dflag ? OT_LONG : OT_WORD;
if (i386_record_modrm (&ir))
return -1;
- if (ir.mod != 3)
- {
- if (i386_record_lea_modrm (&ir))
- return -1;
- }
+ if (ir.mod == 3 || ir.regmap[X86_RECORD_R8_REGNUM])
+ {
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.regmap[X86_RECORD_R8_REGNUM]?
+ (ir.reg | rex_r) : ir.rm);
+ }
else
- {
- if (record_arch_list_add_reg (ir.regcache, ir.rm))
- return -1;
- }
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ {
+ ir.ot = ir.dflag ? OT_LONG : OT_WORD;
+ if (i386_record_lea_modrm (&ir))
+ return -1;
+ }
+ if (!ir.regmap[X86_RECORD_R8_REGNUM])
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* lar */
@@ -5138,13 +5248,19 @@ reswitch:
case 0x0f03:
if (i386_record_modrm (&ir))
return -1;
- if (record_arch_list_add_reg (ir.regcache, ir.reg))
- return -1;
- if (record_arch_list_add_reg (ir.regcache, I386_EFLAGS_REGNUM))
- return -1;
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.reg | rex_r);
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

case 0x0f18:
+ if (i386_record_modrm (&ir))
+ return -1;
+ if (ir.mod == 3 && ir.reg == 3)
+ {
+ ir.addr -= 3;
+ opcode = opcode << 8 | ir.modrm;
+ goto no_support;
+ }
break;

/* nop (multi byte) */
@@ -5165,7 +5281,7 @@ reswitch:
return -1;
if ((ir.modrm & 0xc0) != 0xc0)
{
- ir.addr -= 2;
+ ir.addr -= 3;
opcode = opcode << 8 | ir.modrm;
goto no_support;
}
@@ -5177,16 +5293,12 @@ reswitch:
case 4:
case 8:
if (opcode & 2)
- {
- }
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
else
- {
- if (record_arch_list_add_reg (ir.regcache, ir.rm))
- return -1;
- }
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
break;
default:
- ir.addr -= 2;
+ ir.addr -= 3;
opcode = opcode << 8 | ir.modrm;
goto no_support;
break;
@@ -5202,22 +5314,19 @@ reswitch:
if ((ir.modrm & 0xc0) != 0xc0 || ir.reg == 4
|| ir.reg == 5 || ir.reg >= 8)
{
- ir.addr -= 2;
+ ir.addr -= 3;
opcode = opcode << 8 | ir.modrm;
goto no_support;
}
if (opcode & 2)
- {
- }
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
else
- {
- if (record_arch_list_add_reg (ir.regcache, ir.rm))
- return -1;
- }
+ I386_RECORD_ARCH_LIST_ADD_REG (ir.rm | ir.rex_b);
break;

/* clts */
case 0x0f06:
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_EFLAGS_REGNUM);
break;

/* MMX/SSE/SSE2/PNI support */
@@ -5232,9 +5341,8 @@ reswitch:
break;
}

-/* In the future, Maybe still need to deal with need_dasm */
- if (record_arch_list_add_reg (ir.regcache, I386_EIP_REGNUM))
- return -1;
+ /* In the future, Maybe still need to deal with need_dasm */
+ I386_RECORD_ARCH_LIST_ADD_REG (X86_RECORD_REIP_REGNUM);
if (record_arch_list_add_end ())
return -1;

@@ -5247,6 +5355,15 @@ no_support:
return -1;
}

+static const int i386_record_regmap[] =
+{
+ I386_EAX_REGNUM, I386_ECX_REGNUM, I386_EDX_REGNUM, I386_EBX_REGNUM,
+ I386_ESP_REGNUM, I386_EBP_REGNUM, I386_ESI_REGNUM, I386_EDI_REGNUM,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ I386_EIP_REGNUM, I386_EFLAGS_REGNUM, I386_CS_REGNUM, I386_SS_REGNUM,
+ I386_DS_REGNUM, I386_ES_REGNUM, I386_FS_REGNUM, I386_GS_REGNUM
+};
+
\f
static struct gdbarch *
i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
@@ -5307,6 +5424,8 @@ i386_gdbarch_init (struct gdbarch_info i
tdep->sc_pc_offset = -1;
tdep->sc_sp_offset = -1;

+ tdep->record_regmap = i386_record_regmap;
+
/* The format used for `long double' on almost all i386 targets is
the i387 extended floating-point format. In fact, of all targets
in the GCC 2.95 tree, only OSF/1 does it different, and insists
--- a/i386-tdep.h
+++ b/i386-tdep.h
@@ -111,10 +111,15 @@ struct gdbarch_tdep
struct type *i387_ext_type;

/* Process record/replay target. */
+ /* The map for registers because the AMD64's registers order
+ in GDB is not same as I386 instructions. */
+ const int *record_regmap;
/* Parse intx80 args. */
int (*i386_intx80_record) (struct regcache *regcache);
/* Parse sysenter args. */
int (*i386_sysenter_record) (struct regcache *regcache);
+ /* Parse syscall args. */
+ int (*i386_syscall_record) (struct regcache *regcache);
};

/* Floating-point registers. */
@@ -151,6 +156,36 @@ enum i386_regnum
I386_ST0_REGNUM /* %st(0) */
};

+/* Register numbers of RECORD_REGMAP. */
+
+enum record_i386_regnum
+{
+ X86_RECORD_REAX_REGNUM,
+ X86_RECORD_RECX_REGNUM,
+ X86_RECORD_REDX_REGNUM,
+ X86_RECORD_REBX_REGNUM,
+ X86_RECORD_RESP_REGNUM,
+ X86_RECORD_REBP_REGNUM,
+ X86_RECORD_RESI_REGNUM,
+ X86_RECORD_REDI_REGNUM,
+ X86_RECORD_R8_REGNUM,
+ X86_RECORD_R9_REGNUM,
+ X86_RECORD_R10_REGNUM,
+ X86_RECORD_R11_REGNUM,
+ X86_RECORD_R12_REGNUM,
+ X86_RECORD_R13_REGNUM,
+ X86_RECORD_R14_REGNUM,
+ X86_RECORD_R15_REGNUM,
+ X86_RECORD_REIP_REGNUM,
+ X86_RECORD_EFLAGS_REGNUM,
+ X86_RECORD_CS_REGNUM,
+ X86_RECORD_SS_REGNUM,
+ X86_RECORD_DS_REGNUM,
+ X86_RECORD_ES_REGNUM,
+ X86_RECORD_FS_REGNUM,
+ X86_RECORD_GS_REGNUM,
+};
+
#define I386_NUM_GREGS 16
#define I386_NUM_FREGS 16
#define I386_NUM_XREGS 9