File: memtag-globals-asm.cpp

package info (click to toggle)
llvm-toolchain-17 1%3A17.0.6-22
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,799,624 kB
  • sloc: cpp: 6,428,607; ansic: 1,383,196; asm: 793,408; python: 223,504; objc: 75,364; f90: 60,502; lisp: 33,869; pascal: 15,282; sh: 9,684; perl: 7,453; ml: 4,937; awk: 3,523; makefile: 2,889; javascript: 2,149; xml: 888; fortran: 619; cs: 573
file content (261 lines) | stat: -rw-r--r-- 11,263 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
// REQUIRES: aarch64-registered-target

// RUN: %clang_cc1 -S -x c++ -std=c++11 -triple aarch64-linux-android31 \
// RUN:   -fsanitize=memtag-globals -o %t.out %s
// RUN: FileCheck %s --input-file=%t.out
// RUN: FileCheck %s --input-file=%t.out --check-prefix=CHECK-A
// RUN: FileCheck %s --input-file=%t.out --check-prefix=CHECK-B
// RUN: FileCheck %s --input-file=%t.out --check-prefix=CHECK-C
// RUN: FileCheck %s --input-file=%t.out --check-prefix=CHECK-D
// RUN: FileCheck %s --input-file=%t.out --check-prefix=CHECK-E
// RUN: FileCheck %s --input-file=%t.out --check-prefix=CHECK-F
// RUN: FileCheck %s --input-file=%t.out --check-prefix=CHECK-G
// RUN: FileCheck %s --input-file=%t.out --check-prefix=CHECK-H
// RUN: FileCheck %s --input-file=%t.out --check-prefix=CHECK-I
// RUN: FileCheck %s --input-file=%t.out --check-prefix=CHECK-J
// RUN: FileCheck %s --input-file=%t.out --check-prefix=CHECK-K
// RUN: FileCheck %s --input-file=%t.out --check-prefix=CHECK-L
// RUN: FileCheck %s --input-file=%t.out --check-prefix=CHECK-M
// RUN: FileCheck %s --input-file=%t.out --check-prefix=CHECK-N
// RUN: FileCheck %s --input-file=%t.out --check-prefix=CHECK-O
// RUN: FileCheck %s --input-file=%t.out --check-prefix=CHECK-P
// RUN: FileCheck %s --input-file=%t.out --check-prefix=CHECK-Q
// RUN: FileCheck %s --input-file=%t.out --check-prefix=CHECK-R

// RUN: %clang_cc1 -O3 -S -x c++ -std=c++11 -triple aarch64-linux-android31 \
// RUN:   -fsanitize=memtag-globals -o %t.out %s
// RUN: FileCheck %s --input-file=%t.out
// RUN: FileCheck %s --input-file=%t.out --check-prefix=CHECK-A
// RUN: FileCheck %s --input-file=%t.out --check-prefix=CHECK-B
// RUN: FileCheck %s --input-file=%t.out --check-prefix=CHECK-C
// RUN: FileCheck %s --input-file=%t.out --check-prefix=CHECK-D
// RUN: FileCheck %s --input-file=%t.out --check-prefix=CHECK-E
// RUN: FileCheck %s --input-file=%t.out --check-prefix=CHECK-F
// RUN: FileCheck %s --input-file=%t.out --check-prefix=CHECK-G
// RUN: FileCheck %s --input-file=%t.out --check-prefix=CHECK-H
// RUN: FileCheck %s --input-file=%t.out --check-prefix=CHECK-I
// RUN: FileCheck %s --input-file=%t.out --check-prefix=CHECK-J
// RUN: FileCheck %s --input-file=%t.out --check-prefix=CHECK-K
// RUN: FileCheck %s --input-file=%t.out --check-prefix=CHECK-L
// RUN: FileCheck %s --input-file=%t.out --check-prefix=CHECK-M
// RUN: FileCheck %s --input-file=%t.out --check-prefix=CHECK-N
// RUN: FileCheck %s --input-file=%t.out --check-prefix=CHECK-O
// RUN: FileCheck %s --input-file=%t.out --check-prefix=CHECK-P
// RUN: FileCheck %s --input-file=%t.out --check-prefix=CHECK-Q
// RUN: FileCheck %s --input-file=%t.out --check-prefix=CHECK-R

/// Ensure that emulated TLS also doesn't get sanitized.
// RUN: %clang_cc1 -S -x c++ -std=c++11 -triple aarch64-linux-android31 \
// RUN:   -fsanitize=memtag-globals -o - %s | FileCheck %s

// CHECK-A: .memtag global_int
// CHECK-A: .globl global_int
// CHECK-A: .p2align 4, 0x0
// CHECK-A: .size global_int, 16
int global_int;
// CHECK-B: .memtag _ZL9local_int
// CHECK-B: .local _ZL9local_int
// CHECK-B: .comm _ZL9local_int,16,16
static int local_int;

// CHECK-C: .memtag _ZL12local_buffer
// CHECK-C: .local _ZL12local_buffer
// CHECK-C: .comm _ZL12local_buffer,16,16
static char local_buffer[16];
// CHECK-D: .memtag _ZL22local_buffer_local_end
// CHECK-D: .p2align 4, 0x0
// CHECK-D: _ZL22local_buffer_local_end:
// CHECK-D: .xword _ZL12local_buffer+16
// CHECK-D: .size _ZL22local_buffer_local_end, 16
static char* local_buffer_local_end = &local_buffer[16];
// CHECK-E: .memtag local_buffer_global_end
// CHECK-E: .globl local_buffer_global_end
// CHECK-E  .p2align 4, 0x0
// CHECK-E: local_buffer_global_end:
// CHECK-E: .xword _ZL12local_buffer+16
// CHECK-E: .size local_buffer_global_end, 16
char* local_buffer_global_end = &local_buffer[16];

// CHECK-F: .memtag global_buffer
// CHECK-F: .globl global_buffer
// CHECK-F: .p2align 4, 0x0
// CHECK-F: .size global_buffer, 16
char global_buffer[16];
// CHECK-G: .memtag _ZL23global_buffer_local_end
// CHECK-G: .p2align 4, 0x0
// CHECK-G: _ZL23global_buffer_local_end:
// CHECK-G: .xword global_buffer+16
// CHECK-G: .size _ZL23global_buffer_local_end, 16
static char* global_buffer_local_end = &global_buffer[16];
// CHECK-H: .memtag global_buffer_global_end
// CHECK-H: .p2align 4, 0x0
// CHECK-H: global_buffer_global_end:
// CHECK-H: .xword global_buffer+16
// CHECK-H: .size global_buffer_global_end, 16
char* global_buffer_global_end = &global_buffer[16];

class MyClass {
 public:
  virtual ~MyClass() {}
  static int my_class_int;
  static const int my_class_const_int;
  virtual int virtual_func() { return 1; }
};
// CHECK-I: .memtag _ZN7MyClass12my_class_intE
// CHECK-I: .globl _ZN7MyClass12my_class_intE
// CHECK-I: .p2align 4, 0x0
// CHECK-I: .size _ZN7MyClass12my_class_intE, 16
int MyClass::my_class_int;
// CHECK-NOT: .memtag _ZN7MyClass18my_class_const_intE
const int MyClass::my_class_const_int = 1;

// CHECK-J: .memtag global_my_class
// CHECK-J: .globl global_my_class
// CHECK-J: .p2align 4, 0x0
// CHECK-J: .size global_my_class, 16
MyClass global_my_class;
// CHECK-K: .memtag _ZL14local_my_class
// CHECK-K: .p2align 4, 0x0
// CHECK-K: .size _ZL14local_my_class, 16
static MyClass local_my_class;

// CHECK-NOT: .memtag _ZL18local_const_string
static const char local_const_string[] = "this is a local string";
// CHECK-L: .memtag _ZL12local_string
// CHECK-L: .p2align 4, 0x0
// CHECK-L: .size _ZL12local_string, 32
static char local_string[] = "this is a local string";

// CHECK-M: .memtag global_atomic_int
// CHECK-M: .globl global_atomic_int
// CHECK-M: .p2align 4, 0x0
// CHECK-M: .size global_atomic_int, 16
_Atomic(int) global_atomic_int;
// CHECK-N: .memtag _ZL16local_atomic_int
// CHECK-N: .local _ZL16local_atomic_int
// CHECK-N: .comm _ZL16local_atomic_int,16,16
static _Atomic(int) local_atomic_int;

union MyUnion {
  int i;
  char c;
};

// CHECK-O: .memtag global_union
// CHECK-O: .globl global_union
// CHECK-O: .p2align 4, 0x0
// CHECK-O: .size global_union, 16
MyUnion global_union;
// CHECK-P: .memtag _ZL11local_union
// CHECK-P: .local _ZL11local_union
// CHECK-P: .comm _ZL11local_union,16,16
static MyUnion local_union;

// CHECK-NOT: .memtag {{.*}}global_tls
thread_local int global_tls;
// CHECK-NOT: .memtag {{.*}}local_tls
static thread_local int local_tls;

/// Prevent the compiler from realising that non-const local variables are not
/// modified, and constant inlining into f().
const void* export_pointers(int c) {
  switch (c) {
    case 0:  return &local_int;
    case 1:  return &local_buffer;
    case 2:  return &local_buffer_local_end;
    case 3:  return &global_buffer_local_end;
    case 4:  return &MyClass::my_class_int;
    case 6:  return &local_my_class;
    case 8:  return &local_string;
    case 9:  return &local_atomic_int;
    case 10: return &local_union;
    case 11: return &local_tls;
  }
  return nullptr;
}

/// Ensure that all tagged globals are loaded/referenced via. the GOT.
// CHECK-NOT:      .memtag _Z1fi
// CHECK-Q:        _Z1fi:
int f(int x) {
  // CHECK-R: .memtag _ZZ1fiE12function_int
  // CHECK-R: .local _ZZ1fiE12function_int
  // CHECK-R: .comm _ZZ1fiE12function_int,16,16
  static int function_int = 0;
  /// Prevent non-const `f` from being promoted to a constant and inlined.
  function_int += x;

  return
  // CHECK-Q-DAG: adrp [[REG_A:x[0-9]+]], :got:global_int
  // CHECK-Q-DAG: ldr  [[REG_A2:x[0-9]+]], [[[REG_A]], :got_lo12:global_int]
  // CHECK-Q-DAG: ldr  {{.*}}, [[[REG_A2]]]
      global_int +
  // CHECK-Q-DAG: adrp [[REG_B:x[0-9]+]], :got:_ZL9local_int
  // CHECK-Q-DAG: ldr  [[REG_B2:x[0-9]+]], [[[REG_B]], :got_lo12:_ZL9local_int]
  // CHECK-Q-DAG: ldr  {{.*}}, [[[REG_B2]]]
      local_int +
  // CHECK-Q-DAG: adrp  [[REG_C:x[0-9]+]], :got:_ZL12local_buffer
  // CHECK-Q-DAG: ldr   [[REG_C2:x[0-9]+]], [[[REG_C]], :got_lo12:_ZL12local_buffer]
  // CHECK-Q-DAG: ldrsb {{.*}}, [[[REG_C2]]]
      local_buffer[0] +
  // CHECK-Q-DAG: adrp   [[REG_D:x[0-9]+]], :got:_ZL22local_buffer_local_end
  // CHECK-Q-DAG: ldr    [[REG_D2:x[0-9]+]], [[[REG_D]], :got_lo12:_ZL22local_buffer_local_end]
  // CHECK-Q-DAG: ldr    [[REG_D3:x[0-9]+]], [[[REG_D2]]]
  // CHECK-Q-DAG: ldursb {{.*}}, [[[REG_D3]], #-16]
      local_buffer_local_end[-16] +
  // CHECK-Q-DAG: adrp   [[REG_E:x[0-9]+]], :got:local_buffer_global_end
  // CHECK-Q-DAG: ldr    [[REG_E2:x[0-9]+]], [[[REG_E]], :got_lo12:local_buffer_global_end]
  // CHECK-Q-DAG: ldr    [[REG_E3:x[0-9]+]], [[[REG_E2]]]
  // CHECK-Q-DAG: ldursb {{.*}}, [[[REG_E3]], #-16]
      local_buffer_global_end[-16] +
  // CHECK-Q-DAG: adrp  [[REG_F:x[0-9]+]], :got:global_buffer{{$}}
  // CHECK-Q-DAG: ldr   [[REG_F2:x[0-9]+]], [[[REG_F]], :got_lo12:global_buffer]
  // CHECK-Q-DAG: ldrsb {{.*}}, [[[REG_F2]]]
      global_buffer[0] +
  // CHECK-Q-DAG: adrp   [[REG_G:x[0-9]+]], :got:_ZL23global_buffer_local_end
  // CHECK-Q-DAG: ldr    [[REG_G2:x[0-9]+]], [[[REG_G]], :got_lo12:_ZL23global_buffer_local_end]
  // CHECK-Q-DAG: ldr    [[REG_G3:x[0-9]+]], [[[REG_G2]]]
  // CHECK-Q-DAG: ldursb {{.*}}, [[[REG_G3]], #-16]
      global_buffer_local_end[-16] +
  // CHECK-Q-DAG: adrp   [[REG_H:x[0-9]+]], :got:global_buffer_global_end
  // CHECK-Q-DAG: ldr    [[REG_H2:x[0-9]+]], [[[REG_H]], :got_lo12:global_buffer_global_end]
  // CHECK-Q-DAG: ldr    [[REG_H3:x[0-9]+]], [[[REG_H2]]]
  // CHECK-Q-DAG: ldursb {{.*}}, [[[REG_H3]], #-16]
      global_buffer_global_end[-16] +
  // CHECK-Q-DAG: adrp [[REG_I:x[0-9]+]], :got:_ZN7MyClass12my_class_intE
  // CHECK-Q-DAG: ldr  [[REG_I2:x[0-9]+]], [[[REG_I]], :got_lo12:_ZN7MyClass12my_class_intE]
  // CHECK-Q-DAG: ldr  {{.*}}, [[[REG_I2]]]
      MyClass::my_class_int +
  /// Constant values - ignore.
      MyClass::my_class_const_int +
      global_my_class.virtual_func() +
      local_my_class.virtual_func() +
      local_const_string[0] +
  // CHECK-Q-DAG: adrp  [[REG_J:x[0-9]+]], :got:_ZL12local_string
  // CHECK-Q-DAG: ldr   [[REG_J2:x[0-9]+]], [[[REG_J]], :got_lo12:_ZL12local_string]
  // CHECK-Q-DAG: ldrsb {{.*}}, [[[REG_J2]]]
      local_string[0] +
  // CHECK-Q-DAG: adrp  [[REG_K:x[0-9]+]], :got:_ZL16local_atomic_int
  // CHECK-Q-DAG: ldr   [[REG_K2:x[0-9]+]], [[[REG_K]], :got_lo12:_ZL16local_atomic_int]
  // CHECK-Q-DAG: ldar {{.*}}, [[[REG_K2]]]
      local_atomic_int +
  // CHECK-Q-DAG: adrp [[REG_L:x[0-9]+]], :got:global_atomic_int
  // CHECK-Q-DAG: ldr  [[REG_L2:x[0-9]+]], [[[REG_L]], :got_lo12:global_atomic_int]
  // CHECK-Q-DAG: ldar {{.*}}, [[[REG_L2]]]
      global_atomic_int +
  // CHECK-Q-DAG: adrp [[REG_M:x[0-9]+]], :got:global_union
  // CHECK-Q-DAG: ldr  [[REG_M2:x[0-9]+]], [[[REG_M]], :got_lo12:global_union]
  // CHECK-Q-DAG: ldr  {{.*}}, [[[REG_M2]]]
      global_union.i +
  // CHECK-Q-DAG: adrp  [[REG_N:x[0-9]+]], :got:_ZL11local_union
  // CHECK-Q-DAG: ldr   [[REG_N2:x[0-9]+]], [[[REG_N]], :got_lo12:_ZL11local_union]
  // CHECK-Q-DAG: ldrsb {{.*}}, [[[REG_N2]]]
      local_union.c +
  /// Global variables - ignore.
      global_tls +
      local_tls +
  // CHECK-Q-DAG: adrp  [[REG_O:x[0-9]+]], :got:_ZZ1fiE12function_int
  // CHECK-Q-DAG: ldr   [[REG_O2:x[0-9]+]], [[[REG_O]], :got_lo12:_ZZ1fiE12function_int]
  // CHECK-Q-DAG: ldr   {{.*}}, [[[REG_O2]]]
      function_int;
}