15c48b108SAl Viro /*
25c48b108SAl Viro * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
35c48b108SAl Viro * Licensed under the GPL
45c48b108SAl Viro */
55c48b108SAl Viro
65c48b108SAl Viro #ifndef __SYSDEP_STUB_H
75c48b108SAl Viro #define __SYSDEP_STUB_H
85c48b108SAl Viro
95c48b108SAl Viro #include <asm/ptrace.h>
109f0b4807SJohannes Berg #include <generated/asm-offsets.h>
115c48b108SAl Viro
125c48b108SAl Viro #define STUB_MMAP_NR __NR_mmap2
135c48b108SAl Viro #define MMAP_OFFSET(o) ((o) >> UM_KERN_PAGE_SHIFT)
145c48b108SAl Viro
stub_syscall0(long syscall)155c48b108SAl Viro static inline long stub_syscall0(long syscall)
165c48b108SAl Viro {
175c48b108SAl Viro long ret;
185c48b108SAl Viro
195c48b108SAl Viro __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall));
205c48b108SAl Viro
215c48b108SAl Viro return ret;
225c48b108SAl Viro }
235c48b108SAl Viro
stub_syscall1(long syscall,long arg1)245c48b108SAl Viro static inline long stub_syscall1(long syscall, long arg1)
255c48b108SAl Viro {
265c48b108SAl Viro long ret;
275c48b108SAl Viro
285c48b108SAl Viro __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1));
295c48b108SAl Viro
305c48b108SAl Viro return ret;
315c48b108SAl Viro }
325c48b108SAl Viro
stub_syscall2(long syscall,long arg1,long arg2)335c48b108SAl Viro static inline long stub_syscall2(long syscall, long arg1, long arg2)
345c48b108SAl Viro {
355c48b108SAl Viro long ret;
365c48b108SAl Viro
375c48b108SAl Viro __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1),
385c48b108SAl Viro "c" (arg2));
395c48b108SAl Viro
405c48b108SAl Viro return ret;
415c48b108SAl Viro }
425c48b108SAl Viro
stub_syscall3(long syscall,long arg1,long arg2,long arg3)435c48b108SAl Viro static inline long stub_syscall3(long syscall, long arg1, long arg2, long arg3)
445c48b108SAl Viro {
455c48b108SAl Viro long ret;
465c48b108SAl Viro
475c48b108SAl Viro __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1),
485c48b108SAl Viro "c" (arg2), "d" (arg3));
495c48b108SAl Viro
505c48b108SAl Viro return ret;
515c48b108SAl Viro }
525c48b108SAl Viro
stub_syscall4(long syscall,long arg1,long arg2,long arg3,long arg4)535c48b108SAl Viro static inline long stub_syscall4(long syscall, long arg1, long arg2, long arg3,
545c48b108SAl Viro long arg4)
555c48b108SAl Viro {
565c48b108SAl Viro long ret;
575c48b108SAl Viro
585c48b108SAl Viro __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1),
595c48b108SAl Viro "c" (arg2), "d" (arg3), "S" (arg4));
605c48b108SAl Viro
615c48b108SAl Viro return ret;
625c48b108SAl Viro }
635c48b108SAl Viro
stub_syscall5(long syscall,long arg1,long arg2,long arg3,long arg4,long arg5)645c48b108SAl Viro static inline long stub_syscall5(long syscall, long arg1, long arg2, long arg3,
655c48b108SAl Viro long arg4, long arg5)
665c48b108SAl Viro {
675c48b108SAl Viro long ret;
685c48b108SAl Viro
695c48b108SAl Viro __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1),
705c48b108SAl Viro "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5));
715c48b108SAl Viro
725c48b108SAl Viro return ret;
735c48b108SAl Viro }
745c48b108SAl Viro
trap_myself(void)755c48b108SAl Viro static inline void trap_myself(void)
765c48b108SAl Viro {
775c48b108SAl Viro __asm("int3");
785c48b108SAl Viro }
795c48b108SAl Viro
remap_stack_and_trap(void)80dc01a3b9SJohannes Berg static inline void remap_stack_and_trap(void)
815c48b108SAl Viro {
829f0b4807SJohannes Berg __asm__ volatile (
839f0b4807SJohannes Berg "movl %%esp,%%ebx ;"
849f0b4807SJohannes Berg "andl %0,%%ebx ;"
859f0b4807SJohannes Berg "movl %1,%%eax ;"
869f0b4807SJohannes Berg "movl %%ebx,%%edi ; addl %2,%%edi ; movl (%%edi),%%edi ;"
879f0b4807SJohannes Berg "movl %%ebx,%%ebp ; addl %3,%%ebp ; movl (%%ebp),%%ebp ;"
889f0b4807SJohannes Berg "int $0x80 ;"
899f0b4807SJohannes Berg "addl %4,%%ebx ; movl %%eax, (%%ebx) ;"
909f0b4807SJohannes Berg "int $3"
919f0b4807SJohannes Berg : :
92*6032aca0SJohannes Berg "g" (~(STUB_DATA_PAGES * UM_KERN_PAGE_SIZE - 1)),
939f0b4807SJohannes Berg "g" (STUB_MMAP_NR),
949f0b4807SJohannes Berg "g" (UML_STUB_FIELD_FD),
959f0b4807SJohannes Berg "g" (UML_STUB_FIELD_OFFSET),
969f0b4807SJohannes Berg "g" (UML_STUB_FIELD_CHILD_ERR),
97*6032aca0SJohannes Berg "c" (STUB_DATA_PAGES * UM_KERN_PAGE_SIZE),
985c48b108SAl Viro "d" (PROT_READ | PROT_WRITE),
999f0b4807SJohannes Berg "S" (MAP_FIXED | MAP_SHARED)
1009f0b4807SJohannes Berg :
1019f0b4807SJohannes Berg "memory");
1025c48b108SAl Viro }
1035c48b108SAl Viro
get_stub_data(void)104*6032aca0SJohannes Berg static __always_inline void *get_stub_data(void)
105adf9ae0dSJohannes Berg {
106adf9ae0dSJohannes Berg unsigned long ret;
107adf9ae0dSJohannes Berg
108adf9ae0dSJohannes Berg asm volatile (
109adf9ae0dSJohannes Berg "movl %%esp,%0 ;"
110adf9ae0dSJohannes Berg "andl %1,%0"
111adf9ae0dSJohannes Berg : "=a" (ret)
112*6032aca0SJohannes Berg : "g" (~(STUB_DATA_PAGES * UM_KERN_PAGE_SIZE - 1)));
113adf9ae0dSJohannes Berg
114adf9ae0dSJohannes Berg return (void *)ret;
115adf9ae0dSJohannes Berg }
1165c48b108SAl Viro #endif
117