オブジェクトモジュール内の静的スコープで関数をオーバーライドする方法はありますか?
このようなものから始めると、グローバルシンボル「foo」を持つモジュールは、ローカルシンボル「bar」を呼び出す関数であり、ローカルシンボル「baz」を呼び出します。
[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
1つのグローバル「foo」と2つのローカル「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はグローバルシンボルであり、モジュールの外部からアクセスできます。ここまでは順調ですね。
しかし、「baz」の上に自分の関数を挿入し、「bar」に挿入した「baz」と呼ばせる場合はどうなりますか?
それを行う方法はありますか?
--wrapオプションはそれを行わないようです...
[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()から呼び出されたbazはラップされましたが、barはラップされたbazではなくローカルbazを呼び出します。
バーにラップされたバズを呼び出させる方法はありますか?
オブジェクトコードを変更して関数呼び出しのアドレスをいじくり回す必要がある場合でも、自動化された方法で実行できれば十分かもしれませんが、その場合は少なくともi386とx86_64で動作する必要があります。
-スティーブ