xref: /netbsd-src/external/gpl3/gdb/dist/gdbserver/linux-x86-tdesc.cc (revision 64f917f5a88990e32dd65fcd4348042fa7f852b9)
18dffb485Schristos /* GNU/Linux/x86-64 specific target description, for the remote server
28dffb485Schristos    for GDB.
3*64f917f5Schristos    Copyright (C) 2017-2024 Free Software Foundation, Inc.
48dffb485Schristos 
58dffb485Schristos    This file is part of GDB.
68dffb485Schristos 
78dffb485Schristos    This program is free software; you can redistribute it and/or modify
88dffb485Schristos    it under the terms of the GNU General Public License as published by
98dffb485Schristos    the Free Software Foundation; either version 3 of the License, or
108dffb485Schristos    (at your option) any later version.
118dffb485Schristos 
128dffb485Schristos    This program is distributed in the hope that it will be useful,
138dffb485Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
148dffb485Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
158dffb485Schristos    GNU General Public License for more details.
168dffb485Schristos 
178dffb485Schristos    You should have received a copy of the GNU General Public License
188dffb485Schristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
198dffb485Schristos 
208dffb485Schristos #include "tdesc.h"
218dffb485Schristos #include "linux-x86-tdesc.h"
228dffb485Schristos #include "arch/i386.h"
238dffb485Schristos #include "gdbsupport/x86-xstate.h"
248dffb485Schristos #ifdef __x86_64__
258dffb485Schristos #include "arch/amd64.h"
268dffb485Schristos #endif
278dffb485Schristos #include "x86-tdesc.h"
288dffb485Schristos 
298dffb485Schristos /* Return the right x86_linux_tdesc index for a given XCR0.  Return
308dffb485Schristos    X86_TDESC_LAST if can't find a match.  */
318dffb485Schristos 
328dffb485Schristos static enum x86_linux_tdesc
338dffb485Schristos xcr0_to_tdesc_idx (uint64_t xcr0, bool is_x32)
348dffb485Schristos {
358dffb485Schristos   if (xcr0 & X86_XSTATE_PKRU)
368dffb485Schristos     {
378dffb485Schristos       if (is_x32)
388dffb485Schristos 	{
398dffb485Schristos 	  /* No x32 MPX and PKU, fall back to avx_avx512.  */
408dffb485Schristos 	  return X86_TDESC_AVX_AVX512;
418dffb485Schristos 	}
428dffb485Schristos       else
438dffb485Schristos 	return X86_TDESC_AVX_MPX_AVX512_PKU;
448dffb485Schristos     }
458dffb485Schristos   else if (xcr0 & X86_XSTATE_AVX512)
468dffb485Schristos     return X86_TDESC_AVX_AVX512;
478dffb485Schristos   else if ((xcr0 & X86_XSTATE_AVX_MPX_MASK) == X86_XSTATE_AVX_MPX_MASK)
488dffb485Schristos     {
498dffb485Schristos       if (is_x32) /* No MPX on x32.  */
508dffb485Schristos 	return X86_TDESC_AVX;
518dffb485Schristos       else
528dffb485Schristos 	return X86_TDESC_AVX_MPX;
538dffb485Schristos     }
548dffb485Schristos   else if (xcr0 & X86_XSTATE_MPX)
558dffb485Schristos     {
568dffb485Schristos       if (is_x32) /* No MPX on x32.  */
578dffb485Schristos 	return X86_TDESC_AVX;
588dffb485Schristos       else
598dffb485Schristos 	return X86_TDESC_MPX;
608dffb485Schristos     }
618dffb485Schristos   else if (xcr0 & X86_XSTATE_AVX)
628dffb485Schristos     return X86_TDESC_AVX;
638dffb485Schristos   else if (xcr0 & X86_XSTATE_SSE)
648dffb485Schristos     return X86_TDESC_SSE;
658dffb485Schristos   else if (xcr0 & X86_XSTATE_X87)
668dffb485Schristos     return X86_TDESC_MMX;
678dffb485Schristos   else
688dffb485Schristos     return X86_TDESC_LAST;
698dffb485Schristos }
708dffb485Schristos 
718dffb485Schristos #if defined __i386__ || !defined IN_PROCESS_AGENT
728dffb485Schristos 
738dffb485Schristos static struct target_desc *i386_tdescs[X86_TDESC_LAST] = { };
748dffb485Schristos 
758dffb485Schristos /* Return the target description according to XCR0.  */
768dffb485Schristos 
778dffb485Schristos const struct target_desc *
788dffb485Schristos i386_linux_read_description (uint64_t xcr0)
798dffb485Schristos {
808dffb485Schristos   enum x86_linux_tdesc idx = xcr0_to_tdesc_idx (xcr0, false);
818dffb485Schristos 
828dffb485Schristos   if (idx == X86_TDESC_LAST)
838dffb485Schristos     return NULL;
848dffb485Schristos 
858dffb485Schristos   struct target_desc **tdesc = &i386_tdescs[idx];
868dffb485Schristos 
878dffb485Schristos   if (*tdesc == NULL)
888dffb485Schristos     {
898dffb485Schristos       *tdesc = i386_create_target_description (xcr0, true, false);
908dffb485Schristos 
918dffb485Schristos       init_target_desc (*tdesc, i386_expedite_regs);
928dffb485Schristos     }
938dffb485Schristos 
948dffb485Schristos   return *tdesc;;
958dffb485Schristos }
968dffb485Schristos #endif
978dffb485Schristos 
988dffb485Schristos #ifdef __x86_64__
998dffb485Schristos 
1008dffb485Schristos static target_desc *amd64_tdescs[X86_TDESC_LAST] = { };
1018dffb485Schristos static target_desc *x32_tdescs[X86_TDESC_LAST] = { };
1028dffb485Schristos 
1038dffb485Schristos const struct target_desc *
1048dffb485Schristos amd64_linux_read_description (uint64_t xcr0, bool is_x32)
1058dffb485Schristos {
1068dffb485Schristos   enum x86_linux_tdesc idx = xcr0_to_tdesc_idx (xcr0, is_x32);
1078dffb485Schristos 
1088dffb485Schristos   if (idx == X86_TDESC_LAST)
1098dffb485Schristos     return NULL;
1108dffb485Schristos 
1118dffb485Schristos   struct target_desc **tdesc = NULL;
1128dffb485Schristos 
1138dffb485Schristos   if (is_x32)
1148dffb485Schristos     tdesc = &x32_tdescs[idx];
1158dffb485Schristos   else
1168dffb485Schristos     tdesc = &amd64_tdescs[idx];
1178dffb485Schristos 
1188dffb485Schristos   if (*tdesc == NULL)
1198dffb485Schristos     {
1208dffb485Schristos       *tdesc = amd64_create_target_description (xcr0, is_x32, true, true);
1218dffb485Schristos 
1228dffb485Schristos       init_target_desc (*tdesc, amd64_expedite_regs);
1238dffb485Schristos     }
1248dffb485Schristos   return *tdesc;
1258dffb485Schristos }
1268dffb485Schristos 
1278dffb485Schristos #endif
1288dffb485Schristos 
1298dffb485Schristos #ifndef IN_PROCESS_AGENT
1308dffb485Schristos 
1318dffb485Schristos int
1328dffb485Schristos i386_get_ipa_tdesc_idx (const struct target_desc *tdesc)
1338dffb485Schristos {
1348dffb485Schristos   for (int i = 0; i < X86_TDESC_LAST; i++)
1358dffb485Schristos     {
1368dffb485Schristos       if (tdesc == i386_tdescs[i])
1378dffb485Schristos 	return i;
1388dffb485Schristos     }
1398dffb485Schristos 
1408dffb485Schristos   /* If none tdesc is found, return the one with minimum features.  */
1418dffb485Schristos   return X86_TDESC_MMX;
1428dffb485Schristos }
1438dffb485Schristos 
1448dffb485Schristos #if defined __x86_64__
1458dffb485Schristos int
1468dffb485Schristos amd64_get_ipa_tdesc_idx (const struct target_desc *tdesc)
1478dffb485Schristos {
1488dffb485Schristos   for (int i = 0; i < X86_TDESC_LAST; i++)
1498dffb485Schristos     {
1508dffb485Schristos       if (tdesc == amd64_tdescs[i])
1518dffb485Schristos 	return i;
1528dffb485Schristos     }
1538dffb485Schristos   for (int i = 0; i < X86_TDESC_LAST; i++)
1548dffb485Schristos     {
1558dffb485Schristos       if (tdesc == x32_tdescs[i])
1568dffb485Schristos 	return i;
1578dffb485Schristos     }
1588dffb485Schristos 
1598dffb485Schristos   return X86_TDESC_SSE;
1608dffb485Schristos }
1618dffb485Schristos 
1628dffb485Schristos #endif
1638dffb485Schristos #endif
164