blob: 3b49f00afc348e963e4f2a03298c58b14be30583 [file] [log] [blame]
Ben Murdochda12d292016-06-02 14:46:10 +01001// Copyright 2015 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#include <iostream> // NOLINT(readability/streams)
6
7#include "src/v8.h"
8#include "test/cctest/cctest.h"
9
10#include "src/arm64/simulator-arm64.h"
11#include "src/arm64/utils-arm64.h"
12#include "src/disassembler.h"
13#include "src/factory.h"
14#include "src/macro-assembler.h"
15#include "src/ostreams.h"
16#include "test/cctest/compiler/c-signature.h"
17#include "test/cctest/compiler/call-tester.h"
18
19using namespace v8::base;
20using namespace v8::internal;
21using namespace v8::internal::compiler;
22
23#define __ masm.
24
25static int64_t DummyStaticFunction(Object* result) { return 1; }
26
Ben Murdochc5610432016-08-08 18:44:38 +010027TEST(WasmRelocationArm64MemoryReference) {
Ben Murdochda12d292016-06-02 14:46:10 +010028 Isolate* isolate = CcTest::i_isolate();
29 HandleScope scope(isolate);
30 v8::internal::byte buffer[4096];
31 DummyStaticFunction(NULL);
32 int64_t imm = 1234567;
33
34 MacroAssembler masm(isolate, buffer, sizeof buffer,
35 v8::internal::CodeObjectRequired::kYes);
36
37 __ Mov(x0, Immediate(imm, RelocInfo::WASM_MEMORY_REFERENCE));
38 __ Ret();
39
40 CodeDesc desc;
41 masm.GetCode(&desc);
42 Handle<Code> code = isolate->factory()->NewCode(
43 desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
44
45 CSignature0<int64_t> csig;
46 CodeRunner<int64_t> runnable(isolate, code, &csig);
47 int64_t ret_value = runnable.Call();
48 CHECK_EQ(ret_value, imm);
49
50#ifdef DEBUG
51 OFStream os(stdout);
52 code->Print(os);
Ben Murdochc5610432016-08-08 18:44:38 +010053 ::printf("f() = %" PRIx64 "\n\n", ret_value);
Ben Murdochda12d292016-06-02 14:46:10 +010054#endif
55 size_t offset = 1234;
56
57 // Relocating reference by offset
58 int mode_mask = (1 << RelocInfo::WASM_MEMORY_REFERENCE);
59 for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
60 RelocInfo::Mode mode = it.rinfo()->rmode();
61 if (RelocInfo::IsWasmMemoryReference(mode)) {
62 // Dummy values of size used here as the objective of the test is to
63 // verify that the immediate is patched correctly
64 it.rinfo()->update_wasm_memory_reference(
65 it.rinfo()->wasm_memory_reference(),
66 it.rinfo()->wasm_memory_reference() + offset, 1, 2,
67 SKIP_ICACHE_FLUSH);
68 }
69 }
70
71 // Call into relocated code object
72 ret_value = runnable.Call();
73 CHECK_EQ((imm + offset), ret_value);
74
75#ifdef DEBUG
76 code->Print(os);
Ben Murdochc5610432016-08-08 18:44:38 +010077 ::printf("f() = %" PRIx64 "\n\n", ret_value);
78#endif
79}
80
81TEST(WasmRelocationArm64MemorySizeReference) {
82 CcTest::InitializeVM();
83 Isolate* isolate = CcTest::i_isolate();
84 HandleScope scope(isolate);
85 v8::internal::byte buffer[4096];
86 DummyStaticFunction(NULL);
87 Immediate size = Immediate(512, RelocInfo::WASM_MEMORY_SIZE_REFERENCE);
88 Label fail;
89
90 MacroAssembler masm(isolate, buffer, sizeof buffer,
91 v8::internal::CodeObjectRequired::kYes);
92
93 __ Mov(x0, size);
94 __ Cmp(x0, size);
95 __ B(ne, &fail);
96 __ Ret();
97 __ Bind(&fail);
98 __ Mov(x0, Immediate(0xdeadbeef));
99 __ Ret();
100
101 CodeDesc desc;
102 masm.GetCode(&desc);
103 Handle<Code> code = isolate->factory()->NewCode(
104 desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
105
106 CSignature0<int64_t> csig;
107 CodeRunner<int64_t> runnable(isolate, code, &csig);
108 int64_t ret_value = runnable.Call();
109 CHECK_NE(ret_value, 0xdeadbeef);
110
111#ifdef DEBUG
112 OFStream os(stdout);
113 code->Print(os);
114 ::printf("f() = %" PRIx64 "\n\n", ret_value);
115#endif
116 int32_t diff = 512;
117
118 int mode_mask = (1 << RelocInfo::WASM_MEMORY_SIZE_REFERENCE);
119 for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
120 RelocInfo::Mode mode = it.rinfo()->rmode();
121 if (RelocInfo::IsWasmMemorySizeReference(mode)) {
122 it.rinfo()->update_wasm_memory_reference(
123 reinterpret_cast<Address>(0x1234), reinterpret_cast<Address>(0x1234),
124 it.rinfo()->wasm_memory_size_reference(),
125 it.rinfo()->wasm_memory_size_reference() + diff, SKIP_ICACHE_FLUSH);
126 }
127 }
128
129 ret_value = runnable.Call();
130 CHECK_NE(ret_value, 0xdeadbeef);
131
132#ifdef DEBUG
133 code->Print(os);
134 ::printf("f() = %" PRIx64 "\n\n", ret_value);
Ben Murdochda12d292016-06-02 14:46:10 +0100135#endif
136}
137
138#undef __