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