diff options
author | Indu Bhagat <indu.bhagat@oracle.com> | 2024-05-27 15:40:39 -0700 |
---|---|---|
committer | Indu Bhagat <indu.bhagat@oracle.com> | 2024-06-30 11:39:26 -0700 |
commit | 0f0d5e753ad735d0f6b6a39e7078157083fa3c46 (patch) | |
tree | 1766fe21e6a50b58be40598eb79969e0697f1dbd | |
parent | 8891a9751f91dd00b9d5656a5e6cb1fc77697868 (diff) | |
download | gdb-0f0d5e753ad735d0f6b6a39e7078157083fa3c46.zip gdb-0f0d5e753ad735d0f6b6a39e7078157083fa3c46.tar.gz gdb-0f0d5e753ad735d0f6b6a39e7078157083fa3c46.tar.bz2 |
gas: scfi: make scfi_state_restore_reg function more precise
[No changes in V3, V4]
[New in V2]
- This patch is orthogonal to aarch64 support. It is included here
because the testcase added for it is aarch64 specific. It is a
bugfix really.
[End of New in V2]
When the SCFI machinery detects that a register has been restored from
stack, it makes some state changes in the SCFI state object.
Prior to the patch, scfi_state_restore_reg () was setting a value of
(reg, CFI_IN_REG) for (base, state) respectively. This was causing
issues in the cmp_scfi_state () function:
- The default state of all (callee-saved) regs at the beginning of
function is set to (0, CFI_UNDEFINED).
- If a register is saved and restored on some control path, the state
of reg is (reg, CFI_IN_REG) on that path.
- On another control path where the register was perhaps not
used (or saved/restored on stack) remains (0, CFI_UNDEFINED).
- The two states should be treated equal, however, at the point in
program after the register has been restored.
Fix this by resetting the state to (0, CFI_UNDEFINED) in
scfi_state_restore_reg ().
A testcase (scfi-cfg-4.s) for this is added in a subsequent commit.
gas/
* scfi.c (scfi_state_restore_reg): Reset to 0, CFI_UNDEFINED
for base, state.
-rw-r--r-- | gas/scfi.c | 9 |
1 files changed, 5 insertions, 4 deletions
@@ -223,11 +223,12 @@ scfi_state_restore_reg (scfi_stateS *state, unsigned int reg) gas_assert (state->regs[reg].state == CFI_ON_STACK); gas_assert (state->regs[reg].base == REG_CFA); - state->regs[reg].base = reg; + /* PS: the register may still be on stack much after the restore. Reset the + SCFI state to CFI_UNDEFINED, however, to indicate that the most updated + source of value is register itself from here onwards. */ + state->regs[reg].base = 0; state->regs[reg].offset = 0; - /* PS: the register may still be on stack much after the restore, but the - SCFI state keeps the state as 'in register'. */ - state->regs[reg].state = CFI_IN_REG; + state->regs[reg].state = CFI_UNDEFINED; } /* Identify if the given GAS instruction GINSN saves a register |