⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 symbol.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
            }
        }
        regfree(&mod_regex);
        regfree(&sym_regex);
        return TRUE;
    }
    module = module_find_by_addr(pcs, BaseOfDll, DMT_UNKNOWN);
    if (!(module = module_get_debug(pcs, module)))
        return FALSE;

    /* we always ignore module name from Mask when BaseOfDll is defined */
    if (Mask && (bang = strchr(Mask, '!')))
    {
        if (bang == Mask) return FALSE;
        Mask = bang + 1;
    }

    compile_regex(Mask ? Mask : "*", -1, &sym_regex);
    symt_enum_module(module, &sym_regex, EnumSymbolsCallback, UserContext);
    regfree(&sym_regex);

    return TRUE;
}

struct sym_enumerate
{
    void*                       ctx;
    PSYM_ENUMSYMBOLS_CALLBACK   cb;
};

static BOOL CALLBACK sym_enumerate_cb(PSYMBOL_INFO syminfo, ULONG size, void* ctx)
{
    struct sym_enumerate*       se = (struct sym_enumerate*)ctx;
    return (se->cb)(syminfo->Name, syminfo->Address, syminfo->Size, se->ctx);
}

/***********************************************************************
 *		SymEnumerateSymbols (DBGHELP.@)
 */
BOOL WINAPI SymEnumerateSymbols(HANDLE hProcess, DWORD BaseOfDll,
                                PSYM_ENUMSYMBOLS_CALLBACK EnumSymbolsCallback, 
                                PVOID UserContext)
{
    struct sym_enumerate        se;

    se.ctx = UserContext;
    se.cb  = EnumSymbolsCallback;
    
    return SymEnumSymbols(hProcess, BaseOfDll, NULL, sym_enumerate_cb, &se);
}

/******************************************************************
 *		SymFromAddr (DBGHELP.@)
 *
 */
BOOL WINAPI SymFromAddr(HANDLE hProcess, DWORD64 Address, 
                        DWORD64* Displacement, PSYMBOL_INFO Symbol)
{
    struct process*     pcs = process_find_by_handle(hProcess);
    struct module*      module;
    struct symt_ht*     sym;
    int                 idx;

    if (!pcs) return FALSE;
    module = module_find_by_addr(pcs, Address, DMT_UNKNOWN);
    if (!(module = module_get_debug(pcs, module))) return FALSE;
    if ((idx = symt_find_nearest(module, Address)) == -1) return FALSE;

    sym = module->addr_sorttab[idx];

    symt_fill_sym_info(module, &sym->symt, Symbol);
    if (Displacement) *Displacement = Address - Symbol->Address;
    return TRUE;
}

/******************************************************************
 *		SymGetSymFromAddr (DBGHELP.@)
 *
 */
BOOL WINAPI SymGetSymFromAddr(HANDLE hProcess, DWORD Address,
                              PDWORD Displacement, PIMAGEHLP_SYMBOL Symbol)
{
    char        buffer[sizeof(SYMBOL_INFO) + 256];
    SYMBOL_INFO*si = (SYMBOL_INFO*)buffer;
    size_t      len;
    DWORD64     Displacement64;

    if (Symbol->SizeOfStruct < sizeof(*Symbol)) return FALSE;
    si->SizeOfStruct = sizeof(*si);
    si->MaxNameLen = 256;
    if (!SymFromAddr(hProcess, Address, &Displacement64, si))
        return FALSE;

    if (Displacement)
        *Displacement = Displacement64;
    Symbol->Address = si->Address;
    Symbol->Size    = si->Size;
    Symbol->Flags   = si->Flags;
    len = min(Symbol->MaxNameLength, si->MaxNameLen);
    strncpy(Symbol->Name, si->Name, len);
    Symbol->Name[len - 1] = '\0';
    return TRUE;
}

/******************************************************************
 *		SymFromName (DBGHELP.@)
 *
 */
BOOL WINAPI SymFromName(HANDLE hProcess, LPSTR Name, PSYMBOL_INFO Symbol)
{
    struct process*             pcs = process_find_by_handle(hProcess);
    struct module*              module;
    struct hash_table_iter      hti;
    void*                       ptr;
    struct symt_ht*             sym = NULL;
    const char*                 name;

    TRACE("(%p, %s, %p)\n", hProcess, Name, Symbol);
    if (!pcs) return FALSE;
    if (Symbol->SizeOfStruct < sizeof(*Symbol)) return FALSE;
    name = strchr(Name, '!');
    if (name)
    {
        char    tmp[128];
        assert(name - Name < sizeof(tmp));
        memcpy(tmp, Name, name - Name);
        tmp[name - Name] = '\0';
        module = module_find_by_name(pcs, tmp, DMT_UNKNOWN);
        if (!module) return FALSE;
        Name = (char*)(name + 1);
    }
    else module = pcs->lmodules;

    /* FIXME: Name could be made out of a regular expression */
    for (; module; module = (name) ? NULL : module->next)
    {
        if (module->module.SymType == SymNone) continue;
        if (module->module.SymType == SymDeferred)
        {
            struct module*      xmodule = module_get_debug(pcs, module);
            if (!xmodule || xmodule != module) continue;
        }
        hash_table_iter_init(&module->ht_symbols, &hti, Name);
        while ((ptr = hash_table_iter_up(&hti)))
        {
            sym = GET_ENTRY(ptr, struct symt_ht, hash_elt);

            if (!strcmp(sym->hash_elt.name, Name))
            {
                symt_fill_sym_info(module, &sym->symt, Symbol);
                return TRUE;
            }
        }
    }
    return FALSE;
}

/***********************************************************************
 *		SymGetSymFromName (DBGHELP.@)
 */
BOOL WINAPI SymGetSymFromName(HANDLE hProcess, LPSTR Name, PIMAGEHLP_SYMBOL Symbol)
{
    char        buffer[sizeof(SYMBOL_INFO) + 256];
    SYMBOL_INFO*si = (SYMBOL_INFO*)buffer;
    size_t      len;

    if (Symbol->SizeOfStruct < sizeof(*Symbol)) return FALSE;
    si->SizeOfStruct = sizeof(*si);
    si->MaxNameLen = 256;
    if (!SymFromName(hProcess, Name, si)) return FALSE;

    Symbol->Address = si->Address;
    Symbol->Size    = si->Size;
    Symbol->Flags   = si->Flags;
    len = min(Symbol->MaxNameLength, si->MaxNameLen);
    strncpy(Symbol->Name, si->Name, len);
    Symbol->Name[len - 1] = '\0';
    return TRUE;
}

/******************************************************************
 *		sym_fill_func_line_info
 *
 * fills information about a file
 */
BOOL symt_fill_func_line_info(struct module* module, struct symt_function* func, 
                              DWORD addr, IMAGEHLP_LINE* line)
{
    struct line_info*   dli = NULL;
    BOOL                found = FALSE;

    assert(func->symt.tag == SymTagFunction);

    while ((dli = vector_iter_down(&func->vlines, dli)))
    {
        if (!dli->is_source_file)
        {
            if (found || dli->u.pc_offset > addr) continue;
            line->LineNumber = dli->line_number;
            line->Address    = dli->u.pc_offset;
            line->Key        = dli;
            found = TRUE;
            continue;
        }
        if (found)
        {
            line->FileName = (char*)source_get(module, dli->u.source_file);
            return TRUE;
        }
    }
    return FALSE;
}

/***********************************************************************
 *		SymGetSymNext (DBGHELP.@)
 */
BOOL WINAPI SymGetSymNext(HANDLE hProcess, PIMAGEHLP_SYMBOL Symbol)
{
    /* algo:
     * get module from Symbol.Address
     * get index in module.addr_sorttab of Symbol.Address
     * increment index
     * if out of module bounds, move to next module in process address space
     */
    FIXME("(%p, %p): stub\n", hProcess, Symbol);
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return FALSE;
}

/***********************************************************************
 *		SymGetSymPrev (DBGHELP.@)
 */

BOOL WINAPI SymGetSymPrev(HANDLE hProcess, PIMAGEHLP_SYMBOL Symbol)
{
    FIXME("(%p, %p): stub\n", hProcess, Symbol);
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return FALSE;
}

/******************************************************************
 *		SymGetLineFromAddr (DBGHELP.@)
 *
 */
BOOL WINAPI SymGetLineFromAddr(HANDLE hProcess, DWORD dwAddr, 
                               PDWORD pdwDisplacement, PIMAGEHLP_LINE Line)
{
    struct process*     pcs = process_find_by_handle(hProcess);
    struct module*      module;
    int                 idx;

    TRACE("%p %08lx %p %p\n", hProcess, dwAddr, pdwDisplacement, Line);

    if (Line->SizeOfStruct < sizeof(*Line)) return FALSE;

    if (!pcs) return FALSE;
    module = module_find_by_addr(pcs, dwAddr, DMT_UNKNOWN);
    if (!(module = module_get_debug(pcs, module))) return FALSE;
    if ((idx = symt_find_nearest(module, dwAddr)) == -1) return FALSE;

    if (module->addr_sorttab[idx]->symt.tag != SymTagFunction) return FALSE;
    if (!symt_fill_func_line_info(module, 
                                  (struct symt_function*)module->addr_sorttab[idx],
                                  dwAddr, Line)) return FALSE;
    if (pdwDisplacement) *pdwDisplacement = dwAddr - Line->Address;
    return TRUE;
}

/******************************************************************
 *		SymGetLinePrev (DBGHELP.@)
 *
 */
BOOL WINAPI SymGetLinePrev(HANDLE hProcess, PIMAGEHLP_LINE Line)
{
    struct process*     pcs = process_find_by_handle(hProcess);
    struct module*      module;
    struct line_info*   li;
    BOOL                in_search = FALSE;

    TRACE("(%p %p)\n", hProcess, Line);

    if (Line->SizeOfStruct < sizeof(*Line)) return FALSE;

    if (!pcs) return FALSE;
    module = module_find_by_addr(pcs, Line->Address, DMT_UNKNOWN);
    if (!(module = module_get_debug(pcs, module))) return FALSE;

    if (Line->Key == 0) return FALSE;
    li = (struct line_info*)Line->Key;
    /* things are a bit complicated because when we encounter a DLIT_SOURCEFILE
     * element we have to go back until we find the prev one to get the real
     * source file name for the DLIT_OFFSET element just before 
     * the first DLIT_SOURCEFILE
     */
    while (!li->is_first)
    {
        li--;
        if (!li->is_source_file)
        {
            Line->LineNumber = li->line_number;
            Line->Address    = li->u.pc_offset;
            Line->Key        = li;
            if (!in_search) return TRUE;
        }
        else
        {
            if (in_search)
            {
                Line->FileName = (char*)source_get(module, li->u.source_file);
                return TRUE;
            }
            in_search = TRUE;
        }
    }
    SetLastError(ERROR_NO_MORE_ITEMS); /* FIXME */
    return FALSE;
}

BOOL symt_get_func_line_next(struct module* module, PIMAGEHLP_LINE line)
{
    struct line_info*   li;

    if (line->Key == 0) return FALSE;
    li = (struct line_info*)line->Key;
    while (!li->is_last)
    {
        li++;
        if (!li->is_source_file)
        {
            line->LineNumber = li->line_number;
            line->Address    = li->u.pc_offset;
            line->Key        = li;
            return TRUE;
        }
        line->FileName = (char*)source_get(module, li->u.source_file);
    }
    return FALSE;
}

/******************************************************************
 *		SymGetLineNext (DBGHELP.@)
 *
 */
BOOL WINAPI SymGetLineNext(HANDLE hProcess, PIMAGEHLP_LINE Line)
{
    struct process*     pcs = process_find_by_handle(hProcess);
    struct module*      module;

    TRACE("(%p %p)\n", hProcess, Line);

    if (Line->SizeOfStruct < sizeof(*Line)) return FALSE;
    if (!pcs) return FALSE;
    module = module_find_by_addr(pcs, Line->Address, DMT_UNKNOWN);
    if (!(module = module_get_debug(pcs, module))) return FALSE;

    if (symt_get_func_line_next(module, Line)) return TRUE;
    SetLastError(ERROR_NO_MORE_ITEMS); /* FIXME */
    return FALSE;
}

/***********************************************************************
 *		SymFunctionTableAccess (DBGHELP.@)
 */
PVOID WINAPI SymFunctionTableAccess(HANDLE hProcess, DWORD AddrBase)
{
    FIXME("(%p, 0x%08lx): stub\n", hProcess, AddrBase);
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return FALSE;
}

/***********************************************************************
 *		SymUnDName (DBGHELP.@)
 */
BOOL WINAPI SymUnDName(PIMAGEHLP_SYMBOL sym, LPSTR UnDecName, DWORD UnDecNameLength)
{
    TRACE("(%p %s %lu): stub\n", sym, UnDecName, UnDecNameLength);
    return UnDecorateSymbolName(sym->Name, UnDecName, UnDecNameLength, 
                                UNDNAME_COMPLETE) != 0;
}

static void* und_alloc(size_t len) { return HeapAlloc(GetProcessHeap(), 0, len); }
static void  und_free (void* ptr)  { HeapFree(GetProcessHeap(), 0, ptr); }

/***********************************************************************
 *		UnDecorateSymbolName (DBGHELP.@)
 */
DWORD WINAPI UnDecorateSymbolName(LPCSTR DecoratedName, LPSTR UnDecoratedName,
                                  DWORD UndecoratedLength, DWORD Flags)
{
    /* undocumented from msvcrt */
    static char* (*p_undname)(char*, const char*, int, void* (*)(size_t), void (*)(void*), unsigned short);
    static WCHAR szMsvcrt[] = {'m','s','v','c','r','t','.','d','l','l',0};

    TRACE("(%s, %p, %ld, 0x%08lx): stub\n",
          debugstr_a(DecoratedName), UnDecoratedName, UndecoratedLength, Flags);

    if (!p_undname)
    {
        if (!hMsvcrt) hMsvcrt = LoadLibraryW(szMsvcrt);
        if (hMsvcrt) p_undname = (void*)GetProcAddress(hMsvcrt, "__unDName");
        if (!p_undname) return 0;
    }

    if (!UnDecoratedName) return 0;
    if (!p_undname(UnDecoratedName, DecoratedName, UndecoratedLength, 
                   und_alloc, und_free, Flags))
        return 0;
    return strlen(UnDecoratedName);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -