Yang Jim
Yang Jim

Reputation: 13

C++ linux: How to get an exported function's address from a loaded library?

I've tried to approch this the default way, dlopen the library and dlsym it. But when I dlopen it, this error pops up: dlopen failed: library "libfmod.so" not found: needed by /.../libSwordsman.so in namespace (default)

However, when I go into proc/self/maps, the libfmod.so is loaded, but the dlopen still refuses to load libSwordsman.so. After reading some docs, I used RTLD_NOLOAD to test if it can retrive the handle, but it returns null, which means its not loaded acc to the docs.

dlopen failed: library "/.../libSwordsman.so" wasn't loaded

But I clearly see its loaded in the /proc/self/maps file. And dladdr the Base Address I found in proc/maps returns a vaild Dl_info pointer with the correct value. So maybe this library didnt get loaded via dlopen? I searched about other ways to load a library, and found nothing. I was going to use the dladdr1 api with the flag RTLD_DL_LINKMAP to retrive a pointer to a link_map (which is the "handle" that dlopen gives you but in void*) but I realize that android dont have this api.

So now my best bet is to use the base addr and calc every function offset to it, but I would prefer dlsym to save time if you guys can think of a way to obtain this so's handle.

Upvotes: 1

Views: 546

Answers (1)

Lorinczy Zsigmond
Lorinczy Zsigmond

Reputation: 1910

Your problem X is this:

dlopen failed: library "libfmod.so" not found: needed by /.../libSwordsman.so in namespace (default)

This means that ELF-header of libSwordsman.so doesn't contain the path to find libfmod.so.

The solution is using option -Wl,-rpath,/some/where/lib/ when linking libSwordman.so

Explanation: loading-time, the dependent libraries have to be found in the file-system, even if they are already loaded into memory.

It is not enough that a library with the same name (libfmod.so) is already loaded: the device/inode numbers have to match. (To verify the matching, the loader first finds the shared library in the file-system using the rpath (or runpath) entries in the main executable and/or the calling shared object.)

Note: calling dlopen(RTLD_NOLOAD) doesn't help before a successful load of that library. (For example, if I want a dlopen-handle to glibc (libc.so.6), I can use RTLD_NOLOAD, because it is quite likely to have been already loaded.)

Upvotes: 1

Related Questions