本がどっかに埋もれてしまってて記憶に頼って書く。間違ってたらスマソ。

tryブロックの開始・終了アドレスとcatchハンドラのアドレスのテーブルをリ
ンカが生成、例外発生したらスタックからリターンアドレスを探し、テーブル
の範囲に入っているものがあったら該当するハンドラに跳ぶ。

Cで適当に書いてみるとこんな風かも。__builtin_*はgccには実際にある関数
だが、rewind_jump()はlongjmp()のような何か。

struct exception_info;
struct exception_block {
  void (*start)(), (*end)(), (*handler)(struct exception_info *);
};

const struct exception_block exception_blocks[] = {
  ...
};

static int search_exception_block(const void *key, const void *elem)
{
  const struct exception_block *block = elem;
  if (key < elem->start) return -1;
  if (key >= elem->end) return 1;
  return 0;
}

void _throw_(struct exception_info *exc)
{
  void (*ret)();
  int i;
  for (i = 1; (ret = __builtin_return_address(i)); ++i) {
    const struct exception_block *block;
    block = bsearch(ret, exception_blocks,
            sizeof(exception_blocks) / sizeof(struct exception_block),
            sizeof(struct exception_block), search_exception_block);
    if (block) {
      rewind_jump(ret, __builtin_frame_address(i), exc);
    }
  }
}