summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2016-01-18 18:27:21 +0000
committerjhb <jhb@FreeBSD.org>2016-01-18 18:27:21 +0000
commite6d9c6386f7459b113c9c9586b3364d2ffd472b3 (patch)
tree74ba68a5c50bce5ed0eb00cf26bc8f79f267249b
parent628004b7857599544a8b1f99cb2114e13254a693 (diff)
downloadFreeBSD-src-e6d9c6386f7459b113c9c9586b3364d2ffd472b3.zip
FreeBSD-src-e6d9c6386f7459b113c9c9586b3364d2ffd472b3.tar.gz
MFC 290728:
Export various helper variables describing the layout and size of certain kernel structures for use by debuggers. This mostly aids in examining cores from a kernel without debug symbols as a debugger can infer these values if debug symbols are available. One set of variables describes the layout of 'struct linker_file' to walk the list of loaded kernel modules. A second set of variables describes the layout of 'struct proc' and 'struct thread' to walk the list of processes in the kernel and the threads in each process. The 'pcb_size' variable is used to index into the stoppcbs[] array. The 'vm_maxuser_address' is used to distinguish kernel virtual addresses from user addresses. This doesn't have to be perfect, and 'vm_maxuser_address' is a cheap and simple way to differentiate kernel pointers from simple values like TIDs and PIDs. While here, annotate the fields in struct pcb used by kgdb on amd64 and i386 to note that their ABI should be preserved. Annotations for other platforms will be added in the future.
-rw-r--r--sys/amd64/include/pcb.h20
-rw-r--r--sys/i386/include/pcb.h16
-rw-r--r--sys/kern/kern_linker.c6
-rw-r--r--sys/kern/kern_mib.c5
-rw-r--r--sys/kern/kern_proc.c15
-rw-r--r--sys/vm/vm_kern.c3
6 files changed, 51 insertions, 14 deletions
diff --git a/sys/amd64/include/pcb.h b/sys/amd64/include/pcb.h
index 4bf9a4f..3f8d4c7 100644
--- a/sys/amd64/include/pcb.h
+++ b/sys/amd64/include/pcb.h
@@ -44,15 +44,19 @@
#include <machine/segments.h>
#ifdef __amd64__
+/*
+ * NB: The fields marked with (*) are used by kernel debuggers. Their
+ * ABI should be preserved.
+ */
struct pcb {
- register_t pcb_r15;
- register_t pcb_r14;
- register_t pcb_r13;
- register_t pcb_r12;
- register_t pcb_rbp;
- register_t pcb_rsp;
- register_t pcb_rbx;
- register_t pcb_rip;
+ register_t pcb_r15; /* (*) */
+ register_t pcb_r14; /* (*) */
+ register_t pcb_r13; /* (*) */
+ register_t pcb_r12; /* (*) */
+ register_t pcb_rbp; /* (*) */
+ register_t pcb_rsp; /* (*) */
+ register_t pcb_rbx; /* (*) */
+ register_t pcb_rip; /* (*) */
register_t pcb_fsbase;
register_t pcb_gsbase;
register_t pcb_kgsbase;
diff --git a/sys/i386/include/pcb.h b/sys/i386/include/pcb.h
index 4bfd603..558565b 100644
--- a/sys/i386/include/pcb.h
+++ b/sys/i386/include/pcb.h
@@ -44,13 +44,17 @@
#endif
#include <machine/npx.h>
+/*
+ * NB: The fields marked with (*) are used by kernel debuggers. Their
+ * ABI should be preserved.
+ */
struct pcb {
- int pcb_edi;
- int pcb_esi;
- int pcb_ebp;
- int pcb_esp;
- int pcb_ebx;
- int pcb_eip;
+ int pcb_edi; /* (*) */
+ int pcb_esi; /* (*) */
+ int pcb_ebp; /* (*) */
+ int pcb_esp; /* (*) */
+ int pcb_ebx; /* (*) */
+ int pcb_eip; /* (*) */
struct segment_descriptor pcb_fsd;
struct segment_descriptor pcb_gsd;
int pcb_ds;
diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c
index e379f5f..78eab87 100644
--- a/sys/kern/kern_linker.c
+++ b/sys/kern/kern_linker.c
@@ -71,6 +71,12 @@ SYSCTL_INT(_debug, OID_AUTO, kld_debug, CTLFLAG_RW | CTLFLAG_TUN,
TUNABLE_INT("debug.kld_debug", &kld_debug);
#endif
+/* These variables are used by kernel debuggers to enumerate loaded files. */
+const int kld_off_address = offsetof(struct linker_file, address);
+const int kld_off_filename = offsetof(struct linker_file, filename);
+const int kld_off_pathname = offsetof(struct linker_file, pathname);
+const int kld_off_next = offsetof(struct linker_file, link.tqe_next);
+
/*
* static char *linker_search_path(const char *name, struct mod_depend
* *verinfo);
diff --git a/sys/kern/kern_mib.c b/sys/kern/kern_mib.c
index 0307791..ccecbc9 100644
--- a/sys/kern/kern_mib.c
+++ b/sys/kern/kern_mib.c
@@ -574,6 +574,11 @@ SYSCTL_INT(_debug_sizeof, OID_AUTO, buf, CTLFLAG_RD,
SYSCTL_INT(_debug_sizeof, OID_AUTO, kinfo_proc, CTLFLAG_RD,
SYSCTL_NULL_INT_PTR, sizeof(struct kinfo_proc), "sizeof(struct kinfo_proc)");
+/* Used by kernel debuggers. */
+const int pcb_size = sizeof(struct pcb);
+SYSCTL_INT(_debug_sizeof, OID_AUTO, pcb, CTLFLAG_RD,
+ SYSCTL_NULL_INT_PTR, sizeof(struct pcb), "sizeof(struct pcb)");
+
/* XXX compatibility, remove for 6.0 */
#include <sys/imgact.h>
#include <sys/imgact_elf.h>
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index c9b7ca3..6b60840 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -139,6 +139,21 @@ struct sx proctree_lock;
struct mtx ppeers_lock;
uma_zone_t proc_zone;
+/*
+ * The offset of various fields in struct proc and struct thread.
+ * These are used by kernel debuggers to enumerate kernel threads and
+ * processes.
+ */
+const int proc_off_p_pid = offsetof(struct proc, p_pid);
+const int proc_off_p_comm = offsetof(struct proc, p_comm);
+const int proc_off_p_list = offsetof(struct proc, p_list);
+const int proc_off_p_threads = offsetof(struct proc, p_threads);
+const int thread_off_td_tid = offsetof(struct thread, td_tid);
+const int thread_off_td_name = offsetof(struct thread, td_name);
+const int thread_off_td_oncpu = offsetof(struct thread, td_oncpu);
+const int thread_off_td_pcb = offsetof(struct thread, td_pcb);
+const int thread_off_td_plist = offsetof(struct thread, td_plist);
+
int kstack_pages = KSTACK_PAGES;
SYSCTL_INT(_kern, OID_AUTO, kstack_pages, CTLFLAG_RD, &kstack_pages, 0,
"Kernel stack size in pages");
diff --git a/sys/vm/vm_kern.c b/sys/vm/vm_kern.c
index 291d0dd..d605c23 100644
--- a/sys/vm/vm_kern.c
+++ b/sys/vm/vm_kern.c
@@ -94,6 +94,9 @@ vm_map_t pipe_map;
const void *zero_region;
CTASSERT((ZERO_REGION_SIZE & PAGE_MASK) == 0);
+/* NB: Used by kernel debuggers. */
+const u_long vm_maxuser_address = VM_MAXUSER_ADDRESS;
+
SYSCTL_ULONG(_vm, OID_AUTO, min_kernel_address, CTLFLAG_RD,
SYSCTL_NULL_ULONG_PTR, VM_MIN_KERNEL_ADDRESS, "Min kernel address");
OpenPOWER on IntegriCloud