| 1 | /* $Id: kHlpSys-darwin.c 29 2009-07-01 20:30:29Z bird $ */ | 
|---|
| 2 | /** @file | 
|---|
| 3 | * kHlpBare - | 
|---|
| 4 | */ | 
|---|
| 5 |  | 
|---|
| 6 | /* | 
|---|
| 7 | * Copyright (c) 2006-2007 Knut St. Osmundsen <bird-kStuff-spamix@anduin.net> | 
|---|
| 8 | * | 
|---|
| 9 | * Permission is hereby granted, free of charge, to any person | 
|---|
| 10 | * obtaining a copy of this software and associated documentation | 
|---|
| 11 | * files (the "Software"), to deal in the Software without | 
|---|
| 12 | * restriction, including without limitation the rights to use, | 
|---|
| 13 | * copy, modify, merge, publish, distribute, sublicense, and/or sell | 
|---|
| 14 | * copies of the Software, and to permit persons to whom the | 
|---|
| 15 | * Software is furnished to do so, subject to the following | 
|---|
| 16 | * conditions: | 
|---|
| 17 | * | 
|---|
| 18 | * The above copyright notice and this permission notice shall be | 
|---|
| 19 | * included in all copies or substantial portions of the Software. | 
|---|
| 20 | * | 
|---|
| 21 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | 
|---|
| 22 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | 
|---|
| 23 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | 
|---|
| 24 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | 
|---|
| 25 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | 
|---|
| 26 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | 
|---|
| 27 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | 
|---|
| 28 | * OTHER DEALINGS IN THE SOFTWARE. | 
|---|
| 29 | */ | 
|---|
| 30 |  | 
|---|
| 31 | #include <k/kHlpSys.h> | 
|---|
| 32 | #include <unistd.h> | 
|---|
| 33 | #include <errno.h> | 
|---|
| 34 | #include <dlfcn.h> | 
|---|
| 35 | #include <sys/mman.h> | 
|---|
| 36 | #include <mach/mach_time.h> | 
|---|
| 37 |  | 
|---|
| 38 |  | 
|---|
| 39 | #define USE_DARWIN_SYSCALLS | 
|---|
| 40 |  | 
|---|
| 41 | #if K_ARCH == K_ARCH_X86_32 | 
|---|
| 42 | # define DARWIN_SYSCALL(name, code) \ | 
|---|
| 43 | asm("\ | 
|---|
| 44 | .text                                   \n\ | 
|---|
| 45 | .globl _" #name "                       \n\ | 
|---|
| 46 | _" #name ":                             \n\ | 
|---|
| 47 | mov     $ " #code ", %eax           \n\ | 
|---|
| 48 | call    1f                          \n\ | 
|---|
| 49 | 1:                                      \n\ | 
|---|
| 50 | pop     %edx                        \n\ | 
|---|
| 51 | mov     %esp, %ecx                  \n\ | 
|---|
| 52 | sysenter                            \n\ | 
|---|
| 53 | jnae    2f                          \n\ | 
|---|
| 54 | ret                                 \n\ | 
|---|
| 55 | 2:                                      \n\ | 
|---|
| 56 | neg     %eax                        \n\ | 
|---|
| 57 | ret                                 \n\ | 
|---|
| 58 | ") | 
|---|
| 59 |  | 
|---|
| 60 | # define DARWIN_SYSCALL_RET64(name, code) \ | 
|---|
| 61 | asm("\ | 
|---|
| 62 | .text                                   \n\ | 
|---|
| 63 | .globl _" #name "                       \n\ | 
|---|
| 64 | _" #name ":                             \n\ | 
|---|
| 65 | mov     $ " #code ", %eax           \n\ | 
|---|
| 66 | int     $0x80                       \n\ | 
|---|
| 67 | jnae    2f                          \n\ | 
|---|
| 68 | ret                                 \n\ | 
|---|
| 69 | 2:                                      \n\ | 
|---|
| 70 | neg     %eax                        \n\ | 
|---|
| 71 | mov     $0xffffffff, %edx           \n\ | 
|---|
| 72 | ret                                 \n\ | 
|---|
| 73 | ") | 
|---|
| 74 |  | 
|---|
| 75 | # define DARWIN_SYSCALL_NOERR(name, code) \ | 
|---|
| 76 | asm("\ | 
|---|
| 77 | .text                                   \n\ | 
|---|
| 78 | .globl _" #name "                       \n\ | 
|---|
| 79 | _" #name ":                             \n\ | 
|---|
| 80 | mov     $ " #code ", %eax           \n\ | 
|---|
| 81 | call    1f                          \n\ | 
|---|
| 82 | 1:                                      \n\ | 
|---|
| 83 | pop     %edx                        \n\ | 
|---|
| 84 | mov     %esp, %ecx                  \n\ | 
|---|
| 85 | sysenter                            \n\ | 
|---|
| 86 | ret                                 \n\ | 
|---|
| 87 | ") | 
|---|
| 88 |  | 
|---|
| 89 | #elif K_ARCH == K_ARCH_AMD64 | 
|---|
| 90 | # define DARWIN_SYSCALL(name, code) \ | 
|---|
| 91 | asm("\ | 
|---|
| 92 | .text                                   \n\ | 
|---|
| 93 | .globl _" #name "                       \n\ | 
|---|
| 94 | _" #name ":                             \n\ | 
|---|
| 95 | mov     $ " #code ", %eax           \n\ | 
|---|
| 96 | mov     %rcx, %r10                  \n\ | 
|---|
| 97 | sysenter                            \n\ | 
|---|
| 98 | jnae    2f                          \n\ | 
|---|
| 99 | ret                                 \n\ | 
|---|
| 100 | 2:                                      \n\ | 
|---|
| 101 | neg     %eax                        \n\ | 
|---|
| 102 | movsx   %eax, %rax                  \n\ | 
|---|
| 103 | ret                                 \n\ | 
|---|
| 104 | ") | 
|---|
| 105 |  | 
|---|
| 106 | # define DARWIN_SYSCALL_RET64(name, code) DARWIN_SYSCALL_RET(name, code) | 
|---|
| 107 |  | 
|---|
| 108 | # define DARWIN_SYSCALL_NOERR(name, code) \ | 
|---|
| 109 | asm("\ | 
|---|
| 110 | .text                                   \n\ | 
|---|
| 111 | .globl _" #name "                       \n\ | 
|---|
| 112 | _" #name ":                             \n\ | 
|---|
| 113 | mov     $ " #code ", %eax           \n\ | 
|---|
| 114 | mov     %rcx, %r10                  \n\ | 
|---|
| 115 | sysenter                            \n\ | 
|---|
| 116 | ret                                 \n\ | 
|---|
| 117 | ") | 
|---|
| 118 |  | 
|---|
| 119 |  | 
|---|
| 120 | #else | 
|---|
| 121 | # error later... | 
|---|
| 122 | #endif | 
|---|
| 123 |  | 
|---|
| 124 |  | 
|---|
| 125 | #if K_ARCH == K_ARCH_X86_32 && defined(USE_DARWIN_SYSCALLS) | 
|---|
| 126 | DARWIN_SYSCALL(kHlpSys_readlink, 0x000c003a); | 
|---|
| 127 | #elif K_ARCH == K_ARCH_AMD64 && defined(USE_DARWIN_SYSCALLS) | 
|---|
| 128 | DARWIN_SYSCALL(kHlpSys_readlink, 0x0200003a); | 
|---|
| 129 | #else | 
|---|
| 130 | KSSIZE      kHlpSys_readlink(const char *pszPath, char *pszBuf, KSIZE cbBuf) | 
|---|
| 131 | { | 
|---|
| 132 | KSSIZE cbRet = readlink(pszPath, pszBuf, cbBuf); | 
|---|
| 133 | return cbRet >= 0 ? cbRet : -errno; | 
|---|
| 134 | } | 
|---|
| 135 | #endif | 
|---|
| 136 |  | 
|---|
| 137 |  | 
|---|
| 138 | #if K_ARCH == K_ARCH_X86_32 && defined(USE_DARWIN_SYSCALLS) | 
|---|
| 139 | DARWIN_SYSCALL(kHlpSys_open, 0x000c0005); | 
|---|
| 140 | #elif K_ARCH == K_ARCH_AMD64 && defined(USE_DARWIN_SYSCALLS) | 
|---|
| 141 | DARWIN_SYSCALL(kHlpSys_open, 0x02000005); | 
|---|
| 142 | #else | 
|---|
| 143 | int         kHlpSys_open(const char *filename, int flags, int mode) | 
|---|
| 144 | { | 
|---|
| 145 | int fd = open(filename, flags, mode); | 
|---|
| 146 | return fd >= 0 ? fd : -errno; | 
|---|
| 147 | } | 
|---|
| 148 | #endif | 
|---|
| 149 |  | 
|---|
| 150 |  | 
|---|
| 151 | #if K_ARCH == K_ARCH_X86_32 && defined(USE_DARWIN_SYSCALLS) | 
|---|
| 152 | DARWIN_SYSCALL(kHlpSys_close, 0x000c0006); | 
|---|
| 153 | #elif K_ARCH == K_ARCH_AMD64 && defined(USE_DARWIN_SYSCALLS) | 
|---|
| 154 | DARWIN_SYSCALL(kHlpSys_close, 0x02000006); | 
|---|
| 155 | #else | 
|---|
| 156 | int         kHlpSys_close(int fd) | 
|---|
| 157 | { | 
|---|
| 158 | if (!close(fd)) | 
|---|
| 159 | return 0; | 
|---|
| 160 | return -errno; | 
|---|
| 161 | } | 
|---|
| 162 | #endif | 
|---|
| 163 |  | 
|---|
| 164 |  | 
|---|
| 165 | #if K_ARCH == K_ARCH_X86_32 && defined(USE_DARWIN_SYSCALLS) | 
|---|
| 166 | DARWIN_SYSCALL_RET64(kHlpSys_lseek, 0x000000c7); | 
|---|
| 167 | #elif K_ARCH == K_ARCH_AMD64 && defined(USE_DARWIN_SYSCALLS) | 
|---|
| 168 | DARWIN_SYSCALL_RET64(kHlpSys_lseek, 0x020000c7); | 
|---|
| 169 | #else | 
|---|
| 170 | KFOFF       kHlpSys_lseek(int fd, int whench, KFOFF off) | 
|---|
| 171 | { | 
|---|
| 172 | KFOFF offRet = lseek(fd, whench, off); | 
|---|
| 173 | return offRet >= 0 ? offRet : -errno; | 
|---|
| 174 | } | 
|---|
| 175 | #endif | 
|---|
| 176 |  | 
|---|
| 177 |  | 
|---|
| 178 | #if K_ARCH == K_ARCH_X86_32 && defined(USE_DARWIN_SYSCALLS) | 
|---|
| 179 | DARWIN_SYSCALL(kHlpSys_read, 0x000c0003); | 
|---|
| 180 | #elif K_ARCH == K_ARCH_AMD64 && defined(USE_DARWIN_SYSCALLS) | 
|---|
| 181 | DARWIN_SYSCALL(kHlpSys_read, 0x02000003); | 
|---|
| 182 | #else | 
|---|
| 183 | KSSIZE      kHlpSys_read(int fd, void *pvBuf, KSIZE cbBuf) | 
|---|
| 184 | { | 
|---|
| 185 | KSSIZE cbRead = read(fd, pvBuf, cbBuf); | 
|---|
| 186 | return cbRead >= 0 ? cbRead : -errno; | 
|---|
| 187 | } | 
|---|
| 188 | #endif | 
|---|
| 189 |  | 
|---|
| 190 |  | 
|---|
| 191 | #if K_ARCH == K_ARCH_X86_32 && defined(USE_DARWIN_SYSCALLS) | 
|---|
| 192 | DARWIN_SYSCALL(kHlpSys_write, 0x000c0004); | 
|---|
| 193 | #elif K_ARCH == K_ARCH_AMD64 && defined(USE_DARWIN_SYSCALLS) | 
|---|
| 194 | DARWIN_SYSCALL(kHlpSys_write, 0x02000004); | 
|---|
| 195 | #else | 
|---|
| 196 | KSSIZE      kHlpSys_write(int fd, const void *pvBuf, KSIZE cbBuf) | 
|---|
| 197 | { | 
|---|
| 198 | KSSIZE cbWritten = write(fd, pvBuf, cbBuf); | 
|---|
| 199 | return cbWritten >= 0 ? cbWritten : -errno; | 
|---|
| 200 | } | 
|---|
| 201 | #endif | 
|---|
| 202 |  | 
|---|
| 203 |  | 
|---|
| 204 | #if K_ARCH == K_ARCH_X86_32 && defined(USE_DARWIN_SYSCALLS) | 
|---|
| 205 | DARWIN_SYSCALL(kHlpSys_mmap, 0x020000c5); | 
|---|
| 206 | #elif K_ARCH == K_ARCH_AMD64 && defined(USE_DARWIN_SYSCALLS) | 
|---|
| 207 | DARWIN_SYSCALL(kHlpSys_mmap, 0x020000c5); | 
|---|
| 208 | #else | 
|---|
| 209 | void       *kHlpSys_mmap(void *addr, KSIZE len, int prot, int flags, int fd, KI64 off) | 
|---|
| 210 | { | 
|---|
| 211 | void *pv = mmap(addr, len, prot, flags, fd, off); | 
|---|
| 212 | return pv != (void *)-1 | 
|---|
| 213 | ? pv | 
|---|
| 214 | : errno < 256 ? (void *)(long)errno : (void *)(long)ENOMEM; | 
|---|
| 215 | } | 
|---|
| 216 | #endif | 
|---|
| 217 |  | 
|---|
| 218 |  | 
|---|
| 219 | #if K_ARCH == K_ARCH_X86_32 && defined(USE_DARWIN_SYSCALLS) | 
|---|
| 220 | DARWIN_SYSCALL(kHlpSys_mprotect, 0x000c004a); | 
|---|
| 221 | #elif K_ARCH == K_ARCH_AMD64 && defined(USE_DARWIN_SYSCALLS) | 
|---|
| 222 | DARWIN_SYSCALL(kHlpSys_mprotect, 0x0200004a); | 
|---|
| 223 | #else | 
|---|
| 224 | int         kHlpSys_mprotect(void *addr, KSIZE len, int prot) | 
|---|
| 225 | { | 
|---|
| 226 | if (!mprotect(addr, len, prot)) | 
|---|
| 227 | return 0; | 
|---|
| 228 | return -errno; | 
|---|
| 229 | } | 
|---|
| 230 | #endif | 
|---|
| 231 |  | 
|---|
| 232 |  | 
|---|
| 233 | #if K_ARCH == K_ARCH_X86_32 && defined(USE_DARWIN_SYSCALLS) | 
|---|
| 234 | DARWIN_SYSCALL(kHlpSys_munmap, 0x00080049); | 
|---|
| 235 | #elif K_ARCH == K_ARCH_AMD64 && defined(USE_DARWIN_SYSCALLS) | 
|---|
| 236 | DARWIN_SYSCALL(kHlpSys_munmap, 0x02000049); | 
|---|
| 237 | #else | 
|---|
| 238 | int         kHlpSys_munmap(void *addr, KSIZE len) | 
|---|
| 239 | { | 
|---|
| 240 | if (!munmap(addr, len)) | 
|---|
| 241 | return 0; | 
|---|
| 242 | return -errno; | 
|---|
| 243 | } | 
|---|
| 244 | #endif | 
|---|
| 245 |  | 
|---|
| 246 |  | 
|---|
| 247 | #if K_ARCH == K_ARCH_X86_32 && defined(USE_DARWIN_SYSCALLS) | 
|---|
| 248 | DARWIN_SYSCALL(kHlpSys_exit, 0x00040001); | 
|---|
| 249 | #elif K_ARCH == K_ARCH_AMD64 && defined(USE_DARWIN_SYSCALLS) | 
|---|
| 250 | DARWIN_SYSCALL(kHlpSys_exit, 0x02000001); | 
|---|
| 251 | #else | 
|---|
| 252 | void        kHlpSys_exit(int rc) | 
|---|
| 253 | { | 
|---|
| 254 | _Exit(rc); | 
|---|
| 255 | } | 
|---|
| 256 | #endif | 
|---|
| 257 |  | 
|---|
| 258 |  | 
|---|
| 259 | /* | 
|---|
| 260 | * Some other stuff we'll be needing - Move to an appropriate place? | 
|---|
| 261 | */ | 
|---|
| 262 |  | 
|---|
| 263 | #if K_ARCH == K_ARCH_X86_32 && defined(USE_DARWIN_SYSCALLS) | 
|---|
| 264 | DARWIN_SYSCALL_NOERR(mach_task_self, 0xffffffe4); | 
|---|
| 265 | #elif K_ARCH == K_ARCH_AMD64 && defined(USE_DARWIN_SYSCALLS) | 
|---|
| 266 | DARWIN_SYSCALL_NOERR(mach_task_self, 0xffffffe4); | 
|---|
| 267 | #endif | 
|---|
| 268 |  | 
|---|
| 269 | //#if K_ARCH == K_ARCH_X86_32 && defined(USE_DARWIN_SYSCALLS) | 
|---|
| 270 | //DARWIN_SYSCALL(semaphore_create, 0x00040001); | 
|---|
| 271 | //#elif K_ARCH == K_ARCH_AMD64 && defined(USE_DARWIN_SYSCALLS) | 
|---|
| 272 | //DARWIN_SYSCALL(semaphore_create, 0x02000001); | 
|---|
| 273 | //#endif | 
|---|
| 274 | #ifdef USE_DARWIN_SYSCALLS | 
|---|
| 275 | kern_return_t semaphore_create(task_t t, semaphore_t *ps, int p, int v) | 
|---|
| 276 | { | 
|---|
| 277 | return 0; | 
|---|
| 278 | } | 
|---|
| 279 | #endif | 
|---|
| 280 |  | 
|---|
| 281 | //#if K_ARCH == K_ARCH_X86_32 && defined(USE_DARWIN_SYSCALLS) | 
|---|
| 282 | //DARWIN_SYSCALL(semaphore_destroy, 0x00040001); | 
|---|
| 283 | //#elif K_ARCH == K_ARCH_AMD64 && defined(USE_DARWIN_SYSCALLS) | 
|---|
| 284 | //DARWIN_SYSCALL(semaphore_destroy, 0x02000001); | 
|---|
| 285 | //#endif | 
|---|
| 286 | #ifdef USE_DARWIN_SYSCALLS | 
|---|
| 287 | kern_return_t semaphore_destroy(task_t t, semaphore_t s) | 
|---|
| 288 | { | 
|---|
| 289 | return 0; | 
|---|
| 290 | } | 
|---|
| 291 | #endif | 
|---|
| 292 |  | 
|---|
| 293 |  | 
|---|
| 294 | #if K_ARCH == K_ARCH_X86_32 && defined(USE_DARWIN_SYSCALLS) | 
|---|
| 295 | DARWIN_SYSCALL(semaphore_wait, 0xffffffdc); | 
|---|
| 296 | #elif K_ARCH == K_ARCH_AMD64 && defined(USE_DARWIN_SYSCALLS) | 
|---|
| 297 | DARWIN_SYSCALL(semaphore_wait, 0xffffffdc); | 
|---|
| 298 | #endif | 
|---|
| 299 |  | 
|---|
| 300 | #if K_ARCH == K_ARCH_X86_32 && defined(USE_DARWIN_SYSCALLS) | 
|---|
| 301 | DARWIN_SYSCALL(semaphore_signal, 0xffffffdf); | 
|---|
| 302 | #elif K_ARCH == K_ARCH_AMD64 && defined(USE_DARWIN_SYSCALLS) | 
|---|
| 303 | DARWIN_SYSCALL(semaphore_signal, 0xffffffdf); | 
|---|
| 304 | #endif | 
|---|
| 305 |  | 
|---|
| 306 | #if K_ARCH == K_ARCH_X86_32 && defined(USE_DARWIN_SYSCALLS) | 
|---|
| 307 | DARWIN_SYSCALL(mach_wait_until, 0xffffffa6); | 
|---|
| 308 | #elif K_ARCH == K_ARCH_AMD64 && defined(USE_DARWIN_SYSCALLS) | 
|---|
| 309 | DARWIN_SYSCALL(mach_wait_until, 0xffffffa6); | 
|---|
| 310 | #endif | 
|---|
| 311 |  | 
|---|
| 312 | #if K_ARCH == K_ARCH_X86_32 && defined(USE_DARWIN_SYSCALLS) | 
|---|
| 313 | DARWIN_SYSCALL(mach_timebase_info, 0xffffffa7); | 
|---|
| 314 | #elif K_ARCH == K_ARCH_AMD64 && defined(USE_DARWIN_SYSCALLS) | 
|---|
| 315 | DARWIN_SYSCALL(mach_timebase_info, 0xffffffa7); | 
|---|
| 316 | #endif | 
|---|
| 317 |  | 
|---|
| 318 | #if K_ARCH == K_ARCH_X86_32 && defined(USE_DARWIN_SYSCALLS) | 
|---|
| 319 | asm("\n\ | 
|---|
| 320 | .text                           \n\ | 
|---|
| 321 | .globl _mach_absolute_time      \n\ | 
|---|
| 322 | _mach_absolute_time:            \n\ | 
|---|
| 323 | mov     $0xffff1700, %edx   \n\ | 
|---|
| 324 | jmp     *%edx\n"); /* common page stuff. */ | 
|---|
| 325 | #elif K_ARCH == K_ARCH_AMD64 && defined(USE_DARWIN_SYSCALLS) | 
|---|
| 326 | #endif | 
|---|
| 327 |  | 
|---|
| 328 |  | 
|---|
| 329 | void *dlopen(const char *pszModule, int fFlags) | 
|---|
| 330 | { | 
|---|
| 331 | return NULL; | 
|---|
| 332 | } | 
|---|
| 333 |  | 
|---|
| 334 |  | 
|---|
| 335 | int dlclose(void *pvMod) | 
|---|
| 336 | { | 
|---|
| 337 |  | 
|---|
| 338 | } | 
|---|
| 339 |  | 
|---|
| 340 |  | 
|---|
| 341 | void *dlsym(void *pvMod, const char *pszSymbol) | 
|---|
| 342 | { | 
|---|
| 343 | return NULL; | 
|---|
| 344 | } | 
|---|
| 345 |  | 
|---|