1515bc8c1Sserge-sans-paille#!/usr/bin/env python
23c2c4bb2SGreg Clayton
33c2c4bb2SGreg Clayton#----------------------------------------------------------------------
43c2c4bb2SGreg Clayton# Be sure to add the python path that points to the LLDB shared library.
53c2c4bb2SGreg Clayton#
63c2c4bb2SGreg Clayton# To use this in the embedded python interpreter using "lldb":
73c2c4bb2SGreg Clayton#
83c2c4bb2SGreg Clayton#   cd /path/containing/crashlog.py
93c2c4bb2SGreg Clayton#   lldb
103c2c4bb2SGreg Clayton#   (lldb) script import crashlog
113c2c4bb2SGreg Clayton#   "crashlog" command installed, type "crashlog --help" for detailed help
123c2c4bb2SGreg Clayton#   (lldb) crashlog ~/Library/Logs/DiagnosticReports/a.crash
133c2c4bb2SGreg Clayton#
143c2c4bb2SGreg Clayton# The benefit of running the crashlog command inside lldb in the
153c2c4bb2SGreg Clayton# embedded python interpreter is when the command completes, there
163c2c4bb2SGreg Clayton# will be a target with all of the files loaded at the locations
173c2c4bb2SGreg Clayton# described in the crash log. Only the files that have stack frames
183c2c4bb2SGreg Clayton# in the backtrace will be loaded unless the "--load-all" option
193c2c4bb2SGreg Clayton# has been specified. This allows users to explore the program in the
203c2c4bb2SGreg Clayton# state it was in right at crash time.
213c2c4bb2SGreg Clayton#
223c2c4bb2SGreg Clayton# On MacOSX csh, tcsh:
233c2c4bb2SGreg Clayton#   ( setenv PYTHONPATH /path/to/LLDB.framework/Resources/Python ; ./crashlog.py ~/Library/Logs/DiagnosticReports/a.crash )
243c2c4bb2SGreg Clayton#
253c2c4bb2SGreg Clayton# On MacOSX sh, bash:
263c2c4bb2SGreg Clayton#   PYTHONPATH=/path/to/LLDB.framework/Resources/Python ./crashlog.py ~/Library/Logs/DiagnosticReports/a.crash
273c2c4bb2SGreg Clayton#----------------------------------------------------------------------
283c2c4bb2SGreg Clayton
299a8e777fSDavide Italianofrom __future__ import print_function
303c2c4bb2SGreg Claytonimport lldb
313c2c4bb2SGreg Claytonimport optparse
323c2c4bb2SGreg Claytonimport os
333c2c4bb2SGreg Claytonimport plistlib
343c2c4bb2SGreg Claytonimport re
353c2c4bb2SGreg Claytonimport shlex
363c2c4bb2SGreg Claytonimport sys
373c2c4bb2SGreg Claytonimport time
383c2c4bb2SGreg Claytonimport uuid
393c2c4bb2SGreg Clayton
40b9c1b51eSKate Stone
41814ad734SDavide Italianoclass Address:
423c2c4bb2SGreg Clayton    """Class that represents an address that will be symbolicated"""
43b9c1b51eSKate Stone
443c2c4bb2SGreg Clayton    def __init__(self, target, load_addr):
453c2c4bb2SGreg Clayton        self.target = target
463c2c4bb2SGreg Clayton        self.load_addr = load_addr  # The load address that this object represents
47b9c1b51eSKate Stone        # the resolved lldb.SBAddress (if any), named so_addr for
48b9c1b51eSKate Stone        # section/offset address
49b9c1b51eSKate Stone        self.so_addr = None
503c2c4bb2SGreg Clayton        self.sym_ctx = None  # The cached symbol context for this address
51b9c1b51eSKate Stone        # Any original textual description of this address to be used as a
52b9c1b51eSKate Stone        # backup in case symbolication fails
53b9c1b51eSKate Stone        self.description = None
543c2c4bb2SGreg Clayton        self.symbolication = None  # The cached symbolicated string that describes this address
553c2c4bb2SGreg Clayton        self.inlined = False
56b9c1b51eSKate Stone
573c2c4bb2SGreg Clayton    def __str__(self):
583c2c4bb2SGreg Clayton        s = "%#16.16x" % (self.load_addr)
593c2c4bb2SGreg Clayton        if self.symbolication:
603c2c4bb2SGreg Clayton            s += " %s" % (self.symbolication)
613c2c4bb2SGreg Clayton        elif self.description:
623c2c4bb2SGreg Clayton            s += " %s" % (self.description)
633c2c4bb2SGreg Clayton        elif self.so_addr:
643c2c4bb2SGreg Clayton            s += " %s" % (self.so_addr)
653c2c4bb2SGreg Clayton        return s
663c2c4bb2SGreg Clayton
673c2c4bb2SGreg Clayton    def resolve_addr(self):
68b9c1b51eSKate Stone        if self.so_addr is None:
693c2c4bb2SGreg Clayton            self.so_addr = self.target.ResolveLoadAddress(self.load_addr)
703c2c4bb2SGreg Clayton        return self.so_addr
713c2c4bb2SGreg Clayton
723c2c4bb2SGreg Clayton    def is_inlined(self):
733c2c4bb2SGreg Clayton        return self.inlined
743c2c4bb2SGreg Clayton
753c2c4bb2SGreg Clayton    def get_symbol_context(self):
76b9c1b51eSKate Stone        if self.sym_ctx is None:
773c2c4bb2SGreg Clayton            sb_addr = self.resolve_addr()
783c2c4bb2SGreg Clayton            if sb_addr:
79b9c1b51eSKate Stone                self.sym_ctx = self.target.ResolveSymbolContextForAddress(
80b9c1b51eSKate Stone                    sb_addr, lldb.eSymbolContextEverything)
813c2c4bb2SGreg Clayton            else:
823c2c4bb2SGreg Clayton                self.sym_ctx = lldb.SBSymbolContext()
833c2c4bb2SGreg Clayton        return self.sym_ctx
843c2c4bb2SGreg Clayton
853c2c4bb2SGreg Clayton    def get_instructions(self):
863c2c4bb2SGreg Clayton        sym_ctx = self.get_symbol_context()
873c2c4bb2SGreg Clayton        if sym_ctx:
883c2c4bb2SGreg Clayton            function = sym_ctx.GetFunction()
893c2c4bb2SGreg Clayton            if function:
903c2c4bb2SGreg Clayton                return function.GetInstructions(self.target)
913c2c4bb2SGreg Clayton            return sym_ctx.GetSymbol().GetInstructions(self.target)
923c2c4bb2SGreg Clayton        return None
933c2c4bb2SGreg Clayton
94a7fb1dcdSGreg Clayton    def symbolicate(self, verbose=False):
95b9c1b51eSKate Stone        if self.symbolication is None:
963c2c4bb2SGreg Clayton            self.symbolication = ''
973c2c4bb2SGreg Clayton            self.inlined = False
983c2c4bb2SGreg Clayton            sym_ctx = self.get_symbol_context()
993c2c4bb2SGreg Clayton            if sym_ctx:
1003c2c4bb2SGreg Clayton                module = sym_ctx.GetModule()
1013c2c4bb2SGreg Clayton                if module:
102a7fb1dcdSGreg Clayton                    # Print full source file path in verbose mode
103a7fb1dcdSGreg Clayton                    if verbose:
104a7fb1dcdSGreg Clayton                        self.symbolication += str(module.GetFileSpec()) + '`'
105a7fb1dcdSGreg Clayton                    else:
1063c2c4bb2SGreg Clayton                        self.symbolication += module.GetFileSpec().GetFilename() + '`'
1073c2c4bb2SGreg Clayton                    function_start_load_addr = -1
1083c2c4bb2SGreg Clayton                    function = sym_ctx.GetFunction()
1093c2c4bb2SGreg Clayton                    block = sym_ctx.GetBlock()
1103c2c4bb2SGreg Clayton                    line_entry = sym_ctx.GetLineEntry()
1113c2c4bb2SGreg Clayton                    symbol = sym_ctx.GetSymbol()
112b9c1b51eSKate Stone                    inlined_block = block.GetContainingInlinedBlock()
1133c2c4bb2SGreg Clayton                    if function:
1143c2c4bb2SGreg Clayton                        self.symbolication += function.GetName()
1153c2c4bb2SGreg Clayton
1163c2c4bb2SGreg Clayton                        if inlined_block:
1173c2c4bb2SGreg Clayton                            self.inlined = True
118b9c1b51eSKate Stone                            self.symbolication += ' [inlined] ' + \
119b9c1b51eSKate Stone                                inlined_block.GetInlinedName()
120b9c1b51eSKate Stone                            block_range_idx = inlined_block.GetRangeIndexForBlockAddress(
121b9c1b51eSKate Stone                                self.so_addr)
1223c2c4bb2SGreg Clayton                            if block_range_idx < lldb.UINT32_MAX:
123b9c1b51eSKate Stone                                block_range_start_addr = inlined_block.GetRangeStartAddress(
124b9c1b51eSKate Stone                                    block_range_idx)
125b9c1b51eSKate Stone                                function_start_load_addr = block_range_start_addr.GetLoadAddress(
126b9c1b51eSKate Stone                                    self.target)
1273c2c4bb2SGreg Clayton                        if function_start_load_addr == -1:
1283c2c4bb2SGreg Clayton                            function_start_load_addr = function.GetStartAddress().GetLoadAddress(self.target)
1293c2c4bb2SGreg Clayton                    elif symbol:
1303c2c4bb2SGreg Clayton                        self.symbolication += symbol.GetName()
1313c2c4bb2SGreg Clayton                        function_start_load_addr = symbol.GetStartAddress().GetLoadAddress(self.target)
1323c2c4bb2SGreg Clayton                    else:
1333c2c4bb2SGreg Clayton                        self.symbolication = ''
1343c2c4bb2SGreg Clayton                        return False
1353c2c4bb2SGreg Clayton
136b9c1b51eSKate Stone                    # Dump the offset from the current function or symbol if it
137b9c1b51eSKate Stone                    # is non zero
1383c2c4bb2SGreg Clayton                    function_offset = self.load_addr - function_start_load_addr
1393c2c4bb2SGreg Clayton                    if function_offset > 0:
1403c2c4bb2SGreg Clayton                        self.symbolication += " + %u" % (function_offset)
1413c2c4bb2SGreg Clayton                    elif function_offset < 0:
1423c2c4bb2SGreg Clayton                        self.symbolication += " %i (invalid negative offset, file a bug) " % function_offset
1433c2c4bb2SGreg Clayton
1443c2c4bb2SGreg Clayton                    # Print out any line information if any is available
1453c2c4bb2SGreg Clayton                    if line_entry.GetFileSpec():
146a7fb1dcdSGreg Clayton                        # Print full source file path in verbose mode
147a7fb1dcdSGreg Clayton                        if verbose:
148a7fb1dcdSGreg Clayton                            self.symbolication += ' at %s' % line_entry.GetFileSpec()
149a7fb1dcdSGreg Clayton                        else:
1503c2c4bb2SGreg Clayton                            self.symbolication += ' at %s' % line_entry.GetFileSpec().GetFilename()
1513c2c4bb2SGreg Clayton                        self.symbolication += ':%u' % line_entry.GetLine()
1523c2c4bb2SGreg Clayton                        column = line_entry.GetColumn()
1533c2c4bb2SGreg Clayton                        if column > 0:
1543c2c4bb2SGreg Clayton                            self.symbolication += ':%u' % column
1553c2c4bb2SGreg Clayton                    return True
1563c2c4bb2SGreg Clayton        return False
1573c2c4bb2SGreg Clayton
158b9c1b51eSKate Stone
159814ad734SDavide Italianoclass Section:
1603c2c4bb2SGreg Clayton    """Class that represents an load address range"""
1613c2c4bb2SGreg Clayton    sect_info_regex = re.compile('(?P<name>[^=]+)=(?P<range>.*)')
1623c2c4bb2SGreg Clayton    addr_regex = re.compile('^\s*(?P<start>0x[0-9A-Fa-f]+)\s*$')
163b9c1b51eSKate Stone    range_regex = re.compile(
164b9c1b51eSKate Stone        '^\s*(?P<start>0x[0-9A-Fa-f]+)\s*(?P<op>[-+])\s*(?P<end>0x[0-9A-Fa-f]+)\s*$')
1653c2c4bb2SGreg Clayton
1663c2c4bb2SGreg Clayton    def __init__(self, start_addr=None, end_addr=None, name=None):
1673c2c4bb2SGreg Clayton        self.start_addr = start_addr
1683c2c4bb2SGreg Clayton        self.end_addr = end_addr
1693c2c4bb2SGreg Clayton        self.name = name
1703c2c4bb2SGreg Clayton
171641c23f3SGreg Clayton    @classmethod
172641c23f3SGreg Clayton    def InitWithSBTargetAndSBSection(cls, target, section):
173641c23f3SGreg Clayton        sect_load_addr = section.GetLoadAddress(target)
174641c23f3SGreg Clayton        if sect_load_addr != lldb.LLDB_INVALID_ADDRESS:
175b9c1b51eSKate Stone            obj = cls(
176b9c1b51eSKate Stone                sect_load_addr,
177b9c1b51eSKate Stone                sect_load_addr +
178b9c1b51eSKate Stone                section.size,
179b9c1b51eSKate Stone                section.name)
180641c23f3SGreg Clayton            return obj
181641c23f3SGreg Clayton        else:
182641c23f3SGreg Clayton            return None
183641c23f3SGreg Clayton
1843c2c4bb2SGreg Clayton    def contains(self, addr):
185b9c1b51eSKate Stone        return self.start_addr <= addr and addr < self.end_addr
1863c2c4bb2SGreg Clayton
1873c2c4bb2SGreg Clayton    def set_from_string(self, s):
1883c2c4bb2SGreg Clayton        match = self.sect_info_regex.match(s)
1893c2c4bb2SGreg Clayton        if match:
1903c2c4bb2SGreg Clayton            self.name = match.group('name')
1913c2c4bb2SGreg Clayton            range_str = match.group('range')
1923c2c4bb2SGreg Clayton            addr_match = self.addr_regex.match(range_str)
1933c2c4bb2SGreg Clayton            if addr_match:
1943c2c4bb2SGreg Clayton                self.start_addr = int(addr_match.group('start'), 16)
1953c2c4bb2SGreg Clayton                self.end_addr = None
1963c2c4bb2SGreg Clayton                return True
1973c2c4bb2SGreg Clayton
1983c2c4bb2SGreg Clayton            range_match = self.range_regex.match(range_str)
1993c2c4bb2SGreg Clayton            if range_match:
2003c2c4bb2SGreg Clayton                self.start_addr = int(range_match.group('start'), 16)
2013c2c4bb2SGreg Clayton                self.end_addr = int(range_match.group('end'), 16)
2023c2c4bb2SGreg Clayton                op = range_match.group('op')
2033c2c4bb2SGreg Clayton                if op == '+':
2043c2c4bb2SGreg Clayton                    self.end_addr += self.start_addr
2053c2c4bb2SGreg Clayton                return True
206a658ab9fSDavide Italiano        print('error: invalid section info string "%s"' % s)
207a658ab9fSDavide Italiano        print('Valid section info formats are:')
208a658ab9fSDavide Italiano        print('Format                Example                    Description')
209a658ab9fSDavide Italiano        print('--------------------- -----------------------------------------------')
210a658ab9fSDavide Italiano        print('<name>=<base>        __TEXT=0x123000             Section from base address only')
211a658ab9fSDavide Italiano        print('<name>=<base>-<end>  __TEXT=0x123000-0x124000    Section from base address and end address')
212a658ab9fSDavide Italiano        print('<name>=<base>+<size> __TEXT=0x123000+0x1000      Section from base address and size')
2133c2c4bb2SGreg Clayton        return False
2143c2c4bb2SGreg Clayton
2153c2c4bb2SGreg Clayton    def __str__(self):
2163c2c4bb2SGreg Clayton        if self.name:
217b9c1b51eSKate Stone            if self.end_addr is not None:
218b9c1b51eSKate Stone                if self.start_addr is not None:
219b9c1b51eSKate Stone                    return "%s=[0x%16.16x - 0x%16.16x)" % (
220b9c1b51eSKate Stone                        self.name, self.start_addr, self.end_addr)
2213c2c4bb2SGreg Clayton            else:
222b9c1b51eSKate Stone                if self.start_addr is not None:
2233c2c4bb2SGreg Clayton                    return "%s=0x%16.16x" % (self.name, self.start_addr)
2243c2c4bb2SGreg Clayton            return self.name
2253c2c4bb2SGreg Clayton        return "<invalid>"
2263c2c4bb2SGreg Clayton
227b9c1b51eSKate Stone
228814ad734SDavide Italianoclass Image:
2293c2c4bb2SGreg Clayton    """A class that represents an executable image and any associated data"""
2303c2c4bb2SGreg Clayton
2313c2c4bb2SGreg Clayton    def __init__(self, path, uuid=None):
2323c2c4bb2SGreg Clayton        self.path = path
2333c2c4bb2SGreg Clayton        self.resolved_path = None
234f51a23fbSGreg Clayton        self.resolved = False
235f51a23fbSGreg Clayton        self.unavailable = False
2363c2c4bb2SGreg Clayton        self.uuid = uuid
2373c2c4bb2SGreg Clayton        self.section_infos = list()
2383c2c4bb2SGreg Clayton        self.identifier = None
2393c2c4bb2SGreg Clayton        self.version = None
2403c2c4bb2SGreg Clayton        self.arch = None
2413c2c4bb2SGreg Clayton        self.module = None
2423c2c4bb2SGreg Clayton        self.symfile = None
2433c2c4bb2SGreg Clayton        self.slide = None
2443c2c4bb2SGreg Clayton
245641c23f3SGreg Clayton    @classmethod
246641c23f3SGreg Clayton    def InitWithSBTargetAndSBModule(cls, target, module):
247adb99821SBruce Mitchener        '''Initialize this Image object with a module from a target.'''
248641c23f3SGreg Clayton        obj = cls(module.file.fullpath, module.uuid)
249641c23f3SGreg Clayton        obj.resolved_path = module.platform_file.fullpath
250641c23f3SGreg Clayton        obj.resolved = True
251641c23f3SGreg Clayton        for section in module.sections:
252b9c1b51eSKate Stone            symb_section = Section.InitWithSBTargetAndSBSection(
253b9c1b51eSKate Stone                target, section)
254641c23f3SGreg Clayton            if symb_section:
255641c23f3SGreg Clayton                obj.section_infos.append(symb_section)
256641c23f3SGreg Clayton        obj.arch = module.triple
257641c23f3SGreg Clayton        obj.module = module
258641c23f3SGreg Clayton        obj.symfile = None
259641c23f3SGreg Clayton        obj.slide = None
260641c23f3SGreg Clayton        return obj
261a16cb16aSGreg Clayton
2623c2c4bb2SGreg Clayton    def dump(self, prefix):
263a658ab9fSDavide Italiano        print("%s%s" % (prefix, self))
2643c2c4bb2SGreg Clayton
2651f746071SGreg Clayton    def debug_dump(self):
266a658ab9fSDavide Italiano        print('path = "%s"' % (self.path))
267a658ab9fSDavide Italiano        print('resolved_path = "%s"' % (self.resolved_path))
268a658ab9fSDavide Italiano        print('resolved = %i' % (self.resolved))
269a658ab9fSDavide Italiano        print('unavailable = %i' % (self.unavailable))
270a658ab9fSDavide Italiano        print('uuid = %s' % (self.uuid))
271a658ab9fSDavide Italiano        print('section_infos = %s' % (self.section_infos))
272a658ab9fSDavide Italiano        print('identifier = "%s"' % (self.identifier))
273a658ab9fSDavide Italiano        print('version = %s' % (self.version))
274a658ab9fSDavide Italiano        print('arch = %s' % (self.arch))
275a658ab9fSDavide Italiano        print('module = %s' % (self.module))
276a658ab9fSDavide Italiano        print('symfile = "%s"' % (self.symfile))
277a658ab9fSDavide Italiano        print('slide = %i (0x%x)' % (self.slide, self.slide))
2781f746071SGreg Clayton
2793c2c4bb2SGreg Clayton    def __str__(self):
280641c23f3SGreg Clayton        s = ''
281641c23f3SGreg Clayton        if self.uuid:
282641c23f3SGreg Clayton            s += "%s " % (self.get_uuid())
283641c23f3SGreg Clayton        if self.arch:
284641c23f3SGreg Clayton            s += "%s " % (self.arch)
285641c23f3SGreg Clayton        if self.version:
286641c23f3SGreg Clayton            s += "%s " % (self.version)
287641c23f3SGreg Clayton        resolved_path = self.get_resolved_path()
288641c23f3SGreg Clayton        if resolved_path:
289641c23f3SGreg Clayton            s += "%s " % (resolved_path)
2903c2c4bb2SGreg Clayton        for section_info in self.section_infos:
2913c2c4bb2SGreg Clayton            s += ", %s" % (section_info)
292b9c1b51eSKate Stone        if self.slide is not None:
2933c2c4bb2SGreg Clayton            s += ', slide = 0x%16.16x' % self.slide
2943c2c4bb2SGreg Clayton        return s
2953c2c4bb2SGreg Clayton
2963c2c4bb2SGreg Clayton    def add_section(self, section):
2973c2c4bb2SGreg Clayton        # print "added '%s' to '%s'" % (section, self.path)
2983c2c4bb2SGreg Clayton        self.section_infos.append(section)
2993c2c4bb2SGreg Clayton
3003c2c4bb2SGreg Clayton    def get_section_containing_load_addr(self, load_addr):
3013c2c4bb2SGreg Clayton        for section_info in self.section_infos:
3023c2c4bb2SGreg Clayton            if section_info.contains(load_addr):
3033c2c4bb2SGreg Clayton                return section_info
3043c2c4bb2SGreg Clayton        return None
3053c2c4bb2SGreg Clayton
3063c2c4bb2SGreg Clayton    def get_resolved_path(self):
3073c2c4bb2SGreg Clayton        if self.resolved_path:
3083c2c4bb2SGreg Clayton            return self.resolved_path
3093c2c4bb2SGreg Clayton        elif self.path:
3103c2c4bb2SGreg Clayton            return self.path
3113c2c4bb2SGreg Clayton        return None
3123c2c4bb2SGreg Clayton
3133c2c4bb2SGreg Clayton    def get_resolved_path_basename(self):
3143c2c4bb2SGreg Clayton        path = self.get_resolved_path()
3153c2c4bb2SGreg Clayton        if path:
3163c2c4bb2SGreg Clayton            return os.path.basename(path)
3173c2c4bb2SGreg Clayton        return None
3183c2c4bb2SGreg Clayton
3193c2c4bb2SGreg Clayton    def symfile_basename(self):
3203c2c4bb2SGreg Clayton        if self.symfile:
3213c2c4bb2SGreg Clayton            return os.path.basename(self.symfile)
3223c2c4bb2SGreg Clayton        return None
3233c2c4bb2SGreg Clayton
3243c2c4bb2SGreg Clayton    def has_section_load_info(self):
325b9c1b51eSKate Stone        return self.section_infos or self.slide is not None
3263c2c4bb2SGreg Clayton
3273c2c4bb2SGreg Clayton    def load_module(self, target):
328f51a23fbSGreg Clayton        if self.unavailable:
329f51a23fbSGreg Clayton            return None  # We already warned that we couldn't find this module, so don't return an error string
3303c2c4bb2SGreg Clayton        # Load this module into "target" using the section infos to
3313c2c4bb2SGreg Clayton        # set the section load addresses
3323c2c4bb2SGreg Clayton        if self.has_section_load_info():
3333c2c4bb2SGreg Clayton            if target:
3343c2c4bb2SGreg Clayton                if self.module:
3353c2c4bb2SGreg Clayton                    if self.section_infos:
3363c2c4bb2SGreg Clayton                        num_sections_loaded = 0
3373c2c4bb2SGreg Clayton                        for section_info in self.section_infos:
3383c2c4bb2SGreg Clayton                            if section_info.name:
339b9c1b51eSKate Stone                                section = self.module.FindSection(
340b9c1b51eSKate Stone                                    section_info.name)
3413c2c4bb2SGreg Clayton                                if section:
342b9c1b51eSKate Stone                                    error = target.SetSectionLoadAddress(
343b9c1b51eSKate Stone                                        section, section_info.start_addr)
3443c2c4bb2SGreg Clayton                                    if error.Success():
3453c2c4bb2SGreg Clayton                                        num_sections_loaded += 1
3463c2c4bb2SGreg Clayton                                    else:
3473c2c4bb2SGreg Clayton                                        return 'error: %s' % error.GetCString()
3483c2c4bb2SGreg Clayton                                else:
3493c2c4bb2SGreg Clayton                                    return 'error: unable to find the section named "%s"' % section_info.name
3503c2c4bb2SGreg Clayton                            else:
351b9c1b51eSKate Stone                                return 'error: unable to find "%s" section in "%s"' % (
352b9c1b51eSKate Stone                                    range.name, self.get_resolved_path())
3533c2c4bb2SGreg Clayton                        if num_sections_loaded == 0:
3543c2c4bb2SGreg Clayton                            return 'error: no sections were successfully loaded'
3553c2c4bb2SGreg Clayton                    else:
356b9c1b51eSKate Stone                        err = target.SetModuleLoadAddress(
357b9c1b51eSKate Stone                            self.module, self.slide)
3583c2c4bb2SGreg Clayton                        if err.Fail():
3593c2c4bb2SGreg Clayton                            return err.GetCString()
3603c2c4bb2SGreg Clayton                    return None
3613c2c4bb2SGreg Clayton                else:
3623c2c4bb2SGreg Clayton                    return 'error: invalid module'
3633c2c4bb2SGreg Clayton            else:
3643c2c4bb2SGreg Clayton                return 'error: invalid target'
3653c2c4bb2SGreg Clayton        else:
3663c2c4bb2SGreg Clayton            return 'error: no section infos'
3673c2c4bb2SGreg Clayton
3683c2c4bb2SGreg Clayton    def add_module(self, target):
3693c2c4bb2SGreg Clayton        '''Add the Image described in this object to "target" and load the sections if "load" is True.'''
3703c2c4bb2SGreg Clayton        if target:
371b9c1b51eSKate Stone            # Try and find using UUID only first so that paths need not match
372b9c1b51eSKate Stone            # up
37360bb58f6SGreg Clayton            uuid_str = self.get_normalized_uuid_string()
37460bb58f6SGreg Clayton            if uuid_str:
37560bb58f6SGreg Clayton                self.module = target.AddModule(None, None, uuid_str)
3763c2c4bb2SGreg Clayton            if not self.module:
377f99295c3SGreg Clayton                self.locate_module_and_debug_symbols()
378f51a23fbSGreg Clayton                if self.unavailable:
379f51a23fbSGreg Clayton                    return None
380f99295c3SGreg Clayton                resolved_path = self.get_resolved_path()
381b9c1b51eSKate Stone                self.module = target.AddModule(
382*e31b2d7dSVedant Kumar                    resolved_path, None, uuid_str, self.symfile)
3833c2c4bb2SGreg Clayton            if not self.module:
384b9c1b51eSKate Stone                return 'error: unable to get module for (%s) "%s"' % (
385b9c1b51eSKate Stone                    self.arch, self.get_resolved_path())
3863c2c4bb2SGreg Clayton            if self.has_section_load_info():
3873c2c4bb2SGreg Clayton                return self.load_module(target)
3883c2c4bb2SGreg Clayton            else:
3893c2c4bb2SGreg Clayton                return None  # No sections, the module was added to the target, so success
3903c2c4bb2SGreg Clayton        else:
3913c2c4bb2SGreg Clayton            return 'error: invalid target'
3923c2c4bb2SGreg Clayton
3933c2c4bb2SGreg Clayton    def locate_module_and_debug_symbols(self):
3943c2c4bb2SGreg Clayton        # By default, just use the paths that were supplied in:
3953c2c4bb2SGreg Clayton        # self.path
3963c2c4bb2SGreg Clayton        # self.resolved_path
3973c2c4bb2SGreg Clayton        # self.module
3983c2c4bb2SGreg Clayton        # self.symfile
3993c2c4bb2SGreg Clayton        # Subclasses can inherit from this class and override this function
400f51a23fbSGreg Clayton        self.resolved = True
4013c2c4bb2SGreg Clayton        return True
4023c2c4bb2SGreg Clayton
4033c2c4bb2SGreg Clayton    def get_uuid(self):
40460bb58f6SGreg Clayton        if not self.uuid and self.module:
4053c2c4bb2SGreg Clayton            self.uuid = uuid.UUID(self.module.GetUUIDString())
4063c2c4bb2SGreg Clayton        return self.uuid
4073c2c4bb2SGreg Clayton
40860bb58f6SGreg Clayton    def get_normalized_uuid_string(self):
40960bb58f6SGreg Clayton        if self.uuid:
41060bb58f6SGreg Clayton            return str(self.uuid).upper()
41160bb58f6SGreg Clayton        return None
41260bb58f6SGreg Clayton
413c29c24beSJonas Devlieghere    def create_target(self, debugger):
4143c2c4bb2SGreg Clayton        '''Create a target using the information in this Image object.'''
415f51a23fbSGreg Clayton        if self.unavailable:
416f51a23fbSGreg Clayton            return None
417f51a23fbSGreg Clayton
4183c2c4bb2SGreg Clayton        if self.locate_module_and_debug_symbols():
419b9c1b51eSKate Stone            resolved_path = self.get_resolved_path()
4203c2c4bb2SGreg Clayton            path_spec = lldb.SBFileSpec(resolved_path)
4213c2c4bb2SGreg Clayton            error = lldb.SBError()
422c29c24beSJonas Devlieghere            target = debugger.CreateTarget(
423b9c1b51eSKate Stone                resolved_path, self.arch, None, False, error)
4243c2c4bb2SGreg Clayton            if target:
4253c2c4bb2SGreg Clayton                self.module = target.FindModule(path_spec)
4263c2c4bb2SGreg Clayton                if self.has_section_load_info():
4273c2c4bb2SGreg Clayton                    err = self.load_module(target)
4283c2c4bb2SGreg Clayton                    if err:
429a658ab9fSDavide Italiano                        print('ERROR: ', err)
4303c2c4bb2SGreg Clayton                return target
4313c2c4bb2SGreg Clayton            else:
432a658ab9fSDavide Italiano                print('error: unable to create a valid target for (%s) "%s"' % (self.arch, self.path))
4333c2c4bb2SGreg Clayton        else:
434a658ab9fSDavide Italiano            print('error: unable to locate main executable (%s) "%s"' % (self.arch, self.path))
4353c2c4bb2SGreg Clayton        return None
4363c2c4bb2SGreg Clayton
437b9c1b51eSKate Stone
438814ad734SDavide Italianoclass Symbolicator:
4393c2c4bb2SGreg Clayton
44099ea2c46SJonas Devlieghere    def __init__(self, debugger=None, target=None, images=list()):
44199ea2c46SJonas Devlieghere        """A class the represents the information needed to symbolicate
44299ea2c46SJonas Devlieghere        addresses in a program.
44399ea2c46SJonas Devlieghere
44499ea2c46SJonas Devlieghere        Do not call this initializer directly, but rather use the factory
44599ea2c46SJonas Devlieghere        methods.
44699ea2c46SJonas Devlieghere        """
447c29c24beSJonas Devlieghere        self.debugger = debugger
44899ea2c46SJonas Devlieghere        self.target = target
44999ea2c46SJonas Devlieghere        self.images = images  # a list of images to be used when symbolicating
450a16cb16aSGreg Clayton        self.addr_mask = 0xffffffffffffffff
4513c2c4bb2SGreg Clayton
452641c23f3SGreg Clayton    @classmethod
453641c23f3SGreg Clayton    def InitWithSBTarget(cls, target):
45499ea2c46SJonas Devlieghere        """Initialize a new Symbolicator with an existing SBTarget."""
45599ea2c46SJonas Devlieghere        obj = cls(target=target)
456641c23f3SGreg Clayton        triple = target.triple
457641c23f3SGreg Clayton        if triple:
458641c23f3SGreg Clayton            arch = triple.split('-')[0]
459641c23f3SGreg Clayton            if "arm" in arch:
460641c23f3SGreg Clayton                obj.addr_mask = 0xfffffffffffffffe
461641c23f3SGreg Clayton
462641c23f3SGreg Clayton        for module in target.modules:
463641c23f3SGreg Clayton            image = Image.InitWithSBTargetAndSBModule(target, module)
464641c23f3SGreg Clayton            obj.images.append(image)
465641c23f3SGreg Clayton        return obj
466641c23f3SGreg Clayton
46799ea2c46SJonas Devlieghere    @classmethod
46899ea2c46SJonas Devlieghere    def InitWithSBDebugger(cls, debugger, images):
46999ea2c46SJonas Devlieghere        """Initialize a new Symbolicator with an existing debugger and list of
47099ea2c46SJonas Devlieghere        images. The Symbolicator will create the target."""
47199ea2c46SJonas Devlieghere        obj = cls(debugger=debugger, images=images)
47299ea2c46SJonas Devlieghere        return obj
47399ea2c46SJonas Devlieghere
4743c2c4bb2SGreg Clayton    def __str__(self):
4753c2c4bb2SGreg Clayton        s = "Symbolicator:\n"
4763c2c4bb2SGreg Clayton        if self.target:
4773c2c4bb2SGreg Clayton            s += "Target = '%s'\n" % (self.target)
478641c23f3SGreg Clayton            s += "Target modules:\n"
4793c2c4bb2SGreg Clayton            for m in self.target.modules:
480641c23f3SGreg Clayton                s += str(m) + "\n"
4813c2c4bb2SGreg Clayton        s += "Images:\n"
4823c2c4bb2SGreg Clayton        for image in self.images:
4833c2c4bb2SGreg Clayton            s += '    %s\n' % (image)
4843c2c4bb2SGreg Clayton        return s
4853c2c4bb2SGreg Clayton
4863c2c4bb2SGreg Clayton    def find_images_with_identifier(self, identifier):
4873c2c4bb2SGreg Clayton        images = list()
4883c2c4bb2SGreg Clayton        for image in self.images:
4893c2c4bb2SGreg Clayton            if image.identifier == identifier:
4903c2c4bb2SGreg Clayton                images.append(image)
49148d157ddSGreg Clayton        if len(images) == 0:
4926c42aa77SGreg Clayton            regex_text = '^.*\.%s$' % (re.escape(identifier))
49348d157ddSGreg Clayton            regex = re.compile(regex_text)
49448d157ddSGreg Clayton            for image in self.images:
49548d157ddSGreg Clayton                if regex.match(image.identifier):
49648d157ddSGreg Clayton                    images.append(image)
4973c2c4bb2SGreg Clayton        return images
4983c2c4bb2SGreg Clayton
4993c2c4bb2SGreg Clayton    def find_image_containing_load_addr(self, load_addr):
5003c2c4bb2SGreg Clayton        for image in self.images:
501f51a23fbSGreg Clayton            if image.get_section_containing_load_addr(load_addr):
5023c2c4bb2SGreg Clayton                return image
5033c2c4bb2SGreg Clayton        return None
5043c2c4bb2SGreg Clayton
5053c2c4bb2SGreg Clayton    def create_target(self):
5063c2c4bb2SGreg Clayton        if self.target:
5073c2c4bb2SGreg Clayton            return self.target
5083c2c4bb2SGreg Clayton
5093c2c4bb2SGreg Clayton        if self.images:
5103c2c4bb2SGreg Clayton            for image in self.images:
511c29c24beSJonas Devlieghere                self.target = image.create_target(self.debugger)
5123c2c4bb2SGreg Clayton                if self.target:
513a16cb16aSGreg Clayton                    if self.target.GetAddressByteSize() == 4:
514a16cb16aSGreg Clayton                        triple = self.target.triple
515a16cb16aSGreg Clayton                        if triple:
516a16cb16aSGreg Clayton                            arch = triple.split('-')[0]
517a16cb16aSGreg Clayton                            if "arm" in arch:
518a16cb16aSGreg Clayton                                self.addr_mask = 0xfffffffffffffffe
5193c2c4bb2SGreg Clayton                    return self.target
5203c2c4bb2SGreg Clayton        return None
5213c2c4bb2SGreg Clayton
522a7fb1dcdSGreg Clayton    def symbolicate(self, load_addr, verbose=False):
523f51a23fbSGreg Clayton        if not self.target:
524f51a23fbSGreg Clayton            self.create_target()
5253c2c4bb2SGreg Clayton        if self.target:
52659c40ff3SGreg Clayton            live_process = False
52759c40ff3SGreg Clayton            process = self.target.process
52859c40ff3SGreg Clayton            if process:
52959c40ff3SGreg Clayton                state = process.state
530fdc2515cSGreg Clayton                if state > lldb.eStateUnloaded and state < lldb.eStateDetached:
53159c40ff3SGreg Clayton                    live_process = True
53259c40ff3SGreg Clayton            # If we don't have a live process, we can attempt to find the image
53359c40ff3SGreg Clayton            # that a load address belongs to and lazily load its module in the
53459c40ff3SGreg Clayton            # target, but we shouldn't do any of this if we have a live process
53559c40ff3SGreg Clayton            if not live_process:
536f51a23fbSGreg Clayton                image = self.find_image_containing_load_addr(load_addr)
537f51a23fbSGreg Clayton                if image:
538f51a23fbSGreg Clayton                    image.add_module(self.target)
5393c2c4bb2SGreg Clayton            symbolicated_address = Address(self.target, load_addr)
540a7fb1dcdSGreg Clayton            if symbolicated_address.symbolicate(verbose):
5413c2c4bb2SGreg Clayton                if symbolicated_address.so_addr:
5423c2c4bb2SGreg Clayton                    symbolicated_addresses = list()
5433c2c4bb2SGreg Clayton                    symbolicated_addresses.append(symbolicated_address)
5443c2c4bb2SGreg Clayton                    # See if we were able to reconstruct anything?
545b9c1b51eSKate Stone                    while True:
5463c2c4bb2SGreg Clayton                        inlined_parent_so_addr = lldb.SBAddress()
547b9c1b51eSKate Stone                        inlined_parent_sym_ctx = symbolicated_address.sym_ctx.GetParentOfInlinedScope(
548b9c1b51eSKate Stone                            symbolicated_address.so_addr, inlined_parent_so_addr)
5493c2c4bb2SGreg Clayton                        if not inlined_parent_sym_ctx:
5503c2c4bb2SGreg Clayton                            break
5513c2c4bb2SGreg Clayton                        if not inlined_parent_so_addr:
5523c2c4bb2SGreg Clayton                            break
5533c2c4bb2SGreg Clayton
554b9c1b51eSKate Stone                        symbolicated_address = Address(
555b9c1b51eSKate Stone                            self.target, inlined_parent_so_addr.GetLoadAddress(
556b9c1b51eSKate Stone                                self.target))
5573c2c4bb2SGreg Clayton                        symbolicated_address.sym_ctx = inlined_parent_sym_ctx
5583c2c4bb2SGreg Clayton                        symbolicated_address.so_addr = inlined_parent_so_addr
559a7fb1dcdSGreg Clayton                        symbolicated_address.symbolicate(verbose)
5603c2c4bb2SGreg Clayton
5613c2c4bb2SGreg Clayton                        # push the new frame onto the new frame stack
5623c2c4bb2SGreg Clayton                        symbolicated_addresses.append(symbolicated_address)
5633c2c4bb2SGreg Clayton
5643c2c4bb2SGreg Clayton                    if symbolicated_addresses:
5653c2c4bb2SGreg Clayton                        return symbolicated_addresses
566f51a23fbSGreg Clayton        else:
567a658ab9fSDavide Italiano            print('error: no target in Symbolicator')
5683c2c4bb2SGreg Clayton        return None
5693c2c4bb2SGreg Clayton
5703c2c4bb2SGreg Clayton
571b9c1b51eSKate Stonedef disassemble_instructions(
572b9c1b51eSKate Stone        target,
573b9c1b51eSKate Stone        instructions,
574b9c1b51eSKate Stone        pc,
575b9c1b51eSKate Stone        insts_before_pc,
576b9c1b51eSKate Stone        insts_after_pc,
577b9c1b51eSKate Stone        non_zeroeth_frame):
5783c2c4bb2SGreg Clayton    lines = list()
5793c2c4bb2SGreg Clayton    pc_index = -1
5803c2c4bb2SGreg Clayton    comment_column = 50
5813c2c4bb2SGreg Clayton    for inst_idx, inst in enumerate(instructions):
582b9c1b51eSKate Stone        inst_pc = inst.GetAddress().GetLoadAddress(target)
5833c2c4bb2SGreg Clayton        if pc == inst_pc:
5843c2c4bb2SGreg Clayton            pc_index = inst_idx
5853c2c4bb2SGreg Clayton        mnemonic = inst.GetMnemonic(target)
5863c2c4bb2SGreg Clayton        operands = inst.GetOperands(target)
5873c2c4bb2SGreg Clayton        comment = inst.GetComment(target)
5883c2c4bb2SGreg Clayton        lines.append("%#16.16x: %8s %s" % (inst_pc, mnemonic, operands))
5893c2c4bb2SGreg Clayton        if comment:
5903c2c4bb2SGreg Clayton            line_len = len(lines[-1])
5913c2c4bb2SGreg Clayton            if line_len < comment_column:
5923c2c4bb2SGreg Clayton                lines[-1] += ' ' * (comment_column - line_len)
5933c2c4bb2SGreg Clayton                lines[-1] += "; %s" % comment
5943c2c4bb2SGreg Clayton
5953c2c4bb2SGreg Clayton    if pc_index >= 0:
596b9c1b51eSKate Stone        # If we are disassembling the non-zeroeth frame, we need to backup the
597b9c1b51eSKate Stone        # PC by 1
5983c2c4bb2SGreg Clayton        if non_zeroeth_frame and pc_index > 0:
5993c2c4bb2SGreg Clayton            pc_index = pc_index - 1
6003c2c4bb2SGreg Clayton        if insts_before_pc == -1:
6013c2c4bb2SGreg Clayton            start_idx = 0
6023c2c4bb2SGreg Clayton        else:
6033c2c4bb2SGreg Clayton            start_idx = pc_index - insts_before_pc
6043c2c4bb2SGreg Clayton        if start_idx < 0:
6053c2c4bb2SGreg Clayton            start_idx = 0
6063c2c4bb2SGreg Clayton        if insts_before_pc == -1:
6073c2c4bb2SGreg Clayton            end_idx = inst_idx
6083c2c4bb2SGreg Clayton        else:
6093c2c4bb2SGreg Clayton            end_idx = pc_index + insts_after_pc
6103c2c4bb2SGreg Clayton        if end_idx > inst_idx:
6113c2c4bb2SGreg Clayton            end_idx = inst_idx
6123c2c4bb2SGreg Clayton        for i in range(start_idx, end_idx + 1):
6133c2c4bb2SGreg Clayton            if i == pc_index:
614a658ab9fSDavide Italiano                print(' -> ', lines[i])
6153c2c4bb2SGreg Clayton            else:
616a658ab9fSDavide Italiano                print('    ', lines[i])
6173c2c4bb2SGreg Clayton
618b9c1b51eSKate Stone
6193c2c4bb2SGreg Claytondef print_module_section_data(section):
620a658ab9fSDavide Italiano    print(section)
6213c2c4bb2SGreg Clayton    section_data = section.GetSectionData()
6223c2c4bb2SGreg Clayton    if section_data:
6233c2c4bb2SGreg Clayton        ostream = lldb.SBStream()
6243c2c4bb2SGreg Clayton        section_data.GetDescription(ostream, section.GetFileAddress())
625a658ab9fSDavide Italiano        print(ostream.GetData())
6263c2c4bb2SGreg Clayton
627b9c1b51eSKate Stone
6283c2c4bb2SGreg Claytondef print_module_section(section, depth):
629a658ab9fSDavide Italiano    print(section)
6303c2c4bb2SGreg Clayton    if depth > 0:
6313c2c4bb2SGreg Clayton        num_sub_sections = section.GetNumSubSections()
6323c2c4bb2SGreg Clayton        for sect_idx in range(num_sub_sections):
633b9c1b51eSKate Stone            print_module_section(
634b9c1b51eSKate Stone                section.GetSubSectionAtIndex(sect_idx), depth - 1)
635b9c1b51eSKate Stone
6363c2c4bb2SGreg Clayton
6373c2c4bb2SGreg Claytondef print_module_sections(module, depth):
6383c2c4bb2SGreg Clayton    for sect in module.section_iter():
6393c2c4bb2SGreg Clayton        print_module_section(sect, depth)
6403c2c4bb2SGreg Clayton
641b9c1b51eSKate Stone
6423c2c4bb2SGreg Claytondef print_module_symbols(module):
6433c2c4bb2SGreg Clayton    for sym in module:
644a658ab9fSDavide Italiano        print(sym)
6453c2c4bb2SGreg Clayton
646b9c1b51eSKate Stone
647c29c24beSJonas Devliegheredef Symbolicate(debugger, command_args):
6483c2c4bb2SGreg Clayton
6493c2c4bb2SGreg Clayton    usage = "usage: %prog [options] <addr1> [addr2 ...]"
6503c2c4bb2SGreg Clayton    description = '''Symbolicate one or more addresses using LLDB's python scripting API..'''
651b9c1b51eSKate Stone    parser = optparse.OptionParser(
652b9c1b51eSKate Stone        description=description,
653b9c1b51eSKate Stone        prog='crashlog.py',
654b9c1b51eSKate Stone        usage=usage)
655b9c1b51eSKate Stone    parser.add_option(
656b9c1b51eSKate Stone        '-v',
657b9c1b51eSKate Stone        '--verbose',
658b9c1b51eSKate Stone        action='store_true',
659b9c1b51eSKate Stone        dest='verbose',
660b9c1b51eSKate Stone        help='display verbose debug info',
661b9c1b51eSKate Stone        default=False)
662b9c1b51eSKate Stone    parser.add_option(
663b9c1b51eSKate Stone        '-p',
664b9c1b51eSKate Stone        '--platform',
665b9c1b51eSKate Stone        type='string',
666b9c1b51eSKate Stone        metavar='platform',
667b9c1b51eSKate Stone        dest='platform',
668b9c1b51eSKate Stone        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".')
669b9c1b51eSKate Stone    parser.add_option(
670b9c1b51eSKate Stone        '-f',
671b9c1b51eSKate Stone        '--file',
672b9c1b51eSKate Stone        type='string',
673b9c1b51eSKate Stone        metavar='file',
674b9c1b51eSKate Stone        dest='file',
675b9c1b51eSKate Stone        help='Specify a file to use when symbolicating')
676b9c1b51eSKate Stone    parser.add_option(
677b9c1b51eSKate Stone        '-a',
678b9c1b51eSKate Stone        '--arch',
679b9c1b51eSKate Stone        type='string',
680b9c1b51eSKate Stone        metavar='arch',
681b9c1b51eSKate Stone        dest='arch',
682b9c1b51eSKate Stone        help='Specify a architecture to use when symbolicating')
683b9c1b51eSKate Stone    parser.add_option(
684b9c1b51eSKate Stone        '-s',
685b9c1b51eSKate Stone        '--slide',
686b9c1b51eSKate Stone        type='int',
687b9c1b51eSKate Stone        metavar='slide',
688b9c1b51eSKate Stone        dest='slide',
689b9c1b51eSKate Stone        help='Specify the slide to use on the file specified with the --file option',
690b9c1b51eSKate Stone        default=None)
691b9c1b51eSKate Stone    parser.add_option(
692b9c1b51eSKate Stone        '--section',
693b9c1b51eSKate Stone        type='string',
694b9c1b51eSKate Stone        action='append',
695b9c1b51eSKate Stone        dest='section_strings',
696b9c1b51eSKate Stone        help='specify <sect-name>=<start-addr> or <sect-name>=<start-addr>-<end-addr>')
6973c2c4bb2SGreg Clayton    try:
6983c2c4bb2SGreg Clayton        (options, args) = parser.parse_args(command_args)
6993c2c4bb2SGreg Clayton    except:
7003c2c4bb2SGreg Clayton        return
701c29c24beSJonas Devlieghere    symbolicator = Symbolicator(debugger)
702b9c1b51eSKate Stone    images = list()
7033c2c4bb2SGreg Clayton    if options.file:
704b9c1b51eSKate Stone        image = Image(options.file)
7053c2c4bb2SGreg Clayton        image.arch = options.arch
706b9c1b51eSKate Stone        # Add any sections that were specified with one or more --section
707b9c1b51eSKate Stone        # options
7083c2c4bb2SGreg Clayton        if options.section_strings:
7093c2c4bb2SGreg Clayton            for section_str in options.section_strings:
7103c2c4bb2SGreg Clayton                section = Section()
7113c2c4bb2SGreg Clayton                if section.set_from_string(section_str):
7123c2c4bb2SGreg Clayton                    image.add_section(section)
7133c2c4bb2SGreg Clayton                else:
7143c2c4bb2SGreg Clayton                    sys.exit(1)
715b9c1b51eSKate Stone        if options.slide is not None:
7163c2c4bb2SGreg Clayton            image.slide = options.slide
7173c2c4bb2SGreg Clayton        symbolicator.images.append(image)
7183c2c4bb2SGreg Clayton
7193c2c4bb2SGreg Clayton    target = symbolicator.create_target()
7203c2c4bb2SGreg Clayton    if options.verbose:
721a658ab9fSDavide Italiano        print(symbolicator)
7223c2c4bb2SGreg Clayton    if target:
7233c2c4bb2SGreg Clayton        for addr_str in args:
7243c2c4bb2SGreg Clayton            addr = int(addr_str, 0)
725b9c1b51eSKate Stone            symbolicated_addrs = symbolicator.symbolicate(
726b9c1b51eSKate Stone                addr, options.verbose)
7273c2c4bb2SGreg Clayton            for symbolicated_addr in symbolicated_addrs:
728a658ab9fSDavide Italiano                print(symbolicated_addr)
729a658ab9fSDavide Italiano            print()
7303c2c4bb2SGreg Clayton    else:
731a658ab9fSDavide Italiano        print('error: no target for %s' % (symbolicator))
7323c2c4bb2SGreg Clayton
7333c2c4bb2SGreg Claytonif __name__ == '__main__':
7343c2c4bb2SGreg Clayton    # Create a new debugger instance
735c29c24beSJonas Devlieghere    debugger = lldb.SBDebugger.Create()
736c29c24beSJonas Devlieghere    Symbolicate(debugger, sys.argv[1:])
737c29c24beSJonas Devlieghere    SBDebugger.Destroy(debugger)
738