xref: /illumos-gate/usr/src/cmd/sgs/elfdump/common/gen_struct_layout.c (revision 8533946bd264dca901fdf56bf3da1d81e728b423)
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 static void
591 gen_prsecflags(void)
592 {
593 	START(prsecflags, prsecflags_t);
594 	SCALAR_FIELD(prsecflags_t, pr_version, 0);
595 	SCALAR_FIELD(prsecflags_t, pr_effective, 0);
596 	SCALAR_FIELD(prsecflags_t, pr_inherit, 0);
597 	SCALAR_FIELD(prsecflags_t, pr_lower, 0);
598 	SCALAR_FIELD(prsecflags_t, pr_upper, 0);
599 	END;
600 }
601 
602 /*ARGSUSED*/
603 int
604 main(int argc, char *argv[])
605 {
606 	const char *fmt = "\t&%s_layout,\n";
607 
608 	/* get obj file for input */
609 	if (argc < 3) {
610 		(void) fprintf(stderr,
611 		    "usage: %s {object_file} {MACH}\n", argv[0]);
612 		exit(1);
613 	}
614 
615 	objfile = argv[1];
616 	machname = argv[2];
617 
618 	get_ctf_file(objfile);
619 
620 	(void) printf("#include <struct_layout.h>\n");
621 
622 	gen_auxv();
623 	gen_prgregset();
624 	gen_lwpstatus();
625 	gen_pstatus();
626 	gen_prstatus();
627 	gen_psinfo();
628 	gen_prpsinfo();
629 	gen_lwpsinfo();
630 	gen_prcred();
631 	gen_prpriv();
632 	gen_priv_impl_info();
633 	gen_fltset();
634 	gen_siginfo();
635 	gen_sigset();
636 	gen_sigaction();
637 	gen_stack();
638 	gen_sysset();
639 	gen_timestruc();
640 	gen_utsname();
641 	gen_prfdinfo();
642 	gen_prsecflags();
643 
644 	/*
645 	 * Generate the full arch_layout description
646 	 */
647 	(void) printf(
648 	    "\n\n\n\nstatic const sl_arch_layout_t layout_%s = {\n",
649 	    machname);
650 	(void) printf(fmt, "auxv");
651 	(void) printf(fmt, "fltset");
652 	(void) printf(fmt, "lwpsinfo");
653 	(void) printf(fmt, "lwpstatus");
654 	(void) printf(fmt, "prcred");
655 	(void) printf(fmt, "priv_impl_info");
656 	(void) printf(fmt, "prpriv");
657 	(void) printf(fmt, "psinfo");
658 	(void) printf(fmt, "pstatus");
659 	(void) printf(fmt, "prgregset");
660 	(void) printf(fmt, "prpsinfo");
661 	(void) printf(fmt, "prstatus");
662 	(void) printf(fmt, "sigaction");
663 	(void) printf(fmt, "siginfo");
664 	(void) printf(fmt, "sigset");
665 	(void) printf(fmt, "stack");
666 	(void) printf(fmt, "sysset");
667 	(void) printf(fmt, "timestruc");
668 	(void) printf(fmt, "utsname");
669 	(void) printf(fmt, "prfdinfo");
670 	(void) printf(fmt, "prsecflags");
671 	(void) printf("};\n");
672 
673 	/*
674 	 * A public function, to make the information available
675 	 */
676 	(void) printf("\n\nconst sl_arch_layout_t *\n");
677 	(void) printf("struct_layout_%s(void)\n", machname);
678 	(void) printf("{\n\treturn (&layout_%s);\n}\n", machname);
679 
680 	return (0);
681 }
682 
683 /*
684  * Helper functions using the CTF library to get type info.
685  */
686 
687 static void
688 get_ctf_file(char *fname)
689 {
690 	int ctferr;
691 
692 	objfile = fname;
693 	if ((ctf = ctf_open(objfile, &ctferr)) == NULL) {
694 		errx(1, "Couldn't open object file %s: %s\n", objfile,
695 		    ctf_errmsg(ctferr));
696 	}
697 }
698 
699 static void
700 print_row(int boff, int eltlen, int nelts, int issigned, char *comment)
701 {
702 	(void) printf("\t{ %d,\t%d,\t%d,\t%d },\t\t/* %s */\n",
703 	    boff, eltlen, nelts, issigned, comment);
704 }
705 
706 static void
707 do_start(char *sname, char *tname)
708 {
709 	do_start_name(sname);
710 	do_start_sizeof(tname, NULL);
711 }
712 
713 static void
714 do_start_name(char *sname)
715 {
716 	(void) printf("\n\nstatic const sl_%s_layout_t %s_layout = {\n",
717 	    sname, sname);
718 }
719 
720 static void
721 do_end(void)
722 {
723 	(void) printf("};\n");
724 }
725 
726 static void
727 do_start_sizeof(char *tname, char *rtname)
728 {
729 	char comment[100];
730 	ctf_id_t stype;
731 	int sz;
732 
733 	if (rtname == NULL)
734 		rtname = tname;
735 
736 	if ((stype = ctf_lookup_by_name(ctf, rtname)) == CTF_ERR)
737 		errx(1, "Couldn't find type %s", rtname);
738 	if ((stype = ctf_type_resolve(ctf, stype)) == CTF_ERR)
739 		errx(1, "Couldn't resolve type %s", tname);
740 
741 	if ((sz = (int)ctf_type_size(ctf, stype)) < 0) {
742 		errx(1, "Couldn't get size for type %s", tname);
743 	} else if (sz == 0) {
744 		errx(1, "Invalid type size 0 for %s", tname);
745 	}
746 
747 	(void) snprintf(comment, sizeof (comment), "sizeof (%s)", tname);
748 	print_row(0, sz, 0, 0, comment);
749 }
750 
751 static void
752 do_scalar_field(char *tname, char *fname, int _sign, char *dotfield)
753 {
754 	int rc, off, sz, ftype;
755 
756 	rc = get_field_info(tname, fname, dotfield, &off, &ftype);
757 	if (rc < 0)
758 		errx(1, "Can't get field info for %s->%s", tname, fname);
759 
760 	if ((ftype = ctf_type_resolve(ctf, ftype)) == CTF_ERR)
761 		errx(1, "Couldn't resolve type of %s->%s", tname, fname);
762 
763 	if ((sz = (int)ctf_type_size(ctf, ftype)) < 0) {
764 		errx(1, "Couldn't get size for type ID %d", ftype);
765 	} else if (sz == 0) {
766 		errx(1, "Invalid type size 0 for type ID %d", ftype);
767 	}
768 
769 	print_row(off, sz, 0, _sign, fname);
770 }
771 
772 static void
773 do_array_field(char *tname, char *fname,
774     int _sign, char *dotfield)
775 {
776 	char comment[100];
777 	ctf_arinfo_t ai;
778 	int typekind;
779 	int esz, rc, off, 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 	typekind = ctf_type_kind(ctf, ftype);
789 	if (typekind != CTF_K_ARRAY)
790 		errx(1, "Wrong type for %s->%s", tname, fname);
791 
792 	rc = ctf_array_info(ctf, ftype, &ai);
793 	if (rc != 0)
794 		errx(1, "Can't get array info for %s->%s\n", tname, fname);
795 	esz = ctf_type_size(ctf, ai.ctr_contents);
796 	if (esz < 0)
797 		errx(1, "Can't get element size for %s->%s\n", tname, fname);
798 
799 	(void) snprintf(comment, sizeof (comment), "%s[]", fname);
800 	print_row(off, esz, ai.ctr_nelems, _sign, comment);
801 }
802 
803 static void
804 do_array_type(char *tname, char *fname,	int _sign)
805 {
806 	ctf_arinfo_t ai;
807 	int stype, typekind;
808 	int esz, rc;
809 
810 	if ((stype = ctf_lookup_by_name(ctf, tname)) == CTF_ERR)
811 		errx(1, "Couldn't find type %s", tname);
812 	if ((stype = ctf_type_resolve(ctf, stype)) == CTF_ERR)
813 		errx(1, "Couldn't resolve type %s", tname);
814 
815 	typekind = ctf_type_kind(ctf, stype);
816 	if (typekind != CTF_K_ARRAY)
817 		errx(1, "Wrong type for %s->%s", tname, fname);
818 
819 	rc = ctf_array_info(ctf, stype, &ai);
820 	if (rc != 0)
821 		errx(1, "Can't get array info for %s->%s\n", tname, fname);
822 	esz = ctf_type_size(ctf, ai.ctr_contents);
823 	if (esz < 0)
824 		errx(1, "Can't get element size for %s->%s\n", tname, fname);
825 
826 	print_row(0, esz, ai.ctr_nelems, _sign, fname);
827 }
828 
829 
830 struct gfinfo {
831 	char *tname;	/* top type name, i.e. the struct */
832 	char *fname;	/* field name */
833 	char *dotname;	/* full field name with dots (optional) */
834 	char *prefix;	/* current field search prefix */
835 	int base_off;
836 	int fld_off;
837 	int fld_type;
838 };
839 
840 static int gfi_iter(const char *fname, ctf_id_t mbrtid,
841 	ulong_t off, void *varg);
842 
843 /*
844  * Lookup field "fname" in type "tname".  If "dotname" is non-NULL,
845  * that's the full field name with dots, i.e. a_un.un_foo, which
846  * we must search for by walking the struct CTF recursively.
847  */
848 static int
849 get_field_info(char *tname, char *fname, char *dotname,
850     int *offp, int *tidp)
851 {
852 	struct gfinfo gfi;
853 	ctf_id_t stype;
854 	int typekind;
855 	int rc;
856 
857 	if ((stype = ctf_lookup_by_name(ctf, tname)) == CTF_ERR)
858 		errx(1, "Couldn't find type %s", tname);
859 	if ((stype = ctf_type_resolve(ctf, stype)) == CTF_ERR)
860 		errx(1, "Couldn't resolve type %s", tname);
861 
862 	/* If fname has a dot, use it as dotname too. */
863 	if (dotname == NULL && strchr(fname, '.') != NULL)
864 		dotname = fname;
865 
866 	gfi.tname = tname;
867 	gfi.fname = fname;
868 	gfi.dotname = dotname;
869 	gfi.prefix = "";
870 	gfi.base_off = 0;
871 	gfi.fld_off = 0;
872 	gfi.fld_type = 0;
873 
874 	typekind = ctf_type_kind(ctf, stype);
875 	switch (typekind) {
876 
877 	case CTF_K_STRUCT:
878 	case CTF_K_UNION:
879 		rc = ctf_member_iter(ctf, stype, gfi_iter, &gfi);
880 		break;
881 
882 	default:
883 		errx(1, "Unexpected top-level type for %s", tname);
884 		break;
885 	}
886 
887 	if (rc < 0)
888 		errx(1, "Error getting info for %s.%s", stype, fname);
889 	if (rc == 0)
890 		errx(1, "Did not find %s.%s", tname, fname);
891 
892 	*offp = gfi.fld_off;
893 	*tidp = gfi.fld_type;
894 
895 	return (0);
896 }
897 
898 /*
899  * Iteration callback for ctf_member_iter
900  * Return <0 on error, 0 to keep looking, >0 for found.
901  *
902  * If no dotname, simple search for fieldname.
903  * If we're asked to search with dotname, we need to do a full
904  * recursive walk of the types under the dotname.
905  */
906 int
907 gfi_iter(const char *fieldname, ctf_id_t mbrtid, ulong_t off, void *varg)
908 {
909 	char namebuf[100];
910 	struct gfinfo *gfi = varg;
911 	char *saveprefix;
912 	int saveoff;
913 	int typekind;
914 	int byteoff;
915 	int len, rc;
916 
917 	byteoff = gfi->base_off + (int)(off >> 3);
918 
919 	/* Easy cases first: no dotname */
920 	if (gfi->dotname == NULL) {
921 		if (strcmp(gfi->fname, fieldname) == 0) {
922 			gfi->fld_off = byteoff;
923 			gfi->fld_type = mbrtid;
924 			return (1);
925 		}
926 		return (0);
927 	}
928 
929 	/* Exact match on the dotname? */
930 	(void) snprintf(namebuf, sizeof (namebuf), "%s%s",
931 	    gfi->prefix, fieldname);
932 	if (strcmp(gfi->dotname, namebuf) == 0) {
933 		gfi->fld_off = byteoff;
934 		gfi->fld_type = mbrtid;
935 		return (1);
936 	}
937 
938 	/*
939 	 * May need to recurse under this field, but
940 	 * only if there's a match through '.'
941 	 */
942 	(void) strlcat(namebuf, ".", sizeof (namebuf));
943 	len = strlen(namebuf);
944 	if (strncmp(gfi->dotname, namebuf, len) != 0)
945 		return (0);
946 
947 	typekind = ctf_type_kind(ctf, mbrtid);
948 	switch (typekind) {
949 	case CTF_K_STRUCT:
950 	case CTF_K_UNION:
951 		break;
952 	default:
953 		return (0);
954 	}
955 
956 	/* Recursively walk members */
957 	saveprefix = gfi->prefix;
958 	saveoff = gfi->base_off;
959 	gfi->prefix = namebuf;
960 	gfi->base_off = byteoff;
961 	rc = ctf_member_iter(ctf, mbrtid, gfi_iter, gfi);
962 	gfi->prefix = saveprefix;
963 	gfi->base_off = saveoff;
964 
965 	return (rc);
966 }
967