xref: /freebsd/usr.bin/procstat/procstat_auxv.c (revision 97759ccc715c4b365432c16d763c50eecfcb1100)
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