syscall_arch.h 5.4 KB
Newer Older
R
Rich Felker 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
#define __SYSCALL_LL_E(x) (x)
#define __SYSCALL_LL_O(x) (x)

__attribute__((visibility("hidden")))
long (__syscall)(long, ...);

#define SYSCALL_RLIM_INFINITY (-1UL/2)

#include <sys/stat.h>
struct kernel_stat {
	unsigned int st_dev;
	unsigned int __pad1[3];
	unsigned long long st_ino;
	unsigned int st_mode;
	unsigned int st_nlink;
	int st_uid;
	int st_gid;
	unsigned int st_rdev;
	unsigned int __pad2[3];
	long long st_size;
	unsigned int st_atime_sec;
	unsigned int st_atime_nsec;
	unsigned int st_mtime_sec;
	unsigned int st_mtime_nsec;
	unsigned int st_ctime_sec;
	unsigned int st_ctime_nsec;
	unsigned int st_blksize;
	unsigned int __pad3;
	unsigned long long st_blocks;
};

static void __stat_fix(struct kernel_stat *kst, struct stat *st)
{
	st->st_dev = kst->st_dev;
	st->st_ino = kst->st_ino;
	st->st_mode = kst->st_mode;
	st->st_nlink = kst->st_nlink;
	st->st_uid = kst->st_uid;
	st->st_gid = kst->st_gid;
	st->st_rdev = kst->st_rdev;
	st->st_size = kst->st_size;
	st->st_atim.tv_sec = kst->st_atime_sec;
	st->st_atim.tv_nsec = kst->st_atime_nsec;
	st->st_mtim.tv_sec = kst->st_mtime_sec;
	st->st_mtim.tv_nsec = kst->st_mtime_nsec;
	st->st_ctim.tv_sec = kst->st_ctime_sec;
	st->st_ctim.tv_nsec = kst->st_ctime_nsec;
	st->st_blksize = kst->st_blksize;
	st->st_blocks = kst->st_blocks;
}

static inline long __syscall0(long n)
{
	register long r7 __asm__("$7");
	register long r2 __asm__("$2");
	__asm__ __volatile__ (
		"daddu $2,$0,%2 ; syscall"
		: "=&r"(r2), "=r"(r7) : "ir"(n), "0"(r2), "1"(r7)
		: "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
		  "$14", "$15", "$24", "$25", "hi", "lo", "memory");
	return r7 ? -r2 : r2;
}

static inline long __syscall1(long n, long a)
{
	register long r4 __asm__("$4") = a;
	register long r7 __asm__("$7");
	register long r2 __asm__("$2");
	__asm__ __volatile__ (
		"daddu $2,$0,%2 ; syscall"
		: "=&r"(r2), "=r"(r7) : "ir"(n), "0"(r2), "1"(r7),
		  "r"(r4)
		: "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
		  "$14", "$15", "$24", "$25", "hi", "lo", "memory");
	return r7 ? -r2 : r2;
}

static inline long __syscall2(long n, long a, long b)
{
	struct kernel_stat kst;
	long ret;
	register long r4 __asm__("$4");
	register long r5 __asm__("$5");
	register long r7 __asm__("$7");
	register long r2 __asm__("$2");

	r5 = b;
	if (n == SYS_stat || n == SYS_fstat || n == SYS_lstat)
		r5 = (long) &kst;

	r4 = a;
	__asm__ __volatile__ (
		"daddu $2,$0,%2 ; syscall"
		: "=&r"(r2), "=r"(r7) : "ir"(n), "0"(r2), "1"(r7),
		  "r"(r4), "r"(r5)
		: "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
		  "$14", "$15", "$24", "$25", "hi", "lo", "memory");

	if (r7) return -r2;
	ret = r2;

	if (n == SYS_stat || n == SYS_fstat || n == SYS_lstat)
		__stat_fix(&kst, (struct stat *)b);

	return ret;
}

static inline long __syscall3(long n, long a, long b, long c)
{
	struct kernel_stat kst;
	long ret;
	register long r4 __asm__("$4");
	register long r5 __asm__("$5");
	register long r6 __asm__("$6");
	register long r7 __asm__("$7");
	register long r2 __asm__("$2");

	r5 = b;
	if (n == SYS_stat || n == SYS_fstat || n == SYS_lstat)
		r5 = (long) &kst;

	r4 = a;
	r6 = c;
	__asm__ __volatile__ (
		"daddu $2,$0,%2 ; syscall"
		: "=&r"(r2), "=r"(r7) : "ir"(n), "0"(r2), "1"(r7),
		  "r"(r4), "r"(r5), "r"(r6)
		: "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
		  "$14", "$15", "$24", "$25", "hi", "lo", "memory");

	if (r7) return -r2;
	ret = r2;

	if (n == SYS_stat || n == SYS_fstat || n == SYS_lstat)
		__stat_fix(&kst, (struct stat *)b);

	return ret;
}

static inline long __syscall4(long n, long a, long b, long c, long d)
{
	struct kernel_stat kst;
	long ret;
	register long r4 __asm__("$4");
	register long r5 __asm__("$5");
	register long r6 __asm__("$6");
	register long r7 __asm__("$7");
	register long r2 __asm__("$2");

R
Rich Felker 已提交
150
	r4 = a;
R
Rich Felker 已提交
151
	r5 = b;
R
Rich Felker 已提交
152 153
	r6 = c;
	r7 = d;
R
Rich Felker 已提交
154 155
	if (n == SYS_stat || n == SYS_fstat || n == SYS_lstat)
		r5 = (long) &kst;
R
Rich Felker 已提交
156 157
	if (n == SYS_newfstatat)
		r6 = (long) &kst;
R
Rich Felker 已提交
158 159 160 161 162 163 164 165 166 167 168 169 170

	__asm__ __volatile__ (
		"daddu $2,$0,%2 ; syscall"
		: "=&r"(r2), "=r"(r7) : "ir"(n), "0"(r2), "1"(r7),
		  "r"(r4), "r"(r5), "r"(r6)
		: "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
		  "$14", "$15", "$24", "$25", "hi", "lo", "memory");

	if (r7) return -r2;
	ret = r2;

	if (n == SYS_stat || n == SYS_fstat || n == SYS_lstat)
		__stat_fix(&kst, (struct stat *)b);
R
Rich Felker 已提交
171 172
	if (n == SYS_newfstatat)
		__stat_fix(&kst, (struct stat *)c);
R
Rich Felker 已提交
173 174 175 176 177 178 179 180

	return ret;
}

static inline long __syscall5(long n, long a, long b, long c, long d, long e)
{
	long r2;
	long old_b = b;
R
Rich Felker 已提交
181
	long old_c = c;
R
Rich Felker 已提交
182 183 184 185
	struct kernel_stat kst;

	if (n == SYS_stat || n == SYS_fstat || n == SYS_lstat)
		b = (long) &kst;
R
Rich Felker 已提交
186 187
	if (n == SYS_newfstatat)
		c = (long) &kst;
R
Rich Felker 已提交
188 189 190 191 192 193

	r2 = (__syscall)(n, a, b, c, d, e);
	if (r2 > -4096UL) return r2;

	if (n == SYS_stat || n == SYS_fstat || n == SYS_lstat)
		__stat_fix(&kst, (struct stat *)old_b);
R
Rich Felker 已提交
194 195
	if (n == SYS_newfstatat)
		__stat_fix(&kst, (struct stat *)old_c);
R
Rich Felker 已提交
196 197 198 199 200 201 202 203

	return r2;
}

static inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)
{
	long r2;
	long old_b = b;
R
Rich Felker 已提交
204
	long old_c = c;
R
Rich Felker 已提交
205 206 207 208
	struct kernel_stat kst;

	if (n == SYS_stat || n == SYS_fstat || n == SYS_lstat)
		b = (long) &kst;
R
Rich Felker 已提交
209 210
	if (n == SYS_newfstatat)
		c = (long) &kst;
R
Rich Felker 已提交
211 212 213 214 215 216

	r2 = (__syscall)(n, a, b, c, d, e, f);
	if (r2 > -4096UL) return r2;

	if (n == SYS_stat || n == SYS_fstat || n == SYS_lstat)
		__stat_fix(&kst, (struct stat *)old_b);
R
Rich Felker 已提交
217 218
	if (n == SYS_newfstatat)
		__stat_fix(&kst, (struct stat *)old_c);
R
Rich Felker 已提交
219 220 221 222 223 224 225

	return r2;
}

#define VDSO_USEFUL
#define VDSO_CGT_SYM "__vdso_clock_gettime"
#define VDSO_CGT_VER "LINUX_2.6"