• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; Test basic address sanitizer instrumentation.
2;
3; RUN: opt < %s -hwasan -hwasan-recover=0 -S | FileCheck %s --check-prefixes=CHECK,ABORT,DYNAMIC-SHADOW
4; RUN: opt < %s -hwasan -hwasan-recover=1 -S | FileCheck %s --check-prefixes=CHECK,RECOVER,DYNAMIC-SHADOW
5; RUN: opt < %s -hwasan -hwasan-recover=0 -hwasan-mapping-offset=0 -S | FileCheck %s --check-prefixes=CHECK,ABORT,ZERO-BASED-SHADOW
6; RUN: opt < %s -hwasan -hwasan-recover=1 -hwasan-mapping-offset=0 -S | FileCheck %s --check-prefixes=CHECK,RECOVER,ZERO-BASED-SHADOW
7
8target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
9target triple = "aarch64--linux-android"
10
11define i8 @test_load8(i8* %a) sanitize_hwaddress {
12; CHECK-LABEL: @test_load8(
13; CHECK: %[[A:[^ ]*]] = ptrtoint i8* %a to i64
14; CHECK: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
15; CHECK: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
16; CHECK: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
17; CHECK: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
18; DYNAMIC-SHADOW: %[[D_DYN:[^ ]*]] = add i64 %[[D]], %.hwasan.shadow
19; DYNAMIC-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D_DYN]] to i8*
20; ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
21; CHECK: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
22; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
23; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
24
25; ABORT: call void asm sideeffect "brk #2304", "{x0}"(i64 %[[A]])
26; ABORT: unreachable
27; RECOVER: call void asm sideeffect "brk #2336", "{x0}"(i64 %[[A]])
28; RECOVER: br label
29
30; CHECK: %[[G:[^ ]*]] = load i8, i8* %a, align 4
31; CHECK: ret i8 %[[G]]
32
33entry:
34  %b = load i8, i8* %a, align 4
35  ret i8 %b
36}
37
38define i16 @test_load16(i16* %a) sanitize_hwaddress {
39; CHECK-LABEL: @test_load16(
40; CHECK: %[[A:[^ ]*]] = ptrtoint i16* %a to i64
41; CHECK: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
42; CHECK: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
43; CHECK: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
44; CHECK: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
45; DYNAMIC-SHADOW: %[[D_DYN:[^ ]*]] = add i64 %[[D]], %.hwasan.shadow
46; DYNAMIC-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D_DYN]] to i8*
47; ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
48; CHECK: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
49; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
50; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
51
52; ABORT: call void asm sideeffect "brk #2305", "{x0}"(i64 %[[A]])
53; ABORT: unreachable
54; RECOVER: call void asm sideeffect "brk #2337", "{x0}"(i64 %[[A]])
55; RECOVER: br label
56
57; CHECK: %[[G:[^ ]*]] = load i16, i16* %a, align 4
58; CHECK: ret i16 %[[G]]
59
60entry:
61  %b = load i16, i16* %a, align 4
62  ret i16 %b
63}
64
65define i32 @test_load32(i32* %a) sanitize_hwaddress {
66; CHECK-LABEL: @test_load32(
67; CHECK: %[[A:[^ ]*]] = ptrtoint i32* %a to i64
68; CHECK: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
69; CHECK: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
70; CHECK: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
71; CHECK: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
72; DYNAMIC-SHADOW: %[[D_DYN:[^ ]*]] = add i64 %[[D]], %.hwasan.shadow
73; DYNAMIC-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D_DYN]] to i8*
74; ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
75; CHECK: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
76; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
77; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
78
79; ABORT: call void asm sideeffect "brk #2306", "{x0}"(i64 %[[A]])
80; ABORT: unreachable
81; RECOVER: call void asm sideeffect "brk #2338", "{x0}"(i64 %[[A]])
82; RECOVER: br label
83
84; CHECK: %[[G:[^ ]*]] = load i32, i32* %a, align 4
85; CHECK: ret i32 %[[G]]
86
87entry:
88  %b = load i32, i32* %a, align 4
89  ret i32 %b
90}
91
92define i64 @test_load64(i64* %a) sanitize_hwaddress {
93; CHECK-LABEL: @test_load64(
94; CHECK: %[[A:[^ ]*]] = ptrtoint i64* %a to i64
95; CHECK: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
96; CHECK: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
97; CHECK: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
98; CHECK: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
99; DYNAMIC-SHADOW: %[[D_DYN:[^ ]*]] = add i64 %[[D]], %.hwasan.shadow
100; DYNAMIC-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D_DYN]] to i8*
101; ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
102; CHECK: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
103; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
104; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
105
106; ABORT: call void asm sideeffect "brk #2307", "{x0}"(i64 %[[A]])
107; ABORT: unreachable
108; RECOVER: call void asm sideeffect "brk #2339", "{x0}"(i64 %[[A]])
109; RECOVER: br label
110
111; CHECK: %[[G:[^ ]*]] = load i64, i64* %a, align 8
112; CHECK: ret i64 %[[G]]
113
114entry:
115  %b = load i64, i64* %a, align 8
116  ret i64 %b
117}
118
119define i128 @test_load128(i128* %a) sanitize_hwaddress {
120; CHECK-LABEL: @test_load128(
121; CHECK: %[[A:[^ ]*]] = ptrtoint i128* %a to i64
122; CHECK: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
123; CHECK: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
124; CHECK: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
125; CHECK: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
126; DYNAMIC-SHADOW: %[[D_DYN:[^ ]*]] = add i64 %[[D]], %.hwasan.shadow
127; DYNAMIC-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D_DYN]] to i8*
128; ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
129; CHECK: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
130; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
131; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
132
133; ABORT: call void asm sideeffect "brk #2308", "{x0}"(i64 %[[A]])
134; ABORT: unreachable
135; RECOVER: call void asm sideeffect "brk #2340", "{x0}"(i64 %[[A]])
136; RECOVER: br label
137
138; CHECK: %[[G:[^ ]*]] = load i128, i128* %a, align 16
139; CHECK: ret i128 %[[G]]
140
141entry:
142  %b = load i128, i128* %a, align 16
143  ret i128 %b
144}
145
146define i40 @test_load40(i40* %a) sanitize_hwaddress {
147; CHECK-LABEL: @test_load40(
148; CHECK: %[[A:[^ ]*]] = ptrtoint i40* %a to i64
149; ABORT: call void @__hwasan_loadN(i64 %[[A]], i64 5)
150; RECOVER: call void @__hwasan_loadN_noabort(i64 %[[A]], i64 5)
151; CHECK: %[[B:[^ ]*]] = load i40, i40* %a
152; CHECK: ret i40 %[[B]]
153
154entry:
155  %b = load i40, i40* %a, align 4
156  ret i40 %b
157}
158
159define void @test_store8(i8* %a, i8 %b) sanitize_hwaddress {
160; CHECK-LABEL: @test_store8(
161; CHECK: %[[A:[^ ]*]] = ptrtoint i8* %a to i64
162; CHECK: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
163; CHECK: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
164; CHECK: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
165; CHECK: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
166; DYNAMIC-SHADOW: %[[D_DYN:[^ ]*]] = add i64 %[[D]], %.hwasan.shadow
167; DYNAMIC-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D_DYN]] to i8*
168; ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
169; CHECK: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
170; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
171; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
172
173; ABORT: call void asm sideeffect "brk #2320", "{x0}"(i64 %[[A]])
174; ABORT: unreachable
175; RECOVER: call void asm sideeffect "brk #2352", "{x0}"(i64 %[[A]])
176; RECOVER: br label
177
178; CHECK: store i8 %b, i8* %a, align 4
179; CHECK: ret void
180
181entry:
182  store i8 %b, i8* %a, align 4
183  ret void
184}
185
186define void @test_store16(i16* %a, i16 %b) sanitize_hwaddress {
187; CHECK-LABEL: @test_store16(
188; CHECK: %[[A:[^ ]*]] = ptrtoint i16* %a to i64
189; CHECK: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
190; CHECK: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
191; CHECK: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
192; CHECK: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
193; DYNAMIC-SHADOW: %[[D_DYN:[^ ]*]] = add i64 %[[D]], %.hwasan.shadow
194; DYNAMIC-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D_DYN]] to i8*
195; ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
196; CHECK: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
197; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
198; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
199
200; ABORT: call void asm sideeffect "brk #2321", "{x0}"(i64 %[[A]])
201; ABORT: unreachable
202; RECOVER: call void asm sideeffect "brk #2353", "{x0}"(i64 %[[A]])
203; RECOVER: br label
204
205; CHECK: store i16 %b, i16* %a, align 4
206; CHECK: ret void
207
208entry:
209  store i16 %b, i16* %a, align 4
210  ret void
211}
212
213define void @test_store32(i32* %a, i32 %b) sanitize_hwaddress {
214; CHECK-LABEL: @test_store32(
215; CHECK: %[[A:[^ ]*]] = ptrtoint i32* %a to i64
216; CHECK: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
217; CHECK: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
218; CHECK: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
219; CHECK: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
220; DYNAMIC-SHADOW: %[[D_DYN:[^ ]*]] = add i64 %[[D]], %.hwasan.shadow
221; DYNAMIC-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D_DYN]] to i8*
222; ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
223; CHECK: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
224; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
225; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
226
227; ABORT: call void asm sideeffect "brk #2322", "{x0}"(i64 %[[A]])
228; ABORT: unreachable
229; RECOVER: call void asm sideeffect "brk #2354", "{x0}"(i64 %[[A]])
230; RECOVER: br label
231
232; CHECK: store i32 %b, i32* %a, align 4
233; CHECK: ret void
234
235entry:
236  store i32 %b, i32* %a, align 4
237  ret void
238}
239
240define void @test_store64(i64* %a, i64 %b) sanitize_hwaddress {
241; CHECK-LABEL: @test_store64(
242; CHECK: %[[A:[^ ]*]] = ptrtoint i64* %a to i64
243; CHECK: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
244; CHECK: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
245; CHECK: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
246; CHECK: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
247; DYNAMIC-SHADOW: %[[D_DYN:[^ ]*]] = add i64 %[[D]], %.hwasan.shadow
248; DYNAMIC-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D_DYN]] to i8*
249; ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
250; CHECK: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
251; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
252; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
253
254; ABORT: call void asm sideeffect "brk #2323", "{x0}"(i64 %[[A]])
255; ABORT: unreachable
256; RECOVER: call void asm sideeffect "brk #2355", "{x0}"(i64 %[[A]])
257; RECOVER: br label
258
259; CHECK: store i64 %b, i64* %a, align 8
260; CHECK: ret void
261
262entry:
263  store i64 %b, i64* %a, align 8
264  ret void
265}
266
267define void @test_store128(i128* %a, i128 %b) sanitize_hwaddress {
268; CHECK-LABEL: @test_store128(
269; CHECK: %[[A:[^ ]*]] = ptrtoint i128* %a to i64
270; CHECK: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
271; CHECK: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
272; CHECK: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
273; CHECK: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
274; DYNAMIC-SHADOW: %[[D_DYN:[^ ]*]] = add i64 %[[D]], %.hwasan.shadow
275; DYNAMIC-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D_DYN]] to i8*
276; ZERO-BASED-SHADOW: %[[E:[^ ]*]] = inttoptr i64 %[[D]] to i8*
277; CHECK: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
278; CHECK: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
279; CHECK: br i1 %[[F]], label {{.*}}, label {{.*}}, !prof {{.*}}
280
281; ABORT: call void asm sideeffect "brk #2324", "{x0}"(i64 %[[A]])
282; ABORT: unreachable
283; RECOVER: call void asm sideeffect "brk #2356", "{x0}"(i64 %[[A]])
284; RECOVER: br label
285
286; CHECK: store i128 %b, i128* %a, align 16
287; CHECK: ret void
288
289entry:
290  store i128 %b, i128* %a, align 16
291  ret void
292}
293
294define void @test_store40(i40* %a, i40 %b) sanitize_hwaddress {
295; CHECK-LABEL: @test_store40(
296; CHECK: %[[A:[^ ]*]] = ptrtoint i40* %a to i64
297; ABORT: call void @__hwasan_storeN(i64 %[[A]], i64 5)
298; RECOVER: call void @__hwasan_storeN_noabort(i64 %[[A]], i64 5)
299; CHECK: store i40 %b, i40* %a
300; CHECK: ret void
301
302entry:
303  store i40 %b, i40* %a, align 4
304  ret void
305}
306
307define void @test_store_unaligned(i64* %a, i64 %b) sanitize_hwaddress {
308; CHECK-LABEL: @test_store_unaligned(
309; CHECK: %[[A:[^ ]*]] = ptrtoint i64* %a to i64
310; ABORT: call void @__hwasan_storeN(i64 %[[A]], i64 8)
311; RECOVER: call void @__hwasan_storeN_noabort(i64 %[[A]], i64 8)
312; CHECK: store i64 %b, i64* %a, align 4
313; CHECK: ret void
314
315entry:
316  store i64 %b, i64* %a, align 4
317  ret void
318}
319
320define i8 @test_load_noattr(i8* %a) {
321; CHECK-LABEL: @test_load_noattr(
322; CHECK-NEXT: entry:
323; CHECK-NEXT: %[[B:[^ ]*]] = load i8, i8* %a
324; CHECK-NEXT: ret i8 %[[B]]
325
326entry:
327  %b = load i8, i8* %a, align 4
328  ret i8 %b
329}
330
331define i8 @test_load_notmyattr(i8* %a) sanitize_address {
332; CHECK-LABEL: @test_load_notmyattr(
333; CHECK-NEXT: entry:
334; CHECK-NEXT: %[[B:[^ ]*]] = load i8, i8* %a
335; CHECK-NEXT: ret i8 %[[B]]
336
337entry:
338  %b = load i8, i8* %a, align 4
339  ret i8 %b
340}
341
342define i8 @test_load_addrspace(i8 addrspace(256)* %a) sanitize_hwaddress {
343; CHECK-LABEL: @test_load_addrspace(
344; CHECK-NEXT: entry:
345; DYNAMIC-SHADOW: %.hwasan.shadow = call i64 asm "", "=r,0"([0 x i8]* @__hwasan_shadow)
346; CHECK-NEXT: %[[B:[^ ]*]] = load i8, i8 addrspace(256)* %a
347; CHECK-NEXT: ret i8 %[[B]]
348
349entry:
350  %b = load i8, i8 addrspace(256)* %a, align 4
351  ret i8 %b
352}
353
354; CHECK: declare void @__hwasan_init()
355
356; CHECK:      define internal void @hwasan.module_ctor() {
357; CHECK-NEXT:   call void @__hwasan_init()
358; CHECK-NEXT:   ret void
359; CHECK-NEXT: }
360