📄 sys_call.s
字号:
/* * linux/kernel/sys_call.S * * Copyright (C) 1991, 1992 Linus Torvalds *//* * sys_call.S contains the system-call and fault low-level handling routines. * This also contains the timer-interrupt handler, as well as all interrupts * and faults that can result in a task-switch. * * NOTE: This code handles signal-recognition, which happens every time * after a timer-interrupt and after each system call. * * I changed all the .align's to 4 (16 byte alignment), as that's faster * on a 486. * * Stack layout in 'ret_from_system_call': * ptrace needs to have all regs on the stack. * if the order here is changed, it needs to be * updated in fork.c:copy_process, signal.c:do_signal, * ptrace.c and ptrace.h * * 0(%esp) - %ebx * 4(%esp) - %ecx * 8(%esp) - %edx * C(%esp) - %esi * 10(%esp) - %edi * 14(%esp) - %ebp * 18(%esp) - %eax * 1C(%esp) - %ds * 20(%esp) - %es * 24(%esp) - %fs * 28(%esp) - %gs * 2C(%esp) - orig_eax * 30(%esp) - %eip * 34(%esp) - %cs * 38(%esp) - %eflags * 3C(%esp) - %oldesp * 40(%esp) - %oldss */#include <linux/segment.h>EBX = 0x00ECX = 0x04EDX = 0x08ESI = 0x0CEDI = 0x10EBP = 0x14EAX = 0x18DS = 0x1CES = 0x20FS = 0x24GS = 0x28ORIG_EAX = 0x2CEIP = 0x30CS = 0x34EFLAGS = 0x38OLDESP = 0x3COLDSS = 0x40CF_MASK = 0x00000001IF_MASK = 0x00000200NT_MASK = 0x00004000VM_MASK = 0x00020000/* * these are offsets into the task-struct. */state = 0counter = 4priority = 8signal = 12blocked = 16flags = 20errno = 24dbgreg6 = 52dbgreg7 = 56ENOSYS = 38.globl _system_call,_lcall7.globl _device_not_available, _coprocessor_error.globl _divide_error,_debug,_nmi,_int3,_overflow,_bounds,_invalid_op.globl _double_fault,_coprocessor_segment_overrun.globl _invalid_TSS,_segment_not_present,_stack_segment.globl _general_protection,_reserved.globl _alignment_check,_page_fault.globl ret_from_sys_call#define SAVE_ALL \ cld; \ push %gs; \ push %fs; \ push %es; \ push %ds; \ pushl %eax; \ pushl %ebp; \ pushl %edi; \ pushl %esi; \ pushl %edx; \ pushl %ecx; \ pushl %ebx; \ movl $(KERNEL_DS),%edx; \ mov %dx,%ds; \ mov %dx,%es; \ movl $(USER_DS),%edx; \ mov %dx,%fs;#define RESTORE_ALL \ cmpw $(KERNEL_CS),CS(%esp); \ je 1f; \ movl _current,%eax; \ movl dbgreg7(%eax),%ebx; \ movl %ebx,%db7; \1: popl %ebx; \ popl %ecx; \ popl %edx; \ popl %esi; \ popl %edi; \ popl %ebp; \ popl %eax; \ pop %ds; \ pop %es; \ pop %fs; \ pop %gs; \ addl $4,%esp; \ iret.align 4_lcall7: pushfl # We get a different stack layout with call gates, pushl %eax # which has to be cleaned up later.. SAVE_ALL movl EIP(%esp),%eax # due to call gates, this is eflags, not eip.. movl CS(%esp),%edx # this is eip.. movl EFLAGS(%esp),%ecx # and this is cs.. movl %eax,EFLAGS(%esp) # movl %edx,EIP(%esp) # Now we move them to their "normal" places movl %ecx,CS(%esp) # movl %esp,%eax pushl %eax call _iABI_emulate popl %eax jmp ret_from_sys_call.align 4handle_bottom_half: pushfl incl _intr_count sti call _do_bottom_half popfl decl _intr_count jmp 9f.align 4reschedule: pushl $ret_from_sys_call jmp _schedule.align 4_system_call: pushl %eax # save orig_eax SAVE_ALL movl $-ENOSYS,EAX(%esp) cmpl _NR_syscalls,%eax jae ret_from_sys_call movl _current,%ebx andl $~CF_MASK,EFLAGS(%esp) # clear carry - assume no errors movl $0,errno(%ebx) movl %db6,%edx movl %edx,dbgreg6(%ebx) # save current hardware debugging status testb $0x20,flags(%ebx) # PF_TRACESYS jne 1f call _sys_call_table(,%eax,4) movl %eax,EAX(%esp) # save the return value movl errno(%ebx),%edx negl %edx je ret_from_sys_call movl %edx,EAX(%esp) orl $(CF_MASK),EFLAGS(%esp) # set carry to indicate error jmp ret_from_sys_call.align 41: call _syscall_trace movl ORIG_EAX(%esp),%eax call _sys_call_table(,%eax,4) movl %eax,EAX(%esp) # save the return value movl _current,%eax movl errno(%eax),%edx negl %edx je 1f movl %edx,EAX(%esp) orl $(CF_MASK),EFLAGS(%esp) # set carry to indicate error1: call _syscall_trace .align 4,0x90ret_from_sys_call: cmpl $0,_intr_count jne 2f movl _bh_mask,%eax andl _bh_active,%eax jne handle_bottom_half9: movl EFLAGS(%esp),%eax # check VM86 flag: CS/SS are testl $(VM_MASK),%eax # different then jne 1f cmpw $(KERNEL_CS),CS(%esp) # was old code segment supervisor ? je 2f1: sti orl $(IF_MASK),%eax # these just try to make sure andl $~NT_MASK,%eax # the program doesn't do anything movl %eax,EFLAGS(%esp) # stupid cmpl $0,_need_resched jne reschedule movl _current,%eax cmpl _task,%eax # task[0] cannot have signals je 2f cmpl $0,state(%eax) # state jne reschedule cmpl $0,counter(%eax) # counter je reschedule movl blocked(%eax),%ecx movl %ecx,%ebx # save blocked in %ebx for signal handling notl %ecx andl signal(%eax),%ecx jne signal_return2: RESTORE_ALL.align 4signal_return: movl %esp,%ecx pushl %ecx testl $(VM_MASK),EFLAGS(%ecx) jne v86_signal_return pushl %ebx call _do_signal popl %ebx popl %ebx RESTORE_ALL.align 4v86_signal_return: call _save_v86_state movl %eax,%esp pushl %eax pushl %ebx call _do_signal popl %ebx popl %ebx RESTORE_ALL.align 4_divide_error: pushl $0 # no error code pushl $_do_divide_error.align 4,0x90error_code: push %fs push %es push %ds pushl %eax pushl %ebp pushl %edi pushl %esi pushl %edx pushl %ecx pushl %ebx movl $0,%eax movl %eax,%db7 # disable hardware debugging... cld movl $-1, %eax xchgl %eax, ORIG_EAX(%esp) # orig_eax (get the error code. ) xorl %ebx,%ebx # zero ebx mov %gs,%bx # get the lower order bits of gs xchgl %ebx, GS(%esp) # get the address and save gs. pushl %eax # push the error code lea 4(%esp),%edx pushl %edx movl $(KERNEL_DS),%edx mov %dx,%ds mov %dx,%es movl $(USER_DS),%edx mov %dx,%fs pushl %eax movl _current,%eax movl %db6,%edx movl %edx,dbgreg6(%eax) # save current hardware debugging status popl %eax call *%ebx addl $8,%esp jmp ret_from_sys_call.align 4_coprocessor_error: pushl $0 pushl $_do_coprocessor_error jmp error_code.align 4_device_not_available: pushl $-1 # mark this as an int SAVE_ALL pushl $ret_from_sys_call movl %cr0,%eax testl $0x4,%eax # EM (math emulation bit) je _math_state_restore pushl $0 # temporary storage for ORIG_EIP call _math_emulate addl $4,%esp ret.align 4_debug: pushl $0 pushl $_do_debug jmp error_code.align 4_nmi: pushl $0 pushl $_do_nmi jmp error_code.align 4_int3: pushl $0 pushl $_do_int3 jmp error_code.align 4_overflow: pushl $0 pushl $_do_overflow jmp error_code.align 4_bounds: pushl $0 pushl $_do_bounds jmp error_code.align 4_invalid_op: pushl $0 pushl $_do_invalid_op jmp error_code.align 4_coprocessor_segment_overrun: pushl $0 pushl $_do_coprocessor_segment_overrun jmp error_code.align 4_reserved: pushl $0 pushl $_do_reserved jmp error_code.align 4_double_fault: pushl $_do_double_fault jmp error_code.align 4_invalid_TSS: pushl $_do_invalid_TSS jmp error_code.align 4_segment_not_present: pushl $_do_segment_not_present jmp error_code.align 4_stack_segment: pushl $_do_stack_segment jmp error_code.align 4_general_protection: pushl $_do_general_protection jmp error_code.align 4_alignment_check: pushl $_do_alignment_check jmp error_code.align 4_page_fault: pushl $_do_page_fault jmp error_code
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -