diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp index 61dfc6411fc3a..2f7712171bab2 100644 --- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp @@ -1847,6 +1847,12 @@ void HWAddressSanitizer::instrumentPersonalityFunctions() { IsLocal ? GlobalValue::InternalLinkage : GlobalValue::LinkOnceODRLinkage, ThunkName, &M); + // TODO: think about other attributes as well. + if (any_of(P.second, [](const Function *F) { + return F->hasFnAttribute("branch-target-enforcement"); + })) { + ThunkFn->addFnAttr("branch-target-enforcement"); + } if (!IsLocal) { ThunkFn->setVisibility(GlobalValue::HiddenVisibility); ThunkFn->setComdat(M.getOrInsertComdat(ThunkName)); diff --git a/llvm/test/Instrumentation/HWAddressSanitizer/personality-bti.ll b/llvm/test/Instrumentation/HWAddressSanitizer/personality-bti.ll new file mode 100644 index 0000000000000..3183a184c9d0d --- /dev/null +++ b/llvm/test/Instrumentation/HWAddressSanitizer/personality-bti.ll @@ -0,0 +1,95 @@ +; RUN: opt < %s -mtriple aarch64-linux-android29 -passes=hwasan -S | FileCheck %s --check-prefix=NOPERS +; RUN: opt < %s -mtriple aarch64-linux-android30 -passes=hwasan -S | FileCheck %s --check-prefix=PERS + +; NOPERS: define void @nostack() #{{[0-9]+}} { +; PERS: define void @nostack() #{{[0-9]+}} { +define void @nostack() sanitize_hwaddress "branch-target-enforcement" { + ret void +} + +; NOPERS: define void @stack1() #{{[0-9]+}} { +; PERS: personality {{.*}} @__hwasan_personality_thunk +define void @stack1() sanitize_hwaddress "branch-target-enforcement" { + %p = alloca i8 + call void @sink(ptr %p) + ret void +} + + +; NOPERS: personality ptr @global +; PERS: personality {{.*}} @__hwasan_personality_thunk.global +define void @stack2() sanitize_hwaddress "branch-target-enforcement" personality ptr @global { + %p = alloca i8 + call void @sink(ptr %p) + ret void +} + +define internal void @local() { + ret void +} + +@local_alias = internal alias void (), ptr @local + +; NOPERS: personality ptr @local +; PERS: personality {{.*}} @__hwasan_personality_thunk.local +define void @stack3() sanitize_hwaddress "branch-target-enforcement" personality ptr @local { + %p = alloca i8 + call void @sink(ptr %p) + ret void +} + +; NOPERS: personality ptr @local_alias +; PERS: personality {{.*}} @__hwasan_personality_thunk.local_alias +define void @stack4() sanitize_hwaddress "branch-target-enforcement" personality ptr @local_alias { + %p = alloca i8 + call void @sink(ptr %p) + ret void +} + +; NOPERS: personality ptr inttoptr (i64 1 to ptr) +; PERS: personality ptr @__hwasan_personality_thunk. +define void @stack5() sanitize_hwaddress "branch-target-enforcement" personality ptr inttoptr (i64 1 to ptr) { + %p = alloca i8 + call void @sink(ptr %p) + ret void +} + +; NOPERS: personality ptr inttoptr (i64 2 to ptr) +; PERS: personality ptr @__hwasan_personality_thunk..1 +define void @stack6() sanitize_hwaddress "branch-target-enforcement" personality ptr inttoptr (i64 2 to ptr) { + %p = alloca i8 + call void @sink(ptr %p) + ret void +} + +declare void @global() +declare void @sink(ptr) + +!llvm.module.flags = !{!0} +!0 = !{i32 8, !"branch-target-enforcement", i32 1} + +; PERS: define linkonce_odr hidden i32 @__hwasan_personality_thunk(i32 %0, i32 %1, i64 %2, ptr %3, ptr %4) [[ATTRS:#[0-9]+]] comdat +; PERS: %5 = tail call i32 @__hwasan_personality_wrapper(i32 %0, i32 %1, i64 %2, ptr %3, ptr %4, ptr null, ptr @_Unwind_GetGR, ptr @_Unwind_GetCFA) +; PERS: ret i32 %5 + +; PERS: define linkonce_odr hidden i32 @__hwasan_personality_thunk.global(i32 %0, i32 %1, i64 %2, ptr %3, ptr %4) {{.*}}[[ATTRS]] comdat +; PERS: %5 = tail call i32 @__hwasan_personality_wrapper(i32 %0, i32 %1, i64 %2, ptr %3, ptr %4, ptr @global, ptr @_Unwind_GetGR, ptr @_Unwind_GetCFA) +; PERS: ret i32 %5 + +; PERS: define internal i32 @__hwasan_personality_thunk.local(i32 %0, i32 %1, i64 %2, ptr %3, ptr %4) {{.*}}[[ATTRS]] +; PERS: %5 = tail call i32 @__hwasan_personality_wrapper(i32 %0, i32 %1, i64 %2, ptr %3, ptr %4, ptr @local, ptr @_Unwind_GetGR, ptr @_Unwind_GetCFA) +; PERS: ret i32 %5 + +; PERS: define internal i32 @__hwasan_personality_thunk.local_alias(i32 %0, i32 %1, i64 %2, ptr %3, ptr %4) {{.*}}[[ATTRS]] +; PERS: %5 = tail call i32 @__hwasan_personality_wrapper(i32 %0, i32 %1, i64 %2, ptr %3, ptr %4, ptr @local_alias, ptr @_Unwind_GetGR, ptr @_Unwind_GetCFA) +; PERS: ret i32 %5 + +; PERS: define internal i32 @__hwasan_personality_thunk.(i32 %0, i32 %1, i64 %2, ptr %3, ptr %4) {{.*}}[[ATTRS]] { +; PERS: %5 = tail call i32 @__hwasan_personality_wrapper(i32 %0, i32 %1, i64 %2, ptr %3, ptr %4, ptr inttoptr (i64 1 to ptr), ptr @_Unwind_GetGR, ptr @_Unwind_GetCFA) +; PERS: ret i32 %5 + +; PERS: define internal i32 @__hwasan_personality_thunk..1(i32 %0, i32 %1, i64 %2, ptr %3, ptr %4) {{.*}}[[ATTRS]] { +; PERS: %5 = tail call i32 @__hwasan_personality_wrapper(i32 %0, i32 %1, i64 %2, ptr %3, ptr %4, ptr inttoptr (i64 2 to ptr), ptr @_Unwind_GetGR, ptr @_Unwind_GetCFA) +; PERS: ret i32 %5 + +; PERS: {{.*}}[[ATTRS]] = {{.*}}branch-target-enforcement