if (CodeGenOpts.NoPLT)
getModule().setRtLibUseGOT();
+ if (CodeGenOpts.UnwindTables)
+ getModule().setUwtable();
SimplifyPersonality();
// ASAN: @__special_global{{.*}} global { i32, [60 x i8] }{{.*}}, align 32
// KASAN: @__special_global{{.*}} global i32
-// CHECK-LABEL: define internal void @asan.module_ctor
+/// Without -fasynchronous-unwind-tables, ctor and dtor get the uwtable attribute.
+// CHECK-LABEL: define internal void @asan.module_ctor() #[[#ATTR:]] {
// ASAN-NEXT: call void @__asan_init
// ASAN-NEXT: call void @__asan_version_mismatch_check
// KASAN-NOT: call void @__asan_init
// KASAN-NEXT: call void @__asan_register_globals({{.*}}, i{{32|64}} 5)
// CHECK-NEXT: ret void
-// CHECK-LABEL: define internal void @asan.module_dtor
+// CHECK: define internal void @asan.module_dtor() #[[#ATTR]] {
// CHECK-NEXT: call void @__asan_unregister_globals
// CHECK-NEXT: ret void
+// CHECK: attributes #[[#ATTR]] = { nounwind }
+
+/// If -fasynchronous-unwind-tables, set the module flag "uwtable". ctor/dtor
+/// will thus get the uwtable attribute.
+// RUN: %clang_cc1 -emit-llvm -fsanitize=address -munwind-tables -o - %s | FileCheck %s --check-prefixes=UWTABLE
+// UWTABLE: define internal void @asan.module_dtor() #[[#ATTR:]] {
+// UWTABLE: attributes #[[#ATTR]] = { nounwind uwtable }
+// UWTABLE: ![[#]] = !{i32 7, !"uwtable", i32 1}
+
// CHECK: !llvm.asan.globals = !{![[EXTRA_GLOBAL:[0-9]+]], ![[GLOBAL:[0-9]+]], ![[DYN_INIT_GLOBAL:[0-9]+]], ![[ATTR_GLOBAL:[0-9]+]], ![[BLACKLISTED_GLOBAL:[0-9]+]], ![[SECTIONED_GLOBAL:[0-9]+]], ![[SPECIAL_GLOBAL:[0-9]+]], ![[STATIC_VAR:[0-9]+]], ![[LITERAL:[0-9]+]]}
// CHECK: ![[EXTRA_GLOBAL]] = !{{{.*}} ![[EXTRA_GLOBAL_LOC:[0-9]+]], !"extra_global", i1 false, i1 false}
// CHECK: ![[EXTRA_GLOBAL_LOC]] = !{!"{{.*}}extra-source.cpp", i32 1, i32 5}
; CHECK: __asan_init
-; CHECK-DAG: define internal void @asan.module_ctor() {
+; CHECK-DAG: define internal void @asan.module_ctor() #[[#]] {
; CHECK: {{.*}} call void @__asan_init()
; CHECK: {{.*}} call void @__asan_version_mismatch_check_v8()
; CHECK: ret void
// RUN: %clang_cc1 -fsanitize=address -fsanitize-address-globals-dead-stripping -fno-integrated-as -emit-llvm -o - -triple x86_64-linux %s | FileCheck %s --check-prefix=WITHOUT-GC
// RUN: %clang_cc1 -fsanitize=address -fdata-sections -emit-llvm -o - -triple x86_64-linux %s | FileCheck %s --check-prefix=WITHOUT-GC
-// WITH-GC: define internal void @asan.module_ctor() comdat {
-// WITHOUT-GC: define internal void @asan.module_ctor() {
+// WITH-GC: define internal void @asan.module_ctor() #[[#]] comdat {
+// WITHOUT-GC: define internal void @asan.module_ctor() #[[#]] {
static Function *Create(FunctionType *Ty, LinkageTypes Linkage,
const Twine &N, Module &M);
+ static Function *createWithDefaultAttr(FunctionType *Ty, LinkageTypes Linkage,
+ unsigned AddrSpace,
+ const Twine &N = "",
+ Module *M = nullptr);
+
// Provide fast operand accessors.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
/// Set that PLT should be avoid for RTLib calls.
void setRtLibUseGOT();
+ /// Get/set whether synthesized functions should get the uwtable attribute.
+ bool getUwtable() const;
+ void setUwtable();
+
/// @name Utility functions for querying and setting the build SDK version
/// @{
return Create(Ty, Linkage, M.getDataLayout().getProgramAddressSpace(), N, &M);
}
+Function *Function::createWithDefaultAttr(FunctionType *Ty,
+ LinkageTypes Linkage,
+ unsigned AddrSpace, const Twine &N,
+ Module *M) {
+ auto *F = new Function(Ty, Linkage, AddrSpace, N, M);
+ if (M->getUwtable())
+ F->addAttribute(AttributeList::FunctionIndex, Attribute::UWTable);
+ return F;
+}
+
void Function::removeFromParent() {
getParent()->getFunctionList().remove(getIterator());
}
addModuleFlag(ModFlagBehavior::Max, "RtLibUseGOT", 1);
}
+bool Module::getUwtable() const {
+ auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("uwtable"));
+ return Val && (cast<ConstantInt>(Val->getValue())->getZExtValue() > 0);
+}
+
+void Module::setUwtable() { addModuleFlag(ModFlagBehavior::Max, "uwtable", 1); }
+
void Module::setSDKVersion(const VersionTuple &V) {
SmallVector<unsigned, 3> Entries;
Entries.push_back(V.getMajor());
}
Instruction *ModuleAddressSanitizer::CreateAsanModuleDtor(Module &M) {
- AsanDtorFunction =
- Function::Create(FunctionType::get(Type::getVoidTy(*C), false),
- GlobalValue::InternalLinkage, kAsanModuleDtorName, &M);
+ AsanDtorFunction = Function::createWithDefaultAttr(
+ FunctionType::get(Type::getVoidTy(*C), false),
+ GlobalValue::InternalLinkage, 0, kAsanModuleDtorName, &M);
+ AsanDtorFunction->addAttribute(AttributeList::FunctionIndex,
+ Attribute::NoUnwind);
BasicBlock *AsanDtorBB = BasicBlock::Create(*C, "", AsanDtorFunction);
return ReturnInst::Create(*C, AsanDtorBB);
}
Function *llvm::createSanitizerCtor(Module &M, StringRef CtorName) {
- Function *Ctor = Function::Create(
+ Function *Ctor = Function::createWithDefaultAttr(
FunctionType::get(Type::getVoidTy(M.getContext()), false),
- GlobalValue::InternalLinkage, CtorName, &M);
+ GlobalValue::InternalLinkage, 0, CtorName, &M);
+ Ctor->addAttribute(AttributeList::FunctionIndex, Attribute::NoUnwind);
BasicBlock *CtorBB = BasicBlock::Create(M.getContext(), "", Ctor);
ReturnInst::Create(M.getContext(), CtorBB);
return Ctor;
ret void
}
-; CHECK: define internal void @asan.module_ctor()
+;; ctor/dtor have the nounwind attribute. See uwtable.ll, they additionally have
+;; the uwtable attribute with the module flag "uwtable".
+; CHECK: define internal void @asan.module_ctor() #[[#ATTR:]] {{(comdat )?}}{
; CHECK: call void @__asan_init()
+; CHECK: attributes #[[#ATTR]] = { nounwind }
+
; PROF
; CHECK: ![[PROF]] = !{!"branch_weights", i32 1, i32 100000}
; CHECK-NOT: @llvm.global_dtors
; CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 1, void ()* @asan.module_ctor, i8* bitcast (void ()* @asan.module_ctor to i8*) }]
; CHECK-NOT: @llvm.global_dtors
-; CHECK: define internal void @asan.module_ctor() comdat
+; CHECK: define internal void @asan.module_ctor() #[[#]] comdat
; CHECK-NOT: @llvm.global_dtors
--- /dev/null
+; RUN: opt < %s -passes='asan-pipeline' -S | FileCheck %s
+
+target triple = "x86_64-unknown-linux-gnu"
+
+@g = dso_local global i32 0, align 4
+
+define i32 @test_load() sanitize_address {
+entry:
+ %tmp = load i32, i32* @g, align 4
+ ret i32 %tmp
+}
+
+!llvm.module.flags = !{!0}
+
+;; Due to -fasynchronous-unwind-tables.
+!0 = !{i32 7, !"uwtable", i32 1}
+
+;; Set the uwtable attribute on ctor/dtor.
+; CHECK: define internal void @asan.module_ctor() #[[#ATTR:]]
+; CHECK: define internal void @asan.module_dtor() #[[#ATTR]]
+; CHECK: attributes #[[#ATTR]] = { nounwind uwtable }
; CHECK: declare void @__hwasan_init()
-; CHECK: define internal void @hwasan.module_ctor() comdat {
+; CHECK: define internal void @hwasan.module_ctor() #[[#ATTR:]] comdat {
; CHECK-NEXT: call void @__hwasan_init()
; CHECK-NEXT: ret void
; CHECK-NEXT: }
+
+; CHECK: attributes #[[#ATTR]] = { nounwind }
; CHECK: declare void @__hwasan_init()
-; CHECK: define internal void @hwasan.module_ctor() comdat {
+; CHECK: define internal void @hwasan.module_ctor() #[[#]] comdat {
; CHECK-NEXT: call void @__hwasan_init()
; CHECK-NEXT: ret void
; CHECK-NEXT: }
; CHECK-NEXT: ret i8*
-; CHECK-LABEL: define internal void @msan.module_ctor() {
+; CHECK-LABEL: define internal void @msan.module_ctor() #[[#ATTR:]] {
; CHECK: call void @__msan_init()
; CHECK-CALLS: declare void @__msan_maybe_warning_1(i8 zeroext, i32 zeroext)
; CHECK-CALLS: declare void @__msan_maybe_store_origin_4(i32 zeroext, i8*, i32 zeroext)
; CHECK-CALLS: declare void @__msan_maybe_warning_8(i64 zeroext, i32 zeroext)
; CHECK-CALLS: declare void @__msan_maybe_store_origin_8(i64 zeroext, i8*, i32 zeroext)
+
+; CHECK: attributes #[[#ATTR]] = { nounwind }
; Module ctors should have stable names across modules, not something like
; @sancov.module_ctor.3 that may cause duplicate ctors after linked together.
-; CHECK: define internal void @sancov.module_ctor_trace_pc_guard() comdat {
-; CHECK: define internal void @sancov.module_ctor_8bit_counters() comdat {
+; CHECK: define internal void @sancov.module_ctor_trace_pc_guard() #[[#]] comdat {
+; CHECK: define internal void @sancov.module_ctor_8bit_counters() #[[#]] comdat {
target 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"
target triple = "x86_64-unknown-linux-gnu"
; Module ctors should have stable names across modules, not something like
; @sancov.module_ctor.3 that may cause duplicate ctors after linked together.
-; CHECK: define internal void @sancov.module_ctor_trace_pc_guard() comdat {
-; CHECK: define internal void @sancov.module_ctor_bool_flag() comdat {
+; CHECK: define internal void @sancov.module_ctor_trace_pc_guard() #[[#]] comdat {
+; CHECK: define internal void @sancov.module_ctor_bool_flag() #[[#]] comdat {
target 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"
target triple = "x86_64-unknown-linux-gnu"
ret void
}
-; ELF-LABEL: define internal void @sancov.module_ctor_trace_pc_guard() comdat {
-; MACHO-LABEL: define internal void @sancov.module_ctor_trace_pc_guard() {
+; ELF-LABEL: define internal void @sancov.module_ctor_trace_pc_guard() #2 comdat {
+; MACHO-LABEL: define internal void @sancov.module_ctor_trace_pc_guard() #2 {
+
+; CHECK: attributes #2 = { nounwind }