Home | History | Annotate | Download | only in common
      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