2011-05-31 15 views
7

Tengo un complemento en forma de biblioteca compartida (bar.so) que enlaza con un programa más grande (foo). Tanto foo como bar.so dependen de la misma biblioteca de terceros (baz) pero necesitan mantener sus implementaciones de baz completamente separadas. Así que cuando conecto foo (usando los archivos de objetos y archivos suministrados), necesito que ignore cualquier uso de baz en bar.so y viceversa.¿Cómo restringir el acceso a los símbolos en un objeto compartido?

En este momento, si me enlace foo con --trace-symbol=baz_fun donde baz_fun es uno de los símbolos ofensivos que recibo el siguiente resultado:

bar.so: definition of baz_fun 
foo/src.a(baz.o): reference to baz_fun 

creo que esto me está diciendo que hace referencia a foo baz_fun de bar.so (y la ejecución de foo confirma esto).

Soluciones que he intentado:

  • Uso objcopy "localizar" los símbolos de interés: objcopy --localize-symbols=local.syms bar.so donde local.syms contiene todos los símbolos de interés. Creo que podría confundirme aquí y tal vez "local" no significa lo que creo que significa. De todos modos, obtengo el mismo resultado del enlace de arriba. Debo señalar que si ejecuto la herramienta nm en bar.so antes de usar objcopy, todos los símbolos en cuestión tienen el indicador T (mayúsculas indicando global) y después de objcopy tienen un t indicando que son locales ahora. Entonces parece que estoy usando objcopy correctamente.
  • Compilación con -fvisibility=hidden Sin embargo, debido a algunas otras limitaciones, necesito utilizar GCC 3.3, que no parece ser compatible con esa característica. Es posible que pueda actualizar a una versión más nueva de GCC, pero me gustaría que me confirme que compilar con esta bandera me ayudará antes de ir por ese camino.

Otras cosas a tener en cuenta:

  • no tengo acceso al código fuente de cualquiera de foo o Baz
  • yo preferiría mantener toda mi plug-in en un objeto compartido (bar.so). Baz es en realidad una biblioteca de licencias, así que no quiero que separa

Respuesta

3

Uso dlopen para cargar el plugin con RTLD_DEEPBIND bandera.

(editar)

Tenga en cuenta que RTLD_DEEPBIND es específica de Linux y la necesidad glibc 2.3.4 o posterior.

+0

Tal vez estoy malentendido, pero ¿cómo puedo hacer esto si no tengo acceso al código fuente de foo que carga mi complemento, bar.so? – brady

+0

Ok, si solo controla la barra y no foo, puede dividir la barra en dos bibliotecas, bar1 y bar2. bar1 proporciona la interfaz del complemento y reenvía todas las llamadas a bar2, y bar2 implementa todo. bar1 debe llamar a 'dlopen (" libbar2.so ", RTLD_NOW | RTLD_DEEPBIND)' y 'dlsym' todas las funciones que necesita. O puede mantener una barra, y 'dlopen (" libbaz.so ", RTLD_NOW | RTLD_DEEPBIND)' desde allí, y 'dlsym' todas las funciones que necesite. Utilice el método que necesite menos llamadas a 'dlsym'. –

Cuestiones relacionadas