xref: /openbmc/qemu/linux-user/i386/vdso.S (revision 516fffc9933cb21fad41ca8f7bf465d238d4d375)
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