23 """A class that allows us to store a flag name, its short name,
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.
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.
42 self.
short_name = name.replace(
"TYPE_INSTANCE_FLAG_",
"")
45 """Sort by value order."""
46 return self.
value < other.value
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
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.
71 if TYPE_FLAGS
is None:
77 flag.short_name
for flag
in TYPE_FLAGS
if self.
val & flag.value
81 return "0x%x [%s]" % (self.
val,
"|".join(flag_list))
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.
95 iflags = gdb.lookup_type(
"enum type_instance_flag_value")
97 print(
"Warning: Cannot find enum type_instance_flag_value type.")
98 print(
" `struct type' pretty-printer will be degraded")
100 TYPE_FLAGS = [
TypeFlag(field.name, field.enumval)
for field
in iflags.fields()]
105 """Pretty-print an object of type struct type"""
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"])
118 fields.append(
"length = %d" % self.
val[
"m_length"])
119 fields.append(
"main_type = %s" % self.
val[
"main_type"])
120 return "\n{" +
",\n ".join(fields) +
"}"
124 """Pretty-print an objet of type main_type"""
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".
139 field.name.replace(
"flag_",
"")
141 if field.name.startswith(
"flag_")
and self.
val[field.name]
143 return "|".join(fields)
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"]
150 return "%s (gdbarch)" % self.
val[
"m_owner"][
"gdbarch"]
153 """Return an image of the loc component inside the given field
156 loc_val = field_val[
"m_loc"]
157 loc_kind = str(field_val[
"m_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"]
169 return "m_loc = ??? (unsupported m_loc_kind value)"
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[
"m_artificial"]:
176 label +=
" (artificial)"
178 fields.append(
"m_name = %s" % f[
"m_name"])
179 fields.append(
"m_type = %s" % f[
"m_type"])
180 fields.append(
"m_loc_kind = %s" % f[
"m_loc_kind"])
181 fields.append(
"bitsize = %d" % f[
"m_bitsize"])
183 return label +
"\n" +
" {" +
",\n ".join(fields) +
"}"
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":
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))
201 """Return an image of the main_type bounds."""
202 b = self.
val[
"flds_bnds"][
"bounds"].dereference()
206 img =
"flds_bnds.bounds = {%s, %s}" % (low, high)
207 if b[
"flag_bound_evaluated"]:
208 img +=
" [evaluated]"
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":
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":
231 "calling_convention = %d"
232 % type_specific[
"func_stuff"][
"calling_convention"]
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":
241 "scaling_factor: <opaque> (call __gmpz_dump with "
242 " _mp_num and _mp_den fields if needed)"
244 elif type_specific_kind ==
"TYPE_SPECIFIC_INT":
245 img =
"int_stuff = { bit_size = %d, bit_offset = %d }" % (
246 type_specific[
"int_stuff"][
"bit_size"],
247 type_specific[
"int_stuff"][
"bit_offset"],
251 "type_specific = ??? (unknown type_specific_kind: %s)"
257 """Return a pretty-printed image of our main_type."""
259 fields.append(
"name = %s" % self.
val[
"name"])
260 fields.append(
"code = %s" % self.
val[
"code"])
263 fields.append(
"target_type = %s" % self.
val[
"m_target_type"])
264 if self.
val[
"m_nfields"] > 0:
265 for fieldno
in range(self.
val[
"m_nfields"]):
267 if self.
val[
"code"] == gdb.TYPE_CODE_RANGE:
271 return "\n{" +
",\n ".join(fields) +
"}"
275 """Print CORE_ADDR values as hex."""
281 return hex(int(self.
_val))
285 """Print a struct intrusive_list."""
293 "intrusive_list_node<{}>".format(self.
_item_type.tag)
303 member_node_ptr = self.
_conv_type.template_argument(1)
304 member_node_ptr = member_node_ptr.cast(gdb.lookup_type(
"int"))
315 """Return True if the list items use a node as a member, False if
316 they use a node as a base class.
319 if self.
_conv_type.name.startswith(
"intrusive_member_node<"):
321 elif self.
_conv_type.name.startswith(
"intrusive_base_node<"):
325 "Unexpected intrusive_list value -> node converter type: {}".format(
331 s =
"intrusive list of {}".format(self.
_item_type)
334 node_member = self.
_conv_type.template_argument(1)
335 s +=
", linked through {}".format(node_member)
340 """Given ELEM_PTR, a pointer to a list element, return a pointer to the
341 corresponding intrusive_list_node.
344 assert elem_ptr.type.code == gdb.TYPE_CODE_PTR
358 """Generator that yields one tuple per list item."""
360 elem_ptr = self.
_val[
"m_front"]
363 yield (str(idx), elem_ptr.dereference())
365 elem_ptr = node_ptr[
"next"]
373 """Pretty-printer for htab_t hash tables."""
382 n = int(self.
_val[
"n_elements"]) - int(self.
_val[
"n_deleted"])
383 return "htab_t with {} elements".format(n)
386 size = int(self.
_val[
"size"])
387 entries = self.
_val[
"entries"]
390 for entries_i
in range(size):
391 entry = entries[entries_i]
394 if int(entry)
in (0, 1):
397 yield (str(child_i), entry)
402 """A routine that returns the correct pretty printer for VAL
403 if appropriate. Returns None otherwise.
409 elif tag ==
"main_type":
411 elif name ==
"CORE_ADDR":
413 elif tag
is not None and tag.startswith(
"intrusive_list<"):
415 elif name ==
"htab_t":
421 """A routine to register a pretty-printer against the given OBJFILE."""
422 objfile.pretty_printers.append(type_lookup_function)
425if __name__ ==
"__main__":
426 if gdb.current_objfile()
is not None:
437 if os.path.basename(objfile.filename) ==
"gdb":
438 objfile.pretty_printers.append(type_lookup_function)
_as_node_ptr(self, elem_ptr)
_children_generator(self)
struct_field_img(self, fieldno)
bound_img(self, bound_name)
struct_field_location_img(self, field_val)
__init__(self, name, value)
register_pretty_printer(objfile)
type_lookup_function(val)
struct field * fields() const