105 lines · python
1# DExTer : Debugging Experience Tester2# ~~~~~~ ~ ~~ ~ ~~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-exception7 8from collections import namedtuple9from ctypes import *10from functools import partial11 12from .utils import *13 14Symbol = namedtuple("Symbol", ["num", "name", "type", "value"])15 16 17class IDebugSymbolGroup2(Structure):18 pass19 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.contents63 self.vt = self.symgroup.lpVtbl.contents64 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.value70 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.value76 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.value83 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 None92 aborter(res, "GetSymbolTypeName")93 thelen = self.ulong.value94 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