diff --git a/compiler-rt/test/cfi/mfcall.cpp b/compiler-rt/test/cfi/mfcall.cpp index d4666df8d5333..f95251f5adb44 100644 --- a/compiler-rt/test/cfi/mfcall.cpp +++ b/compiler-rt/test/cfi/mfcall.cpp @@ -63,12 +63,12 @@ int main(int argc, char **argv) { switch (argv[1][0]) { case 'a': // A: runtime error: control flow integrity check for type 'int (S::*)()' failed during non-virtual pointer to member function call - // A: note: S::f1() defined here + // A: note: S::f1() {{.*}}defined here (s.*bitcast(&S::f1))(); break; case 'b': // B: runtime error: control flow integrity check for type 'int (T::*)()' failed during non-virtual pointer to member function call - // B: note: S::f2() defined here + // B: note: S::f2() {{.*}}defined here (t.*bitcast(&S::f2))(); break; case 'c': diff --git a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp index 486205c8a3848..8b21d81bc9678 100644 --- a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp +++ b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp @@ -30,6 +30,8 @@ #include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/Analysis/TypeMetadataUtils.h" #include "llvm/Analysis/ValueTracking.h" +#include "llvm/BinaryFormat/ELF.h" +#include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Constant.h" @@ -73,6 +75,7 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/TargetParser/Triple.h" #include "llvm/Transforms/IPO.h" +#include "llvm/Transforms/IPO/CrossDSOCFI.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/ModuleUtils.h" #include @@ -498,6 +501,10 @@ class LowerTypeTestsModule { GlobalVariable *GlobalAnnotation; DenseSet FunctionAnnotations; + // Cross-DSO CFI emits jumptable entries for exported functions as well as + // address taken functions in case they are address taken in other modules. + bool CrossDsoCfi = M.getModuleFlag("Cross-DSO CFI") != nullptr; + bool shouldExportConstantsAsAbsoluteSymbols(); uint8_t *exportTypeId(StringRef TypeId, const TypeIdLowering &TIL); TypeIdLowering importTypeId(StringRef TypeId); @@ -1527,6 +1534,20 @@ Triple::ArchType LowerTypeTestsModule::selectJumpTableArmEncoding( void LowerTypeTestsModule::createJumpTable( Function *F, ArrayRef Functions, Triple::ArchType JumpTableArch) { + unsigned JumpTableEntrySize = getJumpTableEntrySize(JumpTableArch); + // Give the jumptable section this type in order to enable jumptable + // relaxation. Only do this if cross-DSO CFI is disabled because jumptable + // relaxation violates cross-DSO CFI's restrictions on the ordering of the + // jumptable relative to other sections. + if (!CrossDsoCfi) + F->setMetadata(LLVMContext::MD_elf_section_properties, + MDNode::get(F->getContext(), + ArrayRef{ + ConstantAsMetadata::get(ConstantInt::get( + Int64Ty, ELF::SHT_LLVM_CFI_JUMP_TABLE)), + ConstantAsMetadata::get(ConstantInt::get( + Int64Ty, JumpTableEntrySize))})); + BasicBlock *BB = BasicBlock::Create(M.getContext(), "entry", F); IRBuilder<> IRB(BB); @@ -1547,7 +1568,7 @@ void LowerTypeTestsModule::createJumpTable( IRB.CreateUnreachable(); // Align the whole table by entry size. - F->setAlignment(Align(getJumpTableEntrySize(JumpTableArch))); + F->setAlignment(Align(JumpTableEntrySize)); // Skip prologue. // Disabled on win32 due to https://llvm.org/bugs/show_bug.cgi?id=28641#c3. // Luckily, this function does not get any prologue even without the @@ -2114,10 +2135,6 @@ bool LowerTypeTestsModule::lower() { unsigned CurUniqueId = 0; SmallVector Types; - // Cross-DSO CFI emits jumptable entries for exported functions as well as - // address taken functions in case they are address taken in other modules. - const bool CrossDsoCfi = M.getModuleFlag("Cross-DSO CFI") != nullptr; - struct ExportedFunctionInfo { CfiFunctionLinkage Linkage; MDNode *FuncMD; // {name, linkage, type[, type...]} diff --git a/llvm/test/Transforms/LowerTypeTests/aarch64-jumptable.ll b/llvm/test/Transforms/LowerTypeTests/aarch64-jumptable.ll index 8a90174bb3ff1..a14d2677e3d70 100644 --- a/llvm/test/Transforms/LowerTypeTests/aarch64-jumptable.ll +++ b/llvm/test/Transforms/LowerTypeTests/aarch64-jumptable.ll @@ -49,7 +49,7 @@ define i1 @foo(ptr %p) { ; ; AARCH64: Function Attrs: naked noinline ; AARCH64-LABEL: define private void @.cfi.jumptable -; AARCH64-SAME: () #[[ATTR1:[0-9]+]] align 8 { +; AARCH64-SAME: () #[[ATTR1:[0-9]+]] align 8 ; AARCH64-NEXT: entry: ; AARCH64-NEXT: call void asm sideeffect "bti c\0Ab $0\0A", "s"(ptr @f.cfi) ; AARCH64-NEXT: call void asm sideeffect "bti c\0Ab $0\0A", "s"(ptr @g.cfi) diff --git a/llvm/test/Transforms/LowerTypeTests/function-arm-thumb.ll b/llvm/test/Transforms/LowerTypeTests/function-arm-thumb.ll index 3c6c4280a0ca2..6eeb2c493b30a 100644 --- a/llvm/test/Transforms/LowerTypeTests/function-arm-thumb.ll +++ b/llvm/test/Transforms/LowerTypeTests/function-arm-thumb.ll @@ -33,14 +33,14 @@ define void @addrtaken() { !0 = !{i32 0, !"typeid1"} !1 = !{i32 0, !"typeid2"} -; CHECK: define private void {{.*}} #[[AT:.*]] align 4 { +; CHECK: define private void {{.*}} #[[AT:.*]] align 4 ; CHECK-NEXT: entry: ; CHECK-NEXT: call void asm sideeffect "b.w $0\0A", "s"(ptr @f1.cfi) ; CHECK-NEXT: call void asm sideeffect "b.w $0\0A", "s"(ptr @g1.cfi) ; CHECK-NEXT: unreachable ; CHECK-NEXT: } -; CHECK: define private void {{.*}} #[[AA:.*]] align 4 { +; CHECK: define private void {{.*}} #[[AA:.*]] align 4 ; CHECK-NEXT: entry: ; CHECK-NEXT: call void asm sideeffect "b $0\0A", "s"(ptr @f2.cfi) ; CHECK-NEXT: call void asm sideeffect "b $0\0A", "s"(ptr @g2.cfi) diff --git a/llvm/test/Transforms/LowerTypeTests/function-disjoint.ll b/llvm/test/Transforms/LowerTypeTests/function-disjoint.ll index ae676df6e9f31..88a3c3dd59ce4 100644 --- a/llvm/test/Transforms/LowerTypeTests/function-disjoint.ll +++ b/llvm/test/Transforms/LowerTypeTests/function-disjoint.ll @@ -39,10 +39,10 @@ define i1 @foo(ptr %p) { ret i1 %z } -; X64: define private void @[[JT1]]() #{{.*}} align 8 { +; X64: define private void @[[JT1]]() #{{.*}} align 8 ; X64: call void asm sideeffect "jmp ${0:c}@plt\0Aint3\0Aint3\0Aint3\0A", "s"(ptr @g.cfi) -; X64: define private void @[[JT0]]() #{{.*}} align 8 { +; X64: define private void @[[JT0]]() #{{.*}} align 8 ; X64: call void asm sideeffect "jmp ${0:c}@plt\0Aint3\0Aint3\0Aint3\0A", "s"(ptr @f.cfi) ; WASM32: ![[I1]] = !{i64 2} diff --git a/llvm/test/Transforms/LowerTypeTests/function-weak.ll b/llvm/test/Transforms/LowerTypeTests/function-weak.ll index 4ea03b6c2c1fa..d4e031767607b 100644 --- a/llvm/test/Transforms/LowerTypeTests/function-weak.ll +++ b/llvm/test/Transforms/LowerTypeTests/function-weak.ll @@ -133,10 +133,10 @@ define i1 @foo(ptr %p) { ret i1 %x } -; X86: define private void @[[JT]]() #{{.*}} align 8 { -; ARM: define private void @[[JT]]() #{{.*}} align 4 { -; RISCV: define private void @[[JT]]() #{{.*}} align 8 { -; LOONGARCH64: define private void @[[JT]]() #{{.*}} align 8 { +; X86: define private void @[[JT]]() #{{.*}} align 8 +; ARM: define private void @[[JT]]() #{{.*}} align 4 +; RISCV: define private void @[[JT]]() #{{.*}} align 8 +; LOONGARCH64: define private void @[[JT]]() #{{.*}} align 8 ; CHECK-LABEL: define internal void @__cfi_global_var_init() section ".text.startup" { ; CHECK-NEXT: entry: diff --git a/llvm/test/Transforms/LowerTypeTests/function.ll b/llvm/test/Transforms/LowerTypeTests/function.ll index ab3cfb6acccf8..bad3b65bd302b 100644 --- a/llvm/test/Transforms/LowerTypeTests/function.ll +++ b/llvm/test/Transforms/LowerTypeTests/function.ll @@ -62,9 +62,9 @@ define i1 @foo(ptr %p) { ret i1 %x } -; JT4: define private void @[[JT]]() #[[ATTR:.*]] align 4 { -; JT8: define private void @[[JT]]() #[[ATTR:.*]] align 8 { -; JT16: define private void @[[JT]]() #[[ATTR:.*]] align 16 { +; JT4: define private void @[[JT]]() #[[ATTR:.*]] align 4 !elf_section_properties ![[PROP:[0-9]*]] { +; JT8: define private void @[[JT]]() #[[ATTR:.*]] align 8 !elf_section_properties ![[PROP:[0-9]*]] { +; JT16: define private void @[[JT]]() #[[ATTR:.*]] align 16 !elf_section_properties ![[PROP:[0-9]*]] { ; X86: jmp ${0:c}@plt ; X86-SAME: int3 @@ -122,5 +122,9 @@ define i1 @foo(ptr %p) { ; RISCV: attributes #[[ATTR]] = { naked noinline "target-features"="-c,-relax" } ; LOONGARCH64: attributes #[[ATTR]] = { naked noinline } +; JT4: ![[PROP]] = !{i64 1879002126, i64 4} +; JT8: ![[PROP]] = !{i64 1879002126, i64 8} +; JT16: ![[PROP]] = !{i64 1879002126, i64 16} + ; WASM32: ![[I0]] = !{i64 1} ; WASM32: ![[I1]] = !{i64 2} diff --git a/llvm/test/Transforms/LowerTypeTests/x86-jumptable.ll b/llvm/test/Transforms/LowerTypeTests/x86-jumptable.ll index 76acf9469785d..052e49b02a9db 100644 --- a/llvm/test/Transforms/LowerTypeTests/x86-jumptable.ll +++ b/llvm/test/Transforms/LowerTypeTests/x86-jumptable.ll @@ -23,7 +23,7 @@ define i1 @foo(ptr %p) { !0 = !{i32 0, !"typeid1"} !1 = !{i32 8, !"cf-protection-branch", i32 1} -; X86: define private void @.cfi.jumptable() #[[#ATTR:]] align 16 { +; X86: define private void @.cfi.jumptable() #[[#ATTR:]] align 16 ; X86-NEXT: entry: ; X86_32-NEXT: call void asm sideeffect "endbr32\0Ajmp ${0:c}@plt\0A.balign 16, 0xcc\0A", "s"(ptr @f.cfi) ; X86_32-NEXT: call void asm sideeffect "endbr32\0Ajmp ${0:c}@plt\0A.balign 16, 0xcc\0A", "s"(ptr @g.cfi)