Commit 13cb0504 authored by Michael Starzinger's avatar Michael Starzinger Committed by Commit Bot

[wasm] Fix JumpTableAssembler corrupting surrounding code.

We instantiate the JumpTableAssembler in patching mode (i.e. directly on
existing code without an intermittent buffer). In this mode it is not
possible to record reloc information. This makes sure we no longer just
blindly write into the non-existing buffer.

R=clemensh@chromium.org
BUG=v8:8028

Change-Id: I4abb8f06cf819fef608e901c4740263f0cecd08a
Reviewed-on: https://chromium-review.googlesource.com/1166834
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Reviewed-by: 's avatarClemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54966}
parent 363fe1eb
......@@ -5094,6 +5094,7 @@ void Assembler::dq(uint64_t value) {
}
void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
if (options().disable_reloc_info_for_patching) return;
if (RelocInfo::IsNone(rmode) ||
// Don't record external references unless the heap will be serialized.
(RelocInfo::IsOnlyForSerializer(rmode) &&
......
......@@ -4749,6 +4749,7 @@ void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data,
ConstantPoolMode constant_pool_mode) {
// Non-relocatable constants should not end up in the literal pool.
DCHECK(!RelocInfo::IsNone(rmode));
if (options().disable_reloc_info_for_patching) return;
// We do not try to reuse pool constants.
RelocInfo rinfo(reinterpret_cast<Address>(pc_), rmode, data, nullptr);
......@@ -4775,7 +4776,7 @@ void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data,
// For modes that cannot use the constant pool, a different sequence of
// instructions will be emitted by this function's caller.
if (!RelocInfo::IsNone(rmode) && write_reloc_info) {
if (write_reloc_info) {
// Don't record external references unless the heap will be serialized.
if (RelocInfo::IsOnlyForSerializer(rmode) &&
!options().record_reloc_info_for_serialization && !emit_debug_code()) {
......
......@@ -138,11 +138,15 @@ class HeapObjectRequest {
enum class CodeObjectRequired { kNo, kYes };
struct V8_EXPORT_PRIVATE AssemblerOptions {
// Recording reloc info and for external references and off-heap targets is
// Recording reloc info for external references and off-heap targets is
// needed whenever code is serialized, e.g. into the snapshot or as a WASM
// module. This flag allows this reloc info to be disabled for code that
// will not survive process destruction.
bool record_reloc_info_for_serialization = true;
// Recording reloc info can be disabled wholesale. This is needed when the
// assembler is used on existing code directly (e.g. JumpTableAssembler)
// without any buffer to hold reloc information.
bool disable_reloc_info_for_patching = false;
// Enables access to exrefs by computing a delta from the root array.
// Only valid if code will not survive the process.
bool enable_root_array_delta_access = false;
......
......@@ -3324,6 +3324,7 @@ void Assembler::dd(Label* label) {
void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
DCHECK(!RelocInfo::IsNone(rmode));
if (options().disable_reloc_info_for_patching) return;
// Don't record external references unless the heap will be serialized.
if (RelocInfo::IsOnlyForSerializer(rmode) &&
!options().record_reloc_info_for_serialization && !emit_debug_code()) {
......
......@@ -3854,6 +3854,7 @@ void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
// We do not try to reuse pool constants.
RelocInfo rinfo(reinterpret_cast<Address>(pc_), rmode, data, nullptr);
if (!RelocInfo::IsNone(rinfo.rmode())) {
if (options().disable_reloc_info_for_patching) return;
if (RelocInfo::IsOnlyForSerializer(rmode) &&
!options().record_reloc_info_for_serialization && !emit_debug_code()) {
return;
......
......@@ -4199,6 +4199,7 @@ void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
// We do not try to reuse pool constants.
RelocInfo rinfo(reinterpret_cast<Address>(pc_), rmode, data, nullptr);
if (!RelocInfo::IsNone(rinfo.rmode())) {
if (options().disable_reloc_info_for_patching) return;
// Don't record external references unless the heap will be serialized.
if (RelocInfo::IsOnlyForSerializer(rmode) &&
!options().record_reloc_info_for_serialization && !emit_debug_code()) {
......
......@@ -2070,6 +2070,7 @@ void Assembler::dp(uintptr_t data) {
void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
if (options().disable_reloc_info_for_patching) return;
if (RelocInfo::IsNone(rmode) ||
// Don't record external references unless the heap will be serialized.
(RelocInfo::IsOnlyForSerializer(rmode) &&
......
......@@ -794,6 +794,7 @@ void Assembler::dp(uintptr_t data) {
}
void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
if (options().disable_reloc_info_for_patching) return;
if (RelocInfo::IsNone(rmode) ||
// Don't record external references unless the heap will be serialized.
(RelocInfo::IsOnlyForSerializer(rmode) &&
......
......@@ -81,16 +81,9 @@ class JumpTableAssembler : public TurboAssembler {
}
private:
// {JumpTableAssembler} is never used during snapshot generation, and its code
// must be independent of the code range of any isolate anyway. So just use
// this default {Options} for each {JumpTableAssembler}.
JumpTableAssembler()
: TurboAssembler(nullptr, AssemblerOptions{}, nullptr, 0,
CodeObjectRequired::kNo) {}
// Instantiate a {JumpTableAssembler} for patching.
explicit JumpTableAssembler(Address slot_addr, int size = 256)
: TurboAssembler(nullptr, AssemblerOptions{},
: TurboAssembler(nullptr, JumpTableAssemblerOptions(),
reinterpret_cast<void*>(slot_addr), size,
CodeObjectRequired::kNo) {}
......@@ -135,6 +128,16 @@ class JumpTableAssembler : public TurboAssembler {
static constexpr int kJumpTableSlotsPerLine =
kJumpTableLineSize / kJumpTableSlotSize;
// {JumpTableAssembler} is never used during snapshot generation, and its code
// must be independent of the code range of any isolate anyway. Just ensure
// that no relocation information is recorded, there is no buffer to store it
// since it is instantiated in patching mode in existing code directly.
static AssemblerOptions JumpTableAssemblerOptions() {
AssemblerOptions options;
options.disable_reloc_info_for_patching = true;
return options;
}
void EmitLazyCompileJumpSlot(uint32_t func_index,
Address lazy_compile_target);
......
......@@ -4941,6 +4941,7 @@ void Assembler::dq(Label* label) {
void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
DCHECK(!RelocInfo::IsNone(rmode));
if (options().disable_reloc_info_for_patching) return;
if (RelocInfo::IsOnlyForSerializer(rmode) &&
!options().record_reloc_info_for_serialization && !emit_debug_code()) {
return;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment