summaryrefslogtreecommitdiff
path: root/deps/v8/test/cctest/test-run-wasm-relocation-arm64.cc
blob: 3b49f00afc348e963e4f2a03298c58b14be30583 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <iostream>  // NOLINT(readability/streams)

#include "src/v8.h"
#include "test/cctest/cctest.h"

#include "src/arm64/simulator-arm64.h"
#include "src/arm64/utils-arm64.h"
#include "src/disassembler.h"
#include "src/factory.h"
#include "src/macro-assembler.h"
#include "src/ostreams.h"
#include "test/cctest/compiler/c-signature.h"
#include "test/cctest/compiler/call-tester.h"

using namespace v8::base;
using namespace v8::internal;
using namespace v8::internal::compiler;

#define __ masm.

static int64_t DummyStaticFunction(Object* result) { return 1; }

TEST(WasmRelocationArm64MemoryReference) {
  Isolate* isolate = CcTest::i_isolate();
  HandleScope scope(isolate);
  v8::internal::byte buffer[4096];
  DummyStaticFunction(NULL);
  int64_t imm = 1234567;

  MacroAssembler masm(isolate, buffer, sizeof buffer,
                      v8::internal::CodeObjectRequired::kYes);

  __ Mov(x0, Immediate(imm, RelocInfo::WASM_MEMORY_REFERENCE));
  __ Ret();

  CodeDesc desc;
  masm.GetCode(&desc);
  Handle<Code> code = isolate->factory()->NewCode(
      desc, Code::ComputeFlags(Code::STUB), Handle<Code>());

  CSignature0<int64_t> csig;
  CodeRunner<int64_t> runnable(isolate, code, &csig);
  int64_t ret_value = runnable.Call();
  CHECK_EQ(ret_value, imm);

#ifdef DEBUG
  OFStream os(stdout);
  code->Print(os);
  ::printf("f() = %" PRIx64 "\n\n", ret_value);
#endif
  size_t offset = 1234;

  // Relocating reference by offset
  int mode_mask = (1 << RelocInfo::WASM_MEMORY_REFERENCE);
  for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
    RelocInfo::Mode mode = it.rinfo()->rmode();
    if (RelocInfo::IsWasmMemoryReference(mode)) {
      // Dummy values of size used here as the objective of the test is to
      // verify that the immediate is patched correctly
      it.rinfo()->update_wasm_memory_reference(
          it.rinfo()->wasm_memory_reference(),
          it.rinfo()->wasm_memory_reference() + offset, 1, 2,
          SKIP_ICACHE_FLUSH);
    }
  }

  // Call into relocated code object
  ret_value = runnable.Call();
  CHECK_EQ((imm + offset), ret_value);

#ifdef DEBUG
  code->Print(os);
  ::printf("f() = %" PRIx64 "\n\n", ret_value);
#endif
}

TEST(WasmRelocationArm64MemorySizeReference) {
  CcTest::InitializeVM();
  Isolate* isolate = CcTest::i_isolate();
  HandleScope scope(isolate);
  v8::internal::byte buffer[4096];
  DummyStaticFunction(NULL);
  Immediate size = Immediate(512, RelocInfo::WASM_MEMORY_SIZE_REFERENCE);
  Label fail;

  MacroAssembler masm(isolate, buffer, sizeof buffer,
                      v8::internal::CodeObjectRequired::kYes);

  __ Mov(x0, size);
  __ Cmp(x0, size);
  __ B(ne, &fail);
  __ Ret();
  __ Bind(&fail);
  __ Mov(x0, Immediate(0xdeadbeef));
  __ Ret();

  CodeDesc desc;
  masm.GetCode(&desc);
  Handle<Code> code = isolate->factory()->NewCode(
      desc, Code::ComputeFlags(Code::STUB), Handle<Code>());

  CSignature0<int64_t> csig;
  CodeRunner<int64_t> runnable(isolate, code, &csig);
  int64_t ret_value = runnable.Call();
  CHECK_NE(ret_value, 0xdeadbeef);

#ifdef DEBUG
  OFStream os(stdout);
  code->Print(os);
  ::printf("f() = %" PRIx64 "\n\n", ret_value);
#endif
  int32_t diff = 512;

  int mode_mask = (1 << RelocInfo::WASM_MEMORY_SIZE_REFERENCE);
  for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
    RelocInfo::Mode mode = it.rinfo()->rmode();
    if (RelocInfo::IsWasmMemorySizeReference(mode)) {
      it.rinfo()->update_wasm_memory_reference(
          reinterpret_cast<Address>(0x1234), reinterpret_cast<Address>(0x1234),
          it.rinfo()->wasm_memory_size_reference(),
          it.rinfo()->wasm_memory_size_reference() + diff, SKIP_ICACHE_FLUSH);
    }
  }

  ret_value = runnable.Call();
  CHECK_NE(ret_value, 0xdeadbeef);

#ifdef DEBUG
  code->Print(os);
  ::printf("f() = %" PRIx64 "\n\n", ret_value);
#endif
}

#undef __