mirror of
https://github.com/kubenetworks/kubevpn.git
synced 2025-10-07 16:20:56 +08:00
feat: upgrade client-go version to v0.29.0 (#109)
* feat: upgrade client-go version to v0.29.0 * feat: upgrade coredns version * chore: update README.md
This commit is contained in:
1
vendor/github.com/ebitengine/purego/.gitignore
generated
vendored
Normal file
1
vendor/github.com/ebitengine/purego/.gitignore
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*~
|
201
vendor/github.com/ebitengine/purego/LICENSE
generated
vendored
Normal file
201
vendor/github.com/ebitengine/purego/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
74
vendor/github.com/ebitengine/purego/README.md
generated
vendored
Normal file
74
vendor/github.com/ebitengine/purego/README.md
generated
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
# purego
|
||||
[](https://pkg.go.dev/github.com/ebitengine/purego?GOOS=darwin)
|
||||
|
||||
A library for calling C functions from Go without Cgo.
|
||||
|
||||
## Motivation
|
||||
|
||||
The [Ebitengine](https://github.com/hajimehoshi/ebiten) game engine was ported to use only Go on Windows. This enabled
|
||||
cross-compiling to Windows from any other operating system simply by setting `GOOS=windows`. The purego project was
|
||||
born to bring that same vision to the other platforms supported by Ebitengine.
|
||||
|
||||
## Benefits
|
||||
|
||||
- **Simple Cross-Compilation**: No C means you can build for other platforms easily without a C compiler.
|
||||
- **Faster Compilation**: Efficiently cache your entirely Go builds.
|
||||
- **Smaller Binaries**: Using Cgo generates a C wrapper function for each C function called. Purego doesn't!
|
||||
- **Dynamic Linking**: Load symbols at runtime and use it as a plugin system.
|
||||
- **Foreign Function Interface**: Call into other languages that are compiled into shared objects.
|
||||
|
||||
## Example
|
||||
|
||||
This example only works on macOS and Linux. For a complete example look at [libc](https://github.com/ebitengine/purego/tree/main/examples/libc) which supports Windows and FreeBSD.
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
|
||||
"github.com/ebitengine/purego"
|
||||
)
|
||||
|
||||
func getSystemLibrary() string {
|
||||
switch runtime.GOOS {
|
||||
case "darwin":
|
||||
return "/usr/lib/libSystem.B.dylib"
|
||||
case "linux":
|
||||
return "libc.so.6"
|
||||
default:
|
||||
panic(fmt.Errorf("GOOS=%s is not supported", runtime.GOOS))
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
libc, err := purego.Dlopen(getSystemLibrary(), purego.RTLD_NOW|purego.RTLD_GLOBAL)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
var puts func(string)
|
||||
purego.RegisterLibFunc(&puts, libc, "puts")
|
||||
puts("Calling C from Go without Cgo!")
|
||||
}
|
||||
```
|
||||
|
||||
Then to run: `CGO_ENABLED=0 go run main.go`
|
||||
|
||||
### External Code
|
||||
|
||||
Purego uses code that originates from the Go runtime. These files are under the BSD-3
|
||||
License that can be found [in the Go Source](https://github.com/golang/go/blob/master/LICENSE).
|
||||
This is a list of the copied files:
|
||||
|
||||
* `abi_*.h` from package `runtime/cgo`
|
||||
* `zcallback_darwin_*.s` from package `runtime`
|
||||
* `internal/fakecgo/abi_*.h` from package `runtime/cgo`
|
||||
* `internal/fakecgo/asm_GOARCH.s` from package `runtime/cgo`
|
||||
* `internal/fakecgo/callbacks.go` from package `runtime/cgo`
|
||||
* `internal/fakecgo/go_GOOS_GOARCH.go` from package `runtime/cgo`
|
||||
* `internal/fakecgo/iscgo.go` from package `runtime/cgo`
|
||||
* `internal/fakecgo/setenv.go` from package `runtime/cgo`
|
||||
* `internal/fakecgo/freebsd.go` from package `runtime/cgo`
|
||||
|
||||
The files `abi_*.h` and `internal/fakecgo/abi_*.h` are the same because Bazel does not support cross-package use of `#include` so we need each one once per package. (cf. [issue](https://github.com/bazelbuild/rules_go/issues/3636))
|
99
vendor/github.com/ebitengine/purego/abi_amd64.h
generated
vendored
Normal file
99
vendor/github.com/ebitengine/purego/abi_amd64.h
generated
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Macros for transitioning from the host ABI to Go ABI0.
|
||||
//
|
||||
// These save the frame pointer, so in general, functions that use
|
||||
// these should have zero frame size to suppress the automatic frame
|
||||
// pointer, though it's harmless to not do this.
|
||||
|
||||
#ifdef GOOS_windows
|
||||
|
||||
// REGS_HOST_TO_ABI0_STACK is the stack bytes used by
|
||||
// PUSH_REGS_HOST_TO_ABI0.
|
||||
#define REGS_HOST_TO_ABI0_STACK (28*8 + 8)
|
||||
|
||||
// PUSH_REGS_HOST_TO_ABI0 prepares for transitioning from
|
||||
// the host ABI to Go ABI0 code. It saves all registers that are
|
||||
// callee-save in the host ABI and caller-save in Go ABI0 and prepares
|
||||
// for entry to Go.
|
||||
//
|
||||
// Save DI SI BP BX R12 R13 R14 R15 X6-X15 registers and the DF flag.
|
||||
// Clear the DF flag for the Go ABI.
|
||||
// MXCSR matches the Go ABI, so we don't have to set that,
|
||||
// and Go doesn't modify it, so we don't have to save it.
|
||||
#define PUSH_REGS_HOST_TO_ABI0() \
|
||||
PUSHFQ \
|
||||
CLD \
|
||||
ADJSP $(REGS_HOST_TO_ABI0_STACK - 8) \
|
||||
MOVQ DI, (0*0)(SP) \
|
||||
MOVQ SI, (1*8)(SP) \
|
||||
MOVQ BP, (2*8)(SP) \
|
||||
MOVQ BX, (3*8)(SP) \
|
||||
MOVQ R12, (4*8)(SP) \
|
||||
MOVQ R13, (5*8)(SP) \
|
||||
MOVQ R14, (6*8)(SP) \
|
||||
MOVQ R15, (7*8)(SP) \
|
||||
MOVUPS X6, (8*8)(SP) \
|
||||
MOVUPS X7, (10*8)(SP) \
|
||||
MOVUPS X8, (12*8)(SP) \
|
||||
MOVUPS X9, (14*8)(SP) \
|
||||
MOVUPS X10, (16*8)(SP) \
|
||||
MOVUPS X11, (18*8)(SP) \
|
||||
MOVUPS X12, (20*8)(SP) \
|
||||
MOVUPS X13, (22*8)(SP) \
|
||||
MOVUPS X14, (24*8)(SP) \
|
||||
MOVUPS X15, (26*8)(SP)
|
||||
|
||||
#define POP_REGS_HOST_TO_ABI0() \
|
||||
MOVQ (0*0)(SP), DI \
|
||||
MOVQ (1*8)(SP), SI \
|
||||
MOVQ (2*8)(SP), BP \
|
||||
MOVQ (3*8)(SP), BX \
|
||||
MOVQ (4*8)(SP), R12 \
|
||||
MOVQ (5*8)(SP), R13 \
|
||||
MOVQ (6*8)(SP), R14 \
|
||||
MOVQ (7*8)(SP), R15 \
|
||||
MOVUPS (8*8)(SP), X6 \
|
||||
MOVUPS (10*8)(SP), X7 \
|
||||
MOVUPS (12*8)(SP), X8 \
|
||||
MOVUPS (14*8)(SP), X9 \
|
||||
MOVUPS (16*8)(SP), X10 \
|
||||
MOVUPS (18*8)(SP), X11 \
|
||||
MOVUPS (20*8)(SP), X12 \
|
||||
MOVUPS (22*8)(SP), X13 \
|
||||
MOVUPS (24*8)(SP), X14 \
|
||||
MOVUPS (26*8)(SP), X15 \
|
||||
ADJSP $-(REGS_HOST_TO_ABI0_STACK - 8) \
|
||||
POPFQ
|
||||
|
||||
#else
|
||||
// SysV ABI
|
||||
|
||||
#define REGS_HOST_TO_ABI0_STACK (6*8)
|
||||
|
||||
// SysV MXCSR matches the Go ABI, so we don't have to set that,
|
||||
// and Go doesn't modify it, so we don't have to save it.
|
||||
// Both SysV and Go require DF to be cleared, so that's already clear.
|
||||
// The SysV and Go frame pointer conventions are compatible.
|
||||
#define PUSH_REGS_HOST_TO_ABI0() \
|
||||
ADJSP $(REGS_HOST_TO_ABI0_STACK) \
|
||||
MOVQ BP, (5*8)(SP) \
|
||||
LEAQ (5*8)(SP), BP \
|
||||
MOVQ BX, (0*8)(SP) \
|
||||
MOVQ R12, (1*8)(SP) \
|
||||
MOVQ R13, (2*8)(SP) \
|
||||
MOVQ R14, (3*8)(SP) \
|
||||
MOVQ R15, (4*8)(SP)
|
||||
|
||||
#define POP_REGS_HOST_TO_ABI0() \
|
||||
MOVQ (0*8)(SP), BX \
|
||||
MOVQ (1*8)(SP), R12 \
|
||||
MOVQ (2*8)(SP), R13 \
|
||||
MOVQ (3*8)(SP), R14 \
|
||||
MOVQ (4*8)(SP), R15 \
|
||||
MOVQ (5*8)(SP), BP \
|
||||
ADJSP $-(REGS_HOST_TO_ABI0_STACK)
|
||||
|
||||
#endif
|
39
vendor/github.com/ebitengine/purego/abi_arm64.h
generated
vendored
Normal file
39
vendor/github.com/ebitengine/purego/abi_arm64.h
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Macros for transitioning from the host ABI to Go ABI0.
|
||||
//
|
||||
// These macros save and restore the callee-saved registers
|
||||
// from the stack, but they don't adjust stack pointer, so
|
||||
// the user should prepare stack space in advance.
|
||||
// SAVE_R19_TO_R28(offset) saves R19 ~ R28 to the stack space
|
||||
// of ((offset)+0*8)(RSP) ~ ((offset)+9*8)(RSP).
|
||||
//
|
||||
// SAVE_F8_TO_F15(offset) saves F8 ~ F15 to the stack space
|
||||
// of ((offset)+0*8)(RSP) ~ ((offset)+7*8)(RSP).
|
||||
//
|
||||
// R29 is not saved because Go will save and restore it.
|
||||
|
||||
#define SAVE_R19_TO_R28(offset) \
|
||||
STP (R19, R20), ((offset)+0*8)(RSP) \
|
||||
STP (R21, R22), ((offset)+2*8)(RSP) \
|
||||
STP (R23, R24), ((offset)+4*8)(RSP) \
|
||||
STP (R25, R26), ((offset)+6*8)(RSP) \
|
||||
STP (R27, g), ((offset)+8*8)(RSP)
|
||||
#define RESTORE_R19_TO_R28(offset) \
|
||||
LDP ((offset)+0*8)(RSP), (R19, R20) \
|
||||
LDP ((offset)+2*8)(RSP), (R21, R22) \
|
||||
LDP ((offset)+4*8)(RSP), (R23, R24) \
|
||||
LDP ((offset)+6*8)(RSP), (R25, R26) \
|
||||
LDP ((offset)+8*8)(RSP), (R27, g) /* R28 */
|
||||
#define SAVE_F8_TO_F15(offset) \
|
||||
FSTPD (F8, F9), ((offset)+0*8)(RSP) \
|
||||
FSTPD (F10, F11), ((offset)+2*8)(RSP) \
|
||||
FSTPD (F12, F13), ((offset)+4*8)(RSP) \
|
||||
FSTPD (F14, F15), ((offset)+6*8)(RSP)
|
||||
#define RESTORE_F8_TO_F15(offset) \
|
||||
FLDPD ((offset)+0*8)(RSP), (F8, F9) \
|
||||
FLDPD ((offset)+2*8)(RSP), (F10, F11) \
|
||||
FLDPD ((offset)+4*8)(RSP), (F12, F13) \
|
||||
FLDPD ((offset)+6*8)(RSP), (F14, F15)
|
15
vendor/github.com/ebitengine/purego/cgo.go
generated
vendored
Normal file
15
vendor/github.com/ebitengine/purego/cgo.go
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build cgo && (darwin || freebsd || linux)
|
||||
|
||||
package purego
|
||||
|
||||
// if CGO_ENABLED=1 import the Cgo runtime to ensure that it is set up properly.
|
||||
// This is required since some frameworks need TLS setup the C way which Go doesn't do.
|
||||
// We currently don't support ios in fakecgo mode so force Cgo or fail
|
||||
// Even if CGO_ENABLED=1 the Cgo runtime is not imported unless `import "C"` is used.
|
||||
// which will import this package automatically. Normally this isn't an issue since it
|
||||
// usually isn't possible to call into C without using that import. However, with purego
|
||||
// it is since we don't use `import "C"`!
|
||||
import _ "runtime/cgo"
|
15
vendor/github.com/ebitengine/purego/dlerror.go
generated
vendored
Normal file
15
vendor/github.com/ebitengine/purego/dlerror.go
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2023 The Ebitengine Authors
|
||||
|
||||
//go:build darwin || freebsd || linux
|
||||
|
||||
package purego
|
||||
|
||||
// Dlerror represents an error value returned from Dlopen, Dlsym, or Dlclose.
|
||||
type Dlerror struct {
|
||||
s string
|
||||
}
|
||||
|
||||
func (e Dlerror) Error() string {
|
||||
return e.s
|
||||
}
|
94
vendor/github.com/ebitengine/purego/dlfcn.go
generated
vendored
Normal file
94
vendor/github.com/ebitengine/purego/dlfcn.go
generated
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build darwin || freebsd || linux
|
||||
|
||||
package purego
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Unix Specification for dlfcn.h: https://pubs.opengroup.org/onlinepubs/7908799/xsh/dlfcn.h.html
|
||||
|
||||
var (
|
||||
fnDlopen func(path string, mode int) uintptr
|
||||
fnDlsym func(handle uintptr, name string) uintptr
|
||||
fnDlerror func() string
|
||||
fnDlclose func(handle uintptr) bool
|
||||
)
|
||||
|
||||
func init() {
|
||||
RegisterFunc(&fnDlopen, dlopenABI0)
|
||||
RegisterFunc(&fnDlsym, dlsymABI0)
|
||||
RegisterFunc(&fnDlerror, dlerrorABI0)
|
||||
RegisterFunc(&fnDlclose, dlcloseABI0)
|
||||
}
|
||||
|
||||
// Dlopen examines the dynamic library or bundle file specified by path. If the file is compatible
|
||||
// with the current process and has not already been loaded into the
|
||||
// current process, it is loaded and linked. After being linked, if it contains
|
||||
// any initializer functions, they are called, before Dlopen
|
||||
// returns. It returns a handle that can be used with Dlsym and Dlclose.
|
||||
// A second call to Dlopen with the same path will return the same handle, but the internal
|
||||
// reference count for the handle will be incremented. Therefore, all
|
||||
// Dlopen calls should be balanced with a Dlclose call.
|
||||
func Dlopen(path string, mode int) (uintptr, error) {
|
||||
u := fnDlopen(path, mode)
|
||||
if u == 0 {
|
||||
return 0, Dlerror{fnDlerror()}
|
||||
}
|
||||
return u, nil
|
||||
}
|
||||
|
||||
// Dlsym takes a "handle" of a dynamic library returned by Dlopen and the symbol name.
|
||||
// It returns the address where that symbol is loaded into memory. If the symbol is not found,
|
||||
// in the specified library or any of the libraries that were automatically loaded by Dlopen
|
||||
// when that library was loaded, Dlsym returns zero.
|
||||
func Dlsym(handle uintptr, name string) (uintptr, error) {
|
||||
u := fnDlsym(handle, name)
|
||||
if u == 0 {
|
||||
return 0, Dlerror{fnDlerror()}
|
||||
}
|
||||
return u, nil
|
||||
}
|
||||
|
||||
// Dlclose decrements the reference count on the dynamic library handle.
|
||||
// If the reference count drops to zero and no other loaded libraries
|
||||
// use symbols in it, then the dynamic library is unloaded.
|
||||
func Dlclose(handle uintptr) error {
|
||||
if fnDlclose(handle) {
|
||||
return Dlerror{fnDlerror()}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//go:linkname openLibrary openLibrary
|
||||
func openLibrary(name string) (uintptr, error) {
|
||||
return Dlopen(name, RTLD_NOW|RTLD_GLOBAL)
|
||||
}
|
||||
|
||||
func loadSymbol(handle uintptr, name string) (uintptr, error) {
|
||||
return Dlsym(handle, name)
|
||||
}
|
||||
|
||||
// these functions exist in dlfcn_stubs.s and are calling C functions linked to in dlfcn_GOOS.go
|
||||
// the indirection is necessary because a function is actually a pointer to the pointer to the code.
|
||||
// sadly, I do not know of anyway to remove the assembly stubs entirely because //go:linkname doesn't
|
||||
// appear to work if you link directly to the C function on darwin arm64.
|
||||
|
||||
//go:linkname dlopen dlopen
|
||||
var dlopen uintptr
|
||||
var dlopenABI0 = uintptr(unsafe.Pointer(&dlopen))
|
||||
|
||||
//go:linkname dlsym dlsym
|
||||
var dlsym uintptr
|
||||
var dlsymABI0 = uintptr(unsafe.Pointer(&dlsym))
|
||||
|
||||
//go:linkname dlclose dlclose
|
||||
var dlclose uintptr
|
||||
var dlcloseABI0 = uintptr(unsafe.Pointer(&dlclose))
|
||||
|
||||
//go:linkname dlerror dlerror
|
||||
var dlerror uintptr
|
||||
var dlerrorABI0 = uintptr(unsafe.Pointer(&dlerror))
|
19
vendor/github.com/ebitengine/purego/dlfcn_darwin.go
generated
vendored
Normal file
19
vendor/github.com/ebitengine/purego/dlfcn_darwin.go
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
package purego
|
||||
|
||||
// Source for constants: https://opensource.apple.com/source/dyld/dyld-360.14/include/dlfcn.h.auto.html
|
||||
|
||||
const (
|
||||
RTLD_DEFAULT = ^uintptr(0) - 1 // Pseudo-handle for dlsym so search for any loaded symbol
|
||||
RTLD_LAZY = 0x1 // Relocations are performed at an implementation-dependent time.
|
||||
RTLD_NOW = 0x2 // Relocations are performed when the object is loaded.
|
||||
RTLD_LOCAL = 0x4 // All symbols are not made available for relocation processing by other modules.
|
||||
RTLD_GLOBAL = 0x8 // All symbols are available for relocation processing of other modules.
|
||||
)
|
||||
|
||||
//go:cgo_import_dynamic purego_dlopen dlopen "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_dlsym dlsym "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_dlerror dlerror "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_dlclose dlclose "/usr/lib/libSystem.B.dylib"
|
18
vendor/github.com/ebitengine/purego/dlfcn_freebsd.go
generated
vendored
Normal file
18
vendor/github.com/ebitengine/purego/dlfcn_freebsd.go
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
package purego
|
||||
|
||||
// Constants as defined in https://github.com/freebsd/freebsd-src/blob/main/include/dlfcn.h
|
||||
const (
|
||||
RTLD_DEFAULT = ^uintptr(0) - 2 // Pseudo-handle for dlsym so search for any loaded symbol
|
||||
RTLD_LAZY = 0x00001 // Relocations are performed at an implementation-dependent time.
|
||||
RTLD_NOW = 0x00002 // Relocations are performed when the object is loaded.
|
||||
RTLD_LOCAL = 0x00000 // All symbols are not made available for relocation processing by other modules.
|
||||
RTLD_GLOBAL = 0x00100 // All symbols are available for relocation processing of other modules.
|
||||
)
|
||||
|
||||
//go:cgo_import_dynamic purego_dlopen dlopen "libc.so.7"
|
||||
//go:cgo_import_dynamic purego_dlsym dlsym "libc.so.7"
|
||||
//go:cgo_import_dynamic purego_dlerror dlerror "libc.so.7"
|
||||
//go:cgo_import_dynamic purego_dlclose dlclose "libc.so.7"
|
14
vendor/github.com/ebitengine/purego/dlfcn_linux.go
generated
vendored
Normal file
14
vendor/github.com/ebitengine/purego/dlfcn_linux.go
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
package purego
|
||||
|
||||
// Source for constants: https://codebrowser.dev/glibc/glibc/bits/dlfcn.h.html
|
||||
|
||||
const (
|
||||
RTLD_DEFAULT = 0x00000 // Pseudo-handle for dlsym so search for any loaded symbol
|
||||
RTLD_LAZY = 0x00001 // Relocations are performed at an implementation-dependent time.
|
||||
RTLD_NOW = 0x00002 // Relocations are performed when the object is loaded.
|
||||
RTLD_LOCAL = 0x00000 // All symbols are not made available for relocation processing by other modules.
|
||||
RTLD_GLOBAL = 0x00100 // All symbols are available for relocation processing of other modules.
|
||||
)
|
19
vendor/github.com/ebitengine/purego/dlfcn_nocgo_linux.go
generated
vendored
Normal file
19
vendor/github.com/ebitengine/purego/dlfcn_nocgo_linux.go
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo
|
||||
|
||||
package purego
|
||||
|
||||
// if there is no Cgo we must link to each of the functions from dlfcn.h
|
||||
// then the functions are called inside dlfcn_stubs.s
|
||||
|
||||
//go:cgo_import_dynamic purego_dlopen dlopen "libdl.so.2"
|
||||
//go:cgo_import_dynamic purego_dlsym dlsym "libdl.so.2"
|
||||
//go:cgo_import_dynamic purego_dlerror dlerror "libdl.so.2"
|
||||
//go:cgo_import_dynamic purego_dlclose dlclose "libdl.so.2"
|
||||
|
||||
// on amd64 we don't need the following line - on 386 we do...
|
||||
// anyway - with those lines the output is better (but doesn't matter) - without it on amd64 we get multiple DT_NEEDED with "libc.so.6" etc
|
||||
|
||||
//go:cgo_import_dynamic _ _ "libdl.so.2"
|
26
vendor/github.com/ebitengine/purego/dlfcn_stubs.s
generated
vendored
Normal file
26
vendor/github.com/ebitengine/purego/dlfcn_stubs.s
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build darwin || freebsd || (linux && !cgo)
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// func dlopen(path *byte, mode int) (ret uintptr)
|
||||
TEXT dlopen(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_dlopen(SB)
|
||||
RET
|
||||
|
||||
// func dlsym(handle uintptr, symbol *byte) (ret uintptr)
|
||||
TEXT dlsym(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_dlsym(SB)
|
||||
RET
|
||||
|
||||
// func dlerror() (ret *byte)
|
||||
TEXT dlerror(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_dlerror(SB)
|
||||
RET
|
||||
|
||||
// func dlclose(handle uintptr) (ret int)
|
||||
TEXT dlclose(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_dlclose(SB)
|
||||
RET
|
309
vendor/github.com/ebitengine/purego/func.go
generated
vendored
Normal file
309
vendor/github.com/ebitengine/purego/func.go
generated
vendored
Normal file
@@ -0,0 +1,309 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build darwin || freebsd || linux || windows
|
||||
|
||||
package purego
|
||||
|
||||
import (
|
||||
"math"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"unsafe"
|
||||
|
||||
"github.com/ebitengine/purego/internal/strings"
|
||||
)
|
||||
|
||||
// RegisterLibFunc is a wrapper around RegisterFunc that uses the C function returned from Dlsym(handle, name).
|
||||
// It panics if it can't find the name symbol.
|
||||
func RegisterLibFunc(fptr interface{}, handle uintptr, name string) {
|
||||
sym, err := loadSymbol(handle, name)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
RegisterFunc(fptr, sym)
|
||||
}
|
||||
|
||||
// RegisterFunc takes a pointer to a Go function representing the calling convention of the C function.
|
||||
// fptr will be set to a function that when called will call the C function given by cfn with the
|
||||
// parameters passed in the correct registers and stack.
|
||||
//
|
||||
// A panic is produced if the type is not a function pointer or if the function returns more than 1 value.
|
||||
//
|
||||
// These conversions describe how a Go type in the fptr will be used to call
|
||||
// the C function. It is important to note that there is no way to verify that fptr
|
||||
// matches the C function. This also holds true for struct types where the padding
|
||||
// needs to be ensured to match that of C; RegisterFunc does not verify this.
|
||||
//
|
||||
// # Type Conversions (Go <=> C)
|
||||
//
|
||||
// string <=> char*
|
||||
// bool <=> _Bool
|
||||
// uintptr <=> uintptr_t
|
||||
// uint <=> uint32_t or uint64_t
|
||||
// uint8 <=> uint8_t
|
||||
// uint16 <=> uint16_t
|
||||
// uint32 <=> uint32_t
|
||||
// uint64 <=> uint64_t
|
||||
// int <=> int32_t or int64_t
|
||||
// int8 <=> int8_t
|
||||
// int16 <=> int16_t
|
||||
// int32 <=> int32_t
|
||||
// int64 <=> int64_t
|
||||
// float32 <=> float (WIP)
|
||||
// float64 <=> double (WIP)
|
||||
// struct <=> struct (WIP)
|
||||
// func <=> C function
|
||||
// unsafe.Pointer, *T <=> void*
|
||||
// []T => void*
|
||||
//
|
||||
// There is a special case when the last argument of fptr is a variadic interface (or []interface}
|
||||
// it will be expanded into a call to the C function as if it had the arguments in that slice.
|
||||
// This means that using arg ...interface{} is like a cast to the function with the arguments inside arg.
|
||||
// This is not the same as C variadic.
|
||||
//
|
||||
// There are some limitations when using RegisterFunc on Linux. First, there is no support for function arguments.
|
||||
// Second, float32 and float64 arguments and return values do not work when CGO_ENABLED=1. Otherwise, Linux
|
||||
// has the same feature parity as Darwin.
|
||||
//
|
||||
// # Memory
|
||||
//
|
||||
// In general it is not possible for purego to guarantee the lifetimes of objects returned or received from
|
||||
// calling functions using RegisterFunc. For arguments to a C function it is important that the C function doesn't
|
||||
// hold onto a reference to Go memory. This is the same as the [Cgo rules].
|
||||
//
|
||||
// However, there are some special cases. When passing a string as an argument if the string does not end in a null
|
||||
// terminated byte (\x00) then the string will be copied into memory maintained by purego. The memory is only valid for
|
||||
// that specific call. Therefore, if the C code keeps a reference to that string it may become invalid at some
|
||||
// undefined time. However, if the string does already contain a null-terminated byte then no copy is done.
|
||||
// It is then the responsibility of the caller to ensure the string stays alive as long as it's needed in C memory.
|
||||
// This can be done using runtime.KeepAlive or allocating the string in C memory using malloc. When a C function
|
||||
// returns a null-terminated pointer to char a Go string can be used. Purego will allocate a new string in Go memory
|
||||
// and copy the data over. This string will be garbage collected whenever Go decides it's no longer referenced.
|
||||
// This C created string will not be freed by purego. If the pointer to char is not null-terminated or must continue
|
||||
// to point to C memory (because it's a buffer for example) then use a pointer to byte and then convert that to a slice
|
||||
// using unsafe.Slice. Doing this means that it becomes the responsibility of the caller to care about the lifetime
|
||||
// of the pointer
|
||||
//
|
||||
// # Example
|
||||
//
|
||||
// All functions below call this C function:
|
||||
//
|
||||
// char *foo(char *str);
|
||||
//
|
||||
// // Let purego convert types
|
||||
// var foo func(s string) string
|
||||
// goString := foo("copied")
|
||||
// // Go will garbage collect this string
|
||||
//
|
||||
// // Manually, handle allocations
|
||||
// var foo2 func(b string) *byte
|
||||
// mustFree := foo2("not copied\x00")
|
||||
// defer free(mustFree)
|
||||
//
|
||||
// [Cgo rules]: https://pkg.go.dev/cmd/cgo#hdr-Go_references_to_C
|
||||
func RegisterFunc(fptr interface{}, cfn uintptr) {
|
||||
fn := reflect.ValueOf(fptr).Elem()
|
||||
ty := fn.Type()
|
||||
if ty.Kind() != reflect.Func {
|
||||
panic("purego: fptr must be a function pointer")
|
||||
}
|
||||
if ty.NumOut() > 1 {
|
||||
panic("purego: function can only return zero or one values")
|
||||
}
|
||||
if cfn == 0 {
|
||||
panic("purego: cfn is nil")
|
||||
}
|
||||
{
|
||||
// this code checks how many registers and stack this function will use
|
||||
// to avoid crashing with too many arguments
|
||||
var ints int
|
||||
var floats int
|
||||
var stack int
|
||||
for i := 0; i < ty.NumIn(); i++ {
|
||||
arg := ty.In(i)
|
||||
switch arg.Kind() {
|
||||
case reflect.String, reflect.Uintptr, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
|
||||
reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Ptr, reflect.UnsafePointer, reflect.Slice,
|
||||
reflect.Func, reflect.Bool:
|
||||
if ints < numOfIntegerRegisters() {
|
||||
ints++
|
||||
} else {
|
||||
stack++
|
||||
}
|
||||
case reflect.Float32, reflect.Float64:
|
||||
if floats < numOfFloats {
|
||||
floats++
|
||||
} else {
|
||||
stack++
|
||||
}
|
||||
default:
|
||||
panic("purego: unsupported kind " + arg.Kind().String())
|
||||
}
|
||||
}
|
||||
sizeOfStack := maxArgs - numOfIntegerRegisters()
|
||||
if stack > sizeOfStack {
|
||||
panic("purego: too many arguments")
|
||||
}
|
||||
}
|
||||
v := reflect.MakeFunc(ty, func(args []reflect.Value) (results []reflect.Value) {
|
||||
if len(args) > 0 {
|
||||
if variadic, ok := args[len(args)-1].Interface().([]interface{}); ok {
|
||||
// subtract one from args bc the last argument in args is []interface{}
|
||||
// which we are currently expanding
|
||||
tmp := make([]reflect.Value, len(args)-1+len(variadic))
|
||||
n := copy(tmp, args[:len(args)-1])
|
||||
for i, v := range variadic {
|
||||
tmp[n+i] = reflect.ValueOf(v)
|
||||
}
|
||||
args = tmp
|
||||
}
|
||||
}
|
||||
var sysargs [maxArgs]uintptr
|
||||
stack := sysargs[numOfIntegerRegisters():]
|
||||
var floats [numOfFloats]uintptr
|
||||
var numInts int
|
||||
var numFloats int
|
||||
var numStack int
|
||||
var addStack, addInt, addFloat func(x uintptr)
|
||||
if runtime.GOARCH == "arm64" || runtime.GOOS != "windows" {
|
||||
// Windows arm64 uses the same calling convention as macOS and Linux
|
||||
addStack = func(x uintptr) {
|
||||
stack[numStack] = x
|
||||
numStack++
|
||||
}
|
||||
addInt = func(x uintptr) {
|
||||
if numInts >= numOfIntegerRegisters() {
|
||||
addStack(x)
|
||||
} else {
|
||||
sysargs[numInts] = x
|
||||
numInts++
|
||||
}
|
||||
}
|
||||
addFloat = func(x uintptr) {
|
||||
if numFloats < len(floats) {
|
||||
floats[numFloats] = x
|
||||
numFloats++
|
||||
} else {
|
||||
addStack(x)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// On Windows amd64 the arguments are passed in the numbered registered.
|
||||
// So the first int is in the first integer register and the first float
|
||||
// is in the second floating register if there is already a first int.
|
||||
// This is in contrast to how macOS and Linux pass arguments which
|
||||
// tries to use as many registers as possible in the calling convention.
|
||||
addStack = func(x uintptr) {
|
||||
sysargs[numStack] = x
|
||||
numStack++
|
||||
}
|
||||
addInt = addStack
|
||||
addFloat = addStack
|
||||
}
|
||||
|
||||
var keepAlive []interface{}
|
||||
defer func() {
|
||||
runtime.KeepAlive(keepAlive)
|
||||
runtime.KeepAlive(args)
|
||||
}()
|
||||
for _, v := range args {
|
||||
switch v.Kind() {
|
||||
case reflect.String:
|
||||
ptr := strings.CString(v.String())
|
||||
keepAlive = append(keepAlive, ptr)
|
||||
addInt(uintptr(unsafe.Pointer(ptr)))
|
||||
case reflect.Uintptr, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
addInt(uintptr(v.Uint()))
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
addInt(uintptr(v.Int()))
|
||||
case reflect.Ptr, reflect.UnsafePointer, reflect.Slice:
|
||||
// There is no need to keepAlive this pointer separately because it is kept alive in the args variable
|
||||
addInt(v.Pointer())
|
||||
case reflect.Func:
|
||||
addInt(NewCallback(v.Interface()))
|
||||
case reflect.Bool:
|
||||
if v.Bool() {
|
||||
addInt(1)
|
||||
} else {
|
||||
addInt(0)
|
||||
}
|
||||
case reflect.Float32:
|
||||
addFloat(uintptr(math.Float32bits(float32(v.Float()))))
|
||||
case reflect.Float64:
|
||||
addFloat(uintptr(math.Float64bits(v.Float())))
|
||||
default:
|
||||
panic("purego: unsupported kind: " + v.Kind().String())
|
||||
}
|
||||
}
|
||||
// TODO: support structs
|
||||
var r1, r2 uintptr
|
||||
if runtime.GOARCH == "arm64" || runtime.GOOS != "windows" {
|
||||
// Use the normal arm64 calling convention even on Windows
|
||||
syscall := syscall9Args{
|
||||
cfn,
|
||||
sysargs[0], sysargs[1], sysargs[2], sysargs[3], sysargs[4], sysargs[5], sysargs[6], sysargs[7], sysargs[8],
|
||||
floats[0], floats[1], floats[2], floats[3], floats[4], floats[5], floats[6], floats[7],
|
||||
0, 0, 0,
|
||||
}
|
||||
runtime_cgocall(syscall9XABI0, unsafe.Pointer(&syscall))
|
||||
r1, r2 = syscall.r1, syscall.r2
|
||||
} else {
|
||||
// This is a fallback for amd64, 386, and arm. Note this may not support floats
|
||||
r1, r2, _ = syscall_syscall9X(cfn, sysargs[0], sysargs[1], sysargs[2], sysargs[3], sysargs[4], sysargs[5], sysargs[6], sysargs[7], sysargs[8])
|
||||
}
|
||||
if ty.NumOut() == 0 {
|
||||
return nil
|
||||
}
|
||||
outType := ty.Out(0)
|
||||
v := reflect.New(outType).Elem()
|
||||
switch outType.Kind() {
|
||||
case reflect.Uintptr, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
v.SetUint(uint64(r1))
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
v.SetInt(int64(r1))
|
||||
case reflect.Bool:
|
||||
v.SetBool(byte(r1) != 0)
|
||||
case reflect.UnsafePointer:
|
||||
// We take the address and then dereference it to trick go vet from creating a possible miss-use of unsafe.Pointer
|
||||
v.SetPointer(*(*unsafe.Pointer)(unsafe.Pointer(&r1)))
|
||||
case reflect.Ptr:
|
||||
// It is safe to have the address of r1 not escape because it is immediately dereferenced with .Elem()
|
||||
v = reflect.NewAt(outType, runtime_noescape(unsafe.Pointer(&r1))).Elem()
|
||||
case reflect.Func:
|
||||
// wrap this C function in a nicely typed Go function
|
||||
v = reflect.New(outType)
|
||||
RegisterFunc(v.Interface(), r1)
|
||||
case reflect.String:
|
||||
v.SetString(strings.GoString(r1))
|
||||
case reflect.Float32:
|
||||
// NOTE: r2 is only the floating return value on 64bit platforms.
|
||||
// On 32bit platforms r2 is the upper part of a 64bit return.
|
||||
v.SetFloat(float64(math.Float32frombits(uint32(r2))))
|
||||
case reflect.Float64:
|
||||
// NOTE: r2 is only the floating return value on 64bit platforms.
|
||||
// On 32bit platforms r2 is the upper part of a 64bit return.
|
||||
v.SetFloat(math.Float64frombits(uint64(r2)))
|
||||
default:
|
||||
panic("purego: unsupported return kind: " + outType.Kind().String())
|
||||
}
|
||||
return []reflect.Value{v}
|
||||
})
|
||||
fn.Set(v)
|
||||
}
|
||||
|
||||
func numOfIntegerRegisters() int {
|
||||
switch runtime.GOARCH {
|
||||
case "arm64":
|
||||
return 8
|
||||
case "amd64":
|
||||
return 6
|
||||
// TODO: figure out why 386 tests are not working
|
||||
/*case "386":
|
||||
return 0
|
||||
case "arm":
|
||||
return 4*/
|
||||
default:
|
||||
panic("purego: unknown GOARCH (" + runtime.GOARCH + ")")
|
||||
}
|
||||
}
|
17
vendor/github.com/ebitengine/purego/go_runtime.go
generated
vendored
Normal file
17
vendor/github.com/ebitengine/purego/go_runtime.go
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build darwin || freebsd || linux || windows
|
||||
|
||||
package purego
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
//go:linkname runtime_cgocall runtime.cgocall
|
||||
func runtime_cgocall(fn uintptr, arg unsafe.Pointer) int32 // from runtime/sys_libc.go
|
||||
|
||||
//go:linkname runtime_noescape runtime.noescape
|
||||
//go:noescape
|
||||
func runtime_noescape(p unsafe.Pointer) unsafe.Pointer // from runtime/stubs.go
|
58
vendor/github.com/ebitengine/purego/internal/cgo/syscall_cgo_unix.go
generated
vendored
Normal file
58
vendor/github.com/ebitengine/purego/internal/cgo/syscall_cgo_unix.go
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build freebsd || linux
|
||||
|
||||
package cgo
|
||||
|
||||
// this file is placed inside internal/cgo and not package purego
|
||||
// because Cgo and assembly files can't be in the same package.
|
||||
|
||||
/*
|
||||
#cgo LDFLAGS: -ldl
|
||||
|
||||
#include <stdint.h>
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
typedef struct syscall9Args {
|
||||
uintptr_t fn;
|
||||
uintptr_t a1, a2, a3, a4, a5, a6, a7, a8, a9;
|
||||
uintptr_t f1, f2, f3, f4, f5, f6, f7, f8;
|
||||
uintptr_t r1, r2, err;
|
||||
} syscall9Args;
|
||||
|
||||
void syscall9(struct syscall9Args *args) {
|
||||
assert((args->f1|args->f2|args->f3|args->f4|args->f5|args->f6|args->f7|args->f8) == 0);
|
||||
uintptr_t (*func_name)(uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6, uintptr_t a7, uintptr_t a8, uintptr_t a9);
|
||||
*(void**)(&func_name) = (void*)(args->fn);
|
||||
uintptr_t r1 = func_name(args->a1,args->a2,args->a3,args->a4,args->a5,args->a6,args->a7,args->a8,args->a9);
|
||||
args->r1 = r1;
|
||||
args->err = errno;
|
||||
}
|
||||
|
||||
*/
|
||||
import "C"
|
||||
import "unsafe"
|
||||
|
||||
// assign purego.syscall9XABI0 to the C version of this function.
|
||||
var Syscall9XABI0 = unsafe.Pointer(C.syscall9)
|
||||
|
||||
// all that is needed is to assign each dl function because then its
|
||||
// symbol will then be made available to the linker and linked to inside dlfcn.go
|
||||
var (
|
||||
_ = C.dlopen
|
||||
_ = C.dlsym
|
||||
_ = C.dlerror
|
||||
_ = C.dlclose
|
||||
)
|
||||
|
||||
//go:nosplit
|
||||
func Syscall9X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2, err uintptr) {
|
||||
args := C.syscall9Args{C.uintptr_t(fn), C.uintptr_t(a1), C.uintptr_t(a2), C.uintptr_t(a3),
|
||||
C.uintptr_t(a4), C.uintptr_t(a5), C.uintptr_t(a6),
|
||||
C.uintptr_t(a7), C.uintptr_t(a8), C.uintptr_t(a9), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
C.syscall9(&args)
|
||||
return uintptr(args.r1), uintptr(args.r2), uintptr(args.err)
|
||||
}
|
99
vendor/github.com/ebitengine/purego/internal/fakecgo/abi_amd64.h
generated
vendored
Normal file
99
vendor/github.com/ebitengine/purego/internal/fakecgo/abi_amd64.h
generated
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Macros for transitioning from the host ABI to Go ABI0.
|
||||
//
|
||||
// These save the frame pointer, so in general, functions that use
|
||||
// these should have zero frame size to suppress the automatic frame
|
||||
// pointer, though it's harmless to not do this.
|
||||
|
||||
#ifdef GOOS_windows
|
||||
|
||||
// REGS_HOST_TO_ABI0_STACK is the stack bytes used by
|
||||
// PUSH_REGS_HOST_TO_ABI0.
|
||||
#define REGS_HOST_TO_ABI0_STACK (28*8 + 8)
|
||||
|
||||
// PUSH_REGS_HOST_TO_ABI0 prepares for transitioning from
|
||||
// the host ABI to Go ABI0 code. It saves all registers that are
|
||||
// callee-save in the host ABI and caller-save in Go ABI0 and prepares
|
||||
// for entry to Go.
|
||||
//
|
||||
// Save DI SI BP BX R12 R13 R14 R15 X6-X15 registers and the DF flag.
|
||||
// Clear the DF flag for the Go ABI.
|
||||
// MXCSR matches the Go ABI, so we don't have to set that,
|
||||
// and Go doesn't modify it, so we don't have to save it.
|
||||
#define PUSH_REGS_HOST_TO_ABI0() \
|
||||
PUSHFQ \
|
||||
CLD \
|
||||
ADJSP $(REGS_HOST_TO_ABI0_STACK - 8) \
|
||||
MOVQ DI, (0*0)(SP) \
|
||||
MOVQ SI, (1*8)(SP) \
|
||||
MOVQ BP, (2*8)(SP) \
|
||||
MOVQ BX, (3*8)(SP) \
|
||||
MOVQ R12, (4*8)(SP) \
|
||||
MOVQ R13, (5*8)(SP) \
|
||||
MOVQ R14, (6*8)(SP) \
|
||||
MOVQ R15, (7*8)(SP) \
|
||||
MOVUPS X6, (8*8)(SP) \
|
||||
MOVUPS X7, (10*8)(SP) \
|
||||
MOVUPS X8, (12*8)(SP) \
|
||||
MOVUPS X9, (14*8)(SP) \
|
||||
MOVUPS X10, (16*8)(SP) \
|
||||
MOVUPS X11, (18*8)(SP) \
|
||||
MOVUPS X12, (20*8)(SP) \
|
||||
MOVUPS X13, (22*8)(SP) \
|
||||
MOVUPS X14, (24*8)(SP) \
|
||||
MOVUPS X15, (26*8)(SP)
|
||||
|
||||
#define POP_REGS_HOST_TO_ABI0() \
|
||||
MOVQ (0*0)(SP), DI \
|
||||
MOVQ (1*8)(SP), SI \
|
||||
MOVQ (2*8)(SP), BP \
|
||||
MOVQ (3*8)(SP), BX \
|
||||
MOVQ (4*8)(SP), R12 \
|
||||
MOVQ (5*8)(SP), R13 \
|
||||
MOVQ (6*8)(SP), R14 \
|
||||
MOVQ (7*8)(SP), R15 \
|
||||
MOVUPS (8*8)(SP), X6 \
|
||||
MOVUPS (10*8)(SP), X7 \
|
||||
MOVUPS (12*8)(SP), X8 \
|
||||
MOVUPS (14*8)(SP), X9 \
|
||||
MOVUPS (16*8)(SP), X10 \
|
||||
MOVUPS (18*8)(SP), X11 \
|
||||
MOVUPS (20*8)(SP), X12 \
|
||||
MOVUPS (22*8)(SP), X13 \
|
||||
MOVUPS (24*8)(SP), X14 \
|
||||
MOVUPS (26*8)(SP), X15 \
|
||||
ADJSP $-(REGS_HOST_TO_ABI0_STACK - 8) \
|
||||
POPFQ
|
||||
|
||||
#else
|
||||
// SysV ABI
|
||||
|
||||
#define REGS_HOST_TO_ABI0_STACK (6*8)
|
||||
|
||||
// SysV MXCSR matches the Go ABI, so we don't have to set that,
|
||||
// and Go doesn't modify it, so we don't have to save it.
|
||||
// Both SysV and Go require DF to be cleared, so that's already clear.
|
||||
// The SysV and Go frame pointer conventions are compatible.
|
||||
#define PUSH_REGS_HOST_TO_ABI0() \
|
||||
ADJSP $(REGS_HOST_TO_ABI0_STACK) \
|
||||
MOVQ BP, (5*8)(SP) \
|
||||
LEAQ (5*8)(SP), BP \
|
||||
MOVQ BX, (0*8)(SP) \
|
||||
MOVQ R12, (1*8)(SP) \
|
||||
MOVQ R13, (2*8)(SP) \
|
||||
MOVQ R14, (3*8)(SP) \
|
||||
MOVQ R15, (4*8)(SP)
|
||||
|
||||
#define POP_REGS_HOST_TO_ABI0() \
|
||||
MOVQ (0*8)(SP), BX \
|
||||
MOVQ (1*8)(SP), R12 \
|
||||
MOVQ (2*8)(SP), R13 \
|
||||
MOVQ (3*8)(SP), R14 \
|
||||
MOVQ (4*8)(SP), R15 \
|
||||
MOVQ (5*8)(SP), BP \
|
||||
ADJSP $-(REGS_HOST_TO_ABI0_STACK)
|
||||
|
||||
#endif
|
39
vendor/github.com/ebitengine/purego/internal/fakecgo/abi_arm64.h
generated
vendored
Normal file
39
vendor/github.com/ebitengine/purego/internal/fakecgo/abi_arm64.h
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Macros for transitioning from the host ABI to Go ABI0.
|
||||
//
|
||||
// These macros save and restore the callee-saved registers
|
||||
// from the stack, but they don't adjust stack pointer, so
|
||||
// the user should prepare stack space in advance.
|
||||
// SAVE_R19_TO_R28(offset) saves R19 ~ R28 to the stack space
|
||||
// of ((offset)+0*8)(RSP) ~ ((offset)+9*8)(RSP).
|
||||
//
|
||||
// SAVE_F8_TO_F15(offset) saves F8 ~ F15 to the stack space
|
||||
// of ((offset)+0*8)(RSP) ~ ((offset)+7*8)(RSP).
|
||||
//
|
||||
// R29 is not saved because Go will save and restore it.
|
||||
|
||||
#define SAVE_R19_TO_R28(offset) \
|
||||
STP (R19, R20), ((offset)+0*8)(RSP) \
|
||||
STP (R21, R22), ((offset)+2*8)(RSP) \
|
||||
STP (R23, R24), ((offset)+4*8)(RSP) \
|
||||
STP (R25, R26), ((offset)+6*8)(RSP) \
|
||||
STP (R27, g), ((offset)+8*8)(RSP)
|
||||
#define RESTORE_R19_TO_R28(offset) \
|
||||
LDP ((offset)+0*8)(RSP), (R19, R20) \
|
||||
LDP ((offset)+2*8)(RSP), (R21, R22) \
|
||||
LDP ((offset)+4*8)(RSP), (R23, R24) \
|
||||
LDP ((offset)+6*8)(RSP), (R25, R26) \
|
||||
LDP ((offset)+8*8)(RSP), (R27, g) /* R28 */
|
||||
#define SAVE_F8_TO_F15(offset) \
|
||||
FSTPD (F8, F9), ((offset)+0*8)(RSP) \
|
||||
FSTPD (F10, F11), ((offset)+2*8)(RSP) \
|
||||
FSTPD (F12, F13), ((offset)+4*8)(RSP) \
|
||||
FSTPD (F14, F15), ((offset)+6*8)(RSP)
|
||||
#define RESTORE_F8_TO_F15(offset) \
|
||||
FLDPD ((offset)+0*8)(RSP), (F8, F9) \
|
||||
FLDPD ((offset)+2*8)(RSP), (F10, F11) \
|
||||
FLDPD ((offset)+4*8)(RSP), (F12, F13) \
|
||||
FLDPD ((offset)+6*8)(RSP), (F14, F15)
|
39
vendor/github.com/ebitengine/purego/internal/fakecgo/asm_amd64.s
generated
vendored
Normal file
39
vendor/github.com/ebitengine/purego/internal/fakecgo/asm_amd64.s
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "textflag.h"
|
||||
#include "abi_amd64.h"
|
||||
|
||||
// Called by C code generated by cmd/cgo.
|
||||
// func crosscall2(fn, a unsafe.Pointer, n int32, ctxt uintptr)
|
||||
// Saves C callee-saved registers and calls cgocallback with three arguments.
|
||||
// fn is the PC of a func(a unsafe.Pointer) function.
|
||||
// This signature is known to SWIG, so we can't change it.
|
||||
TEXT crosscall2(SB), NOSPLIT|NOFRAME, $0-0
|
||||
PUSH_REGS_HOST_TO_ABI0()
|
||||
|
||||
// Make room for arguments to cgocallback.
|
||||
ADJSP $0x18
|
||||
|
||||
#ifndef GOOS_windows
|
||||
MOVQ DI, 0x0(SP) // fn
|
||||
MOVQ SI, 0x8(SP) // arg
|
||||
|
||||
// Skip n in DX.
|
||||
MOVQ CX, 0x10(SP) // ctxt
|
||||
|
||||
#else
|
||||
MOVQ CX, 0x0(SP) // fn
|
||||
MOVQ DX, 0x8(SP) // arg
|
||||
|
||||
// Skip n in R8.
|
||||
MOVQ R9, 0x10(SP) // ctxt
|
||||
|
||||
#endif
|
||||
|
||||
CALL runtime·cgocallback(SB)
|
||||
|
||||
ADJSP $-0x18
|
||||
POP_REGS_HOST_TO_ABI0()
|
||||
RET
|
36
vendor/github.com/ebitengine/purego/internal/fakecgo/asm_arm64.s
generated
vendored
Normal file
36
vendor/github.com/ebitengine/purego/internal/fakecgo/asm_arm64.s
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "textflag.h"
|
||||
#include "abi_arm64.h"
|
||||
|
||||
// Called by C code generated by cmd/cgo.
|
||||
// func crosscall2(fn, a unsafe.Pointer, n int32, ctxt uintptr)
|
||||
// Saves C callee-saved registers and calls cgocallback with three arguments.
|
||||
// fn is the PC of a func(a unsafe.Pointer) function.
|
||||
TEXT crosscall2(SB), NOSPLIT|NOFRAME, $0
|
||||
/*
|
||||
* We still need to save all callee save register as before, and then
|
||||
* push 3 args for fn (R0, R1, R3), skipping R2.
|
||||
* Also note that at procedure entry in gc world, 8(RSP) will be the
|
||||
* first arg.
|
||||
*/
|
||||
SUB $(8*24), RSP
|
||||
STP (R0, R1), (8*1)(RSP)
|
||||
MOVD R3, (8*3)(RSP)
|
||||
|
||||
SAVE_R19_TO_R28(8*4)
|
||||
SAVE_F8_TO_F15(8*14)
|
||||
STP (R29, R30), (8*22)(RSP)
|
||||
|
||||
// Initialize Go ABI environment
|
||||
BL runtime·load_g(SB)
|
||||
BL runtime·cgocallback(SB)
|
||||
|
||||
RESTORE_R19_TO_R28(8*4)
|
||||
RESTORE_F8_TO_F15(8*14)
|
||||
LDP (8*22)(RSP), (R29, R30)
|
||||
|
||||
ADD $(8*24), RSP
|
||||
RET
|
93
vendor/github.com/ebitengine/purego/internal/fakecgo/callbacks.go
generated
vendored
Normal file
93
vendor/github.com/ebitengine/purego/internal/fakecgo/callbacks.go
generated
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
// Copyright 2011 The Go 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:build darwin || freebsd || linux
|
||||
|
||||
package fakecgo
|
||||
|
||||
import (
|
||||
_ "unsafe"
|
||||
)
|
||||
|
||||
// TODO: decide if we need _runtime_cgo_panic_internal
|
||||
|
||||
//go:linkname x_cgo_init_trampoline x_cgo_init_trampoline
|
||||
//go:linkname _cgo_init _cgo_init
|
||||
var x_cgo_init_trampoline byte
|
||||
var _cgo_init = &x_cgo_init_trampoline
|
||||
|
||||
// Creates a new system thread without updating any Go state.
|
||||
//
|
||||
// This method is invoked during shared library loading to create a new OS
|
||||
// thread to perform the runtime initialization. This method is similar to
|
||||
// _cgo_sys_thread_start except that it doesn't update any Go state.
|
||||
|
||||
//go:linkname x_cgo_thread_start_trampoline x_cgo_thread_start_trampoline
|
||||
//go:linkname _cgo_thread_start _cgo_thread_start
|
||||
var x_cgo_thread_start_trampoline byte
|
||||
var _cgo_thread_start = &x_cgo_thread_start_trampoline
|
||||
|
||||
// Notifies that the runtime has been initialized.
|
||||
//
|
||||
// We currently block at every CGO entry point (via _cgo_wait_runtime_init_done)
|
||||
// to ensure that the runtime has been initialized before the CGO call is
|
||||
// executed. This is necessary for shared libraries where we kickoff runtime
|
||||
// initialization in a separate thread and return without waiting for this
|
||||
// thread to complete the init.
|
||||
|
||||
//go:linkname x_cgo_notify_runtime_init_done_trampoline x_cgo_notify_runtime_init_done_trampoline
|
||||
//go:linkname _cgo_notify_runtime_init_done _cgo_notify_runtime_init_done
|
||||
var x_cgo_notify_runtime_init_done_trampoline byte
|
||||
var _cgo_notify_runtime_init_done = &x_cgo_notify_runtime_init_done_trampoline
|
||||
|
||||
// Indicates whether a dummy thread key has been created or not.
|
||||
//
|
||||
// When calling go exported function from C, we register a destructor
|
||||
// callback, for a dummy thread key, by using pthread_key_create.
|
||||
|
||||
//go:linkname _cgo_pthread_key_created _cgo_pthread_key_created
|
||||
var x_cgo_pthread_key_created uintptr
|
||||
var _cgo_pthread_key_created = &x_cgo_pthread_key_created
|
||||
|
||||
// Set the x_crosscall2_ptr C function pointer variable point to crosscall2.
|
||||
// It's for the runtime package to call at init time.
|
||||
func set_crosscall2() {
|
||||
// nothing needs to be done here for fakecgo
|
||||
// because it's possible to just call cgocallback directly
|
||||
}
|
||||
|
||||
//go:linkname _set_crosscall2 runtime.set_crosscall2
|
||||
var _set_crosscall2 = set_crosscall2
|
||||
|
||||
// Store the g into the thread-specific value.
|
||||
// So that pthread_key_destructor will dropm when the thread is exiting.
|
||||
|
||||
//go:linkname x_cgo_bindm_trampoline x_cgo_bindm_trampoline
|
||||
//go:linkname _cgo_bindm _cgo_bindm
|
||||
var x_cgo_bindm_trampoline byte
|
||||
var _cgo_bindm = &x_cgo_bindm_trampoline
|
||||
|
||||
// TODO: decide if we need x_cgo_set_context_function
|
||||
// TODO: decide if we need _cgo_yield
|
||||
|
||||
var (
|
||||
// In Go 1.20 the race detector was rewritten to pure Go
|
||||
// on darwin. This means that when CGO_ENABLED=0 is set
|
||||
// fakecgo is built with race detector code. This is not
|
||||
// good since this code is pretending to be C. The go:norace
|
||||
// pragma is not enough, since it only applies to the native
|
||||
// ABIInternal function. The ABIO wrapper (which is necessary,
|
||||
// since all references to text symbols from assembly will use it)
|
||||
// does not inherit the go:norace pragma, so it will still be
|
||||
// instrumented by the race detector.
|
||||
//
|
||||
// To circumvent this issue, using closure calls in the
|
||||
// assembly, which forces the compiler to use the ABIInternal
|
||||
// native implementation (which has go:norace) instead.
|
||||
threadentry_call = threadentry
|
||||
x_cgo_init_call = x_cgo_init
|
||||
x_cgo_setenv_call = x_cgo_setenv
|
||||
x_cgo_unsetenv_call = x_cgo_unsetenv
|
||||
x_cgo_thread_start_call = x_cgo_thread_start
|
||||
)
|
33
vendor/github.com/ebitengine/purego/internal/fakecgo/doc.go
generated
vendored
Normal file
33
vendor/github.com/ebitengine/purego/internal/fakecgo/doc.go
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build darwin || freebsd
|
||||
|
||||
// Package fakecgo implements the Cgo runtime (runtime/cgo) entirely in Go.
|
||||
// This allows code that calls into C to function properly when CGO_ENABLED=0.
|
||||
//
|
||||
// # Goals
|
||||
//
|
||||
// fakecgo attempts to replicate the same naming structure as in the runtime.
|
||||
// For example, functions that have the prefix "gcc_*" are named "go_*".
|
||||
// This makes it easier to port other GOOSs and GOARCHs as well as to keep
|
||||
// it in sync with runtime/cgo.
|
||||
//
|
||||
// # Support
|
||||
//
|
||||
// Currently, fakecgo only supports macOS on amd64 & arm64. It also cannot
|
||||
// be used with -buildmode=c-archive because that requires special initialization
|
||||
// that fakecgo does not implement at the moment.
|
||||
//
|
||||
// # Usage
|
||||
//
|
||||
// Using fakecgo is easy just import _ "github.com/ebitengine/purego" and then
|
||||
// set the environment variable CGO_ENABLED=0.
|
||||
// The recommended usage for fakecgo is to prefer using runtime/cgo if possible
|
||||
// but if cross-compiling or fast build times are important fakecgo is available.
|
||||
// Purego will pick which ever Cgo runtime is available and prefer the one that
|
||||
// comes with Go (runtime/cgo).
|
||||
package fakecgo
|
||||
|
||||
//go:generate go run gen.go
|
||||
//go:generate gofmt -s -w symbols.go
|
27
vendor/github.com/ebitengine/purego/internal/fakecgo/freebsd.go
generated
vendored
Normal file
27
vendor/github.com/ebitengine/purego/internal/fakecgo/freebsd.go
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
// Copyright 2010 The Go 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:build freebsd && !cgo
|
||||
|
||||
package fakecgo
|
||||
|
||||
import _ "unsafe" // for go:linkname
|
||||
|
||||
// Supply environ and __progname, because we don't
|
||||
// link against the standard FreeBSD crt0.o and the
|
||||
// libc dynamic library needs them.
|
||||
|
||||
// Note: when building with cross-compiling or CGO_ENABLED=0, add
|
||||
// the following argument to `go` so that these symbols are defined by
|
||||
// making fakecgo the Cgo.
|
||||
// -gcflags="github.com/ebitengine/purego/internal/fakecgo=-std"
|
||||
|
||||
//go:linkname _environ environ
|
||||
//go:linkname _progname __progname
|
||||
|
||||
//go:cgo_export_dynamic environ
|
||||
//go:cgo_export_dynamic __progname
|
||||
|
||||
var _environ uintptr
|
||||
var _progname uintptr
|
71
vendor/github.com/ebitengine/purego/internal/fakecgo/go_darwin_amd64.go
generated
vendored
Normal file
71
vendor/github.com/ebitengine/purego/internal/fakecgo/go_darwin_amd64.go
generated
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package fakecgo
|
||||
|
||||
import "unsafe"
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func _cgo_sys_thread_start(ts *ThreadStart) {
|
||||
var attr pthread_attr_t
|
||||
var ign, oset sigset_t
|
||||
var p pthread_t
|
||||
var size size_t
|
||||
var err int
|
||||
|
||||
sigfillset(&ign)
|
||||
pthread_sigmask(SIG_SETMASK, &ign, &oset)
|
||||
|
||||
size = pthread_get_stacksize_np(pthread_self())
|
||||
pthread_attr_init(&attr)
|
||||
pthread_attr_setstacksize(&attr, size)
|
||||
// Leave stacklo=0 and set stackhi=size; mstart will do the rest.
|
||||
ts.g.stackhi = uintptr(size)
|
||||
|
||||
err = _cgo_try_pthread_create(&p, &attr, unsafe.Pointer(threadentry_trampolineABI0), ts)
|
||||
|
||||
pthread_sigmask(SIG_SETMASK, &oset, nil)
|
||||
|
||||
if err != 0 {
|
||||
print("fakecgo: pthread_create failed: ")
|
||||
println(err)
|
||||
abort()
|
||||
}
|
||||
}
|
||||
|
||||
// threadentry_trampolineABI0 maps the C ABI to Go ABI then calls the Go function
|
||||
//
|
||||
//go:linkname x_threadentry_trampoline threadentry_trampoline
|
||||
var x_threadentry_trampoline byte
|
||||
var threadentry_trampolineABI0 = &x_threadentry_trampoline
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func threadentry(v unsafe.Pointer) unsafe.Pointer {
|
||||
ts := *(*ThreadStart)(v)
|
||||
free(v)
|
||||
|
||||
setg_trampoline(setg_func, uintptr(unsafe.Pointer(ts.g)))
|
||||
|
||||
// faking funcs in go is a bit a... involved - but the following works :)
|
||||
fn := uintptr(unsafe.Pointer(&ts.fn))
|
||||
(*(*func())(unsafe.Pointer(&fn)))()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// here we will store a pointer to the provided setg func
|
||||
var setg_func uintptr
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func x_cgo_init(g *G, setg uintptr) {
|
||||
var size size_t
|
||||
|
||||
setg_func = setg
|
||||
|
||||
size = pthread_get_stacksize_np(pthread_self())
|
||||
g.stacklo = uintptr(unsafe.Add(unsafe.Pointer(&size), -size+4096))
|
||||
}
|
86
vendor/github.com/ebitengine/purego/internal/fakecgo/go_darwin_arm64.go
generated
vendored
Normal file
86
vendor/github.com/ebitengine/purego/internal/fakecgo/go_darwin_arm64.go
generated
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package fakecgo
|
||||
|
||||
import "unsafe"
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func _cgo_sys_thread_start(ts *ThreadStart) {
|
||||
var attr pthread_attr_t
|
||||
var ign, oset sigset_t
|
||||
var p pthread_t
|
||||
var size size_t
|
||||
var err int
|
||||
|
||||
sigfillset(&ign)
|
||||
pthread_sigmask(SIG_SETMASK, &ign, &oset)
|
||||
|
||||
size = pthread_get_stacksize_np(pthread_self())
|
||||
pthread_attr_init(&attr)
|
||||
pthread_attr_setstacksize(&attr, size)
|
||||
// Leave stacklo=0 and set stackhi=size; mstart will do the rest.
|
||||
ts.g.stackhi = uintptr(size)
|
||||
|
||||
err = _cgo_try_pthread_create(&p, &attr, unsafe.Pointer(threadentry_trampolineABI0), ts)
|
||||
|
||||
pthread_sigmask(SIG_SETMASK, &oset, nil)
|
||||
|
||||
if err != 0 {
|
||||
print("fakecgo: pthread_create failed: ")
|
||||
println(err)
|
||||
abort()
|
||||
}
|
||||
}
|
||||
|
||||
// threadentry_trampolineABI0 maps the C ABI to Go ABI then calls the Go function
|
||||
//
|
||||
//go:linkname x_threadentry_trampoline threadentry_trampoline
|
||||
var x_threadentry_trampoline byte
|
||||
var threadentry_trampolineABI0 = &x_threadentry_trampoline
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func threadentry(v unsafe.Pointer) unsafe.Pointer {
|
||||
ts := *(*ThreadStart)(v)
|
||||
free(v)
|
||||
|
||||
// TODO: support ios
|
||||
//#if TARGET_OS_IPHONE
|
||||
// darwin_arm_init_thread_exception_port();
|
||||
//#endif
|
||||
setg_trampoline(setg_func, uintptr(unsafe.Pointer(ts.g)))
|
||||
|
||||
// faking funcs in go is a bit a... involved - but the following works :)
|
||||
fn := uintptr(unsafe.Pointer(&ts.fn))
|
||||
(*(*func())(unsafe.Pointer(&fn)))()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// here we will store a pointer to the provided setg func
|
||||
var setg_func uintptr
|
||||
|
||||
// x_cgo_init(G *g, void (*setg)(void*)) (runtime/cgo/gcc_linux_amd64.c)
|
||||
// This get's called during startup, adjusts stacklo, and provides a pointer to setg_gcc for us
|
||||
// Additionally, if we set _cgo_init to non-null, go won't do it's own TLS setup
|
||||
// This function can't be go:systemstack since go is not in a state where the systemcheck would work.
|
||||
//
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func x_cgo_init(g *G, setg uintptr) {
|
||||
var size size_t
|
||||
|
||||
setg_func = setg
|
||||
size = pthread_get_stacksize_np(pthread_self())
|
||||
g.stacklo = uintptr(unsafe.Add(unsafe.Pointer(&size), -size+4096))
|
||||
|
||||
//TODO: support ios
|
||||
//#if TARGET_OS_IPHONE
|
||||
// darwin_arm_init_mach_exception_handler();
|
||||
// darwin_arm_init_thread_exception_port();
|
||||
// init_working_dir();
|
||||
//#endif
|
||||
}
|
93
vendor/github.com/ebitengine/purego/internal/fakecgo/go_freebsd_amd64.go
generated
vendored
Normal file
93
vendor/github.com/ebitengine/purego/internal/fakecgo/go_freebsd_amd64.go
generated
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package fakecgo
|
||||
|
||||
import "unsafe"
|
||||
|
||||
//go:nosplit
|
||||
func _cgo_sys_thread_start(ts *ThreadStart) {
|
||||
var attr pthread_attr_t
|
||||
var ign, oset sigset_t
|
||||
var p pthread_t
|
||||
var size size_t
|
||||
var err int
|
||||
|
||||
//fprintf(stderr, "runtime/cgo: _cgo_sys_thread_start: fn=%p, g=%p\n", ts->fn, ts->g); // debug
|
||||
sigfillset(&ign)
|
||||
pthread_sigmask(SIG_SETMASK, &ign, &oset)
|
||||
|
||||
pthread_attr_init(&attr)
|
||||
pthread_attr_getstacksize(&attr, &size)
|
||||
// Leave stacklo=0 and set stackhi=size; mstart will do the rest.
|
||||
ts.g.stackhi = uintptr(size)
|
||||
|
||||
err = _cgo_try_pthread_create(&p, &attr, unsafe.Pointer(threadentry_trampolineABI0), ts)
|
||||
|
||||
pthread_sigmask(SIG_SETMASK, &oset, nil)
|
||||
|
||||
if err != 0 {
|
||||
print("fakecgo: pthread_create failed: ")
|
||||
println(err)
|
||||
abort()
|
||||
}
|
||||
}
|
||||
|
||||
// threadentry_trampolineABI0 maps the C ABI to Go ABI then calls the Go function
|
||||
//
|
||||
//go:linkname x_threadentry_trampoline threadentry_trampoline
|
||||
var x_threadentry_trampoline byte
|
||||
var threadentry_trampolineABI0 = &x_threadentry_trampoline
|
||||
|
||||
//go:nosplit
|
||||
func threadentry(v unsafe.Pointer) unsafe.Pointer {
|
||||
ts := *(*ThreadStart)(v)
|
||||
free(v)
|
||||
|
||||
setg_trampoline(setg_func, uintptr(unsafe.Pointer(ts.g)))
|
||||
|
||||
// faking funcs in go is a bit a... involved - but the following works :)
|
||||
fn := uintptr(unsafe.Pointer(&ts.fn))
|
||||
(*(*func())(unsafe.Pointer(&fn)))()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// here we will store a pointer to the provided setg func
|
||||
var setg_func uintptr
|
||||
|
||||
//go:nosplit
|
||||
func x_cgo_init(g *G, setg uintptr) {
|
||||
var size size_t
|
||||
var attr *pthread_attr_t
|
||||
|
||||
/* The memory sanitizer distributed with versions of clang
|
||||
before 3.8 has a bug: if you call mmap before malloc, mmap
|
||||
may return an address that is later overwritten by the msan
|
||||
library. Avoid this problem by forcing a call to malloc
|
||||
here, before we ever call malloc.
|
||||
|
||||
This is only required for the memory sanitizer, so it's
|
||||
unfortunate that we always run it. It should be possible
|
||||
to remove this when we no longer care about versions of
|
||||
clang before 3.8. The test for this is
|
||||
misc/cgo/testsanitizers.
|
||||
|
||||
GCC works hard to eliminate a seemingly unnecessary call to
|
||||
malloc, so we actually use the memory we allocate. */
|
||||
|
||||
setg_func = setg
|
||||
attr = (*pthread_attr_t)(malloc(unsafe.Sizeof(*attr)))
|
||||
if attr == nil {
|
||||
println("fakecgo: malloc failed")
|
||||
abort()
|
||||
}
|
||||
pthread_attr_init(attr)
|
||||
pthread_attr_getstacksize(attr, &size)
|
||||
// runtime/cgo uses __builtin_frame_address(0) instead of `uintptr(unsafe.Pointer(&size))`
|
||||
// but this should be OK since we are taking the address of the first variable in this function.
|
||||
g.stacklo = uintptr(unsafe.Pointer(&size)) - uintptr(size) + 4096
|
||||
pthread_attr_destroy(attr)
|
||||
free(unsafe.Pointer(attr))
|
||||
}
|
96
vendor/github.com/ebitengine/purego/internal/fakecgo/go_freebsd_arm64.go
generated
vendored
Normal file
96
vendor/github.com/ebitengine/purego/internal/fakecgo/go_freebsd_arm64.go
generated
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package fakecgo
|
||||
|
||||
import "unsafe"
|
||||
|
||||
//go:nosplit
|
||||
func _cgo_sys_thread_start(ts *ThreadStart) {
|
||||
var attr pthread_attr_t
|
||||
var ign, oset sigset_t
|
||||
var p pthread_t
|
||||
var size size_t
|
||||
var err int
|
||||
|
||||
//fprintf(stderr, "runtime/cgo: _cgo_sys_thread_start: fn=%p, g=%p\n", ts->fn, ts->g); // debug
|
||||
sigfillset(&ign)
|
||||
pthread_sigmask(SIG_SETMASK, &ign, &oset)
|
||||
|
||||
pthread_attr_init(&attr)
|
||||
pthread_attr_getstacksize(&attr, &size)
|
||||
// Leave stacklo=0 and set stackhi=size; mstart will do the rest.
|
||||
ts.g.stackhi = uintptr(size)
|
||||
|
||||
err = _cgo_try_pthread_create(&p, &attr, unsafe.Pointer(threadentry_trampolineABI0), ts)
|
||||
|
||||
pthread_sigmask(SIG_SETMASK, &oset, nil)
|
||||
|
||||
if err != 0 {
|
||||
print("fakecgo: pthread_create failed: ")
|
||||
println(err)
|
||||
abort()
|
||||
}
|
||||
}
|
||||
|
||||
// threadentry_trampolineABI0 maps the C ABI to Go ABI then calls the Go function
|
||||
//
|
||||
//go:linkname x_threadentry_trampoline threadentry_trampoline
|
||||
var x_threadentry_trampoline byte
|
||||
var threadentry_trampolineABI0 = &x_threadentry_trampoline
|
||||
|
||||
//go:nosplit
|
||||
func threadentry(v unsafe.Pointer) unsafe.Pointer {
|
||||
ts := *(*ThreadStart)(v)
|
||||
free(v)
|
||||
|
||||
setg_trampoline(setg_func, uintptr(unsafe.Pointer(ts.g)))
|
||||
|
||||
// faking funcs in go is a bit a... involved - but the following works :)
|
||||
fn := uintptr(unsafe.Pointer(&ts.fn))
|
||||
(*(*func())(unsafe.Pointer(&fn)))()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// here we will store a pointer to the provided setg func
|
||||
var setg_func uintptr
|
||||
|
||||
// x_cgo_init(G *g, void (*setg)(void*)) (runtime/cgo/gcc_linux_amd64.c)
|
||||
// This get's called during startup, adjusts stacklo, and provides a pointer to setg_gcc for us
|
||||
// Additionally, if we set _cgo_init to non-null, go won't do it's own TLS setup
|
||||
// This function can't be go:systemstack since go is not in a state where the systemcheck would work.
|
||||
//
|
||||
//go:nosplit
|
||||
func x_cgo_init(g *G, setg uintptr) {
|
||||
var size size_t
|
||||
var attr *pthread_attr_t
|
||||
|
||||
/* The memory sanitizer distributed with versions of clang
|
||||
before 3.8 has a bug: if you call mmap before malloc, mmap
|
||||
may return an address that is later overwritten by the msan
|
||||
library. Avoid this problem by forcing a call to malloc
|
||||
here, before we ever call malloc.
|
||||
|
||||
This is only required for the memory sanitizer, so it's
|
||||
unfortunate that we always run it. It should be possible
|
||||
to remove this when we no longer care about versions of
|
||||
clang before 3.8. The test for this is
|
||||
misc/cgo/testsanitizers.
|
||||
|
||||
GCC works hard to eliminate a seemingly unnecessary call to
|
||||
malloc, so we actually use the memory we allocate. */
|
||||
|
||||
setg_func = setg
|
||||
attr = (*pthread_attr_t)(malloc(unsafe.Sizeof(*attr)))
|
||||
if attr == nil {
|
||||
println("fakecgo: malloc failed")
|
||||
abort()
|
||||
}
|
||||
pthread_attr_init(attr)
|
||||
pthread_attr_getstacksize(attr, &size)
|
||||
g.stacklo = uintptr(unsafe.Pointer(&size)) - uintptr(size) + 4096
|
||||
pthread_attr_destroy(attr)
|
||||
free(unsafe.Pointer(attr))
|
||||
}
|
66
vendor/github.com/ebitengine/purego/internal/fakecgo/go_libinit.go
generated
vendored
Normal file
66
vendor/github.com/ebitengine/purego/internal/fakecgo/go_libinit.go
generated
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build darwin || freebsd || linux
|
||||
|
||||
package fakecgo
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var (
|
||||
pthread_g pthread_key_t
|
||||
|
||||
runtime_init_cond = PTHREAD_COND_INITIALIZER
|
||||
runtime_init_mu = PTHREAD_MUTEX_INITIALIZER
|
||||
runtime_init_done int
|
||||
)
|
||||
|
||||
//go:nosplit
|
||||
func x_cgo_notify_runtime_init_done() {
|
||||
pthread_mutex_lock(&runtime_init_mu)
|
||||
runtime_init_done = 1
|
||||
pthread_cond_broadcast(&runtime_init_cond)
|
||||
pthread_mutex_unlock(&runtime_init_mu)
|
||||
}
|
||||
|
||||
// Store the g into a thread-specific value associated with the pthread key pthread_g.
|
||||
// And pthread_key_destructor will dropm when the thread is exiting.
|
||||
func x_cgo_bindm(g unsafe.Pointer) {
|
||||
// We assume this will always succeed, otherwise, there might be extra M leaking,
|
||||
// when a C thread exits after a cgo call.
|
||||
// We only invoke this function once per thread in runtime.needAndBindM,
|
||||
// and the next calls just reuse the bound m.
|
||||
pthread_setspecific(pthread_g, g)
|
||||
}
|
||||
|
||||
// _cgo_try_pthread_create retries pthread_create if it fails with
|
||||
// EAGAIN.
|
||||
//
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func _cgo_try_pthread_create(thread *pthread_t, attr *pthread_attr_t, pfn unsafe.Pointer, arg *ThreadStart) int {
|
||||
var ts syscall.Timespec
|
||||
// tries needs to be the same type as syscall.Timespec.Nsec
|
||||
// but the fields are int32 on 32bit and int64 on 64bit.
|
||||
// tries is assigned to syscall.Timespec.Nsec in order to match its type.
|
||||
tries := ts.Nsec
|
||||
var err int
|
||||
|
||||
for tries = 0; tries < 20; tries++ {
|
||||
err = int(pthread_create(thread, attr, pfn, unsafe.Pointer(arg)))
|
||||
if err == 0 {
|
||||
pthread_detach(*thread)
|
||||
return 0
|
||||
}
|
||||
if err != int(syscall.EAGAIN) {
|
||||
return err
|
||||
}
|
||||
ts.Sec = 0
|
||||
ts.Nsec = (tries + 1) * 1000 * 1000 // Milliseconds.
|
||||
nanosleep(&ts, nil)
|
||||
}
|
||||
return int(syscall.EAGAIN)
|
||||
}
|
93
vendor/github.com/ebitengine/purego/internal/fakecgo/go_linux_amd64.go
generated
vendored
Normal file
93
vendor/github.com/ebitengine/purego/internal/fakecgo/go_linux_amd64.go
generated
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package fakecgo
|
||||
|
||||
import "unsafe"
|
||||
|
||||
//go:nosplit
|
||||
func _cgo_sys_thread_start(ts *ThreadStart) {
|
||||
var attr pthread_attr_t
|
||||
var ign, oset sigset_t
|
||||
var p pthread_t
|
||||
var size size_t
|
||||
var err int
|
||||
|
||||
//fprintf(stderr, "runtime/cgo: _cgo_sys_thread_start: fn=%p, g=%p\n", ts->fn, ts->g); // debug
|
||||
sigfillset(&ign)
|
||||
pthread_sigmask(SIG_SETMASK, &ign, &oset)
|
||||
|
||||
pthread_attr_init(&attr)
|
||||
pthread_attr_getstacksize(&attr, &size)
|
||||
// Leave stacklo=0 and set stackhi=size; mstart will do the rest.
|
||||
ts.g.stackhi = uintptr(size)
|
||||
|
||||
err = _cgo_try_pthread_create(&p, &attr, unsafe.Pointer(threadentry_trampolineABI0), ts)
|
||||
|
||||
pthread_sigmask(SIG_SETMASK, &oset, nil)
|
||||
|
||||
if err != 0 {
|
||||
print("fakecgo: pthread_create failed: ")
|
||||
println(err)
|
||||
abort()
|
||||
}
|
||||
}
|
||||
|
||||
// threadentry_trampolineABI0 maps the C ABI to Go ABI then calls the Go function
|
||||
//
|
||||
//go:linkname x_threadentry_trampoline threadentry_trampoline
|
||||
var x_threadentry_trampoline byte
|
||||
var threadentry_trampolineABI0 = &x_threadentry_trampoline
|
||||
|
||||
//go:nosplit
|
||||
func threadentry(v unsafe.Pointer) unsafe.Pointer {
|
||||
ts := *(*ThreadStart)(v)
|
||||
free(v)
|
||||
|
||||
setg_trampoline(setg_func, uintptr(unsafe.Pointer(ts.g)))
|
||||
|
||||
// faking funcs in go is a bit a... involved - but the following works :)
|
||||
fn := uintptr(unsafe.Pointer(&ts.fn))
|
||||
(*(*func())(unsafe.Pointer(&fn)))()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// here we will store a pointer to the provided setg func
|
||||
var setg_func uintptr
|
||||
|
||||
//go:nosplit
|
||||
func x_cgo_init(g *G, setg uintptr) {
|
||||
var size size_t
|
||||
var attr *pthread_attr_t
|
||||
|
||||
/* The memory sanitizer distributed with versions of clang
|
||||
before 3.8 has a bug: if you call mmap before malloc, mmap
|
||||
may return an address that is later overwritten by the msan
|
||||
library. Avoid this problem by forcing a call to malloc
|
||||
here, before we ever call malloc.
|
||||
|
||||
This is only required for the memory sanitizer, so it's
|
||||
unfortunate that we always run it. It should be possible
|
||||
to remove this when we no longer care about versions of
|
||||
clang before 3.8. The test for this is
|
||||
misc/cgo/testsanitizers.
|
||||
|
||||
GCC works hard to eliminate a seemingly unnecessary call to
|
||||
malloc, so we actually use the memory we allocate. */
|
||||
|
||||
setg_func = setg
|
||||
attr = (*pthread_attr_t)(malloc(unsafe.Sizeof(*attr)))
|
||||
if attr == nil {
|
||||
println("fakecgo: malloc failed")
|
||||
abort()
|
||||
}
|
||||
pthread_attr_init(attr)
|
||||
pthread_attr_getstacksize(attr, &size)
|
||||
// runtime/cgo uses __builtin_frame_address(0) instead of `uintptr(unsafe.Pointer(&size))`
|
||||
// but this should be OK since we are taking the address of the first variable in this function.
|
||||
g.stacklo = uintptr(unsafe.Pointer(&size)) - uintptr(size) + 4096
|
||||
pthread_attr_destroy(attr)
|
||||
free(unsafe.Pointer(attr))
|
||||
}
|
96
vendor/github.com/ebitengine/purego/internal/fakecgo/go_linux_arm64.go
generated
vendored
Normal file
96
vendor/github.com/ebitengine/purego/internal/fakecgo/go_linux_arm64.go
generated
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package fakecgo
|
||||
|
||||
import "unsafe"
|
||||
|
||||
//go:nosplit
|
||||
func _cgo_sys_thread_start(ts *ThreadStart) {
|
||||
var attr pthread_attr_t
|
||||
var ign, oset sigset_t
|
||||
var p pthread_t
|
||||
var size size_t
|
||||
var err int
|
||||
|
||||
//fprintf(stderr, "runtime/cgo: _cgo_sys_thread_start: fn=%p, g=%p\n", ts->fn, ts->g); // debug
|
||||
sigfillset(&ign)
|
||||
pthread_sigmask(SIG_SETMASK, &ign, &oset)
|
||||
|
||||
pthread_attr_init(&attr)
|
||||
pthread_attr_getstacksize(&attr, &size)
|
||||
// Leave stacklo=0 and set stackhi=size; mstart will do the rest.
|
||||
ts.g.stackhi = uintptr(size)
|
||||
|
||||
err = _cgo_try_pthread_create(&p, &attr, unsafe.Pointer(threadentry_trampolineABI0), ts)
|
||||
|
||||
pthread_sigmask(SIG_SETMASK, &oset, nil)
|
||||
|
||||
if err != 0 {
|
||||
print("fakecgo: pthread_create failed: ")
|
||||
println(err)
|
||||
abort()
|
||||
}
|
||||
}
|
||||
|
||||
// threadentry_trampolineABI0 maps the C ABI to Go ABI then calls the Go function
|
||||
//
|
||||
//go:linkname x_threadentry_trampoline threadentry_trampoline
|
||||
var x_threadentry_trampoline byte
|
||||
var threadentry_trampolineABI0 = &x_threadentry_trampoline
|
||||
|
||||
//go:nosplit
|
||||
func threadentry(v unsafe.Pointer) unsafe.Pointer {
|
||||
ts := *(*ThreadStart)(v)
|
||||
free(v)
|
||||
|
||||
setg_trampoline(setg_func, uintptr(unsafe.Pointer(ts.g)))
|
||||
|
||||
// faking funcs in go is a bit a... involved - but the following works :)
|
||||
fn := uintptr(unsafe.Pointer(&ts.fn))
|
||||
(*(*func())(unsafe.Pointer(&fn)))()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// here we will store a pointer to the provided setg func
|
||||
var setg_func uintptr
|
||||
|
||||
// x_cgo_init(G *g, void (*setg)(void*)) (runtime/cgo/gcc_linux_amd64.c)
|
||||
// This get's called during startup, adjusts stacklo, and provides a pointer to setg_gcc for us
|
||||
// Additionally, if we set _cgo_init to non-null, go won't do it's own TLS setup
|
||||
// This function can't be go:systemstack since go is not in a state where the systemcheck would work.
|
||||
//
|
||||
//go:nosplit
|
||||
func x_cgo_init(g *G, setg uintptr) {
|
||||
var size size_t
|
||||
var attr *pthread_attr_t
|
||||
|
||||
/* The memory sanitizer distributed with versions of clang
|
||||
before 3.8 has a bug: if you call mmap before malloc, mmap
|
||||
may return an address that is later overwritten by the msan
|
||||
library. Avoid this problem by forcing a call to malloc
|
||||
here, before we ever call malloc.
|
||||
|
||||
This is only required for the memory sanitizer, so it's
|
||||
unfortunate that we always run it. It should be possible
|
||||
to remove this when we no longer care about versions of
|
||||
clang before 3.8. The test for this is
|
||||
misc/cgo/testsanitizers.
|
||||
|
||||
GCC works hard to eliminate a seemingly unnecessary call to
|
||||
malloc, so we actually use the memory we allocate. */
|
||||
|
||||
setg_func = setg
|
||||
attr = (*pthread_attr_t)(malloc(unsafe.Sizeof(*attr)))
|
||||
if attr == nil {
|
||||
println("fakecgo: malloc failed")
|
||||
abort()
|
||||
}
|
||||
pthread_attr_init(attr)
|
||||
pthread_attr_getstacksize(attr, &size)
|
||||
g.stacklo = uintptr(unsafe.Pointer(&size)) - uintptr(size) + 4096
|
||||
pthread_attr_destroy(attr)
|
||||
free(unsafe.Pointer(attr))
|
||||
}
|
18
vendor/github.com/ebitengine/purego/internal/fakecgo/go_setenv.go
generated
vendored
Normal file
18
vendor/github.com/ebitengine/purego/internal/fakecgo/go_setenv.go
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build darwin || freebsd || linux
|
||||
|
||||
package fakecgo
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func x_cgo_setenv(arg *[2]*byte) {
|
||||
setenv(arg[0], arg[1], 1)
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func x_cgo_unsetenv(arg *[1]*byte) {
|
||||
unsetenv(arg[0])
|
||||
}
|
33
vendor/github.com/ebitengine/purego/internal/fakecgo/go_util.go
generated
vendored
Normal file
33
vendor/github.com/ebitengine/purego/internal/fakecgo/go_util.go
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build darwin || freebsd || linux
|
||||
|
||||
package fakecgo
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// _cgo_thread_start is split into three parts in cgo since only one part is system dependent (keep it here for easier handling)
|
||||
|
||||
// _cgo_thread_start(ThreadStart *arg) (runtime/cgo/gcc_util.c)
|
||||
// This get's called instead of the go code for creating new threads
|
||||
// -> pthread_* stuff is used, so threads are setup correctly for C
|
||||
// If this is missing, TLS is only setup correctly on thread 1!
|
||||
// This function should be go:systemstack instead of go:nosplit (but that requires runtime)
|
||||
//
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func x_cgo_thread_start(arg *ThreadStart) {
|
||||
var ts *ThreadStart
|
||||
// Make our own copy that can persist after we return.
|
||||
// _cgo_tsan_acquire();
|
||||
ts = (*ThreadStart)(malloc(unsafe.Sizeof(*ts)))
|
||||
// _cgo_tsan_release();
|
||||
if ts == nil {
|
||||
println("fakecgo: out of memory in thread_start")
|
||||
abort()
|
||||
}
|
||||
// *ts = *arg would cause a writebarrier so use memmove instead
|
||||
memmove(unsafe.Pointer(ts), unsafe.Pointer(arg), unsafe.Sizeof(*ts))
|
||||
_cgo_sys_thread_start(ts) // OS-dependent half
|
||||
}
|
19
vendor/github.com/ebitengine/purego/internal/fakecgo/iscgo.go
generated
vendored
Normal file
19
vendor/github.com/ebitengine/purego/internal/fakecgo/iscgo.go
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
// Copyright 2010 The Go 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:build darwin || freebsd || linux
|
||||
|
||||
// The runtime package contains an uninitialized definition
|
||||
// for runtime·iscgo. Override it to tell the runtime we're here.
|
||||
// There are various function pointers that should be set too,
|
||||
// but those depend on dynamic linker magic to get initialized
|
||||
// correctly, and sometimes they break. This variable is a
|
||||
// backup: it depends only on old C style static linking rules.
|
||||
|
||||
package fakecgo
|
||||
|
||||
import _ "unsafe" // for go:linkname
|
||||
|
||||
//go:linkname _iscgo runtime.iscgo
|
||||
var _iscgo bool = true
|
35
vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo.go
generated
vendored
Normal file
35
vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo.go
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build darwin || freebsd || linux
|
||||
|
||||
package fakecgo
|
||||
|
||||
type (
|
||||
size_t uintptr
|
||||
sigset_t [128]byte
|
||||
pthread_attr_t [64]byte
|
||||
pthread_t int
|
||||
pthread_key_t uint64
|
||||
)
|
||||
|
||||
// for pthread_sigmask:
|
||||
|
||||
type sighow int32
|
||||
|
||||
const (
|
||||
SIG_BLOCK sighow = 0
|
||||
SIG_UNBLOCK sighow = 1
|
||||
SIG_SETMASK sighow = 2
|
||||
)
|
||||
|
||||
type G struct {
|
||||
stacklo uintptr
|
||||
stackhi uintptr
|
||||
}
|
||||
|
||||
type ThreadStart struct {
|
||||
g *G
|
||||
tls *uintptr
|
||||
fn uintptr
|
||||
}
|
20
vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo_darwin.go
generated
vendored
Normal file
20
vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo_darwin.go
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
package fakecgo
|
||||
|
||||
type (
|
||||
pthread_mutex_t struct {
|
||||
sig int64
|
||||
opaque [56]byte
|
||||
}
|
||||
pthread_cond_t struct {
|
||||
sig int64
|
||||
opaque [40]byte
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
PTHREAD_COND_INITIALIZER = pthread_cond_t{sig: 0x3CB0B1BB}
|
||||
PTHREAD_MUTEX_INITIALIZER = pthread_mutex_t{sig: 0x32AAABA7}
|
||||
)
|
14
vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo_freebsd.go
generated
vendored
Normal file
14
vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo_freebsd.go
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
package fakecgo
|
||||
|
||||
type (
|
||||
pthread_cond_t uintptr
|
||||
pthread_mutex_t uintptr
|
||||
)
|
||||
|
||||
var (
|
||||
PTHREAD_COND_INITIALIZER = pthread_cond_t(0)
|
||||
PTHREAD_MUTEX_INITIALIZER = pthread_mutex_t(0)
|
||||
)
|
14
vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo_linux.go
generated
vendored
Normal file
14
vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo_linux.go
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
package fakecgo
|
||||
|
||||
type (
|
||||
pthread_cond_t [48]byte
|
||||
pthread_mutex_t [48]byte
|
||||
)
|
||||
|
||||
var (
|
||||
PTHREAD_COND_INITIALIZER = pthread_cond_t{}
|
||||
PTHREAD_MUTEX_INITIALIZER = pthread_mutex_t{}
|
||||
)
|
19
vendor/github.com/ebitengine/purego/internal/fakecgo/setenv.go
generated
vendored
Normal file
19
vendor/github.com/ebitengine/purego/internal/fakecgo/setenv.go
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
// Copyright 2011 The Go 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:build darwin || freebsd || linux
|
||||
|
||||
package fakecgo
|
||||
|
||||
import _ "unsafe" // for go:linkname
|
||||
|
||||
//go:linkname x_cgo_setenv_trampoline x_cgo_setenv_trampoline
|
||||
//go:linkname _cgo_setenv runtime._cgo_setenv
|
||||
var x_cgo_setenv_trampoline byte
|
||||
var _cgo_setenv = &x_cgo_setenv_trampoline
|
||||
|
||||
//go:linkname x_cgo_unsetenv_trampoline x_cgo_unsetenv_trampoline
|
||||
//go:linkname _cgo_unsetenv runtime._cgo_unsetenv
|
||||
var x_cgo_unsetenv_trampoline byte
|
||||
var _cgo_unsetenv = &x_cgo_unsetenv_trampoline
|
184
vendor/github.com/ebitengine/purego/internal/fakecgo/symbols.go
generated
vendored
Normal file
184
vendor/github.com/ebitengine/purego/internal/fakecgo/symbols.go
generated
vendored
Normal file
@@ -0,0 +1,184 @@
|
||||
// Code generated by 'go generate' with gen.go. DO NOT EDIT.
|
||||
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build darwin || freebsd || linux
|
||||
|
||||
package fakecgo
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// setg_trampoline calls setg with the G provided
|
||||
func setg_trampoline(setg uintptr, G uintptr)
|
||||
|
||||
//go:linkname memmove runtime.memmove
|
||||
func memmove(to, from unsafe.Pointer, n uintptr)
|
||||
|
||||
// call5 takes fn the C function and 5 arguments and calls the function with those arguments
|
||||
func call5(fn, a1, a2, a3, a4, a5 uintptr) uintptr
|
||||
|
||||
func malloc(size uintptr) unsafe.Pointer {
|
||||
ret := call5(mallocABI0, uintptr(size), 0, 0, 0, 0)
|
||||
// this indirection is to avoid go vet complaining about possible misuse of unsafe.Pointer
|
||||
return *(*unsafe.Pointer)(unsafe.Pointer(&ret))
|
||||
}
|
||||
|
||||
func free(ptr unsafe.Pointer) {
|
||||
call5(freeABI0, uintptr(ptr), 0, 0, 0, 0)
|
||||
}
|
||||
|
||||
func setenv(name *byte, value *byte, overwrite int32) int32 {
|
||||
return int32(call5(setenvABI0, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(value)), uintptr(overwrite), 0, 0))
|
||||
}
|
||||
|
||||
func unsetenv(name *byte) int32 {
|
||||
return int32(call5(unsetenvABI0, uintptr(unsafe.Pointer(name)), 0, 0, 0, 0))
|
||||
}
|
||||
|
||||
func sigfillset(set *sigset_t) int32 {
|
||||
return int32(call5(sigfillsetABI0, uintptr(unsafe.Pointer(set)), 0, 0, 0, 0))
|
||||
}
|
||||
|
||||
func nanosleep(ts *syscall.Timespec, rem *syscall.Timespec) int32 {
|
||||
return int32(call5(nanosleepABI0, uintptr(unsafe.Pointer(ts)), uintptr(unsafe.Pointer(rem)), 0, 0, 0))
|
||||
}
|
||||
|
||||
func abort() {
|
||||
call5(abortABI0, 0, 0, 0, 0, 0)
|
||||
}
|
||||
|
||||
func pthread_attr_init(attr *pthread_attr_t) int32 {
|
||||
return int32(call5(pthread_attr_initABI0, uintptr(unsafe.Pointer(attr)), 0, 0, 0, 0))
|
||||
}
|
||||
|
||||
func pthread_create(thread *pthread_t, attr *pthread_attr_t, start unsafe.Pointer, arg unsafe.Pointer) int32 {
|
||||
return int32(call5(pthread_createABI0, uintptr(unsafe.Pointer(thread)), uintptr(unsafe.Pointer(attr)), uintptr(start), uintptr(arg), 0))
|
||||
}
|
||||
|
||||
func pthread_detach(thread pthread_t) int32 {
|
||||
return int32(call5(pthread_detachABI0, uintptr(thread), 0, 0, 0, 0))
|
||||
}
|
||||
|
||||
func pthread_sigmask(how sighow, ign *sigset_t, oset *sigset_t) int32 {
|
||||
return int32(call5(pthread_sigmaskABI0, uintptr(how), uintptr(unsafe.Pointer(ign)), uintptr(unsafe.Pointer(oset)), 0, 0))
|
||||
}
|
||||
|
||||
func pthread_self() pthread_t {
|
||||
return pthread_t(call5(pthread_selfABI0, 0, 0, 0, 0, 0))
|
||||
}
|
||||
|
||||
func pthread_get_stacksize_np(thread pthread_t) size_t {
|
||||
return size_t(call5(pthread_get_stacksize_npABI0, uintptr(thread), 0, 0, 0, 0))
|
||||
}
|
||||
|
||||
func pthread_attr_getstacksize(attr *pthread_attr_t, stacksize *size_t) int32 {
|
||||
return int32(call5(pthread_attr_getstacksizeABI0, uintptr(unsafe.Pointer(attr)), uintptr(unsafe.Pointer(stacksize)), 0, 0, 0))
|
||||
}
|
||||
|
||||
func pthread_attr_setstacksize(attr *pthread_attr_t, size size_t) int32 {
|
||||
return int32(call5(pthread_attr_setstacksizeABI0, uintptr(unsafe.Pointer(attr)), uintptr(size), 0, 0, 0))
|
||||
}
|
||||
|
||||
func pthread_attr_destroy(attr *pthread_attr_t) int32 {
|
||||
return int32(call5(pthread_attr_destroyABI0, uintptr(unsafe.Pointer(attr)), 0, 0, 0, 0))
|
||||
}
|
||||
|
||||
func pthread_mutex_lock(mutex *pthread_mutex_t) int32 {
|
||||
return int32(call5(pthread_mutex_lockABI0, uintptr(unsafe.Pointer(mutex)), 0, 0, 0, 0))
|
||||
}
|
||||
|
||||
func pthread_mutex_unlock(mutex *pthread_mutex_t) int32 {
|
||||
return int32(call5(pthread_mutex_unlockABI0, uintptr(unsafe.Pointer(mutex)), 0, 0, 0, 0))
|
||||
}
|
||||
|
||||
func pthread_cond_broadcast(cond *pthread_cond_t) int32 {
|
||||
return int32(call5(pthread_cond_broadcastABI0, uintptr(unsafe.Pointer(cond)), 0, 0, 0, 0))
|
||||
}
|
||||
|
||||
func pthread_setspecific(key pthread_key_t, value unsafe.Pointer) int32 {
|
||||
return int32(call5(pthread_setspecificABI0, uintptr(key), uintptr(value), 0, 0, 0))
|
||||
}
|
||||
|
||||
//go:linkname _malloc _malloc
|
||||
var _malloc uintptr
|
||||
var mallocABI0 = uintptr(unsafe.Pointer(&_malloc))
|
||||
|
||||
//go:linkname _free _free
|
||||
var _free uintptr
|
||||
var freeABI0 = uintptr(unsafe.Pointer(&_free))
|
||||
|
||||
//go:linkname _setenv _setenv
|
||||
var _setenv uintptr
|
||||
var setenvABI0 = uintptr(unsafe.Pointer(&_setenv))
|
||||
|
||||
//go:linkname _unsetenv _unsetenv
|
||||
var _unsetenv uintptr
|
||||
var unsetenvABI0 = uintptr(unsafe.Pointer(&_unsetenv))
|
||||
|
||||
//go:linkname _sigfillset _sigfillset
|
||||
var _sigfillset uintptr
|
||||
var sigfillsetABI0 = uintptr(unsafe.Pointer(&_sigfillset))
|
||||
|
||||
//go:linkname _nanosleep _nanosleep
|
||||
var _nanosleep uintptr
|
||||
var nanosleepABI0 = uintptr(unsafe.Pointer(&_nanosleep))
|
||||
|
||||
//go:linkname _abort _abort
|
||||
var _abort uintptr
|
||||
var abortABI0 = uintptr(unsafe.Pointer(&_abort))
|
||||
|
||||
//go:linkname _pthread_attr_init _pthread_attr_init
|
||||
var _pthread_attr_init uintptr
|
||||
var pthread_attr_initABI0 = uintptr(unsafe.Pointer(&_pthread_attr_init))
|
||||
|
||||
//go:linkname _pthread_create _pthread_create
|
||||
var _pthread_create uintptr
|
||||
var pthread_createABI0 = uintptr(unsafe.Pointer(&_pthread_create))
|
||||
|
||||
//go:linkname _pthread_detach _pthread_detach
|
||||
var _pthread_detach uintptr
|
||||
var pthread_detachABI0 = uintptr(unsafe.Pointer(&_pthread_detach))
|
||||
|
||||
//go:linkname _pthread_sigmask _pthread_sigmask
|
||||
var _pthread_sigmask uintptr
|
||||
var pthread_sigmaskABI0 = uintptr(unsafe.Pointer(&_pthread_sigmask))
|
||||
|
||||
//go:linkname _pthread_self _pthread_self
|
||||
var _pthread_self uintptr
|
||||
var pthread_selfABI0 = uintptr(unsafe.Pointer(&_pthread_self))
|
||||
|
||||
//go:linkname _pthread_get_stacksize_np _pthread_get_stacksize_np
|
||||
var _pthread_get_stacksize_np uintptr
|
||||
var pthread_get_stacksize_npABI0 = uintptr(unsafe.Pointer(&_pthread_get_stacksize_np))
|
||||
|
||||
//go:linkname _pthread_attr_getstacksize _pthread_attr_getstacksize
|
||||
var _pthread_attr_getstacksize uintptr
|
||||
var pthread_attr_getstacksizeABI0 = uintptr(unsafe.Pointer(&_pthread_attr_getstacksize))
|
||||
|
||||
//go:linkname _pthread_attr_setstacksize _pthread_attr_setstacksize
|
||||
var _pthread_attr_setstacksize uintptr
|
||||
var pthread_attr_setstacksizeABI0 = uintptr(unsafe.Pointer(&_pthread_attr_setstacksize))
|
||||
|
||||
//go:linkname _pthread_attr_destroy _pthread_attr_destroy
|
||||
var _pthread_attr_destroy uintptr
|
||||
var pthread_attr_destroyABI0 = uintptr(unsafe.Pointer(&_pthread_attr_destroy))
|
||||
|
||||
//go:linkname _pthread_mutex_lock _pthread_mutex_lock
|
||||
var _pthread_mutex_lock uintptr
|
||||
var pthread_mutex_lockABI0 = uintptr(unsafe.Pointer(&_pthread_mutex_lock))
|
||||
|
||||
//go:linkname _pthread_mutex_unlock _pthread_mutex_unlock
|
||||
var _pthread_mutex_unlock uintptr
|
||||
var pthread_mutex_unlockABI0 = uintptr(unsafe.Pointer(&_pthread_mutex_unlock))
|
||||
|
||||
//go:linkname _pthread_cond_broadcast _pthread_cond_broadcast
|
||||
var _pthread_cond_broadcast uintptr
|
||||
var pthread_cond_broadcastABI0 = uintptr(unsafe.Pointer(&_pthread_cond_broadcast))
|
||||
|
||||
//go:linkname _pthread_setspecific _pthread_setspecific
|
||||
var _pthread_setspecific uintptr
|
||||
var pthread_setspecificABI0 = uintptr(unsafe.Pointer(&_pthread_setspecific))
|
27
vendor/github.com/ebitengine/purego/internal/fakecgo/symbols_darwin.go
generated
vendored
Normal file
27
vendor/github.com/ebitengine/purego/internal/fakecgo/symbols_darwin.go
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
// Code generated by 'go generate' with gen.go. DO NOT EDIT.
|
||||
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
package fakecgo
|
||||
|
||||
//go:cgo_import_dynamic purego_malloc malloc "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_free free "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_setenv setenv "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_unsetenv unsetenv "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_sigfillset sigfillset "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_nanosleep nanosleep "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_abort abort "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_init pthread_attr_init "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_pthread_create pthread_create "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_pthread_detach pthread_detach "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_pthread_sigmask pthread_sigmask "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_pthread_self pthread_self "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_pthread_get_stacksize_np pthread_get_stacksize_np "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_getstacksize pthread_attr_getstacksize "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_setstacksize pthread_attr_setstacksize "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_destroy pthread_attr_destroy "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_pthread_mutex_lock pthread_mutex_lock "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_pthread_mutex_unlock pthread_mutex_unlock "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_pthread_cond_broadcast pthread_cond_broadcast "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_pthread_setspecific pthread_setspecific "/usr/lib/libSystem.B.dylib"
|
27
vendor/github.com/ebitengine/purego/internal/fakecgo/symbols_freebsd.go
generated
vendored
Normal file
27
vendor/github.com/ebitengine/purego/internal/fakecgo/symbols_freebsd.go
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
// Code generated by 'go generate' with gen.go. DO NOT EDIT.
|
||||
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
package fakecgo
|
||||
|
||||
//go:cgo_import_dynamic purego_malloc malloc "libc.so.7"
|
||||
//go:cgo_import_dynamic purego_free free "libc.so.7"
|
||||
//go:cgo_import_dynamic purego_setenv setenv "libc.so.7"
|
||||
//go:cgo_import_dynamic purego_unsetenv unsetenv "libc.so.7"
|
||||
//go:cgo_import_dynamic purego_sigfillset sigfillset "libc.so.7"
|
||||
//go:cgo_import_dynamic purego_nanosleep nanosleep "libc.so.7"
|
||||
//go:cgo_import_dynamic purego_abort abort "libc.so.7"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_init pthread_attr_init "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_create pthread_create "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_detach pthread_detach "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_sigmask pthread_sigmask "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_self pthread_self "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_get_stacksize_np pthread_get_stacksize_np "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_getstacksize pthread_attr_getstacksize "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_setstacksize pthread_attr_setstacksize "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_destroy pthread_attr_destroy "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_mutex_lock pthread_mutex_lock "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_mutex_unlock pthread_mutex_unlock "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_cond_broadcast pthread_cond_broadcast "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_setspecific pthread_setspecific "libpthread.so"
|
27
vendor/github.com/ebitengine/purego/internal/fakecgo/symbols_linux.go
generated
vendored
Normal file
27
vendor/github.com/ebitengine/purego/internal/fakecgo/symbols_linux.go
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
// Code generated by 'go generate' with gen.go. DO NOT EDIT.
|
||||
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
package fakecgo
|
||||
|
||||
//go:cgo_import_dynamic purego_malloc malloc "libc.so.6"
|
||||
//go:cgo_import_dynamic purego_free free "libc.so.6"
|
||||
//go:cgo_import_dynamic purego_setenv setenv "libc.so.6"
|
||||
//go:cgo_import_dynamic purego_unsetenv unsetenv "libc.so.6"
|
||||
//go:cgo_import_dynamic purego_sigfillset sigfillset "libc.so.6"
|
||||
//go:cgo_import_dynamic purego_nanosleep nanosleep "libc.so.6"
|
||||
//go:cgo_import_dynamic purego_abort abort "libc.so.6"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_init pthread_attr_init "libpthread.so.0"
|
||||
//go:cgo_import_dynamic purego_pthread_create pthread_create "libpthread.so.0"
|
||||
//go:cgo_import_dynamic purego_pthread_detach pthread_detach "libpthread.so.0"
|
||||
//go:cgo_import_dynamic purego_pthread_sigmask pthread_sigmask "libpthread.so.0"
|
||||
//go:cgo_import_dynamic purego_pthread_self pthread_self "libpthread.so.0"
|
||||
//go:cgo_import_dynamic purego_pthread_get_stacksize_np pthread_get_stacksize_np "libpthread.so.0"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_getstacksize pthread_attr_getstacksize "libpthread.so.0"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_setstacksize pthread_attr_setstacksize "libpthread.so.0"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_destroy pthread_attr_destroy "libpthread.so.0"
|
||||
//go:cgo_import_dynamic purego_pthread_mutex_lock pthread_mutex_lock "libpthread.so.0"
|
||||
//go:cgo_import_dynamic purego_pthread_mutex_unlock pthread_mutex_unlock "libpthread.so.0"
|
||||
//go:cgo_import_dynamic purego_pthread_cond_broadcast pthread_cond_broadcast "libpthread.so.0"
|
||||
//go:cgo_import_dynamic purego_pthread_setspecific pthread_setspecific "libpthread.so.0"
|
104
vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_amd64.s
generated
vendored
Normal file
104
vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_amd64.s
generated
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build darwin || linux || freebsd
|
||||
|
||||
/*
|
||||
trampoline for emulating required C functions for cgo in go (see cgo.go)
|
||||
(we convert cdecl calling convention to go and vice-versa)
|
||||
|
||||
Since we're called from go and call into C we can cheat a bit with the calling conventions:
|
||||
- in go all the registers are caller saved
|
||||
- in C we have a couple of callee saved registers
|
||||
|
||||
=> we can use BX, R12, R13, R14, R15 instead of the stack
|
||||
|
||||
C Calling convention cdecl used here (we only need integer args):
|
||||
1. arg: DI
|
||||
2. arg: SI
|
||||
3. arg: DX
|
||||
4. arg: CX
|
||||
5. arg: R8
|
||||
6. arg: R9
|
||||
We don't need floats with these functions -> AX=0
|
||||
return value will be in AX
|
||||
*/
|
||||
#include "textflag.h"
|
||||
#include "go_asm.h"
|
||||
|
||||
// these trampolines map the gcc ABI to Go ABI and then calls into the Go equivalent functions.
|
||||
|
||||
TEXT x_cgo_init_trampoline(SB), NOSPLIT, $16
|
||||
MOVQ DI, AX
|
||||
MOVQ SI, BX
|
||||
MOVQ ·x_cgo_init_call(SB), DX
|
||||
MOVQ (DX), CX
|
||||
CALL CX
|
||||
RET
|
||||
|
||||
TEXT x_cgo_thread_start_trampoline(SB), NOSPLIT, $8
|
||||
MOVQ DI, AX
|
||||
MOVQ ·x_cgo_thread_start_call(SB), DX
|
||||
MOVQ (DX), CX
|
||||
CALL CX
|
||||
RET
|
||||
|
||||
TEXT x_cgo_setenv_trampoline(SB), NOSPLIT, $8
|
||||
MOVQ DI, AX
|
||||
MOVQ ·x_cgo_setenv_call(SB), DX
|
||||
MOVQ (DX), CX
|
||||
CALL CX
|
||||
RET
|
||||
|
||||
TEXT x_cgo_unsetenv_trampoline(SB), NOSPLIT, $8
|
||||
MOVQ DI, AX
|
||||
MOVQ ·x_cgo_unsetenv_call(SB), DX
|
||||
MOVQ (DX), CX
|
||||
CALL CX
|
||||
RET
|
||||
|
||||
TEXT x_cgo_notify_runtime_init_done_trampoline(SB), NOSPLIT, $0
|
||||
CALL ·x_cgo_notify_runtime_init_done(SB)
|
||||
RET
|
||||
|
||||
TEXT x_cgo_bindm_trampoline(SB), NOSPLIT, $0
|
||||
CALL ·x_cgo_bindm(SB)
|
||||
RET
|
||||
|
||||
// func setg_trampoline(setg uintptr, g uintptr)
|
||||
TEXT ·setg_trampoline(SB), NOSPLIT, $0-16
|
||||
MOVQ G+8(FP), DI
|
||||
MOVQ setg+0(FP), BX
|
||||
XORL AX, AX
|
||||
CALL BX
|
||||
RET
|
||||
|
||||
TEXT threadentry_trampoline(SB), NOSPLIT, $16
|
||||
MOVQ DI, AX
|
||||
MOVQ ·threadentry_call(SB), DX
|
||||
MOVQ (DX), CX
|
||||
CALL CX
|
||||
RET
|
||||
|
||||
TEXT ·call5(SB), NOSPLIT, $0-56
|
||||
MOVQ fn+0(FP), BX
|
||||
MOVQ a1+8(FP), DI
|
||||
MOVQ a2+16(FP), SI
|
||||
MOVQ a3+24(FP), DX
|
||||
MOVQ a4+32(FP), CX
|
||||
MOVQ a5+40(FP), R8
|
||||
|
||||
XORL AX, AX // no floats
|
||||
|
||||
PUSHQ BP // save BP
|
||||
MOVQ SP, BP // save SP inside BP bc BP is callee-saved
|
||||
SUBQ $16, SP // allocate space for alignment
|
||||
ANDQ $-16, SP // align on 16 bytes for SSE
|
||||
|
||||
CALL BX
|
||||
|
||||
MOVQ BP, SP // get SP back
|
||||
POPQ BP // restore BP
|
||||
|
||||
MOVQ AX, ret+48(FP)
|
||||
RET
|
72
vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_arm64.s
generated
vendored
Normal file
72
vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_arm64.s
generated
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build darwin || freebsd || linux
|
||||
|
||||
#include "textflag.h"
|
||||
#include "go_asm.h"
|
||||
|
||||
// these trampolines map the gcc ABI to Go ABI and then calls into the Go equivalent functions.
|
||||
|
||||
TEXT x_cgo_init_trampoline(SB), NOSPLIT, $0-0
|
||||
MOVD R0, 8(RSP)
|
||||
MOVD R1, 16(RSP)
|
||||
MOVD ·x_cgo_init_call(SB), R26
|
||||
MOVD (R26), R2
|
||||
CALL (R2)
|
||||
RET
|
||||
|
||||
TEXT x_cgo_thread_start_trampoline(SB), NOSPLIT, $0-0
|
||||
MOVD R0, 8(RSP)
|
||||
MOVD ·x_cgo_thread_start_call(SB), R26
|
||||
MOVD (R26), R2
|
||||
CALL (R2)
|
||||
RET
|
||||
|
||||
TEXT x_cgo_setenv_trampoline(SB), NOSPLIT, $0-0
|
||||
MOVD R0, 8(RSP)
|
||||
MOVD ·x_cgo_setenv_call(SB), R26
|
||||
MOVD (R26), R2
|
||||
CALL (R2)
|
||||
RET
|
||||
|
||||
TEXT x_cgo_unsetenv_trampoline(SB), NOSPLIT, $0-0
|
||||
MOVD R0, 8(RSP)
|
||||
MOVD ·x_cgo_unsetenv_call(SB), R26
|
||||
MOVD (R26), R2
|
||||
CALL (R2)
|
||||
RET
|
||||
|
||||
TEXT x_cgo_notify_runtime_init_done_trampoline(SB), NOSPLIT, $0-0
|
||||
CALL ·x_cgo_notify_runtime_init_done(SB)
|
||||
RET
|
||||
|
||||
TEXT x_cgo_bindm_trampoline(SB), NOSPLIT, $0
|
||||
CALL ·x_cgo_bindm(SB)
|
||||
RET
|
||||
|
||||
// func setg_trampoline(setg uintptr, g uintptr)
|
||||
TEXT ·setg_trampoline(SB), NOSPLIT, $0-16
|
||||
MOVD G+8(FP), R0
|
||||
MOVD setg+0(FP), R1
|
||||
CALL R1
|
||||
RET
|
||||
|
||||
TEXT threadentry_trampoline(SB), NOSPLIT, $0-0
|
||||
MOVD R0, 8(RSP)
|
||||
MOVD ·threadentry_call(SB), R26
|
||||
MOVD (R26), R2
|
||||
CALL (R2)
|
||||
MOVD $0, R0 // TODO: get the return value from threadentry
|
||||
RET
|
||||
|
||||
TEXT ·call5(SB), NOSPLIT, $0-0
|
||||
MOVD fn+0(FP), R6
|
||||
MOVD a1+8(FP), R0
|
||||
MOVD a2+16(FP), R1
|
||||
MOVD a3+24(FP), R2
|
||||
MOVD a4+32(FP), R3
|
||||
MOVD a5+40(FP), R4
|
||||
CALL R6
|
||||
MOVD R0, ret+48(FP)
|
||||
RET
|
90
vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_stubs.s
generated
vendored
Normal file
90
vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_stubs.s
generated
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
// Code generated by 'go generate' with gen.go. DO NOT EDIT.
|
||||
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build darwin || freebsd || linux
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// these stubs are here because it is not possible to go:linkname directly the C functions on darwin arm64
|
||||
|
||||
TEXT _malloc(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_malloc(SB)
|
||||
RET
|
||||
|
||||
TEXT _free(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_free(SB)
|
||||
RET
|
||||
|
||||
TEXT _setenv(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_setenv(SB)
|
||||
RET
|
||||
|
||||
TEXT _unsetenv(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_unsetenv(SB)
|
||||
RET
|
||||
|
||||
TEXT _sigfillset(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_sigfillset(SB)
|
||||
RET
|
||||
|
||||
TEXT _nanosleep(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_nanosleep(SB)
|
||||
RET
|
||||
|
||||
TEXT _abort(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_abort(SB)
|
||||
RET
|
||||
|
||||
TEXT _pthread_attr_init(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_attr_init(SB)
|
||||
RET
|
||||
|
||||
TEXT _pthread_create(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_create(SB)
|
||||
RET
|
||||
|
||||
TEXT _pthread_detach(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_detach(SB)
|
||||
RET
|
||||
|
||||
TEXT _pthread_sigmask(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_sigmask(SB)
|
||||
RET
|
||||
|
||||
TEXT _pthread_self(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_self(SB)
|
||||
RET
|
||||
|
||||
TEXT _pthread_get_stacksize_np(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_get_stacksize_np(SB)
|
||||
RET
|
||||
|
||||
TEXT _pthread_attr_getstacksize(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_attr_getstacksize(SB)
|
||||
RET
|
||||
|
||||
TEXT _pthread_attr_setstacksize(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_attr_setstacksize(SB)
|
||||
RET
|
||||
|
||||
TEXT _pthread_attr_destroy(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_attr_destroy(SB)
|
||||
RET
|
||||
|
||||
TEXT _pthread_mutex_lock(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_mutex_lock(SB)
|
||||
RET
|
||||
|
||||
TEXT _pthread_mutex_unlock(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_mutex_unlock(SB)
|
||||
RET
|
||||
|
||||
TEXT _pthread_cond_broadcast(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_cond_broadcast(SB)
|
||||
RET
|
||||
|
||||
TEXT _pthread_setspecific(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_setspecific(SB)
|
||||
RET
|
40
vendor/github.com/ebitengine/purego/internal/strings/strings.go
generated
vendored
Normal file
40
vendor/github.com/ebitengine/purego/internal/strings/strings.go
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
package strings
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// hasSuffix tests whether the string s ends with suffix.
|
||||
func hasSuffix(s, suffix string) bool {
|
||||
return len(s) >= len(suffix) && s[len(s)-len(suffix):] == suffix
|
||||
}
|
||||
|
||||
// CString converts a go string to *byte that can be passed to C code.
|
||||
func CString(name string) *byte {
|
||||
if hasSuffix(name, "\x00") {
|
||||
return &(*(*[]byte)(unsafe.Pointer(&name)))[0]
|
||||
}
|
||||
b := make([]byte, len(name)+1)
|
||||
copy(b, name)
|
||||
return &b[0]
|
||||
}
|
||||
|
||||
// GoString copies a null-terminated char* to a Go string.
|
||||
func GoString(c uintptr) string {
|
||||
// We take the address and then dereference it to trick go vet from creating a possible misuse of unsafe.Pointer
|
||||
ptr := *(*unsafe.Pointer)(unsafe.Pointer(&c))
|
||||
if ptr == nil {
|
||||
return ""
|
||||
}
|
||||
var length int
|
||||
for {
|
||||
if *(*byte)(unsafe.Add(ptr, uintptr(length))) == '\x00' {
|
||||
break
|
||||
}
|
||||
length++
|
||||
}
|
||||
return string(unsafe.Slice((*byte)(ptr), length))
|
||||
}
|
13
vendor/github.com/ebitengine/purego/is_ios.go
generated
vendored
Normal file
13
vendor/github.com/ebitengine/purego/is_ios.go
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo
|
||||
|
||||
package purego
|
||||
|
||||
// if you are getting this error it means that you have
|
||||
// CGO_ENABLED=0 while trying to build for ios.
|
||||
// purego does not support this mode yet.
|
||||
// the fix is to set CGO_ENABLED=1 which will require
|
||||
// a C compiler.
|
||||
var _ = _PUREGO_REQUIRES_CGO_ON_IOS
|
25
vendor/github.com/ebitengine/purego/nocgo.go
generated
vendored
Normal file
25
vendor/github.com/ebitengine/purego/nocgo.go
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo && (darwin || freebsd || linux)
|
||||
|
||||
package purego
|
||||
|
||||
// if CGO_ENABLED=0 import fakecgo to setup the Cgo runtime correctly.
|
||||
// This is required since some frameworks need TLS setup the C way which Go doesn't do.
|
||||
// We currently don't support ios in fakecgo mode so force Cgo or fail
|
||||
//
|
||||
// The way that the Cgo runtime (runtime/cgo) works is by setting some variables found
|
||||
// in runtime with non-null GCC compiled functions. The variables that are replaced are
|
||||
// var (
|
||||
// iscgo bool // in runtime/cgo.go
|
||||
// _cgo_init unsafe.Pointer // in runtime/cgo.go
|
||||
// _cgo_thread_start unsafe.Pointer // in runtime/cgo.go
|
||||
// _cgo_notify_runtime_init_done unsafe.Pointer // in runtime/cgo.go
|
||||
// _cgo_setenv unsafe.Pointer // in runtime/env_posix.go
|
||||
// _cgo_unsetenv unsafe.Pointer // in runtime/env_posix.go
|
||||
// )
|
||||
// importing fakecgo will set these (using //go:linkname) with functions written
|
||||
// entirely in Go (except for some assembly trampolines to change GCC ABI to Go ABI).
|
||||
// Doing so makes it possible to build applications that call into C without CGO_ENABLED=1.
|
||||
import _ "github.com/ebitengine/purego/internal/fakecgo"
|
143
vendor/github.com/ebitengine/purego/sys_amd64.s
generated
vendored
Normal file
143
vendor/github.com/ebitengine/purego/sys_amd64.s
generated
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build darwin || freebsd || (!cgo && linux)
|
||||
|
||||
#include "textflag.h"
|
||||
#include "abi_amd64.h"
|
||||
#include "go_asm.h"
|
||||
#include "funcdata.h"
|
||||
|
||||
// syscall9X calls a function in libc on behalf of the syscall package.
|
||||
// syscall9X takes a pointer to a struct like:
|
||||
// struct {
|
||||
// fn uintptr
|
||||
// a1 uintptr
|
||||
// a2 uintptr
|
||||
// a3 uintptr
|
||||
// a4 uintptr
|
||||
// a5 uintptr
|
||||
// a6 uintptr
|
||||
// a7 uintptr
|
||||
// a8 uintptr
|
||||
// a9 uintptr
|
||||
// r1 uintptr
|
||||
// r2 uintptr
|
||||
// err uintptr
|
||||
// }
|
||||
// syscall9X must be called on the g0 stack with the
|
||||
// C calling convention (use libcCall).
|
||||
GLOBL ·syscall9XABI0(SB), NOPTR|RODATA, $8
|
||||
DATA ·syscall9XABI0(SB)/8, $syscall9X(SB)
|
||||
TEXT syscall9X(SB), NOSPLIT|NOFRAME, $0
|
||||
PUSHQ BP
|
||||
MOVQ SP, BP
|
||||
SUBQ $32, SP
|
||||
MOVQ DI, 24(BP) // save the pointer
|
||||
|
||||
MOVQ syscall9Args_f1(DI), X0 // f1
|
||||
MOVQ syscall9Args_f2(DI), X1 // f2
|
||||
MOVQ syscall9Args_f3(DI), X2 // f3
|
||||
MOVQ syscall9Args_f4(DI), X3 // f4
|
||||
MOVQ syscall9Args_f5(DI), X4 // f5
|
||||
MOVQ syscall9Args_f6(DI), X5 // f6
|
||||
MOVQ syscall9Args_f7(DI), X6 // f7
|
||||
MOVQ syscall9Args_f8(DI), X7 // f8
|
||||
|
||||
MOVQ syscall9Args_fn(DI), R10 // fn
|
||||
MOVQ syscall9Args_a2(DI), SI // a2
|
||||
MOVQ syscall9Args_a3(DI), DX // a3
|
||||
MOVQ syscall9Args_a4(DI), CX // a4
|
||||
MOVQ syscall9Args_a5(DI), R8 // a5
|
||||
MOVQ syscall9Args_a6(DI), R9 // a6
|
||||
MOVQ syscall9Args_a7(DI), R11 // a7
|
||||
MOVQ syscall9Args_a8(DI), R12 // a8
|
||||
MOVQ syscall9Args_a9(DI), R13 // a9
|
||||
MOVQ syscall9Args_a1(DI), DI // a1
|
||||
|
||||
// push the remaining paramters onto the stack
|
||||
MOVQ R11, 0(SP) // push a7
|
||||
MOVQ R12, 8(SP) // push a8
|
||||
MOVQ R13, 16(SP) // push a9
|
||||
XORL AX, AX // vararg: say "no float args"
|
||||
|
||||
CALL R10
|
||||
|
||||
MOVQ 24(BP), DI // get the pointer back
|
||||
MOVQ AX, syscall9Args_r1(DI) // r1
|
||||
MOVQ X0, syscall9Args_r2(DI) // r2
|
||||
|
||||
XORL AX, AX // no error (it's ignored anyway)
|
||||
ADDQ $32, SP
|
||||
MOVQ BP, SP
|
||||
POPQ BP
|
||||
RET
|
||||
|
||||
TEXT callbackasm1(SB), NOSPLIT|NOFRAME, $0
|
||||
// remove return address from stack, we are not returning to callbackasm, but to its caller.
|
||||
MOVQ 0(SP), AX
|
||||
ADDQ $8, SP
|
||||
|
||||
MOVQ 0(SP), R10 // get the return SP so that we can align register args with stack args
|
||||
|
||||
// make space for first six int and 8 float arguments below the frame
|
||||
ADJSP $14*8, SP
|
||||
MOVSD X0, (1*8)(SP)
|
||||
MOVSD X1, (2*8)(SP)
|
||||
MOVSD X2, (3*8)(SP)
|
||||
MOVSD X3, (4*8)(SP)
|
||||
MOVSD X4, (5*8)(SP)
|
||||
MOVSD X5, (6*8)(SP)
|
||||
MOVSD X6, (7*8)(SP)
|
||||
MOVSD X7, (8*8)(SP)
|
||||
MOVQ DI, (9*8)(SP)
|
||||
MOVQ SI, (10*8)(SP)
|
||||
MOVQ DX, (11*8)(SP)
|
||||
MOVQ CX, (12*8)(SP)
|
||||
MOVQ R8, (13*8)(SP)
|
||||
MOVQ R9, (14*8)(SP)
|
||||
LEAQ 8(SP), R8 // R8 = address of args vector
|
||||
|
||||
MOVQ R10, 0(SP) // push the stack pointer below registers
|
||||
|
||||
// determine index into runtime·cbs table
|
||||
MOVQ $callbackasm(SB), DX
|
||||
SUBQ DX, AX
|
||||
MOVQ $0, DX
|
||||
MOVQ $5, CX // divide by 5 because each call instruction in ·callbacks is 5 bytes long
|
||||
DIVL CX
|
||||
SUBQ $1, AX // subtract 1 because return PC is to the next slot
|
||||
|
||||
// Switch from the host ABI to the Go ABI.
|
||||
PUSH_REGS_HOST_TO_ABI0()
|
||||
|
||||
// Create a struct callbackArgs on our stack to be passed as
|
||||
// the "frame" to cgocallback and on to callbackWrap.
|
||||
// $24 to make enough room for the arguments to runtime.cgocallback
|
||||
SUBQ $(24+callbackArgs__size), SP
|
||||
MOVQ AX, (24+callbackArgs_index)(SP) // callback index
|
||||
MOVQ R8, (24+callbackArgs_args)(SP) // address of args vector
|
||||
MOVQ $0, (24+callbackArgs_result)(SP) // result
|
||||
LEAQ 24(SP), AX // take the address of callbackArgs
|
||||
|
||||
// Call cgocallback, which will call callbackWrap(frame).
|
||||
MOVQ ·callbackWrap_call(SB), DI // Get the ABIInternal function pointer
|
||||
MOVQ (DI), DI // without <ABIInternal> by using a closure.
|
||||
MOVQ AX, SI // frame (address of callbackArgs)
|
||||
MOVQ $0, CX // context
|
||||
|
||||
CALL crosscall2(SB) // runtime.cgocallback(fn, frame, ctxt uintptr)
|
||||
|
||||
// Get callback result.
|
||||
MOVQ (24+callbackArgs_result)(SP), AX
|
||||
ADDQ $(24+callbackArgs__size), SP // remove callbackArgs struct
|
||||
|
||||
POP_REGS_HOST_TO_ABI0()
|
||||
|
||||
MOVQ 0(SP), R10 // get the SP back
|
||||
|
||||
ADJSP $-14*8, SP // remove arguments
|
||||
|
||||
MOVQ R10, 0(SP)
|
||||
|
||||
RET
|
63
vendor/github.com/ebitengine/purego/sys_arm64.s
generated
vendored
Normal file
63
vendor/github.com/ebitengine/purego/sys_arm64.s
generated
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build darwin || freebsd || (!cgo && linux) || windows
|
||||
|
||||
#include "textflag.h"
|
||||
#include "go_asm.h"
|
||||
#include "funcdata.h"
|
||||
|
||||
// syscall9X calls a function in libc on behalf of the syscall package.
|
||||
// syscall9X takes a pointer to a struct like:
|
||||
// struct {
|
||||
// fn uintptr
|
||||
// a1 uintptr
|
||||
// a2 uintptr
|
||||
// a3 uintptr
|
||||
// a4 uintptr
|
||||
// a5 uintptr
|
||||
// a6 uintptr
|
||||
// a7 uintptr
|
||||
// a8 uintptr
|
||||
// a9 uintptr
|
||||
// r1 uintptr
|
||||
// r2 uintptr
|
||||
// err uintptr
|
||||
// }
|
||||
// syscall9X must be called on the g0 stack with the
|
||||
// C calling convention (use libcCall).
|
||||
GLOBL ·syscall9XABI0(SB), NOPTR|RODATA, $8
|
||||
DATA ·syscall9XABI0(SB)/8, $syscall9X(SB)
|
||||
TEXT syscall9X(SB), NOSPLIT, $0
|
||||
SUB $16, RSP // push structure pointer
|
||||
MOVD R0, 8(RSP)
|
||||
|
||||
FMOVD syscall9Args_f1(R0), F0 // f1
|
||||
FMOVD syscall9Args_f2(R0), F1 // f2
|
||||
FMOVD syscall9Args_f3(R0), F2 // f3
|
||||
FMOVD syscall9Args_f4(R0), F3 // f4
|
||||
FMOVD syscall9Args_f5(R0), F4 // f5
|
||||
FMOVD syscall9Args_f6(R0), F5 // f6
|
||||
FMOVD syscall9Args_f7(R0), F6 // f7
|
||||
FMOVD syscall9Args_f8(R0), F7 // f8
|
||||
|
||||
MOVD syscall9Args_fn(R0), R12 // fn
|
||||
MOVD syscall9Args_a2(R0), R1 // a2
|
||||
MOVD syscall9Args_a3(R0), R2 // a3
|
||||
MOVD syscall9Args_a4(R0), R3 // a4
|
||||
MOVD syscall9Args_a5(R0), R4 // a5
|
||||
MOVD syscall9Args_a6(R0), R5 // a6
|
||||
MOVD syscall9Args_a7(R0), R6 // a7
|
||||
MOVD syscall9Args_a8(R0), R7 // a8
|
||||
MOVD syscall9Args_a9(R0), R8 // a9
|
||||
MOVD syscall9Args_a1(R0), R0 // a1
|
||||
|
||||
MOVD R8, (RSP) // push a9 onto stack
|
||||
|
||||
BL (R12)
|
||||
|
||||
MOVD 8(RSP), R2 // pop structure pointer
|
||||
ADD $16, RSP
|
||||
MOVD R0, syscall9Args_r1(R2) // save r1
|
||||
FMOVD F0, syscall9Args_r2(R2) // save r2
|
||||
RET
|
70
vendor/github.com/ebitengine/purego/sys_unix_arm64.s
generated
vendored
Normal file
70
vendor/github.com/ebitengine/purego/sys_unix_arm64.s
generated
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2023 The Ebitengine Authors
|
||||
|
||||
//go:build darwin || freebsd || (!cgo && linux)
|
||||
|
||||
#include "textflag.h"
|
||||
#include "go_asm.h"
|
||||
#include "funcdata.h"
|
||||
#include "abi_arm64.h"
|
||||
|
||||
TEXT callbackasm1(SB), NOSPLIT|NOFRAME, $0
|
||||
NO_LOCAL_POINTERS
|
||||
|
||||
// On entry, the trampoline in zcallback_darwin_arm64.s left
|
||||
// the callback index in R12 (which is volatile in the C ABI).
|
||||
|
||||
// Save callback register arguments R0-R7 and F0-F7.
|
||||
// We do this at the top of the frame so they're contiguous with stack arguments.
|
||||
SUB $(16*8), RSP, R14
|
||||
FSTPD (F0, F1), (0*8)(R14)
|
||||
FSTPD (F2, F3), (2*8)(R14)
|
||||
FSTPD (F4, F5), (4*8)(R14)
|
||||
FSTPD (F6, F7), (6*8)(R14)
|
||||
STP (R0, R1), (8*8)(R14)
|
||||
STP (R2, R3), (10*8)(R14)
|
||||
STP (R4, R5), (12*8)(R14)
|
||||
STP (R6, R7), (14*8)(R14)
|
||||
|
||||
// Adjust SP by frame size.
|
||||
SUB $(26*8), RSP
|
||||
|
||||
// It is important to save R27 because the go assembler
|
||||
// uses it for move instructions for a variable.
|
||||
// This line:
|
||||
// MOVD ·callbackWrap_call(SB), R0
|
||||
// Creates the instructions:
|
||||
// ADRP 14335(PC), R27
|
||||
// MOVD 388(27), R0
|
||||
// R27 is a callee saved register so we are responsible
|
||||
// for ensuring its value doesn't change. So save it and
|
||||
// restore it at the end of this function.
|
||||
// R30 is the link register. crosscall2 doesn't save it
|
||||
// so it's saved here.
|
||||
STP (R27, R30), 0(RSP)
|
||||
|
||||
// Create a struct callbackArgs on our stack.
|
||||
MOVD $(callbackArgs__size)(RSP), R13
|
||||
MOVD R12, callbackArgs_index(R13) // callback index
|
||||
MOVD R14, callbackArgs_args(R13) // address of args vector
|
||||
MOVD ZR, callbackArgs_result(R13) // result
|
||||
|
||||
// Move parameters into registers
|
||||
// Get the ABIInternal function pointer
|
||||
// without <ABIInternal> by using a closure.
|
||||
MOVD ·callbackWrap_call(SB), R0
|
||||
MOVD (R0), R0 // fn unsafe.Pointer
|
||||
MOVD R13, R1 // frame (&callbackArgs{...})
|
||||
MOVD $0, R3 // ctxt uintptr
|
||||
|
||||
BL crosscall2(SB)
|
||||
|
||||
// Get callback result.
|
||||
MOVD $(callbackArgs__size)(RSP), R13
|
||||
MOVD callbackArgs_result(R13), R0
|
||||
|
||||
// Restore LR and R27
|
||||
LDP 0(RSP), (R27, R30)
|
||||
ADD $(26*8), RSP
|
||||
|
||||
RET
|
40
vendor/github.com/ebitengine/purego/syscall.go
generated
vendored
Normal file
40
vendor/github.com/ebitengine/purego/syscall.go
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build darwin || freebsd || linux || windows
|
||||
|
||||
package purego
|
||||
|
||||
const (
|
||||
maxArgs = 9
|
||||
numOfFloats = 8 // arm64 and amd64 both have 8 float registers
|
||||
)
|
||||
|
||||
// SyscallN takes fn, a C function pointer and a list of arguments as uintptr.
|
||||
// There is an internal maximum number of arguments that SyscallN can take. It panics
|
||||
// when the maximum is exceeded. It returns the result and the libc error code if there is one.
|
||||
//
|
||||
// NOTE: SyscallN does not properly call functions that have both integer and float parameters.
|
||||
// See discussion comment https://github.com/ebiten/purego/pull/1#issuecomment-1128057607
|
||||
// for an explanation of why that is.
|
||||
//
|
||||
// On amd64, if there are more than 8 floats the 9th and so on will be placed incorrectly on the
|
||||
// stack.
|
||||
//
|
||||
// The pragma go:nosplit is not needed at this function declaration because it uses go:uintptrescapes
|
||||
// which forces all the objects that the uintptrs point to onto the heap where a stack split won't affect
|
||||
// their memory location.
|
||||
//
|
||||
//go:uintptrescapes
|
||||
func SyscallN(fn uintptr, args ...uintptr) (r1, r2, err uintptr) {
|
||||
if fn == 0 {
|
||||
panic("purego: fn is nil")
|
||||
}
|
||||
if len(args) > maxArgs {
|
||||
panic("purego: too many arguments to SyscallN")
|
||||
}
|
||||
// add padding so there is no out-of-bounds slicing
|
||||
var tmp [maxArgs]uintptr
|
||||
copy(tmp[:], args)
|
||||
return syscall_syscall9X(fn, tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5], tmp[6], tmp[7], tmp[8])
|
||||
}
|
30
vendor/github.com/ebitengine/purego/syscall_cgo_linux.go
generated
vendored
Normal file
30
vendor/github.com/ebitengine/purego/syscall_cgo_linux.go
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build cgo
|
||||
|
||||
package purego
|
||||
|
||||
import (
|
||||
_ "unsafe" // for go:linkname
|
||||
|
||||
"github.com/ebitengine/purego/internal/cgo"
|
||||
)
|
||||
|
||||
var syscall9XABI0 = uintptr(cgo.Syscall9XABI0)
|
||||
|
||||
// this is only here to make the assembly files happy :)
|
||||
type syscall9Args struct {
|
||||
fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr
|
||||
f1, f2, f3, f4, f5, f6, f7, f8 uintptr
|
||||
r1, r2, err uintptr
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func syscall_syscall9X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2, err uintptr) {
|
||||
return cgo.Syscall9X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9)
|
||||
}
|
||||
|
||||
func NewCallback(_ interface{}) uintptr {
|
||||
panic("purego: NewCallback not supported")
|
||||
}
|
214
vendor/github.com/ebitengine/purego/syscall_sysv.go
generated
vendored
Normal file
214
vendor/github.com/ebitengine/purego/syscall_sysv.go
generated
vendored
Normal file
@@ -0,0 +1,214 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build darwin || freebsd || (!cgo && linux && (amd64 || arm64))
|
||||
|
||||
package purego
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"runtime"
|
||||
"sync"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var syscall9XABI0 uintptr
|
||||
|
||||
type syscall9Args struct {
|
||||
fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr
|
||||
f1, f2, f3, f4, f5, f6, f7, f8 uintptr
|
||||
r1, r2, err uintptr
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func syscall_syscall9X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2, err uintptr) {
|
||||
args := syscall9Args{
|
||||
fn, a1, a2, a3, a4, a5, a6, a7, a8, a9,
|
||||
a1, a2, a3, a4, a5, a6, a7, a8,
|
||||
r1, r2, err,
|
||||
}
|
||||
runtime_cgocall(syscall9XABI0, unsafe.Pointer(&args))
|
||||
return args.r1, args.r2, args.err
|
||||
}
|
||||
|
||||
// NewCallback converts a Go function to a function pointer conforming to the C calling convention.
|
||||
// This is useful when interoperating with C code requiring callbacks. The argument is expected to be a
|
||||
// function with zero or one uintptr-sized result. The function must not have arguments with size larger than the size
|
||||
// of uintptr. Only a limited number of callbacks may be created in a single Go process, and any memory allocated
|
||||
// for these callbacks is never released. At least 2000 callbacks can always be created. Although this function
|
||||
// provides similar functionality to windows.NewCallback it is distinct.
|
||||
//
|
||||
// NOTE: Linux is currently not supported and will panic if called.
|
||||
func NewCallback(fn interface{}) uintptr {
|
||||
if runtime.GOOS == "linux" {
|
||||
panic("purego: NewCallback not supported")
|
||||
}
|
||||
return compileCallback(fn)
|
||||
}
|
||||
|
||||
// maxCb is the maximum number of callbacks
|
||||
// only increase this if you have added more to the callbackasm function
|
||||
const maxCB = 2000
|
||||
|
||||
var cbs struct {
|
||||
lock sync.Mutex
|
||||
numFn int // the number of functions currently in cbs.funcs
|
||||
funcs [maxCB]reflect.Value // the saved callbacks
|
||||
}
|
||||
|
||||
type callbackArgs struct {
|
||||
index uintptr
|
||||
// args points to the argument block.
|
||||
//
|
||||
// The structure of the arguments goes
|
||||
// float registers followed by the
|
||||
// integer registers followed by the stack.
|
||||
//
|
||||
// This variable is treated as a continuous
|
||||
// block of memory containing all of the arguments
|
||||
// for this callback.
|
||||
args unsafe.Pointer
|
||||
// Below are out-args from callbackWrap
|
||||
result uintptr
|
||||
}
|
||||
|
||||
func compileCallback(fn interface{}) uintptr {
|
||||
val := reflect.ValueOf(fn)
|
||||
if val.Kind() != reflect.Func {
|
||||
panic("purego: the type must be a function but was not")
|
||||
}
|
||||
if val.IsNil() {
|
||||
panic("purego: function must not be nil")
|
||||
}
|
||||
ty := val.Type()
|
||||
for i := 0; i < ty.NumIn(); i++ {
|
||||
in := ty.In(i)
|
||||
switch in.Kind() {
|
||||
case reflect.Struct, reflect.Interface, reflect.Func, reflect.Slice,
|
||||
reflect.Chan, reflect.Complex64, reflect.Complex128,
|
||||
reflect.String, reflect.Map, reflect.Invalid:
|
||||
panic("purego: unsupported argument type: " + in.Kind().String())
|
||||
}
|
||||
}
|
||||
output:
|
||||
switch {
|
||||
case ty.NumOut() == 1:
|
||||
switch ty.Out(0).Kind() {
|
||||
case reflect.Pointer, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
|
||||
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr,
|
||||
reflect.Bool, reflect.UnsafePointer:
|
||||
break output
|
||||
}
|
||||
panic("purego: unsupported return type: " + ty.String())
|
||||
case ty.NumOut() > 1:
|
||||
panic("purego: callbacks can only have one return")
|
||||
}
|
||||
cbs.lock.Lock()
|
||||
defer cbs.lock.Unlock()
|
||||
if cbs.numFn >= maxCB {
|
||||
panic("purego: the maximum number of callbacks has been reached")
|
||||
}
|
||||
cbs.funcs[cbs.numFn] = val
|
||||
cbs.numFn++
|
||||
return callbackasmAddr(cbs.numFn - 1)
|
||||
}
|
||||
|
||||
const ptrSize = unsafe.Sizeof((*int)(nil))
|
||||
|
||||
const callbackMaxFrame = 64 * ptrSize
|
||||
|
||||
// callbackasm is implemented in zcallback_GOOS_GOARCH.s
|
||||
//
|
||||
//go:linkname __callbackasm callbackasm
|
||||
var __callbackasm byte
|
||||
var callbackasmABI0 = uintptr(unsafe.Pointer(&__callbackasm))
|
||||
|
||||
// callbackWrap_call allows the calling of the ABIInternal wrapper
|
||||
// which is required for runtime.cgocallback without the
|
||||
// <ABIInternal> tag which is only allowed in the runtime.
|
||||
// This closure is used inside sys_darwin_GOARCH.s
|
||||
var callbackWrap_call = callbackWrap
|
||||
|
||||
// callbackWrap is called by assembly code which determines which Go function to call.
|
||||
// This function takes the arguments and passes them to the Go function and returns the result.
|
||||
func callbackWrap(a *callbackArgs) {
|
||||
cbs.lock.Lock()
|
||||
fn := cbs.funcs[a.index]
|
||||
cbs.lock.Unlock()
|
||||
fnType := fn.Type()
|
||||
args := make([]reflect.Value, fnType.NumIn())
|
||||
frame := (*[callbackMaxFrame]uintptr)(a.args)
|
||||
var floatsN int // floatsN represents the number of float arguments processed
|
||||
var intsN int // intsN represents the number of integer arguments processed
|
||||
// stack points to the index into frame of the current stack element.
|
||||
// The stack begins after the float and integer registers.
|
||||
stack := numOfIntegerRegisters() + numOfFloats
|
||||
for i := range args {
|
||||
var pos int
|
||||
switch fnType.In(i).Kind() {
|
||||
case reflect.Float32, reflect.Float64:
|
||||
if floatsN >= numOfFloats {
|
||||
pos = stack
|
||||
stack++
|
||||
} else {
|
||||
pos = floatsN
|
||||
}
|
||||
floatsN++
|
||||
default:
|
||||
if intsN >= numOfIntegerRegisters() {
|
||||
pos = stack
|
||||
stack++
|
||||
} else {
|
||||
// the integers begin after the floats in frame
|
||||
pos = intsN + numOfFloats
|
||||
}
|
||||
intsN++
|
||||
}
|
||||
args[i] = reflect.NewAt(fnType.In(i), unsafe.Pointer(&frame[pos])).Elem()
|
||||
}
|
||||
ret := fn.Call(args)
|
||||
if len(ret) > 0 {
|
||||
switch k := ret[0].Kind(); k {
|
||||
case reflect.Uint, reflect.Uint64, reflect.Uint32, reflect.Uint16, reflect.Uint8, reflect.Uintptr:
|
||||
a.result = uintptr(ret[0].Uint())
|
||||
case reflect.Int, reflect.Int64, reflect.Int32, reflect.Int16, reflect.Int8:
|
||||
a.result = uintptr(ret[0].Int())
|
||||
case reflect.Bool:
|
||||
if ret[0].Bool() {
|
||||
a.result = 1
|
||||
} else {
|
||||
a.result = 0
|
||||
}
|
||||
case reflect.Pointer:
|
||||
a.result = ret[0].Pointer()
|
||||
case reflect.UnsafePointer:
|
||||
a.result = ret[0].Pointer()
|
||||
default:
|
||||
panic("purego: unsupported kind: " + k.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// callbackasmAddr returns address of runtime.callbackasm
|
||||
// function adjusted by i.
|
||||
// On x86 and amd64, runtime.callbackasm is a series of CALL instructions,
|
||||
// and we want callback to arrive at
|
||||
// correspondent call instruction instead of start of
|
||||
// runtime.callbackasm.
|
||||
// On ARM, runtime.callbackasm is a series of mov and branch instructions.
|
||||
// R12 is loaded with the callback index. Each entry is two instructions,
|
||||
// hence 8 bytes.
|
||||
func callbackasmAddr(i int) uintptr {
|
||||
var entrySize int
|
||||
switch runtime.GOARCH {
|
||||
default:
|
||||
panic("purego: unsupported architecture")
|
||||
case "386", "amd64":
|
||||
entrySize = 5
|
||||
case "arm", "arm64":
|
||||
// On ARM and ARM64, each entry is a MOV instruction
|
||||
// followed by a branch instruction
|
||||
entrySize = 8
|
||||
}
|
||||
return callbackasmABI0 + uintptr(i*entrySize)
|
||||
}
|
45
vendor/github.com/ebitengine/purego/syscall_windows.go
generated
vendored
Normal file
45
vendor/github.com/ebitengine/purego/syscall_windows.go
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
package purego
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
_ "unsafe" // only for go:linkname
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
var syscall9XABI0 uintptr
|
||||
|
||||
type syscall9Args struct {
|
||||
fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr
|
||||
f1, f2, f3, f4, f5, f6, f7, f8 uintptr
|
||||
r1, r2, err uintptr
|
||||
}
|
||||
|
||||
func syscall_syscall9X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2, err uintptr) {
|
||||
r1, r2, errno := syscall.Syscall9(fn, 9, a1, a2, a3, a4, a5, a6, a7, a8, a9)
|
||||
return r1, r2, uintptr(errno)
|
||||
}
|
||||
|
||||
// NewCallback converts a Go function to a function pointer conforming to the stdcall calling convention.
|
||||
// This is useful when interoperating with Windows code requiring callbacks. The argument is expected to be a
|
||||
// function with one uintptr-sized result. The function must not have arguments with size larger than the
|
||||
// size of uintptr. Only a limited number of callbacks may be created in a single Go process, and any memory
|
||||
// allocated for these callbacks is never released. Between NewCallback and NewCallbackCDecl, at least 1024
|
||||
// callbacks can always be created. Although this function is similiar to the darwin version it may act
|
||||
// differently.
|
||||
func NewCallback(fn interface{}) uintptr {
|
||||
return syscall.NewCallback(fn)
|
||||
}
|
||||
|
||||
//go:linkname openLibrary openLibrary
|
||||
func openLibrary(name string) (uintptr, error) {
|
||||
handle, err := windows.LoadLibrary(name)
|
||||
return uintptr(handle), err
|
||||
}
|
||||
|
||||
func loadSymbol(handle uintptr, name string) (uintptr, error) {
|
||||
return windows.GetProcAddress(windows.Handle(handle), name)
|
||||
}
|
2014
vendor/github.com/ebitengine/purego/zcallback_amd64.s
generated
vendored
Normal file
2014
vendor/github.com/ebitengine/purego/zcallback_amd64.s
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
4014
vendor/github.com/ebitengine/purego/zcallback_arm64.s
generated
vendored
Normal file
4014
vendor/github.com/ebitengine/purego/zcallback_arm64.s
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user