CILのlogwrites

以前、CIL (C Intermediate Language)を調べたことがありました。そこでの最初のつまずき。

とりあえず、どんなものか動かしてみようと、http://kerneis.github.com/cil/にあるドキュメントを読んで、「7 The CIL Driver」にならってcillyで–dologwritesを使ってみました。

$ cat hello1.c
#include <stdio.h>

main() {
puts(“Hello, World!\n”);
}
$ cilly –save-temps –dologwrites hello1.c -o hello1
gcc -D_GNUCC -E -DCIL=1 hello1.c -o ./hello1.i
/usr/local/libexec/cil/obj/x86_LINUX/cilly.asm.exe –out ./hello1.cil.c –dologwrites ./hello1.i
hello1.c:4: Warning: Body of function main falls-through. Adding a return statement
gcc -D_GNUCC -E ./hello1.cil.c -o ./hello1.cil.i
gcc -D_GNUCC -c -o ./hello1.o ./hello1.cil.i
gcc -D_GNUCC -o hello1 ./hello1.o
$ ./hello1
Hello, World!

いろいろやっても何も起こりません。hello1.cil.cを見ても変わっているところはなさそうです。さんざん試した結果、ためしに別のモジュールを使ってみました。

$ cilly –save-temps –dologcalls hello1.c -o hello1
gcc -D_GNUCC -E -DCIL=1 hello1.c -o ./hello1.i
/usr/local/libexec/cil/obj/x86_LINUX/cilly.asm.exe –out ./hello1.cil.c –dologcalls ./hello1.i
hello1.c:4: Warning: Body of function main falls-through. Adding a return statement
Adding prototype for call logging function printf
gcc -D_GNUCC -E ./hello1.cil.c -o ./hello1.cil.i
gcc -D_GNUCC -c -o ./hello1.o ./hello1.cil.i
./hello1.cil.c:4: 警告: conflicting types for built-in function ‘printf’
gcc -D_GNUCC -o hello1 ./hello1.o
$ ./hello1
enter main
call puts
Hello, World!

return from puts
exit main

cillyはうまく動いているようです。hello1.cil.cもそれなりに処理が追加されていました。

 

cillyがちゃんと動いていそうなことがわかったので、元のlogwritesモジュールはなぜうまくいかなかったかを調べてみると、二つの罠にはまっていました。

罠1

ドキュメントをよく読むと、

--dologwrites. Insert code in the processed source to print the address of all memory writes.

と書いてありました。そう、メモリー書き込み部分にコードが挿入されるのです。そこで、次のコードを試してみました。

$ cat hello2.c
#include <stdio.h>
#include <stdlib.h>

char *p;
main() {
p = (char *)malloc(100);
fgets(p, 100, stdin);
puts(p);
}
$ cilly –save-temps –dologwrites hello2.c -o hello2
gcc -D_GNUCC -E -DCIL=1 hello2.c -o ./hello2.i
/usr/local/libexec/cil/obj/x86_LINUX/cilly.asm.exe –out ./hello2.cil.c –dologwrites ./hello2.i
hello2.c:8: Warning: Body of function main falls-through. Adding a return statement
gcc -D_GNUCC -E ./hello2.cil.c -o ./hello2.cil.i
gcc -D_GNUCC -c -o ./hello2.o ./hello2.cil.i
gcc -D_GNUCC -o hello2 ./hello2.o
$ ./hello2
Hello, World!
Hello, World!

うぅん、何も出力されません。でもhello2.cil.cにはなにやらコードが挿入されています。

罠2

hello2.cil.cを見てみると、

syslog(1, “Write %p to 0x%08x at %s:%d (p)\n”, (char *)tmp, & p, “hello2.c”, 6);

とあります。そこで/var/log/messagesを見てみると、ありました。

hello2: Write 0x95a010 to 0x00600a50 at hello2.c:6 (p)

うぅん、私の知識と読み込みが足りないのはわかっていますが、最初に書く例はもっとわかりやすいものにして欲しい。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA