#!/usr/bin/python
from __future__ import print_function

import lldb
import optparse
import shlex
import string
import sys


class DumpLineTables:
    command_name = "dump-line-tables"
    short_decription = "Dumps full paths to compile unit files and optionally all line table files."
    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.'
    usage = "usage: %prog [options] MODULE1 [MODULE2 ...]"
    def create_options(self):
        self.parser = optparse.OptionParser(
            description=self.description,
            prog=self.command_name,
            usage=self.usage)

        self.parser.add_option(
            '-v',
            '--verbose',
            action='store_true',
            dest='verbose',
            help='Display verbose output.',
            default=False)

    def get_short_help(self):
        return self.short_decription

    def get_long_help(self):
        return self.help_string

    def __init__(self, debugger, unused):
        self.create_options()
        self.help_string = self.parser.format_help()

    def __call__(self, debugger, command, exe_ctx, result):
        # Use the Shell Lexer to properly parse up command options just like a
        # shell would
        command_args = shlex.split(command)

        try:
            (options, args) = self.parser.parse_args(command_args)
        except:
            # if you don't handle exceptions, passing an incorrect argument to the OptionParser will cause LLDB to exit
            # (courtesy of OptParse dealing with argument errors by throwing SystemExit)
            result.SetError("option parsing failed")
            return

        # Always get program state from the SBExecutionContext passed in as exe_ctx
        target = exe_ctx.GetTarget()
        if not target.IsValid():
            result.SetError("invalid target")
            return

        for module_path in args:
            module = target.module[module_path]
            if not module:
                result.SetError('no module found that matches "%s".' % (module_path))
                return
            num_cus = module.GetNumCompileUnits()
            print('Module: "%s"' % (module.file.fullpath), end=' ', file=result)
            if num_cus == 0:
                print('no debug info.', file=result)
                continue
            print('has %u compile units:' % (num_cus), file=result)
            for cu_idx in range(num_cus):
                cu = module.GetCompileUnitAtIndex(cu_idx)
                print('  Compile Unit: %s' % (cu.file.fullpath), file=result)
                for line_idx in range(cu.GetNumLineEntries()):
                    line_entry = cu.GetLineEntryAtIndex(line_idx)
                    start_file_addr = line_entry.addr.file_addr
                    end_file_addr = line_entry.end_addr.file_addr
                    # If the two addresses are equal, this line table entry
                    # is a termination entry
                    if options.verbose:
                        if start_file_addr != end_file_addr:
                            result.PutCString(
                                '    [%#x - %#x): %s' %
                                (start_file_addr, end_file_addr, line_entry))
                    else:
                        if start_file_addr == end_file_addr:
                            result.PutCString('    %#x: END' %
                                              (start_file_addr))
                        else:
                            result.PutCString(
                                '    %#x: %s' %
                                (start_file_addr, line_entry))
                    if start_file_addr == end_file_addr:
                        result.PutCString("\n")


class DumpFiles:
    command_name = "dump-files"
    short_description = "Dumps full paths to compile unit files and optionally all line table files."
    usage = "usage: %prog [options] MODULE1 [MODULE2 ...]"
    description = '''This class adds a dump-files command to the LLDB interpreter.

This command will dump all compile unit file paths found for each source file
for the binaries specified as arguments in the current target. Specify the
--support-files or -s option to see all file paths that a compile unit uses in
its lines tables. This is handy for troubleshooting why breakpoints aren't
working in IDEs that specify full paths to source files when setting file and
line breakpoints. Sometimes symlinks cause the debug info to contain the symlink
path and an IDE will resolve the path to the actual file and use the resolved
path when setting breakpoints.
'''
    def create_options(self):
        # Pass add_help_option = False, since this keeps the command in line with lldb commands,
        # and we wire up "help command" to work by providing the long & short help methods below.
        self.parser = optparse.OptionParser(
            description = self.description,
            prog = self.command_name,
            usage = self.usage,
            add_help_option = False)

        self.parser.add_option(
            '-s',
            '--support-files',
            action = 'store_true',
            dest = 'support_files',
            help = 'Dumps full paths to all files used in a compile unit.',
            default = False)

    def get_short_help(self):
        return self.short_description

    def get_long_help(self):
        return self.help_string

    def __init__(self, debugger, unused):
        self.create_options()
        self.help_string = self.parser.format_help()

    def __call__(self, debugger, command, exe_ctx, result):
        # Use the Shell Lexer to properly parse up command options just like a
        # shell would
        command_args = shlex.split(command)

        try:
            (options, args) = self.parser.parse_args(command_args)
        except:
            # if you don't handle exceptions, passing an incorrect argument to the OptionParser will cause LLDB to exit
            # (courtesy of OptParse dealing with argument errors by throwing SystemExit)
            result.SetError("option parsing failed")
            return

        # Always get program state from the SBExecutionContext passed in as exe_ctx
        target = exe_ctx.GetTarget()
        if not target.IsValid():
            result.SetError("invalid target")
            return

        if len(args) == 0:
            result.SetError("one or more executable paths must be specified")
            return

        for module_path in args:
            module = target.module[module_path]
            if not module:
                result.SetError('no module found that matches "%s".' % (module_path))
                return
            num_cus = module.GetNumCompileUnits()
            print('Module: "%s"' % (module.file.fullpath), end=' ', file=result)
            if num_cus == 0:
                print('no debug info.', file=result)
                continue
            print('has %u compile units:' % (num_cus), file=result)
            for i in range(num_cus):
                cu = module.GetCompileUnitAtIndex(i)
                print('  Compile Unit: %s' % (cu.file.fullpath), file=result)
                if options.support_files:
                    num_support_files = cu.GetNumSupportFiles()
                    for j in range(num_support_files):
                        path = cu.GetSupportFileAtIndex(j).fullpath
                        print('    file[%u]: %s' % (j, path), file=result)


def __lldb_init_module(debugger, dict):
    # This initializer is being run from LLDB in the embedded command interpreter

    # Add any commands contained in this module to LLDB
    debugger.HandleCommand(
        'command script add -c %s.DumpLineTables %s' % (__name__,
                                                        DumpLineTables.command_name))
    debugger.HandleCommand(
        'command script add -c %s.DumpFiles %s' % (__name__, DumpFiles.command_name))
    print('The "%s" and "%s" commands have been installed.' % (DumpLineTables.command_name,
                                                               DumpFiles.command_name))
