1185493Speter#include <sys/cdefs.h> 2185493Speter__FBSDID("$FreeBSD: stable/10/lib/libutil/kinfo_getvmmap.c 312032 2017-01-13 08:39:40Z ngie $"); 3185493Speter 4186512Srwatson#include <sys/param.h> 5312032Sngie#include <sys/sysctl.h> 6185493Speter#include <sys/user.h> 7185493Speter#include <stdlib.h> 8185493Speter#include <string.h> 9185493Speter 10185493Speter#include "libutil.h" 11185493Speter 12185493Speterstruct kinfo_vmentry * 13185493Speterkinfo_getvmmap(pid_t pid, int *cntp) 14185493Speter{ 15185493Speter int mib[4]; 16185493Speter int error; 17185493Speter int cnt; 18185493Speter size_t len; 19185493Speter char *buf, *bp, *eb; 20185493Speter struct kinfo_vmentry *kiv, *kp, *kv; 21185493Speter 22186314Smarcus *cntp = 0; 23185493Speter len = 0; 24185493Speter mib[0] = CTL_KERN; 25185493Speter mib[1] = KERN_PROC; 26185493Speter mib[2] = KERN_PROC_VMMAP; 27185493Speter mib[3] = pid; 28185493Speter 29312032Sngie error = sysctl(mib, nitems(mib), NULL, &len, NULL, 0); 30185493Speter if (error) 31186314Smarcus return (NULL); 32185493Speter len = len * 4 / 3; 33185493Speter buf = malloc(len); 34185493Speter if (buf == NULL) 35186314Smarcus return (NULL); 36312032Sngie error = sysctl(mib, nitems(mib), buf, &len, NULL, 0); 37185493Speter if (error) { 38185493Speter free(buf); 39186314Smarcus return (NULL); 40185493Speter } 41185493Speter /* Pass 1: count items */ 42185493Speter cnt = 0; 43185493Speter bp = buf; 44185493Speter eb = buf + len; 45185493Speter while (bp < eb) { 46185553Speter kv = (struct kinfo_vmentry *)(uintptr_t)bp; 47295454Sjhb if (kv->kve_structsize == 0) 48295454Sjhb break; 49185493Speter bp += kv->kve_structsize; 50185493Speter cnt++; 51185493Speter } 52185493Speter 53185493Speter kiv = calloc(cnt, sizeof(*kiv)); 54185493Speter if (kiv == NULL) { 55185493Speter free(buf); 56186314Smarcus return (NULL); 57185493Speter } 58185493Speter bp = buf; 59185493Speter eb = buf + len; 60185493Speter kp = kiv; 61185493Speter /* Pass 2: unpack */ 62185493Speter while (bp < eb) { 63185553Speter kv = (struct kinfo_vmentry *)(uintptr_t)bp; 64295454Sjhb if (kv->kve_structsize == 0) 65295454Sjhb break; 66185493Speter /* Copy/expand into pre-zeroed buffer */ 67185493Speter memcpy(kp, kv, kv->kve_structsize); 68185493Speter /* Advance to next packed record */ 69185493Speter bp += kv->kve_structsize; 70185493Speter /* Set field size to fixed length, advance */ 71185493Speter kp->kve_structsize = sizeof(*kp); 72185493Speter kp++; 73185493Speter } 74185493Speter free(buf); 75185493Speter *cntp = cnt; 76185493Speter return (kiv); /* Caller must free() return value */ 77185493Speter} 78