■
やや続き。暇つぶしに。
DWARF2を見てると、メモリアロケート時の手間だけでなんとなくいけるような気がしてきた。
struct nanika *p = gc_malloc( get_type_info("nanika") );
どうしても、こんな感じになってしまうけど。
struct nanika *p = malloc( sizeof(struct nanika) );
大して手間は変わらないはず。
ただ、型の名前空間がひとつしかなくて、プログラム内で、同じ名前の型をひとつしか作れない、という問題があるのだけど。その問題を避けるには、
/* file.c で定義されてる 型 nanika */ struct nanika *p = gc_malloc( get_type_info("file.c","nanika") );
こんな感じになってしまう。
が、まあ、それはそのうちなんとかなるだろう(超適当)、ということでDWARF2を調べてみた。
http://morihyphen.hp.infoseek.co.jp/files/garbage-0.0.1.tar.gz
ビルドしてできるtestloadになんか実行ファイルをつっこむと、ローカル変数を見る。
int func() { int var_integer = 0; int *var_pointer = 100; }
こういうのを、コンパイルして、引数に渡して、実行すると
func: 8048364-804837a var_integer: offset:-4 (int value) var_pointer: offset:-8 (pointer value)
こんな感じ。offsetの値が、フレームレジスタから見た、変数が埋まってるところの位置。まだ適当だけど。
関数のアドレスと、ローカル変数がポインタかどうかわかるようになれば、
- GC呼び出し
- CIE、FDEをたどってバックトレース拾う
- アドレスから関数拾ってくる。関数からローカル変数拾ってくる
- 変数がポインタだったらルート集合に追加
というのが可能になるので正確なルート集合は求められる。
やる気が出ればもう少し続く。
memo://configure.inはシェルスクリプトと同じ問題を持っている。つまり、迂闊にスペースを入れてはいけない。