xref: /freebsd/usr.bin/procstat/procstat_auxv.c (revision c7046f76)
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 #ifdef AT_USRSTACKBASE
250 		case AT_USRSTACKBASE:
251 			xo_emit("{dw:/%s}{Lw:/%-16s/%s}"
252 			    "{:AT_USRSTACKBASE/%#lx}\n",
253 			    prefix, "AT_USRSTACKBASE", auxv[i].a_un.a_val);
254 			break;
255 #endif
256 #ifdef AT_USRSTACKLIM
257 		case AT_USRSTACKLIM:
258 			xo_emit("{dw:/%s}{Lw:/%-16s/%s}"
259 			    "{:AT_USRSTACKLIM/%#lx}\n",
260 			    prefix, "AT_USRSTACKLIM", auxv[i].a_un.a_val);
261 			break;
262 #endif
263 		default:
264 			xo_emit("{dw:/%s}{Lw:/%16ld/%ld}{:UNKNOWN/%#lx}\n",
265 			    prefix, auxv[i].a_type, auxv[i].a_un.a_val);
266 			break;
267 		}
268 	}
269 	xo_emit("\n");
270 	procstat_freeauxv(procstat, auxv);
271 }
272 
273