mirror of
https://github.com/CTCaer/switch-l4t-atf.git
synced 2025-02-20 18:40:54 +00:00
Merge "backtrace: Strip PAC field when PAUTH is enabled" into integration
This commit is contained in:
commit
7871fff2a2
@ -37,6 +37,47 @@ struct frame_record {
|
||||
uintptr_t return_addr;
|
||||
};
|
||||
|
||||
/*
|
||||
* Strip the Pointer Authentication Code (PAC) from the address to retrieve the
|
||||
* original one.
|
||||
*
|
||||
* The PAC field is stored on the high bits of the address and defined as:
|
||||
* - PAC field = Xn[54:bottom_PAC_bit], when address tagging is used.
|
||||
* - PAC field = Xn[63:56, 54:bottom_PAC_bit], without address tagging.
|
||||
*
|
||||
* With bottom_PAC_bit = 64 - TCR_ELx.TnSZ
|
||||
*/
|
||||
#if ENABLE_PAUTH
|
||||
static uintptr_t demangle_address(uintptr_t addr)
|
||||
{
|
||||
unsigned int el, t0sz, bottom_pac_bit;
|
||||
uint64_t tcr, pac_mask;
|
||||
|
||||
/*
|
||||
* Different virtual address space size can be defined for each EL.
|
||||
* Ensure that we use the proper one by reading the corresponding
|
||||
* TCR_ELx register.
|
||||
*/
|
||||
el = get_current_el();
|
||||
|
||||
if (el == 3U) {
|
||||
tcr = read_tcr_el3();
|
||||
} else if (el == 2U) {
|
||||
tcr = read_tcr_el2();
|
||||
} else {
|
||||
tcr = read_tcr_el1();
|
||||
}
|
||||
|
||||
/* T0SZ = TCR_ELx[5:0] */
|
||||
t0sz = tcr & 0x1f;
|
||||
bottom_pac_bit = 64 - t0sz;
|
||||
pac_mask = (1ULL << bottom_pac_bit) - 1;
|
||||
|
||||
/* demangle the address with the computed mask */
|
||||
return (addr & pac_mask);
|
||||
}
|
||||
#endif /* ENABLE_PAUTH */
|
||||
|
||||
static const char *get_el_str(unsigned int el)
|
||||
{
|
||||
if (el == 3U) {
|
||||
@ -57,6 +98,15 @@ static bool is_address_readable(uintptr_t addr)
|
||||
{
|
||||
unsigned int el = get_current_el();
|
||||
|
||||
#if ENABLE_PAUTH
|
||||
/*
|
||||
* When pointer authentication is enabled, the LR value saved on the
|
||||
* stack contains a PAC. It must be stripped to retrieve the return
|
||||
* address.
|
||||
*/
|
||||
addr = demangle_address(addr);
|
||||
#endif
|
||||
|
||||
if (el == 3U) {
|
||||
ats1e3r(addr);
|
||||
} else if (el == 2U) {
|
||||
@ -201,6 +251,15 @@ static void unwind_stack(struct frame_record *fr, uintptr_t current_pc,
|
||||
*/
|
||||
call_site = fr->return_addr - 4U;
|
||||
|
||||
#if ENABLE_PAUTH
|
||||
/*
|
||||
* When pointer authentication is enabled, the LR value saved on
|
||||
* the stack contains a PAC. It must be stripped to retrieve the
|
||||
* return address.
|
||||
*/
|
||||
call_site = demangle_address(call_site);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If the address is invalid it means that the frame record is
|
||||
* probably corrupted.
|
||||
|
Loading…
x
Reference in New Issue
Block a user