1*a1367443SRichard Henderson/* 2*a1367443SRichard Henderson * i386 linux replacement vdso. 3*a1367443SRichard Henderson * 4*a1367443SRichard Henderson * Copyright 2023 Linaro, Ltd. 5*a1367443SRichard Henderson * 6*a1367443SRichard Henderson * SPDX-License-Identifier: GPL-2.0-or-later 7*a1367443SRichard Henderson */ 8*a1367443SRichard Henderson 9*a1367443SRichard Henderson#include <asm/unistd.h> 10*a1367443SRichard Henderson#include "vdso-asmoffset.h" 11*a1367443SRichard Henderson 12*a1367443SRichard Henderson.macro endf name 13*a1367443SRichard Henderson .globl \name 14*a1367443SRichard Henderson .type \name, @function 15*a1367443SRichard Henderson .size \name, . - \name 16*a1367443SRichard Henderson.endm 17*a1367443SRichard Henderson 18*a1367443SRichard Henderson.macro vdso_syscall1 name, nr 19*a1367443SRichard Henderson\name: 20*a1367443SRichard Henderson .cfi_startproc 21*a1367443SRichard Henderson mov %ebx, %edx 22*a1367443SRichard Henderson .cfi_register %ebx, %edx 23*a1367443SRichard Henderson mov 4(%esp), %ebx 24*a1367443SRichard Henderson mov $\nr, %eax 25*a1367443SRichard Henderson int $0x80 26*a1367443SRichard Henderson mov %edx, %ebx 27*a1367443SRichard Henderson ret 28*a1367443SRichard Henderson .cfi_endproc 29*a1367443SRichard Hendersonendf \name 30*a1367443SRichard Henderson.endm 31*a1367443SRichard Henderson 32*a1367443SRichard Henderson.macro vdso_syscall2 name, nr 33*a1367443SRichard Henderson\name: 34*a1367443SRichard Henderson .cfi_startproc 35*a1367443SRichard Henderson mov %ebx, %edx 36*a1367443SRichard Henderson .cfi_register %ebx, %edx 37*a1367443SRichard Henderson mov 4(%esp), %ebx 38*a1367443SRichard Henderson mov 8(%esp), %ecx 39*a1367443SRichard Henderson mov $\nr, %eax 40*a1367443SRichard Henderson int $0x80 41*a1367443SRichard Henderson mov %edx, %ebx 42*a1367443SRichard Henderson ret 43*a1367443SRichard Henderson .cfi_endproc 44*a1367443SRichard Hendersonendf \name 45*a1367443SRichard Henderson.endm 46*a1367443SRichard Henderson 47*a1367443SRichard Henderson.macro vdso_syscall3 name, nr 48*a1367443SRichard Henderson\name: 49*a1367443SRichard Henderson .cfi_startproc 50*a1367443SRichard Henderson push %ebx 51*a1367443SRichard Henderson .cfi_adjust_cfa_offset 4 52*a1367443SRichard Henderson .cfi_rel_offset %ebx, 0 53*a1367443SRichard Henderson mov 8(%esp), %ebx 54*a1367443SRichard Henderson mov 12(%esp), %ecx 55*a1367443SRichard Henderson mov 16(%esp), %edx 56*a1367443SRichard Henderson mov $\nr, %eax 57*a1367443SRichard Henderson int $0x80 58*a1367443SRichard Henderson pop %ebx 59*a1367443SRichard Henderson .cfi_adjust_cfa_offset -4 60*a1367443SRichard Henderson .cfi_restore %ebx 61*a1367443SRichard Henderson ret 62*a1367443SRichard Henderson .cfi_endproc 63*a1367443SRichard Hendersonendf \name 64*a1367443SRichard Henderson.endm 65*a1367443SRichard Henderson 66*a1367443SRichard Henderson__kernel_vsyscall: 67*a1367443SRichard Henderson .cfi_startproc 68*a1367443SRichard Henderson int $0x80 69*a1367443SRichard Henderson ret 70*a1367443SRichard Henderson .cfi_endproc 71*a1367443SRichard Hendersonendf __kernel_vsyscall 72*a1367443SRichard Henderson 73*a1367443SRichard Hendersonvdso_syscall2 __vdso_clock_gettime, __NR_clock_gettime 74*a1367443SRichard Hendersonvdso_syscall2 __vdso_clock_gettime64, __NR_clock_gettime64 75*a1367443SRichard Hendersonvdso_syscall2 __vdso_clock_getres, __NR_clock_getres 76*a1367443SRichard Hendersonvdso_syscall2 __vdso_gettimeofday, __NR_gettimeofday 77*a1367443SRichard Hendersonvdso_syscall1 __vdso_time, __NR_time 78*a1367443SRichard Hendersonvdso_syscall3 __vdso_getcpu, __NR_gettimeofday 79*a1367443SRichard Henderson 80*a1367443SRichard Henderson/* 81*a1367443SRichard Henderson * Signal return handlers. 82*a1367443SRichard Henderson */ 83*a1367443SRichard Henderson 84*a1367443SRichard Henderson .cfi_startproc simple 85*a1367443SRichard Henderson .cfi_signal_frame 86*a1367443SRichard Henderson 87*a1367443SRichard Henderson/* 88*a1367443SRichard Henderson * For convenience, put the cfa just above eip in sigcontext, and count 89*a1367443SRichard Henderson * offsets backward from there. Re-compute the cfa in the two contexts 90*a1367443SRichard Henderson * we have for signal unwinding. This is far simpler than the 91*a1367443SRichard Henderson * DW_CFA_expression form that the kernel uses, and is equally correct. 92*a1367443SRichard Henderson */ 93*a1367443SRichard Henderson 94*a1367443SRichard Henderson .cfi_def_cfa %esp, SIGFRAME_SIGCONTEXT_eip + 4 95*a1367443SRichard Henderson 96*a1367443SRichard Henderson .cfi_offset %eip, -4 97*a1367443SRichard Henderson /* err, -8 */ 98*a1367443SRichard Henderson /* trapno, -12 */ 99*a1367443SRichard Henderson .cfi_offset %eax, -16 100*a1367443SRichard Henderson .cfi_offset %ecx, -20 101*a1367443SRichard Henderson .cfi_offset %edx, -24 102*a1367443SRichard Henderson .cfi_offset %ebx, -28 103*a1367443SRichard Henderson .cfi_offset %esp, -32 104*a1367443SRichard Henderson .cfi_offset %ebp, -36 105*a1367443SRichard Henderson .cfi_offset %esi, -40 106*a1367443SRichard Henderson .cfi_offset %edi, -44 107*a1367443SRichard Henderson 108*a1367443SRichard Henderson/* 109*a1367443SRichard Henderson * While this frame is marked as a signal frame, that only applies to how 110*a1367443SRichard Henderson * the return address is handled for the outer frame. The return address 111*a1367443SRichard Henderson * that arrived here, from the inner frame, is not marked as a signal frame 112*a1367443SRichard Henderson * and so the unwinder still tries to subtract 1 to examine the presumed 113*a1367443SRichard Henderson * call insn. Thus we must extend the unwind info to a nop before the start. 114*a1367443SRichard Henderson */ 115*a1367443SRichard Henderson nop 116*a1367443SRichard Henderson 117*a1367443SRichard Henderson__kernel_sigreturn: 118*a1367443SRichard Henderson popl %eax /* pop sig */ 119*a1367443SRichard Henderson .cfi_adjust_cfa_offset -4 120*a1367443SRichard Henderson movl $__NR_sigreturn, %eax 121*a1367443SRichard Henderson int $0x80 122*a1367443SRichard Hendersonendf __kernel_sigreturn 123*a1367443SRichard Henderson 124*a1367443SRichard Henderson .cfi_def_cfa_offset RT_SIGFRAME_SIGCONTEXT_eip + 4 125*a1367443SRichard Henderson nop 126*a1367443SRichard Henderson 127*a1367443SRichard Henderson__kernel_rt_sigreturn: 128*a1367443SRichard Henderson movl $__NR_rt_sigreturn, %eax 129*a1367443SRichard Henderson int $0x80 130*a1367443SRichard Hendersonendf __kernel_rt_sigreturn 131*a1367443SRichard Henderson 132*a1367443SRichard Henderson .cfi_endproc 133*a1367443SRichard Henderson 134*a1367443SRichard Henderson/* 135*a1367443SRichard Henderson * TODO: Add elf notes. E.g. 136*a1367443SRichard Henderson * 137*a1367443SRichard Henderson * #include <linux/elfnote.h> 138*a1367443SRichard Henderson * ELFNOTE_START(Linux, 0, "a") 139*a1367443SRichard Henderson * .long LINUX_VERSION_CODE 140*a1367443SRichard Henderson * ELFNOTE_END 141*a1367443SRichard Henderson * 142*a1367443SRichard Henderson * but what version number would we set for QEMU? 143*a1367443SRichard Henderson */ 144