Reputation: 2110
At runtime I need to print out an address, and then find which function that address is part of. The functions are in a shared library so are not at a fixed address. My map file obviously just shows the relative offsets for each shared library func. Is it possible at runtime to query where a library has been loaded, so that I can subtract that value from my address to get the correct map file offset?
Currently I'm doing a slightly hacky approch whereby I also print out the address of one function in the library, then find that function in the map file to figure out where the load address must be. I would rather have a generic method that didn't require you to name a reference function.
(GDB is not available in my setup). Thanks.
Upvotes: 11
Views: 12475
Reputation: 4395
Check the System V ABI, chapter 5. For the lazy ones out there, here is the standard way to do this for systems supporting the ELF binary format:
#include <link.h>
off_t load_offset;
for (Elf64_Dyn *dyn = _DYNAMIC; dyn->d_tag != DT_NULL; ++dyn) {
if (dyn->d_tag == DT_DEBUG) {
struct r_debug *r_debug = (struct r_debug *) dyn->d_un.d_ptr;
struct link_map *link_map = r_debug->r_map;
while (link_map) {
if (strcmp(link_map->l_name, libname) == 0) {
load_offset = (off_t)link_map->l_addr;
break;
}
link_map = link_map->l_next;
}
break;
}
}
This does not rely on any GNU extension.
On GNU systems, the macro ElfW(Dyn) will return either Elf64_Dyn or Elf32_Dyn which is handy.
Upvotes: 2
Reputation: 361
dladdr does this, end of. :-)
More comprehnsively, dladdr will take an address and work out which library and symbol it corresponds to... and then it'll give you the name of the library, the name of the symbol, and the base addresses of each. Personally I think that's nifty, it's also making my current debugging job a lit easier.
Hope this helps!
Upvotes: 8
Reputation: 61
Try to take a look at /proc/[PID]/maps file. This should contain the address of library mapping in process memory address space.
If you want to reach the executable portion, use readelf on your library and find the offset of .text section.
Upvotes: 4
Reputation: 99993
On a recent linux, you can use dl_iterate_phdr
to find out the addresses of the shared libs.
Upvotes: 8
Reputation: 33385
GNU backtrace library?
I wouldn't rely on hacky approaches for something like this. I don't think there's any guarantee that the contents of libraries are loaded into contiguous memory.
Upvotes: 0