arm64: remove pcb_pc

The program counter field in the PCB is written in exactly one place,
makectx(), upon entry to the debugger. For threads other than curthread,
its value will be empty, or bogus. Rather than writing to this field in
more places, it can be removed in favor of using the value in the link
register.

To make this clearer, pcb->pcb_x[30] is renamed to pcb->pcb_lr, similar
to what already exists in struct trapframe. Also, prefer lr to x30 in
assembly, as it better conveys intention.

This improves PC_REGS() for kdb_thread != curthread. It is required for
a functional gdb(4) stub, fixing the output of `info threads`, in
particular.

The space occupied by pcb_pc is retained, for compatibility with kgdb.

Reviewed by:	markj, jhb
MFC after:	2 weeks
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D27720
This commit is contained in:
mhorne 2020-12-21 12:16:09 -04:00 committed by Mitchell Horne
parent e9bb4ce3d0
commit 5f66d5a313
9 changed files with 18 additions and 17 deletions

View File

@ -109,7 +109,7 @@ db_trace_thread(struct thread *thr, int count)
frame.sp = (uintptr_t)ctx->pcb_sp;
frame.fp = (uintptr_t)ctx->pcb_x[29];
frame.pc = (uintptr_t)ctx->pcb_x[30];
frame.pc = (uintptr_t)ctx->pcb_lr;
db_stack_trace_cmd(thr, &frame);
} else
db_trace_self();

View File

@ -39,7 +39,7 @@ __FBSDID("$FreeBSD$");
sub sp, sp, #128
.endif
sub sp, sp, #(TF_SIZE + 16)
stp x29, x30, [sp, #(TF_SIZE)]
stp x29, lr, [sp, #(TF_SIZE)]
stp x28, x29, [sp, #(TF_X + 28 * 8)]
stp x26, x27, [sp, #(TF_X + 26 * 8)]
stp x24, x25, [sp, #(TF_X + 24 * 8)]

View File

@ -60,6 +60,7 @@ ASSYM(PC_SSBD, offsetof(struct pcpu, pc_ssbd));
ASSYM(PCB_SIZE, roundup2(sizeof(struct pcb), STACKALIGNBYTES + 1));
ASSYM(PCB_SINGLE_STEP_SHIFT, PCB_SINGLE_STEP_SHIFT);
ASSYM(PCB_REGS, offsetof(struct pcb, pcb_x));
ASSYM(PCB_LR, offsetof(struct pcb, pcb_lr));
ASSYM(PCB_SP, offsetof(struct pcb, pcb_sp));
ASSYM(PCB_TPIDRRO, offsetof(struct pcb, pcb_tpidrro_el0));
ASSYM(PCB_ONFAULT, offsetof(struct pcb, pcb_onfault));

View File

@ -732,11 +732,11 @@ makectx(struct trapframe *tf, struct pcb *pcb)
{
int i;
for (i = 0; i < PCB_LR; i++)
for (i = 0; i < nitems(pcb->pcb_x); i++)
pcb->pcb_x[i] = tf->tf_x[i];
pcb->pcb_x[PCB_LR] = tf->tf_lr;
pcb->pcb_pc = tf->tf_elr;
/* NB: pcb_lr is the PC, see PC_REGS() in db_machdep.h */
pcb->pcb_lr = tf->tf_elr;
pcb->pcb_sp = tf->tf_sp;
}

View File

@ -71,7 +71,7 @@ stack_save_td(struct stack *st, struct thread *td)
frame.sp = td->td_pcb->pcb_sp;
frame.fp = td->td_pcb->pcb_x[29];
frame.pc = td->td_pcb->pcb_x[30];
frame.pc = td->td_pcb->pcb_lr;
stack_capture(td, st, &frame);
return (0);

View File

@ -101,7 +101,7 @@ ENTRY(cpu_throw)
ldp x24, x25, [x4, #PCB_REGS + 24 * 8]
ldp x26, x27, [x4, #PCB_REGS + 26 * 8]
ldp x28, x29, [x4, #PCB_REGS + 28 * 8]
ldr x30, [x4, #PCB_REGS + 30 * 8]
ldr lr, [x4, #PCB_LR]
ret
END(cpu_throw)
@ -132,7 +132,7 @@ ENTRY(cpu_switch)
stp x24, x25, [x4, #PCB_REGS + 24 * 8]
stp x26, x27, [x4, #PCB_REGS + 26 * 8]
stp x28, x29, [x4, #PCB_REGS + 28 * 8]
str x30, [x4, #PCB_REGS + 30 * 8]
str lr, [x4, #PCB_LR]
/* And the old stack pointer */
mov x5, sp
mrs x6, tpidrro_el0
@ -198,7 +198,7 @@ ENTRY(cpu_switch)
ldp x24, x25, [x4, #PCB_REGS + 24 * 8]
ldp x26, x27, [x4, #PCB_REGS + 26 * 8]
ldp x28, x29, [x4, #PCB_REGS + 28 * 8]
ldr x30, [x4, #PCB_REGS + 30 * 8]
ldr lr, [x4, #PCB_LR]
str xzr, [x4, #PCB_REGS + 18 * 8]
ret
@ -270,7 +270,7 @@ ENTRY(savectx)
stp x24, x25, [x0, #PCB_REGS + 24 * 8]
stp x26, x27, [x0, #PCB_REGS + 26 * 8]
stp x28, x29, [x0, #PCB_REGS + 28 * 8]
str x30, [x0, #PCB_REGS + 30 * 8]
str lr, [x0, #PCB_LR]
/* And the old stack pointer */
mov x5, sp
mrs x6, tpidrro_el0

View File

@ -102,7 +102,7 @@ cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags)
/* Set the return value registers for fork() */
td2->td_pcb->pcb_x[8] = (uintptr_t)fork_return;
td2->td_pcb->pcb_x[9] = (uintptr_t)td2;
td2->td_pcb->pcb_x[PCB_LR] = (uintptr_t)fork_trampoline;
td2->td_pcb->pcb_lr = (uintptr_t)fork_trampoline;
td2->td_pcb->pcb_sp = (uintptr_t)td2->td_frame;
td2->td_pcb->pcb_fpusaved = &td2->td_pcb->pcb_fpustate;
td2->td_pcb->pcb_vfpcpu = UINT_MAX;
@ -173,7 +173,7 @@ cpu_copy_thread(struct thread *td, struct thread *td0)
td->td_pcb->pcb_x[8] = (uintptr_t)fork_return;
td->td_pcb->pcb_x[9] = (uintptr_t)td;
td->td_pcb->pcb_x[PCB_LR] = (uintptr_t)fork_trampoline;
td->td_pcb->pcb_lr = (uintptr_t)fork_trampoline;
td->td_pcb->pcb_sp = (uintptr_t)td->td_frame;
td->td_pcb->pcb_fpusaved = &td->td_pcb->pcb_fpustate;
td->td_pcb->pcb_vfpcpu = UINT_MAX;
@ -265,7 +265,7 @@ cpu_fork_kthread_handler(struct thread *td, void (*func)(void *), void *arg)
td->td_pcb->pcb_x[8] = (uintptr_t)func;
td->td_pcb->pcb_x[9] = (uintptr_t)arg;
td->td_pcb->pcb_x[PCB_LR] = (uintptr_t)fork_trampoline;
td->td_pcb->pcb_lr = (uintptr_t)fork_trampoline;
td->td_pcb->pcb_sp = (uintptr_t)td->td_frame;
td->td_pcb->pcb_fpusaved = &td->td_pcb->pcb_fpustate;
td->td_pcb->pcb_vfpcpu = UINT_MAX;

View File

@ -43,7 +43,7 @@
typedef vm_offset_t db_addr_t;
typedef long db_expr_t;
#define PC_REGS() ((db_addr_t)kdb_thrctx->pcb_pc)
#define PC_REGS() ((db_addr_t)kdb_thrctx->pcb_lr)
#define BKPT_INST (0xd4200000)
#define BKPT_SIZE (4)

View File

@ -36,10 +36,10 @@
struct trapframe;
#define PCB_LR 30
struct pcb {
uint64_t pcb_x[31];
uint64_t pcb_pc;
uint64_t pcb_x[30];
uint64_t pcb_lr;
uint64_t _reserved; /* Was pcb_pc */
/* These two need to be in order as we access them together */
uint64_t pcb_sp;
uint64_t pcb_tpidr_el0;