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