/* go-callers.c -- get callers for Go.

   Copyright 2012 The Go Authors. All rights reserved.
   Use of this source code is governed by a BSD-style
   license that can be found in the LICENSE file.  */

#include "config.h"

#include "backtrace.h"

#include "runtime.h"
#include "array.h"

/* This is set to non-zero when calling backtrace_full.  This is used
   to avoid getting hanging on a recursive lock in dl_iterate_phdr on
   older versions of glibc when a SIGPROF signal arrives while
   collecting a backtrace.  */

uint32 __go_runtime_in_callers;

/* Argument passed to callback function.  */

struct callers_data
{
  Location *locbuf;
  int skip;
  int index;
  int max;
  int keep_thunks;
};

/* Callback function for backtrace_full.  Just collect the locations.
   Return zero to continue, non-zero to stop.  */

static int
callback (void *data, uintptr_t pc, const char *filename, int lineno,
	  const char *function)
{
  struct callers_data *arg = (struct callers_data *) data;
  Location *loc;

  /* Skip split stack functions.  */
  if (function != NULL)
    {
      const char *p;

      p = function;
      if (__builtin_strncmp (p, "___", 3) == 0)
	++p;
      if (__builtin_strncmp (p, "__morestack_", 12) == 0)
	return 0;
    }
  else if (filename != NULL)
    {
      const char *p;

      p = strrchr (filename, '/');
      if (p == NULL)
	p = filename;
      if (__builtin_strncmp (p, "/morestack.S", 12) == 0)
	return 0;
    }

  /* Skip thunks and recover functions.  There is no equivalent to
     these functions in the gc toolchain, so returning them here means
     significantly different results for runtime.Caller(N).  */
  if (function != NULL && !arg->keep_thunks)
    {
      const char *p;

      p = function + __builtin_strlen (function);
      while (p > function && p[-1] >= '0' && p[-1] <= '9')
	--p;
      if (p - function > 7 && __builtin_strncmp (p - 7, "..thunk", 7) == 0)
	return 0;
      if (p - function > 3 && __builtin_strcmp (p - 3, "..r") == 0)
	return 0;
      if (p - function > 6 && __builtin_strncmp (p - 6, "..stub", 6) == 0)
	return 0;
    }

  if (arg->skip > 0)
    {
      --arg->skip;
      return 0;
    }

  loc = &arg->locbuf[arg->index];

  /* On the call to backtrace_full the pc value was most likely
     decremented if there was a normal call, since the pc referred to
     the instruction where the call returned and not the call itself.
     This was done so that the line number referred to the call
     instruction.  To make sure the actual pc from the call stack is
     used, it is incremented here.

     In the case of a signal, the pc was not decremented by
     backtrace_full but still incremented here.  That doesn't really
     hurt anything since the line number is right and the pc refers to
     the same instruction.  */

  loc->pc = pc + 1;

  /* The libbacktrace library says that these strings might disappear,
     but with the current implementation they won't.  We can't easily
     allocate memory here, so for now assume that we can save a
     pointer to the strings.  */
  loc->filename = runtime_gostringnocopy ((const byte *) filename);
  loc->function = runtime_gostringnocopy ((const byte *) function);

  loc->lineno = lineno;
  ++arg->index;

  /* There is no point to tracing past certain runtime functions.
     Stopping the backtrace here can avoid problems on systems that
     don't provide proper unwind information for makecontext, such as
     Solaris (http://gcc.gnu.org/PR52583 comment #21).  */
  if (function != NULL)
    {
      if (__builtin_strcmp (function, "makecontext") == 0)
	return 1;
      if (filename != NULL)
	{
	  const char *p;

	  p = strrchr (filename, '/');
	  if (p == NULL)
	    p = filename;
	  if (__builtin_strcmp (p, "/proc.c") == 0)
	    {
	      if (__builtin_strcmp (function, "runtime_mstart") == 0)
		return 1;
	    }
	  else if (__builtin_strcmp (p, "/proc.go") == 0)
	    {
	      if (__builtin_strcmp (function, "runtime.kickoff") == 0
		  || __builtin_strcmp (function, "runtime.main") == 0)
		return 1;
	    }
	}
    }

  return arg->index >= arg->max;
}

/* Syminfo callback.  */

void
__go_syminfo_fnname_callback (void *data,
			      uintptr_t pc __attribute__ ((unused)),
			      const char *symname,
			      uintptr_t address __attribute__ ((unused)),
			      uintptr_t size __attribute__ ((unused)))
{
  String* strptr = (String*) data;

  if (symname != NULL)
    *strptr = runtime_gostringnocopy ((const byte *) symname);
}

/* Error callback.  */

static void
error_callback (void *data __attribute__ ((unused)),
		const char *msg, int errnum)
{
  if (errnum == -1)
    {
      /* No debug info available.  Carry on as best we can.  */
      return;
    }
  if (errnum != 0)
    runtime_printf ("%s errno %d\n", msg, errnum);
  runtime_throw (msg);
}

/* Return whether we are already collecting a stack trace. This is
   called from the signal handler.  */

bool alreadyInCallers(void)
  __attribute__ ((no_split_stack));
bool alreadyInCallers(void)
  __asm__ (GOSYM_PREFIX "runtime.alreadyInCallers");

bool
alreadyInCallers()
{
  return runtime_atomicload(&__go_runtime_in_callers) > 0;
}

/* Gather caller PC's.  */

int32
runtime_callers (int32 skip, Location *locbuf, int32 m, bool keep_thunks)
{
  struct callers_data data;
  struct backtrace_state* state;
  int32 i;

  data.locbuf = locbuf;
  data.skip = skip + 1;
  data.index = 0;
  data.max = m;
  data.keep_thunks = keep_thunks;
  runtime_xadd (&__go_runtime_in_callers, 1);
  state = __go_get_backtrace_state ();
  backtrace_full (state, 0, callback, error_callback, &data);
  runtime_xadd (&__go_runtime_in_callers, -1);

  /* For some reason GCC sometimes loses the name of a thunk function
     at the top of the stack.  If we are skipping thunks, skip that
     one too.  */
  if (!keep_thunks
      && data.index > 2
      && locbuf[data.index - 2].function.len == 0
      && locbuf[data.index - 1].function.str != NULL
      && __builtin_strcmp ((const char *) locbuf[data.index - 1].function.str,
			   "runtime.kickoff") == 0)
    {
      locbuf[data.index - 2] = locbuf[data.index - 1];
      --data.index;
    }

  /* Try to use backtrace_syminfo to fill in any missing function
     names.  This can happen when tracing through an object which has
     no debug info; backtrace_syminfo will look at the symbol table to
     get the name.  This should only happen when tracing through code
     that is not written in Go and is not part of libgo.  */
  for (i = 0; i < data.index; ++i)
    {
      if (locbuf[i].function.len == 0 && locbuf[i].pc != 0)
	backtrace_syminfo (state, locbuf[i].pc, __go_syminfo_fnname_callback,
			   error_callback, &locbuf[i].function);
    }

  return data.index;
}

intgo Callers (intgo, struct __go_open_array)
  __asm__ (GOSYM_PREFIX "runtime.Callers");

intgo
Callers (intgo skip, struct __go_open_array pc)
{
  Location *locbuf;
  int ret;
  int i;

  /* Note that calling mallocgc here assumes that we are not going to
     store any allocated Go pointers in the slice.  */
  locbuf = (Location *) runtime_mallocgc (pc.__count * sizeof (Location),
					  nil, false);

  /* In the Go 1 release runtime.Callers has an off-by-one error,
     which we can not correct because it would break backward
     compatibility.  Normally we would add 1 to SKIP here, but we
     don't so that we are compatible.  */
  ret = runtime_callers (skip, locbuf, pc.__count, false);

  for (i = 0; i < ret; i++)
    ((uintptr *) pc.__values)[i] = locbuf[i].pc;

  return ret;
}
