diff --git a/src/cmd/dist/build.go b/src/cmd/dist/build.go index 2b382a1c025649..2b4818cc893198 100644 --- a/src/cmd/dist/build.go +++ b/src/cmd/dist/build.go @@ -1811,6 +1811,7 @@ var cgoEnabled = map[string]bool{ "plan9/386": false, "plan9/amd64": false, "plan9/arm": false, + "plan9/arm64": false, "solaris/amd64": true, "windows/386": true, "windows/amd64": true, diff --git a/src/cmd/go/internal/work/exec.go b/src/cmd/go/internal/work/exec.go index 0c9e96aebbf080..ce078ffd2b1f99 100644 --- a/src/cmd/go/internal/work/exec.go +++ b/src/cmd/go/internal/work/exec.go @@ -2075,6 +2075,7 @@ var objectMagic = [][]byte{ {0x00, 0x00, 0x01, 0xEB}, // Plan 9 i386 {0x00, 0x00, 0x8a, 0x97}, // Plan 9 amd64 {0x00, 0x00, 0x06, 0x47}, // Plan 9 arm + {0x00, 0x00, 0x8c, 0x47}, // Plan 9 arm64 {0x00, 0x61, 0x73, 0x6D}, // WASM {0x01, 0xDF}, // XCOFF 32bit {0x01, 0xF7}, // XCOFF 64bit diff --git a/src/cmd/go/testdata/script/work_env.txt b/src/cmd/go/testdata/script/work_env.txt index 8b1779ea703725..54e51dae0fddb6 100644 --- a/src/cmd/go/testdata/script/work_env.txt +++ b/src/cmd/go/testdata/script/work_env.txt @@ -1,7 +1,7 @@ go env GOWORK stdout '^'$GOPATH'[\\/]src[\\/]go.work$' go env -stdout '^(set )?GOWORK=''?'$GOPATH'[\\/]src[\\/]go.work''?$' +stdout '^(set )?GOWORK=["'']?'$GOPATH'[\\/]src[\\/]go.work["'']?$' cd .. go env GOWORK diff --git a/src/cmd/internal/objfile/plan9obj.go b/src/cmd/internal/objfile/plan9obj.go index edd40230cec0c2..f9801c07aaa9c2 100644 --- a/src/cmd/internal/objfile/plan9obj.go +++ b/src/cmd/internal/objfile/plan9obj.go @@ -137,6 +137,8 @@ func (f *plan9File) goarch() string { return "amd64" case plan9obj.MagicARM: return "arm" + case plan9obj.MagicARM64: + return "arm64" } return "" } diff --git a/src/cmd/link/internal/arm64/obj.go b/src/cmd/link/internal/arm64/obj.go index 3d358155badbca..cc3b113fabc95d 100644 --- a/src/cmd/link/internal/arm64/obj.go +++ b/src/cmd/link/internal/arm64/obj.go @@ -47,6 +47,9 @@ func Init() (*sys.Arch, ld.Arch) { Dwarfreglr: dwarfRegLR, TrampLimit: 0x7c00000, // 26-bit signed offset * 4, leave room for PLT etc. + Plan9Magic: 0x8c47, + Plan9_64Bit: true, + Adddynrel: adddynrel, Archinit: archinit, Archreloc: archreloc, @@ -85,12 +88,12 @@ func archinit(ctxt *ld.Link) { ld.Exitf("unknown -H option: %v", ctxt.HeadType) case objabi.Hplan9: /* plan 9 */ - ld.HEADR = 32 + ld.HEADR = 32 + 8 if *ld.FlagRound == -1 { - *ld.FlagRound = 4096 + *ld.FlagRound = 0x10000 } if *ld.FlagTextAddr == -1 { - *ld.FlagTextAddr = ld.Rnd(4096, *ld.FlagRound) + int64(ld.HEADR) + *ld.FlagTextAddr = ld.Rnd(0x10000, *ld.FlagRound) + int64(ld.HEADR) } case objabi.Hlinux, /* arm64 elf */ diff --git a/src/cmd/link/internal/ld/main.go b/src/cmd/link/internal/ld/main.go index d913953944bc43..8fee98190c40f5 100644 --- a/src/cmd/link/internal/ld/main.go +++ b/src/cmd/link/internal/ld/main.go @@ -193,7 +193,7 @@ func Main(arch *sys.Arch, theArch Arch) { addstrdata1(ctxt, "runtime.buildVersion="+buildVersion) // TODO(matloob): define these above and then check flag values here - if ctxt.Arch.Family == sys.AMD64 && buildcfg.GOOS == "plan9" { + if (ctxt.Arch.Family == sys.AMD64 || ctxt.Arch.Family == sys.ARM64) && buildcfg.GOOS == "plan9" { flag.BoolVar(&flag8, "8", false, "use 64-bit addresses in symbol table") } flagHeadType := flag.String("H", "", "set header `type`") diff --git a/src/cmd/link/internal/ld/symtab.go b/src/cmd/link/internal/ld/symtab.go index a0345ca1c7b7b7..dd2a16bd956283 100644 --- a/src/cmd/link/internal/ld/symtab.go +++ b/src/cmd/link/internal/ld/symtab.go @@ -294,7 +294,7 @@ func putplan9sym(ctxt *Link, ldr *loader.Loader, s loader.Sym, char SymbolType) } l := 4 addr := ldr.SymValue(s) - if ctxt.IsAMD64() && !flag8 { + if (ctxt.IsAMD64() || ctxt.IsARM64()) && !flag8 { ctxt.Out.Write32b(uint32(addr >> 32)) l = 8 } diff --git a/src/cmd/vendor/golang.org/x/sys/plan9/asm_plan9_arm64.s b/src/cmd/vendor/golang.org/x/sys/plan9/asm_plan9_arm64.s new file mode 100644 index 00000000000000..9014318d4d6047 --- /dev/null +++ b/src/cmd/vendor/golang.org/x/sys/plan9/asm_plan9_arm64.s @@ -0,0 +1,28 @@ +// 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" + +// System call support for plan9 on arm64 + +// Just jump to package syscall's implementation for all these functions. +// The runtime may know about them. + +TEXT ·Syscall(SB),NOSPLIT,$0-64 + JMP syscall·Syscall(SB) + +TEXT ·Syscall6(SB),NOSPLIT,$0-88 + JMP syscall·Syscall6(SB) + +TEXT ·RawSyscall(SB),NOSPLIT,$0-56 + JMP syscall·RawSyscall(SB) + +TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 + JMP syscall·RawSyscall6(SB) + +TEXT ·seek(SB),NOSPLIT,$0-56 + JMP syscall·seek(SB) + +TEXT ·exit(SB),NOSPLIT,$8-8 + JMP syscall·exit(SB) diff --git a/src/cmd/vendor/golang.org/x/sys/plan9/zsyscall_plan9_arm64.go b/src/cmd/vendor/golang.org/x/sys/plan9/zsyscall_plan9_arm64.go new file mode 100644 index 00000000000000..dd0265ac7aedf6 --- /dev/null +++ b/src/cmd/vendor/golang.org/x/sys/plan9/zsyscall_plan9_arm64.go @@ -0,0 +1,286 @@ +// go run mksyscall.go -l32 -plan9 -tags plan9,arm64 syscall_plan9.go +// Code generated by the command above; DO NOT EDIT. + +//go:build plan9 && arm64 +// +build plan9,arm64 + +package plan9 + +import "unsafe" + + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func fd2path(fd int, buf []byte) (err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_FD2PATH, uintptr(fd), uintptr(_p0), uintptr(len(buf))) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func pipe(p *[2]int32) (err error) { + r0, _, e1 := Syscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func await(s []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(s) > 0 { + _p0 = unsafe.Pointer(&s[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_AWAIT, uintptr(_p0), uintptr(len(s)), 0) + n = int(r0) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func open(path string, mode int) (fd int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) + fd = int(r0) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func create(path string, mode int, perm uint32) (fd int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + r0, _, e1 := Syscall(SYS_CREATE, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm)) + fd = int(r0) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func remove(path string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + r0, _, e1 := Syscall(SYS_REMOVE, uintptr(unsafe.Pointer(_p0)), 0, 0) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func stat(path string, edir []byte) (n int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(edir) > 0 { + _p1 = unsafe.Pointer(&edir[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir))) + n = int(r0) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func bind(name string, old string, flag int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(name) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(old) + if err != nil { + return + } + r0, _, e1 := Syscall(SYS_BIND, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flag)) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func mount(fd int, afd int, old string, flag int, aname string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(old) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(aname) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_MOUNT, uintptr(fd), uintptr(afd), uintptr(unsafe.Pointer(_p0)), uintptr(flag), uintptr(unsafe.Pointer(_p1)), 0) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func wstat(path string, edir []byte) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(edir) > 0 { + _p1 = unsafe.Pointer(&edir[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_WSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir))) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func chdir(path string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + r0, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Dup(oldfd int, newfd int) (fd int, err error) { + r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), uintptr(newfd), 0) + fd = int(r0) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Pread(fd int, p []byte, offset int64) (n int, err error) { + var _p0 unsafe.Pointer + if len(p) > 0 { + _p0 = unsafe.Pointer(&p[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0) + n = int(r0) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Pwrite(fd int, p []byte, offset int64) (n int, err error) { + var _p0 unsafe.Pointer + if len(p) > 0 { + _p0 = unsafe.Pointer(&p[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0) + n = int(r0) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Close(fd int) (err error) { + r0, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fstat(fd int, edir []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(edir) > 0 { + _p0 = unsafe.Pointer(&edir[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir))) + n = int(r0) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fwstat(fd int, edir []byte) (err error) { + var _p0 unsafe.Pointer + if len(edir) > 0 { + _p0 = unsafe.Pointer(&edir[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_FWSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir))) + if int32(r0) == -1 { + err = e1 + } + return +} diff --git a/src/debug/buildinfo/buildinfo.go b/src/debug/buildinfo/buildinfo.go index d202d5050a2786..3ceb23cfffe546 100644 --- a/src/debug/buildinfo/buildinfo.go +++ b/src/debug/buildinfo/buildinfo.go @@ -274,7 +274,7 @@ func hasPlan9Magic(magic []byte) bool { if len(magic) >= 4 { m := binary.BigEndian.Uint32(magic) switch m { - case plan9obj.Magic386, plan9obj.MagicAMD64, plan9obj.MagicARM: + case plan9obj.Magic386, plan9obj.MagicAMD64, plan9obj.MagicARM, plan9obj.MagicARM64: return true } } diff --git a/src/debug/plan9obj/file.go b/src/debug/plan9obj/file.go index 0880c3cc182003..d89c6cd78b36ba 100644 --- a/src/debug/plan9obj/file.go +++ b/src/debug/plan9obj/file.go @@ -130,7 +130,7 @@ func (f *File) Close() error { func parseMagic(magic []byte) (uint32, error) { m := binary.BigEndian.Uint32(magic) switch m { - case Magic386, MagicAMD64, MagicARM: + case Magic386, MagicAMD64, MagicARM, MagicARM64: return m, nil } return 0, &formatError{0, "bad magic number", magic} @@ -145,7 +145,7 @@ func NewFile(r io.ReaderAt) (*File, error) { if _, err := r.ReadAt(magic[:], 0); err != nil { return nil, err } - _, err := parseMagic(magic[:]) + m, err := parseMagic(magic[:]) if err != nil { return nil, err } @@ -169,7 +169,11 @@ func NewFile(r io.ReaderAt) (*File, error) { return nil, err } f.PtrSize = 8 - f.LoadAddress = 0x200000 + if m == MagicARM64 { + f.LoadAddress = 0x10000 + } else { + f.LoadAddress = 0x200000 + } f.HdrSize += 8 } diff --git a/src/debug/plan9obj/file_test.go b/src/debug/plan9obj/file_test.go index 7e107bca2f52d8..75498fcb5fe4eb 100644 --- a/src/debug/plan9obj/file_test.go +++ b/src/debug/plan9obj/file_test.go @@ -38,6 +38,17 @@ var fileTests = []fileTest{ {"pcsz", 0xca0, 0x7947}, }, }, + { + "testdata/arm64-plan9-exec", + FileHeader{MagicARM64, 0x408, 0x1003c, 8, 0x10000, 40}, + []*SectionHeader{ + {"text", 0x4a00, 0x28}, + {"data", 0xaa0, 0x4a28}, + {"syms", 0x294a, 0x54c8}, + {"spsz", 0x0, 0x7e12}, + {"pcsz", 0xa6c, 0x7e12}, + }, + }, } func TestOpen(t *testing.T) { diff --git a/src/debug/plan9obj/plan9obj.go b/src/debug/plan9obj/plan9obj.go index 7a194514c2c719..98e97a26820240 100644 --- a/src/debug/plan9obj/plan9obj.go +++ b/src/debug/plan9obj/plan9obj.go @@ -33,4 +33,5 @@ const ( Magic386 = (4*11+0)*11 + 7 MagicAMD64 = (4*26+0)*26 + 7 + Magic64 MagicARM = (4*20+0)*20 + 7 + MagicARM64 = (4*28+0)*28 + 7 + Magic64 ) diff --git a/src/debug/plan9obj/testdata/arm64-plan9-exec b/src/debug/plan9obj/testdata/arm64-plan9-exec new file mode 100755 index 00000000000000..3fa2c423e5b943 Binary files /dev/null and b/src/debug/plan9obj/testdata/arm64-plan9-exec differ diff --git a/src/internal/platform/zosarch.go b/src/internal/platform/zosarch.go index a2f5b22ea9a656..a81735caca5baa 100644 --- a/src/internal/platform/zosarch.go +++ b/src/internal/platform/zosarch.go @@ -53,6 +53,7 @@ var List = []OSArch{ {"plan9", "386"}, {"plan9", "amd64"}, {"plan9", "arm"}, + {"plan9", "arm64"}, {"solaris", "amd64"}, {"wasip1", "wasm"}, {"windows", "386"}, @@ -106,6 +107,7 @@ var distInfo = map[OSArch]osArchInfo{ {"plan9", "386"}: {}, {"plan9", "amd64"}: {}, {"plan9", "arm"}: {}, + {"plan9", "arm64"}: {}, {"solaris", "amd64"}: {CgoSupported: true}, {"wasip1", "wasm"}: {}, {"windows", "386"}: {CgoSupported: true, FirstClass: true}, diff --git a/src/net/udpsock_test.go b/src/net/udpsock_test.go index a79e9f83c11098..a0cedb748b021f 100644 --- a/src/net/udpsock_test.go +++ b/src/net/udpsock_test.go @@ -679,7 +679,7 @@ func TestIPv6WriteMsgUDPAddrPortTargetAddrIPVersion(t *testing.T) { } switch runtime.GOOS { - case "dragonfly", "openbsd": + case "dragonfly", "openbsd", "plan9": // DragonflyBSD's IPv6 sockets are always IPv6-only, according to the man page: // https://www.dragonflybsd.org/cgi/web-man?command=ip6 (search for IPV6_V6ONLY). // OpenBSD's IPv6 sockets are always IPv6-only, according to the man page: diff --git a/src/runtime/defs_plan9_arm64.go b/src/runtime/defs_plan9_arm64.go new file mode 100644 index 00000000000000..e6803c9adff5bf --- /dev/null +++ b/src/runtime/defs_plan9_arm64.go @@ -0,0 +1,103 @@ +// 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. + +package runtime + +const _PAGESHIFT = 16 +const _PAGESIZE = 1 << _PAGESHIFT + +type ureg struct { + /* AArch64 registers */ + r0 uint64 /* general registers */ + r1 uint64 /* ... */ + r2 uint64 /* ... */ + r3 uint64 /* ... */ + r4 uint64 /* ... */ + r5 uint64 /* ... */ + r6 uint64 /* ... */ + r7 uint64 /* ... */ + r8 uint64 /* ... */ + r9 uint64 /* ... */ + r10 uint64 /* ... */ + r11 uint64 /* ... */ + r12 uint64 /* ... */ + r13 uint64 /* ... */ + r14 uint64 /* ... */ + r15 uint64 /* ... */ + r16 uint64 /* ... */ + r17 uint64 /* ... */ + r18 uint64 /* ... */ + r19 uint64 /* ... */ + r20 uint64 /* ... */ + r21 uint64 /* ... */ + r22 uint64 /* ... */ + r23 uint64 /* ... */ + r24 uint64 /* ... */ + r25 uint64 /* ... */ + r26 uint64 /* ... */ + r27 uint64 /* ... */ + r28 uint64 /* ... */ + r29 uint64 /* ... */ + r30 uint64 /* link (lr) */ + sp uint64 + pc uint64 /* interrupted addr */ + psr uint64 + typ uint64 /* of exception */ +} + +type sigctxt struct { + u *ureg +} + +//go:nosplit +//go:nowritebarrierrec +func (c *sigctxt) pc() uintptr { return uintptr(c.u.pc) } + +func (c *sigctxt) sp() uintptr { return uintptr(c.u.sp) } +func (c *sigctxt) lr() uintptr { return uintptr(c.u.r30) } + +func (c *sigctxt) setpc(x uintptr) { c.u.pc = uint64(x) } +func (c *sigctxt) setsp(x uintptr) { c.u.sp = uint64(x) } +func (c *sigctxt) setlr(x uintptr) { c.u.r30 = uint64(x) } +func (c *sigctxt) savelr(x uintptr) { c.u.r0 = uint64(x) } + +func dumpregs(u *ureg) { + print("r0 ", hex(u.r0), "\n") + print("r1 ", hex(u.r1), "\n") + print("r2 ", hex(u.r2), "\n") + print("r3 ", hex(u.r3), "\n") + print("r4 ", hex(u.r4), "\n") + print("r5 ", hex(u.r5), "\n") + print("r6 ", hex(u.r6), "\n") + print("r7 ", hex(u.r7), "\n") + print("r8 ", hex(u.r8), "\n") + print("r9 ", hex(u.r9), "\n") + print("r10 ", hex(u.r10), "\n") + print("r11 ", hex(u.r11), "\n") + print("r12 ", hex(u.r12), "\n") + print("r13 ", hex(u.r13), "\n") + print("r14 ", hex(u.r14), "\n") + print("r15 ", hex(u.r15), "\n") + print("r16 ", hex(u.r16), "\n") + print("r17 ", hex(u.r17), "\n") + print("r18 ", hex(u.r18), "\n") + print("r19 ", hex(u.r19), "\n") + print("r20 ", hex(u.r20), "\n") + print("r21 ", hex(u.r21), "\n") + print("r22 ", hex(u.r22), "\n") + print("r23 ", hex(u.r23), "\n") + print("r24 ", hex(u.r24), "\n") + print("r25 ", hex(u.r25), "\n") + print("r26 ", hex(u.r26), "\n") + print("r27 ", hex(u.r27), "\n") + print("r28 ", hex(u.r28), "\n") + print("r29 ", hex(u.r29), "\n") + print("r30 ", hex(u.r30), "\n") + print("sp ", hex(u.sp), "\n") + print("pc ", hex(u.pc), "\n") + print("psr ", hex(u.psr), "\n") + print("type ", hex(u.typ), "\n") +} + +func sigpanictramp() diff --git a/src/runtime/os_plan9.go b/src/runtime/os_plan9.go index 80c101f1a18c6f..f7381012ea5f84 100644 --- a/src/runtime/os_plan9.go +++ b/src/runtime/os_plan9.go @@ -587,10 +587,3 @@ func nanotime1() int64 { // fall back to unix time return int64(frombe(t[0])) } - -//go:nosplit -func walltime() (sec int64, nsec int32) { - var t [1]uint64 - readtime(&t[0], 1, 1) - return timesplit(frombe(t[0])) -} diff --git a/src/runtime/os_plan9_386.go b/src/runtime/os_plan9_386.go new file mode 100644 index 00000000000000..66f09f4c43e939 --- /dev/null +++ b/src/runtime/os_plan9_386.go @@ -0,0 +1,12 @@ +// Copyright 2025 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 runtime + +//go:nosplit +func walltime() (sec int64, nsec int32) { + var t [1]uint64 + readtime(&t[0], 1, 1) + return timesplit(frombe(t[0])) +} diff --git a/src/runtime/os_plan9_amd64.go b/src/runtime/os_plan9_amd64.go new file mode 100644 index 00000000000000..66f09f4c43e939 --- /dev/null +++ b/src/runtime/os_plan9_amd64.go @@ -0,0 +1,12 @@ +// Copyright 2025 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 runtime + +//go:nosplit +func walltime() (sec int64, nsec int32) { + var t [1]uint64 + readtime(&t[0], 1, 1) + return timesplit(frombe(t[0])) +} diff --git a/src/runtime/os_plan9_arm.go b/src/runtime/os_plan9_arm.go index cce622932361ac..2e9530eb9a621e 100644 --- a/src/runtime/os_plan9_arm.go +++ b/src/runtime/os_plan9_arm.go @@ -13,3 +13,10 @@ func cputicks() int64 { // runtime·nanotime() is a poor approximation of CPU ticks that is enough for the profiler. return nanotime() } + +//go:nosplit +func walltime() (sec int64, nsec int32) { + var t [1]uint64 + readtime(&t[0], 1, 1) + return timesplit(frombe(t[0])) +} diff --git a/src/runtime/os_plan9_arm64.go b/src/runtime/os_plan9_arm64.go new file mode 100644 index 00000000000000..3d3dd7e4117dd8 --- /dev/null +++ b/src/runtime/os_plan9_arm64.go @@ -0,0 +1,12 @@ +// 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. + +package runtime + +//go:nosplit +func cputicks() int64 { + // Currently cputicks() is used in blocking profiler and to seed runtime·fastrand(). + // runtime·nanotime() is a poor approximation of CPU ticks that is enough for the profiler. + return nanotime() +} diff --git a/src/runtime/rt0_plan9_arm64.s b/src/runtime/rt0_plan9_arm64.s new file mode 100644 index 00000000000000..192ff382ef5d7a --- /dev/null +++ b/src/runtime/rt0_plan9_arm64.s @@ -0,0 +1,16 @@ +// 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" + +//in plan 9 argc is at top of stack followed by ptrs to arguments + +TEXT _rt0_arm64_plan9(SB),NOSPLIT|NOFRAME,$0 + MOVD R0, _tos(SB) + MOVD 0(RSP), R0 + MOVD $8(RSP), R1 + MOVD $runtime·rt0_go(SB), R2 + BL (R2) + +GLOBL _tos(SB), NOPTR, $8 diff --git a/src/runtime/sys_plan9_arm64.s b/src/runtime/sys_plan9_arm64.s new file mode 100644 index 00000000000000..618aafb02e7431 --- /dev/null +++ b/src/runtime/sys_plan9_arm64.s @@ -0,0 +1,313 @@ +// 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 "go_asm.h" +#include "go_tls.h" +#include "textflag.h" + +// from ../syscall/zsysnum_plan9.go + +#define SYS_SYSR1 0 +#define SYS_BIND 2 +#define SYS_CHDIR 3 +#define SYS_CLOSE 4 +#define SYS_DUP 5 +#define SYS_ALARM 6 +#define SYS_EXEC 7 +#define SYS_EXITS 8 +#define SYS_FAUTH 10 +#define SYS_SEGBRK 12 +#define SYS_OPEN 14 +#define SYS_OSEEK 16 +#define SYS_SLEEP 17 +#define SYS_RFORK 19 +#define SYS_PIPE 21 +#define SYS_CREATE 22 +#define SYS_FD2PATH 23 +#define SYS_BRK_ 24 +#define SYS_REMOVE 25 +#define SYS_NOTIFY 28 +#define SYS_NOTED 29 +#define SYS_SEGATTACH 30 +#define SYS_SEGDETACH 31 +#define SYS_SEGFREE 32 +#define SYS_SEGFLUSH 33 +#define SYS_RENDEZVOUS 34 +#define SYS_UNMOUNT 35 +#define SYS_SEMACQUIRE 37 +#define SYS_SEMRELEASE 38 +#define SYS_SEEK 39 +#define SYS_FVERSION 40 +#define SYS_ERRSTR 41 +#define SYS_STAT 42 +#define SYS_FSTAT 43 +#define SYS_WSTAT 44 +#define SYS_FWSTAT 45 +#define SYS_MOUNT 46 +#define SYS_AWAIT 47 +#define SYS_PREAD 50 +#define SYS_PWRITE 51 +#define SYS_TSEMACQUIRE 52 +#define SYS_NSEC 53 + +//func open(name *byte, mode int, perm int32) int +TEXT runtime·open(SB),NOSPLIT,$0-20 + MOVD $SYS_OPEN, R0 + SVC $0 + MOVWU R0, ret+16(FP) + RET + +//func pread(fd int32, buf unsafe.Pointer, nbytes int32, offset int64) int32 +TEXT runtime·pread(SB),NOSPLIT,$0-36 + MOVD $SYS_PREAD, R0 + SVC $0 + MOVWU R0, ret+32(FP) + RET + +//func pwrite(fd int32, buf unsafe.Pointer, nbytes int32, offset int64) int32 +TEXT runtime·pwrite(SB),NOSPLIT,$0-36 + MOVD $SYS_PWRITE, R0 + SVC $0 + MOVWU R0, ret+32(FP) + RET + +//func seek(fd int32, offset int64, whence int32) int64 +TEXT runtime·seek(SB),NOSPLIT,$0-32 + MOVD $ret+24(FP), R0 + MOVWU fd+0(FP), R2 + MOVD offset+8(FP), R3 + MOVWU whence+16(FP), R4 + + MOVD $sysargs-0(SP), R1 + + MOVD R0, 8(R1) + MOVWU R2, 16(R1) + MOVD R3, 24(R1) + MOVWU R4, 32(R1) + + MOVD $SYS_SEEK, R0 + SVC $0 + + CMP $-1, R0 + BNE 2(PC) + MOVD R0, ret+24(FP) + RET + +//func closefd(fd int32) int32 +TEXT runtime·closefd(SB),NOSPLIT,$0-12 + MOVD $SYS_CLOSE, R0 + SVC $0 + MOVWU R0, ret+8(FP) + RET + +//func dupfd(old, new int32) int32 +TEXT runtime·dupfd(SB),NOSPLIT,$0-12 + MOVD $SYS_DUP, R0 + SVC $0 + MOVWU R0, ret+8(FP) + RET + +//func exits(msg *byte) +TEXT runtime·exits(SB),NOSPLIT,$0-8 + MOVD $SYS_EXITS, R0 + SVC $0 + RET + +//func brk_(addr unsafe.Pointer) int32 +TEXT runtime·brk_(SB),NOSPLIT,$0-12 + MOVD $SYS_BRK_, R0 + SVC $0 + MOVWU R0, ret+8(FP) + RET + +//func sleep(ms int32) int32 +TEXT runtime·sleep(SB),NOSPLIT,$0-12 + MOVD $SYS_SLEEP, R0 + SVC $0 + MOVWU R0, ret+8(FP) + RET + +//func plan9_semacquire(addr *uint32, block int32) int32 +TEXT runtime·plan9_semacquire(SB),NOSPLIT,$0-20 + MOVD $SYS_SEMACQUIRE, R0 + SVC $0 + MOVWU R0, ret+16(FP) + RET + +//func plan9_tsemacquire(addr *uint32, ms int32) int32 +TEXT runtime·plan9_tsemacquire(SB),NOSPLIT,$0-20 + MOVD $SYS_TSEMACQUIRE, R0 + SVC $0 + MOVWU R0, ret+16(FP) + RET + +// func timesplit(u uint64) (sec int64, nsec int32) +TEXT runtime·timesplit(SB), NOSPLIT, $0 + // R1 = u (nanoseconds) + MOVD u+0(FP), R1 + + // --- reciprocal multiply to get seconds --- + MOVW $0x89705f41, R2 // reciprocal constant ≈ 2^61 / 1e9 + UMULH R1, R2, R3 // high 64 bits of (u * constant) + LSR $29, R3, R4 // R4 = seconds (int64) + + // --- compute remainder = u - sec*1e9 --- + MOVD $1000000000, R5 + MUL R4, R5, R6 + SUB R6, R1, R1 // R1 = remainder + + // --- branchless correction --- + // if remainder >= 1e9: + // remainder -= 1e9 + // sec += 1 + + SUB R5, R1, R7 // R7 = remainder - 1e9 + LSR $63, R7, R8 // R8 = 1 if remainder < 1e9, else 0 + EOR $1, R8 // invert: R8 = 1 if remainder >= 1e9, else 0 + + // remainder -= R8 * 1e9 + NEG R8, R9 // R9 = -R8 (0 or -1) + MADD R9, R5, R1, R1 // R1 = R1 + R9*R5 → subtract 1e9 if flag=1 + + // sec += R8 + ADD R8, R4, R4 + + // --- store results --- + MOVD R4, sec+0(FP) + MOVW R1, nsec+8(FP) + RET + +//func nsec(*int64) int64 +TEXT runtime·nsec(SB),NOSPLIT|NOFRAME,$0-16 + MOVD $SYS_NSEC, R0 + SVC $0 + MOVD R0, ret+8(FP) + RET + +// func walltime() (sec int64, nsec int32) +TEXT runtime·walltime(SB),NOSPLIT,$16-12 + // use nsec system call to get current time in nanoseconds + MOVD $SYS_NSEC, R0 + SVC $0 + + MOVD R0, R1 + MOVD $1000000000, R2 + UDIV R2, R1 + + MOVD R1, R3 + MUL R3, R2 + SUB R2, R0 + + MOVD R1,sec+0(FP) + MOVWU R0,nsec+8(FP) + RET + +//func notify(fn unsafe.Pointer) int32 +TEXT runtime·notify(SB),NOSPLIT,$0-12 + MOVD $SYS_NOTIFY, R0 + SVC $0 + MOVWU R0, ret+8(FP) + RET + +//func noted(mode int32) int32 +TEXT runtime·noted(SB),NOSPLIT,$0-12 + MOVD $SYS_NOTED, R0 + SVC $0 + MOVWU R0, ret+8(FP) + RET + +//func plan9_semrelease(addr *uint32, count int32) int32 +TEXT runtime·plan9_semrelease(SB),NOSPLIT,$0-20 + MOVD $SYS_SEMRELEASE, R0 + SVC $0 + MOVWU R0, ret+16(FP) + RET + +//func rfork(flags int32) int32 +TEXT runtime·rfork(SB),NOSPLIT,$0-12 + MOVD $SYS_RFORK, R0 + SVC $0 + MOVWU R0, ret+8(FP) + RET + +//func tstart_plan9(newm *m) +TEXT runtime·tstart_plan9(SB),NOSPLIT,$8-8 + MOVD newm+0(FP), R1 + MOVD m_g0(R1), g + + // Layout new m scheduler stack on os stack. + MOVD RSP, R0 + MOVD R0, g_stack+stack_hi(g) + SUB $(64*1024), R0 + MOVD R0, (g_stack+stack_lo)(g) + MOVD R0, g_stackguard0(g) + MOVD R0, g_stackguard1(g) + + // Initialize procid from TOS struct. + MOVD _tos(SB), R0 + MOVWU 64(R0), R0 + MOVD R0, m_procid(R1) // save pid as m->procid + + BL runtime·mstart(SB) + + // Exit the thread. + MOVD $0, R0 + MOVD R0, 8(RSP) + CALL runtime·exits(SB) + JMP 0(PC) + +//func sigtramp(ureg, note unsafe.Pointer) +TEXT runtime·sigtramp(SB),NOSPLIT,$0-16 + // check that g and m exist + CMP $0, g + BEQ 4(PC) + MOVD g_m(g), R0 + CMP $0, R0 + BNE 2(PC) + BL runtime·badsignal2(SB) // will exit + + // save args + MOVD ureg+0(FP), R1 + MOVD note+8(FP), R2 + + // change stack + MOVD m_gsignal(R0), R3 + MOVD (g_stack+stack_hi)(R3), R4 + MOVD R4, RSP + + // make room for args, retval and g + SUB $48, RSP + + // save g + MOVD g, R3 + MOVD R3, 40(RSP) + + // g = m->gsignal + MOVD m_gsignal(R0), g + + // load args and call sighandler + MOVD R1, 8(RSP) + MOVD R2, 16(RSP) + MOVD R3, 24(RSP) + + BL runtime·sighandler(SB) + MOVWU 32(RSP), R0 // retval + + // restore g + MOVD 40(RSP), g + + // call noted(R0) + MOVD R0, 8(RSP) + BL runtime·noted(SB) + RET + +//func sigpanictramp() +TEXT runtime·sigpanictramp(SB),NOSPLIT,$0-0 + MOVD.W R0, -16(RSP) + B runtime·sigpanic(SB) + +//func setfpmasks() +// Mask all SSE floating-point exceptions (only amd64?) +TEXT runtime·setfpmasks(SB),NOSPLIT,$0 + RET diff --git a/src/runtime/tls_arm64.h b/src/runtime/tls_arm64.h index 3aa8c63d39d7b2..afa6cf639f01d5 100644 --- a/src/runtime/tls_arm64.h +++ b/src/runtime/tls_arm64.h @@ -36,6 +36,10 @@ #define MRS_TPIDR_R0 WORD $0xd53bd040 // MRS TPIDR_EL0, R0 #endif +#ifdef GOOS_plan9 +#define MRS_TPIDR_R0 WORD $0xd53bd040 // MRS TPIDR_EL0, R0 +#endif + #ifdef GOOS_windows #define TLS_windows #endif diff --git a/src/syscall/asm_plan9_arm64.s b/src/syscall/asm_plan9_arm64.s new file mode 100644 index 00000000000000..6605fb49a0b8f6 --- /dev/null +++ b/src/syscall/asm_plan9_arm64.s @@ -0,0 +1,216 @@ +// 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 "funcdata.h" + +#define SYS_ERRSTR 41 /* from zsysnum_plan9.go */ +#define SYS_SEEK 39 /* from zsysnum_plan9.go */ + +// System call support for plan9 on arm64 + +//func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err ErrorString) +TEXT ·Syscall(SB),NOSPLIT,$168-64 + NO_LOCAL_POINTERS + BL runtime·entersyscall(SB) + + MOVD trap+0(FP), R0 + MOVD a1+8(FP), R2 + MOVD a2+16(FP), R3 + MOVD a3+24(FP), R4 + + // move to syscall args + MOVD R2, sysargs-192(FP) + MOVD R3, sysargs-184(FP) + MOVD R4, sysargs-176(FP) + + SVC $0 + + // put return values into r1, r2, err + MOVD R0, r1+32(FP) + MOVD R1, r2+40(FP) + MOVD ZR, err+48(FP) + + // put error if needed + CMP $-1, R0 + BEQ syscallerr + BL runtime·exitsyscall(SB) + MOVD $·emptystring+0(SB), R2 + B syscallok +syscallerr: + MOVD $errbuf-128(SP), R2 + MOVD $128, R3 + + MOVD $SYS_ERRSTR, R0 + MOVD R2, err-192(FP) + MOVD R3, nerr-184(FP) + SVC $0 + + BL runtime·exitsyscall(SB) + BL runtime·gostring(SB) + MOVD $str-160(SP), R2 +syscallok: + MOVD $err+48(FP), R1 + MOVD 0(R2), R3 + MOVD 8(R2), R4 + MOVD R3, 0(R1) + MOVD R4, 8(R1) + RET + + +//func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err ErrorString) +// Actually Syscall5 but the rest of the code expects it to be named Syscall6. +TEXT ·Syscall6(SB),NOSPLIT,$168-88 + NO_LOCAL_POINTERS + BL runtime·entersyscall(SB) + + MOVD trap+0(FP), R1 + MOVD a1+8(FP), R2 + MOVD a2+16(FP), R3 + MOVD a3+24(FP), R4 + MOVD a4+32(FP), R5 + MOVD a5+40(FP), R6 + MOVD a6+48(FP), R7 + + // dereference pointers + MOVD R1, R0 + MOVD R2, sysargs-192(FP) + MOVD R3, sysargs-184(FP) + MOVD R4, sysargs-176(FP) + MOVD R5, sysargs-168(FP) + MOVD R6, sysargs-160(FP) + MOVD R7, sysargs-152(FP) + + SVC $0 + + // put return value into r1, r2, err + MOVD R0, r1+56(FP) + MOVD R1, r2+64(FP) + MOVD ZR, err+72(FP) + + // put error if needed + CMP $-1, R0 + BEQ syscall6err + BL runtime·exitsyscall(SB) + MOVD $·emptystring+0(SB), R2 + B syscall6ok +syscall6err: + MOVD $errbuf-128(SP), R2 + MOVD $128, R3 + + MOVD $SYS_ERRSTR, R0 + MOVD R2, err-192(FP) + MOVD R3, nerr-184(FP) + SVC $0 + + BL runtime·exitsyscall(SB) + BL runtime·gostring(SB) + MOVD $str-160(SP), R2 +syscall6ok: + MOVD $err+72(FP), R1 + MOVD 0(R2), R3 + MOVD 8(R2), R4 + MOVD R3, 0(R1) + MOVD R4, 8(R1) + RET + +//func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) +TEXT ·RawSyscall(SB),NOSPLIT,$24-56 + MOVD trap+0(FP), R1 + MOVD a1+8(FP), R2 + MOVD a2+16(FP), R3 + MOVD a3+24(FP), R4 + + // move to syscall args + MOVD R1, R0 + MOVD R2, sysargs-48(FP) + MOVD R3, sysargs-40(FP) + MOVD R4, sysargs-32(FP) + + SVC $0 + + // put return values into r1, r2, err + MOVD R0, r1+32(FP) + MOVD R0, r2+40(FP) + MOVD R0, err+48(FP) + + RET + +//func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) +// Actually RawSyscall5 but the rest of the code expects it to be named RawSyscall6. +TEXT ·RawSyscall6(SB),NOSPLIT,$48-80 + MOVD trap+0(FP), R1 + MOVD a1+8(FP), R2 + MOVD a2+16(FP), R3 + MOVD a3+24(FP), R4 + MOVD a4+32(FP), R5 + MOVD a5+40(FP), R6 + MOVD a6+48(FP), R7 + + // move to syscall args + MOVD R1, R0 + MOVD R2, sysargs-64(FP) + MOVD R3, sysargs-56(FP) + MOVD R4, sysargs-48(FP) + MOVD R5, sysargs-40(FP) + MOVD R6, sysargs-32(FP) + MOVD R7, sysargs-24(FP) + + SVC $0 + + // put return values into r1, r2, err + MOVD R0, r1+56(FP) + MOVD R1, r2+64(FP) + MOVD ZR, err+72(FP) + + RET + +//func seek(placeholder uintptr, fd int, offset int64, whence int) (newoffset int64, err string) +TEXT ·seek(SB),NOSPLIT,$168-56 + NO_LOCAL_POINTERS + + MOVD $newoffset+32(FP), R0 + MOVWU fd+8(FP), R2 + MOVD offset+16(FP), R3 + MOVWU whence+24(FP), R4 + + // move to syscall args + MOVD R0, sysargs-192(FP) + MOVWU R2, sysargs-184(FP) + MOVD R3, sysargs-176(FP) + MOVWU R4, sysargs-168(FP) + + MOVD $SYS_SEEK, R0 + SVC $0 + + // put err + MOVD ZR, err+40(FP) + + // put error if needed + CMP $-1, R0 + BEQ syscallerr + MOVD $·emptystring+0(SB), R2 + B syscallok +syscallerr: + MOVD R0, newoffset+32(FP) + + MOVD $errbuf-128(SP), R2 + MOVD $128, R3 + + MOVD $SYS_ERRSTR, R0 + MOVD R2, err-192(FP) + MOVD R3, nerr-184(FP) + SVC $0 + + BL runtime·gostring(SB) + MOVD $str-160(SP), R2 +syscallok: + MOVD $err+40(FP), R1 + MOVD 0(R2), R3 + MOVD 8(R2), R4 + MOVD R3, 0(R1) + MOVD R4, 8(R1) + RET + + diff --git a/src/syscall/zsyscall_plan9_arm64.go b/src/syscall/zsyscall_plan9_arm64.go new file mode 100644 index 00000000000000..2be5bd9a75771e --- /dev/null +++ b/src/syscall/zsyscall_plan9_arm64.go @@ -0,0 +1,284 @@ +// mksyscall.pl -l32 -plan9 -tags plan9,arm64 syscall_plan9.go +// Code generated by the command above; DO NOT EDIT. + +//go:build plan9 && arm64 + +package syscall + +import "unsafe" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func fd2path(fd int, buf []byte) (err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_FD2PATH, uintptr(fd), uintptr(_p0), uintptr(len(buf))) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func pipe(p *[2]int32) (err error) { + r0, _, e1 := Syscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func await(s []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(s) > 0 { + _p0 = unsafe.Pointer(&s[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_AWAIT, uintptr(_p0), uintptr(len(s)), 0) + n = int(r0) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func open(path string, mode int) (fd int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) + fd = int(r0) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func create(path string, mode int, perm uint32) (fd int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + r0, _, e1 := Syscall(SYS_CREATE, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm)) + fd = int(r0) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func remove(path string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + r0, _, e1 := Syscall(SYS_REMOVE, uintptr(unsafe.Pointer(_p0)), 0, 0) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func stat(path string, edir []byte) (n int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(edir) > 0 { + _p1 = unsafe.Pointer(&edir[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir))) + n = int(r0) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func bind(name string, old string, flag int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(name) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(old) + if err != nil { + return + } + r0, _, e1 := Syscall(SYS_BIND, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flag)) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func mount(fd int, afd int, old string, flag int, aname string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(old) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(aname) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_MOUNT, uintptr(fd), uintptr(afd), uintptr(unsafe.Pointer(_p0)), uintptr(flag), uintptr(unsafe.Pointer(_p1)), 0) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func wstat(path string, edir []byte) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(edir) > 0 { + _p1 = unsafe.Pointer(&edir[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_WSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir))) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func chdir(path string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + r0, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Dup(oldfd int, newfd int) (fd int, err error) { + r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), uintptr(newfd), 0) + fd = int(r0) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Pread(fd int, p []byte, offset int64) (n int, err error) { + var _p0 unsafe.Pointer + if len(p) > 0 { + _p0 = unsafe.Pointer(&p[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0) + n = int(r0) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Pwrite(fd int, p []byte, offset int64) (n int, err error) { + var _p0 unsafe.Pointer + if len(p) > 0 { + _p0 = unsafe.Pointer(&p[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0) + n = int(r0) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Close(fd int) (err error) { + r0, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fstat(fd int, edir []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(edir) > 0 { + _p0 = unsafe.Pointer(&edir[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir))) + n = int(r0) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fwstat(fd int, edir []byte) (err error) { + var _p0 unsafe.Pointer + if len(edir) > 0 { + _p0 = unsafe.Pointer(&edir[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_FWSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir))) + if int32(r0) == -1 { + err = e1 + } + return +}