|
@@ -0,0 +1,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
|