 a1367443ba
			
		
	
	
		a1367443ba
		
	
	
	
	
		
			
			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>
		
			
				
	
	
		
			144 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			144 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| /*
 | |
|  * 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?
 | |
|  */
 |