forked from OSchip/llvm-project
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:
parent
befa6f0caa
commit
c44e20cec0
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
# ==========================================================
|
# ==========================================================
|
||||||
|
|
|
@ -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())
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue