Есть ли способ переопределить функции со статической областью действия
внутри объектного модуля?
Если я начну с чего-то вроде этого, модуль
с глобальным символом "Foo" является функцией, которая вызывает
местный символ "бар", который называет местный символ "баз"
[scameron@localhost ~]$ 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();
}
[scameron@localhost ~]$ gcc -g -c foo.c
[scameron@localhost ~]$ 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
Он имеет один глобальный, "foo" и два локальных "bar" и "baz."
Предположим, я хочу написать несколько юнит-тестов, которые используют bar и baz,
Я могу сделать:
[scameron@localhost ~]$ cat barbaz
bar
baz
[scameron@localhost ~]$ objcopy --globalize-symbols=barbaz foo.o foo2.o
[scameron@localhost ~]$ 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
[scameron@localhost ~]$
А теперь bar и baz являются глобальными символами и доступны из
вне модуля. Пока все хорошо.
Но что, если я хочу вставить свою собственную функцию поверх
из "баз", и есть ли "бар" называть мой вставленный "баз"?
Есть ли способ сделать это?
- опция переноса, похоже, не делает этого ...
[scameron@localhost ~]$ 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();
}
[scameron@localhost ~]$ gcc -o ibaz ibaz.c foo2.o -Xlinker --wrap -Xlinker baz
[scameron@localhost ~]$ ./ibaz
foo
bar
baz
wrapped baz
[scameron@localhost ~]$
База, вызванная из main (), завернута, но
Бар по-прежнему вызывает локальный баз, а не завернутый баз.
Есть ли способ заставить бар вызывать завернутый баз?
Даже если для этого требуется изменить объектный код, чтобы он соответствовал адресам вызовов функций, если это можно сделать автоматически, это может быть достаточно, но в этом случае он должен работать как минимум на i386 и x86_64. .
- Стив