-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1267 Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
- Loading branch information
Showing
8 changed files
with
271 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
include $(BUILD_DIR)/tests/tcg/i386-linux-user/config-target.mak | ||
|
||
SUBDIR = $(SRC_PATH)/linux-user/i386 | ||
VPATH += $(SUBDIR) | ||
|
||
all: $(SUBDIR)/vdso.so | ||
|
||
$(SUBDIR)/vdso.so: vdso.S vdso.ld vdso-asmoffset.h | ||
$(CC) -o $@ -m32 -nostdlib -shared -Wl,-h,linux-gate.so.1 \ | ||
-Wl,--build-id=sha1 -Wl,--hash-style=both \ | ||
-Wl,-T,$(SUBDIR)/vdso.ld $< |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
/* | ||
* offsetof(struct sigframe, sc.eip) | ||
* offsetof(struct rt_sigframe, uc.tuc_mcontext.eip) | ||
*/ | ||
#define SIGFRAME_SIGCONTEXT_eip 64 | ||
#define RT_SIGFRAME_SIGCONTEXT_eip 220 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
/* | ||
* i386 linux replacement vdso. | ||
* | ||
* Copyright 2023 Linaro, Ltd. | ||
* | ||
* SPDX-License-Identifier: GPL-2.0-or-later | ||
*/ | ||
|
||
#include <asm/unistd.h> | ||
#include "vdso-asmoffset.h" | ||
|
||
.macro endf name | ||
.globl \name | ||
.type \name, @function | ||
.size \name, . - \name | ||
.endm | ||
|
||
.macro vdso_syscall1 name, nr | ||
\name: | ||
.cfi_startproc | ||
mov %ebx, %edx | ||
.cfi_register %ebx, %edx | ||
mov 4(%esp), %ebx | ||
mov $\nr, %eax | ||
int $0x80 | ||
mov %edx, %ebx | ||
ret | ||
.cfi_endproc | ||
endf \name | ||
.endm | ||
|
||
.macro vdso_syscall2 name, nr | ||
\name: | ||
.cfi_startproc | ||
mov %ebx, %edx | ||
.cfi_register %ebx, %edx | ||
mov 4(%esp), %ebx | ||
mov 8(%esp), %ecx | ||
mov $\nr, %eax | ||
int $0x80 | ||
mov %edx, %ebx | ||
ret | ||
.cfi_endproc | ||
endf \name | ||
.endm | ||
|
||
.macro vdso_syscall3 name, nr | ||
\name: | ||
.cfi_startproc | ||
push %ebx | ||
.cfi_adjust_cfa_offset 4 | ||
.cfi_rel_offset %ebx, 0 | ||
mov 8(%esp), %ebx | ||
mov 12(%esp), %ecx | ||
mov 16(%esp), %edx | ||
mov $\nr, %eax | ||
int $0x80 | ||
pop %ebx | ||
.cfi_adjust_cfa_offset -4 | ||
.cfi_restore %ebx | ||
ret | ||
.cfi_endproc | ||
endf \name | ||
.endm | ||
|
||
__kernel_vsyscall: | ||
.cfi_startproc | ||
int $0x80 | ||
ret | ||
.cfi_endproc | ||
endf __kernel_vsyscall | ||
|
||
vdso_syscall2 __vdso_clock_gettime, __NR_clock_gettime | ||
vdso_syscall2 __vdso_clock_gettime64, __NR_clock_gettime64 | ||
vdso_syscall2 __vdso_clock_getres, __NR_clock_getres | ||
vdso_syscall2 __vdso_gettimeofday, __NR_gettimeofday | ||
vdso_syscall1 __vdso_time, __NR_time | ||
vdso_syscall3 __vdso_getcpu, __NR_gettimeofday | ||
|
||
/* | ||
* Signal return handlers. | ||
*/ | ||
|
||
.cfi_startproc simple | ||
.cfi_signal_frame | ||
|
||
/* | ||
* For convenience, put the cfa just above eip in sigcontext, and count | ||
* offsets backward from there. Re-compute the cfa in the two contexts | ||
* we have for signal unwinding. This is far simpler than the | ||
* DW_CFA_expression form that the kernel uses, and is equally correct. | ||
*/ | ||
|
||
.cfi_def_cfa %esp, SIGFRAME_SIGCONTEXT_eip + 4 | ||
|
||
.cfi_offset %eip, -4 | ||
/* err, -8 */ | ||
/* trapno, -12 */ | ||
.cfi_offset %eax, -16 | ||
.cfi_offset %ecx, -20 | ||
.cfi_offset %edx, -24 | ||
.cfi_offset %ebx, -28 | ||
.cfi_offset %esp, -32 | ||
.cfi_offset %ebp, -36 | ||
.cfi_offset %esi, -40 | ||
.cfi_offset %edi, -44 | ||
|
||
/* | ||
* While this frame is marked as a signal frame, that only applies to how | ||
* the return address is handled for the outer frame. The return address | ||
* that arrived here, from the inner frame, is not marked as a signal frame | ||
* and so the unwinder still tries to subtract 1 to examine the presumed | ||
* call insn. Thus we must extend the unwind info to a nop before the start. | ||
*/ | ||
nop | ||
|
||
__kernel_sigreturn: | ||
popl %eax /* pop sig */ | ||
.cfi_adjust_cfa_offset -4 | ||
movl $__NR_sigreturn, %eax | ||
int $0x80 | ||
endf __kernel_sigreturn | ||
|
||
.cfi_def_cfa_offset RT_SIGFRAME_SIGCONTEXT_eip + 4 | ||
nop | ||
|
||
__kernel_rt_sigreturn: | ||
movl $__NR_rt_sigreturn, %eax | ||
int $0x80 | ||
endf __kernel_rt_sigreturn | ||
|
||
.cfi_endproc | ||
|
||
/* | ||
* TODO: Add elf notes. E.g. | ||
* | ||
* #include <linux/elfnote.h> | ||
* ELFNOTE_START(Linux, 0, "a") | ||
* .long LINUX_VERSION_CODE | ||
* ELFNOTE_END | ||
* | ||
* but what version number would we set for QEMU? | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
/* | ||
* Linker script for linux i386 replacement vdso. | ||
* | ||
* Copyright 2023 Linaro, Ltd. | ||
* | ||
* SPDX-License-Identifier: GPL-2.0-or-later | ||
*/ | ||
|
||
ENTRY(__kernel_vsyscall) | ||
|
||
VERSION { | ||
LINUX_2.6 { | ||
global: | ||
__vdso_clock_gettime; | ||
__vdso_gettimeofday; | ||
__vdso_time; | ||
__vdso_clock_getres; | ||
__vdso_clock_gettime64; | ||
__vdso_getcpu; | ||
}; | ||
|
||
LINUX_2.5 { | ||
global: | ||
__kernel_vsyscall; | ||
__kernel_sigreturn; | ||
__kernel_rt_sigreturn; | ||
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 | ||
.data : { | ||
/* | ||
* There ought not be any real read-write data. | ||
* But since we manipulated the segment layout, | ||
* we have to put these sections somewhere. | ||
*/ | ||
*(.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 =0x90909090 | ||
} |
Binary file not shown.