1 /* $NetBSD: nlist.c,v 1.28 2020/08/26 10:54:12 simonb Exp $ */ 2 3 /* 4 * Copyright (c) 2000 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Simon Burge. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * Copyright (c) 1990, 1993, 1994 34 * The Regents of the University of California. All rights reserved. 35 * 36 * Redistribution and use in source and binary forms, with or without 37 * modification, are permitted provided that the following conditions 38 * are met: 39 * 1. Redistributions of source code must retain the above copyright 40 * notice, this list of conditions and the following disclaimer. 41 * 2. Redistributions in binary form must reproduce the above copyright 42 * notice, this list of conditions and the following disclaimer in the 43 * documentation and/or other materials provided with the distribution. 44 * 3. Neither the name of the University nor the names of its contributors 45 * may be used to endorse or promote products derived from this software 46 * without specific prior written permission. 47 * 48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 58 * SUCH DAMAGE. 59 */ 60 61 #include <sys/cdefs.h> 62 #ifndef lint 63 #if 0 64 static char sccsid[] = "@(#)nlist.c 8.4 (Berkeley) 4/2/94"; 65 #else 66 __RCSID("$NetBSD: nlist.c,v 1.28 2020/08/26 10:54:12 simonb Exp $"); 67 #endif 68 #endif /* not lint */ 69 70 #include <sys/param.h> 71 #include <sys/time.h> 72 #include <sys/lwp.h> 73 #include <sys/proc.h> 74 #include <sys/resource.h> 75 #include <sys/sysctl.h> 76 77 #include <err.h> 78 #include <errno.h> 79 #include <kvm.h> 80 #include <math.h> 81 #include <nlist.h> 82 #include <stdio.h> 83 #include <string.h> 84 #include <unistd.h> 85 86 #include "ps.h" 87 88 struct nlist psnl[] = { 89 { .n_name = "_fscale" }, 90 #define X_FSCALE 0 91 { .n_name = "_ccpu" }, 92 #define X_CCPU 1 93 { .n_name = "_physmem" }, 94 #define X_PHYSMEM 2 95 { .n_name = "_maxslp" }, 96 #define X_MAXSLP 3 97 { .n_name = NULL } 98 }; 99 100 double log_ccpu; /* log of kernel _ccpu variable */ 101 int nlistread; /* if nlist already read. */ 102 int mempages; /* number of pages of phys. memory */ 103 int fscale; /* kernel _fscale variable */ 104 int maxslp; /* kernel _maxslp variable */ 105 int uspace; /* kernel USPACE value */ 106 107 /* XXX Hopefully reasonable default */ 108 #define MEMPAGES 0 109 #ifndef FSCALE 110 #define FSCALE (1 << 8) 111 #endif 112 #define LOG_CCPU (-1.0 / 20.0) 113 #ifndef MAXSLP 114 #define MAXSLP 20 115 #endif 116 #define DEF_USPACE (getpagesize()) 117 118 #define kread(x, v) \ 119 kvm_read(kd, psnl[x].n_value, (char *)&v, sizeof v) != sizeof(v) 120 121 void 122 donlist(void) 123 { 124 fixpt_t xccpu; 125 126 nlistread = 1; 127 128 if (kvm_nlist(kd, psnl)) { 129 nlisterr(psnl); 130 eval = 1; 131 fscale = FSCALE; 132 mempages = MEMPAGES; 133 log_ccpu = LOG_CCPU; 134 maxslp = MAXSLP; 135 return; 136 } 137 138 if (kread(X_FSCALE, fscale)) { 139 warnx("fscale: %s", kvm_geterr(kd)); 140 eval = 1; 141 fscale = FSCALE; 142 } 143 144 if (kread(X_PHYSMEM, mempages)) { 145 warnx("avail_start: %s", kvm_geterr(kd)); 146 eval = 1; 147 mempages = MEMPAGES; 148 } 149 150 if (kread(X_CCPU, xccpu)) { 151 warnx("ccpu: %s", kvm_geterr(kd)); 152 eval = 1; 153 log_ccpu = LOG_CCPU; 154 } else 155 log_ccpu = log((double)xccpu / fscale); 156 157 if (kread(X_MAXSLP, maxslp)) { 158 warnx("maxslp: %s", kvm_geterr(kd)); 159 eval = 1; 160 maxslp = MAXSLP; 161 } 162 } 163 164 void 165 donlist_sysctl(void) 166 { 167 int mib[2]; 168 size_t size; 169 fixpt_t xccpu; 170 uint64_t memsize; 171 172 nlistread = 1; 173 174 mib[0] = CTL_KERN; 175 mib[1] = KERN_FSCALE; 176 size = sizeof(fscale); 177 if (sysctl(mib, 2, &fscale, &size, NULL, 0)) { 178 warn("sysctl kern.fscale"); 179 eval = 1; 180 fscale = FSCALE; 181 } 182 183 mib[0] = CTL_HW; 184 mib[1] = HW_PHYSMEM64; 185 size = sizeof(memsize); 186 if (sysctl(mib, 2, &memsize, &size, NULL, 0)) { 187 warn("sysctl hw.avail_start"); 188 eval = 1; 189 mempages = MEMPAGES; 190 } else 191 mempages = memsize / getpagesize(); 192 193 mib[0] = CTL_KERN; 194 mib[1] = KERN_CCPU; 195 size = sizeof(xccpu); 196 if (sysctl(mib, 2, &xccpu, &size, NULL, 0)) { 197 warn("sysctl kern.ccpu"); 198 eval = 1; 199 log_ccpu = LOG_CCPU; 200 } else 201 log_ccpu = log((double)xccpu / fscale); 202 203 mib[0] = CTL_VM; 204 mib[1] = VM_MAXSLP; 205 size = sizeof(maxslp); 206 if (sysctl(mib, 2, &maxslp, &size, NULL, 0)) { 207 warn("sysctl vm.maxslp"); 208 eval = 1; 209 maxslp = MAXSLP; 210 } 211 212 mib[0] = CTL_VM; 213 mib[1] = VM_USPACE; 214 size = sizeof(uspace); 215 if (sysctl(mib, 2, &uspace, &size, NULL, 0)) { 216 warn("sysctl vm.uspace"); 217 eval = 1; 218 uspace = DEF_USPACE; 219 } 220 } 221 222 void 223 nlisterr(struct nlist nl[]) 224 { 225 int i; 226 227 (void)fprintf(stderr, "ps: nlist: can't find following symbols:"); 228 for (i = 0; nl[i].n_name != NULL; i++) 229 if (nl[i].n_value == 0) 230 (void)fprintf(stderr, " %s", nl[i].n_name); 231 (void)fprintf(stderr, "\n"); 232 } 233