私の主な目的は、プログラムがクラッシュしたときに、LBR レジスタによって維持されている最後の 16 分岐のアドレス値を取得することです。今まで2つの方法を試しました-
1) msr-tools これにより、コマンド ラインから msr 値を読み取ることができます。C プログラム自体からシステム コールを作成し、値を読み取ろうとします。しかし、レジスタ値は、プログラム自体のアドレスに関連していないようです。ほとんどの場合、レジスターはシステム コードの他のブランチから汚染されています。リング 0 とファー ジャンプの分岐の記録をオフにしてみました。しかし、それは役に立ちません。まだ無関係な値を取得しています。
2) カーネル モジュールを介したアクセス わかりました、msr レジスタに直接アクセスし、おそらくレジスタ汚染を回避するために、非常に単純なモジュールを作成しました (これまでにこれを行ったことはありません)。
これが私が持っているものです -
#define LBR 0x1d9 //IA32_DEBUGCTL MSR
//I first set this to some non 0 value using wrmsr (msr-tools)
static void __init do_rdmsr(unsigned msr, unsigned unused2)
{
uint64_t msr_value;
__asm__ __volatile__ (" rdmsr"
: "=A" (msr_value)
: "c" (msr)
);
printk(KERN_EMERG "%lu \n",msr_value);
}
static int hello_init(void)
{
printk(KERN_EMERG "Value is ");
do_rdmsr (LBR,0);
return 0;
}
static void hello_exit(void)
{
printk(KERN_EMERG "End\n");
}
module_init(hello_init);
module_exit(hello_exit);
しかし、問題は、dmesg を使用して出力を読み取るたびに、
Value is 0
(私は他のレジスタを試しました - それは常に0になります)
ここで私が忘れていることはありますか?何か助けはありますか?ありがとう