xref: /illumos-gate/usr/src/cmd/sgs/elfdump/common/gen_struct_layout.c (revision 7655c6d53c36750b508636f48c73a2de57754e5a)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  *
26  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
27  * Copyright 2018 Joyent, Inc.
28  * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
29  */
30 
31 /*
32  * This program is used to generate the contents of the
33  * struct_layout_XXX.c files that contain per-architecture
34  * structure layout information.
35  *
36  * Although not part of elfdump, it is built by the makefile
37  * along with it. Note, the Makefile only builds versions that
38  * are natively supported and therefore you must manually run
39  * this for other architectures.
40  *
41  * To use it:
42  *
43  *	1) Run it, capturing the output in a file.
44  *	2) If this is a replacement for an existing file,
45  *		diff the new and old copies to ensure only
46  *		the changes you expected are present.
47  *	3) Put the new file in the common directory under the name
48  *		struct_layout_XXX.c, where XXX is the name of
49  *		the architecture (i386, amd64, sparc, sparcv9, etc).
50  *	2) Add any necessary header and copyright comments.
51  *	3) If this is a new architecture:
52  *		- Add an extern statement for struct_layout_XXX()
53  *			to struct_layout.h
54  *		- Add a case for it to the function sl_struct_layout()
55  *			in struct_layout.c.
56  */
57 
58 #include <string.h>
59 #include <stdio.h>
60 #include <stdlib.h>
61 #include <ctype.h>
62 #include <err.h>
63 #include <sys/types.h>
64 #include <libctf.h>
65 
66 /*
67  * This extracts CTF information from a temporary object file.
68  *
69  * START and END bracket a struct layout definition. They issue
70  * the typedef boilerplate, and the standard first element (sizeof)
71  * which captures the overall size of the structure.
72  *
73  * SCALAR_FIELD is for scalar struct fields
74  *
75  * ARRAY_FIELD is for  array struct fields
76  *
77  * ARRAY_TYPE is for plain (non-struct) array types
78  */
79 #define	START(_name, _type) \
80 	do_start(#_name, #_type)
81 #define	END (void) \
82 	do_end()
83 #define	SCALAR_FIELD(_type, _field, _sign) \
84 	do_scalar_field(#_type, #_field, _sign, NULL)
85 #define	SCALAR_FIELD4(_type, _field, _sign, _rtype) \
86 	do_scalar_field(#_type, #_field, _sign, _rtype)
87 #define	ARRAY_FIELD(_type, _field, _sign) \
88 	do_array_field(#_type, #_field, _sign, NULL)
89 #define	ARRAY_TYPE(_type, _sign) \
90 	do_array_type(#_type, "elt0", _sign)
91 
92 static void do_start(char *_name, char *_type);
93 static void do_end(void);
94 static void do_start_name(char *name);
95 static void do_start_sizeof(char *_type, char *realtype);
96 static void do_scalar_field(char *_type, char *_field,
97 	int _sign, char *dotfield);
98 static void do_array_field(char *_type, char *_field,
99 	int _sign, char *dotfield);
100 static void do_array_type(char *_type, char *_field, int _sign);
101 
102 static void get_ctf_file(char *fname);
103 static int get_field_info(char *tname, char *fname, char *dotname,
104 	int *offp, int *sizep);
105 
106 static ctf_file_t *ctf;
107 static char *objfile;
108 static char *machname;
109 
110 /* auxv_t, <sys/auxv.h> */
111 static void
112 gen_auxv(void)
113 {
114 	START(auxv, auxv_t);
115 
116 	SCALAR_FIELD(auxv_t,	a_type,	1);
117 	SCALAR_FIELD(auxv_t,	a_un.a_val,	1);
118 	SCALAR_FIELD(auxv_t,	a_un.a_ptr,	0);
119 	SCALAR_FIELD(auxv_t,	a_un.a_fcn,	0);
120 
121 	END;
122 }
123 
124 
125 /* prgregset_t, <sys/prgregset.h> */
126 static void
127 gen_prgregset(void)
128 {
129 	START(prgregset, prgregset_t);
130 
131 	ARRAY_TYPE(prgregset_t,	0);
132 
133 	END;
134 }
135 
136 
137 /* lwpstatus_t, <sys/procfs.h> */
138 static void
139 gen_lwpstatus(void)
140 {
141 	START(lwpstatus, lwpstatus_t);
142 
143 	SCALAR_FIELD(lwpstatus_t,	pr_flags,	0);
144 	SCALAR_FIELD(lwpstatus_t,	pr_lwpid,	0);
145 	SCALAR_FIELD(lwpstatus_t,	pr_why,		0);
146 	SCALAR_FIELD(lwpstatus_t,	pr_what,	0);
147 	SCALAR_FIELD(lwpstatus_t,	pr_cursig,	0);
148 	SCALAR_FIELD(lwpstatus_t,	pr_info,	0);
149 	SCALAR_FIELD(lwpstatus_t,	pr_lwppend,	0);
150 	SCALAR_FIELD(lwpstatus_t,	pr_lwphold,	0);
151 	SCALAR_FIELD(lwpstatus_t,	pr_action,	0);
152 	SCALAR_FIELD(lwpstatus_t,	pr_altstack,	0);
153 	SCALAR_FIELD(lwpstatus_t,	pr_oldcontext,	0);
154 	SCALAR_FIELD(lwpstatus_t,	pr_syscall,	0);
155 	SCALAR_FIELD(lwpstatus_t,	pr_nsysarg,	0);
156 	SCALAR_FIELD(lwpstatus_t,	pr_errno,	0);
157 	ARRAY_FIELD(lwpstatus_t,	pr_sysarg,	0);
158 	SCALAR_FIELD(lwpstatus_t,	pr_rval1,	0);
159 	SCALAR_FIELD(lwpstatus_t,	pr_rval2,	0);
160 	ARRAY_FIELD(lwpstatus_t,	pr_clname,	0);
161 	SCALAR_FIELD(lwpstatus_t,	pr_tstamp,	0);
162 	SCALAR_FIELD(lwpstatus_t,	pr_utime,	0);
163 	SCALAR_FIELD(lwpstatus_t,	pr_stime,	0);
164 	SCALAR_FIELD(lwpstatus_t,	pr_errpriv,	0);
165 	SCALAR_FIELD(lwpstatus_t,	pr_ustack,	0);
166 	SCALAR_FIELD(lwpstatus_t,	pr_instr,	0);
167 	SCALAR_FIELD(lwpstatus_t,	pr_reg,		0);
168 	SCALAR_FIELD(lwpstatus_t,	pr_fpreg,	0);
169 
170 	END;
171 }
172 
173 
174 /* pstatus_t, <sys/procfs.h> */
175 static void
176 gen_pstatus(void)
177 {
178 	START(pstatus, pstatus_t);
179 
180 	SCALAR_FIELD(pstatus_t,		pr_flags,	1);
181 	SCALAR_FIELD(pstatus_t,		pr_nlwp,	1);
182 	SCALAR_FIELD(pstatus_t,		pr_pid,		0);
183 	SCALAR_FIELD(pstatus_t,		pr_ppid,	0);
184 	SCALAR_FIELD(pstatus_t,		pr_pgid,	0);
185 	SCALAR_FIELD(pstatus_t,		pr_sid,		0);
186 	SCALAR_FIELD(pstatus_t,		pr_aslwpid,	1);
187 	SCALAR_FIELD(pstatus_t,		pr_agentid,	1);
188 	SCALAR_FIELD(pstatus_t,		pr_sigpend,	0);
189 	SCALAR_FIELD(pstatus_t,		pr_brkbase,	0);
190 	SCALAR_FIELD(pstatus_t,		pr_brksize,	0);
191 	SCALAR_FIELD(pstatus_t,		pr_stkbase,	0);
192 	SCALAR_FIELD(pstatus_t,		pr_stksize,	0);
193 	SCALAR_FIELD(pstatus_t,		pr_utime,	0);
194 	SCALAR_FIELD(pstatus_t,		pr_stime,	0);
195 	SCALAR_FIELD(pstatus_t,		pr_cutime,	0);
196 	SCALAR_FIELD(pstatus_t,		pr_cstime,	0);
197 	SCALAR_FIELD(pstatus_t,		pr_sigtrace,	0);
198 	SCALAR_FIELD(pstatus_t,		pr_flttrace,	0);
199 	SCALAR_FIELD(pstatus_t,		pr_sysentry,	0);
200 	SCALAR_FIELD(pstatus_t,		pr_sysexit,	0);
201 	SCALAR_FIELD(pstatus_t,		pr_dmodel,	0);
202 	SCALAR_FIELD(pstatus_t,		pr_taskid,	1);
203 	SCALAR_FIELD(pstatus_t,		pr_projid,	1);
204 	SCALAR_FIELD(pstatus_t,		pr_nzomb,	1);
205 	SCALAR_FIELD(pstatus_t,		pr_zoneid,	1);
206 	SCALAR_FIELD(pstatus_t,		pr_lwp,		0);
207 
208 	END;
209 }
210 
211 
212 /* prstatus_t, <sys/old_procfs.h> */
213 static void
214 gen_prstatus(void)
215 {
216 	START(prstatus, prstatus_t);
217 
218 	SCALAR_FIELD(prstatus_t,	pr_flags,	1);
219 	SCALAR_FIELD(prstatus_t,	pr_why,		1);
220 	SCALAR_FIELD(prstatus_t,	pr_what,	1);
221 	SCALAR_FIELD(prstatus_t,	pr_info,	0);
222 	SCALAR_FIELD(prstatus_t,	pr_cursig,	1);
223 	SCALAR_FIELD(prstatus_t,	pr_nlwp,	0);
224 	SCALAR_FIELD(prstatus_t,	pr_sigpend,	0);
225 	SCALAR_FIELD(prstatus_t,	pr_sighold,	0);
226 	SCALAR_FIELD(prstatus_t,	pr_altstack,	0);
227 	SCALAR_FIELD(prstatus_t,	pr_action,	0);
228 	SCALAR_FIELD(prstatus_t,	pr_pid,		0);
229 	SCALAR_FIELD(prstatus_t,	pr_ppid,	0);
230 	SCALAR_FIELD(prstatus_t,	pr_pgrp,	0);
231 	SCALAR_FIELD(prstatus_t,	pr_sid,		0);
232 	SCALAR_FIELD(prstatus_t,	pr_utime,	0);
233 	SCALAR_FIELD(prstatus_t,	pr_stime,	0);
234 	SCALAR_FIELD(prstatus_t,	pr_cutime,	0);
235 	SCALAR_FIELD(prstatus_t,	pr_cstime,	0);
236 	ARRAY_FIELD(prstatus_t,		pr_clname,	0);
237 	SCALAR_FIELD(prstatus_t,	pr_syscall,	1);
238 	SCALAR_FIELD(prstatus_t,	pr_nsysarg,	1);
239 	ARRAY_FIELD(prstatus_t,		pr_sysarg,	1);
240 	SCALAR_FIELD(prstatus_t,	pr_who,		0);
241 	SCALAR_FIELD(prstatus_t,	pr_lwppend,	0);
242 	SCALAR_FIELD(prstatus_t,	pr_oldcontext,	0);
243 	SCALAR_FIELD(prstatus_t,	pr_brkbase,	0);
244 	SCALAR_FIELD(prstatus_t,	pr_brksize,	0);
245 	SCALAR_FIELD(prstatus_t,	pr_stkbase,	0);
246 	SCALAR_FIELD(prstatus_t,	pr_stksize,	0);
247 	SCALAR_FIELD(prstatus_t,	pr_processor,	1);
248 	SCALAR_FIELD(prstatus_t,	pr_bind,	1);
249 	SCALAR_FIELD(prstatus_t,	pr_instr,	1);
250 	SCALAR_FIELD(prstatus_t,	pr_reg,		0);
251 
252 	END;
253 }
254 
255 
256 /* psinfo_t, <sys/procfs.h> */
257 static void
258 gen_psinfo(void)
259 {
260 	START(psinfo, psinfo_t);
261 
262 	SCALAR_FIELD(psinfo_t,		pr_flag,	1);
263 	SCALAR_FIELD(psinfo_t,		pr_nlwp,	1);
264 	SCALAR_FIELD(psinfo_t,		pr_pid,		0);
265 	SCALAR_FIELD(psinfo_t,		pr_ppid,	0);
266 	SCALAR_FIELD(psinfo_t,		pr_pgid,	0);
267 	SCALAR_FIELD(psinfo_t,		pr_sid,		0);
268 	SCALAR_FIELD(psinfo_t,		pr_uid,		0);
269 	SCALAR_FIELD(psinfo_t,		pr_euid,	0);
270 	SCALAR_FIELD(psinfo_t,		pr_gid,		0);
271 	SCALAR_FIELD(psinfo_t,		pr_egid,	0);
272 	SCALAR_FIELD(psinfo_t,		pr_addr,	0);
273 	SCALAR_FIELD(psinfo_t,		pr_size,	0);
274 	SCALAR_FIELD(psinfo_t,		pr_rssize,	0);
275 	SCALAR_FIELD(psinfo_t,		pr_ttydev,	0);
276 	SCALAR_FIELD(psinfo_t,		pr_pctcpu,	0);
277 	SCALAR_FIELD(psinfo_t,		pr_pctmem,	0);
278 	SCALAR_FIELD(psinfo_t,		pr_start,	0);
279 	SCALAR_FIELD(psinfo_t,		pr_time,	0);
280 	SCALAR_FIELD(psinfo_t,		pr_ctime,	0);
281 	ARRAY_FIELD(psinfo_t,		pr_fname,	0);
282 	ARRAY_FIELD(psinfo_t,		pr_psargs,	0);
283 	SCALAR_FIELD(psinfo_t,		pr_wstat,	1);
284 	SCALAR_FIELD(psinfo_t,		pr_argc,	1);
285 	SCALAR_FIELD(psinfo_t,		pr_argv,	0);
286 	SCALAR_FIELD(psinfo_t,		pr_envp,	0);
287 	SCALAR_FIELD(psinfo_t,		pr_dmodel,	0);
288 	SCALAR_FIELD(psinfo_t,		pr_taskid,	0);
289 	SCALAR_FIELD(psinfo_t,		pr_projid,	0);
290 	SCALAR_FIELD(psinfo_t,		pr_nzomb,	1);
291 	SCALAR_FIELD(psinfo_t,		pr_poolid,	0);
292 	SCALAR_FIELD(psinfo_t,		pr_zoneid,	0);
293 	SCALAR_FIELD(psinfo_t,		pr_contract,	0);
294 	SCALAR_FIELD(psinfo_t,		pr_lwp,		0);
295 
296 	END;
297 }
298 
299 /* prpsinfo_t, <sys/old_procfs.h> */
300 static void
301 gen_prpsinfo(void)
302 {
303 	START(prpsinfo, prpsinfo_t);
304 
305 	SCALAR_FIELD(prpsinfo_t,	pr_state,	0);
306 	SCALAR_FIELD(prpsinfo_t,	pr_sname,	0);
307 	SCALAR_FIELD(prpsinfo_t,	pr_zomb,	0);
308 	SCALAR_FIELD(prpsinfo_t,	pr_nice,	0);
309 	SCALAR_FIELD(prpsinfo_t,	pr_flag,	0);
310 	SCALAR_FIELD(prpsinfo_t,	pr_uid,		0);
311 	SCALAR_FIELD(prpsinfo_t,	pr_gid,		0);
312 	SCALAR_FIELD(prpsinfo_t,	pr_pid,		0);
313 	SCALAR_FIELD(prpsinfo_t,	pr_ppid,	0);
314 	SCALAR_FIELD(prpsinfo_t,	pr_pgrp,	0);
315 	SCALAR_FIELD(prpsinfo_t,	pr_sid,		0);
316 	SCALAR_FIELD(prpsinfo_t,	pr_addr,	0);
317 	SCALAR_FIELD(prpsinfo_t,	pr_size,	0);
318 	SCALAR_FIELD(prpsinfo_t,	pr_rssize,	0);
319 	SCALAR_FIELD(prpsinfo_t,	pr_wchan,	0);
320 	SCALAR_FIELD(prpsinfo_t,	pr_start,	0);
321 	SCALAR_FIELD(prpsinfo_t,	pr_time,	0);
322 	SCALAR_FIELD(prpsinfo_t,	pr_pri,		1);
323 	SCALAR_FIELD(prpsinfo_t,	pr_oldpri,	0);
324 	SCALAR_FIELD(prpsinfo_t,	pr_cpu,		0);
325 	SCALAR_FIELD(prpsinfo_t,	pr_ottydev,	0);
326 	SCALAR_FIELD(prpsinfo_t,	pr_lttydev,	0);
327 	ARRAY_FIELD(prpsinfo_t,		pr_clname,	0);
328 	ARRAY_FIELD(prpsinfo_t,		pr_fname,	0);
329 	ARRAY_FIELD(prpsinfo_t,		pr_psargs,	0);
330 	SCALAR_FIELD(prpsinfo_t,	pr_syscall,	1);
331 	SCALAR_FIELD(prpsinfo_t,	pr_ctime,	0);
332 	SCALAR_FIELD(prpsinfo_t,	pr_bysize,	0);
333 	SCALAR_FIELD(prpsinfo_t,	pr_byrssize,	0);
334 	SCALAR_FIELD(prpsinfo_t,	pr_argc,	1);
335 	SCALAR_FIELD(prpsinfo_t,	pr_argv,	0);
336 	SCALAR_FIELD(prpsinfo_t,	pr_envp,	0);
337 	SCALAR_FIELD(prpsinfo_t,	pr_wstat,	1);
338 	SCALAR_FIELD(prpsinfo_t,	pr_pctcpu,	0);
339 	SCALAR_FIELD(prpsinfo_t,	pr_pctmem,	0);
340 	SCALAR_FIELD(prpsinfo_t,	pr_euid,	0);
341 	SCALAR_FIELD(prpsinfo_t,	pr_egid,	0);
342 	SCALAR_FIELD(prpsinfo_t,	pr_aslwpid,	0);
343 	SCALAR_FIELD(prpsinfo_t,	pr_dmodel,	0);
344 
345 	END;
346 }
347 
348 /* lwpsinfo_t, <sys/procfs.h> */
349 static void
350 gen_lwpsinfo(void)
351 {
352 	START(lwpsinfo, lwpsinfo_t);
353 
354 	SCALAR_FIELD(lwpsinfo_t,	pr_flag,	1);
355 	SCALAR_FIELD(lwpsinfo_t,	pr_lwpid,	0);
356 	SCALAR_FIELD(lwpsinfo_t,	pr_addr,	0);
357 	SCALAR_FIELD(lwpsinfo_t,	pr_wchan,	0);
358 	SCALAR_FIELD(lwpsinfo_t,	pr_stype,	0);
359 	SCALAR_FIELD(lwpsinfo_t,	pr_state,	0);
360 	SCALAR_FIELD(lwpsinfo_t,	pr_sname,	0);
361 	SCALAR_FIELD(lwpsinfo_t,	pr_nice,	0);
362 	SCALAR_FIELD(lwpsinfo_t,	pr_syscall,	0);
363 	SCALAR_FIELD(lwpsinfo_t,	pr_oldpri,	0);
364 	SCALAR_FIELD(lwpsinfo_t,	pr_cpu,		0);
365 	SCALAR_FIELD(lwpsinfo_t,	pr_pri,		1);
366 	SCALAR_FIELD(lwpsinfo_t,	pr_pctcpu,	0);
367 	SCALAR_FIELD(lwpsinfo_t,	pr_start,	0);
368 	SCALAR_FIELD(lwpsinfo_t,	pr_time,	0);
369 	ARRAY_FIELD(lwpsinfo_t,		pr_clname,	0);
370 	ARRAY_FIELD(lwpsinfo_t,		pr_name,	0);
371 	SCALAR_FIELD(lwpsinfo_t,	pr_onpro,	1);
372 	SCALAR_FIELD(lwpsinfo_t,	pr_bindpro,	1);
373 	SCALAR_FIELD(lwpsinfo_t,	pr_bindpset,	1);
374 	SCALAR_FIELD(lwpsinfo_t,	pr_lgrp,	1);
375 
376 	END;
377 }
378 
379 /* prcred_t, <sys/procfs.h> */
380 static void
381 gen_prcred(void)
382 {
383 	START(prcred, prcred_t);
384 
385 	SCALAR_FIELD(prcred_t,		pr_euid,	0);
386 	SCALAR_FIELD(prcred_t,		pr_ruid,	0);
387 	SCALAR_FIELD(prcred_t,		pr_suid,	0);
388 	SCALAR_FIELD(prcred_t,		pr_egid,	0);
389 	SCALAR_FIELD(prcred_t,		pr_rgid,	0);
390 	SCALAR_FIELD(prcred_t,		pr_sgid,	0);
391 	SCALAR_FIELD(prcred_t,		pr_ngroups,	1);
392 	ARRAY_FIELD(prcred_t,		pr_groups,	0);
393 
394 	END;
395 }
396 
397 /* prpriv_t, <sys/procfs.h> */
398 static void
399 gen_prpriv(void)
400 {
401 	START(prpriv, prpriv_t);
402 
403 	SCALAR_FIELD(prpriv_t,		pr_nsets,	0);
404 	SCALAR_FIELD(prpriv_t,		pr_setsize,	0);
405 	SCALAR_FIELD(prpriv_t,		pr_infosize,	0);
406 	ARRAY_FIELD(prpriv_t,		pr_sets,	0);
407 
408 	END;
409 }
410 
411 
412 /* priv_impl_info_t, <sys/priv.h> */
413 static void
414 gen_priv_impl_info(void)
415 {
416 	START(priv_impl_info, priv_impl_info_t);
417 
418 	SCALAR_FIELD(priv_impl_info_t,	priv_headersize,	0);
419 	SCALAR_FIELD(priv_impl_info_t,	priv_flags,		0);
420 	SCALAR_FIELD(priv_impl_info_t,	priv_nsets,		0);
421 	SCALAR_FIELD(priv_impl_info_t,	priv_setsize,		0);
422 	SCALAR_FIELD(priv_impl_info_t,	priv_max,		0);
423 	SCALAR_FIELD(priv_impl_info_t,	priv_infosize,		0);
424 	SCALAR_FIELD(priv_impl_info_t,	priv_globalinfosize,	0);
425 
426 	END;
427 }
428 
429 
430 /* fltset_t, <sys/fault.h> */
431 static void
432 gen_fltset(void)
433 {
434 	START(fltset, fltset_t);
435 
436 	ARRAY_FIELD(fltset_t,	word,	0);
437 
438 	END;
439 }
440 
441 /*
442  * Layout description of siginfo_t, <sys/siginfo.h>
443  *
444  * Note: many siginfo_t members are #defines mapping to
445  * long dotted members of sub-structs or unions, and
446  * we need the full member spec (with dots) for those.
447  */
448 static void
449 gen_siginfo(void)
450 {
451 	START(siginfo, siginfo_t);
452 
453 	SCALAR_FIELD(siginfo_t,		si_signo,		0);
454 	SCALAR_FIELD(siginfo_t,		si_errno,		0);
455 	SCALAR_FIELD(siginfo_t,		si_code,		1);
456 
457 	SCALAR_FIELD4(siginfo_t,	si_value.sival_int,	0,
458 	    "__data.__proc.__pdata.__kill.__value.sival_int");
459 
460 	SCALAR_FIELD4(siginfo_t,	si_value.sival_ptr,	0,
461 	    "__data.__proc.__pdata.__kill.__value.sival_ptr");
462 
463 	SCALAR_FIELD4(siginfo_t,	si_pid,			0,
464 	    "__data.__proc.__pid");
465 
466 	SCALAR_FIELD4(siginfo_t,	si_uid,			0,
467 	    "__data.__proc.__pdata.__kill.__uid");
468 
469 	SCALAR_FIELD4(siginfo_t,	si_ctid,		0,
470 	    "__data.__proc.__ctid");
471 
472 	SCALAR_FIELD4(siginfo_t,	si_zoneid,		0,
473 	    "__data.__proc.__zoneid");
474 
475 	SCALAR_FIELD4(siginfo_t,	si_entity,		0,
476 	    "__data.__rctl.__entity");
477 
478 	SCALAR_FIELD4(siginfo_t,	si_addr,		0,
479 	    "__data.__fault.__addr");
480 
481 	SCALAR_FIELD4(siginfo_t,	si_status,		0,
482 	    "__data.__proc.__pdata.__cld.__status");
483 
484 	SCALAR_FIELD4(siginfo_t,	si_band,		0,
485 	    "__data.__file.__band");
486 
487 	END;
488 }
489 
490 /* sigset_t, <sys/signal.h> */
491 static void
492 gen_sigset(void)
493 {
494 	START(sigset, sigset_t);
495 
496 	ARRAY_FIELD(sigset_t,	__sigbits,	0);
497 
498 	END;
499 }
500 
501 
502 /* struct sigaction, <sys/signal.h> */
503 static void
504 gen_sigaction(void)
505 {
506 	START(sigaction, struct sigaction);
507 
508 	SCALAR_FIELD(struct sigaction,	sa_flags,	0);
509 
510 	SCALAR_FIELD4(struct sigaction,	sa_handler,	0,
511 	    "_funcptr._handler");
512 
513 	SCALAR_FIELD4(struct sigaction,	sa_sigaction,	0,
514 	    "_funcptr._sigaction");
515 
516 	SCALAR_FIELD(struct sigaction,	sa_mask,	0);
517 
518 	END;
519 }
520 
521 /* stack_t, <sys/signal.h> */
522 static void
523 gen_stack(void)
524 {
525 	START(stack, stack_t);
526 
527 	SCALAR_FIELD(stack_t,	ss_sp,		0);
528 	SCALAR_FIELD(stack_t,	ss_size,	0);
529 	SCALAR_FIELD(stack_t,	ss_flags,	0);
530 
531 	END;
532 }
533 
534 /* sysset_t, <sys/syscall.h> */
535 static void
536 gen_sysset(void)
537 {
538 	START(sysset, sysset_t);
539 
540 	ARRAY_FIELD(sysset_t,	word,	0);
541 
542 	END;
543 }
544 
545 /* timestruc_t, <sys/time_impl.h> */
546 static void
547 gen_timestruc(void)
548 {
549 	START(timestruc, timestruc_t);
550 
551 	SCALAR_FIELD(timestruc_t,	tv_sec,		0);
552 	SCALAR_FIELD(timestruc_t,	tv_nsec,	0);
553 
554 	END;
555 }
556 
557 /* struct utsname, <sys/utsname.h> */
558 static void
559 gen_utsname(void)
560 {
561 	START(utsname, struct utsname);
562 
563 	ARRAY_FIELD(struct utsname,	sysname,	0);
564 	ARRAY_FIELD(struct utsname,	nodename,	0);
565 	ARRAY_FIELD(struct utsname,	release,	0);
566 	ARRAY_FIELD(struct utsname,	version,	0);
567 	ARRAY_FIELD(struct utsname,	machine,	0);
568 
569 	END;
570 }
571 
572 static void
573 gen_prfdinfo(void)
574 {
575 	START(prfdinfo, prfdinfo_core_t);
576 
577 	SCALAR_FIELD(prfdinfo_core_t,	pr_fd,		0);
578 	SCALAR_FIELD(prfdinfo_core_t,	pr_mode,	0);
579 	SCALAR_FIELD(prfdinfo_core_t,	pr_uid,		0);
580 	SCALAR_FIELD(prfdinfo_core_t,	pr_gid,		0);
581 	SCALAR_FIELD(prfdinfo_core_t,	pr_major,	0);
582 	SCALAR_FIELD(prfdinfo_core_t,	pr_minor,	0);
583 	SCALAR_FIELD(prfdinfo_core_t,	pr_rmajor,	0);
584 	SCALAR_FIELD(prfdinfo_core_t,	pr_rminor,	0);
585 	SCALAR_FIELD(prfdinfo_core_t,	pr_ino,		0);
586 	SCALAR_FIELD(prfdinfo_core_t,	pr_offset,	0);
587 	SCALAR_FIELD(prfdinfo_core_t,	pr_size,	0);
588 	SCALAR_FIELD(prfdinfo_core_t,	pr_fileflags,	0);
589 	SCALAR_FIELD(prfdinfo_core_t,	pr_fdflags,	0);
590 	ARRAY_FIELD(prfdinfo_core_t,	pr_path,	0);
591 
592 	END;
593 }
594 
595 static void
596 gen_prsecflags(void)
597 {
598 	START(prsecflags, prsecflags_t);
599 	SCALAR_FIELD(prsecflags_t, pr_version, 0);
600 	SCALAR_FIELD(prsecflags_t, pr_effective, 0);
601 	SCALAR_FIELD(prsecflags_t, pr_inherit, 0);
602 	SCALAR_FIELD(prsecflags_t, pr_lower, 0);
603 	SCALAR_FIELD(prsecflags_t, pr_upper, 0);
604 	END;
605 }
606 
607 static void
608 gen_prlwpname(void)
609 {
610 	START(prlwpname, prlwpname_t);
611 	SCALAR_FIELD(prlwpname_t, pr_lwpid, 0);
612 	ARRAY_FIELD(prlwpname_t, pr_lwpname, 0);
613 	END;
614 }
615 
616 static void
617 gen_prupanic(void)
618 {
619 	START(prupanic, prupanic_t);
620 	SCALAR_FIELD(prupanic_t, pru_version, 0);
621 	SCALAR_FIELD(prupanic_t, pru_flags, 0);
622 	ARRAY_FIELD(prupanic_t, pru_data, 0);
623 	END;
624 }
625 
626 static void
627 gen_prcwd(void)
628 {
629 	START(prcwd, prcwd_t);
630 	SCALAR_FIELD(prcwd_t, prcwd_fsid, 0);
631 	ARRAY_FIELD(prcwd_t, prcwd_fsname, 0);
632 	ARRAY_FIELD(prcwd_t, prcwd_mntpt, 0);
633 	ARRAY_FIELD(prcwd_t, prcwd_mntspec, 0);
634 	ARRAY_FIELD(prcwd_t, prcwd_cwd, 0);
635 	END;
636 }
637 
638 /*ARGSUSED*/
639 int
640 main(int argc, char *argv[])
641 {
642 	const char *fmt = "\t&%s_layout,\n";
643 
644 	/* get obj file for input */
645 	if (argc < 3) {
646 		(void) fprintf(stderr,
647 		    "usage: %s {object_file} {MACH}\n", argv[0]);
648 		exit(1);
649 	}
650 
651 	objfile = argv[1];
652 	machname = argv[2];
653 
654 	get_ctf_file(objfile);
655 
656 	(void) printf("#include <struct_layout.h>\n");
657 
658 	gen_auxv();
659 	gen_prgregset();
660 	gen_lwpstatus();
661 	gen_pstatus();
662 	gen_prstatus();
663 	gen_psinfo();
664 	gen_prpsinfo();
665 	gen_lwpsinfo();
666 	gen_prcred();
667 	gen_prpriv();
668 	gen_priv_impl_info();
669 	gen_fltset();
670 	gen_siginfo();
671 	gen_sigset();
672 	gen_sigaction();
673 	gen_stack();
674 	gen_sysset();
675 	gen_timestruc();
676 	gen_utsname();
677 	gen_prfdinfo();
678 	gen_prsecflags();
679 	gen_prlwpname();
680 	gen_prupanic();
681 	gen_prcwd();
682 
683 	/*
684 	 * Generate the full arch_layout description
685 	 */
686 	(void) printf(
687 	    "\n\n\n\nstatic const sl_arch_layout_t layout_%s = {\n",
688 	    machname);
689 	(void) printf(fmt, "auxv");
690 	(void) printf(fmt, "fltset");
691 	(void) printf(fmt, "lwpsinfo");
692 	(void) printf(fmt, "lwpstatus");
693 	(void) printf(fmt, "prcred");
694 	(void) printf(fmt, "priv_impl_info");
695 	(void) printf(fmt, "prpriv");
696 	(void) printf(fmt, "psinfo");
697 	(void) printf(fmt, "pstatus");
698 	(void) printf(fmt, "prgregset");
699 	(void) printf(fmt, "prpsinfo");
700 	(void) printf(fmt, "prstatus");
701 	(void) printf(fmt, "sigaction");
702 	(void) printf(fmt, "siginfo");
703 	(void) printf(fmt, "sigset");
704 	(void) printf(fmt, "stack");
705 	(void) printf(fmt, "sysset");
706 	(void) printf(fmt, "timestruc");
707 	(void) printf(fmt, "utsname");
708 	(void) printf(fmt, "prfdinfo");
709 	(void) printf(fmt, "prsecflags");
710 	(void) printf(fmt, "prlwpname");
711 	(void) printf(fmt, "prupanic");
712 	(void) printf(fmt, "prcwd");
713 	(void) printf("};\n");
714 
715 	/*
716 	 * A public function, to make the information available
717 	 */
718 	(void) printf("\n\nconst sl_arch_layout_t *\n");
719 	(void) printf("struct_layout_%s(void)\n", machname);
720 	(void) printf("{\n\treturn (&layout_%s);\n}\n", machname);
721 
722 	return (0);
723 }
724 
725 /*
726  * Helper functions using the CTF library to get type info.
727  */
728 
729 static void
730 get_ctf_file(char *fname)
731 {
732 	int ctferr;
733 
734 	objfile = fname;
735 	if ((ctf = ctf_open(objfile, &ctferr)) == NULL) {
736 		errx(1, "Couldn't open object file %s: %s\n", objfile,
737 		    ctf_errmsg(ctferr));
738 	}
739 }
740 
741 static void
742 print_row(int boff, int eltlen, int nelts, int issigned, char *comment)
743 {
744 	(void) printf("\t{ %d,\t%d,\t%d,\t%d },\t\t/* %s */\n",
745 	    boff, eltlen, nelts, issigned, comment);
746 }
747 
748 static void
749 do_start(char *sname, char *tname)
750 {
751 	do_start_name(sname);
752 	do_start_sizeof(tname, NULL);
753 }
754 
755 static void
756 do_start_name(char *sname)
757 {
758 	(void) printf("\n\nstatic const sl_%s_layout_t %s_layout = {\n",
759 	    sname, sname);
760 }
761 
762 static void
763 do_end(void)
764 {
765 	(void) printf("};\n");
766 }
767 
768 static void
769 do_start_sizeof(char *tname, char *rtname)
770 {
771 	char comment[100];
772 	ctf_id_t stype;
773 	int sz;
774 
775 	if (rtname == NULL)
776 		rtname = tname;
777 
778 	if ((stype = ctf_lookup_by_name(ctf, rtname)) == CTF_ERR)
779 		errx(1, "Couldn't find type %s", rtname);
780 	if ((stype = ctf_type_resolve(ctf, stype)) == CTF_ERR)
781 		errx(1, "Couldn't resolve type %s", tname);
782 
783 	if ((sz = (int)ctf_type_size(ctf, stype)) < 0) {
784 		errx(1, "Couldn't get size for type %s", tname);
785 	} else if (sz == 0) {
786 		errx(1, "Invalid type size 0 for %s", tname);
787 	}
788 
789 	(void) snprintf(comment, sizeof (comment), "sizeof (%s)", tname);
790 	print_row(0, sz, 0, 0, comment);
791 }
792 
793 static void
794 do_scalar_field(char *tname, char *fname, int _sign, char *dotfield)
795 {
796 	int rc, off, sz, ftype;
797 
798 	rc = get_field_info(tname, fname, dotfield, &off, &ftype);
799 	if (rc < 0)
800 		errx(1, "Can't get field info for %s->%s", tname, fname);
801 
802 	if ((ftype = ctf_type_resolve(ctf, ftype)) == CTF_ERR)
803 		errx(1, "Couldn't resolve type of %s->%s", tname, fname);
804 
805 	if ((sz = (int)ctf_type_size(ctf, ftype)) < 0) {
806 		errx(1, "Couldn't get size for type ID %d", ftype);
807 	} else if (sz == 0) {
808 		errx(1, "Invalid type size 0 for type ID %d", ftype);
809 	}
810 
811 	print_row(off, sz, 0, _sign, fname);
812 }
813 
814 static void
815 do_array_field(char *tname, char *fname,
816     int _sign, char *dotfield)
817 {
818 	char comment[100];
819 	ctf_arinfo_t ai;
820 	int typekind;
821 	int esz, rc, off, ftype;
822 
823 	rc = get_field_info(tname, fname, dotfield, &off, &ftype);
824 	if (rc < 0)
825 		errx(1, "Can't get field info for %s->%s", tname, fname);
826 
827 	if ((ftype = ctf_type_resolve(ctf, ftype)) == CTF_ERR)
828 		errx(1, "Couldn't resolve type of %s->%s", tname, fname);
829 
830 	typekind = ctf_type_kind(ctf, ftype);
831 	if (typekind != CTF_K_ARRAY)
832 		errx(1, "Wrong type for %s->%s", tname, fname);
833 
834 	rc = ctf_array_info(ctf, ftype, &ai);
835 	if (rc != 0)
836 		errx(1, "Can't get array info for %s->%s\n", tname, fname);
837 	esz = ctf_type_size(ctf, ai.ctr_contents);
838 	if (esz < 0)
839 		errx(1, "Can't get element size for %s->%s\n", tname, fname);
840 
841 	(void) snprintf(comment, sizeof (comment), "%s[]", fname);
842 	print_row(off, esz, ai.ctr_nelems, _sign, comment);
843 }
844 
845 static void
846 do_array_type(char *tname, char *fname,	int _sign)
847 {
848 	ctf_arinfo_t ai;
849 	int stype, typekind;
850 	int esz, rc;
851 
852 	if ((stype = ctf_lookup_by_name(ctf, tname)) == CTF_ERR)
853 		errx(1, "Couldn't find type %s", tname);
854 	if ((stype = ctf_type_resolve(ctf, stype)) == CTF_ERR)
855 		errx(1, "Couldn't resolve type %s", tname);
856 
857 	typekind = ctf_type_kind(ctf, stype);
858 	if (typekind != CTF_K_ARRAY)
859 		errx(1, "Wrong type for %s->%s", tname, fname);
860 
861 	rc = ctf_array_info(ctf, stype, &ai);
862 	if (rc != 0)
863 		errx(1, "Can't get array info for %s->%s\n", tname, fname);
864 	esz = ctf_type_size(ctf, ai.ctr_contents);
865 	if (esz < 0)
866 		errx(1, "Can't get element size for %s->%s\n", tname, fname);
867 
868 	print_row(0, esz, ai.ctr_nelems, _sign, fname);
869 }
870 
871 
872 struct gfinfo {
873 	char *tname;	/* top type name, i.e. the struct */
874 	char *fname;	/* field name */
875 	char *dotname;	/* full field name with dots (optional) */
876 	char *prefix;	/* current field search prefix */
877 	int base_off;
878 	int fld_off;
879 	int fld_type;
880 };
881 
882 static int gfi_iter(const char *fname, ctf_id_t mbrtid,
883 	ulong_t off, void *varg);
884 
885 /*
886  * Lookup field "fname" in type "tname".  If "dotname" is non-NULL,
887  * that's the full field name with dots, i.e. a_un.un_foo, which
888  * we must search for by walking the struct CTF recursively.
889  */
890 static int
891 get_field_info(char *tname, char *fname, char *dotname,
892     int *offp, int *tidp)
893 {
894 	struct gfinfo gfi;
895 	ctf_id_t stype;
896 	int typekind;
897 	int rc;
898 
899 	if ((stype = ctf_lookup_by_name(ctf, tname)) == CTF_ERR)
900 		errx(1, "Couldn't find type %s", tname);
901 	if ((stype = ctf_type_resolve(ctf, stype)) == CTF_ERR)
902 		errx(1, "Couldn't resolve type %s", tname);
903 
904 	/* If fname has a dot, use it as dotname too. */
905 	if (dotname == NULL && strchr(fname, '.') != NULL)
906 		dotname = fname;
907 
908 	gfi.tname = tname;
909 	gfi.fname = fname;
910 	gfi.dotname = dotname;
911 	gfi.prefix = "";
912 	gfi.base_off = 0;
913 	gfi.fld_off = 0;
914 	gfi.fld_type = 0;
915 
916 	typekind = ctf_type_kind(ctf, stype);
917 	switch (typekind) {
918 
919 	case CTF_K_STRUCT:
920 	case CTF_K_UNION:
921 		rc = ctf_member_iter(ctf, stype, gfi_iter, &gfi);
922 		break;
923 
924 	default:
925 		errx(1, "Unexpected top-level type for %s", tname);
926 		break;
927 	}
928 
929 	if (rc < 0)
930 		errx(1, "Error getting info for %s.%s", tname, fname);
931 	if (rc == 0)
932 		errx(1, "Did not find %s.%s", tname, fname);
933 
934 	*offp = gfi.fld_off;
935 	*tidp = gfi.fld_type;
936 
937 	return (0);
938 }
939 
940 /*
941  * Iteration callback for ctf_member_iter
942  * Return <0 on error, 0 to keep looking, >0 for found.
943  *
944  * If no dotname, simple search for fieldname.
945  * If we're asked to search with dotname, we need to do a full
946  * recursive walk of the types under the dotname.
947  */
948 int
949 gfi_iter(const char *fieldname, ctf_id_t mbrtid, ulong_t off, void *varg)
950 {
951 	char namebuf[100];
952 	struct gfinfo *gfi = varg;
953 	char *saveprefix;
954 	int saveoff;
955 	int typekind;
956 	int byteoff;
957 	int len, rc;
958 
959 	byteoff = gfi->base_off + (int)(off >> 3);
960 
961 	/* Easy cases first: no dotname */
962 	if (gfi->dotname == NULL) {
963 		if (strcmp(gfi->fname, fieldname) == 0) {
964 			gfi->fld_off = byteoff;
965 			gfi->fld_type = mbrtid;
966 			return (1);
967 		}
968 		return (0);
969 	}
970 
971 	/* Exact match on the dotname? */
972 	(void) snprintf(namebuf, sizeof (namebuf), "%s%s",
973 	    gfi->prefix, fieldname);
974 	if (strcmp(gfi->dotname, namebuf) == 0) {
975 		gfi->fld_off = byteoff;
976 		gfi->fld_type = mbrtid;
977 		return (1);
978 	}
979 
980 	/*
981 	 * May need to recurse under this field, but
982 	 * only if there's a match through '.'
983 	 */
984 	(void) strlcat(namebuf, ".", sizeof (namebuf));
985 	len = strlen(namebuf);
986 	if (strncmp(gfi->dotname, namebuf, len) != 0)
987 		return (0);
988 
989 	typekind = ctf_type_kind(ctf, mbrtid);
990 	switch (typekind) {
991 	case CTF_K_STRUCT:
992 	case CTF_K_UNION:
993 		break;
994 	default:
995 		return (0);
996 	}
997 
998 	/* Recursively walk members */
999 	saveprefix = gfi->prefix;
1000 	saveoff = gfi->base_off;
1001 	gfi->prefix = namebuf;
1002 	gfi->base_off = byteoff;
1003 	rc = ctf_member_iter(ctf, mbrtid, gfi_iter, gfi);
1004 	gfi->prefix = saveprefix;
1005 	gfi->base_off = saveoff;
1006 
1007 	return (rc);
1008 }
1009