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