Skip to content

Commit 6152999

Browse files
authored
[CodeGen][ARM64EC] Don't treat guest exit thunks as indirect calls (#165885)
Guest exit thunks serve as glue for performing direct calls, so they shouldn’t treat the target as an indirect one. Spotted by @coneco-cy in #165504.
1 parent 2a42a85 commit 6152999

File tree

2 files changed

+50
-13
lines changed

2 files changed

+50
-13
lines changed

llvm/lib/Target/AArch64/AArch64Arm64ECCallLowering.cpp

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -655,16 +655,10 @@ Function *AArch64Arm64ECCallLowering::buildGuestExitThunk(Function *F) {
655655
BasicBlock *BB = BasicBlock::Create(M->getContext(), "", GuestExit);
656656
IRBuilder<> B(BB);
657657

658-
// Load the global symbol as a pointer to the check function.
659-
Value *GuardFn;
660-
if (cfguard_module_flag == 2 && !F->hasFnAttribute("guard_nocf"))
661-
GuardFn = GuardFnCFGlobal;
662-
else
663-
GuardFn = GuardFnGlobal;
664-
LoadInst *GuardCheckLoad = B.CreateLoad(PtrTy, GuardFn);
665-
666-
// Create new call instruction. The CFGuard check should always be a call,
667-
// even if the original CallBase is an Invoke or CallBr instruction.
658+
// Create new call instruction. The call check should always be a call,
659+
// even if the original CallBase is an Invoke or CallBr instructio.
660+
// This is treated as a direct call, so do not use GuardFnCFGlobal.
661+
LoadInst *GuardCheckLoad = B.CreateLoad(PtrTy, GuardFnGlobal);
668662
Function *Thunk = buildExitThunk(F->getFunctionType(), F->getAttributes());
669663
CallInst *GuardCheck = B.CreateCall(
670664
GuardFnType, GuardCheckLoad, {F, Thunk});

llvm/test/CodeGen/AArch64/cfguard-arm64ec.ll

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,58 @@
22

33
declare void @called()
44
declare void @escaped()
5-
define void @f(ptr %dst) {
5+
define void @f(ptr %dst, ptr readonly %f) {
66
call void @called()
7+
; CHECK: bl "#called"
78
store ptr @escaped, ptr %dst
8-
ret void
9+
call void %f()
10+
; CHECK: adrp x10, $iexit_thunk$cdecl$v$v
11+
; CHECK-NEXT: add x10, x10, :lo12:$iexit_thunk$cdecl$v$v
12+
; CHECK-NEXT: str x8, [x20]
13+
; CHECK-NEXT: adrp x8, __os_arm64x_check_icall_cfg
14+
; CHECK-NEXT: ldr x8, [x8, :lo12:__os_arm64x_check_icall_cfg]
15+
; CHECK-NEXT: mov x11,
16+
; CHECK-NEXT: blr x8
17+
; CHECK-NEXT: blr x11
18+
ret void
919
}
1020

21+
; CHECK-LABEL: .def "#called$exit_thunk";
22+
; CHECK-NEXT: .scl 2;
23+
; CHECK-NEXT: .type 32;
24+
; CHECK-NEXT: .endef
25+
; CHECK-NEXT: .section .wowthk$aa,"xr",discard,"#called$exit_thunk"
26+
; CHECK-NEXT: .globl "#called$exit_thunk" // -- Begin function #called$exit_thunk
27+
; CHECK-NEXT: .p2align 2
28+
; CHECK-NEXT: "#called$exit_thunk": // @"#called$exit_thunk"
29+
; CHECK-NEXT: .weak_anti_dep called
30+
; CHECK-NEXT: called = "#called"
31+
; CHECK-NEXT: .weak_anti_dep "#called"
32+
; CHECK-NEXT: "#called" = "#called$exit_thunk"
33+
; CHECK-NEXT: .seh_proc "#called$exit_thunk"
34+
; CHECK-NEXT: // %bb.0:
35+
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
36+
; CHECK-NEXT: .seh_save_reg_x x30, 16
37+
; CHECK-NEXT: .seh_endprologue
38+
; CHECK-NEXT: adrp x8, __os_arm64x_check_icall
39+
; CHECK-NEXT: adrp x11, called
40+
; CHECK-NEXT: add x11, x11, :lo12:called
41+
; CHECK-NEXT: ldr x8, [x8, :lo12:__os_arm64x_check_icall]
42+
; CHECK-NEXT: adrp x10, $iexit_thunk$cdecl$v$v
43+
; CHECK-NEXT: add x10, x10, :lo12:$iexit_thunk$cdecl$v$v
44+
; CHECK-NEXT: blr x8
45+
; CHECK-NEXT: .seh_startepilogue
46+
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
47+
; CHECK-NEXT: .seh_save_reg_x x30, 16
48+
; CHECK-NEXT: .seh_endepilogue
49+
; CHECK-NEXT: br x11
50+
; CHECK-NEXT: .seh_endfunclet
51+
; CHECK-NEXT: .seh_endproc
52+
1153
!llvm.module.flags = !{!0}
12-
!0 = !{i32 2, !"cfguard", i32 1}
54+
!0 = !{i32 2, !"cfguard", i32 2}
1355

1456
; CHECK-LABEL: .section .gfids$y,"dr"
1557
; CHECK-NEXT: .symidx escaped
58+
; CHECK-NEXT: .symidx $iexit_thunk$cdecl$v$v
1659
; CHECK-NOT: .symidx

0 commit comments

Comments
 (0)