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 * $FreeBSD$ 30 */ 31 32 #include <sys/param.h> 33 #include <sys/elf.h> 34 #include <sys/sysctl.h> 35 #include <sys/user.h> 36 37 #include <vm/vm.h> 38 39 #include <err.h> 40 #include <errno.h> 41 #include <libprocstat.h> 42 #include <limits.h> 43 #include <stdio.h> 44 #include <stdlib.h> 45 #include <string.h> 46 47 #include "procstat.h" 48 49 void 50 procstat_auxv(struct procstat *procstat, struct kinfo_proc *kipp) 51 { 52 Elf_Auxinfo *auxv; 53 u_int count, i; 54 static char prefix[256]; 55 56 if ((procstat_opts & PS_OPT_NOHEADER) == 0) 57 xo_emit("{T:/%5s %-16s %-16s %-16s}\n", "PID", "COMM", "AUXV", 58 "VALUE"); 59 60 auxv = procstat_getauxv(procstat, kipp, &count); 61 if (auxv == NULL) 62 return; 63 snprintf(prefix, sizeof(prefix), "%5d %-16s", kipp->ki_pid, 64 kipp->ki_comm); 65 66 xo_emit("{e:process_id/%5d/%d}{e:command/%-16s/%s}", kipp->ki_pid, 67 kipp->ki_comm); 68 69 for (i = 0; i < count; i++) { 70 switch(auxv[i].a_type) { 71 case AT_NULL: 72 return; 73 case AT_IGNORE: 74 break; 75 case AT_EXECFD: 76 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_EXECFD/%ld}\n", 77 prefix, "AT_EXECFD", (long)auxv[i].a_un.a_val); 78 break; 79 case AT_PHDR: 80 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_PHDR/%p}\n", 81 prefix, "AT_PHDR", auxv[i].a_un.a_ptr); 82 break; 83 case AT_PHENT: 84 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_PHENT/%ld}\n", 85 prefix, "AT_PHENT", (long)auxv[i].a_un.a_val); 86 break; 87 case AT_PHNUM: 88 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_PHNUM/%ld}\n", 89 prefix, "AT_PHNUM", (long)auxv[i].a_un.a_val); 90 break; 91 case AT_PAGESZ: 92 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_PAGESZ/%ld}\n", 93 prefix, "AT_PAGESZ", (long)auxv[i].a_un.a_val); 94 break; 95 case AT_BASE: 96 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_BASE/%p}\n", 97 prefix, "AT_BASE", auxv[i].a_un.a_ptr); 98 break; 99 case AT_FLAGS: 100 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_FLAGS/%#lx}\n", 101 prefix, "AT_FLAGS", (u_long)auxv[i].a_un.a_val); 102 break; 103 case AT_ENTRY: 104 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_ENTRY/%p}\n", 105 prefix, "AT_ENTRY", auxv[i].a_un.a_ptr); 106 break; 107 #ifdef AT_NOTELF 108 case AT_NOTELF: 109 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_NOTELF/%ld}\n", 110 prefix, "AT_NOTELF", (long)auxv[i].a_un.a_val); 111 break; 112 #endif 113 #ifdef AT_UID 114 case AT_UID: 115 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_UID/%ld}\n", 116 prefix, "AT_UID", (long)auxv[i].a_un.a_val); 117 break; 118 #endif 119 #ifdef AT_EUID 120 case AT_EUID: 121 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_EUID/%ld}\n", 122 prefix, "AT_EUID", (long)auxv[i].a_un.a_val); 123 break; 124 #endif 125 #ifdef AT_GID 126 case AT_GID: 127 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_GID/%ld}\n", 128 prefix, "AT_GID", (long)auxv[i].a_un.a_val); 129 break; 130 #endif 131 #ifdef AT_EGID 132 case AT_EGID: 133 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_EGID/%ld}\n", 134 prefix, "AT_EGID", (long)auxv[i].a_un.a_val); 135 break; 136 #endif 137 case AT_EXECPATH: 138 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_EXECPATH/%p}\n", 139 prefix, "AT_EXECPATH", auxv[i].a_un.a_ptr); 140 break; 141 case AT_CANARY: 142 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_CANARY/%p}\n", 143 prefix, "AT_CANARY", auxv[i].a_un.a_ptr); 144 break; 145 case AT_CANARYLEN: 146 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_CANARYLEN/%ld}\n", 147 prefix, "AT_CANARYLEN", (long)auxv[i].a_un.a_val); 148 break; 149 case AT_OSRELDATE: 150 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_OSRELDATE/%ld}\n", 151 prefix, "AT_OSRELDATE", (long)auxv[i].a_un.a_val); 152 break; 153 case AT_NCPUS: 154 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_NCPUS/%ld}\n", 155 prefix, "AT_NCPUS", (long)auxv[i].a_un.a_val); 156 break; 157 case AT_PAGESIZES: 158 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_PAGESIZES/%p}\n", 159 prefix, "AT_PAGESIZES", auxv[i].a_un.a_ptr); 160 break; 161 case AT_PAGESIZESLEN: 162 xo_emit("{dw:/%s}{Lw:/%-16s/%s}" 163 "{:AT_PAGESIZESLEN/%ld}\n", prefix, 164 "AT_PAGESIZESLEN", (long)auxv[i].a_un.a_val); 165 break; 166 case AT_STACKPROT: 167 if ((auxv[i].a_un.a_val & VM_PROT_EXECUTE) != 0) 168 xo_emit("{dw:/%s}{Lw:/%-16s/%s}" 169 "{:AT_STACKPROT/%s}\n", prefix, 170 "AT_STACKPROT", "EXECUTABLE"); 171 else 172 xo_emit("{dw:/%s}{Lw:/%-16s/%s}" 173 "{:AT_STACKPROT/%s}\n", prefix, 174 "AT_STACKPROT", "NONEXECUTABLE"); 175 break; 176 #ifdef AT_TIMEKEEP 177 case AT_TIMEKEEP: 178 xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_TIMEKEEP/%p}\n", 179 prefix, "AT_TIMEKEEP", auxv[i].a_un.a_ptr); 180 break; 181 #endif 182 default: 183 xo_emit("{dw:/%s}{Lw:/%16ld/%ld}{:UNKNOWN/%#lx}\n", 184 prefix, auxv[i].a_type, auxv[i].a_un.a_val); 185 break; 186 } 187 } 188 xo_emit("\n"); 189 procstat_freeauxv(procstat, auxv); 190 } 191 192