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