1b8021494Sopenharmony_ci// Copyright 2022, VIXL authors
2b8021494Sopenharmony_ci// All rights reserved.
3b8021494Sopenharmony_ci//
4b8021494Sopenharmony_ci// Redistribution and use in source and binary forms, with or without
5b8021494Sopenharmony_ci// modification, are permitted provided that the following conditions are met:
6b8021494Sopenharmony_ci//
7b8021494Sopenharmony_ci//   * Redistributions of source code must retain the above copyright notice,
8b8021494Sopenharmony_ci//     this list of conditions and the following disclaimer.
9b8021494Sopenharmony_ci//   * Redistributions in binary form must reproduce the above copyright notice,
10b8021494Sopenharmony_ci//     this list of conditions and the following disclaimer in the documentation
11b8021494Sopenharmony_ci//     and/or other materials provided with the distribution.
12b8021494Sopenharmony_ci//   * Neither the name of ARM Limited nor the names of its contributors may be
13b8021494Sopenharmony_ci//     used to endorse or promote products derived from this software without
14b8021494Sopenharmony_ci//     specific prior written permission.
15b8021494Sopenharmony_ci//
16b8021494Sopenharmony_ci// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17b8021494Sopenharmony_ci// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18b8021494Sopenharmony_ci// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19b8021494Sopenharmony_ci// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20b8021494Sopenharmony_ci// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21b8021494Sopenharmony_ci// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22b8021494Sopenharmony_ci// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23b8021494Sopenharmony_ci// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24b8021494Sopenharmony_ci// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25b8021494Sopenharmony_ci// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26b8021494Sopenharmony_ci
27b8021494Sopenharmony_ci#include <sys/mman.h>
28b8021494Sopenharmony_ci#include <unistd.h>
29b8021494Sopenharmony_ci
30b8021494Sopenharmony_ci#include "test-runner.h"
31b8021494Sopenharmony_ci#include "test-utils.h"
32b8021494Sopenharmony_ci
33b8021494Sopenharmony_ci#include "aarch64/cpu-aarch64.h"
34b8021494Sopenharmony_ci#include "aarch64/disasm-aarch64.h"
35b8021494Sopenharmony_ci#include "aarch64/macro-assembler-aarch64.h"
36b8021494Sopenharmony_ci#include "aarch64/simulator-aarch64.h"
37b8021494Sopenharmony_ci#include "aarch64/test-utils-aarch64.h"
38b8021494Sopenharmony_ci#include "test-assembler-aarch64.h"
39b8021494Sopenharmony_ci
40b8021494Sopenharmony_cinamespace vixl {
41b8021494Sopenharmony_cinamespace aarch64 {
42b8021494Sopenharmony_ci
43b8021494Sopenharmony_ci#ifdef VIXL_INCLUDE_SIMULATOR_AARCH64
44b8021494Sopenharmony_ciTEST(test_metadata_mte) {
45b8021494Sopenharmony_ci  SETUP_WITH_FEATURES(CPUFeatures::kMTE);
46b8021494Sopenharmony_ci
47b8021494Sopenharmony_ci  size_t data_size = 320;
48b8021494Sopenharmony_ci  void* tagged_address = simulator.Mmap(NULL,
49b8021494Sopenharmony_ci                                        data_size,
50b8021494Sopenharmony_ci                                        PROT_READ | PROT_WRITE | PROT_MTE,
51b8021494Sopenharmony_ci                                        MAP_PRIVATE | MAP_ANONYMOUS,
52b8021494Sopenharmony_ci                                        -1,
53b8021494Sopenharmony_ci                                        0);
54b8021494Sopenharmony_ci
55b8021494Sopenharmony_ci  START();
56b8021494Sopenharmony_ci
57b8021494Sopenharmony_ci  Register tagged_heap_ptr = x20;
58b8021494Sopenharmony_ci  __ Mov(tagged_heap_ptr, reinterpret_cast<uintptr_t>(tagged_address));
59b8021494Sopenharmony_ci  for (int i = 0; i < 10; i++) {
60b8021494Sopenharmony_ci    __ Ldr(w0, MemOperand(tagged_heap_ptr, i * 32));
61b8021494Sopenharmony_ci    __ Str(w0, MemOperand(tagged_heap_ptr, i * 32));
62b8021494Sopenharmony_ci  }
63b8021494Sopenharmony_ci  __ Ldr(x2, MemOperand(tagged_heap_ptr, 8));
64b8021494Sopenharmony_ci  __ Ldrb(w3, MemOperand(tagged_heap_ptr, 1));
65b8021494Sopenharmony_ci  __ Ldrh(w4, MemOperand(tagged_heap_ptr, 67));
66b8021494Sopenharmony_ci
67b8021494Sopenharmony_ci  __ Addg(x21, tagged_heap_ptr, 16, 2);
68b8021494Sopenharmony_ci
69b8021494Sopenharmony_ci  END();
70b8021494Sopenharmony_ci
71b8021494Sopenharmony_ci  if (CAN_RUN()) {
72b8021494Sopenharmony_ci    RUN();
73b8021494Sopenharmony_ci  }
74b8021494Sopenharmony_ci
75b8021494Sopenharmony_ci  simulator.Munmap(tagged_address, data_size, PROT_MTE);
76b8021494Sopenharmony_ci}
77b8021494Sopenharmony_ci
78b8021494Sopenharmony_ci#ifdef VIXL_NEGATIVE_TESTING
79b8021494Sopenharmony_ciTEST(test_metadata_mte_neg) {
80b8021494Sopenharmony_ci  CPUFeatures features(CPUFeatures::kMTE);
81b8021494Sopenharmony_ci  SETUP_WITH_FEATURES(features);
82b8021494Sopenharmony_ci  size_t data_size = 320;
83b8021494Sopenharmony_ci  void* tagged_address = simulator.Mmap(NULL,
84b8021494Sopenharmony_ci                                        data_size,
85b8021494Sopenharmony_ci                                        PROT_READ | PROT_WRITE | PROT_MTE,
86b8021494Sopenharmony_ci                                        MAP_PRIVATE | MAP_ANONYMOUS,
87b8021494Sopenharmony_ci                                        -1,
88b8021494Sopenharmony_ci                                        0);
89b8021494Sopenharmony_ci
90b8021494Sopenharmony_ci  START();
91b8021494Sopenharmony_ci
92b8021494Sopenharmony_ci  Register tagged_heap_ptr = x20;
93b8021494Sopenharmony_ci  __ Mov(tagged_heap_ptr, reinterpret_cast<uintptr_t>(tagged_address));
94b8021494Sopenharmony_ci  __ Addg(x21, tagged_heap_ptr, 16, 2);
95b8021494Sopenharmony_ci
96b8021494Sopenharmony_ci  // The memory tag has been changed and becomes invalid.
97b8021494Sopenharmony_ci  __ Ldr(w0, MemOperand(x21));
98b8021494Sopenharmony_ci  __ Str(w0, MemOperand(x21));
99b8021494Sopenharmony_ci
100b8021494Sopenharmony_ci  // Out-of-bound access error.
101b8021494Sopenharmony_ci  __ Ldr(w0, MemOperand(tagged_heap_ptr, 320));
102b8021494Sopenharmony_ci  __ Str(w0, MemOperand(tagged_heap_ptr, 336));
103b8021494Sopenharmony_ci  __ Ldr(w0, MemOperand(tagged_heap_ptr, -8));
104b8021494Sopenharmony_ci  __ Str(w0, MemOperand(tagged_heap_ptr, -16));
105b8021494Sopenharmony_ci
106b8021494Sopenharmony_ci  void* tagged_address_2 = simulator.Mmap(NULL,
107b8021494Sopenharmony_ci                                          data_size,
108b8021494Sopenharmony_ci                                          PROT_READ | PROT_WRITE | PROT_MTE,
109b8021494Sopenharmony_ci                                          MAP_PRIVATE | MAP_ANONYMOUS,
110b8021494Sopenharmony_ci                                          -1,
111b8021494Sopenharmony_ci                                          0);
112b8021494Sopenharmony_ci
113b8021494Sopenharmony_ci  __ Mov(x22, reinterpret_cast<uintptr_t>(tagged_address_2));
114b8021494Sopenharmony_ci  simulator.Munmap(tagged_address_2, data_size, PROT_MTE);
115b8021494Sopenharmony_ci
116b8021494Sopenharmony_ci  // Use-after-free error.
117b8021494Sopenharmony_ci  __ Ldr(w0, MemOperand(x22));
118b8021494Sopenharmony_ci
119b8021494Sopenharmony_ci  END();
120b8021494Sopenharmony_ci
121b8021494Sopenharmony_ci  if (CAN_RUN()) {
122b8021494Sopenharmony_ci    MUST_FAIL_WITH_MESSAGE(RUN(), "Tag mismatch.");
123b8021494Sopenharmony_ci  }
124b8021494Sopenharmony_ci
125b8021494Sopenharmony_ci  simulator.Munmap(tagged_address, data_size, PROT_MTE);
126b8021494Sopenharmony_ci}
127b8021494Sopenharmony_ci#endif  // VIXL_NEGATIVE_TESTING
128b8021494Sopenharmony_ci#endif  // VIXL_INCLUDE_SIMULATOR_AARCH64
129b8021494Sopenharmony_ci}  // namespace aarch64
130b8021494Sopenharmony_ci}  // namespace vixl
131