2011-07-08 13 views
19

En primer lugar, estoy pidiendo esto desde una perspectiva técnica, no una perspectiva del usuario del código de la biblioteca. Un ejemplo de una diferencia es que los objetos compartidos contienen encabezados de programas y los archivos ordinarios de objetos no. ¿Cuáles son las otras diferencias?¿Cuáles son las diferencias de encabezado ELF entre un archivo de objeto ELF y un objeto compartido?

En cuanto a la finalidad de mi pregunta, intento averiguar qué contenido se debe eliminar de un archivo de objeto compartido para que el vinculador lo trate como un archivo de objeto común e intente reubicarlo y vincularlo estáticamente en el archivo ejecutable generado, en lugar de identificarlo como una biblioteca compartida y generar una referencia DT_NEEDED. Esto, a su vez, es el primer paso para la "conversión" primitiva de una biblioteca compartida a algo que puede vincularse estáticamente (sin embargo, es necesario seguir trabajando para hacer que las deslocalizaciones sean satisfactorias).

+0

No es una respuesta a su pregunta, pero puede encontrar la opción '-r' en' ld' useful – bdonlan

+0

Si no son exactamente lo que está buscando, al menos pueden ayudar: http: // statifier. sourceforge.net/ (enlazará libs compartidos directamente en un binario) y http://libraryopt.sourceforge.net/ (rompe una lib compartida, elimina símbolos innecesarios y los reconstruye) ... ¿quizás una combinación de los dos? – technosaurus

+0

Gracias por las ideas, pero no tuve buenos resultados con el estatificador, y me di cuenta de que debería haber una transformación mecánica (aunque moderadamente dolorosa y posiblemente fallida en algunas bibliotecas realmente extrañas con segmentos de carga no estándar) para convertir una biblioteca compartida en una única archivo reubicable '.o' para vinculación estática. –

Respuesta

11

Una de las principales diferencias que encontrará es que, durante la etapa de enlace final, una cantidad de componentes de la biblioteca C están vinculados estáticamente en la biblioteca, formando los símbolos INIT y FINI, entre otras cosas. Se especifican con las entradas DT_INIT y DT_FINI en el encabezado del programa; deberá transformarlos en entradas estáticas de constructor/destructor. Las entradas DT_NEEDED se perderán en una transformación en .o; deberá volver a agregarlos manualmente.

El PLT generado en la etapa de enlace final debe fusionarse con el archivo de salida final o transformarse en reubicaciones normales; esto no es trivial, ya que el PLT es solo código. El GOT también es un problema; está ubicado en un desplazamiento relativo fijo del segmento .text y contiene punteros a los miembros de datos. También, sin embargo, contiene un puntero a la estructura _DYNAMIC, del cual solo puede haber uno por biblioteca o ejecutable. Y no puede cambiar las compensaciones en el GOT, porque están referenciadas directamente desde el código.

Por lo tanto, es bastante difícil convertir un .so en un verdadero .o de nuevo; se perdió información en la conversión a PLT/GOT. Un mejor enfoque podría ser modificar el enlazador dinámico en la biblioteca C para admitir el enlace de una biblioteca compartida que ya está asignada en la memoria como una imagen estática. Es decir, convertiría el .so en un .o simplemente convirtiéndolo en una sección de solo lectura alineada con la página; a continuación, transfiéralo al vinculador dinámico para reasignar con los permisos apropiados y realizar la inicialización de la biblioteca compartida normal. A continuación, agregue un constructor estático para llamar a la biblioteca C para inicializar la biblioteca compartida. Finalmente, agregue los símbolos exportados apropiados para que se correspondan con los símbolos dinámicos en el segmento .text de la biblioteca compartida.

Un problema con este enfoque, sin embargo, es que los constructores estáticos pueden ejecutarse antes que el constructor estático que inicializa su falso solib. En este caso, no deben intentar llamar a funciones desde el solib, o probablemente se bloquee, ya que el solib aún no se ha inicializado. Esto podría evitarse haciendo que los símbolos exportados apunten a una función de trampolín que asegure que el solib se inicialice primero (aunque no tan fácil con los símbolos de datos)

También podría ser útil para usted this previous question .

+3

Lo más importante, sin embargo, el tipo (Elf_Ehdr.e_type) también debe cambiar. (EXEC/DYN vs. REL) –

Cuestiones relacionadas