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)
- In
Backtrace.c:228:
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;
}- In
PdbCache.c:320:
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;- In
PdbCache.c:328:
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;- In
PdbCache.c:348:
PdbCache cache = PdbCacheInit(base);
Zstr name = NULL;
bool ok = !PdbCacheResolve(&cache, (Zstr)missing, 0, 0x1000, &name, NULL);
PdbCacheDeinit(&cache);
DefaultAllocatorDeinit(&alloc);- In
PdbCache.c:380:
Zstr name = NULL;
u32 off = 0;
ok = PdbCacheResolve(&cache, pe_name, mbase, mbase + 0x1100, &name, &off);
ok = ok && name && ZstrCompare(name, "winproc") == 0 && off == 0;
PdbCacheDeinit(&cache);- In
PdbCache.c:414:
Zstr name = NULL;
// PE opens, PDB lookup fails -> resolve returns false.
ok = !PdbCacheResolve(&cache, (Zstr)pe_path, 0x140000000ull, 0x140001100ull, &name, NULL);
PdbCacheDeinit(&cache);
// Teardown returns every allocation (the failed-lookup candidate too).
- In
PdbCache.c:452:
Zstr name = NULL;
// PDB opens but GUID/age disagree -> resolve rejects it.
ok = !PdbCacheResolve(&cache, (Zstr)pe_path, 0x140000000ull, 0x140001100ull, &name, NULL);
PdbCacheDeinit(&cache);
// The briefly-opened, then-rejected PDB must be freed.
- In
PdbCache.c:491:
u32 off = 0;
bool ra = PdbCacheResolve(&cache, (Zstr)a_pe, mbase, mbase + 0x1100, &name, &off);
bool rb = PdbCacheResolve(&cache, (Zstr)b_pe, mbase, mbase + 0x1100, &name, &off);- In
PdbCache.c:492:
bool ra = PdbCacheResolve(&cache, (Zstr)a_pe, mbase, mbase + 0x1100, &name, &off);
bool rb = PdbCacheResolve(&cache, (Zstr)b_pe, mbase, mbase + 0x1100, &name, &off);
// Both modules now open and cached; snapshot the live allocations.
- In
PdbCache.c:499:
// Re-resolve B at a different IP: must hit B's existing slot.
Zstr name2 = NULL;
bool rb2 = PdbCacheResolve(&cache, (Zstr)b_pe, mbase, mbase + 0x1108, &name2, &off);
size after = DebugAllocatorLiveCount(&alloc);- In
PdbCache.c:539:
Zstr name = NULL;
u32 off = 0;
bool r = PdbCacheResolve(&cache, (Zstr)pe_path, mbase, mbase + 0x1100, &name, &off);
// A populated cache with an opened PE+PDB sits strictly above baseline.
- In
PdbCache.c:586:
u32 off = 0;
// ip exactly at module_base -> RVA 0 -> resolves under real `<`.
ok = PdbCacheResolve(&cache, (Zstr)pe_path, mbase, mbase, &name, &off);
ok = ok && name && ZstrCompare(name, "winzero") == 0 && off == 0;
PdbCacheDeinit(&cache);- In
PdbCache.c:619:
Zstr name = NULL;
u32 off = 0;
ok = PdbCacheResolve(&cache, (Zstr)pe_path, mbase, mbase + 0xFFFFFFFFull, &name, &off);
ok = ok && name && ZstrCompare(name, "winmax") == 0 && off == 0;
PdbCacheDeinit(&cache);- In
PdbCache.c:655:
u32 off = 0;
// ip strictly below module_base -> delegated resolve returns false.
ok = !PdbCacheResolve(&cache, &mod, mbase, mbase - 1, &name, &off);
}
PdbCacheDeinit(&cache);- In
PdbCache.c:691:
Zstr name = NULL;
u32 off = 0;
ok = PdbCacheResolve(&cache, (Zstr)pe_path, mbase, mbase + 0x1100, &name, &off);
ok = ok && name && ZstrCompare(name, "winproc") == 0 && off == 0;
PdbCacheDeinit(&cache);- In
PdbCache.c:727:
PdbCache cache = PdbCacheInit(a);
Zstr name = NULL;
ok = !PdbCacheResolve(&cache, (Zstr)pe_path, 0x140000000ull, 0x140001100ull, &name, NULL);
PdbCacheDeinit(&cache);
ok = ok && DebugAllocatorLiveCount(&alloc) == baseline;- In
PdbCache.c:766:
Zstr nb = NULL;
u32 off = 0;
bool ra = PdbCacheResolve(&cache, (Zstr)a_pe, mbase, mbase + 0x1100, &na, &off);
bool rb = PdbCacheResolve(&cache, (Zstr)b_pe, mbase, mbase + 0x1100, &nb, &off);
ok = ra && rb && na && nb && ZstrCompare(na, "aproc") == 0 && ZstrCompare(nb, "bproc") == 0;- In
PdbCache.c:767:
u32 off = 0;
bool ra = PdbCacheResolve(&cache, (Zstr)a_pe, mbase, mbase + 0x1100, &na, &off);
bool rb = PdbCacheResolve(&cache, (Zstr)b_pe, mbase, mbase + 0x1100, &nb, &off);
ok = ra && rb && na && nb && ZstrCompare(na, "aproc") == 0 && ZstrCompare(nb, "bproc") == 0;
PdbCacheDeinit(&cache);- In
PdbCache.c:809:
// Two distinct modules -> two cache entries, each opening a PE+PDB.
bool ra = PdbCacheResolve(&cache, (Zstr)a_pe, mbase, mbase + 0x1100, &name, &off);
bool rb = PdbCacheResolve(&cache, (Zstr)b_pe, mbase, mbase + 0x1100, &name, &off);- In
PdbCache.c:810:
// Two distinct modules -> two cache entries, each opening a PE+PDB.
bool ra = PdbCacheResolve(&cache, (Zstr)a_pe, mbase, mbase + 0x1100, &name, &off);
bool rb = PdbCacheResolve(&cache, (Zstr)b_pe, mbase, mbase + 0x1100, &name, &off);
// A populated two-entry cache sits strictly above baseline.
- In
PdbCache.c:841:
PdbCache cache = PdbCacheInit(&bp);
Zstr name = NULL;
if (PdbCacheResolve(&cache, (char *)"/x", 0, 0x1000, &name, NULL))
return false; // the entry must have failed to allocate
Last updated on