diff options
author | David du Colombier <0intro@gmail.com> | 2014-11-21 19:39:01 +0100 |
---|---|---|
committer | David du Colombier <0intro@gmail.com> | 2014-11-21 19:39:01 +0100 |
commit | f5c70e8582808d3372d00cb44f87828b4855ddc7 (patch) | |
tree | 89dd5349e213a3c7662a71d5ba4592358b8bf911 /src/runtime/os_plan9_amd64.go | |
parent | ecbbc98fca8ef53f6b63083a00372b0a5f38f420 (diff) | |
download | go-f5c70e8582808d3372d00cb44f87828b4855ddc7.tar.gz |
[dev.cc] runtime: convert Plan 9 port to Go
Thanks to Aram H?v?rneanu, Nick Owens
and Russ Cox for the early reviews.
LGTM=aram, rsc
R=rsc, lucio.dere, aram, ality
CC=golang-codereviews, mischief
https://codereview.appspot.com/175370043
Diffstat (limited to 'src/runtime/os_plan9_amd64.go')
-rw-r--r-- | src/runtime/os_plan9_amd64.go | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/src/runtime/os_plan9_amd64.go b/src/runtime/os_plan9_amd64.go new file mode 100644 index 000000000..8727dcc20 --- /dev/null +++ b/src/runtime/os_plan9_amd64.go @@ -0,0 +1,139 @@ +// 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. + +package runtime + +import "unsafe" + +func dumpregs(u *ureg) { + print("ax ", hex(u.ax), "\n") + print("bx ", hex(u.bx), "\n") + print("cx ", hex(u.cx), "\n") + print("dx ", hex(u.dx), "\n") + print("di ", hex(u.di), "\n") + print("si ", hex(u.si), "\n") + print("bp ", hex(u.bp), "\n") + print("sp ", hex(u.sp), "\n") + print("r8 ", hex(u.r8), "\n") + print("r9 ", hex(u.r9), "\n") + print("r10 ", hex(u.r10), "\n") + print("r11 ", hex(u.r11), "\n") + print("r12 ", hex(u.r12), "\n") + print("r13 ", hex(u.r13), "\n") + print("r14 ", hex(u.r14), "\n") + print("r15 ", hex(u.r15), "\n") + print("ip ", hex(u.ip), "\n") + print("flags ", hex(u.flags), "\n") + print("cs ", hex(uint64(u.cs)), "\n") + print("fs ", hex(uint64(u.fs)), "\n") + print("gs ", hex(uint64(u.gs)), "\n") +} + +func sighandler(_ureg *ureg, note *byte, gp *g) int { + _g_ := getg() + var t sigTabT + var docrash bool + var length int + var sig int + var flags int + + // The kernel will never pass us a nil note or ureg so we probably + // made a mistake somewhere in sigtramp. + if _ureg == nil || note == nil { + print("sighandler: ureg ", _ureg, " note ", note, "\n") + goto Throw + } + // Check that the note is no more than ERRMAX bytes (including + // the trailing NUL). We should never receive a longer note. + length = findnull(note) + if length > _ERRMAX-1 { + print("sighandler: note is longer than ERRMAX\n") + goto Throw + } + // See if the note matches one of the patterns in sigtab. + // Notes that do not match any pattern can be handled at a higher + // level by the program but will otherwise be ignored. + flags = _SigNotify + for sig, t = range sigtable { + n := len(t.name) + if length < n { + continue + } + if strncmp(note, &t.name[0], uintptr(n)) == 0 { + flags = t.flags + break + } + } + if flags&_SigGoExit != 0 { + exits((*byte)(add(unsafe.Pointer(note), 9))) // Strip "go: exit " prefix. + } + if flags&_SigPanic != 0 { + // Copy the error string from sigtramp's stack into m->notesig so + // we can reliably access it from the panic routines. + memmove(unsafe.Pointer(_g_.m.notesig), unsafe.Pointer(note), uintptr(length+1)) + gp.sig = uint32(sig) + gp.sigpc = uintptr(_ureg.ip) + // Only push sigpanic if PC != 0. + // + // If PC == 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 sigpanic instead. (Otherwise the trace will end at + // sigpanic and we won't get to see who faulted). + if _ureg.ip != 0 { + sp := _ureg.sp + if regSize > ptrSize { + sp -= ptrSize + *(*uintptr)(unsafe.Pointer(uintptr(sp))) = 0 + } + sp -= ptrSize + *(*uintptr)(unsafe.Pointer(uintptr(sp))) = uintptr(_ureg.ip) + _ureg.sp = sp + } + _ureg.ip = uint64(funcPC(sigpanic)) + return _NCONT + } + if flags&_SigNotify != 0 { + // TODO(ality): See if os/signal wants it. + //if(sigsend(...)) + // return _NCONT; + } + if flags&_SigKill != 0 { + goto Exit + } + if flags&_SigThrow == 0 { + return _NCONT + } +Throw: + _g_.m.throwing = 1 + _g_.m.caughtsig = gp + startpanic() + print(gostringnocopy(note), "\n") + print("PC=", hex(_ureg.ip), "\n") + print("\n") + if gotraceback(&docrash) > 0 { + goroutineheader(gp) + tracebacktrap(uintptr(_ureg.ip), uintptr(_ureg.sp), 0, gp) + tracebackothers(gp) + print("\n") + dumpregs(_ureg) + } + if docrash { + crash() + } +Exit: + goexitsall(note) + exits(note) + return _NDFLT // not reached +} + +func sigenable(sig uint32) { +} + +func sigdisable(sig uint32) { +} + +func resetcpuprofiler(hz int32) { + // TODO: Enable profiling interrupts. + getg().m.profilehz = hz +} |