root/usr/src/cmd/sgs/elfdump/common/struct_layout.h
/*
 * 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.
 * Copyright 2018 Joyent, Inc.
 * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
 */

#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


/*
 * illumos 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 prfdinfo_core_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;

typedef struct {
        sl_field_t              sizeof_struct;
        sl_field_t              pr_version;
        sl_field_t              pr_effective;
        sl_field_t              pr_inherit;
        sl_field_t              pr_lower;
        sl_field_t              pr_upper;
} sl_prsecflags_layout_t;

typedef struct {
        sl_field_t              sizeof_struct;
        sl_field_t              pr_lwpid;
        sl_field_t              pr_lwpname;
} sl_prlwpname_layout_t;

typedef struct {
        sl_field_t              sizeof_struct;
        sl_field_t              pru_version;
        sl_field_t              pru_flags;
        sl_field_t              pru_data;
} sl_prupanic_layout_t;

typedef struct {
        sl_field_t              sizeof_struct;
        sl_field_t              prcwd_fsid;
        sl_field_t              prcwd_fsname;
        sl_field_t              prcwd_mntpt;
        sl_field_t              prcwd_mntspec;
        sl_field_t              prcwd_cwd;
} sl_prcwd_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 */
        const sl_prsecflags_layout_t    *prsecflags;    /* prsecflags_t */
        const sl_prlwpname_layout_t     *prlwpname;     /* prlwpname_t */
        const sl_prupanic_layout_t      *prupanic;      /* prupanic_t */
        const sl_prcwd_layout_t         *prcwd;         /* prcwd_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 */