For mingw target, if a symbol is not marked DSO local, a `.refptr` is generated for it. This makes CFG check calls use an extra pointer dereference, which adds extra overhead compared to the MSVC version, so mark the CFG guard check funciton pointer DSO local to stop it. This should have no effect on MSVC target. Also adapt the existing cfguard tests to run for mingw targets, so that this change is checked. Reviewed By: rnk Differential Revision: https://reviews.llvm.org/D132331
229 lines
10 KiB
LLVM
229 lines
10 KiB
LLVM
; RUN: llc < %s -mtriple=x86_64-w64-windows-gnu | FileCheck %s
|
|
; Control Flow Guard is currently only available on Windows
|
|
|
|
; This file was generated from the following source, using this command line:
|
|
; clang++ -target x86_64-w64-windows-gnu cfguard-mingw.cpp -S -emit-llvm -o cfguard-mingw.ll -O -Xclang -cfguard
|
|
;
|
|
;-------------------------------------------------------------------------------
|
|
; class __attribute__((dllexport)) Base {
|
|
; public:
|
|
; __attribute__((dllexport)) Base() = default;
|
|
; __attribute__((dllexport)) virtual ~Base() = default;
|
|
; __attribute__((dllexport)) virtual int calc() const {
|
|
; return m_field * 2;
|
|
; }
|
|
; int m_field{0};
|
|
; };
|
|
;
|
|
; class __attribute__((dllexport)) Derived : public Base {
|
|
; public:
|
|
; __attribute__((dllexport)) Derived() = default;
|
|
; __attribute__((dllexport)) ~Derived() override = default;
|
|
; __attribute__((dllexport)) int calc() const override {
|
|
; return m_field * 2 + m_newfield;
|
|
; }
|
|
; int m_newfield{0};
|
|
; };
|
|
;
|
|
; __attribute((noinline)) void address_taken() {}
|
|
; __attribute((noinline)) void address_not_taken() {}
|
|
;
|
|
; using fn_t = void (*)();
|
|
; __attribute__((dllexport)) fn_t get_address() {
|
|
; address_not_taken();
|
|
; return &address_taken;
|
|
; }
|
|
;-------------------------------------------------------------------------------
|
|
|
|
; CHECK: .set @feat.00, 2048
|
|
|
|
; CHECK: .section .gfids$y
|
|
; CHECK: .symidx _ZNK7Derived4calcEv
|
|
; CHECK: .symidx _Z13address_takenv
|
|
|
|
; ModuleID = 'cfguard-mingw.cpp'
|
|
source_filename = "cfguard-mingw.cpp"
|
|
target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
|
target triple = "x86_64-w64-windows-gnu"
|
|
|
|
%class.Base = type <{ ptr, i32, [4 x i8] }>
|
|
%class.Derived = type { %class.Base.base, i32 }
|
|
%class.Base.base = type <{ ptr, i32 }>
|
|
|
|
$_ZN4BaseC2Ev = comdat any
|
|
|
|
$_ZN4BaseC1Ev = comdat any
|
|
|
|
$_ZNK4Base4calcEv = comdat any
|
|
|
|
$_ZN4BaseD2Ev = comdat any
|
|
|
|
$_ZN4BaseD1Ev = comdat any
|
|
|
|
$_ZN4BaseD0Ev = comdat any
|
|
|
|
$_ZN7DerivedC2Ev = comdat any
|
|
|
|
$_ZN7DerivedC1Ev = comdat any
|
|
|
|
$_ZNK7Derived4calcEv = comdat any
|
|
|
|
$_ZN7DerivedD2Ev = comdat any
|
|
|
|
$_ZN7DerivedD1Ev = comdat any
|
|
|
|
$_ZN7DerivedD0Ev = comdat any
|
|
|
|
$_ZTV4Base = comdat any
|
|
|
|
$_ZTV7Derived = comdat any
|
|
|
|
$_ZTS4Base = comdat any
|
|
|
|
$_ZTI4Base = comdat any
|
|
|
|
$_ZTS7Derived = comdat any
|
|
|
|
$_ZTI7Derived = comdat any
|
|
|
|
@_ZTV4Base = weak_odr dso_local dllexport unnamed_addr constant { [5 x ptr] } { [5 x ptr] [ptr null, ptr @_ZTI4Base, ptr @_ZN4BaseD1Ev, ptr @_ZN4BaseD0Ev, ptr @_ZNK4Base4calcEv] }, comdat, align 8
|
|
@_ZTV7Derived = weak_odr dso_local dllexport unnamed_addr constant { [5 x ptr] } { [5 x ptr] [ptr null, ptr @_ZTI7Derived, ptr @_ZN7DerivedD1Ev, ptr @_ZN7DerivedD0Ev, ptr @_ZNK7Derived4calcEv] }, comdat, align 8
|
|
@_ZTVN10__cxxabiv117__class_type_infoE = external global ptr
|
|
@_ZTS4Base = linkonce_odr dso_local constant [6 x i8] c"4Base\00", comdat, align 1
|
|
@_ZTI4Base = linkonce_odr dso_local constant { ptr, ptr } { ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), ptr @_ZTS4Base }, comdat, align 8
|
|
@_ZTVN10__cxxabiv120__si_class_type_infoE = external global ptr
|
|
@_ZTS7Derived = linkonce_odr dso_local constant [9 x i8] c"7Derived\00", comdat, align 1
|
|
@_ZTI7Derived = linkonce_odr dso_local constant { ptr, ptr, ptr } { ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv120__si_class_type_infoE, i64 2), ptr @_ZTS7Derived, ptr @_ZTI4Base }, comdat, align 8
|
|
|
|
; Function Attrs: nounwind uwtable
|
|
define weak_odr dso_local dllexport void @_ZN4BaseC2Ev(ptr noundef nonnull align 8 dereferenceable(12) %0) unnamed_addr #0 comdat align 2 {
|
|
store ptr getelementptr inbounds ({ [5 x ptr] }, ptr @_ZTV4Base, i64 0, inrange i32 0, i64 2), ptr %0, align 8, !tbaa !5
|
|
%2 = getelementptr inbounds %class.Base, ptr %0, i64 0, i32 1
|
|
store i32 0, ptr %2, align 8, !tbaa !8
|
|
ret void
|
|
}
|
|
|
|
; Function Attrs: nounwind uwtable
|
|
define weak_odr dso_local dllexport void @_ZN4BaseC1Ev(ptr noundef nonnull align 8 dereferenceable(12) %0) unnamed_addr #0 comdat align 2 {
|
|
store ptr getelementptr inbounds ({ [5 x ptr] }, ptr @_ZTV4Base, i64 0, inrange i32 0, i64 2), ptr %0, align 8, !tbaa !5
|
|
%2 = getelementptr inbounds %class.Base, ptr %0, i64 0, i32 1
|
|
store i32 0, ptr %2, align 8, !tbaa !8
|
|
ret void
|
|
}
|
|
|
|
; Function Attrs: mustprogress nounwind uwtable
|
|
define weak_odr dso_local dllexport noundef i32 @_ZNK4Base4calcEv(ptr noundef nonnull align 8 dereferenceable(12) %0) unnamed_addr #1 comdat align 2 {
|
|
%2 = getelementptr inbounds %class.Base, ptr %0, i64 0, i32 1
|
|
%3 = load i32, ptr %2, align 8, !tbaa !8
|
|
%4 = shl nsw i32 %3, 1
|
|
ret i32 %4
|
|
}
|
|
|
|
; Function Attrs: nounwind uwtable
|
|
define weak_odr dso_local dllexport void @_ZN4BaseD2Ev(ptr noundef nonnull align 8 dereferenceable(12) %0) unnamed_addr #0 comdat align 2 {
|
|
ret void
|
|
}
|
|
|
|
; Function Attrs: nounwind uwtable
|
|
define weak_odr dso_local dllexport void @_ZN4BaseD1Ev(ptr noundef nonnull align 8 dereferenceable(12) %0) unnamed_addr #0 comdat align 2 {
|
|
ret void
|
|
}
|
|
|
|
; Function Attrs: nounwind uwtable
|
|
define weak_odr dso_local dllexport void @_ZN4BaseD0Ev(ptr noundef nonnull align 8 dereferenceable(12) %0) unnamed_addr #0 comdat align 2 {
|
|
tail call void @_ZdlPv(ptr noundef nonnull %0) #5
|
|
ret void
|
|
}
|
|
|
|
; Function Attrs: nobuiltin nounwind
|
|
declare dso_local void @_ZdlPv(ptr noundef) local_unnamed_addr #2
|
|
|
|
; Function Attrs: nounwind uwtable
|
|
define weak_odr dso_local dllexport void @_ZN7DerivedC2Ev(ptr noundef nonnull align 8 dereferenceable(16) %0) unnamed_addr #0 comdat align 2 {
|
|
store ptr getelementptr inbounds ({ [5 x ptr] }, ptr @_ZTV4Base, i64 0, inrange i32 0, i64 2), ptr %0, align 8, !tbaa !5
|
|
%2 = getelementptr inbounds %class.Base, ptr %0, i64 0, i32 1
|
|
store i32 0, ptr %2, align 8, !tbaa !8
|
|
store ptr getelementptr inbounds ({ [5 x ptr] }, ptr @_ZTV7Derived, i64 0, inrange i32 0, i64 2), ptr %0, align 8, !tbaa !5
|
|
%3 = getelementptr inbounds %class.Derived, ptr %0, i64 0, i32 1
|
|
store i32 0, ptr %3, align 4, !tbaa !12
|
|
ret void
|
|
}
|
|
|
|
; Function Attrs: nounwind uwtable
|
|
define weak_odr dso_local dllexport void @_ZN7DerivedC1Ev(ptr noundef nonnull align 8 dereferenceable(16) %0) unnamed_addr #0 comdat align 2 {
|
|
store ptr getelementptr inbounds ({ [5 x ptr] }, ptr @_ZTV4Base, i64 0, inrange i32 0, i64 2), ptr %0, align 8, !tbaa !5
|
|
%2 = getelementptr inbounds %class.Base, ptr %0, i64 0, i32 1
|
|
store i32 0, ptr %2, align 8, !tbaa !8
|
|
store ptr getelementptr inbounds ({ [5 x ptr] }, ptr @_ZTV7Derived, i64 0, inrange i32 0, i64 2), ptr %0, align 8, !tbaa !5
|
|
%3 = getelementptr inbounds %class.Derived, ptr %0, i64 0, i32 1
|
|
store i32 0, ptr %3, align 4, !tbaa !12
|
|
ret void
|
|
}
|
|
|
|
; Function Attrs: mustprogress nounwind uwtable
|
|
define weak_odr dso_local dllexport noundef i32 @_ZNK7Derived4calcEv(ptr noundef nonnull align 8 dereferenceable(16) %0) unnamed_addr #1 comdat align 2 {
|
|
%2 = getelementptr inbounds %class.Base, ptr %0, i64 0, i32 1
|
|
%3 = load i32, ptr %2, align 8, !tbaa !8
|
|
%4 = shl nsw i32 %3, 1
|
|
%5 = getelementptr inbounds %class.Derived, ptr %0, i64 0, i32 1
|
|
%6 = load i32, ptr %5, align 4, !tbaa !12
|
|
%7 = add nsw i32 %4, %6
|
|
ret i32 %7
|
|
}
|
|
|
|
; Function Attrs: nounwind uwtable
|
|
define weak_odr dso_local dllexport void @_ZN7DerivedD2Ev(ptr noundef nonnull align 8 dereferenceable(16) %0) unnamed_addr #0 comdat align 2 {
|
|
ret void
|
|
}
|
|
|
|
; Function Attrs: nounwind uwtable
|
|
define weak_odr dso_local dllexport void @_ZN7DerivedD1Ev(ptr noundef nonnull align 8 dereferenceable(16) %0) unnamed_addr #0 comdat align 2 {
|
|
ret void
|
|
}
|
|
|
|
; Function Attrs: nounwind uwtable
|
|
define weak_odr dso_local dllexport void @_ZN7DerivedD0Ev(ptr noundef nonnull align 8 dereferenceable(16) %0) unnamed_addr #0 comdat align 2 {
|
|
tail call void @_ZdlPv(ptr noundef nonnull %0) #5
|
|
ret void
|
|
}
|
|
|
|
; Function Attrs: mustprogress nofree noinline norecurse nosync nounwind readnone willreturn uwtable
|
|
define dso_local void @_Z13address_takenv() #3 {
|
|
ret void
|
|
}
|
|
|
|
; Function Attrs: mustprogress nofree noinline norecurse nosync nounwind readnone willreturn uwtable
|
|
define dso_local void @_Z17address_not_takenv() local_unnamed_addr #3 {
|
|
ret void
|
|
}
|
|
|
|
; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn uwtable
|
|
define dso_local dllexport noundef nonnull ptr @_Z11get_addressv() local_unnamed_addr #4 {
|
|
ret ptr @_Z13address_takenv
|
|
}
|
|
|
|
attributes #0 = { nounwind uwtable "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
|
|
attributes #1 = { mustprogress nounwind uwtable "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
|
|
attributes #2 = { nobuiltin nounwind "frame-pointer"="none" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
|
|
attributes #3 = { mustprogress nofree noinline norecurse nosync nounwind readnone willreturn uwtable "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
|
|
attributes #4 = { mustprogress nofree norecurse nosync nounwind readnone willreturn uwtable "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
|
|
attributes #5 = { builtin nounwind }
|
|
|
|
!llvm.module.flags = !{!0, !1, !2, !3}
|
|
!llvm.ident = !{!4}
|
|
|
|
!0 = !{i32 2, !"cfguard", i32 2}
|
|
!1 = !{i32 1, !"wchar_size", i32 2}
|
|
!2 = !{i32 8, !"PIC Level", i32 2}
|
|
!3 = !{i32 7, !"uwtable", i32 2}
|
|
!4 = !{!"clang version 16.0.0"}
|
|
!5 = !{!6, !6, i64 0}
|
|
!6 = !{!"vtable pointer", !7, i64 0}
|
|
!7 = !{!"Simple C++ TBAA"}
|
|
!8 = !{!9, !10, i64 8}
|
|
!9 = !{!"_ZTS4Base", !10, i64 8}
|
|
!10 = !{!"int", !11, i64 0}
|
|
!11 = !{!"omnipotent char", !7, i64 0}
|
|
!12 = !{!13, !10, i64 12}
|
|
!13 = !{!"_ZTS7Derived", !9, i64 0, !10, i64 12}
|