Merge "fix: backtrace stack unwind misses lr adjustment" into integration

This commit is contained in:
Manish Pandey 2022-10-12 11:32:08 +02:00 committed by TrustedFirmware Code Review
commit 626f6d983d

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -37,6 +37,23 @@ struct frame_record {
uintptr_t return_addr;
};
static inline uintptr_t extract_address(uintptr_t address)
{
uintptr_t ret = address;
#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.
*/
xpaci(ret);
#endif
return ret;
}
const char *get_el_str(unsigned int el)
{
if (el == 3U) {
@ -53,18 +70,11 @@ const char *get_el_str(unsigned int el)
* the current EL, false otherwise.
*/
#ifdef __aarch64__
static bool is_address_readable(uintptr_t addr)
static bool is_address_readable(uintptr_t address)
{
unsigned int el = get_current_el();
uintptr_t addr = extract_address(address);
#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.
*/
xpaci(addr);
#endif
if (el == 3U) {
ats1e3r(addr);
} else if (el == 2U) {
@ -185,7 +195,8 @@ static void unwind_stack(struct frame_record *fr, uintptr_t current_pc,
return;
}
if (fr->return_addr != link_register) {
call_site = extract_address(fr->return_addr);
if (call_site != link_register) {
printf("ERROR: Corrupted stack (frame record address = %p)\n",
fr);
return;
@ -207,16 +218,9 @@ static void unwind_stack(struct frame_record *fr, uintptr_t current_pc,
* call was made is the instruction before the return address,
* which is always 4 bytes before it.
*/
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.
*/
xpaci(call_site);
#endif
call_site = extract_address(fr->return_addr) - 4U;
/*
* If the address is invalid it means that the frame record is
* probably corrupted.