Skip to content

Commit

Permalink
[cfi][wasm] Create table entries for indirectly callable builtins
Browse files Browse the repository at this point in the history
Design doc linked in the referenced bug.

Bug: 363975785
Change-Id: Id5daca5cd216dc034eb7bfe6c0359932fa084d94
Cq-Include-Trybots: luci.v8.try:v8_linux64_pku_rel
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5831364
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Commit-Queue: Stephen Röttger <sroettger@google.com>
Reviewed-by: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/main@{#95945}
  • Loading branch information
sroettger authored and V8 LUCI CQ committed Sep 4, 2024
1 parent fd03be9 commit 2166490
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 0 deletions.
28 changes: 28 additions & 0 deletions src/builtins/builtins-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,34 @@ constexpr bool Builtins::IsJSEntryVariant(Builtin builtin) {
UNREACHABLE();
}

#ifdef V8_ENABLE_WEBASSEMBLY

// static
template <Builtin builtin>
constexpr size_t Builtins::WasmBuiltinHandleArrayIndex() {
size_t index;
if constexpr (builtin == Builtin::kWasmToOnHeapWasmToJsTrampoline) {
index = 0;
} else if constexpr (builtin == Builtin::kWasmToJsWrapperInvalidSig) {
index = 1;
} else {
static_assert(builtin == Builtin::kWasmToJsWrapperAsm);
index = 2;
}
static_assert(Builtins::kWasmIndirectlyCallableBuiltins[index] == builtin);
return index;
}

// static
template <Builtin builtin>
wasm::WasmCodePointerTable::Handle Builtins::WasmBuiltinHandleOf(
Isolate* isolate) {
return isolate
->wasm_builtin_code_handles()[WasmBuiltinHandleArrayIndex<builtin>()];
}

#endif // V8_ENABLE_WEBASSEMBLY

} // namespace internal
} // namespace v8

Expand Down
26 changes: 26 additions & 0 deletions src/builtins/builtins.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
#include "src/objects/type-hints.h"
#include "src/sandbox/code-entrypoint-tag.h"

#ifdef V8_ENABLE_WEBASSEMBLY
#include "src/wasm/wasm-code-pointer-table.h"
#endif

namespace v8 {
namespace internal {

Expand Down Expand Up @@ -107,6 +111,21 @@ class Builtins {
kLastBytecodeHandlerPlusOne == kBuiltinCount;
static_assert(kBytecodeHandlersAreSortedLast);

#ifdef V8_ENABLE_WEBASSEMBLY
// The list of builtins that can be called indirectly from Wasm and need an
// entry in the WasmCodePointerTable.
static constexpr Builtin kWasmIndirectlyCallableBuiltins[] = {
Builtin::kWasmToOnHeapWasmToJsTrampoline,
Builtin::kWasmToJsWrapperInvalidSig, Builtin::kWasmToJsWrapperAsm};
static constexpr size_t kNumWasmIndirectlyCallableBuiltins =
arraysize(kWasmIndirectlyCallableBuiltins);
using WasmBuiltinHandleArray =
wasm::WasmCodePointerTable::Handle[kNumWasmIndirectlyCallableBuiltins];
// TODO(sroettger): this can be consteval, but the gcc bot doesn't support it.
template <Builtin builtin>
static constexpr size_t WasmBuiltinHandleArrayIndex();
#endif

static constexpr bool IsBuiltinId(Builtin builtin) {
return builtin != Builtin::kNoBuiltinId;
}
Expand Down Expand Up @@ -201,6 +220,13 @@ class Builtins {
// builtin_entry_table, initialized earlier via {InitializeIsolateDataTables}.
static inline Address EntryOf(Builtin builtin, Isolate* isolate);

#ifdef V8_ENABLE_WEBASSEMBLY
// Returns a handle to the WasmCodePointerTable entry for a given builtin.
template <Builtin builtin>
static inline wasm::WasmCodePointerTable::Handle WasmBuiltinHandleOf(
Isolate* isolate);
#endif

V8_EXPORT_PRIVATE static Kind KindOf(Builtin builtin);
static const char* KindNameOf(Builtin builtin);

Expand Down
19 changes: 19 additions & 0 deletions src/execution/isolate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,12 @@
#endif // V8_ENABLE_MAGLEV

#if V8_ENABLE_WEBASSEMBLY
#include "src/builtins/builtins-inl.h"
#include "src/debug/debug-wasm-objects.h"
#include "src/trap-handler/trap-handler.h"
#include "src/wasm/stacks.h"
#include "src/wasm/wasm-code-manager.h"
#include "src/wasm/wasm-code-pointer-table-inl.h"
#include "src/wasm/wasm-engine.h"
#include "src/wasm/wasm-module.h"
#include "src/wasm/wasm-objects.h"
Expand Down Expand Up @@ -4097,6 +4099,15 @@ Isolate::Isolate(IsolateGroup* isolate_group)
embedded_data.InstructionStartOf(Builtin::kWasmTrapHandlerLandingPad);
i::trap_handler::SetLandingPad(landing_pad);
}
wasm::WasmCodePointerTable* wasm_code_pointer_table =
wasm::GetProcessWideWasmCodePointerTable();
for (size_t i = 0; i < Builtins::kNumWasmIndirectlyCallableBuiltins; i++) {
// TODO(sroettger): investigate if we can use a global set of handles for
// these builtins.
wasm_builtin_code_handles_[i] =
wasm_code_pointer_table->AllocateAndInitializeEntry(Builtins::EntryOf(
Builtins::kWasmIndirectlyCallableBuiltins[i], this));
}
#endif // V8_ENABLE_WEBASSEMBLY

MicrotaskQueue::SetUpDefaultMicrotaskQueue(this);
Expand Down Expand Up @@ -4599,6 +4610,14 @@ Isolate::~Isolate() {
read_only_heap_ = nullptr;
}

#if V8_ENABLE_WEBASSEMBLY
wasm::WasmCodePointerTable* wasm_code_pointer_table =
wasm::GetProcessWideWasmCodePointerTable();
for (size_t i = 0; i < Builtins::kNumWasmIndirectlyCallableBuiltins; i++) {
wasm_code_pointer_table->FreeEntry(wasm_builtin_code_handles_[i]);
}
#endif

// isolate_group_ released in caller, to ensure that all member destructors
// run before potentially unmapping the isolate's VirtualMemoryArea.
}
Expand Down
4 changes: 4 additions & 0 deletions src/execution/isolate.h
Original file line number Diff line number Diff line change
Expand Up @@ -1374,6 +1374,9 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
}
wasm::WasmOrphanedGlobalHandle* NewWasmOrphanedGlobalHandle();
wasm::StackPool& stack_pool() { return stack_pool_; }
Builtins::WasmBuiltinHandleArray& wasm_builtin_code_handles() {
return wasm_builtin_code_handles_;
}
#endif // V8_ENABLE_WEBASSEMBLY

GlobalHandles* global_handles() const { return global_handles_; }
Expand Down Expand Up @@ -2750,6 +2753,7 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
#endif // V8_ENABLE_DRUMBRAKE
wasm::WasmOrphanedGlobalHandle* wasm_orphaned_handle_ = nullptr;
wasm::StackPool stack_pool_;
Builtins::WasmBuiltinHandleArray wasm_builtin_code_handles_;
#endif

// Enables the host application to provide a mechanism for recording a
Expand Down
2 changes: 2 additions & 0 deletions src/wasm/wasm-code-pointer-table.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ class V8_EXPORT_PRIVATE WasmCodePointerTable
WasmCodePointerTable(const WasmCodePointerTable&) = delete;
WasmCodePointerTable& operator=(const WasmCodePointerTable&) = delete;

using Handle = uint32_t;

using WriteScope = CFIMetadataWriteScope;

// The table should be initialized exactly once before use.
Expand Down

0 comments on commit 2166490

Please sign in to comment.