1 /* SPDX-License-Identifier: LGPL-2.1 OR MIT */ 1 2 /* 3 * i386 specific definitions for NOLIBC 4 * Copyright (C) 2017-2022 Willy Tarreau <w@1w 5 */ 6 7 #ifndef _NOLIBC_ARCH_I386_H 8 #define _NOLIBC_ARCH_I386_H 9 10 #include "compiler.h" 11 #include "crt.h" 12 13 /* Syscalls for i386 : 14 * - mostly similar to x86_64 15 * - registers are 32-bit 16 * - syscall number is passed in eax 17 * - arguments are in ebx, ecx, edx, esi, ed 18 * - all registers are preserved (except eax 19 * - the system call is performed by calling 20 * - syscall return comes in eax 21 * - the arguments are cast to long and assi 22 * which are then simply passed as registe 23 * don't have to experience issues with re 24 * - the syscall number is always specified 25 * some registers before (gcc refuses a %- 26 * 27 * Also, i386 supports the old_select syscall 28 */ 29 #define __ARCH_WANT_SYS_OLD_SELECT 30 31 #define my_syscall0(num) 32 ({ 33 long _ret; 34 register long _num __asm__ ("eax") = ( 35 36 __asm__ volatile ( 37 "int $0x80\n" 38 : "=a" (_ret) 39 : ""(_num) 40 : "memory", "cc" 41 ); 42 _ret; 43 }) 44 45 #define my_syscall1(num, arg1) 46 ({ 47 long _ret; 48 register long _num __asm__ ("eax") = ( 49 register long _arg1 __asm__ ("ebx") = 50 51 __asm__ volatile ( 52 "int $0x80\n" 53 : "=a" (_ret) 54 : "r"(_arg1), 55 ""(_num) 56 : "memory", "cc" 57 ); 58 _ret; 59 }) 60 61 #define my_syscall2(num, arg1, arg2) 62 ({ 63 long _ret; 64 register long _num __asm__ ("eax") = ( 65 register long _arg1 __asm__ ("ebx") = 66 register long _arg2 __asm__ ("ecx") = 67 68 __asm__ volatile ( 69 "int $0x80\n" 70 : "=a" (_ret) 71 : "r"(_arg1), "r"(_arg2), 72 ""(_num) 73 : "memory", "cc" 74 ); 75 _ret; 76 }) 77 78 #define my_syscall3(num, arg1, arg2, arg3) 79 ({ 80 long _ret; 81 register long _num __asm__ ("eax") = ( 82 register long _arg1 __asm__ ("ebx") = 83 register long _arg2 __asm__ ("ecx") = 84 register long _arg3 __asm__ ("edx") = 85 86 __asm__ volatile ( 87 "int $0x80\n" 88 : "=a" (_ret) 89 : "r"(_arg1), "r"(_arg2), "r"( 90 ""(_num) 91 : "memory", "cc" 92 ); 93 _ret; 94 }) 95 96 #define my_syscall4(num, arg1, arg2, arg3, arg 97 ({ 98 long _ret; 99 register long _num __asm__ ("eax") = ( 100 register long _arg1 __asm__ ("ebx") = 101 register long _arg2 __asm__ ("ecx") = 102 register long _arg3 __asm__ ("edx") = 103 register long _arg4 __asm__ ("esi") = 104 105 __asm__ volatile ( 106 "int $0x80\n" 107 : "=a" (_ret) 108 : "r"(_arg1), "r"(_arg2), "r"( 109 ""(_num) 110 : "memory", "cc" 111 ); 112 _ret; 113 }) 114 115 #define my_syscall5(num, arg1, arg2, arg3, arg 116 ({ 117 long _ret; 118 register long _num __asm__ ("eax") = ( 119 register long _arg1 __asm__ ("ebx") = 120 register long _arg2 __asm__ ("ecx") = 121 register long _arg3 __asm__ ("edx") = 122 register long _arg4 __asm__ ("esi") = 123 register long _arg5 __asm__ ("edi") = 124 125 __asm__ volatile ( 126 "int $0x80\n" 127 : "=a" (_ret) 128 : "r"(_arg1), "r"(_arg2), "r"( 129 ""(_num) 130 : "memory", "cc" 131 ); 132 _ret; 133 }) 134 135 #define my_syscall6(num, arg1, arg2, arg3, arg 136 ({ 137 long _eax = (long)(num); 138 long _arg6 = (long)(arg6); /* Always i 139 __asm__ volatile ( 140 "pushl %[_arg6]\n\t" 141 "pushl %%ebp\n\t" 142 "movl 4(%%esp),%%ebp\n\t" 143 "int $0x80\n\t" 144 "popl %%ebp\n\t" 145 "addl $4,%%esp\n\t" 146 : "+a"(_eax) /* %ea 147 : "b"(arg1), /* %eb 148 "c"(arg2), /* %ec 149 "d"(arg3), /* %ed 150 "S"(arg4), /* %es 151 "D"(arg5), /* %ed 152 [_arg6]"m"(_arg6) /* mem 153 : "memory", "cc" 154 ); 155 _eax; 156 }) 157 158 /* startup code */ 159 /* 160 * i386 System V ABI mandates: 161 * 1) last pushed argument must be 16-byte ali 162 * 2) The deepest stack frame should be set to 163 * 164 */ 165 void __attribute__((weak, noreturn)) __nolibc_ 166 { 167 __asm__ volatile ( 168 "xor %ebp, %ebp\n" /* z 169 "mov %esp, %eax\n" /* s 170 "add $12, %esp\n" /* a 171 "and $-16, %esp\n" /* t 172 "sub $12, %esp\n" /* s 173 "push %eax\n" /* p 174 "call _start_c\n" /* t 175 "hlt\n" /* e 176 ); 177 __nolibc_entrypoint_epilogue(); 178 } 179 180 #endif /* _NOLIBC_ARCH_I386_H */ 181
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.