ElfResolveAddress
Description
Look up the symbol whose [value, value+size) range contains vaddr. Searches symbols first, then dynamic_symbols — so static (non-exported) functions resolve when .symtab is present.
vaddr is the file-relative virtual address — i.e. for a runtime pointer in a ET_DYN (PIE / shared object), the caller subtracts the load base first. For ET_EXEC it’s the address as-is.
Parameters
| Name | Direction | Description |
|---|---|---|
self |
in | Parsed ELF file. |
vaddr |
in | Virtual address to resolve. |
Success
Returns a pointer to the matching ElfSymbol. The pointer is valid until ElfDeinit.
Failure
Returns NULL if no symbol covers vaddr.
Usage example (Cross-references)
Usage examples (Cross-references)
- In
Elf.c:576:
}
const ElfSymbol *ElfResolveAddress(const Elf *self, u64 vaddr) {
if (!self)
return NULL;- In
Elf.c:426:
// Exactly at the symbol start.
const ElfSymbol *s = ElfResolveAddress(&elf, FUNC_VADDR);
bool ok = s && s->name && ZstrCompare(s->name, "my_func") == 0;- In
Elf.c:430:
// Inside the body.
s = ElfResolveAddress(&elf, FUNC_VADDR + FUNC_SIZE / 2);
ok = ok && s && ZstrCompare(s->name, "my_func") == 0;- In
Elf.c:434:
// Last covered byte.
s = ElfResolveAddress(&elf, FUNC_VADDR + FUNC_SIZE - 1);
ok = ok && s && ZstrCompare(s->name, "my_func") == 0;- In
Elf.c:438:
// Just past the end -> no match.
s = ElfResolveAddress(&elf, FUNC_VADDR + FUNC_SIZE);
ok = ok && s == NULL;- In
Elf.c:442:
// Below the symbol -> no match.
s = ElfResolveAddress(&elf, FUNC_VADDR - 1);
ok = ok && s == NULL;- In
Elf.c:1781:
bool ok = true;
s = ElfResolveAddress(&elf, SF_ALPHA_VADDR); // exact start
ok = ok && s && s->name && ZstrCompare(s->name, "alpha") == 0;
s = ElfResolveAddress(&elf, SF_ALPHA_VADDR + SF_ALPHA_SIZE - 1); // last byte
- In
Elf.c:1783:
s = ElfResolveAddress(&elf, SF_ALPHA_VADDR); // exact start
ok = ok && s && s->name && ZstrCompare(s->name, "alpha") == 0;
s = ElfResolveAddress(&elf, SF_ALPHA_VADDR + SF_ALPHA_SIZE - 1); // last byte
ok = ok && s && s->name && ZstrCompare(s->name, "alpha") == 0;
s = ElfResolveAddress(&elf, SF_ALPHA_VADDR + SF_ALPHA_SIZE); // just past
- In
Elf.c:1785:
s = ElfResolveAddress(&elf, SF_ALPHA_VADDR + SF_ALPHA_SIZE - 1); // last byte
ok = ok && s && s->name && ZstrCompare(s->name, "alpha") == 0;
s = ElfResolveAddress(&elf, SF_ALPHA_VADDR + SF_ALPHA_SIZE); // just past
ok = ok && (s == NULL || ZstrCompare(s->name, "alpha") != 0);- In
Elf.c:1802:
return false;
}
const ElfSymbol *hit = ElfResolveAddress(&elf, SF_BETA_VADDR);
const ElfSymbol *miss = ElfResolveAddress(&elf, SF_BETA_VADDR + 1);
bool ok = hit && hit->name && ZstrCompare(hit->name, "beta") == 0 && miss == NULL;- In
Elf.c:1803:
}
const ElfSymbol *hit = ElfResolveAddress(&elf, SF_BETA_VADDR);
const ElfSymbol *miss = ElfResolveAddress(&elf, SF_BETA_VADDR + 1);
bool ok = hit && hit->name && ZstrCompare(hit->name, "beta") == 0 && miss == NULL;
ElfDeinit(&elf);- In
Elf.c:1821:
return false;
}
const ElfSymbol *s = ElfResolveAddress(&elf, SF_BETA_VADDR);
bool ok = s && s->name && ZstrCompare(s->name, "beta") == 0 && s->bind == ELF_SYMBOL_BIND_GLOBAL;
ElfDeinit(&elf);- In
Elf.c:1842:
// [0x1000, 0x1040). best starts at alpha; local is seen later and must
// NOT displace it because local is not GLOBAL.
const ElfSymbol *s = ElfResolveAddress(&elf, SF_ALPHA_VADDR + 4);
bool ok = s && s->name && ZstrCompare(s->name, "alpha") == 0 && s->bind == ELF_SYMBOL_BIND_GLOBAL;
ElfDeinit(&elf);- In
Stripped.c:70:
// (3) Symbol lookup against .symtab/.dynsym should miss for our
// static helpers (they're not exported, and .symtab is gone).
const ElfSymbol *sym = ElfResolveAddress(&stripped, file_relative);
bool sym_missing_or_unnamed = (!sym) || (sym && (!sym->name || !sym->name[0]));
if (!sym_missing_or_unnamed) {
Last updated on