From c44e20cec085817890434d84d5e9552fa0777245 Mon Sep 17 00:00:00 2001 From: Johnny Chen Date: Fri, 30 Sep 2011 00:42:49 +0000 Subject: [PATCH] Migrate the in_range(symbol, section) and symbol_iter(module, section) utility functions from lldbutil.py to the lldb.py proper. The in_range() function becomes a function in the lldb module. And the symbol_iter() function becomes a method within the SBModule called symbol_in_section_iter(). Example: # Iterates the text section and prints each symbols within each sub-section. for subsec in text_sec: print INDENT + repr(subsec) for sym in exe_module.symbol_in_section_iter(subsec): print INDENT2 + repr(sym) print INDENT2 + 'symbol type: %s' % symbol_type_to_str(sym.GetType()) might produce this following output: [0x0000000100001780-0x0000000100001d5c) a.out.__TEXT.__text id = {0x00000004}, name = 'mask_access(MaskAction, unsigned int)', range = [0x00000001000017c0-0x0000000100001870) symbol type: code id = {0x00000008}, name = 'thread_func(void*)', range = [0x0000000100001870-0x00000001000019b0) symbol type: code id = {0x0000000c}, name = 'main', range = [0x00000001000019b0-0x0000000100001d5c) symbol type: code id = {0x00000023}, name = 'start', address = 0x0000000100001780 symbol type: code [0x0000000100001d5c-0x0000000100001da4) a.out.__TEXT.__stubs id = {0x00000024}, name = '__stack_chk_fail', range = [0x0000000100001d5c-0x0000000100001d62) symbol type: trampoline id = {0x00000028}, name = 'exit', range = [0x0000000100001d62-0x0000000100001d68) symbol type: trampoline id = {0x00000029}, name = 'fflush', range = [0x0000000100001d68-0x0000000100001d6e) symbol type: trampoline id = {0x0000002a}, name = 'fgets', range = [0x0000000100001d6e-0x0000000100001d74) symbol type: trampoline id = {0x0000002b}, name = 'printf', range = [0x0000000100001d74-0x0000000100001d7a) symbol type: trampoline id = {0x0000002c}, name = 'pthread_create', range = [0x0000000100001d7a-0x0000000100001d80) symbol type: trampoline id = {0x0000002d}, name = 'pthread_join', range = [0x0000000100001d80-0x0000000100001d86) symbol type: trampoline id = {0x0000002e}, name = 'pthread_mutex_lock', range = [0x0000000100001d86-0x0000000100001d8c) symbol type: trampoline id = {0x0000002f}, name = 'pthread_mutex_unlock', range = [0x0000000100001d8c-0x0000000100001d92) symbol type: trampoline id = {0x00000030}, name = 'rand', range = [0x0000000100001d92-0x0000000100001d98) symbol type: trampoline id = {0x00000031}, name = 'strtoul', range = [0x0000000100001d98-0x0000000100001d9e) symbol type: trampoline id = {0x00000032}, name = 'usleep', range = [0x0000000100001d9e-0x0000000100001da4) symbol type: trampoline [0x0000000100001da4-0x0000000100001e2c) a.out.__TEXT.__stub_helper [0x0000000100001e2c-0x0000000100001f10) a.out.__TEXT.__cstring [0x0000000100001f10-0x0000000100001f68) a.out.__TEXT.__unwind_info [0x0000000100001f68-0x0000000100001ff8) a.out.__TEXT.__eh_frame llvm-svn: 140830 --- lldb/scripts/Python/interface/SBModule.i | 58 ++++++++++++++++++- lldb/scripts/Python/modify-python-lldb.py | 45 ++++++++++++-- lldb/test/lldbutil.py | 28 --------- .../module_section/TestModuleAndSection.py | 4 +- 4 files changed, 99 insertions(+), 36 deletions(-) diff --git a/lldb/scripts/Python/interface/SBModule.i b/lldb/scripts/Python/interface/SBModule.i index b85b8965024a..84470abc2338 100644 --- a/lldb/scripts/Python/interface/SBModule.i +++ b/lldb/scripts/Python/interface/SBModule.i @@ -32,7 +32,63 @@ and rich comparion methods which allow the API program to use, print 'This module is the same as that module' to test module equality. A module also contains object file sections, namely -SBSection. SBModule supports section iteration through section_iter()." +SBSection. SBModule supports section iteration through section_iter(), for +example, + + print 'Number of sections: %d' % module.GetNumSections() + for sec in module.section_iter(): + print sec + +And to iterate the symbols within a SBSection, use symbol_in_section_iter(), + + # Iterates the text section and prints each symbols within each sub-section. + for subsec in text_sec: + print INDENT + repr(subsec) + for sym in exe_module.symbol_in_section_iter(subsec): + print INDENT2 + repr(sym) + print INDENT2 + 'symbol type: %s' % symbol_type_to_str(sym.GetType()) + +might produce this following output: + + [0x0000000100001780-0x0000000100001d5c) a.out.__TEXT.__text + id = {0x00000004}, name = 'mask_access(MaskAction, unsigned int)', range = [0x00000001000017c0-0x0000000100001870) + symbol type: code + id = {0x00000008}, name = 'thread_func(void*)', range = [0x0000000100001870-0x00000001000019b0) + symbol type: code + id = {0x0000000c}, name = 'main', range = [0x00000001000019b0-0x0000000100001d5c) + symbol type: code + id = {0x00000023}, name = 'start', address = 0x0000000100001780 + symbol type: code + [0x0000000100001d5c-0x0000000100001da4) a.out.__TEXT.__stubs + id = {0x00000024}, name = '__stack_chk_fail', range = [0x0000000100001d5c-0x0000000100001d62) + symbol type: trampoline + id = {0x00000028}, name = 'exit', range = [0x0000000100001d62-0x0000000100001d68) + symbol type: trampoline + id = {0x00000029}, name = 'fflush', range = [0x0000000100001d68-0x0000000100001d6e) + symbol type: trampoline + id = {0x0000002a}, name = 'fgets', range = [0x0000000100001d6e-0x0000000100001d74) + symbol type: trampoline + id = {0x0000002b}, name = 'printf', range = [0x0000000100001d74-0x0000000100001d7a) + symbol type: trampoline + id = {0x0000002c}, name = 'pthread_create', range = [0x0000000100001d7a-0x0000000100001d80) + symbol type: trampoline + id = {0x0000002d}, name = 'pthread_join', range = [0x0000000100001d80-0x0000000100001d86) + symbol type: trampoline + id = {0x0000002e}, name = 'pthread_mutex_lock', range = [0x0000000100001d86-0x0000000100001d8c) + symbol type: trampoline + id = {0x0000002f}, name = 'pthread_mutex_unlock', range = [0x0000000100001d8c-0x0000000100001d92) + symbol type: trampoline + id = {0x00000030}, name = 'rand', range = [0x0000000100001d92-0x0000000100001d98) + symbol type: trampoline + id = {0x00000031}, name = 'strtoul', range = [0x0000000100001d98-0x0000000100001d9e) + symbol type: trampoline + id = {0x00000032}, name = 'usleep', range = [0x0000000100001d9e-0x0000000100001da4) + symbol type: trampoline + [0x0000000100001da4-0x0000000100001e2c) a.out.__TEXT.__stub_helper + [0x0000000100001e2c-0x0000000100001f10) a.out.__TEXT.__cstring + [0x0000000100001f10-0x0000000100001f68) a.out.__TEXT.__unwind_info + [0x0000000100001f68-0x0000000100001ff8) a.out.__TEXT.__eh_frame +" ) SBModule; class SBModule { diff --git a/lldb/scripts/Python/modify-python-lldb.py b/lldb/scripts/Python/modify-python-lldb.py index ac523be956d1..95f68a339b61 100644 --- a/lldb/scripts/Python/modify-python-lldb.py +++ b/lldb/scripts/Python/modify-python-lldb.py @@ -59,8 +59,27 @@ EIGHT_SPACES = ' ' * 8 one_liner_docstring_pattern = re.compile('^(%s|%s)""".*"""$' % (TWO_SPACES, EIGHT_SPACES)) # -# lldb_iter() should appear before our first SB* class definition. +# lldb_helpers and lldb_iter() should appear before our first SB* class definition. # +lldb_helpers = ''' +def in_range(symbol, section): + symSA = symbol.GetStartAddress().GetFileAddress() + symEA = symbol.GetEndAddress().GetFileAddress() + secSA = section.GetFileAddress() + secEA = secSA + section.GetByteSize() + + if symEA != LLDB_INVALID_ADDRESS: + if secSA <= symSA and symEA <= secEA: + return True + else: + return False + else: + if secSA <= symSA and symSA < secEA: + return True + else: + return False +''' + lldb_iter_def = ''' # =================================== # Iterator for lldb container objects @@ -166,6 +185,16 @@ ne_def = " def __ne__(self, other): return not self.__eq__(other)" # Delegate to self.IsValid() if it is defined for the current lldb object. nonzero_def = " def __nonzero__(self): return self.IsValid()" +# A convenience iterator for SBSymbol! +symbol_in_section_iter_def = ''' + def symbol_in_section_iter(self, section): + """Given a module and its contained section, returns an iterator on the + symbols within the section.""" + for sym in self: + if in_range(sym, section): + yield sym +''' + # # This dictionary defines a mapping from classname to (getsize, getelem) tuple. # @@ -193,7 +222,9 @@ d = { 'SBBreakpoint': ('GetNumLocations', 'GetLocationAtIndex'), }, # SBModule has an additional section_iter(), see below. - 'SBModule-extra': ('GetNumSections', 'GetSectionAtIndex') + 'SBModule-section': ('GetNumSections', 'GetSectionAtIndex'), + # As well as symbol_in_section_iter(). + 'SBModule-symbol-in-section': symbol_in_section_iter_def } # @@ -305,8 +336,10 @@ for line in content.splitlines(): if state == NORMAL: match = class_pattern.search(line) - # Inserts the lldb_iter() definition before the first class definition. + # Inserts lldb_helpers and the lldb_iter() definition before the first + # class definition. if not lldb_iter_defined and match: + new_content.add_line(lldb_helpers) new_content.add_line(lldb_iter_def) lldb_iter_defined = True @@ -341,9 +374,11 @@ for line in content.splitlines(): new_content.add_line(eq_def % (cls, list_to_frag(e[cls]))) new_content.add_line(ne_def) - # SBModule has an extra SBSection iterator! + # SBModule has an extra SBSection iterator and symbol_in_section_iter()! if cls == "SBModule": - new_content.add_line(section_iter % d[cls+'-extra']) + new_content.add_line(section_iter % d[cls+'-section']) + new_content.add_line(d[cls+'-symbol-in-section']) + # This special purpose iterator is for SBValue only!!! if cls == "SBValue": new_content.add_line(linked_list_iter_def) diff --git a/lldb/test/lldbutil.py b/lldb/test/lldbutil.py index a9896fa39545..740c932fc8f6 100644 --- a/lldb/test/lldbutil.py +++ b/lldb/test/lldbutil.py @@ -44,34 +44,6 @@ def disassemble(target, function_or_symbol): print >> buf, i return buf.getvalue() -# ====================================================== -# Utilities for iterating a module's section for symbols -# ====================================================== - -def in_range(symbol, section): - symSA = symbol.GetStartAddress().GetFileAddress() - symEA = symbol.GetEndAddress().GetFileAddress() - secSA = section.GetFileAddress() - secEA = secSA + section.GetByteSize() - - if symEA != lldb.LLDB_INVALID_ADDRESS: - if secSA <= symSA and symEA <= secEA: - return True - else: - return False - else: - if secSA <= symSA and symSA < secEA: - return True - else: - return False - -def symbol_iter(module, section): - """Given a module and its contained section, returns an iterator on the - symbols within the section.""" - for sym in module: - if in_range(sym, section): - yield sym - # ========================================================== # Integer (byte size 1, 2, 4, and 8) to bytearray conversion # ========================================================== diff --git a/lldb/test/python_api/module_section/TestModuleAndSection.py b/lldb/test/python_api/module_section/TestModuleAndSection.py index cecc5ab61f29..671af56e8360 100644 --- a/lldb/test/python_api/module_section/TestModuleAndSection.py +++ b/lldb/test/python_api/module_section/TestModuleAndSection.py @@ -45,14 +45,14 @@ class ModuleAndSectionAPIsTestCase(TestBase): print sec print INDENT + "Number of subsections: %d" % sec.GetNumSubSections() if sec.GetNumSubSections() == 0: - for sym in symbol_iter(exe_module, sec): + for sym in exe_module.symbol_in_section_iter(sec): print INDENT + repr(sym) print INDENT + "symbol type: %s" % symbol_type_to_str(sym.GetType()) else: for subsec in sec: print INDENT + repr(subsec) # Now print the symbols belonging to the subsection.... - for sym in symbol_iter(exe_module, subsec): + for sym in exe_module.symbol_in_section_iter(subsec): print INDENT2 + repr(sym) print INDENT2 + "symbol type: %s" % symbol_type_to_str(sym.GetType())