// Copyright (c) 2010 Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// The ExceptionHandler object installs signal handlers for a number of
// signals. We rely on the signal handler running on the thread which crashed
// in order to identify it. This is true of the synchronous signals (SEGV etc),
// but not true of ABRT. Thus, if you send ABRT to yourself in a program which
// uses ExceptionHandler, you need to use tgkill to direct it to the current
// thread.
//
// The signal flow looks like this:
//
//   SignalHandler (uses a global stack of ExceptionHandler objects to find
//        |         one to handle the signal. If the first rejects it, try
//        |         the second etc...)
//        V
//   HandleSignal ----------------------------| (clones a new process which
//        |                                   |  shares an address space with
//   (wait for cloned                         |  the crashed process. This
//     process)                               |  allows us to ptrace the crashed
//        |                                   |  process)
//        V                                   V
//   (set signal handler to             ThreadEntry (static function to bounce
//    SIG_DFL and rethrow,                    |      back into the object)
//    killing the crashed                     |
//    process)                                V
//                                          DoDump  (writes minidump)
//                                            |
//                                            V
//                                         sys_exit
//

// This code is a little fragmented. Different functions of the ExceptionHandler
// class run in a number of different contexts. Some of them run in a normal
// context and are easy to code, others run in a compromised context and the
// restrictions at the top of minidump_writer.cc apply: no libc and use the
// alternative malloc. Each function should have comment above it detailing the
// context which it runs in.

#include "client/linux/handler/exception_handler.h"

#include <errno.h>
#include <fcntl.h>
#include <linux/limits.h>
#include <pthread.h>
#include <sched.h>
#include <signal.h>
#include <stdio.h>
#include <sys/mman.h>
#include <sys/prctl.h>
#include <sys/syscall.h>
#include <sys/wait.h>
#include <unistd.h>

#include <sys/signal.h>
#include <sys/ucontext.h>
#include <sys/user.h>
#include <ucontext.h>

#include <algorithm>
#include <utility>
#include <vector>

#include "common/basictypes.h"
#include "common/linux/linux_libc_support.h"
#include "common/memory_allocator.h"
#include "client/linux/log/log.h"
#include "client/linux/microdump_writer/microdump_writer.h"
#include "client/linux/minidump_writer/linux_dumper.h"
#include "client/linux/minidump_writer/minidump_writer.h"
#include "common/linux/eintr_wrapper.h"
#include "third_party/lss/linux_syscall_support.h"

#if defined(__ANDROID__)
#include "linux/sched.h"
#endif

#ifndef PR_SET_PTRACER
#define PR_SET_PTRACER 0x59616d61
#endif

namespace google_breakpad {

namespace {
// The list of signals which we consider to be crashes. The default action for
// all these signals must be Core (see man 7 signal) because we rethrow the
// signal after handling it and expect that it'll be fatal.
const int kExceptionSignals[] = {
  SIGSEGV, SIGABRT, SIGFPE, SIGILL, SIGBUS, SIGTRAP
};
const int kNumHandledSignals =
    sizeof(kExceptionSignals) / sizeof(kExceptionSignals[0]);
struct sigaction old_handlers[kNumHandledSignals];
bool handlers_installed = false;

// InstallAlternateStackLocked will store the newly installed stack in new_stack
// and (if it exists) the previously installed stack in old_stack.
stack_t old_stack;
stack_t new_stack;
bool stack_installed = false;

// Create an alternative stack to run the signal handlers on. This is done since
// the signal might have been caused by a stack overflow.
// Runs before crashing: normal context.
void InstallAlternateStackLocked() {
  if (stack_installed)
    return;

  memset(&old_stack, 0, sizeof(old_stack));
  memset(&new_stack, 0, sizeof(new_stack));

  // SIGSTKSZ may be too small to prevent the signal handlers from overrunning
  // the alternative stack. Ensure that the size of the alternative stack is
  // large enough.
  static const unsigned kSigStackSize = std::max(16384, SIGSTKSZ);

  // Only set an alternative stack if there isn't already one, or if the current
  // one is too small.
  if (sys_sigaltstack(NULL, &old_stack) == -1 || !old_stack.ss_sp ||
      old_stack.ss_size < kSigStackSize) {
    new_stack.ss_sp = calloc(1, kSigStackSize);
    new_stack.ss_size = kSigStackSize;

    if (sys_sigaltstack(&new_stack, NULL) == -1) {
      free(new_stack.ss_sp);
      return;
    }
    stack_installed = true;
  }
}

// Runs before crashing: normal context.
void RestoreAlternateStackLocked() {
  if (!stack_installed)
    return;

  stack_t current_stack;
  if (sys_sigaltstack(NULL, &current_stack) == -1)
    return;

  // Only restore the old_stack if the current alternative stack is the one
  // installed by the call to InstallAlternateStackLocked.
  if (current_stack.ss_sp == new_stack.ss_sp) {
    if (old_stack.ss_sp) {
      if (sys_sigaltstack(&old_stack, NULL) == -1)
        return;
    } else {
      stack_t disable_stack;
      disable_stack.ss_flags = SS_DISABLE;
      if (sys_sigaltstack(&disable_stack, NULL) == -1)
        return;
    }
  }

  free(new_stack.ss_sp);
  stack_installed = false;
}

void InstallDefaultHandler(int sig) {
#if defined(__ANDROID__)
  // Android L+ expose signal and sigaction symbols that override the system
  // ones. There is a bug in these functions where a request to set the handler
  // to SIG_DFL is ignored. In that case, an infinite loop is entered as the
  // signal is repeatedly sent to breakpad's signal handler.
  // To work around this, directly call the system's sigaction.
  struct kernel_sigaction sa;
  memset(&sa, 0, sizeof(sa));
  sys_sigemptyset(&sa.sa_mask);
  sa.sa_handler_ = SIG_DFL;
  sa.sa_flags = SA_RESTART;
  sys_rt_sigaction(sig, &sa, NULL, sizeof(kernel_sigset_t));
#else
  signal(sig, SIG_DFL);
#endif
}

// The global exception handler stack. This is needed because there may exist
// multiple ExceptionHandler instances in a process. Each will have itself
// registered in this stack.
std::vector<ExceptionHandler*>* g_handler_stack_ = NULL;
pthread_mutex_t g_handler_stack_mutex_ = PTHREAD_MUTEX_INITIALIZER;

// sizeof(CrashContext) can be too big w.r.t the size of alternatate stack
// for SignalHandler(). Keep the crash context as a .bss field. Exception
// handlers are serialized by the |g_handler_stack_mutex_| and at most one at a
// time can use |g_crash_context_|.
ExceptionHandler::CrashContext g_crash_context_;

FirstChanceHandler g_first_chance_handler_ = nullptr;
}  // namespace

// Runs before crashing: normal context.
ExceptionHandler::ExceptionHandler(const MinidumpDescriptor& descriptor,
                                   FilterCallback filter,
                                   MinidumpCallback callback,
                                   void* callback_context,
                                   bool install_handler,
                                   const int server_fd)
    : filter_(filter),
      callback_(callback),
      callback_context_(callback_context),
      minidump_descriptor_(descriptor),
      crash_handler_(NULL) {
  if (server_fd >= 0)
    crash_generation_client_.reset(CrashGenerationClient::TryCreate(server_fd));

  if (!IsOutOfProcess() && !minidump_descriptor_.IsFD() &&
      !minidump_descriptor_.IsMicrodumpOnConsole())
    minidump_descriptor_.UpdatePath();

#if defined(__ANDROID__)
  if (minidump_descriptor_.IsMicrodumpOnConsole())
    logger::initializeCrashLogWriter();
#endif

  pthread_mutex_lock(&g_handler_stack_mutex_);

  // Pre-fault the crash context struct. This is to avoid failing due to OOM
  // if handling an exception when the process ran out of virtual memory.
  memset(&g_crash_context_, 0, sizeof(g_crash_context_));

  if (!g_handler_stack_)
    g_handler_stack_ = new std::vector<ExceptionHandler*>;
  if (install_handler) {
    InstallAlternateStackLocked();
    InstallHandlersLocked();
  }
  g_handler_stack_->push_back(this);
  pthread_mutex_unlock(&g_handler_stack_mutex_);
}

// Runs before crashing: normal context.
ExceptionHandler::~ExceptionHandler() {
  pthread_mutex_lock(&g_handler_stack_mutex_);
  std::vector<ExceptionHandler*>::iterator handler =
      std::find(g_handler_stack_->begin(), g_handler_stack_->end(), this);
  g_handler_stack_->erase(handler);
  if (g_handler_stack_->empty()) {
    delete g_handler_stack_;
    g_handler_stack_ = NULL;
    RestoreAlternateStackLocked();
    RestoreHandlersLocked();
  }
  pthread_mutex_unlock(&g_handler_stack_mutex_);
}

// Runs before crashing: normal context.
// static
bool ExceptionHandler::InstallHandlersLocked() {
  if (handlers_installed)
    return false;

  // Fail if unable to store all the old handlers.
  for (int i = 0; i < kNumHandledSignals; ++i) {
    if (sigaction(kExceptionSignals[i], NULL, &old_handlers[i]) == -1)
      return false;
  }

  struct sigaction sa;
  memset(&sa, 0, sizeof(sa));
  sigemptyset(&sa.sa_mask);

  // Mask all exception signals when we're handling one of them.
  for (int i = 0; i < kNumHandledSignals; ++i)
    sigaddset(&sa.sa_mask, kExceptionSignals[i]);

  sa.sa_sigaction = SignalHandler;
  sa.sa_flags = SA_ONSTACK | SA_SIGINFO;

  for (int i = 0; i < kNumHandledSignals; ++i) {
    if (sigaction(kExceptionSignals[i], &sa, NULL) == -1) {
      // At this point it is impractical to back out changes, and so failure to
      // install a signal is intentionally ignored.
    }
  }
  handlers_installed = true;
  return true;
}

// This function runs in a compromised context: see the top of the file.
// Runs on the crashing thread.
// static
void ExceptionHandler::RestoreHandlersLocked() {
  if (!handlers_installed)
    return;

  for (int i = 0; i < kNumHandledSignals; ++i) {
    if (sigaction(kExceptionSignals[i], &old_handlers[i], NULL) == -1) {
      InstallDefaultHandler(kExceptionSignals[i]);
    }
  }
  handlers_installed = false;
}

// void ExceptionHandler::set_crash_handler(HandlerCallback callback) {
//   crash_handler_ = callback;
// }

// This function runs in a compromised context: see the top of the file.
// Runs on the crashing thread.
// static
void ExceptionHandler::SignalHandler(int sig, siginfo_t* info, void* uc) {

  // Give the first chance handler a chance to recover from this signal
  //
  // This is primarily used by V8. V8 uses guard regions to guarantee memory
  // safety in WebAssembly. This means some signals might be expected if they
  // originate from Wasm code while accessing the guard region. We give V8 the
  // chance to handle and recover from these signals first.
  if (g_first_chance_handler_ != nullptr &&
      g_first_chance_handler_(sig, info, uc)) {
    return;
  }

  // All the exception signals are blocked at this point.
  pthread_mutex_lock(&g_handler_stack_mutex_);

  // Sometimes, Breakpad runs inside a process where some other buggy code
  // saves and restores signal handlers temporarily with 'signal'
  // instead of 'sigaction'. This loses the SA_SIGINFO flag associated
  // with this function. As a consequence, the values of 'info' and 'uc'
  // become totally bogus, generally inducing a crash.
  //
  // The following code tries to detect this case. When it does, it
  // resets the signal handlers with sigaction + SA_SIGINFO and returns.
  // This forces the signal to be thrown again, but this time the kernel
  // will call the function with the right arguments.
  struct sigaction cur_handler;
  if (sigaction(sig, NULL, &cur_handler) == 0 &&
      cur_handler.sa_sigaction == SignalHandler &&
      (cur_handler.sa_flags & SA_SIGINFO) == 0) {
    // Reset signal handler with the right flags.
    sigemptyset(&cur_handler.sa_mask);
    sigaddset(&cur_handler.sa_mask, sig);

    cur_handler.sa_sigaction = SignalHandler;
    cur_handler.sa_flags = SA_ONSTACK | SA_SIGINFO;

    if (sigaction(sig, &cur_handler, NULL) == -1) {
      // When resetting the handler fails, try to reset the
      // default one to avoid an infinite loop here.
      InstallDefaultHandler(sig);
    }
    pthread_mutex_unlock(&g_handler_stack_mutex_);
    return;
  }

  bool handled = false;
  for (int i = g_handler_stack_->size() - 1; !handled && i >= 0; --i) {
    handled = (*g_handler_stack_)[i]->HandleSignal(sig, info, uc);
  }

  // Upon returning from this signal handler, sig will become unmasked and then
  // it will be retriggered. If one of the ExceptionHandlers handled it
  // successfully, restore the default handler. Otherwise, restore the
  // previously installed handler. Then, when the signal is retriggered, it will
  // be delivered to the appropriate handler.
  if (handled) {
    InstallDefaultHandler(sig);
  } else {
    RestoreHandlersLocked();
  }

  pthread_mutex_unlock(&g_handler_stack_mutex_);

  // info->si_code <= 0 iff SI_FROMUSER (SI_FROMKERNEL otherwise).
  if (info->si_code <= 0 || sig == SIGABRT) {
    // This signal was triggered by somebody sending us the signal with kill().
    // In order to retrigger it, we have to queue a new signal by calling
    // kill() ourselves.  The special case (si_pid == 0 && sig == SIGABRT) is
    // due to the kernel sending a SIGABRT from a user request via SysRQ.
    if (sys_tgkill(getpid(), syscall(__NR_gettid), sig) < 0) {
      // If we failed to kill ourselves (e.g. because a sandbox disallows us
      // to do so), we instead resort to terminating our process. This will
      // result in an incorrect exit code.
      _exit(1);
    }
  } else {
    // This was a synchronous signal triggered by a hard fault (e.g. SIGSEGV).
    // No need to reissue the signal. It will automatically trigger again,
    // when we return from the signal handler.
  }
}

struct ThreadArgument {
  pid_t pid;  // the crashing process
  const MinidumpDescriptor* minidump_descriptor;
  ExceptionHandler* handler;
  const void* context;  // a CrashContext structure
  size_t context_size;
};

// This is the entry function for the cloned process. We are in a compromised
// context here: see the top of the file.
// static
int ExceptionHandler::ThreadEntry(void *arg) {
  const ThreadArgument *thread_arg = reinterpret_cast<ThreadArgument*>(arg);

  // Close the write end of the pipe. This allows us to fail if the parent dies
  // while waiting for the continue signal.
  sys_close(thread_arg->handler->fdes[1]);

  // Block here until the crashing process unblocks us when
  // we're allowed to use ptrace
  thread_arg->handler->WaitForContinueSignal();
  sys_close(thread_arg->handler->fdes[0]);

  return thread_arg->handler->DoDump(thread_arg->pid, thread_arg->context,
                                     thread_arg->context_size) == false;
}

// This function runs in a compromised context: see the top of the file.
// Runs on the crashing thread.
bool ExceptionHandler::HandleSignal(int /*sig*/, siginfo_t* info, void* uc) {
  if (filter_ && !filter_(callback_context_))
    return false;

  // Allow ourselves to be dumped if the signal is trusted.
  bool signal_trusted = info->si_code > 0;
  bool signal_pid_trusted = info->si_code == SI_USER ||
      info->si_code == SI_TKILL;
  if (signal_trusted || (signal_pid_trusted && info->si_pid == getpid())) {
    sys_prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
  }

  // Fill in all the holes in the struct to make Valgrind happy.
  memset(&g_crash_context_, 0, sizeof(g_crash_context_));
  memcpy(&g_crash_context_.siginfo, info, sizeof(siginfo_t));
  memcpy(&g_crash_context_.context, uc, sizeof(ucontext_t));
#if defined(__aarch64__)
  ucontext_t* uc_ptr = (ucontext_t*)uc;
  struct fpsimd_context* fp_ptr =
      (struct fpsimd_context*)&uc_ptr->uc_mcontext.__reserved;
  if (fp_ptr->head.magic == FPSIMD_MAGIC) {
    memcpy(&g_crash_context_.float_state, fp_ptr,
           sizeof(g_crash_context_.float_state));
  }
#elif !defined(__ARM_EABI__) && !defined(__mips__)
  // FP state is not part of user ABI on ARM Linux.
  // In case of MIPS Linux FP state is already part of ucontext_t
  // and 'float_state' is not a member of CrashContext.
  ucontext_t* uc_ptr = (ucontext_t*)uc;
  if (uc_ptr->uc_mcontext.fpregs) {
    memcpy(&g_crash_context_.float_state, uc_ptr->uc_mcontext.fpregs,
           sizeof(g_crash_context_.float_state));
  }
#endif
  g_crash_context_.tid = syscall(__NR_gettid);
  if (crash_handler_ != NULL) {
    if (crash_handler_(&g_crash_context_, sizeof(g_crash_context_),
                       callback_context_)) {
      return true;
    }
  }
  return GenerateDump(&g_crash_context_);
}

// This is a public interface to HandleSignal that allows the client to
// generate a crash dump. This function may run in a compromised context.
bool ExceptionHandler::SimulateSignalDelivery(int sig) {
  siginfo_t siginfo = {};
  // Mimic a trusted signal to allow tracing the process (see
  // ExceptionHandler::HandleSignal().
  siginfo.si_code = SI_USER;
  siginfo.si_pid = getpid();
  ucontext_t context;
  getcontext(&context);
  return HandleSignal(sig, &siginfo, &context);
}

// This function may run in a compromised context: see the top of the file.
bool ExceptionHandler::GenerateDump(CrashContext *context) {
  if (IsOutOfProcess())
    return crash_generation_client_->RequestDump(context, sizeof(*context));

  // Allocating too much stack isn't a problem, and better to err on the side
  // of caution than smash it into random locations.
  static const unsigned kChildStackSize = 16000;
  PageAllocator allocator;
  uint8_t* stack = reinterpret_cast<uint8_t*>(allocator.Alloc(kChildStackSize));
  if (!stack)
    return false;
  // clone() needs the top-most address. (scrub just to be safe)
  stack += kChildStackSize;
  my_memset(stack - 16, 0, 16);

  ThreadArgument thread_arg;
  thread_arg.handler = this;
  thread_arg.minidump_descriptor = &minidump_descriptor_;
  thread_arg.pid = getpid();
  thread_arg.context = context;
  thread_arg.context_size = sizeof(*context);

  // We need to explicitly enable ptrace of parent processes on some
  // kernels, but we need to know the PID of the cloned process before we
  // can do this. Create a pipe here which we can use to block the
  // cloned process after creating it, until we have explicitly enabled ptrace
  if (sys_pipe(fdes) == -1) {
    // Creating the pipe failed. We'll log an error but carry on anyway,
    // as we'll probably still get a useful crash report. All that will happen
    // is the write() and read() calls will fail with EBADF
    static const char no_pipe_msg[] = "ExceptionHandler::GenerateDump "
                                      "sys_pipe failed:";
    logger::write(no_pipe_msg, sizeof(no_pipe_msg) - 1);
    logger::write(strerror(errno), strlen(strerror(errno)));
    logger::write("\n", 1);

    // Ensure fdes[0] and fdes[1] are invalid file descriptors.
    fdes[0] = fdes[1] = -1;
  }

  const pid_t child = sys_clone(
      ThreadEntry, stack, CLONE_FS | CLONE_UNTRACED, &thread_arg, NULL, NULL,
      NULL);
  if (child == -1) {
    sys_close(fdes[0]);
    sys_close(fdes[1]);
    return false;
  }

  // Close the read end of the pipe.
  sys_close(fdes[0]);
  // Allow the child to ptrace us
  sys_prctl(PR_SET_PTRACER, child, 0, 0, 0);
  SendContinueSignalToChild();
  int status;
  const int r = HANDLE_EINTR(sys_waitpid(child, &status, __WALL));

  sys_close(fdes[1]);

  if (r == -1) {
    static const char msg[] = "ExceptionHandler::GenerateDump waitpid failed:";
    logger::write(msg, sizeof(msg) - 1);
    logger::write(strerror(errno), strlen(strerror(errno)));
    logger::write("\n", 1);
  }

  bool success = r != -1 && WIFEXITED(status) && WEXITSTATUS(status) == 0;
  if (callback_)
    success = callback_(minidump_descriptor_, callback_context_, success);
  return success;
}

// This function runs in a compromised context: see the top of the file.
void ExceptionHandler::SendContinueSignalToChild() {
  static const char okToContinueMessage = 'a';
  int r;
  r = HANDLE_EINTR(sys_write(fdes[1], &okToContinueMessage, sizeof(char)));
  if (r == -1) {
    static const char msg[] = "ExceptionHandler::SendContinueSignalToChild "
                              "sys_write failed:";
    logger::write(msg, sizeof(msg) - 1);
    logger::write(strerror(errno), strlen(strerror(errno)));
    logger::write("\n", 1);
  }
}

// This function runs in a compromised context: see the top of the file.
// Runs on the cloned process.
void ExceptionHandler::WaitForContinueSignal() {
  int r;
  char receivedMessage;
  r = HANDLE_EINTR(sys_read(fdes[0], &receivedMessage, sizeof(char)));
  if (r == -1) {
    static const char msg[] = "ExceptionHandler::WaitForContinueSignal "
                              "sys_read failed:";
    logger::write(msg, sizeof(msg) - 1);
    logger::write(strerror(errno), strlen(strerror(errno)));
    logger::write("\n", 1);
  }
}

// This function runs in a compromised context: see the top of the file.
// Runs on the cloned process.
bool ExceptionHandler::DoDump(pid_t crashing_process, const void* context,
                              size_t context_size) {
  const bool may_skip_dump =
      minidump_descriptor_.skip_dump_if_principal_mapping_not_referenced();
  const uintptr_t principal_mapping_address =
      minidump_descriptor_.address_within_principal_mapping();
  const bool sanitize_stacks = minidump_descriptor_.sanitize_stacks();
  if (minidump_descriptor_.IsMicrodumpOnConsole()) {
    return google_breakpad::WriteMicrodump(
        crashing_process,
        context,
        context_size,
        mapping_list_,
        may_skip_dump,
        principal_mapping_address,
        sanitize_stacks,
        *minidump_descriptor_.microdump_extra_info());
  }
  if (minidump_descriptor_.IsFD()) {
    return google_breakpad::WriteMinidump(minidump_descriptor_.fd(),
                                          minidump_descriptor_.size_limit(),
                                          crashing_process,
                                          context,
                                          context_size,
                                          mapping_list_,
                                          app_memory_list_,
                                          may_skip_dump,
                                          principal_mapping_address,
                                          sanitize_stacks);
  }
  return google_breakpad::WriteMinidump(minidump_descriptor_.path(),
                                        minidump_descriptor_.size_limit(),
                                        crashing_process,
                                        context,
                                        context_size,
                                        mapping_list_,
                                        app_memory_list_,
                                        may_skip_dump,
                                        principal_mapping_address,
                                        sanitize_stacks);
}

// static
bool ExceptionHandler::WriteMinidump(const string& dump_path,
                                     MinidumpCallback callback,
                                     void* callback_context) {
  MinidumpDescriptor descriptor(dump_path);
  ExceptionHandler eh(descriptor, NULL, callback, callback_context, false, -1);
  return eh.WriteMinidump();
}

// In order to making using EBP to calculate the desired value for ESP
// a valid operation, ensure that this function is compiled with a
// frame pointer using the following attribute. This attribute
// is supported on GCC but not on clang.
#if defined(__i386__) && defined(__GNUC__) && !defined(__clang__)
__attribute__((optimize("no-omit-frame-pointer")))
#endif
bool ExceptionHandler::WriteMinidump() {
  if (!IsOutOfProcess() && !minidump_descriptor_.IsFD() &&
      !minidump_descriptor_.IsMicrodumpOnConsole()) {
    // Update the path of the minidump so that this can be called multiple times
    // and new files are created for each minidump.  This is done before the
    // generation happens, as clients may want to access the MinidumpDescriptor
    // after this call to find the exact path to the minidump file.
    minidump_descriptor_.UpdatePath();
  } else if (minidump_descriptor_.IsFD()) {
    // Reposition the FD to its beginning and resize it to get rid of the
    // previous minidump info.
    lseek(minidump_descriptor_.fd(), 0, SEEK_SET);
    ignore_result(ftruncate(minidump_descriptor_.fd(), 0));
  }

  // Allow this process to be dumped.
  sys_prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);

  CrashContext context;
  int getcontext_result = getcontext(&context.context);
  if (getcontext_result)
    return false;

#if defined(__i386__)
  // In CPUFillFromUContext in minidumpwriter.cc the stack pointer is retrieved
  // from REG_UESP instead of from REG_ESP. REG_UESP is the user stack pointer
  // and it only makes sense when running in kernel mode with a different stack
  // pointer. When WriteMiniDump is called during normal processing REG_UESP is
  // zero which leads to bad minidump files.
  if (!context.context.uc_mcontext.gregs[REG_UESP]) {
    // If REG_UESP is set to REG_ESP then that includes the stack space for the
    // CrashContext object in this function, which is about 128 KB. Since the
    // Linux dumper only records 32 KB of stack this would mean that nothing
    // useful would be recorded. A better option is to set REG_UESP to REG_EBP,
    // perhaps with a small negative offset in case there is any code that
    // objects to them being equal.
    context.context.uc_mcontext.gregs[REG_UESP] =
      context.context.uc_mcontext.gregs[REG_EBP] - 16;
    // The stack saving is based off of REG_ESP so it must be set to match the
    // new REG_UESP.
    context.context.uc_mcontext.gregs[REG_ESP] =
      context.context.uc_mcontext.gregs[REG_UESP];
  }
#endif

#if !defined(__ARM_EABI__) && !defined(__aarch64__) && !defined(__mips__)
  // FPU state is not part of ARM EABI ucontext_t.
  memcpy(&context.float_state, context.context.uc_mcontext.fpregs,
         sizeof(context.float_state));
#endif
  context.tid = sys_gettid();

  // Add an exception stream to the minidump for better reporting.
  memset(&context.siginfo, 0, sizeof(context.siginfo));
  context.siginfo.si_signo = MD_EXCEPTION_CODE_LIN_DUMP_REQUESTED;
#if defined(__i386__)
  context.siginfo.si_addr =
      reinterpret_cast<void*>(context.context.uc_mcontext.gregs[REG_EIP]);
#elif defined(__x86_64__)
  context.siginfo.si_addr =
      reinterpret_cast<void*>(context.context.uc_mcontext.gregs[REG_RIP]);
#elif defined(__arm__)
  context.siginfo.si_addr =
      reinterpret_cast<void*>(context.context.uc_mcontext.arm_pc);
#elif defined(__aarch64__)
  context.siginfo.si_addr =
      reinterpret_cast<void*>(context.context.uc_mcontext.pc);
#elif defined(__mips__)
  context.siginfo.si_addr =
      reinterpret_cast<void*>(context.context.uc_mcontext.pc);
#else
#error "This code has not been ported to your platform yet."
#endif

  return GenerateDump(&context);
}

void ExceptionHandler::AddMappingInfo(const string& name,
                                      const uint8_t identifier[sizeof(MDGUID)],
                                      uintptr_t start_address,
                                      size_t mapping_size,
                                      size_t file_offset) {
  MappingInfo info;
  info.start_addr = start_address;
  info.size = mapping_size;
  info.offset = file_offset;
  strncpy(info.name, name.c_str(), sizeof(info.name) - 1);
  info.name[sizeof(info.name) - 1] = '\0';

  MappingEntry mapping;
  mapping.first = info;
  memcpy(mapping.second, identifier, sizeof(MDGUID));
  mapping_list_.push_back(mapping);
}

void ExceptionHandler::RegisterAppMemory(void* ptr, size_t length) {
  AppMemoryList::iterator iter =
    std::find(app_memory_list_.begin(), app_memory_list_.end(), ptr);
  if (iter != app_memory_list_.end()) {
    // Don't allow registering the same pointer twice.
    return;
  }

  AppMemory app_memory;
  app_memory.ptr = ptr;
  app_memory.length = length;
  app_memory_list_.push_back(app_memory);
}

void ExceptionHandler::UnregisterAppMemory(void* ptr) {
  AppMemoryList::iterator iter =
    std::find(app_memory_list_.begin(), app_memory_list_.end(), ptr);
  if (iter != app_memory_list_.end()) {
    app_memory_list_.erase(iter);
  }
}

// static
bool ExceptionHandler::WriteMinidumpForChild(pid_t child,
                                             pid_t child_blamed_thread,
                                             const string& dump_path,
                                             MinidumpCallback callback,
                                             void* callback_context) {
  // This function is not run in a compromised context.
  MinidumpDescriptor descriptor(dump_path);
  descriptor.UpdatePath();
  if (!google_breakpad::WriteMinidump(descriptor.path(),
                                      child,
                                      child_blamed_thread))
      return false;

  return callback ? callback(descriptor, callback_context, true) : true;
}

void SetFirstChanceExceptionHandler(FirstChanceHandler callback) {
  g_first_chance_handler_ = callback;
}

}  // namespace google_breakpad
