// Copyright 2020 The Libc Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go.generate echo package libc > ccgo.go
//go:generate go run generate.go
//go:generate go fmt ./...

// Package libc provides run time support for ccgo generated programs and // implements selected parts of the C standard library.
package libc // import "modernc.org/libc" //TODO use O_RDONLY etc. from fcntl header //TODO use t.Alloc/Free where appropriate import ( mbits gotime ) type ( // RawMem64 represents the biggest uint64 array the runtime can handle. RawMem64 [unsafe.Sizeof(RawMem{}) / unsafe.Sizeof(uint64(0))]uint64 ) var ( allocMu sync.Mutex environInitialized bool isWindows bool ) // Keep these outside of the var block otherwise go generate will miss them. var Xenviron uintptr var Xstdin = newFile(nil, unistd.STDIN_FILENO) var Xstdout = newFile(nil, unistd.STDOUT_FILENO) var Xstderr = newFile(nil, unistd.STDERR_FILENO) func () { SetEnviron(nil, os.Environ()) } func () uintptr { if !environInitialized { SetEnviron(nil, os.Environ()) } return Xenviron } func () uintptr { if !environInitialized { SetEnviron(nil, os.Environ()) } return uintptr(unsafe.Pointer(&Xenviron)) } func ( *TLS) uintptr { return X__errno_location() } // int * __errno_location(void); func ( *TLS) uintptr { return .errnop } func ( func(*TLS, int32, uintptr) int32) { if dmesgs { , := os.Getwd() dmesg("%v: %v, wd %v, %v", origin(1), os.Args, , ) defer func() { if := recover(); != nil { dmesg("%v: CRASH: %v\n%s", origin(1), , debug.Stack()) } }() } runtime.LockOSThread() := &TLS{errnop: uintptr(unsafe.Pointer(&errno0))} := Xcalloc(, 1, types.Size_t((len(os.Args)+1)*int(uintptrSize))) if == 0 { panic("OOM") } := for , := range os.Args { := Xcalloc(, 1, types.Size_t(len()+1)) if == 0 { panic("OOM") } copy((*RawMem)(unsafe.Pointer())[:len():len()], ) *(*uintptr)(unsafe.Pointer()) = += uintptrSize } SetEnviron(, os.Environ()) := false if memgrind { if := os.Getenv("LIBC_MEMGRIND_START"); != "0" { MemAuditStart() = true } } = NewTLS() := (, int32(len(os.Args)), ) exit(, , ) } func ( *TLS, int32) { exit(, , false) } func ( *TLS, int32, bool) { if len(Covered) != 0 { := bufio.NewWriter(os.Stdout) CoverReport() .Flush() } if len(CoveredC) != 0 { := bufio.NewWriter(os.Stdout) CoverCReport() .Flush() } for , := range atExit { () } if { .Close() if tlsBalance != 0 { fmt.Fprintf(os.Stderr, "non zero TLS balance: %d\n", tlsBalance) = 1 } } X_exit(nil, ) } // void _exit(int status); func ( *TLS, int32) { if dmesgs { dmesg("%v: EXIT %v", origin(1), ) } os.Exit(int()) } func ( *TLS, []string) { environInitialized = true := Xcalloc(, 1, types.Size_t((len()+1)*(int(uintptrSize)))) if == 0 { panic("OOM") } Xenviron = for , := range { := Xcalloc(, 1, types.Size_t(len()+1)) if == 0 { panic("OOM") } copy((*(*RawMem)(unsafe.Pointer()))[:len():len()], ) *(*uintptr)(unsafe.Pointer()) = += uintptrSize } } // void setbuf(FILE *stream, char *buf); func ( *TLS, , uintptr) { //TODO panic(todo("")) } // size_t confstr(int name, char *buf, size_t len); func ( *TLS, int32, uintptr, types.Size_t) types.Size_t { panic(todo("")) } // int puts(const char *s); func ( *TLS, uintptr) int32 { panic(todo("")) } var ( randomMu sync.Mutex randomGen = rand.New(rand.NewSource(42)) ) // long int random(void); func ( *TLS) long { randomMu.Lock() := randomGen.Int63n(math.MaxInt32 + 1) randomMu.Unlock() return long() } func ( []byte) (int, error) { // if dmesgs { // dmesg("%v: %s", origin(1), b) // } if , := os.Stdout.Write(); != nil { return -1, } return len(), nil } func ( *TLS) { Xabort() } func ( *TLS, int32) int32 { return Xabs(, ) } func ( *TLS, uint64) int32 { return int32(mbits.LeadingZeros64()) } func () { panic(todo("internal error: should never be called")) } func ( *TLS, , float64) float64 { return Xcopysign(, , ) } func ( *TLS, , float32) float32 { return Xcopysignf(, , ) } func ( *TLS, int32) { Xexit(, ) } func ( *TLS, , long) long { return } func ( *TLS, float64) float64 { return Xfabs(, ) } func ( *TLS, uintptr) { Xfree(, ) } func ( *TLS) float64 { return math.Inf(1) } func ( *TLS) float32 { return float32(math.Inf(1)) } func ( *TLS) float64 { return math.Inf(1) } func ( *TLS) float32 { return float32(math.Inf(1)) } func ( *TLS, types.Size_t) uintptr { return Xmalloc(, ) } func ( *TLS, , uintptr, types.Size_t) int32 { return Xmemcmp(, , , ) } func ( *TLS, uintptr) float32 { return float32(math.NaN()) } func ( *TLS, , uintptr) {} func ( *TLS, , uintptr) int32 { return Xprintf(, , ) } func ( *TLS, uintptr, int32) uintptr { return Xstrchr(, , ) } func ( *TLS, , uintptr) int32 { return Xstrcmp(, , ) } func ( *TLS, , uintptr) uintptr { return Xstrcpy(, , ) } func ( *TLS, uintptr) types.Size_t { return Xstrlen(, ) } func ( *TLS) { Xabort() } func ( *TLS, float64) int32 { return X__builtin_isnan(, ) } func ( *TLS, float32) int32 { return Xisnanf(, ) } func ( *TLS, float64) int32 { return Xisnanl(, ) } func ( *TLS, , , uintptr) int32 { return Xfprintf(, , , ) } // int __builtin_popcount (unsigned int x) func ( *TLS, uint32) int32 { return int32(mbits.OnesCount32()) } // char * __builtin___strcpy_chk (char *dest, const char *src, size_t os); func ( *TLS, , uintptr, types.Size_t) uintptr { return Xstrcpy(, , ) } func ( *TLS, uintptr, types.Size_t, , , int32, types.Off_t) uintptr { return Xmmap(, , , , , , ) } // uint16_t __builtin_bswap16 (uint32_t x) func ( *TLS, uint16) uint16 { return <<8 | >>8 } // uint32_t __builtin_bswap32 (uint32_t x) func ( *TLS, uint32) uint32 { return <<24 | &0xff00<<8 | &0xff0000>>8 | >>24 } // uint64_t __builtin_bswap64 (uint64_t x) func ( *TLS, uint64) uint64 { return <<56 | &0xff00<<40 | &0xff0000<<24 | &0xff000000<<8 | &0xff00000000>>8 | &0xff0000000000>>24 | &0xff000000000000>>40 | >>56 } // bool __builtin_add_overflow (type1 a, type2 b, type3 *res) func ( *TLS, , int64, uintptr) int32 { , := mathutil.AddOverflowInt64(, ) *(*int64)(unsafe.Pointer()) = return Bool32() } // bool __builtin_add_overflow (type1 a, type2 b, type3 *res) func ( *TLS, , uint32, uintptr) int32 { := + *(*uint32)(unsafe.Pointer()) = return Bool32( < ) } // bool __builtin_add_overflow (type1 a, type2 b, type3 *res) func ( *TLS, , uint64, uintptr) int32 { := + *(*uint64)(unsafe.Pointer()) = return Bool32( < ) } // bool __builtin_sub_overflow (type1 a, type2 b, type3 *res) func ( *TLS, , int64, uintptr) int32 { , := mathutil.SubOverflowInt64(, ) *(*int64)(unsafe.Pointer()) = return Bool32() } // bool __builtin_mul_overflow (type1 a, type2 b, type3 *res) func ( *TLS, , int64, uintptr) int32 { , := mathutil.MulOverflowInt64(, ) *(*int64)(unsafe.Pointer()) = return Bool32() } // bool __builtin_mul_overflow (type1 a, type2 b, type3 *res) func ( *TLS, , uint64, uintptr) int32 { , := mbits.Mul64(, ) *(*uint64)(unsafe.Pointer()) = return Bool32( != 0) } // bool __builtin_mul_overflow (type1 a, type2 b, type3 *res) func ( *TLS, , Uint128, uintptr) int32 { , := .mulOvf() *(*Uint128)(unsafe.Pointer()) = return Bool32() } func ( *TLS) { fmt.Fprintf(os.Stderr, "unrechable\n") os.Stderr.Sync() Xexit(, 1) } func ( *TLS, uintptr, types.Size_t, , uintptr) int32 { return Xsnprintf(, , , , ) } func ( *TLS, , , uintptr) ( int32) { return Xsprintf(, , , ) } func ( *TLS, , uintptr, types.Size_t) ( uintptr) { return Xmemcpy(, , , ) } // void * __builtin___memcpy_chk (void *dest, const void *src, size_t n, size_t os); func ( *TLS, , uintptr, , types.Size_t) ( uintptr) { if != ^types.Size_t(0) && < { Xabort() } return Xmemcpy(, , , ) } func ( *TLS, uintptr, int32, types.Size_t) uintptr { return Xmemset(, , , ) } // void * __builtin___memset_chk (void *s, int c, size_t n, size_t os); func ( *TLS, uintptr, int32, , types.Size_t) uintptr { if < { Xabort() } return Xmemset(, , , ) } // size_t __builtin_object_size (const void * ptr, int type) func ( *TLS, uintptr, int32) types.Size_t { return ^types.Size_t(0) //TODO frontend magic } var atomicLoadStore16 sync.Mutex func ( uintptr, int16) uint16 { atomicLoadStore16.Lock() := *(*uint16)(unsafe.Pointer()) atomicLoadStore16.Unlock() return } func ( uintptr, uint16, int32) { atomicLoadStore16.Lock() *(*uint16)(unsafe.Pointer()) = atomicLoadStore16.Unlock() } // int sprintf(char *str, const char *format, ...); func ( *TLS, , , uintptr) ( int32) { := printf(, ) = int32(len()) copy((*RawMem)(unsafe.Pointer())[::], ) *(*byte)(unsafe.Pointer( + uintptr())) = 0 return int32(len()) } // int __builtin___sprintf_chk (char *s, int flag, size_t os, const char *fmt, ...); func ( *TLS, uintptr, int32, types.Size_t, , uintptr) ( int32) { return Xsprintf(, , , ) } // void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)); func ( *TLS, uintptr, , types.Size_t, uintptr) { sort.Sort(&sorter{ len: int(), base: , sz: uintptr(), f: (*struct { func(*TLS, uintptr, uintptr) int32 })(unsafe.Pointer(&struct{ uintptr }{}))., t: , }) } // void __assert_fail(const char * assertion, const char * file, unsigned int line, const char * function); func ( *TLS, , uintptr, uint32, uintptr) { fmt.Fprintf(os.Stderr, "assertion failure: %s:%d.%s: %s\n", GoString(), , GoString(), GoString()) if memgrind { fmt.Fprintf(os.Stderr, "%s\n", debug.Stack()) } os.Stderr.Sync() Xexit(, 1) } // int vprintf(const char *format, va_list ap); func ( *TLS, , uintptr) int32 { return Xprintf(, , ) } // int vsprintf(char *str, const char *format, va_list ap); func ( *TLS, , , uintptr) int32 { panic(todo("")) } // int vsnprintf(char *str, size_t size, const char *format, va_list ap); func ( *TLS, uintptr, types.Size_t, , uintptr) int32 { return Xsnprintf(, , , , ) } // int obstack_vprintf (struct obstack *obstack, const char *template, va_list ap) func ( *TLS, , , uintptr) int32 { panic(todo("")) } // extern void _obstack_newchunk(struct obstack *, int); func ( *TLS, uintptr, int32) int32 { panic(todo("")) } // int _obstack_begin (struct obstack *h, _OBSTACK_SIZE_T size, _OBSTACK_SIZE_T alignment, void *(*chunkfun) (size_t), void (*freefun) (void *)) func ( *TLS, uintptr, , int32, , uintptr) int32 { panic(todo("")) } // void obstack_free (struct obstack *h, void *obj) func ( *TLS, , uintptr) { panic(todo("")) } // unsigned int sleep(unsigned int seconds); func ( *TLS, uint32) uint32 { gotime.Sleep(gotime.Second * gotime.Duration()) return 0 } // size_t strcspn(const char *s, const char *reject); func ( *TLS, , uintptr) ( types.Size_t) { := newBits(256) for { := *(*byte)(unsafe.Pointer()) if == 0 { break } ++ .set(int()) } for { := *(*byte)(unsafe.Pointer()) if == 0 || .has(int()) { return } ++ ++ } } // int printf(const char *format, ...); func ( *TLS, , uintptr) int32 { , := write(printf(, )) return int32() } // int snprintf(char *str, size_t size, const char *format, ...); func ( *TLS, uintptr, types.Size_t, , uintptr) ( int32) { switch { case 0: return 0 case 1: *(*byte)(unsafe.Pointer()) = 0 return 0 } := printf(, ) if len()+1 > int() { = [:-1] } = int32(len()) copy((*RawMem)(unsafe.Pointer())[::], ) *(*byte)(unsafe.Pointer( + uintptr())) = 0 return } // int __builtin___snprintf_chk(char * str, size_t maxlen, int flag, size_t os, const char * format, ...); func ( *TLS, uintptr, types.Size_t, int32, types.Size_t, , uintptr) ( int32) { if != ^types.Size_t(0) && > { Xabort() } return Xsnprintf(, , , , ) } // int __builtin___vsnprintf_chk (char *s, size_t maxlen, int flag, size_t os, const char *fmt, va_list ap); func ( *TLS, uintptr, types.Size_t, int32, types.Size_t, , uintptr) ( int32) { if != ^types.Size_t(0) && > { Xabort() } return Xsnprintf(, , , , ) } // int abs(int j); func ( *TLS, int32) int32 { if >= 0 { return } return - } func ( *TLS, float64) int32 { return Bool32(math.IsNaN()) } func ( *TLS, float64) float64 { return math.Acos() } func ( *TLS, float64) float64 { return math.Acosh() } func ( *TLS, float64) float64 { return math.Asin() } func ( *TLS, float64) float64 { return math.Asinh() } func ( *TLS, float64) float64 { return math.Atan() } func ( *TLS, , float64) float64 { return math.Atan2(, ) } func ( *TLS, float64) float64 { return math.Atanh() } func ( *TLS, float64) float64 { return math.Ceil() } func ( *TLS, float32) float32 { return float32(math.Ceil(float64())) } func ( *TLS, , float64) float64 { return math.Copysign(, ) } func ( *TLS, , float32) float32 { return float32(math.Copysign(float64(), float64())) } func ( *TLS, float64) float64 { return math.Cos() } func ( *TLS, float32) float32 { return float32(math.Cos(float64())) } func ( *TLS, float64) float64 { return math.Cosh() } func ( *TLS, float64) float64 { return math.Exp() } func ( *TLS, float64) float64 { return math.Abs() } func ( *TLS, float32) float32 { return float32(math.Abs(float64())) } func ( *TLS, float64) float64 { return math.Floor() } func ( *TLS, , float64) float64 { return math.Mod(, ) } func ( *TLS, , float64) float64 { return math.Hypot(, ) } func ( *TLS, float64) int32 { return X__builtin_isnan(, ) } func ( *TLS, float32) int32 { return Bool32(math.IsNaN(float64())) } func ( *TLS, float64) int32 { return Bool32(math.IsNaN()) } // ccgo has to handle long double as double as Go does not support long double. func ( *TLS, float64, int32) float64 { return math.Ldexp(, int()) } func ( *TLS, float64) float64 { return math.Log() } func ( *TLS, float64) float64 { return math.Log10() } func ( *TLS, float64) float64 { return math.Round() } func ( *TLS, float64) float64 { return math.Sin() } func ( *TLS, float32) float32 { return float32(math.Sin(float64())) } func ( *TLS, float64) float64 { return math.Sinh() } func ( *TLS, float64) float64 { return math.Sqrt() } func ( *TLS, float64) float64 { return math.Tan() } func ( *TLS, float64) float64 { return math.Tanh() } func ( *TLS, float64) float64 { return math.Trunc() } var nextRand = uint64(1) // int rand(void); func ( *TLS) int32 { nextRand = nextRand*1103515245 + 12345 return int32(uint32(nextRand / (math.MaxUint32 + 1) % math.MaxInt32)) } func ( *TLS, , float64) float64 { := math.Pow(, ) if > 0 && == 1 && >= -1.0000000000000000715e-18 && < -1e-30 { = 0.9999999999999999 } return } func ( *TLS, float64, uintptr) float64 { , := math.Frexp() *(*int32)(unsafe.Pointer()) = int32() return } func ( *TLS, float64, uintptr) float64 { , := math.Modf() *(*float64)(unsafe.Pointer()) = return } // char *strncpy(char *dest, const char *src, size_t n) func ( *TLS, , uintptr, types.Size_t) ( uintptr) { = for := *(*int8)(unsafe.Pointer()); != 0 && > 0; -- { *(*int8)(unsafe.Pointer()) = ++ ++ = *(*int8)(unsafe.Pointer()) } for ; uintptr() > 0; -- { *(*int8)(unsafe.Pointer()) = 0 ++ } return } // char * __builtin___strncpy_chk (char *dest, const char *src, size_t n, size_t os); func ( *TLS, , uintptr, , types.Size_t) ( uintptr) { if != ^types.Size_t(0) && < { Xabort() } return Xstrncpy(, , , ) } // int strcmp(const char *s1, const char *s2) func ( *TLS, , uintptr) int32 { for { := *(*byte)(unsafe.Pointer()) ++ := *(*byte)(unsafe.Pointer()) ++ if != || == 0 || == 0 { return int32() - int32() } } } // size_t strlen(const char *s) func ( *TLS, uintptr) ( types.Size_t) { if == 0 { return 0 } for ; *(*int8)(unsafe.Pointer()) != 0; ++ { ++ } return } // char *strcat(char *dest, const char *src) func ( *TLS, , uintptr) ( uintptr) { = for *(*int8)(unsafe.Pointer()) != 0 { ++ } for { := *(*int8)(unsafe.Pointer()) ++ *(*int8)(unsafe.Pointer()) = ++ if == 0 { return } } } // char * __builtin___strcat_chk (char *dest, const char *src, size_t os); func ( *TLS, , uintptr, types.Size_t) ( uintptr) { return Xstrcat(, , ) } // int strncmp(const char *s1, const char *s2, size_t n) func ( *TLS, , uintptr, types.Size_t) int32 { var , byte for ; != 0; -- { = *(*byte)(unsafe.Pointer()) ++ = *(*byte)(unsafe.Pointer()) ++ if != { return int32() - int32() } if == 0 { return 0 } } return 0 } // char *strcpy(char *dest, const char *src) func ( *TLS, , uintptr) ( uintptr) { = // src0 := src for ; ; ++ { := *(*int8)(unsafe.Pointer()) ++ *(*int8)(unsafe.Pointer()) = if == 0 { return } } } // char *strchr(const char *s, int c) func ( *TLS, uintptr, int32) uintptr { for { := *(*byte)(unsafe.Pointer()) if == byte() { return } if == 0 { return 0 } ++ } } // char *strrchr(const char *s, int c) func ( *TLS, uintptr, int32) ( uintptr) { for { := *(*byte)(unsafe.Pointer()) if == 0 { return } if == byte() { = } ++ } } // void *memset(void *s, int c, size_t n) func ( *TLS, uintptr, int32, types.Size_t) uintptr { if != 0 { := byte( & 0xff) //this will make sure that on platforms where they are not equally alligned //we clear out the first few bytes until allignment := % unsafe.Alignof(uint64(0)) if > uintptr() { = uintptr() } := (*RawMem)(unsafe.Pointer())[::] -= types.Size_t() for := range { [] = } if >= 8 { := uint64() + uint64()<<8 + uint64()<<16 + uint64()<<24 + uint64()<<32 + uint64()<<40 + uint64()<<48 + uint64()<<56 := (*RawMem64)(unsafe.Pointer( + ))[: /8 : /8] for := range { [] = } } if %8 != 0 { = (*RawMem)(unsafe.Pointer( + + uintptr(-%8)))[: %8 : %8] for := range { [] = } } } return } // void *memcpy(void *dest, const void *src, size_t n); func ( *TLS, , uintptr, types.Size_t) ( uintptr) { if == 0 { return } := (*RawMem)(unsafe.Pointer())[::] := (*RawMem)(unsafe.Pointer())[::] copy(, ) return } // int memcmp(const void *s1, const void *s2, size_t n); func ( *TLS, , uintptr, types.Size_t) int32 { for ; != 0; -- { := *(*byte)(unsafe.Pointer()) ++ := *(*byte)(unsafe.Pointer()) ++ if < { return -1 } if > { return 1 } } return 0 } // void *memchr(const void *s, int c, size_t n); func ( *TLS, uintptr, int32, types.Size_t) uintptr { for ; != 0; -- { if *(*byte)(unsafe.Pointer()) == byte() { return } ++ } return 0 } // void *memmove(void *dest, const void *src, size_t n); func ( *TLS, , uintptr, types.Size_t) uintptr { if == 0 { return } copy((*RawMem)(unsafe.Pointer(uintptr()))[::], (*RawMem)(unsafe.Pointer(uintptr()))[::]) return } // void * __builtin___memmove_chk (void *dest, const void *src, size_t n, size_t os); func ( *TLS, , uintptr, , types.Size_t) uintptr { if != ^types.Size_t(0) && < { Xabort() } return Xmemmove(, , , ) } // char *getenv(const char *name); func ( *TLS, uintptr) uintptr { return getenv(Environ(), GoString()) } func ( uintptr, string) uintptr { for ; ; += uintptrSize { := *(*uintptr)(unsafe.Pointer()) if == 0 { return 0 } := GoString() := strings.SplitN(, "=", 2) if len() != 2 { panic(todo("%q %q %q", , , )) } if [0] == { return + uintptr(len()) + 1 } } } // char *strstr(const char *haystack, const char *needle); func ( *TLS, , uintptr) uintptr { := GoString() := GoString() if := strings.Index(, ); >= 0 { := + uintptr() return } return 0 } // int putc(int c, FILE *stream); func ( *TLS, int32, uintptr) int32 { return Xfputc(, , ) } // int atoi(const char *nptr); func ( *TLS, uintptr) int32 { , , , , := strToUint64(, , 10) switch { case : return int32(-) default: return int32() } } // double atof(const char *nptr); func ( *TLS, uintptr) float64 { , := strToFloatt64(, , 64) // if dmesgs { // dmesg("%v: %q: %v", origin(1), GoString(nptr), n) // } return } // int tolower(int c); func ( *TLS, int32) int32 { if >= 'A' && <= 'Z' { return + ('a' - 'A') } return } // int toupper(int c); func ( *TLS, int32) int32 { if >= 'a' && <= 'z' { return - ('a' - 'A') } return } // int isatty(int fd); func ( *TLS, int32) int32 { return Bool32(isatty.IsTerminal(uintptr())) } // long atol(const char *nptr); func ( *TLS, uintptr) long { , , , , := strToUint64(, , 10) switch { case : return long(-) default: return long() } } // time_t mktime(struct tm *tm); func ( *TLS, uintptr) types.Time_t { := gotime.Local if := getenv(Environ(), "TZ"); != 0 { , := parseZone(GoString()) = gotime.FixedZone(, ) } := gotime.Date( int((*time.Tm)(unsafe.Pointer()).Ftm_year+1900), gotime.Month((*time.Tm)(unsafe.Pointer()).Ftm_mon+1), int((*time.Tm)(unsafe.Pointer()).Ftm_mday), int((*time.Tm)(unsafe.Pointer()).Ftm_hour), int((*time.Tm)(unsafe.Pointer()).Ftm_min), int((*time.Tm)(unsafe.Pointer()).Ftm_sec), 0, , ) (*time.Tm)(unsafe.Pointer()).Ftm_wday = int32(.Weekday()) (*time.Tm)(unsafe.Pointer()).Ftm_yday = int32(.YearDay() - 1) return types.Time_t(.Unix()) } // char *strpbrk(const char *s, const char *accept); func ( *TLS, , uintptr) uintptr { := newBits(256) for { := *(*byte)(unsafe.Pointer()) if == 0 { break } .set(int()) ++ } for { := *(*byte)(unsafe.Pointer()) if == 0 { return 0 } if .has(int()) { return } ++ } } // int strcasecmp(const char *s1, const char *s2); func ( *TLS, , uintptr) int32 { for { := *(*byte)(unsafe.Pointer()) if >= 'a' && <= 'z' { = - ('a' - 'A') } ++ := *(*byte)(unsafe.Pointer()) if >= 'a' && <= 'z' { = - ('a' - 'A') } ++ if != || == 0 || == 0 { := int32() - int32() return } } } var __ctype_b_table = [...]uint16{ //TODO use symbolic constants 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x2003, 0x2002, 0x2002, 0x2002, 0x2002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x6001, 0xc004, 0xc004, 0xc004, 0xc004, 0xc004, 0xc004, 0xc004, 0xc004, 0xc004, 0xc004, 0xc004, 0xc004, 0xc004, 0xc004, 0xc004, 0xd808, 0xd808, 0xd808, 0xd808, 0xd808, 0xd808, 0xd808, 0xd808, 0xd808, 0xd808, 0xc004, 0xc004, 0xc004, 0xc004, 0xc004, 0xc004, 0xc004, 0xd508, 0xd508, 0xd508, 0xd508, 0xd508, 0xd508, 0xc508, 0xc508, 0xc508, 0xc508, 0xc508, 0xc508, 0xc508, 0xc508, 0xc508, 0xc508, 0xc508, 0xc508, 0xc508, 0xc508, 0xc508, 0xc508, 0xc508, 0xc508, 0xc508, 0xc508, 0xc004, 0xc004, 0xc004, 0xc004, 0xc004, 0xc004, 0xd608, 0xd608, 0xd608, 0xd608, 0xd608, 0xd608, 0xc608, 0xc608, 0xc608, 0xc608, 0xc608, 0xc608, 0xc608, 0xc608, 0xc608, 0xc608, 0xc608, 0xc608, 0xc608, 0xc608, 0xc608, 0xc608, 0xc608, 0xc608, 0xc608, 0xc608, 0xc004, 0xc004, 0xc004, 0xc004, 0x0002, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, } var ptable = uintptr(unsafe.Pointer(&__ctype_b_table[128])) // const unsigned short * * __ctype_b_loc (void); func ( *TLS) uintptr { return uintptr(unsafe.Pointer(&ptable)) } func ( *TLS, uint16) uint16 { return uint16((*[2]byte)(unsafe.Pointer(&))[0])<<8 | uint16((*[2]byte)(unsafe.Pointer(&))[1]) } // uint16_t htons(uint16_t hostshort); func ( *TLS, uint16) uint16 { var [2]byte [0] = byte( >> 8) [1] = byte() return *(*uint16)(unsafe.Pointer(&)) } // uint32_t htonl(uint32_t hostlong); func ( *TLS, uint32) uint32 { var [4]byte [0] = byte( >> 24) [1] = byte( >> 16) [2] = byte( >> 8) [3] = byte() return *(*uint32)(unsafe.Pointer(&)) } // FILE *fopen(const char *pathname, const char *mode); func ( *TLS, , uintptr) uintptr { return Xfopen64(, , ) //TODO 32 bit } func ( string, ...interface{}) { if dmesgs { dmesg(, ...) } } // void sqlite3_log(int iErrCode, const char *zFormat, ...); func ( *TLS, int32, uintptr, uintptr) { // if dmesgs { // dmesg("%v: iErrCode: %v, msg: %s\n%s", origin(1), iErrCode, printf(zFormat, args), debug.Stack()) // } } // int _IO_putc(int __c, _IO_FILE *__fp); func ( *TLS, int32, uintptr) int32 { return Xputc(, , ) } // int atexit(void (*function)(void)); func ( *TLS, uintptr) int32 { panic(todo("")) } // int vasprintf(char **strp, const char *fmt, va_list ap); func ( *TLS, , , uintptr) int32 { panic(todo("")) } func ( *int32) ( int32) { return atomic.LoadInt32() } func ( *int64) ( int64) { return atomic.LoadInt64() } func ( *uint32) ( uint32) { return atomic.LoadUint32() } func ( *uint64) ( uint64) { return atomic.LoadUint64() } func ( *uintptr) ( uintptr) { return atomic.LoadUintptr() } func ( *float32) ( float32) { return math.Float32frombits(atomic.LoadUint32((*uint32)(unsafe.Pointer()))) } func ( *float64) ( float64) { return math.Float64frombits(atomic.LoadUint64((*uint64)(unsafe.Pointer()))) } func ( uintptr) ( int32) { return atomic.LoadInt32((*int32)(unsafe.Pointer())) } func ( uintptr) ( int64) { return atomic.LoadInt64((*int64)(unsafe.Pointer())) } func ( uintptr) ( uint32) { return atomic.LoadUint32((*uint32)(unsafe.Pointer())) } func ( uintptr) ( uint64) { return atomic.LoadUint64((*uint64)(unsafe.Pointer())) } func ( uintptr) ( uintptr) { return atomic.LoadUintptr((*uintptr)(unsafe.Pointer())) } func ( uintptr) ( float32) { return math.Float32frombits(atomic.LoadUint32((*uint32)(unsafe.Pointer()))) } func ( uintptr) ( float64) { return math.Float64frombits(atomic.LoadUint64((*uint64)(unsafe.Pointer()))) } func ( *int32, int32) { atomic.StoreInt32(, ) } func ( *int64, int64) { atomic.StoreInt64(, ) } func ( *uint32, uint32) { atomic.StoreUint32(, ) } func ( *uint64, uint64) { atomic.StoreUint64(, ) } func ( *uintptr, uintptr) { atomic.StoreUintptr(, ) } func ( *float32, float32) { atomic.StoreUint32((*uint32)(unsafe.Pointer()), math.Float32bits()) } func ( *float64, float64) { atomic.StoreUint64((*uint64)(unsafe.Pointer()), math.Float64bits()) } func ( uintptr, int32) { atomic.StoreInt32((*int32)(unsafe.Pointer()), ) } func ( uintptr, int64) { atomic.StoreInt64((*int64)(unsafe.Pointer()), ) } func ( uintptr, uint32) { atomic.StoreUint32((*uint32)(unsafe.Pointer()), ) } func ( uintptr, uint64) { atomic.StoreUint64((*uint64)(unsafe.Pointer()), ) } func ( uintptr, uintptr) { atomic.StoreUintptr((*uintptr)(unsafe.Pointer()), ) } func ( uintptr, float32) { atomic.StoreUint32((*uint32)(unsafe.Pointer()), math.Float32bits()) } func ( uintptr, float64) { atomic.StoreUint64((*uint64)(unsafe.Pointer()), math.Float64bits()) } func ( *int32, int32) ( int32) { return atomic.AddInt32(, ) } func ( *int64, int64) ( int64) { return atomic.AddInt64(, ) } func ( *uint32, uint32) ( uint32) { return atomic.AddUint32(, ) } func ( *uint64, uint64) ( uint64) { return atomic.AddUint64(, ) } func ( *uintptr, uintptr) ( uintptr) { return atomic.AddUintptr(, ) } func ( *float32, float32) ( float32) { := AtomicLoadFloat32() + AtomicStoreFloat32(, ) return } func ( *float64, float64) ( float64) { := AtomicLoadFloat64() + AtomicStoreFloat64(, ) return } // size_t mbstowcs(wchar_t *dest, const char *src, size_t n); func ( *TLS, , uintptr, types.Size_t) types.Size_t { panic(todo("")) } // int mbtowc(wchar_t *pwc, const char *s, size_t n); func ( *TLS, , uintptr, types.Size_t) int32 { panic(todo("")) } // size_t __ctype_get_mb_cur_max(void); func ( *TLS) types.Size_t { panic(todo("")) } // int wctomb(char *s, wchar_t wc); func ( *TLS, uintptr, wchar_t) int32 { panic(todo("")) } // int mblen(const char *s, size_t n); func ( *TLS, uintptr, types.Size_t) int32 { panic(todo("")) } // ssize_t readv(int fd, const struct iovec *iov, int iovcnt); func ( *TLS, int32, uintptr, int32) types.Ssize_t { panic(todo("")) } // int openpty(int *amaster, int *aslave, char *name, // const struct termios *termp, // const struct winsize *winp); func ( *TLS, , , , , uintptr) int32 { panic(todo("")) } // pid_t setsid(void); func ( *TLS) types.Pid_t { panic(todo("")) } // int pselect(int nfds, fd_set *readfds, fd_set *writefds, // fd_set *exceptfds, const struct timespec *timeout, // const sigset_t *sigmask); func ( *TLS, int32, , , , , uintptr) int32 { panic(todo("")) } // int kill(pid_t pid, int sig); func ( *TLS, types.Pid_t, int32) int32 { panic(todo("")) } // int tcsendbreak(int fd, int duration); func ( *TLS, , int32) int32 { panic(todo("")) } // int wcwidth(wchar_t c); func ( *TLS, wchar_t) int32 { panic(todo("")) } // int clock_gettime(clockid_t clk_id, struct timespec *tp); func ( *TLS, int32, uintptr) int32 { panic(todo("")) } // int posix_fadvise(int fd, off_t offset, off_t len, int advice); func ( *TLS, int32, , types.Off_t, int32) int32 { panic(todo("")) } // int initstate_r(unsigned int seed, char *statebuf, // size_t statelen, struct random_data *buf); func ( *TLS, uint32, uintptr, types.Size_t, uintptr) int32 { panic(todo("")) } // int random_r(struct random_data *buf, int32_t *result); func ( *TLS, , uintptr) int32 { panic(todo("")) } // AtExit will attempt to run f at process exit. The execution cannot be // guaranteed, neither its ordering with respect to any other handlers // registered by AtExit. func ( func()) { atExitMu.Lock() atExit = append(atExit, ) atExitMu.Unlock() }