/*1* Code for the vDSO. This version uses the sysenter instruction.2*3* First get the common code for the sigreturn entry points.4* This must come first.5*/6#include "sigreturn.S"78/*9* The caller puts arg2 in %ecx, which gets pushed. The kernel will use10* %ecx itself for arg2. The pushing is because the sysexit instruction11* (found in entry.S) requires that we clobber %ecx with the desired %esp.12* User code might expect that %ecx is unclobbered though, as it would be13* for returning via the iret instruction, so we must push and pop.14*15* The caller puts arg3 in %edx, which the sysexit instruction requires16* for %eip. Thus, exactly as for arg2, we must push and pop.17*18* Arg6 is different. The caller puts arg6 in %ebp. Since the sysenter19* instruction clobbers %esp, the user's %esp won't even survive entry20* into the kernel. We store %esp in %ebp. Code in entry.S must fetch21* arg6 from the stack.22*23* You can not use this vsyscall for the clone() syscall because the24* three words on the parent stack do not get copied to the child.25*/26.text27.globl __kernel_vsyscall28.type __kernel_vsyscall,@function29ALIGN30__kernel_vsyscall:31.LSTART_vsyscall:32push %ecx33.Lpush_ecx:34push %edx35.Lpush_edx:36push %ebp37.Lenter_kernel:38movl %esp,%ebp39sysenter4041/* 7: align return point with nop's to make disassembly easier */42.space 7,0x904344/* 14: System call restart point is here! (SYSENTER_RETURN-2) */45jmp .Lenter_kernel46/* 16: System call normal return point is here! */47VDSO32_SYSENTER_RETURN: /* Symbol used by sysenter.c via vdso32-syms.h */48pop %ebp49.Lpop_ebp:50pop %edx51.Lpop_edx:52pop %ecx53.Lpop_ecx:54ret55.LEND_vsyscall:56.size __kernel_vsyscall,.-.LSTART_vsyscall57.previous5859.section .eh_frame,"a",@progbits60.LSTARTFRAMEDLSI:61.long .LENDCIEDLSI-.LSTARTCIEDLSI62.LSTARTCIEDLSI:63.long 0 /* CIE ID */64.byte 1 /* Version number */65.string "zR" /* NUL-terminated augmentation string */66.uleb128 1 /* Code alignment factor */67.sleb128 -4 /* Data alignment factor */68.byte 8 /* Return address register column */69.uleb128 1 /* Augmentation value length */70.byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */71.byte 0x0c /* DW_CFA_def_cfa */72.uleb128 473.uleb128 474.byte 0x88 /* DW_CFA_offset, column 0x8 */75.uleb128 176.align 477.LENDCIEDLSI:78.long .LENDFDEDLSI-.LSTARTFDEDLSI /* Length FDE */79.LSTARTFDEDLSI:80.long .LSTARTFDEDLSI-.LSTARTFRAMEDLSI /* CIE pointer */81.long .LSTART_vsyscall-. /* PC-relative start address */82.long .LEND_vsyscall-.LSTART_vsyscall83.uleb128 084/* What follows are the instructions for the table generation.85We have to record all changes of the stack pointer. */86.byte 0x40 + (.Lpush_ecx-.LSTART_vsyscall) /* DW_CFA_advance_loc */87.byte 0x0e /* DW_CFA_def_cfa_offset */88.byte 0x08 /* RA at offset 8 now */89.byte 0x40 + (.Lpush_edx-.Lpush_ecx) /* DW_CFA_advance_loc */90.byte 0x0e /* DW_CFA_def_cfa_offset */91.byte 0x0c /* RA at offset 12 now */92.byte 0x40 + (.Lenter_kernel-.Lpush_edx) /* DW_CFA_advance_loc */93.byte 0x0e /* DW_CFA_def_cfa_offset */94.byte 0x10 /* RA at offset 16 now */95.byte 0x85, 0x04 /* DW_CFA_offset %ebp -16 */96/* Finally the epilogue. */97.byte 0x40 + (.Lpop_ebp-.Lenter_kernel) /* DW_CFA_advance_loc */98.byte 0x0e /* DW_CFA_def_cfa_offset */99.byte 0x0c /* RA at offset 12 now */100.byte 0xc5 /* DW_CFA_restore %ebp */101.byte 0x40 + (.Lpop_edx-.Lpop_ebp) /* DW_CFA_advance_loc */102.byte 0x0e /* DW_CFA_def_cfa_offset */103.byte 0x08 /* RA at offset 8 now */104.byte 0x40 + (.Lpop_ecx-.Lpop_edx) /* DW_CFA_advance_loc */105.byte 0x0e /* DW_CFA_def_cfa_offset */106.byte 0x04 /* RA at offset 4 now */107.align 4108.LENDFDEDLSI:109.previous110111/*112* Emit a symbol with the size of this .eh_frame data,113* to verify it matches the other versions.114*/115VDSO32_vsyscall_eh_frame_size = (.LENDFDEDLSI-.LSTARTFRAMEDLSI)116117118