1*515bc8c1Sserge-sans-paille#!/usr/bin/env python
26ee38046SSerge Gueltonfrom __future__ import print_function
3994ba647SGreg Clayton
4994ba647SGreg Claytonimport lldb
5994ba647SGreg Claytonimport shlex
6994ba647SGreg Claytonimport sys
76ee38046SSerge Gueltontry:
86ee38046SSerge Guelton    from tkinter import *
96ee38046SSerge Guelton    import tkinter.ttk as ttk
106ee38046SSerge Gueltonexcept ImportError:
11994ba647SGreg Clayton    from Tkinter import *
12994ba647SGreg Clayton    import ttk
13994ba647SGreg Clayton
14b9c1b51eSKate Stone
152f547177SGreg Claytonclass ValueTreeItemDelegate(object):
16b9c1b51eSKate Stone
172f547177SGreg Clayton    def __init__(self, value):
182f547177SGreg Clayton        self.value = value
19994ba647SGreg Clayton
202f547177SGreg Clayton    def get_item_dictionary(self):
212f547177SGreg Clayton        name = self.value.name
22994ba647SGreg Clayton        if name is None:
23994ba647SGreg Clayton            name = ''
242f547177SGreg Clayton        typename = self.value.type
25994ba647SGreg Clayton        if typename is None:
26994ba647SGreg Clayton            typename = ''
272f547177SGreg Clayton        value = self.value.value
28994ba647SGreg Clayton        if value is None:
29994ba647SGreg Clayton            value = ''
302f547177SGreg Clayton        summary = self.value.summary
31994ba647SGreg Clayton        if summary is None:
32994ba647SGreg Clayton            summary = ''
332f547177SGreg Clayton        has_children = self.value.MightHaveChildren()
342f547177SGreg Clayton        return {'#0': name,
352f547177SGreg Clayton                'typename': typename,
362f547177SGreg Clayton                'value': value,
372f547177SGreg Clayton                'summary': summary,
382f547177SGreg Clayton                'children': has_children,
392f547177SGreg Clayton                'tree-item-delegate': self}
40994ba647SGreg Clayton
412f547177SGreg Clayton    def get_child_item_dictionaries(self):
42994ba647SGreg Clayton        item_dicts = list()
432f547177SGreg Clayton        for i in range(self.value.num_children):
44b9c1b51eSKate Stone            item_delegate = ValueTreeItemDelegate(
45b9c1b51eSKate Stone                self.value.GetChildAtIndex(i))
462f547177SGreg Clayton            item_dicts.append(item_delegate.get_item_dictionary())
47994ba647SGreg Clayton        return item_dicts
48994ba647SGreg Clayton
49b9c1b51eSKate Stone
502f547177SGreg Claytonclass FrameTreeItemDelegate(object):
51b9c1b51eSKate Stone
52994ba647SGreg Clayton    def __init__(self, frame):
53994ba647SGreg Clayton        self.frame = frame
54994ba647SGreg Clayton
552f547177SGreg Clayton    def get_item_dictionary(self):
562f547177SGreg Clayton        id = self.frame.GetFrameID()
57b9c1b51eSKate Stone        name = 'frame #%u' % (id)
582f547177SGreg Clayton        value = '0x%16.16x' % (self.frame.GetPC())
592f547177SGreg Clayton        stream = lldb.SBStream()
602f547177SGreg Clayton        self.frame.GetDescription(stream)
612f547177SGreg Clayton        summary = stream.GetData().split("`")[1]
62b9c1b51eSKate Stone        return {
63b9c1b51eSKate Stone            '#0': name,
642f547177SGreg Clayton            'value': value,
652f547177SGreg Clayton            'summary': summary,
66b9c1b51eSKate Stone            'children': self.frame.GetVariables(
67b9c1b51eSKate Stone                True,
68b9c1b51eSKate Stone                True,
69b9c1b51eSKate Stone                True,
70b9c1b51eSKate Stone                True).GetSize() > 0,
712f547177SGreg Clayton            'tree-item-delegate': self}
72994ba647SGreg Clayton
732f547177SGreg Clayton    def get_child_item_dictionaries(self):
74994ba647SGreg Clayton        item_dicts = list()
75994ba647SGreg Clayton        variables = self.frame.GetVariables(True, True, True, True)
76994ba647SGreg Clayton        n = variables.GetSize()
77994ba647SGreg Clayton        for i in range(n):
782f547177SGreg Clayton            item_delegate = ValueTreeItemDelegate(variables[i])
792f547177SGreg Clayton            item_dicts.append(item_delegate.get_item_dictionary())
80994ba647SGreg Clayton        return item_dicts
81994ba647SGreg Clayton
82b9c1b51eSKate Stone
832f547177SGreg Claytonclass ThreadTreeItemDelegate(object):
84b9c1b51eSKate Stone
852f547177SGreg Clayton    def __init__(self, thread):
862f547177SGreg Clayton        self.thread = thread
872f547177SGreg Clayton
882f547177SGreg Clayton    def get_item_dictionary(self):
892f547177SGreg Clayton        num_frames = self.thread.GetNumFrames()
902f547177SGreg Clayton        name = 'thread #%u' % (self.thread.GetIndexID())
912f547177SGreg Clayton        value = '0x%x' % (self.thread.GetThreadID())
922f547177SGreg Clayton        summary = '%u frames' % (num_frames)
932f547177SGreg Clayton        return {'#0': name,
942f547177SGreg Clayton                'value': value,
952f547177SGreg Clayton                'summary': summary,
962f547177SGreg Clayton                'children': num_frames > 0,
972f547177SGreg Clayton                'tree-item-delegate': self}
982f547177SGreg Clayton
992f547177SGreg Clayton    def get_child_item_dictionaries(self):
1002f547177SGreg Clayton        item_dicts = list()
1012f547177SGreg Clayton        for frame in self.thread:
1022f547177SGreg Clayton            item_delegate = FrameTreeItemDelegate(frame)
1032f547177SGreg Clayton            item_dicts.append(item_delegate.get_item_dictionary())
1042f547177SGreg Clayton        return item_dicts
1052f547177SGreg Clayton
106b9c1b51eSKate Stone
1072f547177SGreg Claytonclass ProcessTreeItemDelegate(object):
108b9c1b51eSKate Stone
1092f547177SGreg Clayton    def __init__(self, process):
1102f547177SGreg Clayton        self.process = process
1112f547177SGreg Clayton
1122f547177SGreg Clayton    def get_item_dictionary(self):
1132f547177SGreg Clayton        id = self.process.GetProcessID()
1142f547177SGreg Clayton        num_threads = self.process.GetNumThreads()
1152f547177SGreg Clayton        value = str(self.process.GetProcessID())
1162f547177SGreg Clayton        summary = self.process.target.executable.fullpath
1172f547177SGreg Clayton        return {'#0': 'process',
1182f547177SGreg Clayton                'value': value,
1192f547177SGreg Clayton                'summary': summary,
1202f547177SGreg Clayton                'children': num_threads > 0,
1212f547177SGreg Clayton                'tree-item-delegate': self}
1222f547177SGreg Clayton
1232f547177SGreg Clayton    def get_child_item_dictionaries(self):
1242f547177SGreg Clayton        item_dicts = list()
1252f547177SGreg Clayton        for thread in self.process:
1262f547177SGreg Clayton            item_delegate = ThreadTreeItemDelegate(thread)
1272f547177SGreg Clayton            item_dicts.append(item_delegate.get_item_dictionary())
1282f547177SGreg Clayton        return item_dicts
1292f547177SGreg Clayton
130b9c1b51eSKate Stone
1312f547177SGreg Claytonclass TargetTreeItemDelegate(object):
132b9c1b51eSKate Stone
1332f547177SGreg Clayton    def __init__(self, target):
1342f547177SGreg Clayton        self.target = target
1352f547177SGreg Clayton
1362f547177SGreg Clayton    def get_item_dictionary(self):
1372f547177SGreg Clayton        value = str(self.target.triple)
1382f547177SGreg Clayton        summary = self.target.executable.fullpath
1392f547177SGreg Clayton        return {'#0': 'target',
1402f547177SGreg Clayton                'value': value,
1412f547177SGreg Clayton                'summary': summary,
1422f547177SGreg Clayton                'children': True,
1432f547177SGreg Clayton                'tree-item-delegate': self}
1442f547177SGreg Clayton
1452f547177SGreg Clayton    def get_child_item_dictionaries(self):
1462f547177SGreg Clayton        item_dicts = list()
1472f547177SGreg Clayton        image_item_delegate = TargetImagesTreeItemDelegate(self.target)
1482f547177SGreg Clayton        item_dicts.append(image_item_delegate.get_item_dictionary())
1492f547177SGreg Clayton        return item_dicts
1502f547177SGreg Clayton
151b9c1b51eSKate Stone
1522f547177SGreg Claytonclass TargetImagesTreeItemDelegate(object):
153b9c1b51eSKate Stone
1542f547177SGreg Clayton    def __init__(self, target):
1552f547177SGreg Clayton        self.target = target
1562f547177SGreg Clayton
1572f547177SGreg Clayton    def get_item_dictionary(self):
1582f547177SGreg Clayton        value = str(self.target.triple)
1592f547177SGreg Clayton        summary = self.target.executable.fullpath
1602f547177SGreg Clayton        num_modules = self.target.GetNumModules()
1612f547177SGreg Clayton        return {'#0': 'images',
1622f547177SGreg Clayton                'value': '',
1632f547177SGreg Clayton                'summary': '%u images' % num_modules,
1642f547177SGreg Clayton                'children': num_modules > 0,
1652f547177SGreg Clayton                'tree-item-delegate': self}
1662f547177SGreg Clayton
1672f547177SGreg Clayton    def get_child_item_dictionaries(self):
1682f547177SGreg Clayton        item_dicts = list()
1692f547177SGreg Clayton        for i in range(self.target.GetNumModules()):
1702f547177SGreg Clayton            module = self.target.GetModuleAtIndex(i)
171b9c1b51eSKate Stone            image_item_delegate = ModuleTreeItemDelegate(
172b9c1b51eSKate Stone                self.target, module, i)
1732f547177SGreg Clayton            item_dicts.append(image_item_delegate.get_item_dictionary())
1742f547177SGreg Clayton        return item_dicts
1752f547177SGreg Clayton
176b9c1b51eSKate Stone
1772f547177SGreg Claytonclass ModuleTreeItemDelegate(object):
178b9c1b51eSKate Stone
1792f547177SGreg Clayton    def __init__(self, target, module, index):
1802f547177SGreg Clayton        self.target = target
1812f547177SGreg Clayton        self.module = module
1822f547177SGreg Clayton        self.index = index
1832f547177SGreg Clayton
1842f547177SGreg Clayton    def get_item_dictionary(self):
1852f547177SGreg Clayton        name = 'module %u' % (self.index)
1862f547177SGreg Clayton        value = self.module.file.basename
1872f547177SGreg Clayton        summary = self.module.file.dirname
1882f547177SGreg Clayton        return {'#0': name,
1892f547177SGreg Clayton                'value': value,
1902f547177SGreg Clayton                'summary': summary,
1912f547177SGreg Clayton                'children': True,
1922f547177SGreg Clayton                'tree-item-delegate': self}
1932f547177SGreg Clayton
1942f547177SGreg Clayton    def get_child_item_dictionaries(self):
1952f547177SGreg Clayton        item_dicts = list()
196b9c1b51eSKate Stone        sections_item_delegate = ModuleSectionsTreeItemDelegate(
197b9c1b51eSKate Stone            self.target, self.module)
1982f547177SGreg Clayton        item_dicts.append(sections_item_delegate.get_item_dictionary())
1992f547177SGreg Clayton
200b9c1b51eSKate Stone        symbols_item_delegate = ModuleSymbolsTreeItemDelegate(
201b9c1b51eSKate Stone            self.target, self.module)
2022f547177SGreg Clayton        item_dicts.append(symbols_item_delegate.get_item_dictionary())
2032f547177SGreg Clayton
204b9c1b51eSKate Stone        comp_units_item_delegate = ModuleCompileUnitsTreeItemDelegate(
205b9c1b51eSKate Stone            self.target, self.module)
2062f547177SGreg Clayton        item_dicts.append(comp_units_item_delegate.get_item_dictionary())
2072f547177SGreg Clayton        return item_dicts
2082f547177SGreg Clayton
209b9c1b51eSKate Stone
2102f547177SGreg Claytonclass ModuleSectionsTreeItemDelegate(object):
211b9c1b51eSKate Stone
2122f547177SGreg Clayton    def __init__(self, target, module):
2132f547177SGreg Clayton        self.target = target
2142f547177SGreg Clayton        self.module = module
2152f547177SGreg Clayton
2162f547177SGreg Clayton    def get_item_dictionary(self):
2172f547177SGreg Clayton        name = 'sections'
2182f547177SGreg Clayton        value = ''
2192f547177SGreg Clayton        summary = '%u sections' % (self.module.GetNumSections())
2202f547177SGreg Clayton        return {'#0': name,
2212f547177SGreg Clayton                'value': value,
2222f547177SGreg Clayton                'summary': summary,
2232f547177SGreg Clayton                'children': True,
2242f547177SGreg Clayton                'tree-item-delegate': self}
2252f547177SGreg Clayton
2262f547177SGreg Clayton    def get_child_item_dictionaries(self):
2272f547177SGreg Clayton        item_dicts = list()
2282f547177SGreg Clayton        num_sections = self.module.GetNumSections()
2292f547177SGreg Clayton        for i in range(num_sections):
2302f547177SGreg Clayton            section = self.module.GetSectionAtIndex(i)
2312f547177SGreg Clayton            image_item_delegate = SectionTreeItemDelegate(self.target, section)
2322f547177SGreg Clayton            item_dicts.append(image_item_delegate.get_item_dictionary())
2332f547177SGreg Clayton        return item_dicts
2342f547177SGreg Clayton
235b9c1b51eSKate Stone
2362f547177SGreg Claytonclass SectionTreeItemDelegate(object):
237b9c1b51eSKate Stone
2382f547177SGreg Clayton    def __init__(self, target, section):
2392f547177SGreg Clayton        self.target = target
2402f547177SGreg Clayton        self.section = section
2412f547177SGreg Clayton
2422f547177SGreg Clayton    def get_item_dictionary(self):
2432f547177SGreg Clayton        name = self.section.name
2442f547177SGreg Clayton        section_load_addr = self.section.GetLoadAddress(self.target)
2452f547177SGreg Clayton        if section_load_addr != lldb.LLDB_INVALID_ADDRESS:
2462f547177SGreg Clayton            value = '0x%16.16x' % (section_load_addr)
2472f547177SGreg Clayton        else:
2482f547177SGreg Clayton            value = '0x%16.16x *' % (self.section.file_addr)
2492f547177SGreg Clayton        summary = ''
2502f547177SGreg Clayton        return {'#0': name,
2512f547177SGreg Clayton                'value': value,
2522f547177SGreg Clayton                'summary': summary,
2532f547177SGreg Clayton                'children': self.section.GetNumSubSections() > 0,
2542f547177SGreg Clayton                'tree-item-delegate': self}
2552f547177SGreg Clayton
2562f547177SGreg Clayton    def get_child_item_dictionaries(self):
2572f547177SGreg Clayton        item_dicts = list()
2582f547177SGreg Clayton        num_sections = self.section.GetNumSubSections()
2592f547177SGreg Clayton        for i in range(num_sections):
2602f547177SGreg Clayton            section = self.section.GetSubSectionAtIndex(i)
2612f547177SGreg Clayton            image_item_delegate = SectionTreeItemDelegate(self.target, section)
2622f547177SGreg Clayton            item_dicts.append(image_item_delegate.get_item_dictionary())
2632f547177SGreg Clayton        return item_dicts
2642f547177SGreg Clayton
265b9c1b51eSKate Stone
2662f547177SGreg Claytonclass ModuleCompileUnitsTreeItemDelegate(object):
267b9c1b51eSKate Stone
2682f547177SGreg Clayton    def __init__(self, target, module):
2692f547177SGreg Clayton        self.target = target
2702f547177SGreg Clayton        self.module = module
2712f547177SGreg Clayton
2722f547177SGreg Clayton    def get_item_dictionary(self):
2732f547177SGreg Clayton        name = 'compile units'
2742f547177SGreg Clayton        value = ''
2752f547177SGreg Clayton        summary = '%u compile units' % (self.module.GetNumSections())
2762f547177SGreg Clayton        return {'#0': name,
2772f547177SGreg Clayton                'value': value,
2782f547177SGreg Clayton                'summary': summary,
2792f547177SGreg Clayton                'children': self.module.GetNumCompileUnits() > 0,
2802f547177SGreg Clayton                'tree-item-delegate': self}
2812f547177SGreg Clayton
2822f547177SGreg Clayton    def get_child_item_dictionaries(self):
2832f547177SGreg Clayton        item_dicts = list()
2842f547177SGreg Clayton        num_cus = self.module.GetNumCompileUnits()
2852f547177SGreg Clayton        for i in range(num_cus):
2862f547177SGreg Clayton            cu = self.module.GetCompileUnitAtIndex(i)
2872f547177SGreg Clayton            image_item_delegate = CompileUnitTreeItemDelegate(self.target, cu)
2882f547177SGreg Clayton            item_dicts.append(image_item_delegate.get_item_dictionary())
2892f547177SGreg Clayton        return item_dicts
2902f547177SGreg Clayton
291b9c1b51eSKate Stone
2922f547177SGreg Claytonclass CompileUnitTreeItemDelegate(object):
293b9c1b51eSKate Stone
2942f547177SGreg Clayton    def __init__(self, target, cu):
2952f547177SGreg Clayton        self.target = target
2962f547177SGreg Clayton        self.cu = cu
2972f547177SGreg Clayton
2982f547177SGreg Clayton    def get_item_dictionary(self):
2992f547177SGreg Clayton        name = self.cu.GetFileSpec().basename
3002f547177SGreg Clayton        value = ''
3012f547177SGreg Clayton        num_lines = self.cu.GetNumLineEntries()
3022f547177SGreg Clayton        summary = ''
3032f547177SGreg Clayton        return {'#0': name,
3042f547177SGreg Clayton                'value': value,
3052f547177SGreg Clayton                'summary': summary,
3062f547177SGreg Clayton                'children': num_lines > 0,
3072f547177SGreg Clayton                'tree-item-delegate': self}
3082f547177SGreg Clayton
3092f547177SGreg Clayton    def get_child_item_dictionaries(self):
3102f547177SGreg Clayton        item_dicts = list()
3112f547177SGreg Clayton        item_delegate = LineTableTreeItemDelegate(self.target, self.cu)
3122f547177SGreg Clayton        item_dicts.append(item_delegate.get_item_dictionary())
3132f547177SGreg Clayton        return item_dicts
3142f547177SGreg Clayton
315b9c1b51eSKate Stone
3162f547177SGreg Claytonclass LineTableTreeItemDelegate(object):
317b9c1b51eSKate Stone
3182f547177SGreg Clayton    def __init__(self, target, cu):
3192f547177SGreg Clayton        self.target = target
3202f547177SGreg Clayton        self.cu = cu
3212f547177SGreg Clayton
3222f547177SGreg Clayton    def get_item_dictionary(self):
3232f547177SGreg Clayton        name = 'line table'
3242f547177SGreg Clayton        value = ''
3252f547177SGreg Clayton        num_lines = self.cu.GetNumLineEntries()
3262f547177SGreg Clayton        summary = '%u line entries' % (num_lines)
3272f547177SGreg Clayton        return {'#0': name,
3282f547177SGreg Clayton                'value': value,
3292f547177SGreg Clayton                'summary': summary,
3302f547177SGreg Clayton                'children': num_lines > 0,
3312f547177SGreg Clayton                'tree-item-delegate': self}
3322f547177SGreg Clayton
3332f547177SGreg Clayton    def get_child_item_dictionaries(self):
3342f547177SGreg Clayton        item_dicts = list()
3352f547177SGreg Clayton        num_lines = self.cu.GetNumLineEntries()
3362f547177SGreg Clayton        for i in range(num_lines):
3372f547177SGreg Clayton            line_entry = self.cu.GetLineEntryAtIndex(i)
338b9c1b51eSKate Stone            item_delegate = LineEntryTreeItemDelegate(
339b9c1b51eSKate Stone                self.target, line_entry, i)
3402f547177SGreg Clayton            item_dicts.append(item_delegate.get_item_dictionary())
3412f547177SGreg Clayton        return item_dicts
3422f547177SGreg Clayton
343b9c1b51eSKate Stone
3442f547177SGreg Claytonclass LineEntryTreeItemDelegate(object):
345b9c1b51eSKate Stone
3462f547177SGreg Clayton    def __init__(self, target, line_entry, index):
3472f547177SGreg Clayton        self.target = target
3482f547177SGreg Clayton        self.line_entry = line_entry
3492f547177SGreg Clayton        self.index = index
3502f547177SGreg Clayton
3512f547177SGreg Clayton    def get_item_dictionary(self):
3522f547177SGreg Clayton        name = str(self.index)
3532f547177SGreg Clayton        address = self.line_entry.GetStartAddress()
3542f547177SGreg Clayton        load_addr = address.GetLoadAddress(self.target)
3552f547177SGreg Clayton        if load_addr != lldb.LLDB_INVALID_ADDRESS:
3562f547177SGreg Clayton            value = '0x%16.16x' % (load_addr)
3572f547177SGreg Clayton        else:
3582f547177SGreg Clayton            value = '0x%16.16x *' % (address.file_addr)
359b9c1b51eSKate Stone        summary = self.line_entry.GetFileSpec().fullpath + ':' + \
360b9c1b51eSKate Stone            str(self.line_entry.line)
3612f547177SGreg Clayton        return {'#0': name,
3622f547177SGreg Clayton                'value': value,
3632f547177SGreg Clayton                'summary': summary,
3642f547177SGreg Clayton                'children': False,
3652f547177SGreg Clayton                'tree-item-delegate': self}
3662f547177SGreg Clayton
3672f547177SGreg Clayton    def get_child_item_dictionaries(self):
3682f547177SGreg Clayton        item_dicts = list()
3692f547177SGreg Clayton        return item_dicts
3702f547177SGreg Clayton
371b9c1b51eSKate Stone
3722f547177SGreg Claytonclass InstructionTreeItemDelegate(object):
373b9c1b51eSKate Stone
3742f547177SGreg Clayton    def __init__(self, target, instr):
3752f547177SGreg Clayton        self.target = target
3762f547177SGreg Clayton        self.instr = instr
3772f547177SGreg Clayton
3782f547177SGreg Clayton    def get_item_dictionary(self):
3792f547177SGreg Clayton        address = self.instr.GetAddress()
3802f547177SGreg Clayton        load_addr = address.GetLoadAddress(self.target)
3812f547177SGreg Clayton        if load_addr != lldb.LLDB_INVALID_ADDRESS:
3822f547177SGreg Clayton            name = '0x%16.16x' % (load_addr)
3832f547177SGreg Clayton        else:
3842f547177SGreg Clayton            name = '0x%16.16x *' % (address.file_addr)
385b9c1b51eSKate Stone        value = self.instr.GetMnemonic(
386b9c1b51eSKate Stone            self.target) + ' ' + self.instr.GetOperands(self.target)
3872f547177SGreg Clayton        summary = self.instr.GetComment(self.target)
3882f547177SGreg Clayton        return {'#0': name,
3892f547177SGreg Clayton                'value': value,
3902f547177SGreg Clayton                'summary': summary,
3912f547177SGreg Clayton                'children': False,
3922f547177SGreg Clayton                'tree-item-delegate': self}
3932f547177SGreg Clayton
394b9c1b51eSKate Stone
3952f547177SGreg Claytonclass ModuleSymbolsTreeItemDelegate(object):
396b9c1b51eSKate Stone
3972f547177SGreg Clayton    def __init__(self, target, module):
3982f547177SGreg Clayton        self.target = target
3992f547177SGreg Clayton        self.module = module
4002f547177SGreg Clayton
4012f547177SGreg Clayton    def get_item_dictionary(self):
4022f547177SGreg Clayton        name = 'symbols'
4032f547177SGreg Clayton        value = ''
4042f547177SGreg Clayton        summary = '%u symbols' % (self.module.GetNumSymbols())
4052f547177SGreg Clayton        return {'#0': name,
4062f547177SGreg Clayton                'value': value,
4072f547177SGreg Clayton                'summary': summary,
4082f547177SGreg Clayton                'children': True,
4092f547177SGreg Clayton                'tree-item-delegate': self}
4102f547177SGreg Clayton
4112f547177SGreg Clayton    def get_child_item_dictionaries(self):
4122f547177SGreg Clayton        item_dicts = list()
4132f547177SGreg Clayton        num_symbols = self.module.GetNumSymbols()
4142f547177SGreg Clayton        for i in range(num_symbols):
4152f547177SGreg Clayton            symbol = self.module.GetSymbolAtIndex(i)
416b9c1b51eSKate Stone            image_item_delegate = SymbolTreeItemDelegate(
417b9c1b51eSKate Stone                self.target, symbol, i)
4182f547177SGreg Clayton            item_dicts.append(image_item_delegate.get_item_dictionary())
4192f547177SGreg Clayton        return item_dicts
4202f547177SGreg Clayton
421b9c1b51eSKate Stone
4222f547177SGreg Claytonclass SymbolTreeItemDelegate(object):
423b9c1b51eSKate Stone
4242f547177SGreg Clayton    def __init__(self, target, symbol, index):
4252f547177SGreg Clayton        self.target = target
4262f547177SGreg Clayton        self.symbol = symbol
4272f547177SGreg Clayton        self.index = index
4282f547177SGreg Clayton
4292f547177SGreg Clayton    def get_item_dictionary(self):
4302f547177SGreg Clayton        address = self.symbol.GetStartAddress()
4312f547177SGreg Clayton        name = '[%u]' % self.index
4322f547177SGreg Clayton        symbol_load_addr = address.GetLoadAddress(self.target)
4332f547177SGreg Clayton        if symbol_load_addr != lldb.LLDB_INVALID_ADDRESS:
4342f547177SGreg Clayton            value = '0x%16.16x' % (symbol_load_addr)
4352f547177SGreg Clayton        else:
4362f547177SGreg Clayton            value = '0x%16.16x *' % (address.file_addr)
4372f547177SGreg Clayton        summary = self.symbol.name
4382f547177SGreg Clayton        return {'#0': name,
4392f547177SGreg Clayton                'value': value,
4402f547177SGreg Clayton                'summary': summary,
4412f547177SGreg Clayton                'children': False,
4422f547177SGreg Clayton                'tree-item-delegate': self}
4432f547177SGreg Clayton
4442f547177SGreg Clayton    def get_child_item_dictionaries(self):
4452f547177SGreg Clayton        item_dicts = list()
4462f547177SGreg Clayton        return item_dicts
4472f547177SGreg Clayton
4482f547177SGreg Clayton
449994ba647SGreg Claytonclass DelegateTree(ttk.Frame):
450994ba647SGreg Clayton
4512f547177SGreg Clayton    def __init__(self, column_dicts, delegate, title, name):
452994ba647SGreg Clayton        ttk.Frame.__init__(self, name=name)
453994ba647SGreg Clayton        self.pack(expand=Y, fill=BOTH)
454994ba647SGreg Clayton        self.master.title(title)
455994ba647SGreg Clayton        self.delegate = delegate
4562f547177SGreg Clayton        self.columns_dicts = column_dicts
457994ba647SGreg Clayton        self.item_id_to_item_dict = dict()
458994ba647SGreg Clayton        frame = Frame(self)
459994ba647SGreg Clayton        frame.pack(side=TOP, fill=BOTH, expand=Y)
460994ba647SGreg Clayton        self._create_treeview(frame)
461994ba647SGreg Clayton        self._populate_root()
462994ba647SGreg Clayton
463994ba647SGreg Clayton    def _create_treeview(self, parent):
464994ba647SGreg Clayton        frame = ttk.Frame(parent)
465994ba647SGreg Clayton        frame.pack(side=TOP, fill=BOTH, expand=Y)
466994ba647SGreg Clayton
467994ba647SGreg Clayton        column_ids = list()
4682f547177SGreg Clayton        for i in range(1, len(self.columns_dicts)):
4692f547177SGreg Clayton            column_ids.append(self.columns_dicts[i]['id'])
470994ba647SGreg Clayton        # create the tree and scrollbars
471994ba647SGreg Clayton        self.tree = ttk.Treeview(columns=column_ids)
472994ba647SGreg Clayton
473994ba647SGreg Clayton        scroll_bar_v = ttk.Scrollbar(orient=VERTICAL, command=self.tree.yview)
474b9c1b51eSKate Stone        scroll_bar_h = ttk.Scrollbar(
475b9c1b51eSKate Stone            orient=HORIZONTAL, command=self.tree.xview)
476994ba647SGreg Clayton        self.tree['yscroll'] = scroll_bar_v.set
477994ba647SGreg Clayton        self.tree['xscroll'] = scroll_bar_h.set
478994ba647SGreg Clayton
479994ba647SGreg Clayton        # setup column headings and columns properties
4802f547177SGreg Clayton        for columns_dict in self.columns_dicts:
481b9c1b51eSKate Stone            self.tree.heading(
482b9c1b51eSKate Stone                columns_dict['id'],
483b9c1b51eSKate Stone                text=columns_dict['text'],
484b9c1b51eSKate Stone                anchor=columns_dict['anchor'])
485b9c1b51eSKate Stone            self.tree.column(
486b9c1b51eSKate Stone                columns_dict['id'],
487b9c1b51eSKate Stone                stretch=columns_dict['stretch'])
488994ba647SGreg Clayton
489994ba647SGreg Clayton        # add tree and scrollbars to frame
490994ba647SGreg Clayton        self.tree.grid(in_=frame, row=0, column=0, sticky=NSEW)
491994ba647SGreg Clayton        scroll_bar_v.grid(in_=frame, row=0, column=1, sticky=NS)
492994ba647SGreg Clayton        scroll_bar_h.grid(in_=frame, row=1, column=0, sticky=EW)
493994ba647SGreg Clayton
494994ba647SGreg Clayton        # set frame resizing priorities
495994ba647SGreg Clayton        frame.rowconfigure(0, weight=1)
496994ba647SGreg Clayton        frame.columnconfigure(0, weight=1)
497994ba647SGreg Clayton
498994ba647SGreg Clayton        # action to perform when a node is expanded
499994ba647SGreg Clayton        self.tree.bind('<<TreeviewOpen>>', self._update_tree)
500994ba647SGreg Clayton
501994ba647SGreg Clayton    def insert_items(self, parent_id, item_dicts):
502994ba647SGreg Clayton        for item_dict in item_dicts:
5032f547177SGreg Clayton            name = None
5042f547177SGreg Clayton            values = list()
5052f547177SGreg Clayton            first = True
5062f547177SGreg Clayton            for columns_dict in self.columns_dicts:
5072f547177SGreg Clayton                if first:
5082f547177SGreg Clayton                    name = item_dict[columns_dict['id']]
5092f547177SGreg Clayton                    first = False
5102f547177SGreg Clayton                else:
5112f547177SGreg Clayton                    values.append(item_dict[columns_dict['id']])
512994ba647SGreg Clayton            item_id = self.tree.insert(parent_id,  # root item has an empty name
513994ba647SGreg Clayton                                       END,
5142f547177SGreg Clayton                                       text=name,
5152f547177SGreg Clayton                                       values=values)
516994ba647SGreg Clayton            self.item_id_to_item_dict[item_id] = item_dict
517994ba647SGreg Clayton            if item_dict['children']:
518994ba647SGreg Clayton                self.tree.insert(item_id, END, text='dummy')
519994ba647SGreg Clayton
520994ba647SGreg Clayton    def _populate_root(self):
521994ba647SGreg Clayton        # use current directory as root node
5222f547177SGreg Clayton        self.insert_items('', self.delegate.get_child_item_dictionaries())
523994ba647SGreg Clayton
524994ba647SGreg Clayton    def _update_tree(self, event):
525994ba647SGreg Clayton        # user expanded a node - build the related directory
526994ba647SGreg Clayton        item_id = self.tree.focus()      # the id of the expanded node
527994ba647SGreg Clayton        children = self.tree.get_children(item_id)
528994ba647SGreg Clayton        if len(children):
529994ba647SGreg Clayton            first_child = children[0]
530994ba647SGreg Clayton            # if the node only has a 'dummy' child, remove it and
531994ba647SGreg Clayton            # build new directory; skip if the node is already
532994ba647SGreg Clayton            # populated
533994ba647SGreg Clayton            if self.tree.item(first_child, option='text') == 'dummy':
534994ba647SGreg Clayton                self.tree.delete(first_child)
5352f547177SGreg Clayton                item_dict = self.item_id_to_item_dict[item_id]
536b9c1b51eSKate Stone                item_dicts = item_dict[
537b9c1b51eSKate Stone                    'tree-item-delegate'].get_child_item_dictionaries()
538994ba647SGreg Clayton                self.insert_items(item_id, item_dicts)
539994ba647SGreg Clayton
540b9c1b51eSKate Stone
541994ba647SGreg Clayton@lldb.command("tk-variables")
542994ba647SGreg Claytondef tk_variable_display(debugger, command, result, dict):
543b9c1b51eSKate Stone    # needed for tree creation in TK library as it uses sys.argv...
544b9c1b51eSKate Stone    sys.argv = ['tk-variables']
545994ba647SGreg Clayton    target = debugger.GetSelectedTarget()
546994ba647SGreg Clayton    if not target:
547525cd59fSSerge Guelton        print("invalid target", file=result)
548994ba647SGreg Clayton        return
549994ba647SGreg Clayton    process = target.GetProcess()
550994ba647SGreg Clayton    if not process:
551525cd59fSSerge Guelton        print("invalid process", file=result)
552994ba647SGreg Clayton        return
553994ba647SGreg Clayton    thread = process.GetSelectedThread()
554994ba647SGreg Clayton    if not thread:
555525cd59fSSerge Guelton        print("invalid thread", file=result)
556994ba647SGreg Clayton        return
557994ba647SGreg Clayton    frame = thread.GetSelectedFrame()
558994ba647SGreg Clayton    if not frame:
559525cd59fSSerge Guelton        print("invalid frame", file=result)
560994ba647SGreg Clayton        return
561994ba647SGreg Clayton    # Parse command line args
562994ba647SGreg Clayton    command_args = shlex.split(command)
5632f547177SGreg Clayton    column_dicts = [{'id': '#0', 'text': 'Name', 'anchor': W, 'stretch': 0},
5642f547177SGreg Clayton                    {'id': 'typename', 'text': 'Type', 'anchor': W, 'stretch': 0},
5652f547177SGreg Clayton                    {'id': 'value', 'text': 'Value', 'anchor': W, 'stretch': 0},
5662f547177SGreg Clayton                    {'id': 'summary', 'text': 'Summary', 'anchor': W, 'stretch': 1}]
567b9c1b51eSKate Stone    tree = DelegateTree(
568b9c1b51eSKate Stone        column_dicts,
569b9c1b51eSKate Stone        FrameTreeItemDelegate(frame),
570b9c1b51eSKate Stone        'Variables',
571b9c1b51eSKate Stone        'lldb-tk-variables')
572994ba647SGreg Clayton    tree.mainloop()
573994ba647SGreg Clayton
574b9c1b51eSKate Stone
575994ba647SGreg Clayton@lldb.command("tk-process")
576994ba647SGreg Claytondef tk_process_display(debugger, command, result, dict):
577b9c1b51eSKate Stone    # needed for tree creation in TK library as it uses sys.argv...
578b9c1b51eSKate Stone    sys.argv = ['tk-process']
579994ba647SGreg Clayton    target = debugger.GetSelectedTarget()
580994ba647SGreg Clayton    if not target:
581525cd59fSSerge Guelton        print("invalid target", file=result)
582994ba647SGreg Clayton        return
583994ba647SGreg Clayton    process = target.GetProcess()
584994ba647SGreg Clayton    if not process:
585525cd59fSSerge Guelton        print("invalid process", file=result)
586994ba647SGreg Clayton        return
587994ba647SGreg Clayton    # Parse command line args
5882f547177SGreg Clayton    columnd_dicts = [{'id': '#0', 'text': 'Name', 'anchor': W, 'stretch': 0},
5892f547177SGreg Clayton                     {'id': 'value', 'text': 'Value', 'anchor': W, 'stretch': 0},
590b9c1b51eSKate Stone                     {'id': 'summary', 'text': 'Summary', 'anchor': W, 'stretch': 1}]
591994ba647SGreg Clayton    command_args = shlex.split(command)
592b9c1b51eSKate Stone    tree = DelegateTree(
593b9c1b51eSKate Stone        columnd_dicts,
594b9c1b51eSKate Stone        ProcessTreeItemDelegate(process),
595b9c1b51eSKate Stone        'Process',
596b9c1b51eSKate Stone        'lldb-tk-process')
5972f547177SGreg Clayton    tree.mainloop()
5982f547177SGreg Clayton
599b9c1b51eSKate Stone
6002f547177SGreg Clayton@lldb.command("tk-target")
6012f547177SGreg Claytondef tk_target_display(debugger, command, result, dict):
602b9c1b51eSKate Stone    # needed for tree creation in TK library as it uses sys.argv...
603b9c1b51eSKate Stone    sys.argv = ['tk-target']
6042f547177SGreg Clayton    target = debugger.GetSelectedTarget()
6052f547177SGreg Clayton    if not target:
606525cd59fSSerge Guelton        print("invalid target", file=result)
6072f547177SGreg Clayton        return
6082f547177SGreg Clayton    # Parse command line args
6092f547177SGreg Clayton    columnd_dicts = [{'id': '#0', 'text': 'Name', 'anchor': W, 'stretch': 0},
6102f547177SGreg Clayton                     {'id': 'value', 'text': 'Value', 'anchor': W, 'stretch': 0},
611b9c1b51eSKate Stone                     {'id': 'summary', 'text': 'Summary', 'anchor': W, 'stretch': 1}]
6122f547177SGreg Clayton    command_args = shlex.split(command)
613b9c1b51eSKate Stone    tree = DelegateTree(
614b9c1b51eSKate Stone        columnd_dicts,
615b9c1b51eSKate Stone        TargetTreeItemDelegate(target),
616b9c1b51eSKate Stone        'Target',
617b9c1b51eSKate Stone        'lldb-tk-target')
618994ba647SGreg Clayton    tree.mainloop()
619