63b61837cd
(recommitting the right diff..)
178 lines
4.3 KiB
Plaintext
178 lines
4.3 KiB
Plaintext
$OpenBSD: patch-dialects_n+obsd_dproc_c,v 1.2 2012/03/15 21:39:53 sthen Exp $
|
|
--- dialects/n+obsd/dproc.c.orig Wed May 11 14:54:00 2005
|
|
+++ dialects/n+obsd/dproc.c Sun Jan 8 20:40:43 2012
|
|
@@ -172,7 +172,10 @@ gather_proc_info()
|
|
static int pofb = 0;
|
|
#endif /* defined(HASFSTRUCT) */
|
|
|
|
-#if defined(HASKVMGETPROC2)
|
|
+#if defined(HASKVMGETPROCS)
|
|
+ struct kinfo_proc *p;
|
|
+#define KVMPROCSZ sizeof(struct kinfo_proc)
|
|
+#elif defined(HASKVMGETPROC2)
|
|
struct kinfo_proc2 *p;
|
|
#define KVMPROCSZ2 sizeof(struct kinfo_proc2)
|
|
#else /* !defined(HASKVMGETPROC2) */
|
|
@@ -183,11 +186,13 @@ gather_proc_info()
|
|
* Read the process table.
|
|
*/
|
|
|
|
-#if defined(HASKVMGETPROC2)
|
|
+#if defined(HASKVMGETPROCS)
|
|
+ P = kvm_getprocs(Kd, KERN_PROC_ALL, 0, KVMPROCSZ, &Np);
|
|
+#elif defined(HASKVMGETPROC2)
|
|
P = kvm_getproc2(Kd, KERN_PROC_ALL, 0, KVMPROCSZ2, &Np);
|
|
#else /* !defined(HASKVMGETPROC2) */
|
|
P = kvm_getprocs(Kd, KERN_PROC_ALL, 0, &Np);
|
|
-#endif /* defined(HASKVMGETPROC2) &/
|
|
+#endif /* defined(HASKVMGETPROC2) */
|
|
|
|
if (!P) {
|
|
(void) fprintf(stderr, "%s: can't read process table: %s\n",
|
|
@@ -503,19 +508,98 @@ kread(addr, buf, len)
|
|
return((br == len) ? 0 : 1);
|
|
}
|
|
|
|
+/*
|
|
+ * Download vmmap_entries from the kernel into our address space.
|
|
+ * We fix up the addr tree while downloading.
|
|
+ *
|
|
+ * Returns: the size of the tree on success, or -1 on failure.
|
|
+ * On failure, *rptr needs to be passed to unload_vmmap_entries to free
|
|
+ * the lot.
|
|
+ */
|
|
+ssize_t
|
|
+load_vmmap_entries(KA_T kptr, struct vm_map_entry **rptr,
|
|
+ struct vm_map_entry *parent)
|
|
+{
|
|
+ struct vm_map_entry *entry;
|
|
+ KA_T left_kptr, right_kptr;
|
|
+ ssize_t left_sz;
|
|
+ ssize_t right_sz;
|
|
|
|
+ if (kptr == 0)
|
|
+ return 0;
|
|
+
|
|
+ /* Need space. */
|
|
+ entry = malloc(sizeof(*entry));
|
|
+ if (entry == NULL)
|
|
+ return -1;
|
|
+
|
|
+ /* Download entry at kptr. */
|
|
+ if (!kread(kptr, (char *)entry, sizeof(*entry))) {
|
|
+ free(entry);
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Update addr pointers to have sane values in this address space.
|
|
+ * We save the kernel pointers in {left,right}_kptr, so we have them
|
|
+ * available to download children.
|
|
+ */
|
|
+ left_kptr = (KA_T) RB_LEFT(entry, daddrs.addr_entry);
|
|
+ right_kptr = (KA_T) RB_RIGHT(entry, daddrs.addr_entry);
|
|
+ RB_LEFT(entry, daddrs.addr_entry) =
|
|
+ RB_RIGHT(entry, daddrs.addr_entry) = NULL;
|
|
+ /* Fill in parent pointer. */
|
|
+ RB_PARENT(entry, daddrs.addr_entry) = parent;
|
|
+
|
|
+ /*
|
|
+ * Consistent state reached, fill in *rptr.
|
|
+ */
|
|
+ *rptr = entry;
|
|
+
|
|
+ /*
|
|
+ * Download left, right.
|
|
+ * On failure, our map is in a state that can be handled by
|
|
+ * unload_vmmap_entries.
|
|
+ */
|
|
+ left_sz = load_vmmap_entries(left_kptr,
|
|
+ &RB_LEFT(entry, daddrs.addr_entry), entry);
|
|
+ if (left_sz == -1)
|
|
+ return -1;
|
|
+ right_sz = load_vmmap_entries(right_kptr,
|
|
+ &RB_RIGHT(entry, daddrs.addr_entry), entry);
|
|
+ if (right_sz == -1)
|
|
+ return -1;
|
|
+
|
|
+ return 1 + left_sz + right_sz;
|
|
+}
|
|
+
|
|
/*
|
|
+ * Free the vmmap entries in the given tree.
|
|
+ */
|
|
+void
|
|
+unload_vmmap_entries(struct vm_map_entry *entry)
|
|
+{
|
|
+ if (entry == NULL)
|
|
+ return;
|
|
+
|
|
+ unload_vmmap_entries(RB_LEFT(entry, daddrs.addr_entry));
|
|
+ unload_vmmap_entries(RB_RIGHT(entry, daddrs.addr_entry));
|
|
+ free(entry);
|
|
+}
|
|
+
|
|
+/*
|
|
* process_text() - process text information
|
|
*/
|
|
void
|
|
process_text(vm)
|
|
KA_T vm; /* kernel vm space pointer */
|
|
{
|
|
- int i, j;
|
|
+ int j;
|
|
KA_T ka;
|
|
int n = 0;
|
|
struct vm_map_entry vmme, *e;
|
|
struct vmspace vmsp;
|
|
+ struct uvm_map_addr root;
|
|
|
|
#if !defined(UVM)
|
|
struct pager_struct pg;
|
|
@@ -536,20 +620,12 @@ process_text(vm)
|
|
return;
|
|
#endif /* !defined(UVM) */
|
|
|
|
- for (i = 0; i < vmsp.vm_map.nentries; i++) {
|
|
+ RB_INIT(&root);
|
|
+ if (load_vmmap_entries((KA_T) RB_ROOT(&vmsp.vm_map.addr),
|
|
+ &RB_ROOT(&root), NULL) == -1)
|
|
+ goto do_unload;
|
|
|
|
- /*
|
|
- * Read the next vm_map_entry.
|
|
- */
|
|
- if (!i)
|
|
- e = &vmsp.vm_map.header;
|
|
- else {
|
|
- if (!(ka = (KA_T)e->next))
|
|
- return;
|
|
- e = &vmme;
|
|
- if (kread(ka, (char *)e, sizeof(vmme)))
|
|
- return;
|
|
- }
|
|
+ RB_FOREACH(e, uvm_map_addr, &root) {
|
|
|
|
#if defined(UVM)
|
|
/*
|
|
@@ -581,4 +657,19 @@ process_text(vm)
|
|
#endif /* defined(UVM) */
|
|
|
|
}
|
|
+
|
|
+do_unload:
|
|
+ unload_vmmap_entries(RB_ROOT(&root));
|
|
}
|
|
+
|
|
+/*
|
|
+ * Don't implement address comparison.
|
|
+ */
|
|
+static __inline int
|
|
+no_impl(void *p, void *q)
|
|
+{
|
|
+ abort(); /* Should not be called. */
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+RB_GENERATE(uvm_map_addr, vm_map_entry, daddrs.addr_entry, no_impl);
|