child.c (2863B)
1 /* Tier 2 demo: child program execve'd by forktest. Prints argv and 2 * exits 42 so the parent's waitid can verify si_status round-trips. */ 3 4 typedef long i64; 5 typedef unsigned long u64; 6 7 #if defined(__x86_64__) 8 #define SYS_write 1 9 #define SYS_exit_group 60 10 #else 11 #define SYS_write 64 12 #define SYS_exit_group 93 13 #endif 14 15 extern i64 syscall6(u64 nr, u64 a, u64 b, u64 c, u64 d, u64 e, u64 f); 16 17 static i64 sys_write(int fd, const void *buf, u64 n) { return syscall6(SYS_write, (u64)fd, (u64)buf, n, 0,0,0); } 18 static void sys_exit(int c) { syscall6(SYS_exit_group, (u64)c, 0,0,0,0,0); for(;;); } 19 20 void *memset(void *d, int c, u64 n) { 21 unsigned char *dd = d; for (u64 i = 0; i < n; i++) dd[i] = (unsigned char)c; return d; 22 } 23 24 static u64 strlen_(const char *s) { u64 n = 0; while (s[n]) n++; return n; } 25 static void puts_(const char *s) { sys_write(1, s, strlen_(s)); } 26 static void put_d(i64 v) { 27 char buf[24]; int i = 0; 28 if (v == 0) { sys_write(1, "0", 1); return; } 29 if (v < 0) { sys_write(1, "-", 1); v = -v; } 30 while (v) { buf[i++] = '0' + (char)(v % 10); v /= 10; } 31 while (i--) sys_write(1, &buf[i], 1); 32 } 33 34 void _start_c(long argc, char **argv) { 35 puts_("[child] argc="); put_d(argc); puts_("\n"); 36 for (long i = 0; i < argc; i++) { 37 puts_("[child] argv["); put_d(i); puts_("] = "); puts_(argv[i]); puts_("\n"); 38 } 39 puts_("[child] exiting 42\n"); 40 sys_exit(42); 41 } 42 43 /* See forktest.c for the .globl-after-label tcc 0.9.26 quirk. */ 44 #if defined(__x86_64__) 45 asm( 46 "_start: mov (%rsp), %rdi\n" 47 ".globl _start\n" 48 ".type _start, @function\n" 49 " lea 8(%rsp), %rsi\n" 50 " call _start_c\n" 51 "\n" 52 "syscall6:\n" 53 ".globl syscall6\n" 54 ".type syscall6, @function\n" 55 " mov %rdi, %rax\n" 56 " mov %rsi, %rdi\n" 57 " mov %rdx, %rsi\n" 58 " mov %rcx, %rdx\n" 59 " mov %r8, %r10\n" 60 " mov %r9, %r8\n" 61 " mov 8(%rsp), %r9\n" 62 " int $0x80\n" 63 " ret\n"); 64 #elif defined(__riscv) 65 asm( 66 "_start: ld a0, 0(sp)\n" 67 ".globl _start\n" 68 ".type _start, @function\n" 69 " addi a1, sp, 8\n" 70 " tail _start_c\n" 71 "\n" 72 "syscall6:\n" 73 ".globl syscall6\n" 74 ".type syscall6, @function\n" 75 " mv a7, a0\n" 76 " mv a0, a1\n" 77 " mv a1, a2\n" 78 " mv a2, a3\n" 79 " mv a3, a4\n" 80 " mv a4, a5\n" 81 " mv a5, a6\n" 82 " ecall\n" 83 " ret\n"); 84 #else 85 asm( 86 "_start: ldr x0, [sp]\n" 87 ".globl _start\n" 88 ".type _start, %function\n" 89 " add x1, sp, #8\n" 90 " b _start_c\n" 91 "\n" 92 "syscall6:\n" 93 ".globl syscall6\n" 94 ".type syscall6, %function\n" 95 " mov x8, x0\n" 96 " mov x0, x1\n" 97 " mov x1, x2\n" 98 " mov x2, x3\n" 99 " mov x3, x4\n" 100 " mov x4, x5\n" 101 " mov x5, x6\n" 102 " svc #0\n" 103 " ret\n"); 104 #endif