mirror of
https://github.com/golang/go
synced 2024-11-24 23:17:57 -07:00
runtime: Changes to the runtime to support NetBSD.
R=rsc CC=golang-dev https://golang.org/cl/5477052
This commit is contained in:
parent
ecf4a9216e
commit
26089cfe25
146
src/pkg/runtime/netbsd/386/defs.h
Normal file
146
src/pkg/runtime/netbsd/386/defs.h
Normal file
@ -0,0 +1,146 @@
|
||||
// godefs -f -m32 defs.c
|
||||
|
||||
// MACHINE GENERATED - DO NOT EDIT.
|
||||
|
||||
// Constants
|
||||
enum {
|
||||
PROT_NONE = 0,
|
||||
PROT_READ = 0x1,
|
||||
PROT_WRITE = 0x2,
|
||||
PROT_EXEC = 0x4,
|
||||
MAP_ANON = 0x1000,
|
||||
MAP_PRIVATE = 0x2,
|
||||
MAP_FIXED = 0x10,
|
||||
SA_SIGINFO = 0x40,
|
||||
SA_RESTART = 0x2,
|
||||
SA_ONSTACK = 0x1,
|
||||
EINTR = 0x4,
|
||||
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 = 0,
|
||||
ITIMER_VIRTUAL = 0x1,
|
||||
ITIMER_PROF = 0x2,
|
||||
};
|
||||
|
||||
// Types
|
||||
#pragma pack on
|
||||
|
||||
typedef struct Sigaltstack Sigaltstack;
|
||||
struct Sigaltstack {
|
||||
void *ss_sp;
|
||||
uint32 ss_size;
|
||||
int32 ss_flags;
|
||||
};
|
||||
|
||||
typedef uint32 Sigset;
|
||||
|
||||
typedef struct Siginfo Siginfo;
|
||||
struct Siginfo {
|
||||
int32 si_signo;
|
||||
int32 si_code;
|
||||
int32 si_errno;
|
||||
byte _data[116];
|
||||
};
|
||||
|
||||
typedef union Sigval Sigval;
|
||||
union Sigval {
|
||||
int32 sival_int;
|
||||
void *sival_ptr;
|
||||
};
|
||||
|
||||
typedef struct StackT StackT;
|
||||
struct StackT {
|
||||
void *ss_sp;
|
||||
uint32 ss_size;
|
||||
int32 ss_flags;
|
||||
};
|
||||
|
||||
typedef struct Timespec Timespec;
|
||||
struct Timespec {
|
||||
int32 tv_sec;
|
||||
int32 tv_nsec;
|
||||
};
|
||||
|
||||
typedef struct Timeval Timeval;
|
||||
struct Timeval {
|
||||
int32 tv_sec;
|
||||
int32 tv_usec;
|
||||
};
|
||||
|
||||
typedef struct Itimerval Itimerval;
|
||||
struct Itimerval {
|
||||
Timeval it_interval;
|
||||
Timeval it_value;
|
||||
};
|
||||
|
||||
typedef void sfxsave64;
|
||||
|
||||
typedef void usavefpu;
|
||||
|
||||
typedef struct Sigcontext Sigcontext;
|
||||
struct Sigcontext {
|
||||
int32 sc_gs;
|
||||
int32 sc_fs;
|
||||
int32 sc_es;
|
||||
int32 sc_ds;
|
||||
int32 sc_edi;
|
||||
int32 sc_esi;
|
||||
int32 sc_ebp;
|
||||
int32 sc_ebx;
|
||||
int32 sc_edx;
|
||||
int32 sc_ecx;
|
||||
int32 sc_eax;
|
||||
int32 sc_eip;
|
||||
int32 sc_cs;
|
||||
int32 sc_eflags;
|
||||
int32 sc_esp;
|
||||
int32 sc_ss;
|
||||
int32 sc_onstack;
|
||||
int32 sc_mask;
|
||||
int32 sc_trapno;
|
||||
int32 sc_err;
|
||||
usavefpu *sc_fpstate;
|
||||
};
|
||||
#pragma pack off
|
6
src/pkg/runtime/netbsd/386/rt0.s
Normal file
6
src/pkg/runtime/netbsd/386/rt0.s
Normal file
@ -0,0 +1,6 @@
|
||||
// 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.
|
||||
|
||||
TEXT _rt0_386_netbsd(SB),7,$0
|
||||
JMP _rt0_386(SB)
|
189
src/pkg/runtime/netbsd/386/signal.c
Normal file
189
src/pkg/runtime/netbsd/386/signal.c
Normal file
@ -0,0 +1,189 @@
|
||||
// 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 "runtime.h"
|
||||
#include "defs.h"
|
||||
#include "signals.h"
|
||||
#include "os.h"
|
||||
|
||||
extern void runtime·sigtramp(void);
|
||||
|
||||
typedef struct sigaction {
|
||||
union {
|
||||
void (*__sa_handler)(int32);
|
||||
void (*__sa_sigaction)(int32, Siginfo*, void *);
|
||||
} __sigaction_u; /* signal handler */
|
||||
uint32 sa_mask; /* signal mask to apply */
|
||||
int32 sa_flags; /* see signal options below */
|
||||
} Sigaction;
|
||||
|
||||
void
|
||||
runtime·dumpregs(Sigcontext *r)
|
||||
{
|
||||
runtime·printf("eax %x\n", r->sc_eax);
|
||||
runtime·printf("ebx %x\n", r->sc_ebx);
|
||||
runtime·printf("ecx %x\n", r->sc_ecx);
|
||||
runtime·printf("edx %x\n", r->sc_edx);
|
||||
runtime·printf("edi %x\n", r->sc_edi);
|
||||
runtime·printf("esi %x\n", r->sc_esi);
|
||||
runtime·printf("ebp %x\n", r->sc_ebp);
|
||||
runtime·printf("esp %x\n", r->sc_esp);
|
||||
runtime·printf("eip %x\n", r->sc_eip);
|
||||
runtime·printf("eflags %x\n", r->sc_eflags);
|
||||
runtime·printf("cs %x\n", r->sc_cs);
|
||||
runtime·printf("fs %x\n", r->sc_fs);
|
||||
runtime·printf("gs %x\n", r->sc_gs);
|
||||
}
|
||||
|
||||
String
|
||||
runtime·signame(int32 sig)
|
||||
{
|
||||
if(sig < 0 || sig >= NSIG)
|
||||
return runtime·emptystring;
|
||||
return runtime·gostringnocopy((byte*)runtime·sigtab[sig].name);
|
||||
}
|
||||
|
||||
void
|
||||
runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
|
||||
{
|
||||
Sigcontext *r = context;
|
||||
uintptr *sp;
|
||||
|
||||
if(sig == SIGPROF) {
|
||||
runtime·sigprof((uint8*)r->sc_eip, (uint8*)r->sc_esp, nil, gp);
|
||||
return;
|
||||
}
|
||||
|
||||
if(gp != nil && (runtime·sigtab[sig].flags & SigPanic)) {
|
||||
// Make it look like a call to the signal func.
|
||||
// Have to pass arguments out of band since
|
||||
// augmenting the stack frame would break
|
||||
// the unwinding code.
|
||||
gp->sig = sig;
|
||||
gp->sigcode0 = info->si_code;
|
||||
gp->sigcode1 = *(uintptr*)((byte*)info + 12); /* si_addr */
|
||||
gp->sigpc = r->sc_eip;
|
||||
|
||||
// Only push runtime·sigpanic if r->sc_eip != 0.
|
||||
// If r->sc_eip == 0, probably panicked because of a
|
||||
// call to a nil func. Not pushing that onto sp will
|
||||
// make the trace look like a call to runtime·sigpanic instead.
|
||||
// (Otherwise the trace will end at runtime·sigpanic and we
|
||||
// won't get to see who faulted.)
|
||||
if(r->sc_eip != 0) {
|
||||
sp = (uintptr*)r->sc_esp;
|
||||
*--sp = r->sc_eip;
|
||||
r->sc_esp = (uintptr)sp;
|
||||
}
|
||||
r->sc_eip = (uintptr)runtime·sigpanic;
|
||||
return;
|
||||
}
|
||||
|
||||
if(runtime·sigtab[sig].flags & SigQueue) {
|
||||
if(runtime·sigsend(sig) || (runtime·sigtab[sig].flags & SigIgnore))
|
||||
return;
|
||||
runtime·exit(2); // SIGINT, SIGTERM, etc
|
||||
}
|
||||
|
||||
if(runtime·panicking) // traceback already printed
|
||||
runtime·exit(2);
|
||||
runtime·panicking = 1;
|
||||
|
||||
if(sig < 0 || sig >= NSIG)
|
||||
runtime·printf("Signal %d\n", sig);
|
||||
else
|
||||
runtime·printf("%s\n", runtime·sigtab[sig].name);
|
||||
|
||||
runtime·printf("PC=%X\n", r->sc_eip);
|
||||
runtime·printf("\n");
|
||||
|
||||
if(runtime·gotraceback()){
|
||||
runtime·traceback((void*)r->sc_eip, (void*)r->sc_esp, 0, gp);
|
||||
runtime·tracebackothers(gp);
|
||||
runtime·dumpregs(r);
|
||||
}
|
||||
|
||||
runtime·exit(2);
|
||||
}
|
||||
|
||||
// Called from kernel on signal stack, so no stack split.
|
||||
#pragma textflag 7
|
||||
void
|
||||
runtime·sigignore(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
runtime·signalstack(byte *p, int32 n)
|
||||
{
|
||||
Sigaltstack st;
|
||||
|
||||
st.ss_sp = (int8*)p;
|
||||
st.ss_size = n;
|
||||
st.ss_flags = 0;
|
||||
runtime·sigaltstack(&st, nil);
|
||||
}
|
||||
|
||||
static void
|
||||
sigaction(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
|
||||
{
|
||||
Sigaction sa;
|
||||
|
||||
runtime·memclr((byte*)&sa, sizeof sa);
|
||||
sa.sa_flags = SA_SIGINFO|SA_ONSTACK;
|
||||
if(restart)
|
||||
sa.sa_flags |= SA_RESTART;
|
||||
sa.sa_mask = ~0ULL;
|
||||
if (fn == runtime·sighandler)
|
||||
fn = (void*)runtime·sigtramp;
|
||||
sa.__sigaction_u.__sa_sigaction = (void*)fn;
|
||||
runtime·sigaction(i, &sa, nil);
|
||||
}
|
||||
|
||||
void
|
||||
runtime·initsig(int32 queue)
|
||||
{
|
||||
int32 i;
|
||||
void *fn;
|
||||
|
||||
runtime·siginit();
|
||||
|
||||
for(i = 0; i<NSIG; i++) {
|
||||
if(runtime·sigtab[i].flags) {
|
||||
if((runtime·sigtab[i].flags & SigQueue) != queue)
|
||||
continue;
|
||||
if(runtime·sigtab[i].flags & (SigCatch | SigQueue))
|
||||
fn = runtime·sighandler;
|
||||
else
|
||||
fn = runtime·sigignore;
|
||||
sigaction(i, fn, (runtime·sigtab[i].flags & SigRestart) != 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
runtime·resetcpuprofiler(int32 hz)
|
||||
{
|
||||
Itimerval it;
|
||||
|
||||
runtime·memclr((byte*)&it, sizeof it);
|
||||
if(hz == 0) {
|
||||
runtime·setitimer(ITIMER_PROF, &it, nil);
|
||||
sigaction(SIGPROF, SIG_IGN, true);
|
||||
} else {
|
||||
sigaction(SIGPROF, runtime·sighandler, true);
|
||||
it.it_interval.tv_sec = 0;
|
||||
it.it_interval.tv_usec = 1000000 / hz;
|
||||
it.it_value = it.it_interval;
|
||||
runtime·setitimer(ITIMER_PROF, &it, nil);
|
||||
}
|
||||
m->profilehz = hz;
|
||||
}
|
||||
|
||||
void
|
||||
os·sigpipe(void)
|
||||
{
|
||||
sigaction(SIGPIPE, SIG_DFL, false);
|
||||
runtime·raisesigpipe();
|
||||
}
|
324
src/pkg/runtime/netbsd/386/sys.s
Normal file
324
src/pkg/runtime/netbsd/386/sys.s
Normal file
@ -0,0 +1,324 @@
|
||||
// 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.
|
||||
//
|
||||
// System calls and other sys.stuff for 386, NetBSD
|
||||
// /usr/src/sys/kern/syscalls.master for syscall numbers.
|
||||
//
|
||||
|
||||
#include "386/asm.h"
|
||||
|
||||
// Exit the entire program (like C exit)
|
||||
TEXT runtime·exit(SB),7,$-4
|
||||
MOVL $1, AX
|
||||
INT $0x80
|
||||
CALL runtime·notok(SB)
|
||||
RET
|
||||
|
||||
TEXT runtime·exit1(SB),7,$-4
|
||||
MOVL $302, AX // sys_threxit
|
||||
INT $0x80
|
||||
JAE 2(PC)
|
||||
CALL runtime·notok(SB)
|
||||
RET
|
||||
|
||||
TEXT runtime·write(SB),7,$-4
|
||||
MOVL $4, AX // sys_write
|
||||
INT $0x80
|
||||
RET
|
||||
|
||||
TEXT runtime·usleep(SB),7,$20
|
||||
MOVL $0, DX
|
||||
MOVL usec+0(FP), AX
|
||||
MOVL $1000000, CX
|
||||
DIVL CX
|
||||
MOVL AX, 12(SP) // tv_sec
|
||||
MOVL $1000, AX
|
||||
MULL DX
|
||||
MOVL AX, 16(SP) // tv_nsec
|
||||
|
||||
MOVL $0, 0(SP)
|
||||
LEAL 12(SP), AX
|
||||
MOVL AX, 4(SP) // arg 1 - rqtp
|
||||
MOVL $0, 8(SP) // arg 2 - rmtp
|
||||
MOVL $240, AX // sys_nanosleep
|
||||
INT $0x80
|
||||
RET
|
||||
|
||||
TEXT runtime·raisesigpipe(SB),7,$12
|
||||
MOVL $299, AX // sys_getthrid
|
||||
INT $0x80
|
||||
MOVL $0, 0(SP)
|
||||
MOVL AX, 4(SP) // arg 1 - pid
|
||||
MOVL $13, 8(SP) // arg 2 - signum == SIGPIPE
|
||||
MOVL $37, AX // sys_kill
|
||||
INT $0x80
|
||||
RET
|
||||
|
||||
TEXT runtime·notok(SB),7,$0
|
||||
MOVL $0xf1, 0xf1
|
||||
RET
|
||||
|
||||
TEXT runtime·mmap(SB),7,$36
|
||||
LEAL arg0+0(FP), SI
|
||||
LEAL 4(SP), DI
|
||||
CLD
|
||||
MOVSL // arg 1 - addr
|
||||
MOVSL // arg 2 - len
|
||||
MOVSL // arg 3 - prot
|
||||
MOVSL // arg 4 - flags
|
||||
MOVSL // arg 5 - fd
|
||||
MOVL $0, AX
|
||||
STOSL // arg 6 - pad
|
||||
MOVSL // arg 7 - offset
|
||||
MOVL $0, AX // top 64 bits of file offset
|
||||
STOSL
|
||||
MOVL $197, AX // sys_mmap
|
||||
INT $0x80
|
||||
JCC 2(PC)
|
||||
NEGL AX
|
||||
RET
|
||||
|
||||
TEXT runtime·munmap(SB),7,$-4
|
||||
MOVL $73, AX // sys_munmap
|
||||
INT $0x80
|
||||
JAE 2(PC)
|
||||
CALL runtime·notok(SB)
|
||||
RET
|
||||
|
||||
TEXT runtime·setitimer(SB),7,$-4
|
||||
MOVL $83, AX
|
||||
INT $0x80
|
||||
RET
|
||||
|
||||
// func now() (sec int64, nsec int32)
|
||||
TEXT time·now(SB), 7, $32
|
||||
MOVL $116, AX
|
||||
LEAL 12(SP), BX
|
||||
MOVL BX, 4(SP)
|
||||
MOVL $0, 8(SP)
|
||||
INT $0x80
|
||||
MOVL 12(SP), AX // sec
|
||||
MOVL 16(SP), BX // usec
|
||||
|
||||
// sec is in AX, usec in BX
|
||||
MOVL AX, sec+0(FP)
|
||||
MOVL $0, sec+4(FP)
|
||||
IMULL $1000, BX
|
||||
MOVL BX, nsec+8(FP)
|
||||
RET
|
||||
|
||||
// int64 nanotime(void) so really
|
||||
// void nanotime(int64 *nsec)
|
||||
TEXT runtime·nanotime(SB),7,$32
|
||||
MOVL $116, AX
|
||||
LEAL 12(SP), BX
|
||||
MOVL BX, 4(SP)
|
||||
MOVL $0, 8(SP)
|
||||
INT $0x80
|
||||
MOVL 12(SP), AX // sec
|
||||
MOVL 16(SP), BX // usec
|
||||
|
||||
// sec is in AX, usec in BX
|
||||
// convert to DX:AX nsec
|
||||
MOVL $1000000000, CX
|
||||
MULL CX
|
||||
IMULL $1000, BX
|
||||
ADDL BX, AX
|
||||
ADCL $0, DX
|
||||
|
||||
MOVL ret+0(FP), DI
|
||||
MOVL AX, 0(DI)
|
||||
MOVL DX, 4(DI)
|
||||
RET
|
||||
|
||||
TEXT runtime·sigaction(SB),7,$-4
|
||||
MOVL $46, AX // sys_sigaction
|
||||
INT $0x80
|
||||
JAE 2(PC)
|
||||
CALL runtime·notok(SB)
|
||||
RET
|
||||
|
||||
TEXT runtime·sigtramp(SB),7,$44
|
||||
get_tls(CX)
|
||||
|
||||
// save g
|
||||
MOVL g(CX), DI
|
||||
MOVL DI, 20(SP)
|
||||
|
||||
// g = m->gsignal
|
||||
MOVL m(CX), BX
|
||||
MOVL m_gsignal(BX), BX
|
||||
MOVL BX, g(CX)
|
||||
|
||||
// copy arguments for call to sighandler
|
||||
MOVL signo+0(FP), BX
|
||||
MOVL BX, 0(SP)
|
||||
MOVL info+4(FP), BX
|
||||
MOVL BX, 4(SP)
|
||||
MOVL context+8(FP), BX
|
||||
MOVL BX, 8(SP)
|
||||
MOVL DI, 12(SP)
|
||||
|
||||
CALL runtime·sighandler(SB)
|
||||
|
||||
// restore g
|
||||
get_tls(CX)
|
||||
MOVL 20(SP), BX
|
||||
MOVL BX, g(CX)
|
||||
|
||||
// call sigreturn
|
||||
MOVL context+8(FP), AX
|
||||
MOVL $0, 0(SP) // syscall gap
|
||||
MOVL AX, 4(SP) // arg 1 - sigcontext
|
||||
MOVL $103, AX // sys_sigreturn
|
||||
INT $0x80
|
||||
CALL runtime·notok(SB)
|
||||
RET
|
||||
|
||||
// int32 rfork_thread(int32 flags, void *stack, M *m, G *g, void (*fn)(void));
|
||||
TEXT runtime·rfork_thread(SB),7,$8
|
||||
MOVL flags+8(SP), AX
|
||||
MOVL stack+12(SP), CX
|
||||
|
||||
// Copy m, g, fn off parent stack for use by child.
|
||||
SUBL $16, CX
|
||||
MOVL mm+16(SP), SI
|
||||
MOVL SI, 0(CX)
|
||||
MOVL gg+20(SP), SI
|
||||
MOVL SI, 4(CX)
|
||||
MOVL fn+24(SP), SI
|
||||
MOVL SI, 8(CX)
|
||||
MOVL $1234, 12(CX)
|
||||
MOVL CX, SI
|
||||
|
||||
MOVL $0, 0(SP) // syscall gap
|
||||
MOVL AX, 4(SP) // arg 1 - flags
|
||||
MOVL $251, AX // sys_rfork
|
||||
INT $0x80
|
||||
|
||||
// Return if rfork syscall failed
|
||||
JCC 4(PC)
|
||||
NEGL AX
|
||||
MOVL AX, 48(SP)
|
||||
RET
|
||||
|
||||
// In parent, return.
|
||||
CMPL AX, $0
|
||||
JEQ 3(PC)
|
||||
MOVL AX, 48(SP)
|
||||
RET
|
||||
|
||||
// In child, on new stack.
|
||||
MOVL SI, SP
|
||||
|
||||
// Paranoia: check that SP is as we expect.
|
||||
MOVL 12(SP), BP
|
||||
CMPL BP, $1234
|
||||
JEQ 2(PC)
|
||||
INT $3
|
||||
|
||||
// Reload registers
|
||||
MOVL 0(SP), BX // m
|
||||
MOVL 4(SP), DX // g
|
||||
MOVL 8(SP), SI // fn
|
||||
|
||||
// Initialize m->procid to thread ID
|
||||
MOVL $299, AX // sys_getthrid
|
||||
INT $0x80
|
||||
MOVL AX, m_procid(BX)
|
||||
|
||||
// Set FS to point at m->tls
|
||||
LEAL m_tls(BX), BP
|
||||
PUSHAL // save registers
|
||||
PUSHL BP
|
||||
CALL runtime·settls(SB)
|
||||
POPL AX
|
||||
POPAL
|
||||
|
||||
// Now segment is established. Initialize m, g.
|
||||
get_tls(AX)
|
||||
MOVL DX, g(AX)
|
||||
MOVL BX, m(AX)
|
||||
|
||||
CALL runtime·stackcheck(SB) // smashes AX, CX
|
||||
MOVL 0(DX), DX // paranoia; check they are not nil
|
||||
MOVL 0(BX), BX
|
||||
|
||||
// more paranoia; check that stack splitting code works
|
||||
PUSHAL
|
||||
CALL runtime·emptyfunc(SB)
|
||||
POPAL
|
||||
|
||||
// Call fn
|
||||
CALL SI
|
||||
|
||||
CALL runtime·exit1(SB)
|
||||
MOVL $0x1234, 0x1005
|
||||
RET
|
||||
|
||||
TEXT runtime·sigaltstack(SB),7,$-8
|
||||
MOVL $288, AX // sys_sigaltstack
|
||||
MOVL new+4(SP), BX
|
||||
MOVL old+8(SP), CX
|
||||
INT $0x80
|
||||
CMPL AX, $0xfffff001
|
||||
JLS 2(PC)
|
||||
INT $3
|
||||
RET
|
||||
|
||||
TEXT runtime·setldt(SB),7,$8
|
||||
// Under NetBSD we set the GS base instead of messing with the LDT.
|
||||
MOVL 16(SP), AX // tls0
|
||||
MOVL AX, 0(SP)
|
||||
CALL runtime·settls(SB)
|
||||
RET
|
||||
|
||||
TEXT runtime·settls(SB),7,$16
|
||||
// adjust for ELF: wants to use -8(GS) and -4(GS) for g and m
|
||||
MOVL 20(SP), CX
|
||||
ADDL $8, CX
|
||||
MOVL CX, 0(CX)
|
||||
MOVL $0, 0(SP) // syscall gap
|
||||
MOVL $9, 4(SP) // I386_SET_GSBASE (machine/sysarch.h)
|
||||
MOVL CX, 8(SP) // pointer to base
|
||||
MOVL $165, AX // sys_sysarch
|
||||
INT $0x80
|
||||
JCC 2(PC)
|
||||
CALL runtime·notok(SB)
|
||||
RET
|
||||
|
||||
TEXT runtime·osyield(SB),7,$-4
|
||||
MOVL $298, AX // sys_sched_yield
|
||||
INT $0x80
|
||||
RET
|
||||
|
||||
TEXT runtime·thrsleep(SB),7,$-4
|
||||
MOVL $300, AX // sys_thrsleep
|
||||
INT $0x80
|
||||
RET
|
||||
|
||||
TEXT runtime·thrwakeup(SB),7,$-4
|
||||
MOVL $301, AX // sys_thrwakeup
|
||||
INT $0x80
|
||||
RET
|
||||
|
||||
TEXT runtime·sysctl(SB),7,$28
|
||||
LEAL arg0+0(FP), SI
|
||||
LEAL 4(SP), DI
|
||||
CLD
|
||||
MOVSL // arg 1 - name
|
||||
MOVSL // arg 2 - namelen
|
||||
MOVSL // arg 3 - oldp
|
||||
MOVSL // arg 4 - oldlenp
|
||||
MOVSL // arg 5 - newp
|
||||
MOVSL // arg 6 - newlen
|
||||
MOVL $202, AX // sys___sysctl
|
||||
INT $0x80
|
||||
JCC 3(PC)
|
||||
NEGL AX
|
||||
RET
|
||||
MOVL $0, AX
|
||||
RET
|
||||
|
||||
GLOBL runtime·tlsoffset(SB),$4
|
158
src/pkg/runtime/netbsd/amd64/defs.h
Normal file
158
src/pkg/runtime/netbsd/amd64/defs.h
Normal file
@ -0,0 +1,158 @@
|
||||
// godefs -f -m64 defs.c
|
||||
|
||||
// MACHINE GENERATED - DO NOT EDIT.
|
||||
|
||||
// Constants
|
||||
enum {
|
||||
PROT_NONE = 0,
|
||||
PROT_READ = 0x1,
|
||||
PROT_WRITE = 0x2,
|
||||
PROT_EXEC = 0x4,
|
||||
MAP_ANON = 0x1000,
|
||||
MAP_PRIVATE = 0x2,
|
||||
MAP_FIXED = 0x10,
|
||||
SA_SIGINFO = 0x40,
|
||||
SA_RESTART = 0x2,
|
||||
SA_ONSTACK = 0x1,
|
||||
EINTR = 0x4,
|
||||
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 = 0,
|
||||
ITIMER_VIRTUAL = 0x1,
|
||||
ITIMER_PROF = 0x2,
|
||||
};
|
||||
|
||||
// Types
|
||||
#pragma pack on
|
||||
|
||||
typedef struct Sigaltstack Sigaltstack;
|
||||
struct Sigaltstack {
|
||||
void *ss_sp;
|
||||
uint64 ss_size;
|
||||
int32 ss_flags;
|
||||
byte pad_godefs_0[4];
|
||||
};
|
||||
|
||||
typedef uint32 Sigset;
|
||||
|
||||
typedef struct Siginfo Siginfo;
|
||||
struct Siginfo {
|
||||
int32 si_signo;
|
||||
int32 si_code;
|
||||
int32 si_errno;
|
||||
byte pad_godefs_0[4];
|
||||
byte _data[120];
|
||||
};
|
||||
|
||||
typedef union Sigval Sigval;
|
||||
union Sigval {
|
||||
int32 sival_int;
|
||||
void *sival_ptr;
|
||||
};
|
||||
|
||||
typedef struct StackT StackT;
|
||||
struct StackT {
|
||||
void *ss_sp;
|
||||
uint64 ss_size;
|
||||
int32 ss_flags;
|
||||
byte pad_godefs_0[4];
|
||||
};
|
||||
|
||||
typedef struct Timespec Timespec;
|
||||
struct Timespec {
|
||||
int32 tv_sec;
|
||||
byte pad_godefs_0[4];
|
||||
int64 tv_nsec;
|
||||
};
|
||||
|
||||
typedef struct Timeval Timeval;
|
||||
struct Timeval {
|
||||
int64 tv_sec;
|
||||
int64 tv_usec;
|
||||
};
|
||||
|
||||
typedef struct Itimerval Itimerval;
|
||||
struct Itimerval {
|
||||
Timeval it_interval;
|
||||
Timeval it_value;
|
||||
};
|
||||
|
||||
typedef void sfxsave64;
|
||||
|
||||
typedef void usavefpu;
|
||||
|
||||
typedef struct Sigcontext Sigcontext;
|
||||
struct Sigcontext {
|
||||
int64 sc_rdi;
|
||||
int64 sc_rsi;
|
||||
int64 sc_rdx;
|
||||
int64 sc_rcx;
|
||||
int64 sc_r8;
|
||||
int64 sc_r9;
|
||||
int64 sc_r10;
|
||||
int64 sc_r11;
|
||||
int64 sc_r12;
|
||||
int64 sc_r13;
|
||||
int64 sc_r14;
|
||||
int64 sc_r15;
|
||||
int64 sc_rbp;
|
||||
int64 sc_rbx;
|
||||
int64 sc_rax;
|
||||
int64 sc_gs;
|
||||
int64 sc_fs;
|
||||
int64 sc_es;
|
||||
int64 sc_ds;
|
||||
int64 sc_trapno;
|
||||
int64 sc_err;
|
||||
int64 sc_rip;
|
||||
int64 sc_cs;
|
||||
int64 sc_rflags;
|
||||
int64 sc_rsp;
|
||||
int64 sc_ss;
|
||||
sfxsave64 *sc_fpstate;
|
||||
int32 sc_onstack;
|
||||
int32 sc_mask;
|
||||
};
|
||||
#pragma pack off
|
8
src/pkg/runtime/netbsd/amd64/rt0.s
Normal file
8
src/pkg/runtime/netbsd/amd64/rt0.s
Normal file
@ -0,0 +1,8 @@
|
||||
// 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.
|
||||
|
||||
TEXT _rt0_amd64_netbsd(SB),7,$-8
|
||||
MOVQ $_rt0_amd64(SB), DX
|
||||
MOVQ SP, DI
|
||||
JMP DX
|
199
src/pkg/runtime/netbsd/amd64/signal.c
Normal file
199
src/pkg/runtime/netbsd/amd64/signal.c
Normal file
@ -0,0 +1,199 @@
|
||||
// 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 "runtime.h"
|
||||
#include "defs.h"
|
||||
#include "signals.h"
|
||||
#include "os.h"
|
||||
|
||||
extern void runtime·sigtramp(void);
|
||||
|
||||
typedef struct sigaction {
|
||||
union {
|
||||
void (*__sa_handler)(int32);
|
||||
void (*__sa_sigaction)(int32, Siginfo*, void *);
|
||||
} __sigaction_u; /* signal handler */
|
||||
uint32 sa_mask; /* signal mask to apply */
|
||||
int32 sa_flags; /* see signal options below */
|
||||
} Sigaction;
|
||||
|
||||
void
|
||||
runtime·dumpregs(Sigcontext *r)
|
||||
{
|
||||
runtime·printf("rax %X\n", r->sc_rax);
|
||||
runtime·printf("rbx %X\n", r->sc_rbx);
|
||||
runtime·printf("rcx %X\n", r->sc_rcx);
|
||||
runtime·printf("rdx %X\n", r->sc_rdx);
|
||||
runtime·printf("rdi %X\n", r->sc_rdi);
|
||||
runtime·printf("rsi %X\n", r->sc_rsi);
|
||||
runtime·printf("rbp %X\n", r->sc_rbp);
|
||||
runtime·printf("rsp %X\n", r->sc_rsp);
|
||||
runtime·printf("r8 %X\n", r->sc_r8);
|
||||
runtime·printf("r9 %X\n", r->sc_r9);
|
||||
runtime·printf("r10 %X\n", r->sc_r10);
|
||||
runtime·printf("r11 %X\n", r->sc_r11);
|
||||
runtime·printf("r12 %X\n", r->sc_r12);
|
||||
runtime·printf("r13 %X\n", r->sc_r13);
|
||||
runtime·printf("r14 %X\n", r->sc_r14);
|
||||
runtime·printf("r15 %X\n", r->sc_r15);
|
||||
runtime·printf("rip %X\n", r->sc_rip);
|
||||
runtime·printf("rflags %X\n", r->sc_rflags);
|
||||
runtime·printf("cs %X\n", r->sc_cs);
|
||||
runtime·printf("fs %X\n", r->sc_fs);
|
||||
runtime·printf("gs %X\n", r->sc_gs);
|
||||
}
|
||||
|
||||
String
|
||||
runtime·signame(int32 sig)
|
||||
{
|
||||
if(sig < 0 || sig >= NSIG)
|
||||
return runtime·emptystring;
|
||||
return runtime·gostringnocopy((byte*)runtime·sigtab[sig].name);
|
||||
}
|
||||
|
||||
void
|
||||
runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
|
||||
{
|
||||
Sigcontext *r = context;
|
||||
uintptr *sp;
|
||||
|
||||
if(sig == SIGPROF) {
|
||||
runtime·sigprof((uint8*)r->sc_rip,
|
||||
(uint8*)r->sc_rsp, nil, gp);
|
||||
return;
|
||||
}
|
||||
|
||||
if(gp != nil && (runtime·sigtab[sig].flags & SigPanic)) {
|
||||
// Make it look like a call to the signal func.
|
||||
// Have to pass arguments out of band since
|
||||
// augmenting the stack frame would break
|
||||
// the unwinding code.
|
||||
gp->sig = sig;
|
||||
gp->sigcode0 = info->si_code;
|
||||
gp->sigcode1 = *(uintptr*)((byte*)info + 16); /* si_addr */
|
||||
gp->sigpc = r->sc_rip;
|
||||
|
||||
// Only push runtime·sigpanic if r->mc_rip != 0.
|
||||
// If r->mc_rip == 0, probably panicked because of a
|
||||
// call to a nil func. Not pushing that onto sp will
|
||||
// make the trace look like a call to runtime·sigpanic instead.
|
||||
// (Otherwise the trace will end at runtime·sigpanic and we
|
||||
// won't get to see who faulted.)
|
||||
if(r->sc_rip != 0) {
|
||||
sp = (uintptr*)r->sc_rsp;
|
||||
*--sp = r->sc_rip;
|
||||
r->sc_rsp = (uintptr)sp;
|
||||
}
|
||||
r->sc_rip = (uintptr)runtime·sigpanic;
|
||||
return;
|
||||
}
|
||||
|
||||
if(runtime·sigtab[sig].flags & SigQueue) {
|
||||
if(runtime·sigsend(sig)
|
||||
|| (runtime·sigtab[sig].flags & SigIgnore))
|
||||
return;
|
||||
runtime·exit(2); // SIGINT, SIGTERM, etc
|
||||
}
|
||||
|
||||
if(runtime·panicking) // traceback already printed
|
||||
runtime·exit(2);
|
||||
runtime·panicking = 1;
|
||||
|
||||
if(sig < 0 || sig >= NSIG)
|
||||
runtime·printf("Signal %d\n", sig);
|
||||
else
|
||||
runtime·printf("%s\n", runtime·sigtab[sig].name);
|
||||
|
||||
runtime·printf("PC=%X\n", r->sc_rip);
|
||||
runtime·printf("\n");
|
||||
|
||||
if(runtime·gotraceback()){
|
||||
runtime·traceback((void*)r->sc_rip, (void*)r->sc_rsp, 0, gp);
|
||||
runtime·tracebackothers(gp);
|
||||
runtime·dumpregs(r);
|
||||
}
|
||||
|
||||
runtime·exit(2);
|
||||
}
|
||||
|
||||
// Called from kernel on signal stack, so no stack split.
|
||||
#pragma textflag 7
|
||||
void
|
||||
runtime·sigignore(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
runtime·signalstack(byte *p, int32 n)
|
||||
{
|
||||
Sigaltstack st;
|
||||
|
||||
st.ss_sp = (int8*)p;
|
||||
st.ss_size = n;
|
||||
st.ss_flags = 0;
|
||||
runtime·sigaltstack(&st, nil);
|
||||
}
|
||||
|
||||
static void
|
||||
sigaction(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
|
||||
{
|
||||
Sigaction sa;
|
||||
|
||||
runtime·memclr((byte*)&sa, sizeof sa);
|
||||
sa.sa_flags = SA_SIGINFO|SA_ONSTACK;
|
||||
if(restart)
|
||||
sa.sa_flags |= SA_RESTART;
|
||||
sa.sa_mask = ~0ULL;
|
||||
if (fn == runtime·sighandler)
|
||||
fn = (void*)runtime·sigtramp;
|
||||
sa.__sigaction_u.__sa_sigaction = (void*)fn;
|
||||
runtime·sigaction(i, &sa, nil);
|
||||
}
|
||||
|
||||
void
|
||||
runtime·initsig(int32 queue)
|
||||
{
|
||||
int32 i;
|
||||
void *fn;
|
||||
|
||||
runtime·siginit();
|
||||
|
||||
for(i = 0; i<NSIG; i++) {
|
||||
if(runtime·sigtab[i].flags) {
|
||||
if((runtime·sigtab[i].flags & SigQueue) != queue)
|
||||
continue;
|
||||
if(runtime·sigtab[i].flags & (SigCatch | SigQueue))
|
||||
fn = runtime·sighandler;
|
||||
else
|
||||
fn = runtime·sigignore;
|
||||
sigaction(i, fn, (runtime·sigtab[i].flags & SigRestart) != 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
runtime·resetcpuprofiler(int32 hz)
|
||||
{
|
||||
Itimerval it;
|
||||
|
||||
runtime·memclr((byte*)&it, sizeof it);
|
||||
if(hz == 0) {
|
||||
runtime·setitimer(ITIMER_PROF, &it, nil);
|
||||
sigaction(SIGPROF, SIG_IGN, true);
|
||||
} else {
|
||||
sigaction(SIGPROF, runtime·sighandler, true);
|
||||
it.it_interval.tv_sec = 0;
|
||||
it.it_interval.tv_usec = 1000000 / hz;
|
||||
it.it_value = it.it_interval;
|
||||
runtime·setitimer(ITIMER_PROF, &it, nil);
|
||||
}
|
||||
m->profilehz = hz;
|
||||
}
|
||||
|
||||
void
|
||||
os·sigpipe(void)
|
||||
{
|
||||
sigaction(SIGPIPE, SIG_DFL, false);
|
||||
runtime·raisesigpipe();
|
||||
}
|
268
src/pkg/runtime/netbsd/amd64/sys.s
Normal file
268
src/pkg/runtime/netbsd/amd64/sys.s
Normal file
@ -0,0 +1,268 @@
|
||||
// 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.
|
||||
//
|
||||
// System calls and other sys.stuff for AMD64, NetBSD
|
||||
// /usr/src/sys/kern/syscalls.master for syscall numbers.
|
||||
//
|
||||
|
||||
#include "amd64/asm.h"
|
||||
|
||||
// int64 rfork_thread(int32 flags, void *stack, M *m, G *g, void (*fn)(void));
|
||||
TEXT runtime·rfork_thread(SB),7,$0
|
||||
MOVL flags+8(SP), DI
|
||||
MOVQ stack+16(SP), SI
|
||||
|
||||
// Copy m, g, fn off parent stack for use by child.
|
||||
MOVQ mm+24(SP), R8
|
||||
MOVQ gg+32(SP), R9
|
||||
MOVQ fn+40(SP), R12
|
||||
|
||||
MOVL $251, AX // sys_rfork
|
||||
SYSCALL
|
||||
|
||||
// Return if rfork syscall failed
|
||||
JCC 3(PC)
|
||||
NEGL AX
|
||||
RET
|
||||
|
||||
// In parent, return.
|
||||
CMPL AX, $0
|
||||
JEQ 2(PC)
|
||||
RET
|
||||
|
||||
// In child, on new stack.
|
||||
MOVQ SI, SP
|
||||
|
||||
// Initialize m->procid to thread ID
|
||||
MOVL $299, AX // sys_getthrid
|
||||
SYSCALL
|
||||
MOVQ AX, m_procid(R8)
|
||||
|
||||
// Set FS to point at m->tls.
|
||||
LEAQ m_tls(R8), DI
|
||||
CALL runtime·settls(SB)
|
||||
|
||||
// In child, set up new stack
|
||||
get_tls(CX)
|
||||
MOVQ R8, m(CX)
|
||||
MOVQ R9, g(CX)
|
||||
CALL runtime·stackcheck(SB)
|
||||
|
||||
// Call fn
|
||||
CALL R12
|
||||
|
||||
// It shouldn't return. If it does, exit
|
||||
MOVL $302, AX // sys_threxit
|
||||
SYSCALL
|
||||
JMP -3(PC) // keep exiting
|
||||
|
||||
TEXT runtime·osyield(SB),7,$0
|
||||
MOVL $298, AX // sys_sched_yield
|
||||
SYSCALL
|
||||
RET
|
||||
|
||||
TEXT runtime·thrsleep(SB),7,$0
|
||||
MOVQ 8(SP), DI // arg 1 - ident
|
||||
MOVL 16(SP), SI // arg 2 - clock_id
|
||||
MOVQ 24(SP), DX // arg 3 - tp
|
||||
MOVQ 32(SP), R10 // arg 4 - lock
|
||||
MOVL $300, AX // sys_thrsleep
|
||||
SYSCALL
|
||||
RET
|
||||
|
||||
TEXT runtime·thrwakeup(SB),7,$0
|
||||
MOVQ 8(SP), DI // arg 1 - ident
|
||||
MOVL 16(SP), SI // arg 2 - n
|
||||
MOVL $301, AX // sys_thrwakeup
|
||||
SYSCALL
|
||||
RET
|
||||
|
||||
// Exit the entire program (like C exit)
|
||||
TEXT runtime·exit(SB),7,$-8
|
||||
MOVL 8(SP), DI // arg 1 - exit status
|
||||
MOVL $1, AX // sys_exit
|
||||
SYSCALL
|
||||
CALL runtime·notok(SB)
|
||||
RET
|
||||
|
||||
TEXT runtime·exit1(SB),7,$-8
|
||||
MOVL $302, AX // sys_threxit
|
||||
SYSCALL
|
||||
CALL runtime·notok(SB)
|
||||
RET
|
||||
|
||||
TEXT runtime·write(SB),7,$-8
|
||||
MOVL 8(SP), DI // arg 1 - fd
|
||||
MOVQ 16(SP), SI // arg 2 - buf
|
||||
MOVL 24(SP), DX // arg 3 - nbyte
|
||||
MOVL $4, AX // sys_write
|
||||
SYSCALL
|
||||
RET
|
||||
|
||||
TEXT runtime·usleep(SB),7,$16
|
||||
MOVL $0, DX
|
||||
MOVL usec+0(FP), AX
|
||||
MOVL $1000000, CX
|
||||
DIVL CX
|
||||
MOVQ AX, 0(SP) // tv_sec
|
||||
MOVL $1000, AX
|
||||
MULL DX
|
||||
MOVQ AX, 8(SP) // tv_nsec
|
||||
|
||||
MOVQ SP, DI // arg 1 - rqtp
|
||||
MOVQ $0, SI // arg 2 - rmtp
|
||||
MOVL $240, AX // sys_nanosleep
|
||||
SYSCALL
|
||||
RET
|
||||
|
||||
TEXT runtime·raisesigpipe(SB),7,$16
|
||||
MOVL $299, AX // sys_getthrid
|
||||
SYSCALL
|
||||
MOVQ AX, DI // arg 1 - pid
|
||||
MOVQ $13, SI // arg 2 - signum == SIGPIPE
|
||||
MOVL $37, AX // sys_kill
|
||||
SYSCALL
|
||||
RET
|
||||
|
||||
TEXT runtime·setitimer(SB),7,$-8
|
||||
MOVL 8(SP), DI // arg 1 - which
|
||||
MOVQ 16(SP), SI // arg 2 - itv
|
||||
MOVQ 24(SP), DX // arg 3 - oitv
|
||||
MOVL $83, AX // sys_setitimer
|
||||
SYSCALL
|
||||
RET
|
||||
|
||||
// func now() (sec int64, nsec int32)
|
||||
TEXT time·now(SB), 7, $32
|
||||
LEAQ 8(SP), DI // arg 1 - tp
|
||||
MOVQ $0, SI // arg 2 - tzp
|
||||
MOVL $116, AX // sys_gettimeofday
|
||||
SYSCALL
|
||||
MOVQ 8(SP), AX // sec
|
||||
MOVL 16(SP), DX // usec
|
||||
|
||||
// sec is in AX, usec in DX
|
||||
MOVQ AX, sec+0(FP)
|
||||
IMULQ $1000, DX
|
||||
MOVL DX, nsec+8(FP)
|
||||
RET
|
||||
|
||||
TEXT runtime·nanotime(SB),7,$32
|
||||
LEAQ 8(SP), DI // arg 1 - tp
|
||||
MOVQ $0, SI // arg 2 - tzp
|
||||
MOVL $116, AX // sys_gettimeofday
|
||||
SYSCALL
|
||||
MOVQ 8(SP), AX // sec
|
||||
MOVL 16(SP), DX // usec
|
||||
|
||||
// sec is in AX, usec in DX
|
||||
// return nsec in AX
|
||||
IMULQ $1000000000, AX
|
||||
IMULQ $1000, DX
|
||||
ADDQ DX, AX
|
||||
RET
|
||||
|
||||
TEXT runtime·sigaction(SB),7,$-8
|
||||
MOVL 8(SP), DI // arg 1 - signum
|
||||
MOVQ 16(SP), SI // arg 2 - nsa
|
||||
MOVQ 24(SP), DX // arg 3 - osa
|
||||
MOVL $46, AX
|
||||
SYSCALL
|
||||
JCC 2(PC)
|
||||
CALL runtime·notok(SB)
|
||||
RET
|
||||
|
||||
TEXT runtime·sigtramp(SB),7,$64
|
||||
get_tls(BX)
|
||||
|
||||
// save g
|
||||
MOVQ g(BX), R10
|
||||
MOVQ R10, 40(SP)
|
||||
|
||||
// g = m->signal
|
||||
MOVQ m(BX), BP
|
||||
MOVQ m_gsignal(BP), BP
|
||||
MOVQ BP, g(BX)
|
||||
|
||||
MOVQ DI, 0(SP)
|
||||
MOVQ SI, 8(SP)
|
||||
MOVQ DX, 16(SP)
|
||||
MOVQ R10, 24(SP)
|
||||
|
||||
CALL runtime·sighandler(SB)
|
||||
|
||||
// restore g
|
||||
get_tls(BX)
|
||||
MOVQ 40(SP), R10
|
||||
MOVQ R10, g(BX)
|
||||
RET
|
||||
|
||||
TEXT runtime·mmap(SB),7,$0
|
||||
MOVQ 8(SP), DI // arg 1 - addr
|
||||
MOVQ 16(SP), SI // arg 2 - len
|
||||
MOVL 24(SP), DX // arg 3 - prot
|
||||
MOVL 28(SP), R10 // arg 4 - flags
|
||||
MOVL 32(SP), R8 // arg 5 - fd
|
||||
MOVQ 36(SP), R9
|
||||
SUBQ $16, SP
|
||||
MOVQ R9, 8(SP) // arg 7 - offset (passed on stack)
|
||||
MOVQ $0, R9 // arg 6 - pad
|
||||
MOVL $197, AX
|
||||
SYSCALL
|
||||
JCC 2(PC)
|
||||
NEGL AX
|
||||
ADDQ $16, SP
|
||||
RET
|
||||
|
||||
TEXT runtime·munmap(SB),7,$0
|
||||
MOVQ 8(SP), DI // arg 1 - addr
|
||||
MOVQ 16(SP), SI // arg 2 - len
|
||||
MOVL $73, AX // sys_munmap
|
||||
SYSCALL
|
||||
JCC 2(PC)
|
||||
CALL runtime·notok(SB)
|
||||
RET
|
||||
|
||||
TEXT runtime·notok(SB),7,$-8
|
||||
MOVL $0xf1, BP
|
||||
MOVQ BP, (BP)
|
||||
RET
|
||||
|
||||
TEXT runtime·sigaltstack(SB),7,$-8
|
||||
MOVQ new+8(SP), DI // arg 1 - nss
|
||||
MOVQ old+16(SP), SI // arg 2 - oss
|
||||
MOVQ $288, AX // sys_sigaltstack
|
||||
SYSCALL
|
||||
JCC 2(PC)
|
||||
CALL runtime·notok(SB)
|
||||
RET
|
||||
|
||||
// set tls base to DI
|
||||
TEXT runtime·settls(SB),7,$8
|
||||
// adjust for ELF: wants to use -16(FS) and -8(FS) for g and m
|
||||
ADDQ $16, DI
|
||||
MOVQ DI, 0(SP)
|
||||
MOVQ SP, SI
|
||||
MOVQ $12, DI // AMD64_SET_FSBASE (machine/sysarch.h)
|
||||
MOVQ $165, AX // sys_sysarch
|
||||
SYSCALL
|
||||
JCC 2(PC)
|
||||
CALL runtime·notok(SB)
|
||||
RET
|
||||
|
||||
TEXT runtime·sysctl(SB),7,$0
|
||||
MOVQ 8(SP), DI // arg 1 - name
|
||||
MOVL 16(SP), SI // arg 2 - namelen
|
||||
MOVQ 24(SP), DX // arg 3 - oldp
|
||||
MOVQ 32(SP), R10 // arg 4 - oldlenp
|
||||
MOVQ 40(SP), R8 // arg 5 - newp
|
||||
MOVQ 48(SP), R9 // arg 6 - newlen
|
||||
MOVQ $202, AX // sys___sysctl
|
||||
SYSCALL
|
||||
JCC 3(PC)
|
||||
NEGL AX
|
||||
RET
|
||||
MOVL $0, AX
|
||||
RET
|
||||
|
109
src/pkg/runtime/netbsd/defs.go
Normal file
109
src/pkg/runtime/netbsd/defs.go
Normal file
@ -0,0 +1,109 @@
|
||||
// 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.
|
||||
|
||||
/*
|
||||
Input to cgo.
|
||||
|
||||
GOARCH=amd64 cgo -cdefs defs.go >amd64/defs.h
|
||||
GOARCH=386 cgo -cdefs defs.go >386/defs.h
|
||||
*/
|
||||
|
||||
package runtime
|
||||
|
||||
/*
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/signal.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
const (
|
||||
PROT_NONE = C.PROT_NONE
|
||||
PROT_READ = C.PROT_READ
|
||||
PROT_WRITE = C.PROT_WRITE
|
||||
PROT_EXEC = C.PROT_EXEC
|
||||
|
||||
MAP_ANON = C.MAP_ANON
|
||||
MAP_PRIVATE = C.MAP_PRIVATE
|
||||
MAP_FIXED = C.MAP_FIXED
|
||||
|
||||
SA_SIGINFO = C.SA_SIGINFO
|
||||
SA_RESTART = C.SA_RESTART
|
||||
SA_ONSTACK = C.SA_ONSTACK
|
||||
|
||||
EINTR = C.EINTR
|
||||
|
||||
SIGHUP = C.SIGHUP
|
||||
SIGINT = C.SIGINT
|
||||
SIGQUIT = C.SIGQUIT
|
||||
SIGILL = C.SIGILL
|
||||
SIGTRAP = C.SIGTRAP
|
||||
SIGABRT = C.SIGABRT
|
||||
SIGEMT = C.SIGEMT
|
||||
SIGFPE = C.SIGFPE
|
||||
SIGKILL = C.SIGKILL
|
||||
SIGBUS = C.SIGBUS
|
||||
SIGSEGV = C.SIGSEGV
|
||||
SIGSYS = C.SIGSYS
|
||||
SIGPIPE = C.SIGPIPE
|
||||
SIGALRM = C.SIGALRM
|
||||
SIGTERM = C.SIGTERM
|
||||
SIGURG = C.SIGURG
|
||||
SIGSTOP = C.SIGSTOP
|
||||
SIGTSTP = C.SIGTSTP
|
||||
SIGCONT = C.SIGCONT
|
||||
SIGCHLD = C.SIGCHLD
|
||||
SIGTTIN = C.SIGTTIN
|
||||
SIGTTOU = C.SIGTTOU
|
||||
SIGIO = C.SIGIO
|
||||
SIGXCPU = C.SIGXCPU
|
||||
SIGXFSZ = C.SIGXFSZ
|
||||
SIGVTALRM = C.SIGVTALRM
|
||||
SIGPROF = C.SIGPROF
|
||||
SIGWINCH = C.SIGWINCH
|
||||
SIGINFO = C.SIGINFO
|
||||
SIGUSR1 = C.SIGUSR1
|
||||
SIGUSR2 = C.SIGUSR2
|
||||
|
||||
FPE_INTDIV = C.FPE_INTDIV
|
||||
FPE_INTOVF = C.FPE_INTOVF
|
||||
FPE_FLTDIV = C.FPE_FLTDIV
|
||||
FPE_FLTOVF = C.FPE_FLTOVF
|
||||
FPE_FLTUND = C.FPE_FLTUND
|
||||
FPE_FLTRES = C.FPE_FLTRES
|
||||
FPE_FLTINV = C.FPE_FLTINV
|
||||
FPE_FLTSUB = C.FPE_FLTSUB
|
||||
|
||||
BUS_ADRALN = C.BUS_ADRALN
|
||||
BUS_ADRERR = C.BUS_ADRERR
|
||||
BUS_OBJERR = C.BUS_OBJERR
|
||||
|
||||
SEGV_MAPERR = C.SEGV_MAPERR
|
||||
SEGV_ACCERR = C.SEGV_ACCERR
|
||||
|
||||
ITIMER_REAL = C.ITIMER_REAL
|
||||
ITIMER_VIRTUAL = C.ITIMER_VIRTUAL
|
||||
ITIMER_PROF = C.ITIMER_PROF
|
||||
)
|
||||
|
||||
type Sigaltstack C.struct_sigaltstack
|
||||
type Sigset C.sigset_t
|
||||
type Siginfo C.siginfo_t
|
||||
type Sigval C.union_sigval
|
||||
|
||||
type StackT C.stack_t
|
||||
|
||||
type Timespec C.struct_timespec
|
||||
type Timeval C.struct_timeval
|
||||
type Itimerval C.struct_itimerval
|
||||
|
||||
// This is a hack to avoid pulling in machine/fpu.h.
|
||||
type sfxsave64 struct{}
|
||||
type usavefpu struct{}
|
||||
|
||||
type Sigcontext C.struct_sigcontext
|
85
src/pkg/runtime/netbsd/mem.c
Normal file
85
src/pkg/runtime/netbsd/mem.c
Normal file
@ -0,0 +1,85 @@
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "runtime.h"
|
||||
#include "arch.h"
|
||||
#include "defs.h"
|
||||
#include "os.h"
|
||||
#include "malloc.h"
|
||||
|
||||
enum
|
||||
{
|
||||
ENOMEM = 12,
|
||||
};
|
||||
|
||||
void*
|
||||
runtime·SysAlloc(uintptr n)
|
||||
{
|
||||
void *v;
|
||||
|
||||
mstats.sys += n;
|
||||
v = runtime·mmap(nil, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, -1, 0);
|
||||
if(v < (void*)4096)
|
||||
return nil;
|
||||
return v;
|
||||
}
|
||||
|
||||
void
|
||||
runtime·SysUnused(void *v, uintptr n)
|
||||
{
|
||||
USED(v);
|
||||
USED(n);
|
||||
// TODO(rsc): call madvise MADV_DONTNEED
|
||||
}
|
||||
|
||||
void
|
||||
runtime·SysFree(void *v, uintptr n)
|
||||
{
|
||||
mstats.sys -= n;
|
||||
runtime·munmap(v, n);
|
||||
}
|
||||
|
||||
void*
|
||||
runtime·SysReserve(void *v, uintptr n)
|
||||
{
|
||||
void *p;
|
||||
|
||||
// On 64-bit, people with ulimit -v set complain if we reserve too
|
||||
// much address space. Instead, assume that the reservation is okay
|
||||
// and check the assumption in SysMap.
|
||||
if(sizeof(void*) == 8)
|
||||
return v;
|
||||
|
||||
p = runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
|
||||
if (p == ((void *)-ENOMEM))
|
||||
return nil;
|
||||
else
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
runtime·SysMap(void *v, uintptr n)
|
||||
{
|
||||
void *p;
|
||||
|
||||
mstats.sys += n;
|
||||
|
||||
// On 64-bit, we don't actually have v reserved, so tread carefully.
|
||||
if(sizeof(void*) == 8) {
|
||||
p = runtime·mmap(v, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, -1, 0);
|
||||
if(p == (void*)-ENOMEM)
|
||||
runtime·throw("runtime: out of memory");
|
||||
if(p != v) {
|
||||
runtime·printf("runtime: address space conflict: map(%p) = %p\n", v, p);
|
||||
runtime·throw("runtime: address space conflict");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
p = runtime·mmap(v, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0);
|
||||
if(p == (void*)-ENOMEM)
|
||||
runtime·throw("runtime: out of memory");
|
||||
if(p != v)
|
||||
runtime·throw("runtime: cannot map pages in arena address space");
|
||||
}
|
17
src/pkg/runtime/netbsd/os.h
Normal file
17
src/pkg/runtime/netbsd/os.h
Normal file
@ -0,0 +1,17 @@
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#define SIG_DFL ((void*)0)
|
||||
#define SIG_IGN ((void*)1)
|
||||
|
||||
struct sigaction;
|
||||
|
||||
void runtime·sigpanic(void);
|
||||
void runtime·sigaltstack(Sigaltstack*, Sigaltstack*);
|
||||
void runtime·sigaction(int32, struct sigaction*, struct sigaction*);
|
||||
void runtime·setitimerval(int32, Itimerval*, Itimerval*);
|
||||
void runtime·setitimer(int32, Itimerval*, Itimerval*);
|
||||
int32 runtime·sysctl(uint32*, uint32, byte*, uintptr*, byte*, uintptr);
|
||||
|
||||
void runtime·raisesigpipe(void);
|
52
src/pkg/runtime/netbsd/signals.h
Normal file
52
src/pkg/runtime/netbsd/signals.h
Normal file
@ -0,0 +1,52 @@
|
||||
// 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.
|
||||
|
||||
#define C SigCatch
|
||||
#define I SigIgnore
|
||||
#define R SigRestart
|
||||
#define Q SigQueue
|
||||
#define P SigPanic
|
||||
|
||||
SigTab runtime·sigtab[] = {
|
||||
/* 0 */ 0, "SIGNONE: no trap",
|
||||
/* 1 */ Q+R, "SIGHUP: terminal line hangup",
|
||||
/* 2 */ Q+R, "SIGINT: interrupt",
|
||||
/* 3 */ C, "SIGQUIT: quit",
|
||||
/* 4 */ C, "SIGILL: illegal instruction",
|
||||
/* 5 */ C, "SIGTRAP: trace trap",
|
||||
/* 6 */ C, "SIGABRT: abort",
|
||||
/* 7 */ C, "SIGEMT: EMT instruction",
|
||||
/* 8 */ C+P, "SIGFPE: floating-point exception",
|
||||
/* 9 */ 0, "SIGKILL: kill",
|
||||
/* 10 */ C+P, "SIGBUS: bus error",
|
||||
/* 11 */ C+P, "SIGSEGV: segmentation violation",
|
||||
/* 12 */ C, "SIGSYS: bad system call",
|
||||
/* 13 */ I, "SIGPIPE: write to broken pipe",
|
||||
/* 14 */ Q+I+R, "SIGALRM: alarm clock",
|
||||
/* 15 */ Q+R, "SIGTERM: termination",
|
||||
/* 16 */ Q+I+R, "SIGURG: urgent condition on socket",
|
||||
/* 17 */ 0, "SIGSTOP: stop, unblockable",
|
||||
/* 18 */ Q+I+R, "SIGTSTP: stop from tty",
|
||||
/* 19 */ 0, "SIGCONT: continue",
|
||||
/* 20 */ Q+I+R, "SIGCHLD: child status has changed",
|
||||
/* 21 */ Q+I+R, "SIGTTIN: background read from tty",
|
||||
/* 22 */ Q+I+R, "SIGTTOU: background write to tty",
|
||||
/* 23 */ Q+I+R, "SIGIO: i/o now possible",
|
||||
/* 24 */ Q+I+R, "SIGXCPU: cpu limit exceeded",
|
||||
/* 25 */ Q+I+R, "SIGXFSZ: file size limit exceeded",
|
||||
/* 26 */ Q+I+R, "SIGVTALRM: virtual alarm clock",
|
||||
/* 27 */ Q+I+R, "SIGPROF: profiling alarm clock",
|
||||
/* 28 */ Q+I+R, "SIGWINCH: window size change",
|
||||
/* 29 */ Q+I+R, "SIGINFO: information request",
|
||||
/* 30 */ Q+I+R, "SIGUSR1: user-defined signal 1",
|
||||
/* 31 */ Q+I+R, "SIGUSR2: user-defined signal 2",
|
||||
/* 32 */ Q+I+R, "SIGTHR: reserved",
|
||||
};
|
||||
#undef C
|
||||
#undef I
|
||||
#undef R
|
||||
#undef Q
|
||||
#undef P
|
||||
|
||||
#define NSIG 33
|
197
src/pkg/runtime/netbsd/thread.c
Normal file
197
src/pkg/runtime/netbsd/thread.c
Normal file
@ -0,0 +1,197 @@
|
||||
// Use of this source file is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.`
|
||||
|
||||
#include "runtime.h"
|
||||
#include "defs.h"
|
||||
#include "os.h"
|
||||
#include "stack.h"
|
||||
|
||||
enum
|
||||
{
|
||||
ESRCH = 3,
|
||||
ENOTSUP = 91,
|
||||
|
||||
// From NetBSD's sys/time.h
|
||||
CLOCK_REALTIME = 0,
|
||||
CLOCK_VIRTUAL = 1,
|
||||
CLOCK_PROF = 2,
|
||||
CLOCK_MONOTONIC = 3
|
||||
};
|
||||
|
||||
extern SigTab runtime·sigtab[];
|
||||
|
||||
extern int64 runtime·rfork_thread(int32 flags, void *stack, M *m, G *g, void (*fn)(void));
|
||||
extern int32 runtime·thrsleep(void *ident, int32 clock_id, void *tsp, void *lock);
|
||||
extern int32 runtime·thrwakeup(void *ident, int32 n);
|
||||
|
||||
// From NetBSD's <sys/sysctl.h>
|
||||
#define CTL_HW 6
|
||||
#define HW_NCPU 3
|
||||
|
||||
static int32
|
||||
getncpu(void)
|
||||
{
|
||||
uint32 mib[2];
|
||||
uint32 out;
|
||||
int32 ret;
|
||||
uintptr nout;
|
||||
|
||||
// Fetch hw.ncpu via sysctl.
|
||||
mib[0] = CTL_HW;
|
||||
mib[1] = HW_NCPU;
|
||||
nout = sizeof out;
|
||||
out = 0;
|
||||
ret = runtime·sysctl(mib, 2, (byte*)&out, &nout, nil, 0);
|
||||
if(ret >= 0)
|
||||
return out;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
uintptr
|
||||
runtime·semacreate(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32
|
||||
runtime·semasleep(int64 ns)
|
||||
{
|
||||
Timespec ts;
|
||||
|
||||
// spin-mutex lock
|
||||
while(runtime·xchg(&m->waitsemalock, 1))
|
||||
runtime·osyield();
|
||||
|
||||
for(;;) {
|
||||
// lock held
|
||||
if(m->waitsemacount == 0) {
|
||||
// sleep until semaphore != 0 or timeout.
|
||||
// thrsleep unlocks m->waitsemalock.
|
||||
if(ns < 0)
|
||||
runtime·thrsleep(&m->waitsemacount, 0, nil, &m->waitsemalock);
|
||||
else {
|
||||
ns += runtime·nanotime();
|
||||
ts.tv_sec = ns/1000000000LL;
|
||||
ts.tv_nsec = ns%1000000000LL;
|
||||
runtime·thrsleep(&m->waitsemacount, CLOCK_REALTIME, &ts, &m->waitsemalock);
|
||||
}
|
||||
// reacquire lock
|
||||
while(runtime·xchg(&m->waitsemalock, 1))
|
||||
runtime·osyield();
|
||||
}
|
||||
|
||||
// lock held (again)
|
||||
if(m->waitsemacount != 0) {
|
||||
// semaphore is available.
|
||||
m->waitsemacount--;
|
||||
// spin-mutex unlock
|
||||
runtime·atomicstore(&m->waitsemalock, 0);
|
||||
return 0; // semaphore acquired
|
||||
}
|
||||
|
||||
// semaphore not available.
|
||||
// if there is a timeout, stop now.
|
||||
// otherwise keep trying.
|
||||
if(ns >= 0)
|
||||
break;
|
||||
}
|
||||
|
||||
// lock held but giving up
|
||||
// spin-mutex unlock
|
||||
runtime·atomicstore(&m->waitsemalock, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
runtime·semawakeup(M *mp)
|
||||
{
|
||||
uint32 ret;
|
||||
|
||||
// spin-mutex lock
|
||||
while(runtime·xchg(&mp->waitsemalock, 1))
|
||||
runtime·osyield();
|
||||
mp->waitsemacount++;
|
||||
ret = runtime·thrwakeup(&mp->waitsemacount, 1);
|
||||
if(ret != 0 && ret != ESRCH)
|
||||
runtime·printf("thrwakeup addr=%p sem=%d ret=%d\n", &mp->waitsemacount, mp->waitsemacount, ret);
|
||||
// spin-mutex unlock
|
||||
runtime·atomicstore(&mp->waitsemalock, 0);
|
||||
}
|
||||
|
||||
// From NetBSD's sys/param.h
|
||||
#define RFPROC (1<<4) /* change child (else changes curproc) */
|
||||
#define RFMEM (1<<5) /* share `address space' */
|
||||
#define RFNOWAIT (1<<6) /* parent need not wait() on child */
|
||||
#define RFTHREAD (1<<13) /* create a thread, not a process */
|
||||
|
||||
void
|
||||
runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void))
|
||||
{
|
||||
int32 flags;
|
||||
int32 ret;
|
||||
|
||||
flags = RFPROC | RFTHREAD | RFMEM | RFNOWAIT;
|
||||
|
||||
if (0) {
|
||||
runtime·printf(
|
||||
"newosproc stk=%p m=%p g=%p fn=%p id=%d/%d ostk=%p\n",
|
||||
stk, m, g, fn, m->id, m->tls[0], &m);
|
||||
}
|
||||
|
||||
m->tls[0] = m->id; // so 386 asm can find it
|
||||
|
||||
if((ret = runtime·rfork_thread(flags, stk, m, g, fn)) < 0) {
|
||||
runtime·printf("runtime: failed to create new OS thread (have %d already; errno=%d)\n", runtime·mcount() - 1, -ret);
|
||||
if (ret == -ENOTSUP)
|
||||
runtime·printf("runtime: is kern.rthreads disabled?\n");
|
||||
runtime·throw("runtime.newosproc");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
runtime·osinit(void)
|
||||
{
|
||||
runtime·ncpu = getncpu();
|
||||
}
|
||||
|
||||
void
|
||||
runtime·goenvs(void)
|
||||
{
|
||||
runtime·goenvs_unix();
|
||||
}
|
||||
|
||||
// Called to initialize a new m (including the bootstrap m).
|
||||
void
|
||||
runtime·minit(void)
|
||||
{
|
||||
// Initialize signal handling
|
||||
m->gsignal = runtime·malg(32*1024);
|
||||
runtime·signalstack(m->gsignal->stackguard - StackGuard, 32*1024);
|
||||
}
|
||||
|
||||
void
|
||||
runtime·sigpanic(void)
|
||||
{
|
||||
switch(g->sig) {
|
||||
case SIGBUS:
|
||||
if(g->sigcode0 == BUS_ADRERR && g->sigcode1 < 0x1000)
|
||||
runtime·panicstring("invalid memory address or nil pointer dereference");
|
||||
runtime·printf("unexpected fault address %p\n", g->sigcode1);
|
||||
runtime·throw("fault");
|
||||
case SIGSEGV:
|
||||
if((g->sigcode0 == 0 || g->sigcode0 == SEGV_MAPERR || g->sigcode0 == SEGV_ACCERR) && g->sigcode1 < 0x1000)
|
||||
runtime·panicstring("invalid memory address or nil pointer dereference");
|
||||
runtime·printf("unexpected fault address %p\n", g->sigcode1);
|
||||
runtime·throw("fault");
|
||||
case SIGFPE:
|
||||
switch(g->sigcode0) {
|
||||
case FPE_INTDIV:
|
||||
runtime·panicstring("integer divide by zero");
|
||||
case FPE_INTOVF:
|
||||
runtime·panicstring("integer overflow");
|
||||
}
|
||||
runtime·panicstring("floating point error");
|
||||
}
|
||||
runtime·panicstring(runtime·sigtab[g->sig].name);
|
||||
}
|
Loading…
Reference in New Issue
Block a user