9 changed files with 307 additions and 18 deletions
@ -0,0 +1,17 @@ |
|||
include $(BUILD_DIR)/tests/tcg/arm-linux-user/config-target.mak |
|||
|
|||
SUBDIR = $(SRC_PATH)/linux-user/arm |
|||
VPATH += $(SUBDIR) |
|||
|
|||
all: $(SUBDIR)/vdso-be.so $(SUBDIR)/vdso-le.so |
|||
|
|||
# Adding -use-blx disables unneeded interworking without actually using blx.
|
|||
LDFLAGS = -nostdlib -shared -Wl,-use-blx \
|
|||
-Wl,-h,linux-vdso.so.1 -Wl,--build-id=sha1 \
|
|||
-Wl,--hash-style=both -Wl,-T,$(SUBDIR)/vdso.ld |
|||
|
|||
$(SUBDIR)/vdso-be.so: vdso.S vdso.ld vdso-asmoffset.h |
|||
$(CC) -o $@ $(LDFLAGS) -mbig-endian $< |
|||
|
|||
$(SUBDIR)/vdso-le.so: vdso.S vdso.ld vdso-asmoffset.h |
|||
$(CC) -o $@ $(LDFLAGS) -mlittle-endian $< |
|||
@ -0,0 +1,3 @@ |
|||
/* offsetof(struct sigframe, retcode[3]) */ |
|||
#define SIGFRAME_RC3_OFFSET 756 |
|||
#define RT_SIGFRAME_RC3_OFFSET 884 |
|||
Binary file not shown.
Binary file not shown.
@ -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 |
|||
@ -0,0 +1,67 @@ |
|||
/* |
|||
* Linker script for linux arm replacement vdso. |
|||
* |
|||
* Copyright 2023 Linaro, Ltd. |
|||
* |
|||
* SPDX-License-Identifier: GPL-2.0-or-later |
|||
*/ |
|||
|
|||
VERSION { |
|||
LINUX_2.6 { |
|||
global: |
|||
__vdso_clock_gettime; |
|||
__vdso_gettimeofday; |
|||
__vdso_clock_getres; |
|||
__vdso_clock_gettime64; |
|||
|
|||
local: *; |
|||
}; |
|||
} |
|||
|
|||
|
|||
PHDRS { |
|||
phdr PT_PHDR FLAGS(4) PHDRS; |
|||
load PT_LOAD FLAGS(7) FILEHDR PHDRS; /* FLAGS=RWX */ |
|||
dynamic PT_DYNAMIC FLAGS(4); |
|||
eh_frame_hdr PT_GNU_EH_FRAME; |
|||
note PT_NOTE FLAGS(4); |
|||
} |
|||
|
|||
SECTIONS { |
|||
. = SIZEOF_HEADERS; |
|||
|
|||
/* |
|||
* The following, including the FILEHDRS and PHDRS, are modified |
|||
* when we relocate the binary. We want them to be initially |
|||
* writable for the relocation; we'll force them read-only after. |
|||
*/ |
|||
.note : { *(.note*) } :load :note |
|||
.dynamic : { *(.dynamic) } :load :dynamic |
|||
.dynsym : { *(.dynsym) } :load |
|||
/* |
|||
* There ought not be any real read-write data. |
|||
* But since we manipulated the segment layout, |
|||
* we have to put these sections somewhere. |
|||
*/ |
|||
.data : { |
|||
*(.data*) |
|||
*(.sdata*) |
|||
*(.got.plt) *(.got) |
|||
*(.gnu.linkonce.d.*) |
|||
*(.bss*) |
|||
*(.dynbss*) |
|||
*(.gnu.linkonce.b.*) |
|||
} |
|||
|
|||
.rodata : { *(.rodata*) } |
|||
.hash : { *(.hash) } |
|||
.gnu.hash : { *(.gnu.hash) } |
|||
.dynstr : { *(.dynstr) } |
|||
.gnu.version : { *(.gnu.version) } |
|||
.gnu.version_d : { *(.gnu.version_d) } |
|||
.gnu.version_r : { *(.gnu.version_r) } |
|||
.eh_frame_hdr : { *(.eh_frame_hdr) } :load :eh_frame_hdr |
|||
.eh_frame : { *(.eh_frame) } :load |
|||
|
|||
.text : { *(.text*) } :load |
|||
} |
|||
Loading…
Reference in new issue