From 4c2d301f6abfa3af6572a66d6c780f0580285c81 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Wed, 27 Mar 2019 10:08:25 -0700 Subject: [PATCH] world - Fix fstat and gcore * fstat needs to iterate vm_map_entry's via the RB tree, but it isn't entirely trivial because we have to kread(). * gcore needs to steal a different field for its iterator when building a map from procfs. * Fixes buildworld. Reported-by: zrj --- usr.bin/fstat/fstat.c | 89 ++++++++++++++++++++++++++++++++++------- usr.bin/gcore/elfcore.c | 6 +-- 2 files changed, 77 insertions(+), 18 deletions(-) diff --git a/usr.bin/fstat/fstat.c b/usr.bin/fstat/fstat.c index 6bc6637d0b..46f0164792 100644 --- a/usr.bin/fstat/fstat.c +++ b/usr.bin/fstat/fstat.c @@ -94,6 +94,7 @@ DEVS *devs; static void make_printable(char *buf, int len); +static int kreadent(const void *kaddr, vm_map_entry_t copy); #ifdef notdef struct nlist nl[] = { @@ -113,6 +114,11 @@ int wflg_cmd = 10; int pid_width = 5; int ino_width = 6; +const char *Uname; +char *Comm; +int Pid; + + struct fdnode *ofiles; /* buffer of pointers to file structures */ int maxfiles; @@ -267,10 +273,6 @@ main(int argc, char **argv) exit(0); } -const char *Uname; -char *Comm; -int Pid; - #define PREFIX(i) \ printf("%-8.8s %-*s %*d", Uname, wflg_cmd, Comm, pid_width, Pid); \ switch(i) { \ @@ -387,13 +389,67 @@ dofiles(struct kinfo_proc *kp, struct proc *p) } } +static +vm_map_entry_t +kinfo_vm_map_entry_first(vm_map_t map, vm_map_entry_t copy) +{ + vm_map_entry_t ken; + + ken = map->rb_root.rbh_root; + if (ken == NULL) + return NULL; + if (!kreadent(ken, copy)) + return NULL; + while (copy->rb_entry.rbe_left) { + ken = copy->rb_entry.rbe_left; + if (!kreadent(ken, copy)) + return NULL; + } + return ken; +} + +static +vm_map_entry_t +kinfo_vm_map_entry_next(vm_map_entry_t ken, vm_map_entry_t copy) +{ + vm_map_entry_t ken2; + + if (copy->rb_entry.rbe_right) { + ken = copy->rb_entry.rbe_right; + if (!kreadent(ken, copy)) + return NULL; + while (copy->rb_entry.rbe_left) { + ken = copy->rb_entry.rbe_left; + if (!kreadent(ken, copy)) + return NULL; + } + } else { + if ((ken2 = copy->rb_entry.rbe_parent) == NULL) + return NULL; + if (!kreadent(ken2, copy)) + return NULL; + if (ken == copy->rb_entry.rbe_left) { + ken = ken2; + } else { + while (ken == copy->rb_entry.rbe_right) { + ken = ken2; + ken2 = copy->rb_entry.rbe_parent; + if (!kreadent(ken2, copy)) + return NULL; + } + ken = ken2; + } + } + return ken; +} + static void dommap(struct proc *p) { struct vmspace vmspace; vm_map_t map; struct vm_map_entry entry; - vm_map_entry_t entryp; + vm_map_entry_t ken; struct vm_object object; vm_object_t objp; int prot, fflags; @@ -405,16 +461,9 @@ dommap(struct proc *p) } map = &vmspace.vm_map; - - for (entryp = map->header.next; entryp != &p->p_vmspace->vm_map.header; - entryp = entry.next) { - if (!kread(entryp, &entry, sizeof(entry))) { - dprintf(stderr, - "can't read vm_map_entry at %p for pid %d\n", - (void *)entryp, Pid); - return; - } - + for (ken = kinfo_vm_map_entry_first(map, &entry); + ken; + ken = kinfo_vm_map_entry_next(ken, &entry)) { if (entry.maptype == VM_MAPTYPE_SUBMAP) continue; @@ -1016,3 +1065,13 @@ kread(const void *kaddr, void *uaddr, size_t nbytes) return(0); } +static +int +kreadent(const void *kaddr, vm_map_entry_t copy) +{ + if (kread(kaddr, copy, sizeof(*copy))) + return 1; + dprintf(stderr, "can't read vm_map_entry at %p for pid %d\n", + kaddr, Pid); + return 0; +} diff --git a/usr.bin/gcore/elfcore.c b/usr.bin/gcore/elfcore.c index 018cd81b0f..59f30facb5 100644 --- a/usr.bin/gcore/elfcore.c +++ b/usr.bin/gcore/elfcore.c @@ -213,7 +213,7 @@ each_writable_segment(vm_map_entry_t map, segment_callback func, void *closure) { vm_map_entry_t entry; - for (entry = map; entry != NULL; entry = entry->next) + for (entry = map; entry; entry = entry->rb_entry.rbe_parent) (*func)(entry, closure); } @@ -359,7 +359,7 @@ static void freemap(vm_map_entry_t map) { while (map != NULL) { - vm_map_entry_t next = map->next; + vm_map_entry_t next = map->rb_entry.rbe_parent; free(map); map = next; } @@ -531,7 +531,7 @@ readmap(pid_t pid) ent->protection |= VM_PROT_EXECUTE; *linkp = ent; - linkp = &ent->next; + linkp = &ent->rb_entry.rbe_parent; } free(mapbuf); return map; -- 2.41.0