c - linux interfaz de llamadas al sistema
¿Cómo puedo volver a implementar(o ajustar) una función syscall en Linux? (2)
Los símbolos son resueltos por el enlazador en el orden en que los enumera en la línea de comando, por lo que si incluyó su biblioteca antes de la biblioteca estándar tendría prioridad. Para gcc necesitarías especificar
gcc <BLAH> -nodefaultlibs <BLAH BLAH> -lYOUR_LIB <OTHER_LIBS>
De esta manera sus bibliotecas serían buscadas y encontradas primero.
Supongamos que quiero ocuparme completamente de la llamada al sistema abierto (), tal vez para ajustar el syscall real y realizar algún registro. Una forma de hacer esto es usar LD_PRELOAD para cargar una biblioteca de objetos compartida (hecha por el usuario) que toma el punto de entrada abierto ().
La rutina open () hecha por el usuario obtiene el puntero a la función glibc open()
al dlsym()
y lo llama.
La solución propuesta anteriormente es una solución dinámica, sin embargo. Supongamos que quiero vincular mi propia envoltura open()
estáticamente. ¿Cómo lo haría? Supongo que el mecanismo es el mismo, pero también supongo que habrá un conflicto de símbolos entre el open()
definido por el usuario y el libc open()
.
Por favor comparte cualquier otra técnica para lograr el mismo objetivo.
Puede utilizar la función de ld
proporcionada por ld
. Del man ld
:
--wrap symbol
Use una función de envoltura para el símbolo. Cualquier referencia indefinida alsymbol
se resolverá a__wrap_symbol
.Cualquier referencia no definida a
__real_symbol
se resolverá comosymbol
.
Así que solo tiene que usar el prefijo __wrap_
para su función de envoltura y __real_
cuando quiera llamar a la función real. Un ejemplo simple es:
malloc_wrapper.c
:
#include <stdio.h>
void *__real_malloc (size_t);
/* This function wraps the real malloc */
void * __wrap_malloc (size_t size)
{
void *lptr = __real_malloc(size);
printf("Malloc: %lu bytes @%p/n", size, lptr);
return lptr;
}
Aplicación de prueba testapp.c
:
#include <stdio.h>
#include <stdlib.h>
int main()
{
free(malloc(1024)); // malloc will resolve to __wrap_malloc
return 0;
}
Luego compila la aplicación:
gcc -c malloc_wrapper.c
gcc -c testapp.c
gcc -Wl,-wrap,malloc testapp.o malloc_wrapper.o -o testapp
La salida de la aplicación resultante será:
$ ./testapp
Malloc: 1024 bytes @0x20d8010