162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
362306a36Sopenharmony_ci * Licensed under the GPL
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#ifndef __SYSDEP_STUB_H
762306a36Sopenharmony_ci#define __SYSDEP_STUB_H
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <asm/ptrace.h>
1062306a36Sopenharmony_ci#include <generated/asm-offsets.h>
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#define STUB_MMAP_NR __NR_mmap2
1362306a36Sopenharmony_ci#define MMAP_OFFSET(o) ((o) >> UM_KERN_PAGE_SHIFT)
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_cistatic inline long stub_syscall0(long syscall)
1662306a36Sopenharmony_ci{
1762306a36Sopenharmony_ci	long ret;
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci	__asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall));
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci	return ret;
2262306a36Sopenharmony_ci}
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_cistatic inline long stub_syscall1(long syscall, long arg1)
2562306a36Sopenharmony_ci{
2662306a36Sopenharmony_ci	long ret;
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci	__asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1));
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci	return ret;
3162306a36Sopenharmony_ci}
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_cistatic inline long stub_syscall2(long syscall, long arg1, long arg2)
3462306a36Sopenharmony_ci{
3562306a36Sopenharmony_ci	long ret;
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci	__asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1),
3862306a36Sopenharmony_ci			"c" (arg2));
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci	return ret;
4162306a36Sopenharmony_ci}
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_cistatic inline long stub_syscall3(long syscall, long arg1, long arg2, long arg3)
4462306a36Sopenharmony_ci{
4562306a36Sopenharmony_ci	long ret;
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci	__asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1),
4862306a36Sopenharmony_ci			"c" (arg2), "d" (arg3));
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci	return ret;
5162306a36Sopenharmony_ci}
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_cistatic inline long stub_syscall4(long syscall, long arg1, long arg2, long arg3,
5462306a36Sopenharmony_ci				 long arg4)
5562306a36Sopenharmony_ci{
5662306a36Sopenharmony_ci	long ret;
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci	__asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1),
5962306a36Sopenharmony_ci			"c" (arg2), "d" (arg3), "S" (arg4));
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci	return ret;
6262306a36Sopenharmony_ci}
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_cistatic inline long stub_syscall5(long syscall, long arg1, long arg2, long arg3,
6562306a36Sopenharmony_ci				 long arg4, long arg5)
6662306a36Sopenharmony_ci{
6762306a36Sopenharmony_ci	long ret;
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci	__asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1),
7062306a36Sopenharmony_ci			"c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5));
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci	return ret;
7362306a36Sopenharmony_ci}
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_cistatic inline void trap_myself(void)
7662306a36Sopenharmony_ci{
7762306a36Sopenharmony_ci	__asm("int3");
7862306a36Sopenharmony_ci}
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_cistatic inline void remap_stack_and_trap(void)
8162306a36Sopenharmony_ci{
8262306a36Sopenharmony_ci	__asm__ volatile (
8362306a36Sopenharmony_ci		"movl %%esp,%%ebx ;"
8462306a36Sopenharmony_ci		"andl %0,%%ebx ;"
8562306a36Sopenharmony_ci		"movl %1,%%eax ;"
8662306a36Sopenharmony_ci		"movl %%ebx,%%edi ; addl %2,%%edi ; movl (%%edi),%%edi ;"
8762306a36Sopenharmony_ci		"movl %%ebx,%%ebp ; addl %3,%%ebp ; movl (%%ebp),%%ebp ;"
8862306a36Sopenharmony_ci		"int $0x80 ;"
8962306a36Sopenharmony_ci		"addl %4,%%ebx ; movl %%eax, (%%ebx) ;"
9062306a36Sopenharmony_ci		"int $3"
9162306a36Sopenharmony_ci		: :
9262306a36Sopenharmony_ci		"g" (~(STUB_DATA_PAGES * UM_KERN_PAGE_SIZE - 1)),
9362306a36Sopenharmony_ci		"g" (STUB_MMAP_NR),
9462306a36Sopenharmony_ci		"g" (UML_STUB_FIELD_FD),
9562306a36Sopenharmony_ci		"g" (UML_STUB_FIELD_OFFSET),
9662306a36Sopenharmony_ci		"g" (UML_STUB_FIELD_CHILD_ERR),
9762306a36Sopenharmony_ci		"c" (STUB_DATA_PAGES * UM_KERN_PAGE_SIZE),
9862306a36Sopenharmony_ci		"d" (PROT_READ | PROT_WRITE),
9962306a36Sopenharmony_ci		"S" (MAP_FIXED | MAP_SHARED)
10062306a36Sopenharmony_ci		:
10162306a36Sopenharmony_ci		"memory");
10262306a36Sopenharmony_ci}
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_cistatic __always_inline void *get_stub_data(void)
10562306a36Sopenharmony_ci{
10662306a36Sopenharmony_ci	unsigned long ret;
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_ci	asm volatile (
10962306a36Sopenharmony_ci		"movl %%esp,%0 ;"
11062306a36Sopenharmony_ci		"andl %1,%0"
11162306a36Sopenharmony_ci		: "=a" (ret)
11262306a36Sopenharmony_ci		: "g" (~(STUB_DATA_PAGES * UM_KERN_PAGE_SIZE - 1)));
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci	return (void *)ret;
11562306a36Sopenharmony_ci}
11662306a36Sopenharmony_ci#endif
117