Annotation of linux/kernel/sys_call.S, revision 1.1.1.5

1.1       root        1: /*
                      2:  *  linux/kernel/sys_call.S
                      3:  *
1.1.1.4   root        4:  *  Copyright (C) 1991, 1992  Linus Torvalds
1.1       root        5:  */
                      6: 
                      7: /*
                      8:  * sys_call.S  contains the system-call and fault low-level handling routines.
                      9:  * This also contains the timer-interrupt handler, as well as all interrupts
                     10:  * and faults that can result in a task-switch.
                     11:  *
                     12:  * NOTE: This code handles signal-recognition, which happens every time
                     13:  * after a timer-interrupt and after each system call.
                     14:  *
1.1.1.5 ! root       15:  * I changed all the .align's to 4 (16 byte alignment), as that's faster
        !            16:  * on a 486.
        !            17:  *
1.1       root       18:  * Stack layout in 'ret_from_system_call':
                     19:  *     ptrace needs to have all regs on the stack.
                     20:  *     if the order here is changed, it needs to be 
                     21:  *     updated in fork.c:copy_process, signal.c:do_signal,
                     22:  *     ptrace.c and ptrace.h
                     23:  *
                     24:  *      0(%esp) - %ebx
                     25:  *      4(%esp) - %ecx
                     26:  *      8(%esp) - %edx
                     27:  *       C(%esp) - %esi
                     28:  *     10(%esp) - %edi
                     29:  *     14(%esp) - %ebp
                     30:  *     18(%esp) - %eax
                     31:  *     1C(%esp) - %ds
                     32:  *     20(%esp) - %es
                     33:  *      24(%esp) - %fs
                     34:  *     28(%esp) - %gs
                     35:  *     2C(%esp) - orig_eax
                     36:  *     30(%esp) - %eip
                     37:  *     34(%esp) - %cs
                     38:  *     38(%esp) - %eflags
                     39:  *     3C(%esp) - %oldesp
                     40:  *     40(%esp) - %oldss
                     41:  */
                     42: 
                     43: EBX            = 0x00
                     44: ECX            = 0x04
                     45: EDX            = 0x08
                     46: ESI            = 0x0C
                     47: EDI            = 0x10
                     48: EBP            = 0x14
                     49: EAX            = 0x18
                     50: DS             = 0x1C
                     51: ES             = 0x20
                     52: FS             = 0x24
                     53: GS             = 0x28
                     54: ORIG_EAX       = 0x2C
                     55: EIP            = 0x30
                     56: CS             = 0x34
                     57: EFLAGS         = 0x38
                     58: OLDESP         = 0x3C
                     59: OLDSS          = 0x40
                     60: 
1.1.1.5 ! root       61: IF_MASK                = 0x00000200
        !            62: NT_MASK                = 0x00004000
        !            63: VM_MASK                = 0x00020000
        !            64: 
1.1       root       65: /*
                     66:  * these are offsets into the task-struct.
                     67:  */
                     68: state          = 0
                     69: counter                = 4
                     70: priority       = 8
                     71: signal         = 12
                     72: sigaction      = 16            # MUST be 16 (=len of sigaction)
                     73: blocked                = (33*16)
1.1.1.5 ! root       74: saved_kernel_stack = ((33*16)+4)
1.1       root       75: 
                     76: /*
                     77:  * offsets within sigaction
                     78:  */
                     79: sa_handler     = 0
                     80: sa_mask                = 4
                     81: sa_flags       = 8
                     82: sa_restorer    = 12
                     83: 
                     84: ENOSYS = 38
                     85: 
1.1.1.4   root       86: .globl _system_call,_sys_execve
1.1       root       87: .globl _device_not_available, _coprocessor_error
                     88: .globl _divide_error,_debug,_nmi,_int3,_overflow,_bounds,_invalid_op
                     89: .globl _double_fault,_coprocessor_segment_overrun
                     90: .globl _invalid_TSS,_segment_not_present,_stack_segment
1.1.1.4   root       91: .globl _general_protection,_reserved
1.1       root       92: .globl _alignment_check,_page_fault
1.1.1.4   root       93: .globl ret_from_sys_call
1.1       root       94: 
                     95: #define SAVE_ALL \
                     96:        cld; \
                     97:        push %gs; \
                     98:        push %fs; \
                     99:        push %es; \
                    100:        push %ds; \
                    101:        pushl %eax; \
                    102:        pushl %ebp; \
                    103:        pushl %edi; \
                    104:        pushl %esi; \
                    105:        pushl %edx; \
                    106:        pushl %ecx; \
                    107:        pushl %ebx; \
                    108:        movl $0x10,%edx; \
                    109:        mov %dx,%ds; \
                    110:        mov %dx,%es; \
                    111:        movl $0x17,%edx; \
                    112:        mov %dx,%fs
                    113: 
1.1.1.5 ! root      114: .align 4
1.1       root      115: reschedule:
                    116:        pushl $ret_from_sys_call
                    117:        jmp _schedule
1.1.1.5 ! root      118: .align 4
1.1       root      119: _system_call:
1.1.1.4   root      120:        pushl %eax                      # save orig_eax
1.1       root      121:        SAVE_ALL
1.1.1.4   root      122:        movl $-ENOSYS,EAX(%esp)
1.1       root      123:        cmpl _NR_syscalls,%eax
1.1.1.4   root      124:        jae ret_from_sys_call
1.1       root      125:        call _sys_call_table(,%eax,4)
                    126:        movl %eax,EAX(%esp)             # save the return value
1.1.1.5 ! root      127:        .align 4,0x90
1.1       root      128: ret_from_sys_call:
1.1.1.5 ! root      129:        movl EFLAGS(%esp),%eax          # check VM86 flag: CS/SS are
        !           130:        testl $VM_MASK,%eax             # different then
        !           131:        jne 4f
1.1       root      132:        cmpw $0x0f,CS(%esp)             # was old code segment supervisor ?
                    133:        jne 2f
                    134:        cmpw $0x17,OLDSS(%esp)          # was stack segment = 0x17 ?
                    135:        jne 2f
1.1.1.5 ! root      136: 4:     orl $IF_MASK,%eax               # these just try to make sure
        !           137:        andl $~NT_MASK,%eax             # the program doesn't do anything
        !           138:        movl %eax,EFLAGS(%esp)          # stupid
1.1.1.4   root      139: 1:     cmpl $0,_need_resched
1.1       root      140:        jne reschedule
1.1.1.4   root      141:        movl _current,%eax
1.1.1.5 ! root      142:        cmpl _task,%eax                 # task[0] cannot have signals
        !           143:        je 2f
1.1       root      144:        cmpl $0,state(%eax)             # state
                    145:        jne reschedule
                    146:        cmpl $0,counter(%eax)           # counter
                    147:        je reschedule
                    148:        movl signal(%eax),%ebx
                    149:        movl blocked(%eax),%ecx
                    150:        notl %ecx
                    151:        andl %ebx,%ecx
                    152:        bsfl %ecx,%ecx
                    153:        je 2f
                    154:        btrl %ecx,%ebx
1.1.1.5 ! root      155:        incl %ecx
1.1       root      156:        movl %ebx,signal(%eax)
1.1.1.2   root      157:        movl %esp,%ebx
1.1.1.5 ! root      158:        testl $VM_MASK,EFLAGS(%esp)
        !           159:        je 3f
1.1.1.2   root      160:        pushl %ebx
1.1.1.5 ! root      161:        pushl %ecx
        !           162:        call _save_v86_state
        !           163:        popl %ecx
        !           164:        movl %eax,%ebx
        !           165:        movl %eax,%esp
        !           166: 3:     pushl %ebx
1.1       root      167:        pushl %ecx
                    168:        call _do_signal
                    169:        popl %ecx
1.1.1.2   root      170:        popl %ebx
1.1       root      171:        testl %eax, %eax
                    172:        jne 1b                  # see if we need to switch tasks, or do more signals
                    173: 2:     popl %ebx
                    174:        popl %ecx
                    175:        popl %edx
                    176:        popl %esi
                    177:        popl %edi
                    178:        popl %ebp
                    179:        popl %eax
                    180:        pop %ds
                    181:        pop %es
                    182:        pop %fs
                    183:        pop %gs
                    184:        addl $4,%esp            # skip the orig_eax
                    185:        iret
                    186: 
1.1.1.5 ! root      187: .align 4
1.1       root      188: _sys_execve:
                    189:        lea (EIP+4)(%esp),%eax  # don't forget about the return address.
                    190:        pushl %eax
                    191:        call _do_execve
                    192:        addl $4,%esp
                    193:        ret
                    194: 
1.1.1.5 ! root      195: .align 4
1.1       root      196: _divide_error:
                    197:        pushl $0                # no error code
                    198:        pushl $_do_divide_error
1.1.1.5 ! root      199: .align 4,0x90
1.1       root      200: error_code:
                    201:        push %fs
                    202:        push %es
                    203:        push %ds
                    204:        pushl %eax
                    205:        pushl %ebp
                    206:        pushl %edi
                    207:        pushl %esi
                    208:        pushl %edx
                    209:        pushl %ecx
                    210:        pushl %ebx
                    211:        cld
                    212:        movl $-1, %eax
                    213:        xchgl %eax, ORIG_EAX(%esp)      # orig_eax (get the error code. )
                    214:        xorl %ebx,%ebx                  # zero ebx
                    215:        mov %gs,%bx                     # get the lower order bits of gs
                    216:        xchgl %ebx, GS(%esp)            # get the address and save gs.
                    217:        pushl %eax                      # push the error code
                    218:        lea 52(%esp),%edx
                    219:        pushl %edx
                    220:        movl $0x10,%edx
                    221:        mov %dx,%ds
                    222:        mov %dx,%es
                    223:        movl $0x17,%edx
                    224:        mov %dx,%fs
                    225:        call *%ebx
                    226:        addl $8,%esp
                    227:        jmp ret_from_sys_call
                    228: 
1.1.1.5 ! root      229: .align 4
1.1.1.4   root      230: _coprocessor_error:
                    231:        pushl $0
                    232:        pushl $_do_coprocessor_error
                    233:        jmp error_code
                    234: 
1.1.1.5 ! root      235: .align 4
1.1.1.4   root      236: _device_not_available:
                    237:        pushl $-1               # mark this as an int
                    238:        SAVE_ALL
                    239:        pushl $ret_from_sys_call
                    240:        clts                            # clear TS so that we can use math
                    241:        movl %cr0,%eax
                    242:        testl $0x4,%eax                 # EM (math emulation bit)
                    243:        je _math_state_restore
                    244:        pushl $0                # temporary storage for ORIG_EIP
                    245:        call _math_emulate
                    246:        addl $4,%esp
                    247:        ret
                    248: 
1.1.1.5 ! root      249: .align 4
1.1       root      250: _debug:
                    251:        pushl $0
1.1.1.4   root      252:        pushl $_do_debug
1.1       root      253:        jmp error_code
                    254: 
1.1.1.5 ! root      255: .align 4
1.1       root      256: _nmi:
                    257:        pushl $0
                    258:        pushl $_do_nmi
                    259:        jmp error_code
                    260: 
1.1.1.5 ! root      261: .align 4
1.1       root      262: _int3:
                    263:        pushl $0
                    264:        pushl $_do_int3
                    265:        jmp error_code
                    266: 
1.1.1.5 ! root      267: .align 4
1.1       root      268: _overflow:
                    269:        pushl $0
                    270:        pushl $_do_overflow
                    271:        jmp error_code
                    272: 
1.1.1.5 ! root      273: .align 4
1.1       root      274: _bounds:
                    275:        pushl $0
                    276:        pushl $_do_bounds
                    277:        jmp error_code
                    278: 
1.1.1.5 ! root      279: .align 4
1.1       root      280: _invalid_op:
                    281:        pushl $0
                    282:        pushl $_do_invalid_op
                    283:        jmp error_code
                    284: 
1.1.1.5 ! root      285: .align 4
1.1       root      286: _coprocessor_segment_overrun:
                    287:        pushl $0
                    288:        pushl $_do_coprocessor_segment_overrun
                    289:        jmp error_code
                    290: 
1.1.1.5 ! root      291: .align 4
1.1       root      292: _reserved:
                    293:        pushl $0
                    294:        pushl $_do_reserved
                    295:        jmp error_code
                    296: 
1.1.1.5 ! root      297: .align 4
1.1       root      298: _double_fault:
                    299:        pushl $_do_double_fault
                    300:        jmp error_code
                    301: 
1.1.1.5 ! root      302: .align 4
1.1       root      303: _invalid_TSS:
                    304:        pushl $_do_invalid_TSS
                    305:        jmp error_code
                    306: 
1.1.1.5 ! root      307: .align 4
1.1       root      308: _segment_not_present:
                    309:        pushl $_do_segment_not_present
                    310:        jmp error_code
                    311: 
1.1.1.5 ! root      312: .align 4
1.1       root      313: _stack_segment:
                    314:        pushl $_do_stack_segment
                    315:        jmp error_code
                    316: 
1.1.1.5 ! root      317: .align 4
1.1       root      318: _general_protection:
                    319:        pushl $_do_general_protection
                    320:        jmp error_code
                    321: 
1.1.1.5 ! root      322: .align 4
1.1       root      323: _alignment_check:
                    324:        pushl $_do_alignment_check
                    325:        jmp error_code
                    326: 
1.1.1.5 ! root      327: .align 4
1.1       root      328: _page_fault:
                    329:        pushl $_do_page_fault
                    330:        jmp error_code

unix.superglobalmegacorp.com