mirror of
https://github.com/opnsense/src.git
synced 2026-06-09 00:32:25 -04:00
Implement makectx(). The makectx() function is used by KDB to create
a PCB from a trapframe for purposes of unwinding the stack. The PCB is used as the thread context and all but the thread that entered the debugger has a valid PCB. This function can also be used to create a context for the threads running on the CPUs that have been stopped when the debugger got entered. This however is not done at the time of this commit.
This commit is contained in:
parent
0aefe3632e
commit
5a39cbaf69
10 changed files with 108 additions and 1 deletions
|
|
@ -1989,6 +1989,29 @@ alpha_pa_access(vm_offset_t pa)
|
|||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Construct a PCB from a trapframe. This is called from kdb_trap() where
|
||||
* we want to start a backtrace from the function that caused us to enter
|
||||
* the debugger. We have the context in the trapframe, but base the trace
|
||||
* on the PCB. The PCB doesn't have to be perfect, as long as it contains
|
||||
* enough for a backtrace.
|
||||
*/
|
||||
void
|
||||
makectx(struct trapframe *tf, struct pcb *pcb)
|
||||
{
|
||||
|
||||
pcb->pcb_context[0] = tf->tf_regs[FRAME_S0];
|
||||
pcb->pcb_context[1] = tf->tf_regs[FRAME_S1];
|
||||
pcb->pcb_context[2] = tf->tf_regs[FRAME_S2];
|
||||
pcb->pcb_context[3] = tf->tf_regs[FRAME_S3];
|
||||
pcb->pcb_context[4] = tf->tf_regs[FRAME_S4];
|
||||
pcb->pcb_context[5] = tf->tf_regs[FRAME_S5];
|
||||
pcb->pcb_context[6] = tf->tf_regs[FRAME_S6];
|
||||
pcb->pcb_context[7] = tf->tf_regs[FRAME_PC];
|
||||
pcb->pcb_context[8] = tf->tf_regs[FRAME_PS];
|
||||
pcb->pcb_hw.apcb_ksp = tf->tf_regs[FRAME_SP];
|
||||
}
|
||||
|
||||
int
|
||||
fill_regs(td, regs)
|
||||
struct thread *td;
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ struct pcb {
|
|||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
void makectx(struct trapframe *, struct pcb *);
|
||||
void savectx(struct pcb *);
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -1265,6 +1265,27 @@ cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size)
|
|||
pcpu->pc_acpi_id = 0xffffffff;
|
||||
}
|
||||
|
||||
/*
|
||||
* Construct a PCB from a trapframe. This is called from kdb_trap() where
|
||||
* we want to start a backtrace from the function that caused us to enter
|
||||
* the debugger. We have the context in the trapframe, but base the trace
|
||||
* on the PCB. The PCB doesn't have to be perfect, as long as it contains
|
||||
* enough for a backtrace.
|
||||
*/
|
||||
void
|
||||
makectx(struct trapframe *tf, struct pcb *pcb)
|
||||
{
|
||||
|
||||
pcb->pcb_r12 = tf->tf_r12;
|
||||
pcb->pcb_r13 = tf->tf_r13;
|
||||
pcb->pcb_r14 = tf->tf_r14;
|
||||
pcb->pcb_r15 = tf->tf_r15;
|
||||
pcb->pcb_rbp = tf->tf_rbp;
|
||||
pcb->pcb_rbx = tf->tf_rbx;
|
||||
pcb->pcb_rip = tf->tf_rip;
|
||||
pcb->pcb_rsp = (ISPL(tf->tf_cs)) ? tf->tf_rsp : (long)(tf + 1) - 8;
|
||||
}
|
||||
|
||||
int
|
||||
ptrace_set_pc(struct thread *td, unsigned long addr)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -78,6 +78,9 @@ struct pcb {
|
|||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
struct trapframe;
|
||||
|
||||
void makectx(struct trapframe *, struct pcb *);
|
||||
void savectx(struct pcb *);
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -2206,6 +2206,25 @@ f00f_hack(void *unused)
|
|||
}
|
||||
#endif /* defined(I586_CPU) && !NO_F00F_HACK */
|
||||
|
||||
/*
|
||||
* Construct a PCB from a trapframe. This is called from kdb_trap() where
|
||||
* we want to start a backtrace from the function that caused us to enter
|
||||
* the debugger. We have the context in the trapframe, but base the trace
|
||||
* on the PCB. The PCB doesn't have to be perfect, as long as it contains
|
||||
* enough for a backtrace.
|
||||
*/
|
||||
void
|
||||
makectx(struct trapframe *tf, struct pcb *pcb)
|
||||
{
|
||||
|
||||
pcb->pcb_edi = tf->tf_edi;
|
||||
pcb->pcb_esi = tf->tf_esi;
|
||||
pcb->pcb_ebp = tf->tf_ebp;
|
||||
pcb->pcb_ebx = tf->tf_ebx;
|
||||
pcb->pcb_eip = tf->tf_eip;
|
||||
pcb->pcb_esp = (ISPL(tf->tf_cs)) ? tf->tf_esp : (int)(tf + 1) - 8;
|
||||
}
|
||||
|
||||
int
|
||||
ptrace_set_pc(struct thread *td, u_long addr)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -74,6 +74,9 @@ struct pcb {
|
|||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
struct trapframe;
|
||||
|
||||
void makectx(struct trapframe *, struct pcb *);
|
||||
void savectx(struct pcb *);
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -1017,6 +1017,23 @@ freebsd4_sigreturn(struct thread *td, struct freebsd4_sigreturn_args *uap)
|
|||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Construct a PCB from a trapframe. This is called from kdb_trap() where
|
||||
* we want to start a backtrace from the function that caused us to enter
|
||||
* the debugger. We have the context in the trapframe, but base the trace
|
||||
* on the PCB. The PCB doesn't have to be perfect, as long as it contains
|
||||
* enough for a backtrace.
|
||||
*/
|
||||
void
|
||||
makectx(struct trapframe *tf, struct pcb *pcb)
|
||||
{
|
||||
|
||||
pcb->pcb_special = tf->tf_special;
|
||||
pcb->pcb_special.__spare = ~0UL; /* XXX see unwind.c */
|
||||
save_callee_saved(&pcb->pcb_preserved);
|
||||
save_callee_saved_fp(&pcb->pcb_preserved_fp);
|
||||
}
|
||||
|
||||
int
|
||||
get_mcontext(struct thread *td, mcontext_t *mc, int flags)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*-
|
||||
* Copyright (c) 2003 Doug Rabson
|
||||
* Copyright (c) 2003,2004 Marcel Moolenaar
|
||||
* Copyright (c) 2000 Doug Rabson
|
||||
* All rights reserved.
|
||||
*
|
||||
|
|
@ -59,6 +59,10 @@ struct pcb {
|
|||
#ifdef _KERNEL
|
||||
|
||||
#define savectx(p) swapctx(p, NULL)
|
||||
|
||||
struct trapframe;
|
||||
|
||||
void makectx(struct trapframe *, struct pcb *);
|
||||
void restorectx(struct pcb *) __dead2;
|
||||
int swapctx(struct pcb *old, struct pcb *new);
|
||||
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ struct pcb {
|
|||
} __aligned(64);
|
||||
|
||||
#ifdef _KERNEL
|
||||
void makectx(struct trapframe *, struct pcb *);
|
||||
int savectx(struct pcb *pcb);
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -564,6 +564,21 @@ freebsd4_sigreturn(struct thread *td, struct freebsd4_sigreturn_args *uap)
|
|||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Construct a PCB from a trapframe. This is called from kdb_trap() where
|
||||
* we want to start a backtrace from the function that caused us to enter
|
||||
* the debugger. We have the context in the trapframe, but base the trace
|
||||
* on the PCB. The PCB doesn't have to be perfect, as long as it contains
|
||||
* enough for a backtrace.
|
||||
*/
|
||||
void
|
||||
makectx(struct trapframe *tf, struct pcb *pcb)
|
||||
{
|
||||
|
||||
pcb->pcb_pc = tf->tf_tpc;
|
||||
pcb->pcb_sp = tf->tf_sp;
|
||||
}
|
||||
|
||||
int
|
||||
get_mcontext(struct thread *td, mcontext_t *mc, int flags)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue