1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 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 __FBSDID("$FreeBSD$"); 32 33 #include <sys/param.h> 34 #include <sys/elf.h> 35 #include <sys/sysctl.h> 36 #include <sys/user.h> 37 38 #include <vm/vm.h> 39 40 #include <err.h> 41 #include <errno.h> 42 #include <libprocstat.h> 43 #include <limits.h> 44 #include <stdio.h> 45 #include <stdlib.h> 46 #include <string.h> 47 48 #include "procstat.h" 49 50 void 51 procstat_auxv(struct procstat *procstat, struct kinfo_proc *kipp) 52 { 53 Elf_Auxinfo *auxv; 54 u_int count, i; 55 static char prefix[256]; 56 57 if ((procstat_opts & PS_OPT_NOHEADER) == 0) 58 xo_emit("{T:/%5s %-16s %-16s %-16s}\n", "PID", "COMM", "AUXV", 59 "VALUE"); 60 61 auxv = procstat_getauxv(procstat, kipp, &count); 62 if (auxv == NULL) 63 return; 64 snprintf(prefix, sizeof(prefix), "%5d %-16s", kipp->ki_pid, 65 kipp->ki_comm); 66 67 xo_emit("{e:process_id/%5d/%d}{e:command/%-16s/%s}", kipp->ki_pid, 68 kipp->ki_comm); 69 70 for (i = 0; i < count; i++) { 71 switch(auxv[i].a_type) { 72 case AT_NULL: 73 return; 74 case AT_IGNORE: 75 break; 76 case AT_EXECFD: 77 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_EXECFD/%ld}\n", 78 prefix, "AT_EXECFD", (long)auxv[i].a_un.a_val); 79 break; 80 case AT_PHDR: 81 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_PHDR/%p}\n", 82 prefix, "AT_PHDR", auxv[i].a_un.a_ptr); 83 break; 84 case AT_PHENT: 85 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_PHENT/%ld}\n", 86 prefix, "AT_PHENT", (long)auxv[i].a_un.a_val); 87 break; 88 case AT_PHNUM: 89 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_PHNUM/%ld}\n", 90 prefix, "AT_PHNUM", (long)auxv[i].a_un.a_val); 91 break; 92 case AT_PAGESZ: 93 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_PAGESZ/%ld}\n", 94 prefix, "AT_PAGESZ", (long)auxv[i].a_un.a_val); 95 break; 96 case AT_BASE: 97 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_BASE/%p}\n", 98 prefix, "AT_BASE", auxv[i].a_un.a_ptr); 99 break; 100 case AT_FLAGS: 101 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_FLAGS/%#lx}\n", 102 prefix, "AT_FLAGS", (u_long)auxv[i].a_un.a_val); 103 break; 104 case AT_ENTRY: 105 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_ENTRY/%p}\n", 106 prefix, "AT_ENTRY", auxv[i].a_un.a_ptr); 107 break; 108 #ifdef AT_NOTELF 109 case AT_NOTELF: 110 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_NOTELF/%ld}\n", 111 prefix, "AT_NOTELF", (long)auxv[i].a_un.a_val); 112 break; 113 #endif 114 #ifdef AT_UID 115 case AT_UID: 116 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_UID/%ld}\n", 117 prefix, "AT_UID", (long)auxv[i].a_un.a_val); 118 break; 119 #endif 120 #ifdef AT_EUID 121 case AT_EUID: 122 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_EUID/%ld}\n", 123 prefix, "AT_EUID", (long)auxv[i].a_un.a_val); 124 break; 125 #endif 126 #ifdef AT_GID 127 case AT_GID: 128 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_GID/%ld}\n", 129 prefix, "AT_GID", (long)auxv[i].a_un.a_val); 130 break; 131 #endif 132 #ifdef AT_EGID 133 case AT_EGID: 134 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_EGID/%ld}\n", 135 prefix, "AT_EGID", (long)auxv[i].a_un.a_val); 136 break; 137 #endif 138 case AT_EXECPATH: 139 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_EXECPATH/%p}\n", 140 prefix, "AT_EXECPATH", auxv[i].a_un.a_ptr); 141 break; 142 case AT_CANARY: 143 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_CANARY/%p}\n", 144 prefix, "AT_CANARY", auxv[i].a_un.a_ptr); 145 break; 146 case AT_CANARYLEN: 147 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_CANARYLEN/%ld}\n", 148 prefix, "AT_CANARYLEN", (long)auxv[i].a_un.a_val); 149 break; 150 case AT_OSRELDATE: 151 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_OSRELDATE/%ld}\n", 152 prefix, "AT_OSRELDATE", (long)auxv[i].a_un.a_val); 153 break; 154 case AT_NCPUS: 155 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_NCPUS/%ld}\n", 156 prefix, "AT_NCPUS", (long)auxv[i].a_un.a_val); 157 break; 158 case AT_PAGESIZES: 159 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_PAGESIZES/%p}\n", 160 prefix, "AT_PAGESIZES", auxv[i].a_un.a_ptr); 161 break; 162 case AT_PAGESIZESLEN: 163 xo_emit("{dw:/%s}{Lw:/%-16s/%s}" 164 "{:AT_PAGESIZESLEN/%ld}\n", prefix, 165 "AT_PAGESIZESLEN", (long)auxv[i].a_un.a_val); 166 break; 167 case AT_STACKPROT: 168 if ((auxv[i].a_un.a_val & VM_PROT_EXECUTE) != 0) 169 xo_emit("{dw:/%s}{Lw:/%-16s/%s}" 170 "{:AT_STACKPROT/%s}\n", prefix, 171 "AT_STACKPROT", "EXECUTABLE"); 172 else 173 xo_emit("{dw:/%s}{Lw:/%-16s/%s}" 174 "{:AT_STACKPROT/%s}\n", prefix, 175 "AT_STACKPROT", "NONEXECUTABLE"); 176 break; 177 #ifdef AT_TIMEKEEP 178 case AT_TIMEKEEP: 179 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_TIMEKEEP/%p}\n", 180 prefix, "AT_TIMEKEEP", auxv[i].a_un.a_ptr); 181 break; 182 #endif 183 #ifdef AT_EHDRFLAGS 184 case AT_EHDRFLAGS: 185 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_EHDRFLAGS/%#lx}\n", 186 prefix, "AT_EHDRFLAGS", (u_long)auxv[i].a_un.a_val); 187 break; 188 #endif 189 #ifdef AT_HWCAP 190 case AT_HWCAP: 191 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_HWCAP/%#lx}\n", 192 prefix, "AT_HWCAP", (u_long)auxv[i].a_un.a_val); 193 break; 194 #endif 195 #ifdef AT_HWCAP2 196 case AT_HWCAP2: 197 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_HWCAP2/%#lx}\n", 198 prefix, "AT_HWCAP2", (u_long)auxv[i].a_un.a_val); 199 break; 200 #endif 201 #ifdef AT_BSDFLAGS 202 case AT_BSDFLAGS: 203 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_BSDFLAGS/%#lx}\n", 204 prefix, "AT_BSDFLAGS", (u_long)auxv[i].a_un.a_val); 205 break; 206 #endif 207 #ifdef AT_ARGC 208 case AT_ARGC: 209 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_ARGC/%ld}\n", 210 prefix, "AT_ARGC", (long)auxv[i].a_un.a_val); 211 break; 212 #endif 213 #ifdef AT_ARGV 214 case AT_ARGV: 215 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_ARGV/%p}\n", 216 prefix, "AT_ARGV", auxv[i].a_un.a_ptr); 217 break; 218 #endif 219 #ifdef AT_ENVC 220 case AT_ENVC: 221 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_ENVC/%ld}\n", 222 prefix, "AT_ENVC", (long)auxv[i].a_un.a_val); 223 break; 224 #endif 225 #ifdef AT_ENVV 226 case AT_ENVV: 227 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_ENVV/%p}\n", 228 prefix, "AT_ENVV", auxv[i].a_un.a_ptr); 229 break; 230 #endif 231 #ifdef AT_PS_STRINGS 232 case AT_PS_STRINGS: 233 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_PS_STRINGS/%p}\n", 234 prefix, "AT_PS_STRINGS", auxv[i].a_un.a_ptr); 235 break; 236 #endif 237 #ifdef AT_FXRNG 238 case AT_FXRNG: 239 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_FXRNG/%p}\n", 240 prefix, "AT_FXRNG", auxv[i].a_un.a_ptr); 241 break; 242 #endif 243 #ifdef AT_KPRELOAD 244 case AT_KPRELOAD: 245 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_KPRELOAD/%p}\n", 246 prefix, "AT_KPRELOAD", auxv[i].a_un.a_ptr); 247 break; 248 #endif 249 default: 250 xo_emit("{dw:/%s}{Lw:/%16ld/%ld}{:UNKNOWN/%#lx}\n", 251 prefix, auxv[i].a_type, auxv[i].a_un.a_val); 252 break; 253 } 254 } 255 xo_emit("\n"); 256 procstat_freeauxv(procstat, auxv); 257 } 258 259