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