The main function of traps: its function is called by asm.s to print the interrupt information, the interrupt vector is set through set_trap_gate (such as: set_trap_gate(0,÷_error);), and the assembly is written in the c language.
Register variable: register defines a register variable, which can be operated like a register in assembly, and is a bridge linking C language and assembly.
Such as: register char __res;
The defined die function prints information, and other interrupts call this function to print interrupt information:
如:void do_divide_error(long esp, long error_code)
{
die("divide error",esp,error_code);
}
The following functions are to read register data and die function
_inline char get_seg_byte(unsigned short segm, void *addr)
{
register char __res;
_asm{
push fs
mov ax,segm
mov fs,ax
mov ebx,addr
mov al,byte ptr fs:[ebx]
mov __res,al
pop fs
}
return __res;
}
// 取段seg 中地址addr 处的一个长字(4 字节)。
_inline long
get_seg_long(unsigned short segm,long *addr) {
register unsigned long __res;
_asm{
push fs
mov ax,segm
mov fs,ax
mov ebx,addr
mov eax,fs:[ebx]
mov __res,eax
pop fs
}
return __res;
}
//#define get_seg_long(seg,addr) ({ \
//register unsigned long __res; \
//__asm__("push %%fs;mov %%ax,%%fs;movl %%fs:%2,%%eax;pop %%fs" \
// :"=a" (__res):"0" (seg),"m" (*(addr))); \
//__res;})
// Take the value of the fs segment register (selector).
_inline unsigned short _fs() { register unsigned short __res; _asm mov ax,fs _asm mov __res,ax return __res; }
// This subroutine is used to print the name of the error interrupt, error number, EIP, EFLAGS, ESP, fs segment register value of the calling program,
// segment base address, segment length, process number pid, task number, 10 words Section script. If the stack is in the user data section, then
// print 16 bytes of stack content.
static void die(char * str,long esp_ptr,long nr)
{ long * esp = (long *) esp_ptr; int i;
printk("%s: %04x\n\r",str,nr&0xffff);
printk("EIP:\t%04x:%p\nEFLAGS:\t%p\nESP:\t%04x:%p\n",
esp[1],esp[0],esp[2],esp[4],esp[3]);
printk("fs: %04x\n",_fs());
printk("base: %p, limit: %p\n",get_base(current->ldt[1]),get_limit(0x17));
if (esp[4] == 0x17) {
printk("Stack: ");
for (i=0;i<4;i++)
printk("%p ",get_seg_long(0x17,i+(long *)esp[3]));
printk("\n");
}
str(i);
printk("Pid: %d, process nr: %d\n\r",current->pid,0xffff & i);
for(i=0;i<10;i++)
printk("%02x ",0xff & get_seg_byte(esp[1],(i+(char *)esp[0])));
printk("\n\r");
do_exit(11); /* play segment exception */
}