]>
git.saurik.com Git - apple/xnu.git/blob - tools/lldbmacros/structanalyze.py
4 _UnionStructClass
= [ lldb
.eTypeClassStruct
, lldb
.eTypeClassClass
, lldb
.eTypeClassUnion
]
6 def _showStructPacking(O
, symbol
, begin_offset
=0, symsize
=0, typedef
=None, outerSize
=0, memberName
=None):
8 recursively parse the field members of structure.
9 params : O the output formatter (standard.py)
10 symbol (lldb.SBType) reference to symbol in binary
11 returns: string containing lines of output.
13 ctype
= "unknown type"
17 sym_size
= symbol
.GetByteSize()
19 if symbol
.GetTypeClass() == lldb
.eTypeClassUnion
:
23 if symbol
.GetTypeClass() == lldb
.eTypeClassStruct
:
25 if symbol
.GetTypeClass() == lldb
.eTypeClassClass
:
29 if not outerSize
or outerSize
== sym_size
:
30 outstr
= O
.format("{:04d},[{:4d}]", begin_offset
, sym_size
)
31 elif outerSize
< sym_size
: # happens with c++ inheritance
32 outstr
= O
.format("{:04d},[{:4d}]", begin_offset
, outerSize
)
34 outstr
= O
.format("{:04d},[{:4d}]{VT.DarkRed}{{{:+d}}}{VT.Default}",
35 begin_offset
, sym_size
, outerSize
- sym_size
)
38 outstr
+= O
.format(" {0}", typedef
)
39 if symbol
.IsAnonymousType():
40 outstr
+= O
.format(" ({VT.DarkMagenta}anonymous {0}{VT.Default})", ctype
)
42 outstr
+= O
.format(" ({VT.DarkMagenta}{0} {1}{VT.Default})", ctype
, symbol
.GetName())
44 outstr
+= O
.format(" {0} {{", memberName
)
52 _packed_bit_offset
= 0
53 _nfields
= symbol
.GetNumberOfFields()
56 _next_offset_in_bits
= 0
57 _nclasses
= symbol
.GetNumberOfDirectBaseClasses()
59 for i
in range(_nclasses
):
60 member
= symbol
.GetDirectBaseClassAtIndex(i
)
62 m_size_bits
= symbol
.GetDirectBaseClassAtIndex(i
+ 1).GetOffsetInBits()
64 m_size_bits
= symbol
.GetFieldAtIndex(0).GetOffsetInBits()
66 m_size_bits
= symbol
.GetByteSize() * 8
68 m_offset
= member
.GetOffsetInBytes() + begin_offset
69 m_type
= member
.GetType()
70 m_name
= member
.GetName()
71 m_size
= m_size_bits
/ 8
73 _previous_size
= m_size
74 _packed_bit_offset
= member
.GetOffsetInBits() + m_size_bits
76 _showStructPacking(O
, m_type
, m_offset
, str(m_type
), outerSize
=m_size
, memberName
=m_name
)
78 for i
in range(_nfields
):
79 member
= symbol
.GetFieldAtIndex(i
)
80 m_offset
= member
.GetOffsetInBytes() + begin_offset
81 m_offset_bits
= member
.GetOffsetInBits()
83 m_type
= member
.GetType()
84 m_name
= member
.GetName()
85 m_size
= m_type
.GetByteSize()
87 if member
.IsBitfield():
89 m_size_bits
= member
.GetBitfieldSizeInBits()
92 m_size_bits
= m_size
* 8
94 if not is_union
and _packed_bit_offset
< m_offset_bits
:
95 m_previous_offset
= begin_offset
+ _packed_bit_offset
/ 8
96 m_hole_bits
= m_offset_bits
- _packed_bit_offset
97 if _packed_bit_offset
% 8 == 0:
98 print O
.format("{:04d},[{:4d}] ({VT.DarkRed}*** padding ***{VT.Default})",
99 m_previous_offset
, m_hole_bits
/ 8)
101 print O
.format("{:04d},[{:4d}] ({VT.Brown}*** padding : {:d} ***{VT.Default})",
102 m_previous_offset
, _previous_size
, m_hole_bits
)
104 _previous_size
= m_size
105 _packed_bit_offset
= m_offset_bits
+ m_size_bits
107 _type_class
= m_type
.GetTypeClass()
108 _canonical_type
= m_type
.GetCanonicalType()
109 _canonical_type_class
= m_type
.GetCanonicalType().GetTypeClass()
111 if _type_class
== lldb
.eTypeClassTypedef
and _canonical_type_class
in _UnionStructClass
:
112 _showStructPacking(O
, _canonical_type
, m_offset
, str(m_type
), outerSize
=union_size
, memberName
=m_name
)
113 elif _type_class
in _UnionStructClass
:
114 _showStructPacking(O
, m_type
, m_offset
, outerSize
=union_size
, memberName
=m_name
)
116 outstr
= O
.format("{:04d},[{:4d}]", m_offset
, m_size
)
117 if is_union
and union_size
!= m_size_bits
/ 8:
118 outstr
+= O
.format("{VT.DarkRed}{{{:+d}}}{VT.Default}",
119 union_size
- m_size_bits
/ 8)
121 outstr
+= O
.format(" ({VT.DarkGreen}{:s} : {:d}{VT.Default}) {:s}",
122 m_type
.GetName(), m_size_bits
, m_name
)
124 outstr
+= O
.format(" ({VT.DarkGreen}{:s}{VT.Default}) {:s}",
125 m_type
.GetName(), m_name
)
128 referenceSize
= min(outerSize
, sym_size
) or sym_size
129 if not is_union
and _packed_bit_offset
< referenceSize
* 8:
130 m_previous_offset
= begin_offset
+ _packed_bit_offset
/ 8
131 m_hole_bits
= referenceSize
* 8 - _packed_bit_offset
132 offset
= _packed_bit_offset
/ 8 + begin_offset
133 if _packed_bit_offset
% 8 == 0:
134 print O
.format("{:04d},[{:4d}] ({VT.DarkRed}*** padding ***{VT.Default})",
135 m_previous_offset
, m_hole_bits
/ 8)
137 print O
.format("{:04d},[{:4d}] ({VT.Brown}padding : {:d}{VT.Default})\n",
138 m_previous_offset
, _previous_size
, m_hole_bits
)
142 @lldb_command('showstructpacking', fancy
=True)
143 def showStructInfo(cmd_args
=None, cmd_options
={}, O
=None):
144 """Show how a structure is packed in the binary. The format is
145 <offset>, [<size_of_member>] (<type>) <name>
148 (lldb) showstructpacking pollfd
149 0,[ 8] struct pollfd {
151 4,[ 2] (short) events
152 6,[ 2] (short) revents
155 syntax: showstructpacking task
158 raise ArgumentError("Please provide a type name.")
160 ty_name
= cmd_args
[0]
162 sym
= gettype(ty_name
)
164 return O
.error("Cannot find type named {0}", ty_name
)
166 if sym
.GetTypeClass() == lldb
.eTypeClassTypedef
:
167 sym
= sym
.GetCanonicalType()
169 if sym
.GetTypeClass() not in _UnionStructClass
:
170 return O
.error("{0} is not a structure/union/class type", ty_name
)
172 _showStructPacking(O
, sym
, 0)
174 # EndMacro: showstructinto