| ; RUN: rm -rf %t && split-file %s %t && cd %t |
| |
| ;--- err1.ll |
| |
| ; RUN: not --crash llc < err1.ll -mtriple aarch64-elf -mattr=+pauth \ |
| ; RUN: -global-isel=0 -verify-machineinstrs 2>&1 | FileCheck --check-prefix=ERR1 %s |
| ; RUN: not --crash llc < err1.ll -mtriple arm64-apple-ios -mattr=+pauth \ |
| ; RUN: -global-isel=0 -verify-machineinstrs 2>&1 | FileCheck --check-prefix=ERR1 %s |
| |
| @g = external global i32 |
| |
| define ptr @foo() { |
| ; ERR1: LLVM ERROR: key in ptrauth global out of range [0, 3] |
| ret ptr ptrauth (ptr @g, i32 4) |
| } |
| |
| ;--- err2.ll |
| |
| ; RUN: not --crash llc < err2.ll -mtriple aarch64-elf -mattr=+pauth \ |
| ; RUN: -global-isel=0 -verify-machineinstrs 2>&1 | FileCheck --check-prefix=ERR2 %s |
| ; RUN: not --crash llc < err2.ll -mtriple arm64-apple-ios -mattr=+pauth \ |
| ; RUN: -global-isel=0 -verify-machineinstrs 2>&1 | FileCheck --check-prefix=ERR2 %s |
| |
| @g = external global i32 |
| |
| define ptr @foo() { |
| ; ERR2: LLVM ERROR: constant discriminator in ptrauth global out of range [0, 0xffff] |
| ret ptr ptrauth (ptr @g, i32 2, i64 65536) |
| } |
| |
| ;--- err3.ll |
| |
| ; RUN: not --crash llc < err3.ll -mtriple aarch64-elf -mattr=+pauth \ |
| ; RUN: -global-isel=0 -verify-machineinstrs 2>&1 | FileCheck --check-prefix=ERR3 %s |
| ; RUN: not --crash llc < err3.ll -mtriple arm64-apple-ios -mattr=+pauth \ |
| ; RUN: -global-isel=0 -verify-machineinstrs 2>&1 | FileCheck --check-prefix=ERR3 %s |
| |
| @g_weak = extern_weak global i32 |
| |
| define ptr @foo() { |
| ; ERR3: LLVM ERROR: unsupported non-zero offset in weak ptrauth global reference |
| ret ptr ptrauth (ptr getelementptr (i8, ptr @g_weak, i64 16), i32 2, i64 42) |
| } |
| |
| ;--- err4.ll |
| |
| ; RUN: not --crash llc < err4.ll -mtriple aarch64-elf -mattr=+pauth \ |
| ; RUN: -global-isel=0 -verify-machineinstrs 2>&1 | FileCheck --check-prefix=ERR4 %s |
| ; RUN: not --crash llc < err4.ll -mtriple arm64-apple-ios -mattr=+pauth \ |
| ; RUN: -global-isel=0 -verify-machineinstrs 2>&1 | FileCheck --check-prefix=ERR4 %s |
| |
| @g_weak = extern_weak global i32 |
| @g_weak.ref.da.42.addr = dso_local constant ptr ptrauth (ptr @g_weak, i32 2, i64 42, ptr @g_weak.ref.da.42.addr) |
| |
| define ptr @foo() { |
| ; ERR4: LLVM ERROR: unsupported weak addr-div ptrauth global |
| ret ptr ptrauth (ptr @g_weak, i32 0, i64 42, ptr @g_weak.ref.da.42.addr) |
| } |
| |
| ;--- err5.ll |
| |
| ; RUN: not --crash llc < err5.ll -mtriple aarch64-windows -mattr=+pauth \ |
| ; RUN: -global-isel=0 -verify-machineinstrs 2>&1 | FileCheck --check-prefix=ERR5 %s |
| |
| @g = external global i32 |
| |
| define ptr @foo() { |
| ; ERR5: LLVM ERROR: ptrauth global lowering only supported on MachO/ELF |
| ret ptr ptrauth (ptr @g, i32 0) |
| } |
| |
| ;--- ok.ll |
| |
| ; RUN: llc < ok.ll -mtriple aarch64-elf -mattr=+pauth -global-isel=0 \ |
| ; RUN: -verify-machineinstrs | FileCheck %s --check-prefix=ELF |
| ; RUN: llc < ok.ll -mtriple aarch64-elf -mattr=+pauth -global-isel=0 \ |
| ; RUN: -verify-machineinstrs -filetype=obj |
| |
| ; RUN: llc < ok.ll -mtriple arm64-apple-ios -mattr=+pauth -global-isel=0 \ |
| ; RUN: -verify-machineinstrs | FileCheck %s --check-prefix=MACHO |
| ; RUN: llc < ok.ll -mtriple arm64-apple-ios -mattr=+pauth -global-isel=0 \ |
| ; RUN: -verify-machineinstrs -filetype=obj |
| |
| @g = external global i32 |
| @g_weak = extern_weak global i32 |
| @g_strong_def = dso_local constant i32 42 |
| |
| define ptr @test_global_zero_disc() { |
| ; ELF-LABEL: test_global_zero_disc: |
| ; ELF: // %bb.0: |
| ; ELF-NEXT: adrp x16, :got:g |
| ; ELF-NEXT: ldr x16, [x16, :got_lo12:g] |
| ; ELF-NEXT: paciza x16 |
| ; ELF-NEXT: mov x0, x16 |
| ; ELF-NEXT: ret |
| |
| ; MACHO-LABEL: _test_global_zero_disc: |
| ; MACHO: ; %bb.0: |
| ; MACHO-NEXT: adrp x16, _g@GOTPAGE |
| ; MACHO-NEXT: ldr x16, [x16, _g@GOTPAGEOFF] |
| ; MACHO-NEXT: paciza x16 |
| ; MACHO-NEXT: mov x0, x16 |
| ; MACHO-NEXT: ret |
| |
| ret ptr ptrauth (ptr @g, i32 0) |
| } |
| |
| define ptr @test_global_offset_zero_disc() { |
| ; ELF-LABEL: test_global_offset_zero_disc: |
| ; ELF: // %bb.0: |
| ; ELF-NEXT: adrp x16, :got:g |
| ; ELF-NEXT: ldr x16, [x16, :got_lo12:g] |
| ; ELF-NEXT: add x16, x16, #16 |
| ; ELF-NEXT: pacdza x16 |
| ; ELF-NEXT: mov x0, x16 |
| ; ELF-NEXT: ret |
| |
| ; MACHO-LABEL: _test_global_offset_zero_disc: |
| ; MACHO: ; %bb.0: |
| ; MACHO-NEXT: adrp x16, _g@GOTPAGE |
| ; MACHO-NEXT: ldr x16, [x16, _g@GOTPAGEOFF] |
| ; MACHO-NEXT: add x16, x16, #16 |
| ; MACHO-NEXT: pacdza x16 |
| ; MACHO-NEXT: mov x0, x16 |
| ; MACHO-NEXT: ret |
| |
| ret ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 16), i32 2) |
| } |
| |
| define ptr @test_global_neg_offset_zero_disc() { |
| ; ELF-LABEL: test_global_neg_offset_zero_disc: |
| ; ELF: // %bb.0: |
| ; ELF-NEXT: adrp x16, :got:g |
| ; ELF-NEXT: ldr x16, [x16, :got_lo12:g] |
| ; ELF-NEXT: sub x16, x16, #576 |
| ; ELF-NEXT: sub x16, x16, #30, lsl #12 |
| ; ELF-NEXT: pacdza x16 |
| ; ELF-NEXT: mov x0, x16 |
| ; ELF-NEXT: ret |
| |
| ; MACHO-LABEL: _test_global_neg_offset_zero_disc: |
| ; MACHO: ; %bb.0: |
| ; MACHO-NEXT: adrp x16, _g@GOTPAGE |
| ; MACHO-NEXT: ldr x16, [x16, _g@GOTPAGEOFF] |
| ; MACHO-NEXT: sub x16, x16, #576 |
| ; MACHO-NEXT: sub x16, x16, #30, lsl #12 |
| ; MACHO-NEXT: pacdza x16 |
| ; MACHO-NEXT: mov x0, x16 |
| ; MACHO-NEXT: ret |
| |
| ret ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 -123456), i32 2) |
| } |
| |
| define ptr @test_global_big_offset_zero_disc() { |
| ; ELF-LABEL: test_global_big_offset_zero_disc: |
| ; ELF: // %bb.0: |
| ; ELF-NEXT: adrp x16, :got:g |
| ; ELF-NEXT: ldr x16, [x16, :got_lo12:g] |
| ; ELF-NEXT: mov x17, #1 |
| ; ELF-NEXT: movk x17, #32769, lsl #16 |
| ; ELF-NEXT: add x16, x16, x17 |
| ; ELF-NEXT: pacdza x16 |
| ; ELF-NEXT: mov x0, x16 |
| ; ELF-NEXT: ret |
| |
| ; MACHO-LABEL: _test_global_big_offset_zero_disc: |
| ; MACHO: ; %bb.0: |
| ; MACHO-NEXT: adrp x16, _g@GOTPAGE |
| ; MACHO-NEXT: ldr x16, [x16, _g@GOTPAGEOFF] |
| ; MACHO-NEXT: mov x17, #1 |
| ; MACHO-NEXT: movk x17, #32769, lsl #16 |
| ; MACHO-NEXT: add x16, x16, x17 |
| ; MACHO-NEXT: pacdza x16 |
| ; MACHO-NEXT: mov x0, x16 |
| ; MACHO-NEXT: ret |
| |
| ret ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 add (i64 2147483648, i64 65537)), i32 2) |
| } |
| |
| define ptr @test_global_big_neg_offset_zero_disc() { |
| ; ELF-LABEL: test_global_big_neg_offset_zero_disc: |
| ; ELF: // %bb.0: |
| ; ELF-NEXT: adrp x16, :got:g |
| ; ELF-NEXT: ldr x16, [x16, :got_lo12:g] |
| ; ELF-NEXT: mov x17, #-52501 |
| ; ELF-NEXT: movk x17, #63652, lsl #16 |
| ; ELF-NEXT: add x16, x16, x17 |
| ; ELF-NEXT: pacdza x16 |
| ; ELF-NEXT: mov x0, x16 |
| ; ELF-NEXT: ret |
| |
| ; MACHO-LABEL: _test_global_big_neg_offset_zero_disc: |
| ; MACHO: ; %bb.0: |
| ; MACHO-NEXT: adrp x16, _g@GOTPAGE |
| ; MACHO-NEXT: ldr x16, [x16, _g@GOTPAGEOFF] |
| ; MACHO-NEXT: mov x17, #-52501 |
| ; MACHO-NEXT: movk x17, #63652, lsl #16 |
| ; MACHO-NEXT: add x16, x16, x17 |
| ; MACHO-NEXT: pacdza x16 |
| ; MACHO-NEXT: mov x0, x16 |
| ; MACHO-NEXT: ret |
| |
| ret ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 -123456789), i32 2) |
| } |
| |
| define ptr @test_global_huge_neg_offset_zero_disc() { |
| ; ELF-LABEL: test_global_huge_neg_offset_zero_disc: |
| ; ELF: // %bb.0: |
| ; ELF-NEXT: adrp x16, :got:g |
| ; ELF-NEXT: ldr x16, [x16, :got_lo12:g] |
| ; ELF-NEXT: mov x17, #-65536 |
| ; ELF-NEXT: movk x17, #0, lsl #16 |
| ; ELF-NEXT: movk x17, #0, lsl #32 |
| ; ELF-NEXT: movk x17, #32768, lsl #48 |
| ; ELF-NEXT: add x16, x16, x17 |
| ; ELF-NEXT: pacdza x16 |
| ; ELF-NEXT: mov x0, x16 |
| ; ELF-NEXT: ret |
| |
| ; MACHO-LABEL: _test_global_huge_neg_offset_zero_disc: |
| ; MACHO: ; %bb.0: |
| ; MACHO-NEXT: adrp x16, _g@GOTPAGE |
| ; MACHO-NEXT: ldr x16, [x16, _g@GOTPAGEOFF] |
| ; MACHO-NEXT: mov x17, #-65536 |
| ; MACHO-NEXT: movk x17, #0, lsl #16 |
| ; MACHO-NEXT: movk x17, #0, lsl #32 |
| ; MACHO-NEXT: movk x17, #32768, lsl #48 |
| ; MACHO-NEXT: add x16, x16, x17 |
| ; MACHO-NEXT: pacdza x16 |
| ; MACHO-NEXT: mov x0, x16 |
| ; MACHO-NEXT: ret |
| |
| ret ptr ptrauth (ptr getelementptr (i8, ptr @g, i64 -9223372036854775808), i32 2) |
| } |
| |
| define ptr @test_global_disc() { |
| ; ELF-LABEL: test_global_disc: |
| ; ELF: // %bb.0: |
| ; ELF-NEXT: adrp x16, :got:g |
| ; ELF-NEXT: ldr x16, [x16, :got_lo12:g] |
| ; ELF-NEXT: mov x17, #42 // =0x2a |
| ; ELF-NEXT: pacia x16, x17 |
| ; ELF-NEXT: mov x0, x16 |
| ; ELF-NEXT: ret |
| |
| ; MACHO-LABEL: _test_global_disc: |
| ; MACHO: ; %bb.0: |
| ; MACHO-NEXT: adrp x16, _g@GOTPAGE |
| ; MACHO-NEXT: ldr x16, [x16, _g@GOTPAGEOFF] |
| ; MACHO-NEXT: mov x17, #42 ; =0x2a |
| ; MACHO-NEXT: pacia x16, x17 |
| ; MACHO-NEXT: mov x0, x16 |
| ; MACHO-NEXT: ret |
| |
| ret ptr ptrauth (ptr @g, i32 0, i64 42) |
| } |
| |
| @g.ref.da.42.addr = dso_local constant ptr ptrauth (ptr @g, i32 2, i64 42, ptr @g.ref.da.42.addr) |
| |
| define ptr @test_global_addr_disc() { |
| ; ELF-LABEL: test_global_addr_disc: |
| ; ELF: // %bb.0: |
| ; ELF-NEXT: adrp x8, g.ref.da.42.addr |
| ; ELF-NEXT: add x8, x8, :lo12:g.ref.da.42.addr |
| ; ELF-NEXT: adrp x16, :got:g |
| ; ELF-NEXT: ldr x16, [x16, :got_lo12:g] |
| ; ELF-NEXT: mov x17, x8 |
| ; ELF-NEXT: movk x17, #42, lsl #48 |
| ; ELF-NEXT: pacda x16, x17 |
| ; ELF-NEXT: mov x0, x16 |
| ; ELF-NEXT: ret |
| |
| ; MACHO-LABEL: _test_global_addr_disc: |
| ; MACHO: ; %bb.0: |
| ; MACHO-NEXT: Lloh{{.*}}: |
| ; MACHO-NEXT: adrp x8, _g.ref.da.42.addr@PAGE |
| ; MACHO-NEXT: Lloh{{.*}}: |
| ; MACHO-NEXT: add x8, x8, _g.ref.da.42.addr@PAGEOFF |
| ; MACHO-NEXT: adrp x16, _g@GOTPAGE |
| ; MACHO-NEXT: ldr x16, [x16, _g@GOTPAGEOFF] |
| ; MACHO-NEXT: mov x17, x8 |
| ; MACHO-NEXT: movk x17, #42, lsl #48 |
| ; MACHO-NEXT: pacda x16, x17 |
| ; MACHO-NEXT: mov x0, x16 |
| ; MACHO-NEXT: ret |
| |
| ret ptr ptrauth (ptr @g, i32 2, i64 42, ptr @g.ref.da.42.addr) |
| } |
| |
| define ptr @test_global_process_specific() { |
| ; ELF-LABEL: test_global_process_specific: |
| ; ELF: // %bb.0: |
| ; ELF-NEXT: adrp x16, :got:g |
| ; ELF-NEXT: ldr x16, [x16, :got_lo12:g] |
| ; ELF-NEXT: pacizb x16 |
| ; ELF-NEXT: mov x0, x16 |
| ; ELF-NEXT: ret |
| |
| ; MACHO-LABEL: _test_global_process_specific: |
| ; MACHO: ; %bb.0: |
| ; MACHO-NEXT: adrp x16, _g@GOTPAGE |
| ; MACHO-NEXT: ldr x16, [x16, _g@GOTPAGEOFF] |
| ; MACHO-NEXT: pacizb x16 |
| ; MACHO-NEXT: mov x0, x16 |
| ; MACHO-NEXT: ret |
| |
| ret ptr ptrauth (ptr @g, i32 1) |
| } |
| |
| ; Non-external symbols don't need to be accessed through the GOT. |
| |
| define ptr @test_global_strong_def() { |
| ; ELF-LABEL: test_global_strong_def: |
| ; ELF: // %bb.0: |
| ; ELF-NEXT: adrp x16, g_strong_def |
| ; ELF-NEXT: add x16, x16, :lo12:g_strong_def |
| ; ELF-NEXT: pacdza x16 |
| ; ELF-NEXT: mov x0, x16 |
| ; ELF-NEXT: ret |
| |
| ; MACHO-LABEL: _test_global_strong_def: |
| ; MACHO: ; %bb.0: |
| ; MACHO-NEXT: adrp x16, _g_strong_def@PAGE |
| ; MACHO-NEXT: add x16, x16, _g_strong_def@PAGEOFF |
| ; MACHO-NEXT: pacdza x16 |
| ; MACHO-NEXT: mov x0, x16 |
| ; MACHO-NEXT: ret |
| |
| ret ptr ptrauth (ptr @g_strong_def, i32 2) |
| } |
| |
| ; weak symbols can't be assumed to be non-nil. Use $auth_ptr$ stub slot always. |
| ; The alternative is to emit a null-check here, but that'd be redundant with |
| ; whatever null-check follows in user code. |
| |
| define ptr @test_global_weak() { |
| ; ELF-LABEL: test_global_weak: |
| ; ELF: // %bb.0: |
| ; ELF-NEXT: adrp x0, g_weak$auth_ptr$ia$42 |
| ; ELF-NEXT: ldr x0, [x0, :lo12:g_weak$auth_ptr$ia$42] |
| ; ELF-NEXT: ret |
| |
| ; MACHO-LABEL: _test_global_weak: |
| ; MACHO: ; %bb.0: |
| ; MACHO-NEXT: adrp x0, l_g_weak$auth_ptr$ia$42@PAGE |
| ; MACHO-NEXT: ldr x0, [x0, l_g_weak$auth_ptr$ia$42@PAGEOFF] |
| ; MACHO-NEXT: ret |
| |
| ret ptr ptrauth (ptr @g_weak, i32 0, i64 42) |
| } |
| |
| ; Test another weak symbol to check that stubs are emitted in a stable order. |
| |
| @g_weak_2 = extern_weak global i32 |
| |
| define ptr @test_global_weak_2() { |
| ; ELF-LABEL: test_global_weak_2: |
| ; ELF: // %bb.0: |
| ; ELF-NEXT: adrp x0, g_weak_2$auth_ptr$ia$42 |
| ; ELF-NEXT: ldr x0, [x0, :lo12:g_weak_2$auth_ptr$ia$42] |
| ; ELF-NEXT: ret |
| |
| ; MACHO-LABEL: _test_global_weak_2: |
| ; MACHO: ; %bb.0: |
| ; MACHO-NEXT: adrp x0, l_g_weak_2$auth_ptr$ia$42@PAGE |
| ; MACHO-NEXT: ldr x0, [x0, l_g_weak_2$auth_ptr$ia$42@PAGEOFF] |
| ; MACHO-NEXT: ret |
| |
| ret ptr ptrauth (ptr @g_weak_2, i32 0, i64 42) |
| } |
| |
| ; ELF-LABEL: g_weak$auth_ptr$ia$42: |
| ; ELF-NEXT: .xword g_weak@AUTH(ia,42) |
| ; ELF-LABEL: g_weak_2$auth_ptr$ia$42: |
| ; ELF-NEXT: .xword g_weak_2@AUTH(ia,42) |
| |
| ; MACHO-LABEL: l_g_weak$auth_ptr$ia$42: |
| ; MACHO-NEXT: .quad _g_weak@AUTH(ia,42) |
| ; MACHO-LABEL: l_g_weak_2$auth_ptr$ia$42: |
| ; MACHO-NEXT: .quad _g_weak_2@AUTH(ia,42) |