# DExTer : Debugging Experience Tester # ~~~~~~ ~ ~~ ~ ~~ # # Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. # See https://llvm.org/LICENSE.txt for license information. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception from collections import namedtuple from ctypes import * from functools import partial from .utils import * Symbol = namedtuple("Symbol", ["num", "name", "type", "value"]) class IDebugSymbolGroup2(Structure): pass class IDebugSymbolGroup2Vtbl(Structure): wrp = partial(WINFUNCTYPE, c_long, POINTER(IDebugSymbolGroup2)) ids_getnumbersymbols = wrp(c_ulong_p) ids_getsymbolname = wrp(c_ulong, c_char_p, c_ulong, c_ulong_p) ids_getsymboltypename = wrp(c_ulong, c_char_p, c_ulong, c_ulong_p) ids_getsymbolvaluetext = wrp(c_ulong, c_char_p, c_ulong, c_ulong_p) _fields_ = [ ("QueryInterface", c_void_p), ("AddRef", c_void_p), ("Release", c_void_p), ("GetNumberSymbols", ids_getnumbersymbols), ("AddSymbol", c_void_p), ("RemoveSymbolByName", c_void_p), ("RemoveSymbolByIndex", c_void_p), ("GetSymbolName", ids_getsymbolname), ("GetSymbolParameters", c_void_p), ("ExpandSymbol", c_void_p), ("OutputSymbols", c_void_p), ("WriteSymbol", c_void_p), ("OutputAsType", c_void_p), ("AddSymbolWide", c_void_p), ("RemoveSymbolByNameWide", c_void_p), ("GetSymbolNameWide", c_void_p), ("WritesymbolWide", c_void_p), ("OutputAsTypeWide", c_void_p), ("GetSymbolTypeName", ids_getsymboltypename), ("GetSymbolTypeNameWide", c_void_p), ("GetSymbolSize", c_void_p), ("GetSymbolOffset", c_void_p), ("GetSymbolRegister", c_void_p), ("GetSymbolValueText", ids_getsymbolvaluetext), ("GetSymbolValueTextWide", c_void_p), ("GetSymbolEntryInformation", c_void_p) ] IDebugSymbolGroup2._fields_ = [("lpVtbl", POINTER(IDebugSymbolGroup2Vtbl))] class SymbolGroup(object): def __init__(self, symgroup): self.symgroup = symgroup.contents self.vt = self.symgroup.lpVtbl.contents self.ulong = c_ulong() def GetNumberSymbols(self): res = self.vt.GetNumberSymbols(self.symgroup, byref(self.ulong)) aborter(res, "GetNumberSymbols") return self.ulong.value def GetSymbolName(self, idx): buf = create_string_buffer(256) res = self.vt.GetSymbolName(self.symgroup, idx, buf, 255, byref(self.ulong)) aborter(res, "GetSymbolName") thelen = self.ulong.value return string_at(buf).decode("ascii") def GetSymbolTypeName(self, idx): buf = create_string_buffer(256) res = self.vt.GetSymbolTypeName(self.symgroup, idx, buf, 255, byref(self.ulong)) aborter(res, "GetSymbolTypeName") thelen = self.ulong.value return string_at(buf).decode("ascii") def GetSymbolValueText(self, idx, handleserror=False): buf = create_string_buffer(256) res = self.vt.GetSymbolValueText(self.symgroup, idx, buf, 255, byref(self.ulong)) if res != 0 and handleserror: return None aborter(res, "GetSymbolTypeName") thelen = self.ulong.value return string_at(buf).decode("ascii") def get_symbol(self, idx): name = self.GetSymbolName(idx) thetype = self.GetSymbolTypeName(idx) value = self.GetSymbolValueText(idx) return Symbol(idx, name, thetype, value) def get_all_symbols(self): num_syms = self.GetNumberSymbols() return list(map(self.get_symbol, list(range(num_syms))))