dr7 register global enabled but ran only once.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I used the dr0 register to trigger the int 1 exception when some
instruction fetched.
Even I enabled the global option in dr7,it still only run only once.
Any suggestions?
-----
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>

MODULE_LICENSE("Dual BSD/GPL");
MODULE_DESCRIPTION("example DR register.");

extern void my_debug_routine(void);

unsigned long ret_from_intr_p=0xc0102fc9; // ret_from_intr ,Got it
from /proc/kallsyms.

unsigned long old_debug_routine_p;
unsigned long my_debug_routine_p=(unsigned long)&my_debug_routine;

struct dr7_bit {
       unsigned gl0:2;  unsigned gl1:2;  unsigned gl2:2;  unsigned gl3:2;
       unsigned gle:2;  unsigned rsvd:1; unsigned non1:2; unsigned
gd:1; unsigned non0:2;
       unsigned rw0:2;  unsigned len0:2; unsigned rw1:2;  unsigned len1:2;
       unsigned rw2:2;  unsigned len2:2; unsigned rw3:2;  unsigned len3:2;
};

void open_debug_register(void)
{
       unsigned long rd0,rd7 = 0UL;
       struct dr7_bit *dr7;
       rd0 = ret_from_intr_p;
       dr7 = (struct dr7_bit *)&rd7;

       dr7->gle = 3;
	dr7->rsvd=1;

       dr7->len0 = 0;
       dr7->rw0 = 0;
       dr7->gl0 = 2;        // global enable.

     __asm__("mov %0,%%ebx \n\tmov %%ebx,%%dr7\n\tmov %1,%%ebx\n\tmov
%%ebx,%%dr0" ::"m"(rd7),"m"(rd0));

}

struct descriptor_idt
{
	unsigned short offset_low,seg_selector;
	unsigned char reserved,flag;
	unsigned short offset_high;
};

unsigned long counter=0UL;
void show_counter_value(void)
{
	printk("current counter is %lu\n",counter);	
}
	
void my_debug_routine(void)
{
	__asm__ __volatile__("\n\taddl $1,%0\n\tjmp
*%1":"=m"(counter):"m"(old_debug_routine_p));
}

void update_idt_entry (int n, unsigned long *addr, int how)
{
	unsigned char idtr[6];
	struct descriptor_idt * idt_p;
	__asm__ __volatile__ ("sidt %0": "=m" (idtr));
	idt_p= &((struct descriptor_idt*)*(unsigned long*)&idtr[2])[n];
	switch (how){
		case 0:
			*addr= (idt_p->offset_high <<16)+ idt_p->offset_low;
			break;
		case 1:
			idt_p->offset_high= (unsigned short)(*addr >> 16);
			idt_p->offset_low = (unsigned short)(*addr & 0x0000ffff);
			break;
	}
	return ;
}

int my_module_init(void)
{
	open_debug_register();
	update_idt_entry(1,&old_debug_routine_p,0);
	update_idt_entry(1,&my_debug_routine_p,1);
	return 0;
}

void my_module_exit(void)
{
	update_idt_entry(1,&old_debug_routine_p,1);
	show_counter_value();
	return ;
}

module_init(my_module_init);
module_exit(my_module_exit);
-
To unsubscribe from this list: send the line "unsubscribe linux-apps" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Device Mapper]

  Powered by Linux