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