tipos texto lista informatica extensiones ejemplos ejecutables archivos c linux shared-libraries glibc dlopen

texto - construyendo un.so que también es un ejecutable



tipos de archivos y extensiones en informatica (3)

La creación de su biblioteca compartida con la opción -pie parece darle todo lo que desea:

/* pie.c */ #include <stdio.h> int foo() { printf("in %s %s:%d/n", __func__, __FILE__, __LINE__); return 42; } int main() { printf("in %s %s:%d/n", __func__, __FILE__, __LINE__); return foo(); } /* main.c */ #include <stdio.h> extern int foo(void); int main() { printf("in %s %s:%d/n", __func__, __FILE__, __LINE__); return foo(); } $ gcc -fPIC -pie -o pie.so pie.c -Wl,-E $ gcc main.c ./pie.so $ ./pie.so in main pie.c:9 in foo pie.c:4 $ ./a.out in main main.c:6 in foo pie.c:4 $

PS glibc implementa write(3) través de la llamada al sistema porque no tiene otro lugar para llamar (ya es el nivel más bajo). Esto no tiene nada que ver con poder ejecutar libc.so.6 .

Así que probablemente todos sepan que glibc /lib/libc.so.6 se puede ejecutar en el shell como un ejecutable normal, en cuyo caso imprime su información de versión y sale. Esto se hace mediante la definición de un punto de entrada en .so. En algunos casos, podría ser interesante usar esto también para otros proyectos. Desafortunadamente, el punto de entrada de bajo nivel que puede establecer mediante la opción -e de ld es un nivel demasiado bajo: el cargador dinámico no está disponible, por lo que no puede llamar a ninguna función de biblioteca adecuada. glibc por esta razón implementa la llamada al sistema write () a través de una llamada al sistema desnuda en este punto de entrada.

Mi pregunta ahora es, ¿alguien puede pensar de una buena manera cómo uno puede arrancar un enlazador dinámico completo desde ese punto de entrada para poder acceder a las funciones de otros .so?


No es una buena manera, pero crearía un pequeño envoltorio ejecutable alrededor del .so que llama a la función de punto de entrada que quiero ejecutar.


Supongo que tendrías tu ld -e apuntar a un punto de entrada que luego usaría la familia de funciones dlopen() para encontrar y cargar el resto del enlazador dinámico. Por supuesto, debe asegurarse de que dlopen() mismo esté enlazado estáticamente o tenga que implementar suficiente de su propio código auxiliar de enlace para llegar a él (utilizando interfaces de llamadas del sistema como mmap() tal como lo hace libc.

Nada de eso me suena "agradable". De hecho, solo la idea de leer las fuentes glibc (y el código fuente ld-linux , como un ejemplo) lo suficiente como para evaluar el tamaño del trabajo me parece bastante canoso. También podría ser una pesadilla de portabilidad. Puede haber diferencias importantes entre cómo Linux implementa ld-linux y cómo se realizan los enlaces en OpenSolaris, FreeBSD, etc. (No lo sé).