gdb-gdb.py.in: Don't print value's tag_name
[external/binutils.git] / gdb / gdb-gdb.py.in
1 # Copyright (C) 2009-2018 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 import gdb
19 import os.path
20
21 class TypeFlag:
22     """A class that allows us to store a flag name, its short name,
23     and its value.
24
25     In the GDB sources, struct type has a component called instance_flags
26     in which the value is the addition of various flags.  These flags are
27     defined by the enumerates type_instance_flag_value.  This class helps us
28     recreate a list with all these flags that is easy to manipulate and sort.
29     Because all flag names start with TYPE_INSTANCE_FLAG_, a short_name
30     attribute is provided that strips this prefix.
31
32     ATTRIBUTES
33       name:  The enumeration name (eg: "TYPE_INSTANCE_FLAG_CONST").
34       value: The associated value.
35       short_name: The enumeration name, with the suffix stripped.
36     """
37     def __init__(self, name, value):
38         self.name = name
39         self.value = value
40         self.short_name = name.replace("TYPE_INSTANCE_FLAG_", '')
41
42     def __lt__(self, other):
43         """Sort by value order."""
44         return self.value < other.value
45         
46
47 # A list of all existing TYPE_INSTANCE_FLAGS_* enumerations,
48 # stored as TypeFlags objects.  Lazy-initialized.
49 TYPE_FLAGS = None
50
51 class TypeFlagsPrinter:
52     """A class that prints a decoded form of an instance_flags value.
53
54     This class uses a global named TYPE_FLAGS, which is a list of
55     all defined TypeFlag values.  Using a global allows us to compute
56     this list only once.
57
58     This class relies on a couple of enumeration types being defined.
59     If not, then printing of the instance_flag is going to be degraded,
60     but it's not a fatal error.
61     """
62     def __init__(self, val):
63         self.val = val
64     def __str__(self):
65         global TYPE_FLAGS
66         if TYPE_FLAGS is None:
67             self.init_TYPE_FLAGS()
68         if not self.val:
69             return "0"
70         if TYPE_FLAGS:
71             flag_list = [flag.short_name for flag in TYPE_FLAGS
72                          if self.val & flag.value]
73         else:
74             flag_list = ["???"]
75         return "0x%x [%s]" % (self.val, "|".join(flag_list))
76     def init_TYPE_FLAGS(self):
77         """Initialize the TYPE_FLAGS global as a list of TypeFlag objects.
78         This operation requires the search of a couple of enumeration types.
79         If not found, a warning is printed on stdout, and TYPE_FLAGS is
80         set to the empty list.
81
82         The resulting list is sorted by increasing value, to facilitate
83         printing of the list of flags used in an instance_flags value.
84         """
85         global TYPE_FLAGS
86         TYPE_FLAGS = []
87         try:
88             iflags = gdb.lookup_type("enum type_instance_flag_value")
89         except:
90             print("Warning: Cannot find enum type_instance_flag_value type.")
91             print("         `struct type' pretty-printer will be degraded")
92             return
93         TYPE_FLAGS = [TypeFlag(field.name, field.enumval)
94                       for field in iflags.fields()]
95         TYPE_FLAGS.sort()
96
97 class StructTypePrettyPrinter:
98     """Pretty-print an object of type struct type"""
99     def __init__(self, val):
100         self.val = val
101     def to_string(self):
102         fields = []
103         fields.append("pointer_type = %s" % self.val['pointer_type'])
104         fields.append("reference_type = %s" % self.val['reference_type'])
105         fields.append("chain = %s" % self.val['reference_type'])
106         fields.append("instance_flags = %s"
107                       % TypeFlagsPrinter(self.val['instance_flags']))
108         fields.append("length = %d" % self.val['length'])
109         fields.append("main_type = %s" % self.val['main_type'])
110         return "\n{" + ",\n ".join(fields) + "}"
111
112 class StructMainTypePrettyPrinter:
113     """Pretty-print an objet of type main_type"""
114     def __init__(self, val):
115         self.val = val
116     def flags_to_string(self):
117         """struct main_type contains a series of components that
118         are one-bit ints whose name start with "flag_".  For instance:
119         flag_unsigned, flag_stub, etc.  In essence, these components are
120         really boolean flags, and this method prints a short synthetic
121         version of the value of all these flags.  For instance, if
122         flag_unsigned and flag_static are the only components set to 1,
123         this function will return "unsigned|static".
124         """
125         fields = [field.name.replace("flag_", "")
126                   for field in self.val.type.fields()
127                   if field.name.startswith("flag_")
128                      and self.val[field.name]]
129         return "|".join(fields)
130     def owner_to_string(self):
131         """Return an image of component "owner".
132         """
133         if self.val['flag_objfile_owned'] != 0:
134             return "%s (objfile)" % self.val['owner']['objfile']
135         else:
136             return "%s (gdbarch)" % self.val['owner']['gdbarch']
137     def struct_field_location_img(self, field_val):
138         """Return an image of the loc component inside the given field
139         gdb.Value.
140         """
141         loc_val = field_val['loc']
142         loc_kind = str(field_val['loc_kind'])
143         if loc_kind == "FIELD_LOC_KIND_BITPOS":
144             return 'bitpos = %d' % loc_val['bitpos']
145         elif loc_kind == "FIELD_LOC_KIND_ENUMVAL":
146             return 'enumval = %d' % loc_val['enumval']
147         elif loc_kind == "FIELD_LOC_KIND_PHYSADDR":
148             return 'physaddr = 0x%x' % loc_val['physaddr']
149         elif loc_kind == "FIELD_LOC_KIND_PHYSNAME":
150             return 'physname = %s' % loc_val['physname']
151         elif loc_kind == "FIELD_LOC_KIND_DWARF_BLOCK":
152             return 'dwarf_block = %s' % loc_val['dwarf_block']
153         else:
154             return 'loc = ??? (unsupported loc_kind value)'
155     def struct_field_img(self, fieldno):
156         """Return an image of the main_type field number FIELDNO.
157         """
158         f = self.val['flds_bnds']['fields'][fieldno]
159         label = "flds_bnds.fields[%d]:" % fieldno
160         if f['artificial']:
161             label += " (artificial)"
162         fields = []
163         fields.append("name = %s" % f['name'])
164         fields.append("type = %s" % f['type'])
165         fields.append("loc_kind = %s" % f['loc_kind'])
166         fields.append("bitsize = %d" % f['bitsize'])
167         fields.append(self.struct_field_location_img(f))
168         return label + "\n" + "  {" + ",\n   ".join(fields) + "}"
169     def bounds_img(self):
170         """Return an image of the main_type bounds.
171         """
172         b = self.val['flds_bnds']['bounds'].dereference()
173         low = str(b['low'])
174         if b['low_undefined'] != 0:
175             low += " (undefined)"
176         high = str(b['high'])
177         if b['high_undefined'] != 0:
178             high += " (undefined)"
179         return "flds_bnds.bounds = {%s, %s}" % (low, high)
180     def type_specific_img(self):
181         """Return a string image of the main_type type_specific union.
182         Only the relevant component of that union is printed (based on
183         the value of the type_specific_kind field.
184         """
185         type_specific_kind = str(self.val['type_specific_field'])
186         type_specific = self.val['type_specific']
187         if type_specific_kind == "TYPE_SPECIFIC_NONE":
188             img = 'type_specific_field = %s' % type_specific_kind
189         elif type_specific_kind == "TYPE_SPECIFIC_CPLUS_STUFF":
190             img = "cplus_stuff = %s" % type_specific['cplus_stuff']
191         elif type_specific_kind == "TYPE_SPECIFIC_GNAT_STUFF":
192             img = ("gnat_stuff = {descriptive_type = %s}"
193                    % type_specific['gnat_stuff']['descriptive_type'])
194         elif type_specific_kind == "TYPE_SPECIFIC_FLOATFORMAT":
195             img = "floatformat[0..1] = %s" % type_specific['floatformat']
196         elif type_specific_kind == "TYPE_SPECIFIC_FUNC":
197             img = ("calling_convention = %d"
198                    % type_specific['func_stuff']['calling_convention'])
199             # tail_call_list is not printed.
200         elif type_specific_kind == "TYPE_SPECIFIC_SELF_TYPE":
201             img = "self_type = %s" % type_specific['self_type']
202         else:
203             img = ("type_specific = ??? (unknown type_secific_kind: %s)"
204                    % type_specific_kind)
205         return img
206
207     def to_string(self):
208         """Return a pretty-printed image of our main_type.
209         """
210         fields = []
211         fields.append("name = %s" % self.val['name'])
212         fields.append("code = %s" % self.val['code'])
213         fields.append("flags = [%s]" % self.flags_to_string())
214         fields.append("owner = %s" % self.owner_to_string())
215         fields.append("target_type = %s" % self.val['target_type'])
216         if self.val['nfields'] > 0:
217             for fieldno in range(self.val['nfields']):
218                 fields.append(self.struct_field_img(fieldno))
219         if self.val['code'] == gdb.TYPE_CODE_RANGE:
220             fields.append(self.bounds_img())
221         fields.append(self.type_specific_img())
222
223         return "\n{" + ",\n ".join(fields) + "}"
224
225 def type_lookup_function(val):
226     """A routine that returns the correct pretty printer for VAL
227     if appropriate.  Returns None otherwise.
228     """
229     if val.type.tag == "type":
230         return StructTypePrettyPrinter(val)
231     elif val.type.tag == "main_type":
232         return StructMainTypePrettyPrinter(val)
233     return None
234
235 def register_pretty_printer(objfile):
236     """A routine to register a pretty-printer against the given OBJFILE.
237     """
238     objfile.pretty_printers.append(type_lookup_function)
239
240 if __name__ == "__main__":
241     if gdb.current_objfile() is not None:
242         # This is the case where this script is being "auto-loaded"
243         # for a given objfile.  Register the pretty-printer for that
244         # objfile.
245         register_pretty_printer(gdb.current_objfile())
246     else:
247         # We need to locate the objfile corresponding to the GDB
248         # executable, and register the pretty-printer for that objfile.
249         # FIXME: The condition used to match the objfile is too simplistic
250         # and will not work on Windows.
251         for objfile in gdb.objfiles():
252             if os.path.basename(objfile.filename) == "gdb":
253                 objfile.pretty_printers.append(type_lookup_function)