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

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(&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, __go_syminfo_fnname_callback,
			   error_callback, &locbuf[i].function);
    }

  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;
}
