xref: /netbsd-src/external/gpl3/gdb/dist/gdbserver/tdesc.cc (revision 13ed34fa5696ce1ff8e9519eeb5619eee4331db8)
1*13ed34faSchristos /* Copyright (C) 2012-2024 Free Software Foundation, Inc.
28dffb485Schristos 
38dffb485Schristos    This file is part of GDB.
48dffb485Schristos 
58dffb485Schristos    This program is free software; you can redistribute it and/or modify
68dffb485Schristos    it under the terms of the GNU General Public License as published by
78dffb485Schristos    the Free Software Foundation; either version 3 of the License, or
88dffb485Schristos    (at your option) any later version.
98dffb485Schristos 
108dffb485Schristos    This program is distributed in the hope that it will be useful,
118dffb485Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
128dffb485Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
138dffb485Schristos    GNU General Public License for more details.
148dffb485Schristos 
158dffb485Schristos    You should have received a copy of the GNU General Public License
168dffb485Schristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
178dffb485Schristos 
188dffb485Schristos #include "tdesc.h"
198dffb485Schristos #include "regdef.h"
208dffb485Schristos 
218dffb485Schristos #ifndef IN_PROCESS_AGENT
228dffb485Schristos 
238dffb485Schristos target_desc::~target_desc ()
248dffb485Schristos {
258dffb485Schristos   xfree ((char *) arch);
268dffb485Schristos   xfree ((char *) osabi);
278dffb485Schristos }
288dffb485Schristos 
298dffb485Schristos bool target_desc::operator== (const target_desc &other) const
308dffb485Schristos {
318dffb485Schristos   if (reg_defs != other.reg_defs)
328dffb485Schristos     return false;
338dffb485Schristos 
34*13ed34faSchristos   /* Compare the two vectors of expedited registers.  They will only match
35*13ed34faSchristos      if the following conditions are met:
36*13ed34faSchristos 
37*13ed34faSchristos      - Both vectors have the same number of elements.
38*13ed34faSchristos      - Both vectors contain the same elements.
39*13ed34faSchristos      - The elements of both vectors appear in the same order.  */
40*13ed34faSchristos   if (expedite_regs != other.expedite_regs)
418dffb485Schristos     return false;
428dffb485Schristos 
438dffb485Schristos   return true;
448dffb485Schristos }
458dffb485Schristos 
468dffb485Schristos #endif
478dffb485Schristos 
488dffb485Schristos void target_desc::accept (tdesc_element_visitor &v) const
498dffb485Schristos {
508dffb485Schristos #ifndef IN_PROCESS_AGENT
518dffb485Schristos   v.visit_pre (this);
528dffb485Schristos 
538dffb485Schristos   for (const tdesc_feature_up &feature : features)
548dffb485Schristos     feature->accept (v);
558dffb485Schristos 
568dffb485Schristos   v.visit_post (this);
578dffb485Schristos #endif
588dffb485Schristos }
598dffb485Schristos 
608dffb485Schristos void
618dffb485Schristos init_target_desc (struct target_desc *tdesc,
628dffb485Schristos 		  const char **expedite_regs)
638dffb485Schristos {
648dffb485Schristos   int offset = 0;
658dffb485Schristos 
668dffb485Schristos   /* Go through all the features and populate reg_defs.  */
678dffb485Schristos   for (const tdesc_feature_up &feature : tdesc->features)
688dffb485Schristos     for (const tdesc_reg_up &treg : feature->registers)
698dffb485Schristos       {
708dffb485Schristos 	int regnum = treg->target_regnum;
718dffb485Schristos 
728dffb485Schristos 	/* Register number will increase (possibly with gaps) or be zero.  */
738dffb485Schristos 	gdb_assert (regnum == 0 || regnum >= tdesc->reg_defs.size ());
748dffb485Schristos 
758dffb485Schristos 	if (regnum != 0)
768dffb485Schristos 	  tdesc->reg_defs.resize (regnum, gdb::reg (offset));
778dffb485Schristos 
788dffb485Schristos 	tdesc->reg_defs.emplace_back (treg->name.c_str (), offset,
798dffb485Schristos 				      treg->bitsize);
808dffb485Schristos 	offset += treg->bitsize;
818dffb485Schristos       }
828dffb485Schristos 
838dffb485Schristos   tdesc->registers_size = offset / 8;
848dffb485Schristos 
858dffb485Schristos   /* Make sure PBUFSIZ is large enough to hold a full register
868dffb485Schristos      packet.  */
878dffb485Schristos   gdb_assert (2 * tdesc->registers_size + 32 <= PBUFSIZ);
888dffb485Schristos 
898dffb485Schristos #ifndef IN_PROCESS_AGENT
90*13ed34faSchristos   /* Drop the contents of the previous vector, if any.  */
91*13ed34faSchristos   tdesc->expedite_regs.clear ();
92*13ed34faSchristos 
93*13ed34faSchristos   /* Initialize the vector with new expedite registers contents.  */
94*13ed34faSchristos   int expedite_count = 0;
95*13ed34faSchristos   while (expedite_regs[expedite_count] != nullptr)
96*13ed34faSchristos     tdesc->expedite_regs.push_back (expedite_regs[expedite_count++]);
978dffb485Schristos #endif
988dffb485Schristos }
998dffb485Schristos 
1008dffb485Schristos /* See gdbsupport/tdesc.h.  */
1018dffb485Schristos 
1024b169a6bSchristos target_desc_up
1038dffb485Schristos allocate_target_description (void)
1048dffb485Schristos {
1054b169a6bSchristos   return target_desc_up (new target_desc ());
1068dffb485Schristos }
1078dffb485Schristos 
1088dffb485Schristos /* See gdbsupport/tdesc.h.  */
1098dffb485Schristos 
1108dffb485Schristos void
1118dffb485Schristos target_desc_deleter::operator() (struct target_desc *target_desc) const
1128dffb485Schristos {
1138dffb485Schristos   delete target_desc;
1148dffb485Schristos }
1158dffb485Schristos 
1168dffb485Schristos #ifndef IN_PROCESS_AGENT
1178dffb485Schristos 
1188dffb485Schristos static const struct target_desc default_description {};
1198dffb485Schristos 
1208dffb485Schristos void
1218dffb485Schristos copy_target_description (struct target_desc *dest,
1228dffb485Schristos 			 const struct target_desc *src)
1238dffb485Schristos {
1248dffb485Schristos   dest->reg_defs = src->reg_defs;
1258dffb485Schristos   dest->expedite_regs = src->expedite_regs;
1268dffb485Schristos   dest->registers_size = src->registers_size;
1278dffb485Schristos   dest->xmltarget = src->xmltarget;
1288dffb485Schristos }
1298dffb485Schristos 
1308dffb485Schristos const struct target_desc *
1318dffb485Schristos current_target_desc (void)
1328dffb485Schristos {
1338dffb485Schristos   if (current_thread == NULL)
1348dffb485Schristos     return &default_description;
1358dffb485Schristos 
1368dffb485Schristos   return current_process ()->tdesc;
1378dffb485Schristos }
1388dffb485Schristos 
1398dffb485Schristos /* An empty structure.  */
1408dffb485Schristos 
1418dffb485Schristos struct tdesc_compatible_info { };
1428dffb485Schristos 
1438dffb485Schristos /* See gdbsupport/tdesc.h.  */
1448dffb485Schristos 
1458dffb485Schristos const std::vector<tdesc_compatible_info_up> &
1468dffb485Schristos tdesc_compatible_info_list (const target_desc *target_desc)
1478dffb485Schristos {
1488dffb485Schristos   static std::vector<tdesc_compatible_info_up> empty;
1498dffb485Schristos   return empty;
1508dffb485Schristos }
1518dffb485Schristos 
1528dffb485Schristos /* See gdbsupport/tdesc.h.  */
1538dffb485Schristos 
1548dffb485Schristos const char *
1558dffb485Schristos tdesc_compatible_info_arch_name (const tdesc_compatible_info_up &c_info)
1568dffb485Schristos {
1578dffb485Schristos   return nullptr;
1588dffb485Schristos }
1598dffb485Schristos 
1608dffb485Schristos /* See gdbsupport/tdesc.h.  */
1618dffb485Schristos 
1628dffb485Schristos const char *
1638dffb485Schristos tdesc_architecture_name (const struct target_desc *target_desc)
1648dffb485Schristos {
1658dffb485Schristos   return target_desc->arch;
1668dffb485Schristos }
1678dffb485Schristos 
1688dffb485Schristos /* See gdbsupport/tdesc.h.  */
1698dffb485Schristos 
1708dffb485Schristos void
1718dffb485Schristos set_tdesc_architecture (struct target_desc *target_desc,
1728dffb485Schristos 			const char *name)
1738dffb485Schristos {
1748dffb485Schristos   target_desc->arch = xstrdup (name);
1758dffb485Schristos }
1768dffb485Schristos 
1778dffb485Schristos /* See gdbsupport/tdesc.h.  */
1788dffb485Schristos 
1798dffb485Schristos const char *
1808dffb485Schristos tdesc_osabi_name (const struct target_desc *target_desc)
1818dffb485Schristos {
1828dffb485Schristos   return target_desc->osabi;
1838dffb485Schristos }
1848dffb485Schristos 
1858dffb485Schristos /* See gdbsupport/tdesc.h.  */
1868dffb485Schristos 
1878dffb485Schristos void
1888dffb485Schristos set_tdesc_osabi (struct target_desc *target_desc, const char *name)
1898dffb485Schristos {
1908dffb485Schristos   target_desc->osabi = xstrdup (name);
1918dffb485Schristos }
1928dffb485Schristos 
1938dffb485Schristos /* See gdbsupport/tdesc.h.  */
1948dffb485Schristos 
1958dffb485Schristos const char *
1968dffb485Schristos tdesc_get_features_xml (const target_desc *tdesc)
1978dffb485Schristos {
1988dffb485Schristos   /* Either .xmltarget or .features is not NULL.  */
1998dffb485Schristos   gdb_assert (tdesc->xmltarget != NULL
2008dffb485Schristos 	      || (!tdesc->features.empty ()
2018dffb485Schristos 		  && tdesc->arch != NULL));
2028dffb485Schristos 
2038dffb485Schristos   if (tdesc->xmltarget == NULL)
2048dffb485Schristos     {
2058dffb485Schristos       std::string buffer ("@");
2068dffb485Schristos       print_xml_feature v (&buffer);
2078dffb485Schristos       tdesc->accept (v);
2088dffb485Schristos       tdesc->xmltarget = xstrdup (buffer.c_str ());
2098dffb485Schristos     }
2108dffb485Schristos 
2118dffb485Schristos   return tdesc->xmltarget;
2128dffb485Schristos }
2138dffb485Schristos #endif
2148dffb485Schristos 
2158dffb485Schristos /* See gdbsupport/tdesc.h.  */
2168dffb485Schristos 
2178dffb485Schristos struct tdesc_feature *
2188dffb485Schristos tdesc_create_feature (struct target_desc *tdesc, const char *name)
2198dffb485Schristos {
2208dffb485Schristos   struct tdesc_feature *new_feature = new tdesc_feature (name);
2218dffb485Schristos   tdesc->features.emplace_back (new_feature);
2228dffb485Schristos   return new_feature;
2238dffb485Schristos }
2248dffb485Schristos 
2258dffb485Schristos /* See gdbsupport/tdesc.h.  */
2268dffb485Schristos 
2278dffb485Schristos bool
2288dffb485Schristos tdesc_contains_feature (const target_desc *tdesc, const std::string &feature)
2298dffb485Schristos {
2308dffb485Schristos   gdb_assert (tdesc != nullptr);
2318dffb485Schristos 
2328dffb485Schristos   for (const tdesc_feature_up &f : tdesc->features)
2338dffb485Schristos     {
2348dffb485Schristos       if (f->name == feature)
2358dffb485Schristos 	return true;
2368dffb485Schristos     }
2378dffb485Schristos 
2388dffb485Schristos   return false;
2398dffb485Schristos }
240