/* Go language support routines for GDB, the GNU debugger.

   Copyright (C) 2012-2022 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

/* TODO:
   - split stacks
   - printing of native types
   - goroutines
   - lots more
   - gccgo mangling needs redoing
     It's too hard, for example, to know whether one is looking at a mangled
     Go symbol or not, and their are ambiguities, e.g., the demangler may
     get passed *any* symbol, including symbols from other languages
     and including symbols that are already demangled.
     One thought is to at least add an _G prefix.
   - 6g mangling isn't supported yet
*/

#include "defs.h"
#include "gdbsupport/gdb_obstack.h"
#include "block.h"
#include "symtab.h"
#include "language.h"
#include "varobj.h"
#include "go-lang.h"
#include "c-lang.h"
#include "parser-defs.h"
#include "gdbarch.h"

#include <ctype.h>

/* The main function in the main package.  */
static const char GO_MAIN_MAIN[] = "main.main";

/* Function returning the special symbol name used by Go for the main
   procedure in the main program if it is found in minimal symbol list.
   This function tries to find minimal symbols so that it finds them even
   if the program was compiled without debugging information.  */

const char *
go_main_name (void)
{
  struct bound_minimal_symbol msym;

  msym = lookup_minimal_symbol (GO_MAIN_MAIN, NULL, NULL);
  if (msym.minsym != NULL)
    return GO_MAIN_MAIN;

  /* No known entry procedure found, the main program is probably not Go.  */
  return NULL;
}

/* Return non-zero if TYPE is a gccgo string.
   We assume CHECK_TYPEDEF has already been done.  */

static int
gccgo_string_p (struct type *type)
{
  /* gccgo strings don't necessarily have a name we can use.  */

  if (type->num_fields () == 2)
    {
      struct type *type0 = type->field (0).type ();
      struct type *type1 = type->field (1).type ();

      type0 = check_typedef (type0);
      type1 = check_typedef (type1);

      if (type0->code () == TYPE_CODE_PTR
	  && strcmp (type->field (0).name (), "__data") == 0
	  && type1->code () == TYPE_CODE_INT
	  && strcmp (type->field (1).name (), "__length") == 0)
	{
	  struct type *target_type = TYPE_TARGET_TYPE (type0);

	  target_type = check_typedef (target_type);

	  if (target_type->code () == TYPE_CODE_INT
	      && TYPE_LENGTH (target_type) == 1
	      && strcmp (target_type->name (), "uint8") == 0)
	    return 1;
	}
    }

  return 0;
}

/* Return non-zero if TYPE is a 6g string.
   We assume CHECK_TYPEDEF has already been done.  */

static int
sixg_string_p (struct type *type)
{
  if (type->num_fields () == 2
      && type->name () != NULL
      && strcmp (type->name (), "string") == 0)
    return 1;

  return 0;
}

/* Classify the kind of Go object that TYPE is.
   TYPE is a TYPE_CODE_STRUCT, used to represent a Go object.  */

enum go_type
go_classify_struct_type (struct type *type)
{
  type = check_typedef (type);

  /* Recognize strings as they're useful to be able to print without
     pretty-printers.  */
  if (gccgo_string_p (type)
      || sixg_string_p (type))
    return GO_TYPE_STRING;

  return GO_TYPE_NONE;
}

/* Subroutine of unpack_mangled_go_symbol to simplify it.
   Given "[foo.]bar.baz", store "bar" in *PACKAGEP and "baz" in *OBJECTP.
   We stomp on the last '.' to nul-terminate "bar".
   The caller is responsible for memory management.  */

static void
unpack_package_and_object (char *buf,
			   const char **packagep, const char **objectp)
{
  char *last_dot;

  last_dot = strrchr (buf, '.');
  gdb_assert (last_dot != NULL);
  *objectp = last_dot + 1;
  *last_dot = '\0';
  last_dot = strrchr (buf, '.');
  if (last_dot != NULL)
    *packagep = last_dot + 1;
  else
    *packagep = buf;
}

/* Given a mangled Go symbol, find its package name, object name, and
   method type (if present).
   E.g., for "libgo_net.textproto.String.N33_libgo_net.textproto.ProtocolError"
   *PACKAGEP = "textproto"
   *OBJECTP = "String"
   *METHOD_TYPE_PACKAGEP = "textproto"
   *METHOD_TYPE_OBJECTP = "ProtocolError"

   Space for the resulting strings is malloc'd in one buffer.
   PACKAGEP,OBJECTP,METHOD_TYPE* will (typically) point into this buffer.
   [There are a few exceptions, but the caller is still responsible for
   freeing the resulting pointer.]
   A pointer to this buffer is returned, or NULL if symbol isn't a
   mangled Go symbol.
   The caller is responsible for freeing the result.

   *METHOD_TYPE_IS_POINTERP is set to a boolean indicating if
   the method type is a pointer.

   There may be value in returning the outer container,
   i.e., "net" in the above example, but for now it's not needed.
   Plus it's currently not straightforward to compute,
   it comes from -fgo-prefix, and there's no algorithm to compute it.

   If we ever need to unpack the method type, this routine should work
   for that too.  */

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)
{
  char *buf;
  char *p;
  int len = strlen (mangled_name);
  /* Pointer to last digit in "N<digit(s)>_".  */
  char *saw_digit;
  /* Pointer to "N" if valid "N<digit(s)>_" found.  */
  char *method_type;
  /* Pointer to the first '.'.  */
  const char *first_dot;
  /* Pointer to the last '.'.  */
  const char *last_dot;
  /* Non-zero if we saw a pointer indicator.  */
  int saw_pointer;

  *packagep = *objectp = NULL;
  *method_type_packagep = *method_type_objectp = NULL;
  *method_type_is_pointerp = 0;

  /* main.init is mangled specially.  */
  if (strcmp (mangled_name, "__go_init_main") == 0)
    {
      char *package = xstrdup ("main");

      *packagep = package;
      *objectp = "init";
      return package;
    }

  /* main.main is mangled specially (missing prefix).  */
  if (strcmp (mangled_name, "main.main") == 0)
    {
      char *package = xstrdup ("main");

      *packagep = package;
      *objectp = "main";
      return package;
    }

  /* We may get passed, e.g., "main.T.Foo", which is *not* mangled.
     Alas it looks exactly like "prefix.package.object."
     To cope for now we only recognize the following prefixes:

     go: the default
     libgo_.*: used by gccgo's runtime

     Thus we don't support -fgo-prefix (except as used by the runtime).  */
  if (!startswith (mangled_name, "go.")
      && !startswith (mangled_name, "libgo_"))
    return NULL;

  /* Quick check for whether a search may be fruitful.  */
  /* Ignore anything with @plt, etc. in it.  */
  if (strchr (mangled_name, '@') != NULL)
    return NULL;
  /* It must have at least two dots.  */
  first_dot = strchr (mangled_name, '.');
  if (first_dot == NULL)
    return NULL;
  /* Treat "foo.bar" as unmangled.  It can collide with lots of other
     languages and it's not clear what the consequences are.
     And except for main.main, all gccgo symbols are at least
     prefix.package.object.  */
  last_dot = strrchr (mangled_name, '.');
  if (last_dot == first_dot)
    return NULL;

  /* More quick checks.  */
  if (last_dot[1] == '\0' /* foo. */
      || last_dot[-1] == '.') /* foo..bar */
    return NULL;

  /* At this point we've decided we have a mangled Go symbol.  */

  buf = xstrdup (mangled_name);

  /* Search backwards looking for "N<digit(s)>".  */
  p = buf + len;
  saw_digit = method_type = NULL;
  saw_pointer = 0;
  while (p > buf)
    {
      int current = *(const unsigned char *) --p;
      int current_is_digit = isdigit (current);

      if (saw_digit)
	{
	  if (current_is_digit)
	    continue;
	  if (current == 'N'
	      && ((p > buf && p[-1] == '.')
		  || (p > buf + 1 && p[-1] == 'p' && p[-2] == '.')))
	    {
	      if (atoi (p + 1) == strlen (saw_digit + 2))
		{
		  if (p[-1] == '.')
		    method_type = p - 1;
		  else
		    {
		      gdb_assert (p[-1] == 'p');
		      saw_pointer = 1;
		      method_type = p - 2;
		    }
		  break;
		}
	    }
	  /* Not what we're looking for, reset and keep looking.  */
	  saw_digit = NULL;
	  saw_pointer = 0;
	  continue;
	}
      if (current_is_digit && p[1] == '_')
	{
	  /* Possible start of method "this" [sic] type.  */
	  saw_digit = p;
	  continue;
	}
    }

  if (method_type != NULL
      /* Ensure not something like "..foo".  */
      && (method_type > buf && method_type[-1] != '.'))
    {
      unpack_package_and_object (saw_digit + 2,
				 method_type_packagep, method_type_objectp);
      *method_type = '\0';
      *method_type_is_pointerp = saw_pointer;
    }

  unpack_package_and_object (buf, packagep, objectp);
  return buf;
}

/* Implements the la_demangle language_defn routine for language Go.

   N.B. This may get passed *any* symbol, including symbols from other
   languages and including symbols that are already demangled.
   Both of these situations are kinda unfortunate, but that's how things
   are today.

   N.B. This currently only supports gccgo's mangling.

   N.B. gccgo's mangling needs, I think, changing.
   This demangler can't work in all situations,
   thus not too much effort is currently put into it.  */

gdb::unique_xmalloc_ptr<char>
go_language::demangle_symbol (const char *mangled_name, int options) const
{
  const char *package_name;
  const char *object_name;
  const char *method_type_package_name;
  const char *method_type_object_name;
  int method_type_is_pointer;

  if (mangled_name == NULL)
    return NULL;

  gdb::unique_xmalloc_ptr<char> name_buf
    (unpack_mangled_go_symbol (mangled_name,
			       &package_name, &object_name,
			       &method_type_package_name,
			       &method_type_object_name,
			       &method_type_is_pointer));
  if (name_buf == NULL)
    return NULL;

  auto_obstack tempbuf;

  /* Print methods as they appear in "method expressions".  */
  if (method_type_package_name != NULL)
    {
      /* FIXME: Seems like we should include package_name here somewhere.  */
      if (method_type_is_pointer)
	  obstack_grow_str (&tempbuf, "(*");
      obstack_grow_str (&tempbuf, method_type_package_name);
      obstack_grow_str (&tempbuf, ".");
      obstack_grow_str (&tempbuf, method_type_object_name);
      if (method_type_is_pointer)
	obstack_grow_str (&tempbuf, ")");
      obstack_grow_str (&tempbuf, ".");
      obstack_grow_str (&tempbuf, object_name);
    }
  else
    {
      obstack_grow_str (&tempbuf, package_name);
      obstack_grow_str (&tempbuf, ".");
      obstack_grow_str (&tempbuf, object_name);
    }
  obstack_grow_str0 (&tempbuf, "");

  return make_unique_xstrdup ((const char *) obstack_finish (&tempbuf));
}

/* Given a Go symbol, return its package or NULL if unknown.
   Space for the result is malloc'd, caller must free.  */

char *
go_symbol_package_name (const struct symbol *sym)
{
  const char *mangled_name = sym->linkage_name ();
  const char *package_name;
  const char *object_name;
  const char *method_type_package_name;
  const char *method_type_object_name;
  int method_type_is_pointer;
  char *name_buf;
  char *result;

  gdb_assert (sym->language () == language_go);
  name_buf = unpack_mangled_go_symbol (mangled_name,
				       &package_name, &object_name,
				       &method_type_package_name,
				       &method_type_object_name,
				       &method_type_is_pointer);
  /* Some Go symbols don't have mangled form we interpret (yet).  */
  if (name_buf == NULL)
    return NULL;
  result = xstrdup (package_name);
  xfree (name_buf);
  return result;
}

/* Return the package that BLOCK is in, or NULL if there isn't one.
   Space for the result is malloc'd, caller must free.  */

char *
go_block_package_name (const struct block *block)
{
  while (block != NULL)
    {
      struct symbol *function = block->function ();

      if (function != NULL)
	{
	  char *package_name = go_symbol_package_name (function);

	  if (package_name != NULL)
	    return package_name;

	  /* Stop looking if we find a function without a package name.
	     We're most likely outside of Go and thus the concept of the
	     "current" package is gone.  */
	  return NULL;
	}

      block = block->superblock ();
    }

  return NULL;
}

/* See language.h.  */

void
go_language::language_arch_info (struct gdbarch *gdbarch,
				 struct language_arch_info *lai) const
{
  const struct builtin_go_type *builtin = builtin_go_type (gdbarch);

  /* Helper function to allow shorter lines below.  */
  auto add  = [&] (struct type * t) -> struct type *
  {
    lai->add_primitive_type (t);
    return t;
  };

  add (builtin->builtin_void);
  add (builtin->builtin_char);
  add (builtin->builtin_bool);
  add (builtin->builtin_int);
  add (builtin->builtin_uint);
  add (builtin->builtin_uintptr);
  add (builtin->builtin_int8);
  add (builtin->builtin_int16);
  add (builtin->builtin_int32);
  add (builtin->builtin_int64);
  add (builtin->builtin_uint8);
  add (builtin->builtin_uint16);
  add (builtin->builtin_uint32);
  add (builtin->builtin_uint64);
  add (builtin->builtin_float32);
  add (builtin->builtin_float64);
  add (builtin->builtin_complex64);
  add (builtin->builtin_complex128);

  lai->set_string_char_type (builtin->builtin_char);
  lai->set_bool_type (builtin->builtin_bool, "bool");
}

/* Single instance of the Go language class.  */

static go_language go_language_defn;

static void *
build_go_types (struct gdbarch *gdbarch)
{
  struct builtin_go_type *builtin_go_type
    = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct builtin_go_type);

  builtin_go_type->builtin_void
    = arch_type (gdbarch, TYPE_CODE_VOID, TARGET_CHAR_BIT, "void");
  builtin_go_type->builtin_char
    = arch_character_type (gdbarch, 8, 1, "char");
  builtin_go_type->builtin_bool
    = arch_boolean_type (gdbarch, 8, 0, "bool");
  builtin_go_type->builtin_int
    = arch_integer_type (gdbarch, gdbarch_int_bit (gdbarch), 0, "int");
  builtin_go_type->builtin_uint
    = arch_integer_type (gdbarch, gdbarch_int_bit (gdbarch), 1, "uint");
  builtin_go_type->builtin_uintptr
    = arch_integer_type (gdbarch, gdbarch_ptr_bit (gdbarch), 1, "uintptr");
  builtin_go_type->builtin_int8
    = arch_integer_type (gdbarch, 8, 0, "int8");
  builtin_go_type->builtin_int16
    = arch_integer_type (gdbarch, 16, 0, "int16");
  builtin_go_type->builtin_int32
    = arch_integer_type (gdbarch, 32, 0, "int32");
  builtin_go_type->builtin_int64
    = arch_integer_type (gdbarch, 64, 0, "int64");
  builtin_go_type->builtin_uint8
    = arch_integer_type (gdbarch, 8, 1, "uint8");
  builtin_go_type->builtin_uint16
    = arch_integer_type (gdbarch, 16, 1, "uint16");
  builtin_go_type->builtin_uint32
    = arch_integer_type (gdbarch, 32, 1, "uint32");
  builtin_go_type->builtin_uint64
    = arch_integer_type (gdbarch, 64, 1, "uint64");
  builtin_go_type->builtin_float32
    = arch_float_type (gdbarch, 32, "float32", floatformats_ieee_single);
  builtin_go_type->builtin_float64
    = arch_float_type (gdbarch, 64, "float64", floatformats_ieee_double);
  builtin_go_type->builtin_complex64
    = init_complex_type ("complex64", builtin_go_type->builtin_float32);
  builtin_go_type->builtin_complex128
    = init_complex_type ("complex128", builtin_go_type->builtin_float64);

  return builtin_go_type;
}

static struct gdbarch_data *go_type_data;

const struct builtin_go_type *
builtin_go_type (struct gdbarch *gdbarch)
{
  return (const struct builtin_go_type *) gdbarch_data (gdbarch, go_type_data);
}

void _initialize_go_language ();
void
_initialize_go_language ()
{
  go_type_data = gdbarch_data_register_post_init (build_go_types);
}
