参照元†
返り値†
CONFIG_DEBUG_BUGVERBOSE が On の場合†
#ifdef CONFIG_DEBUG_BUGVERBOSE
#ifdef CONFIG_X86_32
# define __BUG_C0 "2:\t.long 1b, %c0\n"
- BUG() の実行されたアドレス(= 1b(無効命令の先頭にある後方ラベル)を
セクションに書く。
サイズは 32ビット。
- BUG() の実行されたファイル名のアドレス(= %c0: __FILE__)を
セクションに書く。
サイズは 32ビット。
#else
# define __BUG_C0 "2:\t.long 1b - 2b, %c0 - 2b\n"
- BUG_C0 のアドレス(= 2b(__BUG_C0 の先頭にある後方ラベル))と
BUG() の実行されたアドレス(= 1b(無効命令の先頭にある後方ラベル))の差を
セクションに書く。
サイズは 32ビット。
- BUG_C0 のアドレス(= 2b(__BUG_C0 の先頭にある後方ラベル))と
BUG() の実行されたファイル名のアドレス(= %c0: __FILE__)の差を
セクションに書く。
サイズは 32ビット。
#endif
BUG() 関数の定義†
#define BUG() \
do { \
asm volatile("1:\tud2\n" \
- 無効命令を実行する。無効命令実行割り込みが入る。
- コンパイラの最適化で移動、消去されないように
volatile キーワードをつける。
".pushsection __bug_table,\"a\"\n" \
- 以降、__bug_table セクションに対する操作をする。
- 元のセクションはコンパイラが記憶しておく(LIFO 方式)。
- __bug_table セクションは struct bug_entry の配列である。
bug_entry は BUG() の実行されたアドレスや
ソースコードファイル名などを保持している。
- 以下 .popsection までの命令にて、
struct bug_entry の各メンバに対応する情報をセクションに書き込む。
- BUG() の実行されたアドレス
- BUG() の実行されたファイル名のアドレス
- BUG() が実行された行数
- フラグ
__BUG_C0 \
- BUG() を実行したアドレスと、
BUG() の実行されたファイル名のアドレスを
セクションに書く
"\t.word %c1, 0\n" \
- BUG() が実行された行数(=%c1: __LINE__)を
セクションに書く。
サイズは 16ビット。
- フラグ(0 固定)を
セクションに書く。
サイズは 16ビット。
"\t.org 2b+%c2\n" \
- 次のエントリの開始地点を、
エントリの先頭(ラベル 2b)+ sizeof(struct bug_entry) にする。
".popsection" \
- 以降、__bug_table セクションに切り替える前の、
元のセクションに対する操作をする。
: : "i" (__FILE__), "i" (__LINE__), \
"i" (sizeof(struct bug_entry))); \
unreachable(); \
} while (0)
CONFIG_DEBUG_BUGVERBOSE が Off の場合†
#else
#define BUG() \
do { \
asm volatile("ud2"); \
- 無効命令を実行する。無効命令実行割り込みが入る。
- コンパイラの最適化で移動、消去されない
ように volatile キーワードをつける。
unreachable(); \
- 実行されないコードであることをマークする。
- もし実行された場合は無限ループになる(x86)。
他のアーキテクチャでは不明。
} while (0)
#endif
コメント†