]>
git.saurik.com Git - apple/xnu.git/blob - tools/lldbmacros/structanalyze.py
4 def _showStructPacking(symbol
, prefix
, begin_offset
=0, typedef
=None):
6 recursively parse the field members of structure.
7 params : symbol (lldb.SBType) reference to symbol in binary
8 prefix (string) string to be prefixed for each line of output. Useful for recursive struct parsing.
9 returns: string containing lines of output.
11 ctype
= "unknown type"
12 if symbol
.GetTypeClass() == lldb
.eTypeClassUnion
:
14 if symbol
.GetTypeClass() == lldb
.eTypeClassStruct
:
18 outstr
= "[%4d] (%s) (%s) %s { " % (symbol
.GetByteSize(), typedef
, ctype
, symbol
.GetName()) + "\n"
20 outstr
= "[%4d] (%s) %s { " % (symbol
.GetByteSize(), ctype
, symbol
.GetName()) + "\n"
21 numFields
= symbol
.GetNumberOfFields()
22 _has_memory_hole
= False
23 _compact_size
= 0 # asuming the struct is perfectly packed
24 _compact_offset
= begin_offset
25 _previous_bit_offset
= 0
26 for i
in range(numFields
):
27 member
= symbol
.GetFieldAtIndex(i
)
28 m_offset
= member
.GetOffsetInBytes() + begin_offset
29 m_offset_bits
= member
.GetOffsetInBits()
30 m_type
= member
.GetType()
31 m_name
= member
.GetName()
32 m_size
= m_type
.GetByteSize()
34 debugstr
= "" # + str((m_size, m_offset , m_offset_bits, _previous_bit_offset, _compact_offset, begin_offset))
35 if _compact_offset
!= m_offset
and (m_offset_bits
- _previous_bit_offset
) > m_size
*8 :
36 _has_memory_hole
= True
37 warningstr
= " *** Possible memory hole ***"
38 _compact_offset
= m_offset
39 _compact_offset
+= m_size
41 _type_class
= m_type
.GetTypeClass()
42 _canonical_type
= m_type
.GetCanonicalType()
43 _canonical_type_class
= m_type
.GetCanonicalType().GetTypeClass()
45 if _type_class
== lldb
.eTypeClassTypedef
and (_canonical_type_class
== lldb
.eTypeClassStruct
or _canonical_type_class
== lldb
.eTypeClassUnion
) :
46 outstr
+= prefix
+ ("*%4d," % m_offset
) + _showStructPacking(_canonical_type
, prefix
+" ", m_offset
, str(m_type
)) + warningstr
+ debugstr
+ "\n"
47 elif _type_class
== lldb
.eTypeClassStruct
or _type_class
== lldb
.eTypeClassUnion
:
48 outstr
+= prefix
+ ("*%4d," % m_offset
) + _showStructPacking(m_type
, prefix
+" ", m_offset
) + warningstr
+ debugstr
+ "\n"
50 outstr
+= prefix
+ ("+%4d,[%4d] (%s) %s" % (m_offset
, m_size
, m_type
.GetName(), m_name
)) + warningstr
+ debugstr
+ "\n"
52 _previous_bit_offset
= m_offset_bits
53 outstr
+= prefix
+ "}"
54 if _has_memory_hole
== True :
55 outstr
+= " *** Warning: Struct layout leaves memory hole *** "
58 @lldb_command('showstructpacking')
59 def showStructInfo(cmd_args
=None):
60 """Show how a structure is packed in the binary. The format is
61 +<offset>, [<size_of_member>] (<type>) <name>
63 (lldb) script lldbmacros.showStructInfo("pollfd")
64 [ 8] (struct) pollfd {
66 + 4,[ 2] (short) events
67 + 6,[ 2] (short) revents
69 syntax: showstructpacking task
72 raise ArgumentError("Please provide a type name.")
74 sym
= gettype(cmd_args
[0])
76 print "No such struct found"
77 if sym
.GetTypeClass() == lldb
.eTypeClassTypedef
:
78 sym
= sym
.GetCanonicalType()
79 if sym
.GetTypeClass() != lldb
.eTypeClassStruct
:
80 print "%s is not a structure" % cmd_args
[0]
82 print _showStructPacking(sym
,"", 0)
84 # EndMacro: showstructinto