Finding the load address of a shared library in Linux
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.
On a recent linux, you can use dl_iterate_phdr
to find out the addresses of the shared libs.
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!
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.
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.
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.
精彩评论