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
This commit is contained in:
Johnny Chen 2011-09-30 00:42:49 +00:00
parent befa6f0caa
commit c44e20cec0
4 changed files with 99 additions and 36 deletions

View File

@ -32,7 +32,63 @@ and rich comparion methods which allow the API program to use,
print 'This module is the same as that module' print 'This module is the same as that module'
to test module equality. A module also contains object file sections, namely 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; ) SBModule;
class SBModule class SBModule
{ {

View File

@ -59,8 +59,27 @@ EIGHT_SPACES = ' ' * 8
one_liner_docstring_pattern = re.compile('^(%s|%s)""".*"""$' % (TWO_SPACES, EIGHT_SPACES)) 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 = ''' lldb_iter_def = '''
# =================================== # ===================================
# Iterator for lldb container objects # 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. # Delegate to self.IsValid() if it is defined for the current lldb object.
nonzero_def = " def __nonzero__(self): return self.IsValid()" 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. # 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 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: if state == NORMAL:
match = class_pattern.search(line) 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: if not lldb_iter_defined and match:
new_content.add_line(lldb_helpers)
new_content.add_line(lldb_iter_def) new_content.add_line(lldb_iter_def)
lldb_iter_defined = True 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(eq_def % (cls, list_to_frag(e[cls])))
new_content.add_line(ne_def) 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": 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!!! # This special purpose iterator is for SBValue only!!!
if cls == "SBValue": if cls == "SBValue":
new_content.add_line(linked_list_iter_def) new_content.add_line(linked_list_iter_def)

View File

@ -44,34 +44,6 @@ def disassemble(target, function_or_symbol):
print >> buf, i print >> buf, i
return buf.getvalue() 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 # Integer (byte size 1, 2, 4, and 8) to bytearray conversion
# ========================================================== # ==========================================================

View File

@ -45,14 +45,14 @@ class ModuleAndSectionAPIsTestCase(TestBase):
print sec print sec
print INDENT + "Number of subsections: %d" % sec.GetNumSubSections() print INDENT + "Number of subsections: %d" % sec.GetNumSubSections()
if sec.GetNumSubSections() == 0: 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 + repr(sym)
print INDENT + "symbol type: %s" % symbol_type_to_str(sym.GetType()) print INDENT + "symbol type: %s" % symbol_type_to_str(sym.GetType())
else: else:
for subsec in sec: for subsec in sec:
print INDENT + repr(subsec) print INDENT + repr(subsec)
# Now print the symbols belonging to the subsection.... # 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 + repr(sym)
print INDENT2 + "symbol type: %s" % symbol_type_to_str(sym.GetType()) print INDENT2 + "symbol type: %s" % symbol_type_to_str(sym.GetType())