Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 4 additions & 10 deletions llvm/lib/Target/AArch64/AArch64Arm64ECCallLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -655,16 +655,10 @@ Function *AArch64Arm64ECCallLowering::buildGuestExitThunk(Function *F) {
BasicBlock *BB = BasicBlock::Create(M->getContext(), "", GuestExit);
IRBuilder<> B(BB);

// Load the global symbol as a pointer to the check function.
Value *GuardFn;
if (cfguard_module_flag == 2 && !F->hasFnAttribute("guard_nocf"))
GuardFn = GuardFnCFGlobal;
else
GuardFn = GuardFnGlobal;
LoadInst *GuardCheckLoad = B.CreateLoad(PtrTy, GuardFn);

// Create new call instruction. The CFGuard check should always be a call,
// even if the original CallBase is an Invoke or CallBr instruction.
// Create new call instruction. The call check should always be a call,
// even if the original CallBase is an Invoke or CallBr instructio.
// This is treated as a direct call, so do not use GuardFnCFGlobal.
LoadInst *GuardCheckLoad = B.CreateLoad(PtrTy, GuardFnGlobal);
Function *Thunk = buildExitThunk(F->getFunctionType(), F->getAttributes());
CallInst *GuardCheck = B.CreateCall(
GuardFnType, GuardCheckLoad, {F, Thunk});
Expand Down
49 changes: 46 additions & 3 deletions llvm/test/CodeGen/AArch64/cfguard-arm64ec.ll
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,58 @@

declare void @called()
declare void @escaped()
define void @f(ptr %dst) {
define void @f(ptr %dst, ptr readonly %f) {
call void @called()
; CHECK: bl "#called"
store ptr @escaped, ptr %dst
ret void
call void %f()
; CHECK: adrp x10, $iexit_thunk$cdecl$v$v
; CHECK-NEXT: add x10, x10, :lo12:$iexit_thunk$cdecl$v$v
; CHECK-NEXT: str x8, [x20]
; CHECK-NEXT: adrp x8, __os_arm64x_check_icall_cfg
; CHECK-NEXT: ldr x8, [x8, :lo12:__os_arm64x_check_icall_cfg]
; CHECK-NEXT: mov x11,
; CHECK-NEXT: blr x8
; CHECK-NEXT: blr x11
ret void
}

; CHECK-LABEL: .def "#called$exit_thunk";
; CHECK-NEXT: .scl 2;
; CHECK-NEXT: .type 32;
; CHECK-NEXT: .endef
; CHECK-NEXT: .section .wowthk$aa,"xr",discard,"#called$exit_thunk"
; CHECK-NEXT: .globl "#called$exit_thunk" // -- Begin function #called$exit_thunk
; CHECK-NEXT: .p2align 2
; CHECK-NEXT: "#called$exit_thunk": // @"#called$exit_thunk"
; CHECK-NEXT: .weak_anti_dep called
; CHECK-NEXT: called = "#called"
; CHECK-NEXT: .weak_anti_dep "#called"
; CHECK-NEXT: "#called" = "#called$exit_thunk"
; CHECK-NEXT: .seh_proc "#called$exit_thunk"
; CHECK-NEXT: // %bb.0:
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
; CHECK-NEXT: .seh_save_reg_x x30, 16
; CHECK-NEXT: .seh_endprologue
; CHECK-NEXT: adrp x8, __os_arm64x_check_icall
; CHECK-NEXT: adrp x11, called
; CHECK-NEXT: add x11, x11, :lo12:called
; CHECK-NEXT: ldr x8, [x8, :lo12:__os_arm64x_check_icall]
; CHECK-NEXT: adrp x10, $iexit_thunk$cdecl$v$v
; CHECK-NEXT: add x10, x10, :lo12:$iexit_thunk$cdecl$v$v
; CHECK-NEXT: blr x8
; CHECK-NEXT: .seh_startepilogue
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
; CHECK-NEXT: .seh_save_reg_x x30, 16
; CHECK-NEXT: .seh_endepilogue
; CHECK-NEXT: br x11
; CHECK-NEXT: .seh_endfunclet
; CHECK-NEXT: .seh_endproc

!llvm.module.flags = !{!0}
!0 = !{i32 2, !"cfguard", i32 1}
!0 = !{i32 2, !"cfguard", i32 2}

; CHECK-LABEL: .section .gfids$y,"dr"
; CHECK-NEXT: .symidx escaped
; CHECK-NEXT: .symidx $iexit_thunk$cdecl$v$v
; CHECK-NOT: .symidx
Loading