Fix null pointer dereference in process_debug_info()
[binutils-gdb.git] / gdbserver / tdesc.cc
blob3265793da9623f89f9ec60de6e5370328071e0c4
1 /* Copyright (C) 2012-2024 Free Software Foundation, Inc.
3 This file is part of GDB.
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.
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.
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/>. */
18 #include "tdesc.h"
19 #include "regdef.h"
21 #ifndef IN_PROCESS_AGENT
23 target_desc::~target_desc ()
25 xfree ((char *) arch);
26 xfree ((char *) osabi);
29 bool target_desc::operator== (const target_desc &other) const
31 if (reg_defs != other.reg_defs)
32 return false;
34 /* Compare the two vectors of expedited registers. They will only match
35 if the following conditions are met:
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;
43 return true;
46 #endif
48 void target_desc::accept (tdesc_element_visitor &v) const
50 #ifndef IN_PROCESS_AGENT
51 v.visit_pre (this);
53 for (const tdesc_feature_up &feature : features)
54 feature->accept (v);
56 v.visit_post (this);
57 #endif
60 void
61 init_target_desc (struct target_desc *tdesc,
62 const char **expedite_regs)
64 int offset = 0;
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)
70 int regnum = treg->target_regnum;
72 /* Register number will increase (possibly with gaps) or be zero. */
73 gdb_assert (regnum == 0 || regnum >= tdesc->reg_defs.size ());
75 if (regnum != 0)
76 tdesc->reg_defs.resize (regnum, gdb::reg (offset));
78 tdesc->reg_defs.emplace_back (treg->name.c_str (), offset,
79 treg->bitsize);
80 offset += treg->bitsize;
83 tdesc->registers_size = offset / 8;
85 /* Make sure PBUFSIZ is large enough to hold a full register
86 packet. */
87 gdb_assert (2 * tdesc->registers_size + 32 <= PBUFSIZ);
89 #ifndef IN_PROCESS_AGENT
90 /* Drop the contents of the previous vector, if any. */
91 tdesc->expedite_regs.clear ();
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
100 /* See gdbsupport/tdesc.h. */
102 target_desc_up
103 allocate_target_description (void)
105 return target_desc_up (new target_desc ());
108 /* See gdbsupport/tdesc.h. */
110 void
111 target_desc_deleter::operator() (struct target_desc *target_desc) const
113 delete target_desc;
116 #ifndef IN_PROCESS_AGENT
118 static const struct target_desc default_description {};
120 void
121 copy_target_description (struct target_desc *dest,
122 const struct target_desc *src)
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;
130 const struct target_desc *
131 current_target_desc (void)
133 if (current_thread == NULL)
134 return &default_description;
136 return current_process ()->tdesc;
139 /* An empty structure. */
141 struct tdesc_compatible_info { };
143 /* See gdbsupport/tdesc.h. */
145 const std::vector<tdesc_compatible_info_up> &
146 tdesc_compatible_info_list (const target_desc *target_desc)
148 static std::vector<tdesc_compatible_info_up> empty;
149 return empty;
152 /* See gdbsupport/tdesc.h. */
154 const char *
155 tdesc_compatible_info_arch_name (const tdesc_compatible_info_up &c_info)
157 return nullptr;
160 /* See gdbsupport/tdesc.h. */
162 const char *
163 tdesc_architecture_name (const struct target_desc *target_desc)
165 return target_desc->arch;
168 /* See gdbsupport/tdesc.h. */
170 void
171 set_tdesc_architecture (struct target_desc *target_desc,
172 const char *name)
174 target_desc->arch = xstrdup (name);
177 /* See gdbsupport/tdesc.h. */
179 const char *
180 tdesc_osabi_name (const struct target_desc *target_desc)
182 return target_desc->osabi;
185 /* See gdbsupport/tdesc.h. */
187 void
188 set_tdesc_osabi (struct target_desc *target_desc, const char *name)
190 target_desc->osabi = xstrdup (name);
193 /* See gdbsupport/tdesc.h. */
195 const char *
196 tdesc_get_features_xml (const target_desc *tdesc)
198 /* Either .xmltarget or .features is not NULL. */
199 gdb_assert (tdesc->xmltarget != NULL
200 || (!tdesc->features.empty ()
201 && tdesc->arch != NULL));
203 if (tdesc->xmltarget == NULL)
205 std::string buffer ("@");
206 print_xml_feature v (&buffer);
207 tdesc->accept (v);
208 tdesc->xmltarget = xstrdup (buffer.c_str ());
211 return tdesc->xmltarget;
213 #endif
215 /* See gdbsupport/tdesc.h. */
217 struct tdesc_feature *
218 tdesc_create_feature (struct target_desc *tdesc, const char *name)
220 struct tdesc_feature *new_feature = new tdesc_feature (name);
221 tdesc->features.emplace_back (new_feature);
222 return new_feature;
225 /* See gdbsupport/tdesc.h. */
227 bool
228 tdesc_contains_feature (const target_desc *tdesc, const std::string &feature)
230 gdb_assert (tdesc != nullptr);
232 for (const tdesc_feature_up &f : tdesc->features)
234 if (f->name == feature)
235 return true;
238 return false;