Commit d23cba68 authored by Maya Rashish's avatar Maya Rashish Committed by Benny Siegert

all: add start of netbsd/arm64 support

This works well enough to run some code natively on arm64, but not well enough for more complicated code. I've been suggested to start a pull request anyway.

Updates #30824

Change-Id: Ib4f63e0e8a9edfc862cf65b5f1b0fbf9a8a1628e
GitHub-Last-Rev: b01b105e0446e349c8d9895d3ac6918fa0cdc48c
GitHub-Pull-Request: golang/go#29398
Reviewed-on: https://go-review.googlesource.com/c/go/+/155739
Run-TryBot: Benny Siegert <bsiegert@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarBenny Siegert <bsiegert@gmail.com>
parent 78f0de10
......@@ -77,6 +77,8 @@ var contexts = []*build.Context{
{GOOS: "netbsd", GOARCH: "amd64"},
{GOOS: "netbsd", GOARCH: "arm", CgoEnabled: true},
{GOOS: "netbsd", GOARCH: "arm"},
{GOOS: "netbsd", GOARCH: "arm64", CgoEnabled: true},
{GOOS: "netbsd", GOARCH: "arm64"},
{GOOS: "openbsd", GOARCH: "386", CgoEnabled: true},
{GOOS: "openbsd", GOARCH: "386"},
{GOOS: "openbsd", GOARCH: "amd64", CgoEnabled: true},
......
......@@ -1510,6 +1510,7 @@ var cgoEnabled = map[string]bool{
"netbsd/386": true,
"netbsd/amd64": true,
"netbsd/arm": true,
"netbsd/arm64": true,
"openbsd/386": true,
"openbsd/amd64": true,
"openbsd/arm": true,
......
......@@ -359,7 +359,7 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bo
return int64(o1)<<32 | int64(o0), true
case objabi.R_ARM64_TLS_LE:
r.Done = false
if ctxt.HeadType != objabi.Hlinux {
if ctxt.HeadType == objabi.Hdarwin {
ld.Errorf(s, "TLS reloc on unsupported OS %v", ctxt.HeadType)
}
// The TCB is two pointers. This is not documented anywhere, but is
......
......@@ -61,7 +61,7 @@ func Init() (*sys.Arch, ld.Arch) {
Freebsddynld: "XXX",
Openbsddynld: "XXX",
Netbsddynld: "XXX",
Netbsddynld: "/libexec/ld.elf_so",
Dragonflydynld: "XXX",
Solarisdynld: "XXX",
}
......@@ -84,7 +84,8 @@ func archinit(ctxt *ld.Link) {
*ld.FlagRound = 4096
}
case objabi.Hlinux: /* arm64 elf */
case objabi.Hlinux, /* arm64 elf */
objabi.Hnetbsd:
ld.Elfinit(ctxt)
ld.HEADR = ld.ELFRESERVE
if *ld.FlagTextAddr == -1 {
......
// Copyright 2019 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 <sys/types.h>
#include <pthread.h>
#include <signal.h>
#include <string.h>
#include "libcgo.h"
#include "libcgo_unix.h"
static void *threadentry(void*);
static void (*setg_gcc)(void*);
void
x_cgo_init(G *g, void (*setg)(void*))
{
pthread_attr_t attr;
size_t size;
setg_gcc = setg;
pthread_attr_init(&attr);
pthread_attr_getstacksize(&attr, &size);
g->stacklo = (uintptr)&attr - size + 4096;
pthread_attr_destroy(&attr);
}
void
_cgo_sys_thread_start(ThreadStart *ts)
{
pthread_attr_t attr;
sigset_t ign, oset;
pthread_t p;
size_t size;
int err;
sigfillset(&ign);
pthread_sigmask(SIG_SETMASK, &ign, &oset);
pthread_attr_init(&attr);
pthread_attr_getstacksize(&attr, &size);
// Leave stacklo=0 and set stackhi=size; mstart will do the rest.
ts->g->stackhi = size;
err = _cgo_try_pthread_create(&p, &attr, threadentry, ts);
pthread_sigmask(SIG_SETMASK, &oset, nil);
if (err != 0) {
fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
abort();
}
}
static void*
threadentry(void *v)
{
ThreadStart ts;
stack_t ss;
ts = *(ThreadStart*)v;
free(v);
// On NetBSD, a new thread inherits the signal stack of the
// creating thread. That confuses minit, so we remove that
// signal stack here before calling the regular mstart. It's
// a bit baroque to remove a signal stack here only to add one
// in minit, but it's a simple change that keeps NetBSD
// working like other OS's. At this point all signals are
// blocked, so there is no race.
memset(&ss, 0, sizeof ss);
ss.ss_flags = SS_DISABLE;
sigaltstack(&ss, nil);
crosscall1(ts.fn, setg_gcc, (void*)ts.g);
return nil;
}
// created by cgo -cdefs and then converted to Go
// cgo -cdefs defs_netbsd.go defs_netbsd_arm.go
package runtime
const (
_EINTR = 0x4
_EFAULT = 0xe
_PROT_NONE = 0x0
_PROT_READ = 0x1
_PROT_WRITE = 0x2
_PROT_EXEC = 0x4
_MAP_ANON = 0x1000
_MAP_PRIVATE = 0x2
_MAP_FIXED = 0x10
_MADV_FREE = 0x6
_SA_SIGINFO = 0x40
_SA_RESTART = 0x2
_SA_ONSTACK = 0x1
_SIGHUP = 0x1
_SIGINT = 0x2
_SIGQUIT = 0x3
_SIGILL = 0x4
_SIGTRAP = 0x5
_SIGABRT = 0x6
_SIGEMT = 0x7
_SIGFPE = 0x8
_SIGKILL = 0x9
_SIGBUS = 0xa
_SIGSEGV = 0xb
_SIGSYS = 0xc
_SIGPIPE = 0xd
_SIGALRM = 0xe
_SIGTERM = 0xf
_SIGURG = 0x10
_SIGSTOP = 0x11
_SIGTSTP = 0x12
_SIGCONT = 0x13
_SIGCHLD = 0x14
_SIGTTIN = 0x15
_SIGTTOU = 0x16
_SIGIO = 0x17
_SIGXCPU = 0x18
_SIGXFSZ = 0x19
_SIGVTALRM = 0x1a
_SIGPROF = 0x1b
_SIGWINCH = 0x1c
_SIGINFO = 0x1d
_SIGUSR1 = 0x1e
_SIGUSR2 = 0x1f
_FPE_INTDIV = 0x1
_FPE_INTOVF = 0x2
_FPE_FLTDIV = 0x3
_FPE_FLTOVF = 0x4
_FPE_FLTUND = 0x5
_FPE_FLTRES = 0x6
_FPE_FLTINV = 0x7
_FPE_FLTSUB = 0x8
_BUS_ADRALN = 0x1
_BUS_ADRERR = 0x2
_BUS_OBJERR = 0x3
_SEGV_MAPERR = 0x1
_SEGV_ACCERR = 0x2
_ITIMER_REAL = 0x0
_ITIMER_VIRTUAL = 0x1
_ITIMER_PROF = 0x2
_EV_ADD = 0x1
_EV_DELETE = 0x2
_EV_CLEAR = 0x20
_EV_RECEIPT = 0
_EV_ERROR = 0x4000
_EV_EOF = 0x8000
_EVFILT_READ = 0x0
_EVFILT_WRITE = 0x1
)
type sigset struct {
__bits [4]uint32
}
type siginfo struct {
_signo int32
_code int32
_errno int32
_reason uintptr
_reasonx [16]byte
}
type stackt struct {
ss_sp uintptr
ss_size uintptr
ss_flags int32
}
type timespec struct {
tv_sec int64
tv_nsec int64
}
func (ts *timespec) setNsec(ns int64) {
ts.tv_sec = ns / 1e9
ts.tv_nsec = ns % 1e9
}
type timeval struct {
tv_sec int64
tv_usec int32
_ [4]byte // EABI
}
func (tv *timeval) set_usec(x int32) {
tv.tv_usec = x
}
type itimerval struct {
it_interval timeval
it_value timeval
}
type mcontextt struct {
__gregs [35]uint64
__fregs [4160]byte // _NFREG * 128 + 32 + 32
_ [8]uint64 // future use
}
type ucontextt struct {
uc_flags uint32
uc_link *ucontextt
uc_sigmask sigset
uc_stack stackt
_ [4]byte // EABI
uc_mcontext mcontextt
__uc_pad [2]int32
}
type keventt struct {
ident uint64
filter uint32
flags uint32
fflags uint32
pad_cgo_0 [4]byte
data int64
udata *byte
}
// created by cgo -cdefs and then converted to Go
// cgo -cdefs defs_netbsd.go defs_netbsd_arm.go
const (
_REG_X0 = 0
_REG_X1 = 1
_REG_X2 = 2
_REG_X3 = 3
_REG_X4 = 4
_REG_X5 = 5
_REG_X6 = 6
_REG_X7 = 7
_REG_X8 = 8
_REG_X9 = 9
_REG_X10 = 10
_REG_X11 = 11
_REG_X12 = 12
_REG_X13 = 13
_REG_X14 = 14
_REG_X15 = 15
_REG_X16 = 16
_REG_X17 = 17
_REG_X18 = 18
_REG_X19 = 19
_REG_X20 = 20
_REG_X21 = 21
_REG_X22 = 22
_REG_X23 = 23
_REG_X24 = 24
_REG_X25 = 25
_REG_X26 = 26
_REG_X27 = 27
_REG_X28 = 28
_REG_X29 = 29
_REG_X30 = 30
_REG_X31 = 31
_REG_ELR = 32
_REG_SPSR = 33
_REG_TPIDR = 34
)
// Copyright 2019 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
import "unsafe"
func lwp_mcontext_init(mc *mcontextt, stk unsafe.Pointer, mp *m, gp *g, fn uintptr) {
// Machine dependent mcontext initialisation for LWP.
mc.__gregs[_REG_ELR] = uint64(funcPC(lwp_tramp))
mc.__gregs[_REG_X31] = uint64(uintptr(stk))
mc.__gregs[_REG_X0] = uint64(uintptr(unsafe.Pointer(mp)))
mc.__gregs[_REG_X1] = uint64(uintptr(unsafe.Pointer(mp.g0)))
mc.__gregs[_REG_X2] = uint64(fn)
}
//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.
// TODO: need more entropy to better seed fastrand.
return nanotime()
}
// Copyright 2019 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"
TEXT _rt0_arm64_netbsd(SB),NOSPLIT|NOFRAME,$0
MOVD 0(RSP), R0 // argc
ADD $8, RSP, R1 // argv
BL main(SB)
// When building with -buildmode=c-shared, this symbol is called when the shared
// library is loaded.
TEXT _rt0_arm64_netbsd_lib(SB),NOSPLIT,$184
// Preserve callee-save registers.
MOVD R19, 24(RSP)
MOVD R20, 32(RSP)
MOVD R21, 40(RSP)
MOVD R22, 48(RSP)
MOVD R23, 56(RSP)
MOVD R24, 64(RSP)
MOVD R25, 72(RSP)
MOVD R26, 80(RSP)
MOVD R27, 88(RSP)
FMOVD F8, 96(RSP)
FMOVD F9, 104(RSP)
FMOVD F10, 112(RSP)
FMOVD F11, 120(RSP)
FMOVD F12, 128(RSP)
FMOVD F13, 136(RSP)
FMOVD F14, 144(RSP)
FMOVD F15, 152(RSP)
MOVD g, 160(RSP)
// Initialize g as null in case of using g later e.g. sigaction in cgo_sigaction.go
MOVD ZR, g
MOVD R0, _rt0_arm64_netbsd_lib_argc<>(SB)
MOVD R1, _rt0_arm64_netbsd_lib_argv<>(SB)
// Synchronous initialization.
MOVD $runtime·libpreinit(SB), R4
BL (R4)
// Create a new thread to do the runtime initialization and return.
MOVD _cgo_sys_thread_create(SB), R4
CMP $0, R4
BEQ nocgo
MOVD $_rt0_arm64_netbsd_lib_go(SB), R0
MOVD $0, R1
SUB $16, RSP // reserve 16 bytes for sp-8 where fp may be saved.
BL (R4)
ADD $16, RSP
B restore
nocgo:
MOVD $0x800000, R0 // stacksize = 8192KB
MOVD $_rt0_arm64_netbsd_lib_go(SB), R1
MOVD R0, 8(RSP)
MOVD R1, 16(RSP)
MOVD $runtime·newosproc0(SB),R4
BL (R4)
restore:
// Restore callee-save registers.
MOVD 24(RSP), R19
MOVD 32(RSP), R20
MOVD 40(RSP), R21
MOVD 48(RSP), R22
MOVD 56(RSP), R23
MOVD 64(RSP), R24
MOVD 72(RSP), R25
MOVD 80(RSP), R26
MOVD 88(RSP), R27
FMOVD 96(RSP), F8
FMOVD 104(RSP), F9
FMOVD 112(RSP), F10
FMOVD 120(RSP), F11
FMOVD 128(RSP), F12
FMOVD 136(RSP), F13
FMOVD 144(RSP), F14
FMOVD 152(RSP), F15
MOVD 160(RSP), g
RET
TEXT _rt0_arm64_netbsd_lib_go(SB),NOSPLIT,$0
MOVD _rt0_arm64_netbsd_lib_argc<>(SB), R0
MOVD _rt0_arm64_netbsd_lib_argv<>(SB), R1
MOVD $runtime·rt0_go(SB),R4
B (R4)
DATA _rt0_arm64_netbsd_lib_argc<>(SB)/8, $0
GLOBL _rt0_arm64_netbsd_lib_argc<>(SB),NOPTR, $8
DATA _rt0_arm64_netbsd_lib_argv<>(SB)/8, $0
GLOBL _rt0_arm64_netbsd_lib_argv<>(SB),NOPTR, $8
TEXT main(SB),NOSPLIT|NOFRAME,$0
MOVD $runtime·rt0_go(SB), R2
BL (R2)
exit:
MOVD $0, R0
SVC $1 // sys_exit
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build linux darwin
// +build linux darwin netbsd
package runtime
......
// Copyright 2019 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
import "unsafe"
type sigctxt struct {
info *siginfo
ctxt unsafe.Pointer
}
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) regs() *mcontextt {
return (*mcontextt)(unsafe.Pointer(&(*ucontextt)(c.ctxt).uc_mcontext))
}
func (c *sigctxt) r0() uint64 { return c.regs().__gregs[_REG_X0] }
func (c *sigctxt) r1() uint64 { return c.regs().__gregs[_REG_X1] }
func (c *sigctxt) r2() uint64 { return c.regs().__gregs[_REG_X2] }
func (c *sigctxt) r3() uint64 { return c.regs().__gregs[_REG_X3] }
func (c *sigctxt) r4() uint64 { return c.regs().__gregs[_REG_X4] }
func (c *sigctxt) r5() uint64 { return c.regs().__gregs[_REG_X5] }
func (c *sigctxt) r6() uint64 { return c.regs().__gregs[_REG_X6] }
func (c *sigctxt) r7() uint64 { return c.regs().__gregs[_REG_X7] }
func (c *sigctxt) r8() uint64 { return c.regs().__gregs[_REG_X8] }
func (c *sigctxt) r9() uint64 { return c.regs().__gregs[_REG_X9] }
func (c *sigctxt) r10() uint64 { return c.regs().__gregs[_REG_X10] }
func (c *sigctxt) r11() uint64 { return c.regs().__gregs[_REG_X11] }
func (c *sigctxt) r12() uint64 { return c.regs().__gregs[_REG_X12] }
func (c *sigctxt) r13() uint64 { return c.regs().__gregs[_REG_X13] }
func (c *sigctxt) r14() uint64 { return c.regs().__gregs[_REG_X14] }
func (c *sigctxt) r15() uint64 { return c.regs().__gregs[_REG_X15] }
func (c *sigctxt) r16() uint64 { return c.regs().__gregs[_REG_X16] }
func (c *sigctxt) r17() uint64 { return c.regs().__gregs[_REG_X17] }
func (c *sigctxt) r18() uint64 { return c.regs().__gregs[_REG_X18] }
func (c *sigctxt) r19() uint64 { return c.regs().__gregs[_REG_X19] }
func (c *sigctxt) r20() uint64 { return c.regs().__gregs[_REG_X20] }
func (c *sigctxt) r21() uint64 { return c.regs().__gregs[_REG_X21] }
func (c *sigctxt) r22() uint64 { return c.regs().__gregs[_REG_X22] }
func (c *sigctxt) r23() uint64 { return c.regs().__gregs[_REG_X23] }
func (c *sigctxt) r24() uint64 { return c.regs().__gregs[_REG_X24] }
func (c *sigctxt) r25() uint64 { return c.regs().__gregs[_REG_X25] }
func (c *sigctxt) r26() uint64 { return c.regs().__gregs[_REG_X26] }
func (c *sigctxt) r27() uint64 { return c.regs().__gregs[_REG_X27] }
func (c *sigctxt) r28() uint64 { return c.regs().__gregs[_REG_X28] }
func (c *sigctxt) r29() uint64 { return c.regs().__gregs[_REG_X29] }
func (c *sigctxt) lr() uint64 { return c.regs().__gregs[_REG_X30] }
func (c *sigctxt) sp() uint64 { return c.regs().__gregs[_REG_X31] }
//go:nosplit
//go:nowritebarrierrec
func (c *sigctxt) pc() uint64 { return c.regs().__gregs[_REG_ELR] }
func (c *sigctxt) fault() uintptr { return uintptr(c.info._reason) }
func (c *sigctxt) trap() uint64 { return 0 }
func (c *sigctxt) error() uint64 { return 0 }
func (c *sigctxt) oldmask() uint64 { return 0 }
func (c *sigctxt) sigcode() uint64 { return uint64(c.info._code) }
func (c *sigctxt) sigaddr() uint64 { return uint64(c.info._reason) }
func (c *sigctxt) set_pc(x uint64) { c.regs().__gregs[_REG_ELR] = x }
func (c *sigctxt) set_sp(x uint64) { c.regs().__gregs[_REG_X31] = x }
func (c *sigctxt) set_lr(x uint64) { c.regs().__gregs[_REG_X30] = x }
func (c *sigctxt) set_r28(x uint64) { c.regs().__gregs[_REG_X28] = x }
func (c *sigctxt) set_sigcode(x uint64) { c.info._code = int32(x) }
func (c *sigctxt) set_sigaddr(x uint64) {
c.info._reason = uintptr(x)
}
// Copyright 2019 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.
//
// System calls and other sys.stuff for arm64, NetBSD
//
#include "go_asm.h"
#include "go_tls.h"
#include "textflag.h"
#define CLOCK_REALTIME 0
#define CLOCK_MONOTONIC 3
#define FD_CLOEXEC 1
#define F_SETFD 2
#define SYS_exit 1
#define SYS_read 3
#define SYS_write 4
#define SYS_open 5
#define SYS_close 6
#define SYS_getpid 20
#define SYS_kill 37
#define SYS_munmap 73
#define SYS_madvise 75
#define SYS_fcntl 92
#define SYS_mmap 197
#define SYS___sysctl 202
#define SYS___sigaltstack14 281
#define SYS___sigprocmask14 293
#define SYS_getcontext 307
#define SYS_setcontext 308
#define SYS__lwp_create 309
#define SYS__lwp_exit 310
#define SYS__lwp_self 311
#define SYS__lwp_kill 318
#define SYS__lwp_unpark 321
#define SYS___sigaction_sigtramp 340
#define SYS_kqueue 344
#define SYS_sched_yield 350
#define SYS___setitimer50 425
#define SYS___clock_gettime50 427
#define SYS___nanosleep50 430
#define SYS___kevent50 435
#define SYS_openat 468
#define SYS____lwp_park60 478
// int32 lwp_create(void *context, uintptr flags, void *lwpid)
TEXT runtime·lwp_create(SB),NOSPLIT,$0
MOVD ctxt+0(FP), R0
MOVD flags+8(FP), R1
MOVD lwpid+16(FP), R2
SVC $SYS__lwp_create
BCC ok
NEG R0, R0
ok:
MOVW R0, ret+24(FP)
RET
TEXT runtime·lwp_tramp(SB),NOSPLIT,$0
CMP $0, R1
BEQ nog
CMP $0, R2
BEQ nog
MOVD R0, g_m(R1)
MOVD R1, g
nog:
CALL (R2)
MOVD $0, R0 // crash (not reached)
MOVD R0, (R8)
TEXT runtime·osyield(SB),NOSPLIT,$0
SVC $SYS_sched_yield
RET
TEXT runtime·lwp_park(SB),NOSPLIT,$0
MOVW clockid+0(FP), R0 // arg 1 - clockid
MOVW flags+4(FP), R1 // arg 2 - flags
MOVD ts+8(FP), R2 // arg 3 - ts
MOVW unpark+16(FP), R3 // arg 4 - unpark
MOVD hint+24(FP), R4 // arg 5 - hint
MOVD unparkhint+32(FP), R5 // arg 6 - unparkhint
SVC $SYS____lwp_park60
MOVW R0, ret+40(FP)
RET
TEXT runtime·lwp_unpark(SB),NOSPLIT,$0
MOVW lwp+0(FP), R0 // arg 1 - lwp
MOVD hint+8(FP), R1 // arg 2 - hint
SVC $SYS__lwp_unpark
MOVW R0, ret+16(FP)
RET
TEXT runtime·lwp_self(SB),NOSPLIT,$0
SVC $SYS__lwp_self
MOVW R0, ret+0(FP)
RET
// Exit the entire program (like C exit)
TEXT runtime·exit(SB),NOSPLIT,$-8
MOVD code+0(FP), R0 // arg 1 - exit status
SVC $SYS_exit
MOVD $0, R0 // If we're still running,
MOVD R0, (R0) // crash
// XXX the use of R1 here does not make sense.
// Does it not matter?
// func exitThread(wait *uint32)
TEXT runtime·exitThread(SB),NOSPLIT,$0-8
MOVW wait+0(FP), R0
// We're done using the stack.
MOVW $0, R1
STLRW R1, (R0)
SVC $SYS__lwp_exit
JMP 0(PC)
TEXT runtime·open(SB),NOSPLIT|NOFRAME,$-8
MOVD name+0(FP), R0 // arg 1 - pathname
MOVW mode+8(FP), R1 // arg 2 - flags
MOVW perm+12(FP), R2 // arg 3 - mode
SVC $SYS_open
BCC ok
MOVW $-1, R0
ok:
MOVW R0, ret+16(FP)
RET
TEXT runtime·closefd(SB),NOSPLIT,$-8
MOVW fd+0(FP), R0 // arg 1 - fd
SVC $SYS_close
BCC ok
MOVW $-1, R0
ok:
MOVW R0, ret+8(FP)
RET
TEXT runtime·read(SB),NOSPLIT|NOFRAME,$0
MOVW fd+0(FP), R0 // arg 1 - fd
MOVD p+8(FP), R1 // arg 2 - buf
MOVW n+16(FP), R2 // arg 3 - count
SVC $SYS_read
BCC ok
MOVW $-1, R0
ok:
MOVW R0, ret+24(FP)
RET
TEXT runtime·write(SB),NOSPLIT,$-8
MOVD fd+0(FP), R0 // arg 1 - fd
MOVD p+8(FP), R1 // arg 2 - buf
MOVW n+16(FP), R2 // arg 3 - nbyte
SVC $SYS_write
BCC ok
MOVW $-1, R0
ok:
MOVW R1, ret+24(FP)
RET
TEXT runtime·usleep(SB),NOSPLIT,$24-4
MOVW usec+0(FP), R3
MOVD R3, R5
MOVW $1000000, R4
UDIV R4, R3
MOVD R3, 8(RSP) // sec
MUL R3, R4
SUB R4, R5
MOVW $1000, R4
MUL R4, R5
MOVD R5, 16(RSP) // nsec
MOVD RSP, R0 // arg 1 - rqtp
MOVD $0, R1 // arg 2 - rmtp
SVC $SYS___nanosleep50
RET
TEXT runtime·raise(SB),NOSPLIT,$16
SVC $SYS__lwp_self
// arg 1 - target (lwp_self)
MOVW sig+0(FP), R1 // arg 2 - signo
SVC $SYS__lwp_kill
RET
TEXT runtime·raiseproc(SB),NOSPLIT,$16
SVC $SYS_getpid
// arg 1 - pid (from getpid)
MOVD sig+0(FP), R1 // arg 2 - signo
SVC $SYS_kill
RET
TEXT runtime·setitimer(SB),NOSPLIT,$-8
MOVW mode+0(FP), R0 // arg 1 - which
MOVD new+8(FP), R1 // arg 2 - itv
MOVD old+16(FP), R2 // arg 3 - oitv
SVC $SYS___setitimer50
RET
// func walltime() (sec int64, nsec int32)
TEXT runtime·walltime(SB), NOSPLIT, $32
MOVW $CLOCK_REALTIME, R0 // arg 1 - clock_id
MOVW 8(RSP), R1 // arg 2 - tp
SVC $SYS___clock_gettime50
MOVD 8(RSP), R0 // sec
MOVW 16(RSP), R1 // nsec
// sec is in R0, nsec in R1
MOVD R0, sec+0(FP)
MOVW R1, nsec+8(FP)
RET
// int64 nanotime(void) so really
// void nanotime(int64 *nsec)
TEXT runtime·nanotime(SB), NOSPLIT, $32
MOVD $CLOCK_MONOTONIC, R0 // arg 1 - clock_id
MOVD $8(RSP), R1 // arg 2 - tp
SVC $SYS___clock_gettime50
MOVD 8(RSP), R0 // sec
MOVW 16(RSP), R2 // nsec
// sec is in R0, nsec in R2
// return nsec in R2
MOVD $1000000000, R3
MUL R3, R0
ADD R2, R0
MOVD R0, ret+0(FP)
RET
TEXT runtime·getcontext(SB),NOSPLIT,$-8
MOVD ctxt+0(FP), R0 // arg 1 - context
SVC $SYS_getcontext
BCS fail
RET
fail:
MOVD $0, R0
MOVD R0, (R0) // crash
TEXT runtime·sigprocmask(SB),NOSPLIT,$0
MOVW how+0(FP), R0 // arg 1 - how
MOVD new+8(FP), R1 // arg 2 - set
MOVD old+16(FP), R2 // arg 3 - oset
SVC $SYS___sigprocmask14
BCS fail
RET
fail:
MOVD $0, R0
MOVD R0, (R0) // crash
TEXT runtime·sigreturn_tramp(SB),NOSPLIT,$-8
MOVD g, R0
SVC $SYS_setcontext
MOVD $0x4242, R0 // Something failed, return magic number
SVC $SYS_exit
TEXT runtime·sigaction(SB),NOSPLIT,$-8
MOVW sig+0(FP), R0 // arg 1 - signum
MOVD new+8(FP), R1 // arg 2 - nsa
MOVD old+16(FP), R2 // arg 3 - osa
// arg 4 - tramp
MOVD $runtime·sigreturn_tramp(SB), R3
MOVW $2, R4 // arg 5 - vers
SVC $SYS___sigaction_sigtramp
BCS fail
RET
fail:
MOVD $0, R0
MOVD R0, (R0) // crash
// XXX ???
TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
MOVW sig+8(FP), R0
MOVD info+16(FP), R1
MOVD ctx+24(FP), R2
MOVD fn+0(FP), R11
BL (R11)
RET
TEXT runtime·sigtramp(SB),NOSPLIT,$24
// this might be called in external code context,
// where g is not set.
// first save R0, because runtime·load_g will clobber it
MOVD R0, 8(RSP) // signum
MOVB runtime·iscgo(SB), R0
CMP $0, R0
// XXX branch destination
BEQ 2(PC)
BL runtime·load_g(SB)
MOVD R1, 16(RSP)
MOVD R2, 24(RSP)
BL runtime·sigtrampgo(SB)
RET
TEXT runtime·mmap(SB),NOSPLIT,$0
MOVD addr+0(FP), R0 // arg 1 - addr
MOVD n+8(FP), R1 // arg 2 - len
MOVW prot+16(FP), R2 // arg 3 - prot
MOVW flags+20(FP), R3 // arg 4 - flags
MOVW fd+24(FP), R4 // arg 5 - fd
MOVW $0, R5 // arg 6 - pad
MOVD off+28(FP), R6 // arg 7 - offset
SVC $SYS_mmap
BCS fail
MOVD R0, p+32(FP)
MOVD $0, err+40(FP)
RET
fail:
MOVD $0, p+32(FP)
MOVD R0, err+40(FP)
RET
TEXT runtime·munmap(SB),NOSPLIT,$0
MOVD addr+0(FP), R0 // arg 1 - addr
MOVD n+8(FP), R1 // arg 2 - len
SVC $SYS_munmap
BCS fail
RET
fail:
MOVD $0, R0
MOVD R0, (R0) // crash
TEXT runtime·madvise(SB),NOSPLIT,$0
MOVD addr+0(FP), R0 // arg 1 - addr
MOVD n+8(FP), R1 // arg 2 - len
MOVW flags+16(FP), R2 // arg 3 - behav
SVC $SYS_madvise
BCC ok
MOVD $-1, R0
ok:
MOVD R0, ret+24(FP)
RET
TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
MOVD new+0(FP), R0 // arg 1 - nss
MOVD old+8(FP), R1 // arg 2 - oss
SVC $SYS___sigaltstack14
BCS fail
RET
fail:
MOVD $0, R0
MOVD R0, (R0) // crash
TEXT runtime·sysctl(SB),NOSPLIT,$0
MOVD mib+0(FP), R0 // arg 1 - name
MOVW miblen+8(FP), R1 // arg 2 - namelen
MOVD out+16(FP), R2 // arg 3 - oldp
MOVD size+24(FP), R3 // arg 4 - oldlenp
MOVD dst+32(FP), R4 // arg 5 - newp
MOVD ndst+40(FP), R5 // arg 6 - newlen
SVC $SYS___sysctl
BCC ok
NEG R0, R0
ok:
MOVW R0, ret+48(FP)
RET
// int32 runtime·kqueue(void)
TEXT runtime·kqueue(SB),NOSPLIT,$0
MOVD $0, R0
SVC $SYS_kqueue
BCC ok
NEG R0, R0
ok:
MOVW R0, ret+0(FP)
RET
// int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout)
TEXT runtime·kevent(SB),NOSPLIT,$0
MOVW kq+0(FP), R0 // arg 1 - kq
MOVD ch+8(FP), R1 // arg 2 - changelist
MOVW nch+16(FP), R2 // arg 3 - nchanges
MOVD ev+24(FP), R3 // arg 4 - eventlist
MOVW nev+32(FP), R4 // arg 5 - nevents
MOVD ts+40(FP), R5 // arg 6 - timeout
SVC $SYS___kevent50
BCC ok
NEG R0, R0
ok:
MOVW R0, ret+48(FP)
RET
// void runtime·closeonexec(int32 fd)
TEXT runtime·closeonexec(SB),NOSPLIT,$0
MOVW fd+0(FP), R0 // arg 1 - fd
MOVW $F_SETFD, R1
MOVW $FD_CLOEXEC, R2
SVC $SYS_fcntl
RET
......@@ -20,6 +20,11 @@
#define MRS_TPIDR_R0 WORD $0xd53bd060 // MRS TPIDRRO_EL0, R0
#endif
#ifdef GOOS_netbsd
#define TPIDR TPIDRRO_EL0
#define MRS_TPIDR_R0 WORD $0xd53bd040 // MRS TPIDRRO_EL0, R0
#endif
// Define something that will break the build if
// the GOOS is unknown.
#ifndef TPIDR
......
// Copyright 2019 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 ARM64, NetBSD
//
#define SYS_syscall 0
// func Syscall(trap uintptr, a1, a2, a3 uintptr) (r1, r2, err uintptr)
TEXT ·Syscall(SB),NOSPLIT,$0-56
BL runtime·entersyscall(SB)
MOVD trap+0(FP), R17
MOVD a1+8(FP), R0
MOVD a2+16(FP), R1
MOVD a3+24(FP), R2
SVC $SYS_syscall
BCC ok
MOVD $-1, R1
MOVD R1, r1+32(FP) // r1
MOVD ZR, r2+40(FP) // r2
MOVD R0, err+48(FP) // err
BL runtime·exitsyscall(SB)
RET
ok:
MOVD R0, r1+32(FP) // r1
MOVD R1, r2+40(FP) // r2
MOVD ZR, err+48(FP) // err
BL runtime·exitsyscall(SB)
RET
// func RawSyscall(trap uintptr, a1, a2, a3 uintptr) (r1, r2, err uintptr)
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
MOVD trap+0(FP), R17 // syscall entry
MOVD a1+8(FP), R0
MOVD a2+16(FP), R1
MOVD a3+24(FP), R2
SVC $SYS_syscall
BCC ok
MOVD $-1, R1
MOVD R1, r1+32(FP) // r1
MOVD ZR, r2+40(FP) // r2
MOVD R0, err+48(FP) // err
RET
ok:
MOVD R0, r1+32(FP) // r1
MOVD R1, r2+40(FP) // r2
MOVD ZR, err+48(FP) // err
RET
// func Syscall6(trap uintptr, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
TEXT ·Syscall6(SB),NOSPLIT,$0-80
BL runtime·entersyscall(SB)
MOVD trap+0(FP), R17 // syscall entry
MOVD a1+8(FP), R0
MOVD a2+16(FP), R1
MOVD a3+24(FP), R2
MOVD a4+32(FP), R3
MOVD a5+40(FP), R4
MOVD a6+48(FP), R5
SVC $SYS_syscall
BCC ok
MOVD $-1, R1
MOVD R1, r1+56(FP) // r1
MOVD ZR, r2+64(FP) // r2
MOVD R0, err+72(FP) // err
BL runtime·exitsyscall(SB)
RET
ok:
MOVD R0, r1+56(FP) // r1
MOVD R1, r2+64(FP) // r2
MOVD ZR, err+72(FP) // err
BL runtime·exitsyscall(SB)
RET
// func RawSyscall6(trap uintptr, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
MOVD trap+0(FP), R17 // syscall entry
MOVD a1+8(FP), R0
MOVD a2+16(FP), R1
MOVD a3+24(FP), R2
MOVD a4+32(FP), R3
MOVD a5+40(FP), R4
MOVD a6+48(FP), R5
SVC $SYS_syscall
BCC ok
MOVD $-1, R1
MOVD R1, r1+56(FP) // r1
MOVD ZR, r2+64(FP) // r2
MOVD R0, err+72(FP) // err
RET
ok:
MOVD R0, r1+56(FP) // r1
MOVD R1, r2+64(FP) // r2
MOVD ZR, R0
MOVD R0, err+72(FP) // err
RET
// Actually Syscall7
TEXT ·Syscall9(SB),NOSPLIT,$0-104
BL runtime·entersyscall(SB)
MOVD num+0(FP), R17 // syscall entry
MOVD a1+8(FP), R0
MOVD a2+16(FP), R1
MOVD a3+24(FP), R2
MOVD a4+32(FP), R3
MOVD a5+40(FP), R4
MOVD a6+48(FP), R5
MOVD a7+56(FP), R6
//MOVD a8+64(FP), R7
//MOVD a9+72(FP), R8
SVC $SYS_syscall
BCC ok
MOVD $-1, R1
MOVD R1, r1+80(FP) // r1
MOVD ZR, r2+88(FP) // r2
MOVD R0, err+96(FP) // err
BL runtime·exitsyscall(SB)
RET
ok:
MOVD R0, r1+80(FP) // r1
MOVD R1, r2+88(FP) // r2
MOVD ZR, err+96(FP) // err
BL runtime·exitsyscall(SB)
RET
// Copyright 2019 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 syscall
func setTimespec(sec, nsec int64) Timespec {
return Timespec{Sec: sec, Nsec: nsec}
}
func setTimeval(sec, usec int64) Timeval {
return Timeval{Sec: sec, Usec: int32(usec)}
}
func SetKevent(k *Kevent_t, fd, mode, flags int) {
k.Ident = uint64(fd)
k.Filter = uint32(mode)
k.Flags = uint32(flags)
}
func (iov *Iovec) SetLen(length int) {
iov.Len = uint64(length)
}
func (msghdr *Msghdr) SetControllen(length int) {
msghdr.Controllen = uint32(length)
}
func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint32(length)
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs types_netbsd.go
// +build arm64,netbsd
package syscall
const (
sizeofPtr = 0x8
sizeofShort = 0x2
sizeofInt = 0x4
sizeofLong = 0x8
sizeofLongLong = 0x8
)
type (
_C_short int16
_C_int int32
_C_long int64
_C_long_long int64
)
type Timespec struct {
Sec int64
Nsec int64
}
type Timeval struct {
Sec int64
Usec int32
Pad_cgo_0 [4]byte
}
type Rusage struct {
Utime Timeval
Stime Timeval
Maxrss int64
Ixrss int64
Idrss int64
Isrss int64
Minflt int64
Majflt int64
Nswap int64
Inblock int64
Oublock int64
Msgsnd int64
Msgrcv int64
Nsignals int64
Nvcsw int64
Nivcsw int64
}
type Rlimit struct {
Cur uint64
Max uint64
}
type _Gid_t uint32
type Stat_t struct {
Dev uint64
Mode uint32
Pad_cgo_0 [4]byte
Ino uint64
Nlink uint32
Uid uint32
Gid uint32
Pad_cgo_1 [4]byte
Rdev uint64
Atimespec Timespec
Mtimespec Timespec
Ctimespec Timespec
Birthtimespec Timespec
Size int64
Blocks int64
Blksize uint32
Flags uint32
Gen uint32
Spare [2]uint32
Pad_cgo_2 [4]byte
}
type Statfs_t [0]byte
type Flock_t struct {
Start int64
Len int64
Pid int32
Type int16
Whence int16
}
type Dirent struct {
Fileno uint64
Reclen uint16
Namlen uint16
Type uint8
Name [512]int8
Pad_cgo_0 [3]byte
}
type Fsid struct {
X__fsid_val [2]int32
}
const (
pathMax = 0x400
)
type RawSockaddrInet4 struct {
Len uint8
Family uint8
Port uint16
Addr [4]byte /* in_addr */
Zero [8]int8
}
type RawSockaddrInet6 struct {
Len uint8
Family uint8
Port uint16
Flowinfo uint32
Addr [16]byte /* in6_addr */
Scope_id uint32
}
type RawSockaddrUnix struct {
Len uint8
Family uint8
Path [104]int8
}
type RawSockaddrDatalink struct {
Len uint8
Family uint8
Index uint16
Type uint8
Nlen uint8
Alen uint8
Slen uint8
Data [12]int8
}
type RawSockaddr struct {
Len uint8
Family uint8
Data [14]int8
}
type RawSockaddrAny struct {
Addr RawSockaddr
Pad [92]int8
}
type _Socklen uint32
type Linger struct {
Onoff int32
Linger int32
}
type Iovec struct {
Base *byte
Len uint64
}
type IPMreq struct {
Multiaddr [4]byte /* in_addr */
Interface [4]byte /* in_addr */
}
type IPv6Mreq struct {
Multiaddr [16]byte /* in6_addr */
Interface uint32
}
type Msghdr struct {
Name *byte
Namelen uint32
Pad_cgo_0 [4]byte
Iov *Iovec
Iovlen int32
Pad_cgo_1 [4]byte
Control *byte
Controllen uint32
Flags int32
}
type Cmsghdr struct {
Len uint32
Level int32
Type int32
}
type Inet6Pktinfo struct {
Addr [16]byte /* in6_addr */
Ifindex uint32
}
type IPv6MTUInfo struct {
Addr RawSockaddrInet6
Mtu uint32
}
type ICMPv6Filter struct {
Filt [8]uint32
}
const (
SizeofSockaddrInet4 = 0x10
SizeofSockaddrInet6 = 0x1c
SizeofSockaddrAny = 0x6c
SizeofSockaddrUnix = 0x6a
SizeofSockaddrDatalink = 0x14
SizeofLinger = 0x8
SizeofIPMreq = 0x8
SizeofIPv6Mreq = 0x14
SizeofMsghdr = 0x30
SizeofCmsghdr = 0xc
SizeofInet6Pktinfo = 0x14
SizeofIPv6MTUInfo = 0x20
SizeofICMPv6Filter = 0x20
)
const (
PTRACE_TRACEME = 0x0
PTRACE_CONT = 0x7
PTRACE_KILL = 0x8
)
type Kevent_t struct {
Ident uint64
Filter uint32
Flags uint32
Fflags uint32
Pad_cgo_0 [4]byte
Data int64
Udata int64
}
type FdSet struct {
Bits [8]uint32
}
const (
SizeofIfMsghdr = 0x98
SizeofIfData = 0x88
SizeofIfaMsghdr = 0x18
SizeofIfAnnounceMsghdr = 0x18
SizeofRtMsghdr = 0x78
SizeofRtMetrics = 0x50
)
type IfMsghdr struct {
Msglen uint16
Version uint8
Type uint8
Addrs int32
Flags int32
Index uint16
Pad_cgo_0 [2]byte
Data IfData
}
type IfData struct {
Type uint8
Addrlen uint8
Hdrlen uint8
Pad_cgo_0 [1]byte
Link_state int32
Mtu uint64
Metric uint64
Baudrate uint64
Ipackets uint64
Ierrors uint64
Opackets uint64
Oerrors uint64
Collisions uint64
Ibytes uint64
Obytes uint64
Imcasts uint64
Omcasts uint64
Iqdrops uint64
Noproto uint64
Lastchange Timespec
}
type IfaMsghdr struct {
Msglen uint16
Version uint8
Type uint8
Addrs int32
Flags int32
Metric int32
Index uint16
Pad_cgo_0 [6]byte
}
type IfAnnounceMsghdr struct {
Msglen uint16
Version uint8
Type uint8
Index uint16
Name [16]int8
What uint16
}
type RtMsghdr struct {
Msglen uint16
Version uint8
Type uint8
Index uint16
Pad_cgo_0 [2]byte
Flags int32
Addrs int32
Pid int32
Seq int32
Errno int32
Use int32
Inits int32
Pad_cgo_1 [4]byte
Rmx RtMetrics
}
type RtMetrics struct {
Locks uint64
Mtu uint64
Hopcount uint64
Recvpipe uint64
Sendpipe uint64
Ssthresh uint64
Rtt uint64
Rttvar uint64
Expire int64
Pksent int64
}
type Mclpool [0]byte
const (
SizeofBpfVersion = 0x4
SizeofBpfStat = 0x80
SizeofBpfProgram = 0x10
SizeofBpfInsn = 0x8
SizeofBpfHdr = 0x20
)
type BpfVersion struct {
Major uint16
Minor uint16
}
type BpfStat struct {
Recv uint64
Drop uint64
Capt uint64
Padding [13]uint64
}
type BpfProgram struct {
Len uint32
Pad_cgo_0 [4]byte
Insns *BpfInsn
}
type BpfInsn struct {
Code uint16
Jt uint8
Jf uint8
K uint32
}
type BpfHdr struct {
Tstamp BpfTimeval
Caplen uint32
Datalen uint32
Hdrlen uint16
Pad_cgo_0 [6]byte
}
type BpfTimeval struct {
Sec int64
Usec int64
}
const (
_AT_FDCWD = -0x64
)
type Termios struct {
Iflag uint32
Oflag uint32
Cflag uint32
Lflag uint32
Cc [20]uint8
Ispeed int32
Ospeed int32
}
type Sysctlnode struct {
Flags uint32
Num int32
Name [32]int8
Ver uint32
X__rsvd uint32
Un [16]byte
X_sysctl_size [8]byte
X_sysctl_func [8]byte
X_sysctl_parent [8]byte
X_sysctl_desc [8]byte
}
type sigset struct {
X__bits [4]uint32
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment