Home | History | Annotate | Download | only in trap-handler
      1 // Copyright 2017 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // PLEASE READ BEFORE CHANGING THIS FILE!
      6 //
      7 // This file contains code that is used both inside and outside the out of
      8 // bounds signal handler. Because this code runs in a signal handler context,
      9 // use extra care when modifying this file. Here are some rules to follow.
     10 //
     11 // 1. Do not introduce any new external dependencies. This file needs
     12 //    to be self contained so it is easy to audit everything that a
     13 //    signal handler might do.
     14 //
     15 // 2. Any changes must be reviewed by someone from the crash reporting
     16 //    or security team. See OWNERS for suggested reviewers.
     17 //
     18 // For more information, see https://goo.gl/yMeyUY.
     19 
     20 #include "src/trap-handler/trap-handler-internal.h"
     21 
     22 namespace v8 {
     23 namespace internal {
     24 namespace trap_handler {
     25 
     26 // We declare this as int rather than bool as a workaround for a glibc bug, in
     27 // which the dynamic loader cannot handle executables whose TLS area is only
     28 // 1 byte in size; see https://sourceware.org/bugzilla/show_bug.cgi?id=14898.
     29 THREAD_LOCAL int g_thread_in_wasm_code;
     30 
     31 #if V8_TRAP_HANDLER_SUPPORTED
     32 // When using the default signal handler, we save the old one to restore in case
     33 // V8 chooses not to handle the signal.
     34 struct sigaction g_old_handler;
     35 bool g_is_default_signal_handler_registered;
     36 #endif
     37 
     38 V8_EXPORT_PRIVATE void RestoreOriginalSignalHandler() {
     39 #if V8_TRAP_HANDLER_SUPPORTED
     40   if (sigaction(SIGSEGV, &g_old_handler, nullptr) == 0) {
     41     g_is_default_signal_handler_registered = false;
     42   }
     43 #endif
     44 }
     45 
     46 static_assert(sizeof(g_thread_in_wasm_code) > 1,
     47               "sizeof(thread_local_var) must be > 1, see "
     48               "https://sourceware.org/bugzilla/show_bug.cgi?id=14898");
     49 
     50 size_t gNumCodeObjects = 0;
     51 CodeProtectionInfoListEntry* gCodeObjects = nullptr;
     52 std::atomic_size_t gRecoveredTrapCount = {0};
     53 
     54 std::atomic_flag MetadataLock::spinlock_ = ATOMIC_FLAG_INIT;
     55 
     56 MetadataLock::MetadataLock() {
     57   if (g_thread_in_wasm_code) {
     58     abort();
     59   }
     60 
     61   while (spinlock_.test_and_set(std::memory_order::memory_order_acquire)) {
     62   }
     63 }
     64 
     65 MetadataLock::~MetadataLock() {
     66   if (g_thread_in_wasm_code) {
     67     abort();
     68   }
     69 
     70   spinlock_.clear(std::memory_order::memory_order_release);
     71 }
     72 
     73 }  // namespace trap_handler
     74 }  // namespace internal
     75 }  // namespace v8
     76