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 trap handler. Because this code runs in a trap 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//    trap 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
22namespace v8 {
23namespace internal {
24namespace 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.
29thread_local int g_thread_in_wasm_code;
30
31static_assert(sizeof(g_thread_in_wasm_code) > 1,
32              "sizeof(thread_local_var) must be > 1, see "
33              "https://sourceware.org/bugzilla/show_bug.cgi?id=14898");
34
35size_t gNumCodeObjects = 0;
36CodeProtectionInfoListEntry* gCodeObjects = nullptr;
37std::atomic_size_t gRecoveredTrapCount = {0};
38
39std::atomic_flag MetadataLock::spinlock_ = ATOMIC_FLAG_INIT;
40
41MetadataLock::MetadataLock() {
42  if (g_thread_in_wasm_code) {
43    abort();
44  }
45
46  while (spinlock_.test_and_set(std::memory_order_acquire)) {
47  }
48}
49
50MetadataLock::~MetadataLock() {
51  if (g_thread_in_wasm_code) {
52    abort();
53  }
54
55  spinlock_.clear(std::memory_order_release);
56}
57
58}  // namespace trap_handler
59}  // namespace internal
60}  // namespace v8
61