ATLAS Offline Software
Loading...
Searching...
No Matches
pahole.py
Go to the documentation of this file.
1# noqa: ATL902
2# origin: https://github.com/PhilArmstrong/pahole-gdb
3#
4# File: GdbUtils/python/pahole.py
5#
6# pahole command for gdb
7
8# Copyright (C) 2008, 2025 Free Software Foundation, Inc.
9
10# This program is free software; you can redistribute it and/or modify
11# it under the terms of the GNU General Public License as published by
12# the Free Software Foundation; either version 3 of the License, or
13# (at your option) any later version.
14#
15# This program is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18# GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License
21# along with this program. If not, see <http://www.gnu.org/licenses/>.
22
23import gdb
24import gdb.types
25import math
26
27class Pahole (gdb.Command):
28 """Show the holes in a structure.
29This command takes a single argument, a type name.
30It prints the type and displays comments showing where holes are."""
31
32 def __init__ (self):
33 super (Pahole, self).__init__ ("pahole", gdb.COMMAND_DATA,
34 gdb.COMPLETE_SYMBOL)
35
36 def pahole (self, atype, level, name, walk=False, nested=False):
37 if name is None:
38 name = ''
39 tag = atype.tag
40 if tag is None:
41 tag = ''
42 kind = 'struct' if atype.code == gdb.TYPE_CODE_STRUCT else 'union'
43 if not nested:
44 print ('/* %4d 0x%04x */ ' % (atype.sizeof, atype.sizeof), end="")
45 print ('%s%s %s {' % ( ' ' * (2 * level), kind, tag))
46 endpos = 0
47 for field in atype.fields():
48 # Skip static fields
49 if not hasattr (field, ('bitpos')):
50 continue
51 # find the type
52 ftype = field.type.strip_typedefs()
53
54 # Detect hole
55 if endpos < field.bitpos:
56 hole = field.bitpos - endpos
57 print ('/* XXX %4d */ !!' % (hole // 8), end="")
58 print (' ' * (4 + 2 * level - 2), end="")
59 print ('char [%d] __%d_bit_padding__' % (math.ceil(hole / 8), hole))
60
61 # Are we a bitfield?
62 if field.bitsize > 0:
63 fieldsize = field.bitsize
64 else:
65 if (ftype.code == gdb.TYPE_CODE_STRUCT or ftype.code == gdb.TYPE_CODE_UNION) and len(ftype.fields()) == 0:
66 fieldsize = 0 # empty struct
67 else:
68 fieldsize = 8 * ftype.sizeof # will get packing wrong for structs
69
70 print ('/* %3d 0x%03x %4d */ ' % (field.bitpos // 8, field.bitpos // 8, fieldsize // 8), end="")
71 endpos = field.bitpos + fieldsize
72
73 # Walk nested structure or print variable size (this is not a hole)
74 if walk and (ftype.code == gdb.TYPE_CODE_STRUCT or ftype.code == gdb.TYPE_CODE_UNION):
75 print (' ', end="")
76 self.pahole (ftype, level + 1, field.name, walk=walk, nested=True)
77 else:
78 print (' ' * (4 + 2 * level), end="")
79 print ('%s %s' % (str (ftype), field.name),end="")
80 # Append bitfield size if non-standard
81 if fieldsize != ftype.sizeof * 8:
82 print (':%d' % fieldsize)
83 else:
84 print ('')
85
86 # Check for padding at the end
87 if endpos // 8 < atype.sizeof:
88 hole = 8 * atype.sizeof - endpos
89 print ('/* XXX %4d */ !!' % hole, end="")
90 print (' ' * (4 + 2 * level - 2), end="")
91 print ('char [%d] __%d_bit_padding__' % (math.ceil(hole / 8), hole))
92
93 print (' ' * (14 + 2 * level), end="")
94 print (' } %s' % name)
95
96 def invoke (self, arg, from_tty):
97 argv = gdb.string_to_argv(arg)
98 if len(argv) > 2:
99 raise gdb.GdbError('pahole takes a type name and an optional "walk" argument.')
100 stype = gdb.lookup_type (argv[0])
101 ptype = stype.strip_typedefs()
102 if ptype.code != gdb.TYPE_CODE_STRUCT and ptype.code != gdb.TYPE_CODE_UNION:
103 raise gdb.GdbError('%s is not a struct/union type: %s' % (arg, ptype.code))
104
105 # Should the entire object be walked recursively?
106 walk = len(argv) > 1 and argv[1] == "walk"
107
108 self.pahole (ptype, 0, argv[0], walk=walk)
109
110Pahole()
pahole(self, atype, level, name, walk=False, nested=False)
Definition pahole.py:36
invoke(self, arg, from_tty)
Definition pahole.py:96