1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2011 Mikolaj Golub 5 * Copyright (c) 2015 Allan Jude <allanjude@freebsd.org> 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 #include <sys/cdefs.h> 31 #include <sys/param.h> 32 #include <sys/elf.h> 33 #include <sys/sysctl.h> 34 #include <sys/user.h> 35 36 #include <vm/vm.h> 37 38 #include <err.h> 39 #include <errno.h> 40 #include <libprocstat.h> 41 #include <limits.h> 42 #include <stdio.h> 43 #include <stdlib.h> 44 #include <string.h> 45 46 #include "procstat.h" 47 48 void 49 procstat_auxv(struct procstat *procstat, struct kinfo_proc *kipp) 50 { 51 Elf_Auxinfo *auxv; 52 u_int count, i; 53 static char prefix[256]; 54 55 if ((procstat_opts & PS_OPT_NOHEADER) == 0) 56 xo_emit("{T:/%5s %-19s %-16s %-16s}\n", "PID", "COMM", "AUXV", 57 "VALUE"); 58 59 auxv = procstat_getauxv(procstat, kipp, &count); 60 if (auxv == NULL) 61 return; 62 snprintf(prefix, sizeof(prefix), "%5d %-19s", kipp->ki_pid, 63 kipp->ki_comm); 64 65 xo_emit("{e:process_id/%5d/%d}{e:command/%-19s/%s}", kipp->ki_pid, 66 kipp->ki_comm); 67 68 for (i = 0; i < count; i++) { 69 switch(auxv[i].a_type) { 70 case AT_NULL: 71 return; 72 case AT_IGNORE: 73 break; 74 case AT_EXECFD: 75 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_EXECFD/%ld}\n", 76 prefix, "AT_EXECFD", (long)auxv[i].a_un.a_val); 77 break; 78 case AT_PHDR: 79 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_PHDR/%p}\n", 80 prefix, "AT_PHDR", auxv[i].a_un.a_ptr); 81 break; 82 case AT_PHENT: 83 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_PHENT/%ld}\n", 84 prefix, "AT_PHENT", (long)auxv[i].a_un.a_val); 85 break; 86 case AT_PHNUM: 87 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_PHNUM/%ld}\n", 88 prefix, "AT_PHNUM", (long)auxv[i].a_un.a_val); 89 break; 90 case AT_PAGESZ: 91 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_PAGESZ/%ld}\n", 92 prefix, "AT_PAGESZ", (long)auxv[i].a_un.a_val); 93 break; 94 case AT_BASE: 95 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_BASE/%p}\n", 96 prefix, "AT_BASE", auxv[i].a_un.a_ptr); 97 break; 98 case AT_FLAGS: 99 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_FLAGS/%#lx}\n", 100 prefix, "AT_FLAGS", (u_long)auxv[i].a_un.a_val); 101 break; 102 case AT_ENTRY: 103 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_ENTRY/%p}\n", 104 prefix, "AT_ENTRY", auxv[i].a_un.a_ptr); 105 break; 106 #ifdef AT_NOTELF 107 case AT_NOTELF: 108 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_NOTELF/%ld}\n", 109 prefix, "AT_NOTELF", (long)auxv[i].a_un.a_val); 110 break; 111 #endif 112 #ifdef AT_UID 113 case AT_UID: 114 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_UID/%ld}\n", 115 prefix, "AT_UID", (long)auxv[i].a_un.a_val); 116 break; 117 #endif 118 #ifdef AT_EUID 119 case AT_EUID: 120 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_EUID/%ld}\n", 121 prefix, "AT_EUID", (long)auxv[i].a_un.a_val); 122 break; 123 #endif 124 #ifdef AT_GID 125 case AT_GID: 126 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_GID/%ld}\n", 127 prefix, "AT_GID", (long)auxv[i].a_un.a_val); 128 break; 129 #endif 130 #ifdef AT_EGID 131 case AT_EGID: 132 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_EGID/%ld}\n", 133 prefix, "AT_EGID", (long)auxv[i].a_un.a_val); 134 break; 135 #endif 136 case AT_EXECPATH: 137 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_EXECPATH/%p}\n", 138 prefix, "AT_EXECPATH", auxv[i].a_un.a_ptr); 139 break; 140 case AT_CANARY: 141 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_CANARY/%p}\n", 142 prefix, "AT_CANARY", auxv[i].a_un.a_ptr); 143 break; 144 case AT_CANARYLEN: 145 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_CANARYLEN/%ld}\n", 146 prefix, "AT_CANARYLEN", (long)auxv[i].a_un.a_val); 147 break; 148 case AT_OSRELDATE: 149 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_OSRELDATE/%ld}\n", 150 prefix, "AT_OSRELDATE", (long)auxv[i].a_un.a_val); 151 break; 152 case AT_NCPUS: 153 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_NCPUS/%ld}\n", 154 prefix, "AT_NCPUS", (long)auxv[i].a_un.a_val); 155 break; 156 case AT_PAGESIZES: 157 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_PAGESIZES/%p}\n", 158 prefix, "AT_PAGESIZES", auxv[i].a_un.a_ptr); 159 break; 160 case AT_PAGESIZESLEN: 161 xo_emit("{dw:/%s}{Lw:/%-16s/%s}" 162 "{:AT_PAGESIZESLEN/%ld}\n", prefix, 163 "AT_PAGESIZESLEN", (long)auxv[i].a_un.a_val); 164 break; 165 case AT_STACKPROT: 166 if ((auxv[i].a_un.a_val & VM_PROT_EXECUTE) != 0) 167 xo_emit("{dw:/%s}{Lw:/%-16s/%s}" 168 "{:AT_STACKPROT/%s}\n", prefix, 169 "AT_STACKPROT", "EXECUTABLE"); 170 else 171 xo_emit("{dw:/%s}{Lw:/%-16s/%s}" 172 "{:AT_STACKPROT/%s}\n", prefix, 173 "AT_STACKPROT", "NONEXECUTABLE"); 174 break; 175 #ifdef AT_TIMEKEEP 176 case AT_TIMEKEEP: 177 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_TIMEKEEP/%p}\n", 178 prefix, "AT_TIMEKEEP", auxv[i].a_un.a_ptr); 179 break; 180 #endif 181 #ifdef AT_EHDRFLAGS 182 case AT_EHDRFLAGS: 183 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_EHDRFLAGS/%#lx}\n", 184 prefix, "AT_EHDRFLAGS", (u_long)auxv[i].a_un.a_val); 185 break; 186 #endif 187 #ifdef AT_HWCAP 188 case AT_HWCAP: 189 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_HWCAP/%#lx}\n", 190 prefix, "AT_HWCAP", (u_long)auxv[i].a_un.a_val); 191 break; 192 #endif 193 #ifdef AT_HWCAP2 194 case AT_HWCAP2: 195 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_HWCAP2/%#lx}\n", 196 prefix, "AT_HWCAP2", (u_long)auxv[i].a_un.a_val); 197 break; 198 #endif 199 #ifdef AT_BSDFLAGS 200 case AT_BSDFLAGS: 201 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_BSDFLAGS/%#lx}\n", 202 prefix, "AT_BSDFLAGS", (u_long)auxv[i].a_un.a_val); 203 break; 204 #endif 205 #ifdef AT_ARGC 206 case AT_ARGC: 207 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_ARGC/%ld}\n", 208 prefix, "AT_ARGC", (long)auxv[i].a_un.a_val); 209 break; 210 #endif 211 #ifdef AT_ARGV 212 case AT_ARGV: 213 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_ARGV/%p}\n", 214 prefix, "AT_ARGV", auxv[i].a_un.a_ptr); 215 break; 216 #endif 217 #ifdef AT_ENVC 218 case AT_ENVC: 219 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_ENVC/%ld}\n", 220 prefix, "AT_ENVC", (long)auxv[i].a_un.a_val); 221 break; 222 #endif 223 #ifdef AT_ENVV 224 case AT_ENVV: 225 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_ENVV/%p}\n", 226 prefix, "AT_ENVV", auxv[i].a_un.a_ptr); 227 break; 228 #endif 229 #ifdef AT_PS_STRINGS 230 case AT_PS_STRINGS: 231 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_PS_STRINGS/%p}\n", 232 prefix, "AT_PS_STRINGS", auxv[i].a_un.a_ptr); 233 break; 234 #endif 235 #ifdef AT_FXRNG 236 case AT_FXRNG: 237 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_FXRNG/%p}\n", 238 prefix, "AT_FXRNG", auxv[i].a_un.a_ptr); 239 break; 240 #endif 241 #ifdef AT_KPRELOAD 242 case AT_KPRELOAD: 243 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_KPRELOAD/%p}\n", 244 prefix, "AT_KPRELOAD", auxv[i].a_un.a_ptr); 245 break; 246 #endif 247 #ifdef AT_USRSTACKBASE 248 case AT_USRSTACKBASE: 249 xo_emit("{dw:/%s}{Lw:/%-16s/%s}" 250 "{:AT_USRSTACKBASE/%#lx}\n", 251 prefix, "AT_USRSTACKBASE", auxv[i].a_un.a_val); 252 break; 253 #endif 254 #ifdef AT_USRSTACKLIM 255 case AT_USRSTACKLIM: 256 xo_emit("{dw:/%s}{Lw:/%-16s/%s}" 257 "{:AT_USRSTACKLIM/%#lx}\n", 258 prefix, "AT_USRSTACKLIM", auxv[i].a_un.a_val); 259 break; 260 #endif 261 default: 262 xo_emit("{dw:/%s}{Lw:/%16ld/%ld}{:UNKNOWN/%#lx}\n", 263 prefix, auxv[i].a_type, auxv[i].a_un.a_val); 264 break; 265 } 266 } 267 xo_emit("\n"); 268 procstat_freeauxv(procstat, auxv); 269 } 270 271