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