1; Test basic address sanitizer instrumentation. 2; 3 4; RUN: opt < %s -passes=asan -S | FileCheck --check-prefixes=CHECK,CHECK-S3 %s 5; RUN: opt < %s -passes=asan -asan-mapping-scale=5 -S | FileCheck --check-prefixes=CHECK,CHECK-S5 %s 6 7target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 8target triple = "x86_64-unknown-linux-gnu" 9; CHECK: @llvm.used = appending global [1 x ptr] [ptr @asan.module_ctor] 10; CHECK: @llvm.global_ctors = {{.*}}{ i32 1, ptr @asan.module_ctor, ptr @asan.module_ctor } 11 12define i32 @test_load(ptr %a) sanitize_address { 13; CHECK-LABEL: @test_load 14; CHECK-NOT: load 15; CHECK: %[[LOAD_ADDR:[^ ]*]] = ptrtoint ptr %a to i64 16; CHECK-S3: lshr i64 %[[LOAD_ADDR]], 3 17; CHECK-S5: lshr i64 %[[LOAD_ADDR]], 5 18; CHECK: {{or|add}} 19; CHECK: %[[LOAD_SHADOW_PTR:[^ ]*]] = inttoptr 20; CHECK: %[[LOAD_SHADOW:[^ ]*]] = load i8, ptr %[[LOAD_SHADOW_PTR]] 21; CHECK: icmp ne i8 22; CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}!prof ![[PROF:[0-9]+]] 23; 24; First instrumentation block refines the shadow test. 25; CHECK-S3: and i64 %[[LOAD_ADDR]], 7 26; CHECK-S5: and i64 %[[LOAD_ADDR]], 31 27; CHECK: add i64 %{{.*}}, 3 28; CHECK: trunc i64 %{{.*}} to i8 29; CHECK: icmp sge i8 %{{.*}}, %[[LOAD_SHADOW]] 30; CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}} 31; 32; The crash block reports the error. 33; CHECK: call void @__asan_report_load4(i64 %[[LOAD_ADDR]]) 34; CHECK: unreachable 35; 36; The actual load. 37; CHECK: %tmp1 = load i32, ptr %a 38; CHECK: ret i32 %tmp1 39 40 41 42entry: 43 %tmp1 = load i32, ptr %a, align 4 44 ret i32 %tmp1 45} 46 47define void @test_store(ptr %a) sanitize_address { 48; CHECK-LABEL: @test_store 49; CHECK-NOT: store 50; CHECK: %[[STORE_ADDR:[^ ]*]] = ptrtoint ptr %a to i64 51; CHECK-S3: lshr i64 %[[STORE_ADDR]], 3 52; CHECK-S5: lshr i64 %[[STORE_ADDR]], 5 53; CHECK: {{or|add}} 54; CHECK: %[[STORE_SHADOW_PTR:[^ ]*]] = inttoptr 55; CHECK: %[[STORE_SHADOW:[^ ]*]] = load i8, ptr %[[STORE_SHADOW_PTR]] 56; CHECK: icmp ne i8 57; CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}} 58; 59; First instrumentation block refines the shadow test. 60; CHECK-S3: and i64 %[[STORE_ADDR]], 7 61; CHECK-S5: and i64 %[[STORE_ADDR]], 31 62; CHECK: add i64 %{{.*}}, 3 63; CHECK: trunc i64 %{{.*}} to i8 64; CHECK: icmp sge i8 %{{.*}}, %[[STORE_SHADOW]] 65; CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}} 66; 67; The crash block reports the error. 68; CHECK: call void @__asan_report_store4(i64 %[[STORE_ADDR]]) 69; CHECK: unreachable 70; 71; The actual load. 72; CHECK: store i32 42, ptr %a 73; CHECK: ret void 74; 75 76entry: 77 store i32 42, ptr %a, align 4 78 ret void 79} 80 81; Check that asan leaves just one alloca. 82 83declare void @alloca_test_use(ptr) 84define void @alloca_test() sanitize_address { 85entry: 86 %x = alloca [10 x i8], align 1 87 %y = alloca [10 x i8], align 1 88 %z = alloca [10 x i8], align 1 89 call void @alloca_test_use(ptr %x) 90 call void @alloca_test_use(ptr %y) 91 call void @alloca_test_use(ptr %z) 92 ret void 93} 94 95; CHECK-LABEL: define void @alloca_test() 96; CHECK: %asan_local_stack_base = alloca 97; CHECK: = alloca 98; CHECK-NOT: = alloca 99; CHECK: ret void 100 101define void @LongDoubleTest(ptr nocapture %a) nounwind uwtable sanitize_address { 102entry: 103 store x86_fp80 0xK3FFF8000000000000000, ptr %a, align 16 104 ret void 105} 106 107; CHECK-LABEL: LongDoubleTest 108; CHECK: __asan_report_store_n 109; CHECK: __asan_report_store_n 110; CHECK: ret void 111 112 113define void @i40test(ptr %a, ptr %b) nounwind uwtable sanitize_address { 114 entry: 115 %t = load i40, ptr %a 116 store i40 %t, ptr %b, align 8 117 ret void 118} 119 120; CHECK-LABEL: i40test 121; CHECK: __asan_report_load_n{{.*}}, i64 5) 122; CHECK: __asan_report_load_n{{.*}}, i64 5) 123; CHECK: __asan_report_store_n{{.*}}, i64 5) 124; CHECK: __asan_report_store_n{{.*}}, i64 5) 125; CHECK: ret void 126 127define void @i64test_align1(ptr %b) nounwind uwtable sanitize_address { 128 entry: 129 store i64 0, ptr %b, align 1 130 ret void 131} 132 133; CHECK-LABEL: i64test_align1 134; CHECK: __asan_report_store_n{{.*}}, i64 8) 135; CHECK: __asan_report_store_n{{.*}}, i64 8) 136; CHECK: ret void 137 138define void @i128test_align8(ptr %a) nounwind uwtable sanitize_address { 139entry: 140 store i128 0, ptr %a, align 8 141 ret void 142} 143; CHECK-LABEL: define {{[^@]+}}@i128test_align8( 144; CHECK-S3: load i16, ptr %[[#]], align 1 145; CHECK-S3-NEXT: icmp ne i16 %[[#]], 0 146; CHECK-S5: load i8, ptr %[[#]], align 1 147; CHECK-S5: load i8, ptr %[[#]], align 1 148 149define void @i128test_align16(ptr %a) nounwind uwtable sanitize_address { 150entry: 151 store i128 0, ptr %a, align 16 152 ret void 153} 154; CHECK-LABEL: define {{[^@]+}}@i128test_align16( 155; CHECK-S3: load i16, ptr %[[#]], align 2 156; CHECK-S3-NEXT: icmp ne i16 %[[#]], 0 157; CHECK-S5: load i8, ptr %[[#]], align 1 158; CHECK-S5-NEXT: icmp ne i8 %[[#]], 0 159 160define void @i80test(ptr %a, ptr %b) nounwind uwtable sanitize_address { 161 entry: 162 %t = load i80, ptr %a 163 store i80 %t, ptr %b, align 8 164 ret void 165} 166 167; CHECK-LABEL: i80test 168; CHECK: __asan_report_load_n{{.*}}, i64 10) 169; CHECK: __asan_report_load_n{{.*}}, i64 10) 170; CHECK: __asan_report_store_n{{.*}}, i64 10) 171; CHECK: __asan_report_store_n{{.*}}, i64 10) 172; CHECK: ret void 173 174; asan should not instrument functions with available_externally linkage. 175define available_externally i32 @f_available_externally(ptr %a) sanitize_address { 176entry: 177 %tmp1 = load i32, ptr %a 178 ret i32 %tmp1 179} 180; CHECK-LABEL: @f_available_externally 181; CHECK-NOT: __asan_report 182; CHECK: ret i32 183 184 185; CHECK-LABEL: @test_swifterror 186; CHECK-NOT: __asan_report_load 187; CHECK: ret void 188define void @test_swifterror(ptr swifterror) sanitize_address { 189 %swifterror_ptr_value = load ptr, ptr %0 190 ret void 191} 192 193; CHECK-LABEL: @test_swifterror_2 194; CHECK-NOT: __asan_report_store 195; CHECK: ret void 196define void @test_swifterror_2(ptr swifterror) sanitize_address { 197 store ptr null, ptr %0 198 ret void 199} 200 201; CHECK-LABEL: @test_swifterror_3 202; CHECK-NOT: __asan_report_store 203; CHECK: ret void 204define void @test_swifterror_3() sanitize_address { 205 %swifterror_addr = alloca swifterror ptr 206 store ptr null, ptr %swifterror_addr 207 call void @test_swifterror_2(ptr swifterror %swifterror_addr) 208 ret void 209} 210 211;; ctor/dtor have the nounwind attribute. See uwtable.ll, they additionally have 212;; the uwtable attribute with the module flag "uwtable". 213; CHECK: define internal void @asan.module_ctor() #[[#ATTR:]] comdat { 214; CHECK: call void @__asan_init() 215;; __asan_register_elf_globals is called even if this module does not contain instrumented global variables. 216; CHECK: call void @__asan_register_elf_globals(i64 ptrtoint (ptr @___asan_globals_registered to i64), i64 ptrtoint (ptr @__start_asan_globals to i64), i64 ptrtoint (ptr @__stop_asan_globals to i64)) 217 218; CHECK: attributes #[[#ATTR]] = { nounwind } 219 220; PROF 221; CHECK: ![[PROF]] = !{!"branch_weights", i32 1, i32 1048575} 222