You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
99 lines
3.4 KiB
99 lines
3.4 KiB
4 months ago
|
# 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))))
|