mirror of
https://github.com/golang/go
synced 2024-11-21 21:04:41 -07:00
runtime: add runtime support for openbsd 386
Add openbsd 386 runtime support, partially based on the existing freebsd 386 runtime. This requires change 4973043. R=golang-dev, rsc CC=golang-dev https://golang.org/cl/4951043
This commit is contained in:
parent
c20a338c2f
commit
9ef17990c2
6
src/pkg/runtime/openbsd/386/rt0.s
Normal file
6
src/pkg/runtime/openbsd/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_openbsd(SB),7,$0
|
||||
JMP _rt0_386(SB)
|
189
src/pkg/runtime/openbsd/386/signal.c
Normal file
189
src/pkg/runtime/openbsd/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();
|
||||
}
|
254
src/pkg/runtime/openbsd/386/sys.s
Normal file
254
src/pkg/runtime/openbsd/386/sys.s
Normal file
@ -0,0 +1,254 @@
|
||||
// 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, OpenBSD
|
||||
// /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·raisesigpipe(SB),7,$12
|
||||
MOVL $299, AX // sys_getthrid
|
||||
INT $80
|
||||
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
|
||||
|
||||
TEXT runtime·gettime(SB),7,$32
|
||||
MOVL $116, AX
|
||||
LEAL 12(SP), BX
|
||||
MOVL BX, 4(SP)
|
||||
MOVL $0, 8(SP)
|
||||
INT $0x80
|
||||
|
||||
MOVL 12(SP), BX // sec
|
||||
MOVL sec+0(FP), DI
|
||||
MOVL BX, (DI)
|
||||
MOVL $0, 4(DI) // zero extend 32 -> 64 bits
|
||||
|
||||
MOVL 16(SP), BX // usec
|
||||
MOVL usec+4(FP), DI
|
||||
MOVL BX, (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 OpenBSD 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
|
||||
|
||||
GLOBL runtime·tlsoffset(SB),$4
|
@ -14,7 +14,6 @@
|
||||
#include <sys/time.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/signal.h>
|
||||
#include <machine/mcontext.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
|
||||
@ -97,7 +96,8 @@ typedef stack_t $StackT;
|
||||
typedef struct timeval $Timeval;
|
||||
typedef struct itimerval $Itimerval;
|
||||
|
||||
// This is a hack to avoid pulling in machine/fpu.h and struct fxsave64.
|
||||
// This is a hack to avoid pulling in machine/fpu.h.
|
||||
typedef void $sfxsave64;
|
||||
typedef void $usavefpu;
|
||||
|
||||
typedef struct sigcontext $Sigcontext;
|
||||
|
@ -3,6 +3,11 @@
|
||||
#include "os.h"
|
||||
#include "malloc.h"
|
||||
|
||||
enum
|
||||
{
|
||||
ENOMEM = 12,
|
||||
};
|
||||
|
||||
void*
|
||||
runtime·SysAlloc(uintptr n)
|
||||
{
|
||||
@ -33,20 +38,21 @@ runtime·SysFree(void *v, uintptr 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;
|
||||
|
||||
return runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
|
||||
p = runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
|
||||
if (p == ((void *)-ENOMEM))
|
||||
return nil;
|
||||
else
|
||||
return p;
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
ENOMEM = 12,
|
||||
};
|
||||
|
||||
void
|
||||
runtime·SysMap(void *v, uintptr n)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user