brintos

brintos / llvm-project-archived public Read only

0
0
Text · 21.3 KiB · 8ba8fad Raw
607 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 enum import *11from functools import reduce, partial12 13from .symgroup import SymbolGroup, IDebugSymbolGroup214from .utils import *15 16 17class SymbolOptionFlags(IntFlag):18    SYMOPT_CASE_INSENSITIVE = 0x0000000119    SYMOPT_UNDNAME = 0x0000000220    SYMOPT_DEFERRED_LOADS = 0x0000000421    SYMOPT_NO_CPP = 0x0000000822    SYMOPT_LOAD_LINES = 0x0000001023    SYMOPT_OMAP_FIND_NEAREST = 0x0000002024    SYMOPT_LOAD_ANYTHING = 0x0000004025    SYMOPT_IGNORE_CVREC = 0x0000008026    SYMOPT_NO_UNQUALIFIED_LOADS = 0x0000010027    SYMOPT_FAIL_CRITICAL_ERRORS = 0x0000020028    SYMOPT_EXACT_SYMBOLS = 0x0000040029    SYMOPT_ALLOW_ABSOLUTE_SYMBOLS = 0x0000080030    SYMOPT_IGNORE_NT_SYMPATH = 0x0000100031    SYMOPT_INCLUDE_32BIT_MODULES = 0x0000200032    SYMOPT_PUBLICS_ONLY = 0x0000400033    SYMOPT_NO_PUBLICS = 0x0000800034    SYMOPT_AUTO_PUBLICS = 0x0001000035    SYMOPT_NO_IMAGE_SEARCH = 0x0002000036    SYMOPT_SECURE = 0x0004000037    SYMOPT_NO_PROMPTS = 0x0008000038    SYMOPT_DEBUG = 0x8000000039 40 41class ScopeGroupFlags(IntFlag):42    DEBUG_SCOPE_GROUP_ARGUMENTS = 0x0000000143    DEBUG_SCOPE_GROUP_LOCALS = 0x0000000244    DEBUG_SCOPE_GROUP_ALL = 0x0000000345    DEBUG_SCOPE_GROUP_BY_DATAMODEL = 0x0000000446 47 48class DebugModuleNames(IntEnum):49    DEBUG_MODNAME_IMAGE = 0x0000000050    DEBUG_MODNAME_MODULE = 0x0000000151    DEBUG_MODNAME_LOADED_IMAGE = 0x0000000252    DEBUG_MODNAME_SYMBOL_FILE = 0x0000000353    DEBUG_MODNAME_MAPPED_IMAGE = 0x0000000454 55 56class DebugModuleFlags(IntFlag):57    DEBUG_MODULE_LOADED = 0x0000000058    DEBUG_MODULE_UNLOADED = 0x0000000159    DEBUG_MODULE_USER_MODE = 0x0000000260    DEBUG_MODULE_EXE_MODULE = 0x0000000461    DEBUG_MODULE_EXPLICIT = 0x0000000862    DEBUG_MODULE_SECONDARY = 0x0000001063    DEBUG_MODULE_SYNTHETIC = 0x0000002064    DEBUG_MODULE_SYM_BAD_CHECKSUM = 0x0001000065 66 67class DEBUG_MODULE_PARAMETERS(Structure):68    _fields_ = [69        ("Base", c_ulonglong),70        ("Size", c_ulong),71        ("TimeDateStamp", c_ulong),72        ("Checksum", c_ulong),73        ("Flags", c_ulong),74        ("SymbolType", c_ulong),75        ("ImageNameSize", c_ulong),76        ("ModuleNameSize", c_ulong),77        ("LoadedImageNameSize", c_ulong),78        ("SymbolFileNameSize", c_ulong),79        ("MappedImageNameSize", c_ulong),80        ("Reserved", c_ulonglong * 2),81    ]82 83 84PDEBUG_MODULE_PARAMETERS = POINTER(DEBUG_MODULE_PARAMETERS)85 86 87class DEBUG_MODULE_AND_ID(Structure):88    _fields_ = [("ModuleBase", c_ulonglong), ("Id", c_ulonglong)]89 90 91PDEBUG_MODULE_AND_ID = POINTER(DEBUG_MODULE_AND_ID)92 93 94class DEBUG_SYMBOL_ENTRY(Structure):95    _fields_ = [96        ("ModuleBase", c_ulonglong),97        ("Offset", c_ulonglong),98        ("Id", c_ulonglong),99        ("Arg64", c_ulonglong),100        ("Size", c_ulong),101        ("Flags", c_ulong),102        ("TypeId", c_ulong),103        ("NameSize", c_ulong),104        ("Token", c_ulong),105        ("Tag", c_ulong),106        ("Arg32", c_ulong),107        ("Reserved", c_ulong),108    ]109 110 111PDEBUG_SYMBOL_ENTRY = POINTER(DEBUG_SYMBOL_ENTRY)112 113# UUID for DebugSymbols5 interface.114DebugSymbols5IID = IID(115    0xC65FA83E,116    0x1E69,117    0x475E,118    IID_Data4_Type(0x8E, 0x0E, 0xB5, 0xD7, 0x9E, 0x9C, 0xC1, 0x7E),119)120 121 122class IDebugSymbols5(Structure):123    pass124 125 126class IDebugSymbols5Vtbl(Structure):127    wrp = partial(WINFUNCTYPE, c_long, POINTER(IDebugSymbols5))128    ids_getsymboloptions = wrp(c_ulong_p)129    ids_setsymboloptions = wrp(c_ulong)130    ids_getmoduleparameters = wrp(131        c_ulong, c_ulong64_p, c_ulong, PDEBUG_MODULE_PARAMETERS132    )133    ids_getmodulenamestring = wrp(134        c_ulong, c_ulong, c_ulonglong, c_char_p, c_ulong, c_ulong_p135    )136    ids_getoffsetbyname = wrp(c_char_p, c_ulong64_p)137    ids_getlinebyoffset = wrp(138        c_ulonglong, c_ulong_p, c_char_p, c_ulong, c_ulong_p, c_ulong64_p139    )140    ids_getsymbolentriesbyname = wrp(141        c_char_p, c_ulong, PDEBUG_MODULE_AND_ID, c_ulong, c_ulong_p142    )143    ids_getsymbolentrystring = wrp(144        PDEBUG_MODULE_AND_ID, c_ulong, c_char_p, c_ulong, c_ulong_p145    )146    ids_getsymbolentryinformation = wrp(PDEBUG_MODULE_AND_ID, PDEBUG_SYMBOL_ENTRY)147    ids_getcurrentscopeframeindex = wrp(c_ulong_p)148    ids_getnearnamebyoffset = wrp(149        c_ulonglong, c_long, c_char_p, c_ulong, c_ulong_p, c_ulong64_p150    )151    ids_setscopeframebyindex = wrp(c_ulong)152    ids_getscopesymbolgroup2 = wrp(153        c_ulong, POINTER(IDebugSymbolGroup2), POINTER(POINTER(IDebugSymbolGroup2))154    )155    ids_getnamebyinlinecontext = wrp(156        c_ulonglong, c_ulong, c_char_p, c_ulong, c_ulong_p, c_ulong64_p157    )158    ids_getlinebyinlinecontext = wrp(159        c_ulonglong, c_ulong, c_ulong_p, c_char_p, c_ulong, c_ulong_p, c_ulong64_p160    )161    _fields_ = [162        ("QueryInterface", c_void_p),163        ("AddRef", c_void_p),164        ("Release", c_void_p),165        ("GetSymbolOptions", ids_getsymboloptions),166        ("AddSymbolOptions", c_void_p),167        ("RemoveSymbolOptions", c_void_p),168        ("SetSymbolOptions", ids_setsymboloptions),169        ("GetNameByOffset", c_void_p),170        ("GetOffsetByName", ids_getoffsetbyname),171        ("GetNearNameByOffset", ids_getnearnamebyoffset),172        ("GetLineByOffset", ids_getlinebyoffset),173        ("GetOffsetByLine", c_void_p),174        ("GetNumberModules", c_void_p),175        ("GetModuleByIndex", c_void_p),176        ("GetModuleByModuleName", c_void_p),177        ("GetModuleByOffset", c_void_p),178        ("GetModuleNames", c_void_p),179        ("GetModuleParameters", ids_getmoduleparameters),180        ("GetSymbolModule", c_void_p),181        ("GetTypeName", c_void_p),182        ("GetTypeId", c_void_p),183        ("GetTypeSize", c_void_p),184        ("GetFieldOffset", c_void_p),185        ("GetSymbolTypeId", c_void_p),186        ("GetOffsetTypeId", c_void_p),187        ("ReadTypedDataVirtual", c_void_p),188        ("WriteTypedDataVirtual", c_void_p),189        ("OutputTypedDataVirtual", c_void_p),190        ("ReadTypedDataPhysical", c_void_p),191        ("WriteTypedDataPhysical", c_void_p),192        ("OutputTypedDataPhysical", c_void_p),193        ("GetScope", c_void_p),194        ("SetScope", c_void_p),195        ("ResetScope", c_void_p),196        ("GetScopeSymbolGroup", c_void_p),197        ("CreateSymbolGroup", c_void_p),198        ("StartSymbolMatch", c_void_p),199        ("GetNextSymbolMatch", c_void_p),200        ("EndSymbolMatch", c_void_p),201        ("Reload", c_void_p),202        ("GetSymbolPath", c_void_p),203        ("SetSymbolPath", c_void_p),204        ("AppendSymbolPath", c_void_p),205        ("GetImagePath", c_void_p),206        ("SetImagePath", c_void_p),207        ("AppendImagePath", c_void_p),208        ("GetSourcePath", c_void_p),209        ("GetSourcePathElement", c_void_p),210        ("SetSourcePath", c_void_p),211        ("AppendSourcePath", c_void_p),212        ("FindSourceFile", c_void_p),213        ("GetSourceFileLineOffsets", c_void_p),214        ("GetModuleVersionInformation", c_void_p),215        ("GetModuleNameString", ids_getmodulenamestring),216        ("GetConstantName", c_void_p),217        ("GetFieldName", c_void_p),218        ("GetTypeOptions", c_void_p),219        ("AddTypeOptions", c_void_p),220        ("RemoveTypeOptions", c_void_p),221        ("SetTypeOptions", c_void_p),222        ("GetNameByOffsetWide", c_void_p),223        ("GetOffsetByNameWide", c_void_p),224        ("GetNearNameByOffsetWide", c_void_p),225        ("GetLineByOffsetWide", c_void_p),226        ("GetOffsetByLineWide", c_void_p),227        ("GetModuleByModuleNameWide", c_void_p),228        ("GetSymbolModuleWide", c_void_p),229        ("GetTypeNameWide", c_void_p),230        ("GetTypeIdWide", c_void_p),231        ("GetFieldOffsetWide", c_void_p),232        ("GetSymbolTypeIdWide", c_void_p),233        ("GetScopeSymbolGroup2", ids_getscopesymbolgroup2),234        ("CreateSymbolGroup2", c_void_p),235        ("StartSymbolMatchWide", c_void_p),236        ("GetNextSymbolMatchWide", c_void_p),237        ("ReloadWide", c_void_p),238        ("GetSymbolPathWide", c_void_p),239        ("SetSymbolPathWide", c_void_p),240        ("AppendSymbolPathWide", c_void_p),241        ("GetImagePathWide", c_void_p),242        ("SetImagePathWide", c_void_p),243        ("AppendImagePathWide", c_void_p),244        ("GetSourcePathWide", c_void_p),245        ("GetSourcePathElementWide", c_void_p),246        ("SetSourcePathWide", c_void_p),247        ("AppendSourcePathWide", c_void_p),248        ("FindSourceFileWide", c_void_p),249        ("GetSourceFileLineOffsetsWide", c_void_p),250        ("GetModuleVersionInformationWide", c_void_p),251        ("GetModuleNameStringWide", c_void_p),252        ("GetConstantNameWide", c_void_p),253        ("GetFieldNameWide", c_void_p),254        ("IsManagedModule", c_void_p),255        ("GetModuleByModuleName2", c_void_p),256        ("GetModuleByModuleName2Wide", c_void_p),257        ("GetModuleByOffset2", c_void_p),258        ("AddSyntheticModule", c_void_p),259        ("AddSyntheticModuleWide", c_void_p),260        ("RemoveSyntheticModule", c_void_p),261        ("GetCurrentScopeFrameIndex", ids_getcurrentscopeframeindex),262        ("SetScopeFrameByIndex", ids_setscopeframebyindex),263        ("SetScopeFromJitDebugInfo", c_void_p),264        ("SetScopeFromStoredEvent", c_void_p),265        ("OutputSymbolByOffset", c_void_p),266        ("GetFunctionEntryByOffset", c_void_p),267        ("GetFieldTypeAndOffset", c_void_p),268        ("GetFieldTypeAndOffsetWide", c_void_p),269        ("AddSyntheticSymbol", c_void_p),270        ("AddSyntheticSymbolWide", c_void_p),271        ("RemoveSyntheticSymbol", c_void_p),272        ("GetSymbolEntriesByOffset", c_void_p),273        ("GetSymbolEntriesByName", ids_getsymbolentriesbyname),274        ("GetSymbolEntriesByNameWide", c_void_p),275        ("GetSymbolEntryByToken", c_void_p),276        ("GetSymbolEntryInformation", ids_getsymbolentryinformation),277        ("GetSymbolEntryString", ids_getsymbolentrystring),278        ("GetSymbolEntryStringWide", c_void_p),279        ("GetSymbolEntryOffsetRegions", c_void_p),280        ("GetSymbolEntryBySymbolEntry", c_void_p),281        ("GetSourceEntriesByOffset", c_void_p),282        ("GetSourceEntriesByLine", c_void_p),283        ("GetSourceEntriesByLineWide", c_void_p),284        ("GetSourceEntryString", c_void_p),285        ("GetSourceEntryStringWide", c_void_p),286        ("GetSourceEntryOffsetRegions", c_void_p),287        ("GetsourceEntryBySourceEntry", c_void_p),288        ("GetScopeEx", c_void_p),289        ("SetScopeEx", c_void_p),290        ("GetNameByInlineContext", ids_getnamebyinlinecontext),291        ("GetNameByInlineContextWide", c_void_p),292        ("GetLineByInlineContext", ids_getlinebyinlinecontext),293        ("GetLineByInlineContextWide", c_void_p),294        ("OutputSymbolByInlineContext", c_void_p),295        ("GetCurrentScopeFrameIndexEx", c_void_p),296        ("SetScopeFrameByIndexEx", c_void_p),297    ]298 299 300IDebugSymbols5._fields_ = [("lpVtbl", POINTER(IDebugSymbols5Vtbl))]301 302SymbolId = namedtuple("SymbolId", ["ModuleBase", "Id"])303SymbolEntry = namedtuple(304    "SymbolEntry",305    [306        "ModuleBase",307        "Offset",308        "Id",309        "Arg64",310        "Size",311        "Flags",312        "TypeId",313        "NameSize",314        "Token",315        "Tag",316        "Arg32",317    ],318)319DebugModuleParams = namedtuple(320    "DebugModuleParams",321    [322        "Base",323        "Size",324        "TimeDateStamp",325        "Checksum",326        "Flags",327        "SymbolType",328        "ImageNameSize",329        "ModuleNameSize",330        "LoadedImageNameSize",331        "SymbolFileNameSize",332        "MappedImageNameSize",333    ],334)335 336 337class SymTags(IntEnum):338    Null = 0339    Exe = 1340    SymTagFunction = 5341 342 343def make_debug_module_params(cdata):344    fieldvalues = map(lambda y: getattr(cdata, y), DebugModuleParams._fields)345    return DebugModuleParams(*fieldvalues)346 347 348class Symbols(object):349    def __init__(self, symbols):350        self.ptr = symbols351        self.symbols = symbols.contents352        self.vt = self.symbols.lpVtbl.contents353        # Keep some handy ulongs for passing into C methods.354        self.ulong = c_ulong()355        self.ulong64 = c_ulonglong()356 357    def GetCurrentScopeFrameIndex(self):358        res = self.vt.GetCurrentScopeFrameIndex(self.symbols, byref(self.ulong))359        aborter(res, "GetCurrentScopeFrameIndex")360        return self.ulong.value361 362    def SetScopeFrameByIndex(self, idx):363        res = self.vt.SetScopeFrameByIndex(self.symbols, idx)364        aborter(res, "SetScopeFrameByIndex", ignore=[E_EINVAL])365        return res != E_EINVAL366 367    def GetOffsetByName(self, name):368        res = self.vt.GetOffsetByName(369            self.symbols, name.encode("ascii"), byref(self.ulong64)370        )371        aborter(res, "GetOffsetByName {}".format(name))372        return self.ulong64.value373 374    def GetNearNameByOffset(self, addr):375        ptr = create_string_buffer(256)376        pulong = c_ulong()377        disp = c_ulonglong()378        # Zero arg -> "delta" indicating how many symbols to skip379        res = self.vt.GetNearNameByOffset(380            self.symbols, addr, 0, ptr, 255, byref(pulong), byref(disp)381        )382        if res == E_NOINTERFACE:383            return "{noname}"384        aborter(res, "GetNearNameByOffset")385        ptr[255] = "\0".encode("ascii")386        return "{}+{}".format(string_at(ptr).decode("ascii"), disp.value)387 388    def GetModuleByModuleName2(self, name):389        # First zero arg -> module index to search from, second zero arg ->390        # DEBUG_GETMOD_* flags, none of which we use.391        res = self.vt.GetModuleByModuleName2(392            self.symbols, name, 0, 0, None, byref(self.ulong64)393        )394        aborter(res, "GetModuleByModuleName2")395        return self.ulong64.value396 397    def GetScopeSymbolGroup2(self):398        retptr = POINTER(IDebugSymbolGroup2)()399        res = self.vt.GetScopeSymbolGroup2(400            self.symbols, ScopeGroupFlags.DEBUG_SCOPE_GROUP_ALL, None, retptr401        )402        aborter(res, "GetScopeSymbolGroup2")403        return SymbolGroup(retptr)404 405    def GetSymbolEntryString(self, idx, module):406        symid = DEBUG_MODULE_AND_ID()407        symid.ModuleBase = module408        symid.Id = idx409        ptr = create_string_buffer(1024)410        # Zero arg is the string index -- symbols can have multiple names, for now411        # only support the first one.412        res = self.vt.GetSymbolEntryString(413            self.symbols, symid, 0, ptr, 1023, byref(self.ulong)414        )415        aborter(res, "GetSymbolEntryString")416        return string_at(ptr).decode("ascii")417 418    def GetSymbolEntryInformation(self, module, theid):419        symid = DEBUG_MODULE_AND_ID()420        symentry = DEBUG_SYMBOL_ENTRY()421        symid.ModuleBase = module422        symid.Id = theid423        res = self.vt.GetSymbolEntryInformation(self.symbols, symid, symentry)424        aborter(res, "GetSymbolEntryInformation")425        # Fetch fields into SymbolEntry object426        fields = map(lambda x: getattr(symentry, x), SymbolEntry._fields)427        return SymbolEntry(*fields)428 429    def GetSymbolEntriesByName(self, symstr):430        # Initial query to find number of symbol entries431        res = self.vt.GetSymbolEntriesByName(432            self.symbols, symstr.encode("ascii"), 0, None, 0, byref(self.ulong)433        )434        aborter(res, "GetSymbolEntriesByName")435 436        # Build a buffer and query for 'length' entries437        length = self.ulong.value438        symrecs = (DEBUG_MODULE_AND_ID * length)()439        # Zero arg -> flags, of which there are none defined.440        res = self.vt.GetSymbolEntriesByName(441            self.symbols, symstr.encode("ascii"), 0, symrecs, length, byref(self.ulong)442        )443        aborter(res, "GetSymbolEntriesByName")444 445        # Extract 'length' number of SymbolIds446        length = self.ulong.value447 448        def extract(x):449            sym = symrecs[x]450            return SymbolId(sym.ModuleBase, sym.Id)451 452        return [extract(x) for x in range(length)]453 454    def GetSymbolPath(self):455        # Query for length of buffer to allocate456        res = self.vt.GetSymbolPath(self.symbols, None, 0, byref(self.ulong))457        aborter(res, "GetSymbolPath", ignore=[S_FALSE])458 459        # Fetch 'length' length symbol path string460        length = self.ulong.value461        arr = create_string_buffer(length)462        res = self.vt.GetSymbolPath(self.symbols, arr, length, byref(self.ulong))463        aborter(res, "GetSymbolPath")464 465        return string_at(arr).decode("ascii")466 467    def GetSourcePath(self):468        # Query for length of buffer to allocate469        res = self.vt.GetSourcePath(self.symbols, None, 0, byref(self.ulong))470        aborter(res, "GetSourcePath", ignore=[S_FALSE])471 472        # Fetch a string of len 'length'473        length = self.ulong.value474        arr = create_string_buffer(length)475        res = self.vt.GetSourcePath(self.symbols, arr, length, byref(self.ulong))476        aborter(res, "GetSourcePath")477 478        return string_at(arr).decode("ascii")479 480    def SetSourcePath(self, string):481        res = self.vt.SetSourcePath(self.symbols, string.encode("ascii"))482        aborter(res, "SetSourcePath")483        return484 485    def GetModuleParameters(self, base):486        self.ulong64.value = base487        params = DEBUG_MODULE_PARAMETERS()488        # Fetch one module params struct, starting at idx zero489        res = self.vt.GetModuleParameters(490            self.symbols, 1, byref(self.ulong64), 0, byref(params)491        )492        aborter(res, "GetModuleParameters")493        return make_debug_module_params(params)494 495    def GetSymbolOptions(self):496        res = self.vt.GetSymbolOptions(self.symbols, byref(self.ulong))497        aborter(res, "GetSymbolOptions")498        return SymbolOptionFlags(self.ulong.value)499 500    def SetSymbolOptions(self, opts):501        assert isinstance(opts, SymbolOptionFlags)502        res = self.vt.SetSymbolOptions(self.symbols, opts.value)503        aborter(res, "SetSymbolOptions")504        return505 506    def GetLineByOffset(self, offs):507        # Initial query for filename buffer size508        res = self.vt.GetLineByOffset(509            self.symbols, offs, None, None, 0, byref(self.ulong), None510        )511        if res == E_FAIL:512            return None  # Sometimes we just can't get line numbers, of course513        aborter(res, "GetLineByOffset", ignore=[S_FALSE])514 515        # Allocate filename buffer and query for line number too516        filenamelen = self.ulong.value517        text = create_string_buffer(filenamelen)518        line = c_ulong()519        res = self.vt.GetLineByOffset(520            self.symbols, offs, byref(line), text, filenamelen, byref(self.ulong), None521        )522        aborter(res, "GetLineByOffset")523 524        return string_at(text).decode("ascii"), line.value525 526    def GetModuleNameString(self, whichname, base):527        # Initial query for name string length528        res = self.vt.GetModuleNameString(529            self.symbols, whichname, DEBUG_ANY_ID, base, None, 0, byref(self.ulong)530        )531        aborter(res, "GetModuleNameString", ignore=[S_FALSE])532 533        module_name_len = self.ulong.value534        module_name = (c_char * module_name_len)()535        res = self.vt.GetModuleNameString(536            self.symbols,537            whichname,538            DEBUG_ANY_ID,539            base,540            module_name,541            module_name_len,542            None,543        )544        aborter(res, "GetModuleNameString")545 546        return string_at(module_name).decode("ascii")547 548    def GetNameByInlineContext(self, pc, ctx):549        # None args -> ignore output name size and displacement550        buf = create_string_buffer(256)551        res = self.vt.GetNameByInlineContext(552            self.symbols, pc, ctx, buf, 255, None, None553        )554        aborter(res, "GetNameByInlineContext")555        return string_at(buf).decode("ascii")556 557    def GetLineByInlineContext(self, pc, ctx):558        # None args -> ignore output filename size and displacement559        buf = create_string_buffer(256)560        res = self.vt.GetLineByInlineContext(561            self.symbols, pc, ctx, byref(self.ulong), buf, 255, None, None562        )563        aborter(res, "GetLineByInlineContext")564        return string_at(buf).decode("ascii"), self.ulong.value565 566    def get_all_symbols(self):567        main_module_name = self.get_exefile_module_name()568        idnumbers = self.GetSymbolEntriesByName("{}!*".format(main_module_name))569        lst = []570        for symid in idnumbers:571            s = self.GetSymbolEntryString(symid.Id, symid.ModuleBase)572            symentry = self.GetSymbolEntryInformation(symid.ModuleBase, symid.Id)573            lst.append((s, symentry))574        return lst575 576    def get_all_functions(self):577        syms = self.get_all_symbols()578        return [x for x in syms if x[1].Tag == SymTags.SymTagFunction]579 580    def get_all_modules(self):581        params = DEBUG_MODULE_PARAMETERS()582        idx = 0583        res = 0584        all_modules = []585        while res != E_EINVAL:586            res = self.vt.GetModuleParameters(self.symbols, 1, None, idx, byref(params))587            aborter(res, "GetModuleParameters", ignore=[E_EINVAL])588            all_modules.append(make_debug_module_params(params))589            idx += 1590        return all_modules591 592    def get_exefile_module(self):593        all_modules = self.get_all_modules()594        reduce_func = (595            lambda x, y: y if y.Flags & DebugModuleFlags.DEBUG_MODULE_EXE_MODULE else x596        )597        main_module = reduce(reduce_func, all_modules, None)598        if main_module is None:599            raise Exception("Couldn't find the exefile module")600        return main_module601 602    def get_module_name(self, base):603        return self.GetModuleNameString(DebugModuleNames.DEBUG_MODNAME_MODULE, base)604 605    def get_exefile_module_name(self):606        return self.get_module_name(self.get_exefile_module().Base)607