/* go-unwind.c -- unwind the stack for panic/recover.

   Copyright 2010 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 <stdlib.h>
#include <unistd.h>

#include "unwind.h"

#include "runtime.h"

/* These constants are documented here:
   https://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-PDA/LSB-PDA/dwarfext.html
 */

#define DW_EH_PE_omit     0xff
#define DW_EH_PE_absptr   0x00
#define DW_EH_PE_uleb128  0x01
#define DW_EH_PE_udata2   0x02
#define DW_EH_PE_udata4   0x03
#define DW_EH_PE_udata8   0x04
#define DW_EH_PE_sleb128  0x09
#define DW_EH_PE_sdata2   0x0A
#define DW_EH_PE_sdata4   0x0B
#define DW_EH_PE_sdata8   0x0C
#define DW_EH_PE_pcrel    0x10
#define DW_EH_PE_textrel  0x20
#define DW_EH_PE_datarel  0x30
#define DW_EH_PE_funcrel  0x40
#define DW_EH_PE_aligned  0x50
#define DW_EH_PE_indirect 0x80

/* The code for a Go exception.  */

#ifdef __ARM_EABI_UNWINDER__
static const _Unwind_Exception_Class __go_exception_class =
  { 'G', 'N', 'U', 'C', 'G', 'O', '\0', '\0' };
#else
static const _Unwind_Exception_Class __go_exception_class =
  ((((((((_Unwind_Exception_Class) 'G' 
         << 8 | (_Unwind_Exception_Class) 'N')
        << 8 | (_Unwind_Exception_Class) 'U')
       << 8 | (_Unwind_Exception_Class) 'C')
      << 8 | (_Unwind_Exception_Class) 'G')
     << 8 | (_Unwind_Exception_Class) 'O')
    << 8 | (_Unwind_Exception_Class) '\0')
   << 8 | (_Unwind_Exception_Class) '\0');
#endif

/* Rethrow an exception.  */

void rethrowException (void) __asm__(GOSYM_PREFIX "runtime.rethrowException");

void
rethrowException ()
{
  struct _Unwind_Exception *hdr;

  hdr = (struct _Unwind_Exception *) runtime_g()->exception;

#ifdef __USING_SJLJ_EXCEPTIONS__
  _Unwind_SjLj_Resume_or_Rethrow (hdr);
#else
#if defined(_LIBUNWIND_STD_ABI)
  _Unwind_RaiseException (hdr);
#else
  _Unwind_Resume_or_Rethrow (hdr);
#endif
#endif

  /* Rethrowing the exception should not return.  */
  abort();
}

/* Return the size of the type that holds an exception header, so that
   it can be allocated by Go code.  */

uintptr unwindExceptionSize(void)
  __asm__ (GOSYM_PREFIX "runtime.unwindExceptionSize");

uintptr
unwindExceptionSize ()
{
  uintptr ret, align;

  ret = sizeof (struct _Unwind_Exception);
  /* Adjust the size fo make sure that we can get an aligned value.  */
  align = __alignof__ (struct _Unwind_Exception);
  if (align > __alignof__ (uintptr))
    ret += align - __alignof__ (uintptr);
  return ret;
}

/* Throw an exception.  This is called with g->exception pointing to
   an uninitialized _Unwind_Exception instance.  */

void throwException (void) __asm__(GOSYM_PREFIX "runtime.throwException");

void
throwException ()
{
  struct _Unwind_Exception *hdr;
  uintptr align;

  hdr = (struct _Unwind_Exception *)runtime_g ()->exception;

  /* Make sure the value is correctly aligned.  It will be large
     enough, because of unwindExceptionSize.  */
  align = __alignof__ (struct _Unwind_Exception);
  hdr = ((struct _Unwind_Exception *)
	 (((uintptr) hdr + align - 1) &~ (align - 1)));

  __builtin_memcpy (&hdr->exception_class, &__go_exception_class,
		    sizeof hdr->exception_class);
  hdr->exception_cleanup = NULL;

#ifdef __USING_SJLJ_EXCEPTIONS__
  _Unwind_SjLj_RaiseException (hdr);
#else
  _Unwind_RaiseException (hdr);
#endif

  /* Raising an exception should not return.  */
  abort ();
}

static inline _Unwind_Ptr
encoded_value_base (uint8_t encoding, struct _Unwind_Context *context)
{
  if (encoding == DW_EH_PE_omit)
    return 0;
  switch (encoding & 0x70)
    {
      case DW_EH_PE_absptr:
      case DW_EH_PE_pcrel:
      case DW_EH_PE_aligned:
        return 0;
      case DW_EH_PE_textrel:
        return _Unwind_GetTextRelBase(context);
      case DW_EH_PE_datarel:
        return _Unwind_GetDataRelBase(context);
      case DW_EH_PE_funcrel:
        return _Unwind_GetRegionStart(context);
    }
  abort ();
}

/* Read an unsigned leb128 value.  */

static inline const uint8_t *
read_uleb128 (const uint8_t *p, _uleb128_t *val)
{
  unsigned int shift = 0;
  _uleb128_t result = 0;
  uint8_t byte;

  do
    {
      byte = *p++;
      result |= ((_uleb128_t)byte & 0x7f) << shift;
      shift += 7;
    }
  while (byte & 0x80);

  *val = result;
  return p;
}

/* Similar, but read a signed leb128 value.  */

static inline const uint8_t *
read_sleb128 (const uint8_t *p, _sleb128_t *val)
{
  unsigned int shift = 0;
  _uleb128_t result = 0;
  uint8_t byte;

  do
    {
      byte = *p++;
      result |= ((_uleb128_t)byte & 0x7f) << shift;
      shift += 7;
    }
  while (byte & 0x80);

  /* sign extension */
  if (shift < (8 * sizeof(result)) && (byte & 0x40) != 0)
    result |= (((_uleb128_t)~0) << shift);

  *val = (_sleb128_t)result;
  return p;
}

#define ROUND_UP_TO_PVB(x) (x + sizeof(void *) - 1) &- sizeof(void *)

static inline const uint8_t *
read_encoded_value (struct _Unwind_Context *context, uint8_t encoding,
                    const uint8_t *p, _Unwind_Ptr *val)
{
  _Unwind_Ptr base = encoded_value_base (encoding, context);
  _Unwind_Internal_Ptr decoded = 0;
  const uint8_t *origp = p;

  if (encoding == DW_EH_PE_aligned)
    {
      _Unwind_Internal_Ptr uip = (_Unwind_Internal_Ptr)p;
      uip = ROUND_UP_TO_PVB (uip);
      decoded = *(_Unwind_Internal_Ptr *)uip;
      p = (const uint8_t *)(uip + sizeof(void *));
    }
  else
    {
      switch (encoding & 0x0f)
        {
          case DW_EH_PE_sdata2:
            {
              int16_t result;
              __builtin_memcpy (&result, p, sizeof(int16_t));
              decoded = result;
              p += sizeof(int16_t);
              break;
            }
          case DW_EH_PE_udata2:
            {
              uint16_t result;
              __builtin_memcpy (&result, p, sizeof(uint16_t));
              decoded = result;
              p += sizeof(uint16_t);
              break;
            }
          case DW_EH_PE_sdata4:
            {
              int32_t result;
              __builtin_memcpy (&result, p, sizeof(int32_t));
              decoded = result;
              p += sizeof(int32_t);
              break;
            }
          case DW_EH_PE_udata4:
            {
              uint32_t result;
              __builtin_memcpy (&result, p, sizeof(uint32_t));
              decoded = result;
              p += sizeof(uint32_t);
              break;
            }
          case DW_EH_PE_sdata8:
            {
              int64_t result;
              __builtin_memcpy (&result, p, sizeof(int64_t));
              decoded = result;
              p += sizeof(int64_t);
              break;
            }
          case DW_EH_PE_udata8:
            {
              uint64_t result;
              __builtin_memcpy (&result, p, sizeof(uint64_t));
              decoded = result;
              p += sizeof(uint64_t);
              break;
            }
          case DW_EH_PE_uleb128:
            {
              _uleb128_t value;
              p = read_uleb128 (p, &value);
              decoded = (_Unwind_Internal_Ptr)value;
              break;
            }
          case DW_EH_PE_sleb128:
            {
              _sleb128_t value;
              p = read_sleb128 (p, &value);
              decoded = (_Unwind_Internal_Ptr)value;
              break;
            }
          case DW_EH_PE_absptr:
            __builtin_memcpy (&decoded, (const void *)p, sizeof(const void*));
            p += sizeof(void *);
            break;
          default:
            abort ();
        }

      if (decoded == 0)
        {
          *val = decoded;
          return p;
        }

      if ((encoding & 0x70) == DW_EH_PE_pcrel)
        decoded += ((_Unwind_Internal_Ptr)origp);
      else
        decoded += base;

      if ((encoding & DW_EH_PE_indirect) != 0)
        decoded = *(_Unwind_Internal_Ptr *)decoded;
    }
  *val = decoded;
  return p;
}

static inline int
value_size (uint8_t encoding)
{
  switch (encoding & 0x0f)
    {
      case DW_EH_PE_sdata2:
      case DW_EH_PE_udata2:
        return 2;
      case DW_EH_PE_sdata4:
      case DW_EH_PE_udata4:
        return 4;
      case DW_EH_PE_sdata8:
      case DW_EH_PE_udata8:
        return 8;
      default:
        break;
    }
  abort ();
}

/* The rest of this code is really similar to gcc/unwind-c.c and
   libjava/exception.cc.  */

typedef struct
{
  _Unwind_Ptr Start;
  _Unwind_Ptr LPStart;
  _Unwind_Ptr ttype_base;
  const unsigned char *TType;
  const unsigned char *action_table;
  unsigned char ttype_encoding;
  unsigned char call_site_encoding;
} lsda_header_info;

static const unsigned char *
parse_lsda_header (struct _Unwind_Context *context, const unsigned char *p,
		   lsda_header_info *info)
{
  _uleb128_t tmp;
  unsigned char lpstart_encoding;

  info->Start = (context ? _Unwind_GetRegionStart (context) : 0);

  /* Find @LPStart, the base to which landing pad offsets are relative.  */
  lpstart_encoding = *p++;
  if (lpstart_encoding != DW_EH_PE_omit)
    p = read_encoded_value (context, lpstart_encoding, p, &info->LPStart);
  else
    info->LPStart = info->Start;

  /* Find @TType, the base of the handler and exception spec type data.  */
  info->ttype_encoding = *p++;
  if (info->ttype_encoding != DW_EH_PE_omit)
    {
      p = read_uleb128 (p, &tmp);
      info->TType = p + tmp;
    }
  else
    info->TType = 0;

  /* The encoding and length of the call-site table; the action table
     immediately follows.  */
  info->call_site_encoding = *p++;
  p = read_uleb128 (p, &tmp);
  info->action_table = p + tmp;

  return p;
}

/* The personality function is invoked when unwinding the stack due to
   a panic.  Its job is to find the cleanup and exception handlers to
   run.  We can't split the stack here, because we won't be able to
   unwind from that split.  */

#ifdef __ARM_EABI_UNWINDER__
/* ARM EABI personality routines must also unwind the stack.  */
#define CONTINUE_UNWINDING \
  do								\
    {								\
      if (__gnu_unwind_frame (ue_header, context) != _URC_OK)	\
	return _URC_FAILURE;					\
      return _URC_CONTINUE_UNWIND;				\
    }								\
  while (0)
#else
#define CONTINUE_UNWINDING return _URC_CONTINUE_UNWIND
#endif

#ifdef __ARM_EABI_UNWINDER__
#define STOP_UNWINDING _URC_FAILURE
#else
#define STOP_UNWINDING _URC_NORMAL_STOP
#endif

#ifdef __USING_SJLJ_EXCEPTIONS__
#define PERSONALITY_FUNCTION    __gccgo_personality_sj0
#define __builtin_eh_return_data_regno(x) x
#else
#define PERSONALITY_FUNCTION    __gccgo_personality_v0
#endif

#ifdef __ARM_EABI_UNWINDER__
_Unwind_Reason_Code
PERSONALITY_FUNCTION (_Unwind_State, struct _Unwind_Exception *,
		      struct _Unwind_Context *)
  __attribute__ ((no_split_stack, flatten));

_Unwind_Reason_Code
PERSONALITY_FUNCTION (_Unwind_State state,
		      struct _Unwind_Exception * ue_header,
		      struct _Unwind_Context * context)
#else
_Unwind_Reason_Code
PERSONALITY_FUNCTION (int, _Unwind_Action, _Unwind_Exception_Class,
		      struct _Unwind_Exception *, struct _Unwind_Context *)
  __attribute__ ((no_split_stack, flatten));

_Unwind_Reason_Code
PERSONALITY_FUNCTION (int version,
		      _Unwind_Action actions,
		      _Unwind_Exception_Class exception_class,
		      struct _Unwind_Exception *ue_header,
		      struct _Unwind_Context *context)
#endif
{
  lsda_header_info info;
  const unsigned char *language_specific_data, *p, *action_record;
  _Unwind_Ptr landing_pad, ip;
  int ip_before_insn = 0;
  _Bool is_foreign;
  G *g;

#ifdef __ARM_EABI_UNWINDER__
  _Unwind_Action actions;

  switch (state & _US_ACTION_MASK)
    {
    case _US_VIRTUAL_UNWIND_FRAME:
      actions = _UA_SEARCH_PHASE;
      break;

    case _US_UNWIND_FRAME_STARTING:
      actions = _UA_CLEANUP_PHASE;
      if (!(state & _US_FORCE_UNWIND)
	  && ue_header->barrier_cache.sp == _Unwind_GetGR(context, 13))
	actions |= _UA_HANDLER_FRAME;
      break;

    case _US_UNWIND_FRAME_RESUME:
      CONTINUE_UNWINDING;
      break;

    default:
      abort();
    }
  actions |= state & _US_FORCE_UNWIND;

  is_foreign = 0;

  /* The dwarf unwinder assumes the context structure holds things like the
     function and LSDA pointers.  The ARM implementation caches these in
     the exception header (UCB).  To avoid rewriting everything we make the
     virtual IP register point at the UCB.  */
  ip = (_Unwind_Ptr) ue_header;
  _Unwind_SetGR (context, 12, ip);
#else
  if (version != 1)
    return _URC_FATAL_PHASE1_ERROR;

  is_foreign = exception_class != __go_exception_class;
#endif

  language_specific_data = (const unsigned char *)
    _Unwind_GetLanguageSpecificData (context);

  /* If no LSDA, then there are no handlers or cleanups.  */
  if (! language_specific_data)
    CONTINUE_UNWINDING;

  /* Parse the LSDA header.  */
  p = parse_lsda_header (context, language_specific_data, &info);
#ifdef HAVE_GETIPINFO
  ip = _Unwind_GetIPInfo (context, &ip_before_insn);
#else
  ip = _Unwind_GetIP (context);
#endif
  if (! ip_before_insn)
    --ip;
  landing_pad = 0;
  action_record = NULL;

#ifdef __USING_SJLJ_EXCEPTIONS__
  /* The given "IP" is an index into the call-site table, with two
     exceptions -- -1 means no-action, and 0 means terminate.  But
     since we're using uleb128 values, we've not got random access
     to the array.  */
  if ((int) ip <= 0)
    return _URC_CONTINUE_UNWIND;
  else
    {
      _uleb128_t cs_lp, cs_action;
      do
	{
	  p = read_uleb128 (p, &cs_lp);
	  p = read_uleb128 (p, &cs_action);
	}
      while (--ip);

      /* Can never have null landing pad for sjlj -- that would have
	 been indicated by a -1 call site index.  */
      landing_pad = (_Unwind_Ptr)cs_lp + 1;
      if (cs_action)
	action_record = info.action_table + cs_action - 1;
      goto found_something;
    }
#else
  /* Search the call-site table for the action associated with this IP.  */
  while (p < info.action_table)
    {
      _Unwind_Ptr cs_start, cs_len, cs_lp;
      _uleb128_t cs_action;

      /* Note that all call-site encodings are "absolute" displacements.  */
      p = read_encoded_value (0, info.call_site_encoding, p, &cs_start);
      p = read_encoded_value (0, info.call_site_encoding, p, &cs_len);
      p = read_encoded_value (0, info.call_site_encoding, p, &cs_lp);
      p = read_uleb128 (p, &cs_action);

      /* The table is sorted, so if we've passed the ip, stop.  */
      if (ip < info.Start + cs_start)
	p = info.action_table;
      else if (ip < info.Start + cs_start + cs_len)
	{
	  if (cs_lp)
	    landing_pad = info.LPStart + cs_lp;
	  if (cs_action)
	    action_record = info.action_table + cs_action - 1;
	  goto found_something;
	}
    }
#endif

  /* IP is not in table.  No associated cleanups.  */
  CONTINUE_UNWINDING;

 found_something:
  if (landing_pad == 0)
    {
      /* IP is present, but has a null landing pad.
	 No handler to be run.  */
      CONTINUE_UNWINDING;
    }

  if (actions & _UA_SEARCH_PHASE)
    {
      if (action_record == 0)
	{
	  /* This indicates a cleanup rather than an exception
	     handler.  */
	  CONTINUE_UNWINDING;
	}

      return _URC_HANDLER_FOUND;
    }

  /* It's possible for g to be NULL here for an exception thrown by a
     language other than Go.  */
  g = runtime_g ();
  if (g == NULL)
    {
      if (!is_foreign)
	abort ();
    }
  else
    {
      g->exception = ue_header;
      g->isforeign = is_foreign;
    }

  _Unwind_SetGR (context, __builtin_eh_return_data_regno (0),
		 (_Unwind_Ptr) ue_header);
  _Unwind_SetGR (context, __builtin_eh_return_data_regno (1), 0);
  _Unwind_SetIP (context, landing_pad);
  return _URC_INSTALL_CONTEXT;
}

// A dummy personality function, which doesn't capture any exception
// and simply passes by. This is used for functions that don't
// capture exceptions but need LSDA for stack maps.
_Unwind_Reason_Code
__gccgo_personality_dummy (int, _Unwind_Action, _Unwind_Exception_Class,
		      struct _Unwind_Exception *, struct _Unwind_Context *)
  __attribute__ ((no_split_stack));

_Unwind_Reason_Code
__gccgo_personality_dummy (int version __attribute__ ((unused)),
		      _Unwind_Action actions __attribute__ ((unused)),
		      _Unwind_Exception_Class exception_class __attribute__ ((unused)),
		      struct _Unwind_Exception *ue_header __attribute__ ((unused)),
		      struct _Unwind_Context *context __attribute__ ((unused)))
{
  CONTINUE_UNWINDING;
}

// A sentinel value for Go functions.
// A function is a Go function if it has LSDA, which has type info,
// and the first (dummy) landing pad's type info is a pointer to
// this value.
#define GO_FUNC_SENTINEL ((uint64)'G' | ((uint64)'O'<<8) | \
                          ((uint64)'.'<<16) | ((uint64)'.'<<24) | \
                          ((uint64)'F'<<32) | ((uint64)'U'<<40) | \
                          ((uint64)'N'<<48) | ((uint64)'C'<<56))

struct _stackmap {
  uint32 len;
  uint8 data[1]; // variabe length
};

extern void
  runtime_scanstackblockwithmap (uintptr ip, uintptr sp, uintptr size, uint8 *ptrmask, void* gcw)
  __asm__ (GOSYM_PREFIX "runtime.scanstackblockwithmap");

#define FOUND        0
#define NOTFOUND_OK  1
#define NOTFOUND_BAD 2

// Helper function to search for stack maps in the unwinding records of a frame.
// If found, populate ip, sp, and stackmap. Returns the #define'd values above.
static int
findstackmaps (struct _Unwind_Context *context, _Unwind_Ptr *ip, _Unwind_Ptr *sp, struct _stackmap **stackmap)
{
  lsda_header_info info;
  const unsigned char *language_specific_data, *p, *action_record;
  bool first;
  struct _stackmap *stackmap1;
  _Unwind_Ptr ip1;
  int ip_before_insn = 0;
  _sleb128_t index;
  int size;

  language_specific_data = (const unsigned char *)
    _Unwind_GetLanguageSpecificData (context);

  /* If no LSDA, then there is no stack maps.  */
  if (! language_specific_data)
    return NOTFOUND_OK;

  p = parse_lsda_header (context, language_specific_data, &info);

  if (info.TType == NULL)
    return NOTFOUND_OK;

#ifdef HAVE_GETIPINFO
  ip1 = _Unwind_GetIPInfo (context, &ip_before_insn);
#else
  ip1 = _Unwind_GetIP (context);
#endif
  if (! ip_before_insn)
    --ip1;

  size = value_size (info.ttype_encoding);

  action_record = NULL;
  first = true;

  /* Search the call-site table for the action associated with this IP.  */
  while (p < info.action_table)
    {
      _Unwind_Ptr cs_start, cs_len, cs_lp;
      _uleb128_t cs_action;

      /* Note that all call-site encodings are "absolute" displacements.  */
      p = read_encoded_value (0, info.call_site_encoding, p, &cs_start);
      p = read_encoded_value (0, info.call_site_encoding, p, &cs_len);
      p = read_encoded_value (0, info.call_site_encoding, p, &cs_lp);
      p = read_uleb128 (p, &cs_action);

      if (first)
        {
          // For a Go function, the first entry points to the sentinel value.
          // Check this here.
          const unsigned char *p1, *action1;
          uint64 *x;

          if (!cs_action)
            return NOTFOUND_OK;

          action1 = info.action_table + cs_action - 1;
          read_sleb128 (action1, &index);
          p1 = info.TType - index*size;
          read_encoded_value (context, info.ttype_encoding, p1, (_Unwind_Ptr*)&x);
          if (x == NULL || *x != GO_FUNC_SENTINEL)
            return NOTFOUND_OK;

          first = false;
          continue;
        }

      /* The table is sorted, so if we've passed the ip, stop.  */
      if (ip1 < info.Start + cs_start)
        return NOTFOUND_BAD;
      else if (ip1 < info.Start + cs_start + cs_len)
        {
          if (cs_action)
            action_record = info.action_table + cs_action - 1;
          break;
        }
    }

  if (action_record == NULL)
    return NOTFOUND_BAD;

  read_sleb128 (action_record, &index);
  p = info.TType - index*size;
  read_encoded_value (context, info.ttype_encoding, p, (_Unwind_Ptr*)&stackmap1);
  if (stackmap1 == NULL)
    return NOTFOUND_BAD;

  if (ip != NULL)
    *ip = ip1;
  if (sp != NULL)
    *sp = _Unwind_GetCFA (context);
  if (stackmap != NULL)
    *stackmap = stackmap1;
  return FOUND;
}

// Callback function to scan a stack frame with stack maps.
// It skips non-Go functions.
static _Unwind_Reason_Code
scanstackwithmap_callback (struct _Unwind_Context *context, void *arg)
{
  struct _stackmap *stackmap;
  _Unwind_Ptr ip, sp;
  G* gp;
  void *gcw = arg;

  switch (findstackmaps (context, &ip, &sp, &stackmap))
    {
      case NOTFOUND_OK:
        // Not a Go function. Skip this frame.
        return _URC_NO_REASON;
      case NOTFOUND_BAD:
        {
          // No stack map found.
          // If we're scanning from the signal stack, the goroutine
          // may be not stopped at a safepoint. Allow this case.
          gp = runtime_g ();
          if (gp != gp->m->gsignal)
            {
              // TODO: print gp, pc, sp
              runtime_throw ("no stack map");
            }
          return STOP_UNWINDING;
        }
      case FOUND:
        break;
      default:
        abort ();
    }

  runtime_scanstackblockwithmap (ip, sp, (uintptr)(stackmap->len) * sizeof(uintptr), stackmap->data, gcw);

  return _URC_NO_REASON;
}

// Scan the stack with stack maps. Return whether the scan
// succeeded.
bool
scanstackwithmap (void *gcw)
{
  _Unwind_Reason_Code code;
  code = _Unwind_Backtrace (scanstackwithmap_callback, gcw);
  return code == _URC_END_OF_STACK;
}

// Returns whether stack map is enabled.
bool
usestackmaps ()
{
  return runtime_usestackmaps;
}

// Callback function to probe if a stack frame has stack maps.
static _Unwind_Reason_Code
probestackmaps_callback (struct _Unwind_Context *context,
                         void *arg __attribute__ ((unused)))
{
  switch (findstackmaps (context, NULL, NULL, NULL))
    {
      case NOTFOUND_OK:
      case NOTFOUND_BAD:
        return _URC_NO_REASON;
      case FOUND:
        break;
      default:
        abort ();
    }

  // Found a stack map. No need to keep unwinding.
  runtime_usestackmaps = true;
  return STOP_UNWINDING;
}

// Try to find a stack map, store the result in global variable runtime_usestackmaps.
// Called in start-up time from Go code, so there is a Go frame on the stack.
bool
probestackmaps ()
{
  runtime_usestackmaps = false;
  _Unwind_Backtrace (probestackmaps_callback, NULL);
  return runtime_usestackmaps;
}
