LowerTypeTests: Mark CFI jump table sections as eligible for relaxation.
Use !elf_section_properties metadata to set the type and entry size to the correct values, and set the preferred alignment to the entry size to enable last jump table entry placement. Reviewers: vitalybuka, MaskRay Reviewed By: vitalybuka, MaskRay Pull Request: https://github.com/llvm/llvm-project/pull/149261
This commit is contained in:
1 parent
88bd366041
commit
081568eb66
12 files changed
+44
-26
No files matched your search
@@ -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() {{(\(.cfi_jt\) )?}}defined here
|
||||
// A: note: S::f1() {{.*}}defined here
|
||||
(s.*bitcast<S_int>(&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() {{(\(.cfi_jt\) )?}}defined here
|
||||
// B: note: S::f2() {{.*}}defined here
|
||||
(t.*bitcast<T_int>(&S::f2))();
|
||||
break;
|
||||
case 'c':
|
||||
|
||||
@@ -31,6 +31,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"
|
||||
@@ -492,6 +493,10 @@ class LowerTypeTestsModule {
|
||||
GlobalVariable *GlobalAnnotation;
|
||||
DenseSet<Value *> 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);
|
||||
@@ -1584,6 +1589,20 @@ createJumpTableDebugInfo(Function *F, ArrayRef<GlobalTypeMember *> Functions) {
|
||||
void LowerTypeTestsModule::createJumpTable(
|
||||
Function *F, ArrayRef<GlobalTypeMember *> 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<Metadata *>{
|
||||
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);
|
||||
|
||||
@@ -1611,7 +1630,7 @@ void LowerTypeTestsModule::createJumpTable(
|
||||
IRB.CreateUnreachable();
|
||||
|
||||
// Align the whole table by entry size.
|
||||
F->setAlignment(Align(getJumpTableEntrySize(JumpTableArch)));
|
||||
F->setPreferredAlignment(Align(JumpTableEntrySize));
|
||||
F->addFnAttr(Attribute::Naked);
|
||||
if (JumpTableArch == Triple::arm)
|
||||
F->addFnAttr("target-features", "-thumb-mode");
|
||||
@@ -2168,10 +2187,6 @@ bool LowerTypeTestsModule::lower() {
|
||||
unsigned CurUniqueId = 0;
|
||||
SmallVector<MDNode *, 2> 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...]}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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)
|
||||
@@ -134,11 +134,11 @@ 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 {
|
||||
; HEXAGON: define private void @[[JT]]() #{{.*}} align 4 {
|
||||
; 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)
|
||||
; HEXAGON: define private void @[[JT]]() #{{.*}} prefalign(4)
|
||||
|
||||
; CHECK-LABEL: define internal void @__cfi_global_var_init() section ".text.startup" {
|
||||
; CHECK-NEXT: entry:
|
||||
@@ -167,4 +167,4 @@ define i1 @foo(ptr %p) {
|
||||
; CHECK-NEXT: }
|
||||
|
||||
!0 = !{i32 0, !"typeid1"}
|
||||
; CHECK: ![[SELPROF]] = !{!"unknown", !"lowertypetests"}
|
||||
; CHECK: ![[SELPROF]] = !{!"unknown", !"lowertypetests"}
|
||||
@@ -63,9 +63,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
|
||||
@@ -127,5 +127,9 @@ define i1 @foo(ptr %p) {
|
||||
; LOONGARCH64: attributes #[[ATTR]] = { naked noinline }
|
||||
; HEXAGON: 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}
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@ define i1 @foo(ptr %p) {
|
||||
!0 = !{i32 0, !"typeid1"}
|
||||
!1 = !{i32 8, !"cf-protection-branch", i32 1}
|
||||
|
||||
|
||||
;.
|
||||
; X86_32: @[[GLOB0:[0-9]+]] = private unnamed_addr constant [2 x ptr] [ptr @f, ptr @g], align 16
|
||||
; X86_32: @[[GLOB1:[0-9]+]] = private constant [0 x i8] zeroinitializer
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in new issue
Block a user