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 
27 #ifndef	_STRUCT_LAYOUT_H
28 #define	_STRUCT_LAYOUT_H
29 
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 #include	<conv.h>
33 #include	<_machelf.h>
34 
35 /*
36  * Local include file for elfdump, used to define structure layout
37  * definitions for various system structs.
38  */
39 
40 #ifdef	__cplusplus
41 extern "C" {
42 #endif
43 
44 
45 /*
46  * Solaris defines system structs that elfdump needs to display
47  * data from. We have a variety of hurdles to overcome in doing this:
48  *
49  *	- The size of system types can differ between ELFCLASS32 and
50  *		ELFCLASS64.
51  *	- Stucture layout can differ between architectures, so a given
52  *		field can have a different struct offset than is native
53  *		for the system running elfdump. Depending on the struct
54  *		in question, the layout for one platform may be impossible
55  *		to achieve on another.
56  *	- The byte order of the core object can differ from that
57  *		of the system running elfdump.
58  *
59  * The result is that in the fully general case, each architecture
60  * can have a slightly different definition of these structures.
61  * The usual approach of assigning a pointer of the desired structure
62  * type and then accessing fields through that pointer cannot be used
63  * here. That approach can only be used to access structures with the
64  * native layout of the elfdump host. We want any instance of elfdump
65  * to be able to examine a Solaris object for any supported architecture,
66  * so we need a more flexible approach.
67  *
68  * The solution to this problem lies in the fact that the binary
69  * layout of these public types cannot be changed, except in backward
70  * compatible ways. They are written to core files or published in
71  * other ways such that we can't make changes that would make it
72  * impossible to analyze old files. This means that we can build
73  * table of offsets and sizes for each field of each struct, on
74  * a per-archecture basis. These tables can be used to access the
75  * struct fields directly from the note desc data, and elfdump
76  * on any host can read the data from any other host.
77  *
78  * When reading these tables, it can be very helpful to examine
79  * the struct definition at the same time.
80  */
81 
82 /*
83  * sl_field_t is used to describe a struct field
84  */
85 typedef struct {
86 	ushort_t	slf_offset;	/* Offset from start of struct */
87 	ushort_t	slf_eltlen;	/* Size of datum, in bytes */
88 	ushort_t	slf_nelts;	/* 0 for scalar, # of els for array */
89 	uchar_t		slf_sign;	/* True (1) if signed quantity */
90 } sl_field_t;
91 
92 /*
93  * This type is used to extract and manipuate data described by
94  * sl_field_t. We rely on the C guarantee that all the fields in
95  * a union have offset 0.
96  */
97 typedef union {
98 	char		sld_i8;
99 	uchar_t 	sld_ui8;
100 	short		sld_i16;
101 	ushort_t	sld_ui16;
102 	int32_t		sld_i32;
103 	uint32_t	sld_ui32;
104 	int64_t		sld_i64;
105 	uint64_t	sld_ui64;
106 } sl_data_t;
107 
108 /*
109  * Buffer large enough to format any integral value in a field
110  */
111 typedef char sl_fmtbuf_t[CONV64_INV_BUFSIZE * 2];
112 
113 /*
114  * Types of formatting done by fmt_num()
115  */
116 typedef enum {
117 	SL_FMT_NUM_DEC = 0,	/* Decimal integer */
118 	SL_FMT_NUM_HEX = 1,	/* Hex integer, with natural width */
119 	SL_FMT_NUM_ZHEX = 2,	/* Hex integer, fixed width with zero fill  */
120 } sl_fmt_num_t;
121 
122 
123 
124 
125 /*
126  * Layout description of auxv_t, from <sys/auxv.h>.
127  */
128 typedef struct {
129 	sl_field_t		sizeof_struct;
130 	sl_field_t		a_type;
131 	sl_field_t		a_val;
132 	sl_field_t		a_ptr;
133 	sl_field_t		a_fcn;
134 } sl_auxv_layout_t;
135 
136 /*
137  * Layout description of prgregset_t, an architecture specific
138  * array of general register c values
139  */
140 typedef struct {
141 	sl_field_t		sizeof_struct;
142 	sl_field_t		elt0;
143 } sl_prgregset_layout_t;
144 
145 /*
146  * Layout description of lwpstatus_t, from <sys/procfs.h>.
147  */
148 typedef struct {
149 	sl_field_t		sizeof_struct;
150 	sl_field_t		pr_flags;
151 	sl_field_t		pr_lwpid;
152 	sl_field_t		pr_why;
153 	sl_field_t		pr_what;
154 	sl_field_t		pr_cursig;
155 	sl_field_t		pr_info;
156 	sl_field_t		pr_lwppend;
157 	sl_field_t		pr_lwphold;
158 	sl_field_t		pr_action;
159 	sl_field_t		pr_altstack;
160 	sl_field_t		pr_oldcontext;
161 	sl_field_t		pr_syscall;
162 	sl_field_t		pr_nsysarg;
163 	sl_field_t		pr_errno;
164 	sl_field_t		pr_sysarg;
165 	sl_field_t		pr_rval1;
166 	sl_field_t		pr_rval2;
167 	sl_field_t		pr_clname;
168 	sl_field_t		pr_tstamp;
169 	sl_field_t		pr_utime;
170 	sl_field_t		pr_stime;
171 	sl_field_t		pr_errpriv;
172 	sl_field_t		pr_ustack;
173 	sl_field_t		pr_instr;
174 	sl_field_t		pr_reg;
175 	sl_field_t		pr_fpreg;
176 } sl_lwpstatus_layout_t;
177 
178 /*
179  * Layout description of pstatus_t, from <sys/procfs.h>.
180  */
181 typedef struct {
182 	sl_field_t		sizeof_struct;
183 	sl_field_t		pr_flags;
184 	sl_field_t		pr_nlwp;
185 	sl_field_t		pr_pid;
186 	sl_field_t		pr_ppid;
187 	sl_field_t		pr_pgid;
188 	sl_field_t		pr_sid;
189 	sl_field_t		pr_aslwpid;
190 	sl_field_t		pr_agentid;
191 	sl_field_t		pr_sigpend;
192 	sl_field_t		pr_brkbase;
193 	sl_field_t		pr_brksize;
194 	sl_field_t		pr_stkbase;
195 	sl_field_t		pr_stksize;
196 	sl_field_t		pr_utime;
197 	sl_field_t		pr_stime;
198 	sl_field_t		pr_cutime;
199 	sl_field_t		pr_cstime;
200 	sl_field_t		pr_sigtrace;
201 	sl_field_t		pr_flttrace;
202 	sl_field_t		pr_sysentry;
203 	sl_field_t		pr_sysexit;
204 	sl_field_t		pr_dmodel;
205 	sl_field_t		pr_taskid;
206 	sl_field_t		pr_projid;
207 	sl_field_t		pr_nzomb;
208 	sl_field_t		pr_zoneid;
209 	sl_field_t		pr_lwp;
210 } sl_pstatus_layout_t;
211 
212 /*
213  * Layout description of prstatus_t, from <sys/old_procfs.h>.
214  */
215 typedef struct {
216 	sl_field_t		sizeof_struct;
217 	sl_field_t		pr_flags;
218 	sl_field_t		pr_why;
219 	sl_field_t		pr_what;
220 	sl_field_t		pr_info;
221 	sl_field_t		pr_cursig;
222 	sl_field_t		pr_nlwp;
223 	sl_field_t		pr_sigpend;
224 	sl_field_t		pr_sighold;
225 	sl_field_t		pr_altstack;
226 	sl_field_t		pr_action;
227 	sl_field_t		pr_pid;
228 	sl_field_t		pr_ppid;
229 	sl_field_t		pr_pgrp;
230 	sl_field_t		pr_sid;
231 	sl_field_t		pr_utime;
232 	sl_field_t		pr_stime;
233 	sl_field_t		pr_cutime;
234 	sl_field_t		pr_cstime;
235 	sl_field_t		pr_clname;
236 	sl_field_t		pr_syscall;
237 	sl_field_t		pr_nsysarg;
238 	sl_field_t		pr_sysarg;
239 	sl_field_t		pr_who;
240 	sl_field_t		pr_lwppend;
241 	sl_field_t		pr_oldcontext;
242 	sl_field_t		pr_brkbase;
243 	sl_field_t		pr_brksize;
244 	sl_field_t		pr_stkbase;
245 	sl_field_t		pr_stksize;
246 	sl_field_t		pr_processor;
247 	sl_field_t		pr_bind;
248 	sl_field_t		pr_instr;
249 	sl_field_t		pr_reg;
250 } sl_prstatus_layout_t;
251 
252 /*
253  * Layout description of psinfo_t, from <sys/procfs.h>.
254  */
255 typedef struct {
256 	sl_field_t		sizeof_struct;
257 	sl_field_t		pr_flag;
258 	sl_field_t		pr_nlwp;
259 	sl_field_t		pr_pid;
260 	sl_field_t		pr_ppid;
261 	sl_field_t		pr_pgid;
262 	sl_field_t		pr_sid;
263 	sl_field_t		pr_uid;
264 	sl_field_t		pr_euid;
265 	sl_field_t		pr_gid;
266 	sl_field_t		pr_egid;
267 	sl_field_t		pr_addr;
268 	sl_field_t		pr_size;
269 	sl_field_t		pr_rssize;
270 	sl_field_t		pr_ttydev;
271 	sl_field_t		pr_pctcpu;
272 	sl_field_t		pr_pctmem;
273 	sl_field_t		pr_start;
274 	sl_field_t		pr_time;
275 	sl_field_t		pr_ctime;
276 	sl_field_t		pr_fname;
277 	sl_field_t		pr_psargs;
278 	sl_field_t		pr_wstat;
279 	sl_field_t		pr_argc;
280 	sl_field_t		pr_argv;
281 	sl_field_t		pr_envp;
282 	sl_field_t		pr_dmodel;
283 	sl_field_t		pr_taskid;
284 	sl_field_t		pr_projid;
285 	sl_field_t		pr_nzomb;
286 	sl_field_t		pr_poolid;
287 	sl_field_t		pr_zoneid;
288 	sl_field_t		pr_contract;
289 	sl_field_t		pr_lwp;
290 } sl_psinfo_layout_t;
291 
292 /*
293  * Layout description of prpsinfo_t, from <sys/old_procfs.h>.
294  */
295 typedef struct {
296 	sl_field_t		sizeof_struct;
297 	sl_field_t		pr_state;
298 	sl_field_t		pr_sname;
299 	sl_field_t		pr_zomb;
300 	sl_field_t		pr_nice;
301 	sl_field_t		pr_flag;
302 	sl_field_t		pr_uid;
303 	sl_field_t		pr_gid;
304 	sl_field_t		pr_pid;
305 	sl_field_t		pr_ppid;
306 	sl_field_t		pr_pgrp;
307 	sl_field_t		pr_sid;
308 	sl_field_t		pr_addr;
309 	sl_field_t		pr_size;
310 	sl_field_t		pr_rssize;
311 	sl_field_t		pr_wchan;
312 	sl_field_t		pr_start;
313 	sl_field_t		pr_time;
314 	sl_field_t		pr_pri;
315 	sl_field_t		pr_oldpri;
316 	sl_field_t		pr_cpu;
317 	sl_field_t		pr_ottydev;
318 	sl_field_t		pr_lttydev;
319 	sl_field_t		pr_clname;
320 	sl_field_t		pr_fname;
321 	sl_field_t		pr_psargs;
322 	sl_field_t		pr_syscall;
323 	sl_field_t		pr_ctime;
324 	sl_field_t		pr_bysize;
325 	sl_field_t		pr_byrssize;
326 	sl_field_t		pr_argc;
327 	sl_field_t		pr_argv;
328 	sl_field_t		pr_envp;
329 	sl_field_t		pr_wstat;
330 	sl_field_t		pr_pctcpu;
331 	sl_field_t		pr_pctmem;
332 	sl_field_t		pr_euid;
333 	sl_field_t		pr_egid;
334 	sl_field_t		pr_aslwpid;
335 	sl_field_t		pr_dmodel;
336 } sl_prpsinfo_layout_t;
337 
338 /*
339  * Layout description of lwpsinfo_t, from <sys/procfs.h>.
340  */
341 typedef struct {
342 	sl_field_t		sizeof_struct;
343 	sl_field_t		pr_flag;
344 	sl_field_t		pr_lwpid;
345 	sl_field_t		pr_addr;
346 	sl_field_t		pr_wchan;
347 	sl_field_t		pr_stype;
348 	sl_field_t		pr_state;
349 	sl_field_t		pr_sname;
350 	sl_field_t		pr_nice;
351 	sl_field_t		pr_syscall;
352 	sl_field_t		pr_oldpri;
353 	sl_field_t		pr_cpu;
354 	sl_field_t		pr_pri;
355 	sl_field_t		pr_pctcpu;
356 	sl_field_t		pr_start;
357 	sl_field_t		pr_time;
358 	sl_field_t		pr_clname;
359 	sl_field_t		pr_name;
360 	sl_field_t		pr_onpro;
361 	sl_field_t		pr_bindpro;
362 	sl_field_t		pr_bindpset;
363 	sl_field_t		pr_lgrp;
364 } sl_lwpsinfo_layout_t;
365 
366 /*
367  * Layout description of prcred_t, from <sys/procfs.h>.
368  */
369 typedef struct {
370 	sl_field_t		sizeof_struct;
371 	sl_field_t		pr_euid;
372 	sl_field_t		pr_ruid;
373 	sl_field_t		pr_suid;
374 	sl_field_t		pr_egid;
375 	sl_field_t		pr_rgid;
376 	sl_field_t		pr_sgid;
377 	sl_field_t		pr_ngroups;
378 	sl_field_t		pr_groups;
379 } sl_prcred_layout_t;
380 
381 /*
382  * Layout description of prpriv_t, from <sys/procfs.h>.
383  */
384 typedef struct {
385 	sl_field_t		sizeof_struct;
386 	sl_field_t		pr_nsets;
387 	sl_field_t		pr_setsize;
388 	sl_field_t		pr_infosize;
389 	sl_field_t		pr_sets;
390 } sl_prpriv_layout_t;
391 
392 /*
393  * Layout description of priv_impl_info_t, from <sys/priv.h>.
394  */
395 typedef struct {
396 	sl_field_t		sizeof_struct;
397 	sl_field_t		priv_headersize;
398 	sl_field_t		priv_flags;
399 	sl_field_t		priv_nsets;
400 	sl_field_t		priv_setsize;
401 	sl_field_t		priv_max;
402 	sl_field_t		priv_infosize;
403 	sl_field_t		priv_globalinfosize;
404 } sl_priv_impl_info_layout_t;
405 
406 /*
407  * Layout description of fltset_t, from <sys/fault.h>.
408  */
409 typedef struct {
410 	sl_field_t		sizeof_struct;
411 	sl_field_t		word;
412 } sl_fltset_layout_t;
413 
414 /*
415  * Layout description of siginfo_t, from <sys/siginfo.h>.
416  *
417  * siginfo_t is unusual, in that it contains a large union
418  * full of private fields. There are macros defined to give
419  * access to these fields via the names documented in the
420  * siginfo manpage. We stick to the documented names
421  * rather than try to unravel the undocumented blob. Hence,
422  * the layout description below is a "logical" view of siginfo_t.
423  * The fields below are not necessarily in the same order as
424  * they appear in siginfo_t, nor are they everything that is in
425  * that struct. They may also overlap each other, if they are
426  * contained within of the union.
427  *
428  * The f_ prefixes are used to prevent our field names from
429  * clashing with the macros defined in siginfo.h.
430  */
431 typedef struct {
432 	sl_field_t		sizeof_struct;
433 	sl_field_t		f_si_signo;
434 	sl_field_t		f_si_errno;
435 	sl_field_t		f_si_code;
436 	sl_field_t		f_si_value_int;
437 	sl_field_t		f_si_value_ptr;
438 	sl_field_t		f_si_pid;
439 	sl_field_t		f_si_uid;
440 	sl_field_t		f_si_ctid;
441 	sl_field_t		f_si_zoneid;
442 	sl_field_t		f_si_entity;
443 	sl_field_t		f_si_addr;
444 	sl_field_t		f_si_status;
445 	sl_field_t		f_si_band;
446 } sl_siginfo_layout_t;
447 
448 /*
449  * Layout description of sigset_t, from <sys/signal.h>.
450  */
451 typedef struct {
452 	sl_field_t		sizeof_struct;
453 	sl_field_t		sigbits;
454 } sl_sigset_layout_t;
455 
456 /*
457  * Layout description of struct sigaction, from <sys/signal.h>.
458  */
459 typedef struct {
460 	sl_field_t		sizeof_struct;
461 	sl_field_t		sa_flags;
462 	sl_field_t		sa_hand;
463 	sl_field_t		sa_sigact;
464 	sl_field_t		sa_mask;
465 } sl_sigaction_layout_t;
466 
467 /*
468  * Layout description of stack_t, from <sys/signal.h>.
469  */
470 typedef struct {
471 	sl_field_t		sizeof_struct;
472 	sl_field_t		ss_sp;
473 	sl_field_t		ss_size;
474 	sl_field_t		ss_flags;
475 } sl_stack_layout_t;
476 
477 /*
478  * Layout description of sysset_t, from <sys/syscall.h>.
479  */
480 typedef struct {
481 	sl_field_t		sizeof_struct;
482 	sl_field_t		word;
483 } sl_sysset_layout_t;
484 
485 /*
486  * Layout description of timestruc_t, from <sys/time_impl.h>.
487  */
488 typedef struct {
489 	sl_field_t		sizeof_struct;
490 	sl_field_t		tv_sec;
491 	sl_field_t		tv_nsec;
492 } sl_timestruc_layout_t;
493 
494 /*
495  * Layout description of struct utsname, from <sys/utsname.h>.
496  */
497 typedef struct {
498 	sl_field_t		sizeof_struct;
499 	sl_field_t		sysname;
500 	sl_field_t		nodename;
501 	sl_field_t		release;
502 	sl_field_t		version;
503 	sl_field_t		machine;
504 } sl_utsname_layout_t;
505 
506 /*
507  * This type collects all of the layout definitions for
508  * a given architecture.
509  */
510 typedef struct {
511 	const sl_auxv_layout_t		*auxv;		/* auxv_t */
512 	const sl_fltset_layout_t	*fltset;	/* fltset_t */
513 	const sl_lwpsinfo_layout_t	*lwpsinfo;	/* lwpsinfo_t */
514 	const sl_lwpstatus_layout_t	*lwpstatus;	/* lwpstatus_t */
515 	const sl_prcred_layout_t	*prcred;	/* prcred_t */
516 	const sl_priv_impl_info_layout_t *priv_impl_info; /* priv_impl_info_t */
517 	const sl_prpriv_layout_t	*prpriv;	/* prpriv_t */
518 	const sl_psinfo_layout_t	*psinfo;	/* psinfo_t */
519 	const sl_pstatus_layout_t	*pstatus;	/* pstatus_t */
520 	const sl_prgregset_layout_t	*prgregset;	/* prgregset_t */
521 	const sl_prpsinfo_layout_t	*prpsinfo;	/* prpsinfo_t */
522 	const sl_prstatus_layout_t	*prstatus;	/* prstatus_t */
523 	const sl_sigaction_layout_t	*sigaction;	/* struct sigaction */
524 	const sl_siginfo_layout_t	*siginfo;	/* siginfo_t */
525 	const sl_sigset_layout_t	*sigset;	/* sigset_t */
526 	const sl_stack_layout_t		*stack;		/* stack_t */
527 	const sl_sysset_layout_t	*sysset;	/* sysset_t */
528 	const sl_timestruc_layout_t	*timestruc;	/* timestruc_t */
529 	const sl_utsname_layout_t	*utsname;	/* struct utsname */
530 } sl_arch_layout_t;
531 
532 
533 
534 extern	void		sl_extract_num_field(const char *data, int do_swap,
535 			    const sl_field_t *fdesc, sl_data_t *field_data);
536 extern	Word		sl_extract_as_word(const char *data, int do_swap,
537 			    const sl_field_t *fdesc);
538 extern	Lword		sl_extract_as_lword(const char *data, int do_swap,
539 			    const sl_field_t *fdesc);
540 extern	Sword		sl_extract_as_sword(const char *data, int do_swap,
541 			    const sl_field_t *fdesc);
542 extern	const char	*sl_fmt_num(const char *data, int do_swap,
543 			    const sl_field_t *fdesc, sl_fmt_num_t fmt_type,
544 			    sl_fmtbuf_t buf);
545 
546 
547 extern	const sl_arch_layout_t	*sl_mach(Half);
548 extern	const sl_arch_layout_t	*struct_layout_i386(void);
549 extern	const sl_arch_layout_t	*struct_layout_amd64(void);
550 extern	const sl_arch_layout_t	*struct_layout_sparc(void);
551 extern	const sl_arch_layout_t	*struct_layout_sparcv9(void);
552 
553 
554 
555 #ifdef	__cplusplus
556 }
557 #endif
558 
559 #endif	/* _STRUCT_LAYOUT_H */
560