Question

Here's the setup:

  1. There's an application A that loads liba.so (linked at compile time)
  2. liba.so exports a symbol expA
  3. I don't control either A or liba.so
  4. Application A can load a library I specify, libmine.so, into the same process via dlopen (think plugin architecture)
  5. I need to use expA from libmine.so but don't know how to find it without explicitly linking against liba.so, which is what I've been doing so far. I assume this won't work in the real world since that symbol is not guaranteed to be at the same address as the one in my local copy of liba.so (or is it?). libmine.so will be closed-source and can't be recompiled with A.

I've never done anything like this, so am a bit unclear on the details of library loading. For example, if I try to dlopen("liba.so") from within libmine.so, will I get a handle to the already loaded library or a new copy?

In terms of how libmine.so is loaded, all I know is that it will be loaded with RTLD_LAZY (and nothing else).

Any help and pointers would be greatly appreciated!

Was it helpful?

Solution

If all the liba.so library is dlopened using RTLD_GLOBAL, then you can use dlsym(RTLD_DEFAULT, "expA") to find the symbol without needing to reopen the library.

If the liba.so library is dlopened using RTLD_LOCAL then you will need to obtain a handle to the library using dlopen again within your own libmine.so. Note the following:

If the same library is loaded again with dlopen(), the same file handle is returned. The dl library maintains reference counts for library handles, so a dynamic library is not deallocated until dlclose() has been called on it as many times as dlopen() has succeeded on it. The _init() routine, if present, is only called once. But a subsequent call with RTLD_NOW may force symbol resolution for a library earlier loaded with RTLD_LAZY.

i.e. it's the same copy of the library.

the mechanism is (pseudo), assuming expA is a function: int expA(int value):

int (*fpointer)(int) = NULL;

void *handle = dlopen("liba.so", RTLD_LAZY | RTLD_LOCAL);
if (handle != NULL) {
    void *symbol = dlsym(handle, "expA");
    if (symbol != NULL) {
        fpointer = (int (*)(int ))symbol;
    }
}

That's pseudo code, with little to no error handling.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top