En sistemas Linux de 32 bits, invocar esto
$ /lib/libc.so.6
y en sistemas de 64 bits esto
$ /lib/x86_64-linux-gnu/libc.so.6
en un shell, proporciona una salida como esta:
GNU C Library stable release version 2.10.1, by Roland McGrath et al.
Copyright (C) 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 4.4.0 20090506 (Red Hat 4.4.0-4).
Compiled on a Linux >>2.6.18-128.4.1.el5<< system on 2009-08-19.
Available extensions:
The C stubs add-on version 2.1.2.
crypt add-on version 2.1 by Michael Glad and others
GNU Libidn by Simon Josefsson
Native POSIX Threads Library by Ulrich Drepper et al
BIND-8.2.3-T5B
RT using linux kernel aio
For bug reporting instructions, please see:
<http://www.gnu.org/software/libc/bugs.html>.
¿Por qué y cómo sucede esto, y cómo es posible hacer lo mismo en otras bibliotecas compartidas?
Miré /usr/lib
para encontrar ejecutables, y encontré /usr/lib/libvlc.so.5.5.0
. Ejecutarlo condujo a una falla de segmentación . : - /
Respuestas:
Esa biblioteca tiene una
main()
función o punto de entrada equivalente, y se compiló de tal manera que sea útil como un objeto ejecutable y como un objeto compartido.Aquí hay una sugerencia sobre cómo hacer esto, aunque no funciona para mí.
Aquí hay otro en una respuesta a una pregunta similar sobre SO , que descaradamente plagiaré, retocaré y agregaré un poco de explicación.
Primero, fuente de nuestra biblioteca de ejemplo
test.c
:Compila eso:
Aquí, estamos compilando una biblioteca compartida (
-fPIC
), pero le decimos al vinculador que es un ejecutable regular (-pie
) y que haga que su tabla de símbolos sea exportable (-Wl,-E
), de modo que pueda vincularse de manera útil.Y, aunque
file
dirá que es un objeto compartido, funciona como un ejecutable:Ahora necesitamos ver si realmente se puede vincular dinámicamente. Un programa de ejemplo
program.c
:El uso
extern
nos ahorra tener que crear un encabezado. Ahora compila eso:Antes de poder ejecutarlo, debemos agregar la ruta del
libtest.so
cargador dinámico:Ahora:
Y
ldd a.out
mostrará el enlace alibtest.so
.Tenga en cuenta que dudo que así sea cómo se compila realmente glibc, ya que probablemente no sea tan portátil como glibc en sí (ver
man gcc
con respecto a los interruptores-fPIC
y-pie
), pero demuestra el mecanismo básico. Para los detalles reales, tendrías que mirar el archivo fuente MAKE.fuente
nm
en la biblioteca compartida, pero no era una versión de depuración. Entonces, ¿por quélibvlc
y otros se estrellan?libc
es una excepción.ld
ylibpthread
.ld.so
es especial en otros aspectos. Hasta cierto punto, es más un ejecutable real que un ejecutable vinculado dinámicamente normal.Vamos a buscar una respuesta en el repositorio glibc aleatorio en github. Esta versión proporciona un "banner" en el archivo
version.c
.En el mismo archivo hay algunos puntos interesantes:
__libc_print_version
la función que proporciona la impresión en el mismo texto y símbolo__libc_main (void)
que se documenta como un punto de entrada. Entonces se llama a este símbolo cuando se ejecuta la biblioteca.Entonces, ¿cómo sabe el enlazador / compilador que esta es exactamente la función del punto de entrada?
Vamos a sumergirnos en el archivo MAKE . En las banderas de enlace hay una bandera interesante:
Entonces, este es el indicador de enlace para establecer el punto de entrada en la biblioteca. Al crear una biblioteca, puede proporcionar un
-e function_name
comportamiento ejecutable para crear enlaces. ¿Qué es lo que realmente hace? Veamos el manual (algo anticuado pero aún válido) :(la documentación actual se puede encontrar aquí )
Realmente
ld
linker crea un ejecutable con función de punto de entrada si le proporciona la opción de línea de comando-e
(la solución más práctica), proporciona un símbolo de funciónstart
o inyecta una dirección de símbolo en el ensamblador.Sin embargo, tenga en cuenta que claramente no se garantiza que funcione con otros vinculadores (no sé si llvm's lld tiene la misma bandera). Por qué esto debería ser útil para fines distintos de proporcionar información sobre ese archivo, no lo sé.
fuente