Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[JSC] wasm fault trampoline should be C code since it is tagged as CF…
…unctionPtr

https://bugs.webkit.org/show_bug.cgi?id=218781

Reviewed by Keith Miller and Mark Lam.

When returning from signal handler, handler requires that instruction pointer is CFunctionPtrTag-ed.
So we should set C trampoline instead of JIT trampoline here.
This patch implements trampoline in LLInt Wasm code so that we can use CFunctionPtrTag.

* bytecode/BytecodeList.rb:
* llint/WebAssembly.asm:
* wasm/WasmFaultSignalHandler.cpp:
(JSC::Wasm::trapHandler):

Canonical link: https://commits.webkit.org/231473@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@269694 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Constellation committed Nov 11, 2020
1 parent ab2ac01 commit f185772
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 36 deletions.
16 changes: 16 additions & 0 deletions Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,19 @@
2020-11-11 Yusuke Suzuki <ysuzuki@apple.com>

[JSC] wasm fault trampoline should be C code since it is tagged as CFunctionPtr
https://bugs.webkit.org/show_bug.cgi?id=218781

Reviewed by Keith Miller and Mark Lam.

When returning from signal handler, handler requires that instruction pointer is CFunctionPtrTag-ed.
So we should set C trampoline instead of JIT trampoline here.
This patch implements trampoline in LLInt Wasm code so that we can use CFunctionPtrTag.

* bytecode/BytecodeList.rb:
* llint/WebAssembly.asm:
* wasm/WasmFaultSignalHandler.cpp:
(JSC::Wasm::trapHandler):

2020-11-10 Commit Queue <commit-queue@webkit.org>

Unreviewed, reverting r269660.
Expand Down
1 change: 1 addition & 0 deletions Source/JavaScriptCore/bytecode/BytecodeList.rb
Expand Up @@ -1467,6 +1467,7 @@
# Helpers

op :throw_from_slow_path_trampoline
op :throw_from_fault_handler_trampoline

op :call_return_location
op :call_no_tls_return_location
Expand Down
34 changes: 33 additions & 1 deletion Source/JavaScriptCore/llint/WebAssembly.asm
Expand Up @@ -214,9 +214,17 @@ macro restoreCalleeSavesUsedByWasm()
end
end

macro loadWasmInstanceFromTLSTo(reg)
if HAVE_FAST_TLS
tls_loadp WTF_WASM_CONTEXT_KEY, reg
else
crash()
end
end

macro loadWasmInstanceFromTLS()
if HAVE_FAST_TLS
tls_loadp WTF_WASM_CONTEXT_KEY, wasmInstance
loadWasmInstanceFromTLSTo(wasmInstance)
else
crash()
end
Expand Down Expand Up @@ -519,6 +527,30 @@ op(wasm_throw_from_slow_path_trampoline, macro ()
end
end)

op(wasm_throw_from_fault_handler_trampoline, macro ()
move wasmInstance, a2
btqz a1, .instanceReady # a1 is non-zero if FastTLS is enabled.
loadWasmInstanceFromTLSTo(a2)
.instanceReady:
loadp Wasm::Instance::m_pointerToTopEntryFrame[a2], a0
loadp [a0], a0
copyCalleeSavesToEntryFrameCalleeSavesBuffer(a0)

move constexpr Wasm::ExceptionType::OutOfBoundsMemoryAccess, a3
# a2 is Wasm::Instance
move 0, a1
move cfr, a0
cCall4(_slow_path_wasm_throw_exception)

if ARM64E
move r0, a0
leap JSCConfig + constexpr JSC::offsetOfJSCConfigGateMap + (constexpr Gate::exceptionHandler) * PtrSize, a1
jmp [a1], NativeToJITGatePtrTag # ExceptionHandlerPtrTag
else
jmp r0, ExceptionHandlerPtrTag
end
end)

# Disable wide version of narrow-only opcodes
noWide(wasm_enter)
noWide(wasm_wide16)
Expand Down
15 changes: 0 additions & 15 deletions Source/JavaScriptCore/wasm/WasmAirIRGenerator.cpp
Expand Up @@ -776,21 +776,6 @@ AirIRGenerator::AirIRGenerator(const ModuleInformation& info, B3::Procedure& pro
m_code.pinRegister(m_memorySizeGPR);
}

if (info.memory) {
switch (m_mode) {
case MemoryMode::BoundsChecking:
break;
case MemoryMode::Signaling:
// Most memory accesses in signaling mode don't do an explicit
// exception check because they can rely on fault handling to detect
// out-of-bounds accesses. FaultSignalHandler nonetheless needs the
// thunk to exist so that it can jump to that thunk.
if (UNLIKELY(!Thunks::singleton().stub(throwExceptionFromWasmThunkGenerator)))
CRASH();
break;
}
}

m_code.setNumEntrypoints(1);

GPRReg contextInstance = Context::useFastTLS() ? wasmCallingConvention().prologueScratchGPRs[1] : m_wasmContextInstanceGPR;
Expand Down
13 changes: 0 additions & 13 deletions Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp
Expand Up @@ -425,19 +425,6 @@ B3IRGenerator::B3IRGenerator(const ModuleInformation& info, Procedure& procedure
}
this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsMemoryAccess);
});

switch (m_mode) {
case MemoryMode::BoundsChecking:
break;
case MemoryMode::Signaling:
// Most memory accesses in signaling mode don't do an explicit
// exception check because they can rely on fault handling to detect
// out-of-bounds accesses. FaultSignalHandler nonetheless needs the
// thunk to exist so that it can jump to that thunk.
if (UNLIKELY(!Thunks::singleton().stub(throwExceptionFromWasmThunkGenerator)))
CRASH();
break;
}
}

{
Expand Down
11 changes: 4 additions & 7 deletions Source/JavaScriptCore/wasm/WasmFaultSignalHandler.cpp
Expand Up @@ -29,10 +29,12 @@
#if ENABLE(WEBASSEMBLY)

#include "ExecutableAllocator.h"
#include "LLIntData.h"
#include "MachineContext.h"
#include "WasmCallee.h"
#include "WasmCalleeRegistry.h"
#include "WasmCapabilities.h"
#include "WasmContextInlines.h"
#include "WasmExceptionType.h"
#include "WasmMemory.h"
#include "WasmThunks.h"
Expand Down Expand Up @@ -80,13 +82,8 @@ static SignalAction trapHandler(Signal, SigInfo& sigInfo, PlatformRegisters& con
dataLogLnIf(WasmFaultSignalHandlerInternal::verbose, "function start: ", RawPointer(start), " end: ", RawPointer(end));
if (start <= faultingInstruction && faultingInstruction < end) {
dataLogLnIf(WasmFaultSignalHandlerInternal::verbose, "found match");
MacroAssemblerCodeRef<JITThunkPtrTag> exceptionStub = Thunks::singleton().existingStub(throwExceptionFromWasmThunkGenerator);
// If for whatever reason we don't have a stub then we should just treat this like a regular crash.
if (!exceptionStub)
break;
dataLogLnIf(WasmFaultSignalHandlerInternal::verbose, "found stub: ", RawPointer(exceptionStub.code().executableAddress()));
MachineContext::argumentPointer<1>(context) = reinterpret_cast<void*>(ExceptionType::OutOfBoundsMemoryAccess);
MachineContext::setInstructionPointer(context, exceptionStub.code().retagged<CFunctionPtrTag>());
MachineContext::argumentPointer<1>(context) = reinterpret_cast<void*>(static_cast<uintptr_t>(Wasm::Context::useFastTLS()));
MachineContext::setInstructionPointer(context, LLInt::getCodePtr<CFunctionPtrTag>(wasm_throw_from_fault_handler_trampoline));
return SignalAction::Handled;
}
}
Expand Down

0 comments on commit f185772

Please sign in to comment.