Rename gdb/ChangeLog to gdb/ChangeLog-2021
[binutils-gdb.git] / gdb / gdb-gdb.py.in
blobaf9fcfedc2f350d5bf35efdca889d5dbc6d35b5d
1 # Copyright (C) 2009-2021 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 import gdb
19 import os.path
22 class TypeFlag:
23 """A class that allows us to store a flag name, its short name,
24 and its value.
26 In the GDB sources, struct type has a component called instance_flags
27 in which the value is the addition of various flags. These flags are
28 defined by the enumerates type_instance_flag_value. This class helps us
29 recreate a list with all these flags that is easy to manipulate and sort.
30 Because all flag names start with TYPE_INSTANCE_FLAG_, a short_name
31 attribute is provided that strips this prefix.
33 ATTRIBUTES
34 name: The enumeration name (eg: "TYPE_INSTANCE_FLAG_CONST").
35 value: The associated value.
36 short_name: The enumeration name, with the suffix stripped.
37 """
39 def __init__(self, name, value):
40 self.name = name
41 self.value = value
42 self.short_name = name.replace("TYPE_INSTANCE_FLAG_", "")
44 def __lt__(self, other):
45 """Sort by value order."""
46 return self.value < other.value
49 # A list of all existing TYPE_INSTANCE_FLAGS_* enumerations,
50 # stored as TypeFlags objects. Lazy-initialized.
51 TYPE_FLAGS = None
54 class TypeFlagsPrinter:
55 """A class that prints a decoded form of an instance_flags value.
57 This class uses a global named TYPE_FLAGS, which is a list of
58 all defined TypeFlag values. Using a global allows us to compute
59 this list only once.
61 This class relies on a couple of enumeration types being defined.
62 If not, then printing of the instance_flag is going to be degraded,
63 but it's not a fatal error.
64 """
66 def __init__(self, val):
67 self.val = val
69 def __str__(self):
70 global TYPE_FLAGS
71 if TYPE_FLAGS is None:
72 self.init_TYPE_FLAGS()
73 if not self.val:
74 return "0"
75 if TYPE_FLAGS:
76 flag_list = [
77 flag.short_name for flag in TYPE_FLAGS if self.val & flag.value
79 else:
80 flag_list = ["???"]
81 return "0x%x [%s]" % (self.val, "|".join(flag_list))
83 def init_TYPE_FLAGS(self):
84 """Initialize the TYPE_FLAGS global as a list of TypeFlag objects.
85 This operation requires the search of a couple of enumeration types.
86 If not found, a warning is printed on stdout, and TYPE_FLAGS is
87 set to the empty list.
89 The resulting list is sorted by increasing value, to facilitate
90 printing of the list of flags used in an instance_flags value.
91 """
92 global TYPE_FLAGS
93 TYPE_FLAGS = []
94 try:
95 iflags = gdb.lookup_type("enum type_instance_flag_value")
96 except:
97 print("Warning: Cannot find enum type_instance_flag_value type.")
98 print(" `struct type' pretty-printer will be degraded")
99 return
100 TYPE_FLAGS = [TypeFlag(field.name, field.enumval) for field in iflags.fields()]
101 TYPE_FLAGS.sort()
104 class StructTypePrettyPrinter:
105 """Pretty-print an object of type struct type"""
107 def __init__(self, val):
108 self.val = val
110 def to_string(self):
111 fields = []
112 fields.append("pointer_type = %s" % self.val["pointer_type"])
113 fields.append("reference_type = %s" % self.val["reference_type"])
114 fields.append("chain = %s" % self.val["reference_type"])
115 fields.append(
116 "instance_flags = %s" % TypeFlagsPrinter(self.val["m_instance_flags"])
118 fields.append("length = %d" % self.val["length"])
119 fields.append("main_type = %s" % self.val["main_type"])
120 return "\n{" + ",\n ".join(fields) + "}"
123 class StructMainTypePrettyPrinter:
124 """Pretty-print an objet of type main_type"""
126 def __init__(self, val):
127 self.val = val
129 def flags_to_string(self):
130 """struct main_type contains a series of components that
131 are one-bit ints whose name start with "flag_". For instance:
132 flag_unsigned, flag_stub, etc. In essence, these components are
133 really boolean flags, and this method prints a short synthetic
134 version of the value of all these flags. For instance, if
135 flag_unsigned and flag_static are the only components set to 1,
136 this function will return "unsigned|static".
138 fields = [
139 field.name.replace("flag_", "")
140 for field in self.val.type.fields()
141 if field.name.startswith("flag_") and self.val[field.name]
143 return "|".join(fields)
145 def owner_to_string(self):
146 """Return an image of component "owner"."""
147 if self.val["m_flag_objfile_owned"] != 0:
148 return "%s (objfile)" % self.val["m_owner"]["objfile"]
149 else:
150 return "%s (gdbarch)" % self.val["m_owner"]["gdbarch"]
152 def struct_field_location_img(self, field_val):
153 """Return an image of the loc component inside the given field
154 gdb.Value.
156 loc_val = field_val["loc"]
157 loc_kind = str(field_val["loc_kind"])
158 if loc_kind == "FIELD_LOC_KIND_BITPOS":
159 return "bitpos = %d" % loc_val["bitpos"]
160 elif loc_kind == "FIELD_LOC_KIND_ENUMVAL":
161 return "enumval = %d" % loc_val["enumval"]
162 elif loc_kind == "FIELD_LOC_KIND_PHYSADDR":
163 return "physaddr = 0x%x" % loc_val["physaddr"]
164 elif loc_kind == "FIELD_LOC_KIND_PHYSNAME":
165 return "physname = %s" % loc_val["physname"]
166 elif loc_kind == "FIELD_LOC_KIND_DWARF_BLOCK":
167 return "dwarf_block = %s" % loc_val["dwarf_block"]
168 else:
169 return "loc = ??? (unsupported loc_kind value)"
171 def struct_field_img(self, fieldno):
172 """Return an image of the main_type field number FIELDNO."""
173 f = self.val["flds_bnds"]["fields"][fieldno]
174 label = "flds_bnds.fields[%d]:" % fieldno
175 if f["artificial"]:
176 label += " (artificial)"
177 fields = []
178 fields.append("name = %s" % f["name"])
179 fields.append("type = %s" % f["m_type"])
180 fields.append("loc_kind = %s" % f["loc_kind"])
181 fields.append("bitsize = %d" % f["bitsize"])
182 fields.append(self.struct_field_location_img(f))
183 return label + "\n" + " {" + ",\n ".join(fields) + "}"
185 def bound_img(self, bound_name):
186 """Return an image of the given main_type's bound."""
187 bounds = self.val["flds_bnds"]["bounds"].dereference()
188 b = bounds[bound_name]
189 bnd_kind = str(b["m_kind"])
190 if bnd_kind == "PROP_CONST":
191 return str(b["m_data"]["const_val"])
192 elif bnd_kind == "PROP_UNDEFINED":
193 return "(undefined)"
194 else:
195 info = [bnd_kind]
196 if bound_name == "high" and bounds["flag_upper_bound_is_count"]:
197 info.append("upper_bound_is_count")
198 return "{} ({})".format(str(b["m_data"]["baton"]), ",".join(info))
200 def bounds_img(self):
201 """Return an image of the main_type bounds."""
202 b = self.val["flds_bnds"]["bounds"].dereference()
203 low = self.bound_img("low")
204 high = self.bound_img("high")
206 img = "flds_bnds.bounds = {%s, %s}" % (low, high)
207 if b["flag_bound_evaluated"]:
208 img += " [evaluated]"
209 return img
211 def type_specific_img(self):
212 """Return a string image of the main_type type_specific union.
213 Only the relevant component of that union is printed (based on
214 the value of the type_specific_kind field.
216 type_specific_kind = str(self.val["type_specific_field"])
217 type_specific = self.val["type_specific"]
218 if type_specific_kind == "TYPE_SPECIFIC_NONE":
219 img = "type_specific_field = %s" % type_specific_kind
220 elif type_specific_kind == "TYPE_SPECIFIC_CPLUS_STUFF":
221 img = "cplus_stuff = %s" % type_specific["cplus_stuff"]
222 elif type_specific_kind == "TYPE_SPECIFIC_GNAT_STUFF":
223 img = (
224 "gnat_stuff = {descriptive_type = %s}"
225 % type_specific["gnat_stuff"]["descriptive_type"]
227 elif type_specific_kind == "TYPE_SPECIFIC_FLOATFORMAT":
228 img = "floatformat[0..1] = %s" % type_specific["floatformat"]
229 elif type_specific_kind == "TYPE_SPECIFIC_FUNC":
230 img = (
231 "calling_convention = %d"
232 % type_specific["func_stuff"]["calling_convention"]
234 # tail_call_list is not printed.
235 elif type_specific_kind == "TYPE_SPECIFIC_SELF_TYPE":
236 img = "self_type = %s" % type_specific["self_type"]
237 elif type_specific_kind == "TYPE_SPECIFIC_FIXED_POINT":
238 # The scaling factor is an opaque structure, so we cannot
239 # decode its value from Python (not without insider knowledge).
240 img = (
241 "scaling_factor: <opaque> (call __gmpz_dump with "
242 " _mp_num and _mp_den fields if needed)"
244 else:
245 img = (
246 "type_specific = ??? (unknown type_secific_kind: %s)"
247 % type_specific_kind
249 return img
251 def to_string(self):
252 """Return a pretty-printed image of our main_type."""
253 fields = []
254 fields.append("name = %s" % self.val["name"])
255 fields.append("code = %s" % self.val["code"])
256 fields.append("flags = [%s]" % self.flags_to_string())
257 fields.append("owner = %s" % self.owner_to_string())
258 fields.append("target_type = %s" % self.val["target_type"])
259 if self.val["nfields"] > 0:
260 for fieldno in range(self.val["nfields"]):
261 fields.append(self.struct_field_img(fieldno))
262 if self.val["code"] == gdb.TYPE_CODE_RANGE:
263 fields.append(self.bounds_img())
264 fields.append(self.type_specific_img())
266 return "\n{" + ",\n ".join(fields) + "}"
269 class CoreAddrPrettyPrinter:
270 """Print CORE_ADDR values as hex."""
272 def __init__(self, val):
273 self._val = val
275 def to_string(self):
276 return hex(int(self._val))
279 def type_lookup_function(val):
280 """A routine that returns the correct pretty printer for VAL
281 if appropriate. Returns None otherwise.
283 if val.type.tag == "type":
284 return StructTypePrettyPrinter(val)
285 elif val.type.tag == "main_type":
286 return StructMainTypePrettyPrinter(val)
287 elif val.type.name == "CORE_ADDR":
288 return CoreAddrPrettyPrinter(val)
289 return None
292 def register_pretty_printer(objfile):
293 """A routine to register a pretty-printer against the given OBJFILE."""
294 objfile.pretty_printers.append(type_lookup_function)
297 if __name__ == "__main__":
298 if gdb.current_objfile() is not None:
299 # This is the case where this script is being "auto-loaded"
300 # for a given objfile. Register the pretty-printer for that
301 # objfile.
302 register_pretty_printer(gdb.current_objfile())
303 else:
304 # We need to locate the objfile corresponding to the GDB
305 # executable, and register the pretty-printer for that objfile.
306 # FIXME: The condition used to match the objfile is too simplistic
307 # and will not work on Windows.
308 for objfile in gdb.objfiles():
309 if os.path.basename(objfile.filename) == "gdb":
310 objfile.pretty_printers.append(type_lookup_function)