#!/usr/bin/python

#----------------------------------------------------------------------
# Be sure to add the python path that points to the LLDB shared library.
#
# To use this in the embedded python interpreter using "lldb":
#
#   cd /path/containing/crashlog.py
#   lldb
#   (lldb) script import crashlog
#   "crashlog" command installed, type "crashlog --help" for detailed help
#   (lldb) crashlog ~/Library/Logs/DiagnosticReports/a.crash
#
# The benefit of running the crashlog command inside lldb in the 
# embedded python interpreter is when the command completes, there 
# will be a target with all of the files loaded at the locations
# described in the crash log. Only the files that have stack frames
# in the backtrace will be loaded unless the "--load-all" option
# has been specified. This allows users to explore the program in the
# state it was in right at crash time. 
#
# On MacOSX csh, tcsh:
#   ( setenv PYTHONPATH /path/to/LLDB.framework/Resources/Python ; ./crashlog.py ~/Library/Logs/DiagnosticReports/a.crash )
#
# On MacOSX sh, bash:
#   PYTHONPATH=/path/to/LLDB.framework/Resources/Python ./crashlog.py ~/Library/Logs/DiagnosticReports/a.crash
#----------------------------------------------------------------------

import lldb
import commands
import optparse
import os
import plistlib
import re
import shlex
import sys
import time
import uuid

class Address:
    """Class that represents an address that will be symbolicated"""
    def __init__(self, target, load_addr):
        self.target = target
        self.load_addr = load_addr # The load address that this object represents
        self.so_addr = None # the resolved lldb.SBAddress (if any), named so_addr for section/offset address
        self.sym_ctx = None # The cached symbol context for this address
        self.description = None # Any original textual description of this address to be used as a backup in case symbolication fails
        self.symbolication = None # The cached symbolicated string that describes this address
        self.inlined = False
    def __str__(self):
        s = "%#16.16x" % (self.load_addr)
        if self.symbolication:
            s += " %s" % (self.symbolication)
        elif self.description:
            s += " %s" % (self.description)
        elif self.so_addr:
            s += " %s" % (self.so_addr)
        return s

    def resolve_addr(self):
        if self.so_addr == None:
            self.so_addr = self.target.ResolveLoadAddress (self.load_addr)
        return self.so_addr

    def is_inlined(self):
        return self.inlined
    
    def get_symbol_context(self):
        if self.sym_ctx == None:
            sb_addr = self.resolve_addr()
            if sb_addr:
                self.sym_ctx = self.target.ResolveSymbolContextForAddress (sb_addr, lldb.eSymbolContextEverything)
            else:
                self.sym_ctx = lldb.SBSymbolContext()
        return self.sym_ctx

    def get_instructions(self):
        sym_ctx = self.get_symbol_context()
        if sym_ctx:
            function = sym_ctx.GetFunction()
            if function:
                return function.GetInstructions(self.target)
            return sym_ctx.GetSymbol().GetInstructions(self.target)
        return None
    
    def symbolicate(self, verbose = False):
        if self.symbolication == None:
            self.symbolication = ''
            self.inlined = False
            sym_ctx = self.get_symbol_context()
            if sym_ctx:
                module = sym_ctx.GetModule()
                if module:
                    # Print full source file path in verbose mode
                    if verbose:
                        self.symbolication += str(module.GetFileSpec()) + '`'
                    else:
                        self.symbolication += module.GetFileSpec().GetFilename() + '`'
                    function_start_load_addr = -1
                    function = sym_ctx.GetFunction()
                    block = sym_ctx.GetBlock()
                    line_entry = sym_ctx.GetLineEntry()
                    symbol = sym_ctx.GetSymbol()
                    inlined_block = block.GetContainingInlinedBlock();
                    if function:
                        self.symbolication += function.GetName()

                        if inlined_block:
                            self.inlined = True
                            self.symbolication += ' [inlined] ' + inlined_block.GetInlinedName();
                            block_range_idx = inlined_block.GetRangeIndexForBlockAddress (self.so_addr)
                            if block_range_idx < lldb.UINT32_MAX:
                                block_range_start_addr = inlined_block.GetRangeStartAddress (block_range_idx)
                                function_start_load_addr = block_range_start_addr.GetLoadAddress (self.target)
                        if function_start_load_addr == -1:
                            function_start_load_addr = function.GetStartAddress().GetLoadAddress (self.target)
                    elif symbol:
                        self.symbolication += symbol.GetName()
                        function_start_load_addr = symbol.GetStartAddress().GetLoadAddress (self.target)
                    else:
                        self.symbolication = ''
                        return False

                    # Dump the offset from the current function or symbol if it is non zero
                    function_offset = self.load_addr - function_start_load_addr
                    if function_offset > 0:
                        self.symbolication += " + %u" % (function_offset)
                    elif function_offset < 0:
                        self.symbolication += " %i (invalid negative offset, file a bug) " % function_offset

                    # Print out any line information if any is available
                    if line_entry.GetFileSpec():
                        # Print full source file path in verbose mode
                        if verbose:
                            self.symbolication += ' at %s' % line_entry.GetFileSpec()
                        else:
                            self.symbolication += ' at %s' % line_entry.GetFileSpec().GetFilename()
                        self.symbolication += ':%u' % line_entry.GetLine ()
                        column = line_entry.GetColumn()
                        if column > 0:
                            self.symbolication += ':%u' % column
                    return True
        return False

class Section:
    """Class that represents an load address range"""
    sect_info_regex = re.compile('(?P<name>[^=]+)=(?P<range>.*)')
    addr_regex = re.compile('^\s*(?P<start>0x[0-9A-Fa-f]+)\s*$')
    range_regex = re.compile('^\s*(?P<start>0x[0-9A-Fa-f]+)\s*(?P<op>[-+])\s*(?P<end>0x[0-9A-Fa-f]+)\s*$')

    def __init__(self, start_addr = None, end_addr = None, name = None):
        self.start_addr = start_addr
        self.end_addr = end_addr
        self.name = name
    
    @classmethod
    def InitWithSBTargetAndSBSection(cls, target, section):
        sect_load_addr = section.GetLoadAddress(target)
        if sect_load_addr != lldb.LLDB_INVALID_ADDRESS:
            obj = cls(sect_load_addr, sect_load_addr + section.size, section.name)
            return obj
        else:
            return None
        
    def contains(self, addr):
        return self.start_addr <= addr and addr < self.end_addr;
    
    def set_from_string(self, s):
        match = self.sect_info_regex.match (s)
        if match:
            self.name = match.group('name')
            range_str = match.group('range')
            addr_match = self.addr_regex.match(range_str)
            if addr_match:
                self.start_addr = int(addr_match.group('start'), 16)
                self.end_addr = None
                return True

            range_match = self.range_regex.match(range_str)
            if range_match:
                self.start_addr = int(range_match.group('start'), 16)
                self.end_addr = int(range_match.group('end'), 16)
                op = range_match.group('op')
                if op == '+':
                    self.end_addr += self.start_addr
                return True
        print 'error: invalid section info string "%s"' % s
        print 'Valid section info formats are:'
        print 'Format                Example                    Description'
        print '--------------------- -----------------------------------------------'
        print '<name>=<base>        __TEXT=0x123000             Section from base address only'
        print '<name>=<base>-<end>  __TEXT=0x123000-0x124000    Section from base address and end address'
        print '<name>=<base>+<size> __TEXT=0x123000+0x1000      Section from base address and size'
        return False
        
    def __str__(self):
        if self.name:
            if self.end_addr != None:
                if self.start_addr != None:
                    return "%s=[0x%16.16x - 0x%16.16x)" % (self.name, self.start_addr, self.end_addr)
            else:
                if self.start_addr != None:
                    return "%s=0x%16.16x" % (self.name, self.start_addr)
            return self.name
        return "<invalid>"
            
class Image:
    """A class that represents an executable image and any associated data"""
    
    def __init__(self, path, uuid = None):
        self.path = path
        self.resolved_path = None
        self.resolved = False
        self.unavailable = False
        self.uuid = uuid
        self.section_infos = list()
        self.identifier = None
        self.version = None
        self.arch = None
        self.module = None
        self.symfile = None
        self.slide = None
        
    @classmethod
    def InitWithSBTargetAndSBModule(cls, target, module):
        '''Initialize this Image object with a module from a target.'''
        obj = cls(module.file.fullpath, module.uuid)
        obj.resolved_path = module.platform_file.fullpath
        obj.resolved = True
        obj.arch = module.triple
        for section in module.sections:
            symb_section = Section.InitWithSBTargetAndSBSection(target, section)
            if symb_section:
                obj.section_infos.append (symb_section)
        obj.arch = module.triple
        obj.module = module
        obj.symfile = None
        obj.slide = None
        return obj
        
    def dump(self, prefix):
        print "%s%s" % (prefix, self)

    def debug_dump(self):
        print 'path = "%s"' % (self.path)
        print 'resolved_path = "%s"' % (self.resolved_path)
        print 'resolved = %i' % (self.resolved)
        print 'unavailable = %i' % (self.unavailable)
        print 'uuid = %s' % (self.uuid)
        print 'section_infos = %s' % (self.section_infos)
        print 'identifier = "%s"' % (self.identifier)
        print 'version = %s' % (self.version)
        print 'arch = %s' % (self.arch)
        print 'module = %s' % (self.module)
        print 'symfile = "%s"' % (self.symfile)
        print 'slide = %i (0x%x)' % (self.slide, self.slide)
        
    def __str__(self):
        s = ''
        if self.uuid:
            s += "%s " % (self.get_uuid())
        if self.arch:
            s += "%s " % (self.arch)
        if self.version:
            s += "%s " % (self.version)
        resolved_path = self.get_resolved_path()
        if resolved_path:
            s += "%s " % (resolved_path)
        for section_info in self.section_infos:
            s += ", %s" % (section_info)
        if self.slide != None:
            s += ', slide = 0x%16.16x' % self.slide
        return s        
    
    def add_section(self, section):
        #print "added '%s' to '%s'" % (section, self.path)
        self.section_infos.append (section)
        
    def get_section_containing_load_addr (self, load_addr):
        for section_info in self.section_infos:
            if section_info.contains(load_addr):
                return section_info
        return None

    def get_resolved_path(self):
        if self.resolved_path:
            return self.resolved_path
        elif self.path:
            return self.path
        return None

    def get_resolved_path_basename(self):
        path = self.get_resolved_path()
        if path:
            return os.path.basename(path)
        return None

    def symfile_basename(self):
        if self.symfile:
            return os.path.basename(self.symfile)
        return None
    
    def has_section_load_info(self):
        return self.section_infos or self.slide != None
    
    def load_module(self, target):
        if self.unavailable:
            return None # We already warned that we couldn't find this module, so don't return an error string
        # Load this module into "target" using the section infos to
        # set the section load addresses
        if self.has_section_load_info():
            if target:
                if self.module:
                    if self.section_infos:
                        num_sections_loaded = 0
                        for section_info in self.section_infos:
                            if section_info.name:
                                section = self.module.FindSection (section_info.name)
                                if section:
                                    error = target.SetSectionLoadAddress (section, section_info.start_addr)
                                    if error.Success():
                                        num_sections_loaded += 1
                                    else:
                                        return 'error: %s' % error.GetCString()
                                else:
                                    return 'error: unable to find the section named "%s"' % section_info.name
                            else:
                                return 'error: unable to find "%s" section in "%s"' % (range.name, self.get_resolved_path())
                        if num_sections_loaded == 0:
                            return 'error: no sections were successfully loaded'
                    else:
                        err = target.SetModuleLoadAddress(self.module, self.slide)
                        if err.Fail():
                            return err.GetCString()
                    return None
                else:
                    return 'error: invalid module'
            else:
                return 'error: invalid target'
        else:
            return 'error: no section infos'
        
    def add_module(self, target):
        '''Add the Image described in this object to "target" and load the sections if "load" is True.'''
        if target:
            # Try and find using UUID only first so that paths need not match up
            uuid_str = self.get_normalized_uuid_string()
            if uuid_str:
                self.module = target.AddModule (None, None, uuid_str)
            if not self.module:
                self.locate_module_and_debug_symbols ()
                if self.unavailable:
                    return None
                resolved_path = self.get_resolved_path()
                self.module = target.AddModule (resolved_path, self.arch, uuid_str, self.symfile)
            if not self.module:
                return 'error: unable to get module for (%s) "%s"' % (self.arch, self.get_resolved_path())
            if self.has_section_load_info():
                return self.load_module(target)
            else:
                return None # No sections, the module was added to the target, so success
        else:
            return 'error: invalid target'
    
    def locate_module_and_debug_symbols (self):
        # By default, just use the paths that were supplied in:
        # self.path
        # self.resolved_path
        # self.module
        # self.symfile
        # Subclasses can inherit from this class and override this function
        self.resolved = True
        return True
    
    def get_uuid(self):
        if not self.uuid and self.module:
            self.uuid = uuid.UUID(self.module.GetUUIDString())
        return self.uuid

    def get_normalized_uuid_string(self):
        if self.uuid:
            return str(self.uuid).upper()
        return None

    def create_target(self):
        '''Create a target using the information in this Image object.'''
        if self.unavailable:
            return None

        if self.locate_module_and_debug_symbols ():
            resolved_path = self.get_resolved_path();
            path_spec = lldb.SBFileSpec (resolved_path)
            #result.PutCString ('plist[%s] = %s' % (uuid, self.plist))
            error = lldb.SBError()
            target = lldb.debugger.CreateTarget (resolved_path, self.arch, None, False, error);
            if target:
                self.module = target.FindModule(path_spec)
                if self.has_section_load_info():
                    err = self.load_module(target)
                    if err:
                        print 'ERROR: ', err
                return target
            else:
                print 'error: unable to create a valid target for (%s) "%s"' % (self.arch, self.path)
        else:
            print 'error: unable to locate main executable (%s) "%s"' % (self.arch, self.path)
        return None
    
class Symbolicator:

    def __init__(self):
        """A class the represents the information needed to symbolicate addresses in a program"""
        self.target = None
        self.images = list() # a list of images to be used when symbolicating
        self.addr_mask = 0xffffffffffffffff
    
    @classmethod
    def InitWithSBTarget(cls, target):
        obj = cls()
        obj.target = target
        obj.images = list();
        triple = target.triple
        if triple:
            arch = triple.split('-')[0]
            if "arm" in arch:
                obj.addr_mask = 0xfffffffffffffffe

        for module in target.modules:
            image = Image.InitWithSBTargetAndSBModule(target, module)
            obj.images.append(image)
        return obj
        
    def __str__(self):
        s = "Symbolicator:\n"
        if self.target:
            s += "Target = '%s'\n" % (self.target)
            s += "Target modules:\n"
            for m in self.target.modules:
                s += str(m) + "\n"
        s += "Images:\n"
        for image in self.images:
            s += '    %s\n' % (image)
        return s
    
    def find_images_with_identifier(self, identifier):
        images = list()
        for image in self.images:
            if image.identifier == identifier:
                images.append(image)
        if len(images) == 0:
            regex_text = '^.*\.%s$' % (re.escape(identifier))
            regex = re.compile(regex_text)
            for image in self.images:
                if regex.match(image.identifier):
                    images.append(image)
        return images
        
    def find_image_containing_load_addr(self, load_addr):
        for image in self.images:
            if image.get_section_containing_load_addr (load_addr):
                return image
        return None
    
    def create_target(self):
        if self.target:
            return self.target

        if self.images:
            for image in self.images:
                self.target = image.create_target ()
                if self.target:
                    if self.target.GetAddressByteSize() == 4:
                        triple = self.target.triple
                        if triple:
                            arch = triple.split('-')[0]
                            if "arm" in arch:
                                self.addr_mask = 0xfffffffffffffffe
                    return self.target
        return None
    
            
    def symbolicate(self, load_addr, verbose = False):
        if not self.target:
            self.create_target()
        if self.target:
            live_process = False
            process = self.target.process
            if process:
                state = process.state
                if state > lldb.eStateUnloaded and state < lldb.eStateDetached:
                    live_process = True
            # If we don't have a live process, we can attempt to find the image
            # that a load address belongs to and lazily load its module in the
            # target, but we shouldn't do any of this if we have a live process
            if not live_process:
                image = self.find_image_containing_load_addr (load_addr)
                if image:
                    image.add_module (self.target)
            symbolicated_address = Address(self.target, load_addr)
            if symbolicated_address.symbolicate (verbose):
                if symbolicated_address.so_addr:
                    symbolicated_addresses = list()
                    symbolicated_addresses.append(symbolicated_address)
                    # See if we were able to reconstruct anything?
                    while 1:
                        inlined_parent_so_addr = lldb.SBAddress()
                        inlined_parent_sym_ctx = symbolicated_address.sym_ctx.GetParentOfInlinedScope (symbolicated_address.so_addr, inlined_parent_so_addr)
                        if not inlined_parent_sym_ctx:
                            break
                        if not inlined_parent_so_addr:
                            break

                        symbolicated_address = Address(self.target, inlined_parent_so_addr.GetLoadAddress(self.target))
                        symbolicated_address.sym_ctx = inlined_parent_sym_ctx
                        symbolicated_address.so_addr = inlined_parent_so_addr
                        symbolicated_address.symbolicate (verbose)
            
                        # push the new frame onto the new frame stack
                        symbolicated_addresses.append (symbolicated_address)
        
                    if symbolicated_addresses:
                        return symbolicated_addresses
        else:
            print 'error: no target in Symbolicator'
        return None
            
        
def disassemble_instructions (target, instructions, pc, insts_before_pc, insts_after_pc, non_zeroeth_frame):
    lines = list()
    pc_index = -1
    comment_column = 50
    for inst_idx, inst in enumerate(instructions):
        inst_pc = inst.GetAddress().GetLoadAddress(target);
        if pc == inst_pc:
            pc_index = inst_idx
        mnemonic = inst.GetMnemonic (target)
        operands =  inst.GetOperands (target)
        comment =  inst.GetComment (target)
        #data = inst.GetData (target)
        lines.append ("%#16.16x: %8s %s" % (inst_pc, mnemonic, operands))
        if comment:
            line_len = len(lines[-1])
            if line_len < comment_column:
                lines[-1] += ' ' * (comment_column - line_len)
                lines[-1] += "; %s" % comment

    if pc_index >= 0:
        # If we are disassembling the non-zeroeth frame, we need to backup the PC by 1
        if non_zeroeth_frame and pc_index > 0:
            pc_index = pc_index - 1
        if insts_before_pc == -1:
            start_idx = 0
        else:
            start_idx = pc_index - insts_before_pc
        if start_idx < 0:
            start_idx = 0
        if insts_before_pc == -1:
            end_idx = inst_idx
        else:
            end_idx = pc_index + insts_after_pc
        if end_idx > inst_idx:
            end_idx = inst_idx
        for i in range(start_idx, end_idx+1):
            if i == pc_index:
                print ' -> ', lines[i]
            else:
                print '    ', lines[i]

def print_module_section_data (section):
    print section
    section_data = section.GetSectionData()
    if section_data:
        ostream = lldb.SBStream()
        section_data.GetDescription (ostream, section.GetFileAddress())
        print ostream.GetData()

def print_module_section (section, depth):
    print section
    if depth > 0:
        num_sub_sections = section.GetNumSubSections()
        for sect_idx in range(num_sub_sections):
            print_module_section (section.GetSubSectionAtIndex(sect_idx), depth - 1)

def print_module_sections (module, depth):
    for sect in module.section_iter():
        print_module_section (sect, depth)

def print_module_symbols (module):
    for sym in module:
        print sym

def Symbolicate(command_args):
    
    usage = "usage: %prog [options] <addr1> [addr2 ...]"
    description='''Symbolicate one or more addresses using LLDB's python scripting API..'''
    parser = optparse.OptionParser(description=description, prog='crashlog.py',usage=usage)
    parser.add_option('-v', '--verbose', action='store_true', dest='verbose', help='display verbose debug info', default=False)
    parser.add_option('-p', '--platform', type='string', metavar='platform', dest='platform', help='Specify the platform to use when creating the debug target. Valid values include "localhost", "darwin-kernel", "ios-simulator", "remote-freebsd", "remote-macosx", "remote-ios", "remote-linux".')
    parser.add_option('-f', '--file', type='string', metavar='file', dest='file', help='Specify a file to use when symbolicating')
    parser.add_option('-a', '--arch', type='string', metavar='arch', dest='arch', help='Specify a architecture to use when symbolicating')
    parser.add_option('-s', '--slide', type='int', metavar='slide', dest='slide', help='Specify the slide to use on the file specified with the --file option', default=None)
    parser.add_option('--section', type='string', action='append', dest='section_strings', help='specify <sect-name>=<start-addr> or <sect-name>=<start-addr>-<end-addr>')
    try:
        (options, args) = parser.parse_args(command_args)
    except:
        return
    symbolicator = Symbolicator()
    images = list();
    if options.file:
        image = Image(options.file);
        image.arch = options.arch
        # Add any sections that were specified with one or more --section options
        if options.section_strings:
            for section_str in options.section_strings:
                section = Section()
                if section.set_from_string (section_str):
                    image.add_section (section)
                else:
                    sys.exit(1)
        if options.slide != None:
            image.slide = options.slide
        symbolicator.images.append(image)
    
    target = symbolicator.create_target()
    if options.verbose:
        print symbolicator
    if target:
        for addr_str in args:
            addr = int(addr_str, 0)
            symbolicated_addrs = symbolicator.symbolicate(addr, options.verbose)
            for symbolicated_addr in symbolicated_addrs:
                print symbolicated_addr
            print
    else:
        print 'error: no target for %s' % (symbolicator)
        
if __name__ == '__main__':
    # Create a new debugger instance
    lldb.debugger = lldb.SBDebugger.Create()
    Symbolicate (sys.argv[1:])
