Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
adam.huang
Arm Trusted Firmware
Commits
7871fff2
Commit
7871fff2
authored
Jul 17, 2019
by
Soby Mathew
Committed by
TrustedFirmware Code Review
Jul 17, 2019
Browse files
Merge "backtrace: Strip PAC field when PAUTH is enabled" into integration
parents
7a8ef89f
b8b31ad0
Changes
1
Show whitespace changes
Inline
Side-by-side
common/backtrace/backtrace.c
View file @
7871fff2
...
@@ -37,6 +37,47 @@ struct frame_record {
...
@@ -37,6 +37,47 @@ struct frame_record {
uintptr_t
return_addr
;
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
)
static
const
char
*
get_el_str
(
unsigned
int
el
)
{
{
if
(
el
==
3U
)
{
if
(
el
==
3U
)
{
...
@@ -57,6 +98,15 @@ static bool is_address_readable(uintptr_t addr)
...
@@ -57,6 +98,15 @@ static bool is_address_readable(uintptr_t addr)
{
{
unsigned
int
el
=
get_current_el
();
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
)
{
if
(
el
==
3U
)
{
ats1e3r
(
addr
);
ats1e3r
(
addr
);
}
else
if
(
el
==
2U
)
{
}
else
if
(
el
==
2U
)
{
...
@@ -201,6 +251,15 @@ static void unwind_stack(struct frame_record *fr, uintptr_t current_pc,
...
@@ -201,6 +251,15 @@ static void unwind_stack(struct frame_record *fr, uintptr_t current_pc,
*/
*/
call_site
=
fr
->
return_addr
-
4U
;
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
* If the address is invalid it means that the frame record is
* probably corrupted.
* probably corrupted.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment