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"
15 /* Get the function name, file name, and line number for a PC value.
16 We use the backtrace library to get this. */
18 /* Data structure to gather file/line information. */
27 /* Collect file/line information for a PC value. If this is called
28 more than once, due to inlined functions, we use the last call, as
29 that is usually the most useful one. */
32 callback (void *data
, uintptr_t pc
__attribute__ ((unused
)),
33 const char *filename
, int lineno
, const char *function
)
35 struct caller
*c
= (struct caller
*) data
;
46 c
->fn
.len
= __builtin_strlen (function
);
47 s
= runtime_malloc (c
->fn
.len
);
48 __builtin_memcpy (s
, function
, c
->fn
.len
);
61 c
->file
.len
= __builtin_strlen (filename
);
62 s
= runtime_malloc (c
->file
.len
);
63 __builtin_memcpy (s
, filename
, c
->file
.len
);
72 /* The error callback for backtrace_pcinfo and backtrace_syminfo. */
75 error_callback (void *data
__attribute__ ((unused
)),
76 const char *msg
, int errnum
)
81 runtime_printf ("%s errno %d\n", msg
, errnum
);
85 /* The backtrace library state. */
87 static void *back_state
;
89 /* A lock to control creating back_state. */
91 static Lock back_state_lock
;
93 /* Fetch back_state, creating it if necessary. */
95 struct backtrace_state
*
96 __go_get_backtrace_state ()
98 runtime_lock (&back_state_lock
);
99 if (back_state
== NULL
)
101 const char *filename
;
103 filename
= (const char *) runtime_progname ();
104 back_state
= backtrace_create_state (filename
, 1, error_callback
, NULL
);
106 runtime_unlock (&back_state_lock
);
110 /* Return function/file/line information for PC. */
113 __go_file_line (uintptr pc
, String
*fn
, String
*file
, intgo
*line
)
117 runtime_memclr (&c
, sizeof c
);
118 backtrace_pcinfo (__go_get_backtrace_state (), pc
, callback
,
123 return c
.file
.len
> 0;
126 /* Collect symbol information. */
129 syminfo_callback (void *data
, uintptr_t pc
__attribute__ ((unused
)),
130 const char *symname
__attribute__ ((unused
)),
133 uintptr_t *pval
= (uintptr_t *) data
;
138 /* Set *VAL to the value of the symbol for PC. */
141 __go_symbol_value (uintptr_t pc
, uintptr_t *val
)
144 backtrace_syminfo (__go_get_backtrace_state (), pc
, syminfo_callback
,
145 error_callback
, val
);
149 /* The values returned by runtime.Caller. */
159 struct caller_ret
Caller (int n
) __asm__ (GOSYM_PREFIX
"runtime.Caller");
161 Func
*FuncForPC (uintptr_t) __asm__ (GOSYM_PREFIX
"runtime.FuncForPC");
163 /* Implement runtime.Caller. */
168 struct caller_ret ret
;
172 runtime_memclr (&ret
, sizeof ret
);
173 n
= runtime_callers (skip
+ 1, &loc
, 1);
177 ret
.file
= loc
.filename
;
178 ret
.line
= loc
.lineno
;
183 /* Implement runtime.FuncForPC. */
186 FuncForPC (uintptr_t pc
)
194 if (!__go_file_line (pc
, &fn
, &file
, &line
))
197 ret
= (Func
*) runtime_malloc (sizeof (*ret
));
200 if (__go_symbol_value (pc
, &val
))
208 /* Look up the file and line information for a PC within a
211 struct funcline_go_return
217 struct funcline_go_return
218 runtime_funcline_go (Func
*f
, uintptr targetpc
)
219 __asm__ (GOSYM_PREFIX
"runtime.funcline_go");
221 struct funcline_go_return
222 runtime_funcline_go (Func
*f
__attribute__((unused
)), uintptr targetpc
)
224 struct funcline_go_return ret
;
227 if (!__go_file_line (targetpc
, &fn
, &ret
.retfile
, &ret
.retline
))
228 runtime_memclr (&ret
, sizeof ret
);