blob: 305d0089c38986391164a784ad46a7759f5f91b8 [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/ia32/frames-ia32.h"
13#include "src/ic/ic.h"
14#include "src/macro-assembler.h"
15#include "test/cctest/cctest.h"
16#include "test/cctest/compiler/c-signature.h"
17#include "test/cctest/compiler/call-tester.h"
18
19using namespace v8::internal;
20using namespace v8::internal::compiler;
21
22#define __ assm.
23
24static int32_t DummyStaticFunction(Object* result) { return 1; }
25
Ben Murdochc5610432016-08-08 18:44:38 +010026TEST(WasmRelocationIa32MemoryReference) {
Ben Murdochda12d292016-06-02 14:46:10 +010027 Isolate* isolate = CcTest::i_isolate();
28 Zone zone(isolate->allocator());
29 HandleScope scope(isolate);
30 v8::internal::byte buffer[4096];
31 Assembler assm(isolate, buffer, sizeof buffer);
32 DummyStaticFunction(NULL);
33 int32_t imm = 1234567;
34
35 __ mov(eax, Immediate(reinterpret_cast<Address>(imm),
36 RelocInfo::WASM_MEMORY_REFERENCE));
37 __ nop();
38 __ ret(0);
39
40 CSignature0<int32_t> csig;
41 CodeDesc desc;
42 assm.GetCode(&desc);
43 Handle<Code> code = isolate->factory()->NewCode(
44 desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
45 USE(code);
46
47 CodeRunner<int32_t> runnable(isolate, code, &csig);
48 int32_t ret_value = runnable.Call();
49 CHECK_EQ(ret_value, imm);
50
51#ifdef OBJECT_PRINT
52 OFStream os(stdout);
53 code->Print(os);
54 byte* begin = code->instruction_start();
55 byte* end = begin + code->instruction_size();
56 disasm::Disassembler::Disassemble(stdout, begin, end);
57#endif
58
59 size_t offset = 1234;
60
61 // Relocating references by offset
62 int mode_mask = (1 << RelocInfo::WASM_MEMORY_REFERENCE);
63 for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
64 RelocInfo::Mode mode = it.rinfo()->rmode();
65 if (RelocInfo::IsWasmMemoryReference(mode)) {
66 // Dummy values of size used here as the objective of the test is to
67 // verify that the immediate is patched correctly
68 it.rinfo()->update_wasm_memory_reference(
69 it.rinfo()->wasm_memory_reference(),
70 it.rinfo()->wasm_memory_reference() + offset, 1, 2,
71 SKIP_ICACHE_FLUSH);
72 }
73 }
74
75 // Check if immediate is updated correctly
76 ret_value = runnable.Call();
77 CHECK_EQ(ret_value, imm + offset);
78
79#ifdef OBJECT_PRINT
Ben Murdochda12d292016-06-02 14:46:10 +010080 code->Print(os);
81 begin = code->instruction_start();
82 end = begin + code->instruction_size();
83 disasm::Disassembler::Disassemble(stdout, begin, end);
84#endif
85}
86
Ben Murdochc5610432016-08-08 18:44:38 +010087TEST(WasmRelocationIa32MemorySizeReference) {
88 CcTest::InitializeVM();
89 Isolate* isolate = CcTest::i_isolate();
90 Zone zone(isolate->allocator());
91 HandleScope scope(isolate);
92 v8::internal::byte buffer[4096];
93 Assembler assm(isolate, buffer, sizeof buffer);
94 DummyStaticFunction(NULL);
95 int32_t size = 80;
96 Label fail;
97
98 __ mov(eax, Immediate(reinterpret_cast<Address>(size),
99 RelocInfo::WASM_MEMORY_SIZE_REFERENCE));
100 __ cmp(eax, Immediate(reinterpret_cast<Address>(size),
101 RelocInfo::WASM_MEMORY_SIZE_REFERENCE));
102 __ j(not_equal, &fail);
103 __ ret(0);
104 __ bind(&fail);
105 __ mov(eax, 0xdeadbeef);
106 __ ret(0);
107
108 CSignature0<int32_t> csig;
109 CodeDesc desc;
110 assm.GetCode(&desc);
111 Handle<Code> code = isolate->factory()->NewCode(
112 desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
113 USE(code);
114
115 CodeRunner<int32_t> runnable(isolate, code, &csig);
116 int32_t ret_value = runnable.Call();
117 CHECK_NE(ret_value, 0xdeadbeef);
118
119#ifdef OBJECT_PRINT
120 OFStream os(stdout);
121 code->Print(os);
122 byte* begin = code->instruction_start();
123 byte* end = begin + code->instruction_size();
124 disasm::Disassembler::Disassemble(stdout, begin, end);
125#endif
126
127 size_t offset = 10;
128
129 int mode_mask = (1 << RelocInfo::WASM_MEMORY_SIZE_REFERENCE);
130 for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
131 RelocInfo::Mode mode = it.rinfo()->rmode();
132 if (RelocInfo::IsWasmMemorySizeReference(mode)) {
133 it.rinfo()->update_wasm_memory_reference(
134 reinterpret_cast<Address>(1234), reinterpret_cast<Address>(1234),
135 it.rinfo()->wasm_memory_size_reference(),
136 it.rinfo()->wasm_memory_size_reference() + offset, SKIP_ICACHE_FLUSH);
137 }
138 }
139
140 ret_value = runnable.Call();
141 CHECK_NE(ret_value, 0xdeadbeef);
142
143#ifdef OBJECT_PRINT
144 code->Print(os);
145 begin = code->instruction_start();
146 end = begin + code->instruction_size();
147 disasm::Disassembler::Disassemble(stdout, begin, end);
148#endif
149}
Ben Murdochda12d292016-06-02 14:46:10 +0100150#undef __