]> Cypherpunks.ru repositories - gostls13.git/blob - src/runtime/os3_plan9.go
cmd/compile/internal/inline: score call sites exposed by inlines
[gostls13.git] / src / runtime / os3_plan9.go
1 // Copyright 2010 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package runtime
6
7 import (
8         "internal/abi"
9         "internal/goarch"
10         "unsafe"
11 )
12
13 // May run during STW, so write barriers are not allowed.
14 //
15 //go:nowritebarrierrec
16 func sighandler(_ureg *ureg, note *byte, gp *g) int {
17         gsignal := getg()
18         mp := gsignal.m
19
20         var t sigTabT
21         var docrash bool
22         var sig int
23         var flags int
24         var level int32
25
26         c := &sigctxt{_ureg}
27         notestr := gostringnocopy(note)
28
29         // The kernel will never pass us a nil note or ureg so we probably
30         // made a mistake somewhere in sigtramp.
31         if _ureg == nil || note == nil {
32                 print("sighandler: ureg ", _ureg, " note ", note, "\n")
33                 goto Throw
34         }
35         // Check that the note is no more than ERRMAX bytes (including
36         // the trailing NUL). We should never receive a longer note.
37         if len(notestr) > _ERRMAX-1 {
38                 print("sighandler: note is longer than ERRMAX\n")
39                 goto Throw
40         }
41         if isAbortPC(c.pc()) {
42                 // Never turn abort into a panic.
43                 goto Throw
44         }
45         // See if the note matches one of the patterns in sigtab.
46         // Notes that do not match any pattern can be handled at a higher
47         // level by the program but will otherwise be ignored.
48         flags = _SigNotify
49         for sig, t = range sigtable {
50                 if hasPrefix(notestr, t.name) {
51                         flags = t.flags
52                         break
53                 }
54         }
55         if flags&_SigPanic != 0 && gp.throwsplit {
56                 // We can't safely sigpanic because it may grow the
57                 // stack. Abort in the signal handler instead.
58                 flags = (flags &^ _SigPanic) | _SigThrow
59         }
60         if flags&_SigGoExit != 0 {
61                 exits((*byte)(add(unsafe.Pointer(note), 9))) // Strip "go: exit " prefix.
62         }
63         if flags&_SigPanic != 0 {
64                 // Copy the error string from sigtramp's stack into m->notesig so
65                 // we can reliably access it from the panic routines.
66                 memmove(unsafe.Pointer(mp.notesig), unsafe.Pointer(note), uintptr(len(notestr)+1))
67                 gp.sig = uint32(sig)
68                 gp.sigpc = c.pc()
69
70                 pc := c.pc()
71                 sp := c.sp()
72
73                 // If we don't recognize the PC as code
74                 // but we do recognize the top pointer on the stack as code,
75                 // then assume this was a call to non-code and treat like
76                 // pc == 0, to make unwinding show the context.
77                 if pc != 0 && !findfunc(pc).valid() && findfunc(*(*uintptr)(unsafe.Pointer(sp))).valid() {
78                         pc = 0
79                 }
80
81                 // IF LR exists, sigpanictramp must save it to the stack
82                 // before entry to sigpanic so that panics in leaf
83                 // functions are correctly handled. This will smash
84                 // the stack frame but we're not going back there
85                 // anyway.
86                 if usesLR {
87                         c.savelr(c.lr())
88                 }
89
90                 // If PC == 0, probably panicked because of a call to a nil func.
91                 // Not faking that as the return address will make the trace look like a call
92                 // to sigpanic instead. (Otherwise the trace will end at
93                 // sigpanic and we won't get to see who faulted).
94                 if pc != 0 {
95                         if usesLR {
96                                 c.setlr(pc)
97                         } else {
98                                 sp -= goarch.PtrSize
99                                 *(*uintptr)(unsafe.Pointer(sp)) = pc
100                                 c.setsp(sp)
101                         }
102                 }
103                 if usesLR {
104                         c.setpc(abi.FuncPCABI0(sigpanictramp))
105                 } else {
106                         c.setpc(abi.FuncPCABI0(sigpanic0))
107                 }
108                 return _NCONT
109         }
110         if flags&_SigNotify != 0 {
111                 if ignoredNote(note) {
112                         return _NCONT
113                 }
114                 if sendNote(note) {
115                         return _NCONT
116                 }
117         }
118         if flags&_SigKill != 0 {
119                 goto Exit
120         }
121         if flags&_SigThrow == 0 {
122                 return _NCONT
123         }
124 Throw:
125         mp.throwing = throwTypeRuntime
126         mp.caughtsig.set(gp)
127         startpanic_m()
128         print(notestr, "\n")
129         print("PC=", hex(c.pc()), "\n")
130         print("\n")
131         level, _, docrash = gotraceback()
132         if level > 0 {
133                 goroutineheader(gp)
134                 tracebacktrap(c.pc(), c.sp(), c.lr(), gp)
135                 tracebackothers(gp)
136                 print("\n")
137                 dumpregs(_ureg)
138         }
139         if docrash {
140                 crash()
141         }
142 Exit:
143         goexitsall(note)
144         exits(note)
145         return _NDFLT // not reached
146 }
147
148 func sigenable(sig uint32) {
149 }
150
151 func sigdisable(sig uint32) {
152 }
153
154 func sigignore(sig uint32) {
155 }
156
157 func setProcessCPUProfiler(hz int32) {
158 }
159
160 func setThreadCPUProfiler(hz int32) {
161         // TODO: Enable profiling interrupts.
162         getg().m.profilehz = hz
163 }
164
165 // gsignalStack is unused on Plan 9.
166 type gsignalStack struct{}