1 #ifdef SWIGPYTHON
2 %pythoncode%{
3 # ==================================
4 # Helper function for SBModule class
5 # ==================================
6 def in_range(symbol, section):
7     """Test whether a symbol is within the range of a section."""
8     symSA = symbol.GetStartAddress().GetFileAddress()
9     symEA = symbol.GetEndAddress().GetFileAddress()
10     secSA = section.GetFileAddress()
11     secEA = secSA + section.GetByteSize()
12 
13     if symEA != LLDB_INVALID_ADDRESS:
14         if secSA <= symSA and symEA <= secEA:
15             return True
16         else:
17             return False
18     else:
19         if secSA <= symSA and symSA < secEA:
20             return True
21         else:
22             return False
23 %}
24 #endif
25 
26 STRING_EXTENSION_OUTSIDE(SBModule)
27 
28 %extend lldb::SBModule {
29 #ifdef SWIGPYTHON
30     %pythoncode %{
31         def __len__(self):
32             '''Return the number of symbols in a lldb.SBModule object.'''
33             return self.GetNumSymbols()
34 
35         def __iter__(self):
36             '''Iterate over all symbols in a lldb.SBModule object.'''
37             return lldb_iter(self, 'GetNumSymbols', 'GetSymbolAtIndex')
38 
39         def section_iter(self):
40             '''Iterate over all sections in a lldb.SBModule object.'''
41             return lldb_iter(self, 'GetNumSections', 'GetSectionAtIndex')
42 
43         def compile_unit_iter(self):
44             '''Iterate over all compile units in a lldb.SBModule object.'''
45             return lldb_iter(self, 'GetNumCompileUnits', 'GetCompileUnitAtIndex')
46 
47         def symbol_in_section_iter(self, section):
48             '''Given a module and its contained section, returns an iterator on the
49             symbols within the section.'''
50             for sym in self:
51                 if in_range(sym, section):
52                     yield sym
53 
54         class symbols_access(object):
55             re_compile_type = type(re.compile('.'))
56             '''A helper object that will lazily hand out lldb.SBSymbol objects for a module when supplied an index, name, or regular expression.'''
57             def __init__(self, sbmodule):
58                 self.sbmodule = sbmodule
59 
60             def __len__(self):
61                 if self.sbmodule:
62                     return int(self.sbmodule.GetNumSymbols())
63                 return 0
64 
65             def __getitem__(self, key):
66                 count = len(self)
67                 if type(key) is int:
68                     if -count <= key < count:
69                         key %= count
70                         return self.sbmodule.GetSymbolAtIndex(key)
71                 elif type(key) is str:
72                     matches = []
73                     sc_list = self.sbmodule.FindSymbols(key)
74                     for sc in sc_list:
75                         symbol = sc.symbol
76                         if symbol:
77                             matches.append(symbol)
78                     return matches
79                 elif isinstance(key, self.re_compile_type):
80                     matches = []
81                     for idx in range(count):
82                         symbol = self.sbmodule.GetSymbolAtIndex(idx)
83                         added = False
84                         name = symbol.name
85                         if name:
86                             re_match = key.search(name)
87                             if re_match:
88                                 matches.append(symbol)
89                                 added = True
90                         if not added:
91                             mangled = symbol.mangled
92                             if mangled:
93                                 re_match = key.search(mangled)
94                                 if re_match:
95                                     matches.append(symbol)
96                     return matches
97                 else:
98                     print("error: unsupported item type: %s" % type(key))
99                 return None
100 
101         def get_symbols_access_object(self):
102             '''An accessor function that returns a symbols_access() object which allows lazy symbol access from a lldb.SBModule object.'''
103             return self.symbols_access (self)
104 
105         def get_compile_units_access_object (self):
106             '''An accessor function that returns a compile_units_access() object which allows lazy compile unit access from a lldb.SBModule object.'''
107             return self.compile_units_access (self)
108 
109         def get_symbols_array(self):
110             '''An accessor function that returns a list() that contains all symbols in a lldb.SBModule object.'''
111             symbols = []
112             for idx in range(self.num_symbols):
113                 symbols.append(self.GetSymbolAtIndex(idx))
114             return symbols
115 
116         class sections_access(object):
117             re_compile_type = type(re.compile('.'))
118             '''A helper object that will lazily hand out lldb.SBSection objects for a module when supplied an index, name, or regular expression.'''
119             def __init__(self, sbmodule):
120                 self.sbmodule = sbmodule
121 
122             def __len__(self):
123                 if self.sbmodule:
124                     return int(self.sbmodule.GetNumSections())
125                 return 0
126 
127             def __getitem__(self, key):
128                 count = len(self)
129                 if type(key) is int:
130                     if -count <= key < count:
131                         key %= count
132                         return self.sbmodule.GetSectionAtIndex(key)
133                 elif type(key) is str:
134                     for idx in range(count):
135                         section = self.sbmodule.GetSectionAtIndex(idx)
136                         if section.name == key:
137                             return section
138                 elif isinstance(key, self.re_compile_type):
139                     matches = []
140                     for idx in range(count):
141                         section = self.sbmodule.GetSectionAtIndex(idx)
142                         name = section.name
143                         if name:
144                             re_match = key.search(name)
145                             if re_match:
146                                 matches.append(section)
147                     return matches
148                 else:
149                     print("error: unsupported item type: %s" % type(key))
150                 return None
151 
152         class compile_units_access(object):
153             re_compile_type = type(re.compile('.'))
154             '''A helper object that will lazily hand out lldb.SBCompileUnit objects for a module when supplied an index, full or partial path, or regular expression.'''
155             def __init__(self, sbmodule):
156                 self.sbmodule = sbmodule
157 
158             def __len__(self):
159                 if self.sbmodule:
160                     return int(self.sbmodule.GetNumCompileUnits())
161                 return 0
162 
163             def __getitem__(self, key):
164                 count = len(self)
165                 if type(key) is int:
166                     if -count <= key < count:
167                         key %= count
168                         return self.sbmodule.GetCompileUnitAtIndex(key)
169                 elif type(key) is str:
170                     is_full_path = key[0] == '/'
171                     for idx in range(count):
172                         comp_unit = self.sbmodule.GetCompileUnitAtIndex(idx)
173                         if is_full_path:
174                             if comp_unit.file.fullpath == key:
175                                 return comp_unit
176                         else:
177                             if comp_unit.file.basename == key:
178                                 return comp_unit
179                 elif isinstance(key, self.re_compile_type):
180                     matches = []
181                     for idx in range(count):
182                         comp_unit = self.sbmodule.GetCompileUnitAtIndex(idx)
183                         fullpath = comp_unit.file.fullpath
184                         if fullpath:
185                             re_match = key.search(fullpath)
186                             if re_match:
187                                 matches.append(comp_unit)
188                     return matches
189                 else:
190                     print("error: unsupported item type: %s" % type(key))
191                 return None
192 
193         def get_sections_access_object(self):
194             '''An accessor function that returns a sections_access() object which allows lazy section array access.'''
195             return self.sections_access (self)
196 
197         def get_sections_array(self):
198             '''An accessor function that returns an array object that contains all sections in this module object.'''
199             if not hasattr(self, 'sections_array'):
200                 self.sections_array = []
201                 for idx in range(self.num_sections):
202                     self.sections_array.append(self.GetSectionAtIndex(idx))
203             return self.sections_array
204 
205         def get_compile_units_array(self):
206             '''An accessor function that returns an array object that contains all compile_units in this module object.'''
207             if not hasattr(self, 'compile_units_array'):
208                 self.compile_units_array = []
209                 for idx in range(self.GetNumCompileUnits()):
210                     self.compile_units_array.append(self.GetCompileUnitAtIndex(idx))
211             return self.compile_units_array
212 
213         symbols = property(get_symbols_array, None, doc='''A read only property that returns a list() of lldb.SBSymbol objects contained in this module.''')
214         symbol = property(get_symbols_access_object, None, doc='''A read only property that can be used to access symbols by index ("symbol = module.symbol[0]"), name ("symbols = module.symbol['main']"), or using a regular expression ("symbols = module.symbol[re.compile(...)]"). The return value is a single lldb.SBSymbol object for array access, and a list() of lldb.SBSymbol objects for name and regular expression access''')
215         sections = property(get_sections_array, None, doc='''A read only property that returns a list() of lldb.SBSection objects contained in this module.''')
216         compile_units = property(get_compile_units_array, None, doc='''A read only property that returns a list() of lldb.SBCompileUnit objects contained in this module.''')
217         section = property(get_sections_access_object, None, doc='''A read only property that can be used to access symbols by index ("section = module.section[0]"), name ("sections = module.section[\'main\']"), or using a regular expression ("sections = module.section[re.compile(...)]"). The return value is a single lldb.SBSection object for array access, and a list() of lldb.SBSection objects for name and regular expression access''')
218         section = property(get_sections_access_object, None, doc='''A read only property that can be used to access compile units by index ("compile_unit = module.compile_unit[0]"), name ("compile_unit = module.compile_unit[\'main.cpp\']"), or using a regular expression ("compile_unit = module.compile_unit[re.compile(...)]"). The return value is a single lldb.SBCompileUnit object for array access or by full or partial path, and a list() of lldb.SBCompileUnit objects regular expressions.''')
219 
220         def get_uuid(self):
221             return uuid.UUID (self.GetUUIDString())
222 
223         uuid = property(get_uuid, None, doc='''A read only property that returns a standard python uuid.UUID object that represents the UUID of this module.''')
224         file = property(GetFileSpec, None, doc='''A read only property that returns an lldb object that represents the file (lldb.SBFileSpec) for this object file for this module as it is represented where it is being debugged.''')
225         platform_file = property(GetPlatformFileSpec, None, doc='''A read only property that returns an lldb object that represents the file (lldb.SBFileSpec) for this object file for this module as it is represented on the current host system.''')
226         byte_order = property(GetByteOrder, None, doc='''A read only property that returns an lldb enumeration value (lldb.eByteOrderLittle, lldb.eByteOrderBig, lldb.eByteOrderInvalid) that represents the byte order for this module.''')
227         addr_size = property(GetAddressByteSize, None, doc='''A read only property that returns the size in bytes of an address for this module.''')
228         triple = property(GetTriple, None, doc='''A read only property that returns the target triple (arch-vendor-os) for this module.''')
229         num_symbols = property(GetNumSymbols, None, doc='''A read only property that returns number of symbols in the module symbol table as an integer.''')
230         num_sections = property(GetNumSections, None, doc='''A read only property that returns number of sections in the module as an integer.''')
231 
232     %}
233 #endif
234 }
235