1; Test -hwasan-with-ifunc flag. 2; 3; RUN: opt -hwasan -S < %s | \ 4; RUN: FileCheck %s --check-prefixes=CHECK,CHECK-NOGLOBAL,CHECK-TLS,CHECK-HISTORY 5; RUN: opt -hwasan -S -hwasan-with-ifunc=0 -hwasan-with-tls=1 -hwasan-record-stack-history=1 < %s | \ 6; RUN: FileCheck %s --check-prefixes=CHECK,CHECK-NOGLOBAL,CHECK-TLS,CHECK-HISTORY 7; RUN: opt -hwasan -S -hwasan-with-ifunc=0 -hwasan-with-tls=1 -hwasan-record-stack-history=0 < %s | \ 8; RUN: FileCheck %s --check-prefixes=CHECK,CHECK-NOGLOBAL,CHECK-IFUNC,CHECK-NOHISTORY 9; RUN: opt -hwasan -S -hwasan-with-ifunc=0 -hwasan-with-tls=0 < %s | \ 10; RUN: FileCheck %s --check-prefixes=CHECK,CHECK-GLOBAL,CHECK-NOHISTORY 11; RUN: opt -hwasan -S -hwasan-with-ifunc=1 -hwasan-with-tls=0 < %s | \ 12; RUN: FileCheck %s --check-prefixes=CHECK,CHECk-NOGLOBAL,CHECK-IFUNC,CHECK-NOHISTORY 13 14target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" 15target triple = "aarch64--linux-android22" 16 17; CHECK-IFUNC: @__hwasan_shadow = external global [0 x i8] 18; CHECK-NOIFUNC: @__hwasan_shadow_memory_dynamic_address = external global i64 19 20define i32 @test_load(i32* %a) sanitize_hwaddress { 21; First instrumentation in the function must be to load the dynamic shadow 22; address into a local variable. 23; CHECK-LABEL: @test_load 24; CHECK: entry: 25 26; CHECK-NOGLOBAL: %[[A:[^ ]*]] = call i8* asm "", "=r,0"([0 x i8]* @__hwasan_shadow) 27; CHECK-NOGLOBAL: @llvm.hwasan.check.memaccess(i8* %[[A]] 28 29; CHECK-GLOBAL: load i8*, i8** @__hwasan_shadow_memory_dynamic_address 30 31; "store i64" is only used to update stack history (this input IR intentionally does not use any i64) 32; W/o any allocas, the history is not updated, even if it is enabled explicitly with -hwasan-record-stack-history=1 33; CHECK-NOT: store i64 34 35; CHECK: ret i32 36 37entry: 38 %x = load i32, i32* %a, align 4 39 ret i32 %x 40} 41 42declare void @use(i32* %p) 43 44define void @test_alloca() sanitize_hwaddress { 45; First instrumentation in the function must be to load the dynamic shadow 46; address into a local variable. 47; CHECK-LABEL: @test_alloca 48; CHECK: entry: 49 50; CHECK-IFUNC: %[[A:[^ ]*]] = call i8* asm "", "=r,0"([0 x i8]* @__hwasan_shadow) 51; CHECK-IFUNC: getelementptr i8, i8* %[[A]] 52 53; CHECK-GLOBAL: load i8*, i8** @__hwasan_shadow_memory_dynamic_address 54 55; CHECK-TLS: %[[A:[^ ]*]] = call i8* @llvm.thread.pointer() 56; CHECK-TLS: %[[B:[^ ]*]] = getelementptr i8, i8* %[[A]], i32 48 57; CHECK-TLS: %[[C:[^ ]*]] = bitcast i8* %[[B]] to i64* 58; CHECK-TLS: %[[D:[^ ]*]] = load i64, i64* %[[C]] 59; CHECK-TLS: %[[E:[^ ]*]] = ashr i64 %[[D]], 3 60 61; CHECK-NOHISTORY-NOT: store i64 62 63; CHECK-HISTORY: call i64 @llvm.read_register.i64(metadata [[MD:![0-9]*]]) 64; CHECK-HISTORY: %[[PTR:[^ ]*]] = inttoptr i64 %[[D]] to i64* 65; CHECK-HISTORY: store i64 %{{.*}}, i64* %[[PTR]] 66; CHECK-HISTORY: %[[D1:[^ ]*]] = ashr i64 %[[D]], 56 67; CHECK-HISTORY: %[[D2:[^ ]*]] = shl nuw nsw i64 %[[D1]], 12 68; CHECK-HISTORY: %[[D3:[^ ]*]] = xor i64 %[[D2]], -1 69; CHECK-HISTORY: %[[D4:[^ ]*]] = add i64 %[[D]], 8 70; CHECK-HISTORY: %[[D5:[^ ]*]] = and i64 %[[D4]], %[[D3]] 71; CHECK-HISTORY: store i64 %[[D5]], i64* %[[C]] 72 73; CHECK-TLS: %[[F:[^ ]*]] = or i64 %[[D]], 4294967295 74; CHECK-TLS: = add i64 %[[F]], 1 75 76; CHECK-HISTORY: = xor i64 %[[E]], 0 77 78; CHECK-NOHISTORY-NOT: store i64 79 80 81entry: 82 %x = alloca i32, align 4 83 call void @use(i32* %x) 84 ret void 85} 86 87; CHECK-HISTORY: [[MD]] = !{!"pc"} 88