Restrict spsr updated in the arm64 set_regs*

When using ptrace(2) on arm64 to set registers in a 32-bit program we
need to take care to only set some of the fields. Follow the existing
arm64 path and only let the user set the flags fields. This is also the
case in the arm kernel so fixes a change in behaviour between the two.

While here update set_regs to only set spsr and elr once.

Sponsored by:	The FreeBSD Foundation
This commit is contained in:
Andrew Turner 2021-09-13 15:24:34 +00:00
parent ddedf2a11e
commit b029ef7fe6

View File

@ -254,9 +254,7 @@ set_regs(struct thread *td, struct reg *regs)
frame = td->td_frame;
frame->tf_sp = regs->sp;
frame->tf_lr = regs->lr;
frame->tf_elr = regs->elr;
frame->tf_spsr &= ~PSR_FLAGS;
frame->tf_spsr |= regs->spsr & PSR_FLAGS;
memcpy(frame->tf_x, regs->x, sizeof(frame->tf_x));
@ -268,9 +266,13 @@ set_regs(struct thread *td, struct reg *regs)
* it put it.
*/
frame->tf_elr = regs->x[15];
frame->tf_spsr = regs->x[16] & PSR_FLAGS;
}
frame->tf_spsr |= regs->x[16] & PSR_FLAGS;
} else
#endif
{
frame->tf_elr = regs->elr;
frame->tf_spsr |= regs->spsr & PSR_FLAGS;
}
return (0);
}
@ -490,7 +492,8 @@ set_regs32(struct thread *td, struct reg32 *regs)
tf->tf_x[13] = regs->r_sp;
tf->tf_x[14] = regs->r_lr;
tf->tf_elr = regs->r_pc;
tf->tf_spsr = regs->r_cpsr;
tf->tf_spsr &= ~PSR_FLAGS;
tf->tf_spsr |= regs->r_cpsr & PSR_FLAGS;
return (0);
}