2011-09-13 13 views
7

Estoy usando ciertas herramientas GNU, es decir, el Compilador GNU C++ (g ++) y el Enlazador GNU (ld) para crear una biblioteca compartida (.so) así como un archivo binario ejecutable.Problema al obtener el enlazador GNU (ld) para exportar un símbolo

El archivo ejecutable binario utiliza 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*"; 
    }; 
}; 

Nota el uso del asterisco (*) en el archivo para forzar al enlazador 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 que el anterior, pero esta vez sin el uso de la opción de línea de comandos -C;

08053da0 T _ZN14ToolboxManager15registerToolboxERSsS0_RSt3mapISsP17Factory_DSPB_BaseSt4lessISsESaISt4pairIKSsS3_EEE 

Hasta ahora, esto se ve bien. La "T" delante 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 ;

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" en frente de la definición del método de clase ToolboxManager::registerToolbox, denota que el método no está definido en el archivo de biblioteca compartida.

Sin embargo, ocurre un problema cuando ejecuto el binario exextible desde la línea de comandos y este problema da como resultado el siguiente mensaje de error;

./toolbox.so: undefined symbol: _ZN14ToolboxManager15registerToolboxERSsS0_RSt3mapISsP17Factory_DSPB_BaseSt4lessISsESaISt4pairIKSsS3_EEE 

La clase nombre del método mangled 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 clase alterado 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 puede verse, los dos nombres alterados 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 opción del vinculador --export-dynamic instruye al enlazador GNU para agregar todos los símbolos de la tabla de símbolos dinámicos.

Si luego ejecutó el ejecutable binario nuevamente. Esta vez ejecutó correctamente el y la llamada a la función dlopen no produjo un error de símbolo indefinido. Esto me tiene completamente 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 de antemano.

Respuesta

3

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 volver a vincular el ejecutable binario, entonces 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.

Cuestiones relacionadas