#ifdefで区切るのか、もっと抽象化してやるのかは実装者の好みだろう。
コード読んでて感動したのが以下のコメント。
/* On entry %eip points just after the INT3 byte and aims at the * 'kind' value (eg trap_Cerror). For error-trap and Cerror-trap a * number of bytes will follow, the first is the length of the byte * arguments to follow. */ trap = *(unsigned char *)(*os_context_pc_addr(context));これは、Windowsなら、handle_breakpoint_trap、x86環境ならsigtrap_handlerにあるコードなんだけど、どうやってその'kind'を飛ばしているかというと以下のアセンブラから飛んでくる。
.globl GNAME(do_pending_interrupt) TYPE(GNAME(do_pending_interrupt)) .align align_16byte,0x90 GNAME(do_pending_interrupt): TRAP .byte trap_PendingInterrupt ret SIZE(GNAME(do_pending_interrupt))別にdo_pending_interruptである必要はないけど、ようするにこんな感じで飛ばすのである。んで、C側ではEIP(x86)の次のバイトを読む。SIGTRAP飛ばすのに
int3
もしくはud2
使ってる。ud2
だとSIGILLか。最初なんでOSのPCなんて必要なんだろうと思ったけど、こういう理由でいるみたい。「完全解説SBCL」なんて本が出たら多分買うと思う。
No comments:
Post a Comment