Skip to content
PdbCacheResolve

PdbCacheResolve

Description

Resolve runtime_ip to a function name.

Parameters

Name Direction Description
self in,out Cache. Grows on first sight of module_path.
module_path in Path to the loaded PE for the address being resolved. Caller-owned; we copy it.
module_base in Runtime virtual address of the module’s load point. ip - module_base is the RVA.
runtime_ip in Address to resolve.
out_name out On success, pointer to the function name (borrowed from the cached PDB; valid until the next PdbCacheDeinit).
out_offset out On success, byte offset from the function start (rva - function.rva).

Success

Returns true.

Failure

Returns false if the module can’t be opened, no PDB pairs with it, or the RVA falls outside every public function.

Usage example (Cross-references)

Usage examples (Cross-references)
                    u64   module_base = 0;
                    if (win_module_for_ip(frames[i].ip, data, MAX_PATH, &module_base)) {
                        if (PdbCacheResolve(&pdb_cache, data, module_base, (u64)ip, &sym_name, &sym_off)) {
                            named = true;
                        }
        Zstr name        = NULL;
        u32       offset      = 0;
        bool      ok          = PdbCacheResolve(&cache, (Zstr)pe_path, module_base, ip, &name, &offset);
        ok                    = ok && name && ZstrCompare(name, "winproc") == 0 && offset == 0;
        name          = NULL;
        offset        = 0;
        ok            = ok && PdbCacheResolve(&cache, (Zstr)pe_path, module_base, ip2, &name, &offset);
        ok            = ok && name && ZstrCompare(name, "winproc") == 0 && offset == 0x10;
        PdbCache cache = PdbCacheInit(base);
        Zstr name = NULL;
        bool ok   = !PdbCacheResolve(&cache, (Zstr)missing, 0, 0x1000, &name, NULL);
        PdbCacheDeinit(&cache);
        DefaultAllocatorDeinit(&alloc);
            u32       off = 0;
    
            bool r1          = PdbCacheResolve(&cache, (Zstr)fx.pe_path, mbase, mbase + 0x1100, &name1, &off);
            size after_first = VecLen(&cache.entries);
            size after_first = VecLen(&cache.entries);
    
            bool r2           = PdbCacheResolve(&cache, (Zstr)fx.pe_path, mbase, mbase + 0x1110, &name2, &off);
            size after_second = VecLen(&cache.entries);
            u32       off   = 0;
    
            bool rA = PdbCacheResolve(&cache, (Zstr)fa.pe_path, mbase, mbase + 0x1100, &name, &off);
            bool rB = PdbCacheResolve(&cache, (Zstr)fb.pe_path, mbase, mbase + 0x1100, &name, &off);
            size n2 = VecLen(&cache.entries);
    
            bool rA = PdbCacheResolve(&cache, (Zstr)fa.pe_path, mbase, mbase + 0x1100, &name, &off);
            bool rB = PdbCacheResolve(&cache, (Zstr)fb.pe_path, mbase, mbase + 0x1100, &name, &off);
            size n2 = VecLen(&cache.entries);
            // Re-resolve B, which sits at index 1: forces the find loop to
            // Re-resolve B, which sits at index 1: forces the find loop to
            // walk past index 0.
            bool rB2 = PdbCacheResolve(&cache, (Zstr)fb.pe_path, mbase, mbase + 0x1108, &name, &off);
            size n3  = VecLen(&cache.entries);
            Zstr      name  = NULL;
            u32       off   = 0;
            bool      r     = PdbCacheResolve(&cache, (Zstr)fx.pe_path, mbase, mbase + 0x1100, &name, &off);
            bool      grew  = VecLen(&cache.entries) == 1 && DebugAllocatorLiveCount(&dbg) > before;
            Zstr      name  = NULL;
            u32       off   = 0;
            bool      r     = PdbCacheResolve(&cache, (Zstr)fx.pe_path, mbase, mbase + 0x1100, &name, &off);
            result          = r && name && ZstrCompare(name, "winproc") == 0 && off == 0;
            PdbCacheDeinit(&cache);
            //     `<`, rejected under `<=`.
            Zstr nat = NULL;
            bool at  = PdbCacheResolve(&cache, (Zstr)pe_path, mbase, mbase, &nat, &off);
    
            // (b) ip strictly below module_base -> rejected under both (also
            //     guards the RVA-underflow path).
            Zstr nbelow = NULL;
            bool below  = PdbCacheResolve(&cache, (Zstr)pe_path, mbase, mbase - 1, &nbelow, &off);
    
            result = at && nat && ZstrCompare(nat, "winzero") == 0 && off == 0 && !below;
            // ip - module_base == 0xFFFFFFFF exactly -> rva64 == 0xFFFFFFFF.
            Zstr name = NULL;
            bool ok   = PdbCacheResolve(&cache, (Zstr)pe_path, mbase, mbase + 0xFFFFFFFFull, &name, &off);
    
            result = ok && name && ZstrCompare(name, "winmax") == 0 && off == 0;
Last updated on