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
|
/*
* x86-64 linux replacement vdso.
*
* Copyright 2023 Linaro, Ltd.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <asm/unistd.h>
.macro endf name
.globl \name
.type \name, @function
.size \name, . - \name
.endm
.macro weakalias name
\name = __vdso_\name
.weak \name
.endm
.macro vdso_syscall name, nr
__vdso_\name:
mov $\nr, %eax
syscall
ret
endf __vdso_\name
weakalias \name
.endm
.cfi_startproc
vdso_syscall clock_gettime, __NR_clock_gettime
vdso_syscall clock_getres, __NR_clock_getres
vdso_syscall gettimeofday, __NR_gettimeofday
vdso_syscall time, __NR_time
__vdso_getcpu:
/*
* There is no syscall number for this allocated on x64.
* We can handle this several ways:
*
* (1) Invent a syscall number for use within qemu.
* It should be easy enough to pick a number that
* is well out of the way of the kernel numbers.
*
* (2) Force the emulated cpu to support the rdtscp insn,
* and initialize the TSC_AUX value the appropriate value.
*
* (3) Pretend that we're always running on cpu 0.
*
* This last is the one that's implemented here, with the
* tiny bit of extra code to support rdtscp in place.
*/
xor %ecx, %ecx /* rdtscp w/ tsc_aux = 0 */
/* if (cpu != NULL) *cpu = (ecx & 0xfff); */
test %rdi, %rdi
jz 1f
mov %ecx, %eax
and $0xfff, %eax
mov %eax, (%rdi)
/* if (node != NULL) *node = (ecx >> 12); */
1: test %rsi, %rsi
jz 2f
shr $12, %ecx
mov %ecx, (%rsi)
2: xor %eax, %eax
ret
endf __vdso_getcpu
weakalias getcpu
.cfi_endproc
/* TODO: Add elf note for LINUX_VERSION_CODE */
|