1 /* go-caller.c -- runtime.Caller and runtime.FuncForPC for Go.
3 Copyright 2009 The Go Authors. All rights reserved.
4 Use of this source code is governed by a BSD-style
5 license that can be found in the LICENSE file. */
7 /* Implement runtime.Caller. */
11 #include "backtrace.h"
14 #include "go-string.h"
16 /* Get the function name, file name, and line number for a PC value.
17 We use the backtrace library to get this. */
19 /* Data structure to gather file/line information. */
23 struct __go_string fn
;
24 struct __go_string file
;
28 /* Collect file/line information for a PC value. If this is called
29 more than once, due to inlined functions, we use the last call, as
30 that is usually the most useful one. */
33 callback (void *data
, uintptr_t pc
__attribute__ ((unused
)),
34 const char *filename
, int lineno
, const char *function
)
36 struct caller
*c
= (struct caller
*) data
;
47 c
->fn
.__length
= __builtin_strlen (function
);
48 s
= runtime_malloc (c
->fn
.__length
);
49 __builtin_memcpy (s
, function
, c
->fn
.__length
);
50 c
->fn
.__data
= (unsigned char *) s
;
55 c
->file
.__data
= NULL
;
62 c
->file
.__length
= __builtin_strlen (filename
);
63 s
= runtime_malloc (c
->file
.__length
);
64 __builtin_memcpy (s
, filename
, c
->file
.__length
);
65 c
->file
.__data
= (unsigned char *) s
;
73 /* The error callback for backtrace_pcinfo and backtrace_syminfo. */
76 error_callback (void *data
__attribute__ ((unused
)),
77 const char *msg
, int errnum
)
82 runtime_printf ("%s errno %d\n", msg
, errnum
);
86 /* The backtrace library state. */
88 static void *back_state
;
90 /* A lock to control creating back_state. */
92 static Lock back_state_lock
;
94 /* Fetch back_state, creating it if necessary. */
96 struct backtrace_state
*
97 __go_get_backtrace_state ()
99 runtime_lock (&back_state_lock
);
100 if (back_state
== NULL
)
101 back_state
= backtrace_create_state (NULL
, 1, error_callback
, NULL
);
102 runtime_unlock (&back_state_lock
);
106 /* Return function/file/line information for PC. */
109 __go_file_line (uintptr pc
, struct __go_string
*fn
, struct __go_string
*file
,
114 runtime_memclr (&c
, sizeof c
);
115 backtrace_pcinfo (__go_get_backtrace_state (), pc
, callback
,
120 return c
.file
.__length
> 0;
123 /* Collect symbol information. */
126 syminfo_callback (void *data
, uintptr_t pc
__attribute__ ((unused
)),
127 const char *symname
__attribute__ ((unused
)),
130 uintptr_t *pval
= (uintptr_t *) data
;
135 /* Set *VAL to the value of the symbol for PC. */
138 __go_symbol_value (uintptr_t pc
, uintptr_t *val
)
141 backtrace_syminfo (__go_get_backtrace_state (), pc
, syminfo_callback
,
142 error_callback
, &val
);
146 /* The values returned by runtime.Caller. */
151 struct __go_string file
;
156 struct caller_ret
Caller (int n
) asm ("runtime.Caller");
158 Func
*FuncForPC (uintptr_t) asm ("runtime.FuncForPC");
160 /* Implement runtime.Caller. */
165 struct caller_ret ret
;
168 struct __go_string fn
;
170 runtime_memclr (&ret
, sizeof ret
);
171 n
= runtime_callers (skip
+ 1, &pc
, 1);
175 __go_file_line (pc
, &fn
, &ret
.file
, &ret
.line
);
180 /* Implement runtime.FuncForPC. */
183 FuncForPC (uintptr_t pc
)
186 struct __go_string fn
;
187 struct __go_string file
;
191 if (!__go_file_line (pc
, &fn
, &file
, &line
))
194 ret
= (Func
*) runtime_malloc (sizeof (*ret
));
197 if (__go_symbol_value (pc
, &val
))
205 /* Look up the file and line information for a PC within a
208 struct funcline_go_return
210 struct __go_string retfile
;
214 struct funcline_go_return
215 runtime_funcline_go (Func
*f
, uintptr targetpc
)
216 __asm__ ("runtime.funcline_go");
218 struct funcline_go_return
219 runtime_funcline_go (Func
*f
__attribute__((unused
)), uintptr targetpc
)
221 struct funcline_go_return ret
;
222 struct __go_string fn
;
224 if (!__go_file_line (targetpc
, &fn
, &ret
.retfile
, &ret
.retline
))
225 runtime_memclr (&ret
, sizeof ret
);