/* 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;
      case DW_EH_PE_absptr:
        return sizeof(uintptr);
      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;

#ifdef __ARM_EABI_UNWINDER__
  {
    _Unwind_Control_Block *ucbp;
    ucbp = (_Unwind_Control_Block *) _Unwind_GetGR (context, 12);
    if (*ucbp->pr_cache.ehtp & (1u << 31))
      // The "compact" model is used, with one of the predefined
      // personality functions. It doesn't have standard LSDA.
      return NOTFOUND_OK;
  }
#endif

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