blob: b2e6ec3a3b2bc669c390c52c82e507a11e7e90fd [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/arm/assembler-arm-inl.h"
11#include "src/arm/simulator-arm.h"
12#include "src/disassembler.h"
13#include "src/factory.h"
14#include "src/ostreams.h"
15#include "test/cctest/compiler/c-signature.h"
16#include "test/cctest/compiler/call-tester.h"
17
18using namespace v8::base;
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(WasmRelocationArmMemoryReference) {
Ben Murdochda12d292016-06-02 14:46:10 +010027 Isolate* isolate = CcTest::i_isolate();
28 HandleScope scope(isolate);
29 v8::internal::byte buffer[4096];
30 DummyStaticFunction(NULL);
31 int32_t imm = 1234567;
32
33 Assembler assm(isolate, buffer, sizeof buffer);
34
35 __ mov(r0, Operand(imm, RelocInfo::WASM_MEMORY_REFERENCE));
36 __ mov(pc, Operand(lr));
37
38 CodeDesc desc;
39 assm.GetCode(&desc);
40 Handle<Code> code = isolate->factory()->NewCode(
41 desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
42
43 CSignature0<int32_t> csig;
44 CodeRunner<int32_t> runnable(isolate, code, &csig);
45 int32_t ret_value = runnable.Call();
46 CHECK_EQ(ret_value, imm);
47
48#ifdef DEBUG
49 OFStream os(stdout);
50 code->Print(os);
51 ::printf("f() = %d\n\n", ret_value);
52#endif
53 size_t offset = 1234;
54
55 // Relocating references by offset
56 int mode_mask = (1 << RelocInfo::WASM_MEMORY_REFERENCE);
57 for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
58 RelocInfo::Mode mode = it.rinfo()->rmode();
59 if (RelocInfo::IsWasmMemoryReference(mode)) {
60 // Dummy values of size used here as the objective of the test is to
61 // verify that the immediate is patched correctly
62 it.rinfo()->update_wasm_memory_reference(
63 it.rinfo()->wasm_memory_reference(),
64 it.rinfo()->wasm_memory_reference() + offset, 1, 2,
65 SKIP_ICACHE_FLUSH);
66 }
67 }
68
69 // Call into relocated code object
70 ret_value = runnable.Call();
71 CHECK_EQ((imm + offset), ret_value);
72
73#ifdef DEBUG
74 code->Print(os);
75 ::printf("f() = %d\n\n", ret_value);
76#endif
77}
78
Ben Murdochc5610432016-08-08 18:44:38 +010079TEST(WasmRelocationArmMemorySizeReference) {
80 CcTest::InitializeVM();
81 Isolate* isolate = CcTest::i_isolate();
82 HandleScope scope(isolate);
83 v8::internal::byte buffer[4096];
84 DummyStaticFunction(NULL);
85 int32_t size = 512;
86 Label fail;
87
88 Assembler assm(isolate, buffer, sizeof buffer);
89
90 __ mov(r0, Operand(size, RelocInfo::WASM_MEMORY_SIZE_REFERENCE));
91 __ cmp(r0, Operand(size, RelocInfo::WASM_MEMORY_SIZE_REFERENCE));
92 __ b(ne, &fail);
93 __ mov(pc, Operand(lr));
94 __ bind(&fail);
95 __ mov(r0, Operand(0xdeadbeef));
96 __ mov(pc, Operand(lr));
97
98 CodeDesc desc;
99 assm.GetCode(&desc);
100 Handle<Code> code = isolate->factory()->NewCode(
101 desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
102
103 CSignature0<int32_t> csig;
104 CodeRunner<int32_t> runnable(isolate, code, &csig);
105 int32_t ret_value = runnable.Call();
106 CHECK_NE(ret_value, 0xdeadbeef);
107
108#ifdef DEBUG
109 OFStream os(stdout);
110 code->Print(os);
111 ::printf("f() = %d\n\n", ret_value);
112#endif
113 size_t diff = 512;
114
115 int mode_mask = (1 << RelocInfo::WASM_MEMORY_SIZE_REFERENCE);
116 for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
117 RelocInfo::Mode mode = it.rinfo()->rmode();
118 if (RelocInfo::IsWasmMemorySizeReference(mode)) {
119 it.rinfo()->update_wasm_memory_reference(
120 reinterpret_cast<Address>(1234), reinterpret_cast<Address>(1234),
121 it.rinfo()->wasm_memory_size_reference(),
122 it.rinfo()->wasm_memory_size_reference() + diff, SKIP_ICACHE_FLUSH);
123 }
124 }
125
126 ret_value = runnable.Call();
127 CHECK_NE(ret_value, 0xdeadbeef);
128
129#ifdef DEBUG
130 code->Print(os);
131 ::printf("f() = %d\n\n", ret_value);
132#endif
133}
Ben Murdochda12d292016-06-02 14:46:10 +0100134#undef __