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