@@ -6,48 +6,74 @@ package runtime
6
6
7
7
import "unsafe"
8
8
9
+ // Call fn with arg as its argument. Return what fn returns.
10
+ // fn is the raw pc value of the entry point of the desired function.
11
+ // Switches to the system stack, if not already there.
12
+ // Preserves the calling point as the location where a profiler traceback will begin.
13
+ //go:nosplit
14
+ func libcCall (fn , arg unsafe.Pointer ) int32 {
15
+ // Leave caller's PC/SP/G around for traceback.
16
+ gp := getg ()
17
+ var mp * m
18
+ if gp != nil {
19
+ mp = gp .m
20
+ }
21
+ if mp != nil {
22
+ mp .libcallg .set (gp )
23
+ mp .libcallpc = getcallerpc ()
24
+ // sp must be the last, because once async cpu profiler finds
25
+ // all three values to be non-zero, it will use them
26
+ mp .libcallsp = getcallersp ()
27
+ }
28
+ res := asmcgocall (fn , arg )
29
+ if mp != nil {
30
+ mp .libcallsp = 0
31
+ }
32
+ return res
33
+ }
34
+
9
35
// The *_trampoline functions convert from the Go calling convention to the C calling convention
10
36
// and then call the underlying libc function. They are defined in sys_darwin_$ARCH.s.
11
37
12
38
//go:nosplit
13
39
//go:cgo_unsafe_args
14
40
func pthread_attr_init (attr * pthreadattr ) int32 {
15
- return asmcgocall (unsafe .Pointer (funcPC (pthread_attr_init_trampoline )), unsafe .Pointer (& attr ))
41
+ return libcCall (unsafe .Pointer (funcPC (pthread_attr_init_trampoline )), unsafe .Pointer (& attr ))
16
42
}
17
43
func pthread_attr_init_trampoline ()
18
44
19
45
//go:nosplit
20
46
//go:cgo_unsafe_args
21
47
func pthread_attr_setstacksize (attr * pthreadattr , size uintptr ) int32 {
22
- return asmcgocall (unsafe .Pointer (funcPC (pthread_attr_setstacksize_trampoline )), unsafe .Pointer (& attr ))
48
+ return libcCall (unsafe .Pointer (funcPC (pthread_attr_setstacksize_trampoline )), unsafe .Pointer (& attr ))
23
49
}
24
50
func pthread_attr_setstacksize_trampoline ()
25
51
26
52
//go:nosplit
27
53
//go:cgo_unsafe_args
28
54
func pthread_attr_setdetachstate (attr * pthreadattr , state int ) int32 {
29
- return asmcgocall (unsafe .Pointer (funcPC (pthread_attr_setdetachstate_trampoline )), unsafe .Pointer (& attr ))
55
+ return libcCall (unsafe .Pointer (funcPC (pthread_attr_setdetachstate_trampoline )), unsafe .Pointer (& attr ))
30
56
}
31
57
func pthread_attr_setdetachstate_trampoline ()
32
58
33
59
//go:nosplit
34
60
//go:cgo_unsafe_args
35
61
func pthread_create (attr * pthreadattr , start uintptr , arg unsafe.Pointer ) int32 {
36
- return asmcgocall (unsafe .Pointer (funcPC (pthread_create_trampoline )), unsafe .Pointer (& attr ))
62
+ return libcCall (unsafe .Pointer (funcPC (pthread_create_trampoline )), unsafe .Pointer (& attr ))
37
63
}
38
64
func pthread_create_trampoline ()
39
65
40
66
//go:nosplit
41
67
//go:cgo_unsafe_args
42
68
func raise (sig uint32 ) {
43
- asmcgocall (unsafe .Pointer (funcPC (raise_trampoline )), unsafe .Pointer (& sig ))
69
+ libcCall (unsafe .Pointer (funcPC (raise_trampoline )), unsafe .Pointer (& sig ))
44
70
}
45
71
func raise_trampoline ()
46
72
47
73
//go:nosplit
48
74
//go:cgo_unsafe_args
49
75
func pthread_self () (t pthread ) {
50
- asmcgocall (unsafe .Pointer (funcPC (pthread_self_trampoline )), unsafe .Pointer (& t ))
76
+ libcCall (unsafe .Pointer (funcPC (pthread_self_trampoline )), unsafe .Pointer (& t ))
51
77
return
52
78
}
53
79
func pthread_self_trampoline ()
@@ -61,64 +87,64 @@ func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) (un
61
87
ret1 unsafe.Pointer
62
88
ret2 int
63
89
}{addr , n , prot , flags , fd , off , nil , 0 }
64
- asmcgocall (unsafe .Pointer (funcPC (mmap_trampoline )), unsafe .Pointer (& args ))
90
+ libcCall (unsafe .Pointer (funcPC (mmap_trampoline )), unsafe .Pointer (& args ))
65
91
return args .ret1 , args .ret2
66
92
}
67
93
func mmap_trampoline ()
68
94
69
95
//go:nosplit
70
96
//go:cgo_unsafe_args
71
97
func munmap (addr unsafe.Pointer , n uintptr ) {
72
- asmcgocall (unsafe .Pointer (funcPC (munmap_trampoline )), unsafe .Pointer (& addr ))
98
+ libcCall (unsafe .Pointer (funcPC (munmap_trampoline )), unsafe .Pointer (& addr ))
73
99
}
74
100
func munmap_trampoline ()
75
101
76
102
//go:nosplit
77
103
//go:cgo_unsafe_args
78
104
func madvise (addr unsafe.Pointer , n uintptr , flags int32 ) {
79
- asmcgocall (unsafe .Pointer (funcPC (madvise_trampoline )), unsafe .Pointer (& addr ))
105
+ libcCall (unsafe .Pointer (funcPC (madvise_trampoline )), unsafe .Pointer (& addr ))
80
106
}
81
107
func madvise_trampoline ()
82
108
83
109
//go:nosplit
84
110
//go:cgo_unsafe_args
85
111
func read (fd int32 , p unsafe.Pointer , n int32 ) int32 {
86
- return asmcgocall (unsafe .Pointer (funcPC (read_trampoline )), unsafe .Pointer (& fd ))
112
+ return libcCall (unsafe .Pointer (funcPC (read_trampoline )), unsafe .Pointer (& fd ))
87
113
}
88
114
func read_trampoline ()
89
115
90
116
//go:nosplit
91
117
//go:cgo_unsafe_args
92
118
func closefd (fd int32 ) int32 {
93
- return asmcgocall (unsafe .Pointer (funcPC (close_trampoline )), unsafe .Pointer (& fd ))
119
+ return libcCall (unsafe .Pointer (funcPC (close_trampoline )), unsafe .Pointer (& fd ))
94
120
}
95
121
func close_trampoline ()
96
122
97
123
//go:nosplit
98
124
//go:cgo_unsafe_args
99
125
func exit (code int32 ) {
100
- asmcgocall (unsafe .Pointer (funcPC (exit_trampoline )), unsafe .Pointer (& code ))
126
+ libcCall (unsafe .Pointer (funcPC (exit_trampoline )), unsafe .Pointer (& code ))
101
127
}
102
128
func exit_trampoline ()
103
129
104
130
//go:nosplit
105
131
//go:cgo_unsafe_args
106
132
func usleep (usec uint32 ) {
107
- asmcgocall (unsafe .Pointer (funcPC (usleep_trampoline )), unsafe .Pointer (& usec ))
133
+ libcCall (unsafe .Pointer (funcPC (usleep_trampoline )), unsafe .Pointer (& usec ))
108
134
}
109
135
func usleep_trampoline ()
110
136
111
137
//go:nosplit
112
138
//go:cgo_unsafe_args
113
139
func write (fd uintptr , p unsafe.Pointer , n int32 ) int32 {
114
- return asmcgocall (unsafe .Pointer (funcPC (write_trampoline )), unsafe .Pointer (& fd ))
140
+ return libcCall (unsafe .Pointer (funcPC (write_trampoline )), unsafe .Pointer (& fd ))
115
141
}
116
142
func write_trampoline ()
117
143
118
144
//go:nosplit
119
145
//go:cgo_unsafe_args
120
146
func open (name * byte , mode , perm int32 ) (ret int32 ) {
121
- return asmcgocall (unsafe .Pointer (funcPC (open_trampoline )), unsafe .Pointer (& name ))
147
+ return libcCall (unsafe .Pointer (funcPC (open_trampoline )), unsafe .Pointer (& name ))
122
148
}
123
149
func open_trampoline ()
124
150
@@ -129,7 +155,7 @@ func nanotime() int64 {
129
155
t int64 // raw timer
130
156
numer , denom uint32 // conversion factors. nanoseconds = t * numer / denom.
131
157
}
132
- asmcgocall (unsafe .Pointer (funcPC (nanotime_trampoline )), unsafe .Pointer (& r ))
158
+ libcCall (unsafe .Pointer (funcPC (nanotime_trampoline )), unsafe .Pointer (& r ))
133
159
// Note: Apple seems unconcerned about overflow here. See
134
160
// https://developer.apple.com/library/content/qa/qa1398/_index.html
135
161
// Note also, numer == denom == 1 is common.
0 commit comments