234 Commits

Author SHA1 Message Date
Daniel Paoliello
5ee0a71df9
[aarch64][win] Add support for import call optimization (equivalent to MSVC /d2ImportCallOptimization) (#121516)
This change implements import call optimization for AArch64 Windows
(equivalent to the undocumented MSVC `/d2ImportCallOptimization` flag).

Import call optimization adds additional data to the binary which can be
used by the Windows kernel loader to rewrite indirect calls to imported
functions as direct calls. It uses the same [Dynamic Value Relocation
Table mechanism that was leveraged on x64 to implement
`/d2GuardRetpoline`](https://techcommunity.microsoft.com/blog/windowsosplatform/mitigating-spectre-variant-2-with-retpoline-on-windows/295618).

The change to the obj file is to add a new `.impcall` section with the
following layout:
```cpp
  // Per section that contains calls to imported functions:
  //  uint32_t SectionSize: Size in bytes for information in this section.
  //  uint32_t Section Number
  //  Per call to imported function in section:
  //    uint32_t Kind: the kind of imported function.
  //    uint32_t BranchOffset: the offset of the branch instruction in its
  //                            parent section.
  //    uint32_t TargetSymbolId: the symbol id of the called function.
```

NOTE: If the import call optimization feature is enabled, then the
`.impcall` section must be emitted, even if there are no calls to
imported functions.

The implementation is split across a few parts of LLVM:
* During AArch64 instruction selection, the `GlobalValue` for each call
to a global is recorded into the Extra Information for that node.
* During lowering to machine instructions, the called global value for
each call is noted in its containing `MachineFunction`.
* During AArch64 asm printing, if the import call optimization feature
is enabled:
- A (new) `.impcall` directive is emitted for each call to an imported
function.
- The `.impcall` section is emitted with its magic header (but is not
filled in).
* During COFF object writing, the `.impcall` section is filled in based
on each `.impcall` directive that were encountered.

The `.impcall` section can only be filled in when we are writing the
COFF object as it requires the actual section numbers, which are only
assigned at that point (i.e., they don't exist during asm printing).

I had tried to avoid using the Extra Information during instruction
selection and instead implement this either purely during asm printing
or in a `MachineFunctionPass` (as suggested in [on the
forums](https://discourse.llvm.org/t/design-gathering-locations-of-instructions-to-emit-into-a-section/83729/3))
but this was not possible due to how loading and calling an imported
function works on AArch64. Specifically, they are emitted as `ADRP` +
`LDR` (to load the symbol) then a `BR` (to do the call), so at the point
when we have machine instructions, we would have to work backwards
through the instructions to discover what is being called. An initial
prototype did work by inspecting instructions; however, it didn't
correctly handle the case where the same function was called twice in a
row, which caused LLVM to elide the `ADRP` + `LDR` and reuse the
previously loaded address. Worse than that, sometimes for the
double-call case LLVM decided to spill the loaded address to the stack
and then reload it before making the second call. So, instead of trying
to implement logic to discover where the value in a register came from,
I instead recorded the symbol being called at the last place where it
was easy to do: instruction selection.
2025-01-11 21:30:17 -08:00
Thurston Dang
4f42e16516
[hwasan] Omit tag check for null pointers (#122206)
If the pointer to be checked is statically known to be zero, the tag
check will always pass since:
1) the tag is zero
2) shadow memory for address 0 is initialized to 0 and never updated.
We can therefore elide the tag check.

We perform the elision in two places:
1) the HWASan pass
2) when lowering the CHECK_MEMACCESS intrinsic. Conceivably, the HWASan
pass may encounter a "cannot currently statically prove to be null"
pointer (and is therefore unable to omit the intrinsic) that later
optimization passes convert into a statically known-null pointer. As a
last line of defense, we perform elision here too.

This also updates the tests from
https://github.com/llvm/llvm-project/pull/122186
2025-01-09 13:48:26 -08:00
Daniil Kovalev
52bbe20eb4
[PAC][CodeGen][ELF][AArch64] Support signed TLSDESC (#113813)
Depends on #120010

`TLSDESC_AUTH_CALLSEQ` pseudo-instruction is introduced which is later expanded
to actual instruction sequence like the following.

```
adrp  x0, :tlsdesc_auth:var
ldr   x16, [x0, #:tlsdesc_auth_lo12:var]
add   x0, x0, #:tlsdesc_auth_lo12:var
blraa x16, x0
(TPIDR_EL0 offset now in x0)
```

Only SelectionDAG ISel is supported.

Tests starting with 'ptrauth-' have corresponding variants w/o this prefix.
2024-12-28 12:13:39 +03:00
Daniil Kovalev
0ed696e5a3
[PAC][CodeGen][ELF][AArch64] Support signed GOT with tiny code model (#114525)
Support the following relocations and assembly operators:

- `R_AARCH64_AUTH_GOT_ADR_PREL_LO21` (`:got_auth:` for `adr`)
- `R_AARCH64_AUTH_GOT_LD_PREL19` (`:got_auth:` for `ldr`)

`LOADgotAUTH` pseudo-instruction is expanded to actual instruction
sequence like the following.

```
adr x16, :got_auth:sym
ldr x0, [x16]
autia x0, x16
```

Both SelectionDAG and GlobalISel are suppported. For FastISel, we fall
back to SelectionDAG.

Tests starting with 'ptrauth-' have corresponding variants w/o this
prefix.
2024-12-10 14:43:12 +03:00
Anatoly Trosinenko
1fccba5ca1
[AArch64][PAC] Eliminate excessive MOVs when computing blend (#115185)
As function calls do not generally preserve X16 and X17, it is beneficial
to allow AddrDisc operand of BLRA instruction to reside in these
registers and make use of this condition when computing the
discriminator.

This can save up to two MOVs in cases such as loading a (signed) virtual
function pointer via a (signed) pointer to vtable, for example

    ldr   x9, [x16]
    mov   x8, x16
    mov   x17, x8
    movk  x17, #34646, lsl #48
    blraa x9, x17

can be simplified to

    ldr   x8, [x16]
    movk  x16, #34646, lsl #48
    blraa x8, x16
2024-11-27 13:24:32 +03:00
Anatoly Trosinenko
44076c9822
[AArch64][PAC] Move emission of LR checks in tail calls to AsmPrinter (#110705)
Move the emission of the checks performed on the authenticated LR value
during tail calls to AArch64AsmPrinter class, so that different checker
sequences can be reused by pseudo instructions expanded there.
This adds one more option to AuthCheckMethod enumeration, the generic
XPAC variant which is not restricted to checking the LR register.
2024-11-12 18:27:19 +03:00
Kazu Hirata
a41922ad75
[AArch64] Remove unused includes (NFC) (#115685)
Identified with misc-include-cleaner.
2024-11-11 07:35:08 -08:00
Daniil Kovalev
da083e358e
[PAC][CodeGen][ELF][AArch64] Support signed GOT (#113811)
This re-applies #96164 after revert in #102434.

Support the following relocations and assembly operators:

- `R_AARCH64_AUTH_ADR_GOT_PAGE` (`:got_auth:` for `adrp`)
- `R_AARCH64_AUTH_LD64_GOT_LO12_NC` (`:got_auth_lo12:` for `ldr`)
- `R_AARCH64_AUTH_GOT_ADD_LO12_NC` (`:got_auth_lo12:` for `add`)

`LOADgotAUTH` pseudo-instruction is introduced which is later expanded to
actual instruction sequence like the following.

```
adrp x16, :got_auth:sym
add x16, x16, :got_auth_lo12:sym
ldr x0, [x16]
autia x0, x16
```

If a resign is requested, like below, `LOADgotPAC` pseudo is used, and GOT
load is lowered similarly to `LOADgotAUTH`.

```
@var = global i32 0
define ptr @resign_globalvar() {
  ret ptr ptrauth (ptr @var, i32 3, i64 43)
}
```

If FPAC bit is not set and auth instruction is emitted, a check+trap sequence
similar to one used for `AUT` pseudo is emitted to ensure auth success.

Both SelectionDAG and GlobalISel are suppported.
For FastISel, we fall back to SelectionDAG.

Tests starting with 'ptrauth-' have corresponding variants w/o this prefix.

See also specification
https://github.com/ARM-software/abi-aa/blob/main/pauthabielf64/pauthabielf64.rst#appendix-signed-got
2024-11-01 12:21:10 +03:00
Anatoly Trosinenko
21ecd4a9df
[AArch64][PAC] Factor out the emission of pointer check sequence (NFC) (#110702)
When pointer is authenticated or resigned, it may be required to
explicitly check the authenticated value to prevent introducing signing
or authentication oracles. While the check sequence is expensive in
general, a more efficient sequence can be emitted under specific
assumptions.

This commit factors out the emission of the code sequence to check the
authenticated pointer value in preparation for adding other variants
of checking code, as it is currently done when emitting tail calls.
2024-10-25 17:03:15 +03:00
Anatoly Trosinenko
7ca4128d34
[AArch64] Generalize the instruction size checking in AsmPrinter (#110108)
Most of PAuth-related code counts the instructions being inserted and
asserts that no more bytes are emitted than the size returned by the
getInstSizeInBytes(MI) method. This check seems useful not only for
PAuth-related instructions. Also, reimplementing it globally in
AArch64AsmPrinter makes it more robust and simplifies further
refactoring of PAuth-related code.
2024-10-01 17:55:42 +03:00
Anatoly Trosinenko
670a98a1b3
[AArch64] Consistently use EmitToStreamer across the AArch64AsmPrinter (#110107)
In preparation for refactoring the instruction size checks being made by
PAuth-related code, switch all instruction emission in AArch64AsmPrinter
to using EmitToStreamer function.

Introduce a single-operand overload of `EmitToStreamer(MCInst)`, as the
only MCStreamer passed as the first argument is actually `*OutStreamer`.
To decrease the number of code lines changed due to clang-format, do not
touch the existing calls to two-argument EmitToStreamer function so far.
2024-10-01 12:07:22 +03:00
Anatoly Trosinenko
3f8380f3ea
[AArch64] Factor out the emission of MOV and MOVZ/MOVK instructions (#110017)
Throughout the AArch64AsmPrinter implementation, there are a few common
instructions emitted at many places: ORRXrs as an alias of "mov Xd, Xm"
and movz/movk for materialization of constants. This commit introduces
utility functions for emission of these three instructions.
2024-09-27 12:54:28 +03:00
Daniil Kovalev
3d5e8e4693
[PAC][CodeGen] Do not emit trivial 'mov xN, xN' on tail call (#109100)
Under some conditions, a trivial `mov xN xN` instruction was emitted on
tail calls. Consider the following code:

```
class Test {
public:
  virtual void f() {}
};

void call_f(Test *t) {
  t->f();
}
```

Correponding assembly:

```
_Z6call_fP4Test:
        ldr     x16, [x0]
        mov     x17, x0
        movk    x17, #6503, lsl #48
        autda   x16, x17
        ldr     x1, [x16]
 =====> mov     x16, x16
        movk    x16, #54167, lsl #48
        braa    x1, x16
```

This patch makes such movs being omitted.

Co-authored-by: Anatoly Trosinenko <atrosinenko@accesssoftek.com>
2024-09-19 12:17:58 +03:00
Jacek Caban
d550ada5ab
[CodeGen][ARM64EC] Define hybrid_patchable EXP thunk symbol as a function. (#102898)
This is needed for MSVC link.exe to generate redirection metadata for hybrid patchable thunks.
2024-08-13 13:39:42 +02:00
Daniil Kovalev
eb4ac6400b
Revert "[PAC][CodeGen][ELF][AArch64] Support signed GOT" (#102434)
Reverts llvm/llvm-project#96164

See buildbot failure
https://lab.llvm.org/buildbot/#/builders/153/builds/5329
2024-08-08 10:58:45 +03:00
Daniil Kovalev
9dae7fcc92
[PAC][CodeGen][ELF][AArch64] Support signed GOT (#96164)
Depends on #96158 and #96159

Support the following relocations and assembly operators:

- `R_AARCH64_AUTH_ADR_GOT_PAGE` (`:got_auth:` for `adrp`)
- `R_AARCH64_AUTH_LD64_GOT_LO12_NC` (`:got_auth_lo12:` for `ldr`)
- `R_AARCH64_AUTH_GOT_ADD_LO12_NC` (`:got_auth_lo12:` for `add`)

`LOADgotAUTH` pseudo-instruction is introduced which is later expanded
to actual instruction sequence like the following.

```
adrp x16, :got_auth:sym
add x16, x16, :got_auth_lo12:sym
ldr x0, [x16]
autia x0, x16
```

If a resign is requested, like below, `LOADgotPAC` pseudo is used, and
GOT load is lowered similarly to `LOADgotAUTH`.

```
@var = global i32 0
define ptr @resign_globalvar() {
  ret ptr ptrauth (ptr @var, i32 3, i64 43)
}
```

Both SelectionDAG and GlobalISel are suppported. For FastISel, we fall
back to SelectionDAG.

Tests starting with 'ptrauth-' have corresponding variants w/o this
prefix.

See also specification
https://github.com/ARM-software/abi-aa/blob/main/pauthabielf64/pauthabielf64.rst#appendix-signed-got
2024-08-07 11:53:00 +03:00
Daniil Kovalev
6e45fa95be
[PAC][AArch64] Support init/fini array signing (#96478)
If both `-fptrauth-init-fini` and `-fptrauth-calls` are passed, sign
function pointers in `llvm.global_ctors` and `llvm.global_dtors` with
constant discriminator 0xD9D4
(`ptrauth_string_discriminator("init_fini")`). Additionally, if
`-fptrauth-init-fini-address-discrimination` is passed, address
discrimination is used for signing (otherwise, just constant
discriminator is used).

For address discrimination, we use it's special form since uses of
`llvm.global_{c|d}tors` are disallowed (see
`Verifier::visitGlobalVariable`) and we can't emit `getelementptr`
expressions referencing these special arrays. A signed ctor/dtor pointer
with special address discrimination applied looks like the following:

```
ptr ptrauth (ptr @foo, i32 0, i64 55764, ptr inttoptr (i64 1 to ptr))
```
2024-08-06 08:02:13 +03:00
Sergei Barannikov
7a2a36f952
[AsmPrinter] Don't EmitToStreamer instructions lowered by tblgenned code (#100803)
This allows lowering individual instructions in a bundle before a single
call to EmitToStreamer for VLIW targets.
2024-07-29 19:18:18 +03:00
Ahmed Bougacha
d7e8a7487c
[AArch64][PAC] Lower auth/resign into checked sequence. (#79024)
This introduces 3 hardening modes in the authentication step of
auth/resign lowering:
- unchecked, which uses the AUT instructions as-is
- poison, which detects authentication failure (using an XPAC+CMP
  sequence), explicitly yielding the XPAC result rather than the
  AUT result, to avoid leaking
- trap, which additionally traps on authentication failure,
  using BRK #0xC470 + key (IA C470, IB C471, DA C472, DB C473.)

Not all modes are necessarily useful in all contexts, and there
are more performant alternative lowerings in specific contexts
(e.g., when I/D TBI enablement is a target ABI guarantee.)
These will be implemented separately.

This is controlled by the `ptrauth-auth-traps` function attributes,
and can be overridden using `-aarch64-ptrauth-auth-checks=`.

This also adds the FPAC extension, which we haven't needed
before, to improve isel when we can rely on HW checking.
2024-07-22 21:28:01 -07:00
Ahmed Bougacha
b8721fa0af
[AArch64][PAC] Sign block addresses used in indirectbr. (#97647)
Enabled in clang using:
    -fptrauth-indirect-gotos

and at the IR level using function attribute:
    "ptrauth-indirect-gotos"

Signing uses IA and a per-function integer discriminator. The
discriminator isn't ABI-visible, and is currently:
    ptrauth_string_discriminator("<function_name> blockaddress")

A sufficiently sophisticated frontend could benefit from per-indirectbr
discrimination, which would need additional machinery, such as allowing
"ptrauth" bundles on indirectbr. For our purposes, the simple scheme
above is sufficient.

This approach doesn't support subtracting label addresses and using
the result as offsets, because each label address is signed.
Pointer arithmetic on signed pointers corrupts the signature bits,
and because label address expressions aren't typed beyond void*,
we can't do anything reliably intelligent on the arithmetic exprs.
Not signing addresses when used to form offsets would allow
easily hijacking control flow by overwriting the offset.

This diagnoses the basic cases (`&&lbl2 - &&lbl1`) in the frontend,
while we evaluate either alternative implementations (e.g., lowering
blockaddress to a bb number, and indirectbr to a checked jump-table),
or better diagnostics (both at the frontend level and on unencodable
IR constants).
2024-07-22 21:24:39 -07:00
Ahmed Bougacha
6049cd6287
[AArch64][PAC] Lower jump-tables using hardened pseudo. (#97666)
This introduces an alternative hardened lowering for jump-table
dispatch, controlled by the function attribute
`"aarch64-jump-table-hardening"`.
The implementation is centered around a pseudo, BR_JumpTable:

> A hardened but more expensive version of jump-table dispatch.
> This combines the target address computation (otherwise done using
> the JumpTableDest pseudos above) with the branch itself (otherwise
> done using a plain BR) in a single non-attackable sequence.
>
> We take the final entry index as an operand to allow isel freedom.
> This does mean that the index can be attacker-controlled. To
> address that, we also do limited checking of the offset, mainly
> ensuring it still points within the jump-table array.  When it
> doesn't, this branches to the first entry.  We might want it to
> trap instead.
>
> This is intended for use in conjunction with ptrauth for other
> code pointers, to avoid signing jump-table entries and turning
> them into pointers.
>
> Entry index is passed in x16.  Clobbers x16/x17/nzcv.

Jump-table compression isn't supported yet.
2024-07-22 19:01:42 -07:00
Matt Arsenault
a8a7d62d04 AArch64: Avoid using MachineFunction::getMMI 2024-07-20 13:11:39 +04:00
Jacek Caban
6cc8774228
[CodeGen][ARM64EC] Add support for hybrid_patchable attribute. (#92965) 2024-07-19 11:43:25 +02:00
Ahmed Bougacha
5f1bb62c6b
[AArch64][PAC] Lower ptrauth constants in code for MachO. (#97665)
This also adds support for auth stubs on MachO using __DATA,__auth_ptr.

Some of the machinery for auth stubs is already implemented;  this
generalizes that a bit to support MachO, and moves some of the shared
logic into MMIImpls.

In particular, this originally had an AuthStubInfo struct, but we no
longer need it beyond a single MCExpr.  So this provides variants of
the symbol stub helper type declarations and functions for "expr
stubs", where a stub points at an arbitrary MCExpr, rather than
a simple MCSymbol (and a bit).
2024-07-10 15:03:17 -07:00
Daniel Kiss
1782810b84 [Clang][ARM][AArch64] Alway emit protection attributes for functions. (#82819)
So far branch protection, sign return address, guarded control stack
attributes are
only emitted as module flags to indicate the functions need to be
generated with
those features.
The problem is in case of an LTO build the module flags are merged with
the `min`
rule which means if one of the module is not build with sign return
address then the features
will be turned off for all functions. Due to the functions take the
branch-protection and
sign-return-address features from the module flags. The
sign-return-address is
function level option therefore it is expected functions from files that
is
compiled with -mbranch-protection=pac-ret to be protected.
The inliner might inline functions with different set of flags as it
doesn't consider
the module flags.

This patch adds the attributes to all functions and drops the checking
of the module flags
for the code generation.
Module flag is still used for generating the ELF markers.
Also drops the "true"/"false" values from the
branch-protection-enforcement,
branch-protection-pauth-lr, guarded-control-stack attributes as presence
of the
attribute means it is on absence means off and no other option.

Releand with test fixes.
2024-07-10 11:32:41 +02:00
Daniel Kiss
4b2daeccc7
Revert "[Clang][ARM][AArch64] Alway emit protection attributes for functions." (#98284)
Reverts llvm/llvm-project#82819
2024-07-10 10:22:38 +02:00
Daniel Kiss
e15d67cfc2
[Clang][ARM][AArch64] Alway emit protection attributes for functions. (#82819)
So far branch protection, sign return address, guarded control stack
attributes are
only emitted as module flags to indicate the functions need to be
generated with
those features.
The problem is in case of an LTO build the module flags are merged with
the `min`
rule which means if one of the module is not build with sign return
address then the features
will be turned off for all functions. Due to the functions take the
branch-protection and
sign-return-address features from the module flags. The
sign-return-address is
function level option therefore it is expected functions from files that
is
compiled with -mbranch-protection=pac-ret to be protected.
The inliner might inline functions with different set of flags as it
doesn't consider
the module flags.
 
This patch adds the attributes to all functions and drops the checking
of the module flags
for the code generation.
Module flag is still used for generating the ELF markers.
Also drops the "true"/"false" values from the
branch-protection-enforcement,
branch-protection-pauth-lr, guarded-control-stack attributes as presence
of the
attribute means it is on absence means off and no other option.
2024-07-10 10:06:14 +02:00
Nikita Popov
4169338e75
[IR] Don't include Module.h in Analysis.h (NFC) (#97023)
Replace it with a forward declaration instead. Analysis.h is pulled in
by all passes, but not all passes need to access the module.
2024-06-28 14:30:47 +02:00
Daniil Kovalev
1488fb4153
[PAC][AArch64] Lower ptrauth constants in code (#96879)
This re-applies #94241 after fixing buildbot failure, see
https://lab.llvm.org/buildbot/#/builders/51/builds/570

According to standard, `constexpr` variables and `const` variables
initialized with constant expressions can be used in lambdas w/o
capturing - see https://en.cppreference.com/w/cpp/language/lambda.
However, MSVC used on buildkite seems to ignore that rule and does not
allow using such uncaptured variables in lambdas: we have "error C3493:
'Mask16' cannot be implicitly captured because no default capture mode
has been specified" - see
https://buildkite.com/llvm-project/github-pull-requests/builds/73238

Explicitly capturing such a variable, however, makes buildbot fail with
"error: lambda capture 'Mask16' is not required to be captured for this
use [-Werror,-Wunused-lambda-capture]" - see
https://lab.llvm.org/buildbot/#/builders/51/builds/570.

Fix both cases by using `0xffff` value directly instead of giving a name
to it.

Original PR description below.

Depends on #94240.

Define the following pseudos for lowering ptrauth constants in code:

- non-`extern_weak`:
  - no GOT load needed: `MOVaddrPAC` - similar to `MOVaddr`, with added
PAC;
  - GOT load needed: `LOADgotPAC` - similar to `LOADgot`, with added PAC;
- `extern_weak`: `LOADauthptrstatic` - similar to `LOADgot`, but use a
special stub slot named `sym$auth_ptr$key$disc` filled by dynamic linker
during relocation resolving instead of a GOT slot.

---------

Co-authored-by: Ahmed Bougacha <ahmed@bougacha.org>
2024-06-28 07:29:38 +03:00
Daniil Kovalev
99251f5a11
Revert "[PAC][AArch64] Lower ptrauth constants in code (#94241)" (#96865)
This reverts #94241.

See buildbot failure
https://lab.llvm.org/buildbot/#/builders/51/builds/570
2024-06-27 11:10:38 +03:00
Daniil Kovalev
b5cc19e572
[PAC][AArch64] Lower ptrauth constants in code (#94241)
Depends on #94240.

Define the following pseudos for lowering ptrauth constants in code:

- non-`extern_weak`:
  - no GOT load needed: `MOVaddrPAC` - similar to `MOVaddr`, with added
    PAC;
  - GOT load needed: `LOADgotPAC` - similar to `LOADgot`, with added PAC;
- `extern_weak`: `LOADauthptrstatic` - similar to `LOADgot`, but use a
  special stub slot named `sym$auth_ptr$key$disc` filled by dynamic linker
  during relocation resolving instead of a GOT slot.

---------

Co-authored-by: Ahmed Bougacha <ahmed@bougacha.org>
2024-06-27 10:02:17 +03:00
Daniil Kovalev
690480f588
[PAC][AArch64] Lower ptrauth constants in data (#94240)
Lower global references to ptrauth constants into `@AUTH` `MCExpr`'s.
The logic is common for MachO and ELF - test both.

---------

Co-authored-by: Ahmed Bougacha <ahmed@bougacha.org>
2024-06-11 07:28:42 +03:00
Ahmed Bougacha
cc548ec47c
[AArch64][PAC] Lower authenticated calls with ptrauth bundles. (#85736)
This adds codegen support for the "ptrauth" operand bundles, which can
be used to augment indirect calls with the equivalent of an
`@llvm.ptrauth.auth` intrinsic call on the call target (possibly
preceded by an `@llvm.ptrauth.blend` on the auth discriminator if
applicable.)

This allows the generation of combined authenticating calls
on AArch64 (in the BLRA* PAuth instructions), while avoiding
the raw just-authenticated function pointer from being
exposed to attackers.

This is done by threading a PtrAuthInfo descriptor through
the call lowering infrastructure, eventually selecting a BLRA
pseudo.  The pseudo encapsulates the safe discriminator
computation, which together with the real BLRA* call get emitted
in late pseudo expansion in AsmPrinter.

Note that this also applies to the other forms of indirect calls,
notably invokes, rvmarker, and tail calls.  Tail-calls in particular
bring some additional complexity, with the intersecting register
constraints of BTI and PAC discriminator computation.
However this doesn't currently support PAuth_LR tail-call variants.

This also adopts an x8+ allocation order for GPR64noip, matching
GPR64.
2024-05-31 14:08:10 -07:00
Jacek Caban
93c02b7dc3
[CodeGen][ARM64EC] Use MCSymbolRefExpr::VK_None for function aliases. (#92100) 2024-05-16 15:47:39 +02:00
Jacek Caban
f39e75b451
[CodeGen][ARM64EC][NFC] Factor out emitFunctionAlias and getSymbolFromMetadata in emitFunctionEntryLabel. (#92098) 2024-05-15 11:35:02 +02:00
Thurston Dang
365bddf634
[hwasan] Add intrinsics for fixed shadow on Aarch64 (#89319)
This patch introduces HWASan memaccess intrinsics that assume a fixed
shadow (with the offset provided by --hwasan-mapping-offset=...), with
and without short granule support.

The behavior of HWASan is not meaningfully changed by this patch;
future work ("Optimize outlined memaccess for
fixed shadow on Aarch64": https://github.com/llvm/llvm-project/pull/88544) will make HWASan use these intrinsics.

We currently only support lowering the LLVM IR intrinsic to AArch64.

The test case is adapted from hwasan-check-memaccess.ll.
2024-04-22 16:50:19 -07:00
Daniil Kovalev
d97d560fbf
[AArch64][PAC][MC][ELF] Support PAuth ABI compatibility tag (#85236)
Depends on #87545

Emit `GNU_PROPERTY_AARCH64_FEATURE_PAUTH` property in
`.note.gnu.property` section depending on
`aarch64-elf-pauthabi-platform` and `aarch64-elf-pauthabi-version` llvm
module flags.
2024-04-04 21:05:03 +03:00
Billy Laws
f17e415142
[AArch64] Mangle names of all ARM64EC functions with entry thunks (#80996)
This better matches MSVC output in cases where static functions have their addresses taken.
2024-02-22 12:36:18 +01:00
ostannard
5452cbc4a6
[AArch64] Indirect tail-calls cannot use x16 with pac-ret+pc (#81020)
When using -mbranch-protection=pac-ret+pc, x16 is used in the function
epilogue to hold the address of the signing instruction. This is used by
a HINT instruction which can only use x16, so we can't change this. This
means that we can't use it to hold the function pointer for an indirect
tail-call.

There is existing code to force indirect tail-calls to use x16 or x17
when BTI is enabled, so there are now 4 combinations:

bti  pac-ret+pc  Valid function pointer registers
off  off         Any non callee-saved register
on   off         x16 or x17
off  on          Any non callee-saved register except x16
on   on          x17
2024-02-08 15:31:54 +00:00
Eli Friedman
a6065f0fa5
Arm64EC entry/exit thunks, consolidated. (#79067)
This combines the previously posted patches with some additional work
I've done to more closely match MSVC output.

Most of the important logic here is implemented in
AArch64Arm64ECCallLowering. The purpose of the
AArch64Arm64ECCallLowering is to take "normal" IR we'd generate for
other targets, and generate most of the Arm64EC-specific bits:
generating thunks, mangling symbols, generating aliases, and generating
the .hybmp$x table. This is all done late for a few reasons: to
consolidate the logic as much as possible, and to ensure the IR exposed
to optimization passes doesn't contain complex arm64ec-specific
constructs.

The other changes are supporting changes, to handle the new constructs
generated by that pass.

There's a global llvm.arm64ec.symbolmap representing the .hybmp$x
entries for the thunks. This gets handled directly by the AsmPrinter
because it needs symbol indexes that aren't available before that.

There are two new calling conventions used to represent calls to and
from thunks: ARM64EC_Thunk_X64 and ARM64EC_Thunk_Native. There are a few
changes to handle the associated exception-handling info,
SEH_SaveAnyRegQP and SEH_SaveAnyRegQPX.

I've intentionally left out handling for structs with small
non-power-of-two sizes, because that's easily separated out. The rest of
my current work is here. I squashed my current patches because they were
split in ways that didn't really make sense. Maybe I could split out
some bits, but it's hard to meaningfully test most of the parts
independently.

Thanks to @dpaoliello for extensive testing and suggestions.

(Originally posted as https://reviews.llvm.org/D157547 .)
2024-01-22 21:28:07 -08:00
John Brawn
40d5c2bcd4
[clang][AArch64] Add a -mbranch-protection option to enable GCS (#75486)
-mbranch-protection=gcs (enabled by -mbranch-protection=standard) causes
generated objects to be marked with the gcs feature. This is done via
the guarded-control-stack module flag, in a similar way to
branch-target-enforcement and sign-return-address.

Enabling GCS causes the GNU_PROPERTY_AARCH64_FEATURE_1_GCS bit to be set
on generated objects. No code generation changes are required, as GCS
just requires that functions are called using BL and returned from using
RET (or other similar variant instructions), which is already the case.
2024-01-11 12:53:23 +00:00
Jon Roelofs
640c1d3dd1
[llvm] Support IFuncs on Darwin platforms (#73686)
... by lowering them as lazy resolve-on-first-use symbol resolvers. Note that this is subtly different timing than on ELF platforms, where ifunc resolution happens at load time.

Since ld64 and ld-prime don't support all the cases we need for these, we lower them manually in the AsmPrinter.
2023-12-14 14:40:52 -07:00
Matthew Devereau
b967f3a1d7
[AArch64] Separate PNR into its own Register Class (#65306)
This patch separates PNR registers into their own register class instead
of sharing a register class with PPR registers. This primarily allows us
to return more accurate register classes when applying assembly
constraints, but also more protection from supplying an incorrect
predicate type to an invalid register operand.
2023-09-21 19:53:16 +01:00
Daniel Paoliello
0c5c7b52f0 Emit the CodeView S_ARMSWITCHTABLE debug symbol for jump tables
The CodeView `S_ARMSWITCHTABLE` debug symbol is used to describe the layout of a jump table, it contains the following information:

* The address of the branch instruction that uses the jump table.
* The address of the jump table.
* The "base" address that the values in the jump table are relative to.
* The type of each entry (absolute pointer, a relative integer, a relative integer that is shifted).

Together this information can be used by debuggers and binary analysis tools to understand what an jump table indirect branch is doing and where it might jump to.

Documentation for the symbol can be found in the Microsoft PDB library dumper: 0fe89a942f/cvdump/dumpsym7.cpp (L5518)

This change adds support to LLVM to emit the `S_ARMSWITCHTABLE` debug symbol as well as to dump it out (for testing purposes).

Reviewed By: efriedma

Differential Revision: https://reviews.llvm.org/D149367
2023-08-31 12:06:50 -07:00
Arthur Eubanks
0a4fc4ac1c Revert "Emit the CodeView S_ARMSWITCHTABLE debug symbol for jump tables"
This reverts commit 8d0c3db388143f4e058b5f513a70fd5d089d51c3.

Causes crashes, see comments in https://reviews.llvm.org/D149367.

Some follow-up fixes are also reverted:

This reverts commit 636269f4fca44693bfd787b0a37bb0328ffcc085.
This reverts commit 5966079cf4d4de0285004eef051784d0d9f7a3a6.
This reverts commit e7294dbc85d24a08c716d9babbe7f68390cf219b.
2023-08-25 18:34:15 -07:00
Daniel Paoliello
8d0c3db388 Emit the CodeView S_ARMSWITCHTABLE debug symbol for jump tables
The CodeView `S_ARMSWITCHTABLE` debug symbol is used to describe the layout of a jump table, it contains the following information:

* The address of the branch instruction that uses the jump table.
* The address of the jump table.
* The "base" address that the values in the jump table are relative to.
* The type of each entry (absolute pointer, a relative integer, a relative integer that is shifted).

Together this information can be used by debuggers and binary analysis tools to understand what an jump table indirect branch is doing and where it might jump to.

Documentation for the symbol can be found in the Microsoft PDB library dumper: 0fe89a942f/cvdump/dumpsym7.cpp (L5518)

This change adds support to LLVM to emit the `S_ARMSWITCHTABLE` debug symbol as well as to dump it out (for testing purposes).

Reviewed By: efriedma

Differential Revision: https://reviews.llvm.org/D149367
2023-08-25 10:19:17 -07:00
Hiroshi Yamauchi
3406934e4d [MC][COFF][AArch64] Fix the storage class for private linkage symbols.
Use IMAGE_SYM_CLASS_STATIC like X86.

Differential Revision: https://reviews.llvm.org/D158122
2023-08-17 13:54:12 -07:00
Jon Roelofs
250812abe7
Remove a reference to rdar://problem/16473581
Readers can git-blame and find the necessary context if absolutely needed.
Otherwise, the presence of the link doesn't provide much value.

Moral of the story: don't emit `movi.2d #0` on any target affected by this.
2023-08-09 16:09:27 -07:00
Sander de Smalen
6865fbd3da [AArch64][SME] Use fmov instead of NEON movi for FP value.
NEON `movi` is not valid in Streaming SVE mode, so use an `fmov`
instruction instead for zero-initializing a FP value.

Reviewed By: hassnaa-arm

Differential Revision: https://reviews.llvm.org/D155432
2023-07-24 08:48:19 +00:00
Fangrui Song
9e7a052eef [XRay][AArch64] Implement __xray_ArgLoggerEntry 2023-07-05 20:56:00 -07:00