linker gnu ld

linker - Problema al obtener el enlazador GNU(ld) para exportar un símbolo



(1)

He logrado resolver este problema. He encontrado que si elimino las comillas de la siguiente línea;

"ToolboxManager::registerToolbox*"

dentro del archivo ${top_srcdir}/dynamic_symbol_table.txt y luego vuelve a vincular el ejecutable binario, luego funciona. Es decir, la función dlopen ya no fallará.

No puedo evitar preguntarme si hubiera sido más apropiado hacer esta pregunta en la lista de correo de GNU binutils que aquí en este sitio web.

Estoy usando ciertas herramientas de GNU, es decir, el Compilador C ++ de GNU (g ++) y el Enlazador GNU (ld) para crear un archivo de biblioteca compartida (.so), así como un archivo ejecutable binario.

El archivo ejecutable binario hace uso de la función dlopen para cargar dinámicamente el archivo de biblioteca compartida en tiempo de ejecución. Además de esto, el archivo de biblioteca compartida necesita invocar un método de clase particular (llamado ToolboxManager::registerToolbox ) que se define dentro del ejecutable binario. Esto se soluciona obligando al ejecutable binario a exportar el método de clase, que a su vez se lleva a cabo en tiempo de enlace al vincular el ejecutable binario con las siguientes opciones de línea de comando;

-Wl,--dynamic-list=${top_srcdir}/dynamic_symbol_table.txt

donde el archivo ${top_srcdir}/dynamic_symbol_table.txt contiene el siguiente contenido;

{ extern "C++" { "ToolboxManager::registerToolbox*"; }; };

Tenga en cuenta el uso del asterisco (*) en el archivo para obligar al vinculador a exportar todos los símbolos que comienzan con ToolboxManager::registerToolbox .

Cuando ejecuto la utilidad GNU nm ( nm -C -g ./a.out ) en el ejecutable binario resultante, muestra la siguiente información sobre el método de clase mencionado anteriormente;

08053da0 T ToolboxManager::registerToolbox ( std::string&, std::string&, std::map < std::string, Factory_DSPB_Base*, std::less < std::string >, std::allocator < std::pair < std::string const, Factory_DSPB_Base* > > >& )

o, si la utilidad nm se invoca como se indicó anteriormente, pero esta vez sin el uso del interruptor de línea de comando -C;

08053da0 T _ZN14ToolboxManager15registerToolboxERSsS0_RSt3mapISsP17Factory_DSPB_BaseSt4lessISsESaISt4pairIKSsS3_EEE

Hasta el momento, esto se ve bien. La "T" al frente de la definición del método de clase ToolboxManager::registerToolbox , denota que el método reside dentro de la sección Texto / Código del archivo.

De forma similar, si ejecuto la utilidad nm ( nm -C -g ./toolbox.so ) en el archivo de biblioteca compartida, muestra la siguiente información sobre el mismo método de clase mencionado anteriormente;

U ToolboxManager::registerToolbox ( std::string&, std::string&, std::map < std::string, Factory_DSPB_Base*, std::less < std::string >, std::allocator < std::pair < std::string const, Factory_DSPB_Base* > > >& )

Esto también se ve bien. La "U" delante de la definición del método de clase ToolboxManager::registerToolbox indica que el método no está definido en el archivo de biblioteca compartida.

Sin embargo, se produce un problema cuando ejecuto el binario que se puede ejecutar desde la línea de comandos y este problema genera el siguiente mensaje de error;

./toolbox.so: undefined symbol: _ZN14ToolboxManager15registerToolboxERSsS0_RSt3mapISsP17Factory_DSPB_BaseSt4lessISsESaISt4pairIKSsS3_EEE

El nombre del método de clase destrozado que aparece en este mensaje de tiempo de ejecución se muestra a continuación, como la primera de las dos líneas. Para fines de comparación, el nombre del método de la clase destrozada de arriba (y que se generó utilizando el comando nm -g ) se muestra a continuación como la segunda de las dos líneas;

_ZN14ToolboxManager15registerToolboxERSsS0_RSt3mapISsP17Factory_DSPB_BaseSt4lessISsESaISt4pairIKSsS3_EEE _ZN14ToolboxManager15registerToolboxERSsS0_RSt3mapISsP17Factory_DSPB_BaseSt4lessISsESaISt4pairIKSsS3_EEE

Como se puede ver, los dos nombres mutilados son idénticos. Por lo tanto, no puedo entender por qué el símbolo indefinido no puede resolverse en tiempo de ejecución.

Luego volví a vincular el ejecutable binario, sin embargo, esta vez reemplacé el siguiente comando del enlazador;

-Wl,--dynamic-list=${top_srcdir}/dynamic_symbol_table.txt

con el este;

-Wl,--export-dynamic

La --export-dynamic linker indica al --export-dynamic GNU que agregue todos los símbolos a la tabla de símbolos dinámicos.

Si luego se ejecutó el ejecutable binario de nuevo. Esta vez se ejecutó correctamente y la llamada a la función dlopen no dio como resultado un error de símbolo indefinido. Esto me tiene totalmente perplejo, ya que parece que el símbolo se está exportando correctamente en la versión inicial del ejecutable binario. ¿Alguien puede ver el problema aquí? Cualquier ayuda sería inmensamente apreciada.

Gracias por adelantado.