xref: /freebsd/usr.bin/procstat/procstat_auxv.c (revision 2f513db72b034fd5ef7f080b11be5c711c15186a)
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 #ifdef AT_EHDRFLAGS
183 		case AT_EHDRFLAGS:
184 			xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_EHDRFLAGS/%#lx}\n",
185 			    prefix, "AT_EHDRFLAGS", (u_long)auxv[i].a_un.a_val);
186 			break;
187 #endif
188 #ifdef AT_HWCAP
189 		case AT_HWCAP:
190 			xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_HWCAP/%#lx}\n",
191 			    prefix, "AT_HWCAP", (u_long)auxv[i].a_un.a_val);
192 			break;
193 #endif
194 #ifdef AT_HWCAP2
195 		case AT_HWCAP2:
196 			xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_HWCAP2/%#lx}\n",
197 			    prefix, "AT_HWCAP2", (u_long)auxv[i].a_un.a_val);
198 			break;
199 #endif
200 #ifdef AT_BSDFLAGS
201 		case AT_BSDFLAGS:
202 			xo_emit("{dw:/%s}{Lw:/%-16s/%s}{:AT_BSDFLAGS/%#lx}\n",
203 			    prefix, "AT_BSDFLAGS", (u_long)auxv[i].a_un.a_val);
204 			break;
205 #endif
206 		default:
207 			xo_emit("{dw:/%s}{Lw:/%16ld/%ld}{:UNKNOWN/%#lx}\n",
208 			    prefix, auxv[i].a_type, auxv[i].a_un.a_val);
209 			break;
210 		}
211 	}
212 	xo_emit("\n");
213 	procstat_freeauxv(procstat, auxv);
214 }
215 
216