Skip to content

PdbResolveRva

Description

Locate the function whose [rva, rva + size) range contains rva. (For the trailing function whose size is 0 we accept any rva >= function.rva.)

Success

Returns a pointer to the matching entry. Valid until PdbDeinit.

Failure

Returns NULL.

Usage example (Cross-references)

Usage examples (Cross-references)
        u32 rva = (u32)rva64;
    
        const PdbFunction *f = PdbResolveRva(&entry->pdb, rva);
        if (!f)
            return false;
    }
    
    const PdbFunction *PdbResolveRva(const Pdb *self, u32 rva) {
        if (!self || VecLen(&self->functions) == 0)
            return NULL;
        // Direct lookup by RVA.
        if (ok) {
            const PdbFunction *f = PdbResolveRva(&pdb, 0x1100);
            ok                   = f && ZstrCompare(f->name, "my_function") == 0;
        }
        // Exact starts.
        if (ok) {
            const PdbFunction *a = PdbResolveRva(&pdb, 0x1100);
            const PdbFunction *b = PdbResolveRva(&pdb, 0x1200);
            const PdbFunction *c = PdbResolveRva(&pdb, 0x1300);
        if (ok) {
            const PdbFunction *a = PdbResolveRva(&pdb, 0x1100);
            const PdbFunction *b = PdbResolveRva(&pdb, 0x1200);
            const PdbFunction *c = PdbResolveRva(&pdb, 0x1300);
            ok                   = ok && a && ZstrCompare(a->name, "fn_alpha") == 0;
            const PdbFunction *a = PdbResolveRva(&pdb, 0x1100);
            const PdbFunction *b = PdbResolveRva(&pdb, 0x1200);
            const PdbFunction *c = PdbResolveRva(&pdb, 0x1300);
            ok                   = ok && a && ZstrCompare(a->name, "fn_alpha") == 0;
            ok                   = ok && b && ZstrCompare(b->name, "fn_beta") == 0;
        // first/only entry.
        if (ok) {
            const PdbFunction *mid_a = PdbResolveRva(&pdb, 0x11FF); // inside alpha
            const PdbFunction *mid_b = PdbResolveRva(&pdb, 0x12AB); // inside beta
            ok                       = ok && mid_a && ZstrCompare(mid_a->name, "fn_alpha") == 0;
        if (ok) {
            const PdbFunction *mid_a = PdbResolveRva(&pdb, 0x11FF); // inside alpha
            const PdbFunction *mid_b = PdbResolveRva(&pdb, 0x12AB); // inside beta
            ok                       = ok && mid_a && ZstrCompare(mid_a->name, "fn_alpha") == 0;
            ok                       = ok && mid_b && ZstrCompare(mid_b->name, "fn_beta") == 0;
        // Below the first function -> unresolved.
        if (ok)
            ok = PdbResolveRva(&pdb, 0x1000) == NULL;
    
        PdbDeinit(&pdb);
        // second section's VA (0x8000) was used -- not section[0]'s 0x1000.
        if (ok) {
            const PdbFunction *r = PdbResolveRva(&pdb, 0x8010);
            ok                   = r && ZstrCompare(r->name, "in_rdata") == 0;
        }
        }
        if (ok) {
            const PdbFunction *t = PdbResolveRva(&pdb, 0x1040);
            ok                   = t && ZstrCompare(t->name, "in_text") == 0;
        }
        // computed sizes being correct.
        if (ok) {
            const PdbFunction *mid = PdbResolveRva(&pdb, 0x12FF);
            ok                     = mid && ZstrCompare(mid->name, "fn_a") == 0;
        }
        }
        if (ok) {
            const PdbFunction *atb = PdbResolveRva(&pdb, 0x1300);
            ok                     = atb && ZstrCompare(atb->name, "fn_b") == 0;
        }
        // Trailing function: any rva >= its start resolves to it.
        if (ok) {
            const PdbFunction *tail = PdbResolveRva(&pdb, 0x9999);
            ok                      = tail && ZstrCompare(tail->name, "fn_c") == 0;
        }
        // `cur = next` advanced correctly through the overflow branch.
        if (ok) {
            const PdbFunction *r = PdbResolveRva(&pdb, 0x2050);
            ok                   = r && ZstrCompare(r->name, "fn_low") == 0;
        }
        // sides of the block boundary; resolve it to be sure.
        if (ok) {
            const PdbFunction *f = PdbResolveRva(&pdb, 0x3000);
            ok                   = f && ZstrCompare(f->name, "straddling_boundary_function") == 0;
        }
        }
    
        const PdbFunction *first = PdbResolveRva(&pdb, 0x2000);
        ok                       = first && ZstrCompare(first->name, "second_block_function") == 0;
        ok                       = ok && PdbResolveRva(&pdb, 0x1FFF) == NULL; // below first
        const PdbFunction *first = PdbResolveRva(&pdb, 0x2000);
        ok                       = first && ZstrCompare(first->name, "second_block_function") == 0;
        ok                       = ok && PdbResolveRva(&pdb, 0x1FFF) == NULL; // below first
        // Interior of the second-block function resolves to it (greatest
        // rva <= query, not the first/only entry).
        // rva <= query, not the first/only entry).
        if (ok) {
            const PdbFunction *mid = PdbResolveRva(&pdb, 0x2500);
            ok                     = mid && ZstrCompare(mid->name, "second_block_function") == 0;
        }
Last updated on