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 bool target_desc::operator== (const target_desc &other) const 24 { 25 if (reg_defs != other.reg_defs) 26 return false; 27 28 /* Compare the two vectors of expedited registers. They will only match 29 if the following conditions are met: 30 31 - Both vectors have the same number of elements. 32 - Both vectors contain the same elements. 33 - The elements of both vectors appear in the same order. */ 34 if (expedite_regs != other.expedite_regs) 35 return false; 36 37 return true; 38 } 39 40 #endif 41 42 void target_desc::accept (tdesc_element_visitor &v) const 43 { 44 #ifndef IN_PROCESS_AGENT 45 v.visit_pre (this); 46 47 for (const tdesc_feature_up &feature : features) 48 feature->accept (v); 49 50 v.visit_post (this); 51 #endif 52 } 53 54 void 55 init_target_desc (struct target_desc *tdesc, 56 const char **expedite_regs, 57 enum gdb_osabi osabi) 58 { 59 int offset = 0; 60 61 /* Go through all the features and populate reg_defs. */ 62 for (const tdesc_feature_up &feature : tdesc->features) 63 for (const tdesc_reg_up &treg : feature->registers) 64 { 65 int regnum = treg->target_regnum; 66 67 /* Register number will increase (possibly with gaps) or be zero. */ 68 gdb_assert (regnum == 0 || regnum >= tdesc->reg_defs.size ()); 69 70 if (regnum != 0) 71 tdesc->reg_defs.resize (regnum, gdb::reg (offset)); 72 73 tdesc->reg_defs.emplace_back (treg->name.c_str (), offset, 74 treg->bitsize); 75 offset += treg->bitsize; 76 } 77 78 tdesc->registers_size = offset / 8; 79 80 /* Make sure PBUFSIZ is large enough to hold a full register 81 packet. */ 82 gdb_assert (2 * tdesc->registers_size + 32 <= PBUFSIZ); 83 84 #ifndef IN_PROCESS_AGENT 85 /* Drop the contents of the previous vector, if any. */ 86 tdesc->expedite_regs.clear (); 87 88 /* Initialize the vector with new expedite registers contents. */ 89 int expedite_count = 0; 90 while (expedite_regs[expedite_count] != nullptr) 91 tdesc->expedite_regs.push_back (expedite_regs[expedite_count++]); 92 93 set_tdesc_osabi (tdesc, osabi); 94 #endif 95 } 96 97 /* See gdbsupport/tdesc.h. */ 98 99 target_desc_up 100 allocate_target_description (void) 101 { 102 return target_desc_up (new target_desc ()); 103 } 104 105 /* See gdbsupport/tdesc.h. */ 106 107 void 108 target_desc_deleter::operator() (struct target_desc *target_desc) const 109 { 110 delete target_desc; 111 } 112 113 #ifndef IN_PROCESS_AGENT 114 115 static const struct target_desc default_description {}; 116 117 void 118 copy_target_description (struct target_desc *dest, 119 const struct target_desc *src) 120 { 121 dest->reg_defs = src->reg_defs; 122 dest->expedite_regs = src->expedite_regs; 123 dest->registers_size = src->registers_size; 124 dest->xmltarget = src->xmltarget; 125 } 126 127 const struct target_desc * 128 current_target_desc (void) 129 { 130 if (current_thread == NULL) 131 return &default_description; 132 133 return current_process ()->tdesc; 134 } 135 136 /* An empty structure. */ 137 138 struct tdesc_compatible_info { }; 139 140 /* See gdbsupport/tdesc.h. */ 141 142 const std::vector<tdesc_compatible_info_up> & 143 tdesc_compatible_info_list (const target_desc *target_desc) 144 { 145 static std::vector<tdesc_compatible_info_up> empty; 146 return empty; 147 } 148 149 /* See gdbsupport/tdesc.h. */ 150 151 const char * 152 tdesc_compatible_info_arch_name (const tdesc_compatible_info_up &c_info) 153 { 154 return nullptr; 155 } 156 157 /* See gdbsupport/tdesc.h. */ 158 159 const char * 160 tdesc_architecture_name (const struct target_desc *target_desc) 161 { 162 return target_desc->arch.get (); 163 } 164 165 /* See gdbsupport/tdesc.h. */ 166 167 void 168 set_tdesc_architecture (struct target_desc *target_desc, 169 const char *name) 170 { 171 target_desc->arch = make_unique_xstrdup (name); 172 } 173 174 /* See gdbsupport/tdesc.h. */ 175 176 const char * 177 tdesc_osabi_name (const struct target_desc *target_desc) 178 { 179 return target_desc->osabi.get (); 180 } 181 182 /* See gdbsupport/tdesc.h. */ 183 184 void 185 set_tdesc_osabi (struct target_desc *target_desc, enum gdb_osabi osabi) 186 { 187 const char *name = gdbarch_osabi_name (osabi); 188 target_desc->osabi = make_unique_xstrdup (name); 189 } 190 191 /* See gdbsupport/tdesc.h. */ 192 193 const char * 194 tdesc_get_features_xml (const target_desc *tdesc) 195 { 196 /* Either .xmltarget or .features is not NULL. */ 197 gdb_assert (tdesc->xmltarget != NULL 198 || (!tdesc->features.empty () 199 && tdesc_architecture_name (tdesc) != nullptr)); 200 201 if (tdesc->xmltarget == NULL) 202 { 203 std::string buffer ("@"); 204 print_xml_feature v (&buffer); 205 tdesc->accept (v); 206 tdesc->xmltarget = xstrdup (buffer.c_str ()); 207 } 208 209 return tdesc->xmltarget; 210 } 211 #endif 212 213 /* See gdbsupport/tdesc.h. */ 214 215 struct tdesc_feature * 216 tdesc_create_feature (struct target_desc *tdesc, const char *name) 217 { 218 struct tdesc_feature *new_feature = new tdesc_feature (name); 219 tdesc->features.emplace_back (new_feature); 220 return new_feature; 221 } 222 223 /* See gdbsupport/tdesc.h. */ 224 225 bool 226 tdesc_contains_feature (const target_desc *tdesc, const std::string &feature) 227 { 228 gdb_assert (tdesc != nullptr); 229 230 for (const tdesc_feature_up &f : tdesc->features) 231 { 232 if (f->name == feature) 233 return true; 234 } 235 236 return false; 237 } 238