linux kernel analysis of traps.c

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 */
}

Guess you like

Origin blog.csdn.net/wyyy2088511/article/details/108367725