GDB (xrefs)
types.py
Go to the documentation of this file.
1 # Type utilities.
2 # Copyright (C) 2010-2015 Free Software Foundation, Inc.
3 
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 3 of the License, or
7 # (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 
17 """Utilities for working with gdb.Types."""
18 
19 import gdb
20 
21 
22 def get_basic_type(type_):
23  """Return the "basic" type of a type.
24 
25  Arguments:
26  type_: The type to reduce to its basic type.
27 
28  Returns:
29  type_ with const/volatile is stripped away,
30  and typedefs/references converted to the underlying type.
31  """
32 
33  while (type_.code == gdb.TYPE_CODE_REF or
34  type_.code == gdb.TYPE_CODE_TYPEDEF):
35  if type_.code == gdb.TYPE_CODE_REF:
36  type_ = type_.target()
37  else:
38  type_ = type_.strip_typedefs()
39  return type_.unqualified()
40 
41 
42 def has_field(type_, field):
43  """Return True if a type has the specified field.
44 
45  Arguments:
46  type_: The type to examine.
47  It must be one of gdb.TYPE_CODE_STRUCT, gdb.TYPE_CODE_UNION.
48  field: The name of the field to look up.
49 
50  Returns:
51  True if the field is present either in type_ or any baseclass.
52 
53  Raises:
54  TypeError: The type is not a struct or union.
55  """
56 
57  type_ = get_basic_type(type_)
58  if (type_.code != gdb.TYPE_CODE_STRUCT and
59  type_.code != gdb.TYPE_CODE_UNION):
60  raise TypeError("not a struct or union")
61  for f in type_.fields():
62  if f.is_base_class:
63  if has_field(f.type, field):
64  return True
65  else:
66  # NOTE: f.name could be None
67  if f.name == field:
68  return True
69  return False
70 
71 
72 def make_enum_dict(enum_type):
73  """Return a dictionary from a program's enum type.
74 
75  Arguments:
76  enum_type: The enum to compute the dictionary for.
77 
78  Returns:
79  The dictionary of the enum.
80 
81  Raises:
82  TypeError: The type is not an enum.
83  """
84 
85  if enum_type.code != gdb.TYPE_CODE_ENUM:
86  raise TypeError("not an enum type")
87  enum_dict = {}
88  for field in enum_type.fields():
89  # The enum's value is stored in "enumval".
90  enum_dict[field.name] = field.enumval
91  return enum_dict
92 
93 
94 def deep_items (type_):
95  """Return an iterator that recursively traverses anonymous fields.
96 
97  Arguments:
98  type_: The type to traverse. It should be one of
99  gdb.TYPE_CODE_STRUCT or gdb.TYPE_CODE_UNION.
100 
101  Returns:
102  an iterator similar to gdb.Type.iteritems(), i.e., it returns
103  pairs of key, value, but for any anonymous struct or union
104  field that field is traversed recursively, depth-first.
105  """
106  for k, v in type_.iteritems ():
107  if k:
108  yield k, v
109  else:
110  for i in deep_items (v.type):
111  yield i
112 
113 class TypePrinter(object):
114  """The base class for type printers.
115 
116  Instances of this type can be used to substitute type names during
117  'ptype'.
118 
119  A type printer must have at least 'name' and 'enabled' attributes,
120  and supply an 'instantiate' method.
121 
122  The 'instantiate' method must either return None, or return an
123  object which has a 'recognize' method. This method must accept a
124  gdb.Type argument and either return None, meaning that the type
125  was not recognized, or a string naming the type.
126  """
127 
128  def __init__(self, name):
129  self.name = name
130  self.enabled = True
131 
132  def instantiate(self):
133  return None
134 
135 # Helper function for computing the list of type recognizers.
136 def _get_some_type_recognizers(result, plist):
137  for printer in plist:
138  if printer.enabled:
139  inst = printer.instantiate()
140  if inst is not None:
141  result.append(inst)
142  return None
143 
145  "Return a list of the enabled type recognizers for the current context."
146  result = []
147 
148  # First try the objfiles.
149  for objfile in gdb.objfiles():
150  _get_some_type_recognizers(result, objfile.type_printers)
151  # Now try the program space.
152  _get_some_type_recognizers(result, gdb.current_progspace().type_printers)
153  # Finally, globals.
154  _get_some_type_recognizers(result, gdb.type_printers)
155 
156  return result
157 
158 def apply_type_recognizers(recognizers, type_obj):
159  """Apply the given list of type recognizers to the type TYPE_OBJ.
160  If any recognizer in the list recognizes TYPE_OBJ, returns the name
161  given by the recognizer. Otherwise, this returns None."""
162  for r in recognizers:
163  result = r.recognize(type_obj)
164  if result is not None:
165  return result
166  return None
167 
168 def register_type_printer(locus, printer):
169  """Register a type printer.
170  PRINTER is the type printer instance.
171  LOCUS is either an objfile, a program space, or None, indicating
172  global registration."""
173 
174  if locus is None:
175  locus = gdb
176  locus.type_printers.insert(0, printer)
def get_basic_type(type_)
Definition: types.py:22
def __init__(self, name)
Definition: types.py:128
def register_type_printer(locus, printer)
Definition: types.py:168
def deep_items(type_)
Definition: types.py:94
def make_enum_dict(enum_type)
Definition: types.py:72
def has_field(type_, field)
Definition: types.py:42
def _get_some_type_recognizers(result, plist)
Definition: types.py:136
def instantiate(self)
Definition: types.py:132
def apply_type_recognizers(recognizers, type_obj)
Definition: types.py:158
def get_type_recognizers()
Definition: types.py:144