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