libc.go (40250B)
1 // Copyright 2020 The Libc Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go.generate echo package libc > ccgo.go 6 //go:generate go run generate.go 7 //go:generate go fmt ./... 8 9 // Package libc provides run time support for ccgo generated programs and 10 // implements selected parts of the C standard library. 11 package libc // import "modernc.org/libc" 12 13 //TODO use O_RDONLY etc. from fcntl header 14 15 //TODO use t.Alloc/Free where appropriate 16 17 import ( 18 "bufio" 19 crand "crypto/rand" 20 "fmt" 21 "math" 22 mbits "math/bits" 23 "math/rand" 24 "os" 25 "runtime" 26 "runtime/debug" 27 "sort" 28 "strings" 29 "sync" 30 "sync/atomic" 31 gotime "time" 32 "unsafe" 33 34 "github.com/mattn/go-isatty" 35 "modernc.org/libc/errno" 36 "modernc.org/libc/stdio" 37 "modernc.org/libc/sys/types" 38 "modernc.org/libc/time" 39 "modernc.org/libc/unistd" 40 "modernc.org/mathutil" 41 ) 42 43 type ( 44 // RawMem64 represents the biggest uint64 array the runtime can handle. 45 RawMem64 [unsafe.Sizeof(RawMem{}) / unsafe.Sizeof(uint64(0))]uint64 46 ) 47 48 var ( 49 allocMu sync.Mutex 50 environInitialized bool 51 isWindows bool 52 ) 53 54 // Keep these outside of the var block otherwise go generate will miss them. 55 var Xenviron uintptr 56 var Xstdin = newFile(nil, unistd.STDIN_FILENO) 57 var Xstdout = newFile(nil, unistd.STDOUT_FILENO) 58 var Xstderr = newFile(nil, unistd.STDERR_FILENO) 59 60 func setEnviron() { 61 SetEnviron(nil, os.Environ()) 62 } 63 64 func Environ() uintptr { 65 if !environInitialized { 66 SetEnviron(nil, os.Environ()) 67 } 68 return Xenviron 69 } 70 71 func EnvironP() uintptr { 72 if !environInitialized { 73 SetEnviron(nil, os.Environ()) 74 } 75 return uintptr(unsafe.Pointer(&Xenviron)) 76 } 77 78 func X___errno_location(t *TLS) uintptr { 79 return X__errno_location(t) 80 } 81 82 // int * __errno_location(void); 83 func X__errno_location(t *TLS) uintptr { 84 return t.errnop 85 } 86 87 func Start(main func(*TLS, int32, uintptr) int32) { 88 if dmesgs { 89 wd, err := os.Getwd() 90 dmesg("%v: %v, wd %v, %v", origin(1), os.Args, wd, err) 91 92 defer func() { 93 if err := recover(); err != nil { 94 dmesg("%v: CRASH: %v\n%s", origin(1), err, debug.Stack()) 95 } 96 }() 97 } 98 runtime.LockOSThread() 99 t := &TLS{errnop: uintptr(unsafe.Pointer(&errno0))} 100 argv := Xcalloc(t, 1, types.Size_t((len(os.Args)+1)*int(uintptrSize))) 101 if argv == 0 { 102 panic("OOM") 103 } 104 105 p := argv 106 for _, v := range os.Args { 107 s := Xcalloc(t, 1, types.Size_t(len(v)+1)) 108 if s == 0 { 109 panic("OOM") 110 } 111 112 copy((*RawMem)(unsafe.Pointer(s))[:len(v):len(v)], v) 113 *(*uintptr)(unsafe.Pointer(p)) = s 114 p += uintptrSize 115 } 116 SetEnviron(t, os.Environ()) 117 audit := false 118 if memgrind { 119 if s := os.Getenv("LIBC_MEMGRIND_START"); s != "0" { 120 MemAuditStart() 121 audit = true 122 } 123 } 124 t = NewTLS() 125 rc := main(t, int32(len(os.Args)), argv) 126 exit(t, rc, audit) 127 } 128 129 func Xexit(t *TLS, status int32) { exit(t, status, false) } 130 131 func exit(t *TLS, status int32, audit bool) { 132 if len(Covered) != 0 { 133 buf := bufio.NewWriter(os.Stdout) 134 CoverReport(buf) 135 buf.Flush() 136 } 137 if len(CoveredC) != 0 { 138 buf := bufio.NewWriter(os.Stdout) 139 CoverCReport(buf) 140 buf.Flush() 141 } 142 for _, v := range atExit { 143 v() 144 } 145 if audit { 146 t.Close() 147 if tlsBalance != 0 { 148 fmt.Fprintf(os.Stderr, "non zero TLS balance: %d\n", tlsBalance) 149 status = 1 150 } 151 } 152 X_exit(nil, status) 153 } 154 155 // void _exit(int status); 156 func X_exit(_ *TLS, status int32) { 157 if dmesgs { 158 dmesg("%v: EXIT %v", origin(1), status) 159 } 160 os.Exit(int(status)) 161 } 162 163 func SetEnviron(t *TLS, env []string) { 164 if environInitialized { 165 return 166 } 167 168 environInitialized = true 169 p := Xcalloc(t, 1, types.Size_t((len(env)+1)*(int(uintptrSize)))) 170 if p == 0 { 171 panic("OOM") 172 } 173 174 Xenviron = p 175 for _, v := range env { 176 s := Xcalloc(t, 1, types.Size_t(len(v)+1)) 177 if s == 0 { 178 panic("OOM") 179 } 180 181 copy((*(*RawMem)(unsafe.Pointer(s)))[:len(v):len(v)], v) 182 *(*uintptr)(unsafe.Pointer(p)) = s 183 p += uintptrSize 184 } 185 } 186 187 // void setbuf(FILE *stream, char *buf); 188 func Xsetbuf(t *TLS, stream, buf uintptr) { 189 //TODO panic(todo("")) 190 } 191 192 // size_t confstr(int name, char *buf, size_t len); 193 func Xconfstr(t *TLS, name int32, buf uintptr, len types.Size_t) types.Size_t { 194 panic(todo("")) 195 } 196 197 // int puts(const char *s); 198 func Xputs(t *TLS, s uintptr) int32 { 199 n, err := fmt.Printf("%s\n", GoString(s)) 200 if err != nil { 201 return stdio.EOF 202 } 203 204 return int32(n) 205 } 206 207 var ( 208 randomMu sync.Mutex 209 randomGen = rand.New(rand.NewSource(42)) 210 ) 211 212 // long int random(void); 213 func Xrandom(t *TLS) long { 214 randomMu.Lock() 215 r := randomGen.Int63n(math.MaxInt32 + 1) 216 randomMu.Unlock() 217 return long(r) 218 } 219 220 func write(b []byte) (int, error) { 221 // if dmesgs { 222 // dmesg("%v: %s", origin(1), b) 223 // } 224 if _, err := os.Stdout.Write(b); err != nil { 225 return -1, err 226 } 227 228 return len(b), nil 229 } 230 231 func X__builtin_bzero(t *TLS, s uintptr, n types.Size_t) { Xbzero(t, s, n) } 232 func X__builtin_abort(t *TLS) { Xabort(t) } 233 func X__builtin_abs(t *TLS, j int32) int32 { return Xabs(t, j) } 234 func X__builtin_clz(t *TLS, n uint32) int32 { return int32(mbits.LeadingZeros32(n)) } 235 func X__builtin_clzl(t *TLS, n ulong) int32 { return int32(mbits.LeadingZeros64(uint64(n))) } 236 func X__builtin_clzll(t *TLS, n uint64) int32 { return int32(mbits.LeadingZeros64(n)) } 237 func X__builtin_constant_p_impl() { panic(todo("internal error: should never be called")) } 238 func X__builtin_copysign(t *TLS, x, y float64) float64 { return Xcopysign(t, x, y) } 239 func X__builtin_copysignf(t *TLS, x, y float32) float32 { return Xcopysignf(t, x, y) } 240 func X__builtin_copysignl(t *TLS, x, y float64) float64 { return Xcopysign(t, x, y) } 241 func X__builtin_exit(t *TLS, status int32) { Xexit(t, status) } 242 func X__builtin_expect(t *TLS, exp, c long) long { return exp } 243 func X__builtin_fabs(t *TLS, x float64) float64 { return Xfabs(t, x) } 244 func X__builtin_fabsf(t *TLS, x float32) float32 { return Xfabsf(t, x) } 245 func X__builtin_fabsl(t *TLS, x float64) float64 { return Xfabsl(t, x) } 246 func X__builtin_free(t *TLS, ptr uintptr) { Xfree(t, ptr) } 247 func X__builtin_getentropy(t *TLS, buf uintptr, n types.Size_t) int32 { return Xgetentropy(t, buf, n) } 248 func X__builtin_huge_val(t *TLS) float64 { return math.Inf(1) } 249 func X__builtin_huge_valf(t *TLS) float32 { return float32(math.Inf(1)) } 250 func X__builtin_inf(t *TLS) float64 { return math.Inf(1) } 251 func X__builtin_inff(t *TLS) float32 { return float32(math.Inf(1)) } 252 func X__builtin_infl(t *TLS) float64 { return math.Inf(1) } 253 func X__builtin_malloc(t *TLS, size types.Size_t) uintptr { return Xmalloc(t, size) } 254 func X__builtin_memcmp(t *TLS, s1, s2 uintptr, n types.Size_t) int32 { return Xmemcmp(t, s1, s2, n) } 255 func X__builtin_nan(t *TLS, s uintptr) float64 { return math.NaN() } 256 func X__builtin_nanf(t *TLS, s uintptr) float32 { return float32(math.NaN()) } 257 func X__builtin_nanl(t *TLS, s uintptr) float64 { return math.NaN() } 258 func X__builtin_prefetch(t *TLS, addr, args uintptr) {} 259 func X__builtin_printf(t *TLS, s, args uintptr) int32 { return Xprintf(t, s, args) } 260 func X__builtin_strchr(t *TLS, s uintptr, c int32) uintptr { return Xstrchr(t, s, c) } 261 func X__builtin_strcmp(t *TLS, s1, s2 uintptr) int32 { return Xstrcmp(t, s1, s2) } 262 func X__builtin_strcpy(t *TLS, dest, src uintptr) uintptr { return Xstrcpy(t, dest, src) } 263 func X__builtin_strlen(t *TLS, s uintptr) types.Size_t { return Xstrlen(t, s) } 264 func X__builtin_trap(t *TLS) { Xabort(t) } 265 func X__isnan(t *TLS, arg float64) int32 { return X__builtin_isnan(t, arg) } 266 func X__isnanf(t *TLS, arg float32) int32 { return Xisnanf(t, arg) } 267 func X__isnanl(t *TLS, arg float64) int32 { return Xisnanl(t, arg) } 268 269 func Xvfprintf(t *TLS, stream, format, ap uintptr) int32 { return Xfprintf(t, stream, format, ap) } 270 271 // int __builtin_popcount (unsigned int x) 272 func X__builtin_popcount(t *TLS, x uint32) int32 { 273 return int32(mbits.OnesCount32(x)) 274 } 275 276 // int __builtin_popcountl (unsigned long x) 277 func X__builtin_popcountl(t *TLS, x ulong) int32 { 278 return int32(mbits.OnesCount64(uint64(x))) 279 } 280 281 // char * __builtin___strcpy_chk (char *dest, const char *src, size_t os); 282 func X__builtin___strcpy_chk(t *TLS, dest, src uintptr, os types.Size_t) uintptr { 283 return Xstrcpy(t, dest, src) 284 } 285 286 func X__builtin_mmap(t *TLS, addr uintptr, length types.Size_t, prot, flags, fd int32, offset types.Off_t) uintptr { 287 return Xmmap(t, addr, length, prot, flags, fd, offset) 288 } 289 290 // uint16_t __builtin_bswap16 (uint32_t x) 291 func X__builtin_bswap16(t *TLS, x uint16) uint16 { 292 return x<<8 | 293 x>>8 294 } 295 296 // uint32_t __builtin_bswap32 (uint32_t x) 297 func X__builtin_bswap32(t *TLS, x uint32) uint32 { 298 return x<<24 | 299 x&0xff00<<8 | 300 x&0xff0000>>8 | 301 x>>24 302 } 303 304 // uint64_t __builtin_bswap64 (uint64_t x) 305 func X__builtin_bswap64(t *TLS, x uint64) uint64 { 306 return x<<56 | 307 x&0xff00<<40 | 308 x&0xff0000<<24 | 309 x&0xff000000<<8 | 310 x&0xff00000000>>8 | 311 x&0xff0000000000>>24 | 312 x&0xff000000000000>>40 | 313 x>>56 314 } 315 316 // bool __builtin_add_overflow (type1 a, type2 b, type3 *res) 317 func X__builtin_add_overflowInt64(t *TLS, a, b int64, res uintptr) int32 { 318 r, ovf := mathutil.AddOverflowInt64(a, b) 319 *(*int64)(unsafe.Pointer(res)) = r 320 return Bool32(ovf) 321 } 322 323 // bool __builtin_add_overflow (type1 a, type2 b, type3 *res) 324 func X__builtin_add_overflowUint32(t *TLS, a, b uint32, res uintptr) int32 { 325 r := a + b 326 *(*uint32)(unsafe.Pointer(res)) = r 327 return Bool32(r < a) 328 } 329 330 // bool __builtin_add_overflow (type1 a, type2 b, type3 *res) 331 func X__builtin_add_overflowUint64(t *TLS, a, b uint64, res uintptr) int32 { 332 r := a + b 333 *(*uint64)(unsafe.Pointer(res)) = r 334 return Bool32(r < a) 335 } 336 337 // bool __builtin_sub_overflow (type1 a, type2 b, type3 *res) 338 func X__builtin_sub_overflowInt64(t *TLS, a, b int64, res uintptr) int32 { 339 r, ovf := mathutil.SubOverflowInt64(a, b) 340 *(*int64)(unsafe.Pointer(res)) = r 341 return Bool32(ovf) 342 } 343 344 // bool __builtin_mul_overflow (type1 a, type2 b, type3 *res) 345 func X__builtin_mul_overflowInt64(t *TLS, a, b int64, res uintptr) int32 { 346 r, ovf := mathutil.MulOverflowInt64(a, b) 347 *(*int64)(unsafe.Pointer(res)) = r 348 return Bool32(ovf) 349 } 350 351 // bool __builtin_mul_overflow (type1 a, type2 b, type3 *res) 352 func X__builtin_mul_overflowUint64(t *TLS, a, b uint64, res uintptr) int32 { 353 hi, lo := mbits.Mul64(a, b) 354 *(*uint64)(unsafe.Pointer(res)) = lo 355 return Bool32(hi != 0) 356 } 357 358 // bool __builtin_mul_overflow (type1 a, type2 b, type3 *res) 359 func X__builtin_mul_overflowUint128(t *TLS, a, b Uint128, res uintptr) int32 { 360 r, ovf := a.mulOvf(b) 361 *(*Uint128)(unsafe.Pointer(res)) = r 362 return Bool32(ovf) 363 } 364 365 func X__builtin_unreachable(t *TLS) { 366 fmt.Fprintf(os.Stderr, "unrechable\n") 367 os.Stderr.Sync() 368 Xexit(t, 1) 369 } 370 371 func X__builtin_snprintf(t *TLS, str uintptr, size types.Size_t, format, args uintptr) int32 { 372 return Xsnprintf(t, str, size, format, args) 373 } 374 375 func X__builtin_sprintf(t *TLS, str, format, args uintptr) (r int32) { 376 return Xsprintf(t, str, format, args) 377 } 378 379 func X__builtin_memcpy(t *TLS, dest, src uintptr, n types.Size_t) (r uintptr) { 380 return Xmemcpy(t, dest, src, n) 381 } 382 383 // void * __builtin___memcpy_chk (void *dest, const void *src, size_t n, size_t os); 384 func X__builtin___memcpy_chk(t *TLS, dest, src uintptr, n, os types.Size_t) (r uintptr) { 385 if os != ^types.Size_t(0) && n < os { 386 Xabort(t) 387 } 388 389 return Xmemcpy(t, dest, src, n) 390 } 391 392 func X__builtin_memset(t *TLS, s uintptr, c int32, n types.Size_t) uintptr { 393 return Xmemset(t, s, c, n) 394 } 395 396 // void * __builtin___memset_chk (void *s, int c, size_t n, size_t os); 397 func X__builtin___memset_chk(t *TLS, s uintptr, c int32, n, os types.Size_t) uintptr { 398 if os < n { 399 Xabort(t) 400 } 401 402 return Xmemset(t, s, c, n) 403 } 404 405 // size_t __builtin_object_size (const void * ptr, int type) 406 func X__builtin_object_size(t *TLS, p uintptr, typ int32) types.Size_t { 407 return ^types.Size_t(0) //TODO frontend magic 408 } 409 410 var atomicLoadStore16 sync.Mutex 411 412 func AtomicLoadNUint16(ptr uintptr, memorder int32) uint16 { 413 atomicLoadStore16.Lock() 414 r := *(*uint16)(unsafe.Pointer(ptr)) 415 atomicLoadStore16.Unlock() 416 return r 417 } 418 419 func AtomicStoreNUint16(ptr uintptr, val uint16, memorder int32) { 420 atomicLoadStore16.Lock() 421 *(*uint16)(unsafe.Pointer(ptr)) = val 422 atomicLoadStore16.Unlock() 423 } 424 425 // int sprintf(char *str, const char *format, ...); 426 func Xsprintf(t *TLS, str, format, args uintptr) (r int32) { 427 b := printf(format, args) 428 r = int32(len(b)) 429 copy((*RawMem)(unsafe.Pointer(str))[:r:r], b) 430 *(*byte)(unsafe.Pointer(str + uintptr(r))) = 0 431 return int32(len(b)) 432 } 433 434 // int __builtin___sprintf_chk (char *s, int flag, size_t os, const char *fmt, ...); 435 func X__builtin___sprintf_chk(t *TLS, s uintptr, flag int32, os types.Size_t, format, args uintptr) (r int32) { 436 return Xsprintf(t, s, format, args) 437 } 438 439 // void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)); 440 func Xqsort(t *TLS, base uintptr, nmemb, size types.Size_t, compar uintptr) { 441 sort.Sort(&sorter{ 442 len: int(nmemb), 443 base: base, 444 sz: uintptr(size), 445 f: (*struct { 446 f func(*TLS, uintptr, uintptr) int32 447 })(unsafe.Pointer(&struct{ uintptr }{compar})).f, 448 t: t, 449 }) 450 } 451 452 // void __assert_fail(const char * assertion, const char * file, unsigned int line, const char * function); 453 func X__assert_fail(t *TLS, assertion, file uintptr, line uint32, function uintptr) { 454 fmt.Fprintf(os.Stderr, "assertion failure: %s:%d.%s: %s\n", GoString(file), line, GoString(function), GoString(assertion)) 455 if memgrind { 456 fmt.Fprintf(os.Stderr, "%s\n", debug.Stack()) 457 } 458 os.Stderr.Sync() 459 Xexit(t, 1) 460 } 461 462 // int vprintf(const char *format, va_list ap); 463 func Xvprintf(t *TLS, s, ap uintptr) int32 { return Xprintf(t, s, ap) } 464 465 // int vsprintf(char *str, const char *format, va_list ap); 466 func Xvsprintf(t *TLS, str, format, va uintptr) int32 { 467 return Xsprintf(t, str, format, va) 468 } 469 470 // int vsnprintf(char *str, size_t size, const char *format, va_list ap); 471 func Xvsnprintf(t *TLS, str uintptr, size types.Size_t, format, va uintptr) int32 { 472 return Xsnprintf(t, str, size, format, va) 473 } 474 475 // int obstack_vprintf (struct obstack *obstack, const char *template, va_list ap) 476 func Xobstack_vprintf(t *TLS, obstack, template, va uintptr) int32 { 477 panic(todo("")) 478 } 479 480 // extern void _obstack_newchunk(struct obstack *, int); 481 func X_obstack_newchunk(t *TLS, obstack uintptr, length int32) int32 { 482 panic(todo("")) 483 } 484 485 // int _obstack_begin (struct obstack *h, _OBSTACK_SIZE_T size, _OBSTACK_SIZE_T alignment, void *(*chunkfun) (size_t), void (*freefun) (void *)) 486 func X_obstack_begin(t *TLS, obstack uintptr, size, alignment int32, chunkfun, freefun uintptr) int32 { 487 panic(todo("")) 488 } 489 490 // void obstack_free (struct obstack *h, void *obj) 491 func Xobstack_free(t *TLS, obstack, obj uintptr) { 492 panic(todo("")) 493 } 494 495 // unsigned int sleep(unsigned int seconds); 496 func Xsleep(t *TLS, seconds uint32) uint32 { 497 gotime.Sleep(gotime.Second * gotime.Duration(seconds)) 498 return 0 499 } 500 501 // size_t strcspn(const char *s, const char *reject); 502 func Xstrcspn(t *TLS, s, reject uintptr) (r types.Size_t) { 503 bits := newBits(256) 504 for { 505 c := *(*byte)(unsafe.Pointer(reject)) 506 if c == 0 { 507 break 508 } 509 510 reject++ 511 bits.set(int(c)) 512 } 513 for { 514 c := *(*byte)(unsafe.Pointer(s)) 515 if c == 0 || bits.has(int(c)) { 516 return r 517 } 518 519 s++ 520 r++ 521 } 522 } 523 524 // int printf(const char *format, ...); 525 func Xprintf(t *TLS, format, args uintptr) int32 { 526 n, _ := write(printf(format, args)) 527 return int32(n) 528 } 529 530 // int snprintf(char *str, size_t size, const char *format, ...); 531 func Xsnprintf(t *TLS, str uintptr, size types.Size_t, format, args uintptr) (r int32) { 532 if format == 0 { 533 return 0 534 } 535 536 b := printf(format, args) 537 r = int32(len(b)) 538 if size == 0 { 539 return r 540 } 541 542 if len(b)+1 > int(size) { 543 b = b[:size-1] 544 } 545 n := len(b) 546 copy((*RawMem)(unsafe.Pointer(str))[:n:n], b) 547 *(*byte)(unsafe.Pointer(str + uintptr(n))) = 0 548 return r 549 } 550 551 // int __builtin___snprintf_chk(char * str, size_t maxlen, int flag, size_t os, const char * format, ...); 552 func X__builtin___snprintf_chk(t *TLS, str uintptr, maxlen types.Size_t, flag int32, os types.Size_t, format, args uintptr) (r int32) { 553 if os != ^types.Size_t(0) && maxlen > os { 554 Xabort(t) 555 } 556 557 return Xsnprintf(t, str, maxlen, format, args) 558 } 559 560 // int __builtin___vsnprintf_chk (char *s, size_t maxlen, int flag, size_t os, const char *fmt, va_list ap); 561 func X__builtin___vsnprintf_chk(t *TLS, str uintptr, maxlen types.Size_t, flag int32, os types.Size_t, format, args uintptr) (r int32) { 562 if os != ^types.Size_t(0) && maxlen > os { 563 Xabort(t) 564 } 565 566 return Xsnprintf(t, str, maxlen, format, args) 567 } 568 569 // int abs(int j); 570 func Xabs(t *TLS, j int32) int32 { 571 if j >= 0 { 572 return j 573 } 574 575 return -j 576 } 577 578 func Xllabs(tls *TLS, a int64) int64 { 579 if a >= int64(0) { 580 return a 581 } 582 583 return -a 584 } 585 586 func X__builtin_isnan(t *TLS, x float64) int32 { return Bool32(math.IsNaN(x)) } 587 func X__builtin_llabs(tls *TLS, a int64) int64 { return Xllabs(tls, a) } 588 func Xacos(t *TLS, x float64) float64 { return math.Acos(x) } 589 func Xacosh(t *TLS, x float64) float64 { return math.Acosh(x) } 590 func Xasin(t *TLS, x float64) float64 { return math.Asin(x) } 591 func Xasinh(t *TLS, x float64) float64 { return math.Asinh(x) } 592 func Xatan(t *TLS, x float64) float64 { return math.Atan(x) } 593 func Xatan2(t *TLS, x, y float64) float64 { return math.Atan2(x, y) } 594 func Xatanh(t *TLS, x float64) float64 { return math.Atanh(x) } 595 func Xceil(t *TLS, x float64) float64 { return math.Ceil(x) } 596 func Xceilf(t *TLS, x float32) float32 { return float32(math.Ceil(float64(x))) } 597 func Xcopysign(t *TLS, x, y float64) float64 { return math.Copysign(x, y) } 598 func Xcopysignf(t *TLS, x, y float32) float32 { return float32(math.Copysign(float64(x), float64(y))) } 599 func Xcos(t *TLS, x float64) float64 { return math.Cos(x) } 600 func Xcosf(t *TLS, x float32) float32 { return float32(math.Cos(float64(x))) } 601 func Xcosh(t *TLS, x float64) float64 { return math.Cosh(x) } 602 func Xexp(t *TLS, x float64) float64 { return math.Exp(x) } 603 func Xfabs(t *TLS, x float64) float64 { return math.Abs(x) } 604 func Xfabsf(t *TLS, x float32) float32 { return float32(math.Abs(float64(x))) } 605 func Xfloor(t *TLS, x float64) float64 { return math.Floor(x) } 606 func Xfmod(t *TLS, x, y float64) float64 { return math.Mod(x, y) } 607 func Xhypot(t *TLS, x, y float64) float64 { return math.Hypot(x, y) } 608 func Xisnan(t *TLS, x float64) int32 { return X__builtin_isnan(t, x) } 609 func Xisnanf(t *TLS, x float32) int32 { return Bool32(math.IsNaN(float64(x))) } 610 func Xisnanl(t *TLS, x float64) int32 { return Bool32(math.IsNaN(x)) } // ccgo has to handle long double as double as Go does not support long double. 611 func Xldexp(t *TLS, x float64, exp int32) float64 { return math.Ldexp(x, int(exp)) } 612 func Xlog(t *TLS, x float64) float64 { return math.Log(x) } 613 func Xlog10(t *TLS, x float64) float64 { return math.Log10(x) } 614 func Xlog2(t *TLS, x float64) float64 { return math.Log2(x) } 615 func Xround(t *TLS, x float64) float64 { return math.Round(x) } 616 func Xsin(t *TLS, x float64) float64 { return math.Sin(x) } 617 func Xsinf(t *TLS, x float32) float32 { return float32(math.Sin(float64(x))) } 618 func Xsinh(t *TLS, x float64) float64 { return math.Sinh(x) } 619 func Xsqrt(t *TLS, x float64) float64 { return math.Sqrt(x) } 620 func Xtan(t *TLS, x float64) float64 { return math.Tan(x) } 621 func Xtanh(t *TLS, x float64) float64 { return math.Tanh(x) } 622 func Xtrunc(t *TLS, x float64) float64 { return math.Trunc(x) } 623 624 var nextRand = uint64(1) 625 626 // int rand(void); 627 func Xrand(t *TLS) int32 { 628 nextRand = nextRand*1103515245 + 12345 629 return int32(uint32(nextRand / (math.MaxUint32 + 1) % math.MaxInt32)) 630 } 631 632 func Xpow(t *TLS, x, y float64) float64 { 633 r := math.Pow(x, y) 634 if x > 0 && r == 1 && y >= -1.0000000000000000715e-18 && y < -1e-30 { 635 r = 0.9999999999999999 636 } 637 return r 638 } 639 640 func Xfrexp(t *TLS, x float64, exp uintptr) float64 { 641 f, e := math.Frexp(x) 642 *(*int32)(unsafe.Pointer(exp)) = int32(e) 643 return f 644 } 645 646 func Xmodf(t *TLS, x float64, iptr uintptr) float64 { 647 i, f := math.Modf(x) 648 *(*float64)(unsafe.Pointer(iptr)) = i 649 return f 650 } 651 652 // char *strncpy(char *dest, const char *src, size_t n) 653 func Xstrncpy(t *TLS, dest, src uintptr, n types.Size_t) (r uintptr) { 654 r = dest 655 for c := *(*int8)(unsafe.Pointer(src)); c != 0 && n > 0; n-- { 656 *(*int8)(unsafe.Pointer(dest)) = c 657 dest++ 658 src++ 659 c = *(*int8)(unsafe.Pointer(src)) 660 } 661 for ; uintptr(n) > 0; n-- { 662 *(*int8)(unsafe.Pointer(dest)) = 0 663 dest++ 664 } 665 return r 666 } 667 668 // char * __builtin___strncpy_chk (char *dest, const char *src, size_t n, size_t os); 669 func X__builtin___strncpy_chk(t *TLS, dest, src uintptr, n, os types.Size_t) (r uintptr) { 670 if n != ^types.Size_t(0) && os < n { 671 Xabort(t) 672 } 673 674 return Xstrncpy(t, dest, src, n) 675 } 676 677 // int strcmp(const char *s1, const char *s2) 678 func Xstrcmp(t *TLS, s1, s2 uintptr) int32 { 679 for { 680 ch1 := *(*byte)(unsafe.Pointer(s1)) 681 s1++ 682 ch2 := *(*byte)(unsafe.Pointer(s2)) 683 s2++ 684 if ch1 != ch2 || ch1 == 0 || ch2 == 0 { 685 return int32(ch1) - int32(ch2) 686 } 687 } 688 } 689 690 // size_t strlen(const char *s) 691 func Xstrlen(t *TLS, s uintptr) (r types.Size_t) { 692 if s == 0 { 693 return 0 694 } 695 696 for ; *(*int8)(unsafe.Pointer(s)) != 0; s++ { 697 r++ 698 } 699 return r 700 } 701 702 // char *strcat(char *dest, const char *src) 703 func Xstrcat(t *TLS, dest, src uintptr) (r uintptr) { 704 r = dest 705 for *(*int8)(unsafe.Pointer(dest)) != 0 { 706 dest++ 707 } 708 for { 709 c := *(*int8)(unsafe.Pointer(src)) 710 src++ 711 *(*int8)(unsafe.Pointer(dest)) = c 712 dest++ 713 if c == 0 { 714 return r 715 } 716 } 717 } 718 719 // char * __builtin___strcat_chk (char *dest, const char *src, size_t os); 720 func X__builtin___strcat_chk(t *TLS, dest, src uintptr, os types.Size_t) (r uintptr) { 721 return Xstrcat(t, dest, src) 722 } 723 724 // int strncmp(const char *s1, const char *s2, size_t n) 725 func Xstrncmp(t *TLS, s1, s2 uintptr, n types.Size_t) int32 { 726 var ch1, ch2 byte 727 for ; n != 0; n-- { 728 ch1 = *(*byte)(unsafe.Pointer(s1)) 729 s1++ 730 ch2 = *(*byte)(unsafe.Pointer(s2)) 731 s2++ 732 if ch1 != ch2 { 733 return int32(ch1) - int32(ch2) 734 } 735 736 if ch1 == 0 { 737 return 0 738 } 739 } 740 return 0 741 } 742 743 // char *strcpy(char *dest, const char *src) 744 func Xstrcpy(t *TLS, dest, src uintptr) (r uintptr) { 745 r = dest 746 // src0 := src 747 for ; ; dest++ { 748 c := *(*int8)(unsafe.Pointer(src)) 749 src++ 750 *(*int8)(unsafe.Pointer(dest)) = c 751 if c == 0 { 752 return r 753 } 754 } 755 } 756 757 // char *strchr(const char *s, int c) 758 func Xstrchr(t *TLS, s uintptr, c int32) uintptr { 759 for { 760 ch2 := *(*byte)(unsafe.Pointer(s)) 761 if ch2 == byte(c) { 762 return s 763 } 764 765 if ch2 == 0 { 766 return 0 767 } 768 769 s++ 770 } 771 } 772 773 // char *strrchr(const char *s, int c) 774 func Xstrrchr(t *TLS, s uintptr, c int32) (r uintptr) { 775 for { 776 ch2 := *(*byte)(unsafe.Pointer(s)) 777 if ch2 == 0 { 778 return r 779 } 780 781 if ch2 == byte(c) { 782 r = s 783 } 784 s++ 785 } 786 } 787 788 // void *memset(void *s, int c, size_t n) 789 func Xmemset(t *TLS, s uintptr, c int32, n types.Size_t) uintptr { 790 if n != 0 { 791 c := byte(c & 0xff) 792 793 // This will make sure that on platforms where they are not equally aligned we 794 // clear out the first few bytes until allignment 795 bytesBeforeAllignment := s % unsafe.Alignof(uint64(0)) 796 if bytesBeforeAllignment > uintptr(n) { 797 bytesBeforeAllignment = uintptr(n) 798 } 799 b := (*RawMem)(unsafe.Pointer(s))[:bytesBeforeAllignment:bytesBeforeAllignment] 800 n -= types.Size_t(bytesBeforeAllignment) 801 for i := range b { 802 b[i] = c 803 } 804 if n >= 8 { 805 i64 := uint64(c) + uint64(c)<<8 + uint64(c)<<16 + uint64(c)<<24 + uint64(c)<<32 + uint64(c)<<40 + uint64(c)<<48 + uint64(c)<<56 806 b8 := (*RawMem64)(unsafe.Pointer(s + bytesBeforeAllignment))[: n/8 : n/8] 807 for i := range b8 { 808 b8[i] = i64 809 } 810 } 811 if n%8 != 0 { 812 b = (*RawMem)(unsafe.Pointer(s + bytesBeforeAllignment + uintptr(n-n%8)))[: n%8 : n%8] 813 for i := range b { 814 b[i] = c 815 } 816 } 817 } 818 return s 819 } 820 821 // void *memcpy(void *dest, const void *src, size_t n); 822 func Xmemcpy(t *TLS, dest, src uintptr, n types.Size_t) (r uintptr) { 823 if n != 0 { 824 copy((*RawMem)(unsafe.Pointer(dest))[:n:n], (*RawMem)(unsafe.Pointer(src))[:n:n]) 825 } 826 return dest 827 } 828 829 // int memcmp(const void *s1, const void *s2, size_t n); 830 func Xmemcmp(t *TLS, s1, s2 uintptr, n types.Size_t) int32 { 831 for ; n != 0; n-- { 832 c1 := *(*byte)(unsafe.Pointer(s1)) 833 s1++ 834 c2 := *(*byte)(unsafe.Pointer(s2)) 835 s2++ 836 if c1 < c2 { 837 return -1 838 } 839 840 if c1 > c2 { 841 return 1 842 } 843 } 844 return 0 845 } 846 847 // void *memchr(const void *s, int c, size_t n); 848 func Xmemchr(t *TLS, s uintptr, c int32, n types.Size_t) uintptr { 849 for ; n != 0; n-- { 850 if *(*byte)(unsafe.Pointer(s)) == byte(c) { 851 return s 852 } 853 854 s++ 855 } 856 return 0 857 } 858 859 // void *memmove(void *dest, const void *src, size_t n); 860 func Xmemmove(t *TLS, dest, src uintptr, n types.Size_t) uintptr { 861 if n == 0 { 862 return dest 863 } 864 865 copy((*RawMem)(unsafe.Pointer(uintptr(dest)))[:n:n], (*RawMem)(unsafe.Pointer(uintptr(src)))[:n:n]) 866 return dest 867 } 868 869 // void * __builtin___memmove_chk (void *dest, const void *src, size_t n, size_t os); 870 func X__builtin___memmove_chk(t *TLS, dest, src uintptr, n, os types.Size_t) uintptr { 871 if os != ^types.Size_t(0) && os < n { 872 Xabort(t) 873 } 874 875 return Xmemmove(t, dest, src, n) 876 } 877 878 // char *getenv(const char *name); 879 func Xgetenv(t *TLS, name uintptr) uintptr { 880 return getenv(Environ(), GoString(name)) 881 } 882 883 func getenv(p uintptr, nm string) uintptr { 884 for ; ; p += uintptrSize { 885 q := *(*uintptr)(unsafe.Pointer(p)) 886 if q == 0 { 887 return 0 888 } 889 890 s := GoString(q) 891 a := strings.SplitN(s, "=", 2) 892 if len(a) != 2 { 893 panic(todo("%q %q %q", nm, s, a)) 894 } 895 896 if a[0] == nm { 897 return q + uintptr(len(nm)) + 1 898 } 899 } 900 } 901 902 // char *strstr(const char *haystack, const char *needle); 903 func Xstrstr(t *TLS, haystack, needle uintptr) uintptr { 904 hs := GoString(haystack) 905 nd := GoString(needle) 906 if i := strings.Index(hs, nd); i >= 0 { 907 r := haystack + uintptr(i) 908 return r 909 } 910 911 return 0 912 } 913 914 // int putc(int c, FILE *stream); 915 func Xputc(t *TLS, c int32, fp uintptr) int32 { 916 return Xfputc(t, c, fp) 917 } 918 919 // int atoi(const char *nptr); 920 func Xatoi(t *TLS, nptr uintptr) int32 { 921 _, neg, _, n, _ := strToUint64(t, nptr, 10) 922 switch { 923 case neg: 924 return int32(-n) 925 default: 926 return int32(n) 927 } 928 } 929 930 // double atof(const char *nptr); 931 func Xatof(t *TLS, nptr uintptr) float64 { 932 n, _ := strToFloatt64(t, nptr, 64) 933 // if dmesgs { 934 // dmesg("%v: %q: %v", origin(1), GoString(nptr), n) 935 // } 936 return n 937 } 938 939 // int tolower(int c); 940 func Xtolower(t *TLS, c int32) int32 { 941 if c >= 'A' && c <= 'Z' { 942 return c + ('a' - 'A') 943 } 944 945 return c 946 } 947 948 // int toupper(int c); 949 func Xtoupper(t *TLS, c int32) int32 { 950 if c >= 'a' && c <= 'z' { 951 return c - ('a' - 'A') 952 } 953 954 return c 955 } 956 957 // int isatty(int fd); 958 func Xisatty(t *TLS, fd int32) int32 { 959 return Bool32(isatty.IsTerminal(uintptr(fd))) 960 } 961 962 // long atol(const char *nptr); 963 func Xatol(t *TLS, nptr uintptr) long { 964 _, neg, _, n, _ := strToUint64(t, nptr, 10) 965 switch { 966 case neg: 967 return long(-n) 968 default: 969 return long(n) 970 } 971 } 972 973 func getLocalLocation() (loc *gotime.Location) { 974 loc = gotime.Local 975 if r := getenv(Environ(), "TZ"); r != 0 { 976 zname := GoString(r) 977 zone, off := parseZone(zname) 978 loc = gotime.FixedZone(zone, -off) 979 loc2, _ := gotime.LoadLocation(zname) 980 if loc2 != nil { 981 loc = loc2 982 } 983 } 984 return loc 985 986 } 987 988 // time_t mktime(struct tm *tm); 989 func Xmktime(t *TLS, ptm uintptr) time.Time_t { 990 loc := getLocalLocation() 991 tt := gotime.Date( 992 int((*time.Tm)(unsafe.Pointer(ptm)).Ftm_year+1900), 993 gotime.Month((*time.Tm)(unsafe.Pointer(ptm)).Ftm_mon+1), 994 int((*time.Tm)(unsafe.Pointer(ptm)).Ftm_mday), 995 int((*time.Tm)(unsafe.Pointer(ptm)).Ftm_hour), 996 int((*time.Tm)(unsafe.Pointer(ptm)).Ftm_min), 997 int((*time.Tm)(unsafe.Pointer(ptm)).Ftm_sec), 998 0, 999 loc, 1000 ) 1001 (*time.Tm)(unsafe.Pointer(ptm)).Ftm_wday = int32(tt.Weekday()) 1002 (*time.Tm)(unsafe.Pointer(ptm)).Ftm_yday = int32(tt.YearDay() - 1) 1003 return time.Time_t(tt.Unix()) 1004 } 1005 1006 // char *strpbrk(const char *s, const char *accept); 1007 func Xstrpbrk(t *TLS, s, accept uintptr) uintptr { 1008 bits := newBits(256) 1009 for { 1010 b := *(*byte)(unsafe.Pointer(accept)) 1011 if b == 0 { 1012 break 1013 } 1014 1015 bits.set(int(b)) 1016 accept++ 1017 } 1018 for { 1019 b := *(*byte)(unsafe.Pointer(s)) 1020 if b == 0 { 1021 return 0 1022 } 1023 1024 if bits.has(int(b)) { 1025 return s 1026 } 1027 1028 s++ 1029 } 1030 } 1031 1032 // int strcasecmp(const char *s1, const char *s2); 1033 func Xstrcasecmp(t *TLS, s1, s2 uintptr) int32 { 1034 for { 1035 ch1 := *(*byte)(unsafe.Pointer(s1)) 1036 if ch1 >= 'a' && ch1 <= 'z' { 1037 ch1 = ch1 - ('a' - 'A') 1038 } 1039 s1++ 1040 ch2 := *(*byte)(unsafe.Pointer(s2)) 1041 if ch2 >= 'a' && ch2 <= 'z' { 1042 ch2 = ch2 - ('a' - 'A') 1043 } 1044 s2++ 1045 if ch1 != ch2 || ch1 == 0 || ch2 == 0 { 1046 r := int32(ch1) - int32(ch2) 1047 return r 1048 } 1049 } 1050 } 1051 1052 func Xntohs(t *TLS, netshort uint16) uint16 { 1053 return uint16((*[2]byte)(unsafe.Pointer(&netshort))[0])<<8 | uint16((*[2]byte)(unsafe.Pointer(&netshort))[1]) 1054 } 1055 1056 // uint16_t htons(uint16_t hostshort); 1057 func Xhtons(t *TLS, hostshort uint16) uint16 { 1058 var a [2]byte 1059 a[0] = byte(hostshort >> 8) 1060 a[1] = byte(hostshort) 1061 return *(*uint16)(unsafe.Pointer(&a)) 1062 } 1063 1064 // uint32_t htonl(uint32_t hostlong); 1065 func Xhtonl(t *TLS, hostlong uint32) uint32 { 1066 var a [4]byte 1067 a[0] = byte(hostlong >> 24) 1068 a[1] = byte(hostlong >> 16) 1069 a[2] = byte(hostlong >> 8) 1070 a[3] = byte(hostlong) 1071 return *(*uint32)(unsafe.Pointer(&a)) 1072 } 1073 1074 // FILE *fopen(const char *pathname, const char *mode); 1075 func Xfopen(t *TLS, pathname, mode uintptr) uintptr { 1076 return Xfopen64(t, pathname, mode) //TODO 32 bit 1077 } 1078 1079 func Dmesg(s string, args ...interface{}) { 1080 if dmesgs { 1081 dmesg(s, args...) 1082 } 1083 } 1084 1085 // void sqlite3_log(int iErrCode, const char *zFormat, ...); 1086 func X__ccgo_sqlite3_log(t *TLS, iErrCode int32, zFormat uintptr, args uintptr) { 1087 // if dmesgs { 1088 // dmesg("%v: iErrCode: %v, msg: %s\n%s", origin(1), iErrCode, printf(zFormat, args), debug.Stack()) 1089 // } 1090 } 1091 1092 // int _IO_putc(int __c, _IO_FILE *__fp); 1093 func X_IO_putc(t *TLS, c int32, fp uintptr) int32 { 1094 return Xputc(t, c, fp) 1095 } 1096 1097 // int atexit(void (*function)(void)); 1098 func Xatexit(t *TLS, function uintptr) int32 { 1099 AtExit(func() { 1100 (*struct{ f func(*TLS) })(unsafe.Pointer(&struct{ uintptr }{function})).f(t) 1101 }) 1102 return 0 1103 } 1104 1105 // int vasprintf(char **strp, const char *fmt, va_list ap); 1106 func Xvasprintf(t *TLS, strp, fmt, ap uintptr) int32 { 1107 panic(todo("")) 1108 } 1109 1110 func AtomicLoadInt32(addr *int32) (val int32) { return atomic.LoadInt32(addr) } 1111 func AtomicLoadInt64(addr *int64) (val int64) { return atomic.LoadInt64(addr) } 1112 func AtomicLoadUint32(addr *uint32) (val uint32) { return atomic.LoadUint32(addr) } 1113 func AtomicLoadUint64(addr *uint64) (val uint64) { return atomic.LoadUint64(addr) } 1114 func AtomicLoadUintptr(addr *uintptr) (val uintptr) { return atomic.LoadUintptr(addr) } 1115 1116 func AtomicLoadFloat32(addr *float32) (val float32) { 1117 return math.Float32frombits(atomic.LoadUint32((*uint32)(unsafe.Pointer(addr)))) 1118 } 1119 1120 func AtomicLoadFloat64(addr *float64) (val float64) { 1121 return math.Float64frombits(atomic.LoadUint64((*uint64)(unsafe.Pointer(addr)))) 1122 } 1123 1124 func AtomicLoadPInt32(addr uintptr) (val int32) { 1125 return atomic.LoadInt32((*int32)(unsafe.Pointer(addr))) 1126 } 1127 1128 func AtomicLoadPInt64(addr uintptr) (val int64) { 1129 return atomic.LoadInt64((*int64)(unsafe.Pointer(addr))) 1130 } 1131 1132 func AtomicLoadPUint32(addr uintptr) (val uint32) { 1133 return atomic.LoadUint32((*uint32)(unsafe.Pointer(addr))) 1134 } 1135 1136 func AtomicLoadPUint64(addr uintptr) (val uint64) { 1137 return atomic.LoadUint64((*uint64)(unsafe.Pointer(addr))) 1138 } 1139 1140 func AtomicLoadPUintptr(addr uintptr) (val uintptr) { 1141 return atomic.LoadUintptr((*uintptr)(unsafe.Pointer(addr))) 1142 } 1143 1144 func AtomicLoadPFloat32(addr uintptr) (val float32) { 1145 return math.Float32frombits(atomic.LoadUint32((*uint32)(unsafe.Pointer(addr)))) 1146 } 1147 1148 func AtomicLoadPFloat64(addr uintptr) (val float64) { 1149 return math.Float64frombits(atomic.LoadUint64((*uint64)(unsafe.Pointer(addr)))) 1150 } 1151 1152 func AtomicStoreInt32(addr *int32, val int32) { atomic.StoreInt32(addr, val) } 1153 func AtomicStoreInt64(addr *int64, val int64) { atomic.StoreInt64(addr, val) } 1154 func AtomicStoreUint32(addr *uint32, val uint32) { atomic.StoreUint32(addr, val) } 1155 func AtomicStoreUint64(addr *uint64, val uint64) { atomic.StoreUint64(addr, val) } 1156 func AtomicStoreUintptr(addr *uintptr, val uintptr) { atomic.StoreUintptr(addr, val) } 1157 1158 func AtomicStoreFloat32(addr *float32, val float32) { 1159 atomic.StoreUint32((*uint32)(unsafe.Pointer(addr)), math.Float32bits(val)) 1160 } 1161 1162 func AtomicStoreFloat64(addr *float64, val float64) { 1163 atomic.StoreUint64((*uint64)(unsafe.Pointer(addr)), math.Float64bits(val)) 1164 } 1165 1166 func AtomicStorePInt32(addr uintptr, val int32) { 1167 atomic.StoreInt32((*int32)(unsafe.Pointer(addr)), val) 1168 } 1169 1170 func AtomicStorePInt64(addr uintptr, val int64) { 1171 atomic.StoreInt64((*int64)(unsafe.Pointer(addr)), val) 1172 } 1173 1174 func AtomicStorePUint32(addr uintptr, val uint32) { 1175 atomic.StoreUint32((*uint32)(unsafe.Pointer(addr)), val) 1176 } 1177 1178 func AtomicStorePUint64(addr uintptr, val uint64) { 1179 atomic.StoreUint64((*uint64)(unsafe.Pointer(addr)), val) 1180 } 1181 1182 func AtomicStorePUintptr(addr uintptr, val uintptr) { 1183 atomic.StoreUintptr((*uintptr)(unsafe.Pointer(addr)), val) 1184 } 1185 1186 func AtomicStorePFloat32(addr uintptr, val float32) { 1187 atomic.StoreUint32((*uint32)(unsafe.Pointer(addr)), math.Float32bits(val)) 1188 } 1189 1190 func AtomicStorePFloat64(addr uintptr, val float64) { 1191 atomic.StoreUint64((*uint64)(unsafe.Pointer(addr)), math.Float64bits(val)) 1192 } 1193 1194 func AtomicAddInt32(addr *int32, delta int32) (new int32) { return atomic.AddInt32(addr, delta) } 1195 func AtomicAddInt64(addr *int64, delta int64) (new int64) { return atomic.AddInt64(addr, delta) } 1196 func AtomicAddUint32(addr *uint32, delta uint32) (new uint32) { return atomic.AddUint32(addr, delta) } 1197 func AtomicAddUint64(addr *uint64, delta uint64) (new uint64) { return atomic.AddUint64(addr, delta) } 1198 1199 func AtomicAddUintptr(addr *uintptr, delta uintptr) (new uintptr) { 1200 return atomic.AddUintptr(addr, delta) 1201 1202 } 1203 1204 func AtomicAddFloat32(addr *float32, delta float32) (new float32) { 1205 v := AtomicLoadFloat32(addr) + delta 1206 AtomicStoreFloat32(addr, v) 1207 return v 1208 } 1209 1210 func AtomicAddFloat64(addr *float64, delta float64) (new float64) { 1211 v := AtomicLoadFloat64(addr) + delta 1212 AtomicStoreFloat64(addr, v) 1213 return v 1214 } 1215 1216 // size_t mbstowcs(wchar_t *dest, const char *src, size_t n); 1217 func Xmbstowcs(t *TLS, dest, src uintptr, n types.Size_t) types.Size_t { 1218 panic(todo("")) 1219 } 1220 1221 // int mbtowc(wchar_t *pwc, const char *s, size_t n); 1222 func Xmbtowc(t *TLS, pwc, s uintptr, n types.Size_t) int32 { 1223 panic(todo("")) 1224 } 1225 1226 // size_t __ctype_get_mb_cur_max(void); 1227 func X__ctype_get_mb_cur_max(t *TLS) types.Size_t { 1228 panic(todo("")) 1229 } 1230 1231 // int wctomb(char *s, wchar_t wc); 1232 func Xwctomb(t *TLS, s uintptr, wc wchar_t) int32 { 1233 panic(todo("")) 1234 } 1235 1236 // int mblen(const char *s, size_t n); 1237 func Xmblen(t *TLS, s uintptr, n types.Size_t) int32 { 1238 panic(todo("")) 1239 } 1240 1241 // ssize_t readv(int fd, const struct iovec *iov, int iovcnt); 1242 func Xreadv(t *TLS, fd int32, iov uintptr, iovcnt int32) types.Ssize_t { 1243 panic(todo("")) 1244 } 1245 1246 // int openpty(int *amaster, int *aslave, char *name, 1247 // 1248 // const struct termios *termp, 1249 // const struct winsize *winp); 1250 func Xopenpty(t *TLS, amaster, aslave, name, termp, winp uintptr) int32 { 1251 panic(todo("")) 1252 } 1253 1254 // pid_t setsid(void); 1255 func Xsetsid(t *TLS) types.Pid_t { 1256 panic(todo("")) 1257 } 1258 1259 // int pselect(int nfds, fd_set *readfds, fd_set *writefds, 1260 // 1261 // fd_set *exceptfds, const struct timespec *timeout, 1262 // const sigset_t *sigmask); 1263 func Xpselect(t *TLS, nfds int32, readfds, writefds, exceptfds, timeout, sigmask uintptr) int32 { 1264 panic(todo("")) 1265 } 1266 1267 // int kill(pid_t pid, int sig); 1268 func Xkill(t *TLS, pid types.Pid_t, sig int32) int32 { 1269 panic(todo("")) 1270 } 1271 1272 // int tcsendbreak(int fd, int duration); 1273 func Xtcsendbreak(t *TLS, fd, duration int32) int32 { 1274 panic(todo("")) 1275 } 1276 1277 // int wcwidth(wchar_t c); 1278 func Xwcwidth(t *TLS, c wchar_t) int32 { 1279 panic(todo("")) 1280 } 1281 1282 // int clock_gettime(clockid_t clk_id, struct timespec *tp); 1283 func Xclock_gettime(t *TLS, clk_id int32, tp uintptr) int32 { 1284 panic(todo("")) 1285 } 1286 1287 // AtExit will attempt to run f at process exit. The execution cannot be 1288 // guaranteed, neither its ordering with respect to any other handlers 1289 // registered by AtExit. 1290 func AtExit(f func()) { 1291 atExitMu.Lock() 1292 atExit = append(atExit, f) 1293 atExitMu.Unlock() 1294 } 1295 1296 func X__ccgo_dmesg(t *TLS, fmt uintptr, va uintptr) { 1297 if dmesgs { 1298 dmesg("%s", printf(fmt, va)) 1299 } 1300 } 1301 1302 // int getentropy(void *buffer, size_t length); 1303 // 1304 // The getentropy() function writes length bytes of high-quality random data 1305 // to the buffer starting at the location pointed to by buffer. The maximum 1306 // permitted value for the length argument is 256. 1307 func Xgetentropy(t *TLS, buffer uintptr, length size_t) int32 { 1308 const max = 256 1309 switch { 1310 case length == 0: 1311 return 0 1312 case buffer == 0: 1313 t.setErrno(errno.EFAULT) 1314 return -1 1315 case length > max: 1316 t.setErrno(errno.EIO) 1317 return -1 1318 } 1319 1320 if _, err := crand.Read((*RawMem)(unsafe.Pointer(buffer))[:length]); err != nil { 1321 t.setErrno(errno.EIO) 1322 return -1 1323 } 1324 1325 return 0 1326 } 1327 1328 // void * reallocarray(void *ptr, size_t nmemb, size_t size); 1329 func Xreallocarray(t *TLS, ptr uintptr, nmemb, size size_t) uintptr { 1330 hi, lo := mathutil.MulUint128_64(uint64(nmemb), uint64(size)) 1331 if hi != 0 || lo > uint64(unsafe.Sizeof(RawMem{})) { 1332 t.setErrno(errno.ENOMEM) 1333 return 0 1334 } 1335 1336 return Xrealloc(t, ptr, size_t(lo)) 1337 } 1338 1339 // int setjmp(jmp_buf env); 1340 func Xsetjmp(t *TLS, env uintptr) int32 { 1341 return 0 //TODO 1342 } 1343 1344 // void longjmp(jmp_buf env, int val); 1345 func Xlongjmp(t *TLS, env uintptr, val int32) { 1346 panic(todo("")) 1347 } 1348 1349 // https://linux.die.net/man/3/_setjmp 1350 // 1351 // The _longjmp() and _setjmp() functions shall be equivalent to longjmp() and 1352 // setjmp(), respectively, with the additional restriction that _longjmp() and 1353 // _setjmp() shall not manipulate the signal mask. 1354 1355 // int _setjmp(jmp_buf env); 1356 func X_setjmp(t *TLS, env uintptr) int32 { 1357 return 0 //TODO 1358 } 1359 1360 // void _longjmp(jmp_buf env, int val); 1361 func X_longjmp(t *TLS, env uintptr, val int32) { 1362 panic(todo("")) 1363 } 1364 1365 // unsigned __sync_add_and_fetch_uint32(*unsigned, unsigned) 1366 func X__sync_add_and_fetch_uint32(t *TLS, p uintptr, v uint32) uint32 { 1367 return atomic.AddUint32((*uint32)(unsafe.Pointer(p)), v) 1368 } 1369 1370 // unsigned __sync_sub_and_fetch_uint32(*unsigned, unsigned) 1371 func X__sync_sub_and_fetch_uint32(t *TLS, p uintptr, v uint32) uint32 { 1372 return atomic.AddUint32((*uint32)(unsafe.Pointer(p)), -v) 1373 } 1374 1375 // int sched_yield(void); 1376 func Xsched_yield(t *TLS) { 1377 runtime.Gosched() 1378 } 1379 1380 // int getc(FILE *stream); 1381 func Xgetc(t *TLS, stream uintptr) int32 { 1382 return Xfgetc(t, stream) 1383 } 1384 1385 // char *fgets(char *s, int size, FILE *stream); 1386 func Xfgets(t *TLS, s uintptr, size int32, stream uintptr) uintptr { 1387 var b []byte 1388 out: 1389 for ; size > 0; size-- { 1390 switch c := Xfgetc(t, stream); c { 1391 case '\n': 1392 b = append(b, byte(c)) 1393 break out 1394 case stdio.EOF: 1395 break out 1396 default: 1397 b = append(b, byte(c)) 1398 } 1399 } 1400 if len(b) == 0 { 1401 return 0 1402 } 1403 1404 b = append(b, 0) 1405 copy((*RawMem)(unsafe.Pointer(s))[:len(b):len(b)], b) 1406 return s 1407 } 1408 1409 // void bzero(void *s, size_t n); 1410 func Xbzero(t *TLS, s uintptr, n types.Size_t) { 1411 b := (*RawMem)(unsafe.Pointer(s))[:n] 1412 for i := range b { 1413 b[i] = 0 1414 } 1415 } 1416 1417 // char *rindex(const char *s, int c); 1418 func Xrindex(t *TLS, s uintptr, c int32) uintptr { 1419 if s == 0 { 1420 return 0 1421 } 1422 1423 var r uintptr 1424 for { 1425 c2 := int32(*(*byte)(unsafe.Pointer(s))) 1426 if c2 == c { 1427 r = s 1428 } 1429 1430 if c2 == 0 { 1431 return r 1432 } 1433 1434 s++ 1435 } 1436 } 1437 1438 // int isascii(int c); 1439 func Xisascii(t *TLS, c int32) int32 { 1440 return Bool32(c >= 0 && c <= 0x7f) 1441 } 1442 1443 func X__builtin_isunordered(t *TLS, a, b float64) int32 { 1444 return Bool32(math.IsNaN(a) || math.IsNaN(b)) 1445 }