OSDN Git Service

runtime, runtime/pprof: Fix runtime/pprof test to pass, enable it.
[pf3gnuchains/gcc-fork.git] / libgo / runtime / go-caller.c
1 /* go-caller.c -- runtime.Caller and runtime.FuncForPC for Go.
2
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.  */
6
7 /* Implement runtime.Caller.  */
8
9 #include <stdint.h>
10
11 #include "runtime.h"
12 #include "go-string.h"
13
14 /* Get the function name, file name, and line number for a PC value.
15    We use the DWARF debug information to get this.  Rather than write
16    a whole new library in C, we use the existing Go library.
17    Unfortunately, the Go library is only available if the debug/elf
18    package is imported (we use debug/elf for both ELF and Mach-O, in
19    this case).  We arrange for the debug/elf package to register
20    itself, and tweak the various packages that need this information
21    to import debug/elf where possible.  */
22
23 /* The function that returns function/file/line information.  */
24
25 typedef _Bool (*infofn_type) (uintptr_t, struct __go_string *,
26                               struct __go_string *, int *);
27 static infofn_type infofn;
28
29 /* The function that returns the value of a symbol, used to get the
30    entry address of a function.  */
31
32 typedef _Bool (*symvalfn_type) (struct __go_string, uintptr_t *);
33 static symvalfn_type symvalfn;
34
35 /* This is called by debug/elf to register the function that returns
36    function/file/line information.  */
37
38 void RegisterDebugLookup (infofn_type, symvalfn_type)
39   __asm__ ("runtime.RegisterDebugLookup");
40
41 void
42 RegisterDebugLookup (infofn_type pi, symvalfn_type ps)
43 {
44   infofn = pi;
45   symvalfn = ps;
46 }
47
48 /* Return function/file/line information for PC.  */
49
50 _Bool
51 __go_file_line (uintptr pc, struct __go_string *fn, struct __go_string *file,
52                 int *line)
53 {
54   if (infofn == NULL)
55     return 0;
56   return infofn (pc, fn, file, line);
57 }
58
59 /* Return the value of a symbol.  */
60
61 _Bool
62 __go_symbol_value (struct __go_string sym, uintptr_t *val)
63 {
64   if (symvalfn == NULL)
65     return 0;
66   return symvalfn (sym, val);
67 }
68
69 /* The values returned by runtime.Caller.  */
70
71 struct caller_ret
72 {
73   uintptr_t pc;
74   struct __go_string file;
75   int line;
76   _Bool ok;
77 };
78
79 struct caller_ret Caller (int n) asm ("runtime.Caller");
80
81 Func *FuncForPC (uintptr_t) asm ("runtime.FuncForPC");
82
83 /* Implement runtime.Caller.  */
84
85 struct caller_ret
86 Caller (int skip)
87 {
88   struct caller_ret ret;
89   uintptr pc;
90   int32 n;
91   struct __go_string fn;
92
93   runtime_memclr (&ret, sizeof ret);
94   n = runtime_callers (skip + 1, &pc, 1);
95   if (n < 1)
96     return ret;
97   ret.pc = pc;
98   ret.ok = __go_file_line (pc, &fn, &ret.file, &ret.line);
99   return ret;
100 }
101
102 /* Implement runtime.FuncForPC.  */
103
104 Func *
105 FuncForPC (uintptr_t pc)
106 {
107   Func *ret;
108   struct __go_string fn;
109   struct __go_string file;
110   int line;
111   uintptr_t val;
112
113   if (!__go_file_line (pc, &fn, &file, &line))
114     return NULL;
115   if (!__go_symbol_value (fn, &val))
116     return NULL;
117
118   ret = (Func *) runtime_malloc (sizeof (*ret));
119   ret->name = fn;
120   ret->entry = val;
121   return ret;
122 }
123
124 /* Look up the file and line information for a PC within a
125    function.  */
126
127 struct funcline_go_return
128 {
129   struct __go_string retfile;
130   int retline;
131 };
132
133 struct funcline_go_return
134 runtime_funcline_go (Func *f, uintptr targetpc)
135   __asm__ ("runtime.funcline_go");
136
137 struct funcline_go_return
138 runtime_funcline_go (Func *f __attribute__((unused)), uintptr targetpc)
139 {
140   struct funcline_go_return ret;
141   struct __go_string fn;
142
143   if (!__go_file_line (targetpc, &fn, &ret.retfile,  &ret.retline))
144     runtime_memclr (&ret, sizeof ret);
145   return ret;
146 }