From f5b9e11eb8ada0e7cc292f9ecd29a220d1265084 Mon Sep 17 00:00:00 2001 From: Marco Elver Date: Mon, 8 Jul 2024 17:07:00 +0200 Subject: [PATCH] [SanitizerBinaryMetadata] Fix multi-version sanitizer metadata (#97848) It should be valid to combine TUs that have different versions of sanitizer metadata. However, this had not been possible due to giving sanitizer metadata sections, constructors, and destructors (that call callbacks) the same name for different versions. This would then result in the linker attempting to merge sections that contain metadata of different versions, as well as picking any one of the constructors or destructors due to having the same COMDAT key. The end result is that consumers of this data would end up interpreting the metadata incorrectly. Although combining old and new versions is not recommended, more realistic is combining TUs that have been compiled with different target code models (which are also encoded in the sanitizer metadata version). To fix, and properly support multi-version sanitizer metadata, attach the version to section names and internal constructor and destructor names. The ABI remains unchanged. --- .../CodeGen/sanitize-metadata-ignorelist.c | 6 ++-- .../CodeGen/sanitize-metadata-nosanitize.c | 22 ++++++------- clang/test/CodeGen/sanitize-metadata.c | 28 ++++++++-------- .../SanitizerBinaryMetadata.cpp | 32 +++++++++++++------ .../SanitizerBinaryMetadata/atomics.ll | 28 ++++++++-------- .../SanitizerBinaryMetadata/ctor.ll | 18 +++++------ 6 files changed, 73 insertions(+), 61 deletions(-) diff --git a/clang/test/CodeGen/sanitize-metadata-ignorelist.c b/clang/test/CodeGen/sanitize-metadata-ignorelist.c index 24fb4fa62cc537..4dc8c0c35fefee 100644 --- a/clang/test/CodeGen/sanitize-metadata-ignorelist.c +++ b/clang/test/CodeGen/sanitize-metadata-ignorelist.c @@ -50,6 +50,6 @@ void bar() { __atomic_fetch_add(&y, 2, __ATOMIC_RELAXED); } -// ALLOW: __sanitizer_metadata_covered.module_ctor -// FUN: __sanitizer_metadata_covered.module_ctor -// SRC-NOT: __sanitizer_metadata_covered.module_ctor +// ALLOW: __sanitizer_metadata_covered2.module_ctor +// FUN: __sanitizer_metadata_covered2.module_ctor +// SRC-NOT: __sanitizer_metadata_covered{{.*}}.module_ctor diff --git a/clang/test/CodeGen/sanitize-metadata-nosanitize.c b/clang/test/CodeGen/sanitize-metadata-nosanitize.c index 6414956fb67967..388a3df547a734 100644 --- a/clang/test/CodeGen/sanitize-metadata-nosanitize.c +++ b/clang/test/CodeGen/sanitize-metadata-nosanitize.c @@ -2,13 +2,13 @@ // RUN: %clang_cc1 -O -fexperimental-sanitize-metadata=covered -fexperimental-sanitize-metadata=atomics -fexperimental-sanitize-metadata=uar -triple x86_64-gnu-linux -x c -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK //. -// CHECK: @__start_sanmd_covered = extern_weak hidden global ptr -// CHECK: @__stop_sanmd_covered = extern_weak hidden global ptr -// CHECK: @__start_sanmd_atomics = extern_weak hidden global ptr -// CHECK: @__stop_sanmd_atomics = extern_weak hidden global ptr -// CHECK: @llvm.used = appending global [4 x ptr] [ptr @__sanitizer_metadata_covered.module_ctor, ptr @__sanitizer_metadata_covered.module_dtor, ptr @__sanitizer_metadata_atomics.module_ctor, ptr @__sanitizer_metadata_atomics.module_dtor], section "llvm.metadata" -// CHECK: @llvm.global_ctors = appending global [2 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 2, ptr @__sanitizer_metadata_covered.module_ctor, ptr @__sanitizer_metadata_covered.module_ctor }, { i32, ptr, ptr } { i32 2, ptr @__sanitizer_metadata_atomics.module_ctor, ptr @__sanitizer_metadata_atomics.module_ctor }] -// CHECK: @llvm.global_dtors = appending global [2 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 2, ptr @__sanitizer_metadata_covered.module_dtor, ptr @__sanitizer_metadata_covered.module_dtor }, { i32, ptr, ptr } { i32 2, ptr @__sanitizer_metadata_atomics.module_dtor, ptr @__sanitizer_metadata_atomics.module_dtor }] +// CHECK: @__start_sanmd_covered2 = extern_weak hidden global ptr +// CHECK: @__stop_sanmd_covered2 = extern_weak hidden global ptr +// CHECK: @__start_sanmd_atomics2 = extern_weak hidden global ptr +// CHECK: @__stop_sanmd_atomics2 = extern_weak hidden global ptr +// CHECK: @llvm.used = appending global [4 x ptr] [ptr @__sanitizer_metadata_covered2.module_ctor, ptr @__sanitizer_metadata_covered2.module_dtor, ptr @__sanitizer_metadata_atomics2.module_ctor, ptr @__sanitizer_metadata_atomics2.module_dtor], section "llvm.metadata" +// CHECK: @llvm.global_ctors = appending global [2 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 2, ptr @__sanitizer_metadata_covered2.module_ctor, ptr @__sanitizer_metadata_covered2.module_ctor }, { i32, ptr, ptr } { i32 2, ptr @__sanitizer_metadata_atomics2.module_ctor, ptr @__sanitizer_metadata_atomics2.module_ctor }] +// CHECK: @llvm.global_dtors = appending global [2 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 2, ptr @__sanitizer_metadata_covered2.module_dtor, ptr @__sanitizer_metadata_covered2.module_dtor }, { i32, ptr, ptr } { i32 2, ptr @__sanitizer_metadata_atomics2.module_dtor, ptr @__sanitizer_metadata_atomics2.module_dtor }] //. // CHECK: Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none) // CHECK-LABEL: define dso_local void @escape @@ -95,17 +95,17 @@ __attribute__((no_sanitize("all"))) int test_no_sanitize_all(int *x, int *y) { // CHECK: attributes #3 = { mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "no_sanitize_thread" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" } // CHECK: attributes #4 = { nounwind "target-features"="+cx8,+mmx,+sse,+sse2,+x87" } //. -// CHECK: !2 = !{!"sanmd_covered!C", !3} +// CHECK: !2 = !{!"sanmd_covered2!C", !3} // CHECK: !3 = !{i64 0} -// CHECK: !4 = !{!"sanmd_covered!C", !5} +// CHECK: !4 = !{!"sanmd_covered2!C", !5} // CHECK: !5 = !{i64 3} // CHECK: !6 = !{!7, !7, i64 0} // CHECK: !7 = !{!"any pointer", !8, i64 0} // CHECK: !8 = !{!"omnipotent char", !9, i64 0} // CHECK: !9 = !{!"Simple C/C++ TBAA"} -// CHECK: !10 = !{!"sanmd_atomics!C"} +// CHECK: !10 = !{!"sanmd_atomics2!C"} // CHECK: !11 = !{!12, !12, i64 0} // CHECK: !12 = !{!"int", !8, i64 0} -// CHECK: !13 = !{!"sanmd_covered!C", !14} +// CHECK: !13 = !{!"sanmd_covered2!C", !14} // CHECK: !14 = !{i64 2} //. diff --git a/clang/test/CodeGen/sanitize-metadata.c b/clang/test/CodeGen/sanitize-metadata.c index 7e1de0c208845f..55cbc0a19108d2 100644 --- a/clang/test/CodeGen/sanitize-metadata.c +++ b/clang/test/CodeGen/sanitize-metadata.c @@ -1,10 +1,10 @@ // RUN: %clang_cc1 -O -fexperimental-sanitize-metadata=atomics -triple x86_64-gnu-linux -x c -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,ATOMICS // RUN: %clang_cc1 -O -fexperimental-sanitize-metadata=atomics -triple aarch64-gnu-linux -x c -emit-llvm %s -o - | FileCheck %s --check-prefixes=CHECK,ATOMICS -// CHECK: @__start_sanmd_atomics = extern_weak hidden global ptr -// CHECK: @__stop_sanmd_atomics = extern_weak hidden global ptr -// CHECK: @__start_sanmd_covered = extern_weak hidden global ptr -// CHECK: @__stop_sanmd_covered = extern_weak hidden global ptr +// CHECK: @__start_sanmd_atomics2 = extern_weak hidden global ptr +// CHECK: @__stop_sanmd_atomics2 = extern_weak hidden global ptr +// CHECK: @__start_sanmd_covered2 = extern_weak hidden global ptr +// CHECK: @__stop_sanmd_covered2 = extern_weak hidden global ptr int x, y; @@ -21,16 +21,16 @@ int atomics() { __atomic_fetch_add(&x, 1, __ATOMIC_RELAXED); return y; } -// ATOMICS-LABEL: __sanitizer_metadata_atomics.module_ctor -// ATOMICS: call void @__sanitizer_metadata_atomics_add(i32 2, ptr @__start_sanmd_atomics, ptr @__stop_sanmd_atomics) -// ATOMICS-LABEL: __sanitizer_metadata_atomics.module_dtor -// ATOMICS: call void @__sanitizer_metadata_atomics_del(i32 2, ptr @__start_sanmd_atomics, ptr @__stop_sanmd_atomics) +// ATOMICS-LABEL: __sanitizer_metadata_atomics2.module_ctor +// ATOMICS: call void @__sanitizer_metadata_atomics_add(i32 2, ptr @__start_sanmd_atomics2, ptr @__stop_sanmd_atomics2) +// ATOMICS-LABEL: __sanitizer_metadata_atomics2.module_dtor +// ATOMICS: call void @__sanitizer_metadata_atomics_del(i32 2, ptr @__start_sanmd_atomics2, ptr @__stop_sanmd_atomics2) -// CHECK-LABEL: __sanitizer_metadata_covered.module_ctor -// CHECK: call void @__sanitizer_metadata_covered_add(i32 2, ptr @__start_sanmd_covered, ptr @__stop_sanmd_covered) -// CHECK-LABEL: __sanitizer_metadata_covered.module_dtor -// CHECK: call void @__sanitizer_metadata_covered_del(i32 2, ptr @__start_sanmd_covered, ptr @__stop_sanmd_covered) +// CHECK-LABEL: __sanitizer_metadata_covered2.module_ctor +// CHECK: call void @__sanitizer_metadata_covered_add(i32 2, ptr @__start_sanmd_covered2, ptr @__stop_sanmd_covered2) +// CHECK-LABEL: __sanitizer_metadata_covered2.module_dtor +// CHECK: call void @__sanitizer_metadata_covered_del(i32 2, ptr @__start_sanmd_covered2, ptr @__stop_sanmd_covered2) -// ATOMICS: ![[ATOMICS_COVERED]] = !{!"sanmd_covered!C", ![[ATOMICS_COVERED_AUX:[0-9]+]]} +// ATOMICS: ![[ATOMICS_COVERED]] = !{!"sanmd_covered2!C", ![[ATOMICS_COVERED_AUX:[0-9]+]]} // ATOMICS: ![[ATOMICS_COVERED_AUX]] = !{i64 1} -// ATOMICS: ![[ATOMIC_OP]] = !{!"sanmd_atomics!C"} +// ATOMICS: ![[ATOMIC_OP]] = !{!"sanmd_atomics2!C"} diff --git a/llvm/lib/Transforms/Instrumentation/SanitizerBinaryMetadata.cpp b/llvm/lib/Transforms/Instrumentation/SanitizerBinaryMetadata.cpp index 230bb8b0a5dce2..e326f30ad88eeb 100644 --- a/llvm/lib/Transforms/Instrumentation/SanitizerBinaryMetadata.cpp +++ b/llvm/lib/Transforms/Instrumentation/SanitizerBinaryMetadata.cpp @@ -14,6 +14,7 @@ #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" #include "llvm/Analysis/CaptureTracking.h" @@ -130,7 +131,7 @@ class SanitizerBinaryMetadata { std::unique_ptr Ignorelist) : Mod(M), Options(transformOptionsFromCl(std::move(Opts))), Ignorelist(std::move(Ignorelist)), TargetTriple(M.getTargetTriple()), - IRB(M.getContext()) { + VersionStr(utostr(getVersion())), IRB(M.getContext()) { // FIXME: Make it work with other formats. assert(TargetTriple.isOSBinFormatELF() && "ELF only"); assert(!(TargetTriple.isNVPTX() || TargetTriple.isAMDGPU()) && @@ -167,10 +168,10 @@ class SanitizerBinaryMetadata { StringRef getSectionName(StringRef SectionSuffix); // Returns the section start marker name. - Twine getSectionStart(StringRef SectionSuffix); + StringRef getSectionStart(StringRef SectionSuffix); // Returns the section end marker name. - Twine getSectionEnd(StringRef SectionSuffix); + StringRef getSectionEnd(StringRef SectionSuffix); // Returns true if the access to the address should be considered "atomic". bool pretendAtomicAccess(const Value *Addr); @@ -179,6 +180,7 @@ class SanitizerBinaryMetadata { const SanitizerBinaryMetadataOptions Options; std::unique_ptr Ignorelist; const Triple TargetTriple; + const std::string VersionStr; IRBuilder<> IRB; BumpPtrAllocator Alloc; UniqueStringSaver StringPool{Alloc}; @@ -209,19 +211,25 @@ bool SanitizerBinaryMetadata::run() { getSectionMarker(getSectionStart(MI->SectionSuffix), PtrTy), getSectionMarker(getSectionEnd(MI->SectionSuffix), PtrTy), }; + + // Calls to the initialization functions with different versions cannot be + // merged. Give the structors unique names based on the version, which will + // also be used as the COMDAT key. + const std::string StructorPrefix = (MI->FunctionPrefix + VersionStr).str(); + // We declare the _add and _del functions as weak, and only call them if // there is a valid symbol linked. This allows building binaries with // semantic metadata, but without having callbacks. When a tool that wants // the metadata is linked which provides the callbacks, they will be called. Function *Ctor = createSanitizerCtorAndInitFunctions( - Mod, (MI->FunctionPrefix + ".module_ctor").str(), + Mod, StructorPrefix + ".module_ctor", (MI->FunctionPrefix + "_add").str(), InitTypes, InitArgs, /*VersionCheckName=*/StringRef(), /*Weak=*/ClWeakCallbacks) .first; Function *Dtor = createSanitizerCtorAndInitFunctions( - Mod, (MI->FunctionPrefix + ".module_dtor").str(), + Mod, StructorPrefix + ".module_dtor", (MI->FunctionPrefix + "_del").str(), InitTypes, InitArgs, /*VersionCheckName=*/StringRef(), /*Weak=*/ClWeakCallbacks) .first; @@ -454,15 +462,19 @@ SanitizerBinaryMetadata::getSectionMarker(const Twine &MarkerName, Type *Ty) { StringRef SanitizerBinaryMetadata::getSectionName(StringRef SectionSuffix) { // FIXME: Other TargetTriples. // Request ULEB128 encoding for all integer constants. - return StringPool.save(SectionSuffix + "!C"); + return StringPool.save(SectionSuffix + VersionStr + "!C"); } -Twine SanitizerBinaryMetadata::getSectionStart(StringRef SectionSuffix) { - return "__start_" + SectionSuffix; +StringRef SanitizerBinaryMetadata::getSectionStart(StringRef SectionSuffix) { + // Twine only concatenates 2 strings; with >2 strings, concatenating them + // creates Twine temporaries, and returning the final Twine no longer works + // because we'd end up with a stack-use-after-return. So here we also use the + // StringPool to store the new string. + return StringPool.save("__start_" + SectionSuffix + VersionStr); } -Twine SanitizerBinaryMetadata::getSectionEnd(StringRef SectionSuffix) { - return "__stop_" + SectionSuffix; +StringRef SanitizerBinaryMetadata::getSectionEnd(StringRef SectionSuffix) { + return StringPool.save("__stop_" + SectionSuffix + VersionStr); } } // namespace diff --git a/llvm/test/Instrumentation/SanitizerBinaryMetadata/atomics.ll b/llvm/test/Instrumentation/SanitizerBinaryMetadata/atomics.ll index 82b65fe33cd600..320361ed3c0925 100644 --- a/llvm/test/Instrumentation/SanitizerBinaryMetadata/atomics.ll +++ b/llvm/test/Instrumentation/SanitizerBinaryMetadata/atomics.ll @@ -2,10 +2,10 @@ ; Check that atomic memory operations receive PC sections metadata. -; CHECK: @__start_sanmd_atomics = extern_weak hidden global ptr -; CHECK: @__stop_sanmd_atomics = extern_weak hidden global ptr -; CHECK: @__start_sanmd_covered = extern_weak hidden global ptr -; CHECK: @__stop_sanmd_covered = extern_weak hidden global ptr +; CHECK: @__start_sanmd_atomics2 = extern_weak hidden global ptr +; CHECK: @__stop_sanmd_atomics2 = extern_weak hidden global ptr +; CHECK: @__start_sanmd_covered2 = extern_weak hidden global ptr +; CHECK: @__stop_sanmd_covered2 = extern_weak hidden global ptr 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-S128" @@ -2035,46 +2035,46 @@ entry: ; Check that callbacks are emitted. -; CHECK-LABEL: __sanitizer_metadata_atomics.module_ctor +; CHECK-LABEL: __sanitizer_metadata_atomics2.module_ctor ; CHECK-DAG: entry: ; CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr @__sanitizer_metadata_atomics_add, null ; CHECK-NEXT: br i1 [[CMP]], label %callfunc, label %ret ; CHECK-DAG: callfunc: -; CHECK-NEXT: call void @__sanitizer_metadata_atomics_add(i32 2, ptr @__start_sanmd_atomics, ptr @__stop_sanmd_atomics) +; CHECK-NEXT: call void @__sanitizer_metadata_atomics_add(i32 2, ptr @__start_sanmd_atomics2, ptr @__stop_sanmd_atomics2) ; CHECK-NEXT: br label %ret ; CHECK-DAG: ret: ; CHECK-NEXT: ret void -; CHECK-LABEL: __sanitizer_metadata_atomics.module_dtor +; CHECK-LABEL: __sanitizer_metadata_atomics2.module_dtor ; CHECK-DAG: entry: ; CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr @__sanitizer_metadata_atomics_del, null ; CHECK-NEXT: br i1 [[CMP]], label %callfunc, label %ret ; CHECK-DAG: callfunc: -; CHECK-NEXT: call void @__sanitizer_metadata_atomics_del(i32 2, ptr @__start_sanmd_atomics, ptr @__stop_sanmd_atomics) +; CHECK-NEXT: call void @__sanitizer_metadata_atomics_del(i32 2, ptr @__start_sanmd_atomics2, ptr @__stop_sanmd_atomics2) ; CHECK-NEXT: br label %ret ; CHECK-DAG: ret: ; CHECK-NEXT: ret void -; CHECK-LABEL: __sanitizer_metadata_covered.module_ctor +; CHECK-LABEL: __sanitizer_metadata_covered2.module_ctor ; CHECK-DAG: entry: ; CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr @__sanitizer_metadata_covered_add, null ; CHECK-NEXT: br i1 [[CMP]], label %callfunc, label %ret ; CHECK-DAG: callfunc: -; CHECK-NEXT: call void @__sanitizer_metadata_covered_add(i32 2, ptr @__start_sanmd_covered, ptr @__stop_sanmd_covered) +; CHECK-NEXT: call void @__sanitizer_metadata_covered_add(i32 2, ptr @__start_sanmd_covered2, ptr @__stop_sanmd_covered2) ; CHECK-NEXT: br label %ret ; CHECK-DAG: ret: ; CHECK-NEXT: ret void -; CHECK-LABEL: __sanitizer_metadata_covered.module_dtor +; CHECK-LABEL: __sanitizer_metadata_covered2.module_dtor ; CHECK-DAG: entry: ; CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr @__sanitizer_metadata_covered_del, null ; CHECK-NEXT: br i1 [[CMP]], label %callfunc, label %ret ; CHECK-DAG: callfunc: -; CHECK-NEXT: call void @__sanitizer_metadata_covered_del(i32 2, ptr @__start_sanmd_covered, ptr @__stop_sanmd_covered) +; CHECK-NEXT: call void @__sanitizer_metadata_covered_del(i32 2, ptr @__start_sanmd_covered2, ptr @__stop_sanmd_covered2) ; CHECK-NEXT: br label %ret ; CHECK-DAG: ret: ; CHECK-NEXT: ret void -; CHECK: !0 = !{!"sanmd_covered!C", !1} +; CHECK: !0 = !{!"sanmd_covered2!C", !1} ; CHECK: !1 = !{i64 1} -; CHECK: !2 = !{!"sanmd_atomics!C"} +; CHECK: !2 = !{!"sanmd_atomics2!C"} diff --git a/llvm/test/Instrumentation/SanitizerBinaryMetadata/ctor.ll b/llvm/test/Instrumentation/SanitizerBinaryMetadata/ctor.ll index 55f92ea3026ec4..bccc90e9478584 100644 --- a/llvm/test/Instrumentation/SanitizerBinaryMetadata/ctor.ll +++ b/llvm/test/Instrumentation/SanitizerBinaryMetadata/ctor.ll @@ -1,16 +1,16 @@ ; RUN: opt < %s -passes='module(sanmd-module)' -sanitizer-metadata-atomics -S | FileCheck %s -; CHECK: $__sanitizer_metadata_atomics.module_ctor = comdat any -; CHECK: $__sanitizer_metadata_atomics.module_dtor = comdat any -; CHECK: $__sanitizer_metadata_covered.module_ctor = comdat any -; CHECK: $__sanitizer_metadata_covered.module_dtor = comdat any +; CHECK: $__sanitizer_metadata_atomics2.module_ctor = comdat any +; CHECK: $__sanitizer_metadata_atomics2.module_dtor = comdat any +; CHECK: $__sanitizer_metadata_covered2.module_ctor = comdat any +; CHECK: $__sanitizer_metadata_covered2.module_dtor = comdat any -; CHECK: @llvm.used = appending global [4 x ptr] [ptr @__sanitizer_metadata_atomics.module_ctor, ptr @__sanitizer_metadata_atomics.module_dtor, ptr @__sanitizer_metadata_covered.module_ctor, ptr @__sanitizer_metadata_covered.module_dtor], section "llvm.metadata" -; CHECK: @llvm.global_ctors = appending global [2 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 2, ptr @__sanitizer_metadata_atomics.module_ctor, ptr @__sanitizer_metadata_atomics.module_ctor }, { i32, ptr, ptr } { i32 2, ptr @__sanitizer_metadata_covered.module_ctor, ptr @__sanitizer_metadata_covered.module_ctor }] -; CHECK: @llvm.global_dtors = appending global [2 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 2, ptr @__sanitizer_metadata_atomics.module_dtor, ptr @__sanitizer_metadata_atomics.module_dtor }, { i32, ptr, ptr } { i32 2, ptr @__sanitizer_metadata_covered.module_dtor, ptr @__sanitizer_metadata_covered.module_dtor }] +; CHECK: @llvm.used = appending global [4 x ptr] [ptr @__sanitizer_metadata_atomics2.module_ctor, ptr @__sanitizer_metadata_atomics2.module_dtor, ptr @__sanitizer_metadata_covered2.module_ctor, ptr @__sanitizer_metadata_covered2.module_dtor], section "llvm.metadata" +; CHECK: @llvm.global_ctors = appending global [2 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 2, ptr @__sanitizer_metadata_atomics2.module_ctor, ptr @__sanitizer_metadata_atomics2.module_ctor }, { i32, ptr, ptr } { i32 2, ptr @__sanitizer_metadata_covered2.module_ctor, ptr @__sanitizer_metadata_covered2.module_ctor }] +; CHECK: @llvm.global_dtors = appending global [2 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 2, ptr @__sanitizer_metadata_atomics2.module_dtor, ptr @__sanitizer_metadata_atomics2.module_dtor }, { i32, ptr, ptr } { i32 2, ptr @__sanitizer_metadata_covered2.module_dtor, ptr @__sanitizer_metadata_covered2.module_dtor }] -; CHECK: define hidden void @__sanitizer_metadata_covered.module_ctor() #1 comdat { -; CHECK: define hidden void @__sanitizer_metadata_covered.module_dtor() #1 comdat { +; CHECK: define hidden void @__sanitizer_metadata_covered2.module_ctor() #1 comdat { +; CHECK: define hidden void @__sanitizer_metadata_covered2.module_dtor() #1 comdat { target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu"