Skip to content

Commit

Permalink
[SanitizerBinaryMetadata] Fix multi-version sanitizer metadata (#97848)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
melver authored Jul 8, 2024
1 parent 3851186 commit f5b9e11
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 61 deletions.
6 changes: 3 additions & 3 deletions clang/test/CodeGen/sanitize-metadata-ignorelist.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
22 changes: 11 additions & 11 deletions clang/test/CodeGen/sanitize-metadata-nosanitize.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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}
//.
28 changes: 14 additions & 14 deletions clang/test/CodeGen/sanitize-metadata.c
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -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"}
32 changes: 22 additions & 10 deletions llvm/lib/Transforms/Instrumentation/SanitizerBinaryMetadata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -130,7 +131,7 @@ class SanitizerBinaryMetadata {
std::unique_ptr<SpecialCaseList> 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()) &&
Expand Down Expand Up @@ -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);
Expand All @@ -179,6 +180,7 @@ class SanitizerBinaryMetadata {
const SanitizerBinaryMetadataOptions Options;
std::unique_ptr<SpecialCaseList> Ignorelist;
const Triple TargetTriple;
const std::string VersionStr;
IRBuilder<> IRB;
BumpPtrAllocator Alloc;
UniqueStringSaver StringPool{Alloc};
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
28 changes: 14 additions & 14 deletions llvm/test/Instrumentation/SanitizerBinaryMetadata/atomics.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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"}
18 changes: 9 additions & 9 deletions llvm/test/Instrumentation/SanitizerBinaryMetadata/ctor.ll
Original file line number Diff line number Diff line change
@@ -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"
Expand Down

0 comments on commit f5b9e11

Please sign in to comment.