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

/* Collect file/line information for a PC value.  If this is called
   more than once, due to inlined functions, we use 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;

  /* 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)
    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 (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 information for PC.  The index parameter
   is the entry on the stack of inlined functions; -1 means the last
   one.  */

_Bool
__go_file_line (uintptr pc, int index, String *fn, String *file, intgo *line)
{
  struct caller c;

  runtime_memclr (&c, sizeof c);
  c.index = index;
  backtrace_pcinfo (__go_get_backtrace_state (), pc, callback,
		    error_callback, &c);
  *fn = c.fn;
  *file = c.file;
  *line = c.line;
  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_t pc, uintptr_t *val)
{
  *val = 0;
  backtrace_syminfo (__go_get_backtrace_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 (int n) __asm__ (GOSYM_PREFIX "runtime.Caller");

/* Implement runtime.Caller.  */

struct caller_ret
Caller (int 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
{
  String retfn;
  String retfile;
  intgo retline;
};

struct funcfileline_return
runtime_funcfileline (uintptr targetpc, int32 index)
  __asm__ (GOSYM_PREFIX "runtime.funcfileline");

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

  if (!__go_file_line (targetpc, index, &ret.retfn, &ret.retfile,
		       &ret.retline))
    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;
}
