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.
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.
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]
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
26 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
27 * Copyright 2018 Joyent, Inc.
31 * This program is used to generate the contents of the
32 * struct_layout_XXX.c files that contain per-architecture
33 * structure layout information.
35 * Although not part of elfdump, it is built by the makefile
39 * 1) Run it, capturing the output in a file.
40 * 2) If this is a replacement for an existing file,
41 * diff the new and old copies to ensure only
42 * the changes you expected are present.
43 * 3) Put the new file in the common directory under the name
44 * struct_layout_XXX.c, where XXX is the name of
45 * the architecture (i386, amd64, sparc, sparcv9, etc).
46 * 2) Add any necessary header and copyright comments.
47 * 3) If this is a new architecture:
48 * - Add an extern statement for struct_layout_XXX()
50 * - Add a case for it to the function sl_struct_layout()
59 #include <sys/types.h>
63 * This extracts CTF information from a temporary object file.
65 * START and END bracket a struct layout definition. They issue
66 * the typedef boilerplate, and the standard first element (sizeof)
67 * which captures the overall size of the structure.
69 * SCALAR_FIELD is for scalar struct fields
71 * ARRAY_FIELD is for array struct fields
73 * ARRAY_TYPE is for plain (non-struct) array types
75 #define START(_name, _type) \
76 do_start(#_name, #_type)
79 #define SCALAR_FIELD(_type, _field, _sign) \
80 do_scalar_field(#_type, #_field, _sign, NULL)
81 #define SCALAR_FIELD4(_type, _field, _sign, _rtype) \
82 do_scalar_field(#_type, #_field, _sign, _rtype)
83 #define ARRAY_FIELD(_type, _field, _sign) \
84 do_array_field(#_type, #_field, _sign, NULL)
85 #define ARRAY_TYPE(_type, _sign) \
86 do_array_type(#_type, "elt0", _sign)
88 static void do_start(char *_name
, char *_type
);
89 static void do_end(void);
90 static void do_start_name(char *name
);
91 static void do_start_sizeof(char *_type
, char *realtype
);
92 static void do_scalar_field(char *_type
, char *_field
,
93 int _sign
, char *dotfield
);
94 static void do_array_field(char *_type
, char *_field
,
95 int _sign
, char *dotfield
);
96 static void do_array_type(char *_type
, char *_field
, int _sign
);
98 static void get_ctf_file(char *fname
);
99 static int get_field_info(char *tname
, char *fname
, char *dotname
,
100 int *offp
, int *sizep
);
102 static ctf_file_t
*ctf
;
103 static char *objfile
;
104 static char *machname
;
106 /* auxv_t, <sys/auxv.h> */
112 SCALAR_FIELD(auxv_t
, a_type
, 1);
113 SCALAR_FIELD(auxv_t
, a_un
.a_val
, 1);
114 SCALAR_FIELD(auxv_t
, a_un
.a_ptr
, 0);
115 SCALAR_FIELD(auxv_t
, a_un
.a_fcn
, 0);
121 /* prgregset_t, <sys/prgregset.h> */
125 START(prgregset
, prgregset_t
);
127 ARRAY_TYPE(prgregset_t
, 0);
133 /* lwpstatus_t, <sys/procfs.h> */
137 START(lwpstatus
, lwpstatus_t
);
139 SCALAR_FIELD(lwpstatus_t
, pr_flags
, 0);
140 SCALAR_FIELD(lwpstatus_t
, pr_lwpid
, 0);
141 SCALAR_FIELD(lwpstatus_t
, pr_why
, 0);
142 SCALAR_FIELD(lwpstatus_t
, pr_what
, 0);
143 SCALAR_FIELD(lwpstatus_t
, pr_cursig
, 0);
144 SCALAR_FIELD(lwpstatus_t
, pr_info
, 0);
145 SCALAR_FIELD(lwpstatus_t
, pr_lwppend
, 0);
146 SCALAR_FIELD(lwpstatus_t
, pr_lwphold
, 0);
147 SCALAR_FIELD(lwpstatus_t
, pr_action
, 0);
148 SCALAR_FIELD(lwpstatus_t
, pr_altstack
, 0);
149 SCALAR_FIELD(lwpstatus_t
, pr_oldcontext
, 0);
150 SCALAR_FIELD(lwpstatus_t
, pr_syscall
, 0);
151 SCALAR_FIELD(lwpstatus_t
, pr_nsysarg
, 0);
152 SCALAR_FIELD(lwpstatus_t
, pr_errno
, 0);
153 ARRAY_FIELD(lwpstatus_t
, pr_sysarg
, 0);
154 SCALAR_FIELD(lwpstatus_t
, pr_rval1
, 0);
155 SCALAR_FIELD(lwpstatus_t
, pr_rval2
, 0);
156 ARRAY_FIELD(lwpstatus_t
, pr_clname
, 0);
157 SCALAR_FIELD(lwpstatus_t
, pr_tstamp
, 0);
158 SCALAR_FIELD(lwpstatus_t
, pr_utime
, 0);
159 SCALAR_FIELD(lwpstatus_t
, pr_stime
, 0);
160 SCALAR_FIELD(lwpstatus_t
, pr_errpriv
, 0);
161 SCALAR_FIELD(lwpstatus_t
, pr_ustack
, 0);
162 SCALAR_FIELD(lwpstatus_t
, pr_instr
, 0);
163 SCALAR_FIELD(lwpstatus_t
, pr_reg
, 0);
164 SCALAR_FIELD(lwpstatus_t
, pr_fpreg
, 0);
170 /* pstatus_t, <sys/procfs.h> */
174 START(pstatus
, pstatus_t
);
176 SCALAR_FIELD(pstatus_t
, pr_flags
, 1);
177 SCALAR_FIELD(pstatus_t
, pr_nlwp
, 1);
178 SCALAR_FIELD(pstatus_t
, pr_pid
, 0);
179 SCALAR_FIELD(pstatus_t
, pr_ppid
, 0);
180 SCALAR_FIELD(pstatus_t
, pr_pgid
, 0);
181 SCALAR_FIELD(pstatus_t
, pr_sid
, 0);
182 SCALAR_FIELD(pstatus_t
, pr_aslwpid
, 1);
183 SCALAR_FIELD(pstatus_t
, pr_agentid
, 1);
184 SCALAR_FIELD(pstatus_t
, pr_sigpend
, 0);
185 SCALAR_FIELD(pstatus_t
, pr_brkbase
, 0);
186 SCALAR_FIELD(pstatus_t
, pr_brksize
, 0);
187 SCALAR_FIELD(pstatus_t
, pr_stkbase
, 0);
188 SCALAR_FIELD(pstatus_t
, pr_stksize
, 0);
189 SCALAR_FIELD(pstatus_t
, pr_utime
, 0);
190 SCALAR_FIELD(pstatus_t
, pr_stime
, 0);
191 SCALAR_FIELD(pstatus_t
, pr_cutime
, 0);
192 SCALAR_FIELD(pstatus_t
, pr_cstime
, 0);
193 SCALAR_FIELD(pstatus_t
, pr_sigtrace
, 0);
194 SCALAR_FIELD(pstatus_t
, pr_flttrace
, 0);
195 SCALAR_FIELD(pstatus_t
, pr_sysentry
, 0);
196 SCALAR_FIELD(pstatus_t
, pr_sysexit
, 0);
197 SCALAR_FIELD(pstatus_t
, pr_dmodel
, 0);
198 SCALAR_FIELD(pstatus_t
, pr_taskid
, 1);
199 SCALAR_FIELD(pstatus_t
, pr_projid
, 1);
200 SCALAR_FIELD(pstatus_t
, pr_nzomb
, 1);
201 SCALAR_FIELD(pstatus_t
, pr_zoneid
, 1);
202 SCALAR_FIELD(pstatus_t
, pr_lwp
, 0);
208 /* prstatus_t, <sys/old_procfs.h> */
212 START(prstatus
, prstatus_t
);
214 SCALAR_FIELD(prstatus_t
, pr_flags
, 1);
215 SCALAR_FIELD(prstatus_t
, pr_why
, 1);
216 SCALAR_FIELD(prstatus_t
, pr_what
, 1);
217 SCALAR_FIELD(prstatus_t
, pr_info
, 0);
218 SCALAR_FIELD(prstatus_t
, pr_cursig
, 1);
219 SCALAR_FIELD(prstatus_t
, pr_nlwp
, 0);
220 SCALAR_FIELD(prstatus_t
, pr_sigpend
, 0);
221 SCALAR_FIELD(prstatus_t
, pr_sighold
, 0);
222 SCALAR_FIELD(prstatus_t
, pr_altstack
, 0);
223 SCALAR_FIELD(prstatus_t
, pr_action
, 0);
224 SCALAR_FIELD(prstatus_t
, pr_pid
, 0);
225 SCALAR_FIELD(prstatus_t
, pr_ppid
, 0);
226 SCALAR_FIELD(prstatus_t
, pr_pgrp
, 0);
227 SCALAR_FIELD(prstatus_t
, pr_sid
, 0);
228 SCALAR_FIELD(prstatus_t
, pr_utime
, 0);
229 SCALAR_FIELD(prstatus_t
, pr_stime
, 0);
230 SCALAR_FIELD(prstatus_t
, pr_cutime
, 0);
231 SCALAR_FIELD(prstatus_t
, pr_cstime
, 0);
232 ARRAY_FIELD(prstatus_t
, pr_clname
, 0);
233 SCALAR_FIELD(prstatus_t
, pr_syscall
, 1);
234 SCALAR_FIELD(prstatus_t
, pr_nsysarg
, 1);
235 ARRAY_FIELD(prstatus_t
, pr_sysarg
, 1);
236 SCALAR_FIELD(prstatus_t
, pr_who
, 0);
237 SCALAR_FIELD(prstatus_t
, pr_lwppend
, 0);
238 SCALAR_FIELD(prstatus_t
, pr_oldcontext
, 0);
239 SCALAR_FIELD(prstatus_t
, pr_brkbase
, 0);
240 SCALAR_FIELD(prstatus_t
, pr_brksize
, 0);
241 SCALAR_FIELD(prstatus_t
, pr_stkbase
, 0);
242 SCALAR_FIELD(prstatus_t
, pr_stksize
, 0);
243 SCALAR_FIELD(prstatus_t
, pr_processor
, 1);
244 SCALAR_FIELD(prstatus_t
, pr_bind
, 1);
245 SCALAR_FIELD(prstatus_t
, pr_instr
, 1);
246 SCALAR_FIELD(prstatus_t
, pr_reg
, 0);
252 /* psinfo_t, <sys/procfs.h> */
256 START(psinfo
, psinfo_t
);
258 SCALAR_FIELD(psinfo_t
, pr_flag
, 1);
259 SCALAR_FIELD(psinfo_t
, pr_nlwp
, 1);
260 SCALAR_FIELD(psinfo_t
, pr_pid
, 0);
261 SCALAR_FIELD(psinfo_t
, pr_ppid
, 0);
262 SCALAR_FIELD(psinfo_t
, pr_pgid
, 0);
263 SCALAR_FIELD(psinfo_t
, pr_sid
, 0);
264 SCALAR_FIELD(psinfo_t
, pr_uid
, 0);
265 SCALAR_FIELD(psinfo_t
, pr_euid
, 0);
266 SCALAR_FIELD(psinfo_t
, pr_gid
, 0);
267 SCALAR_FIELD(psinfo_t
, pr_egid
, 0);
268 SCALAR_FIELD(psinfo_t
, pr_addr
, 0);
269 SCALAR_FIELD(psinfo_t
, pr_size
, 0);
270 SCALAR_FIELD(psinfo_t
, pr_rssize
, 0);
271 SCALAR_FIELD(psinfo_t
, pr_ttydev
, 0);
272 SCALAR_FIELD(psinfo_t
, pr_pctcpu
, 0);
273 SCALAR_FIELD(psinfo_t
, pr_pctmem
, 0);
274 SCALAR_FIELD(psinfo_t
, pr_start
, 0);
275 SCALAR_FIELD(psinfo_t
, pr_time
, 0);
276 SCALAR_FIELD(psinfo_t
, pr_ctime
, 0);
277 ARRAY_FIELD(psinfo_t
, pr_fname
, 0);
278 ARRAY_FIELD(psinfo_t
, pr_psargs
, 0);
279 SCALAR_FIELD(psinfo_t
, pr_wstat
, 1);
280 SCALAR_FIELD(psinfo_t
, pr_argc
, 1);
281 SCALAR_FIELD(psinfo_t
, pr_argv
, 0);
282 SCALAR_FIELD(psinfo_t
, pr_envp
, 0);
283 SCALAR_FIELD(psinfo_t
, pr_dmodel
, 0);
284 SCALAR_FIELD(psinfo_t
, pr_taskid
, 0);
285 SCALAR_FIELD(psinfo_t
, pr_projid
, 0);
286 SCALAR_FIELD(psinfo_t
, pr_nzomb
, 1);
287 SCALAR_FIELD(psinfo_t
, pr_poolid
, 0);
288 SCALAR_FIELD(psinfo_t
, pr_zoneid
, 0);
289 SCALAR_FIELD(psinfo_t
, pr_contract
, 0);
290 SCALAR_FIELD(psinfo_t
, pr_lwp
, 0);
295 /* prpsinfo_t, <sys/old_procfs.h> */
299 START(prpsinfo
, prpsinfo_t
);
301 SCALAR_FIELD(prpsinfo_t
, pr_state
, 0);
302 SCALAR_FIELD(prpsinfo_t
, pr_sname
, 0);
303 SCALAR_FIELD(prpsinfo_t
, pr_zomb
, 0);
304 SCALAR_FIELD(prpsinfo_t
, pr_nice
, 0);
305 SCALAR_FIELD(prpsinfo_t
, pr_flag
, 0);
306 SCALAR_FIELD(prpsinfo_t
, pr_uid
, 0);
307 SCALAR_FIELD(prpsinfo_t
, pr_gid
, 0);
308 SCALAR_FIELD(prpsinfo_t
, pr_pid
, 0);
309 SCALAR_FIELD(prpsinfo_t
, pr_ppid
, 0);
310 SCALAR_FIELD(prpsinfo_t
, pr_pgrp
, 0);
311 SCALAR_FIELD(prpsinfo_t
, pr_sid
, 0);
312 SCALAR_FIELD(prpsinfo_t
, pr_addr
, 0);
313 SCALAR_FIELD(prpsinfo_t
, pr_size
, 0);
314 SCALAR_FIELD(prpsinfo_t
, pr_rssize
, 0);
315 SCALAR_FIELD(prpsinfo_t
, pr_wchan
, 0);
316 SCALAR_FIELD(prpsinfo_t
, pr_start
, 0);
317 SCALAR_FIELD(prpsinfo_t
, pr_time
, 0);
318 SCALAR_FIELD(prpsinfo_t
, pr_pri
, 1);
319 SCALAR_FIELD(prpsinfo_t
, pr_oldpri
, 0);
320 SCALAR_FIELD(prpsinfo_t
, pr_cpu
, 0);
321 SCALAR_FIELD(prpsinfo_t
, pr_ottydev
, 0);
322 SCALAR_FIELD(prpsinfo_t
, pr_lttydev
, 0);
323 ARRAY_FIELD(prpsinfo_t
, pr_clname
, 0);
324 ARRAY_FIELD(prpsinfo_t
, pr_fname
, 0);
325 ARRAY_FIELD(prpsinfo_t
, pr_psargs
, 0);
326 SCALAR_FIELD(prpsinfo_t
, pr_syscall
, 1);
327 SCALAR_FIELD(prpsinfo_t
, pr_ctime
, 0);
328 SCALAR_FIELD(prpsinfo_t
, pr_bysize
, 0);
329 SCALAR_FIELD(prpsinfo_t
, pr_byrssize
, 0);
330 SCALAR_FIELD(prpsinfo_t
, pr_argc
, 1);
331 SCALAR_FIELD(prpsinfo_t
, pr_argv
, 0);
332 SCALAR_FIELD(prpsinfo_t
, pr_envp
, 0);
333 SCALAR_FIELD(prpsinfo_t
, pr_wstat
, 1);
334 SCALAR_FIELD(prpsinfo_t
, pr_pctcpu
, 0);
335 SCALAR_FIELD(prpsinfo_t
, pr_pctmem
, 0);
336 SCALAR_FIELD(prpsinfo_t
, pr_euid
, 0);
337 SCALAR_FIELD(prpsinfo_t
, pr_egid
, 0);
338 SCALAR_FIELD(prpsinfo_t
, pr_aslwpid
, 0);
339 SCALAR_FIELD(prpsinfo_t
, pr_dmodel
, 0);
344 /* lwpsinfo_t, <sys/procfs.h> */
348 START(lwpsinfo
, lwpsinfo_t
);
350 SCALAR_FIELD(lwpsinfo_t
, pr_flag
, 1);
351 SCALAR_FIELD(lwpsinfo_t
, pr_lwpid
, 0);
352 SCALAR_FIELD(lwpsinfo_t
, pr_addr
, 0);
353 SCALAR_FIELD(lwpsinfo_t
, pr_wchan
, 0);
354 SCALAR_FIELD(lwpsinfo_t
, pr_stype
, 0);
355 SCALAR_FIELD(lwpsinfo_t
, pr_state
, 0);
356 SCALAR_FIELD(lwpsinfo_t
, pr_sname
, 0);
357 SCALAR_FIELD(lwpsinfo_t
, pr_nice
, 0);
358 SCALAR_FIELD(lwpsinfo_t
, pr_syscall
, 0);
359 SCALAR_FIELD(lwpsinfo_t
, pr_oldpri
, 0);
360 SCALAR_FIELD(lwpsinfo_t
, pr_cpu
, 0);
361 SCALAR_FIELD(lwpsinfo_t
, pr_pri
, 1);
362 SCALAR_FIELD(lwpsinfo_t
, pr_pctcpu
, 0);
363 SCALAR_FIELD(lwpsinfo_t
, pr_start
, 0);
364 SCALAR_FIELD(lwpsinfo_t
, pr_time
, 0);
365 ARRAY_FIELD(lwpsinfo_t
, pr_clname
, 0);
366 ARRAY_FIELD(lwpsinfo_t
, pr_name
, 0);
367 SCALAR_FIELD(lwpsinfo_t
, pr_onpro
, 1);
368 SCALAR_FIELD(lwpsinfo_t
, pr_bindpro
, 1);
369 SCALAR_FIELD(lwpsinfo_t
, pr_bindpset
, 1);
370 SCALAR_FIELD(lwpsinfo_t
, pr_lgrp
, 1);
375 /* prcred_t, <sys/procfs.h> */
379 START(prcred
, prcred_t
);
381 SCALAR_FIELD(prcred_t
, pr_euid
, 0);
382 SCALAR_FIELD(prcred_t
, pr_ruid
, 0);
383 SCALAR_FIELD(prcred_t
, pr_suid
, 0);
384 SCALAR_FIELD(prcred_t
, pr_egid
, 0);
385 SCALAR_FIELD(prcred_t
, pr_rgid
, 0);
386 SCALAR_FIELD(prcred_t
, pr_sgid
, 0);
387 SCALAR_FIELD(prcred_t
, pr_ngroups
, 1);
388 ARRAY_FIELD(prcred_t
, pr_groups
, 0);
393 /* prpriv_t, <sys/procfs.h> */
397 START(prpriv
, prpriv_t
);
399 SCALAR_FIELD(prpriv_t
, pr_nsets
, 0);
400 SCALAR_FIELD(prpriv_t
, pr_setsize
, 0);
401 SCALAR_FIELD(prpriv_t
, pr_infosize
, 0);
402 ARRAY_FIELD(prpriv_t
, pr_sets
, 0);
408 /* priv_impl_info_t, <sys/priv.h> */
410 gen_priv_impl_info(void)
412 START(priv_impl_info
, priv_impl_info_t
);
414 SCALAR_FIELD(priv_impl_info_t
, priv_headersize
, 0);
415 SCALAR_FIELD(priv_impl_info_t
, priv_flags
, 0);
416 SCALAR_FIELD(priv_impl_info_t
, priv_nsets
, 0);
417 SCALAR_FIELD(priv_impl_info_t
, priv_setsize
, 0);
418 SCALAR_FIELD(priv_impl_info_t
, priv_max
, 0);
419 SCALAR_FIELD(priv_impl_info_t
, priv_infosize
, 0);
420 SCALAR_FIELD(priv_impl_info_t
, priv_globalinfosize
, 0);
426 /* fltset_t, <sys/fault.h> */
430 START(fltset
, fltset_t
);
432 ARRAY_FIELD(fltset_t
, word
, 0);
438 * Layout description of siginfo_t, <sys/siginfo.h>
440 * Note: many siginfo_t members are #defines mapping to
441 * long dotted members of sub-structs or unions, and
442 * we need the full member spec (with dots) for those.
447 START(siginfo
, siginfo_t
);
449 SCALAR_FIELD(siginfo_t
, si_signo
, 0);
450 SCALAR_FIELD(siginfo_t
, si_errno
, 0);
451 SCALAR_FIELD(siginfo_t
, si_code
, 1);
453 SCALAR_FIELD4(siginfo_t
, si_value
.sival_int
, 0,
454 "__data.__proc.__pdata.__kill.__value.sival_int");
456 SCALAR_FIELD4(siginfo_t
, si_value
.sival_ptr
, 0,
457 "__data.__proc.__pdata.__kill.__value.sival_ptr");
459 SCALAR_FIELD4(siginfo_t
, si_pid
, 0,
460 "__data.__proc.__pid");
462 SCALAR_FIELD4(siginfo_t
, si_uid
, 0,
463 "__data.__proc.__pdata.__kill.__uid");
465 SCALAR_FIELD4(siginfo_t
, si_ctid
, 0,
466 "__data.__proc.__ctid");
468 SCALAR_FIELD4(siginfo_t
, si_zoneid
, 0,
469 "__data.__proc.__zoneid");
471 SCALAR_FIELD4(siginfo_t
, si_entity
, 0,
472 "__data.__rctl.__entity");
474 SCALAR_FIELD4(siginfo_t
, si_addr
, 0,
475 "__data.__fault.__addr");
477 SCALAR_FIELD4(siginfo_t
, si_status
, 0,
478 "__data.__proc.__pdata.__cld.__status");
480 SCALAR_FIELD4(siginfo_t
, si_band
, 0,
481 "__data.__file.__band");
486 /* sigset_t, <sys/signal.h> */
490 START(sigset
, sigset_t
);
492 ARRAY_FIELD(sigset_t
, __sigbits
, 0);
498 /* struct sigaction, <sys/signal.h> */
502 START(sigaction
, struct sigaction
);
504 SCALAR_FIELD(struct sigaction
, sa_flags
, 0);
506 SCALAR_FIELD4(struct sigaction
, sa_handler
, 0,
507 "_funcptr._handler");
509 SCALAR_FIELD4(struct sigaction
, sa_sigaction
, 0,
510 "_funcptr._sigaction");
512 SCALAR_FIELD(struct sigaction
, sa_mask
, 0);
517 /* stack_t, <sys/signal.h> */
521 START(stack
, stack_t
);
523 SCALAR_FIELD(stack_t
, ss_sp
, 0);
524 SCALAR_FIELD(stack_t
, ss_size
, 0);
525 SCALAR_FIELD(stack_t
, ss_flags
, 0);
530 /* sysset_t, <sys/syscall.h> */
534 START(sysset
, sysset_t
);
536 ARRAY_FIELD(sysset_t
, word
, 0);
541 /* timestruc_t, <sys/time_impl.h> */
545 START(timestruc
, timestruc_t
);
547 SCALAR_FIELD(timestruc_t
, tv_sec
, 0);
548 SCALAR_FIELD(timestruc_t
, tv_nsec
, 0);
553 /* struct utsname, <sys/utsname.h> */
557 START(utsname
, struct utsname
);
559 ARRAY_FIELD(struct utsname
, sysname
, 0);
560 ARRAY_FIELD(struct utsname
, nodename
, 0);
561 ARRAY_FIELD(struct utsname
, release
, 0);
562 ARRAY_FIELD(struct utsname
, version
, 0);
563 ARRAY_FIELD(struct utsname
, machine
, 0);
571 START(prfdinfo
, prfdinfo_t
);
573 SCALAR_FIELD(prfdinfo_t
, pr_fd
, 0);
574 SCALAR_FIELD(prfdinfo_t
, pr_mode
, 0);
575 SCALAR_FIELD(prfdinfo_t
, pr_uid
, 0);
576 SCALAR_FIELD(prfdinfo_t
, pr_gid
, 0);
577 SCALAR_FIELD(prfdinfo_t
, pr_major
, 0);
578 SCALAR_FIELD(prfdinfo_t
, pr_minor
, 0);
579 SCALAR_FIELD(prfdinfo_t
, pr_rmajor
, 0);
580 SCALAR_FIELD(prfdinfo_t
, pr_rminor
, 0);
581 SCALAR_FIELD(prfdinfo_t
, pr_ino
, 0);
582 SCALAR_FIELD(prfdinfo_t
, pr_offset
, 0);
583 SCALAR_FIELD(prfdinfo_t
, pr_size
, 0);
584 SCALAR_FIELD(prfdinfo_t
, pr_fileflags
, 0);
585 SCALAR_FIELD(prfdinfo_t
, pr_fdflags
, 0);
586 ARRAY_FIELD(prfdinfo_t
, pr_path
, 0);
594 START(prsecflags
, prsecflags_t
);
595 SCALAR_FIELD(prsecflags_t
, pr_version
, 0);
596 SCALAR_FIELD(prsecflags_t
, pr_effective
, 0);
597 SCALAR_FIELD(prsecflags_t
, pr_inherit
, 0);
598 SCALAR_FIELD(prsecflags_t
, pr_lower
, 0);
599 SCALAR_FIELD(prsecflags_t
, pr_upper
, 0);
606 START(prlwpname
, prlwpname_t
);
607 SCALAR_FIELD(prlwpname_t
, pr_lwpid
, 0);
608 ARRAY_FIELD(prlwpname_t
, pr_lwpname
, 0);
614 main(int argc
, char *argv
[])
616 const char *fmt
= "\t&%s_layout,\n";
618 /* get obj file for input */
620 (void) fprintf(stderr
,
621 "usage: %s {object_file} {MACH}\n", argv
[0]);
628 get_ctf_file(objfile
);
630 (void) printf("#include <struct_layout.h>\n");
642 gen_priv_impl_info();
656 * Generate the full arch_layout description
659 "\n\n\n\nstatic const sl_arch_layout_t layout_%s = {\n",
661 (void) printf(fmt
, "auxv");
662 (void) printf(fmt
, "fltset");
663 (void) printf(fmt
, "lwpsinfo");
664 (void) printf(fmt
, "lwpstatus");
665 (void) printf(fmt
, "prcred");
666 (void) printf(fmt
, "priv_impl_info");
667 (void) printf(fmt
, "prpriv");
668 (void) printf(fmt
, "psinfo");
669 (void) printf(fmt
, "pstatus");
670 (void) printf(fmt
, "prgregset");
671 (void) printf(fmt
, "prpsinfo");
672 (void) printf(fmt
, "prstatus");
673 (void) printf(fmt
, "sigaction");
674 (void) printf(fmt
, "siginfo");
675 (void) printf(fmt
, "sigset");
676 (void) printf(fmt
, "stack");
677 (void) printf(fmt
, "sysset");
678 (void) printf(fmt
, "timestruc");
679 (void) printf(fmt
, "utsname");
680 (void) printf(fmt
, "prfdinfo");
681 (void) printf(fmt
, "prsecflags");
682 (void) printf(fmt
, "prlwpname");
683 (void) printf("};\n");
686 * A public function, to make the information available
688 (void) printf("\n\nconst sl_arch_layout_t *\n");
689 (void) printf("struct_layout_%s(void)\n", machname
);
690 (void) printf("{\n\treturn (&layout_%s);\n}\n", machname
);
696 * Helper functions using the CTF library to get type info.
700 get_ctf_file(char *fname
)
705 if ((ctf
= ctf_open(objfile
, &ctferr
)) == NULL
) {
706 errx(1, "Couldn't open object file %s: %s\n", objfile
,
712 print_row(int boff
, int eltlen
, int nelts
, int issigned
, char *comment
)
714 (void) printf("\t{ %d,\t%d,\t%d,\t%d },\t\t/* %s */\n",
715 boff
, eltlen
, nelts
, issigned
, comment
);
719 do_start(char *sname
, char *tname
)
721 do_start_name(sname
);
722 do_start_sizeof(tname
, NULL
);
726 do_start_name(char *sname
)
728 (void) printf("\n\nstatic const sl_%s_layout_t %s_layout = {\n",
735 (void) printf("};\n");
739 do_start_sizeof(char *tname
, char *rtname
)
748 if ((stype
= ctf_lookup_by_name(ctf
, rtname
)) == CTF_ERR
)
749 errx(1, "Couldn't find type %s", rtname
);
750 if ((stype
= ctf_type_resolve(ctf
, stype
)) == CTF_ERR
)
751 errx(1, "Couldn't resolve type %s", tname
);
753 if ((sz
= (int)ctf_type_size(ctf
, stype
)) < 0) {
754 errx(1, "Couldn't get size for type %s", tname
);
755 } else if (sz
== 0) {
756 errx(1, "Invalid type size 0 for %s", tname
);
759 (void) snprintf(comment
, sizeof (comment
), "sizeof (%s)", tname
);
760 print_row(0, sz
, 0, 0, comment
);
764 do_scalar_field(char *tname
, char *fname
, int _sign
, char *dotfield
)
766 int rc
, off
, sz
, ftype
;
768 rc
= get_field_info(tname
, fname
, dotfield
, &off
, &ftype
);
770 errx(1, "Can't get field info for %s->%s", tname
, fname
);
772 if ((ftype
= ctf_type_resolve(ctf
, ftype
)) == CTF_ERR
)
773 errx(1, "Couldn't resolve type of %s->%s", tname
, fname
);
775 if ((sz
= (int)ctf_type_size(ctf
, ftype
)) < 0) {
776 errx(1, "Couldn't get size for type ID %d", ftype
);
777 } else if (sz
== 0) {
778 errx(1, "Invalid type size 0 for type ID %d", ftype
);
781 print_row(off
, sz
, 0, _sign
, fname
);
785 do_array_field(char *tname
, char *fname
,
786 int _sign
, char *dotfield
)
791 int esz
, rc
, off
, ftype
;
793 rc
= get_field_info(tname
, fname
, dotfield
, &off
, &ftype
);
795 errx(1, "Can't get field info for %s->%s", tname
, fname
);
797 if ((ftype
= ctf_type_resolve(ctf
, ftype
)) == CTF_ERR
)
798 errx(1, "Couldn't resolve type of %s->%s", tname
, fname
);
800 typekind
= ctf_type_kind(ctf
, ftype
);
801 if (typekind
!= CTF_K_ARRAY
)
802 errx(1, "Wrong type for %s->%s", tname
, fname
);
804 rc
= ctf_array_info(ctf
, ftype
, &ai
);
806 errx(1, "Can't get array info for %s->%s\n", tname
, fname
);
807 esz
= ctf_type_size(ctf
, ai
.ctr_contents
);
809 errx(1, "Can't get element size for %s->%s\n", tname
, fname
);
811 (void) snprintf(comment
, sizeof (comment
), "%s[]", fname
);
812 print_row(off
, esz
, ai
.ctr_nelems
, _sign
, comment
);
816 do_array_type(char *tname
, char *fname
, int _sign
)
822 if ((stype
= ctf_lookup_by_name(ctf
, tname
)) == CTF_ERR
)
823 errx(1, "Couldn't find type %s", tname
);
824 if ((stype
= ctf_type_resolve(ctf
, stype
)) == CTF_ERR
)
825 errx(1, "Couldn't resolve type %s", tname
);
827 typekind
= ctf_type_kind(ctf
, stype
);
828 if (typekind
!= CTF_K_ARRAY
)
829 errx(1, "Wrong type for %s->%s", tname
, fname
);
831 rc
= ctf_array_info(ctf
, stype
, &ai
);
833 errx(1, "Can't get array info for %s->%s\n", tname
, fname
);
834 esz
= ctf_type_size(ctf
, ai
.ctr_contents
);
836 errx(1, "Can't get element size for %s->%s\n", tname
, fname
);
838 print_row(0, esz
, ai
.ctr_nelems
, _sign
, fname
);
843 char *tname
; /* top type name, i.e. the struct */
844 char *fname
; /* field name */
845 char *dotname
; /* full field name with dots (optional) */
846 char *prefix
; /* current field search prefix */
852 static int gfi_iter(const char *fname
, ctf_id_t mbrtid
,
853 ulong_t off
, void *varg
);
856 * Lookup field "fname" in type "tname". If "dotname" is non-NULL,
857 * that's the full field name with dots, i.e. a_un.un_foo, which
858 * we must search for by walking the struct CTF recursively.
861 get_field_info(char *tname
, char *fname
, char *dotname
,
862 int *offp
, int *tidp
)
869 if ((stype
= ctf_lookup_by_name(ctf
, tname
)) == CTF_ERR
)
870 errx(1, "Couldn't find type %s", tname
);
871 if ((stype
= ctf_type_resolve(ctf
, stype
)) == CTF_ERR
)
872 errx(1, "Couldn't resolve type %s", tname
);
874 /* If fname has a dot, use it as dotname too. */
875 if (dotname
== NULL
&& strchr(fname
, '.') != NULL
)
880 gfi
.dotname
= dotname
;
886 typekind
= ctf_type_kind(ctf
, stype
);
891 rc
= ctf_member_iter(ctf
, stype
, gfi_iter
, &gfi
);
895 errx(1, "Unexpected top-level type for %s", tname
);
900 errx(1, "Error getting info for %s.%s", stype
, fname
);
902 errx(1, "Did not find %s.%s", tname
, fname
);
905 *tidp
= gfi
.fld_type
;
911 * Iteration callback for ctf_member_iter
912 * Return <0 on error, 0 to keep looking, >0 for found.
914 * If no dotname, simple search for fieldname.
915 * If we're asked to search with dotname, we need to do a full
916 * recursive walk of the types under the dotname.
919 gfi_iter(const char *fieldname
, ctf_id_t mbrtid
, ulong_t off
, void *varg
)
922 struct gfinfo
*gfi
= varg
;
929 byteoff
= gfi
->base_off
+ (int)(off
>> 3);
931 /* Easy cases first: no dotname */
932 if (gfi
->dotname
== NULL
) {
933 if (strcmp(gfi
->fname
, fieldname
) == 0) {
934 gfi
->fld_off
= byteoff
;
935 gfi
->fld_type
= mbrtid
;
941 /* Exact match on the dotname? */
942 (void) snprintf(namebuf
, sizeof (namebuf
), "%s%s",
943 gfi
->prefix
, fieldname
);
944 if (strcmp(gfi
->dotname
, namebuf
) == 0) {
945 gfi
->fld_off
= byteoff
;
946 gfi
->fld_type
= mbrtid
;
951 * May need to recurse under this field, but
952 * only if there's a match through '.'
954 (void) strlcat(namebuf
, ".", sizeof (namebuf
));
955 len
= strlen(namebuf
);
956 if (strncmp(gfi
->dotname
, namebuf
, len
) != 0)
959 typekind
= ctf_type_kind(ctf
, mbrtid
);
968 /* Recursively walk members */
969 saveprefix
= gfi
->prefix
;
970 saveoff
= gfi
->base_off
;
971 gfi
->prefix
= namebuf
;
972 gfi
->base_off
= byteoff
;
973 rc
= ctf_member_iter(ctf
, mbrtid
, gfi_iter
, gfi
);
974 gfi
->prefix
= saveprefix
;
975 gfi
->base_off
= saveoff
;