¿Hay alguna manera de anular las funciones con el alcance estático dentro de un módulo de objeto?¿Es posible anular las funciones estáticas en un módulo de objeto (gcc, ld, x86, objcopy)?
Si comienzo con algo como esto, un módulo con el símbolo "foo" global es una función que se llama símbolos local "barra", que llama a símbolos local "Baz"
[[email protected] ~]$ cat foo.c
#include <stdio.h>
static void baz(void)
{
printf("baz\n");
}
static void bar(void)
{
printf("bar\n");
baz();
}
void foo(void)
{
printf("foo\n");
bar();
}
[[email protected] ~]$ gcc -g -c foo.c
[[email protected] ~]$ objdump -x foo.o | egrep 'foo|bar|baz'
foo.o: file format elf32-i386
foo.o
00000000 l df *ABS* 00000000 foo.c
00000000 l F .text 00000014 baz
00000014 l F .text 00000019 bar
0000002d g F .text 00000019 foo
Tiene uno global, "foo" y dos locales "bar" y "baz".
Supongamos que quiero escribir algunas pruebas unitarias que ejercen bar y baz, que puedo hacer:
[[email protected] ~]$ cat barbaz
bar
baz
[[email protected] ~]$ objcopy --globalize-symbols=barbaz foo.o foo2.o
[[email protected] ~]$ objdump -x foo2.o | egrep 'foo|bar|baz'
foo2.o: file format elf32-i386
foo2.o
00000000 l df *ABS* 00000000 foo.c
00000000 g F .text 00000014 baz
00000014 g F .text 00000019 bar
0000002d g F .text 00000019 foo
[[email protected] ~]$
Y ahora bar y baz son símbolos globales y accesible desde el exterior del módulo . Hasta aquí todo bien.
Pero lo que si quiero interponer mi propia función en la parte superior de "Baz", y tienen "barra" llamar a mi interpuesta "Baz"?
¿Hay alguna manera de hacerlo?
opción --wrap no parece hacerlo ...
[[email protected] ~]$ cat ibaz.c
#include <stdio.h>
extern void foo();
extern void bar();
void __wrap_baz()
{
printf("wrapped baz\n");
}
int main(int argc, char *argv[])
{
foo();
baz();
}
[[email protected] ~]$ gcc -o ibaz ibaz.c foo2.o -Xlinker --wrap -Xlinker baz
[[email protected] ~]$ ./ibaz
foo
bar
baz
wrapped baz
[[email protected] ~]$
El Baz llamada de la principal consiguió envuelto(), pero bar todavía llama a la no Baz Baz local de la envuelta.
¿Hay alguna manera de hacer que la barra llame al baz envuelto?
Incluso si se requiere modificar el código objeto para jugar con las direcciones de las llamadas a funciones, si eso se puede hacer de manera automática, eso podría ser suficiente, pero en ese caso debe funcionar al menos en i386 y x86_64.
- Steve
No he usado símbolos débiles todavía, pero suenan como baz de debilitamiento de su módulo original que le permitirán reemplazarlo por uno nuevo – x539
Imagino que si trata de hacer tales cosas, no tiene acceso a la fuente código –
Tengo acceso al código fuente, pero preferiría no modificar la fuente de la forma habitual de prueba unitaria. En realidad, esto es para probar un módulo de kernel de Linux. En sentido ascendente, por lo general no les gusta que pongan cambios en la fuente solo para acomodar cosas que no son kernel, y para la compatibilidad de parches, no quiero meterme con la fuente innecesariamente. – smcameron