This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH 2/2] x86_64-windows GDB crash due to fs_base/gs_base registers


Hi Joel,

I spent a bit playing with this today.  See comments below.

On 06/25/2018 07:55 PM, Joel Brobecker wrote:
> GDB is currently crashing anytime we try to access the fs_base/gs_base
> registers, either to read them, or to write them. This can be observed
> under various scenarios:
>   - Explicit reference to those registers (eg: print $fs_base) --
>     probably relatively rare;
>   - Calling a function in the inferior, with the crash happening
>     because we are trying to read those registers in order to save
>     their value ahead of making the function call;
>   - Just a plain "info registers";
> 
> The crash was introduced by the following commit:
> 
>     | commit 48aeef91c248291dd03583798904612426b1f40a
>     | Date:   Mon Jun 26 18:14:43 2017 -0700
>     | Subject: Include the fs_base and gs_base registers in amd64 target descriptions.
> 
> The Windows-nat implementation was unfortunately not prepared to deal
> with those new registers. In particular, the way it fetches registers
> is done by using a table where the index is the register number, and
> the value at that index is the offset in the area in the thread's CONTEXT
> data where the corresponding register value is stored.
> 
> For instance, in amd64-windows-nat.c, we can find the mappings static
> array containing the following 57 elements in it:
> 
>     #define context_offset(x) (offsetof (CONTEXT, x))
>     static const int mappings[] =
>     {
>       context_offset (Rax),
>       [...]
>       context_offset (FloatSave.MxCsr)
>     };
> 
> That array is then used by windows_fetch_one_register via:
> 
>     char *context_offset = ((char *) &th->context) + mappings[r];
> 
> The problem is that fs_base's register number is 172, which is
> well past the end of the mappings array (57 elements in total).
> We end up getting an undefined offset, which happens to be so large
> that it then causes the address where we try to read the register
> value (a little bit later) to be invalid, thus crashing GDB with
> a SEGV.
> 
> This patch changes the approach taken for determining the offset
> of a given register. Instead of the target-specific part of
> window-nat (i.e. i386-windows-nat.c and amd64-windows-nat.c)
> registering a table of offsets to windows-nat.c, they now
> register functions that, given a register number, return an
> offset. That way, we can more explicitly match register numbers
> to specific offsets, which is a much less fragile, because
> it doesn't depend on a register numbering which might change.

The gdb register numbering cannot be reordered, because it would break
remote debugging when the remote target does not supply an explicit
xml target description.  The only thing that can be done is add
new registers at the end.  

So to fix this, we could also make windows_nat_target::{fetch,store}_registers
check whether the requested register is within the mappings array.  We could
do that by simply changing the 'mappings' global from a plain pointer to a
gdb::array_view for example (which stores the array's size).  I suspect the
current table based approach generates a little better code (the compiler may
end up generating a table anyway from the switch/case in your patch, but it's
not garanteed), though it shouldn't really matter in practice.

But see below.

> It is also resilient to the addition of new registers in the
> fugure.

"fugure" -> "future"

> 
> And regarding fs_base and gs_base themselves, it appears managing
> those registers might not be supported; could not find a field
> in CONTEXT that would correspond to those registers. So this patch
> treats those two registers as not available. Eg:
> 
>     (gdb) info registers
>     [...]
>     fs_base        <unavailable>
>     gs_base        <unavailable>
> 

Since Windows doesn't expose these to userspace, I'm thinking that it
doesn't make much sense to show the registers at all?  The (xml) target
features are designed exactly such that if you don't have some
optional feature (like org.gnu.gdb.i386.segments), then the corresponding
registers don't exist at all in gdb.  

The attached patch implements that.  It makes amd64_windows_init_abi
create a target description without the org.gnu.gdb.i386.segments
feature.  Seems to work here, smoke testing with cross gdb targetting Windows and
doing "maint print remote-registers", and also, connecting that gdb to a Windows
gdbserver running under wine.

Before / after diff:

  (gdb) info registers 
  rax            0x0                 0
  rbx            0x7b8127f0          2072061936
  rcx            0x0                 0
  rdx            0x0                 0
  rsi            0x7b8127f0          2072061936
  rdi            0x7b8127f0          2072061936
  rbp            0x354ffd0           0x354ffd0
  rsp            0x354fdc8           0x354fdc8
  r8             0x354fcf0           55901424
  r9             0x8                 8
  r10            0x8                 8
  r11            0x246               582
  r12            0x0                 0
  r13            0x0                 0
  r14            0x0                 0
  r15            0x0                 0
  rip            0x7bcafbb5          0x7bcafbb5
  eflags         0x202               [ IF ]
  cs             0x33                51
  ss             0x202002b           33685547
  ds             0x0                 0
  es             0x0                 0
  fs             0x0                 0
  gs             0x2b0000            2818048
- fs_base        <unavailable>
- gs_base        <unavailable>
  (gdb)




> diff --git a/gdb/amd64-windows-nat.c b/gdb/amd64-windows-nat.c
> index 0c7dbed..61aed8d 100644
> --- a/gdb/amd64-windows-nat.c
> +++ b/gdb/amd64-windows-nat.c
> @@ -22,70 +22,86 @@
>  
>  #include <windows.h>
>  
> -#define context_offset(x) (offsetof (CONTEXT, x))
> -static const int mappings[] =
> +/* See context_register_offset_ftype.  */
> +
> +static int
> +amd64_windows_context_register_offset (int regnum)
>  {
> -  context_offset (Rax),
> -  context_offset (Rbx),
> -  context_offset (Rcx),
> -  context_offset (Rdx),
> -  context_offset (Rsi),
> -  context_offset (Rdi),
> -  context_offset (Rbp),
> -  context_offset (Rsp),
> -  context_offset (R8),
> -  context_offset (R9),
> -  context_offset (R10),
> -  context_offset (R11),
> -  context_offset (R12),
> -  context_offset (R13),
> -  context_offset (R14),
> -  context_offset (R15),
> -  context_offset (Rip),
> -  context_offset (EFlags),
> -  context_offset (SegCs),
> -  context_offset (SegSs),
> -  context_offset (SegDs),
> -  context_offset (SegEs),
> -  context_offset (SegFs),
> -  context_offset (SegGs),
> -  context_offset (FloatSave.FloatRegisters[0]),
> -  context_offset (FloatSave.FloatRegisters[1]),
> -  context_offset (FloatSave.FloatRegisters[2]),
> -  context_offset (FloatSave.FloatRegisters[3]),
> -  context_offset (FloatSave.FloatRegisters[4]),
> -  context_offset (FloatSave.FloatRegisters[5]),
> -  context_offset (FloatSave.FloatRegisters[6]),
> -  context_offset (FloatSave.FloatRegisters[7]),
> -  context_offset (FloatSave.ControlWord),
> -  context_offset (FloatSave.StatusWord),
> -  context_offset (FloatSave.TagWord),
> -  context_offset (FloatSave.ErrorSelector),
> -  context_offset (FloatSave.ErrorOffset),
> -  context_offset (FloatSave.DataSelector),
> -  context_offset (FloatSave.DataOffset),
> -  context_offset (FloatSave.ErrorSelector)
> -  /* XMM0-7 */ ,
> -  context_offset (Xmm0),
> -  context_offset (Xmm1),
> -  context_offset (Xmm2),
> -  context_offset (Xmm3),
> -  context_offset (Xmm4),
> -  context_offset (Xmm5),
> -  context_offset (Xmm6),
> -  context_offset (Xmm7),
> -  context_offset (Xmm8),
> -  context_offset (Xmm9),
> -  context_offset (Xmm10),
> -  context_offset (Xmm11),
> -  context_offset (Xmm12),
> -  context_offset (Xmm13),
> -  context_offset (Xmm14),
> -  context_offset (Xmm15),
> -  /* MXCSR */
> -  context_offset (FloatSave.MxCsr)
> -};
> +#define context_offset(x) (offsetof (CONTEXT, x))
> +  switch (regnum)
> +    {
> +      case AMD64_RAX_REGNUM: return context_offset (Rax);
> +      case AMD64_RBX_REGNUM: return context_offset (Rbx);
> +      case AMD64_RCX_REGNUM: return context_offset (Rcx);
> +      case AMD64_RDX_REGNUM: return context_offset (Rdx);
> +      case AMD64_RSI_REGNUM: return context_offset (Rsi);
> +      case AMD64_RDI_REGNUM: return context_offset (Rdi);
> +      case AMD64_RBP_REGNUM: return context_offset (Rbp);
> +      case AMD64_RSP_REGNUM: return context_offset (Rsp);
> +      case AMD64_R8_REGNUM: return context_offset (R8);
> +      case AMD64_R9_REGNUM: return context_offset (R9);
> +      case AMD64_R10_REGNUM: return context_offset (R10);
> +      case AMD64_R11_REGNUM: return context_offset (R11);
> +      case AMD64_R12_REGNUM: return context_offset (R12);
> +      case AMD64_R13_REGNUM: return context_offset (R13);
> +      case AMD64_R14_REGNUM: return context_offset (R14);
> +      case AMD64_R15_REGNUM: return context_offset (R15);
> +      case AMD64_RIP_REGNUM: return context_offset (Rip);
> +      case AMD64_EFLAGS_REGNUM: return context_offset (EFlags);
> +      case AMD64_CS_REGNUM: return context_offset (SegCs);
> +      case AMD64_SS_REGNUM: return context_offset (SegSs);
> +      case AMD64_DS_REGNUM: return context_offset (SegDs);
> +      case AMD64_ES_REGNUM: return context_offset (SegEs);
> +      case AMD64_FS_REGNUM: return context_offset (SegFs);
> +      case AMD64_GS_REGNUM: return context_offset (SegGs);
> +      case AMD64_ST0_REGNUM:
> +	return context_offset (FloatSave.FloatRegisters[0]);
> +      case AMD64_ST1_REGNUM:
> +	return context_offset (FloatSave.FloatRegisters[1]);
> +      case AMD64_ST2_REGNUM:
> +	return context_offset (FloatSave.FloatRegisters[2]);
> +      case AMD64_ST3_REGNUM:
> +	return context_offset (FloatSave.FloatRegisters[3]);
> +      case AMD64_ST4_REGNUM:
> +	return context_offset (FloatSave.FloatRegisters[4]);
> +      case AMD64_ST5_REGNUM:
> +	return context_offset (FloatSave.FloatRegisters[5]);
> +      case AMD64_ST6_REGNUM:
> +	return context_offset (FloatSave.FloatRegisters[6]);
> +      case AMD64_ST7_REGNUM:
> +	return context_offset (FloatSave.FloatRegisters[7]);
> +      case AMD64_FCTRL_REGNUM: return context_offset (FloatSave.ControlWord);
> +      case AMD64_FSTAT_REGNUM: return context_offset (FloatSave.StatusWord);
> +      case AMD64_FTAG_REGNUM: return context_offset (FloatSave.TagWord);
> +      case AMD64_FISEG_REGNUM: return context_offset (FloatSave.ErrorSelector);
> +      case AMD64_FIOFF_REGNUM: return context_offset (FloatSave.ErrorOffset);
> +      case AMD64_FOSEG_REGNUM: return context_offset (FloatSave.DataSelector);
> +      case AMD64_FOOFF_REGNUM: return context_offset (FloatSave.DataOffset);
> +      case AMD64_FOP_REGNUM: return context_offset (FloatSave.ErrorSelector);
> +      case AMD64_XMM0_REGNUM: return context_offset (Xmm0);
> +      case AMD64_XMM1_REGNUM: return context_offset (Xmm1);
> +      case AMD64_XMM2_REGNUM: return context_offset (Xmm2);
> +      case AMD64_XMM3_REGNUM: return context_offset (Xmm3);
> +      case AMD64_XMM4_REGNUM: return context_offset (Xmm4);
> +      case AMD64_XMM5_REGNUM: return context_offset (Xmm5);
> +      case AMD64_XMM6_REGNUM: return context_offset (Xmm6);
> +      case AMD64_XMM7_REGNUM: return context_offset (Xmm7);
> +      case AMD64_XMM8_REGNUM: return context_offset (Xmm8);
> +      case AMD64_XMM9_REGNUM: return context_offset (Xmm9);
> +      case AMD64_XMM10_REGNUM: return context_offset (Xmm10);
> +      case AMD64_XMM11_REGNUM: return context_offset (Xmm11);
> +      case AMD64_XMM12_REGNUM: return context_offset (Xmm12);
> +      case AMD64_XMM13_REGNUM: return context_offset (Xmm13);
> +      case AMD64_XMM14_REGNUM: return context_offset (Xmm14);
> +      case AMD64_XMM15_REGNUM: return context_offset (Xmm15);
> +      case AMD64_MXCSR_REGNUM: return context_offset (FloatSave.MxCsr);

I'd suggest writing the above like this:

#define CASE(GDB, CTX_REG) \
      case GDB_REG: return offsetof (CONTEXT, CTX_REG)

  switch (regnum)
    {
      CASE (AMD64_RAX_REGNUM, Rax);
      CASE (AMD64_RBX_REGNUM, Rbx);
      ...



> +      case AMD64_FSBASE_REGNUM: return -1 /* Not in CONTEXT struct.  */;
> +      case AMD64_GSBASE_REGNUM: return -1 /* Not in CONTEXT struct.  */;
> +   }
>  #undef context_offset
> +  
> +  return -1;
> +}
>  
>  /* segment_register_p_ftype implementation for amd64.  */
>  
> @@ -98,7 +114,7 @@ amd64_windows_segment_register_p (int regnum)
>  void
>  _initialize_amd64_windows_nat (void)
>  {
> -  windows_set_context_register_offsets (mappings);
> +  windows_set_context_register_offset (amd64_windows_context_register_offset);
>    windows_set_segment_register_p (amd64_windows_segment_register_p);
>    x86_set_debug_register_length (8);
>  }
> diff --git a/gdb/i386-tdep.h b/gdb/i386-tdep.h
> index 81a93f1..8cfa935 100644
> --- a/gdb/i386-tdep.h
> +++ b/gdb/i386-tdep.h
> @@ -285,6 +285,29 @@ enum i386_regnum
>    I386_FS_REGNUM,		/* %fs */
>    I386_GS_REGNUM,		/* %gs */
>    I386_ST0_REGNUM,		/* %st(0) */
> +  I386_ST1_REGNUM,		/* %st(1) */
> +  I386_ST2_REGNUM,		/* %st(2) */
> +  I386_ST3_REGNUM,		/* %st(3) */
> +  I386_ST4_REGNUM,		/* %st(4) */
> +  I386_ST5_REGNUM,		/* %st(5) */
> +  I386_ST6_REGNUM,		/* %st(6) */
> +  I386_ST7_REGNUM,		/* %st(7) */
> +  I386_FCTRL_REGNUM,
> +  I386_FSTAT_REGNUM,
> +  I386_FTAG_REGNUM,
> +  I386_FISEG_REGNUM,
> +  I386_FIOFF_REGNUM,
> +  I386_FOSEG_REGNUM,
> +  I386_FOOFF_REGNUM,
> +  I386_FOP_REGNUM,
> +  I386_XMM0_REGNUM,		/* %xmm0 */
> +  I386_XMM1_REGNUM,		/* %xmm1 */
> +  I386_XMM2_REGNUM,		/* %xmm2 */
> +  I386_XMM3_REGNUM,		/* %xmm3 */
> +  I386_XMM4_REGNUM,		/* %xmm4 */
> +  I386_XMM5_REGNUM,		/* %xmm5 */
> +  I386_XMM6_REGNUM,		/* %xmm6 */
> +  I386_XMM7_REGNUM,		/* %xmm7 */
>    I386_MXCSR_REGNUM = 40,	/* %mxcsr */ 
>    I386_YMM0H_REGNUM,		/* %ymm0h */
>    I386_YMM7H_REGNUM = I386_YMM0H_REGNUM + 7,
> diff --git a/gdb/i386-windows-nat.c b/gdb/i386-windows-nat.c
> index 9efe184..1f65774 100644
> --- a/gdb/i386-windows-nat.c
> +++ b/gdb/i386-windows-nat.c
> @@ -22,55 +22,71 @@
>  
>  #include <windows.h>
>  
> -#define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
> -static const int mappings[] =
> +/* See context_register_offset_ftype.  */
> +
> +static int
> +i386_windows_context_register_offset (int regnum)
>  {
> -  context_offset (Eax),
> -  context_offset (Ecx),
> -  context_offset (Edx),
> -  context_offset (Ebx),
> -  context_offset (Esp),
> -  context_offset (Ebp),
> -  context_offset (Esi),
> -  context_offset (Edi),
> -  context_offset (Eip),
> -  context_offset (EFlags),
> -  context_offset (SegCs),
> -  context_offset (SegSs),
> -  context_offset (SegDs),
> -  context_offset (SegEs),
> -  context_offset (SegFs),
> -  context_offset (SegGs),
> -  context_offset (FloatSave.RegisterArea[0 * 10]),
> -  context_offset (FloatSave.RegisterArea[1 * 10]),
> -  context_offset (FloatSave.RegisterArea[2 * 10]),
> -  context_offset (FloatSave.RegisterArea[3 * 10]),
> -  context_offset (FloatSave.RegisterArea[4 * 10]),
> -  context_offset (FloatSave.RegisterArea[5 * 10]),
> -  context_offset (FloatSave.RegisterArea[6 * 10]),
> -  context_offset (FloatSave.RegisterArea[7 * 10]),
> -  context_offset (FloatSave.ControlWord),
> -  context_offset (FloatSave.StatusWord),
> -  context_offset (FloatSave.TagWord),
> -  context_offset (FloatSave.ErrorSelector),
> -  context_offset (FloatSave.ErrorOffset),
> -  context_offset (FloatSave.DataSelector),
> -  context_offset (FloatSave.DataOffset),
> -  context_offset (FloatSave.ErrorSelector)
> -  /* XMM0-7 */ ,
> -  context_offset (ExtendedRegisters[10*16]),
> -  context_offset (ExtendedRegisters[11*16]),
> -  context_offset (ExtendedRegisters[12*16]),
> -  context_offset (ExtendedRegisters[13*16]),
> -  context_offset (ExtendedRegisters[14*16]),
> -  context_offset (ExtendedRegisters[15*16]),
> -  context_offset (ExtendedRegisters[16*16]),
> -  context_offset (ExtendedRegisters[17*16]),
> -  /* MXCSR */
> -  context_offset (ExtendedRegisters[24])
> -};
> +#define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
> +  switch (regnum)
> +    {
> +      case I386_EAX_REGNUM: return context_offset (Eax);
> +      case I386_ECX_REGNUM: return context_offset (Ecx);
> +      case I386_EDX_REGNUM: return context_offset (Edx);
> +      case I386_EBX_REGNUM: return context_offset (Ebx);
> +      case I386_ESP_REGNUM: return context_offset (Esp);
> +      case I386_EBP_REGNUM: return context_offset (Ebp);
> +      case I386_ESI_REGNUM: return context_offset (Esi);
> +      case I386_EDI_REGNUM: return context_offset (Edi);
> +      case I386_EIP_REGNUM: return context_offset (Eip);
> +      case I386_EFLAGS_REGNUM: return context_offset (EFlags);
> +      case I386_CS_REGNUM: return context_offset (SegCs);
> +      case I386_SS_REGNUM: return context_offset (SegSs);
> +      case I386_DS_REGNUM: return context_offset (SegDs);
> +      case I386_ES_REGNUM: return context_offset (SegEs);
> +      case I386_FS_REGNUM: return context_offset (SegFs);
> +      case I386_GS_REGNUM: return context_offset (SegGs);
> +      case I386_ST0_REGNUM:
> +	return context_offset (FloatSave.RegisterArea[0 * 10]);
> +      case I386_ST1_REGNUM:
> +	return context_offset (FloatSave.RegisterArea[1 * 10]);
> +      case I386_ST2_REGNUM:
> +	return context_offset (FloatSave.RegisterArea[2 * 10]);
> +      case I386_ST3_REGNUM:
> +	return context_offset (FloatSave.RegisterArea[3 * 10]);
> +      case I386_ST4_REGNUM:
> +	return context_offset (FloatSave.RegisterArea[4 * 10]);
> +      case I386_ST5_REGNUM:
> +	return context_offset (FloatSave.RegisterArea[5 * 10]);
> +      case I386_ST6_REGNUM:
> +	return context_offset (FloatSave.RegisterArea[6 * 10]);
> +      case I386_ST7_REGNUM:
> +	return context_offset (FloatSave.RegisterArea[7 * 10]);
> +      case I386_FCTRL_REGNUM: return context_offset (FloatSave.ControlWord);
> +      case I386_FSTAT_REGNUM: return context_offset (FloatSave.StatusWord);
> +      case I386_FTAG_REGNUM: return context_offset (FloatSave.TagWord);
> +      case I386_FISEG_REGNUM: return context_offset (FloatSave.ErrorSelector);
> +      case I386_FIOFF_REGNUM: return context_offset (FloatSave.ErrorOffset);
> +      case I386_FOSEG_REGNUM: return context_offset (FloatSave.DataSelector);
> +      case I386_FOOFF_REGNUM: return context_offset (FloatSave.DataOffset);
> +      case I386_FOP_REGNUM: return context_offset (FloatSave.ErrorSelector);
> +      /* XMM0-7 */
> +      case I386_XMM0_REGNUM: return context_offset (ExtendedRegisters[10*16]);
> +      case I386_XMM1_REGNUM: return context_offset (ExtendedRegisters[11*16]);
> +      case I386_XMM2_REGNUM: return context_offset (ExtendedRegisters[12*16]);
> +      case I386_XMM3_REGNUM: return context_offset (ExtendedRegisters[13*16]);
> +      case I386_XMM4_REGNUM: return context_offset (ExtendedRegisters[14*16]);
> +      case I386_XMM5_REGNUM: return context_offset (ExtendedRegisters[15*16]);
> +      case I386_XMM6_REGNUM: return context_offset (ExtendedRegisters[16*16]);
> +      case I386_XMM7_REGNUM: return context_offset (ExtendedRegisters[17*16]);
> +      /* MXCSR */
> +      case I386_MXCSR_REGNUM: return context_offset (ExtendedRegisters[24]);

Ditto.

Note this would create a bit of divergence with the gdbserver
implementation of the same functions.

Thanks,
Pedro Alves
>From cebec834837380395b9ff1288533d65ffda80d74 Mon Sep 17 00:00:00 2001
From: Pedro Alves <palves@redhat.com>
Date: Tue, 26 Jun 2018 16:33:27 +0100
Subject: [PATCH] windows

---
 gdb/amd64-linux-tdep.c         |  3 ++-
 gdb/amd64-tdep.c               | 17 ++++++++++-------
 gdb/amd64-tdep.h               |  3 ++-
 gdb/amd64-windows-tdep.c       |  2 +-
 gdb/arch/amd64.c               |  6 ++++--
 gdb/arch/amd64.h               |  2 +-
 gdb/gdbserver/win32-i386-low.c |  2 +-
 7 files changed, 21 insertions(+), 14 deletions(-)

diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c
index ef9248d708d..7fe37d83f69 100644
--- a/gdb/amd64-linux-tdep.c
+++ b/gdb/amd64-linux-tdep.c
@@ -1594,7 +1594,8 @@ amd64_linux_read_description (uint64_t xcr0_features_bit, bool is_x32)
     }
 
   if (*tdesc == NULL)
-    *tdesc = amd64_create_target_description (xcr0_features_bit, is_x32, true);
+    *tdesc = amd64_create_target_description (xcr0_features_bit, is_x32,
+					      true, true);
 
   return *tdesc;
 }
diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c
index 9f8f018dd15..190e086ebfe 100644
--- a/gdb/amd64-tdep.c
+++ b/gdb/amd64-tdep.c
@@ -3225,7 +3225,8 @@ amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch,
 static void
 amd64_none_init_abi (gdbarch_info info, gdbarch *arch)
 {
-  amd64_init_abi (info, arch, amd64_target_description (X86_XSTATE_SSE_MASK));
+  amd64_init_abi (info, arch, amd64_target_description (X86_XSTATE_SSE_MASK,
+							true));
 }
 
 static struct type *
@@ -3266,25 +3267,27 @@ static void
 amd64_x32_none_init_abi (gdbarch_info info, gdbarch *arch)
 {
   amd64_x32_init_abi (info, arch,
-		      amd64_target_description (X86_XSTATE_SSE_MASK));
+		      amd64_target_description (X86_XSTATE_SSE_MASK, true));
 }
 
 /* Return the target description for a specified XSAVE feature mask.  */
 
 const struct target_desc *
-amd64_target_description (uint64_t xcr0)
+amd64_target_description (uint64_t xcr0, bool segments)
 {
   static target_desc *amd64_tdescs \
-    [2/*AVX*/][2/*MPX*/][2/*AVX512*/][2/*PKRU*/] = {};
+    [2/*AVX*/][2/*MPX*/][2/*AVX512*/][2/*PKRU*/][2/*segments*/] = {};
   target_desc **tdesc;
 
   tdesc = &amd64_tdescs[(xcr0 & X86_XSTATE_AVX) ? 1 : 0]
     [(xcr0 & X86_XSTATE_MPX) ? 1 : 0]
     [(xcr0 & X86_XSTATE_AVX512) ? 1 : 0]
-    [(xcr0 & X86_XSTATE_PKRU) ? 1 : 0];
+    [(xcr0 & X86_XSTATE_PKRU) ? 1 : 0]
+    [segments ? 1 : 0];
 
   if (*tdesc == NULL)
-    *tdesc = amd64_create_target_description (xcr0, false, false);
+    *tdesc = amd64_create_target_description (xcr0, false, false,
+					      segments);
 
   return *tdesc;
 }
@@ -3314,7 +3317,7 @@ _initialize_amd64_tdep (void)
 
   for (auto &a : xml_masks)
     {
-      auto tdesc = amd64_target_description (a.mask);
+      auto tdesc = amd64_target_description (a.mask, true);
 
       selftests::record_xml_tdesc (a.xml, tdesc);
     }
diff --git a/gdb/amd64-tdep.h b/gdb/amd64-tdep.h
index 7d3791ad936..94e012632ff 100644
--- a/gdb/amd64-tdep.h
+++ b/gdb/amd64-tdep.h
@@ -106,7 +106,8 @@ extern void amd64_init_abi (struct gdbarch_info info,
 extern void amd64_x32_init_abi (struct gdbarch_info info,
 				struct gdbarch *gdbarch,
 				const target_desc *default_tdesc);
-extern const struct target_desc *amd64_target_description (uint64_t xcr0);
+extern const struct target_desc *amd64_target_description (uint64_t xcr0,
+							   bool segments);
 
 /* Fill register REGNUM in REGCACHE with the appropriate
    floating-point or SSE register value from *FXSAVE.  If REGNUM is
diff --git a/gdb/amd64-windows-tdep.c b/gdb/amd64-windows-tdep.c
index 83a7f2f32ed..904875baccd 100644
--- a/gdb/amd64-windows-tdep.c
+++ b/gdb/amd64-windows-tdep.c
@@ -1226,7 +1226,7 @@ amd64_windows_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   frame_unwind_append_unwinder (gdbarch, &amd64_windows_frame_unwind);
 
   amd64_init_abi (info, gdbarch,
-		  amd64_target_description (X86_XSTATE_SSE_MASK));
+		  amd64_target_description (X86_XSTATE_SSE_MASK, false));
 
   windows_init_abi (info, gdbarch);
 
diff --git a/gdb/arch/amd64.c b/gdb/arch/amd64.c
index d31d8f1f75a..3a289df12a5 100644
--- a/gdb/arch/amd64.c
+++ b/gdb/arch/amd64.c
@@ -36,7 +36,8 @@
    descriptions for Linux.  */
 
 target_desc *
-amd64_create_target_description (uint64_t xcr0, bool is_x32, bool is_linux)
+amd64_create_target_description (uint64_t xcr0, bool is_x32, bool is_linux,
+				 bool segments)
 {
   target_desc *tdesc = allocate_target_description ();
 
@@ -57,7 +58,8 @@ amd64_create_target_description (uint64_t xcr0, bool is_x32, bool is_linux)
   regnum = create_feature_i386_64bit_sse (tdesc, regnum);
   if (is_linux)
     regnum = create_feature_i386_64bit_linux (tdesc, regnum);
-  regnum = create_feature_i386_64bit_segments (tdesc, regnum);
+  if (segments)
+    regnum = create_feature_i386_64bit_segments (tdesc, regnum);
 
   if (xcr0 & X86_XSTATE_AVX)
     regnum = create_feature_i386_64bit_avx (tdesc, regnum);
diff --git a/gdb/arch/amd64.h b/gdb/arch/amd64.h
index c0c4dc27efe..4a659657da1 100644
--- a/gdb/arch/amd64.h
+++ b/gdb/arch/amd64.h
@@ -19,4 +19,4 @@
 #include <stdint.h>
 
 target_desc *amd64_create_target_description (uint64_t xcr0, bool is_x32,
-					      bool is_linux);
+					      bool is_linux, bool segments);
diff --git a/gdb/gdbserver/win32-i386-low.c b/gdb/gdbserver/win32-i386-low.c
index 16fe2c85b2a..62221688cbd 100644
--- a/gdb/gdbserver/win32-i386-low.c
+++ b/gdb/gdbserver/win32-i386-low.c
@@ -436,7 +436,7 @@ i386_arch_setup (void)
 
 #ifdef __x86_64__
   tdesc = amd64_create_target_description (X86_XSTATE_SSE_MASK, false,
-						 false);
+					   false, false);
   const char **expedite_regs = amd64_expedite_regs;
 #else
   tdesc = i386_create_target_description (X86_XSTATE_SSE_MASK, false);
-- 
2.14.4


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]