diff options
Diffstat (limited to 'arch/x86/um/shared/sysdep')
20 files changed, 695 insertions, 0 deletions
diff --git a/arch/x86/um/shared/sysdep/archsetjmp.h b/arch/x86/um/shared/sysdep/archsetjmp.h new file mode 100644 index 00000000000..ff7766d2822 --- /dev/null +++ b/arch/x86/um/shared/sysdep/archsetjmp.h @@ -0,0 +1,5 @@ +#ifdef __i386__ +#include "archsetjmp_32.h" +#else +#include "archsetjmp_64.h" +#endif diff --git a/arch/x86/um/shared/sysdep/archsetjmp_32.h b/arch/x86/um/shared/sysdep/archsetjmp_32.h new file mode 100644 index 00000000000..0f312085ce1 --- /dev/null +++ b/arch/x86/um/shared/sysdep/archsetjmp_32.h @@ -0,0 +1,22 @@ +/* + * arch/um/include/sysdep-i386/archsetjmp.h + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +struct __jmp_buf { +	unsigned int __ebx; +	unsigned int __esp; +	unsigned int __ebp; +	unsigned int __esi; +	unsigned int __edi; +	unsigned int __eip; +}; + +typedef struct __jmp_buf jmp_buf[1]; + +#define JB_IP __eip +#define JB_SP __esp + +#endif				/* _SETJMP_H */ diff --git a/arch/x86/um/shared/sysdep/archsetjmp_64.h b/arch/x86/um/shared/sysdep/archsetjmp_64.h new file mode 100644 index 00000000000..2af8f12ca16 --- /dev/null +++ b/arch/x86/um/shared/sysdep/archsetjmp_64.h @@ -0,0 +1,24 @@ +/* + * arch/um/include/sysdep-x86_64/archsetjmp.h + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +struct __jmp_buf { +	unsigned long __rbx; +	unsigned long __rsp; +	unsigned long __rbp; +	unsigned long __r12; +	unsigned long __r13; +	unsigned long __r14; +	unsigned long __r15; +	unsigned long __rip; +}; + +typedef struct __jmp_buf jmp_buf[1]; + +#define JB_IP __rip +#define JB_SP __rsp + +#endif				/* _SETJMP_H */ diff --git a/arch/x86/um/shared/sysdep/faultinfo.h b/arch/x86/um/shared/sysdep/faultinfo.h new file mode 100644 index 00000000000..862ecb1c778 --- /dev/null +++ b/arch/x86/um/shared/sysdep/faultinfo.h @@ -0,0 +1,5 @@ +#ifdef __i386__ +#include "faultinfo_32.h" +#else +#include "faultinfo_64.h" +#endif diff --git a/arch/x86/um/shared/sysdep/faultinfo_32.h b/arch/x86/um/shared/sysdep/faultinfo_32.h new file mode 100644 index 00000000000..a26086b8a80 --- /dev/null +++ b/arch/x86/um/shared/sysdep/faultinfo_32.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2004 Fujitsu Siemens Computers GmbH + * Author: Bodo Stroesser <bstroesser@fujitsu-siemens.com> + * Licensed under the GPL + */ + +#ifndef __FAULTINFO_I386_H +#define __FAULTINFO_I386_H + +/* this structure contains the full arch-specific faultinfo + * from the traps. + * On i386, ptrace_faultinfo unfortunately doesn't provide + * all the info, since trap_no is missing. + * All common elements are defined at the same position in + * both structures, thus making it easy to copy the + * contents without knowledge about the structure elements. + */ +struct faultinfo { +        int error_code; /* in ptrace_faultinfo misleadingly called is_write */ +        unsigned long cr2; /* in ptrace_faultinfo called addr */ +        int trap_no; /* missing in ptrace_faultinfo */ +}; + +#define FAULT_WRITE(fi) ((fi).error_code & 2) +#define FAULT_ADDRESS(fi) ((fi).cr2) + +/* This is Page Fault */ +#define SEGV_IS_FIXABLE(fi)	((fi)->trap_no == 14) + +/* SKAS3 has no trap_no on i386, but get_skas_faultinfo() sets it to 0. */ +#define SEGV_MAYBE_FIXABLE(fi)	((fi)->trap_no == 0 && ptrace_faultinfo) + +#define PTRACE_FULL_FAULTINFO 0 + +#endif diff --git a/arch/x86/um/shared/sysdep/faultinfo_64.h b/arch/x86/um/shared/sysdep/faultinfo_64.h new file mode 100644 index 00000000000..f811cbe15d6 --- /dev/null +++ b/arch/x86/um/shared/sysdep/faultinfo_64.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2004 Fujitsu Siemens Computers GmbH + * Author: Bodo Stroesser <bstroesser@fujitsu-siemens.com> + * Licensed under the GPL + */ + +#ifndef __FAULTINFO_X86_64_H +#define __FAULTINFO_X86_64_H + +/* this structure contains the full arch-specific faultinfo + * from the traps. + * On i386, ptrace_faultinfo unfortunately doesn't provide + * all the info, since trap_no is missing. + * All common elements are defined at the same position in + * both structures, thus making it easy to copy the + * contents without knowledge about the structure elements. + */ +struct faultinfo { +        int error_code; /* in ptrace_faultinfo misleadingly called is_write */ +        unsigned long cr2; /* in ptrace_faultinfo called addr */ +        int trap_no; /* missing in ptrace_faultinfo */ +}; + +#define FAULT_WRITE(fi) ((fi).error_code & 2) +#define FAULT_ADDRESS(fi) ((fi).cr2) + +/* This is Page Fault */ +#define SEGV_IS_FIXABLE(fi)	((fi)->trap_no == 14) + +/* No broken SKAS API, which doesn't pass trap_no, here. */ +#define SEGV_MAYBE_FIXABLE(fi)	0 + +#define PTRACE_FULL_FAULTINFO 1 + +#endif diff --git a/arch/x86/um/shared/sysdep/kernel-offsets.h b/arch/x86/um/shared/sysdep/kernel-offsets.h new file mode 100644 index 00000000000..46a9df99f3c --- /dev/null +++ b/arch/x86/um/shared/sysdep/kernel-offsets.h @@ -0,0 +1,18 @@ +#include <linux/stddef.h> +#include <linux/sched.h> +#include <linux/elf.h> +#include <linux/crypto.h> +#include <asm/mman.h> + +#define DEFINE(sym, val) \ +	asm volatile("\n->" #sym " %0 " #val : : "i" (val)) + +#define BLANK() asm volatile("\n->" : : ) + +#define OFFSET(sym, str, mem) \ +	DEFINE(sym, offsetof(struct str, mem)); + +void foo(void) +{ +#include <common-offsets.h> +} diff --git a/arch/x86/um/shared/sysdep/mcontext.h b/arch/x86/um/shared/sysdep/mcontext.h new file mode 100644 index 00000000000..b724c54da31 --- /dev/null +++ b/arch/x86/um/shared/sysdep/mcontext.h @@ -0,0 +1,31 @@ +/*  + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * Licensed under the GPL + */ + +#ifndef __SYS_SIGCONTEXT_X86_H +#define __SYS_SIGCONTEXT_X86_H + +extern void get_regs_from_mc(struct uml_pt_regs *, mcontext_t *); + +#ifdef __i386__ + +#define GET_FAULTINFO_FROM_MC(fi, mc) \ +	{ \ +		(fi).cr2 = (mc)->cr2; \ +		(fi).error_code = (mc)->gregs[REG_ERR]; \ +		(fi).trap_no = (mc)->gregs[REG_TRAPNO]; \ +	} + +#else + +#define GET_FAULTINFO_FROM_MC(fi, mc) \ +	{ \ +		(fi).cr2 = (mc)->gregs[REG_CR2]; \ +		(fi).error_code = (mc)->gregs[REG_ERR]; \ +		(fi).trap_no = (mc)->gregs[REG_TRAPNO]; \ +	} + +#endif + +#endif diff --git a/arch/x86/um/shared/sysdep/ptrace.h b/arch/x86/um/shared/sysdep/ptrace.h new file mode 100644 index 00000000000..eb9356904ad --- /dev/null +++ b/arch/x86/um/shared/sysdep/ptrace.h @@ -0,0 +1,74 @@ +#ifndef __SYSDEP_X86_PTRACE_H +#define __SYSDEP_X86_PTRACE_H + +#include <generated/user_constants.h> +#include <sysdep/faultinfo.h> + +#define MAX_REG_OFFSET (UM_FRAME_SIZE) +#define MAX_REG_NR ((MAX_REG_OFFSET) / sizeof(unsigned long)) + +#define REGS_IP(r) ((r)[HOST_IP]) +#define REGS_SP(r) ((r)[HOST_SP]) +#define REGS_EFLAGS(r) ((r)[HOST_EFLAGS]) +#define REGS_AX(r) ((r)[HOST_AX]) +#define REGS_BX(r) ((r)[HOST_BX]) +#define REGS_CX(r) ((r)[HOST_CX]) +#define REGS_DX(r) ((r)[HOST_DX]) +#define REGS_SI(r) ((r)[HOST_SI]) +#define REGS_DI(r) ((r)[HOST_DI]) +#define REGS_BP(r) ((r)[HOST_BP]) +#define REGS_CS(r) ((r)[HOST_CS]) +#define REGS_SS(r) ((r)[HOST_SS]) +#define REGS_DS(r) ((r)[HOST_DS]) +#define REGS_ES(r) ((r)[HOST_ES]) + +#define UPT_IP(r) REGS_IP((r)->gp) +#define UPT_SP(r) REGS_SP((r)->gp) +#define UPT_EFLAGS(r) REGS_EFLAGS((r)->gp) +#define UPT_AX(r) REGS_AX((r)->gp) +#define UPT_BX(r) REGS_BX((r)->gp) +#define UPT_CX(r) REGS_CX((r)->gp) +#define UPT_DX(r) REGS_DX((r)->gp) +#define UPT_SI(r) REGS_SI((r)->gp) +#define UPT_DI(r) REGS_DI((r)->gp) +#define UPT_BP(r) REGS_BP((r)->gp) +#define UPT_CS(r) REGS_CS((r)->gp) +#define UPT_SS(r) REGS_SS((r)->gp) +#define UPT_DS(r) REGS_DS((r)->gp) +#define UPT_ES(r) REGS_ES((r)->gp) + +#ifdef __i386__ +#include "ptrace_32.h" +#else +#include "ptrace_64.h" +#endif + +struct syscall_args { +	unsigned long args[6]; +}; + +#define SYSCALL_ARGS(r) ((struct syscall_args) \ +			 { .args = { UPT_SYSCALL_ARG1(r),	 \ +				     UPT_SYSCALL_ARG2(r),	 \ +				     UPT_SYSCALL_ARG3(r),	 \ +				     UPT_SYSCALL_ARG4(r),	 \ +				     UPT_SYSCALL_ARG5(r),	 \ +				     UPT_SYSCALL_ARG6(r) } } ) + +struct uml_pt_regs { +	unsigned long gp[MAX_REG_NR]; +	unsigned long fp[MAX_FP_NR]; +	struct faultinfo faultinfo; +	long syscall; +	int is_user; +}; + +#define EMPTY_UML_PT_REGS { } + +#define UPT_SYSCALL_NR(r) ((r)->syscall) +#define UPT_FAULTINFO(r) (&(r)->faultinfo) +#define UPT_IS_USER(r) ((r)->is_user) + +extern int user_context(unsigned long sp); + +#endif /* __SYSDEP_X86_PTRACE_H */ diff --git a/arch/x86/um/shared/sysdep/ptrace_32.h b/arch/x86/um/shared/sysdep/ptrace_32.h new file mode 100644 index 00000000000..b94a108de1d --- /dev/null +++ b/arch/x86/um/shared/sysdep/ptrace_32.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * Licensed under the GPL + */ + +#ifndef __SYSDEP_I386_PTRACE_H +#define __SYSDEP_I386_PTRACE_H + +#define MAX_FP_NR HOST_FPX_SIZE + +static inline void update_debugregs(int seq) {} + +/* syscall emulation path in ptrace */ + +#ifndef PTRACE_SYSEMU +#define PTRACE_SYSEMU 31 +#endif + +void set_using_sysemu(int value); +int get_using_sysemu(void); +extern int sysemu_supported; + +#ifndef PTRACE_SYSEMU_SINGLESTEP +#define PTRACE_SYSEMU_SINGLESTEP 32 +#endif + +#define UPT_SYSCALL_ARG1(r) UPT_BX(r) +#define UPT_SYSCALL_ARG2(r) UPT_CX(r) +#define UPT_SYSCALL_ARG3(r) UPT_DX(r) +#define UPT_SYSCALL_ARG4(r) UPT_SI(r) +#define UPT_SYSCALL_ARG5(r) UPT_DI(r) +#define UPT_SYSCALL_ARG6(r) UPT_BP(r) + +extern void arch_init_registers(int pid); + +#endif diff --git a/arch/x86/um/shared/sysdep/ptrace_64.h b/arch/x86/um/shared/sysdep/ptrace_64.h new file mode 100644 index 00000000000..919789f1071 --- /dev/null +++ b/arch/x86/um/shared/sysdep/ptrace_64.h @@ -0,0 +1,64 @@ +/* + * Copyright 2003 PathScale, Inc. + * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * + * Licensed under the GPL + */ + +#ifndef __SYSDEP_X86_64_PTRACE_H +#define __SYSDEP_X86_64_PTRACE_H + +#define MAX_FP_NR HOST_FP_SIZE + +#define REGS_R8(r) ((r)[HOST_R8]) +#define REGS_R9(r) ((r)[HOST_R9]) +#define REGS_R10(r) ((r)[HOST_R10]) +#define REGS_R11(r) ((r)[HOST_R11]) +#define REGS_R12(r) ((r)[HOST_R12]) +#define REGS_R13(r) ((r)[HOST_R13]) +#define REGS_R14(r) ((r)[HOST_R14]) +#define REGS_R15(r) ((r)[HOST_R15]) + +#define HOST_FS_BASE 21 +#define HOST_GS_BASE 22 +#define HOST_DS 23 +#define HOST_ES 24 +#define HOST_FS 25 +#define HOST_GS 26 + +/* Also defined in asm/ptrace-x86_64.h, but not in libc headers.  So, these + * are already defined for kernel code, but not for userspace code. + */ +#ifndef FS_BASE +/* These aren't defined in ptrace.h, but exist in struct user_regs_struct, + * which is what x86_64 ptrace actually uses. + */ +#define FS_BASE (HOST_FS_BASE * sizeof(long)) +#define GS_BASE (HOST_GS_BASE * sizeof(long)) +#define DS (HOST_DS * sizeof(long)) +#define ES (HOST_ES * sizeof(long)) +#define FS (HOST_FS * sizeof(long)) +#define GS (HOST_GS * sizeof(long)) +#endif + +#define UPT_R8(r) REGS_R8((r)->gp) +#define UPT_R9(r) REGS_R9((r)->gp) +#define UPT_R10(r) REGS_R10((r)->gp) +#define UPT_R11(r) REGS_R11((r)->gp) +#define UPT_R12(r) REGS_R12((r)->gp) +#define UPT_R13(r) REGS_R13((r)->gp) +#define UPT_R14(r) REGS_R14((r)->gp) +#define UPT_R15(r) REGS_R15((r)->gp) + +#define UPT_SYSCALL_ARG1(r) UPT_DI(r) +#define UPT_SYSCALL_ARG2(r) UPT_SI(r) +#define UPT_SYSCALL_ARG3(r) UPT_DX(r) +#define UPT_SYSCALL_ARG4(r) UPT_R10(r) +#define UPT_SYSCALL_ARG5(r) UPT_R8(r) +#define UPT_SYSCALL_ARG6(r) UPT_R9(r) + +static inline void arch_init_registers(int pid) +{ +} + +#endif diff --git a/arch/x86/um/shared/sysdep/ptrace_user.h b/arch/x86/um/shared/sysdep/ptrace_user.h new file mode 100644 index 00000000000..16cd6b5e71f --- /dev/null +++ b/arch/x86/um/shared/sysdep/ptrace_user.h @@ -0,0 +1,27 @@ +#include <generated/user_constants.h> + +#define PT_OFFSET(r) ((r) * sizeof(long)) + +#define PT_SYSCALL_NR(regs) ((regs)[HOST_ORIG_AX]) +#define PT_SYSCALL_NR_OFFSET PT_OFFSET(HOST_ORIG_AX) + +#define PT_SYSCALL_RET_OFFSET PT_OFFSET(HOST_AX) + +#define REGS_IP_INDEX HOST_IP +#define REGS_SP_INDEX HOST_SP + +#ifdef __i386__ +#define FP_SIZE ((HOST_FPX_SIZE > HOST_FP_SIZE) ? HOST_FPX_SIZE : HOST_FP_SIZE) +#else +#define FP_SIZE HOST_FP_SIZE + +/* + * x86_64 FC3 doesn't define this in /usr/include/linux/ptrace.h even though + * it's defined in the kernel's include/linux/ptrace.h. Additionally, use the + * 2.4 name and value for 2.4 host compatibility. + */ +#ifndef PTRACE_OLDSETOPTIONS +#define PTRACE_OLDSETOPTIONS 21 +#endif + +#endif diff --git a/arch/x86/um/shared/sysdep/skas_ptrace.h b/arch/x86/um/shared/sysdep/skas_ptrace.h new file mode 100644 index 00000000000..453febe9899 --- /dev/null +++ b/arch/x86/um/shared/sysdep/skas_ptrace.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __SYSDEP_X86_SKAS_PTRACE_H +#define __SYSDEP_X86_SKAS_PTRACE_H + +struct ptrace_faultinfo { +        int is_write; +        unsigned long addr; +}; + +struct ptrace_ldt { +        int func; +        void *ptr; +        unsigned long bytecount; +}; + +#define PTRACE_LDT 54 + +#endif diff --git a/arch/x86/um/shared/sysdep/stub.h b/arch/x86/um/shared/sysdep/stub.h new file mode 100644 index 00000000000..3f55e5bd3ce --- /dev/null +++ b/arch/x86/um/shared/sysdep/stub.h @@ -0,0 +1,14 @@ +#include <asm/unistd.h> +#include <sys/mman.h> +#include <signal.h> +#include <as-layout.h> +#include <stub-data.h> + +#ifdef __i386__ +#include "stub_32.h" +#else +#include "stub_64.h" +#endif + +extern void stub_segv_handler(int, siginfo_t *, void *); +extern void stub_clone_handler(void); diff --git a/arch/x86/um/shared/sysdep/stub_32.h b/arch/x86/um/shared/sysdep/stub_32.h new file mode 100644 index 00000000000..51fd256c75f --- /dev/null +++ b/arch/x86/um/shared/sysdep/stub_32.h @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) + * Licensed under the GPL + */ + +#ifndef __SYSDEP_STUB_H +#define __SYSDEP_STUB_H + +#include <asm/ptrace.h> + +#define STUB_SYSCALL_RET EAX +#define STUB_MMAP_NR __NR_mmap2 +#define MMAP_OFFSET(o) ((o) >> UM_KERN_PAGE_SHIFT) + +static inline long stub_syscall0(long syscall) +{ +	long ret; + +	__asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall)); + +	return ret; +} + +static inline long stub_syscall1(long syscall, long arg1) +{ +	long ret; + +	__asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1)); + +	return ret; +} + +static inline long stub_syscall2(long syscall, long arg1, long arg2) +{ +	long ret; + +	__asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1), +			"c" (arg2)); + +	return ret; +} + +static inline long stub_syscall3(long syscall, long arg1, long arg2, long arg3) +{ +	long ret; + +	__asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1), +			"c" (arg2), "d" (arg3)); + +	return ret; +} + +static inline long stub_syscall4(long syscall, long arg1, long arg2, long arg3, +				 long arg4) +{ +	long ret; + +	__asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1), +			"c" (arg2), "d" (arg3), "S" (arg4)); + +	return ret; +} + +static inline long stub_syscall5(long syscall, long arg1, long arg2, long arg3, +				 long arg4, long arg5) +{ +	long ret; + +	__asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1), +			"c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5)); + +	return ret; +} + +static inline void trap_myself(void) +{ +	__asm("int3"); +} + +static inline void remap_stack(int fd, unsigned long offset) +{ +	__asm__ volatile ("movl %%eax,%%ebp ; movl %0,%%eax ; int $0x80 ;" +			  "movl %7, %%ebx ; movl %%eax, (%%ebx)" +			  : : "g" (STUB_MMAP_NR), "b" (STUB_DATA), +			    "c" (UM_KERN_PAGE_SIZE), +			    "d" (PROT_READ | PROT_WRITE), +			    "S" (MAP_FIXED | MAP_SHARED), "D" (fd), +			    "a" (offset), +			    "i" (&((struct stub_data *) STUB_DATA)->err) +			  : "memory"); +} + +#endif diff --git a/arch/x86/um/shared/sysdep/stub_64.h b/arch/x86/um/shared/sysdep/stub_64.h new file mode 100644 index 00000000000..994df93c5ed --- /dev/null +++ b/arch/x86/um/shared/sysdep/stub_64.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) + * Licensed under the GPL + */ + +#ifndef __SYSDEP_STUB_H +#define __SYSDEP_STUB_H + +#include <sysdep/ptrace_user.h> + +#define STUB_SYSCALL_RET PT_INDEX(RAX) +#define STUB_MMAP_NR __NR_mmap +#define MMAP_OFFSET(o) (o) + +#define __syscall_clobber "r11","rcx","memory" +#define __syscall "syscall" + +static inline long stub_syscall0(long syscall) +{ +	long ret; + +	__asm__ volatile (__syscall +		: "=a" (ret) +		: "0" (syscall) : __syscall_clobber ); + +	return ret; +} + +static inline long stub_syscall2(long syscall, long arg1, long arg2) +{ +	long ret; + +	__asm__ volatile (__syscall +		: "=a" (ret) +		: "0" (syscall), "D" (arg1), "S" (arg2) : __syscall_clobber ); + +	return ret; +} + +static inline long stub_syscall3(long syscall, long arg1, long arg2, long arg3) +{ +	long ret; + +	__asm__ volatile (__syscall +		: "=a" (ret) +		: "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3) +		: __syscall_clobber ); + +	return ret; +} + +static inline long stub_syscall4(long syscall, long arg1, long arg2, long arg3, +				 long arg4) +{ +	long ret; + +	__asm__ volatile ("movq %5,%%r10 ; " __syscall +		: "=a" (ret) +		: "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3), +		  "g" (arg4) +		: __syscall_clobber, "r10" ); + +	return ret; +} + +static inline long stub_syscall5(long syscall, long arg1, long arg2, long arg3, +				 long arg4, long arg5) +{ +	long ret; + +	__asm__ volatile ("movq %5,%%r10 ; movq %6,%%r8 ; " __syscall +		: "=a" (ret) +		: "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3), +		  "g" (arg4), "g" (arg5) +		: __syscall_clobber, "r10", "r8" ); + +	return ret; +} + +static inline void trap_myself(void) +{ +	__asm("int3"); +} + +static inline void remap_stack(long fd, unsigned long offset) +{ +	__asm__ volatile ("movq %4,%%r10 ; movq %5,%%r8 ; " +			  "movq %6, %%r9; " __syscall "; movq %7, %%rbx ; " +			  "movq %%rax, (%%rbx)": +			  : "a" (STUB_MMAP_NR), "D" (STUB_DATA), +			    "S" (UM_KERN_PAGE_SIZE), +			    "d" (PROT_READ | PROT_WRITE), +                            "g" (MAP_FIXED | MAP_SHARED), "g" (fd), +			    "g" (offset), +			    "i" (&((struct stub_data *) STUB_DATA)->err) +			  : __syscall_clobber, "r10", "r8", "r9" ); +} + +#endif diff --git a/arch/x86/um/shared/sysdep/syscalls.h b/arch/x86/um/shared/sysdep/syscalls.h new file mode 100644 index 00000000000..bd9a89b67e4 --- /dev/null +++ b/arch/x86/um/shared/sysdep/syscalls.h @@ -0,0 +1,5 @@ +#ifdef __i386__ +#include "syscalls_32.h" +#else +#include "syscalls_64.h" +#endif diff --git a/arch/x86/um/shared/sysdep/syscalls_32.h b/arch/x86/um/shared/sysdep/syscalls_32.h new file mode 100644 index 00000000000..68fd2cf526f --- /dev/null +++ b/arch/x86/um/shared/sysdep/syscalls_32.h @@ -0,0 +1,15 @@ +/*  + * Copyright (C) 2000 - 2008 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * Licensed under the GPL + */ + +#include <asm/unistd.h> +#include <sysdep/ptrace.h> + +typedef long syscall_handler_t(struct pt_regs); + +extern syscall_handler_t *sys_call_table[]; + +#define EXECUTE_SYSCALL(syscall, regs) \ +	((long (*)(struct syscall_args)) \ +	 (*sys_call_table[syscall]))(SYSCALL_ARGS(®s->regs)) diff --git a/arch/x86/um/shared/sysdep/syscalls_64.h b/arch/x86/um/shared/sysdep/syscalls_64.h new file mode 100644 index 00000000000..8a7d5e1da98 --- /dev/null +++ b/arch/x86/um/shared/sysdep/syscalls_64.h @@ -0,0 +1,32 @@ +/* + * Copyright 2003 PathScale, Inc. + * + * Licensed under the GPL + */ + +#ifndef __SYSDEP_X86_64_SYSCALLS_H__ +#define __SYSDEP_X86_64_SYSCALLS_H__ + +#include <linux/msg.h> +#include <linux/shm.h> + +typedef long syscall_handler_t(void); + +extern syscall_handler_t *sys_call_table[]; + +#define EXECUTE_SYSCALL(syscall, regs) \ +	(((long (*)(long, long, long, long, long, long)) \ +	  (*sys_call_table[syscall]))(UPT_SYSCALL_ARG1(®s->regs), \ +		 		      UPT_SYSCALL_ARG2(®s->regs), \ +				      UPT_SYSCALL_ARG3(®s->regs), \ +				      UPT_SYSCALL_ARG4(®s->regs), \ +				      UPT_SYSCALL_ARG5(®s->regs), \ +				      UPT_SYSCALL_ARG6(®s->regs))) + +extern long old_mmap(unsigned long addr, unsigned long len, +		     unsigned long prot, unsigned long flags, +		     unsigned long fd, unsigned long pgoff); +extern syscall_handler_t sys_modify_ldt; +extern syscall_handler_t sys_arch_prctl; + +#endif diff --git a/arch/x86/um/shared/sysdep/tls.h b/arch/x86/um/shared/sysdep/tls.h new file mode 100644 index 00000000000..27cce00c6b3 --- /dev/null +++ b/arch/x86/um/shared/sysdep/tls.h @@ -0,0 +1,39 @@ +#ifndef _SYSDEP_TLS_H +#define _SYSDEP_TLS_H + +# ifndef __KERNEL__ + +/* Change name to avoid conflicts with the original one from <asm/ldt.h>, which + * may be named user_desc (but in 2.4 and in header matching its API was named + * modify_ldt_ldt_s). */ + +typedef struct um_dup_user_desc { +	unsigned int  entry_number; +	unsigned int  base_addr; +	unsigned int  limit; +	unsigned int  seg_32bit:1; +	unsigned int  contents:2; +	unsigned int  read_exec_only:1; +	unsigned int  limit_in_pages:1; +	unsigned int  seg_not_present:1; +	unsigned int  useable:1; +#ifdef __x86_64__ +	unsigned int  lm:1; +#endif +} user_desc_t; + +# else /* __KERNEL__ */ + +typedef struct user_desc user_desc_t; + +# endif /* __KERNEL__ */ + +extern int os_set_thread_area(user_desc_t *info, int pid); +extern int os_get_thread_area(user_desc_t *info, int pid); + +#ifdef __i386__ +#define GDT_ENTRY_TLS_MIN_I386 6 +#define GDT_ENTRY_TLS_MIN_X86_64 12 +#endif + +#endif /* _SYSDEP_TLS_H */  | 
