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