Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
For the following example:
int f(void g(), int a) { g(); return a; }If I compile with the following command:
cl /c a.c /d2guardsignret
llvm-readobj gives me the following:
File: a.obj
Format: COFF-ARM64
Arch: aarch64
AddressSize: 64bit
UnwindInformation [
RuntimeFunction {
Function: f (0x0)
ExceptionRecord: $unwind$f (0x0)
ExceptionData {
FunctionLength: 40
Version: 0
ExceptionData: No
EpiloguePacked: Yes
EpilogueOffset: 0
ByteCodeLength: 8
Prologue [
0xd600 ; stp x19, lr, [sp, #0]
0x01 ; sub sp, #16
0xfc ; Bad opcode!
0xe4 ; end
]
}
}
]So apparently there is, in fact, a way to encode this, using the undocumented opcode 0xfc. Why this isn't documented, I have no idea.
Mapping BTI instructions to no-ops seems fine; I can't imagine any other encoding makes sense, even if Microsoft does implement it at some point.
I tried this out - apparently this option has been around since some time in MSVC 2019 at least. And apparently it's also possible to invoke this with /guard:signret. This generates the pacibsp instruction - I wonder if there's a way to make it generate paciasp instead - which I presume would require a separate unwinding opcode to distinguish from pacibsp?
However, curiously, I don't get the output you got, if I compile with the same command - I have to build with /O2 for it to produce this unwind info. Without /O2, I get packed unwind, with CR=2 (which is defined as reserved) - which apparently is a way to handle signed return addresses in packed unwind info too.
I filed https://github.com/MicrosoftDocs/cpp-docs/pull/4202 as an initial attempt to document this (and hopefully poke the right people to document it publicly).
However, curiously, I don't get the output you got, if I compile with the same command - I have to build with /O2 for it to produce this unwind info. Without /O2, I get packed unwind, with CR=2 (which is defined as reserved) - which apparently is a way to handle signed return addresses in packed unwind info too.
Sorry, I think I confused the commands when I posted.
| llvm/lib/Target/AArch64/AArch64FrameLowering.cpp | ||
|---|---|---|
| 1881 | Technically we could support this; we can represent it as "end_c; pac_sign_return_address; end". But we can leave that as a followup. Probably worth adding a testcase for this, in any case. | |
Added a testcase which builds with "target-features"="+v8.3a", to test that we avoid generating "retab" at the moment.
LGTM
| llvm/lib/Target/AArch64/AArch64InstrInfo.cpp | ||
|---|---|---|
| 1021 ↗ | (On Diff #467084) | The original whitespace is right here. (This whole switch is over-indented.) |
Technically we could support this; we can represent it as "end_c; pac_sign_return_address; end". But we can leave that as a followup.
Probably worth adding a testcase for this, in any case.