xref: /netbsd-src/external/gpl3/gdb/dist/gdb/go-lang.c (revision 85893ccd59fc5e3bb06441ce3a0be0cf105d2dd7)
1 /* Go language support routines for GDB, the GNU debugger.
2 
3    Copyright (C) 2012-2024 Free Software Foundation, Inc.
4 
5    This file is part of GDB.
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19 
20 /* TODO:
21    - split stacks
22    - printing of native types
23    - goroutines
24    - lots more
25    - gccgo mangling needs redoing
26      It's too hard, for example, to know whether one is looking at a mangled
27      Go symbol or not, and their are ambiguities, e.g., the demangler may
28      get passed *any* symbol, including symbols from other languages
29      and including symbols that are already demangled.
30      One thought is to at least add an _G prefix.
31    - 6g mangling isn't supported yet
32 */
33 
34 #include "gdbsupport/gdb_obstack.h"
35 #include "block.h"
36 #include "symtab.h"
37 #include "language.h"
38 #include "varobj.h"
39 #include "go-lang.h"
40 #include "c-lang.h"
41 #include "parser-defs.h"
42 #include "gdbarch.h"
43 
44 #include <ctype.h>
45 
46 /* The main function in the main package.  */
47 static const char GO_MAIN_MAIN[] = "main.main";
48 
49 /* Function returning the special symbol name used by Go for the main
50    procedure in the main program if it is found in minimal symbol list.
51    This function tries to find minimal symbols so that it finds them even
52    if the program was compiled without debugging information.  */
53 
54 const char *
55 go_main_name (void)
56 {
57   struct bound_minimal_symbol msym;
58 
59   msym = lookup_minimal_symbol (GO_MAIN_MAIN, NULL, NULL);
60   if (msym.minsym != NULL)
61     return GO_MAIN_MAIN;
62 
63   /* No known entry procedure found, the main program is probably not Go.  */
64   return NULL;
65 }
66 
67 /* Return non-zero if TYPE is a gccgo string.
68    We assume CHECK_TYPEDEF has already been done.  */
69 
70 static int
71 gccgo_string_p (struct type *type)
72 {
73   /* gccgo strings don't necessarily have a name we can use.  */
74 
75   if (type->num_fields () == 2)
76     {
77       struct type *type0 = type->field (0).type ();
78       struct type *type1 = type->field (1).type ();
79 
80       type0 = check_typedef (type0);
81       type1 = check_typedef (type1);
82 
83       if (type0->code () == TYPE_CODE_PTR
84 	  && strcmp (type->field (0).name (), "__data") == 0
85 	  && type1->code () == TYPE_CODE_INT
86 	  && strcmp (type->field (1).name (), "__length") == 0)
87 	{
88 	  struct type *target_type = type0->target_type ();
89 
90 	  target_type = check_typedef (target_type);
91 
92 	  if (target_type->code () == TYPE_CODE_INT
93 	      && target_type->length () == 1
94 	      && strcmp (target_type->name (), "uint8") == 0)
95 	    return 1;
96 	}
97     }
98 
99   return 0;
100 }
101 
102 /* Return non-zero if TYPE is a 6g string.
103    We assume CHECK_TYPEDEF has already been done.  */
104 
105 static int
106 sixg_string_p (struct type *type)
107 {
108   if (type->num_fields () == 2
109       && type->name () != NULL
110       && strcmp (type->name (), "string") == 0)
111     return 1;
112 
113   return 0;
114 }
115 
116 /* Classify the kind of Go object that TYPE is.
117    TYPE is a TYPE_CODE_STRUCT, used to represent a Go object.  */
118 
119 enum go_type
120 go_classify_struct_type (struct type *type)
121 {
122   type = check_typedef (type);
123 
124   /* Recognize strings as they're useful to be able to print without
125      pretty-printers.  */
126   if (gccgo_string_p (type)
127       || sixg_string_p (type))
128     return GO_TYPE_STRING;
129 
130   return GO_TYPE_NONE;
131 }
132 
133 /* Subroutine of unpack_mangled_go_symbol to simplify it.
134    Given "[foo.]bar.baz", store "bar" in *PACKAGEP and "baz" in *OBJECTP.
135    We stomp on the last '.' to nul-terminate "bar".
136    The caller is responsible for memory management.  */
137 
138 static void
139 unpack_package_and_object (char *buf,
140 			   const char **packagep, const char **objectp)
141 {
142   char *last_dot;
143 
144   last_dot = strrchr (buf, '.');
145   gdb_assert (last_dot != NULL);
146   *objectp = last_dot + 1;
147   *last_dot = '\0';
148   last_dot = strrchr (buf, '.');
149   if (last_dot != NULL)
150     *packagep = last_dot + 1;
151   else
152     *packagep = buf;
153 }
154 
155 /* Given a mangled Go symbol, find its package name, object name, and
156    method type (if present).
157    E.g., for "libgo_net.textproto.String.N33_libgo_net.textproto.ProtocolError"
158    *PACKAGEP = "textproto"
159    *OBJECTP = "String"
160    *METHOD_TYPE_PACKAGEP = "textproto"
161    *METHOD_TYPE_OBJECTP = "ProtocolError"
162 
163    Space for the resulting strings is malloc'd in one buffer.
164    PACKAGEP,OBJECTP,METHOD_TYPE* will (typically) point into this buffer.
165    A pointer to this buffer is returned, or NULL if symbol isn't a
166    mangled Go symbol.
167 
168    *METHOD_TYPE_IS_POINTERP is set to a boolean indicating if
169    the method type is a pointer.
170 
171    There may be value in returning the outer container,
172    i.e., "net" in the above example, but for now it's not needed.
173    Plus it's currently not straightforward to compute,
174    it comes from -fgo-prefix, and there's no algorithm to compute it.
175 
176    If we ever need to unpack the method type, this routine should work
177    for that too.  */
178 
179 static gdb::unique_xmalloc_ptr<char>
180 unpack_mangled_go_symbol (const char *mangled_name,
181 			  const char **packagep,
182 			  const char **objectp,
183 			  const char **method_type_packagep,
184 			  const char **method_type_objectp,
185 			  int *method_type_is_pointerp)
186 {
187   char *buf;
188   char *p;
189   int len = strlen (mangled_name);
190   /* Pointer to last digit in "N<digit(s)>_".  */
191   char *saw_digit;
192   /* Pointer to "N" if valid "N<digit(s)>_" found.  */
193   char *method_type;
194   /* Pointer to the first '.'.  */
195   const char *first_dot;
196   /* Pointer to the last '.'.  */
197   const char *last_dot;
198   /* Non-zero if we saw a pointer indicator.  */
199   int saw_pointer;
200 
201   *packagep = *objectp = NULL;
202   *method_type_packagep = *method_type_objectp = NULL;
203   *method_type_is_pointerp = 0;
204 
205   /* main.init is mangled specially.  */
206   if (strcmp (mangled_name, "__go_init_main") == 0)
207     {
208       gdb::unique_xmalloc_ptr<char> package
209 	= make_unique_xstrdup ("main");
210 
211       *packagep = package.get ();
212       *objectp = "init";
213       return package;
214     }
215 
216   /* main.main is mangled specially (missing prefix).  */
217   if (strcmp (mangled_name, "main.main") == 0)
218     {
219       gdb::unique_xmalloc_ptr<char> package
220 	= make_unique_xstrdup ("main");
221 
222       *packagep = package.get ();
223       *objectp = "main";
224       return package;
225     }
226 
227   /* We may get passed, e.g., "main.T.Foo", which is *not* mangled.
228      Alas it looks exactly like "prefix.package.object."
229      To cope for now we only recognize the following prefixes:
230 
231      go: the default
232      libgo_.*: used by gccgo's runtime
233 
234      Thus we don't support -fgo-prefix (except as used by the runtime).  */
235   bool v3;
236   if (startswith (mangled_name, "go_0"))
237     /* V3 mangling detected, see
238        https://go-review.googlesource.com/c/gofrontend/+/271726 .  */
239     v3 = true;
240   else if (startswith (mangled_name, "go.")
241 	   || startswith (mangled_name, "libgo_"))
242     v3 = false;
243   else
244     return NULL;
245 
246   /* Quick check for whether a search may be fruitful.  */
247   /* Ignore anything with @plt, etc. in it.  */
248   if (strchr (mangled_name, '@') != NULL)
249     return NULL;
250 
251   /* It must have at least two dots.  */
252   if (v3)
253     first_dot = strchr (mangled_name, '0');
254   else
255     first_dot = strchr (mangled_name, '.');
256 
257   if (first_dot == NULL)
258     return NULL;
259   /* Treat "foo.bar" as unmangled.  It can collide with lots of other
260      languages and it's not clear what the consequences are.
261      And except for main.main, all gccgo symbols are at least
262      prefix.package.object.  */
263   last_dot = strrchr (mangled_name, '.');
264   if (last_dot == first_dot)
265     return NULL;
266 
267   /* More quick checks.  */
268   if (last_dot[1] == '\0' /* foo. */
269       || last_dot[-1] == '.') /* foo..bar */
270     return NULL;
271 
272   /* At this point we've decided we have a mangled Go symbol.  */
273 
274   gdb::unique_xmalloc_ptr<char> result = make_unique_xstrdup (mangled_name);
275   buf = result.get ();
276 
277   if (v3)
278     {
279       /* Replace "go_0" with "\0go.".  */
280       buf[0] = '\0';
281       buf[1] = 'g';
282       buf[2] = 'o';
283       buf[3] = '.';
284 
285       /* Skip the '\0'.  */
286       buf++;
287     }
288 
289   /* Search backwards looking for "N<digit(s)>".  */
290   p = buf + len;
291   saw_digit = method_type = NULL;
292   saw_pointer = 0;
293   while (p > buf)
294     {
295       int current = *(const unsigned char *) --p;
296       int current_is_digit = isdigit (current);
297 
298       if (saw_digit)
299 	{
300 	  if (current_is_digit)
301 	    continue;
302 	  if (current == 'N'
303 	      && ((p > buf && p[-1] == '.')
304 		  || (p > buf + 1 && p[-1] == 'p' && p[-2] == '.')))
305 	    {
306 	      if (atoi (p + 1) == strlen (saw_digit + 2))
307 		{
308 		  if (p[-1] == '.')
309 		    method_type = p - 1;
310 		  else
311 		    {
312 		      gdb_assert (p[-1] == 'p');
313 		      saw_pointer = 1;
314 		      method_type = p - 2;
315 		    }
316 		  break;
317 		}
318 	    }
319 	  /* Not what we're looking for, reset and keep looking.  */
320 	  saw_digit = NULL;
321 	  saw_pointer = 0;
322 	  continue;
323 	}
324       if (current_is_digit && p[1] == '_')
325 	{
326 	  /* Possible start of method "this" [sic] type.  */
327 	  saw_digit = p;
328 	  continue;
329 	}
330     }
331 
332   if (method_type != NULL
333       /* Ensure not something like "..foo".  */
334       && (method_type > buf && method_type[-1] != '.'))
335     {
336       unpack_package_and_object (saw_digit + 2,
337 				 method_type_packagep, method_type_objectp);
338       *method_type = '\0';
339       *method_type_is_pointerp = saw_pointer;
340     }
341 
342   unpack_package_and_object (buf, packagep, objectp);
343   return result;
344 }
345 
346 /* Implements the la_demangle language_defn routine for language Go.
347 
348    N.B. This may get passed *any* symbol, including symbols from other
349    languages and including symbols that are already demangled.
350    Both of these situations are kinda unfortunate, but that's how things
351    are today.
352 
353    N.B. This currently only supports gccgo's mangling.
354 
355    N.B. gccgo's mangling needs, I think, changing.
356    This demangler can't work in all situations,
357    thus not too much effort is currently put into it.  */
358 
359 gdb::unique_xmalloc_ptr<char>
360 go_language::demangle_symbol (const char *mangled_name, int options) const
361 {
362   const char *package_name;
363   const char *object_name;
364   const char *method_type_package_name;
365   const char *method_type_object_name;
366   int method_type_is_pointer;
367 
368   if (mangled_name == NULL)
369     return NULL;
370 
371   gdb::unique_xmalloc_ptr<char> name_buf
372     (unpack_mangled_go_symbol (mangled_name,
373 			       &package_name, &object_name,
374 			       &method_type_package_name,
375 			       &method_type_object_name,
376 			       &method_type_is_pointer));
377   if (name_buf == NULL)
378     return NULL;
379 
380   auto_obstack tempbuf;
381 
382   /* Print methods as they appear in "method expressions".  */
383   if (method_type_package_name != NULL)
384     {
385       /* FIXME: Seems like we should include package_name here somewhere.  */
386       if (method_type_is_pointer)
387 	  obstack_grow_str (&tempbuf, "(*");
388       obstack_grow_str (&tempbuf, method_type_package_name);
389       obstack_grow_str (&tempbuf, ".");
390       obstack_grow_str (&tempbuf, method_type_object_name);
391       if (method_type_is_pointer)
392 	obstack_grow_str (&tempbuf, ")");
393       obstack_grow_str (&tempbuf, ".");
394       obstack_grow_str (&tempbuf, object_name);
395     }
396   else
397     {
398       obstack_grow_str (&tempbuf, package_name);
399       obstack_grow_str (&tempbuf, ".");
400       obstack_grow_str (&tempbuf, object_name);
401     }
402   obstack_grow_str0 (&tempbuf, "");
403 
404   return make_unique_xstrdup ((const char *) obstack_finish (&tempbuf));
405 }
406 
407 /* See go-lang.h.  */
408 
409 gdb::unique_xmalloc_ptr<char>
410 go_symbol_package_name (const struct symbol *sym)
411 {
412   const char *mangled_name = sym->linkage_name ();
413   const char *package_name;
414   const char *object_name;
415   const char *method_type_package_name;
416   const char *method_type_object_name;
417   int method_type_is_pointer;
418   gdb::unique_xmalloc_ptr<char> name_buf;
419 
420   if (sym->language () != language_go)
421     return nullptr;
422   name_buf = unpack_mangled_go_symbol (mangled_name,
423 				       &package_name, &object_name,
424 				       &method_type_package_name,
425 				       &method_type_object_name,
426 				       &method_type_is_pointer);
427   /* Some Go symbols don't have mangled form we interpret (yet).  */
428   if (name_buf == NULL)
429     return NULL;
430   return make_unique_xstrdup (package_name);
431 }
432 
433 /* See go-lang.h.  */
434 
435 gdb::unique_xmalloc_ptr<char>
436 go_block_package_name (const struct block *block)
437 {
438   while (block != NULL)
439     {
440       struct symbol *function = block->function ();
441 
442       if (function != NULL)
443 	{
444 	  gdb::unique_xmalloc_ptr<char> package_name
445 	    = go_symbol_package_name (function);
446 
447 	  if (package_name != NULL)
448 	    return package_name;
449 
450 	  /* Stop looking if we find a function without a package name.
451 	     We're most likely outside of Go and thus the concept of the
452 	     "current" package is gone.  */
453 	  return NULL;
454 	}
455 
456       block = block->superblock ();
457     }
458 
459   return NULL;
460 }
461 
462 /* See language.h.  */
463 
464 void
465 go_language::language_arch_info (struct gdbarch *gdbarch,
466 				 struct language_arch_info *lai) const
467 {
468   const struct builtin_go_type *builtin = builtin_go_type (gdbarch);
469 
470   /* Helper function to allow shorter lines below.  */
471   auto add  = [&] (struct type * t) -> struct type *
472   {
473     lai->add_primitive_type (t);
474     return t;
475   };
476 
477   add (builtin->builtin_void);
478   add (builtin->builtin_char);
479   add (builtin->builtin_bool);
480   add (builtin->builtin_int);
481   add (builtin->builtin_uint);
482   add (builtin->builtin_uintptr);
483   add (builtin->builtin_int8);
484   add (builtin->builtin_int16);
485   add (builtin->builtin_int32);
486   add (builtin->builtin_int64);
487   add (builtin->builtin_uint8);
488   add (builtin->builtin_uint16);
489   add (builtin->builtin_uint32);
490   add (builtin->builtin_uint64);
491   add (builtin->builtin_float32);
492   add (builtin->builtin_float64);
493   add (builtin->builtin_complex64);
494   add (builtin->builtin_complex128);
495 
496   lai->set_string_char_type (builtin->builtin_char);
497   lai->set_bool_type (builtin->builtin_bool, "bool");
498 }
499 
500 /* Single instance of the Go language class.  */
501 
502 static go_language go_language_defn;
503 
504 static struct builtin_go_type *
505 build_go_types (struct gdbarch *gdbarch)
506 {
507   struct builtin_go_type *builtin_go_type = new struct builtin_go_type;
508 
509   type_allocator alloc (gdbarch);
510   builtin_go_type->builtin_void = builtin_type (gdbarch)->builtin_void;
511   builtin_go_type->builtin_char
512     = init_character_type (alloc, 8, 1, "char");
513   builtin_go_type->builtin_bool
514     = init_boolean_type (alloc, 8, 0, "bool");
515   builtin_go_type->builtin_int
516     = init_integer_type (alloc, gdbarch_int_bit (gdbarch), 0, "int");
517   builtin_go_type->builtin_uint
518     = init_integer_type (alloc, gdbarch_int_bit (gdbarch), 1, "uint");
519   builtin_go_type->builtin_uintptr
520     = init_integer_type (alloc, gdbarch_ptr_bit (gdbarch), 1, "uintptr");
521   builtin_go_type->builtin_int8
522     = init_integer_type (alloc, 8, 0, "int8");
523   builtin_go_type->builtin_int16
524     = init_integer_type (alloc, 16, 0, "int16");
525   builtin_go_type->builtin_int32
526     = init_integer_type (alloc, 32, 0, "int32");
527   builtin_go_type->builtin_int64
528     = init_integer_type (alloc, 64, 0, "int64");
529   builtin_go_type->builtin_uint8
530     = init_integer_type (alloc, 8, 1, "uint8");
531   builtin_go_type->builtin_uint16
532     = init_integer_type (alloc, 16, 1, "uint16");
533   builtin_go_type->builtin_uint32
534     = init_integer_type (alloc, 32, 1, "uint32");
535   builtin_go_type->builtin_uint64
536     = init_integer_type (alloc, 64, 1, "uint64");
537   builtin_go_type->builtin_float32
538     = init_float_type (alloc, 32, "float32", floatformats_ieee_single);
539   builtin_go_type->builtin_float64
540     = init_float_type (alloc, 64, "float64", floatformats_ieee_double);
541   builtin_go_type->builtin_complex64
542     = init_complex_type ("complex64", builtin_go_type->builtin_float32);
543   builtin_go_type->builtin_complex128
544     = init_complex_type ("complex128", builtin_go_type->builtin_float64);
545 
546   return builtin_go_type;
547 }
548 
549 static const registry<gdbarch>::key<struct builtin_go_type> go_type_data;
550 
551 const struct builtin_go_type *
552 builtin_go_type (struct gdbarch *gdbarch)
553 {
554   struct builtin_go_type *result = go_type_data.get (gdbarch);
555   if (result == nullptr)
556     {
557       result = build_go_types (gdbarch);
558       go_type_data.set (gdbarch, result);
559     }
560 
561   return result;
562 }
563