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:296:
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:304:
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:324:
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