]> git.saurik.com Git - apple/xnu.git/blob - tools/lldbmacros/structanalyze.py
xnu-3248.60.10.tar.gz
[apple/xnu.git] / tools / lldbmacros / structanalyze.py
1 import lldb
2 from xnu import *
3
4 def _showStructPacking(symbol, prefix, begin_offset=0):
5 """
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.
10 """
11 ctype = "unknown type"
12 if symbol.GetTypeClass() == lldb.eTypeClassUnion :
13 ctype = "union"
14 if symbol.GetTypeClass() == lldb.eTypeClassStruct :
15 ctype = "struct"
16 outstr = "[%4d] (%s) %s { " % (symbol.GetByteSize(), ctype, symbol.GetName()) + "\n"
17 numFields = symbol.GetNumberOfFields()
18 _has_memory_hole = False
19 _compact_size = 0 # asuming the struct is perfectly packed
20 _compact_offset = begin_offset
21 _previous_bit_offset = 0
22 for i in range(numFields):
23 member = symbol.GetFieldAtIndex(i)
24 m_offset = member.GetOffsetInBytes() + begin_offset
25 m_offset_bits = member.GetOffsetInBits()
26 m_type = member.GetType()
27 m_name = member.GetName()
28 m_size = m_type.GetByteSize()
29 warningstr = ""
30 debugstr = "" # + str((m_size, m_offset , m_offset_bits, _previous_bit_offset, _compact_offset, begin_offset))
31 if _compact_offset != m_offset and (m_offset_bits - _previous_bit_offset) > m_size*8 :
32 _has_memory_hole = True
33 warningstr = " *** Possible memory hole ***"
34 _compact_offset = m_offset
35 _compact_offset += m_size
36 if m_type.GetTypeClass() == lldb.eTypeClassStruct or m_type.GetTypeClass() == lldb.eTypeClassUnion :
37 outstr += prefix + ("*%4d," % m_offset) + _showStructPacking(m_type, prefix+" ", m_offset) + warningstr + debugstr + "\n"
38 else:
39 outstr += prefix + ("+%4d,[%4d] (%s) %s" % (m_offset, m_size, m_type.GetName(), m_name)) + warningstr + debugstr + "\n"
40 if i > 0 :
41 _previous_bit_offset = m_offset_bits
42 outstr += prefix + "}"
43 if _has_memory_hole == True :
44 outstr += " *** Warning: Struct layout leaves memory hole *** "
45 return outstr
46
47 @lldb_command('showstructpacking')
48 def showStructInfo(cmd_args=None):
49 """Show how a structure is packed in the binary. The format is
50 +<offset>, [<size_of_member>] (<type>) <name>
51 For example:
52 (lldb) script lldbmacros.showStructInfo("pollfd")
53 [ 8] (struct) pollfd {
54 + 0,[ 4] (int) fd
55 + 4,[ 2] (short) events
56 + 6,[ 2] (short) revents
57 }
58 syntax: showstructpacking task
59 """
60 if not cmd_args:
61 raise ArgumentError("Please provide a type name.")
62
63 sym = gettype(cmd_args[0])
64 if sym == None:
65 print "No such struct found"
66 if sym.GetTypeClass() == lldb.eTypeClassTypedef:
67 sym = sym.GetCanonicalType()
68 if sym.GetTypeClass() != lldb.eTypeClassStruct:
69 print "%s is not a structure" % cmd_args[0]
70 else:
71 print _showStructPacking(sym,"", 0)
72
73 # EndMacro: showstructinto