Index: gdb/gdbserver/i387-fp.c |
diff --git a/gdb/gdbserver/i387-fp.c b/gdb/gdbserver/i387-fp.c |
index 10e1bc119c8c04da020286c7234b2e8c50723265..1240b67f8bd427436adcd5ae47b9867dcb3f202a 100644 |
--- a/gdb/gdbserver/i387-fp.c |
+++ b/gdb/gdbserver/i387-fp.c |
@@ -1,6 +1,5 @@ |
/* i387-specific utility functions, for the remote server for GDB. |
- Copyright (C) 2000-2002, 2005, 2007-2012 Free Software Foundation, |
- Inc. |
+ Copyright (C) 2000-2013 Free Software Foundation, Inc. |
This file is part of GDB. |
@@ -21,7 +20,8 @@ |
#include "i387-fp.h" |
#include "i386-xstate.h" |
-int num_xmm_registers = 8; |
+static const int num_mpx_bnd_registers = 4; |
+static const int num_mpx_cfg_registers = 2; |
/* Note: These functions preserve the reserved bits in control registers. |
However, gdbserver promptly throws away that information. */ |
@@ -111,6 +111,15 @@ struct i387_xsave { |
/* Space for eight upper 128-bit YMM values, or 16 on x86-64. */ |
unsigned char ymmh_space[256]; |
+ |
+ unsigned char reserved4[128]; |
+ |
+ /* Space for 4 bound registers values of 128 bits. */ |
+ unsigned char mpx_bnd_space[64]; |
+ |
+ /* Space for 2 MPX configuration registers of 64 bits |
+ plus reserved space. */ |
+ unsigned char mpx_cfg_space[16]; |
}; |
void |
@@ -118,7 +127,7 @@ i387_cache_to_fsave (struct regcache *regcache, void *buf) |
{ |
struct i387_fsave *fp = (struct i387_fsave *) buf; |
int i; |
- int st0_regnum = find_regno ("st0"); |
+ int st0_regnum = find_regno (regcache->tdesc, "st0"); |
unsigned long val, val2; |
for (i = 0; i < 8; i++) |
@@ -158,7 +167,7 @@ i387_fsave_to_cache (struct regcache *regcache, const void *buf) |
{ |
struct i387_fsave *fp = (struct i387_fsave *) buf; |
int i; |
- int st0_regnum = find_regno ("st0"); |
+ int st0_regnum = find_regno (regcache->tdesc, "st0"); |
unsigned long val; |
for (i = 0; i < 8; i++) |
@@ -194,9 +203,11 @@ i387_cache_to_fxsave (struct regcache *regcache, void *buf) |
{ |
struct i387_fxsave *fp = (struct i387_fxsave *) buf; |
int i; |
- int st0_regnum = find_regno ("st0"); |
- int xmm0_regnum = find_regno ("xmm0"); |
+ int st0_regnum = find_regno (regcache->tdesc, "st0"); |
+ int xmm0_regnum = find_regno (regcache->tdesc, "xmm0"); |
unsigned long val, val2; |
+ /* Amd64 has 16 xmm regs; I386 has 8 xmm regs. */ |
+ int num_xmm_registers = register_size (regcache->tdesc, 0) == 8 ? 16 : 8; |
for (i = 0; i < 8; i++) |
collect_register (regcache, i + st0_regnum, |
@@ -250,6 +261,8 @@ i387_cache_to_xsave (struct regcache *regcache, void *buf) |
unsigned long long xstate_bv = 0; |
char raw[16]; |
char *p; |
+ /* Amd64 has 16 xmm regs; I386 has 8 xmm regs. */ |
+ int num_xmm_registers = register_size (regcache->tdesc, 0) == 8 ? 16 : 8; |
/* The supported bits in `xstat_bv' are 1 byte. Clear part in |
vector registers if its bit in xstat_bv is zero. */ |
@@ -270,12 +283,20 @@ i387_cache_to_xsave (struct regcache *regcache, void *buf) |
if ((clear_bv & I386_XSTATE_AVX)) |
for (i = 0; i < num_xmm_registers; i++) |
memset (((char *) &fp->ymmh_space[0]) + i * 16, 0, 16); |
+ |
+ if ((clear_bv & I386_XSTATE_BNDREGS)) |
+ for (i = 0; i < num_mpx_bnd_registers; i++) |
+ memset (((char *) &fp->mpx_bnd_space[0]) + i * 16, 0, 16); |
+ |
+ if ((clear_bv & I386_XSTATE_BNDCFG)) |
+ for (i = 0; i < num_mpx_cfg_registers; i++) |
+ memset (((char *) &fp->mpx_cfg_space[0]) + i * 8, 0, 8); |
} |
/* Check if any x87 registers are changed. */ |
if ((x86_xcr0 & I386_XSTATE_X87)) |
{ |
- int st0_regnum = find_regno ("st0"); |
+ int st0_regnum = find_regno (regcache->tdesc, "st0"); |
for (i = 0; i < 8; i++) |
{ |
@@ -292,7 +313,7 @@ i387_cache_to_xsave (struct regcache *regcache, void *buf) |
/* Check if any SSE registers are changed. */ |
if ((x86_xcr0 & I386_XSTATE_SSE)) |
{ |
- int xmm0_regnum = find_regno ("xmm0"); |
+ int xmm0_regnum = find_regno (regcache->tdesc, "xmm0"); |
for (i = 0; i < num_xmm_registers; i++) |
{ |
@@ -309,7 +330,7 @@ i387_cache_to_xsave (struct regcache *regcache, void *buf) |
/* Check if any AVX registers are changed. */ |
if ((x86_xcr0 & I386_XSTATE_AVX)) |
{ |
- int ymm0h_regnum = find_regno ("ymm0h"); |
+ int ymm0h_regnum = find_regno (regcache->tdesc, "ymm0h"); |
for (i = 0; i < num_xmm_registers; i++) |
{ |
@@ -323,6 +344,40 @@ i387_cache_to_xsave (struct regcache *regcache, void *buf) |
} |
} |
+ /* Check if any bound register has changed. */ |
+ if ((x86_xcr0 & I386_XSTATE_BNDREGS)) |
+ { |
+ int bnd0r_regnum = find_regno (regcache->tdesc, "bnd0raw"); |
+ |
+ for (i = 0; i < num_mpx_bnd_registers; i++) |
+ { |
+ collect_register (regcache, i + bnd0r_regnum, raw); |
+ p = ((char *) &fp->mpx_bnd_space[0]) + i * 16; |
+ if (memcmp (raw, p, 16)) |
+ { |
+ xstate_bv |= I386_XSTATE_BNDREGS; |
+ memcpy (p, raw, 16); |
+ } |
+ } |
+ } |
+ |
+ /* Check if any status register has changed. */ |
+ if ((x86_xcr0 & I386_XSTATE_BNDCFG)) |
+ { |
+ int bndcfg_regnum = find_regno (regcache->tdesc, "bndcfgu"); |
+ |
+ for (i = 0; i < num_mpx_cfg_registers; i++) |
+ { |
+ collect_register (regcache, i + bndcfg_regnum, raw); |
+ p = ((char *) &fp->mpx_cfg_space[0]) + i * 8; |
+ if (memcmp (raw, p, 8)) |
+ { |
+ xstate_bv |= I386_XSTATE_BNDCFG; |
+ memcpy (p, raw, 8); |
+ } |
+ } |
+ } |
+ |
/* Update the corresponding bits in xstate_bv if any SSE/AVX |
registers are changed. */ |
fp->xstate_bv |= xstate_bv; |
@@ -414,9 +469,11 @@ i387_fxsave_to_cache (struct regcache *regcache, const void *buf) |
{ |
struct i387_fxsave *fp = (struct i387_fxsave *) buf; |
int i, top; |
- int st0_regnum = find_regno ("st0"); |
- int xmm0_regnum = find_regno ("xmm0"); |
+ int st0_regnum = find_regno (regcache->tdesc, "st0"); |
+ int xmm0_regnum = find_regno (regcache->tdesc, "xmm0"); |
unsigned long val; |
+ /* Amd64 has 16 xmm regs; I386 has 8 xmm regs. */ |
+ int num_xmm_registers = register_size (regcache->tdesc, 0) == 8 ? 16 : 8; |
for (i = 0; i < 8; i++) |
supply_register (regcache, i + st0_regnum, |
@@ -469,6 +526,8 @@ i387_xsave_to_cache (struct regcache *regcache, const void *buf) |
unsigned long val; |
unsigned int clear_bv; |
gdb_byte *p; |
+ /* Amd64 has 16 xmm regs; I386 has 8 xmm regs. */ |
+ int num_xmm_registers = register_size (regcache->tdesc, 0) == 8 ? 16 : 8; |
/* The supported bits in `xstat_bv' are 1 byte. Clear part in |
vector registers if its bit in xstat_bv is zero. */ |
@@ -477,7 +536,7 @@ i387_xsave_to_cache (struct regcache *regcache, const void *buf) |
/* Check if any x87 registers are changed. */ |
if ((x86_xcr0 & I386_XSTATE_X87) != 0) |
{ |
- int st0_regnum = find_regno ("st0"); |
+ int st0_regnum = find_regno (regcache->tdesc, "st0"); |
if ((clear_bv & I386_XSTATE_X87) != 0) |
{ |
@@ -494,7 +553,7 @@ i387_xsave_to_cache (struct regcache *regcache, const void *buf) |
if ((x86_xcr0 & I386_XSTATE_SSE) != 0) |
{ |
- int xmm0_regnum = find_regno ("xmm0"); |
+ int xmm0_regnum = find_regno (regcache->tdesc, "xmm0"); |
if ((clear_bv & I386_XSTATE_SSE)) |
{ |
@@ -511,7 +570,7 @@ i387_xsave_to_cache (struct regcache *regcache, const void *buf) |
if ((x86_xcr0 & I386_XSTATE_AVX) != 0) |
{ |
- int ymm0h_regnum = find_regno ("ymm0h"); |
+ int ymm0h_regnum = find_regno (regcache->tdesc, "ymm0h"); |
if ((clear_bv & I386_XSTATE_AVX) != 0) |
{ |
@@ -526,6 +585,42 @@ i387_xsave_to_cache (struct regcache *regcache, const void *buf) |
} |
} |
+ if ((x86_xcr0 & I386_XSTATE_BNDREGS)) |
+ { |
+ int bnd0r_regnum = find_regno (regcache->tdesc, "bnd0raw"); |
+ |
+ |
+ if ((clear_bv & I386_XSTATE_BNDREGS) != 0) |
+ { |
+ for (i = 0; i < num_mpx_bnd_registers; i++) |
+ supply_register_zeroed (regcache, i + bnd0r_regnum); |
+ } |
+ else |
+ { |
+ p = (gdb_byte *) &fp->mpx_bnd_space[0]; |
+ for (i = 0; i < num_mpx_bnd_registers; i++) |
+ supply_register (regcache, i + bnd0r_regnum, p + i * 16); |
+ } |
+ |
+ } |
+ |
+ if ((x86_xcr0 & I386_XSTATE_BNDCFG)) |
+ { |
+ int bndcfg_regnum = find_regno (regcache->tdesc, "bndcfgu"); |
+ |
+ if ((clear_bv & I386_XSTATE_BNDCFG) != 0) |
+ { |
+ for (i = 0; i < num_mpx_cfg_registers; i++) |
+ supply_register_zeroed (regcache, i + bndcfg_regnum); |
+ } |
+ else |
+ { |
+ p = (gdb_byte *) &fp->mpx_cfg_space[0]; |
+ for (i = 0; i < num_mpx_cfg_registers; i++) |
+ supply_register (regcache, i + bndcfg_regnum, p + i * 8); |
+ } |
+ } |
+ |
supply_register_by_name (regcache, "fioff", &fp->fioff); |
supply_register_by_name (regcache, "fooff", &fp->fooff); |
supply_register_by_name (regcache, "mxcsr", &fp->mxcsr); |