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

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