vtgl

terminal emulator implemented in OpenGL
git clone anongit@rnpnr.xyz:vtgl.git
Log | Files | Refs | Feed | LICENSE

platform_linux_amd64.c (3664B)


      1 /* See LICENSE for license details. */
      2 #ifndef asm
      3 #ifdef __asm
      4 #define asm __asm
      5 #else
      6 #define asm __asm__
      7 #endif
      8 #endif
      9 
     10 /* TODO: X macro that defines all of these with the appropriate function/macro */
     11 #define SYS_read                0
     12 #define SYS_write               1
     13 #define SYS_close               3
     14 #define SYS_mmap                9
     15 #define SYS_ioctl              16
     16 #define SYS_pwrite64           18
     17 #define SYS_madvise            28
     18 #define SYS_clone              56
     19 #define SYS_execve             59
     20 #define SYS_wait4              61
     21 #define SYS_ftruncate          77
     22 #define SYS_setsid            112
     23 #define SYS_prctl             157
     24 #define SYS_futex             202
     25 #define SYS_getdents64        217
     26 #define SYS_clock_gettime     228
     27 #define SYS_exit_group        231
     28 #define SYS_inotify_add_watch 254
     29 #define SYS_inotify_rm_watch  255
     30 #define SYS_openat            257
     31 #define SYS_pselect6          270
     32 #define SYS_dup3              292
     33 #define SYS_inotify_init1     294
     34 #define SYS_memfd_create      319
     35 #define SYS_statx             332
     36 
     37 #define SIGCHLD 17
     38 
     39 #define PAGE_SIZE 4096
     40 
     41 typedef u64 sys_fd_set[16];
     42 
     43 #define DIRENT_RECLEN_OFF 16
     44 #define DIRENT_TYPE_OFF   18
     45 #define DIRENT_NAME_OFF   19
     46 
     47 static FORCE_INLINE i64
     48 syscall1(i64 n, i64 a1)
     49 {
     50 	i64 result;
     51 	asm volatile ("syscall"
     52 		: "=a"(result)
     53 		: "a"(n), "D"(a1)
     54 		: "rcx", "r11", "memory"
     55 	);
     56 	return result;
     57 }
     58 
     59 static FORCE_INLINE i64
     60 syscall2(i64 n, i64 a1, i64 a2)
     61 {
     62 	i64 result;
     63 	asm volatile ("syscall"
     64 		: "=a"(result)
     65 		: "a"(n), "D"(a1), "S"(a2)
     66 		: "rcx", "r11", "memory"
     67 	);
     68 	return result;
     69 }
     70 
     71 static FORCE_INLINE i64
     72 syscall3(i64 n, i64 a1, i64 a2, i64 a3)
     73 {
     74 	i64 result;
     75 	asm volatile ("syscall"
     76 		: "=a"(result)
     77 		: "a"(n), "D"(a1), "S"(a2), "d"(a3)
     78 		: "rcx", "r11", "memory"
     79 	);
     80 	return result;
     81 }
     82 
     83 static FORCE_INLINE i64
     84 syscall4(i64 n, i64 a1, i64 a2, i64 a3, i64 a4)
     85 {
     86 	i64 result;
     87 	register i64 r10 asm("r10") = a4;
     88 	asm volatile ("syscall"
     89 		: "=a"(result)
     90 		: "a"(n), "D"(a1), "S"(a2), "d"(a3), "r"(r10)
     91 		: "rcx", "r11", "memory"
     92 	);
     93 	return result;
     94 }
     95 
     96 
     97 static FORCE_INLINE i64
     98 syscall5(i64 n, i64 a1, i64 a2, i64 a3, i64 a4, i64 a5)
     99 {
    100 	i64 result;
    101 	register i64 r10 asm("r10") = a4;
    102 	register i64 r8  asm("r8")  = a5;
    103 	asm volatile ("syscall"
    104 		: "=a"(result)
    105 		: "a"(n), "D"(a1), "S"(a2), "d"(a3), "r"(r10), "r"(r8)
    106 		: "rcx", "r11", "memory"
    107 	);
    108 	return result;
    109 }
    110 
    111 static FORCE_INLINE i64
    112 syscall6(i64 n, i64 a1, i64 a2, i64 a3, i64 a4, i64 a5, i64 a6)
    113 {
    114 	i64 result;
    115 	register i64 r10 asm("r10") = a4;
    116 	register i64 r8  asm("r8")  = a5;
    117 	register i64 r9  asm("r9")  = a6;
    118 	asm volatile ("syscall"
    119 		: "=a"(result)
    120 		: "a"(n), "D"(a1), "S"(a2), "d"(a3), "r"(r10), "r"(r8), "r"(r9)
    121 		: "rcx", "r11", "memory"
    122 	);
    123 	return result;
    124 }
    125 
    126 /* NOTE: based on code from nullprogram (Chris Wellons) */
    127 __attribute__((naked))
    128 static i64
    129 new_thread(void *stack_base)
    130 {
    131 	asm volatile (
    132 		"mov  %%rdi,    %%rsi\n" // arg2 = new stack
    133 		"mov  $0x50F00, %%edi\n" // arg1 = clone flags (VM|FS|FILES|SIGHAND|THREAD|SYSVMEM)
    134 		"mov  $56,      %%eax\n" // SYS_clone
    135 		"syscall\n"
    136 		"test %%eax, %%eax\n"    // don't mess with the calling thread's stack
    137 		"jne  1f\n"
    138 		"mov  %%rsp, %%rdi\n"
    139 		"sub  $8,    %%rsp\n"    // place a 0 return branch pointer on the child's stack
    140 		"push (%%rdi)\n"         // push the entry point back onto the stack for use by ret
    141 		"1: ret\n"
    142 		::: "rax", "rcx", "rsi", "rdi", "r11", "memory"
    143 	);
    144 }
    145 
    146 #include "platform_linux_common.c"
    147 
    148 #if 0
    149 asm (
    150 	".intel_syntax noprefix\n"
    151 	".global _start\n"
    152 	"_start:\n"
    153 	"	mov	edi, DWORD PTR [rsp]\n"
    154 	"	lea	rsi, [rsp+8]\n"
    155 	"	lea	rdx, [rsi+rdi*8+8]\n"
    156 	"	call	linux_main\n"
    157 	"	ud2\n"
    158 	".att_syntax\n"
    159 );
    160 #endif