我的主要目的是在程序崩溃时获取LBR寄存器维护的最后16个分支的地址值。到目前为止我尝试了两种方式 -
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)
我在这里忘记了什么吗? 有帮助吗?感谢
答案 0 :(得分:1)
使用以下内容:
unsigned long long x86_get_msr(int msr)
{
unsigned long msrl = 0, msrh = 0;
/* NOTE: rdmsr is always return EDX:EAX pair value */
asm volatile ("rdmsr" : "=a"(msrl), "=d"(msrh) : "c"(msr));
return ((unsigned long long)msrh << 32) | msrl;
}