libc_musl.go 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119
  1. // Copyright 2023 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. //go:build linux && (amd64 || arm64 || loong64 || ppc64le || s390x || riscv64 || 386 || arm)
  5. //go:generate go run generator.go
  6. // Package libc is the runtime for programs generated by ccgo/v4 or later.
  7. //
  8. // # Version compatibility
  9. //
  10. // The API of this package, in particular the bits that directly support the
  11. // ccgo compiler, may change in a way that is not backward compatible. If you
  12. // have generated some Go code from C you should stick to the version of this
  13. // package that you used at that time and was tested with your payload. The
  14. // correct way to upgrade to a newer version of this package is to first
  15. // recompile (C to Go) your code with a newer version of ccgo that depends on
  16. // the new libc version.
  17. //
  18. // If you use C to Go translated code provided by others, stick to the version
  19. // of libc that translated code shows in its go.mod file and do not upgrade the
  20. // dependency just because a newer libc is tagged.Vgq
  21. //
  22. // This is if course unfortunate. However, it's somewhat similar to C code
  23. // linked with a specific version of, say GNU libc. When such code asking for
  24. // glibc5 is run on a system with glibc6, or vice versa, it will fail.
  25. //
  26. // As a particular example, if your project imports modernc.org/sqlite you
  27. // should use the same libc version as seen in the go.mod file of the sqlite
  28. // package.
  29. //
  30. // tl;dr: It is not always possible to fix ccgo bugs and/or improve performance
  31. // of the ccgo transpiled code without occasionally making incompatible changes
  32. // to this package.
  33. //
  34. // # Thread Local Storage
  35. //
  36. // A TLS instance represents a main thread or a thread created by
  37. // Xpthread_create. A TLS instance is not safe for concurrent use by multiple
  38. // goroutines.
  39. //
  40. // If a program starts the C main function, a TLS instance is created
  41. // automatically and the goroutine entering main() is locked to the OS thread.
  42. // The translated C code then may create other pthreads by calling
  43. // Xpthread_create.
  44. //
  45. // If the translated C code is part of a library package, new TLS instances
  46. // must be created manually in user/client code. The first TLS instance created
  47. // will be the "main" libc thread, but it will be not locked to OS thread
  48. // automatically. Any subsequently manually created TLS instances will call
  49. // Xpthread_create, but without spawning a new goroutine.
  50. //
  51. // A manual call to Xpthread_create will create a new TLS instance automatically
  52. // and spawn a new goroutine executing the thread function.
  53. // Package libc provides run time support for programs generated by the
  54. // [ccgo] C to Go transpiler, version 4 or later.
  55. //
  56. // # Concurrency
  57. //
  58. // Many C libc functions are not thread safe. Such functions are not safe
  59. // for concurrent use by multiple goroutines in the Go translation as well.
  60. //
  61. // # Thread Local Storage
  62. //
  63. // C threads are modeled as Go goroutines. Every such C thread, ie. a Go
  64. // goroutine, must use its own Thread Local Storage instance implemented by the
  65. // [TLS] type.
  66. //
  67. // # Signals
  68. //
  69. // Signal handling in translated C code is not coordinated with the Go runtime.
  70. // This is probably the same as when running C code via CGo.
  71. //
  72. // # Environmental variables
  73. //
  74. // This package synchronizes its environ with the current Go environ lazily and
  75. // only once.
  76. //
  77. // # libc API documentation copyright
  78. //
  79. // From [Linux man-pages Copyleft]
  80. //
  81. // Permission is granted to make and distribute verbatim copies of this
  82. // manual provided the copyright notice and this permission notice are
  83. // preserved on all copies.
  84. //
  85. // Permission is granted to copy and distribute modified versions of this
  86. // manual under the conditions for verbatim copying, provided that the
  87. // entire resulting derived work is distributed under the terms of a
  88. // permission notice identical to this one.
  89. //
  90. // Since the Linux kernel and libraries are constantly changing, this
  91. // manual page may be incorrect or out-of-date. The author(s) assume no
  92. // responsibility for errors or omissions, or for damages resulting from
  93. // the use of the information contained herein. The author(s) may not have
  94. // taken the same level of care in the production of this manual, which is
  95. // licensed free of charge, as they might when working professionally.
  96. //
  97. // Formatted or processed versions of this manual, if unaccompanied by the
  98. // source, must acknowledge the copyright and authors of this work.
  99. //
  100. // [Linux man-pages Copyleft]: https://spdx.org/licenses/Linux-man-pages-copyleft.html
  101. // [ccgo]: http://modernc.org/ccgo/v4
  102. package libc // import "modernc.org/libc"
  103. import (
  104. "fmt"
  105. "io"
  106. "math"
  107. "math/rand"
  108. "os"
  109. "os/exec"
  110. gosignal "os/signal"
  111. "path/filepath"
  112. "runtime"
  113. "sort"
  114. "strings"
  115. "sync"
  116. "sync/atomic"
  117. "time"
  118. "unsafe"
  119. guuid "github.com/google/uuid"
  120. "golang.org/x/sys/unix"
  121. "modernc.org/libc/uuid/uuid"
  122. "modernc.org/memory"
  123. )
  124. const (
  125. heapAlign = 16
  126. heapGuard = 16
  127. )
  128. var (
  129. _ error = (*MemAuditError)(nil)
  130. allocator memory.Allocator
  131. allocatorMu sync.Mutex
  132. atExitMu sync.Mutex
  133. atExit []func()
  134. tid atomic.Int32 // TLS Go ID
  135. Covered = map[uintptr]struct{}{}
  136. CoveredC = map[string]struct{}{}
  137. coverPCs [1]uintptr //TODO not concurrent safe
  138. )
  139. func init() {
  140. nm, err := os.Executable()
  141. if err != nil {
  142. return
  143. }
  144. Xprogram_invocation_name = mustCString(nm)
  145. Xprogram_invocation_short_name = mustCString(filepath.Base(nm))
  146. X__libc.Fpage_size = Tsize_t(os.Getpagesize())
  147. }
  148. // RawMem64 represents the biggest uint64 array the runtime can handle.
  149. type RawMem64 [unsafe.Sizeof(RawMem{}) / unsafe.Sizeof(uint64(0))]uint64
  150. type MemAuditError struct {
  151. Caller string
  152. Message string
  153. }
  154. func (e *MemAuditError) Error() string {
  155. return fmt.Sprintf("%s: %s", e.Caller, e.Message)
  156. }
  157. // Start executes C's main.
  158. func Start(main func(*TLS, int32, uintptr) int32) {
  159. runtime.LockOSThread()
  160. if isMemBrk {
  161. defer func() {
  162. trc("==== PANIC")
  163. for _, v := range MemAudit() {
  164. trc("", v.Error())
  165. }
  166. }()
  167. }
  168. tls := NewTLS()
  169. Xexit(tls, main(tls, int32(len(os.Args)), mustAllocStrings(os.Args)))
  170. }
  171. func mustAllocStrings(a []string) (r uintptr) {
  172. nPtrs := len(a) + 1
  173. pPtrs := mustCalloc(Tsize_t(uintptr(nPtrs) * unsafe.Sizeof(uintptr(0))))
  174. ptrs := unsafe.Slice((*uintptr)(unsafe.Pointer(pPtrs)), nPtrs)
  175. nBytes := 0
  176. for _, v := range a {
  177. nBytes += len(v) + 1
  178. }
  179. pBytes := mustCalloc(Tsize_t(nBytes))
  180. b := unsafe.Slice((*byte)(unsafe.Pointer(pBytes)), nBytes)
  181. for i, v := range a {
  182. copy(b, v)
  183. b = b[len(v)+1:]
  184. ptrs[i] = pBytes
  185. pBytes += uintptr(len(v)) + 1
  186. }
  187. return pPtrs
  188. }
  189. func mustCString(s string) (r uintptr) {
  190. n := len(s)
  191. r = mustMalloc(Tsize_t(n + 1))
  192. copy(unsafe.Slice((*byte)(unsafe.Pointer(r)), n), s)
  193. *(*byte)(unsafe.Pointer(r + uintptr(n))) = 0
  194. return r
  195. }
  196. // CString returns a pointer to a zero-terminated version of s. The caller is
  197. // responsible for freeing the allocated memory using Xfree.
  198. func CString(s string) (uintptr, error) {
  199. n := len(s)
  200. p := Xmalloc(nil, Tsize_t(n)+1)
  201. if p == 0 {
  202. return 0, fmt.Errorf("CString: cannot allocate %d bytes", n+1)
  203. }
  204. copy(unsafe.Slice((*byte)(unsafe.Pointer(p)), n), s)
  205. *(*byte)(unsafe.Pointer(p + uintptr(n))) = 0
  206. return p, nil
  207. }
  208. func mustMalloc(sz Tsize_t) (r uintptr) {
  209. if r = Xmalloc(nil, sz); r != 0 || sz == 0 {
  210. return r
  211. }
  212. panic(todo("OOM"))
  213. }
  214. func mustCalloc(sz Tsize_t) (r uintptr) {
  215. if r := Xcalloc(nil, 1, sz); r != 0 || sz == 0 {
  216. return r
  217. }
  218. panic(todo("OOM"))
  219. }
  220. type tlsStackSlot struct {
  221. p uintptr
  222. sz Tsize_t
  223. }
  224. // TLS emulates thread local storage. TLS is not safe for concurrent use by
  225. // multiple goroutines.
  226. type TLS struct {
  227. allocaStack []int
  228. allocas []uintptr
  229. jumpBuffers []uintptr
  230. pendingSignals chan os.Signal
  231. pthread uintptr // *t__pthread
  232. pthreadCleanupItems []pthreadCleanupItem
  233. pthreadKeyValues map[Tpthread_key_t]uintptr
  234. sigHandlers map[int32]uintptr
  235. sp int
  236. stack []tlsStackSlot
  237. ID int32
  238. checkSignals bool
  239. ownsPthread bool
  240. }
  241. var __ccgo_environOnce sync.Once
  242. // NewTLS returns a newly created TLS that must be eventually closed to prevent
  243. // resource leaks.
  244. func NewTLS() (r *TLS) {
  245. id := tid.Add(1)
  246. if id == 0 {
  247. id = tid.Add(1)
  248. }
  249. __ccgo_environOnce.Do(func() {
  250. Xenviron = mustAllocStrings(os.Environ())
  251. })
  252. pthread := mustMalloc(Tsize_t(unsafe.Sizeof(t__pthread{})))
  253. *(*t__pthread)(unsafe.Pointer(pthread)) = t__pthread{
  254. Flocale: uintptr(unsafe.Pointer(&X__libc.Fglobal_locale)),
  255. Fself: pthread,
  256. Ftid: id,
  257. }
  258. return &TLS{
  259. ID: id,
  260. ownsPthread: true,
  261. pthread: pthread,
  262. sigHandlers: map[int32]uintptr{},
  263. }
  264. }
  265. // StackSlots reports the number of tls stack slots currently in use.
  266. func (tls *TLS) StackSlots() int {
  267. return tls.sp
  268. }
  269. // int *__errno_location(void)
  270. func X__errno_location(tls *TLS) (r uintptr) {
  271. return tls.pthread + unsafe.Offsetof(t__pthread{}.Ferrno_val)
  272. }
  273. // int *__errno_location(void)
  274. func X___errno_location(tls *TLS) (r uintptr) {
  275. return X__errno_location(tls)
  276. }
  277. func (tls *TLS) setErrno(n int32) {
  278. if tls == nil {
  279. return
  280. }
  281. *(*int32)(unsafe.Pointer(X__errno_location(tls))) = n
  282. }
  283. func (tls *TLS) String() string {
  284. return fmt.Sprintf("TLS#%v pthread=%x", tls.ID, tls.pthread)
  285. }
  286. // Alloc allocates n bytes in tls's local storage. Calls to Alloc() must be
  287. // strictly paired with calls to TLS.Free on function exit. That also means any
  288. // memory from Alloc must not be used after a function returns.
  289. //
  290. // The order matters. This is ok:
  291. //
  292. // p := tls.Alloc(11)
  293. // q := tls.Alloc(22)
  294. // tls.Free(22)
  295. // // q is no more usable here.
  296. // tls.Free(11)
  297. // // p is no more usable here.
  298. //
  299. // This is not correct:
  300. //
  301. // tls.Alloc(11)
  302. // tls.Alloc(22)
  303. // tls.Free(11)
  304. // tls.Free(22)
  305. func (tls *TLS) Alloc(n0 int) (r uintptr) {
  306. // shrink stats speedtest1
  307. // -----------------------------------------------------------------------------------------------
  308. // 0 total 2,544, nallocs 107,553,070, nmallocs 25, nreallocs 107,553,045 10.984s
  309. // 1 total 2,544, nallocs 107,553,070, nmallocs 25, nreallocs 38,905,980 9.597s
  310. // 2 total 2,616, nallocs 107,553,070, nmallocs 25, nreallocs 18,201,284 9.206s
  311. // 3 total 2,624, nallocs 107,553,070, nmallocs 25, nreallocs 16,716,302 9.155s
  312. // 4 total 2,624, nallocs 107,553,070, nmallocs 25, nreallocs 16,156,102 9.398s
  313. // 8 total 3,408, nallocs 107,553,070, nmallocs 25, nreallocs 14,364,274 9.198s
  314. // 16 total 3,976, nallocs 107,553,070, nmallocs 25, nreallocs 6,219,602 8.910s
  315. // ---------------------------------------------------------------------------------------------
  316. // 32 total 5,120, nallocs 107,553,070, nmallocs 25, nreallocs 1,089,037 8.836s
  317. // ---------------------------------------------------------------------------------------------
  318. // 64 total 6,520, nallocs 107,553,070, nmallocs 25, nreallocs 1,788 8.420s
  319. // 128 total 8,848, nallocs 107,553,070, nmallocs 25, nreallocs 1,098 8.833s
  320. // 256 total 8,848, nallocs 107,553,070, nmallocs 25, nreallocs 1,049 9.508s
  321. // 512 total 33,336, nallocs 107,553,070, nmallocs 25, nreallocs 88 8.667s
  322. // none total 33,336, nallocs 107,553,070, nmallocs 25, nreallocs 88 8.408s
  323. const shrinkSegment = 32
  324. n := Tsize_t(n0)
  325. if tls.sp < len(tls.stack) {
  326. p := tls.stack[tls.sp].p
  327. sz := tls.stack[tls.sp].sz
  328. if sz >= n /* && sz <= shrinkSegment*n */ {
  329. // Segment shrinking is nice to have but Tcl does some dirty hacks in coroutine
  330. // handling that require stability of stack addresses, out of the C execution
  331. // model. Disabled.
  332. tls.sp++
  333. return p
  334. }
  335. Xfree(tls, p)
  336. r = mustMalloc(n)
  337. tls.stack[tls.sp] = tlsStackSlot{p: r, sz: Xmalloc_usable_size(tls, r)}
  338. tls.sp++
  339. return r
  340. }
  341. r = mustMalloc(n)
  342. tls.stack = append(tls.stack, tlsStackSlot{p: r, sz: Xmalloc_usable_size(tls, r)})
  343. tls.sp++
  344. return r
  345. }
  346. // Free manages memory of the preceding TLS.Alloc()
  347. func (tls *TLS) Free(n int) {
  348. //TODO shrink stacks if possible. Tcl is currently against.
  349. tls.sp--
  350. if !tls.checkSignals {
  351. return
  352. }
  353. select {
  354. case sig := <-tls.pendingSignals:
  355. signum := int32(sig.(unix.Signal))
  356. h, ok := tls.sigHandlers[signum]
  357. if !ok {
  358. break
  359. }
  360. switch h {
  361. case SIG_DFL:
  362. // nop
  363. case SIG_IGN:
  364. // nop
  365. default:
  366. (*(*func(*TLS, int32))(unsafe.Pointer(&struct{ uintptr }{h})))(tls, signum)
  367. }
  368. default:
  369. // nop
  370. }
  371. }
  372. func (tls *TLS) alloca(n Tsize_t) (r uintptr) {
  373. r = mustMalloc(n)
  374. tls.allocas = append(tls.allocas, r)
  375. return r
  376. }
  377. // AllocaEntry must be called early on function entry when the function calls
  378. // or may call alloca(3).
  379. func (tls *TLS) AllocaEntry() {
  380. tls.allocaStack = append(tls.allocaStack, len(tls.allocas))
  381. }
  382. // AllocaExit must be defer-called on function exit when the function calls or
  383. // may call alloca(3).
  384. func (tls *TLS) AllocaExit() {
  385. n := len(tls.allocaStack)
  386. x := tls.allocaStack[n-1]
  387. tls.allocaStack = tls.allocaStack[:n-1]
  388. for _, v := range tls.allocas[x:] {
  389. Xfree(tls, v)
  390. }
  391. tls.allocas = tls.allocas[:x]
  392. }
  393. func (tls *TLS) Close() {
  394. defer func() { *tls = TLS{} }()
  395. for _, v := range tls.allocas {
  396. Xfree(tls, v)
  397. }
  398. for _, v := range tls.stack /* shrink diabled[:tls.sp] */ {
  399. Xfree(tls, v.p)
  400. }
  401. if tls.ownsPthread {
  402. Xfree(tls, tls.pthread)
  403. }
  404. }
  405. func (tls *TLS) PushJumpBuffer(jb uintptr) {
  406. tls.jumpBuffers = append(tls.jumpBuffers, jb)
  407. }
  408. type LongjmpRetval int32
  409. func (tls *TLS) PopJumpBuffer(jb uintptr) {
  410. n := len(tls.jumpBuffers)
  411. if n == 0 || tls.jumpBuffers[n-1] != jb {
  412. panic(todo("unsupported setjmp/longjmp usage"))
  413. }
  414. tls.jumpBuffers = tls.jumpBuffers[:n-1]
  415. }
  416. func (tls *TLS) Longjmp(jb uintptr, val int32) {
  417. tls.PopJumpBuffer(jb)
  418. if val == 0 {
  419. val = 1
  420. }
  421. panic(LongjmpRetval(val))
  422. }
  423. // ============================================================================
  424. func Xexit(tls *TLS, code int32) {
  425. //TODO atexit finalizers
  426. X__stdio_exit(tls)
  427. for _, v := range atExit {
  428. v()
  429. }
  430. atExitHandlersMu.Lock()
  431. for _, v := range atExitHandlers {
  432. (*(*func(*TLS))(unsafe.Pointer(&struct{ uintptr }{v})))(tls)
  433. }
  434. os.Exit(int(code))
  435. }
  436. func _exit(tls *TLS, code int32) {
  437. Xexit(tls, code)
  438. }
  439. var abort Tsigaction
  440. func Xabort(tls *TLS) {
  441. X__libc_sigaction(tls, SIGABRT, uintptr(unsafe.Pointer(&abort)), 0)
  442. unix.Kill(unix.Getpid(), unix.Signal(SIGABRT))
  443. panic(todo("unrechable"))
  444. }
  445. type lock struct {
  446. sync.Mutex
  447. waiters int
  448. }
  449. var (
  450. locksMu sync.Mutex
  451. locks = map[uintptr]*lock{}
  452. )
  453. /*
  454. T1 T2
  455. lock(&foo) // foo: 0 -> 1
  456. lock(&foo) // foo: 1 -> 2
  457. unlock(&foo) // foo: 2 -> 1, non zero means waiter(s) active
  458. unlock(&foo) // foo: 1 -> 0
  459. */
  460. func ___lock(tls *TLS, p uintptr) {
  461. if atomic.AddInt32((*int32)(unsafe.Pointer(p)), 1) == 1 {
  462. return
  463. }
  464. // foo was already acquired by some other C thread.
  465. locksMu.Lock()
  466. l := locks[p]
  467. if l == nil {
  468. l = &lock{}
  469. locks[p] = l
  470. l.Lock()
  471. }
  472. l.waiters++
  473. locksMu.Unlock()
  474. l.Lock() // Wait for T1 to release foo. (X below)
  475. }
  476. func ___unlock(tls *TLS, p uintptr) {
  477. if atomic.AddInt32((*int32)(unsafe.Pointer(p)), -1) == 0 {
  478. return
  479. }
  480. // Some other C thread is waiting for foo.
  481. locksMu.Lock()
  482. l := locks[p]
  483. if l == nil {
  484. // We are T1 and we got the locksMu locked before T2.
  485. l = &lock{waiters: 1}
  486. l.Lock()
  487. }
  488. l.Unlock() // Release foo, T2 may now lock it. (X above)
  489. l.waiters--
  490. if l.waiters == 0 { // we are T2
  491. delete(locks, p)
  492. }
  493. locksMu.Unlock()
  494. }
  495. type lockedFile struct {
  496. ch chan struct{}
  497. waiters int
  498. }
  499. var (
  500. lockedFilesMu sync.Mutex
  501. lockedFiles = map[uintptr]*lockedFile{}
  502. )
  503. func X__lockfile(tls *TLS, file uintptr) int32 {
  504. return ___lockfile(tls, file)
  505. }
  506. // int __lockfile(FILE *f)
  507. func ___lockfile(tls *TLS, file uintptr) int32 {
  508. panic(todo(""))
  509. // lockedFilesMu.Lock()
  510. // defer lockedFilesMu.Unlock()
  511. // l := lockedFiles[file]
  512. // if l == nil {
  513. // l = &lockedFile{ch: make(chan struct{}, 1)}
  514. // lockedFiles[file] = l
  515. // }
  516. // l.waiters++
  517. // l.ch <- struct{}{}
  518. }
  519. func X__unlockfile(tls *TLS, file uintptr) {
  520. ___unlockfile(tls, file)
  521. }
  522. // void __unlockfile(FILE *f)
  523. func ___unlockfile(tls *TLS, file uintptr) {
  524. panic(todo(""))
  525. lockedFilesMu.Lock()
  526. defer lockedFilesMu.Unlock()
  527. l := lockedFiles[file]
  528. l.waiters--
  529. if l.waiters == 0 {
  530. delete(lockedFiles, file)
  531. }
  532. <-l.ch
  533. }
  534. // void __synccall(void (*func)(void *), void *ctx)
  535. func ___synccall(tls *TLS, fn, ctx uintptr) {
  536. (*(*func(*TLS, uintptr))(unsafe.Pointer(&struct{ uintptr }{fn})))(tls, ctx)
  537. }
  538. // func ___randname(tls *TLS, template uintptr) (r1 uintptr) {
  539. // bp := tls.Alloc(16)
  540. // defer tls.Free(16)
  541. // var i int32
  542. // var r uint64
  543. // var _ /* ts at bp+0 */ Ttimespec
  544. // X__clock_gettime(tls, CLOCK_REALTIME, bp)
  545. // goto _2
  546. // _2:
  547. // r = uint64((*(*Ttimespec)(unsafe.Pointer(bp))).Ftv_sec+(*(*Ttimespec)(unsafe.Pointer(bp))).Ftv_nsec) + uint64(tls.ID)*uint64(65537)
  548. // i = 0
  549. // for {
  550. // if !(i < int32(6)) {
  551. // break
  552. // }
  553. // *(*int8)(unsafe.Pointer(template + uintptr(i))) = int8(uint64('A') + r&uint64(15) + r&uint64(16)*uint64(2))
  554. // goto _3
  555. // _3:
  556. // i++
  557. // r >>= uint64(5)
  558. // }
  559. // return template
  560. // }
  561. // #include <time.h>
  562. // #include <stdint.h>
  563. // #include "pthread_impl.h"
  564. //
  565. // /* This assumes that a check for the
  566. //
  567. // template size has already been made */
  568. //
  569. // char *__randname(char *template)
  570. //
  571. // {
  572. // int i;
  573. // struct timespec ts;
  574. // unsigned long r;
  575. //
  576. // __clock_gettime(CLOCK_REALTIME, &ts);
  577. // r = ts.tv_sec + ts.tv_nsec + __pthread_self()->tid * 65537UL;
  578. // for (i=0; i<6; i++, r>>=5)
  579. // template[i] = 'A'+(r&15)+(r&16)*2;
  580. //
  581. // return template;
  582. // }
  583. func ___randname(tls *TLS, template uintptr) (r1 uintptr) {
  584. var i int32
  585. ts := time.Now().UnixNano()
  586. r := uint64(ts) + uint64(tls.ID)*65537
  587. i = 0
  588. for {
  589. if !(i < int32(6)) {
  590. break
  591. }
  592. *(*int8)(unsafe.Pointer(template + uintptr(i))) = int8(uint64('A') + r&uint64(15) + r&uint64(16)*uint64(2))
  593. goto _3
  594. _3:
  595. i++
  596. r >>= uint64(5)
  597. }
  598. return template
  599. }
  600. func ___get_tp(tls *TLS) uintptr {
  601. return tls.pthread
  602. }
  603. func Xfork(t *TLS) int32 {
  604. if __ccgo_strace {
  605. trc("t=%v, (%v:)", t, origin(2))
  606. }
  607. t.setErrno(ENOSYS)
  608. return -1
  609. }
  610. const SIG_DFL = 0
  611. const SIG_IGN = 1
  612. func Xsignal(tls *TLS, signum int32, handler uintptr) (r uintptr) {
  613. r, tls.sigHandlers[signum] = tls.sigHandlers[signum], handler
  614. switch handler {
  615. case SIG_DFL:
  616. gosignal.Reset(unix.Signal(signum))
  617. case SIG_IGN:
  618. gosignal.Ignore(unix.Signal(signum))
  619. default:
  620. if tls.pendingSignals == nil {
  621. tls.pendingSignals = make(chan os.Signal, 3)
  622. tls.checkSignals = true
  623. }
  624. gosignal.Notify(tls.pendingSignals, unix.Signal(signum))
  625. }
  626. return r
  627. }
  628. var (
  629. atExitHandlersMu sync.Mutex
  630. atExitHandlers []uintptr
  631. )
  632. func Xatexit(tls *TLS, func_ uintptr) (r int32) {
  633. atExitHandlersMu.Lock()
  634. atExitHandlers = append(atExitHandlers, func_)
  635. atExitHandlersMu.Unlock()
  636. return 0
  637. }
  638. var __sync_synchronize_dummy int32
  639. // __sync_synchronize();
  640. func X__sync_synchronize(t *TLS) {
  641. if __ccgo_strace {
  642. trc("t=%v, (%v:)", t, origin(2))
  643. }
  644. // Attempt to implement a full memory barrier without assembler.
  645. atomic.StoreInt32(&__sync_synchronize_dummy, atomic.LoadInt32(&__sync_synchronize_dummy)+1)
  646. }
  647. func Xdlopen(t *TLS, filename uintptr, flags int32) uintptr {
  648. if __ccgo_strace {
  649. trc("t=%v filename=%v flags=%v, (%v:)", t, filename, flags, origin(2))
  650. }
  651. return 0
  652. }
  653. func Xdlsym(t *TLS, handle, symbol uintptr) uintptr {
  654. if __ccgo_strace {
  655. trc("t=%v symbol=%v, (%v:)", t, symbol, origin(2))
  656. }
  657. return 0
  658. }
  659. var dlErrorMsg = []byte("not supported\x00")
  660. func Xdlerror(t *TLS) uintptr {
  661. if __ccgo_strace {
  662. trc("t=%v, (%v:)", t, origin(2))
  663. }
  664. return uintptr(unsafe.Pointer(&dlErrorMsg[0]))
  665. }
  666. func Xdlclose(t *TLS, handle uintptr) int32 {
  667. if __ccgo_strace {
  668. trc("t=%v handle=%v, (%v:)", t, handle, origin(2))
  669. }
  670. panic(todo(""))
  671. }
  672. func Xsystem(t *TLS, command uintptr) int32 {
  673. if __ccgo_strace {
  674. trc("t=%v command=%v, (%v:)", t, command, origin(2))
  675. }
  676. s := GoString(command)
  677. if command == 0 {
  678. panic(todo(""))
  679. }
  680. cmd := exec.Command("sh", "-c", s)
  681. cmd.Stdout = os.Stdout
  682. cmd.Stderr = os.Stderr
  683. err := cmd.Run()
  684. if err != nil {
  685. ps := err.(*exec.ExitError)
  686. return int32(ps.ExitCode())
  687. }
  688. return 0
  689. }
  690. func Xsched_yield(tls *TLS) int32 {
  691. runtime.Gosched()
  692. return 0
  693. }
  694. // AtExit will attempt to run f at process exit. The execution cannot be
  695. // guaranteed, neither its ordering with respect to any other handlers
  696. // registered by AtExit.
  697. func AtExit(f func()) {
  698. atExitMu.Lock()
  699. atExit = append(atExit, f)
  700. atExitMu.Unlock()
  701. }
  702. func Bool64(b bool) int64 {
  703. if b {
  704. return 1
  705. }
  706. return 0
  707. }
  708. func Environ() uintptr {
  709. __ccgo_environOnce.Do(func() {
  710. Xenviron = mustAllocStrings(os.Environ())
  711. })
  712. return Xenviron
  713. }
  714. func EnvironP() uintptr {
  715. __ccgo_environOnce.Do(func() {
  716. Xenviron = mustAllocStrings(os.Environ())
  717. })
  718. return uintptr(unsafe.Pointer(&Xenviron))
  719. }
  720. // NewVaList is like VaList but automatically allocates the correct amount of
  721. // memory for all of the items in args.
  722. //
  723. // The va_list return value is used to pass the constructed var args to var
  724. // args accepting functions. The caller of NewVaList is responsible for freeing
  725. // the va_list.
  726. func NewVaList(args ...interface{}) (va_list uintptr) {
  727. return VaList(NewVaListN(len(args)), args...)
  728. }
  729. // NewVaListN returns a newly allocated va_list for n items. The caller of
  730. // NewVaListN is responsible for freeing the va_list.
  731. func NewVaListN(n int) (va_list uintptr) {
  732. return Xmalloc(nil, Tsize_t(8*n))
  733. }
  734. func SetEnviron(t *TLS, env []string) {
  735. __ccgo_environOnce.Do(func() {
  736. Xenviron = mustAllocStrings(env)
  737. })
  738. }
  739. func Dmesg(s string, args ...interface{}) {
  740. // nop
  741. }
  742. func Xalloca(tls *TLS, size Tsize_t) uintptr {
  743. return tls.alloca(size)
  744. }
  745. // struct cmsghdr *CMSG_NXTHDR(struct msghdr *msgh, struct cmsghdr *cmsg);
  746. func X__cmsg_nxthdr(t *TLS, msgh, cmsg uintptr) uintptr {
  747. panic(todo(""))
  748. }
  749. func Cover() {
  750. runtime.Callers(2, coverPCs[:])
  751. Covered[coverPCs[0]] = struct{}{}
  752. }
  753. func CoverReport(w io.Writer) error {
  754. var a []string
  755. pcs := make([]uintptr, 1)
  756. for pc := range Covered {
  757. pcs[0] = pc
  758. frame, _ := runtime.CallersFrames(pcs).Next()
  759. a = append(a, fmt.Sprintf("%s:%07d:%s", filepath.Base(frame.File), frame.Line, frame.Func.Name()))
  760. }
  761. sort.Strings(a)
  762. _, err := fmt.Fprintf(w, "%s\n", strings.Join(a, "\n"))
  763. return err
  764. }
  765. func CoverC(s string) {
  766. CoveredC[s] = struct{}{}
  767. }
  768. func CoverCReport(w io.Writer) error {
  769. var a []string
  770. for k := range CoveredC {
  771. a = append(a, k)
  772. }
  773. sort.Strings(a)
  774. _, err := fmt.Fprintf(w, "%s\n", strings.Join(a, "\n"))
  775. return err
  776. }
  777. func X__ccgo_dmesg(t *TLS, fmt uintptr, va uintptr) {
  778. panic(todo(""))
  779. }
  780. func X__ccgo_getMutexType(tls *TLS, m uintptr) int32 { /* pthread_mutex_lock.c:3:5: */
  781. panic(todo(""))
  782. }
  783. func X__ccgo_in6addr_anyp(t *TLS) uintptr {
  784. panic(todo(""))
  785. }
  786. func X__ccgo_pthreadAttrGetDetachState(tls *TLS, a uintptr) int32 { /* pthread_attr_get.c:3:5: */
  787. panic(todo(""))
  788. }
  789. func X__ccgo_pthreadMutexattrGettype(tls *TLS, a uintptr) int32 { /* pthread_attr_get.c:93:5: */
  790. panic(todo(""))
  791. }
  792. // void sqlite3_log(int iErrCode, const char *zFormat, ...);
  793. func X__ccgo_sqlite3_log(t *TLS, iErrCode int32, zFormat uintptr, args uintptr) {
  794. // nop
  795. }
  796. // unsigned __sync_add_and_fetch_uint32(*unsigned, unsigned)
  797. func X__sync_add_and_fetch_uint32(t *TLS, p uintptr, v uint32) uint32 {
  798. return atomic.AddUint32((*uint32)(unsafe.Pointer(p)), v)
  799. }
  800. // unsigned __sync_sub_and_fetch_uint32(*unsigned, unsigned)
  801. func X__sync_sub_and_fetch_uint32(t *TLS, p uintptr, v uint32) uint32 {
  802. return atomic.AddUint32((*uint32)(unsafe.Pointer(p)), -v)
  803. }
  804. var (
  805. randomData = map[uintptr]*rand.Rand{}
  806. randomDataMu sync.Mutex
  807. )
  808. // The initstate_r() function is like initstate(3) except that it initializes
  809. // the state in the object pointed to by buf, rather than initializing the
  810. // global state variable. Before calling this function, the buf.state field
  811. // must be initialized to NULL. The initstate_r() function records a pointer
  812. // to the statebuf argument inside the structure pointed to by buf. Thus,
  813. // state‐ buf should not be deallocated so long as buf is still in use. (So,
  814. // statebuf should typically be allocated as a static variable, or allocated on
  815. // the heap using malloc(3) or similar.)
  816. //
  817. // char *initstate_r(unsigned int seed, char *statebuf, size_t statelen, struct random_data *buf);
  818. func Xinitstate_r(t *TLS, seed uint32, statebuf uintptr, statelen Tsize_t, buf uintptr) int32 {
  819. if buf == 0 {
  820. panic(todo(""))
  821. }
  822. randomDataMu.Lock()
  823. defer randomDataMu.Unlock()
  824. randomData[buf] = rand.New(rand.NewSource(int64(seed)))
  825. return 0
  826. }
  827. // int random_r(struct random_data *buf, int32_t *result);
  828. func Xrandom_r(t *TLS, buf, result uintptr) int32 {
  829. randomDataMu.Lock()
  830. defer randomDataMu.Unlock()
  831. mr := randomData[buf]
  832. if RAND_MAX != math.MaxInt32 {
  833. panic(todo(""))
  834. }
  835. *(*int32)(unsafe.Pointer(result)) = mr.Int31()
  836. return 0
  837. }
  838. // void longjmp(jmp_buf env, int val);
  839. func Xlongjmp(t *TLS, env uintptr, val int32) {
  840. panic(todo(""))
  841. }
  842. // void _longjmp(jmp_buf env, int val);
  843. func X_longjmp(t *TLS, env uintptr, val int32) {
  844. panic(todo(""))
  845. }
  846. // int _obstack_begin (struct obstack *h, _OBSTACK_SIZE_T size, _OBSTACK_SIZE_T alignment, void *(*chunkfun) (size_t), void (*freefun) (void *))
  847. func X_obstack_begin(t *TLS, obstack uintptr, size, alignment int32, chunkfun, freefun uintptr) int32 {
  848. panic(todo(""))
  849. }
  850. // extern void _obstack_newchunk(struct obstack *, int);
  851. func X_obstack_newchunk(t *TLS, obstack uintptr, length int32) int32 {
  852. panic(todo(""))
  853. }
  854. // void obstack_free (struct obstack *h, void *obj)
  855. func Xobstack_free(t *TLS, obstack, obj uintptr) {
  856. panic(todo(""))
  857. }
  858. // int obstack_vprintf (struct obstack *obstack, const char *template, va_list ap)
  859. func Xobstack_vprintf(t *TLS, obstack, template, va uintptr) int32 {
  860. panic(todo(""))
  861. }
  862. // int _setjmp(jmp_buf env);
  863. func X_setjmp(t *TLS, env uintptr) int32 {
  864. return 0 //TODO
  865. }
  866. // int setjmp(jmp_buf env);
  867. func Xsetjmp(t *TLS, env uintptr) int32 {
  868. panic(todo(""))
  869. }
  870. // int backtrace(void **buffer, int size);
  871. func Xbacktrace(t *TLS, buf uintptr, size int32) int32 {
  872. panic(todo(""))
  873. }
  874. // void backtrace_symbols_fd(void *const *buffer, int size, int fd);
  875. func Xbacktrace_symbols_fd(t *TLS, buffer uintptr, size, fd int32) {
  876. panic(todo(""))
  877. }
  878. // int fts_close(FTS *ftsp);
  879. func Xfts_close(t *TLS, ftsp uintptr) int32 {
  880. panic(todo(""))
  881. }
  882. // FTS *fts_open(char * const *path_argv, int options, int (*compar)(const FTSENT **, const FTSENT **));
  883. func Xfts_open(t *TLS, path_argv uintptr, options int32, compar uintptr) uintptr {
  884. panic(todo(""))
  885. }
  886. // FTSENT *fts_read(FTS *ftsp);
  887. func Xfts64_read(t *TLS, ftsp uintptr) uintptr {
  888. panic(todo(""))
  889. }
  890. // int fts_close(FTS *ftsp);
  891. func Xfts64_close(t *TLS, ftsp uintptr) int32 {
  892. panic(todo(""))
  893. }
  894. // FTS *fts_open(char * const *path_argv, int options, int (*compar)(const FTSENT **, const FTSENT **));
  895. func Xfts64_open(t *TLS, path_argv uintptr, options int32, compar uintptr) uintptr {
  896. panic(todo(""))
  897. }
  898. // FTSENT *fts_read(FTS *ftsp);
  899. func Xfts_read(t *TLS, ftsp uintptr) uintptr {
  900. panic(todo(""))
  901. }
  902. // FILE *popen(const char *command, const char *type);
  903. func Xpopen(t *TLS, command, type1 uintptr) uintptr {
  904. panic(todo(""))
  905. }
  906. // int sysctlbyname(const char *name, void *oldp, size_t *oldlenp, void *newp, size_t newlen);
  907. func Xsysctlbyname(t *TLS, name, oldp, oldlenp, newp uintptr, newlen Tsize_t) int32 {
  908. oldlen := *(*Tsize_t)(unsafe.Pointer(oldlenp))
  909. switch GoString(name) {
  910. case "hw.ncpu":
  911. if oldlen != 4 {
  912. panic(todo(""))
  913. }
  914. *(*int32)(unsafe.Pointer(oldp)) = int32(runtime.GOMAXPROCS(-1))
  915. return 0
  916. default:
  917. panic(todo(""))
  918. t.setErrno(ENOENT)
  919. return -1
  920. }
  921. }
  922. // void uuid_copy(uuid_t dst, uuid_t src);
  923. func Xuuid_copy(t *TLS, dst, src uintptr) {
  924. if __ccgo_strace {
  925. trc("t=%v src=%v, (%v:)", t, src, origin(2))
  926. }
  927. *(*uuid.Uuid_t)(unsafe.Pointer(dst)) = *(*uuid.Uuid_t)(unsafe.Pointer(src))
  928. }
  929. // int uuid_parse( char *in, uuid_t uu);
  930. func Xuuid_parse(t *TLS, in uintptr, uu uintptr) int32 {
  931. if __ccgo_strace {
  932. trc("t=%v in=%v uu=%v, (%v:)", t, in, uu, origin(2))
  933. }
  934. r, err := guuid.Parse(GoString(in))
  935. if err != nil {
  936. return -1
  937. }
  938. copy((*RawMem)(unsafe.Pointer(uu))[:unsafe.Sizeof(uuid.Uuid_t{})], r[:])
  939. return 0
  940. }
  941. // void uuid_generate_random(uuid_t out);
  942. func Xuuid_generate_random(t *TLS, out uintptr) {
  943. if __ccgo_strace {
  944. trc("t=%v out=%v, (%v:)", t, out, origin(2))
  945. }
  946. x := guuid.New()
  947. copy((*RawMem)(unsafe.Pointer(out))[:], x[:])
  948. }
  949. // void uuid_unparse(uuid_t uu, char *out);
  950. func Xuuid_unparse(t *TLS, uu, out uintptr) {
  951. if __ccgo_strace {
  952. trc("t=%v out=%v, (%v:)", t, out, origin(2))
  953. }
  954. s := (*guuid.UUID)(unsafe.Pointer(uu)).String()
  955. copy((*RawMem)(unsafe.Pointer(out))[:], s)
  956. *(*byte)(unsafe.Pointer(out + uintptr(len(s)))) = 0
  957. }
  958. var Xzero_struct_address Taddress