github.com/afumu/libc@v0.0.6/libc.go (about)

     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 "github.com/afumu/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/afumu/libc/errno"
    35  	"github.com/afumu/libc/stdio"
    36  	"github.com/afumu/libc/sys/types"
    37  	"github.com/afumu/libc/time"
    38  	"github.com/afumu/libc/unistd"
    39  	"github.com/mattn/go-isatty"
    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  }