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_lwp;
 212 } sl_pstatus_layout_t;
 213 
 214 /*
 215  * Layout description of prstatus_t, from <sys/old_procfs.h>.
 216  */
 217 typedef struct {
 218         sl_field_t              sizeof_struct;
 219         sl_field_t              pr_flags;
 220         sl_field_t              pr_why;
 221         sl_field_t              pr_what;
 222         sl_field_t              pr_info;
 223         sl_field_t              pr_cursig;
 224         sl_field_t              pr_nlwp;
 225         sl_field_t              pr_sigpend;
 226         sl_field_t              pr_sighold;
 227         sl_field_t              pr_altstack;
 228         sl_field_t              pr_action;
 229         sl_field_t              pr_pid;
 230         sl_field_t              pr_ppid;
 231         sl_field_t              pr_pgrp;
 232         sl_field_t              pr_sid;
 233         sl_field_t              pr_utime;
 234         sl_field_t              pr_stime;
 235         sl_field_t              pr_cutime;
 236         sl_field_t              pr_cstime;
 237         sl_field_t              pr_clname;
 238         sl_field_t              pr_syscall;
 239         sl_field_t              pr_nsysarg;
 240         sl_field_t              pr_sysarg;
 241         sl_field_t              pr_who;
 242         sl_field_t              pr_lwppend;
 243         sl_field_t              pr_oldcontext;
 244         sl_field_t              pr_brkbase;
 245         sl_field_t              pr_brksize;
 246         sl_field_t              pr_stkbase;
 247         sl_field_t              pr_stksize;
 248         sl_field_t              pr_processor;
 249         sl_field_t              pr_bind;
 250         sl_field_t              pr_instr;
 251         sl_field_t              pr_reg;
 252 } sl_prstatus_layout_t;
 253 
 254 /*
 255  * Layout description of psinfo_t, from <sys/procfs.h>.
 256  */
 257 typedef struct {
 258         sl_field_t              sizeof_struct;
 259         sl_field_t              pr_flag;
 260         sl_field_t              pr_nlwp;
 261         sl_field_t              pr_pid;
 262         sl_field_t              pr_ppid;
 263         sl_field_t              pr_pgid;
 264         sl_field_t              pr_sid;
 265         sl_field_t              pr_uid;
 266         sl_field_t              pr_euid;
 267         sl_field_t              pr_gid;
 268         sl_field_t              pr_egid;
 269         sl_field_t              pr_addr;
 270         sl_field_t              pr_size;
 271         sl_field_t              pr_rssize;
 272         sl_field_t              pr_ttydev;
 273         sl_field_t              pr_pctcpu;
 274         sl_field_t              pr_pctmem;
 275         sl_field_t              pr_start;
 276         sl_field_t              pr_time;
 277         sl_field_t              pr_ctime;
 278         sl_field_t              pr_fname;
 279         sl_field_t              pr_psargs;
 280         sl_field_t              pr_wstat;
 281         sl_field_t              pr_argc;
 282         sl_field_t              pr_argv;
 283         sl_field_t              pr_envp;
 284         sl_field_t              pr_dmodel;
 285         sl_field_t              pr_taskid;
 286         sl_field_t              pr_projid;
 287         sl_field_t              pr_nzomb;
 288         sl_field_t              pr_poolid;
 289         sl_field_t              pr_zoneid;
 290         sl_field_t              pr_contract;
 291         sl_field_t              pr_lwp;
 292 } sl_psinfo_layout_t;
 293 
 294 /*
 295  * Layout description of prpsinfo_t, from <sys/old_procfs.h>.
 296  */
 297 typedef struct {
 298         sl_field_t              sizeof_struct;
 299         sl_field_t              pr_state;
 300         sl_field_t              pr_sname;
 301         sl_field_t              pr_zomb;
 302         sl_field_t              pr_nice;
 303         sl_field_t              pr_flag;
 304         sl_field_t              pr_uid;
 305         sl_field_t              pr_gid;
 306         sl_field_t              pr_pid;
 307         sl_field_t              pr_ppid;
 308         sl_field_t              pr_pgrp;
 309         sl_field_t              pr_sid;
 310         sl_field_t              pr_addr;
 311         sl_field_t              pr_size;
 312         sl_field_t              pr_rssize;
 313         sl_field_t              pr_wchan;
 314         sl_field_t              pr_start;
 315         sl_field_t              pr_time;
 316         sl_field_t              pr_pri;
 317         sl_field_t              pr_oldpri;
 318         sl_field_t              pr_cpu;
 319         sl_field_t              pr_ottydev;
 320         sl_field_t              pr_lttydev;
 321         sl_field_t              pr_clname;
 322         sl_field_t              pr_fname;
 323         sl_field_t              pr_psargs;
 324         sl_field_t              pr_syscall;
 325         sl_field_t              pr_ctime;
 326         sl_field_t              pr_bysize;
 327         sl_field_t              pr_byrssize;
 328         sl_field_t              pr_argc;
 329         sl_field_t              pr_argv;
 330         sl_field_t              pr_envp;
 331         sl_field_t              pr_wstat;
 332         sl_field_t              pr_pctcpu;
 333         sl_field_t              pr_pctmem;
 334         sl_field_t              pr_euid;
 335         sl_field_t              pr_egid;
 336         sl_field_t              pr_aslwpid;
 337         sl_field_t              pr_dmodel;
 338 } sl_prpsinfo_layout_t;
 339 
 340 /*
 341  * Layout description of lwpsinfo_t, from <sys/procfs.h>.
 342  */
 343 typedef struct {
 344         sl_field_t              sizeof_struct;
 345         sl_field_t              pr_flag;
 346         sl_field_t              pr_lwpid;
 347         sl_field_t              pr_addr;
 348         sl_field_t              pr_wchan;
 349         sl_field_t              pr_stype;
 350         sl_field_t              pr_state;
 351         sl_field_t              pr_sname;
 352         sl_field_t              pr_nice;
 353         sl_field_t              pr_syscall;
 354         sl_field_t              pr_oldpri;
 355         sl_field_t              pr_cpu;
 356         sl_field_t              pr_pri;
 357         sl_field_t              pr_pctcpu;
 358         sl_field_t              pr_start;
 359         sl_field_t              pr_time;
 360         sl_field_t              pr_clname;
 361         sl_field_t              pr_name;
 362         sl_field_t              pr_onpro;
 363         sl_field_t              pr_bindpro;
 364         sl_field_t              pr_bindpset;
 365         sl_field_t              pr_lgrp;
 366 } sl_lwpsinfo_layout_t;
 367 
 368 /*
 369  * Layout description of prcred_t, from <sys/procfs.h>.
 370  */
 371 typedef struct {
 372         sl_field_t              sizeof_struct;
 373         sl_field_t              pr_euid;
 374         sl_field_t              pr_ruid;
 375         sl_field_t              pr_suid;
 376         sl_field_t              pr_egid;
 377         sl_field_t              pr_rgid;
 378         sl_field_t              pr_sgid;
 379         sl_field_t              pr_ngroups;
 380         sl_field_t              pr_groups;
 381 } sl_prcred_layout_t;
 382 
 383 /*
 384  * Layout description of prpriv_t, from <sys/procfs.h>.
 385  */
 386 typedef struct {
 387         sl_field_t              sizeof_struct;
 388         sl_field_t              pr_nsets;
 389         sl_field_t              pr_setsize;
 390         sl_field_t              pr_infosize;
 391         sl_field_t              pr_sets;
 392 } sl_prpriv_layout_t;
 393 
 394 /*
 395  * Layout description of priv_impl_info_t, from <sys/priv.h>.
 396  */
 397 typedef struct {
 398         sl_field_t              sizeof_struct;
 399         sl_field_t              priv_headersize;
 400         sl_field_t              priv_flags;
 401         sl_field_t              priv_nsets;
 402         sl_field_t              priv_setsize;
 403         sl_field_t              priv_max;
 404         sl_field_t              priv_infosize;
 405         sl_field_t              priv_globalinfosize;
 406 } sl_priv_impl_info_layout_t;
 407 
 408 /*
 409  * Layout description of fltset_t, from <sys/fault.h>.
 410  */
 411 typedef struct {
 412         sl_field_t              sizeof_struct;
 413         sl_field_t              word;
 414 } sl_fltset_layout_t;
 415 
 416 /*
 417  * Layout description of siginfo_t, from <sys/siginfo.h>.
 418  *
 419  * siginfo_t is unusual, in that it contains a large union
 420  * full of private fields. There are macros defined to give
 421  * access to these fields via the names documented in the
 422  * siginfo manpage. We stick to the documented names
 423  * rather than try to unravel the undocumented blob. Hence,
 424  * the layout description below is a "logical" view of siginfo_t.
 425  * The fields below are not necessarily in the same order as
 426  * they appear in siginfo_t, nor are they everything that is in
 427  * that struct. They may also overlap each other, if they are
 428  * contained within of the union.
 429  *
 430  * The f_ prefixes are used to prevent our field names from
 431  * clashing with the macros defined in siginfo.h.
 432  */
 433 typedef struct {
 434         sl_field_t              sizeof_struct;
 435         sl_field_t              f_si_signo;
 436         sl_field_t              f_si_errno;
 437         sl_field_t              f_si_code;
 438         sl_field_t              f_si_value_int;
 439         sl_field_t              f_si_value_ptr;
 440         sl_field_t              f_si_pid;
 441         sl_field_t              f_si_uid;
 442         sl_field_t              f_si_ctid;
 443         sl_field_t              f_si_zoneid;
 444         sl_field_t              f_si_entity;
 445         sl_field_t              f_si_addr;
 446         sl_field_t              f_si_status;
 447         sl_field_t              f_si_band;
 448 } sl_siginfo_layout_t;
 449 
 450 /*
 451  * Layout description of sigset_t, from <sys/signal.h>.
 452  */
 453 typedef struct {
 454         sl_field_t              sizeof_struct;
 455         sl_field_t              sigbits;
 456 } sl_sigset_layout_t;
 457 
 458 /*
 459  * Layout description of struct sigaction, from <sys/signal.h>.
 460  */
 461 typedef struct {
 462         sl_field_t              sizeof_struct;
 463         sl_field_t              sa_flags;
 464         sl_field_t              sa_hand;
 465         sl_field_t              sa_sigact;
 466         sl_field_t              sa_mask;
 467 } sl_sigaction_layout_t;
 468 
 469 /*
 470  * Layout description of stack_t, from <sys/signal.h>.
 471  */
 472 typedef struct {
 473         sl_field_t              sizeof_struct;
 474         sl_field_t              ss_sp;
 475         sl_field_t              ss_size;
 476         sl_field_t              ss_flags;
 477 } sl_stack_layout_t;
 478 
 479 /*
 480  * Layout description of sysset_t, from <sys/syscall.h>.
 481  */
 482 typedef struct {
 483         sl_field_t              sizeof_struct;
 484         sl_field_t              word;
 485 } sl_sysset_layout_t;
 486 
 487 /*
 488  * Layout description of timestruc_t, from <sys/time_impl.h>.
 489  */
 490 typedef struct {
 491         sl_field_t              sizeof_struct;
 492         sl_field_t              tv_sec;
 493         sl_field_t              tv_nsec;
 494 } sl_timestruc_layout_t;
 495 
 496 /*
 497  * Layout description of struct utsname, from <sys/utsname.h>.
 498  */
 499 typedef struct {
 500         sl_field_t              sizeof_struct;
 501         sl_field_t              sysname;
 502         sl_field_t              nodename;
 503         sl_field_t              release;
 504         sl_field_t              version;
 505         sl_field_t              machine;
 506 } sl_utsname_layout_t;
 507 
 508 /*
 509  * Layout description of prdinfo_t, from <sys/procfs.h>.
 510  */
 511 typedef struct {
 512         sl_field_t              sizeof_struct;
 513         sl_field_t              pr_fd;
 514         sl_field_t              pr_mode;
 515         sl_field_t              pr_uid;
 516         sl_field_t              pr_gid;
 517         sl_field_t              pr_major;
 518         sl_field_t              pr_minor;
 519         sl_field_t              pr_rmajor;
 520         sl_field_t              pr_rminor;
 521         sl_field_t              pr_ino;
 522         sl_field_t              pr_offset;
 523         sl_field_t              pr_size;
 524         sl_field_t              pr_fileflags;
 525         sl_field_t              pr_fdflags;
 526         sl_field_t              pr_path;
 527 } sl_prfdinfo_layout_t;
 528 
 529 typedef struct {
 530         sl_field_t              sizeof_struct;
 531         sl_field_t              pr_version;
 532         sl_field_t              pr_effective;
 533         sl_field_t              pr_inherit;
 534         sl_field_t              pr_lower;
 535         sl_field_t              pr_upper;
 536 } sl_prsecflags_layout_t;
 537 
 538 /*
 539  * This type collects all of the layout definitions for
 540  * a given architecture.
 541  */
 542 typedef struct {
 543         const sl_auxv_layout_t          *auxv;          /* auxv_t */
 544         const sl_fltset_layout_t        *fltset;        /* fltset_t */
 545         const sl_lwpsinfo_layout_t      *lwpsinfo;      /* lwpsinfo_t */
 546         const sl_lwpstatus_layout_t     *lwpstatus;     /* lwpstatus_t */
 547         const sl_prcred_layout_t        *prcred;        /* prcred_t */
 548         const sl_priv_impl_info_layout_t *priv_impl_info; /* priv_impl_info_t */
 549         const sl_prpriv_layout_t        *prpriv;        /* prpriv_t */
 550         const sl_psinfo_layout_t        *psinfo;        /* psinfo_t */
 551         const sl_pstatus_layout_t       *pstatus;       /* pstatus_t */
 552         const sl_prgregset_layout_t     *prgregset;     /* prgregset_t */
 553         const sl_prpsinfo_layout_t      *prpsinfo;      /* prpsinfo_t */
 554         const sl_prstatus_layout_t      *prstatus;      /* prstatus_t */
 555         const sl_sigaction_layout_t     *sigaction;     /* struct sigaction */
 556         const sl_siginfo_layout_t       *siginfo;       /* siginfo_t */
 557         const sl_sigset_layout_t        *sigset;        /* sigset_t */
 558         const sl_stack_layout_t         *stack;         /* stack_t */
 559         const sl_sysset_layout_t        *sysset;        /* sysset_t */
 560         const sl_timestruc_layout_t     *timestruc;     /* timestruc_t */
 561         const sl_utsname_layout_t       *utsname;       /* struct utsname */
 562         const sl_prfdinfo_layout_t      *prfdinfo;      /* prdinfo_t */
 563         const sl_prsecflags_layout_t    *prsecflags;    /* prsecflags_t */
 564 } sl_arch_layout_t;
 565 
 566 
 567 
 568 extern  void            sl_extract_num_field(const char *data, int do_swap,
 569                             const sl_field_t *fdesc, sl_data_t *field_data);
 570 extern  Word            sl_extract_as_word(const char *data, int do_swap,
 571                             const sl_field_t *fdesc);
 572 extern  Lword           sl_extract_as_lword(const char *data, int do_swap,
 573                             const sl_field_t *fdesc);
 574 extern  Sword           sl_extract_as_sword(const char *data, int do_swap,
 575                             const sl_field_t *fdesc);
 576 extern  const char      *sl_fmt_num(const char *data, int do_swap,
 577                             const sl_field_t *fdesc, sl_fmt_num_t fmt_type,
 578                             sl_fmtbuf_t buf);
 579 
 580 
 581 extern  const sl_arch_layout_t  *sl_mach(Half);
 582 extern  const sl_arch_layout_t  *struct_layout_i386(void);
 583 extern  const sl_arch_layout_t  *struct_layout_amd64(void);
 584 extern  const sl_arch_layout_t  *struct_layout_sparc(void);
 585 extern  const sl_arch_layout_t  *struct_layout_sparcv9(void);
 586 
 587 
 588 
 589 #ifdef  __cplusplus
 590 }
 591 #endif
 592 
 593 #endif  /* _STRUCT_LAYOUT_H */