diff --git a/.circleci/config.yml b/.circleci/config.yml index e2069e3485..a3a052c28c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -109,9 +109,9 @@ jobs: # "make lint" fails before go 1.21 because internal/tools/go.mod specifies packages that require go 1.21 fmt-check: false resource_class: large - test-llvm19-go123: + test-llvm19-go124: docker: - - image: golang:1.23-bullseye + - image: golang:1.24-bullseye steps: - test-linux: llvm: "19" @@ -124,4 +124,4 @@ workflows: # least the smoke tests still pass. - test-llvm15-go119 # This tests LLVM 19 support when linking against system libraries. - - test-llvm19-go123 + - test-llvm19-go124 diff --git a/.github/workflows/build-macos.yml b/.github/workflows/build-macos.yml index 07b0d307d0..25b5971783 100644 --- a/.github/workflows/build-macos.yml +++ b/.github/workflows/build-macos.yml @@ -39,7 +39,7 @@ jobs: - name: Install Go uses: actions/setup-go@v5 with: - go-version: '1.23' + go-version: '1.24' cache: true - name: Restore LLVM source cache uses: actions/cache/restore@v4 @@ -143,7 +143,7 @@ jobs: - name: Install Go uses: actions/setup-go@v5 with: - go-version: '1.23' + go-version: '1.24' cache: true - name: Build TinyGo (LLVM ${{ matrix.version }}) run: go install -tags=llvm${{ matrix.version }} diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 139b7d03b7..3cbf33c6b0 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -18,7 +18,7 @@ jobs: # statically linked binary. runs-on: ubuntu-latest container: - image: golang:1.23-alpine + image: golang:1.24-alpine outputs: version: ${{ steps.version.outputs.version }} steps: @@ -146,7 +146,7 @@ jobs: - name: Install Go uses: actions/setup-go@v5 with: - go-version: '1.23' + go-version: '1.24' cache: true - name: Install wasmtime uses: bytecodealliance/actions/wasmtime/setup@v1 @@ -189,7 +189,7 @@ jobs: - name: Install Go uses: actions/setup-go@v5 with: - go-version: '1.23' + go-version: '1.24' cache: true - name: Install Node.js uses: actions/setup-node@v4 @@ -315,7 +315,7 @@ jobs: - name: Install Go uses: actions/setup-go@v5 with: - go-version: '1.23' + go-version: '1.24' cache: true - name: Restore LLVM source cache uses: actions/cache/restore@v4 diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index e1794ef13b..42365f59b7 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -41,7 +41,7 @@ jobs: - name: Install Go uses: actions/setup-go@v5 with: - go-version: '1.23' + go-version: '1.24' cache: true - name: Restore cached LLVM source uses: actions/cache/restore@v4 @@ -156,7 +156,7 @@ jobs: - name: Install Go uses: actions/setup-go@v5 with: - go-version: '1.23' + go-version: '1.24' cache: true - name: Download TinyGo build uses: actions/download-artifact@v4 @@ -186,7 +186,7 @@ jobs: - name: Install Go uses: actions/setup-go@v5 with: - go-version: '1.23' + go-version: '1.24' cache: true - name: Download TinyGo build uses: actions/download-artifact@v4 @@ -222,7 +222,7 @@ jobs: - name: Install Go uses: actions/setup-go@v5 with: - go-version: '1.23' + go-version: '1.24' cache: true - name: Download TinyGo build uses: actions/download-artifact@v4 diff --git a/Dockerfile b/Dockerfile index 9a9effac2b..520ad7c9b5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # tinygo-llvm stage obtains the llvm source for TinyGo -FROM golang:1.23 AS tinygo-llvm +FROM golang:1.24 AS tinygo-llvm RUN apt-get update && \ apt-get install -y apt-utils make cmake clang-15 ninja-build && \ @@ -33,7 +33,7 @@ RUN cd /tinygo/ && \ # tinygo-compiler copies the compiler build over to a base Go container (without # all the build tools etc). -FROM golang:1.23 AS tinygo-compiler +FROM golang:1.24 AS tinygo-compiler # Copy tinygo build. COPY --from=tinygo-compiler-build /tinygo/build/release/tinygo /tinygo diff --git a/GNUmakefile b/GNUmakefile index 423a2a20e0..a13b8fc562 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -309,11 +309,9 @@ TEST_PACKAGES_FAST = \ container/heap \ container/list \ container/ring \ - crypto/des \ crypto/ecdsa \ crypto/elliptic \ crypto/md5 \ - crypto/rc4 \ crypto/sha1 \ crypto/sha256 \ crypto/sha512 \ @@ -355,17 +353,11 @@ TEST_PACKAGES_FAST = \ unique \ $(nil) -# Assume this will go away before Go2, so only check minor version. -ifeq ($(filter $(shell $(GO) env GOVERSION | cut -f 2 -d.), 16 17 18), ) -TEST_PACKAGES_FAST += crypto/internal/nistec/fiat -else -TEST_PACKAGES_FAST += crypto/elliptic/internal/fiat -endif - # archive/zip requires os.ReadAt, which is not yet supported on windows # bytes requires mmap # compress/flate appears to hang on wasi # crypto/aes fails on wasi, needs panic()/recover() +# crypto/des fails on wasi, needs panic()/recover() # crypto/hmac fails on wasi, it exits with a "slice out of range" panic # debug/plan9obj requires os.ReadAt, which is not yet supported on windows # image requires recover(), which is not yet supported on wasi @@ -386,6 +378,7 @@ TEST_PACKAGES_LINUX := \ archive/zip \ compress/flate \ crypto/aes \ + crypto/des \ crypto/hmac \ debug/dwarf \ debug/plan9obj \ @@ -407,6 +400,7 @@ TEST_PACKAGES_DARWIN := $(TEST_PACKAGES_LINUX) TEST_PACKAGES_WINDOWS := \ compress/flate \ + crypto/des \ crypto/hmac \ os/user \ strconv \ @@ -441,7 +435,7 @@ endif # TODO: parallelize, and only show failing tests (no implied -v flag). .PHONY: tinygo-test tinygo-test: - $(TINYGO) test $(TEST_PACKAGES_HOST) $(TEST_PACKAGES_SLOW) + $(TINYGO) test -v $(TEST_PACKAGES_HOST) $(TEST_PACKAGES_SLOW) @# io/fs requires os.ReadDir, not yet supported on windows or wasi. It also @# requires a large stack-size. Hence, io/fs is only run conditionally. @# For more details, see the comments on issue #3143. diff --git a/builder/config.go b/builder/config.go index d1d0a2713b..b36b9333f3 100644 --- a/builder/config.go +++ b/builder/config.go @@ -26,7 +26,7 @@ func NewConfig(options *compileopts.Options) (*compileopts.Config, error) { // Version range supported by TinyGo. const minorMin = 19 - const minorMax = 23 + const minorMax = 24 // Check that we support this Go toolchain version. gorootMajor, gorootMinor, err := goenv.GetGorootVersion() @@ -36,7 +36,7 @@ func NewConfig(options *compileopts.Options) (*compileopts.Config, error) { if gorootMajor != 1 || gorootMinor < minorMin || gorootMinor > minorMax { // Note: when this gets updated, also update the Go compatibility matrix: // https://github.com/tinygo-org/tinygo-site/blob/dev/content/docs/reference/go-compat-matrix.md - return nil, fmt.Errorf("requires go version 1.19 through 1.23, got go%d.%d", gorootMajor, gorootMinor) + return nil, fmt.Errorf("requires go version 1.%d through 1.%d, got go%d.%d", minorMin, minorMax, gorootMajor, gorootMinor) } // Check that the Go toolchain version isn't too new, if we haven't been diff --git a/builder/sizes_test.go b/builder/sizes_test.go index 2b2b08fe6f..a96ce9e6f6 100644 --- a/builder/sizes_test.go +++ b/builder/sizes_test.go @@ -44,7 +44,7 @@ func TestBinarySize(t *testing.T) { // microcontrollers {"hifive1b", "examples/echo", 4560, 280, 0, 2268}, {"microbit", "examples/serial", 2916, 388, 8, 2272}, - {"wioterminal", "examples/pininterrupt", 7315, 1489, 116, 6912}, + {"wioterminal", "examples/pininterrupt", 7359, 1489, 116, 6912}, // TODO: also check wasm. Right now this is difficult, because // wasm binaries are run through wasm-opt and therefore the diff --git a/cgo/cgo.go b/cgo/cgo.go index cb822a38ec..6b8ea4373d 100644 --- a/cgo/cgo.go +++ b/cgo/cgo.go @@ -92,18 +92,18 @@ type noescapingFunc struct { // cgoAliases list type aliases between Go and C, for types that are equivalent // in both languages. See addTypeAliases. var cgoAliases = map[string]string{ - "C.int8_t": "int8", - "C.int16_t": "int16", - "C.int32_t": "int32", - "C.int64_t": "int64", - "C.uint8_t": "uint8", - "C.uint16_t": "uint16", - "C.uint32_t": "uint32", - "C.uint64_t": "uint64", - "C.uintptr_t": "uintptr", - "C.float": "float32", - "C.double": "float64", - "C._Bool": "bool", + "_Cgo_int8_t": "int8", + "_Cgo_int16_t": "int16", + "_Cgo_int32_t": "int32", + "_Cgo_int64_t": "int64", + "_Cgo_uint8_t": "uint8", + "_Cgo_uint16_t": "uint16", + "_Cgo_uint32_t": "uint32", + "_Cgo_uint64_t": "uint64", + "_Cgo_uintptr_t": "uintptr", + "_Cgo_float": "float32", + "_Cgo_double": "float64", + "_Cgo__Bool": "bool", } // builtinAliases are handled specially because they only exist on the Go side @@ -145,48 +145,46 @@ typedef unsigned long long _Cgo_ulonglong; // The string/bytes functions below implement C.CString etc. To make sure the // runtime doesn't need to know the C int type, lengths are converted to uintptr // first. -// These functions will be modified to get a "C." prefix, so the source below -// doesn't reflect the final AST. const generatedGoFilePrefixBase = ` import "syscall" import "unsafe" var _ unsafe.Pointer -//go:linkname C.CString runtime.cgo_CString -func CString(string) *C.char +//go:linkname _Cgo_CString runtime.cgo_CString +func _Cgo_CString(string) *_Cgo_char -//go:linkname C.GoString runtime.cgo_GoString -func GoString(*C.char) string +//go:linkname _Cgo_GoString runtime.cgo_GoString +func _Cgo_GoString(*_Cgo_char) string -//go:linkname C.__GoStringN runtime.cgo_GoStringN -func __GoStringN(*C.char, uintptr) string +//go:linkname _Cgo___GoStringN runtime.cgo_GoStringN +func _Cgo___GoStringN(*_Cgo_char, uintptr) string -func GoStringN(cstr *C.char, length C.int) string { - return C.__GoStringN(cstr, uintptr(length)) +func _Cgo_GoStringN(cstr *_Cgo_char, length _Cgo_int) string { + return _Cgo___GoStringN(cstr, uintptr(length)) } -//go:linkname C.__GoBytes runtime.cgo_GoBytes -func __GoBytes(unsafe.Pointer, uintptr) []byte +//go:linkname _Cgo___GoBytes runtime.cgo_GoBytes +func _Cgo___GoBytes(unsafe.Pointer, uintptr) []byte -func GoBytes(ptr unsafe.Pointer, length C.int) []byte { - return C.__GoBytes(ptr, uintptr(length)) +func _Cgo_GoBytes(ptr unsafe.Pointer, length _Cgo_int) []byte { + return _Cgo___GoBytes(ptr, uintptr(length)) } -//go:linkname C.__CBytes runtime.cgo_CBytes -func __CBytes([]byte) unsafe.Pointer +//go:linkname _Cgo___CBytes runtime.cgo_CBytes +func _Cgo___CBytes([]byte) unsafe.Pointer -func CBytes(b []byte) unsafe.Pointer { - return C.__CBytes(b) +func _Cgo_CBytes(b []byte) unsafe.Pointer { + return _Cgo___CBytes(b) } -//go:linkname C.__get_errno_num runtime.cgo_errno -func __get_errno_num() uintptr +//go:linkname _Cgo___get_errno_num runtime.cgo_errno +func _Cgo___get_errno_num() uintptr ` const generatedGoFilePrefixOther = generatedGoFilePrefixBase + ` -func __get_errno() error { - return syscall.Errno(C.__get_errno_num()) +func _Cgo___get_errno() error { + return syscall.Errno(_Cgo___get_errno_num()) } ` @@ -197,7 +195,7 @@ func __get_errno() error { // map the errno values to match the values in the syscall package. // Source of the errno values: lib/mingw-w64/mingw-w64-headers/crt/errno.h const generatedGoFilePrefixWindows = generatedGoFilePrefixBase + ` -var __errno_mapping = [...]syscall.Errno{ +var _Cgo___errno_mapping = [...]syscall.Errno{ 1: syscall.EPERM, 2: syscall.ENOENT, 3: syscall.ESRCH, @@ -238,10 +236,10 @@ var __errno_mapping = [...]syscall.Errno{ 42: syscall.EILSEQ, } -func __get_errno() error { - num := C.__get_errno_num() - if num < uintptr(len(__errno_mapping)) { - if mapped := __errno_mapping[num]; mapped != 0 { +func _Cgo___get_errno() error { + num := _Cgo___get_errno_num() + if num < uintptr(len(_Cgo___errno_mapping)) { + if mapped := _Cgo___errno_mapping[num]; mapped != 0 { return mapped } } @@ -304,23 +302,6 @@ func Process(files []*ast.File, dir, importPath string, fset *token.FileSet, cfl // If the Comments field is not set to nil, the go/format package will get // confused about where comments should go. p.generated.Comments = nil - // Adjust some of the functions in there. - for _, decl := range p.generated.Decls { - switch decl := decl.(type) { - case *ast.FuncDecl: - switch decl.Name.Name { - case "CString", "GoString", "GoStringN", "__GoStringN", "GoBytes", "__GoBytes", "CBytes", "__CBytes", "__get_errno_num", "__get_errno", "__errno_mapping": - // Adjust the name to have a "C." prefix so it is correctly - // resolved. - decl.Name.Name = "C." + decl.Name.Name - } - } - } - // Patch some types, for example *C.char in C.CString. - cf := p.newCGoFile(nil, -1) // dummy *cgoFile for the walker - astutil.Apply(p.generated, func(cursor *astutil.Cursor) bool { - return cf.walker(cursor, nil) - }, nil) // Find `import "C"` C fragments in the file. p.cgoHeaders = make([]string, len(files)) // combined CGo header fragment for each file @@ -399,7 +380,7 @@ func Process(files []*ast.File, dir, importPath string, fset *token.FileSet, cfl Tok: token.TYPE, } for _, name := range builtinAliases { - typeSpec := p.getIntegerType("C."+name, names["_Cgo_"+name]) + typeSpec := p.getIntegerType("_Cgo_"+name, names["_Cgo_"+name]) gen.Specs = append(gen.Specs, typeSpec) } p.generated.Decls = append(p.generated.Decls, gen) @@ -1272,7 +1253,7 @@ func (p *cgoPackage) getUnnamedDeclName(prefix string, itf interface{}) string { func (f *cgoFile) getASTDeclName(name string, found clangCursor, iscall bool) string { // Some types are defined in stdint.h and map directly to a particular Go // type. - if alias := cgoAliases["C."+name]; alias != "" { + if alias := cgoAliases["_Cgo_"+name]; alias != "" { return alias } node := f.getASTDeclNode(name, found) @@ -1282,7 +1263,7 @@ func (f *cgoFile) getASTDeclName(name string, found clangCursor, iscall bool) st } return node.Name.Name } - return "C." + name + return "_Cgo_" + name } // getASTDeclNode will declare the given C AST node (if not already defined) and @@ -1382,8 +1363,8 @@ extern __typeof(%s) %s __attribute__((alias(%#v))); case *elaboratedTypeInfo: // Add struct bitfields. for _, bitfield := range elaboratedType.bitfields { - f.createBitfieldGetter(bitfield, "C."+name) - f.createBitfieldSetter(bitfield, "C."+name) + f.createBitfieldGetter(bitfield, "_Cgo_"+name) + f.createBitfieldSetter(bitfield, "_Cgo_"+name) } if elaboratedType.unionSize != 0 { // Create union getters/setters. @@ -1392,7 +1373,7 @@ extern __typeof(%s) %s __attribute__((alias(%#v))); f.addError(elaboratedType.pos, fmt.Sprintf("union must have field with a single name, it has %d names", len(field.Names))) continue } - f.createUnionAccessor(field, "C."+name) + f.createUnionAccessor(field, "_Cgo_"+name) } } } @@ -1441,7 +1422,7 @@ func (f *cgoFile) walker(cursor *astutil.Cursor, names map[string]clangCursor) b node.Rhs = append(node.Rhs, &ast.CallExpr{ Fun: &ast.Ident{ NamePos: node.Lhs[1].End(), - Name: "C.__get_errno", + Name: "_Cgo___get_errno", }, }) } @@ -1466,7 +1447,7 @@ func (f *cgoFile) walker(cursor *astutil.Cursor, names map[string]clangCursor) b return true } if x.Name == "C" { - name := "C." + node.Sel.Name + name := "_Cgo_" + node.Sel.Name if found, ok := names[node.Sel.Name]; ok { name = f.getASTDeclName(node.Sel.Name, found, false) } diff --git a/cgo/libclang.go b/cgo/libclang.go index 4da77ff6e7..759417a6ea 100644 --- a/cgo/libclang.go +++ b/cgo/libclang.go @@ -219,7 +219,7 @@ func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, any) { numArgs := int(C.tinygo_clang_Cursor_getNumArguments(c)) obj := &ast.Object{ Kind: ast.Fun, - Name: "C." + name, + Name: "_Cgo_" + name, } exportName := name localName := name @@ -257,7 +257,7 @@ func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, any) { }, Name: &ast.Ident{ NamePos: pos, - Name: "C." + localName, + Name: "_Cgo_" + localName, Obj: obj, }, Type: &ast.FuncType{ @@ -319,7 +319,7 @@ func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, any) { return decl, stringSignature case C.CXCursor_StructDecl, C.CXCursor_UnionDecl: typ := f.makeASTRecordType(c, pos) - typeName := "C." + name + typeName := "_Cgo_" + name typeExpr := typ.typeExpr if typ.unionSize != 0 { // Convert to a single-field struct type. @@ -340,7 +340,7 @@ func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, any) { obj.Decl = typeSpec return typeSpec, typ case C.CXCursor_TypedefDecl: - typeName := "C." + name + typeName := "_Cgo_" + name underlyingType := C.tinygo_clang_getTypedefDeclUnderlyingType(c) obj := &ast.Object{ Kind: ast.Typ, @@ -378,12 +378,12 @@ func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, any) { } obj := &ast.Object{ Kind: ast.Var, - Name: "C." + name, + Name: "_Cgo_" + name, } valueSpec := &ast.ValueSpec{ Names: []*ast.Ident{{ NamePos: pos, - Name: "C." + name, + Name: "_Cgo_" + name, Obj: obj, }}, Type: typeExpr, @@ -407,12 +407,12 @@ func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, any) { } obj := &ast.Object{ Kind: ast.Con, - Name: "C." + name, + Name: "_Cgo_" + name, } valueSpec := &ast.ValueSpec{ Names: []*ast.Ident{{ NamePos: pos, - Name: "C." + name, + Name: "_Cgo_" + name, Obj: obj, }}, Values: []ast.Expr{expr}, @@ -423,7 +423,7 @@ func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, any) { case C.CXCursor_EnumDecl: obj := &ast.Object{ Kind: ast.Typ, - Name: "C." + name, + Name: "_Cgo_" + name, } underlying := C.tinygo_clang_getEnumDeclIntegerType(c) // TODO: gc's CGo implementation uses types such as `uint32` for enums @@ -431,7 +431,7 @@ func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, any) { typeSpec := &ast.TypeSpec{ Name: &ast.Ident{ NamePos: pos, - Name: "C." + name, + Name: "_Cgo_" + name, Obj: obj, }, Assign: pos, @@ -454,12 +454,12 @@ func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, any) { } obj := &ast.Object{ Kind: ast.Con, - Name: "C." + name, + Name: "_Cgo_" + name, } valueSpec := &ast.ValueSpec{ Names: []*ast.Ident{{ NamePos: pos, - Name: "C." + name, + Name: "_Cgo_" + name, Obj: obj, }}, Values: []ast.Expr{expr}, @@ -745,27 +745,27 @@ func (f *cgoFile) makeASTType(typ C.CXType, pos token.Pos) ast.Expr { var typeName string switch typ.kind { case C.CXType_Char_S, C.CXType_Char_U: - typeName = "C.char" + typeName = "_Cgo_char" case C.CXType_SChar: - typeName = "C.schar" + typeName = "_Cgo_schar" case C.CXType_UChar: - typeName = "C.uchar" + typeName = "_Cgo_uchar" case C.CXType_Short: - typeName = "C.short" + typeName = "_Cgo_short" case C.CXType_UShort: - typeName = "C.ushort" + typeName = "_Cgo_ushort" case C.CXType_Int: - typeName = "C.int" + typeName = "_Cgo_int" case C.CXType_UInt: - typeName = "C.uint" + typeName = "_Cgo_uint" case C.CXType_Long: - typeName = "C.long" + typeName = "_Cgo_long" case C.CXType_ULong: - typeName = "C.ulong" + typeName = "_Cgo_ulong" case C.CXType_LongLong: - typeName = "C.longlong" + typeName = "_Cgo_longlong" case C.CXType_ULongLong: - typeName = "C.ulonglong" + typeName = "_Cgo_ulonglong" case C.CXType_Bool: typeName = "bool" case C.CXType_Float, C.CXType_Double, C.CXType_LongDouble: @@ -896,7 +896,7 @@ func (f *cgoFile) makeASTType(typ C.CXType, pos token.Pos) ast.Expr { typeSpelling := getString(C.clang_getTypeSpelling(typ)) typeKindSpelling := getString(C.clang_getTypeKindSpelling(typ.kind)) f.addError(pos, fmt.Sprintf("unknown C type: %v (libclang type kind %s)", typeSpelling, typeKindSpelling)) - typeName = "C." + typeName = "_Cgo_" } return &ast.Ident{ NamePos: pos, @@ -913,7 +913,7 @@ func (p *cgoPackage) getIntegerType(name string, cursor clangCursor) *ast.TypeSp var goName string typeSize := C.clang_Type_getSizeOf(underlyingType) switch name { - case "C.char": + case "_Cgo_char": if typeSize != 1 { // This happens for some very special purpose architectures // (DSPs etc.) that are not currently targeted. @@ -926,7 +926,7 @@ func (p *cgoPackage) getIntegerType(name string, cursor clangCursor) *ast.TypeSp case C.CXType_Char_U: goName = "uint8" } - case "C.schar", "C.short", "C.int", "C.long", "C.longlong": + case "_Cgo_schar", "_Cgo_short", "_Cgo_int", "_Cgo_long", "_Cgo_longlong": switch typeSize { case 1: goName = "int8" @@ -937,7 +937,7 @@ func (p *cgoPackage) getIntegerType(name string, cursor clangCursor) *ast.TypeSp case 8: goName = "int64" } - case "C.uchar", "C.ushort", "C.uint", "C.ulong", "C.ulonglong": + case "_Cgo_uchar", "_Cgo_ushort", "_Cgo_uint", "_Cgo_ulong", "_Cgo_ulonglong": switch typeSize { case 1: goName = "uint8" diff --git a/cgo/testdata/basic.out.go b/cgo/testdata/basic.out.go index 7348ee3791..191cfba38f 100644 --- a/cgo/testdata/basic.out.go +++ b/cgo/testdata/basic.out.go @@ -5,50 +5,50 @@ import "unsafe" var _ unsafe.Pointer -//go:linkname C.CString runtime.cgo_CString -func C.CString(string) *C.char +//go:linkname _Cgo_CString runtime.cgo_CString +func _Cgo_CString(string) *_Cgo_char -//go:linkname C.GoString runtime.cgo_GoString -func C.GoString(*C.char) string +//go:linkname _Cgo_GoString runtime.cgo_GoString +func _Cgo_GoString(*_Cgo_char) string -//go:linkname C.__GoStringN runtime.cgo_GoStringN -func C.__GoStringN(*C.char, uintptr) string +//go:linkname _Cgo___GoStringN runtime.cgo_GoStringN +func _Cgo___GoStringN(*_Cgo_char, uintptr) string -func C.GoStringN(cstr *C.char, length C.int) string { - return C.__GoStringN(cstr, uintptr(length)) +func _Cgo_GoStringN(cstr *_Cgo_char, length _Cgo_int) string { + return _Cgo___GoStringN(cstr, uintptr(length)) } -//go:linkname C.__GoBytes runtime.cgo_GoBytes -func C.__GoBytes(unsafe.Pointer, uintptr) []byte +//go:linkname _Cgo___GoBytes runtime.cgo_GoBytes +func _Cgo___GoBytes(unsafe.Pointer, uintptr) []byte -func C.GoBytes(ptr unsafe.Pointer, length C.int) []byte { - return C.__GoBytes(ptr, uintptr(length)) +func _Cgo_GoBytes(ptr unsafe.Pointer, length _Cgo_int) []byte { + return _Cgo___GoBytes(ptr, uintptr(length)) } -//go:linkname C.__CBytes runtime.cgo_CBytes -func C.__CBytes([]byte) unsafe.Pointer +//go:linkname _Cgo___CBytes runtime.cgo_CBytes +func _Cgo___CBytes([]byte) unsafe.Pointer -func C.CBytes(b []byte) unsafe.Pointer { - return C.__CBytes(b) +func _Cgo_CBytes(b []byte) unsafe.Pointer { + return _Cgo___CBytes(b) } -//go:linkname C.__get_errno_num runtime.cgo_errno -func C.__get_errno_num() uintptr +//go:linkname _Cgo___get_errno_num runtime.cgo_errno +func _Cgo___get_errno_num() uintptr -func C.__get_errno() error { - return syscall.Errno(C.__get_errno_num()) +func _Cgo___get_errno() error { + return syscall.Errno(_Cgo___get_errno_num()) } type ( - C.char uint8 - C.schar int8 - C.uchar uint8 - C.short int16 - C.ushort uint16 - C.int int32 - C.uint uint32 - C.long int32 - C.ulong uint32 - C.longlong int64 - C.ulonglong uint64 + _Cgo_char uint8 + _Cgo_schar int8 + _Cgo_uchar uint8 + _Cgo_short int16 + _Cgo_ushort uint16 + _Cgo_int int32 + _Cgo_uint uint32 + _Cgo_long int32 + _Cgo_ulong uint32 + _Cgo_longlong int64 + _Cgo_ulonglong uint64 ) diff --git a/cgo/testdata/const.out.go b/cgo/testdata/const.out.go index 21705afc4f..0329ba5985 100644 --- a/cgo/testdata/const.out.go +++ b/cgo/testdata/const.out.go @@ -5,58 +5,58 @@ import "unsafe" var _ unsafe.Pointer -//go:linkname C.CString runtime.cgo_CString -func C.CString(string) *C.char +//go:linkname _Cgo_CString runtime.cgo_CString +func _Cgo_CString(string) *_Cgo_char -//go:linkname C.GoString runtime.cgo_GoString -func C.GoString(*C.char) string +//go:linkname _Cgo_GoString runtime.cgo_GoString +func _Cgo_GoString(*_Cgo_char) string -//go:linkname C.__GoStringN runtime.cgo_GoStringN -func C.__GoStringN(*C.char, uintptr) string +//go:linkname _Cgo___GoStringN runtime.cgo_GoStringN +func _Cgo___GoStringN(*_Cgo_char, uintptr) string -func C.GoStringN(cstr *C.char, length C.int) string { - return C.__GoStringN(cstr, uintptr(length)) +func _Cgo_GoStringN(cstr *_Cgo_char, length _Cgo_int) string { + return _Cgo___GoStringN(cstr, uintptr(length)) } -//go:linkname C.__GoBytes runtime.cgo_GoBytes -func C.__GoBytes(unsafe.Pointer, uintptr) []byte +//go:linkname _Cgo___GoBytes runtime.cgo_GoBytes +func _Cgo___GoBytes(unsafe.Pointer, uintptr) []byte -func C.GoBytes(ptr unsafe.Pointer, length C.int) []byte { - return C.__GoBytes(ptr, uintptr(length)) +func _Cgo_GoBytes(ptr unsafe.Pointer, length _Cgo_int) []byte { + return _Cgo___GoBytes(ptr, uintptr(length)) } -//go:linkname C.__CBytes runtime.cgo_CBytes -func C.__CBytes([]byte) unsafe.Pointer +//go:linkname _Cgo___CBytes runtime.cgo_CBytes +func _Cgo___CBytes([]byte) unsafe.Pointer -func C.CBytes(b []byte) unsafe.Pointer { - return C.__CBytes(b) +func _Cgo_CBytes(b []byte) unsafe.Pointer { + return _Cgo___CBytes(b) } -//go:linkname C.__get_errno_num runtime.cgo_errno -func C.__get_errno_num() uintptr +//go:linkname _Cgo___get_errno_num runtime.cgo_errno +func _Cgo___get_errno_num() uintptr -func C.__get_errno() error { - return syscall.Errno(C.__get_errno_num()) +func _Cgo___get_errno() error { + return syscall.Errno(_Cgo___get_errno_num()) } type ( - C.char uint8 - C.schar int8 - C.uchar uint8 - C.short int16 - C.ushort uint16 - C.int int32 - C.uint uint32 - C.long int32 - C.ulong uint32 - C.longlong int64 - C.ulonglong uint64 + _Cgo_char uint8 + _Cgo_schar int8 + _Cgo_uchar uint8 + _Cgo_short int16 + _Cgo_ushort uint16 + _Cgo_int int32 + _Cgo_uint uint32 + _Cgo_long int32 + _Cgo_ulong uint32 + _Cgo_longlong int64 + _Cgo_ulonglong uint64 ) -const C.foo = 3 -const C.bar = C.foo -const C.unreferenced = 4 -const C.referenced = C.unreferenced -const C.fnlike_val = 5 -const C.square_val = (20 * 20) -const C.add_val = (3 + 5) +const _Cgo_foo = 3 +const _Cgo_bar = _Cgo_foo +const _Cgo_unreferenced = 4 +const _Cgo_referenced = _Cgo_unreferenced +const _Cgo_fnlike_val = 5 +const _Cgo_square_val = (20 * 20) +const _Cgo_add_val = (3 + 5) diff --git a/cgo/testdata/errors.out.go b/cgo/testdata/errors.out.go index e0f7d1f541..0ae794087f 100644 --- a/cgo/testdata/errors.out.go +++ b/cgo/testdata/errors.out.go @@ -14,16 +14,16 @@ // testdata/errors.go:3:1: function "unusedFunction" in #cgo noescape line is not used // Type checking errors after CGo processing: -// testdata/errors.go:102: cannot use 2 << 10 (untyped int constant 2048) as C.char value in variable declaration (overflows) +// testdata/errors.go:102: cannot use 2 << 10 (untyped int constant 2048) as _Cgo_char value in variable declaration (overflows) // testdata/errors.go:105: unknown field z in struct literal -// testdata/errors.go:108: undefined: C.SOME_CONST_1 -// testdata/errors.go:110: cannot use C.SOME_CONST_3 (untyped int constant 1234) as byte value in variable declaration (overflows) -// testdata/errors.go:112: undefined: C.SOME_CONST_4 -// testdata/errors.go:114: undefined: C.SOME_CONST_b -// testdata/errors.go:116: undefined: C.SOME_CONST_startspace -// testdata/errors.go:119: undefined: C.SOME_PARAM_CONST_invalid -// testdata/errors.go:122: undefined: C.add_toomuch -// testdata/errors.go:123: undefined: C.add_toolittle +// testdata/errors.go:108: undefined: _Cgo_SOME_CONST_1 +// testdata/errors.go:110: cannot use _Cgo_SOME_CONST_3 (untyped int constant 1234) as byte value in variable declaration (overflows) +// testdata/errors.go:112: undefined: _Cgo_SOME_CONST_4 +// testdata/errors.go:114: undefined: _Cgo_SOME_CONST_b +// testdata/errors.go:116: undefined: _Cgo_SOME_CONST_startspace +// testdata/errors.go:119: undefined: _Cgo_SOME_PARAM_CONST_invalid +// testdata/errors.go:122: undefined: _Cgo_add_toomuch +// testdata/errors.go:123: undefined: _Cgo_add_toolittle package main @@ -32,58 +32,58 @@ import "unsafe" var _ unsafe.Pointer -//go:linkname C.CString runtime.cgo_CString -func C.CString(string) *C.char +//go:linkname _Cgo_CString runtime.cgo_CString +func _Cgo_CString(string) *_Cgo_char -//go:linkname C.GoString runtime.cgo_GoString -func C.GoString(*C.char) string +//go:linkname _Cgo_GoString runtime.cgo_GoString +func _Cgo_GoString(*_Cgo_char) string -//go:linkname C.__GoStringN runtime.cgo_GoStringN -func C.__GoStringN(*C.char, uintptr) string +//go:linkname _Cgo___GoStringN runtime.cgo_GoStringN +func _Cgo___GoStringN(*_Cgo_char, uintptr) string -func C.GoStringN(cstr *C.char, length C.int) string { - return C.__GoStringN(cstr, uintptr(length)) +func _Cgo_GoStringN(cstr *_Cgo_char, length _Cgo_int) string { + return _Cgo___GoStringN(cstr, uintptr(length)) } -//go:linkname C.__GoBytes runtime.cgo_GoBytes -func C.__GoBytes(unsafe.Pointer, uintptr) []byte +//go:linkname _Cgo___GoBytes runtime.cgo_GoBytes +func _Cgo___GoBytes(unsafe.Pointer, uintptr) []byte -func C.GoBytes(ptr unsafe.Pointer, length C.int) []byte { - return C.__GoBytes(ptr, uintptr(length)) +func _Cgo_GoBytes(ptr unsafe.Pointer, length _Cgo_int) []byte { + return _Cgo___GoBytes(ptr, uintptr(length)) } -//go:linkname C.__CBytes runtime.cgo_CBytes -func C.__CBytes([]byte) unsafe.Pointer +//go:linkname _Cgo___CBytes runtime.cgo_CBytes +func _Cgo___CBytes([]byte) unsafe.Pointer -func C.CBytes(b []byte) unsafe.Pointer { - return C.__CBytes(b) +func _Cgo_CBytes(b []byte) unsafe.Pointer { + return _Cgo___CBytes(b) } -//go:linkname C.__get_errno_num runtime.cgo_errno -func C.__get_errno_num() uintptr +//go:linkname _Cgo___get_errno_num runtime.cgo_errno +func _Cgo___get_errno_num() uintptr -func C.__get_errno() error { - return syscall.Errno(C.__get_errno_num()) +func _Cgo___get_errno() error { + return syscall.Errno(_Cgo___get_errno_num()) } type ( - C.char uint8 - C.schar int8 - C.uchar uint8 - C.short int16 - C.ushort uint16 - C.int int32 - C.uint uint32 - C.long int32 - C.ulong uint32 - C.longlong int64 - C.ulonglong uint64 + _Cgo_char uint8 + _Cgo_schar int8 + _Cgo_uchar uint8 + _Cgo_short int16 + _Cgo_ushort uint16 + _Cgo_int int32 + _Cgo_uint uint32 + _Cgo_long int32 + _Cgo_ulong uint32 + _Cgo_longlong int64 + _Cgo_ulonglong uint64 ) -type C.struct_point_t struct { - x C.int - y C.int +type _Cgo_struct_point_t struct { + x _Cgo_int + y _Cgo_int } -type C.point_t = C.struct_point_t +type _Cgo_point_t = _Cgo_struct_point_t -const C.SOME_CONST_3 = 1234 -const C.SOME_PARAM_CONST_valid = 3 + 4 +const _Cgo_SOME_CONST_3 = 1234 +const _Cgo_SOME_PARAM_CONST_valid = 3 + 4 diff --git a/cgo/testdata/flags.out.go b/cgo/testdata/flags.out.go index 8662412296..ac5cf546db 100644 --- a/cgo/testdata/flags.out.go +++ b/cgo/testdata/flags.out.go @@ -10,53 +10,53 @@ import "unsafe" var _ unsafe.Pointer -//go:linkname C.CString runtime.cgo_CString -func C.CString(string) *C.char +//go:linkname _Cgo_CString runtime.cgo_CString +func _Cgo_CString(string) *_Cgo_char -//go:linkname C.GoString runtime.cgo_GoString -func C.GoString(*C.char) string +//go:linkname _Cgo_GoString runtime.cgo_GoString +func _Cgo_GoString(*_Cgo_char) string -//go:linkname C.__GoStringN runtime.cgo_GoStringN -func C.__GoStringN(*C.char, uintptr) string +//go:linkname _Cgo___GoStringN runtime.cgo_GoStringN +func _Cgo___GoStringN(*_Cgo_char, uintptr) string -func C.GoStringN(cstr *C.char, length C.int) string { - return C.__GoStringN(cstr, uintptr(length)) +func _Cgo_GoStringN(cstr *_Cgo_char, length _Cgo_int) string { + return _Cgo___GoStringN(cstr, uintptr(length)) } -//go:linkname C.__GoBytes runtime.cgo_GoBytes -func C.__GoBytes(unsafe.Pointer, uintptr) []byte +//go:linkname _Cgo___GoBytes runtime.cgo_GoBytes +func _Cgo___GoBytes(unsafe.Pointer, uintptr) []byte -func C.GoBytes(ptr unsafe.Pointer, length C.int) []byte { - return C.__GoBytes(ptr, uintptr(length)) +func _Cgo_GoBytes(ptr unsafe.Pointer, length _Cgo_int) []byte { + return _Cgo___GoBytes(ptr, uintptr(length)) } -//go:linkname C.__CBytes runtime.cgo_CBytes -func C.__CBytes([]byte) unsafe.Pointer +//go:linkname _Cgo___CBytes runtime.cgo_CBytes +func _Cgo___CBytes([]byte) unsafe.Pointer -func C.CBytes(b []byte) unsafe.Pointer { - return C.__CBytes(b) +func _Cgo_CBytes(b []byte) unsafe.Pointer { + return _Cgo___CBytes(b) } -//go:linkname C.__get_errno_num runtime.cgo_errno -func C.__get_errno_num() uintptr +//go:linkname _Cgo___get_errno_num runtime.cgo_errno +func _Cgo___get_errno_num() uintptr -func C.__get_errno() error { - return syscall.Errno(C.__get_errno_num()) +func _Cgo___get_errno() error { + return syscall.Errno(_Cgo___get_errno_num()) } type ( - C.char uint8 - C.schar int8 - C.uchar uint8 - C.short int16 - C.ushort uint16 - C.int int32 - C.uint uint32 - C.long int32 - C.ulong uint32 - C.longlong int64 - C.ulonglong uint64 + _Cgo_char uint8 + _Cgo_schar int8 + _Cgo_uchar uint8 + _Cgo_short int16 + _Cgo_ushort uint16 + _Cgo_int int32 + _Cgo_uint uint32 + _Cgo_long int32 + _Cgo_ulong uint32 + _Cgo_longlong int64 + _Cgo_ulonglong uint64 ) -const C.BAR = 3 -const C.FOO_H = 1 +const _Cgo_BAR = 3 +const _Cgo_FOO_H = 1 diff --git a/cgo/testdata/symbols.out.go b/cgo/testdata/symbols.out.go index 2ca80c1e65..8a603cfd7e 100644 --- a/cgo/testdata/symbols.out.go +++ b/cgo/testdata/symbols.out.go @@ -5,80 +5,80 @@ import "unsafe" var _ unsafe.Pointer -//go:linkname C.CString runtime.cgo_CString -func C.CString(string) *C.char +//go:linkname _Cgo_CString runtime.cgo_CString +func _Cgo_CString(string) *_Cgo_char -//go:linkname C.GoString runtime.cgo_GoString -func C.GoString(*C.char) string +//go:linkname _Cgo_GoString runtime.cgo_GoString +func _Cgo_GoString(*_Cgo_char) string -//go:linkname C.__GoStringN runtime.cgo_GoStringN -func C.__GoStringN(*C.char, uintptr) string +//go:linkname _Cgo___GoStringN runtime.cgo_GoStringN +func _Cgo___GoStringN(*_Cgo_char, uintptr) string -func C.GoStringN(cstr *C.char, length C.int) string { - return C.__GoStringN(cstr, uintptr(length)) +func _Cgo_GoStringN(cstr *_Cgo_char, length _Cgo_int) string { + return _Cgo___GoStringN(cstr, uintptr(length)) } -//go:linkname C.__GoBytes runtime.cgo_GoBytes -func C.__GoBytes(unsafe.Pointer, uintptr) []byte +//go:linkname _Cgo___GoBytes runtime.cgo_GoBytes +func _Cgo___GoBytes(unsafe.Pointer, uintptr) []byte -func C.GoBytes(ptr unsafe.Pointer, length C.int) []byte { - return C.__GoBytes(ptr, uintptr(length)) +func _Cgo_GoBytes(ptr unsafe.Pointer, length _Cgo_int) []byte { + return _Cgo___GoBytes(ptr, uintptr(length)) } -//go:linkname C.__CBytes runtime.cgo_CBytes -func C.__CBytes([]byte) unsafe.Pointer +//go:linkname _Cgo___CBytes runtime.cgo_CBytes +func _Cgo___CBytes([]byte) unsafe.Pointer -func C.CBytes(b []byte) unsafe.Pointer { - return C.__CBytes(b) +func _Cgo_CBytes(b []byte) unsafe.Pointer { + return _Cgo___CBytes(b) } -//go:linkname C.__get_errno_num runtime.cgo_errno -func C.__get_errno_num() uintptr +//go:linkname _Cgo___get_errno_num runtime.cgo_errno +func _Cgo___get_errno_num() uintptr -func C.__get_errno() error { - return syscall.Errno(C.__get_errno_num()) +func _Cgo___get_errno() error { + return syscall.Errno(_Cgo___get_errno_num()) } type ( - C.char uint8 - C.schar int8 - C.uchar uint8 - C.short int16 - C.ushort uint16 - C.int int32 - C.uint uint32 - C.long int32 - C.ulong uint32 - C.longlong int64 - C.ulonglong uint64 + _Cgo_char uint8 + _Cgo_schar int8 + _Cgo_uchar uint8 + _Cgo_short int16 + _Cgo_ushort uint16 + _Cgo_int int32 + _Cgo_uint uint32 + _Cgo_long int32 + _Cgo_ulong uint32 + _Cgo_longlong int64 + _Cgo_ulonglong uint64 ) //export foo -func C.foo(a C.int, b C.int) C.int +func _Cgo_foo(a _Cgo_int, b _Cgo_int) _Cgo_int -var C.foo$funcaddr unsafe.Pointer +var _Cgo_foo$funcaddr unsafe.Pointer //export variadic0 //go:variadic -func C.variadic0() +func _Cgo_variadic0() -var C.variadic0$funcaddr unsafe.Pointer +var _Cgo_variadic0$funcaddr unsafe.Pointer //export variadic2 //go:variadic -func C.variadic2(x C.int, y C.int) +func _Cgo_variadic2(x _Cgo_int, y _Cgo_int) -var C.variadic2$funcaddr unsafe.Pointer +var _Cgo_variadic2$funcaddr unsafe.Pointer //export _Cgo_static_173c95a79b6df1980521_staticfunc -func C.staticfunc!symbols.go(x C.int) +func _Cgo_staticfunc!symbols.go(x _Cgo_int) -var C.staticfunc!symbols.go$funcaddr unsafe.Pointer +var _Cgo_staticfunc!symbols.go$funcaddr unsafe.Pointer //export notEscapingFunction //go:noescape -func C.notEscapingFunction(a *C.int) +func _Cgo_notEscapingFunction(a *_Cgo_int) -var C.notEscapingFunction$funcaddr unsafe.Pointer +var _Cgo_notEscapingFunction$funcaddr unsafe.Pointer //go:extern someValue -var C.someValue C.int +var _Cgo_someValue _Cgo_int diff --git a/cgo/testdata/types.out.go b/cgo/testdata/types.out.go index b3fe414b07..3eaa53f1fb 100644 --- a/cgo/testdata/types.out.go +++ b/cgo/testdata/types.out.go @@ -5,158 +5,162 @@ import "unsafe" var _ unsafe.Pointer -//go:linkname C.CString runtime.cgo_CString -func C.CString(string) *C.char +//go:linkname _Cgo_CString runtime.cgo_CString +func _Cgo_CString(string) *_Cgo_char -//go:linkname C.GoString runtime.cgo_GoString -func C.GoString(*C.char) string +//go:linkname _Cgo_GoString runtime.cgo_GoString +func _Cgo_GoString(*_Cgo_char) string -//go:linkname C.__GoStringN runtime.cgo_GoStringN -func C.__GoStringN(*C.char, uintptr) string +//go:linkname _Cgo___GoStringN runtime.cgo_GoStringN +func _Cgo___GoStringN(*_Cgo_char, uintptr) string -func C.GoStringN(cstr *C.char, length C.int) string { - return C.__GoStringN(cstr, uintptr(length)) +func _Cgo_GoStringN(cstr *_Cgo_char, length _Cgo_int) string { + return _Cgo___GoStringN(cstr, uintptr(length)) } -//go:linkname C.__GoBytes runtime.cgo_GoBytes -func C.__GoBytes(unsafe.Pointer, uintptr) []byte +//go:linkname _Cgo___GoBytes runtime.cgo_GoBytes +func _Cgo___GoBytes(unsafe.Pointer, uintptr) []byte -func C.GoBytes(ptr unsafe.Pointer, length C.int) []byte { - return C.__GoBytes(ptr, uintptr(length)) +func _Cgo_GoBytes(ptr unsafe.Pointer, length _Cgo_int) []byte { + return _Cgo___GoBytes(ptr, uintptr(length)) } -//go:linkname C.__CBytes runtime.cgo_CBytes -func C.__CBytes([]byte) unsafe.Pointer +//go:linkname _Cgo___CBytes runtime.cgo_CBytes +func _Cgo___CBytes([]byte) unsafe.Pointer -func C.CBytes(b []byte) unsafe.Pointer { - return C.__CBytes(b) +func _Cgo_CBytes(b []byte) unsafe.Pointer { + return _Cgo___CBytes(b) } -//go:linkname C.__get_errno_num runtime.cgo_errno -func C.__get_errno_num() uintptr +//go:linkname _Cgo___get_errno_num runtime.cgo_errno +func _Cgo___get_errno_num() uintptr -func C.__get_errno() error { - return syscall.Errno(C.__get_errno_num()) +func _Cgo___get_errno() error { + return syscall.Errno(_Cgo___get_errno_num()) } type ( - C.char uint8 - C.schar int8 - C.uchar uint8 - C.short int16 - C.ushort uint16 - C.int int32 - C.uint uint32 - C.long int32 - C.ulong uint32 - C.longlong int64 - C.ulonglong uint64 + _Cgo_char uint8 + _Cgo_schar int8 + _Cgo_uchar uint8 + _Cgo_short int16 + _Cgo_ushort uint16 + _Cgo_int int32 + _Cgo_uint uint32 + _Cgo_long int32 + _Cgo_ulong uint32 + _Cgo_longlong int64 + _Cgo_ulonglong uint64 ) -type C.myint = C.int -type C.struct_point2d_t struct { - x C.int - y C.int -} -type C.point2d_t = C.struct_point2d_t -type C.struct_point3d struct { - x C.int - y C.int - z C.int -} -type C.point3d_t = C.struct_point3d -type C.struct_type1 struct { - _type C.int - __type C.int - ___type C.int -} -type C.struct_type2 struct{ _type C.int } -type C.union_union1_t struct{ i C.int } -type C.union1_t = C.union_union1_t -type C.union_union3_t struct{ $union uint64 } - -func (union *C.union_union3_t) unionfield_i() *C.int { return (*C.int)(unsafe.Pointer(&union.$union)) } -func (union *C.union_union3_t) unionfield_d() *float64 { +type _Cgo_myint = _Cgo_int +type _Cgo_struct_point2d_t struct { + x _Cgo_int + y _Cgo_int +} +type _Cgo_point2d_t = _Cgo_struct_point2d_t +type _Cgo_struct_point3d struct { + x _Cgo_int + y _Cgo_int + z _Cgo_int +} +type _Cgo_point3d_t = _Cgo_struct_point3d +type _Cgo_struct_type1 struct { + _type _Cgo_int + __type _Cgo_int + ___type _Cgo_int +} +type _Cgo_struct_type2 struct{ _type _Cgo_int } +type _Cgo_union_union1_t struct{ i _Cgo_int } +type _Cgo_union1_t = _Cgo_union_union1_t +type _Cgo_union_union3_t struct{ $union uint64 } + +func (union *_Cgo_union_union3_t) unionfield_i() *_Cgo_int { + return (*_Cgo_int)(unsafe.Pointer(&union.$union)) +} +func (union *_Cgo_union_union3_t) unionfield_d() *float64 { return (*float64)(unsafe.Pointer(&union.$union)) } -func (union *C.union_union3_t) unionfield_s() *C.short { - return (*C.short)(unsafe.Pointer(&union.$union)) +func (union *_Cgo_union_union3_t) unionfield_s() *_Cgo_short { + return (*_Cgo_short)(unsafe.Pointer(&union.$union)) } -type C.union3_t = C.union_union3_t -type C.union_union2d struct{ $union [2]uint64 } +type _Cgo_union3_t = _Cgo_union_union3_t +type _Cgo_union_union2d struct{ $union [2]uint64 } -func (union *C.union_union2d) unionfield_i() *C.int { return (*C.int)(unsafe.Pointer(&union.$union)) } -func (union *C.union_union2d) unionfield_d() *[2]float64 { +func (union *_Cgo_union_union2d) unionfield_i() *_Cgo_int { + return (*_Cgo_int)(unsafe.Pointer(&union.$union)) +} +func (union *_Cgo_union_union2d) unionfield_d() *[2]float64 { return (*[2]float64)(unsafe.Pointer(&union.$union)) } -type C.union2d_t = C.union_union2d -type C.union_unionarray_t struct{ arr [10]C.uchar } -type C.unionarray_t = C.union_unionarray_t -type C._Ctype_union___0 struct{ $union [3]uint32 } +type _Cgo_union2d_t = _Cgo_union_union2d +type _Cgo_union_unionarray_t struct{ arr [10]_Cgo_uchar } +type _Cgo_unionarray_t = _Cgo_union_unionarray_t +type _Cgo__Ctype_union___0 struct{ $union [3]uint32 } -func (union *C._Ctype_union___0) unionfield_area() *C.point2d_t { - return (*C.point2d_t)(unsafe.Pointer(&union.$union)) +func (union *_Cgo__Ctype_union___0) unionfield_area() *_Cgo_point2d_t { + return (*_Cgo_point2d_t)(unsafe.Pointer(&union.$union)) } -func (union *C._Ctype_union___0) unionfield_solid() *C.point3d_t { - return (*C.point3d_t)(unsafe.Pointer(&union.$union)) +func (union *_Cgo__Ctype_union___0) unionfield_solid() *_Cgo_point3d_t { + return (*_Cgo_point3d_t)(unsafe.Pointer(&union.$union)) } -type C.struct_struct_nested_t struct { - begin C.point2d_t - end C.point2d_t - tag C.int +type _Cgo_struct_struct_nested_t struct { + begin _Cgo_point2d_t + end _Cgo_point2d_t + tag _Cgo_int - coord C._Ctype_union___0 + coord _Cgo__Ctype_union___0 } -type C.struct_nested_t = C.struct_struct_nested_t -type C.union_union_nested_t struct{ $union [2]uint64 } +type _Cgo_struct_nested_t = _Cgo_struct_struct_nested_t +type _Cgo_union_union_nested_t struct{ $union [2]uint64 } -func (union *C.union_union_nested_t) unionfield_point() *C.point3d_t { - return (*C.point3d_t)(unsafe.Pointer(&union.$union)) +func (union *_Cgo_union_union_nested_t) unionfield_point() *_Cgo_point3d_t { + return (*_Cgo_point3d_t)(unsafe.Pointer(&union.$union)) } -func (union *C.union_union_nested_t) unionfield_array() *C.unionarray_t { - return (*C.unionarray_t)(unsafe.Pointer(&union.$union)) +func (union *_Cgo_union_union_nested_t) unionfield_array() *_Cgo_unionarray_t { + return (*_Cgo_unionarray_t)(unsafe.Pointer(&union.$union)) } -func (union *C.union_union_nested_t) unionfield_thing() *C.union3_t { - return (*C.union3_t)(unsafe.Pointer(&union.$union)) +func (union *_Cgo_union_union_nested_t) unionfield_thing() *_Cgo_union3_t { + return (*_Cgo_union3_t)(unsafe.Pointer(&union.$union)) } -type C.union_nested_t = C.union_union_nested_t -type C.enum_option = C.int -type C.option_t = C.enum_option -type C.enum_option2_t = C.uint -type C.option2_t = C.enum_option2_t -type C.struct_types_t struct { +type _Cgo_union_nested_t = _Cgo_union_union_nested_t +type _Cgo_enum_option = _Cgo_int +type _Cgo_option_t = _Cgo_enum_option +type _Cgo_enum_option2_t = _Cgo_uint +type _Cgo_option2_t = _Cgo_enum_option2_t +type _Cgo_struct_types_t struct { f float32 d float64 - ptr *C.int + ptr *_Cgo_int } -type C.types_t = C.struct_types_t -type C.myIntArray = [10]C.int -type C.struct_bitfield_t struct { - start C.uchar - __bitfield_1 C.uchar +type _Cgo_types_t = _Cgo_struct_types_t +type _Cgo_myIntArray = [10]_Cgo_int +type _Cgo_struct_bitfield_t struct { + start _Cgo_uchar + __bitfield_1 _Cgo_uchar - d C.uchar - e C.uchar + d _Cgo_uchar + e _Cgo_uchar } -func (s *C.struct_bitfield_t) bitfield_a() C.uchar { return s.__bitfield_1 & 0x1f } -func (s *C.struct_bitfield_t) set_bitfield_a(value C.uchar) { +func (s *_Cgo_struct_bitfield_t) bitfield_a() _Cgo_uchar { return s.__bitfield_1 & 0x1f } +func (s *_Cgo_struct_bitfield_t) set_bitfield_a(value _Cgo_uchar) { s.__bitfield_1 = s.__bitfield_1&^0x1f | value&0x1f<<0 } -func (s *C.struct_bitfield_t) bitfield_b() C.uchar { +func (s *_Cgo_struct_bitfield_t) bitfield_b() _Cgo_uchar { return s.__bitfield_1 >> 5 & 0x1 } -func (s *C.struct_bitfield_t) set_bitfield_b(value C.uchar) { +func (s *_Cgo_struct_bitfield_t) set_bitfield_b(value _Cgo_uchar) { s.__bitfield_1 = s.__bitfield_1&^0x20 | value&0x1<<5 } -func (s *C.struct_bitfield_t) bitfield_c() C.uchar { +func (s *_Cgo_struct_bitfield_t) bitfield_c() _Cgo_uchar { return s.__bitfield_1 >> 6 } -func (s *C.struct_bitfield_t) set_bitfield_c(value C.uchar, +func (s *_Cgo_struct_bitfield_t) set_bitfield_c(value _Cgo_uchar, ) { s.__bitfield_1 = s.__bitfield_1&0x3f | value<<6 } -type C.bitfield_t = C.struct_bitfield_t +type _Cgo_bitfield_t = _Cgo_struct_bitfield_t diff --git a/compiler/alias.go b/compiler/alias.go index b0191a7a11..9d57a587e7 100644 --- a/compiler/alias.go +++ b/compiler/alias.go @@ -18,11 +18,12 @@ var stdlibAliases = map[string]string{ // crypto packages "crypto/ed25519/internal/edwards25519/field.feMul": "crypto/ed25519/internal/edwards25519/field.feMulGeneric", "crypto/internal/edwards25519/field.feSquare": "crypto/ed25519/internal/edwards25519/field.feSquareGeneric", - "crypto/md5.block": "crypto/md5.blockGeneric", - "crypto/sha1.block": "crypto/sha1.blockGeneric", - "crypto/sha1.blockAMD64": "crypto/sha1.blockGeneric", - "crypto/sha256.block": "crypto/sha256.blockGeneric", - "crypto/sha512.blockAMD64": "crypto/sha512.blockGeneric", + "crypto/md5.block": "crypto/md5.blockGeneric", + "crypto/sha1.block": "crypto/sha1.blockGeneric", + "crypto/sha1.blockAMD64": "crypto/sha1.blockGeneric", + "crypto/sha256.block": "crypto/sha256.blockGeneric", + "crypto/sha512.blockAMD64": "crypto/sha512.blockGeneric", + "internal/chacha8rand.block": "internal/chacha8rand.block_generic", // AES "crypto/aes.decryptBlockAsm": "crypto/aes.decryptBlock", diff --git a/compiler/symbol.go b/compiler/symbol.go index 5ecf68e54a..1de3c6f39d 100644 --- a/compiler/symbol.go +++ b/compiler/symbol.go @@ -432,9 +432,8 @@ func (c *compilerContext) parsePragmas(info *functionInfo, f *ssa.Function) { // pass for C variadic functions. This includes both explicit // (with ...) and implicit (no parameters in signature) // functions. - if strings.HasPrefix(f.Name(), "C.") { - // This prefix cannot naturally be created, it must have - // been created as a result of CGo preprocessing. + if strings.HasPrefix(f.Name(), "_Cgo_") { + // This prefix was created as a result of CGo preprocessing. info.variadic = true } } diff --git a/src/internal/abi/type.go b/src/internal/abi/type.go new file mode 100644 index 0000000000..d1853e0f3d --- /dev/null +++ b/src/internal/abi/type.go @@ -0,0 +1,7 @@ +package abi + +type Type struct { + // Intentionally left empty. TinyGo uses a different way to represent types, + // so this is unimplementable. The type definition here is purely for + // compatibility. +} diff --git a/src/internal/task/task.go b/src/internal/task/task.go index 546f5ba117..58c02fe846 100644 --- a/src/internal/task/task.go +++ b/src/internal/task/task.go @@ -21,6 +21,9 @@ type Task struct { // state is the underlying running state of the task. state state + // This is needed for some crypto packages. + FipsIndicator uint8 + // DeferFrame stores a pointer to the (stack allocated) defer frame of the // goroutine that is used for the recover builtin. DeferFrame unsafe.Pointer diff --git a/src/machine/flash.go b/src/machine/flash.go index 716fc4a53b..da832afdb8 100644 --- a/src/machine/flash.go +++ b/src/machine/flash.go @@ -64,3 +64,14 @@ type BlockDevice interface { // EraseBlockSize to map addresses to blocks. EraseBlocks(start, len int64) error } + +// pad data if needed so it is long enough for correct byte alignment on writes. +func flashPad(p []byte, writeBlockSize int) []byte { + overflow := len(p) % writeBlockSize + if overflow != 0 { + for i := 0; i < writeBlockSize-overflow; i++ { + p = append(p, 0xff) + } + } + return p +} diff --git a/src/machine/machine_atsamd21.go b/src/machine/machine_atsamd21.go index 3d0abc0fa8..0a5c320ca0 100644 --- a/src/machine/machine_atsamd21.go +++ b/src/machine/machine_atsamd21.go @@ -7,7 +7,6 @@ package machine import ( - "bytes" "device/arm" "device/sam" "errors" @@ -1917,7 +1916,7 @@ func (f flashBlockDevice) WriteAt(p []byte, off int64) (n int, err error) { f.ensureInitComplete() address := FlashDataStart() + uintptr(off) - padded := f.pad(p) + padded := flashPad(p, int(f.WriteBlockSize())) waitWhileFlashBusy() @@ -1992,17 +1991,6 @@ func (f flashBlockDevice) EraseBlocks(start, len int64) error { return nil } -// pad data if needed so it is long enough for correct byte alignment on writes. -func (f flashBlockDevice) pad(p []byte) []byte { - overflow := int64(len(p)) % f.WriteBlockSize() - if overflow == 0 { - return p - } - - padding := bytes.Repeat([]byte{0xff}, int(f.WriteBlockSize()-overflow)) - return append(p, padding...) -} - func (f flashBlockDevice) ensureInitComplete() { if f.initComplete { return diff --git a/src/machine/machine_atsamd51.go b/src/machine/machine_atsamd51.go index bcaaec7212..5cd1d314a2 100644 --- a/src/machine/machine_atsamd51.go +++ b/src/machine/machine_atsamd51.go @@ -7,7 +7,6 @@ package machine import ( - "bytes" "device/arm" "device/sam" "errors" @@ -2174,7 +2173,7 @@ func (f flashBlockDevice) WriteAt(p []byte, off int64) (n int, err error) { } address := FlashDataStart() + uintptr(off) - padded := f.pad(p) + padded := flashPad(p, int(f.WriteBlockSize())) settings := disableFlashCache() defer restoreFlashCache(settings) @@ -2263,17 +2262,6 @@ func (f flashBlockDevice) EraseBlocks(start, len int64) error { return nil } -// pad data if needed so it is long enough for correct byte alignment on writes. -func (f flashBlockDevice) pad(p []byte) []byte { - overflow := int64(len(p)) % f.WriteBlockSize() - if overflow == 0 { - return p - } - - padding := bytes.Repeat([]byte{0xff}, int(f.WriteBlockSize()-overflow)) - return append(p, padding...) -} - func disableFlashCache() uint16 { settings := sam.NVMCTRL.CTRLA.Get() diff --git a/src/machine/machine_nrf.go b/src/machine/machine_nrf.go index 4da6645352..d6d6349f29 100644 --- a/src/machine/machine_nrf.go +++ b/src/machine/machine_nrf.go @@ -3,7 +3,6 @@ package machine import ( - "bytes" "device/nrf" "internal/binary" "runtime/interrupt" @@ -386,7 +385,7 @@ func (f flashBlockDevice) WriteAt(p []byte, off int64) (n int, err error) { } address := FlashDataStart() + uintptr(off) - padded := f.pad(p) + padded := flashPad(p, int(f.WriteBlockSize())) waitWhileFlashBusy() @@ -444,17 +443,6 @@ func (f flashBlockDevice) EraseBlocks(start, len int64) error { return nil } -// pad data if needed so it is long enough for correct byte alignment on writes. -func (f flashBlockDevice) pad(p []byte) []byte { - overflow := int64(len(p)) % f.WriteBlockSize() - if overflow == 0 { - return p - } - - padding := bytes.Repeat([]byte{0xff}, int(f.WriteBlockSize()-overflow)) - return append(p, padding...) -} - func waitWhileFlashBusy() { for nrf.NVMC.GetREADY() != nrf.NVMC_READY_READY_Ready { } diff --git a/src/machine/machine_rp2040_flash.go b/src/machine/machine_rp2040_flash.go index 8ee881e19a..1317c0926a 100644 --- a/src/machine/machine_rp2040_flash.go +++ b/src/machine/machine_rp2040_flash.go @@ -3,7 +3,6 @@ package machine import ( - "bytes" "unsafe" ) @@ -101,17 +100,6 @@ func (f flashBlockDevice) EraseBlocks(start, length int64) error { return f.eraseBlocks(start, length) } -// pad data if needed so it is long enough for correct byte alignment on writes. -func (f flashBlockDevice) pad(p []byte) []byte { - overflow := int64(len(p)) % f.WriteBlockSize() - if overflow == 0 { - return p - } - - padding := bytes.Repeat([]byte{0xff}, int(f.WriteBlockSize()-overflow)) - return append(p, padding...) -} - // return the correct address to be used for write func writeAddress(off int64) uintptr { return readAddress(off) - uintptr(memoryStart) diff --git a/src/machine/machine_rp2040_rom.go b/src/machine/machine_rp2040_rom.go index eea461882d..5541e2a9bf 100644 --- a/src/machine/machine_rp2040_rom.go +++ b/src/machine/machine_rp2040_rom.go @@ -230,7 +230,7 @@ func (f flashBlockDevice) writeAt(p []byte, off int64) (n int, err error) { // e.g. real address 0x10003000 is written to at // 0x00003000 address := writeAddress(off) - padded := f.pad(p) + padded := flashPad(p, int(f.WriteBlockSize())) C.flash_range_write(C.uint32_t(address), (*C.uint8_t)(unsafe.Pointer(&padded[0])), diff --git a/src/machine/machine_stm32_flash.go b/src/machine/machine_stm32_flash.go index 710aa05d00..280dc8987e 100644 --- a/src/machine/machine_stm32_flash.go +++ b/src/machine/machine_stm32_flash.go @@ -5,7 +5,6 @@ package machine import ( "device/stm32" - "bytes" "unsafe" ) @@ -41,7 +40,8 @@ func (f flashBlockDevice) WriteAt(p []byte, off int64) (n int, err error) { unlockFlash() defer lockFlash() - return writeFlashData(FlashDataStart()+uintptr(off), f.pad(p)) + p = flashPad(p, int(f.WriteBlockSize())) + return writeFlashData(FlashDataStart()+uintptr(off), p) } // Size returns the number of bytes in this block device. @@ -90,17 +90,6 @@ func (f flashBlockDevice) EraseBlocks(start, len int64) error { return nil } -// pad data if needed so it is long enough for correct byte alignment on writes. -func (f flashBlockDevice) pad(p []byte) []byte { - overflow := int64(len(p)) % f.WriteBlockSize() - if overflow == 0 { - return p - } - - padding := bytes.Repeat([]byte{0xff}, int(f.WriteBlockSize()-overflow)) - return append(p, padding...) -} - const memoryStart = 0x08000000 func unlockFlash() { diff --git a/src/machine/usb/descriptor/hid.go b/src/machine/usb/descriptor/hid.go index ea65f1ed97..06b9801530 100644 --- a/src/machine/usb/descriptor/hid.go +++ b/src/machine/usb/descriptor/hid.go @@ -1,9 +1,9 @@ package descriptor import ( - "bytes" "errors" "internal/binary" + "internal/bytealg" ) var configurationCDCHID = [configurationTypeLen]byte{ @@ -87,7 +87,7 @@ func FindClassHIDType(des, class []byte) (ClassHIDType, error) { // search only for ClassHIDType without the ClassLength, // in case it has already been set. - idx := bytes.Index(des, class[:ClassHIDTypeLen-2]) + idx := bytealg.Index(des, class[:ClassHIDTypeLen-2]) if idx == -1 { return ClassHIDType{}, errNoClassHIDFound } diff --git a/src/os/file.go b/src/os/file.go index 0e20d1bf10..e7dd214b73 100644 --- a/src/os/file.go +++ b/src/os/file.go @@ -318,6 +318,17 @@ func (f *File) Chmod(mode FileMode) (err error) { return } +// Chdir changes the current working directory to the file, which must be a +// directory. If there is an error, it will be of type *PathError. +func (f *File) Chdir() (err error) { + if f.handle == nil { + err = ErrClosed + } else { + err = f.chdir() + } + return +} + // LinkError records an error during a link or symlink or rename system call and // the paths that caused it. type LinkError struct { diff --git a/src/os/file_other.go b/src/os/file_other.go index 75c0332817..8e7d33e00e 100644 --- a/src/os/file_other.go +++ b/src/os/file_other.go @@ -42,6 +42,12 @@ func NewFile(fd uintptr, name string) *File { return &File{&file{handle: stdioFileHandle(fd), name: name}} } +// Chdir changes the current working directory to the named directory. +// If there is an error, it will be of type *PathError. +func Chdir(dir string) error { + return ErrNotImplemented +} + // Rename renames (moves) oldpath to newpath. // If newpath already exists and is not a directory, Rename replaces it. // OS-specific restrictions may apply when oldpath and newpath are in different directories. @@ -153,3 +159,7 @@ func (f *File) Truncate(size int64) (err error) { func (f *File) chmod(mode FileMode) error { return ErrUnsupported } + +func (f *File) chdir() error { + return ErrNotImplemented +} diff --git a/src/os/file_unix.go b/src/os/file_unix.go index fd4d464f5b..9dc3a91e09 100644 --- a/src/os/file_unix.go +++ b/src/os/file_unix.go @@ -166,6 +166,22 @@ func (f *File) chmod(mode FileMode) error { return nil } +func (f *File) chdir() error { + if f.handle == nil { + return ErrClosed + } + + // TODO: use syscall.Fchdir instead + longName := fixLongPath(f.name) + e := ignoringEINTR(func() error { + return syscall.Chdir(longName) + }) + if e != nil { + return &PathError{Op: "chdir", Path: f.name, Err: e} + } + return nil +} + // ReadAt reads up to len(b) bytes from the File starting at the given absolute offset. // It returns the number of bytes read and any error encountered, possibly io.EOF. // At end of file, Pread returns 0, io.EOF. diff --git a/src/os/file_windows.go b/src/os/file_windows.go index 022381deed..50c5ee7a82 100644 --- a/src/os/file_windows.go +++ b/src/os/file_windows.go @@ -146,3 +146,7 @@ func isWindowsNulName(name string) bool { func (f *File) chmod(mode FileMode) error { return ErrNotImplemented } + +func (f *File) chdir() error { + return ErrNotImplemented +} diff --git a/src/reflect/value.go b/src/reflect/value.go index 69b57fd1cc..7ac71aa184 100644 --- a/src/reflect/value.go +++ b/src/reflect/value.go @@ -271,6 +271,10 @@ func (v Value) Comparable() bool { } } +func (v Value) Equal(u Value) bool { + panic("unimplemented: reflect.Value.Equal") +} + func (v Value) Addr() Value { if !v.CanAddr() { panic("reflect.Value.Addr of unaddressable value") diff --git a/src/runtime/panic.go b/src/runtime/panic.go index ec33a4469c..9ae1f982b9 100644 --- a/src/runtime/panic.go +++ b/src/runtime/panic.go @@ -226,3 +226,8 @@ func divideByZeroPanic() { func blockingPanic() { runtimePanicAt(returnAddress(0), "trying to do blocking operation in exported function") } + +//go:linkname fips_fatal crypto/internal/fips140.fatal +func fips_fatal(msg string) { + runtimePanic(msg) +} diff --git a/src/runtime/scheduler.go b/src/runtime/scheduler.go index 727c7f5f2c..40740da310 100644 --- a/src/runtime/scheduler.go +++ b/src/runtime/scheduler.go @@ -31,3 +31,14 @@ func scheduleLogChan(msg string, ch *channel, t *task.Task) { func Goexit() { panicOrGoexit(nil, panicGoexit) } + +//go:linkname fips_getIndicator crypto/internal/fips140.getIndicator +func fips_getIndicator() uint8 { + return task.Current().FipsIndicator +} + +//go:linkname fips_setIndicator crypto/internal/fips140.setIndicator +func fips_setIndicator(indicator uint8) { + // This indicator is stored per goroutine. + task.Current().FipsIndicator = indicator +} diff --git a/src/runtime/synctest.go b/src/runtime/synctest.go new file mode 100644 index 0000000000..fa11c991fc --- /dev/null +++ b/src/runtime/synctest.go @@ -0,0 +1,15 @@ +package runtime + +// Dummy implementation of synctest functions (we don't support synctest at the +// moment). + +//go:linkname synctest_acquire internal/synctest.acquire +func synctest_acquire() any { + // Dummy: we don't support synctest. + return nil +} + +//go:linkname synctest_release internal/synctest.release +func synctest_release(sg any) { + // Dummy: we don't support synctest. +} diff --git a/src/runtime/time.go b/src/runtime/time.go index 50bf61cf3c..3935b4486e 100644 --- a/src/runtime/time.go +++ b/src/runtime/time.go @@ -1,5 +1,18 @@ package runtime +//go:linkname time_runtimeNano time.runtimeNano +func time_runtimeNano() int64 { + // Note: we're ignoring sync groups here (package testing/synctest). + // See: https://github.com/golang/go/issues/67434 + return nanotime() +} + +//go:linkname time_runtimeNow time.runtimeNow +func time_runtimeNow() (sec int64, nsec int32, mono int64) { + // Also ignoring the sync group here, like time_runtimeNano above. + return now() +} + // timerNode is an element in a linked list of timers. type timerNode struct { next *timerNode diff --git a/src/syscall/syscall_libc.go b/src/syscall/syscall_libc.go index 0ef9784283..86c756383e 100644 --- a/src/syscall/syscall_libc.go +++ b/src/syscall/syscall_libc.go @@ -233,6 +233,10 @@ func (w WaitStatus) Continued() bool { return false } func (w WaitStatus) StopSignal() Signal { return 0 } func (w WaitStatus) TrapCause() int { return 0 } +// Purely here for compatibility. +type Rusage struct { +} + // since rusage is quite a big struct and we stub it out anyway no need to define it here func Wait4(pid int, wstatus *WaitStatus, options int, rusage uintptr) (wpid int, err error) { return 0, ENOSYS // TODO diff --git a/src/syscall/syscall_libc_wasi.go b/src/syscall/syscall_libc_wasi.go index bbf81cd059..479377877b 100644 --- a/src/syscall/syscall_libc_wasi.go +++ b/src/syscall/syscall_libc_wasi.go @@ -120,8 +120,11 @@ const ( SYS_FCNTL64 SYS_FSTATAT64 SYS_IOCTL + SYS_MKDIRAT SYS_OPENAT + SYS_READLINKAT SYS_UNLINKAT + SYS_WAITID PATH_MAX = 4096 ) @@ -438,6 +441,13 @@ type RawSockaddrInet6 struct { // stub } +func RandomGet(b []byte) error { + if len(b) > 0 { + libc_arc4random_buf(unsafe.Pointer(&b[0]), uint(len(b))) + } + return nil +} + // This is a stub, it is not functional. func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) @@ -483,3 +493,8 @@ func libc_fdclosedir(unsafe.Pointer) int32 // //export readdir func libc_readdir(unsafe.Pointer) *Dirent + +// void arc4random_buf(void *buf, size_t buflen); +// +//export arc4random_buf +func libc_arc4random_buf(buf unsafe.Pointer, buflen uint) diff --git a/src/testing/testing.go b/src/testing/testing.go index cd19ada710..121f24ccf7 100644 --- a/src/testing/testing.go +++ b/src/testing/testing.go @@ -17,6 +17,7 @@ import ( "io/fs" "math/rand" "os" + "path/filepath" "runtime" "strconv" "strings" @@ -390,6 +391,49 @@ func (c *common) Setenv(key, value string) { } } +// Chdir calls os.Chdir(dir) and uses Cleanup to restore the current +// working directory to its original value after the test. On Unix, it +// also sets PWD environment variable for the duration of the test. +// +// Because Chdir affects the whole process, it cannot be used +// in parallel tests or tests with parallel ancestors. +func (c *common) Chdir(dir string) { + // Note: function copied from the Go 1.24.0 source tree. + + oldwd, err := os.Open(".") + if err != nil { + c.Fatal(err) + } + if err := os.Chdir(dir); err != nil { + c.Fatal(err) + } + // On POSIX platforms, PWD represents “an absolute pathname of the + // current working directory.” Since we are changing the working + // directory, we should also set or update PWD to reflect that. + switch runtime.GOOS { + case "windows", "plan9": + // Windows and Plan 9 do not use the PWD variable. + default: + if !filepath.IsAbs(dir) { + dir, err = os.Getwd() + if err != nil { + c.Fatal(err) + } + } + c.Setenv("PWD", dir) + } + c.Cleanup(func() { + err := oldwd.Chdir() + oldwd.Close() + if err != nil { + // It's not safe to continue with tests if we can't + // get back to the original working directory. Since + // we are holding a dirfd, this is highly unlikely. + panic("testing.Chdir: " + err.Error()) + } + }) +} + // runCleanup is called at the end of the test. func (c *common) runCleanup() { for {