/* go-caller.c -- look up function/file/line/entry info

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

/* Implement runtime.Caller.  */

#include <stdint.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#include "backtrace.h"

#include "runtime.h"

/* Get the function name, file name, and line number for a PC value.
   We use the backtrace library to get this.  */

/* Data structure to gather file/line information.  */

struct caller
{
  String fn;
  String file;
  intgo line;
  intgo index;
  intgo frames;
  bool more;
};

/* Collect file/line information for a PC value.  If this is called
   more than once, due to inlined functions, we record the number of
   inlined frames but return file/func/line for the last call, as
   that is usually the most useful one.   */

static int
callback (void *data, uintptr_t pc __attribute__ ((unused)),
	  const char *filename, int lineno, const char *function)
{
  struct caller *c = (struct caller *) data;

  /* We want to make sure we return at least one frame.  If we already
     have at least one frame, see if we should skip this one.  */
  if (c->frames > 0
      && function != NULL
      && runtime_skipInCallback (function, NULL))
    return 0;

  /* If we already have a frame, don't increment frames if we should
     skip that one.  */
  if (c->frames == 0
      || c->fn.len == 0
      || !runtime_skipInCallback ((const char *) c->fn.str, NULL))
    c->frames++;

  /* 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.  */
  c->fn = runtime_gostringnocopy ((const byte *) function);
  c->file = runtime_gostringnocopy ((const byte *) filename);
  c->line = lineno;

  if (c->index == 0)
    {
      /* If there are more frames after the indexed one, and we should
	 skip this one, then skip it.  */
      if (c->more
	  && c->fn.len > 0
	  && runtime_skipInCallback((const char *) c->fn.str, NULL))
	return 0;

      return 1;
    }

  if (c->index > 0)
    --c->index;

  return 0;
}

/* The error callback for backtrace_pcinfo and backtrace_syminfo.  */

static void
error_callback (void *data __attribute__ ((unused)),
		const char *msg, int errnum)
{
  if (errnum == -1)
    return;
  if (errnum > 0)
    runtime_printf ("%s errno %d\n", msg, errnum);
  runtime_throw (msg);
}

/* The backtrace library state.  */

static void *back_state;

/* A lock to control creating back_state.  */

static uint32 back_state_lock;

/* The program arguments.  */

extern Slice runtime_get_args(void);

/* Fetch back_state, creating it if necessary.  */

struct backtrace_state *
__go_get_backtrace_state ()
{
  uint32 set;

  /* We may not have a g here, so we can't use runtime_lock.  */
  set = 0;
  while (!__atomic_compare_exchange_n (&back_state_lock, &set, 1, false, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED))
    {
      runtime_osyield ();
      set = 0;
    }
  if (back_state == NULL)
    {
      Slice args;
      const char *filename;
      struct stat s;

      args = runtime_get_args();
      filename = NULL;
      if (args.__count > 0)
	filename = (const char*)((String*)args.__values)[0].str;

      /* If there is no '/' in FILENAME, it was found on PATH, and
	 might not be the same as the file with the same name in the
	 current directory.  */
      if (filename != NULL && __builtin_strchr (filename, '/') == NULL)
	filename = NULL;

      /* If the file is small, then it's not the real executable.
	 This is specifically to deal with Docker, which uses a bogus
	 argv[0] (http://gcc.gnu.org/PR61895).  It would be nice to
	 have a better check for whether this file is the real
	 executable.  */
      if (filename != NULL && (stat (filename, &s) < 0 || s.st_size < 1024))
	filename = NULL;

      back_state = backtrace_create_state (filename, 1, error_callback, NULL);
    }
  __atomic_store_n (&back_state_lock, 0, __ATOMIC_RELEASE);
  return back_state;
}

/* Return function/file/line/nframes information for PC.  The index
   parameter is the entry on the stack of inlined functions; -1 means
   the last one, with *nframes set to the count of inlined frames for
   this PC.  If index is not -1, more is whether there are more frames
   after this one.  */

static _Bool
__go_file_line (uintptr pc, int index, bool more, String *fn, String *file, intgo *line, intgo *nframes)
{
  struct caller c;
  struct backtrace_state *state;

  runtime_memclr (&c, sizeof c);
  c.index = index;
  c.more = more;
  c.frames = 0;
  runtime_xadd (&__go_runtime_in_callers, 1);
  state = __go_get_backtrace_state ();
  runtime_xadd (&__go_runtime_in_callers, -1);
  backtrace_pcinfo (state, pc, callback, error_callback, &c);
  *fn = c.fn;
  *file = c.file;
  *line = c.line;
  *nframes = c.frames;

  // If backtrace_pcinfo didn't get the function name from the debug
  // info, try to get it from the symbol table.
  if (fn->len == 0)
    backtrace_syminfo (state, pc, __go_syminfo_fnname_callback,
		       error_callback, fn);

  return c.file.len > 0;
}

/* Collect symbol information.  */

static void
syminfo_callback (void *data, uintptr_t pc __attribute__ ((unused)),
		  const char *symname __attribute__ ((unused)),
		  uintptr_t address, uintptr_t size __attribute__ ((unused)))
{
  uintptr_t *pval = (uintptr_t *) data;

  *pval = address;
}

/* Set *VAL to the value of the symbol for PC.  */

static _Bool
__go_symbol_value (uintptr pc, uintptr *val)
{
  struct backtrace_state *state;

  *val = 0;
  runtime_xadd (&__go_runtime_in_callers, 1);
  state = __go_get_backtrace_state ();
  runtime_xadd (&__go_runtime_in_callers, -1);
  backtrace_syminfo (state, pc, syminfo_callback,
		     error_callback, val);
  return *val != 0;
}

/* The values returned by runtime.Caller.  */

struct caller_ret
{
  uintptr_t pc;
  String file;
  intgo line;
  _Bool ok;
};

struct caller_ret Caller (intgo n) __asm__ (GOSYM_PREFIX "runtime.Caller");

/* Implement runtime.Caller.  */

struct caller_ret
Caller (intgo skip)
{
  struct caller_ret ret;
  Location loc;
  int32 n;

  runtime_memclr (&ret, sizeof ret);
  n = runtime_callers (skip + 1, &loc, 1, false);
  if (n < 1 || loc.pc == 0)
    return ret;
  ret.pc = loc.pc;
  ret.file = loc.filename;
  ret.line = loc.lineno;
  ret.ok = 1;
  return ret;
}

/* Look up the function name, file name, and line number for a PC.  */

struct funcfileline_return
runtime_funcfileline (uintptr targetpc, int32 index, bool more)
{
  struct funcfileline_return ret;

  if (!__go_file_line (targetpc, index, more, &ret.retfn, &ret.retfile,
		       &ret.retline, &ret.retframes))
    runtime_memclr (&ret, sizeof ret);
  return ret;
}

/* Return the entry point of a function.  */
uintptr runtime_funcentry(uintptr)
  __asm__ (GOSYM_PREFIX "runtime.funcentry");

uintptr
runtime_funcentry (uintptr pc)
{
  uintptr val;

  if (!__go_symbol_value (pc, &val))
    return 0;
  return val;
}
