aboutsummaryrefslogtreecommitdiff
path: root/linux-user/arm/vdso.S
blob: b3bb6491dc2ebdfa9934439c4817a64b69b7b845 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/*
 * arm linux replacement vdso.
 *
 * Copyright 2023 Linaro, Ltd.
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

#include <asm/unistd.h>
#include "vdso-asmoffset.h"

/*
 * All supported cpus have T16 instructions: at least arm4t.
 *
 * We support user-user with m-profile cpus as an extension, because it
 * is useful for testing gcc, which requires we avoid A32 instructions.
 */
	.thumb
	.arch	armv4t
	.eabi_attribute Tag_FP_arch, 0
	.eabi_attribute Tag_ARM_ISA_use, 0

	.text

.macro	raw_syscall n
	.ifne \n < 0x100
	mov	r7, #\n
	.elseif \n < 0x1ff
	mov	r7, #0xff
	add	r7, #(\n - 0xff)
	.else
	.err
	.endif
	swi	#0
.endm

.macro	fdpic_thunk ofs
	ldr	r3, [sp, #\ofs]
	ldmia	r2, {r2, r3}
	mov	r9, r3
	bx	r2
.endm

.macro	endf name
	.globl	\name
	.type	\name, %function
	.size	\name, . - \name
.endm

/*
 * We must save/restore r7 for the EABI syscall number.
 * While we're doing that, we might as well save LR to get a free return,
 * and a branch that is interworking back to ARMv5.
 */

.macro SYSCALL name, nr
\name:
	.cfi_startproc
	push	{r7, lr}
	.cfi_adjust_cfa_offset 8
	.cfi_offset r7, -8
	.cfi_offset lr, -4
	raw_syscall \nr
	pop	{r7, pc}
	.cfi_endproc
endf \name
.endm

SYSCALL	__vdso_clock_gettime, __NR_clock_gettime
SYSCALL __vdso_clock_gettime64, __NR_clock_gettime64
SYSCALL __vdso_clock_getres, __NR_clock_getres
SYSCALL __vdso_gettimeofday, __NR_gettimeofday


/*
 * We, like the real kernel, use a table of sigreturn trampolines.
 * Unlike the real kernel, we do not attempt to pack this into as
 * few bytes as possible -- simply use 8 bytes per slot.
 *
 * Within each slot, use the exact same code sequence as the kernel,
 * lest we trip up someone doing code inspection.
 */

.macro	slot n
	.balign	8
	.org	sigreturn_codes + 8 * \n
.endm

.macro cfi_fdpic_r9 ofs
	/*
	 * fd = *(r13 + ofs)
         * r9 = *(fd + 4)
	 *
	 * DW_CFA_expression r9, length (7),
	 *   DW_OP_breg13, ofs, DW_OP_deref,
	 *   DW_OP_plus_uconst, 4, DW_OP_deref
         */
	.cfi_escape 0x10, 9, 7, 0x7d, (\ofs & 0x7f) + 0x80, (\ofs >> 7), 0x06, 0x23, 4, 0x06
.endm

.macro cfi_fdpic_pc ofs
	/*
	 * fd = *(r13 + ofs)
         * pc = *fd
	 *
	 * DW_CFA_expression lr (14), length (5),
	 *   DW_OP_breg13, ofs, DW_OP_deref, DW_OP_deref
         */
	.cfi_escape 0x10, 14, 5, 0x7d, (\ofs & 0x7f) + 0x80, (\ofs >> 7), 0x06, 0x06
.endm

/*
 * Start the unwind info at least one instruction before the signal
 * trampoline, because the unwinder will assume we are returning
 * after a call site.
 */
	.cfi_startproc simple
	.cfi_signal_frame
	.cfi_return_column 15

	.cfi_def_cfa	sp, 32 + 64
	.cfi_offset	r0, -16 * 4
	.cfi_offset	r1, -15 * 4
	.cfi_offset	r2, -14 * 4
	.cfi_offset	r3, -13 * 4
	.cfi_offset	r4, -12 * 4
	.cfi_offset	r5, -11 * 4
	.cfi_offset	r6, -10 * 4
	.cfi_offset	r7, -9 * 4
	.cfi_offset	r8, -8 * 4
	.cfi_offset	r9, -7 * 4
	.cfi_offset	r10, -6 * 4
	.cfi_offset	r11, -5 * 4
	.cfi_offset	r12, -4 * 4
	.cfi_offset	r13, -3 * 4
	.cfi_offset	r14, -2 * 4
	.cfi_offset	r15, -1 * 4

	nop

	.balign	16
sigreturn_codes:
	/* [EO]ABI sigreturn */
	slot	0
	raw_syscall __NR_sigreturn

	.cfi_def_cfa_offset 160 + 64

	/* [EO]ABI rt_sigreturn */
	slot	1
	raw_syscall __NR_rt_sigreturn

	.cfi_endproc

	/* FDPIC sigreturn */
	.cfi_startproc
	cfi_fdpic_pc SIGFRAME_RC3_OFFSET
	cfi_fdpic_r9 SIGFRAME_RC3_OFFSET

	slot	2
	fdpic_thunk SIGFRAME_RC3_OFFSET
	.cfi_endproc

	/* FDPIC rt_sigreturn */
	.cfi_startproc
	cfi_fdpic_pc RT_SIGFRAME_RC3_OFFSET
	cfi_fdpic_r9 RT_SIGFRAME_RC3_OFFSET

	slot	3
	fdpic_thunk RT_SIGFRAME_RC3_OFFSET
	.cfi_endproc

	.balign	16
endf sigreturn_codes