[AArch64] PR92424: Fix -fpatchable-function-entry=N,M with BTI
authorSzabolcs Nagy <szabolcs.nagy@arm.com>
Wed, 15 Jan 2020 12:23:40 +0000 (12:23 +0000)
committerSzabolcs Nagy <szabolcs.nagy@arm.com>
Tue, 21 Jan 2020 15:54:44 +0000 (15:54 +0000)
commitc292cfe539cd7c060caad826d362ed5e845bfbef
treedba81b6eb7a852688dedbc8b11da1da2b06d128f
parent65be83b5ac0410a5e64c648c36aaf4bd10d09bf2
[AArch64] PR92424: Fix -fpatchable-function-entry=N,M with BTI

This is a workaround that emits a BTI after the function label if that
is followed by a patch area. We try to remove the BTI that follows the
patch area (this may fail e.g. if the first instruction is a PACIASP).

So before this commit -fpatchable-function-entry=3,1 with bti generates

    .section __patchable_function_entries
    .8byte .LPFE
    .text
  .LPFE:
    nop
  foo:
    nop
    nop
    bti c // or paciasp
    ...

and after this commit

    .section __patchable_function_entries
    .8byte .LPFE
    .text
  .LPFE:
    nop
  foo:
    bti c
    nop
    nop
    // may be paciasp
    ...

and with -fpatchable-function-entry=1 (M=0) the code now is

  foo:
    bti c
    .section __patchable_function_entries
    .8byte .LPFE
    .text
  .LPFE:
    nop
    // may be paciasp
    ...

There is a new bti insn in the middle of the patchable area users need
to be aware of unless M=0 (patch area is after the new bti) or M=N
(patch area is before the label, no new bti). Note: bti is not added to
all functions consistently (it can be turned off per function using a
target attribute or the compiler may detect that the function is never
called indirectly), so if bti is inserted in the middle of a patch area
then user code needs to deal with detecting it.

Tested on aarch64-none-linux-gnu.

gcc/ChangeLog:

PR target/92424
* config/aarch64/aarch64.c (aarch64_declare_function_name): Set
cfun->machine->label_is_assembled.
(aarch64_print_patchable_function_entry): New.
(TARGET_ASM_PRINT_PATCHABLE_FUNCTION_ENTRY): Define.
* config/aarch64/aarch64.h (struct machine_function): New field,
label_is_assembled.

gcc/testsuite/ChangeLog:

PR target/92424
* gcc.target/aarch64/pr92424-1.c: New test.
* gcc.target/aarch64/pr92424-2.c: New test.
* gcc.target/aarch64/pr92424-3.c: New test.
gcc/ChangeLog
gcc/config/aarch64/aarch64.c
gcc/config/aarch64/aarch64.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/aarch64/pr92424-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/pr92424-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/pr92424-3.c [new file with mode: 0644]