| 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);
|
|
|