xref: /llvm-project/cross-project-tests/debuginfo-tests/dexter/dex/debugger/dbgeng/symgroup.py (revision f98ee40f4b5d7474fc67e82824bf6abbaedb7b1c)
1# DExTer : Debugging Experience Tester
2# ~~~~~~   ~         ~~         ~   ~~
3#
4# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5# See https://llvm.org/LICENSE.txt for license information.
6# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7
8from collections import namedtuple
9from ctypes import *
10from functools import partial
11
12from .utils import *
13
14Symbol = namedtuple("Symbol", ["num", "name", "type", "value"])
15
16
17class IDebugSymbolGroup2(Structure):
18    pass
19
20
21class IDebugSymbolGroup2Vtbl(Structure):
22    wrp = partial(WINFUNCTYPE, c_long, POINTER(IDebugSymbolGroup2))
23    ids_getnumbersymbols = wrp(c_ulong_p)
24    ids_getsymbolname = wrp(c_ulong, c_char_p, c_ulong, c_ulong_p)
25    ids_getsymboltypename = wrp(c_ulong, c_char_p, c_ulong, c_ulong_p)
26    ids_getsymbolvaluetext = wrp(c_ulong, c_char_p, c_ulong, c_ulong_p)
27    _fields_ = [
28        ("QueryInterface", c_void_p),
29        ("AddRef", c_void_p),
30        ("Release", c_void_p),
31        ("GetNumberSymbols", ids_getnumbersymbols),
32        ("AddSymbol", c_void_p),
33        ("RemoveSymbolByName", c_void_p),
34        ("RemoveSymbolByIndex", c_void_p),
35        ("GetSymbolName", ids_getsymbolname),
36        ("GetSymbolParameters", c_void_p),
37        ("ExpandSymbol", c_void_p),
38        ("OutputSymbols", c_void_p),
39        ("WriteSymbol", c_void_p),
40        ("OutputAsType", c_void_p),
41        ("AddSymbolWide", c_void_p),
42        ("RemoveSymbolByNameWide", c_void_p),
43        ("GetSymbolNameWide", c_void_p),
44        ("WritesymbolWide", c_void_p),
45        ("OutputAsTypeWide", c_void_p),
46        ("GetSymbolTypeName", ids_getsymboltypename),
47        ("GetSymbolTypeNameWide", c_void_p),
48        ("GetSymbolSize", c_void_p),
49        ("GetSymbolOffset", c_void_p),
50        ("GetSymbolRegister", c_void_p),
51        ("GetSymbolValueText", ids_getsymbolvaluetext),
52        ("GetSymbolValueTextWide", c_void_p),
53        ("GetSymbolEntryInformation", c_void_p),
54    ]
55
56
57IDebugSymbolGroup2._fields_ = [("lpVtbl", POINTER(IDebugSymbolGroup2Vtbl))]
58
59
60class SymbolGroup(object):
61    def __init__(self, symgroup):
62        self.symgroup = symgroup.contents
63        self.vt = self.symgroup.lpVtbl.contents
64        self.ulong = c_ulong()
65
66    def GetNumberSymbols(self):
67        res = self.vt.GetNumberSymbols(self.symgroup, byref(self.ulong))
68        aborter(res, "GetNumberSymbols")
69        return self.ulong.value
70
71    def GetSymbolName(self, idx):
72        buf = create_string_buffer(256)
73        res = self.vt.GetSymbolName(self.symgroup, idx, buf, 255, byref(self.ulong))
74        aborter(res, "GetSymbolName")
75        thelen = self.ulong.value
76        return string_at(buf).decode("ascii")
77
78    def GetSymbolTypeName(self, idx):
79        buf = create_string_buffer(256)
80        res = self.vt.GetSymbolTypeName(self.symgroup, idx, buf, 255, byref(self.ulong))
81        aborter(res, "GetSymbolTypeName")
82        thelen = self.ulong.value
83        return string_at(buf).decode("ascii")
84
85    def GetSymbolValueText(self, idx, handleserror=False):
86        buf = create_string_buffer(256)
87        res = self.vt.GetSymbolValueText(
88            self.symgroup, idx, buf, 255, byref(self.ulong)
89        )
90        if res != 0 and handleserror:
91            return None
92        aborter(res, "GetSymbolTypeName")
93        thelen = self.ulong.value
94        return string_at(buf).decode("ascii")
95
96    def get_symbol(self, idx):
97        name = self.GetSymbolName(idx)
98        thetype = self.GetSymbolTypeName(idx)
99        value = self.GetSymbolValueText(idx)
100        return Symbol(idx, name, thetype, value)
101
102    def get_all_symbols(self):
103        num_syms = self.GetNumberSymbols()
104        return list(map(self.get_symbol, list(range(num_syms))))
105