/* 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.  */

static uint32 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_strcmp (p - 6, "..stub") == 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.  */

static void
syminfo_fnname_callback (void *data, uintptr_t pc __attribute__ ((unused)),
			 const char *symname,
			 uintptr_t address __attribute__ ((unused)),
			 uintptr_t size __attribute__ ((unused)))
{
  Location* locptr = (Location*) data;

  if (symname != NULL)
    locptr->function = 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(&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;
  state = __go_get_backtrace_state ();
  runtime_xadd (&runtime_in_callers, 1);
  backtrace_full (state, 0, callback, error_callback, &data);
  runtime_xadd (&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, syminfo_fnname_callback,
			   error_callback, &locbuf[i]);
    }

  return data.index;
}

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

int
Callers (int 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;
}
