1 /*- 2 * Copyright (c) 2011 Mikolaj Golub 3 * Copyright (c) 2015 Allan Jude <allanjude@freebsd.org> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 * $FreeBSD$ 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 (!hflag) 55 xo_emit("{T:/%5s %-16s %-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 %-16s", kipp->ki_pid, 62 kipp->ki_comm); 63 64 xo_emit("{e:process_id/%5d/%d}{e:command/%-16s/%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 default: 181 xo_emit("{dw:/%s}{Lw:/%16ld/%ld}{:UNKNOWN/%#lx}\n", 182 prefix, auxv[i].a_type, auxv[i].a_un.a_val); 183 break; 184 } 185 } 186 xo_emit("\n"); 187 procstat_freeauxv(procstat, auxv); 188 } 189 190