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