/* Copyright 2018 The BoringSSL Authors
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

#include "abi_test.h"

#include <stdarg.h>
#include <stdio.h>

#include <algorithm>
#include <array>

#include <openssl/mem.h>
#include <openssl/rand.h>
#include <openssl/span.h>

#if defined(OPENSSL_X86_64) && defined(SUPPORTS_ABI_TEST)
#if defined(OPENSSL_LINUX) && defined(BORINGSSL_HAVE_LIBUNWIND)
#define SUPPORTS_UNWIND_TEST
#define UNW_LOCAL_ONLY
#include <errno.h>
#include <fcntl.h>
#include <libunwind.h>
#include <pthread.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#elif defined(OPENSSL_WINDOWS)
#define SUPPORTS_UNWIND_TEST
OPENSSL_MSVC_PRAGMA(warning(push, 3))
#include <windows.h>
#include <dbghelp.h>
OPENSSL_MSVC_PRAGMA(warning(pop))
#endif
#endif  // X86_64 && SUPPORTS_ABI_TEST

// FIPS mode breaks unwind tests. See https://crbug.com/boringssl/289.
#if defined(BORINGSSL_FIPS)
#undef SUPPORTS_UNWIND_TEST
#endif


namespace abi_test {

namespace internal {

static bool g_unwind_tests_enabled = false;

std::string FixVAArgsString(const char *str) {
  std::string ret = str;
  size_t idx = ret.find(',');
  if (idx == std::string::npos) {
    return ret + "()";
  }
  size_t idx2 = idx + 1;
  while (idx2 < ret.size() && ret[idx2] == ' ') {
    idx2++;
  }
  while (idx > 0 && ret[idx - 1] == ' ') {
    idx--;
  }
  return ret.substr(0, idx) + "(" + ret.substr(idx2) + ")";
}

#if defined(SUPPORTS_ABI_TEST)
// ForEachMismatch calls |func| for each register where |a| and |b| differ.
template <typename Func>
static void ForEachMismatch(const CallerState &a, const CallerState &b,
                            const Func &func) {
#define CALLER_STATE_REGISTER(type, name) \
  if (a.name != b.name) {                 \
    func(#name);                          \
  }
  LOOP_CALLER_STATE_REGISTERS()
#undef CALLER_STATE_REGISTER
}
#endif  // SUPPORTS_ABI_TEST

#if defined(SUPPORTS_UNWIND_TEST)
// We test unwind metadata by running the function under test with the trap flag
// set. This results in |SIGTRAP| and |EXCEPTION_SINGLE_STEP| on Linux and
// Windows, respectively. We hande these and verify libunwind or the Windows
// unwind APIs unwind successfully.

// IsAncestorStackFrame returns true if |a_sp| is an ancestor stack frame of
// |b_sp|.
static bool IsAncestorStackFrame(crypto_word_t a_sp, crypto_word_t b_sp) {
#if defined(OPENSSL_X86_64)
  // The stack grows down, so ancestor stack frames have higher addresses.
  return a_sp > b_sp;
#else
#error "unknown architecture"
#endif
}

// Implement some string formatting utilties. Ideally we would use |snprintf|,
// but this is called in a signal handler and |snprintf| is not async-signal-
// safe.

#if !defined(OPENSSL_WINDOWS)
static std::array<char, DECIMAL_SIZE(crypto_word_t) + 1> WordToDecimal(
    crypto_word_t v) {
  std::array<char, DECIMAL_SIZE(crypto_word_t) + 1> ret;
  size_t len = 0;
  do {
    ret[len++] = '0' + v % 10;
    v /= 10;
  } while (v != 0);
  for (size_t i = 0; i < len / 2; i++) {
    std::swap(ret[i], ret[len - 1 - i]);
  }
  ret[len] = '\0';
  return ret;
}
#endif  // !OPENSSL_WINDOWS

static std::array<char, sizeof(crypto_word_t) * 2 + 1> WordToHex(
    crypto_word_t v) {
  static const char kHex[] = "0123456789abcdef";
  std::array<char, sizeof(crypto_word_t) * 2 + 1> ret;
  for (size_t i = sizeof(crypto_word_t) - 1; i < sizeof(crypto_word_t); i--) {
    uint8_t b = v & 0xff;
    v >>= 8;
    ret[i * 2] = kHex[b >> 4];
    ret[i * 2 + 1] = kHex[b & 0xf];
  }
  ret[sizeof(crypto_word_t) * 2] = '\0';
  return ret;
}

static void StrCatSignalSafeImpl(bssl::Span<char> out) {}

template <typename... Args>
static void StrCatSignalSafeImpl(bssl::Span<char> out, const char *str,
                                 Args... args) {
  OPENSSL_strlcat(out.data(), str, out.size());
  StrCatSignalSafeImpl(out, args...);
}

template <typename... Args>
static void StrCatSignalSafe(bssl::Span<char> out, Args... args) {
  if (out.empty()) {
    return;
  }
  out[0] = '\0';
  StrCatSignalSafeImpl(out, args...);
}

template <typename... Args>
[[noreturn]] static void FatalError(Args... args) {
  // We cannot use |snprintf| here because it is not async-signal-safe.
  char buf[512];
  StrCatSignalSafe(buf, args..., "\n");
#if defined(OPENSSL_WINDOWS)
  HANDLE stderr_handle = GetStdHandle(STD_ERROR_HANDLE);
  if (stderr_handle != INVALID_HANDLE_VALUE) {
    DWORD unused;
    WriteFile(stderr_handle, buf, strlen(buf), &unused, nullptr);
  }
#else
  ssize_t ret = write(STDERR_FILENO, buf, strlen(buf));
  // We'll abort soon anyway, so if we fail to write the message, there's
  // nothing to do.
  (void)ret;
#endif
  abort();
}

class UnwindStatus {
 public:
  UnwindStatus() : err_(nullptr) {}
  explicit UnwindStatus(const char *err) : err_(err) {}

  bool ok() const { return err_ == nullptr; }
  const char *Error() const { return err_; }

 private:
  const char *err_;
};

template<typename T>
class UnwindStatusOr {
 public:
  UnwindStatusOr(UnwindStatus status) : status_(status) {
    assert(!status_.ok());
  }

  UnwindStatusOr(const T &value) : status_(UnwindStatus()), value_(value) {}

  bool ok() const { return status_.ok(); }
  const char *Error() const { return status_.Error(); }

  const T &ValueOrDie(const char *msg = "Unexpected error") const {
    if (!ok()) {
      FatalError(msg, ": ", Error());
    }
    return value_;
  }

 private:
  UnwindStatus status_;
  T value_;
};

// UnwindCursor abstracts between libunwind and Windows unwind APIs. It is
// async-signal-safe.
#if defined(OPENSSL_WINDOWS)
class UnwindCursor {
 public:
  explicit UnwindCursor(const CONTEXT &ctx) : ctx_(ctx) {
    starting_ip_ = ctx_.Rip;
  }

  crypto_word_t starting_ip() const { return starting_ip_; }

  // Step unwinds the cursor by one frame. On success, it returns whether there
  // were more frames to unwind.
  UnwindStatusOr<bool> Step() {
    bool is_top = is_top_;
    is_top_ = false;

    DWORD64 image_base;
    RUNTIME_FUNCTION *entry =
        RtlLookupFunctionEntry(ctx_.Rip, &image_base, nullptr);
    if (entry == nullptr) {
      // This is a leaf function. Leaf functions do not touch stack or
      // callee-saved registers, so they may be unwound by simulating a ret.
      if (!is_top) {
        return UnwindStatus("leaf function found below the top frame");
      }
      memcpy(&ctx_.Rip, reinterpret_cast<const void *>(ctx_.Rsp),
             sizeof(ctx_.Rip));
      ctx_.Rsp += 8;
      return true;
    }

    // This is a frame function. Call into the Windows unwinder.
    void *handler_data;
    DWORD64 establisher_frame;
    RtlVirtualUnwind(UNW_FLAG_NHANDLER, image_base, ctx_.Rip, entry, &ctx_,
                     &handler_data, &establisher_frame, nullptr);
    return ctx_.Rip != 0;
  }

  // GetIP returns the instruction pointer at the current frame.
  UnwindStatusOr<crypto_word_t> GetIP() { return ctx_.Rip; }

  // GetSP returns the stack pointer at the current frame.
  UnwindStatusOr<crypto_word_t> GetSP() { return ctx_.Rsp; }

  // GetCallerState returns the callee-saved registers at the current frame.
  UnwindStatusOr<CallerState> GetCallerState() {
    CallerState state;
    state.rbx = ctx_.Rbx;
    state.rbp = ctx_.Rbp;
    state.rdi = ctx_.Rdi;
    state.rsi = ctx_.Rsi;
    state.r12 = ctx_.R12;
    state.r13 = ctx_.R13;
    state.r14 = ctx_.R14;
    state.r15 = ctx_.R15;
    memcpy(&state.xmm6, &ctx_.Xmm6, sizeof(Reg128));
    memcpy(&state.xmm7, &ctx_.Xmm7, sizeof(Reg128));
    memcpy(&state.xmm8, &ctx_.Xmm8, sizeof(Reg128));
    memcpy(&state.xmm9, &ctx_.Xmm9, sizeof(Reg128));
    memcpy(&state.xmm10, &ctx_.Xmm10, sizeof(Reg128));
    memcpy(&state.xmm11, &ctx_.Xmm11, sizeof(Reg128));
    memcpy(&state.xmm12, &ctx_.Xmm12, sizeof(Reg128));
    memcpy(&state.xmm13, &ctx_.Xmm13, sizeof(Reg128));
    memcpy(&state.xmm14, &ctx_.Xmm14, sizeof(Reg128));
    memcpy(&state.xmm15, &ctx_.Xmm15, sizeof(Reg128));
    return state;
  }

  // ToString returns a human-readable representation of the address the cursor
  // started at.
  const char *ToString() {
    StrCatSignalSafe(starting_ip_buf_, "0x", WordToHex(starting_ip_).data());
    return starting_ip_buf_;
  }

 private:
  CONTEXT ctx_;
  crypto_word_t starting_ip_;
  char starting_ip_buf_[64];
  bool is_top_ = true;
};
#else  // !OPENSSL_WINDOWS
class UnwindCursor {
 public:
  explicit UnwindCursor(unw_context_t *ctx) : ctx_(ctx) {
    int ret = unw_init_local2(&cursor_, ctx_, UNW_INIT_SIGNAL_FRAME);
    if (ret < 0) {
      FatalError("Error getting unwind context: ", unw_strerror(ret));
    }
    starting_ip_ = GetIP().ValueOrDie("Error getting instruction pointer");
  }

  // Step unwinds the cursor by one frame. On success, it returns whether there
  // were more frames to unwind.
  UnwindStatusOr<bool> Step() {
    int ret = unw_step(&cursor_);
    if (ret < 0) {
      return UNWError(ret);
    }
    return ret != 0;
  }

  // GetIP returns the instruction pointer at the current frame.
  UnwindStatusOr<crypto_word_t> GetIP() {
    crypto_word_t ip;
    int ret = GetReg(&ip, UNW_REG_IP);
    if (ret < 0) {
      return UNWError(ret);
    }
    return ip;
  }

  // GetSP returns the stack pointer at the current frame.
  UnwindStatusOr<crypto_word_t> GetSP() {
    crypto_word_t sp;
    int ret = GetReg(&sp, UNW_REG_SP);
    if (ret < 0) {
      return UNWError(ret);
    }
    return sp;
  }

  // GetCallerState returns the callee-saved registers at the current frame.
  UnwindStatusOr<CallerState> GetCallerState() {
    CallerState state;
    int ret = 0;
#if defined(OPENSSL_X86_64)
    ret = ret < 0 ? ret : GetReg(&state.rbx, UNW_X86_64_RBX);
    ret = ret < 0 ? ret : GetReg(&state.rbp, UNW_X86_64_RBP);
    ret = ret < 0 ? ret : GetReg(&state.r12, UNW_X86_64_R12);
    ret = ret < 0 ? ret : GetReg(&state.r13, UNW_X86_64_R13);
    ret = ret < 0 ? ret : GetReg(&state.r14, UNW_X86_64_R14);
    ret = ret < 0 ? ret : GetReg(&state.r15, UNW_X86_64_R15);
#else
#error "unknown architecture"
#endif
    if (ret < 0) {
      return UNWError(ret);
    }
    return state;
  }

  // ToString returns a human-readable representation of the address the cursor
  // started at, using debug information if available.
  const char *ToString() {
    // Use a new cursor. |cursor_| has already been unwound, and
    // |unw_get_proc_name| is slow so we do not sample it unconditionally in the
    // constructor.
    unw_cursor_t cursor;
    unw_word_t off;
    if (unw_init_local2(&cursor, ctx_, UNW_INIT_SIGNAL_FRAME) != 0 ||
        unw_get_proc_name(&cursor, starting_ip_buf_, sizeof(starting_ip_buf_),
                          &off) != 0) {
      StrCatSignalSafe(starting_ip_buf_, "0x", WordToHex(starting_ip_).data());
      return starting_ip_buf_;
    }
    size_t len = strlen(starting_ip_buf_);
    // Print the offset in decimal, to match gdb's disassembly output and ease
    // debugging.
    StrCatSignalSafe(bssl::Span<char>(starting_ip_buf_).subspan(len), "+",
                     WordToDecimal(off).data(), " (0x",
                     WordToHex(starting_ip_).data(), ")");
    return starting_ip_buf_;
  }

 private:
  static UnwindStatus UNWError(int ret) {
    assert(ret < 0);
    const char *msg = unw_strerror(ret);
    return UnwindStatus(msg == nullptr ? "unknown error" : msg);
  }

  int GetReg(crypto_word_t *out, unw_regnum_t reg) {
    unw_word_t val;
    int ret = unw_get_reg(&cursor_, reg, &val);
    if (ret >= 0) {
      static_assert(sizeof(crypto_word_t) == sizeof(unw_word_t),
                    "crypto_word_t and unw_word_t are inconsistent");
      *out = val;
    }
    return ret;
  }

  unw_context_t *ctx_;
  unw_cursor_t cursor_;
  crypto_word_t starting_ip_;
  char starting_ip_buf_[64];
};
#endif  // OPENSSL_WINDOWS

// g_in_trampoline is true if we are in an instrumented |abi_test_trampoline|
// call, in the region that triggers |SIGTRAP|.
static bool g_in_trampoline = false;
// g_unwind_function_done, if |g_in_trampoline| is true, is whether the function
// under test has returned. It is undefined otherwise.
static bool g_unwind_function_done;
// g_trampoline_state, during an unwind-enabled ABI test, is the state the
// function under test must preserve. It is undefined otherwise.
static CallerState g_trampoline_state;
// g_trampoline_sp, if |g_in_trampoline| is true, is the stack pointer of the
// trampoline frame. It is undefined otherwise.
static crypto_word_t g_trampoline_sp;

// kMaxUnwindErrors is the maximum number of unwind errors reported per
// function. If a function's unwind tables are wrong, we are otherwise likely to
// repeat the same error at multiple addresses.
static constexpr size_t kMaxUnwindErrors = 10;

// Errors are saved in a signal handler. We use a static buffer to avoid
// allocation.
static size_t g_num_unwind_errors = 0;

struct UnwindError {
#if defined(OPENSSL_WINDOWS)
  crypto_word_t ip;
#endif
  char str[512];
};

static UnwindError g_unwind_errors[kMaxUnwindErrors];

template <typename... Args>
static void AddUnwindError(UnwindCursor *cursor, Args... args) {
  if (g_num_unwind_errors >= kMaxUnwindErrors) {
    return;
  }
#if defined(OPENSSL_WINDOWS)
  // Windows symbol functions should not be called when handling an
  // exception. Stash the instruction pointer, to be symbolized later.
  g_unwind_errors[g_num_unwind_errors].ip = cursor->starting_ip();
  StrCatSignalSafe(g_unwind_errors[g_num_unwind_errors].str, args...);
#else
  StrCatSignalSafe(g_unwind_errors[g_num_unwind_errors].str,
                   "unwinding at ", cursor->ToString(), ": ", args...);
#endif
  g_num_unwind_errors++;
}

static void CheckUnwind(UnwindCursor *cursor) {
  const crypto_word_t kStartAddress =
      reinterpret_cast<crypto_word_t>(&abi_test_unwind_start);
  const crypto_word_t kReturnAddress =
      reinterpret_cast<crypto_word_t>(&abi_test_unwind_return);
  const crypto_word_t kStopAddress =
      reinterpret_cast<crypto_word_t>(&abi_test_unwind_stop);

  crypto_word_t sp = cursor->GetSP().ValueOrDie("Error getting stack pointer");
  crypto_word_t ip =
      cursor->GetIP().ValueOrDie("Error getting instruction pointer");
  if (!g_in_trampoline) {
    if (ip != kStartAddress) {
      FatalError("Unexpected SIGTRAP at ", cursor->ToString());
    }

    // Save the current state and begin.
    g_in_trampoline = true;
    g_unwind_function_done = false;
    g_trampoline_sp = sp;
  } else {
    if (sp == g_trampoline_sp || g_unwind_function_done) {
      // |g_unwind_function_done| should imply |sp| is |g_trampoline_sp|, but
      // clearing the trap flag in x86 briefly displaces the stack pointer.
      //
      // Also note we check both |ip| and |sp| below, in case the function under
      // test is also |abi_test_trampoline|.
      if (ip == kReturnAddress && sp == g_trampoline_sp) {
        g_unwind_function_done = true;
      }
      if (ip == kStopAddress && sp == g_trampoline_sp) {
        // |SIGTRAP| is fatal again.
        g_in_trampoline = false;
      }
    } else if (IsAncestorStackFrame(sp, g_trampoline_sp)) {
      // This should never happen. We went past |g_trampoline_sp| without
      // stopping at |kStopAddress|.
      AddUnwindError(cursor, "stack frame is before caller");
      g_in_trampoline = false;
    } else if (g_num_unwind_errors < kMaxUnwindErrors) {
      for (;;) {
        UnwindStatusOr<bool> step_ret = cursor->Step();
        if (!step_ret.ok()) {
          AddUnwindError(cursor, "error unwinding: ", step_ret.Error());
          break;
        }
        // |Step| returns whether there was a frame to unwind.
        if (!step_ret.ValueOrDie()) {
          AddUnwindError(cursor, "could not unwind to starting frame");
          break;
        }

        UnwindStatusOr<crypto_word_t> cur_sp = cursor->GetSP();
        if (!cur_sp.ok()) {
          AddUnwindError(cursor,
                         "error recovering stack pointer: ", cur_sp.Error());
          break;
        }
        if (IsAncestorStackFrame(cur_sp.ValueOrDie(), g_trampoline_sp)) {
          AddUnwindError(cursor, "unwound past starting frame");
          break;
        }
        if (cur_sp.ValueOrDie() == g_trampoline_sp) {
          // We found the parent frame. Check the return address.
          UnwindStatusOr<crypto_word_t> cur_ip = cursor->GetIP();
          if (!cur_ip.ok()) {
            AddUnwindError(cursor,
                           "error recovering return address: ", cur_ip.Error());
          } else if (cur_ip.ValueOrDie() != kReturnAddress) {
            AddUnwindError(cursor, "wrong return address");
          }

          // Check the remaining registers.
          UnwindStatusOr<CallerState> state = cursor->GetCallerState();
          if (!state.ok()) {
            AddUnwindError(cursor,
                           "error recovering registers: ", state.Error());
          } else {
            ForEachMismatch(state.ValueOrDie(), g_trampoline_state,
                            [&](const char *reg) {
                              AddUnwindError(cursor, reg, " was not recovered");
                            });
          }
          break;
        }
      }
    }
  }
}

// ReadUnwindResult adds the results of the most recent unwind test to |out|.
static void ReadUnwindResult(Result *out) {
  for (size_t i = 0; i < g_num_unwind_errors; i++) {
#if defined(OPENSSL_WINDOWS)
    const crypto_word_t ip = g_unwind_errors[i].ip;
    char buf[256];
    DWORD64 displacement;
    struct {
      SYMBOL_INFO info;
      char name_buf[128];
    } symbol;
    memset(&symbol, 0, sizeof(symbol));
    symbol.info.SizeOfStruct = sizeof(symbol.info);
    symbol.info.MaxNameLen = sizeof(symbol.name_buf);
    if (SymFromAddr(GetCurrentProcess(), ip, &displacement, &symbol.info)) {
      snprintf(buf, sizeof(buf), "unwinding at %s+%llu (0x%s): %s",
               symbol.info.Name, displacement, WordToHex(ip).data(),
               g_unwind_errors[i].str);
    } else {
      snprintf(buf, sizeof(buf), "unwinding at 0x%s: %s",
               WordToHex(ip).data(), g_unwind_errors[i].str);
    }
    out->errors.emplace_back(buf);
#else
    out->errors.emplace_back(g_unwind_errors[i].str);
#endif
  }
  if (g_num_unwind_errors == kMaxUnwindErrors) {
    out->errors.emplace_back("(additional errors omitted)");
  }
  g_num_unwind_errors = 0;
}

#if defined(OPENSSL_WINDOWS)
static DWORD g_main_thread;

static long ExceptionHandler(EXCEPTION_POINTERS *info) {
  if (info->ExceptionRecord->ExceptionCode != EXCEPTION_SINGLE_STEP ||
      GetCurrentThreadId() != g_main_thread) {
    return EXCEPTION_CONTINUE_SEARCH;
  }

  UnwindCursor cursor(*info->ContextRecord);
  CheckUnwind(&cursor);
  if (g_in_trampoline) {
    // Windows clears the trap flag, so we must restore it.
    info->ContextRecord->EFlags |= 0x100;
  }
  return EXCEPTION_CONTINUE_EXECUTION;
}

static void EnableUnwindTestsImpl() {
  if (IsDebuggerPresent()) {
    // Unwind tests drive logic via |EXCEPTION_SINGLE_STEP|, which conflicts with
    // debuggers.
    fprintf(stderr, "Debugger detected. Disabling unwind tests.\n");
    return;
  }

  g_main_thread = GetCurrentThreadId();

  SymSetOptions(SYMOPT_DEFERRED_LOADS);
  if (!SymInitialize(GetCurrentProcess(), nullptr, TRUE)) {
    fprintf(stderr, "Could not initialize symbols.\n");
  }

  if (AddVectoredExceptionHandler(0, ExceptionHandler) == nullptr) {
    fprintf(stderr, "Error installing exception handler.\n");
    abort();
  }

  g_unwind_tests_enabled = true;
}
#else  // !OPENSSL_WINDOWS
// HandleEINTR runs |func| and returns the result, retrying the operation on
// |EINTR|.
template <typename Func>
static auto HandleEINTR(const Func &func) -> decltype(func()) {
  decltype(func()) ret;
  do {
    ret = func();
  } while (ret < 0 && errno == EINTR);
  return ret;
}

static bool ReadFileToString(std::string *out, const char *path) {
  out->clear();

  int fd = HandleEINTR([&] { return open(path, O_RDONLY); });
  if (fd < 0) {
    return false;
  }

  for (;;) {
    char buf[1024];
    ssize_t ret = HandleEINTR([&] { return read(fd, buf, sizeof(buf)); });
    if (ret < 0) {
      close(fd);
      return false;
    }
    if (ret == 0) {
      close(fd);
      return true;
    }
    out->append(buf, static_cast<size_t>(ret));
  }
}

static bool IsBeingDebugged() {
  std::string status;
  if (!ReadFileToString(&status, "/proc/self/status")) {
    perror("error reading /proc/self/status");
    return false;
  }
  std::string key = "\nTracerPid:\t";
  size_t idx = status.find(key);
  if (idx == std::string::npos) {
    return false;
  }
  idx += key.size();
  return idx < status.size() && status[idx] != '0';
}

static pthread_t g_main_thread;

static void TrapHandler(int sig, siginfo_t *info, void *ucontext_v) {
  // Note this is a signal handler, so only async-signal-safe functions may be
  // used here. See signal-safety(7). libunwind promises local unwind is
  // async-signal-safe.
  ucontext_t *ucontext = static_cast<ucontext_t*>(ucontext_v);

  // |pthread_equal| is not listed as async-signal-safe, but this is clearly an
  // oversight.
  if (!pthread_equal(g_main_thread, pthread_self())) {
    FatalError("SIGTRAP on background thread");
  }

  UnwindCursor cursor(ucontext);
  CheckUnwind(&cursor);
}

static void EnableUnwindTestsImpl() {
  if (IsBeingDebugged()) {
    // Unwind tests drive logic via |SIGTRAP|, which conflicts with debuggers.
    fprintf(stderr, "Debugger detected. Disabling unwind tests.\n");
    return;
  }

  g_main_thread = pthread_self();

  struct sigaction trap_action;
  OPENSSL_memset(&trap_action, 0, sizeof(trap_action));
  sigemptyset(&trap_action.sa_mask);
  trap_action.sa_flags = SA_SIGINFO;
  trap_action.sa_sigaction = TrapHandler;
  if (sigaction(SIGTRAP, &trap_action, NULL) != 0) {
    perror("sigaction");
    abort();
  }

  g_unwind_tests_enabled = true;
}
#endif  // OPENSSL_WINDOWS

#else  // !SUPPORTS_UNWIND_TEST

#if defined(SUPPORTS_ABI_TEST)
static void ReadUnwindResult(Result *) {}
#endif
static void EnableUnwindTestsImpl() {}

#endif  // SUPPORTS_UNWIND_TEST

#if defined(SUPPORTS_ABI_TEST)
crypto_word_t RunTrampoline(Result *out, crypto_word_t func,
                            const crypto_word_t *argv, size_t argc,
                            bool unwind) {
  CallerState state;
  RAND_bytes(reinterpret_cast<uint8_t *>(&state), sizeof(state));

  unwind &= g_unwind_tests_enabled;
#if defined(SUPPORTS_UNWIND_TEST)
  if (unwind) {
    // Save the caller state for the unwind tester to check for.
    g_trampoline_state = state;
  }
#endif
  CallerState state2 = state;
  crypto_word_t ret = abi_test_trampoline(func, &state2, argv, argc, unwind);
#if defined(OPENSSL_X86_64) || defined(OPENSSL_X86)
  // Query and clear the direction flag early, so negative tests do not
  // interfere with |malloc|.
  bool direction_flag = abi_test_get_and_clear_direction_flag();
#endif  // OPENSSL_X86_64 || OPENSSL_X86

  *out = Result();
  ForEachMismatch(state, state2, [&](const char *reg) {
    out->errors.push_back(std::string(reg) + " was not restored after return");
  });
#if defined(OPENSSL_X86_64) || defined(OPENSSL_X86)
  // Linux and Windows ABIs for x86 require the direction flag be cleared on
  // return. (Some OpenSSL assembly preserves it, which is stronger, but we only
  // require what is specified by the ABI so |CHECK_ABI| works with C compiler
  // output.)
  if (direction_flag) {
    out->errors.emplace_back("Direction flag set after return");
  }
#endif  // OPENSSL_X86_64 || OPENSSL_X86
  if (unwind) {
    ReadUnwindResult(out);
  }
  return ret;
}
#endif  // SUPPORTS_ABI_TEST

}  // namespace internal

void EnableUnwindTests() { internal::EnableUnwindTestsImpl(); }

bool UnwindTestsEnabled() { return internal::g_unwind_tests_enabled; }

}  // namespace abi_test
