]>
git.saurik.com Git - apple/xnu.git/blob - tools/lldbmacros/structanalyze.py
4 _UnionStructClass
= [ lldb
.eTypeClassStruct
, lldb
.eTypeClassClass
, lldb
.eTypeClassUnion
]
6 def _get_offset_formatter(ctx
, fmt_hex
, fmt_dec
):
7 """ Returns a formatter of struct member offsets and sizes.
10 ctx - configuration context
11 fmt_hex - hexadecimal format
12 fmt_dec - decimal format
22 return lambda o
, s
: O
.format(fmt
, o
, s
)
24 def _get_num_formatter(ctx
, fmt_hex
, fmt_dec
):
25 """ Returns a number formatter.
28 ctx - configuration context
29 fmt_hex - hexadecimal format
30 fmt_dec - decimal format
40 return lambda n
: O
.format(fmt
, n
)
42 def _showStructPacking(ctx
, symbol
, begin_offset
=0, symsize
=0, typedef
=None, outerSize
=0, memberName
=None):
43 """ Recursively parse the field members of structure.
46 ctx - context containing configuration settings and the output formatter (standard.py) symbol (lldb.SBType) reference to symbol in binary
48 string containing lines of output.
52 format_offset
= _get_offset_formatter(ctx
, "{:#06x},[{:#6x}]", "{:04d},[{:4d}]")
53 format_num
= _get_num_formatter(ctx
, "{:#04x}", "{:2d}")
55 ctype
= "unknown type"
59 sym_size
= symbol
.GetByteSize()
61 if symbol
.GetTypeClass() == lldb
.eTypeClassUnion
:
65 if symbol
.GetTypeClass() == lldb
.eTypeClassStruct
:
67 if symbol
.GetTypeClass() == lldb
.eTypeClassClass
:
71 if not outerSize
or outerSize
== sym_size
:
72 outstr
= format_offset(begin_offset
, sym_size
)
73 elif outerSize
< sym_size
: # happens with c++ inheritance
74 outstr
= format_offset(begin_offset
, outerSize
)
76 outstr
= O
.format("{:s}{VT.DarkRed}{{{:s}}}{VT.Default}",
77 format_offset(begin_offset
, sym_size
),
78 format_num(outerSize
- sym_size
))
81 outstr
+= O
.format(" {0}", typedef
)
82 if symbol
.IsAnonymousType():
83 outstr
+= O
.format(" ({VT.DarkMagenta}anonymous {0}{VT.Default})", ctype
)
85 outstr
+= O
.format(" ({VT.DarkMagenta}{0} {1}{VT.Default})", ctype
, symbol
.GetName())
87 outstr
+= O
.format(" {0} {{", memberName
)
95 _packed_bit_offset
= 0
96 _nfields
= symbol
.GetNumberOfFields()
99 _next_offset_in_bits
= 0
100 _nclasses
= symbol
.GetNumberOfDirectBaseClasses()
102 for i
in range(_nclasses
):
103 member
= symbol
.GetDirectBaseClassAtIndex(i
)
104 if i
< _nclasses
- 1:
105 m_size_bits
= symbol
.GetDirectBaseClassAtIndex(i
+ 1).GetOffsetInBits()
107 m_size_bits
= symbol
.GetFieldAtIndex(0).GetOffsetInBits()
109 m_size_bits
= symbol
.GetByteSize() * 8
111 m_offset
= member
.GetOffsetInBytes() + begin_offset
112 m_type
= member
.GetType()
113 m_name
= member
.GetName()
114 m_size
= m_size_bits
/ 8
116 _previous_size
= m_size
117 _packed_bit_offset
= member
.GetOffsetInBits() + m_size_bits
119 _showStructPacking(ctx
, m_type
, m_offset
, str(m_type
), outerSize
=m_size
, memberName
=m_name
)
121 for i
in range(_nfields
):
122 member
= symbol
.GetFieldAtIndex(i
)
123 m_offset
= member
.GetOffsetInBytes() + begin_offset
124 m_offset_bits
= member
.GetOffsetInBits()
126 m_type
= member
.GetType()
127 m_name
= member
.GetName()
128 m_size
= m_type
.GetByteSize()
130 if member
.IsBitfield():
132 m_size_bits
= member
.GetBitfieldSizeInBits()
134 m_is_bitfield
= False
135 m_size_bits
= m_size
* 8
137 if not is_union
and _packed_bit_offset
< m_offset_bits
:
138 m_previous_offset
= begin_offset
+ _packed_bit_offset
/ 8
139 m_hole_bits
= m_offset_bits
- _packed_bit_offset
140 if _packed_bit_offset
% 8 == 0:
141 print O
.format("{:s} ({VT.DarkRed}*** padding ***{VT.Default})",
142 format_offset(m_previous_offset
, m_hole_bits
/ 8))
144 print O
.format("{:s} ({VT.Brown}*** padding : {:s} ***{VT.Default})",
145 format_offset(m_previous_offset
, _previous_size
),
146 format_num(m_hole_bits
))
148 _previous_size
= m_size
149 _packed_bit_offset
= m_offset_bits
+ m_size_bits
151 _type_class
= m_type
.GetTypeClass()
152 _canonical_type
= m_type
.GetCanonicalType()
153 _canonical_type_class
= m_type
.GetCanonicalType().GetTypeClass()
155 if _type_class
== lldb
.eTypeClassTypedef
and _canonical_type_class
in _UnionStructClass
:
156 _showStructPacking(ctx
, _canonical_type
, m_offset
, str(m_type
), outerSize
=union_size
, memberName
=m_name
)
157 elif _type_class
in _UnionStructClass
:
158 _showStructPacking(ctx
, m_type
, m_offset
, outerSize
=union_size
, memberName
=m_name
)
160 outstr
= format_offset(m_offset
, m_size
)
161 if is_union
and union_size
!= m_size_bits
/ 8:
162 outstr
+= O
.format("{VT.DarkRed}{{{:s}}}{VT.Default}",
163 format_num(union_size
- m_size_bits
/ 8))
165 outstr
+= O
.format(" ({VT.DarkGreen}{:s} : {:s}{VT.Default}) {:s}",
167 format_num(m_size_bits
),
170 outstr
+= O
.format(" ({VT.DarkGreen}{:s}{VT.Default}) {:s}",
171 m_type
.GetName(), m_name
)
174 referenceSize
= min(outerSize
, sym_size
) or sym_size
175 if not is_union
and _packed_bit_offset
< referenceSize
* 8:
176 m_previous_offset
= begin_offset
+ _packed_bit_offset
/ 8
177 m_hole_bits
= referenceSize
* 8 - _packed_bit_offset
178 if _packed_bit_offset
% 8 == 0:
179 print O
.format("{:s} ({VT.DarkRed}*** padding ***{VT.Default})",
180 format_offset(m_previous_offset
, m_hole_bits
/ 8))
182 print O
.format("{:s} ({VT.Brown}padding : {:s}{VT.Default})\n",
183 format_offset(m_previous_offset
, _previous_size
),
184 format_num(m_hole_bits
))
188 @lldb_command('showstructpacking', "X" , fancy
=True)
189 def showStructInfo(cmd_args
=None, cmd_options
={}, O
=None):
190 """ Show how a structure is packed in the binary.
192 Usage: showstructpacking [-X] <type name>
193 -X : prints struct members offsets and sizes in a hexadecimal format (decimal is default)
196 <offset>, [<size_of_member>] (<type>) <name>
199 (lldb) showstructpacking pollfd
200 0,[ 8] struct pollfd {
202 4,[ 2] (short) events
203 6,[ 2] (short) revents
207 raise ArgumentError("Please provide a type name.")
209 ty_name
= cmd_args
[0]
211 sym
= gettype(ty_name
)
213 return O
.error("Cannot find type named {0}", ty_name
)
215 if sym
.GetTypeClass() == lldb
.eTypeClassTypedef
:
216 sym
= sym
.GetCanonicalType()
218 if sym
.GetTypeClass() not in _UnionStructClass
:
219 return O
.error("{0} is not a structure/union/class type", ty_name
)
221 ctx
= (O
, "-X" in cmd_options
)
223 _showStructPacking(ctx
, sym
, 0)
225 # EndMacro: showstructinto