view usr/src/cmd/sgs/elfdump/common/struct_layout.h @ 13875:f128a109e6d2

3294 pfiles postmortem support Reviewed by: Robert Mustacchi <rm@joyent.com> Reviewed by: Richard Lowe <richlowe@richlowe.net> Approved by: Eric Schrock <eric.schrock@delphix.com>
author Garrett D'Amore <garrett@damore.org>
date Fri, 02 Nov 2012 09:48:42 -0700
parents 9a0603d78ad3
children
line wrap: on
line source

/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */

/*
 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

/*
 * Copyright 2012 DEY Storage Systems, Inc.  All rights reserved.
 */

#ifndef	_STRUCT_LAYOUT_H
#define	_STRUCT_LAYOUT_H

#include	<conv.h>
#include	<_machelf.h>

/*
 * Local include file for elfdump, used to define structure layout
 * definitions for various system structs.
 */

#ifdef	__cplusplus
extern "C" {
#endif


/*
 * Solaris defines system structs that elfdump needs to display
 * data from. We have a variety of hurdles to overcome in doing this:
 *
 *	- The size of system types can differ between ELFCLASS32 and
 *		ELFCLASS64.
 *	- Stucture layout can differ between architectures, so a given
 *		field can have a different struct offset than is native
 *		for the system running elfdump. Depending on the struct
 *		in question, the layout for one platform may be impossible
 *		to achieve on another.
 *	- The byte order of the core object can differ from that
 *		of the system running elfdump.
 *
 * The result is that in the fully general case, each architecture
 * can have a slightly different definition of these structures.
 * The usual approach of assigning a pointer of the desired structure
 * type and then accessing fields through that pointer cannot be used
 * here. That approach can only be used to access structures with the
 * native layout of the elfdump host. We want any instance of elfdump
 * to be able to examine a Solaris object for any supported architecture,
 * so we need a more flexible approach.
 *
 * The solution to this problem lies in the fact that the binary
 * layout of these public types cannot be changed, except in backward
 * compatible ways. They are written to core files or published in
 * other ways such that we can't make changes that would make it
 * impossible to analyze old files. This means that we can build
 * table of offsets and sizes for each field of each struct, on
 * a per-archecture basis. These tables can be used to access the
 * struct fields directly from the note desc data, and elfdump
 * on any host can read the data from any other host.
 *
 * When reading these tables, it can be very helpful to examine
 * the struct definition at the same time.
 */

/*
 * sl_field_t is used to describe a struct field
 */
typedef struct {
	ushort_t	slf_offset;	/* Offset from start of struct */
	ushort_t	slf_eltlen;	/* Size of datum, in bytes */
	ushort_t	slf_nelts;	/* 0 for scalar, # of els for array */
	uchar_t		slf_sign;	/* True (1) if signed quantity */
} sl_field_t;

/*
 * This type is used to extract and manipulate data described by
 * sl_field_t. We rely on the C guarantee that all the fields in
 * a union have offset 0.
 */
typedef union {
	char		sld_i8;
	uchar_t 	sld_ui8;
	short		sld_i16;
	ushort_t	sld_ui16;
	int32_t		sld_i32;
	uint32_t	sld_ui32;
	int64_t		sld_i64;
	uint64_t	sld_ui64;
} sl_data_t;

/*
 * Buffer large enough to format any integral value in a field
 */
typedef char sl_fmtbuf_t[CONV_INV_BUFSIZE * 2];

/*
 * Types of formatting done by fmt_num()
 */
typedef enum {
	SL_FMT_NUM_DEC = 0,	/* Decimal integer */
	SL_FMT_NUM_HEX = 1,	/* Hex integer, with natural width */
	SL_FMT_NUM_ZHEX = 2,	/* Hex integer, fixed width with zero fill  */
} sl_fmt_num_t;




/*
 * Layout description of auxv_t, from <sys/auxv.h>.
 */
typedef struct {
	sl_field_t		sizeof_struct;
	sl_field_t		a_type;
	sl_field_t		a_val;
	sl_field_t		a_ptr;
	sl_field_t		a_fcn;
} sl_auxv_layout_t;

/*
 * Layout description of prgregset_t, an architecture specific
 * array of general register c values
 */
typedef struct {
	sl_field_t		sizeof_struct;
	sl_field_t		elt0;
} sl_prgregset_layout_t;

/*
 * Layout description of lwpstatus_t, from <sys/procfs.h>.
 */
typedef struct {
	sl_field_t		sizeof_struct;
	sl_field_t		pr_flags;
	sl_field_t		pr_lwpid;
	sl_field_t		pr_why;
	sl_field_t		pr_what;
	sl_field_t		pr_cursig;
	sl_field_t		pr_info;
	sl_field_t		pr_lwppend;
	sl_field_t		pr_lwphold;
	sl_field_t		pr_action;
	sl_field_t		pr_altstack;
	sl_field_t		pr_oldcontext;
	sl_field_t		pr_syscall;
	sl_field_t		pr_nsysarg;
	sl_field_t		pr_errno;
	sl_field_t		pr_sysarg;
	sl_field_t		pr_rval1;
	sl_field_t		pr_rval2;
	sl_field_t		pr_clname;
	sl_field_t		pr_tstamp;
	sl_field_t		pr_utime;
	sl_field_t		pr_stime;
	sl_field_t		pr_errpriv;
	sl_field_t		pr_ustack;
	sl_field_t		pr_instr;
	sl_field_t		pr_reg;
	sl_field_t		pr_fpreg;
} sl_lwpstatus_layout_t;

/*
 * Layout description of pstatus_t, from <sys/procfs.h>.
 */
typedef struct {
	sl_field_t		sizeof_struct;
	sl_field_t		pr_flags;
	sl_field_t		pr_nlwp;
	sl_field_t		pr_pid;
	sl_field_t		pr_ppid;
	sl_field_t		pr_pgid;
	sl_field_t		pr_sid;
	sl_field_t		pr_aslwpid;
	sl_field_t		pr_agentid;
	sl_field_t		pr_sigpend;
	sl_field_t		pr_brkbase;
	sl_field_t		pr_brksize;
	sl_field_t		pr_stkbase;
	sl_field_t		pr_stksize;
	sl_field_t		pr_utime;
	sl_field_t		pr_stime;
	sl_field_t		pr_cutime;
	sl_field_t		pr_cstime;
	sl_field_t		pr_sigtrace;
	sl_field_t		pr_flttrace;
	sl_field_t		pr_sysentry;
	sl_field_t		pr_sysexit;
	sl_field_t		pr_dmodel;
	sl_field_t		pr_taskid;
	sl_field_t		pr_projid;
	sl_field_t		pr_nzomb;
	sl_field_t		pr_zoneid;
	sl_field_t		pr_lwp;
} sl_pstatus_layout_t;

/*
 * Layout description of prstatus_t, from <sys/old_procfs.h>.
 */
typedef struct {
	sl_field_t		sizeof_struct;
	sl_field_t		pr_flags;
	sl_field_t		pr_why;
	sl_field_t		pr_what;
	sl_field_t		pr_info;
	sl_field_t		pr_cursig;
	sl_field_t		pr_nlwp;
	sl_field_t		pr_sigpend;
	sl_field_t		pr_sighold;
	sl_field_t		pr_altstack;
	sl_field_t		pr_action;
	sl_field_t		pr_pid;
	sl_field_t		pr_ppid;
	sl_field_t		pr_pgrp;
	sl_field_t		pr_sid;
	sl_field_t		pr_utime;
	sl_field_t		pr_stime;
	sl_field_t		pr_cutime;
	sl_field_t		pr_cstime;
	sl_field_t		pr_clname;
	sl_field_t		pr_syscall;
	sl_field_t		pr_nsysarg;
	sl_field_t		pr_sysarg;
	sl_field_t		pr_who;
	sl_field_t		pr_lwppend;
	sl_field_t		pr_oldcontext;
	sl_field_t		pr_brkbase;
	sl_field_t		pr_brksize;
	sl_field_t		pr_stkbase;
	sl_field_t		pr_stksize;
	sl_field_t		pr_processor;
	sl_field_t		pr_bind;
	sl_field_t		pr_instr;
	sl_field_t		pr_reg;
} sl_prstatus_layout_t;

/*
 * Layout description of psinfo_t, from <sys/procfs.h>.
 */
typedef struct {
	sl_field_t		sizeof_struct;
	sl_field_t		pr_flag;
	sl_field_t		pr_nlwp;
	sl_field_t		pr_pid;
	sl_field_t		pr_ppid;
	sl_field_t		pr_pgid;
	sl_field_t		pr_sid;
	sl_field_t		pr_uid;
	sl_field_t		pr_euid;
	sl_field_t		pr_gid;
	sl_field_t		pr_egid;
	sl_field_t		pr_addr;
	sl_field_t		pr_size;
	sl_field_t		pr_rssize;
	sl_field_t		pr_ttydev;
	sl_field_t		pr_pctcpu;
	sl_field_t		pr_pctmem;
	sl_field_t		pr_start;
	sl_field_t		pr_time;
	sl_field_t		pr_ctime;
	sl_field_t		pr_fname;
	sl_field_t		pr_psargs;
	sl_field_t		pr_wstat;
	sl_field_t		pr_argc;
	sl_field_t		pr_argv;
	sl_field_t		pr_envp;
	sl_field_t		pr_dmodel;
	sl_field_t		pr_taskid;
	sl_field_t		pr_projid;
	sl_field_t		pr_nzomb;
	sl_field_t		pr_poolid;
	sl_field_t		pr_zoneid;
	sl_field_t		pr_contract;
	sl_field_t		pr_lwp;
} sl_psinfo_layout_t;

/*
 * Layout description of prpsinfo_t, from <sys/old_procfs.h>.
 */
typedef struct {
	sl_field_t		sizeof_struct;
	sl_field_t		pr_state;
	sl_field_t		pr_sname;
	sl_field_t		pr_zomb;
	sl_field_t		pr_nice;
	sl_field_t		pr_flag;
	sl_field_t		pr_uid;
	sl_field_t		pr_gid;
	sl_field_t		pr_pid;
	sl_field_t		pr_ppid;
	sl_field_t		pr_pgrp;
	sl_field_t		pr_sid;
	sl_field_t		pr_addr;
	sl_field_t		pr_size;
	sl_field_t		pr_rssize;
	sl_field_t		pr_wchan;
	sl_field_t		pr_start;
	sl_field_t		pr_time;
	sl_field_t		pr_pri;
	sl_field_t		pr_oldpri;
	sl_field_t		pr_cpu;
	sl_field_t		pr_ottydev;
	sl_field_t		pr_lttydev;
	sl_field_t		pr_clname;
	sl_field_t		pr_fname;
	sl_field_t		pr_psargs;
	sl_field_t		pr_syscall;
	sl_field_t		pr_ctime;
	sl_field_t		pr_bysize;
	sl_field_t		pr_byrssize;
	sl_field_t		pr_argc;
	sl_field_t		pr_argv;
	sl_field_t		pr_envp;
	sl_field_t		pr_wstat;
	sl_field_t		pr_pctcpu;
	sl_field_t		pr_pctmem;
	sl_field_t		pr_euid;
	sl_field_t		pr_egid;
	sl_field_t		pr_aslwpid;
	sl_field_t		pr_dmodel;
} sl_prpsinfo_layout_t;

/*
 * Layout description of lwpsinfo_t, from <sys/procfs.h>.
 */
typedef struct {
	sl_field_t		sizeof_struct;
	sl_field_t		pr_flag;
	sl_field_t		pr_lwpid;
	sl_field_t		pr_addr;
	sl_field_t		pr_wchan;
	sl_field_t		pr_stype;
	sl_field_t		pr_state;
	sl_field_t		pr_sname;
	sl_field_t		pr_nice;
	sl_field_t		pr_syscall;
	sl_field_t		pr_oldpri;
	sl_field_t		pr_cpu;
	sl_field_t		pr_pri;
	sl_field_t		pr_pctcpu;
	sl_field_t		pr_start;
	sl_field_t		pr_time;
	sl_field_t		pr_clname;
	sl_field_t		pr_name;
	sl_field_t		pr_onpro;
	sl_field_t		pr_bindpro;
	sl_field_t		pr_bindpset;
	sl_field_t		pr_lgrp;
} sl_lwpsinfo_layout_t;

/*
 * Layout description of prcred_t, from <sys/procfs.h>.
 */
typedef struct {
	sl_field_t		sizeof_struct;
	sl_field_t		pr_euid;
	sl_field_t		pr_ruid;
	sl_field_t		pr_suid;
	sl_field_t		pr_egid;
	sl_field_t		pr_rgid;
	sl_field_t		pr_sgid;
	sl_field_t		pr_ngroups;
	sl_field_t		pr_groups;
} sl_prcred_layout_t;

/*
 * Layout description of prpriv_t, from <sys/procfs.h>.
 */
typedef struct {
	sl_field_t		sizeof_struct;
	sl_field_t		pr_nsets;
	sl_field_t		pr_setsize;
	sl_field_t		pr_infosize;
	sl_field_t		pr_sets;
} sl_prpriv_layout_t;

/*
 * Layout description of priv_impl_info_t, from <sys/priv.h>.
 */
typedef struct {
	sl_field_t		sizeof_struct;
	sl_field_t		priv_headersize;
	sl_field_t		priv_flags;
	sl_field_t		priv_nsets;
	sl_field_t		priv_setsize;
	sl_field_t		priv_max;
	sl_field_t		priv_infosize;
	sl_field_t		priv_globalinfosize;
} sl_priv_impl_info_layout_t;

/*
 * Layout description of fltset_t, from <sys/fault.h>.
 */
typedef struct {
	sl_field_t		sizeof_struct;
	sl_field_t		word;
} sl_fltset_layout_t;

/*
 * Layout description of siginfo_t, from <sys/siginfo.h>.
 *
 * siginfo_t is unusual, in that it contains a large union
 * full of private fields. There are macros defined to give
 * access to these fields via the names documented in the
 * siginfo manpage. We stick to the documented names
 * rather than try to unravel the undocumented blob. Hence,
 * the layout description below is a "logical" view of siginfo_t.
 * The fields below are not necessarily in the same order as
 * they appear in siginfo_t, nor are they everything that is in
 * that struct. They may also overlap each other, if they are
 * contained within of the union.
 *
 * The f_ prefixes are used to prevent our field names from
 * clashing with the macros defined in siginfo.h.
 */
typedef struct {
	sl_field_t		sizeof_struct;
	sl_field_t		f_si_signo;
	sl_field_t		f_si_errno;
	sl_field_t		f_si_code;
	sl_field_t		f_si_value_int;
	sl_field_t		f_si_value_ptr;
	sl_field_t		f_si_pid;
	sl_field_t		f_si_uid;
	sl_field_t		f_si_ctid;
	sl_field_t		f_si_zoneid;
	sl_field_t		f_si_entity;
	sl_field_t		f_si_addr;
	sl_field_t		f_si_status;
	sl_field_t		f_si_band;
} sl_siginfo_layout_t;

/*
 * Layout description of sigset_t, from <sys/signal.h>.
 */
typedef struct {
	sl_field_t		sizeof_struct;
	sl_field_t		sigbits;
} sl_sigset_layout_t;

/*
 * Layout description of struct sigaction, from <sys/signal.h>.
 */
typedef struct {
	sl_field_t		sizeof_struct;
	sl_field_t		sa_flags;
	sl_field_t		sa_hand;
	sl_field_t		sa_sigact;
	sl_field_t		sa_mask;
} sl_sigaction_layout_t;

/*
 * Layout description of stack_t, from <sys/signal.h>.
 */
typedef struct {
	sl_field_t		sizeof_struct;
	sl_field_t		ss_sp;
	sl_field_t		ss_size;
	sl_field_t		ss_flags;
} sl_stack_layout_t;

/*
 * Layout description of sysset_t, from <sys/syscall.h>.
 */
typedef struct {
	sl_field_t		sizeof_struct;
	sl_field_t		word;
} sl_sysset_layout_t;

/*
 * Layout description of timestruc_t, from <sys/time_impl.h>.
 */
typedef struct {
	sl_field_t		sizeof_struct;
	sl_field_t		tv_sec;
	sl_field_t		tv_nsec;
} sl_timestruc_layout_t;

/*
 * Layout description of struct utsname, from <sys/utsname.h>.
 */
typedef struct {
	sl_field_t		sizeof_struct;
	sl_field_t		sysname;
	sl_field_t		nodename;
	sl_field_t		release;
	sl_field_t		version;
	sl_field_t		machine;
} sl_utsname_layout_t;

/*
 * Layout description of prdinfo_t, from <sys/procfs.h>.
 */
typedef struct {
	sl_field_t		sizeof_struct;
	sl_field_t		pr_fd;
	sl_field_t		pr_mode;
	sl_field_t		pr_uid;
	sl_field_t		pr_gid;
	sl_field_t		pr_major;
	sl_field_t		pr_minor;
	sl_field_t		pr_rmajor;
	sl_field_t		pr_rminor;
	sl_field_t		pr_ino;
	sl_field_t		pr_offset;
	sl_field_t		pr_size;
	sl_field_t		pr_fileflags;
	sl_field_t		pr_fdflags;
	sl_field_t		pr_path;
} sl_prfdinfo_layout_t;

/*
 * This type collects all of the layout definitions for
 * a given architecture.
 */
typedef struct {
	const sl_auxv_layout_t		*auxv;		/* auxv_t */
	const sl_fltset_layout_t	*fltset;	/* fltset_t */
	const sl_lwpsinfo_layout_t	*lwpsinfo;	/* lwpsinfo_t */
	const sl_lwpstatus_layout_t	*lwpstatus;	/* lwpstatus_t */
	const sl_prcred_layout_t	*prcred;	/* prcred_t */
	const sl_priv_impl_info_layout_t *priv_impl_info; /* priv_impl_info_t */
	const sl_prpriv_layout_t	*prpriv;	/* prpriv_t */
	const sl_psinfo_layout_t	*psinfo;	/* psinfo_t */
	const sl_pstatus_layout_t	*pstatus;	/* pstatus_t */
	const sl_prgregset_layout_t	*prgregset;	/* prgregset_t */
	const sl_prpsinfo_layout_t	*prpsinfo;	/* prpsinfo_t */
	const sl_prstatus_layout_t	*prstatus;	/* prstatus_t */
	const sl_sigaction_layout_t	*sigaction;	/* struct sigaction */
	const sl_siginfo_layout_t	*siginfo;	/* siginfo_t */
	const sl_sigset_layout_t	*sigset;	/* sigset_t */
	const sl_stack_layout_t		*stack;		/* stack_t */
	const sl_sysset_layout_t	*sysset;	/* sysset_t */
	const sl_timestruc_layout_t	*timestruc;	/* timestruc_t */
	const sl_utsname_layout_t	*utsname;	/* struct utsname */
	const sl_prfdinfo_layout_t	*prfdinfo;	/* prdinfo_t */
} sl_arch_layout_t;



extern	void		sl_extract_num_field(const char *data, int do_swap,
			    const sl_field_t *fdesc, sl_data_t *field_data);
extern	Word		sl_extract_as_word(const char *data, int do_swap,
			    const sl_field_t *fdesc);
extern	Lword		sl_extract_as_lword(const char *data, int do_swap,
			    const sl_field_t *fdesc);
extern	Sword		sl_extract_as_sword(const char *data, int do_swap,
			    const sl_field_t *fdesc);
extern	const char	*sl_fmt_num(const char *data, int do_swap,
			    const sl_field_t *fdesc, sl_fmt_num_t fmt_type,
			    sl_fmtbuf_t buf);


extern	const sl_arch_layout_t	*sl_mach(Half);
extern	const sl_arch_layout_t	*struct_layout_i386(void);
extern	const sl_arch_layout_t	*struct_layout_amd64(void);
extern	const sl_arch_layout_t	*struct_layout_sparc(void);
extern	const sl_arch_layout_t	*struct_layout_sparcv9(void);



#ifdef	__cplusplus
}
#endif

#endif	/* _STRUCT_LAYOUT_H */