summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2004-07-10 19:56:00 +0000
committermarcel <marcel@FreeBSD.org>2004-07-10 19:56:00 +0000
commit006d404cf77cb76437589bef7e0e1bb57c7bd79d (patch)
treeef114b5aee4601f2523b9d10bcaef23b379b7b6a
parent8a7d828338d290e43e0ba04946b945be561589c7 (diff)
downloadFreeBSD-src-006d404cf77cb76437589bef7e0e1bb57c7bd79d.zip
FreeBSD-src-006d404cf77cb76437589bef7e0e1bb57c7bd79d.tar.gz
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.
-rw-r--r--sys/alpha/alpha/machdep.c23
-rw-r--r--sys/alpha/include/pcb.h1
-rw-r--r--sys/amd64/amd64/machdep.c21
-rw-r--r--sys/amd64/include/pcb.h3
-rw-r--r--sys/i386/i386/machdep.c19
-rw-r--r--sys/i386/include/pcb.h3
-rw-r--r--sys/ia64/ia64/machdep.c17
-rw-r--r--sys/ia64/include/pcb.h6
-rw-r--r--sys/sparc64/include/pcb.h1
-rw-r--r--sys/sparc64/sparc64/machdep.c15
10 files changed, 108 insertions, 1 deletions
diff --git a/sys/alpha/alpha/machdep.c b/sys/alpha/alpha/machdep.c
index 005e56e..82c856d 100644
--- a/sys/alpha/alpha/machdep.c
+++ b/sys/alpha/alpha/machdep.c
@@ -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;
diff --git a/sys/alpha/include/pcb.h b/sys/alpha/include/pcb.h
index 982e97b..4375ef2 100644
--- a/sys/alpha/include/pcb.h
+++ b/sys/alpha/include/pcb.h
@@ -58,6 +58,7 @@ struct pcb {
};
#ifdef _KERNEL
+void makectx(struct trapframe *, struct pcb *);
void savectx(struct pcb *);
#endif
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index 2d0fd66..8a107ab 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -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)
{
diff --git a/sys/amd64/include/pcb.h b/sys/amd64/include/pcb.h
index 73d8aa5..305b7ff 100644
--- a/sys/amd64/include/pcb.h
+++ b/sys/amd64/include/pcb.h
@@ -78,6 +78,9 @@ struct pcb {
};
#ifdef _KERNEL
+struct trapframe;
+
+void makectx(struct trapframe *, struct pcb *);
void savectx(struct pcb *);
#endif
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index 9fbc6f9..b1b388c 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -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)
{
diff --git a/sys/i386/include/pcb.h b/sys/i386/include/pcb.h
index c88823a..3f32340 100644
--- a/sys/i386/include/pcb.h
+++ b/sys/i386/include/pcb.h
@@ -74,6 +74,9 @@ struct pcb {
};
#ifdef _KERNEL
+struct trapframe;
+
+void makectx(struct trapframe *, struct pcb *);
void savectx(struct pcb *);
#endif
diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c
index ca75d2c..5c39d05 100644
--- a/sys/ia64/ia64/machdep.c
+++ b/sys/ia64/ia64/machdep.c
@@ -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)
{
diff --git a/sys/ia64/include/pcb.h b/sys/ia64/include/pcb.h
index 23d7e50..d018127 100644
--- a/sys/ia64/include/pcb.h
+++ b/sys/ia64/include/pcb.h
@@ -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);
diff --git a/sys/sparc64/include/pcb.h b/sys/sparc64/include/pcb.h
index 38578d2..1f1e8dc 100644
--- a/sys/sparc64/include/pcb.h
+++ b/sys/sparc64/include/pcb.h
@@ -49,6 +49,7 @@ struct pcb {
} __aligned(64);
#ifdef _KERNEL
+void makectx(struct trapframe *, struct pcb *);
int savectx(struct pcb *pcb);
#endif
diff --git a/sys/sparc64/sparc64/machdep.c b/sys/sparc64/sparc64/machdep.c
index 3db2dd8..2bc8329 100644
--- a/sys/sparc64/sparc64/machdep.c
+++ b/sys/sparc64/sparc64/machdep.c
@@ -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)
{
OpenPOWER on IntegriCloud