1 /* Copyright (C) 2012-2024 Free Software Foundation, Inc. 2 3 This file is part of GDB. 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 3 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 17 18 #include "tdesc.h" 19 #include "regdef.h" 20 21 #ifndef IN_PROCESS_AGENT 22 23 target_desc::~target_desc () 24 { 25 xfree ((char *) arch); 26 xfree ((char *) osabi); 27 } 28 29 bool target_desc::operator== (const target_desc &other) const 30 { 31 if (reg_defs != other.reg_defs) 32 return false; 33 34 /* Compare the two vectors of expedited registers. They will only match 35 if the following conditions are met: 36 37 - Both vectors have the same number of elements. 38 - Both vectors contain the same elements. 39 - The elements of both vectors appear in the same order. */ 40 if (expedite_regs != other.expedite_regs) 41 return false; 42 43 return true; 44 } 45 46 #endif 47 48 void target_desc::accept (tdesc_element_visitor &v) const 49 { 50 #ifndef IN_PROCESS_AGENT 51 v.visit_pre (this); 52 53 for (const tdesc_feature_up &feature : features) 54 feature->accept (v); 55 56 v.visit_post (this); 57 #endif 58 } 59 60 void 61 init_target_desc (struct target_desc *tdesc, 62 const char **expedite_regs) 63 { 64 int offset = 0; 65 66 /* Go through all the features and populate reg_defs. */ 67 for (const tdesc_feature_up &feature : tdesc->features) 68 for (const tdesc_reg_up &treg : feature->registers) 69 { 70 int regnum = treg->target_regnum; 71 72 /* Register number will increase (possibly with gaps) or be zero. */ 73 gdb_assert (regnum == 0 || regnum >= tdesc->reg_defs.size ()); 74 75 if (regnum != 0) 76 tdesc->reg_defs.resize (regnum, gdb::reg (offset)); 77 78 tdesc->reg_defs.emplace_back (treg->name.c_str (), offset, 79 treg->bitsize); 80 offset += treg->bitsize; 81 } 82 83 tdesc->registers_size = offset / 8; 84 85 /* Make sure PBUFSIZ is large enough to hold a full register 86 packet. */ 87 gdb_assert (2 * tdesc->registers_size + 32 <= PBUFSIZ); 88 89 #ifndef IN_PROCESS_AGENT 90 /* Drop the contents of the previous vector, if any. */ 91 tdesc->expedite_regs.clear (); 92 93 /* Initialize the vector with new expedite registers contents. */ 94 int expedite_count = 0; 95 while (expedite_regs[expedite_count] != nullptr) 96 tdesc->expedite_regs.push_back (expedite_regs[expedite_count++]); 97 #endif 98 } 99 100 /* See gdbsupport/tdesc.h. */ 101 102 target_desc_up 103 allocate_target_description (void) 104 { 105 return target_desc_up (new target_desc ()); 106 } 107 108 /* See gdbsupport/tdesc.h. */ 109 110 void 111 target_desc_deleter::operator() (struct target_desc *target_desc) const 112 { 113 delete target_desc; 114 } 115 116 #ifndef IN_PROCESS_AGENT 117 118 static const struct target_desc default_description {}; 119 120 void 121 copy_target_description (struct target_desc *dest, 122 const struct target_desc *src) 123 { 124 dest->reg_defs = src->reg_defs; 125 dest->expedite_regs = src->expedite_regs; 126 dest->registers_size = src->registers_size; 127 dest->xmltarget = src->xmltarget; 128 } 129 130 const struct target_desc * 131 current_target_desc (void) 132 { 133 if (current_thread == NULL) 134 return &default_description; 135 136 return current_process ()->tdesc; 137 } 138 139 /* An empty structure. */ 140 141 struct tdesc_compatible_info { }; 142 143 /* See gdbsupport/tdesc.h. */ 144 145 const std::vector<tdesc_compatible_info_up> & 146 tdesc_compatible_info_list (const target_desc *target_desc) 147 { 148 static std::vector<tdesc_compatible_info_up> empty; 149 return empty; 150 } 151 152 /* See gdbsupport/tdesc.h. */ 153 154 const char * 155 tdesc_compatible_info_arch_name (const tdesc_compatible_info_up &c_info) 156 { 157 return nullptr; 158 } 159 160 /* See gdbsupport/tdesc.h. */ 161 162 const char * 163 tdesc_architecture_name (const struct target_desc *target_desc) 164 { 165 return target_desc->arch; 166 } 167 168 /* See gdbsupport/tdesc.h. */ 169 170 void 171 set_tdesc_architecture (struct target_desc *target_desc, 172 const char *name) 173 { 174 target_desc->arch = xstrdup (name); 175 } 176 177 /* See gdbsupport/tdesc.h. */ 178 179 const char * 180 tdesc_osabi_name (const struct target_desc *target_desc) 181 { 182 return target_desc->osabi; 183 } 184 185 /* See gdbsupport/tdesc.h. */ 186 187 void 188 set_tdesc_osabi (struct target_desc *target_desc, const char *name) 189 { 190 target_desc->osabi = xstrdup (name); 191 } 192 193 /* See gdbsupport/tdesc.h. */ 194 195 const char * 196 tdesc_get_features_xml (const target_desc *tdesc) 197 { 198 /* Either .xmltarget or .features is not NULL. */ 199 gdb_assert (tdesc->xmltarget != NULL 200 || (!tdesc->features.empty () 201 && tdesc->arch != NULL)); 202 203 if (tdesc->xmltarget == NULL) 204 { 205 std::string buffer ("@"); 206 print_xml_feature v (&buffer); 207 tdesc->accept (v); 208 tdesc->xmltarget = xstrdup (buffer.c_str ()); 209 } 210 211 return tdesc->xmltarget; 212 } 213 #endif 214 215 /* See gdbsupport/tdesc.h. */ 216 217 struct tdesc_feature * 218 tdesc_create_feature (struct target_desc *tdesc, const char *name) 219 { 220 struct tdesc_feature *new_feature = new tdesc_feature (name); 221 tdesc->features.emplace_back (new_feature); 222 return new_feature; 223 } 224 225 /* See gdbsupport/tdesc.h. */ 226 227 bool 228 tdesc_contains_feature (const target_desc *tdesc, const std::string &feature) 229 { 230 gdb_assert (tdesc != nullptr); 231 232 for (const tdesc_feature_up &f : tdesc->features) 233 { 234 if (f->name == feature) 235 return true; 236 } 237 238 return false; 239 } 240