blob: 11fa45164e4c3ccdf79be70d285d4902ab8e8c7b [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 <stdlib.h>
6
7#include "src/v8.h"
8
9#include "src/debug/debug.h"
10#include "src/disasm.h"
11#include "src/disassembler.h"
12#include "src/ic/ic.h"
13#include "src/macro-assembler.h"
14#include "test/cctest/cctest.h"
15#include "test/cctest/compiler/c-signature.h"
16#include "test/cctest/compiler/call-tester.h"
17
18using namespace v8::internal;
19using namespace v8::internal::compiler;
20
21#define __ assm.
22
23static int32_t DummyStaticFunction(Object* result) { return 1; }
Ben Murdochc5610432016-08-08 18:44:38 +010024
25TEST(WasmRelocationX64MemoryReference) {
Ben Murdochda12d292016-06-02 14:46:10 +010026 Isolate* isolate = CcTest::i_isolate();
27 HandleScope scope(isolate);
28 v8::internal::byte buffer[4096];
29 Assembler assm(isolate, buffer, sizeof buffer);
30 DummyStaticFunction(NULL);
31 int64_t imm = 1234567;
32
33 __ movq(rax, imm, RelocInfo::WASM_MEMORY_REFERENCE);
34 __ nop();
35 __ ret(0);
36
37 CodeDesc desc;
38 assm.GetCode(&desc);
39 Handle<Code> code = isolate->factory()->NewCode(
40 desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
41 USE(code);
42
43 CSignature0<int64_t> csig;
44 CodeRunner<int64_t> runnable(isolate, code, &csig);
45 int64_t ret_value = runnable.Call();
46 CHECK_EQ(ret_value, imm);
47
48#ifdef OBJECT_PRINT
49 OFStream os(stdout);
50 code->Print(os);
51 byte* begin = code->instruction_start();
52 byte* end = begin + code->instruction_size();
53 disasm::Disassembler::Disassemble(stdout, begin, end);
54#endif
55 size_t offset = 1234;
56
57 // Relocating references 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 // Check if immediate is updated correctly
72 ret_value = runnable.Call();
73 CHECK_EQ(ret_value, imm + offset);
74
75#ifdef OBJECT_PRINT
76 code->Print(os);
77 begin = code->instruction_start();
78 end = begin + code->instruction_size();
79 disasm::Disassembler::Disassemble(stdout, begin, end);
80#endif
81}
82
Ben Murdochc5610432016-08-08 18:44:38 +010083TEST(WasmRelocationX64WasmMemorySizeReference) {
84 CcTest::InitializeVM();
85 Isolate* isolate = CcTest::i_isolate();
86 HandleScope scope(isolate);
87 v8::internal::byte buffer[4096];
88 Assembler assm(isolate, buffer, sizeof buffer);
89 DummyStaticFunction(NULL);
90 int32_t size = 512;
91 Label fail;
92
93 __ movl(rax, Immediate(size, RelocInfo::WASM_MEMORY_SIZE_REFERENCE));
94 __ cmpl(rax, Immediate(size, RelocInfo::WASM_MEMORY_SIZE_REFERENCE));
95 __ j(not_equal, &fail);
96 __ ret(0);
97 __ bind(&fail);
98 __ movl(rax, Immediate(0xdeadbeef));
99 __ ret(0);
100
101 CodeDesc desc;
102 assm.GetCode(&desc);
103 Handle<Code> code = isolate->factory()->NewCode(
104 desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
105 USE(code);
106
107 CSignature0<int64_t> csig;
108 CodeRunner<int64_t> runnable(isolate, code, &csig);
109 int64_t ret_value = runnable.Call();
110 CHECK_NE(ret_value, 0xdeadbeef);
111
112#ifdef OBJECT_PRINT
113 OFStream os(stdout);
114 code->Print(os);
115 byte* begin = code->instruction_start();
116 byte* end = begin + code->instruction_size();
117 disasm::Disassembler::Disassemble(stdout, begin, end);
118#endif
119 int32_t diff = 512;
120
121 int mode_mask = (1 << RelocInfo::WASM_MEMORY_SIZE_REFERENCE);
122 for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
123 RelocInfo::Mode mode = it.rinfo()->rmode();
124 if (RelocInfo::IsWasmMemorySizeReference(mode)) {
125 it.rinfo()->update_wasm_memory_reference(
126 reinterpret_cast<Address>(1234), reinterpret_cast<Address>(1234),
127 it.rinfo()->wasm_memory_size_reference(),
128 it.rinfo()->wasm_memory_size_reference() + diff, SKIP_ICACHE_FLUSH);
129 }
130 }
131
132 ret_value = runnable.Call();
133 CHECK_NE(ret_value, 0xdeadbeef);
134
135#ifdef OBJECT_PRINT
136 code->Print(os);
137 begin = code->instruction_start();
138 end = begin + code->instruction_size();
139 disasm::Disassembler::Disassemble(stdout, begin, end);
140#endif
141}
Ben Murdochda12d292016-06-02 14:46:10 +0100142#undef __