sys_stubs.c (2714B)
1 /* x86_64 syscall stubs matching P1pp.P1pp's sys_* entry points. 2 * Same C ABI as P1pp's labelled entries — our libc.flat.c calls these 3 * with argument shapes copied straight from boot2-syscall.c. 4 * 5 * Linux x86_64 syscall ABI: nr in rax, args in rdi/rsi/rdx/r10/r8/r9, 6 * return in rax. The C ABI hands us the first four args in 7 * rdi/rsi/rdx/rcx; we move rcx → r10 before issuing `syscall` (the 8 * instruction clobbers rcx). 9 */ 10 11 static inline long _syscall0(long nr) { 12 long ret; 13 __asm__ volatile ("syscall" : "=a"(ret) : "0"(nr) : "rcx", "r11", "memory"); 14 return ret; 15 } 16 static inline long _syscall1(long nr, long a) { 17 long ret; 18 __asm__ volatile ("syscall" 19 : "=a"(ret) 20 : "0"(nr), "D"(a) 21 : "rcx", "r11", "memory"); 22 return ret; 23 } 24 static inline long _syscall2(long nr, long a, long b) { 25 long ret; 26 __asm__ volatile ("syscall" 27 : "=a"(ret) 28 : "0"(nr), "D"(a), "S"(b) 29 : "rcx", "r11", "memory"); 30 return ret; 31 } 32 static inline long _syscall3(long nr, long a, long b, long c) { 33 long ret; 34 __asm__ volatile ("syscall" 35 : "=a"(ret) 36 : "0"(nr), "D"(a), "S"(b), "d"(c) 37 : "rcx", "r11", "memory"); 38 return ret; 39 } 40 static inline long _syscall4(long nr, long a, long b, long c, long d) { 41 long ret; 42 register long r10 __asm__("r10") = d; 43 __asm__ volatile ("syscall" 44 : "=a"(ret) 45 : "0"(nr), "D"(a), "S"(b), "d"(c), "r"(r10) 46 : "rcx", "r11", "memory"); 47 return ret; 48 } 49 50 #define NR_read 0 51 #define NR_write 1 52 #define NR_close 3 53 #define NR_lseek 8 54 #define NR_brk 12 55 #define NR_exit 60 56 #define NR_openat 257 57 #define NR_unlinkat 263 58 #define AT_FDCWD (-100) 59 60 long sys_read (long fd, long buf, long n) { return _syscall3(NR_read, fd, buf, n); } 61 long sys_write (long fd, long buf, long n) { return _syscall3(NR_write, fd, buf, n); } 62 long sys_close (long fd) { return _syscall1(NR_close, fd); } 63 long sys_open (long path, long flags, long mode) { return _syscall4(NR_openat, AT_FDCWD, path, flags, mode); } 64 long sys_lseek (long fd, long off, long whence) { return _syscall3(NR_lseek, fd, off, whence); } 65 long sys_brk (long addr) { return _syscall1(NR_brk, addr); } 66 long sys_unlink(long path) { return _syscall3(NR_unlinkat, AT_FDCWD, path, 0); } 67 long sys_exit (long code) { _syscall1(NR_exit, code); for(;;); }