Utilizzando libtool per caricare un nome di funzione duplicato da una libreria condivisa
-
19-09-2019 - |
Domanda
Sto cercando di creare un 'debug' libreria condivisa (cioè, il file .so o dll) che chiama un altro 'reale' libreria condivisa che ha la stessa API C come la biblioteca di debug (in questo caso, per emulare il PKCS # 11 API). Comunque, sto correndo nei guai in cui la mappa di collegamento della libreria di debug è in conflitto con quello della vera biblioteca e causando la libreria di debug per richiamare le proprie funzioni al posto delle corrispondenti funzioni nella vera e propria biblioteca. Ho trovato una soluzione a questo problema utilizzando il comando POSIX dlmopen, ma vorrei capire se lo stesso è possibile utilizzando libtool GNU.
Sul mio sistema Solaris 10, il seguente codice fallisce l'asserzione quando un'applicazione di prova collega in modo statico alla libreria di debug:
#include <dlfcn.h>
int MyFunctionName() {
int (*function_ptr)();
void *handle = dlopen("realsharedlibrary.so", RTDL_LAZY);
*(void **)(&function_ptr) = dlsym(handle, "MyFunctionName");
ASSERT(function_ptr != MyFunctionName); // Fails
return (*function_ptr)();
}
In questo caso, ho un puntatore a funzione alla 'MyFunctionName' locale (nella libreria di debug) al posto del MyFunctionName all'interno della vera libreria condivisa.
ho scoperto che è possibile aggirare questo problema utilizzando il comando 'dlmopen' invece di 'dlopen', e dicendo dlmopen per creare una nuova mappa di collegamento (con il parametro LM_ID_NEWLM
) quando si carica la vera libreria:
int MyFunctionName() {
int (*function_ptr)();
void *handle = dlmopen(LM_ID_NEWLM, "realsharedlibrary.so", RTDL_LAZY);
*(void **)(&function_ptr) = dlsym(handle, "MyFunctionName");
ASSERT(function_ptr != MyFunctionName); // succeeds
return function_ptr(); // call real function
}
Purtroppo, dlmopen non sembra essere incluso all'interno libtool (vale a dire, non vedo una funzione lt_dlmopen in libtool).
E 'possibile fare la stessa cosa utilizzando i comandi libtool - cioè, di creare una nuova mappa di collegamento quando si carica la nuova libreria in modo che non si scontrano con la mappa di collegamento della libreria di debug
?Soluzione
Non ho trovato un buon modo per utilizzare libtool per risolvere questo problema ancora, ma c'è un modo per evitare i Solaris-specifiche 'dlmopen' funzione utilizzando dlopen con queste bandiere:
void *handle = dlopen("realsharedlibrary.so", RTLD_NOW | RTLD_GROUP | RTLD_LOCAL)
A quanto pare, il problema del simbolo-collisioni è risolto utilizzando RTLD_NOW
invece di RTLD_LAZY
e con l'aggiunta di RTLD_GROUP
. Il RTLD_LOCAL
c'è perché POSIX richiede utilizzando RTLD_LOCAL
o RTLD_GLOBAL
, o il comportamento è indefinito. Per Solaris, il comportamento è quello di default RTLD_LOCAL
.
La questione aperta, però, è se è possibile passare questi tipi di bandiere a lt_dlopen.