1 /*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "compiler/tests/unit_test.h"
17 #include "irtoc/backend/compiler/dangling_pointers_checker.h"
18 #include "irtoc/backend/function.h"
19 #include "irtoc/backend/irtoc_runtime.h"
20
21 namespace panda::compiler {
22 class DanglingPointersCheckerTest : public GraphTest {};
23
24 class RelocationHandlerTest : public panda::irtoc::Function {
25 public:
MakeGraphImpl()26 void MakeGraphImpl() override {};
GetName() const27 const char *GetName() const override
28 {
29 return "Test";
30 };
SetTestExternalFunctions(std::initializer_list<std::string> funcs)31 void SetTestExternalFunctions(std::initializer_list<std::string> funcs)
32 {
33 this->SetExternalFunctions(funcs);
34 }
35 };
36
37 // NOLINTBEGIN(readability-magic-numbers)
38
39 // Correct load accumulator from frame with one instruction:
40 // correct_acc_load := LoadI(LiveIn(frame).ptr).Imm(frame_acc_offset).ref
41 // Correct store into frame with instruction:
42 // correct_acc_store := StoreI(LiveIn(frame).ptr, correct_acc_load).Imm(frame_acc_offset).ref
TEST_F(DanglingPointersCheckerTest,test0)43 TEST_F(DanglingPointersCheckerTest, test0)
44 {
45 auto arch = panda::RUNTIME_ARCH;
46 SetGraphArch(arch);
47 if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
48 return;
49 }
50 auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
51 auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
52 RelocationHandlerTest relocationHandler;
53 relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
54 GetGraph()->SetRelocationHandler(&relocationHandler);
55 GetGraph()->SetMethod(&relocationHandler);
56 GetGraph()->SetMode(GraphMode::InterpreterEntry());
57
58 GRAPH(GetGraph())
59 {
60 INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
61 INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
62 INST(2U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
63
64 BASIC_BLOCK(2U, -1L)
65 {
66 INST(5U, Opcode::LoadI).Inputs(0U).ref().Imm(frameAccOffset);
67 INST(6U, Opcode::StoreI).ref().Inputs(0U, 5U).Imm(frameAccOffset);
68
69 // store tag
70 INST(30U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
71 INST(31U, Opcode::StoreI).u64().Inputs(30U, 2U).Imm(accTagOffset);
72
73 INST(3U, Opcode::Call).TypeId(0U).ptr();
74 INST(4U, Opcode::ReturnVoid).v0id();
75 }
76 }
77
78 irtoc::IrtocRuntimeInterface runtime;
79 GetGraph()->SetRuntime(&runtime);
80
81 ASSERT_TRUE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
82 }
83
84 // Correct load accumulator from frame with two instructions:
85 // acc_ptr := AddI(LiveIn(frame).ptr).Imm(frame_acc_offset).ptr
86 // correct_acc_load := LoadI(acc_ptr).Imm(frame_acc_offset).ref
87 // Correct store into frame with instruction:
88 // correct_acc_store := StoreI(LiveIn(frame).ptr, correct_acc_load).Imm(frame_acc_offset).ref
TEST_F(DanglingPointersCheckerTest,test1)89 TEST_F(DanglingPointersCheckerTest, test1)
90 {
91 auto arch = panda::RUNTIME_ARCH;
92 SetGraphArch(arch);
93 if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
94 return;
95 }
96 auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
97 auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
98 RelocationHandlerTest relocationHandler;
99 relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
100 GetGraph()->SetRelocationHandler(&relocationHandler);
101 GetGraph()->SetMethod(&relocationHandler);
102 GetGraph()->SetMode(GraphMode::InterpreterEntry());
103
104 GRAPH(GetGraph())
105 {
106 INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
107 INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
108 INST(2U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
109 CONSTANT(10U, 10U).i64();
110 CONSTANT(11U, 15U).i64();
111
112 BASIC_BLOCK(2U, -1L)
113 {
114 INST(5U, Opcode::AddI).Inputs(0U).Imm(frameAccOffset).ptr();
115 INST(6U, Opcode::LoadI).Inputs(5U).ref().Imm(0U);
116 INST(8U, Opcode::StoreI).ref().Inputs(0U, 6U).Imm(frameAccOffset);
117 INST(7U, Opcode::Mul).Inputs(10U, 11U).i64();
118
119 // store tag
120 INST(30U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
121 INST(31U, Opcode::StoreI).u64().Inputs(30U, 2U).Imm(accTagOffset);
122
123 INST(3U, Opcode::Call).TypeId(0U).Inputs({{compiler::DataType::INT64, 7U}}).ptr();
124 INST(4U, Opcode::ReturnVoid).v0id();
125 }
126 }
127
128 irtoc::IrtocRuntimeInterface runtime;
129 GetGraph()->SetRuntime(&runtime);
130
131 ASSERT_TRUE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
132 }
133
134 // Incorrect load accumulator from fake frame with two instructions:
135 // fake_acc_ptr := AddI(fake_frame).Imm(frame_acc_offset).ptr
136 // incorrect_acc_load := LoadI(fake_acc_ptr).Imm(0).ref
137 // Correct store into frame with instruction:
138 // correct_acc_store := StoreI(LiveIn(frame).ptr, LiveIn(acc).ptr).Imm(frame_acc_offset)
TEST_F(DanglingPointersCheckerTest,test2)139 TEST_F(DanglingPointersCheckerTest, test2)
140 {
141 auto arch = panda::RUNTIME_ARCH;
142 SetGraphArch(arch);
143 if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
144 return;
145 }
146 auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
147 auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
148 RelocationHandlerTest relocationHandler;
149 relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
150 GetGraph()->SetRelocationHandler(&relocationHandler);
151 GetGraph()->SetMethod(&relocationHandler);
152 GetGraph()->SetMode(GraphMode::InterpreterEntry());
153
154 GRAPH(GetGraph())
155 {
156 INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
157 INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
158 INST(2U, Opcode::LiveIn).i64().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
159
160 BASIC_BLOCK(2U, -1L)
161 {
162 INST(5U, Opcode::AddI).Inputs(1U).Imm(frameAccOffset).ptr();
163 INST(6U, Opcode::LoadI).Inputs(5U).ref().Imm(0U);
164 INST(8U, Opcode::StoreI).u64().Inputs(0U, 1U).Imm(frameAccOffset);
165
166 // store tag
167 INST(30U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
168 INST(31U, Opcode::StoreI).u64().Inputs(30U, 2U).Imm(accTagOffset);
169
170 INST(3U, Opcode::Call).TypeId(0U).ptr();
171 INST(4U, Opcode::ReturnVoid).v0id();
172 }
173 }
174
175 irtoc::IrtocRuntimeInterface runtime;
176 GetGraph()->SetRuntime(&runtime);
177
178 ASSERT_TRUE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
179 }
180
181 // Incorrect load accumulator from fake frame with two instructions:
182 // fake_acc_ptr := AddI(fake_frame).Imm(frame_acc_offset).ptr
183 // incorrect_acc_load := LoadI(fake_acc_ptr).Imm(0).ref
184 // Incorrect store fake_acc_load into frame with instruction:
185 // incorrect_acc_store := StoreI(LiveIn(frame).ptr, fake_acc_load).Imm(frame_acc_offset)
TEST_F(DanglingPointersCheckerTest,test3)186 TEST_F(DanglingPointersCheckerTest, test3)
187 {
188 auto arch = panda::RUNTIME_ARCH;
189 SetGraphArch(arch);
190 if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
191 return;
192 }
193 auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
194 auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
195 RelocationHandlerTest relocationHandler;
196 relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
197 GetGraph()->SetRelocationHandler(&relocationHandler);
198 GetGraph()->SetMethod(&relocationHandler);
199 GetGraph()->SetMode(GraphMode::InterpreterEntry());
200
201 GRAPH(GetGraph())
202 {
203 INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
204 INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
205 INST(2U, Opcode::LiveIn).i64().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
206
207 BASIC_BLOCK(2U, -1L)
208 {
209 INST(5U, Opcode::AddI).Inputs(1U).Imm(frameAccOffset).ptr();
210 INST(6U, Opcode::LoadI).Inputs(5U).ref().Imm(0U);
211 INST(8U, Opcode::StoreI).ref().Inputs(0U, 6U).Imm(frameAccOffset);
212
213 // store tag
214 INST(30U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
215 INST(31U, Opcode::StoreI).u64().Inputs(30U, 2U).Imm(accTagOffset);
216
217 INST(3U, Opcode::Call).TypeId(0U).ptr();
218 INST(4U, Opcode::ReturnVoid).v0id();
219 }
220 }
221
222 irtoc::IrtocRuntimeInterface runtime;
223 GetGraph()->SetRuntime(&runtime);
224
225 ASSERT_FALSE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
226 }
227
228 // Incorrect load accumulator from fake frame with two instructions:
229 // fake_acc_ptr := AddI(fake_frame).Imm(frame_acc_offset).ptr
230 // incorrect_acc_load := LoadI(fake_acc_ptr).Imm(0).ref
231 // Incorrect store fake_acc_load into frame with instruction:
232 // incorrect_acc_store := StoreI(LiveIn(frame).ptr, fake_acc_load).Imm(frame_acc_offset)
233 // But acc type is integer: LiveIn(acc).u64; so the check is not performed
TEST_F(DanglingPointersCheckerTest,test4)234 TEST_F(DanglingPointersCheckerTest, test4)
235 {
236 auto arch = panda::RUNTIME_ARCH;
237 SetGraphArch(arch);
238 if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
239 return;
240 }
241 auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
242 auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
243 RelocationHandlerTest relocationHandler;
244 relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
245 GetGraph()->SetRelocationHandler(&relocationHandler);
246 GetGraph()->SetMethod(&relocationHandler);
247 GetGraph()->SetMode(GraphMode::InterpreterEntry());
248
249 GRAPH(GetGraph())
250 {
251 INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
252 INST(1U, Opcode::LiveIn).u64().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
253 INST(2U, Opcode::LiveIn).i64().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
254 INST(10U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["thread"]);
255
256 BASIC_BLOCK(2U, -1L)
257 {
258 INST(5U, Opcode::AddI).Inputs(10U).Imm(frameAccOffset).ptr();
259 INST(6U, Opcode::LoadI).Inputs(5U).ref().Imm(0U);
260 INST(8U, Opcode::StoreI).ref().Inputs(0U, 6U).Imm(frameAccOffset);
261
262 // store tag
263 INST(30U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
264 INST(31U, Opcode::StoreI).u64().Inputs(30U, 2U).Imm(accTagOffset);
265
266 INST(3U, Opcode::Call).TypeId(0U).ptr();
267 INST(4U, Opcode::ReturnVoid).v0id();
268 }
269 }
270
271 irtoc::IrtocRuntimeInterface runtime;
272 GetGraph()->SetRuntime(&runtime);
273
274 ASSERT_TRUE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
275 }
276
277 // Correct load accumulator from last frame definition with two instructions:
278 // last_frame_def := LoadI(LiveIn(frame).ptr).Imm(GetPrevFrameOffset()).ptr
279 // acc_ptr := AddI(last_frame_def).Imm(frame_acc_offset).ptr
280 // correct_acc_load := LoadI(acc_ptr).Imm(0).ref
281 // Correct store into frame with instruction:
282 // correct_acc_store := StoreI(last_frame_def, correct_acc_load).Imm(frame_acc_offset).ref
TEST_F(DanglingPointersCheckerTest,test5)283 TEST_F(DanglingPointersCheckerTest, test5)
284 {
285 auto arch = panda::RUNTIME_ARCH;
286 SetGraphArch(arch);
287 if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
288 return;
289 }
290 auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
291 auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
292 RelocationHandlerTest relocationHandler;
293 relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
294 GetGraph()->SetRelocationHandler(&relocationHandler);
295 GetGraph()->SetMethod(&relocationHandler);
296 GetGraph()->SetMode(GraphMode::InterpreterEntry());
297
298 GRAPH(GetGraph())
299 {
300 INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
301 INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
302 INST(2U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
303 CONSTANT(10U, 10U).i64();
304 CONSTANT(11U, 15U).i64();
305
306 BASIC_BLOCK(2U, -1L)
307 {
308 INST(8U, Opcode::LoadI).Inputs(0U).ptr().Imm(Frame::GetPrevFrameOffset());
309 INST(5U, Opcode::AddI).Inputs(8U).Imm(frameAccOffset).ptr();
310 INST(6U, Opcode::LoadI).Inputs(5U).ref().Imm(0U);
311 INST(7U, Opcode::Mul).Inputs(10U, 11U).i64();
312 INST(9U, Opcode::StoreI).ref().Inputs(8U, 6U).Imm(frameAccOffset);
313
314 // store tag
315 INST(31U, Opcode::StoreI).u64().Inputs(5U, 2U).Imm(accTagOffset);
316
317 INST(3U, Opcode::Call).TypeId(0U).Inputs({{compiler::DataType::INT64, 7U}}).ptr();
318 INST(4U, Opcode::ReturnVoid).v0id();
319 }
320 }
321
322 irtoc::IrtocRuntimeInterface runtime;
323 GetGraph()->SetRuntime(&runtime);
324
325 ASSERT_TRUE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
326 }
327
328 // Correct load accumulator from last frame definition with one instructions:
329 // last_frame_def := LoadI(LiveIn(frame).ptr).Imm(GetPrevFrameOffset()).ptr
330 // correct_acc_load := LoadI(last_frame_def).Imm(frame_acc_offset).ref
331 // Incorrect store into old frame with instruction:
332 // incorrect_acc_store := StoreI(LiveIn(frame).ptr, correct_acc_load).Imm(frame_acc_offset).ref
TEST_F(DanglingPointersCheckerTest,test6)333 TEST_F(DanglingPointersCheckerTest, test6)
334 {
335 auto arch = panda::RUNTIME_ARCH;
336 SetGraphArch(arch);
337 if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
338 return;
339 }
340 auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
341 auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
342 RelocationHandlerTest relocationHandler;
343 relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
344 GetGraph()->SetRelocationHandler(&relocationHandler);
345 GetGraph()->SetMethod(&relocationHandler);
346 GetGraph()->SetMode(GraphMode::InterpreterEntry());
347
348 GRAPH(GetGraph())
349 {
350 INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
351 INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
352 INST(2U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["thread"]);
353 INST(10U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
354
355 BASIC_BLOCK(2U, -1L)
356 {
357 INST(8U, Opcode::LoadI).Inputs(2U).ptr().Imm(ManagedThread::GetFrameOffset());
358 INST(5U, Opcode::LoadI).Inputs(8U).Imm(frameAccOffset).ref();
359 INST(9U, Opcode::StoreI).ref().Inputs(0U, 5U).Imm(frameAccOffset);
360
361 // store tag
362 INST(30U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
363 INST(31U, Opcode::StoreI).u64().Inputs(30U, 10U).Imm(accTagOffset);
364
365 INST(3U, Opcode::Call).TypeId(0U).ptr();
366 INST(4U, Opcode::ReturnVoid).v0id();
367 }
368 }
369
370 irtoc::IrtocRuntimeInterface runtime;
371 GetGraph()->SetRuntime(&runtime);
372
373 ASSERT_FALSE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
374 }
375
376 // Correct load accumulator from last frame definition with one instructions:
377 // last_frame_def := LoadI(LiveIn(frame).ptr).Imm(GetPrevFrameOffset()).ptr
378 // correct_acc_load := LoadI(last_frame_def).Imm(frame_acc_offset).ref
379 // Incorrect store into old frame with instruction:
380 // incorrect_acc_store := StoreI(LiveIn(frame).ptr, correct_acc_load).Imm(frame_acc_offset).ref
TEST_F(DanglingPointersCheckerTest,test7)381 TEST_F(DanglingPointersCheckerTest, test7)
382 {
383 auto arch = panda::RUNTIME_ARCH;
384 SetGraphArch(arch);
385 if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
386 return;
387 }
388 auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
389 auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
390 RelocationHandlerTest relocationHandler;
391 relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
392 GetGraph()->SetRelocationHandler(&relocationHandler);
393 GetGraph()->SetMethod(&relocationHandler);
394 GetGraph()->SetMode(GraphMode::InterpreterEntry());
395
396 GRAPH(GetGraph())
397 {
398 INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
399 INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
400 INST(2U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
401 CONSTANT(10U, 10U).i64();
402 CONSTANT(11U, 15U).i64();
403
404 BASIC_BLOCK(2U, -1L)
405 {
406 INST(8U, Opcode::LoadI).Inputs(0U).ptr().Imm(Frame::GetPrevFrameOffset());
407 INST(5U, Opcode::AddI).Inputs(8U).Imm(frameAccOffset).ptr();
408 INST(6U, Opcode::LoadI).Inputs(5U).ref().Imm(0U);
409 INST(7U, Opcode::Mul).Inputs(10U, 11U).i64();
410 INST(9U, Opcode::StoreI).ref().Inputs(0U, 6U).Imm(frameAccOffset);
411
412 // store tag
413 INST(30U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
414 INST(31U, Opcode::StoreI).u64().Inputs(30U, 2U).Imm(accTagOffset);
415
416 INST(3U, Opcode::Call).TypeId(0U).Inputs({{compiler::DataType::INT64, 7U}}).ptr();
417 INST(4U, Opcode::ReturnVoid).v0id();
418 }
419 }
420
421 irtoc::IrtocRuntimeInterface runtime;
422 GetGraph()->SetRuntime(&runtime);
423
424 ASSERT_FALSE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
425 }
426
427 // Use old accumulator after Call
TEST_F(DanglingPointersCheckerTest,test8)428 TEST_F(DanglingPointersCheckerTest, test8)
429 {
430 auto arch = panda::RUNTIME_ARCH;
431 SetGraphArch(arch);
432 if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
433 return;
434 }
435 auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
436 auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
437 RelocationHandlerTest relocationHandler;
438 relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
439 GetGraph()->SetRelocationHandler(&relocationHandler);
440 GetGraph()->SetMethod(&relocationHandler);
441 GetGraph()->SetMode(GraphMode::InterpreterEntry());
442
443 GRAPH(GetGraph())
444 {
445 INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
446 INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
447 INST(2U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
448
449 BASIC_BLOCK(2U, -1L)
450 {
451 INST(5U, Opcode::LoadI).Inputs(0U).ref().Imm(frameAccOffset);
452 INST(6U, Opcode::StoreI).ref().Inputs(0U, 5U).Imm(frameAccOffset);
453
454 // store tag
455 INST(30U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
456 INST(31U, Opcode::StoreI).u64().Inputs(30U, 2U).Imm(accTagOffset);
457
458 INST(3U, Opcode::Call).TypeId(0U).ptr();
459 INST(7U, Opcode::StoreI).ref().Inputs(0U, 5U).Imm(frameAccOffset);
460 INST(4U, Opcode::ReturnVoid).v0id();
461 }
462 }
463
464 irtoc::IrtocRuntimeInterface runtime;
465 GetGraph()->SetRuntime(&runtime);
466
467 ASSERT_FALSE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
468 }
469
470 // The correct graph. Not use old acc after call.
471 // start_bb
472 // |
473 // V
474 // ------------------------------------
475 // | bb_2 | new_acc_load, new_acc_store |
476 // ------------------------------------
477 // |
478 // V
479 // -------------------- --------------------
480 // | bb_3 | use_old_acc | | bb_4 | use_old_acc |
481 // -------------------- --------------------
482 // | |
483 // V V
484 // ------------- ------
485 // | bb_5 | Call | | bb_8 |
486 // -------------\ -------
487 // | | A |
488 // V V | V
489 // ------ -------- ------
490 // | bb_6 | | bb_7 |-->| bb_9 |--> end_bb
491 // ------ -------- ------
492
TEST_F(DanglingPointersCheckerTest,test9)493 TEST_F(DanglingPointersCheckerTest, test9)
494 {
495 auto arch = panda::RUNTIME_ARCH;
496 SetGraphArch(arch);
497 if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
498 return;
499 }
500 auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
501 auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
502 RelocationHandlerTest relocationHandler;
503 relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
504 GetGraph()->SetRelocationHandler(&relocationHandler);
505 GetGraph()->SetMethod(&relocationHandler);
506 GetGraph()->SetMode(GraphMode::InterpreterEntry());
507
508 GRAPH(GetGraph())
509 {
510 INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
511 INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
512 INST(2U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
513 CONSTANT(10U, 10U);
514 CONSTANT(11U, 11U);
515 CONSTANT(12U, 12U);
516
517 BASIC_BLOCK(2U, 3U, 4U)
518 {
519 INST(4U, Opcode::LoadI).Inputs(0U).ref().Imm(frameAccOffset);
520 INST(5U, Opcode::StoreI).ref().Inputs(0U, 4U).Imm(frameAccOffset);
521 INST(19U, Opcode::AddI).Inputs(11U).Imm(frameAccOffset).u64();
522 INST(20U, Opcode::Mul).Inputs(12U, 19U).u64();
523 INST(22U, Opcode::If).Inputs(19U, 20U).b().CC(CC_LE);
524 }
525 BASIC_BLOCK(3U, 5U)
526 {
527 INST(6U, Opcode::StoreI).ref().Inputs(0U, 4U).Imm(frameAccOffset);
528 }
529 BASIC_BLOCK(4U, 8U)
530 {
531 INST(7U, Opcode::StoreI).ref().Inputs(0U, 4U).Imm(frameAccOffset);
532 }
533 BASIC_BLOCK(5U, 6U, 7U)
534 {
535 // store tag
536 INST(30U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
537 INST(31U, Opcode::StoreI).u64().Inputs(30U, 2U).Imm(accTagOffset);
538
539 INST(3U, Opcode::Call).TypeId(0U).ptr();
540 INST(17U, Opcode::AddI).Inputs(11U).Imm(frameAccOffset).u64();
541 INST(18U, Opcode::Mul).Inputs(12U, 17U).u64();
542 INST(21U, Opcode::If).Inputs(17U, 18U).b().CC(CC_NE);
543 }
544 BASIC_BLOCK(6U, 9U)
545 {
546 INST(8U, Opcode::AddI).Inputs(10U).Imm(frameAccOffset).u64();
547 }
548 BASIC_BLOCK(7U, 8U, 9U)
549 {
550 INST(16U, Opcode::AddI).Inputs(11U).Imm(frameAccOffset).u64();
551 INST(9U, Opcode::Mul).Inputs(12U, 16U).u64();
552 INST(15U, Opcode::If).Inputs(9U, 16U).b().CC(CC_EQ);
553 }
554 BASIC_BLOCK(8U, 9U)
555 {
556 INST(13U, Opcode::AddI).Inputs(12U).Imm(frameAccOffset).u64();
557 }
558
559 BASIC_BLOCK(9U, -1L)
560 {
561 INST(14U, Opcode::ReturnVoid).v0id();
562 }
563 }
564
565 irtoc::IrtocRuntimeInterface runtime;
566 GetGraph()->SetRuntime(&runtime);
567
568 ASSERT_TRUE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
569 }
570
571 // The incorrect graph. Use old acc after call.
572 // start_bb
573 // |
574 // V
575 // ------------------------------------
576 // | bb_2 | new_acc_load, new_acc_store |
577 // ------------------------------------
578 // |
579 // V
580 // -------------------- --------------------
581 // | bb_3 | use_old_acc | | bb_4 | use_old_acc |
582 // -------------------- --------------------
583 // | |
584 // V V
585 // ------------- --------------------
586 // | bb_5 | Call | | bb_8 | use_old_acc |
587 // -------------\ ---------------------
588 // | | A |
589 // V V | V
590 // ------ -------- ------
591 // | bb_6 | | bb_7 |-->| bb_9 |--> end_bb
592 // ------ -------- ------
593
TEST_F(DanglingPointersCheckerTest,test10)594 TEST_F(DanglingPointersCheckerTest, test10)
595 {
596 auto arch = panda::RUNTIME_ARCH;
597 SetGraphArch(arch);
598 if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
599 return;
600 }
601 auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
602 auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
603 RelocationHandlerTest relocationHandler;
604 relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
605 GetGraph()->SetRelocationHandler(&relocationHandler);
606 GetGraph()->SetMethod(&relocationHandler);
607 GetGraph()->SetMode(GraphMode::InterpreterEntry());
608
609 GRAPH(GetGraph())
610 {
611 INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
612 INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
613 INST(2U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
614 CONSTANT(10U, 10U);
615 CONSTANT(11U, 11U);
616 CONSTANT(12U, 12U);
617
618 BASIC_BLOCK(2U, 3U, 4U)
619 {
620 INST(4U, Opcode::LoadI).Inputs(0U).ref().Imm(frameAccOffset);
621 INST(5U, Opcode::StoreI).ref().Inputs(0U, 4U).Imm(frameAccOffset);
622 INST(19U, Opcode::AddI).Inputs(11U).Imm(frameAccOffset).u64();
623 INST(20U, Opcode::Mul).Inputs(12U, 19U).u64();
624 INST(22U, Opcode::If).Inputs(19U, 20U).b().CC(CC_LE);
625 }
626 BASIC_BLOCK(3U, 5U)
627 {
628 INST(6U, Opcode::StoreI).ref().Inputs(0U, 4U).Imm(frameAccOffset);
629 }
630 BASIC_BLOCK(4U, 8U)
631 {
632 INST(7U, Opcode::StoreI).ref().Inputs(0U, 4U).Imm(frameAccOffset);
633 }
634 BASIC_BLOCK(5U, 6U, 7U)
635 {
636 // store tag
637 INST(30U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
638 INST(31U, Opcode::StoreI).u64().Inputs(30U, 2U).Imm(accTagOffset);
639
640 INST(3U, Opcode::Call).TypeId(0U).ptr();
641 INST(17U, Opcode::AddI).Inputs(11U).Imm(frameAccOffset).u64();
642 INST(18U, Opcode::Mul).Inputs(12U, 17U).u64();
643 INST(21U, Opcode::If).Inputs(17U, 18U).b().CC(CC_NE);
644 }
645 BASIC_BLOCK(6U, 9U)
646 {
647 INST(8U, Opcode::AddI).Inputs(10U).Imm(frameAccOffset).u64();
648 }
649 BASIC_BLOCK(7U, 8U, 9U)
650 {
651 INST(16U, Opcode::AddI).Inputs(11U).Imm(frameAccOffset).u64();
652 INST(9U, Opcode::Mul).Inputs(12U, 16U).u64();
653 INST(15U, Opcode::If).Inputs(9U, 16U).b().CC(CC_EQ);
654 }
655 BASIC_BLOCK(8U, 9U)
656 {
657 INST(23U, Opcode::StoreI).ref().Inputs(0U, 4U).Imm(frameAccOffset);
658 INST(13U, Opcode::AddI).Inputs(12U).Imm(frameAccOffset).u64();
659 }
660
661 BASIC_BLOCK(9U, -1L)
662 {
663 INST(14U, Opcode::ReturnVoid).v0id();
664 }
665 }
666
667 irtoc::IrtocRuntimeInterface runtime;
668 GetGraph()->SetRuntime(&runtime);
669
670 ASSERT_FALSE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
671 }
672
673 // The correct graph. Use Phi to define acc that has been changed in one branch.
674 // start_bb
675 // |
676 // V
677 // -----------------------------
678 // | bb_2 |
679 // -----------------------------
680 // | |
681 // V |
682 // ----------------------------- |
683 // | bb_3 | load_acc, change_acc | |
684 // ----------------------------- |
685 // | |
686 // V V
687 // ------------------------------------------------
688 // | | last_acc_def = Phi(live_in, change_acc) |
689 // | bb_4 | store(last_acc_def) |
690 // | | Call |
691 // ------------------------------------------------
692 // |
693 // V
694 // end_bb
695
TEST_F(DanglingPointersCheckerTest,test11)696 TEST_F(DanglingPointersCheckerTest, test11)
697 {
698 auto arch = panda::RUNTIME_ARCH;
699 SetGraphArch(arch);
700 if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
701 return;
702 }
703 auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
704 auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
705 RelocationHandlerTest relocationHandler;
706 relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
707 GetGraph()->SetRelocationHandler(&relocationHandler);
708 GetGraph()->SetMethod(&relocationHandler);
709 GetGraph()->SetMode(GraphMode::InterpreterEntry());
710
711 GRAPH(GetGraph())
712 {
713 INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
714 INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
715 INST(2U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
716 CONSTANT(10U, 10U);
717 CONSTANT(11U, 11U);
718
719 BASIC_BLOCK(2U, 3U, 4U)
720 {
721 INST(3U, Opcode::AddI).Inputs(10U).Imm(frameAccOffset).u64();
722 INST(4U, Opcode::If).Inputs(3U, 11U).b().CC(CC_NE);
723 }
724 BASIC_BLOCK(3U, 4U)
725 {
726 INST(5U, Opcode::LoadI).Inputs(0U).ref().Imm(frameAccOffset);
727 INST(6U, Opcode::AddI).Inputs(5U).ptr().Imm(10U);
728 }
729 BASIC_BLOCK(4U, -1L)
730 {
731 INST(7U, Opcode::Phi).Inputs(1U, 6U).ptr();
732 INST(8U, Opcode::StoreI).ref().Inputs(0U, 7U).Imm(frameAccOffset);
733
734 // store tag
735 INST(21U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
736 INST(22U, Opcode::StoreI).u64().Inputs(21U, 2U).Imm(accTagOffset);
737
738 INST(9U, Opcode::Call).TypeId(0U).ptr();
739 INST(20U, Opcode::ReturnVoid).v0id();
740 }
741 }
742
743 irtoc::IrtocRuntimeInterface runtime;
744 GetGraph()->SetRuntime(&runtime);
745
746 ASSERT_TRUE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
747 }
748
749 // Use object after call:
750 // frame_live_in := LiveIn(frame)
751 // Call
752 // frame_use := LoadI(frame_live_in).Imm(frame_acc_offset).i64
TEST_F(DanglingPointersCheckerTest,test12)753 TEST_F(DanglingPointersCheckerTest, test12)
754 {
755 auto arch = panda::RUNTIME_ARCH;
756 SetGraphArch(arch);
757 if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
758 return;
759 }
760 auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
761 auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
762 RelocationHandlerTest relocationHandler;
763 relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
764 GetGraph()->SetRelocationHandler(&relocationHandler);
765 GetGraph()->SetMethod(&relocationHandler);
766 GetGraph()->SetMode(GraphMode::InterpreterEntry());
767
768 GRAPH(GetGraph())
769 {
770 INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
771 INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
772 INST(2U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
773
774 BASIC_BLOCK(2U, -1L)
775 {
776 INST(7U, Opcode::StoreI).ref().Inputs(0U, 1U).Imm(frameAccOffset);
777
778 // store tag
779 INST(8U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
780 INST(9U, Opcode::StoreI).u64().Inputs(8U, 2U).Imm(accTagOffset);
781
782 INST(3U, Opcode::Call).TypeId(0U).ptr();
783 INST(5U, Opcode::AddI).Inputs(1U).ptr().Imm(frameAccOffset);
784 INST(4U, Opcode::ReturnVoid).v0id();
785 }
786 }
787
788 irtoc::IrtocRuntimeInterface runtime;
789 GetGraph()->SetRuntime(&runtime);
790
791 ASSERT_FALSE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
792 }
793
794 // Use primitive after call:
795 // frame_live_in := LiveIn(frame)
796 // primitive := LoadI(frame_live_in).Imm(offset).u64
797 // Call
798 // primitive_use := AddI(not_object).Imm(10).u64
TEST_F(DanglingPointersCheckerTest,test13)799 TEST_F(DanglingPointersCheckerTest, test13)
800 {
801 auto arch = panda::RUNTIME_ARCH;
802 SetGraphArch(arch);
803 if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
804 return;
805 }
806 auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
807 auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
808 RelocationHandlerTest relocationHandler;
809 relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
810 GetGraph()->SetRelocationHandler(&relocationHandler);
811 GetGraph()->SetMethod(&relocationHandler);
812 GetGraph()->SetMode(GraphMode::InterpreterEntry());
813
814 GRAPH(GetGraph())
815 {
816 INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
817 INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
818 INST(2U, Opcode::LiveIn).u64().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
819
820 BASIC_BLOCK(2U, -1L)
821 {
822 INST(6U, Opcode::LoadI).Inputs(0U).u64().Imm(10U);
823 INST(7U, Opcode::StoreI).ref().Inputs(0U, 1U).Imm(frameAccOffset);
824
825 // store tag
826 INST(8U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
827 INST(9U, Opcode::StoreI).u64().Inputs(8U, 2U).Imm(accTagOffset);
828
829 INST(3U, Opcode::Call).TypeId(0U).ptr();
830 INST(5U, Opcode::AddI).Inputs(6U).u64().Imm(frameAccOffset);
831 INST(4U, Opcode::ReturnVoid).v0id();
832 }
833 }
834
835 irtoc::IrtocRuntimeInterface runtime;
836 GetGraph()->SetRuntime(&runtime);
837
838 ASSERT_TRUE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
839 }
840
841 // Use skipped pointer inst after call:
842 // frame_live_in := LiveIn(frame)
843 // pointer := AddI(frame_live_in).Imm(frame_acc_offset).ptr
844 // Call
845 // primitive := LoadI(pointer).Imm(0).u64
TEST_F(DanglingPointersCheckerTest,test14)846 TEST_F(DanglingPointersCheckerTest, test14)
847 {
848 auto arch = panda::RUNTIME_ARCH;
849 SetGraphArch(arch);
850 if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
851 return;
852 }
853 auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
854 auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
855 RelocationHandlerTest relocationHandler;
856 relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
857 GetGraph()->SetRelocationHandler(&relocationHandler);
858 GetGraph()->SetMethod(&relocationHandler);
859 GetGraph()->SetMode(GraphMode::InterpreterEntry());
860
861 GRAPH(GetGraph())
862 {
863 INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
864 INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
865 INST(2U, Opcode::LiveIn).u64().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
866
867 BASIC_BLOCK(2U, -1L)
868 {
869 INST(6U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
870 INST(7U, Opcode::StoreI).ref().Inputs(0U, 1U).Imm(frameAccOffset);
871
872 // store tag
873 INST(8U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
874 INST(9U, Opcode::StoreI).u64().Inputs(8U, 2U).Imm(accTagOffset);
875
876 INST(3U, Opcode::Call).TypeId(0U).ptr();
877 INST(5U, Opcode::LoadI).Inputs(6U).u64().Imm(0U);
878 INST(4U, Opcode::ReturnVoid).v0id();
879 }
880 }
881
882 irtoc::IrtocRuntimeInterface runtime;
883 GetGraph()->SetRuntime(&runtime);
884
885 ASSERT_TRUE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
886 }
887
888 // Use ref inst after call:
889 // pointer := AddI(acc_live_in).Imm(10).ptr
890 // Call
891 // primitive := LoadI(pointer).Imm(0).u64
TEST_F(DanglingPointersCheckerTest,test15)892 TEST_F(DanglingPointersCheckerTest, test15)
893 {
894 auto arch = panda::RUNTIME_ARCH;
895 SetGraphArch(arch);
896 if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
897 return;
898 }
899 auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
900 auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
901 RelocationHandlerTest relocationHandler;
902 relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
903 GetGraph()->SetRelocationHandler(&relocationHandler);
904 GetGraph()->SetMethod(&relocationHandler);
905 GetGraph()->SetMode(GraphMode::InterpreterEntry());
906
907 GRAPH(GetGraph())
908 {
909 INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
910 INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
911 INST(2U, Opcode::LiveIn).u64().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
912
913 BASIC_BLOCK(2U, -1L)
914 {
915 INST(10U, Opcode::LoadI).Inputs(0U).ref().Imm(10U);
916 INST(6U, Opcode::AddI).Inputs(1U).ptr().Imm(10U);
917 INST(7U, Opcode::StoreI).ref().Inputs(0U, 1U).Imm(frameAccOffset);
918
919 // store tag
920 INST(8U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
921 INST(9U, Opcode::StoreI).u64().Inputs(8U, 2U).Imm(accTagOffset);
922
923 INST(3U, Opcode::Call).TypeId(0U).ptr();
924 INST(5U, Opcode::LoadI).Inputs(10U).u64().Imm(0U);
925 INST(4U, Opcode::ReturnVoid).v0id();
926 }
927 }
928
929 irtoc::IrtocRuntimeInterface runtime;
930 GetGraph()->SetRuntime(&runtime);
931
932 ASSERT_FALSE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
933 }
934
935 // Correct load accumulator from frame:
936 // correct_acc_load := LoadI(LiveIn(frame).ptr).Imm(frame_acc_offset).ref
937 // Correct accumulatore and tag store:
938 // correct_acc_store := StoreI(LiveIn(frame).ptr, correct_acc_load).Imm(frame_acc_offset).ref
939 // acc_ptr := AddI(LiveIn(frame).ptr).Imm(frame_acc_offset).ref
940 // correct_acc_tag_store := StoreI(acc_ptr, LiveIn(acc_tag).u64).Imm(acc_tag_offset).u64
TEST_F(DanglingPointersCheckerTest,test16)941 TEST_F(DanglingPointersCheckerTest, test16)
942 {
943 auto arch = panda::RUNTIME_ARCH;
944 SetGraphArch(arch);
945 if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
946 return;
947 }
948 auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
949 auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
950 RelocationHandlerTest relocationHandler;
951 relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
952 GetGraph()->SetRelocationHandler(&relocationHandler);
953 GetGraph()->SetMethod(&relocationHandler);
954 GetGraph()->SetMode(GraphMode::InterpreterEntry());
955
956 GRAPH(GetGraph())
957 {
958 INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
959 INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
960 INST(2U, Opcode::LiveIn).u64().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
961 INST(3U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["thread"]);
962
963 BASIC_BLOCK(2U, -1L)
964 {
965 INST(4U, Opcode::LoadI).Inputs(0U).ref().Imm(frameAccOffset);
966 INST(5U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
967 INST(6U, Opcode::StoreI).ref().Inputs(0U, 4U).Imm(frameAccOffset);
968 INST(7U, Opcode::StoreI).u64().Inputs(5U, 2U).Imm(accTagOffset);
969 INST(8U, Opcode::Call).TypeId(0U).ptr();
970 INST(9U, Opcode::ReturnVoid).v0id();
971 }
972 }
973
974 irtoc::IrtocRuntimeInterface runtime;
975 GetGraph()->SetRuntime(&runtime);
976
977 ASSERT_TRUE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
978 }
979
980 // Correct load accumulator and tag:
981 // acc_ptr := AddI(LiveIn(frame).ptr).Imm(frame_acc_offset).ptr
982 // correct_acc_load := LoadI(acc_ptr).Imm(frame_acc_offset).ref
983 // correct_acc_tag_load := LoadI(acc_ptr).Imm(acc_tag_offset).u64
984 // Correct accumulatore and tag store:
985 // correct_acc_store := StoreI(LiveIn(frame).ptr, correct_acc_load).Imm(frame_acc_offset).ref
986 // acc_ptr := AddI(LiveIn(frame).ptr).Imm(frame_acc_offset).ref
987 // correct_acc_tag_store := StoreI(acc_ptr, correct_acc_tag_load).Imm(acc_tag_offset).u64
TEST_F(DanglingPointersCheckerTest,test17)988 TEST_F(DanglingPointersCheckerTest, test17)
989 {
990 auto arch = panda::RUNTIME_ARCH;
991 SetGraphArch(arch);
992 if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
993 return;
994 }
995 auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
996 auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
997 RelocationHandlerTest relocationHandler;
998 relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
999 GetGraph()->SetRelocationHandler(&relocationHandler);
1000 GetGraph()->SetMethod(&relocationHandler);
1001 GetGraph()->SetMode(GraphMode::InterpreterEntry());
1002
1003 GRAPH(GetGraph())
1004 {
1005 INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
1006 INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
1007 INST(2U, Opcode::LiveIn).u64().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
1008 INST(3U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["thread"]);
1009
1010 BASIC_BLOCK(2U, -1L)
1011 {
1012 INST(4U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
1013 INST(5U, Opcode::LoadI).Inputs(4U).ref().Imm(0U);
1014 INST(6U, Opcode::LoadI).Inputs(4U).i64().Imm(accTagOffset);
1015 INST(7U, Opcode::StoreI).ref().Inputs(0U, 5U).Imm(frameAccOffset);
1016 INST(8U, Opcode::StoreI).u64().Inputs(4U, 6U).Imm(accTagOffset);
1017 INST(9U, Opcode::Call).TypeId(0U).ptr();
1018 INST(10U, Opcode::ReturnVoid).v0id();
1019 }
1020 }
1021
1022 irtoc::IrtocRuntimeInterface runtime;
1023 GetGraph()->SetRuntime(&runtime);
1024
1025 ASSERT_TRUE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
1026 }
1027
1028 // Correct load accumulator and tag:
1029 // acc_ptr := AddI(LiveIn(frame).ptr).Imm(frame_acc_offset).ptr
1030 // correct_acc_load := LoadI(acc_ptr).Imm(frame_acc_offset).ref
1031 // acc_tag_ptr := AddI(acc_ptr).Imm(acc_tag_offset).ref
1032 // correct_acc_tag_load := LoadI(acc_tag_ptr).Imm(0).u64
1033 // Correct accumulatore and tag store:
1034 // correct_acc_store := StoreI(LiveIn(frame).ptr, correct_acc_load).Imm(frame_acc_offset).ref
1035 // acc_ptr := AddI(LiveIn(frame).ptr).Imm(frame_acc_offset).ref
1036 // correct_acc_tag_store := StoreI(acc_ptr, correct_acc_tag_load).Imm(acc_tag_offset).u64
TEST_F(DanglingPointersCheckerTest,test18)1037 TEST_F(DanglingPointersCheckerTest, test18)
1038 {
1039 auto arch = panda::RUNTIME_ARCH;
1040 SetGraphArch(arch);
1041 if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
1042 return;
1043 }
1044 auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
1045 auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
1046 RelocationHandlerTest relocationHandler;
1047 relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
1048 GetGraph()->SetRelocationHandler(&relocationHandler);
1049 GetGraph()->SetMethod(&relocationHandler);
1050 GetGraph()->SetMode(GraphMode::InterpreterEntry());
1051
1052 GRAPH(GetGraph())
1053 {
1054 INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
1055 INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
1056 INST(2U, Opcode::LiveIn).u64().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
1057 INST(3U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["thread"]);
1058
1059 BASIC_BLOCK(2U, -1L)
1060 {
1061 INST(4U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
1062 INST(5U, Opcode::LoadI).Inputs(4U).ref().Imm(0U);
1063 INST(6U, Opcode::AddI).Inputs(4U).ptr().Imm(accTagOffset);
1064 INST(7U, Opcode::LoadI).Inputs(6U).i64().Imm(0U);
1065 INST(8U, Opcode::StoreI).ref().Inputs(0U, 5U).Imm(frameAccOffset);
1066 INST(9U, Opcode::StoreI).u64().Inputs(4U, 7U).Imm(accTagOffset);
1067 INST(10U, Opcode::Call).TypeId(0U).ptr();
1068 INST(11U, Opcode::ReturnVoid).v0id();
1069 }
1070 }
1071
1072 irtoc::IrtocRuntimeInterface runtime;
1073 GetGraph()->SetRuntime(&runtime);
1074
1075 ASSERT_TRUE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
1076 }
1077
1078 // Correct load accumulator and tag:
1079 // acc_ptr := AddI(LiveIn(frame).ptr).Imm(frame_acc_offset).ptr
1080 // correct_acc_load := LoadI(acc_ptr).Imm(frame_acc_offset).ref
1081 // acc_tag_ptr := AddI(acc_ptr).Imm(acc_tag_offset).ref
1082 // correct_acc_tag_load := LoadI(acc_tag_ptr).Imm(0).u64
1083 // Correct accumulatore and tag store:
1084 // correct_acc_store := StoreI(LiveIn(frame).ptr, correct_acc_load).Imm(frame_acc_offset).ref
1085 // acc_ptr := AddI(LiveIn(frame).ptr).Imm(frame_acc_offset).ref
1086 // incorrect_acc_tag_store := StoreI(acc_ptr, LiveIn(acc_tag).u64).Imm(acc_tag_offset).u64
TEST_F(DanglingPointersCheckerTest,test19)1087 TEST_F(DanglingPointersCheckerTest, test19)
1088 {
1089 auto arch = panda::RUNTIME_ARCH;
1090 SetGraphArch(arch);
1091 if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
1092 return;
1093 }
1094 auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
1095 auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
1096 RelocationHandlerTest relocationHandler;
1097 relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
1098 GetGraph()->SetRelocationHandler(&relocationHandler);
1099 GetGraph()->SetMethod(&relocationHandler);
1100 GetGraph()->SetMode(GraphMode::InterpreterEntry());
1101
1102 GRAPH(GetGraph())
1103 {
1104 INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
1105 INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
1106 INST(2U, Opcode::LiveIn).u64().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
1107 INST(3U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["thread"]);
1108
1109 BASIC_BLOCK(2U, -1L)
1110 {
1111 INST(4U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
1112 INST(5U, Opcode::LoadI).Inputs(4U).ref().Imm(0U);
1113 INST(6U, Opcode::AddI).Inputs(4U).ptr().Imm(accTagOffset);
1114 INST(7U, Opcode::LoadI).Inputs(6U).i64().Imm(0U);
1115 INST(8U, Opcode::StoreI).ref().Inputs(0U, 5U).Imm(frameAccOffset);
1116 INST(9U, Opcode::StoreI).u64().Inputs(4U, 2U).Imm(accTagOffset);
1117 INST(10U, Opcode::Call).TypeId(0U).ptr();
1118 INST(11U, Opcode::ReturnVoid).v0id();
1119 }
1120 }
1121
1122 irtoc::IrtocRuntimeInterface runtime;
1123 GetGraph()->SetRuntime(&runtime);
1124
1125 ASSERT_FALSE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
1126 }
1127
1128 // NOLINTEND(readability-magic-numbers)
1129 } // namespace panda::compiler
1130