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