boot2

Playing with the boostrap
git clone https://git.ryansepassi.com/git/boot2.git
Log | Files | Refs | README

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