1#!/usr/bin/python
2
3import lldb
4import optparse
5import shlex
6import string
7import sys
8
9
10def create_dump_module_line_tables_options():
11    usage = "usage: dump_module_line_tables [options] MODULE1 [MODULE2 ...]"
12    description = '''Dumps all line tables from all compile units for any modules specified as arguments. Specifying the --verbose flag will output address ranges for each line entry.'''
13    parser = optparse.OptionParser(
14        description=description,
15        prog='start_gdb_log',
16        usage=usage)
17    parser.add_option(
18        '-v',
19        '--verbose',
20        action='store_true',
21        dest='verbose',
22        help='Display verbose output.',
23        default=False)
24    return parser
25
26
27def dump_module_line_tables(debugger, command, result, dict):
28    '''Dumps all line tables from all compile units for any modules specified as arguments.'''
29    command_args = shlex.split(command)
30
31    parser = create_dump_module_line_tables_options()
32    try:
33        (options, args) = parser.parse_args(command_args)
34    except:
35        return
36    if command_args:
37        target = debugger.GetSelectedTarget()
38        lldb.target = target
39        for module_name in command_args:
40            result.PutCString('Searching for module "%s"' % (module_name,))
41            module_fspec = lldb.SBFileSpec(module_name, False)
42            module = target.FindModule(module_fspec)
43            if module:
44                for cu_idx in range(module.GetNumCompileUnits()):
45                    cu = module.GetCompileUnitAtIndex(cu_idx)
46                    result.PutCString("\n%s:" % (cu.file))
47                    for line_idx in range(cu.GetNumLineEntries()):
48                        line_entry = cu.GetLineEntryAtIndex(line_idx)
49                        start_file_addr = line_entry.addr.file_addr
50                        end_file_addr = line_entry.end_addr.file_addr
51                        # If the two addresses are equal, this line table entry
52                        # is a termination entry
53                        if options.verbose:
54                            if start_file_addr != end_file_addr:
55                                result.PutCString(
56                                    '[%#x - %#x): %s' %
57                                    (start_file_addr, end_file_addr, line_entry))
58                        else:
59                            if start_file_addr == end_file_addr:
60                                result.PutCString('%#x: END' %
61                                                  (start_file_addr))
62                            else:
63                                result.PutCString(
64                                    '%#x: %s' %
65                                    (start_file_addr, line_entry))
66                        if start_file_addr == end_file_addr:
67                            result.Printf("\n")
68            else:
69                result.PutCString("no module for '%s'" % module)
70    else:
71        result.PutCString("error: invalid target")
72
73parser = create_dump_module_line_tables_options()
74dump_module_line_tables.__doc__ = parser.format_help()
75lldb.debugger.HandleCommand(
76    'command script add -f %s.dump_module_line_tables dump_module_line_tables' %
77    __name__)
78print 'Installed "dump_module_line_tables" command'
79