-
Notifications
You must be signed in to change notification settings - Fork 12.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[libunwind][AArch64] Add support for DWARF expression for RA_SIGN_STATE.
Program may set the RA_SIGN_STATE pseudo register by expressions. Libunwind expected only the DW_CFA_AARCH64_negate_ra_state could change the value of the register which leads to runtime errors on PAC enabled systems. In the recent version of the aadwarf64[1] a limitation is added[2] to forbid the mixing the DW_CFA_AARCH64_negate_ra_state with other DWARF Register Rule Instructions. [1] https://github.com/ARM-software/abi-aa/releases/tag/2022Q1 [2] ARM-software/abi-aa#129 Reviewed By: #libunwind, MaskRay Differential Revision: https://reviews.llvm.org/D123692
- Loading branch information
1 parent
094fb13
commit f6366ef
Showing
2 changed files
with
83 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// -*- C++ -*- | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
// REQUIRES: linux && target={{aarch64-.+}} | ||
|
||
// This test ensures the .cfi_negate_ra_state the RA_SIGN_STATE pseudo register | ||
// could be set directly set by a DWARF expression and the unwinder handles it | ||
// correctly. The two directives can't be mixed in one CIE/FDE sqeuence. | ||
|
||
#include <stdlib.h> | ||
|
||
__attribute__((noinline, target("branch-protection=pac-ret+leaf"))) | ||
void bar() { | ||
// ".cfi_negate_ra_state" is emitted by the compiler. | ||
throw 1; | ||
} | ||
|
||
__attribute__((noinline, target("branch-protection=none"))) | ||
void foo() { | ||
// Here a DWARF expression sets RA_SIGN_STATE. | ||
// The LR is signed manually and stored on the stack. | ||
asm volatile( | ||
".cfi_escape 0x16," // DW_CFA_val_expression | ||
"34," // REG_34(RA_SIGN_STATE) | ||
"1," // expression_length(1) | ||
"0x31\n" // DW_OP_lit1 | ||
"add sp, sp, 16\n" // Restore SP's value before the stack frame is | ||
// created. | ||
"paciasp\n" // Sign the LR. | ||
"str lr, [sp, -0x8]\n" // Overwrite LR on the stack. | ||
"sub sp, sp, 16\n" // Restore SP's value. | ||
); | ||
bar(); | ||
_Exit(-1); | ||
} | ||
|
||
__attribute__((noinline, target("branch-protection=pac-ret"))) | ||
void bazz() { | ||
// ".cfi_negate_ra_state" is emitted by the compiler. | ||
try { | ||
foo(); | ||
} catch (int i) { | ||
if (i == 1) | ||
throw i; | ||
throw 2; | ||
} | ||
} | ||
|
||
int main() { | ||
try { | ||
bazz(); | ||
} catch (int i) { | ||
if (i == 1) | ||
_Exit(0); | ||
} | ||
return -1; | ||
} |