| // RUN: %clang %cflags -march=armv9.5-a+pauth-lr -mbranch-protection=pac-ret %s %p/../../Inputs/asm_main.c -o %t.exe |
| // RUN: llvm-bolt-binary-analysis --scanners=ptrauth-pac-ret %t.exe 2>&1 | FileCheck %s |
| |
| .text |
| |
| .globl f1 |
| .type f1,@function |
| f1: |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| // autiasp |
| // CHECK-LABEL: GS-PAUTH: non-protected ret found in function f1, basic block {{[0-9a-zA-Z.]+}}, at address |
| // CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret |
| // CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are: |
| // CHECK-NEXT: 1. {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 |
| // CHECK-NEXT: This happens in the following basic block: |
| // CHECK-NEXT: {{[0-9a-f]+}}: paciasp |
| // CHECK-NEXT: {{[0-9a-f]+}}: stp x29, x30, [sp, #-0x10]! |
| // CHECK-NEXT: {{[0-9a-f]+}}: mov x29, sp |
| // CHECK-NEXT: {{[0-9a-f]+}}: bl g |
| // CHECK-NEXT: {{[0-9a-f]+}}: add x0, x0, #0x3 |
| // CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 |
| // CHECK-NEXT: {{[0-9a-f]+}}: ret |
| ret |
| .size f1, .-f1 |
| |
| |
| .globl f_intermediate_overwrite1 |
| .type f_intermediate_overwrite1,@function |
| f_intermediate_overwrite1: |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| autiasp |
| ldp x29, x30, [sp], #16 |
| // CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_intermediate_overwrite1, basic block {{[0-9a-zA-Z.]+}} |
| // CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret |
| // CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are: |
| // CHECK-NEXT: 1. {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 |
| // CHECK-NEXT: This happens in the following basic block: |
| // CHECK-NEXT: {{[0-9a-f]+}}: paciasp |
| // CHECK-NEXT: {{[0-9a-f]+}}: stp x29, x30, [sp, #-0x10]! |
| // CHECK-NEXT: {{[0-9a-f]+}}: mov x29, sp |
| // CHECK-NEXT: {{[0-9a-f]+}}: bl g |
| // CHECK-NEXT: {{[0-9a-f]+}}: add x0, x0, #0x3 |
| // CHECK-NEXT: {{[0-9a-f]+}}: autiasp |
| // CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 |
| // CHECK-NEXT: {{[0-9a-f]+}}: ret |
| ret |
| .size f_intermediate_overwrite1, .-f_intermediate_overwrite1 |
| |
| .globl f_intermediate_overwrite2 |
| .type f_intermediate_overwrite2,@function |
| f_intermediate_overwrite2: |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| autiasp |
| mov x30, x0 |
| // CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_intermediate_overwrite2, basic block {{[0-9a-zA-Z.]+}}, at address |
| // CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret |
| // CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are: |
| // CHECK-NEXT: 1. {{[0-9a-f]+}}: mov x30, x0 |
| // CHECK-NEXT: This happens in the following basic block: |
| // CHECK-NEXT: {{[0-9a-f]+}}: paciasp |
| // CHECK-NEXT: {{[0-9a-f]+}}: stp x29, x30, [sp, #-0x10]! |
| // CHECK-NEXT: {{[0-9a-f]+}}: mov x29, sp |
| // CHECK-NEXT: {{[0-9a-f]+}}: bl g |
| // CHECK-NEXT: {{[0-9a-f]+}}: add x0, x0, #0x3 |
| // CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 |
| // CHECK-NEXT: {{[0-9a-f]+}}: autiasp |
| // CHECK-NEXT: {{[0-9a-f]+}}: mov x30, x0 |
| // CHECK-NEXT: {{[0-9a-f]+}}: ret |
| ret |
| .size f_intermediate_overwrite2, .-f_intermediate_overwrite2 |
| |
| .globl f_intermediate_read |
| .type f_intermediate_read,@function |
| f_intermediate_read: |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| autiasp |
| mov x0, x30 |
| // CHECK-NOT: function f_intermediate_read |
| ret |
| .size f_intermediate_read, .-f_intermediate_read |
| |
| .globl f_intermediate_overwrite3 |
| .type f_intermediate_overwrite3,@function |
| f_intermediate_overwrite3: |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| autiasp |
| mov w30, w0 |
| // CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_intermediate_overwrite3, basic block {{[0-9a-zA-Z.]+}}, at address |
| // CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret |
| // CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are: |
| // CHECK-NEXT: 1. {{[0-9a-f]+}}: mov w30, w0 |
| // CHECK-NEXT: This happens in the following basic block: |
| // CHECK-NEXT: {{[0-9a-f]+}}: paciasp |
| // CHECK-NEXT: {{[0-9a-f]+}}: stp x29, x30, [sp, #-0x10]! |
| // CHECK-NEXT: {{[0-9a-f]+}}: mov x29, sp |
| // CHECK-NEXT: {{[0-9a-f]+}}: bl g |
| // CHECK-NEXT: {{[0-9a-f]+}}: add x0, x0, #0x3 |
| // CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 |
| // CHECK-NEXT: {{[0-9a-f]+}}: autiasp |
| // CHECK-NEXT: {{[0-9a-f]+}}: mov w30, w0 |
| // CHECK-NEXT: {{[0-9a-f]+}}: ret |
| ret |
| .size f_intermediate_overwrite3, .-f_intermediate_overwrite3 |
| |
| .globl f_nonx30_ret |
| .type f_nonx30_ret,@function |
| f_nonx30_ret: |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| mov x16, x30 |
| autiasp |
| // CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_nonx30_ret, basic block {{[0-9a-zA-Z.]+}}, at address |
| // CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret x16 |
| // CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are: |
| // CHECK-NEXT: 1. {{[0-9a-f]+}}: mov x16, x30 |
| // CHECK-NEXT: This happens in the following basic block: |
| // CHECK-NEXT: {{[0-9a-f]+}}: paciasp |
| // CHECK-NEXT: {{[0-9a-f]+}}: stp x29, x30, [sp, #-0x10]! |
| // CHECK-NEXT: {{[0-9a-f]+}}: mov x29, sp |
| // CHECK-NEXT: {{[0-9a-f]+}}: bl g |
| // CHECK-NEXT: {{[0-9a-f]+}}: add x0, x0, #0x3 |
| // CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 |
| // CHECK-NEXT: {{[0-9a-f]+}}: mov x16, x30 |
| // CHECK-NEXT: {{[0-9a-f]+}}: autiasp |
| // CHECK-NEXT: {{[0-9a-f]+}}: ret x16 |
| ret x16 |
| .size f_nonx30_ret, .-f_nonx30_ret |
| |
| .globl f_nonx30_ret_ok |
| .type f_nonx30_ret_ok,@function |
| f_nonx30_ret_ok: |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| ldp x29, x30, [sp], #16 |
| autiasp |
| mov x16, x30 |
| // CHECK-NOT: function f_nonx30_ret_ok |
| ret x16 |
| .size f_nonx30_ret_ok, .-f_nonx30_ret_ok |
| |
| .globl f_detect_clobbered_x30_passed_to_other |
| .type f_detect_clobbered_x30_passed_to_other,@function |
| f_detect_clobbered_x30_passed_to_other: |
| str x30, [sp] |
| ldr x30, [sp] |
| // FIXME: Ideally, the pac-ret scanner would report on the following instruction, which |
| // performs a tail call, that x30 might be attacker-controlled. |
| // CHECK-NOT: function f_detect_clobbered_x30_passed_to_other |
| b f_tail_called |
| .size f_detect_clobbered_x30_passed_to_other, .-f_detect_clobbered_x30_passed_to_other |
| |
| .globl f_tail_called |
| .type f_tail_called,@function |
| f_tail_called: |
| ret |
| .size f_tail_called, .-f_tail_called |
| |
| .globl f_nonx30_ret_non_auted |
| .type f_nonx30_ret_non_auted,@function |
| f_nonx30_ret_non_auted: |
| // x1 is neither authenticated nor implicitly considered safe at function entry. |
| // Note that we assume it's fine for x30 to not be authenticated before |
| // returning to, as assuming that x30 is not attacker controlled at function |
| // entry is part (implicitly) of the pac-ret hardening scheme. |
| // |
| // CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_nonx30_ret_non_auted, basic block {{[0-9a-zA-Z.]+}}, at address |
| // CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret |
| // CHECK-NEXT: The 0 instructions that write to the affected registers after any authentication are: |
| ret x1 |
| .size f_nonx30_ret_non_auted, .-f_nonx30_ret_non_auted |
| |
| |
| .globl f_callclobbered_x30 |
| .type f_callclobbered_x30,@function |
| f_callclobbered_x30: |
| bl g |
| // CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_callclobbered_x30, basic block {{[0-9a-zA-Z.]+}}, at address |
| // CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret |
| // CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are: |
| // CHECK-NEXT: 1. {{[0-9a-f]+}}: bl |
| ret |
| .size f_callclobbered_x30, .-f_callclobbered_x30 |
| |
| .globl f_callclobbered_calleesaved |
| .type f_callclobbered_calleesaved,@function |
| f_callclobbered_calleesaved: |
| bl g |
| // CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_callclobbered_calleesaved, basic block {{[0-9a-zA-Z.]+}}, at address |
| // CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret x19 |
| // CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are: |
| // CHECK-NEXT: 1. {{[0-9a-f]+}}: bl |
| // x19, according to the Arm ABI (AAPCS) is a callee-saved register. |
| // Therefore, if function g respects the AAPCS, it should not write |
| // anything to x19. However, we can't know whether function g actually |
| // does respect the AAPCS rules, so the scanner should assume x19 can |
| // get overwritten, and report a gadget if the code does not properly |
| // deal with that. |
| // Furthermore, there's a good chance that callee-saved registers have |
| // been saved on the stack at some point during execution of the callee, |
| // and so should be considered as potentially modified by an |
| // attacker/written to. |
| ret x19 |
| .size f_callclobbered_calleesaved, .-f_callclobbered_calleesaved |
| |
| .globl f_unreachable_instruction |
| .type f_unreachable_instruction,@function |
| f_unreachable_instruction: |
| // CHECK-LABEL: GS-PAUTH: Warning: possibly imprecise CFG, the analysis quality may be degraded in this function. According to BOLT, unreachable code is found in function f_unreachable_instruction, basic block {{[0-9a-zA-Z.]+}}, at address |
| // CHECK-NEXT: The instruction is {{[0-9a-f]+}}: add x0, x1, x2 |
| // CHECK-NOT: instructions that write to the affected registers after any authentication are: |
| b 1f |
| add x0, x1, x2 |
| 1: |
| ret |
| .size f_unreachable_instruction, .-f_unreachable_instruction |
| |
| // Without CFG, the state is reset at labels, assuming every register that can |
| // be clobbered in the function was actually clobbered. |
| |
| .globl lr_untouched_nocfg |
| .type lr_untouched_nocfg,@function |
| lr_untouched_nocfg: |
| // CHECK-NOT: lr_untouched_nocfg |
| adr x2, 1f |
| br x2 |
| 1: |
| ret |
| .size lr_untouched_nocfg, .-lr_untouched_nocfg |
| |
| .globl lr_clobbered_nocfg |
| .type lr_clobbered_nocfg,@function |
| lr_clobbered_nocfg: |
| // CHECK-LABEL: GS-PAUTH: non-protected ret found in function lr_clobbered_nocfg, at address |
| // CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret |
| // CHECK-NEXT: The 0 instructions that write to the affected registers after any authentication are: |
| adr x2, 1f |
| br x2 |
| 1: |
| b 2f |
| bl g // never executed, but affects the expected worst-case scenario |
| 2: |
| ret |
| .size lr_clobbered_nocfg, .-lr_clobbered_nocfg |
| |
| /// Now do a basic sanity check on every different Authentication instruction: |
| |
| .globl f_autiasp |
| .type f_autiasp,@function |
| f_autiasp: |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| autiasp |
| // CHECK-NOT: function f_autiasp |
| ret |
| .size f_autiasp, .-f_autiasp |
| |
| .globl f_autibsp |
| .type f_autibsp,@function |
| f_autibsp: |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| autibsp |
| // CHECK-NOT: function f_autibsp |
| ret |
| .size f_autibsp, .-f_autibsp |
| |
| .globl f_autiaz |
| .type f_autiaz,@function |
| f_autiaz: |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| autiaz |
| // CHECK-NOT: function f_autiaz |
| ret |
| .size f_autiaz, .-f_autiaz |
| |
| .globl f_autibz |
| .type f_autibz,@function |
| f_autibz: |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| autibz |
| // CHECK-NOT: function f_autibz |
| ret |
| .size f_autibz, .-f_autibz |
| |
| .globl f_autia1716 |
| .type f_autia1716,@function |
| f_autia1716: |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| autia1716 |
| // CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_autia1716, basic block {{[0-9a-zA-Z.]+}}, at address |
| // CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret |
| // CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are: |
| // CHECK-NEXT: 1. {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 |
| // CHECK-NEXT: This happens in the following basic block: |
| // CHECK-NEXT: {{[0-9a-f]+}}: paciasp |
| // CHECK-NEXT: {{[0-9a-f]+}}: stp x29, x30, [sp, #-0x10]! |
| // CHECK-NEXT: {{[0-9a-f]+}}: mov x29, sp |
| // CHECK-NEXT: {{[0-9a-f]+}}: bl g |
| // CHECK-NEXT: {{[0-9a-f]+}}: add x0, x0, #0x3 |
| // CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 |
| // CHECK-NEXT: {{[0-9a-f]+}}: autia1716 |
| // CHECK-NEXT: {{[0-9a-f]+}}: ret |
| ret |
| .size f_autia1716, .-f_autia1716 |
| |
| .globl f_autib1716 |
| .type f_autib1716,@function |
| f_autib1716: |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| autib1716 |
| // CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_autib1716, basic block {{[0-9a-zA-Z.]+}}, at address |
| // CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret |
| // CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are: |
| // CHECK-NEXT: 1. {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 |
| // CHECK-NEXT: This happens in the following basic block: |
| // CHECK-NEXT: {{[0-9a-f]+}}: paciasp |
| // CHECK-NEXT: {{[0-9a-f]+}}: stp x29, x30, [sp, #-0x10]! |
| // CHECK-NEXT: {{[0-9a-f]+}}: mov x29, sp |
| // CHECK-NEXT: {{[0-9a-f]+}}: bl g |
| // CHECK-NEXT: {{[0-9a-f]+}}: add x0, x0, #0x3 |
| // CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 |
| // CHECK-NEXT: {{[0-9a-f]+}}: autib1716 |
| // CHECK-NEXT: {{[0-9a-f]+}}: ret |
| ret |
| .size f_autib1716, .-f_autib1716 |
| |
| .globl f_autiax12 |
| .type f_autiax12,@function |
| f_autiax12: |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| autia x12, sp |
| // CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_autiax12, basic block {{[0-9a-zA-Z.]+}}, at address |
| // CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret |
| // CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are: |
| // CHECK-NEXT: 1. {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 |
| // CHECK-NEXT: This happens in the following basic block: |
| // CHECK-NEXT: {{[0-9a-f]+}}: paciasp |
| // CHECK-NEXT: {{[0-9a-f]+}}: stp x29, x30, [sp, #-0x10]! |
| // CHECK-NEXT: {{[0-9a-f]+}}: mov x29, sp |
| // CHECK-NEXT: {{[0-9a-f]+}}: bl g |
| // CHECK-NEXT: {{[0-9a-f]+}}: add x0, x0, #0x3 |
| // CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 |
| // CHECK-NEXT: {{[0-9a-f]+}}: autia x12, sp |
| // CHECK-NEXT: {{[0-9a-f]+}}: ret |
| ret |
| .size f_autiax12, .-f_autiax12 |
| |
| .globl f_autibx12 |
| .type f_autibx12,@function |
| f_autibx12: |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| autib x12, sp |
| // CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_autibx12, basic block {{[0-9a-zA-Z.]+}}, at address |
| // CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret |
| // CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are: |
| // CHECK-NEXT: 1. {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 |
| // CHECK-NEXT: This happens in the following basic block: |
| // CHECK-NEXT: {{[0-9a-f]+}}: paciasp |
| // CHECK-NEXT: {{[0-9a-f]+}}: stp x29, x30, [sp, #-0x10]! |
| // CHECK-NEXT: {{[0-9a-f]+}}: mov x29, sp |
| // CHECK-NEXT: {{[0-9a-f]+}}: bl g |
| // CHECK-NEXT: {{[0-9a-f]+}}: add x0, x0, #0x3 |
| // CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 |
| // CHECK-NEXT: {{[0-9a-f]+}}: autib x12, sp |
| // CHECK-NEXT: {{[0-9a-f]+}}: ret |
| ret |
| .size f_autibx12, .-f_autibx12 |
| |
| .globl f_autiax30 |
| .type f_autiax30,@function |
| f_autiax30: |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| autia x30, sp |
| // CHECK-NOT: function f_autiax30 |
| ret |
| .size f_autiax30, .-f_autiax30 |
| |
| .globl f_autibx30 |
| .type f_autibx30,@function |
| f_autibx30: |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| autib x30, sp |
| // CHECK-NOT: function f_autibx30 |
| ret |
| .size f_autibx30, .-f_autibx30 |
| |
| |
| .globl f_autdax12 |
| .type f_autdax12,@function |
| f_autdax12: |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| autda x12, sp |
| // CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_autdax12, basic block {{[0-9a-zA-Z.]+}}, at address |
| // CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret |
| // CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are: |
| // CHECK-NEXT: 1. {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 |
| // CHECK-NEXT: This happens in the following basic block: |
| // CHECK-NEXT: {{[0-9a-f]+}}: paciasp |
| // CHECK-NEXT: {{[0-9a-f]+}}: stp x29, x30, [sp, #-0x10]! |
| // CHECK-NEXT: {{[0-9a-f]+}}: mov x29, sp |
| // CHECK-NEXT: {{[0-9a-f]+}}: bl g |
| // CHECK-NEXT: {{[0-9a-f]+}}: add x0, x0, #0x3 |
| // CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 |
| // CHECK-NEXT: {{[0-9a-f]+}}: autda x12, sp |
| // CHECK-NEXT: {{[0-9a-f]+}}: ret |
| ret |
| .size f_autdax12, .-f_autdax12 |
| |
| .globl f_autdbx12 |
| .type f_autdbx12,@function |
| f_autdbx12: |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| autdb x12, sp |
| // CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_autdbx12, basic block {{[0-9a-zA-Z.]+}}, at address |
| // CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret |
| // CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are: |
| // CHECK-NEXT: 1. {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 |
| // CHECK-NEXT: This happens in the following basic block: |
| // CHECK-NEXT: {{[0-9a-f]+}}: paciasp |
| // CHECK-NEXT: {{[0-9a-f]+}}: stp x29, x30, [sp, #-0x10]! |
| // CHECK-NEXT: {{[0-9a-f]+}}: mov x29, sp |
| // CHECK-NEXT: {{[0-9a-f]+}}: bl g |
| // CHECK-NEXT: {{[0-9a-f]+}}: add x0, x0, #0x3 |
| // CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 |
| // CHECK-NEXT: {{[0-9a-f]+}}: autdb x12, sp |
| // CHECK-NEXT: {{[0-9a-f]+}}: ret |
| ret |
| .size f_autdbx12, .-f_autdbx12 |
| |
| .globl f_autdax30 |
| .type f_autdax30,@function |
| f_autdax30: |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| autda x30, sp |
| // CHECK-NOT: function f_autdax30 |
| ret |
| .size f_autdax30, .-f_autdax30 |
| |
| .globl f_autdbx30 |
| .type f_autdbx30,@function |
| f_autdbx30: |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| autdb x30, sp |
| // CHECK-NOT: function f_autdbx30 |
| ret |
| .size f_autdbx30, .-f_autdbx30 |
| |
| |
| .globl f_autizax12 |
| .type f_autizax12,@function |
| f_autizax12: |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| autiza x12 |
| // CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_autizax12, basic block {{[0-9a-zA-Z.]+}}, at address |
| // CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret |
| // CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are: |
| // CHECK-NEXT: 1. {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 |
| // CHECK-NEXT: This happens in the following basic block: |
| // CHECK-NEXT: {{[0-9a-f]+}}: paciasp |
| // CHECK-NEXT: {{[0-9a-f]+}}: stp x29, x30, [sp, #-0x10]! |
| // CHECK-NEXT: {{[0-9a-f]+}}: mov x29, sp |
| // CHECK-NEXT: {{[0-9a-f]+}}: bl g |
| // CHECK-NEXT: {{[0-9a-f]+}}: add x0, x0, #0x3 |
| // CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 |
| // CHECK-NEXT: {{[0-9a-f]+}}: autiza x12 |
| // CHECK-NEXT: {{[0-9a-f]+}}: ret |
| ret |
| .size f_autizax12, .-f_autizax12 |
| |
| .globl f_autizbx12 |
| .type f_autizbx12,@function |
| f_autizbx12: |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| autizb x12 |
| // CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_autizbx12, basic block {{[0-9a-zA-Z.]+}}, at address |
| // CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret |
| // CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are: |
| // CHECK-NEXT: 1. {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 |
| // CHECK-NEXT: This happens in the following basic block: |
| // CHECK-NEXT: {{[0-9a-f]+}}: paciasp |
| // CHECK-NEXT: {{[0-9a-f]+}}: stp x29, x30, [sp, #-0x10]! |
| // CHECK-NEXT: {{[0-9a-f]+}}: mov x29, sp |
| // CHECK-NEXT: {{[0-9a-f]+}}: bl g |
| // CHECK-NEXT: {{[0-9a-f]+}}: add x0, x0, #0x3 |
| // CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 |
| // CHECK-NEXT: {{[0-9a-f]+}}: autizb x12 |
| // CHECK-NEXT: {{[0-9a-f]+}}: ret |
| ret |
| .size f_autizbx12, .-f_autizbx12 |
| |
| .globl f_autizax30 |
| .type f_autizax30,@function |
| f_autizax30: |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| autiza x30 |
| // CHECK-NOT: function f_autizax30 |
| ret |
| .size f_autizax30, .-f_autizax30 |
| |
| .globl f_autizbx30 |
| .type f_autizbx30,@function |
| f_autizbx30: |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| autizb x30 |
| // CHECK-NOT: function f_autizbx30 |
| ret |
| .size f_autizbx30, .-f_autizbx30 |
| |
| |
| .globl f_autdzax12 |
| .type f_autdzax12,@function |
| f_autdzax12: |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| autdza x12 |
| // CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_autdzax12, basic block {{[0-9a-zA-Z.]+}}, at address |
| // CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret |
| // CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are: |
| // CHECK-NEXT: 1. {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 |
| // CHECK-NEXT: This happens in the following basic block: |
| // CHECK-NEXT: {{[0-9a-f]+}}: paciasp |
| // CHECK-NEXT: {{[0-9a-f]+}}: stp x29, x30, [sp, #-0x10]! |
| // CHECK-NEXT: {{[0-9a-f]+}}: mov x29, sp |
| // CHECK-NEXT: {{[0-9a-f]+}}: bl g |
| // CHECK-NEXT: {{[0-9a-f]+}}: add x0, x0, #0x3 |
| // CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 |
| // CHECK-NEXT: {{[0-9a-f]+}}: autdza x12 |
| // CHECK-NEXT: {{[0-9a-f]+}}: ret |
| ret |
| .size f_autdzax12, .-f_autdzax12 |
| |
| .globl f_autdzbx12 |
| .type f_autdzbx12,@function |
| f_autdzbx12: |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| autdzb x12 |
| // CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_autdzbx12, basic block {{[0-9a-zA-Z.]+}}, at address |
| // CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret |
| // CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are: |
| // CHECK-NEXT: 1. {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 |
| // CHECK-NEXT: This happens in the following basic block: |
| // CHECK-NEXT: {{[0-9a-f]+}}: paciasp |
| // CHECK-NEXT: {{[0-9a-f]+}}: stp x29, x30, [sp, #-0x10]! |
| // CHECK-NEXT: {{[0-9a-f]+}}: mov x29, sp |
| // CHECK-NEXT: {{[0-9a-f]+}}: bl g |
| // CHECK-NEXT: {{[0-9a-f]+}}: add x0, x0, #0x3 |
| // CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 |
| // CHECK-NEXT: {{[0-9a-f]+}}: autdzb x12 |
| // CHECK-NEXT: {{[0-9a-f]+}}: ret |
| ret |
| .size f_autdzbx12, .-f_autdzbx12 |
| |
| .globl f_autdzax30 |
| .type f_autdzax30,@function |
| f_autdzax30: |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| autdza x30 |
| // CHECK-NOT: function f_autdzax30 |
| ret |
| .size f_autdzax30, .-f_autdzax30 |
| |
| .globl f_autdzbx30 |
| .type f_autdzbx30,@function |
| f_autdzbx30: |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| autdzb x30 |
| // CHECK-NOT: function f_autdzbx30 |
| ret |
| .size f_autdzbx30, .-f_autdzbx30 |
| |
| .globl f_retaa |
| .type f_retaa,@function |
| f_retaa: |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| // CHECK-NOT: function f_retaa |
| retaa |
| .size f_retaa, .-f_retaa |
| |
| .globl f_retab |
| .type f_retab,@function |
| f_retab: |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| // CHECK-NOT: function f_retab |
| retab |
| .size f_retab, .-f_retab |
| |
| .globl f_eretaa |
| .type f_eretaa,@function |
| f_eretaa: |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| // CHECK-LABEL: GS-PAUTH: Warning: pac-ret analysis could not analyze this return instruction in function f_eretaa, basic block {{[0-9a-zA-Z.]+}}, at address |
| // CHECK-NEXT: The instruction is {{[0-9a-f]+}}: eretaa |
| eretaa |
| .size f_eretaa, .-f_eretaa |
| |
| .globl f_eretab |
| .type f_eretab,@function |
| f_eretab: |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| // CHECK-LABEL: GS-PAUTH: Warning: pac-ret analysis could not analyze this return instruction in function f_eretab, basic block {{[0-9a-zA-Z.]+}}, at address |
| // CHECK-NEXT: The instruction is {{[0-9a-f]+}}: eretab |
| eretab |
| .size f_eretab, .-f_eretab |
| |
| .globl f_eret |
| .type f_eret,@function |
| f_eret: |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| // CHECK-LABEL: GS-PAUTH: Warning: pac-ret analysis could not analyze this return instruction in function f_eret, basic block {{[0-9a-zA-Z.]+}}, at address |
| // CHECK-NEXT: The instruction is {{[0-9a-f]+}}: eret |
| eret |
| .size f_eret, .-f_eret |
| |
| .globl f_movx30reg |
| .type f_movx30reg,@function |
| f_movx30reg: |
| // CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_movx30reg, basic block {{[0-9a-zA-Z.]+}}, at address |
| // CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret |
| // CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are: |
| // CHECK-NEXT: 1. {{[0-9a-f]+}}: mov x30, x22 |
| // CHECK-NEXT: This happens in the following basic block: |
| // CHECK-NEXT: {{[0-9a-f]+}}: mov x30, x22 |
| // CHECK-NEXT: {{[0-9a-f]+}}: ret |
| mov x30, x22 |
| ret |
| .size f_movx30reg, .-f_movx30reg |
| |
| .globl f_autiasppci |
| .type f_autiasppci,@function |
| f_autiasppci: |
| 0: |
| pacnbiasppc |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| autiasppc 0b |
| // CHECK-NOT: function f_autiasppci |
| ret |
| .size f_autiasppci, .-f_autiasppci |
| |
| .globl f_autibsppci |
| .type f_autibsppci,@function |
| f_autibsppci: |
| 0: |
| pacnbibsppc |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| autibsppc 0b |
| // CHECK-NOT: function f_autibsppci |
| ret |
| .size f_autibsppci, .-f_autibsppci |
| |
| .globl f_autiasppcr |
| .type f_autiasppcr,@function |
| |
| f_autiasppcr: |
| 0: |
| pacnbiasppc |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| adr x28, 0b |
| autiasppcr x28 |
| // CHECK-NOT: function f_autiasppcr |
| ret |
| .size f_autiasppcr, .-f_autiasppcr |
| |
| f_autibsppcr: |
| 0: |
| pacnbibsppc |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| adr x28, 0b |
| autibsppcr x28 |
| // CHECK-NOT: function f_autibsppcr |
| ret |
| .size f_autibsppcr, .-f_autibsppcr |
| |
| .globl f_retaasppci |
| .type f_retaasppci,@function |
| f_retaasppci: |
| 0: |
| pacnbiasppc |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| // CHECK-NOT: function f_retaasppci |
| retaasppc 0b |
| .size f_retaasppci, .-f_retaasppci |
| |
| .globl f_retabsppci |
| .type f_retabsppci,@function |
| f_retabsppci: |
| 0: |
| pacnbibsppc |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| // CHECK-NOT: function f_retabsppci |
| retabsppc 0b |
| .size f_retabsppci, .-f_retabsppci |
| |
| .globl f_retaasppcr |
| .type f_retaasppcr,@function |
| |
| f_retaasppcr: |
| 0: |
| pacnbiasppc |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| adr x28, 0b |
| // CHECK-NOT: function f_retaasppcr |
| retaasppcr x28 |
| .size f_retaasppcr, .-f_retaasppcr |
| |
| f_retabsppcr: |
| 0: |
| pacnbibsppc |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| adr x28, 0b |
| // CHECK-NOT: function f_retabsppcr |
| retabsppcr x28 |
| .size f_retabsppcr, .-f_retabsppcr |
| |
| .globl f_autia171615 |
| .type f_autia171615,@function |
| f_autia171615: |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| autia171615 |
| // CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_autia171615, basic block {{[0-9a-zA-Z.]+}}, at address |
| // CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret |
| // CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are: |
| // CHECK-NEXT: 1. {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 |
| // CHECK-NEXT: This happens in the following basic block: |
| // CHECK-NEXT: {{[0-9a-f]+}}: paciasp |
| // CHECK-NEXT: {{[0-9a-f]+}}: stp x29, x30, [sp, #-0x10]! |
| // CHECK-NEXT: {{[0-9a-f]+}}: mov x29, sp |
| // CHECK-NEXT: {{[0-9a-f]+}}: bl g |
| // CHECK-NEXT: {{[0-9a-f]+}}: add x0, x0, #0x3 |
| // CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 |
| // CHECK-NEXT: {{[0-9a-f]+}}: autia171615 |
| // CHECK-NEXT: {{[0-9a-f]+}}: ret |
| ret |
| .size f_autia171615, .-f_autia171615 |
| |
| .globl f_autib171615 |
| .type f_autib171615,@function |
| f_autib171615: |
| paciasp |
| stp x29, x30, [sp, #-16]! |
| mov x29, sp |
| bl g |
| add x0, x0, #3 |
| ldp x29, x30, [sp], #16 |
| autib171615 |
| // CHECK-LABEL: GS-PAUTH: non-protected ret found in function f_autib171615, basic block {{[0-9a-zA-Z.]+}}, at address |
| // CHECK-NEXT: The instruction is {{[0-9a-f]+}}: ret |
| // CHECK-NEXT: The 1 instructions that write to the affected registers after any authentication are: |
| // CHECK-NEXT: 1. {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 |
| // CHECK-NEXT: This happens in the following basic block: |
| // CHECK-NEXT: {{[0-9a-f]+}}: paciasp |
| // CHECK-NEXT: {{[0-9a-f]+}}: stp x29, x30, [sp, #-0x10]! |
| // CHECK-NEXT: {{[0-9a-f]+}}: mov x29, sp |
| // CHECK-NEXT: {{[0-9a-f]+}}: bl g |
| // CHECK-NEXT: {{[0-9a-f]+}}: add x0, x0, #0x3 |
| // CHECK-NEXT: {{[0-9a-f]+}}: ldp x29, x30, [sp], #0x10 |
| // CHECK-NEXT: {{[0-9a-f]+}}: autib171615 |
| // CHECK-NEXT: {{[0-9a-f]+}}: ret |
| ret |
| .size f_autib171615, .-f_autib171615 |
| |
| .globl g |
| .type g,@function |
| g: |
| nop |
| ret |
| .size g, .-g |