1 #include <sys/cdefs.h> 2 #include <sys/param.h> 3 #include <sys/sysctl.h> 4 #include <sys/user.h> 5 #include <stdlib.h> 6 #include <string.h> 7 8 #include "libutil.h" 9 10 struct kinfo_vmentry * 11 kinfo_getvmmap(pid_t pid, int *cntp) 12 { 13 int mib[4]; 14 int error; 15 int cnt; 16 size_t len; 17 char *buf, *bp, *eb; 18 struct kinfo_vmentry *kiv, *kp, *kv; 19 20 *cntp = 0; 21 len = 0; 22 mib[0] = CTL_KERN; 23 mib[1] = KERN_PROC; 24 mib[2] = KERN_PROC_VMMAP; 25 mib[3] = pid; 26 27 error = sysctl(mib, nitems(mib), NULL, &len, NULL, 0); 28 if (error) 29 return (NULL); 30 len = len * 4 / 3; 31 buf = malloc(len); 32 if (buf == NULL) 33 return (NULL); 34 error = sysctl(mib, nitems(mib), buf, &len, NULL, 0); 35 if (error) { 36 free(buf); 37 return (NULL); 38 } 39 /* Pass 1: count items */ 40 cnt = 0; 41 bp = buf; 42 eb = buf + len; 43 while (bp < eb) { 44 kv = (struct kinfo_vmentry *)(uintptr_t)bp; 45 if (kv->kve_structsize == 0) 46 break; 47 bp += kv->kve_structsize; 48 cnt++; 49 } 50 51 kiv = calloc(cnt, sizeof(*kiv)); 52 if (kiv == NULL) { 53 free(buf); 54 return (NULL); 55 } 56 bp = buf; 57 eb = buf + len; 58 kp = kiv; 59 /* Pass 2: unpack */ 60 while (bp < eb) { 61 kv = (struct kinfo_vmentry *)(uintptr_t)bp; 62 if (kv->kve_structsize == 0) 63 break; 64 /* Copy/expand into pre-zeroed buffer */ 65 memcpy(kp, kv, kv->kve_structsize); 66 /* Advance to next packed record */ 67 bp += kv->kve_structsize; 68 /* Set field size to fixed length, advance */ 69 kp->kve_structsize = sizeof(*kp); 70 kp++; 71 } 72 free(buf); 73 *cntp = cnt; 74 return (kiv); /* Caller must free() return value */ 75 } 76