Is it possible to lookup the location of a function using ELF? Similar to what
void *f = dlopen(NULL,..);
void *func = dlsym(f, "myfunc");
does, but without requiring -rdynamic
during compilation?
I can see using nm
that the naming of the items is still present in a compiled binary?:
0000000000400716 T lookup
0000000000400759 T main
Can I use this information to locate the items once the program is loaded into memory?
Can I use this information to locate the items once the program is loaded into memory?
You sure can: iterate over all symbols in the a.out
until you find the matching one. Example code to iterate over symbols is here. Or use libelf.
If you need to perform multiple symbol lookups, iterate once (slow) over all symbols, build a map from symbol name to its address, and perform lookups using that map.
Update:
The example you point to seems incomplete? It uses data and elf, where are they coming from?
Yes, you need to apply a little bit of elbow grease to that example.
The data
is location in memory where the a.out
is read
into, or (better) mmap
ed.
You can either mmap
the a.out
yourself, or find the existing mapping via e.g. getauxval(AT_PHDR)
rounded down to page size.
The ehdr
is (ElfW(Ehdr) *)data
(that is, data
cast to Elf32_Ehdr
or Elf64_Ehdr
as appropriate.
If this is not clear, then you probably should just use libelf
, which takes care of the details for you.
Also, does ELF only allow me to find the name of the symbol, or can it actually give me the pointer to the in memory location of the symbol?
It can give you both: str + sym[i].st_name
is the name, sym[i].st_value
is the pointer (the value displayed by nm
).
(presumably the e.g. 0000000000400716 is some relative base address, not the actual in memory location, right?)
No, actually (for this binary) it's the absolute address.
Position-independent binaries do use relative addresses (so you'll need something like getauxval
mentioned above to find the base location of such executable), but this particular binary looks like ET_EXEC
(use readelf -h a.out
to verify this). The address 0x400000
is typical address for loading of non-PIE executables on Linux x86_64 (which is probably what your system is).