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  * Copyright 2018 Joyent, Inc.
  30  */
  31 
  32 #ifndef _STRUCT_LAYOUT_H
  33 #define _STRUCT_LAYOUT_H
  34 
  35 #include        <conv.h>
  36 #include        <_machelf.h>
  37 
  38 /*
  39  * Local include file for elfdump, used to define structure layout
  40  * definitions for various system structs.
  41  */
  42 
  43 #ifdef  __cplusplus
  44 extern "C" {
  45 #endif
  46 
  47 
  48 /*
  49  * Solaris defines system structs that elfdump needs to display
  50  * data from. We have a variety of hurdles to overcome in doing this:
  51  *
  52  *      - The size of system types can differ between ELFCLASS32 and
  53  *              ELFCLASS64.
  54  *      - Stucture layout can differ between architectures, so a given
  55  *              field can have a different struct offset than is native
  56  *              for the system running elfdump. Depending on the struct
  57  *              in question, the layout for one platform may be impossible
  58  *              to achieve on another.
  59  *      - The byte order of the core object can differ from that
  60  *              of the system running elfdump.
  61  *
  62  * The result is that in the fully general case, each architecture
  63  * can have a slightly different definition of these structures.
  64  * The usual approach of assigning a pointer of the desired structure
  65  * type and then accessing fields through that pointer cannot be used
  66  * here. That approach can only be used to access structures with the
  67  * native layout of the elfdump host. We want any instance of elfdump
  68  * to be able to examine a Solaris object for any supported architecture,
  69  * so we need a more flexible approach.
  70  *
  71  * The solution to this problem lies in the fact that the binary
  72  * layout of these public types cannot be changed, except in backward
  73  * compatible ways. They are written to core files or published in
  74  * other ways such that we can't make changes that would make it
  75  * impossible to analyze old files. This means that we can build
  76  * table of offsets and sizes for each field of each struct, on
  77  * a per-archecture basis. These tables can be used to access the
  78  * struct fields directly from the note desc data, and elfdump
  79  * on any host can read the data from any other host.
  80  *
  81  * When reading these tables, it can be very helpful to examine
  82  * the struct definition at the same time.
  83  */
  84 
  85 /*
  86  * sl_field_t is used to describe a struct field
  87  */
  88 typedef struct {
  89         ushort_t        slf_offset;     /* Offset from start of struct */
  90         ushort_t        slf_eltlen;     /* Size of datum, in bytes */
  91         ushort_t        slf_nelts;      /* 0 for scalar, # of els for array */
  92         uchar_t         slf_sign;       /* True (1) if signed quantity */
  93 } sl_field_t;
  94 
  95 /*
  96  * This type is used to extract and manipulate data described by
  97  * sl_field_t. We rely on the C guarantee that all the fields in
  98  * a union have offset 0.
  99  */
 100 typedef union {
 101         char            sld_i8;
 102         uchar_t         sld_ui8;
 103         short           sld_i16;
 104         ushort_t        sld_ui16;
 105         int32_t         sld_i32;
 106         uint32_t        sld_ui32;
 107         int64_t         sld_i64;
 108         uint64_t        sld_ui64;
 109 } sl_data_t;
 110 
 111 /*
 112  * Buffer large enough to format any integral value in a field
 113  */
 114 typedef char sl_fmtbuf_t[CONV_INV_BUFSIZE * 2];
 115 
 116 /*
 117  * Types of formatting done by fmt_num()
 118  */
 119 typedef enum {
 120         SL_FMT_NUM_DEC = 0,     /* Decimal integer */
 121         SL_FMT_NUM_HEX = 1,     /* Hex integer, with natural width */
 122         SL_FMT_NUM_ZHEX = 2,    /* Hex integer, fixed width with zero fill  */
 123 } sl_fmt_num_t;
 124 
 125 
 126 
 127 
 128 /*
 129  * Layout description of auxv_t, from <sys/auxv.h>.
 130  */
 131 typedef struct {
 132         sl_field_t              sizeof_struct;
 133         sl_field_t              a_type;
 134         sl_field_t              a_val;
 135         sl_field_t              a_ptr;
 136         sl_field_t              a_fcn;
 137 } sl_auxv_layout_t;
 138 
 139 /*
 140  * Layout description of prgregset_t, an architecture specific
 141  * array of general register c values
 142  */
 143 typedef struct {
 144         sl_field_t              sizeof_struct;
 145         sl_field_t              elt0;
 146 } sl_prgregset_layout_t;
 147 
 148 /*
 149  * Layout description of lwpstatus_t, from <sys/procfs.h>.
 150  */
 151 typedef struct {
 152         sl_field_t              sizeof_struct;
 153         sl_field_t              pr_flags;
 154         sl_field_t              pr_lwpid;
 155         sl_field_t              pr_why;
 156         sl_field_t              pr_what;
 157         sl_field_t              pr_cursig;
 158         sl_field_t              pr_info;
 159         sl_field_t              pr_lwppend;
 160         sl_field_t              pr_lwphold;
 161         sl_field_t              pr_action;
 162         sl_field_t              pr_altstack;
 163         sl_field_t              pr_oldcontext;
 164         sl_field_t              pr_syscall;
 165         sl_field_t              pr_nsysarg;
 166         sl_field_t              pr_errno;
 167         sl_field_t              pr_sysarg;
 168         sl_field_t              pr_rval1;
 169         sl_field_t              pr_rval2;
 170         sl_field_t              pr_clname;
 171         sl_field_t              pr_tstamp;
 172         sl_field_t              pr_utime;
 173         sl_field_t              pr_stime;
 174         sl_field_t              pr_errpriv;
 175         sl_field_t              pr_ustack;
 176         sl_field_t              pr_instr;
 177         sl_field_t              pr_reg;
 178         sl_field_t              pr_fpreg;
 179 } sl_lwpstatus_layout_t;
 180 
 181 /*
 182  * Layout description of pstatus_t, from <sys/procfs.h>.
 183  */
 184 typedef struct {
 185         sl_field_t              sizeof_struct;
 186         sl_field_t              pr_flags;
 187         sl_field_t              pr_nlwp;
 188         sl_field_t              pr_pid;
 189         sl_field_t              pr_ppid;
 190         sl_field_t              pr_pgid;
 191         sl_field_t              pr_sid;
 192         sl_field_t              pr_aslwpid;
 193         sl_field_t              pr_agentid;
 194         sl_field_t              pr_sigpend;
 195         sl_field_t              pr_brkbase;
 196         sl_field_t              pr_brksize;
 197         sl_field_t              pr_stkbase;
 198         sl_field_t              pr_stksize;
 199         sl_field_t              pr_utime;
 200         sl_field_t              pr_stime;
 201         sl_field_t              pr_cutime;
 202         sl_field_t              pr_cstime;
 203         sl_field_t              pr_sigtrace;
 204         sl_field_t              pr_flttrace;
 205         sl_field_t              pr_sysentry;
 206         sl_field_t              pr_sysexit;
 207         sl_field_t              pr_dmodel;
 208         sl_field_t              pr_taskid;
 209         sl_field_t              pr_projid;
 210         sl_field_t              pr_nzomb;
 211         sl_field_t              pr_zoneid;
 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              pr_version;
 533         sl_field_t              pr_effective;
 534         sl_field_t              pr_inherit;
 535         sl_field_t              pr_lower;
 536         sl_field_t              pr_upper;
 537 } sl_prsecflags_layout_t;
 538 
 539 typedef struct {
 540         sl_field_t              sizeof_struct;
 541         sl_field_t              pr_lwpid;
 542         sl_field_t              pr_lwpname;
 543 } sl_prlwpname_layout_t;
 544 
 545 /*
 546  * This type collects all of the layout definitions for
 547  * a given architecture.
 548  */
 549 typedef struct {
 550         const sl_auxv_layout_t          *auxv;          /* auxv_t */
 551         const sl_fltset_layout_t        *fltset;        /* fltset_t */
 552         const sl_lwpsinfo_layout_t      *lwpsinfo;      /* lwpsinfo_t */
 553         const sl_lwpstatus_layout_t     *lwpstatus;     /* lwpstatus_t */
 554         const sl_prcred_layout_t        *prcred;        /* prcred_t */
 555         const sl_priv_impl_info_layout_t *priv_impl_info; /* priv_impl_info_t */
 556         const sl_prpriv_layout_t        *prpriv;        /* prpriv_t */
 557         const sl_psinfo_layout_t        *psinfo;        /* psinfo_t */
 558         const sl_pstatus_layout_t       *pstatus;       /* pstatus_t */
 559         const sl_prgregset_layout_t     *prgregset;     /* prgregset_t */
 560         const sl_prpsinfo_layout_t      *prpsinfo;      /* prpsinfo_t */
 561         const sl_prstatus_layout_t      *prstatus;      /* prstatus_t */
 562         const sl_sigaction_layout_t     *sigaction;     /* struct sigaction */
 563         const sl_siginfo_layout_t       *siginfo;       /* siginfo_t */
 564         const sl_sigset_layout_t        *sigset;        /* sigset_t */
 565         const sl_stack_layout_t         *stack;         /* stack_t */
 566         const sl_sysset_layout_t        *sysset;        /* sysset_t */
 567         const sl_timestruc_layout_t     *timestruc;     /* timestruc_t */
 568         const sl_utsname_layout_t       *utsname;       /* struct utsname */
 569         const sl_prfdinfo_layout_t      *prfdinfo;      /* prdinfo_t */
 570         const sl_prsecflags_layout_t    *prsecflags;    /* prsecflags_t */
 571         const sl_prlwpname_layout_t     *prlwpname;     /* prlwpname_t */
 572 } sl_arch_layout_t;
 573 
 574 
 575 
 576 extern  void            sl_extract_num_field(const char *data, int do_swap,
 577                             const sl_field_t *fdesc, sl_data_t *field_data);
 578 extern  Word            sl_extract_as_word(const char *data, int do_swap,
 579                             const sl_field_t *fdesc);
 580 extern  Lword           sl_extract_as_lword(const char *data, int do_swap,
 581                             const sl_field_t *fdesc);
 582 extern  Sword           sl_extract_as_sword(const char *data, int do_swap,
 583                             const sl_field_t *fdesc);
 584 extern  const char      *sl_fmt_num(const char *data, int do_swap,
 585                             const sl_field_t *fdesc, sl_fmt_num_t fmt_type,
 586                             sl_fmtbuf_t buf);
 587 
 588 
 589 extern  const sl_arch_layout_t  *sl_mach(Half);
 590 extern  const sl_arch_layout_t  *struct_layout_i386(void);
 591 extern  const sl_arch_layout_t  *struct_layout_amd64(void);
 592 extern  const sl_arch_layout_t  *struct_layout_sparc(void);
 593 extern  const sl_arch_layout_t  *struct_layout_sparcv9(void);
 594 
 595 
 596 
 597 #ifdef  __cplusplus
 598 }
 599 #endif
 600 
 601 #endif  /* _STRUCT_LAYOUT_H */