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 be6cba38d8b3c..10b3e5fa1ce1f 100644 --- a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp +++ b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp @@ -30,6 +30,7 @@ #include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/Analysis/TypeMetadataUtils.h" #include "llvm/Analysis/ValueTracking.h" +#include "llvm/BinaryFormat/ELF.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Constant.h" @@ -498,6 +499,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); @@ -1531,6 +1536,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); @@ -1551,7 +1570,7 @@ void LowerTypeTestsModule::createJumpTable( IRB.CreateUnreachable(); // Align the whole table by entry size. - F->setAlignment(Align(getJumpTableEntrySize(JumpTableArch))); + F->setPreferredAlignment(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 @@ -2115,10 +2134,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..c5f489e14c896 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]+]] prefalign 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/cfi-nounwind-direct-call.ll b/llvm/test/Transforms/LowerTypeTests/cfi-nounwind-direct-call.ll index 2795333effd76..ddda698e3ddd7 100644 --- a/llvm/test/Transforms/LowerTypeTests/cfi-nounwind-direct-call.ll +++ b/llvm/test/Transforms/LowerTypeTests/cfi-nounwind-direct-call.ll @@ -153,7 +153,7 @@ attributes #6 = { noreturn nounwind } ; ; CHECK: Function Attrs: naked nocf_check noinline nounwind ; CHECK-LABEL: define internal void @_Z9nothrow_ei.cfi_jt -; CHECK-SAME: () #[[ATTR5:[0-9]+]] align 8 { +; CHECK-SAME: () #[[ATTR5:[0-9]+]] prefalign 8 { ; CHECK-NEXT: entry: ; CHECK-NEXT: tail call void asm sideeffect "jmp ${0:c}@plt\0Aint3\0Aint3\0Aint3\0A", "s"(ptr nonnull @_Z9nothrow_ei) #[[ATTR7:[0-9]+]] ; CHECK-NEXT: unreachable diff --git a/llvm/test/Transforms/LowerTypeTests/cfi-unwind-direct-call.ll b/llvm/test/Transforms/LowerTypeTests/cfi-unwind-direct-call.ll index 4d5055cc5a760..18eb59d62b413 100644 --- a/llvm/test/Transforms/LowerTypeTests/cfi-unwind-direct-call.ll +++ b/llvm/test/Transforms/LowerTypeTests/cfi-unwind-direct-call.ll @@ -221,7 +221,7 @@ attributes #8 = { noreturn nounwind } ; ; CHECK: Function Attrs: naked nocf_check noinline ; CHECK-LABEL: define internal void @_Z7throw_ei.cfi_jt( -; CHECK-SAME: ) #[[ATTR5:[0-9]+]] align 8 { +; CHECK-SAME: ) #[[ATTR5:[0-9]+]] prefalign 8 { ; CHECK-NEXT: entry: ; CHECK-NEXT: tail call void asm sideeffect "jmp ${0:c}@plt\0Aint3\0Aint3\0Aint3\0A", "s"(ptr nonnull @_Z7throw_ei) #[[ATTR6]] ; CHECK-NEXT: unreachable diff --git a/llvm/test/Transforms/LowerTypeTests/function-arm-thumb.ll b/llvm/test/Transforms/LowerTypeTests/function-arm-thumb.ll index 3c6c4280a0ca2..0a35a524848dd 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:.*]] prefalign 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:.*]] prefalign 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..fa46171dcac05 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]]() #{{.*}} prefalign 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]]() #{{.*}} prefalign 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-ext.ll b/llvm/test/Transforms/LowerTypeTests/function-ext.ll index 9f0247365371e..9d268ae848b68 100644 --- a/llvm/test/Transforms/LowerTypeTests/function-ext.ll +++ b/llvm/test/Transforms/LowerTypeTests/function-ext.ll @@ -37,5 +37,5 @@ declare i1 @llvm.type.test(ptr %ptr, metadata %bitset) nounwind readnone !0 = !{i64 0, !"type1"} !1 = !{i64 0, !"type2"} -; X64: define private void @[[JT]]() #{{.*}} align {{.*}} { +; X64: define private void @[[JT]]() #{{.*}} prefalign {{.*}} { ; X64: call void asm sideeffect "jmp ${0:c}@plt\0Aint3\0Aint3\0Aint3\0A", "s"(ptr @foo1) diff --git a/llvm/test/Transforms/LowerTypeTests/function-weak.ll b/llvm/test/Transforms/LowerTypeTests/function-weak.ll index 4ea03b6c2c1fa..4a6e177b4a5d7 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]]() #{{.*}} prefalign 8 +; ARM: define private void @[[JT]]() #{{.*}} prefalign 4 +; RISCV: define private void @[[JT]]() #{{.*}} prefalign 8 +; LOONGARCH64: define private void @[[JT]]() #{{.*}} prefalign 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..5eba3f44636f6 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:.*]] prefalign 4 !elf_section_properties ![[PROP:[0-9]*]] { +; JT8: define private void @[[JT]]() #[[ATTR:.*]] prefalign 8 !elf_section_properties ![[PROP:[0-9]*]] { +; JT16: define private void @[[JT]]() #[[ATTR:.*]] prefalign 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/section.ll b/llvm/test/Transforms/LowerTypeTests/section.ll index bd91389c60ef0..b6f7668d86591 100644 --- a/llvm/test/Transforms/LowerTypeTests/section.ll +++ b/llvm/test/Transforms/LowerTypeTests/section.ll @@ -19,7 +19,7 @@ entry: ret i1 %0 } -; CHECK: define private void @[[JT]]() #{{.*}} align {{.*}} { +; CHECK: define private void @[[JT]]() #{{.*}} prefalign {{.*}} { declare i1 @llvm.type.test(ptr, metadata) nounwind readnone diff --git a/llvm/test/Transforms/LowerTypeTests/x86-jumptable.ll b/llvm/test/Transforms/LowerTypeTests/x86-jumptable.ll index 76acf9469785d..32c434804961c 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:]] prefalign 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) diff --git a/llvm/test/Transforms/MergeFunc/cfi-thunk-merging.ll b/llvm/test/Transforms/MergeFunc/cfi-thunk-merging.ll index 7767c2b0236de..2c3920c21f3e8 100644 --- a/llvm/test/Transforms/MergeFunc/cfi-thunk-merging.ll +++ b/llvm/test/Transforms/MergeFunc/cfi-thunk-merging.ll @@ -201,7 +201,7 @@ attributes #3 = { noreturn nounwind } ; ; ; LOWERTYPETESTS-LABEL: define private void @.cfi.jumptable -; LOWERTYPETESTS-SAME: () #[[ATTR3:[0-9]+]] align 8 { +; LOWERTYPETESTS-SAME: () #[[ATTR3:[0-9]+]] prefalign 8 !elf_section_properties {{.*}} { ; LOWERTYPETESTS-NEXT: entry: ; LOWERTYPETESTS-NEXT: call void asm sideeffect "jmp ${0:c}@plt\0Aint3\0Aint3\0Aint3\0A", "s"(ptr @f) ; LOWERTYPETESTS-NEXT: call void asm sideeffect "jmp ${0:c}@plt\0Aint3\0Aint3\0Aint3\0A", "s"(ptr @f_thunk)