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         # operator== is a free function, which swig does not handle, so we inject
32         # our own equality operator here
33         def __eq__(self, other):
34             return not self.__ne__(other)
35 
36         def __len__(self):
37             '''Return the number of symbols in a lldb.SBModule object.'''
38             return self.GetNumSymbols()
39 
40         def __iter__(self):
41             '''Iterate over all symbols in a lldb.SBModule object.'''
42             return lldb_iter(self, 'GetNumSymbols', 'GetSymbolAtIndex')
43 
44         def section_iter(self):
45             '''Iterate over all sections in a lldb.SBModule object.'''
46             return lldb_iter(self, 'GetNumSections', 'GetSectionAtIndex')
47 
48         def compile_unit_iter(self):
49             '''Iterate over all compile units in a lldb.SBModule object.'''
50             return lldb_iter(self, 'GetNumCompileUnits', 'GetCompileUnitAtIndex')
51 
52         def symbol_in_section_iter(self, section):
53             '''Given a module and its contained section, returns an iterator on the
54             symbols within the section.'''
55             for sym in self:
56                 if in_range(sym, section):
57                     yield sym
58 
59         class symbols_access(object):
60             re_compile_type = type(re.compile('.'))
61             '''A helper object that will lazily hand out lldb.SBSymbol objects for a module when supplied an index, name, or regular expression.'''
62             def __init__(self, sbmodule):
63                 self.sbmodule = sbmodule
64 
65             def __len__(self):
66                 if self.sbmodule:
67                     return int(self.sbmodule.GetNumSymbols())
68                 return 0
69 
70             def __getitem__(self, key):
71                 count = len(self)
72                 if type(key) is int:
73                     if -count <= key < count:
74                         key %= count
75                         return self.sbmodule.GetSymbolAtIndex(key)
76                 elif type(key) is str:
77                     matches = []
78                     sc_list = self.sbmodule.FindSymbols(key)
79                     for sc in sc_list:
80                         symbol = sc.symbol
81                         if symbol:
82                             matches.append(symbol)
83                     return matches
84                 elif isinstance(key, self.re_compile_type):
85                     matches = []
86                     for idx in range(count):
87                         symbol = self.sbmodule.GetSymbolAtIndex(idx)
88                         added = False
89                         name = symbol.name
90                         if name:
91                             re_match = key.search(name)
92                             if re_match:
93                                 matches.append(symbol)
94                                 added = True
95                         if not added:
96                             mangled = symbol.mangled
97                             if mangled:
98                                 re_match = key.search(mangled)
99                                 if re_match:
100                                     matches.append(symbol)
101                     return matches
102                 else:
103                     print("error: unsupported item type: %s" % type(key))
104                 return None
105 
106         def get_symbols_access_object(self):
107             '''An accessor function that returns a symbols_access() object which allows lazy symbol access from a lldb.SBModule object.'''
108             return self.symbols_access (self)
109 
110         def get_compile_units_access_object (self):
111             '''An accessor function that returns a compile_units_access() object which allows lazy compile unit access from a lldb.SBModule object.'''
112             return self.compile_units_access (self)
113 
114         def get_symbols_array(self):
115             '''An accessor function that returns a list() that contains all symbols in a lldb.SBModule object.'''
116             symbols = []
117             for idx in range(self.num_symbols):
118                 symbols.append(self.GetSymbolAtIndex(idx))
119             return symbols
120 
121         class sections_access(object):
122             re_compile_type = type(re.compile('.'))
123             '''A helper object that will lazily hand out lldb.SBSection objects for a module when supplied an index, name, or regular expression.'''
124             def __init__(self, sbmodule):
125                 self.sbmodule = sbmodule
126 
127             def __len__(self):
128                 if self.sbmodule:
129                     return int(self.sbmodule.GetNumSections())
130                 return 0
131 
132             def __getitem__(self, key):
133                 count = len(self)
134                 if type(key) is int:
135                     if -count <= key < count:
136                         key %= count
137                         return self.sbmodule.GetSectionAtIndex(key)
138                 elif type(key) is str:
139                     for idx in range(count):
140                         section = self.sbmodule.GetSectionAtIndex(idx)
141                         if section.name == key:
142                             return section
143                 elif isinstance(key, self.re_compile_type):
144                     matches = []
145                     for idx in range(count):
146                         section = self.sbmodule.GetSectionAtIndex(idx)
147                         name = section.name
148                         if name:
149                             re_match = key.search(name)
150                             if re_match:
151                                 matches.append(section)
152                     return matches
153                 else:
154                     print("error: unsupported item type: %s" % type(key))
155                 return None
156 
157         class compile_units_access(object):
158             re_compile_type = type(re.compile('.'))
159             '''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.'''
160             def __init__(self, sbmodule):
161                 self.sbmodule = sbmodule
162 
163             def __len__(self):
164                 if self.sbmodule:
165                     return int(self.sbmodule.GetNumCompileUnits())
166                 return 0
167 
168             def __getitem__(self, key):
169                 count = len(self)
170                 if type(key) is int:
171                     if -count <= key < count:
172                         key %= count
173                         return self.sbmodule.GetCompileUnitAtIndex(key)
174                 elif type(key) is str:
175                     is_full_path = key[0] == '/'
176                     for idx in range(count):
177                         comp_unit = self.sbmodule.GetCompileUnitAtIndex(idx)
178                         if is_full_path:
179                             if comp_unit.file.fullpath == key:
180                                 return comp_unit
181                         else:
182                             if comp_unit.file.basename == key:
183                                 return comp_unit
184                 elif isinstance(key, self.re_compile_type):
185                     matches = []
186                     for idx in range(count):
187                         comp_unit = self.sbmodule.GetCompileUnitAtIndex(idx)
188                         fullpath = comp_unit.file.fullpath
189                         if fullpath:
190                             re_match = key.search(fullpath)
191                             if re_match:
192                                 matches.append(comp_unit)
193                     return matches
194                 else:
195                     print("error: unsupported item type: %s" % type(key))
196                 return None
197 
198         def get_sections_access_object(self):
199             '''An accessor function that returns a sections_access() object which allows lazy section array access.'''
200             return self.sections_access (self)
201 
202         def get_sections_array(self):
203             '''An accessor function that returns an array object that contains all sections in this module object.'''
204             if not hasattr(self, 'sections_array'):
205                 self.sections_array = []
206                 for idx in range(self.num_sections):
207                     self.sections_array.append(self.GetSectionAtIndex(idx))
208             return self.sections_array
209 
210         def get_compile_units_array(self):
211             '''An accessor function that returns an array object that contains all compile_units in this module object.'''
212             if not hasattr(self, 'compile_units_array'):
213                 self.compile_units_array = []
214                 for idx in range(self.GetNumCompileUnits()):
215                     self.compile_units_array.append(self.GetCompileUnitAtIndex(idx))
216             return self.compile_units_array
217 
218         symbols = property(get_symbols_array, None, doc='''A read only property that returns a list() of lldb.SBSymbol objects contained in this module.''')
219         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''')
220         sections = property(get_sections_array, None, doc='''A read only property that returns a list() of lldb.SBSection objects contained in this module.''')
221         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.''')
222         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''')
223         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.''')
224 
225         def get_uuid(self):
226             return uuid.UUID (self.GetUUIDString())
227 
228         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.''')
229         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.''')
230         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.''')
231         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.''')
232         addr_size = property(GetAddressByteSize, None, doc='''A read only property that returns the size in bytes of an address for this module.''')
233         triple = property(GetTriple, None, doc='''A read only property that returns the target triple (arch-vendor-os) for this module.''')
234         num_symbols = property(GetNumSymbols, None, doc='''A read only property that returns number of symbols in the module symbol table as an integer.''')
235         num_sections = property(GetNumSections, None, doc='''A read only property that returns number of sections in the module as an integer.''')
236 
237     %}
238 #endif
239 }
240