1*ef5ccd6cSJohn Marino /* Go language support routines for GDB, the GNU debugger.
2*ef5ccd6cSJohn Marino
3*ef5ccd6cSJohn Marino Copyright (C) 2012-2013 Free Software Foundation, Inc.
4*ef5ccd6cSJohn Marino
5*ef5ccd6cSJohn Marino This file is part of GDB.
6*ef5ccd6cSJohn Marino
7*ef5ccd6cSJohn Marino This program is free software; you can redistribute it and/or modify
8*ef5ccd6cSJohn Marino it under the terms of the GNU General Public License as published by
9*ef5ccd6cSJohn Marino the Free Software Foundation; either version 3 of the License, or
10*ef5ccd6cSJohn Marino (at your option) any later version.
11*ef5ccd6cSJohn Marino
12*ef5ccd6cSJohn Marino This program is distributed in the hope that it will be useful,
13*ef5ccd6cSJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
14*ef5ccd6cSJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15*ef5ccd6cSJohn Marino GNU General Public License for more details.
16*ef5ccd6cSJohn Marino
17*ef5ccd6cSJohn Marino You should have received a copy of the GNU General Public License
18*ef5ccd6cSJohn Marino along with this program. If not, see <http://www.gnu.org/licenses/>. */
19*ef5ccd6cSJohn Marino
20*ef5ccd6cSJohn Marino /* TODO:
21*ef5ccd6cSJohn Marino - split stacks
22*ef5ccd6cSJohn Marino - printing of native types
23*ef5ccd6cSJohn Marino - goroutines
24*ef5ccd6cSJohn Marino - lots more
25*ef5ccd6cSJohn Marino - gccgo mangling needs redoing
26*ef5ccd6cSJohn Marino It's too hard, for example, to know whether one is looking at a mangled
27*ef5ccd6cSJohn Marino Go symbol or not, and their are ambiguities, e.g., the demangler may
28*ef5ccd6cSJohn Marino get passed *any* symbol, including symbols from other languages
29*ef5ccd6cSJohn Marino and including symbols that are already demangled.
30*ef5ccd6cSJohn Marino One thought is to at least add an _G prefix.
31*ef5ccd6cSJohn Marino - 6g mangling isn't supported yet
32*ef5ccd6cSJohn Marino */
33*ef5ccd6cSJohn Marino
34*ef5ccd6cSJohn Marino #include "defs.h"
35*ef5ccd6cSJohn Marino #include "gdb_assert.h"
36*ef5ccd6cSJohn Marino #include "gdb_obstack.h"
37*ef5ccd6cSJohn Marino #include "gdb_string.h"
38*ef5ccd6cSJohn Marino #include "block.h"
39*ef5ccd6cSJohn Marino #include "symtab.h"
40*ef5ccd6cSJohn Marino #include "language.h"
41*ef5ccd6cSJohn Marino #include "go-lang.h"
42*ef5ccd6cSJohn Marino #include "c-lang.h"
43*ef5ccd6cSJohn Marino #include "parser-defs.h"
44*ef5ccd6cSJohn Marino
45*ef5ccd6cSJohn Marino #include <ctype.h>
46*ef5ccd6cSJohn Marino
47*ef5ccd6cSJohn Marino /* The main function in the main package. */
48*ef5ccd6cSJohn Marino static const char GO_MAIN_MAIN[] = "main.main";
49*ef5ccd6cSJohn Marino
50*ef5ccd6cSJohn Marino /* Function returning the special symbol name used by Go for the main
51*ef5ccd6cSJohn Marino procedure in the main program if it is found in minimal symbol list.
52*ef5ccd6cSJohn Marino This function tries to find minimal symbols so that it finds them even
53*ef5ccd6cSJohn Marino if the program was compiled without debugging information. */
54*ef5ccd6cSJohn Marino
55*ef5ccd6cSJohn Marino const char *
go_main_name(void)56*ef5ccd6cSJohn Marino go_main_name (void)
57*ef5ccd6cSJohn Marino {
58*ef5ccd6cSJohn Marino struct minimal_symbol *msym;
59*ef5ccd6cSJohn Marino
60*ef5ccd6cSJohn Marino msym = lookup_minimal_symbol (GO_MAIN_MAIN, NULL, NULL);
61*ef5ccd6cSJohn Marino if (msym != NULL)
62*ef5ccd6cSJohn Marino return GO_MAIN_MAIN;
63*ef5ccd6cSJohn Marino
64*ef5ccd6cSJohn Marino /* No known entry procedure found, the main program is probably not Go. */
65*ef5ccd6cSJohn Marino return NULL;
66*ef5ccd6cSJohn Marino }
67*ef5ccd6cSJohn Marino
68*ef5ccd6cSJohn Marino /* Return non-zero if TYPE is a gccgo string.
69*ef5ccd6cSJohn Marino We assume CHECK_TYPEDEF has already been done. */
70*ef5ccd6cSJohn Marino
71*ef5ccd6cSJohn Marino static int
gccgo_string_p(struct type * type)72*ef5ccd6cSJohn Marino gccgo_string_p (struct type *type)
73*ef5ccd6cSJohn Marino {
74*ef5ccd6cSJohn Marino /* gccgo strings don't necessarily have a name we can use. */
75*ef5ccd6cSJohn Marino
76*ef5ccd6cSJohn Marino if (TYPE_NFIELDS (type) == 2)
77*ef5ccd6cSJohn Marino {
78*ef5ccd6cSJohn Marino struct type *type0 = TYPE_FIELD_TYPE (type, 0);
79*ef5ccd6cSJohn Marino struct type *type1 = TYPE_FIELD_TYPE (type, 1);
80*ef5ccd6cSJohn Marino
81*ef5ccd6cSJohn Marino CHECK_TYPEDEF (type0);
82*ef5ccd6cSJohn Marino CHECK_TYPEDEF (type1);
83*ef5ccd6cSJohn Marino
84*ef5ccd6cSJohn Marino if (TYPE_CODE (type0) == TYPE_CODE_PTR
85*ef5ccd6cSJohn Marino && strcmp (TYPE_FIELD_NAME (type, 0), "__data") == 0
86*ef5ccd6cSJohn Marino && TYPE_CODE (type1) == TYPE_CODE_INT
87*ef5ccd6cSJohn Marino && strcmp (TYPE_FIELD_NAME (type, 1), "__length") == 0)
88*ef5ccd6cSJohn Marino {
89*ef5ccd6cSJohn Marino struct type *target_type = TYPE_TARGET_TYPE (type0);
90*ef5ccd6cSJohn Marino
91*ef5ccd6cSJohn Marino CHECK_TYPEDEF (target_type);
92*ef5ccd6cSJohn Marino
93*ef5ccd6cSJohn Marino if (TYPE_CODE (target_type) == TYPE_CODE_INT
94*ef5ccd6cSJohn Marino && TYPE_LENGTH (target_type) == 1
95*ef5ccd6cSJohn Marino && strcmp (TYPE_NAME (target_type), "uint8") == 0)
96*ef5ccd6cSJohn Marino return 1;
97*ef5ccd6cSJohn Marino }
98*ef5ccd6cSJohn Marino }
99*ef5ccd6cSJohn Marino
100*ef5ccd6cSJohn Marino return 0;
101*ef5ccd6cSJohn Marino }
102*ef5ccd6cSJohn Marino
103*ef5ccd6cSJohn Marino /* Return non-zero if TYPE is a 6g string.
104*ef5ccd6cSJohn Marino We assume CHECK_TYPEDEF has already been done. */
105*ef5ccd6cSJohn Marino
106*ef5ccd6cSJohn Marino static int
sixg_string_p(struct type * type)107*ef5ccd6cSJohn Marino sixg_string_p (struct type *type)
108*ef5ccd6cSJohn Marino {
109*ef5ccd6cSJohn Marino if (TYPE_NFIELDS (type) == 2
110*ef5ccd6cSJohn Marino && TYPE_TAG_NAME (type) != NULL
111*ef5ccd6cSJohn Marino && strcmp (TYPE_TAG_NAME (type), "string") == 0)
112*ef5ccd6cSJohn Marino return 1;
113*ef5ccd6cSJohn Marino
114*ef5ccd6cSJohn Marino return 0;
115*ef5ccd6cSJohn Marino }
116*ef5ccd6cSJohn Marino
117*ef5ccd6cSJohn Marino /* Classify the kind of Go object that TYPE is.
118*ef5ccd6cSJohn Marino TYPE is a TYPE_CODE_STRUCT, used to represent a Go object. */
119*ef5ccd6cSJohn Marino
120*ef5ccd6cSJohn Marino enum go_type
go_classify_struct_type(struct type * type)121*ef5ccd6cSJohn Marino go_classify_struct_type (struct type *type)
122*ef5ccd6cSJohn Marino {
123*ef5ccd6cSJohn Marino CHECK_TYPEDEF (type);
124*ef5ccd6cSJohn Marino
125*ef5ccd6cSJohn Marino /* Recognize strings as they're useful to be able to print without
126*ef5ccd6cSJohn Marino pretty-printers. */
127*ef5ccd6cSJohn Marino if (gccgo_string_p (type)
128*ef5ccd6cSJohn Marino || sixg_string_p (type))
129*ef5ccd6cSJohn Marino return GO_TYPE_STRING;
130*ef5ccd6cSJohn Marino
131*ef5ccd6cSJohn Marino return GO_TYPE_NONE;
132*ef5ccd6cSJohn Marino }
133*ef5ccd6cSJohn Marino
134*ef5ccd6cSJohn Marino /* Subroutine of unpack_mangled_go_symbol to simplify it.
135*ef5ccd6cSJohn Marino Given "[foo.]bar.baz", store "bar" in *PACKAGEP and "baz" in *OBJECTP.
136*ef5ccd6cSJohn Marino We stomp on the last '.' to nul-terminate "bar".
137*ef5ccd6cSJohn Marino The caller is responsible for memory management. */
138*ef5ccd6cSJohn Marino
139*ef5ccd6cSJohn Marino static void
unpack_package_and_object(char * buf,const char ** packagep,const char ** objectp)140*ef5ccd6cSJohn Marino unpack_package_and_object (char *buf,
141*ef5ccd6cSJohn Marino const char **packagep, const char **objectp)
142*ef5ccd6cSJohn Marino {
143*ef5ccd6cSJohn Marino char *last_dot;
144*ef5ccd6cSJohn Marino
145*ef5ccd6cSJohn Marino last_dot = strrchr (buf, '.');
146*ef5ccd6cSJohn Marino gdb_assert (last_dot != NULL);
147*ef5ccd6cSJohn Marino *objectp = last_dot + 1;
148*ef5ccd6cSJohn Marino *last_dot = '\0';
149*ef5ccd6cSJohn Marino last_dot = strrchr (buf, '.');
150*ef5ccd6cSJohn Marino if (last_dot != NULL)
151*ef5ccd6cSJohn Marino *packagep = last_dot + 1;
152*ef5ccd6cSJohn Marino else
153*ef5ccd6cSJohn Marino *packagep = buf;
154*ef5ccd6cSJohn Marino }
155*ef5ccd6cSJohn Marino
156*ef5ccd6cSJohn Marino /* Given a mangled Go symbol, find its package name, object name, and
157*ef5ccd6cSJohn Marino method type (if present).
158*ef5ccd6cSJohn Marino E.g., for "libgo_net.textproto.String.N33_libgo_net.textproto.ProtocolError"
159*ef5ccd6cSJohn Marino *PACKAGEP = "textproto"
160*ef5ccd6cSJohn Marino *OBJECTP = "String"
161*ef5ccd6cSJohn Marino *METHOD_TYPE_PACKAGEP = "textproto"
162*ef5ccd6cSJohn Marino *METHOD_TYPE_OBJECTP = "ProtocolError"
163*ef5ccd6cSJohn Marino
164*ef5ccd6cSJohn Marino Space for the resulting strings is malloc'd in one buffer.
165*ef5ccd6cSJohn Marino PACKAGEP,OBJECTP,METHOD_TYPE* will (typically) point into this buffer.
166*ef5ccd6cSJohn Marino [There are a few exceptions, but the caller is still responsible for
167*ef5ccd6cSJohn Marino freeing the resulting pointer.]
168*ef5ccd6cSJohn Marino A pointer to this buffer is returned, or NULL if symbol isn't a
169*ef5ccd6cSJohn Marino mangled Go symbol.
170*ef5ccd6cSJohn Marino The caller is responsible for freeing the result.
171*ef5ccd6cSJohn Marino
172*ef5ccd6cSJohn Marino *METHOD_TYPE_IS_POINTERP is set to a boolean indicating if
173*ef5ccd6cSJohn Marino the method type is a pointer.
174*ef5ccd6cSJohn Marino
175*ef5ccd6cSJohn Marino There may be value in returning the outer container,
176*ef5ccd6cSJohn Marino i.e., "net" in the above example, but for now it's not needed.
177*ef5ccd6cSJohn Marino Plus it's currently not straightforward to compute,
178*ef5ccd6cSJohn Marino it comes from -fgo-prefix, and there's no algorithm to compute it.
179*ef5ccd6cSJohn Marino
180*ef5ccd6cSJohn Marino If we ever need to unpack the method type, this routine should work
181*ef5ccd6cSJohn Marino for that too. */
182*ef5ccd6cSJohn Marino
183*ef5ccd6cSJohn Marino static char *
unpack_mangled_go_symbol(const char * mangled_name,const char ** packagep,const char ** objectp,const char ** method_type_packagep,const char ** method_type_objectp,int * method_type_is_pointerp)184*ef5ccd6cSJohn Marino unpack_mangled_go_symbol (const char *mangled_name,
185*ef5ccd6cSJohn Marino const char **packagep,
186*ef5ccd6cSJohn Marino const char **objectp,
187*ef5ccd6cSJohn Marino const char **method_type_packagep,
188*ef5ccd6cSJohn Marino const char **method_type_objectp,
189*ef5ccd6cSJohn Marino int *method_type_is_pointerp)
190*ef5ccd6cSJohn Marino {
191*ef5ccd6cSJohn Marino char *buf;
192*ef5ccd6cSJohn Marino char *p;
193*ef5ccd6cSJohn Marino int len = strlen (mangled_name);
194*ef5ccd6cSJohn Marino /* Pointer to last digit in "N<digit(s)>_". */
195*ef5ccd6cSJohn Marino char *saw_digit;
196*ef5ccd6cSJohn Marino /* Pointer to "N" if valid "N<digit(s)>_" found. */
197*ef5ccd6cSJohn Marino char *method_type;
198*ef5ccd6cSJohn Marino /* Pointer to the first '.'. */
199*ef5ccd6cSJohn Marino char *first_dot;
200*ef5ccd6cSJohn Marino /* Pointer to the last '.'. */
201*ef5ccd6cSJohn Marino char *last_dot;
202*ef5ccd6cSJohn Marino /* Non-zero if we saw a pointer indicator. */
203*ef5ccd6cSJohn Marino int saw_pointer;
204*ef5ccd6cSJohn Marino
205*ef5ccd6cSJohn Marino *packagep = *objectp = NULL;
206*ef5ccd6cSJohn Marino *method_type_packagep = *method_type_objectp = NULL;
207*ef5ccd6cSJohn Marino *method_type_is_pointerp = 0;
208*ef5ccd6cSJohn Marino
209*ef5ccd6cSJohn Marino /* main.init is mangled specially. */
210*ef5ccd6cSJohn Marino if (strcmp (mangled_name, "__go_init_main") == 0)
211*ef5ccd6cSJohn Marino {
212*ef5ccd6cSJohn Marino char *package = xstrdup ("main");
213*ef5ccd6cSJohn Marino
214*ef5ccd6cSJohn Marino *packagep = package;
215*ef5ccd6cSJohn Marino *objectp = "init";
216*ef5ccd6cSJohn Marino return package;
217*ef5ccd6cSJohn Marino }
218*ef5ccd6cSJohn Marino
219*ef5ccd6cSJohn Marino /* main.main is mangled specially (missing prefix). */
220*ef5ccd6cSJohn Marino if (strcmp (mangled_name, "main.main") == 0)
221*ef5ccd6cSJohn Marino {
222*ef5ccd6cSJohn Marino char *package = xstrdup ("main");
223*ef5ccd6cSJohn Marino
224*ef5ccd6cSJohn Marino *packagep = package;
225*ef5ccd6cSJohn Marino *objectp = "main";
226*ef5ccd6cSJohn Marino return package;
227*ef5ccd6cSJohn Marino }
228*ef5ccd6cSJohn Marino
229*ef5ccd6cSJohn Marino /* We may get passed, e.g., "main.T.Foo", which is *not* mangled.
230*ef5ccd6cSJohn Marino Alas it looks exactly like "prefix.package.object."
231*ef5ccd6cSJohn Marino To cope for now we only recognize the following prefixes:
232*ef5ccd6cSJohn Marino
233*ef5ccd6cSJohn Marino go: the default
234*ef5ccd6cSJohn Marino libgo_.*: used by gccgo's runtime
235*ef5ccd6cSJohn Marino
236*ef5ccd6cSJohn Marino Thus we don't support -fgo-prefix (except as used by the runtime). */
237*ef5ccd6cSJohn Marino if (strncmp (mangled_name, "go.", 3) != 0
238*ef5ccd6cSJohn Marino && strncmp (mangled_name, "libgo_", 6) != 0)
239*ef5ccd6cSJohn Marino return NULL;
240*ef5ccd6cSJohn Marino
241*ef5ccd6cSJohn Marino /* Quick check for whether a search may be fruitful. */
242*ef5ccd6cSJohn Marino /* Ignore anything with @plt, etc. in it. */
243*ef5ccd6cSJohn Marino if (strchr (mangled_name, '@') != NULL)
244*ef5ccd6cSJohn Marino return NULL;
245*ef5ccd6cSJohn Marino /* It must have at least two dots. */
246*ef5ccd6cSJohn Marino first_dot = strchr (mangled_name, '.');
247*ef5ccd6cSJohn Marino if (first_dot == NULL)
248*ef5ccd6cSJohn Marino return NULL;
249*ef5ccd6cSJohn Marino /* Treat "foo.bar" as unmangled. It can collide with lots of other
250*ef5ccd6cSJohn Marino languages and it's not clear what the consequences are.
251*ef5ccd6cSJohn Marino And except for main.main, all gccgo symbols are at least
252*ef5ccd6cSJohn Marino prefix.package.object. */
253*ef5ccd6cSJohn Marino last_dot = strrchr (mangled_name, '.');
254*ef5ccd6cSJohn Marino if (last_dot == first_dot)
255*ef5ccd6cSJohn Marino return NULL;
256*ef5ccd6cSJohn Marino
257*ef5ccd6cSJohn Marino /* More quick checks. */
258*ef5ccd6cSJohn Marino if (last_dot[1] == '\0' /* foo. */
259*ef5ccd6cSJohn Marino || last_dot[-1] == '.') /* foo..bar */
260*ef5ccd6cSJohn Marino return NULL;
261*ef5ccd6cSJohn Marino
262*ef5ccd6cSJohn Marino /* At this point we've decided we have a mangled Go symbol. */
263*ef5ccd6cSJohn Marino
264*ef5ccd6cSJohn Marino buf = xstrdup (mangled_name);
265*ef5ccd6cSJohn Marino
266*ef5ccd6cSJohn Marino /* Search backwards looking for "N<digit(s)>". */
267*ef5ccd6cSJohn Marino p = buf + len;
268*ef5ccd6cSJohn Marino saw_digit = method_type = NULL;
269*ef5ccd6cSJohn Marino saw_pointer = 0;
270*ef5ccd6cSJohn Marino while (p > buf)
271*ef5ccd6cSJohn Marino {
272*ef5ccd6cSJohn Marino int current = *(const unsigned char *) --p;
273*ef5ccd6cSJohn Marino int current_is_digit = isdigit (current);
274*ef5ccd6cSJohn Marino
275*ef5ccd6cSJohn Marino if (saw_digit)
276*ef5ccd6cSJohn Marino {
277*ef5ccd6cSJohn Marino if (current_is_digit)
278*ef5ccd6cSJohn Marino continue;
279*ef5ccd6cSJohn Marino if (current == 'N'
280*ef5ccd6cSJohn Marino && ((p > buf && p[-1] == '.')
281*ef5ccd6cSJohn Marino || (p > buf + 1 && p[-1] == 'p' && p[-2] == '.')))
282*ef5ccd6cSJohn Marino {
283*ef5ccd6cSJohn Marino if (atoi (p + 1) == strlen (saw_digit + 2))
284*ef5ccd6cSJohn Marino {
285*ef5ccd6cSJohn Marino if (p[-1] == '.')
286*ef5ccd6cSJohn Marino method_type = p - 1;
287*ef5ccd6cSJohn Marino else
288*ef5ccd6cSJohn Marino {
289*ef5ccd6cSJohn Marino gdb_assert (p[-1] == 'p');
290*ef5ccd6cSJohn Marino saw_pointer = 1;
291*ef5ccd6cSJohn Marino method_type = p - 2;
292*ef5ccd6cSJohn Marino }
293*ef5ccd6cSJohn Marino break;
294*ef5ccd6cSJohn Marino }
295*ef5ccd6cSJohn Marino }
296*ef5ccd6cSJohn Marino /* Not what we're looking for, reset and keep looking. */
297*ef5ccd6cSJohn Marino saw_digit = NULL;
298*ef5ccd6cSJohn Marino saw_pointer = 0;
299*ef5ccd6cSJohn Marino continue;
300*ef5ccd6cSJohn Marino }
301*ef5ccd6cSJohn Marino if (current_is_digit && p[1] == '_')
302*ef5ccd6cSJohn Marino {
303*ef5ccd6cSJohn Marino /* Possible start of method "this" [sic] type. */
304*ef5ccd6cSJohn Marino saw_digit = p;
305*ef5ccd6cSJohn Marino continue;
306*ef5ccd6cSJohn Marino }
307*ef5ccd6cSJohn Marino }
308*ef5ccd6cSJohn Marino
309*ef5ccd6cSJohn Marino if (method_type != NULL
310*ef5ccd6cSJohn Marino /* Ensure not something like "..foo". */
311*ef5ccd6cSJohn Marino && (method_type > buf && method_type[-1] != '.'))
312*ef5ccd6cSJohn Marino {
313*ef5ccd6cSJohn Marino unpack_package_and_object (saw_digit + 2,
314*ef5ccd6cSJohn Marino method_type_packagep, method_type_objectp);
315*ef5ccd6cSJohn Marino *method_type = '\0';
316*ef5ccd6cSJohn Marino *method_type_is_pointerp = saw_pointer;
317*ef5ccd6cSJohn Marino }
318*ef5ccd6cSJohn Marino
319*ef5ccd6cSJohn Marino unpack_package_and_object (buf, packagep, objectp);
320*ef5ccd6cSJohn Marino return buf;
321*ef5ccd6cSJohn Marino }
322*ef5ccd6cSJohn Marino
323*ef5ccd6cSJohn Marino /* Implements the la_demangle language_defn routine for language Go.
324*ef5ccd6cSJohn Marino
325*ef5ccd6cSJohn Marino N.B. This may get passed *any* symbol, including symbols from other
326*ef5ccd6cSJohn Marino languages and including symbols that are already demangled.
327*ef5ccd6cSJohn Marino Both of these situations are kinda unfortunate, but that's how things
328*ef5ccd6cSJohn Marino are today.
329*ef5ccd6cSJohn Marino
330*ef5ccd6cSJohn Marino N.B. This currently only supports gccgo's mangling.
331*ef5ccd6cSJohn Marino
332*ef5ccd6cSJohn Marino N.B. gccgo's mangling needs, I think, changing.
333*ef5ccd6cSJohn Marino This demangler can't work in all situations,
334*ef5ccd6cSJohn Marino thus not too much effort is currently put into it. */
335*ef5ccd6cSJohn Marino
336*ef5ccd6cSJohn Marino char *
go_demangle(const char * mangled_name,int options)337*ef5ccd6cSJohn Marino go_demangle (const char *mangled_name, int options)
338*ef5ccd6cSJohn Marino {
339*ef5ccd6cSJohn Marino struct obstack tempbuf;
340*ef5ccd6cSJohn Marino char *result;
341*ef5ccd6cSJohn Marino char *name_buf;
342*ef5ccd6cSJohn Marino const char *package_name;
343*ef5ccd6cSJohn Marino const char *object_name;
344*ef5ccd6cSJohn Marino const char *method_type_package_name;
345*ef5ccd6cSJohn Marino const char *method_type_object_name;
346*ef5ccd6cSJohn Marino int method_type_is_pointer;
347*ef5ccd6cSJohn Marino
348*ef5ccd6cSJohn Marino if (mangled_name == NULL)
349*ef5ccd6cSJohn Marino return NULL;
350*ef5ccd6cSJohn Marino
351*ef5ccd6cSJohn Marino name_buf = unpack_mangled_go_symbol (mangled_name,
352*ef5ccd6cSJohn Marino &package_name, &object_name,
353*ef5ccd6cSJohn Marino &method_type_package_name,
354*ef5ccd6cSJohn Marino &method_type_object_name,
355*ef5ccd6cSJohn Marino &method_type_is_pointer);
356*ef5ccd6cSJohn Marino if (name_buf == NULL)
357*ef5ccd6cSJohn Marino return NULL;
358*ef5ccd6cSJohn Marino
359*ef5ccd6cSJohn Marino obstack_init (&tempbuf);
360*ef5ccd6cSJohn Marino
361*ef5ccd6cSJohn Marino /* Print methods as they appear in "method expressions". */
362*ef5ccd6cSJohn Marino if (method_type_package_name != NULL)
363*ef5ccd6cSJohn Marino {
364*ef5ccd6cSJohn Marino /* FIXME: Seems like we should include package_name here somewhere. */
365*ef5ccd6cSJohn Marino if (method_type_is_pointer)
366*ef5ccd6cSJohn Marino obstack_grow_str (&tempbuf, "(*");
367*ef5ccd6cSJohn Marino obstack_grow_str (&tempbuf, method_type_package_name);
368*ef5ccd6cSJohn Marino obstack_grow_str (&tempbuf, ".");
369*ef5ccd6cSJohn Marino obstack_grow_str (&tempbuf, method_type_object_name);
370*ef5ccd6cSJohn Marino if (method_type_is_pointer)
371*ef5ccd6cSJohn Marino obstack_grow_str (&tempbuf, ")");
372*ef5ccd6cSJohn Marino obstack_grow_str (&tempbuf, ".");
373*ef5ccd6cSJohn Marino obstack_grow_str (&tempbuf, object_name);
374*ef5ccd6cSJohn Marino }
375*ef5ccd6cSJohn Marino else
376*ef5ccd6cSJohn Marino {
377*ef5ccd6cSJohn Marino obstack_grow_str (&tempbuf, package_name);
378*ef5ccd6cSJohn Marino obstack_grow_str (&tempbuf, ".");
379*ef5ccd6cSJohn Marino obstack_grow_str (&tempbuf, object_name);
380*ef5ccd6cSJohn Marino }
381*ef5ccd6cSJohn Marino obstack_grow_str0 (&tempbuf, "");
382*ef5ccd6cSJohn Marino
383*ef5ccd6cSJohn Marino result = xstrdup (obstack_finish (&tempbuf));
384*ef5ccd6cSJohn Marino obstack_free (&tempbuf, NULL);
385*ef5ccd6cSJohn Marino xfree (name_buf);
386*ef5ccd6cSJohn Marino return result;
387*ef5ccd6cSJohn Marino }
388*ef5ccd6cSJohn Marino
389*ef5ccd6cSJohn Marino /* Given a Go symbol, return its package or NULL if unknown.
390*ef5ccd6cSJohn Marino Space for the result is malloc'd, caller must free. */
391*ef5ccd6cSJohn Marino
392*ef5ccd6cSJohn Marino char *
go_symbol_package_name(const struct symbol * sym)393*ef5ccd6cSJohn Marino go_symbol_package_name (const struct symbol *sym)
394*ef5ccd6cSJohn Marino {
395*ef5ccd6cSJohn Marino const char *mangled_name = SYMBOL_LINKAGE_NAME (sym);
396*ef5ccd6cSJohn Marino const char *package_name;
397*ef5ccd6cSJohn Marino const char *object_name;
398*ef5ccd6cSJohn Marino const char *method_type_package_name;
399*ef5ccd6cSJohn Marino const char *method_type_object_name;
400*ef5ccd6cSJohn Marino int method_type_is_pointer;
401*ef5ccd6cSJohn Marino char *name_buf;
402*ef5ccd6cSJohn Marino char *result;
403*ef5ccd6cSJohn Marino
404*ef5ccd6cSJohn Marino gdb_assert (SYMBOL_LANGUAGE (sym) == language_go);
405*ef5ccd6cSJohn Marino name_buf = unpack_mangled_go_symbol (mangled_name,
406*ef5ccd6cSJohn Marino &package_name, &object_name,
407*ef5ccd6cSJohn Marino &method_type_package_name,
408*ef5ccd6cSJohn Marino &method_type_object_name,
409*ef5ccd6cSJohn Marino &method_type_is_pointer);
410*ef5ccd6cSJohn Marino /* Some Go symbols don't have mangled form we interpret (yet). */
411*ef5ccd6cSJohn Marino if (name_buf == NULL)
412*ef5ccd6cSJohn Marino return NULL;
413*ef5ccd6cSJohn Marino result = xstrdup (package_name);
414*ef5ccd6cSJohn Marino xfree (name_buf);
415*ef5ccd6cSJohn Marino return result;
416*ef5ccd6cSJohn Marino }
417*ef5ccd6cSJohn Marino
418*ef5ccd6cSJohn Marino /* Return the package that BLOCK is in, or NULL if there isn't one.
419*ef5ccd6cSJohn Marino Space for the result is malloc'd, caller must free. */
420*ef5ccd6cSJohn Marino
421*ef5ccd6cSJohn Marino char *
go_block_package_name(const struct block * block)422*ef5ccd6cSJohn Marino go_block_package_name (const struct block *block)
423*ef5ccd6cSJohn Marino {
424*ef5ccd6cSJohn Marino while (block != NULL)
425*ef5ccd6cSJohn Marino {
426*ef5ccd6cSJohn Marino struct symbol *function = BLOCK_FUNCTION (block);
427*ef5ccd6cSJohn Marino
428*ef5ccd6cSJohn Marino if (function != NULL)
429*ef5ccd6cSJohn Marino {
430*ef5ccd6cSJohn Marino char *package_name = go_symbol_package_name (function);
431*ef5ccd6cSJohn Marino
432*ef5ccd6cSJohn Marino if (package_name != NULL)
433*ef5ccd6cSJohn Marino return package_name;
434*ef5ccd6cSJohn Marino
435*ef5ccd6cSJohn Marino /* Stop looking if we find a function without a package name.
436*ef5ccd6cSJohn Marino We're most likely outside of Go and thus the concept of the
437*ef5ccd6cSJohn Marino "current" package is gone. */
438*ef5ccd6cSJohn Marino return NULL;
439*ef5ccd6cSJohn Marino }
440*ef5ccd6cSJohn Marino
441*ef5ccd6cSJohn Marino block = BLOCK_SUPERBLOCK (block);
442*ef5ccd6cSJohn Marino }
443*ef5ccd6cSJohn Marino
444*ef5ccd6cSJohn Marino return NULL;
445*ef5ccd6cSJohn Marino }
446*ef5ccd6cSJohn Marino
447*ef5ccd6cSJohn Marino /* Table mapping opcodes into strings for printing operators
448*ef5ccd6cSJohn Marino and precedences of the operators.
449*ef5ccd6cSJohn Marino TODO(dje): &^ ? */
450*ef5ccd6cSJohn Marino
451*ef5ccd6cSJohn Marino static const struct op_print go_op_print_tab[] =
452*ef5ccd6cSJohn Marino {
453*ef5ccd6cSJohn Marino {",", BINOP_COMMA, PREC_COMMA, 0},
454*ef5ccd6cSJohn Marino {"=", BINOP_ASSIGN, PREC_ASSIGN, 1},
455*ef5ccd6cSJohn Marino {"||", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0},
456*ef5ccd6cSJohn Marino {"&&", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0},
457*ef5ccd6cSJohn Marino {"|", BINOP_BITWISE_IOR, PREC_BITWISE_IOR, 0},
458*ef5ccd6cSJohn Marino {"^", BINOP_BITWISE_XOR, PREC_BITWISE_XOR, 0},
459*ef5ccd6cSJohn Marino {"&", BINOP_BITWISE_AND, PREC_BITWISE_AND, 0},
460*ef5ccd6cSJohn Marino {"==", BINOP_EQUAL, PREC_EQUAL, 0},
461*ef5ccd6cSJohn Marino {"!=", BINOP_NOTEQUAL, PREC_EQUAL, 0},
462*ef5ccd6cSJohn Marino {"<=", BINOP_LEQ, PREC_ORDER, 0},
463*ef5ccd6cSJohn Marino {">=", BINOP_GEQ, PREC_ORDER, 0},
464*ef5ccd6cSJohn Marino {">", BINOP_GTR, PREC_ORDER, 0},
465*ef5ccd6cSJohn Marino {"<", BINOP_LESS, PREC_ORDER, 0},
466*ef5ccd6cSJohn Marino {">>", BINOP_RSH, PREC_SHIFT, 0},
467*ef5ccd6cSJohn Marino {"<<", BINOP_LSH, PREC_SHIFT, 0},
468*ef5ccd6cSJohn Marino {"+", BINOP_ADD, PREC_ADD, 0},
469*ef5ccd6cSJohn Marino {"-", BINOP_SUB, PREC_ADD, 0},
470*ef5ccd6cSJohn Marino {"*", BINOP_MUL, PREC_MUL, 0},
471*ef5ccd6cSJohn Marino {"/", BINOP_DIV, PREC_MUL, 0},
472*ef5ccd6cSJohn Marino {"%", BINOP_REM, PREC_MUL, 0},
473*ef5ccd6cSJohn Marino {"@", BINOP_REPEAT, PREC_REPEAT, 0},
474*ef5ccd6cSJohn Marino {"-", UNOP_NEG, PREC_PREFIX, 0},
475*ef5ccd6cSJohn Marino {"!", UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
476*ef5ccd6cSJohn Marino {"^", UNOP_COMPLEMENT, PREC_PREFIX, 0},
477*ef5ccd6cSJohn Marino {"*", UNOP_IND, PREC_PREFIX, 0},
478*ef5ccd6cSJohn Marino {"&", UNOP_ADDR, PREC_PREFIX, 0},
479*ef5ccd6cSJohn Marino {"unsafe.Sizeof ", UNOP_SIZEOF, PREC_PREFIX, 0},
480*ef5ccd6cSJohn Marino {"++", UNOP_POSTINCREMENT, PREC_SUFFIX, 0},
481*ef5ccd6cSJohn Marino {"--", UNOP_POSTDECREMENT, PREC_SUFFIX, 0},
482*ef5ccd6cSJohn Marino {NULL, 0, 0, 0}
483*ef5ccd6cSJohn Marino };
484*ef5ccd6cSJohn Marino
485*ef5ccd6cSJohn Marino enum go_primitive_types {
486*ef5ccd6cSJohn Marino go_primitive_type_void,
487*ef5ccd6cSJohn Marino go_primitive_type_char,
488*ef5ccd6cSJohn Marino go_primitive_type_bool,
489*ef5ccd6cSJohn Marino go_primitive_type_int,
490*ef5ccd6cSJohn Marino go_primitive_type_uint,
491*ef5ccd6cSJohn Marino go_primitive_type_uintptr,
492*ef5ccd6cSJohn Marino go_primitive_type_int8,
493*ef5ccd6cSJohn Marino go_primitive_type_int16,
494*ef5ccd6cSJohn Marino go_primitive_type_int32,
495*ef5ccd6cSJohn Marino go_primitive_type_int64,
496*ef5ccd6cSJohn Marino go_primitive_type_uint8,
497*ef5ccd6cSJohn Marino go_primitive_type_uint16,
498*ef5ccd6cSJohn Marino go_primitive_type_uint32,
499*ef5ccd6cSJohn Marino go_primitive_type_uint64,
500*ef5ccd6cSJohn Marino go_primitive_type_float32,
501*ef5ccd6cSJohn Marino go_primitive_type_float64,
502*ef5ccd6cSJohn Marino go_primitive_type_complex64,
503*ef5ccd6cSJohn Marino go_primitive_type_complex128,
504*ef5ccd6cSJohn Marino nr_go_primitive_types
505*ef5ccd6cSJohn Marino };
506*ef5ccd6cSJohn Marino
507*ef5ccd6cSJohn Marino static void
go_language_arch_info(struct gdbarch * gdbarch,struct language_arch_info * lai)508*ef5ccd6cSJohn Marino go_language_arch_info (struct gdbarch *gdbarch,
509*ef5ccd6cSJohn Marino struct language_arch_info *lai)
510*ef5ccd6cSJohn Marino {
511*ef5ccd6cSJohn Marino const struct builtin_go_type *builtin = builtin_go_type (gdbarch);
512*ef5ccd6cSJohn Marino
513*ef5ccd6cSJohn Marino lai->string_char_type = builtin->builtin_char;
514*ef5ccd6cSJohn Marino
515*ef5ccd6cSJohn Marino lai->primitive_type_vector
516*ef5ccd6cSJohn Marino = GDBARCH_OBSTACK_CALLOC (gdbarch, nr_go_primitive_types + 1,
517*ef5ccd6cSJohn Marino struct type *);
518*ef5ccd6cSJohn Marino
519*ef5ccd6cSJohn Marino lai->primitive_type_vector [go_primitive_type_void]
520*ef5ccd6cSJohn Marino = builtin->builtin_void;
521*ef5ccd6cSJohn Marino lai->primitive_type_vector [go_primitive_type_char]
522*ef5ccd6cSJohn Marino = builtin->builtin_char;
523*ef5ccd6cSJohn Marino lai->primitive_type_vector [go_primitive_type_bool]
524*ef5ccd6cSJohn Marino = builtin->builtin_bool;
525*ef5ccd6cSJohn Marino lai->primitive_type_vector [go_primitive_type_int]
526*ef5ccd6cSJohn Marino = builtin->builtin_int;
527*ef5ccd6cSJohn Marino lai->primitive_type_vector [go_primitive_type_uint]
528*ef5ccd6cSJohn Marino = builtin->builtin_uint;
529*ef5ccd6cSJohn Marino lai->primitive_type_vector [go_primitive_type_uintptr]
530*ef5ccd6cSJohn Marino = builtin->builtin_uintptr;
531*ef5ccd6cSJohn Marino lai->primitive_type_vector [go_primitive_type_int8]
532*ef5ccd6cSJohn Marino = builtin->builtin_int8;
533*ef5ccd6cSJohn Marino lai->primitive_type_vector [go_primitive_type_int16]
534*ef5ccd6cSJohn Marino = builtin->builtin_int16;
535*ef5ccd6cSJohn Marino lai->primitive_type_vector [go_primitive_type_int32]
536*ef5ccd6cSJohn Marino = builtin->builtin_int32;
537*ef5ccd6cSJohn Marino lai->primitive_type_vector [go_primitive_type_int64]
538*ef5ccd6cSJohn Marino = builtin->builtin_int64;
539*ef5ccd6cSJohn Marino lai->primitive_type_vector [go_primitive_type_uint8]
540*ef5ccd6cSJohn Marino = builtin->builtin_uint8;
541*ef5ccd6cSJohn Marino lai->primitive_type_vector [go_primitive_type_uint16]
542*ef5ccd6cSJohn Marino = builtin->builtin_uint16;
543*ef5ccd6cSJohn Marino lai->primitive_type_vector [go_primitive_type_uint32]
544*ef5ccd6cSJohn Marino = builtin->builtin_uint32;
545*ef5ccd6cSJohn Marino lai->primitive_type_vector [go_primitive_type_uint64]
546*ef5ccd6cSJohn Marino = builtin->builtin_uint64;
547*ef5ccd6cSJohn Marino lai->primitive_type_vector [go_primitive_type_float32]
548*ef5ccd6cSJohn Marino = builtin->builtin_float32;
549*ef5ccd6cSJohn Marino lai->primitive_type_vector [go_primitive_type_float64]
550*ef5ccd6cSJohn Marino = builtin->builtin_float64;
551*ef5ccd6cSJohn Marino lai->primitive_type_vector [go_primitive_type_complex64]
552*ef5ccd6cSJohn Marino = builtin->builtin_complex64;
553*ef5ccd6cSJohn Marino lai->primitive_type_vector [go_primitive_type_complex128]
554*ef5ccd6cSJohn Marino = builtin->builtin_complex128;
555*ef5ccd6cSJohn Marino
556*ef5ccd6cSJohn Marino lai->bool_type_symbol = "bool";
557*ef5ccd6cSJohn Marino lai->bool_type_default = builtin->builtin_bool;
558*ef5ccd6cSJohn Marino }
559*ef5ccd6cSJohn Marino
560*ef5ccd6cSJohn Marino static const struct language_defn go_language_defn =
561*ef5ccd6cSJohn Marino {
562*ef5ccd6cSJohn Marino "go",
563*ef5ccd6cSJohn Marino language_go,
564*ef5ccd6cSJohn Marino range_check_off,
565*ef5ccd6cSJohn Marino case_sensitive_on,
566*ef5ccd6cSJohn Marino array_row_major,
567*ef5ccd6cSJohn Marino macro_expansion_no,
568*ef5ccd6cSJohn Marino &exp_descriptor_c,
569*ef5ccd6cSJohn Marino go_parse,
570*ef5ccd6cSJohn Marino go_error,
571*ef5ccd6cSJohn Marino null_post_parser,
572*ef5ccd6cSJohn Marino c_printchar, /* Print a character constant. */
573*ef5ccd6cSJohn Marino c_printstr, /* Function to print string constant. */
574*ef5ccd6cSJohn Marino c_emit_char, /* Print a single char. */
575*ef5ccd6cSJohn Marino go_print_type, /* Print a type using appropriate syntax. */
576*ef5ccd6cSJohn Marino c_print_typedef, /* Print a typedef using appropriate
577*ef5ccd6cSJohn Marino syntax. */
578*ef5ccd6cSJohn Marino go_val_print, /* Print a value using appropriate syntax. */
579*ef5ccd6cSJohn Marino c_value_print, /* Print a top-level value. */
580*ef5ccd6cSJohn Marino default_read_var_value, /* la_read_var_value */
581*ef5ccd6cSJohn Marino NULL, /* Language specific skip_trampoline. */
582*ef5ccd6cSJohn Marino NULL, /* name_of_this */
583*ef5ccd6cSJohn Marino basic_lookup_symbol_nonlocal,
584*ef5ccd6cSJohn Marino basic_lookup_transparent_type,
585*ef5ccd6cSJohn Marino go_demangle, /* Language specific symbol demangler. */
586*ef5ccd6cSJohn Marino NULL, /* Language specific
587*ef5ccd6cSJohn Marino class_name_from_physname. */
588*ef5ccd6cSJohn Marino go_op_print_tab, /* Expression operators for printing. */
589*ef5ccd6cSJohn Marino 1, /* C-style arrays. */
590*ef5ccd6cSJohn Marino 0, /* String lower bound. */
591*ef5ccd6cSJohn Marino default_word_break_characters,
592*ef5ccd6cSJohn Marino default_make_symbol_completion_list,
593*ef5ccd6cSJohn Marino go_language_arch_info,
594*ef5ccd6cSJohn Marino default_print_array_index,
595*ef5ccd6cSJohn Marino default_pass_by_reference,
596*ef5ccd6cSJohn Marino c_get_string,
597*ef5ccd6cSJohn Marino NULL,
598*ef5ccd6cSJohn Marino iterate_over_symbols,
599*ef5ccd6cSJohn Marino LANG_MAGIC
600*ef5ccd6cSJohn Marino };
601*ef5ccd6cSJohn Marino
602*ef5ccd6cSJohn Marino static void *
build_go_types(struct gdbarch * gdbarch)603*ef5ccd6cSJohn Marino build_go_types (struct gdbarch *gdbarch)
604*ef5ccd6cSJohn Marino {
605*ef5ccd6cSJohn Marino struct builtin_go_type *builtin_go_type
606*ef5ccd6cSJohn Marino = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct builtin_go_type);
607*ef5ccd6cSJohn Marino
608*ef5ccd6cSJohn Marino builtin_go_type->builtin_void
609*ef5ccd6cSJohn Marino = arch_type (gdbarch, TYPE_CODE_VOID, 1, "void");
610*ef5ccd6cSJohn Marino builtin_go_type->builtin_char
611*ef5ccd6cSJohn Marino = arch_character_type (gdbarch, 8, 1, "char");
612*ef5ccd6cSJohn Marino builtin_go_type->builtin_bool
613*ef5ccd6cSJohn Marino = arch_boolean_type (gdbarch, 8, 0, "bool");
614*ef5ccd6cSJohn Marino builtin_go_type->builtin_int
615*ef5ccd6cSJohn Marino = arch_integer_type (gdbarch, gdbarch_int_bit (gdbarch), 0, "int");
616*ef5ccd6cSJohn Marino builtin_go_type->builtin_uint
617*ef5ccd6cSJohn Marino = arch_integer_type (gdbarch, gdbarch_int_bit (gdbarch), 1, "uint");
618*ef5ccd6cSJohn Marino builtin_go_type->builtin_uintptr
619*ef5ccd6cSJohn Marino = arch_integer_type (gdbarch, gdbarch_ptr_bit (gdbarch), 1, "uintptr");
620*ef5ccd6cSJohn Marino builtin_go_type->builtin_int8
621*ef5ccd6cSJohn Marino = arch_integer_type (gdbarch, 8, 0, "int8");
622*ef5ccd6cSJohn Marino builtin_go_type->builtin_int16
623*ef5ccd6cSJohn Marino = arch_integer_type (gdbarch, 16, 0, "int16");
624*ef5ccd6cSJohn Marino builtin_go_type->builtin_int32
625*ef5ccd6cSJohn Marino = arch_integer_type (gdbarch, 32, 0, "int32");
626*ef5ccd6cSJohn Marino builtin_go_type->builtin_int64
627*ef5ccd6cSJohn Marino = arch_integer_type (gdbarch, 64, 0, "int64");
628*ef5ccd6cSJohn Marino builtin_go_type->builtin_uint8
629*ef5ccd6cSJohn Marino = arch_integer_type (gdbarch, 8, 1, "uint8");
630*ef5ccd6cSJohn Marino builtin_go_type->builtin_uint16
631*ef5ccd6cSJohn Marino = arch_integer_type (gdbarch, 16, 1, "uint16");
632*ef5ccd6cSJohn Marino builtin_go_type->builtin_uint32
633*ef5ccd6cSJohn Marino = arch_integer_type (gdbarch, 32, 1, "uint32");
634*ef5ccd6cSJohn Marino builtin_go_type->builtin_uint64
635*ef5ccd6cSJohn Marino = arch_integer_type (gdbarch, 64, 1, "uint64");
636*ef5ccd6cSJohn Marino builtin_go_type->builtin_float32
637*ef5ccd6cSJohn Marino = arch_float_type (gdbarch, 32, "float32", NULL);
638*ef5ccd6cSJohn Marino builtin_go_type->builtin_float64
639*ef5ccd6cSJohn Marino = arch_float_type (gdbarch, 64, "float64", NULL);
640*ef5ccd6cSJohn Marino builtin_go_type->builtin_complex64
641*ef5ccd6cSJohn Marino = arch_complex_type (gdbarch, "complex64",
642*ef5ccd6cSJohn Marino builtin_go_type->builtin_float32);
643*ef5ccd6cSJohn Marino builtin_go_type->builtin_complex128
644*ef5ccd6cSJohn Marino = arch_complex_type (gdbarch, "complex128",
645*ef5ccd6cSJohn Marino builtin_go_type->builtin_float64);
646*ef5ccd6cSJohn Marino
647*ef5ccd6cSJohn Marino return builtin_go_type;
648*ef5ccd6cSJohn Marino }
649*ef5ccd6cSJohn Marino
650*ef5ccd6cSJohn Marino static struct gdbarch_data *go_type_data;
651*ef5ccd6cSJohn Marino
652*ef5ccd6cSJohn Marino const struct builtin_go_type *
builtin_go_type(struct gdbarch * gdbarch)653*ef5ccd6cSJohn Marino builtin_go_type (struct gdbarch *gdbarch)
654*ef5ccd6cSJohn Marino {
655*ef5ccd6cSJohn Marino return gdbarch_data (gdbarch, go_type_data);
656*ef5ccd6cSJohn Marino }
657*ef5ccd6cSJohn Marino
658*ef5ccd6cSJohn Marino extern initialize_file_ftype _initialize_go_language;
659*ef5ccd6cSJohn Marino
660*ef5ccd6cSJohn Marino void
_initialize_go_language(void)661*ef5ccd6cSJohn Marino _initialize_go_language (void)
662*ef5ccd6cSJohn Marino {
663*ef5ccd6cSJohn Marino go_type_data = gdbarch_data_register_post_init (build_go_types);
664*ef5ccd6cSJohn Marino
665*ef5ccd6cSJohn Marino add_language (&go_language_defn);
666*ef5ccd6cSJohn Marino }
667