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 * Copyright 2015 Nexenta Systems, Inc. All rights reserved. 27 * Copyright 2018 Joyent, Inc. 28 * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. 29 */ 30 31 /* 32 * This program is used to generate the contents of the 33 * struct_layout_XXX.c files that contain per-architecture 34 * structure layout information. 35 * 36 * Although not part of elfdump, it is built by the makefile 37 * along with it. Note, the Makefile only builds versions that 38 * are natively supported and therefore you must manually run 39 * this for other architectures. 40 * 41 * To use it: 42 * 43 * 1) Run it, capturing the output in a file. 44 * 2) If this is a replacement for an existing file, 45 * diff the new and old copies to ensure only 46 * the changes you expected are present. 47 * 3) Put the new file in the common directory under the name 48 * struct_layout_XXX.c, where XXX is the name of 49 * the architecture (i386, amd64, sparc, sparcv9, etc). 50 * 2) Add any necessary header and copyright comments. 51 * 3) If this is a new architecture: 52 * - Add an extern statement for struct_layout_XXX() 53 * to struct_layout.h 54 * - Add a case for it to the function sl_struct_layout() 55 * in struct_layout.c. 56 */ 57 58 #include <string.h> 59 #include <stdio.h> 60 #include <stdlib.h> 61 #include <ctype.h> 62 #include <err.h> 63 #include <sys/types.h> 64 #include <libctf.h> 65 66 /* 67 * This extracts CTF information from a temporary object file. 68 * 69 * START and END bracket a struct layout definition. They issue 70 * the typedef boilerplate, and the standard first element (sizeof) 71 * which captures the overall size of the structure. 72 * 73 * SCALAR_FIELD is for scalar struct fields 74 * 75 * ARRAY_FIELD is for array struct fields 76 * 77 * ARRAY_TYPE is for plain (non-struct) array types 78 */ 79 #define START(_name, _type) \ 80 do_start(#_name, #_type) 81 #define END (void) \ 82 do_end() 83 #define SCALAR_FIELD(_type, _field, _sign) \ 84 do_scalar_field(#_type, #_field, _sign, NULL) 85 #define SCALAR_FIELD4(_type, _field, _sign, _rtype) \ 86 do_scalar_field(#_type, #_field, _sign, _rtype) 87 #define ARRAY_FIELD(_type, _field, _sign) \ 88 do_array_field(#_type, #_field, _sign, NULL) 89 #define ARRAY_TYPE(_type, _sign) \ 90 do_array_type(#_type, "elt0", _sign) 91 92 static void do_start(char *_name, char *_type); 93 static void do_end(void); 94 static void do_start_name(char *name); 95 static void do_start_sizeof(char *_type, char *realtype); 96 static void do_scalar_field(char *_type, char *_field, 97 int _sign, char *dotfield); 98 static void do_array_field(char *_type, char *_field, 99 int _sign, char *dotfield); 100 static void do_array_type(char *_type, char *_field, int _sign); 101 102 static void get_ctf_file(char *fname); 103 static int get_field_info(char *tname, char *fname, char *dotname, 104 int *offp, int *sizep); 105 106 static ctf_file_t *ctf; 107 static char *objfile; 108 static char *machname; 109 110 /* auxv_t, <sys/auxv.h> */ 111 static void 112 gen_auxv(void) 113 { 114 START(auxv, auxv_t); 115 116 SCALAR_FIELD(auxv_t, a_type, 1); 117 SCALAR_FIELD(auxv_t, a_un.a_val, 1); 118 SCALAR_FIELD(auxv_t, a_un.a_ptr, 0); 119 SCALAR_FIELD(auxv_t, a_un.a_fcn, 0); 120 121 END; 122 } 123 124 125 /* prgregset_t, <sys/prgregset.h> */ 126 static void 127 gen_prgregset(void) 128 { 129 START(prgregset, prgregset_t); 130 131 ARRAY_TYPE(prgregset_t, 0); 132 133 END; 134 } 135 136 137 /* lwpstatus_t, <sys/procfs.h> */ 138 static void 139 gen_lwpstatus(void) 140 { 141 START(lwpstatus, lwpstatus_t); 142 143 SCALAR_FIELD(lwpstatus_t, pr_flags, 0); 144 SCALAR_FIELD(lwpstatus_t, pr_lwpid, 0); 145 SCALAR_FIELD(lwpstatus_t, pr_why, 0); 146 SCALAR_FIELD(lwpstatus_t, pr_what, 0); 147 SCALAR_FIELD(lwpstatus_t, pr_cursig, 0); 148 SCALAR_FIELD(lwpstatus_t, pr_info, 0); 149 SCALAR_FIELD(lwpstatus_t, pr_lwppend, 0); 150 SCALAR_FIELD(lwpstatus_t, pr_lwphold, 0); 151 SCALAR_FIELD(lwpstatus_t, pr_action, 0); 152 SCALAR_FIELD(lwpstatus_t, pr_altstack, 0); 153 SCALAR_FIELD(lwpstatus_t, pr_oldcontext, 0); 154 SCALAR_FIELD(lwpstatus_t, pr_syscall, 0); 155 SCALAR_FIELD(lwpstatus_t, pr_nsysarg, 0); 156 SCALAR_FIELD(lwpstatus_t, pr_errno, 0); 157 ARRAY_FIELD(lwpstatus_t, pr_sysarg, 0); 158 SCALAR_FIELD(lwpstatus_t, pr_rval1, 0); 159 SCALAR_FIELD(lwpstatus_t, pr_rval2, 0); 160 ARRAY_FIELD(lwpstatus_t, pr_clname, 0); 161 SCALAR_FIELD(lwpstatus_t, pr_tstamp, 0); 162 SCALAR_FIELD(lwpstatus_t, pr_utime, 0); 163 SCALAR_FIELD(lwpstatus_t, pr_stime, 0); 164 SCALAR_FIELD(lwpstatus_t, pr_errpriv, 0); 165 SCALAR_FIELD(lwpstatus_t, pr_ustack, 0); 166 SCALAR_FIELD(lwpstatus_t, pr_instr, 0); 167 SCALAR_FIELD(lwpstatus_t, pr_reg, 0); 168 SCALAR_FIELD(lwpstatus_t, pr_fpreg, 0); 169 170 END; 171 } 172 173 174 /* pstatus_t, <sys/procfs.h> */ 175 static void 176 gen_pstatus(void) 177 { 178 START(pstatus, pstatus_t); 179 180 SCALAR_FIELD(pstatus_t, pr_flags, 1); 181 SCALAR_FIELD(pstatus_t, pr_nlwp, 1); 182 SCALAR_FIELD(pstatus_t, pr_pid, 0); 183 SCALAR_FIELD(pstatus_t, pr_ppid, 0); 184 SCALAR_FIELD(pstatus_t, pr_pgid, 0); 185 SCALAR_FIELD(pstatus_t, pr_sid, 0); 186 SCALAR_FIELD(pstatus_t, pr_aslwpid, 1); 187 SCALAR_FIELD(pstatus_t, pr_agentid, 1); 188 SCALAR_FIELD(pstatus_t, pr_sigpend, 0); 189 SCALAR_FIELD(pstatus_t, pr_brkbase, 0); 190 SCALAR_FIELD(pstatus_t, pr_brksize, 0); 191 SCALAR_FIELD(pstatus_t, pr_stkbase, 0); 192 SCALAR_FIELD(pstatus_t, pr_stksize, 0); 193 SCALAR_FIELD(pstatus_t, pr_utime, 0); 194 SCALAR_FIELD(pstatus_t, pr_stime, 0); 195 SCALAR_FIELD(pstatus_t, pr_cutime, 0); 196 SCALAR_FIELD(pstatus_t, pr_cstime, 0); 197 SCALAR_FIELD(pstatus_t, pr_sigtrace, 0); 198 SCALAR_FIELD(pstatus_t, pr_flttrace, 0); 199 SCALAR_FIELD(pstatus_t, pr_sysentry, 0); 200 SCALAR_FIELD(pstatus_t, pr_sysexit, 0); 201 SCALAR_FIELD(pstatus_t, pr_dmodel, 0); 202 SCALAR_FIELD(pstatus_t, pr_taskid, 1); 203 SCALAR_FIELD(pstatus_t, pr_projid, 1); 204 SCALAR_FIELD(pstatus_t, pr_nzomb, 1); 205 SCALAR_FIELD(pstatus_t, pr_zoneid, 1); 206 SCALAR_FIELD(pstatus_t, pr_lwp, 0); 207 208 END; 209 } 210 211 212 /* prstatus_t, <sys/old_procfs.h> */ 213 static void 214 gen_prstatus(void) 215 { 216 START(prstatus, prstatus_t); 217 218 SCALAR_FIELD(prstatus_t, pr_flags, 1); 219 SCALAR_FIELD(prstatus_t, pr_why, 1); 220 SCALAR_FIELD(prstatus_t, pr_what, 1); 221 SCALAR_FIELD(prstatus_t, pr_info, 0); 222 SCALAR_FIELD(prstatus_t, pr_cursig, 1); 223 SCALAR_FIELD(prstatus_t, pr_nlwp, 0); 224 SCALAR_FIELD(prstatus_t, pr_sigpend, 0); 225 SCALAR_FIELD(prstatus_t, pr_sighold, 0); 226 SCALAR_FIELD(prstatus_t, pr_altstack, 0); 227 SCALAR_FIELD(prstatus_t, pr_action, 0); 228 SCALAR_FIELD(prstatus_t, pr_pid, 0); 229 SCALAR_FIELD(prstatus_t, pr_ppid, 0); 230 SCALAR_FIELD(prstatus_t, pr_pgrp, 0); 231 SCALAR_FIELD(prstatus_t, pr_sid, 0); 232 SCALAR_FIELD(prstatus_t, pr_utime, 0); 233 SCALAR_FIELD(prstatus_t, pr_stime, 0); 234 SCALAR_FIELD(prstatus_t, pr_cutime, 0); 235 SCALAR_FIELD(prstatus_t, pr_cstime, 0); 236 ARRAY_FIELD(prstatus_t, pr_clname, 0); 237 SCALAR_FIELD(prstatus_t, pr_syscall, 1); 238 SCALAR_FIELD(prstatus_t, pr_nsysarg, 1); 239 ARRAY_FIELD(prstatus_t, pr_sysarg, 1); 240 SCALAR_FIELD(prstatus_t, pr_who, 0); 241 SCALAR_FIELD(prstatus_t, pr_lwppend, 0); 242 SCALAR_FIELD(prstatus_t, pr_oldcontext, 0); 243 SCALAR_FIELD(prstatus_t, pr_brkbase, 0); 244 SCALAR_FIELD(prstatus_t, pr_brksize, 0); 245 SCALAR_FIELD(prstatus_t, pr_stkbase, 0); 246 SCALAR_FIELD(prstatus_t, pr_stksize, 0); 247 SCALAR_FIELD(prstatus_t, pr_processor, 1); 248 SCALAR_FIELD(prstatus_t, pr_bind, 1); 249 SCALAR_FIELD(prstatus_t, pr_instr, 1); 250 SCALAR_FIELD(prstatus_t, pr_reg, 0); 251 252 END; 253 } 254 255 256 /* psinfo_t, <sys/procfs.h> */ 257 static void 258 gen_psinfo(void) 259 { 260 START(psinfo, psinfo_t); 261 262 SCALAR_FIELD(psinfo_t, pr_flag, 1); 263 SCALAR_FIELD(psinfo_t, pr_nlwp, 1); 264 SCALAR_FIELD(psinfo_t, pr_pid, 0); 265 SCALAR_FIELD(psinfo_t, pr_ppid, 0); 266 SCALAR_FIELD(psinfo_t, pr_pgid, 0); 267 SCALAR_FIELD(psinfo_t, pr_sid, 0); 268 SCALAR_FIELD(psinfo_t, pr_uid, 0); 269 SCALAR_FIELD(psinfo_t, pr_euid, 0); 270 SCALAR_FIELD(psinfo_t, pr_gid, 0); 271 SCALAR_FIELD(psinfo_t, pr_egid, 0); 272 SCALAR_FIELD(psinfo_t, pr_addr, 0); 273 SCALAR_FIELD(psinfo_t, pr_size, 0); 274 SCALAR_FIELD(psinfo_t, pr_rssize, 0); 275 SCALAR_FIELD(psinfo_t, pr_ttydev, 0); 276 SCALAR_FIELD(psinfo_t, pr_pctcpu, 0); 277 SCALAR_FIELD(psinfo_t, pr_pctmem, 0); 278 SCALAR_FIELD(psinfo_t, pr_start, 0); 279 SCALAR_FIELD(psinfo_t, pr_time, 0); 280 SCALAR_FIELD(psinfo_t, pr_ctime, 0); 281 ARRAY_FIELD(psinfo_t, pr_fname, 0); 282 ARRAY_FIELD(psinfo_t, pr_psargs, 0); 283 SCALAR_FIELD(psinfo_t, pr_wstat, 1); 284 SCALAR_FIELD(psinfo_t, pr_argc, 1); 285 SCALAR_FIELD(psinfo_t, pr_argv, 0); 286 SCALAR_FIELD(psinfo_t, pr_envp, 0); 287 SCALAR_FIELD(psinfo_t, pr_dmodel, 0); 288 SCALAR_FIELD(psinfo_t, pr_taskid, 0); 289 SCALAR_FIELD(psinfo_t, pr_projid, 0); 290 SCALAR_FIELD(psinfo_t, pr_nzomb, 1); 291 SCALAR_FIELD(psinfo_t, pr_poolid, 0); 292 SCALAR_FIELD(psinfo_t, pr_zoneid, 0); 293 SCALAR_FIELD(psinfo_t, pr_contract, 0); 294 SCALAR_FIELD(psinfo_t, pr_lwp, 0); 295 296 END; 297 } 298 299 /* prpsinfo_t, <sys/old_procfs.h> */ 300 static void 301 gen_prpsinfo(void) 302 { 303 START(prpsinfo, prpsinfo_t); 304 305 SCALAR_FIELD(prpsinfo_t, pr_state, 0); 306 SCALAR_FIELD(prpsinfo_t, pr_sname, 0); 307 SCALAR_FIELD(prpsinfo_t, pr_zomb, 0); 308 SCALAR_FIELD(prpsinfo_t, pr_nice, 0); 309 SCALAR_FIELD(prpsinfo_t, pr_flag, 0); 310 SCALAR_FIELD(prpsinfo_t, pr_uid, 0); 311 SCALAR_FIELD(prpsinfo_t, pr_gid, 0); 312 SCALAR_FIELD(prpsinfo_t, pr_pid, 0); 313 SCALAR_FIELD(prpsinfo_t, pr_ppid, 0); 314 SCALAR_FIELD(prpsinfo_t, pr_pgrp, 0); 315 SCALAR_FIELD(prpsinfo_t, pr_sid, 0); 316 SCALAR_FIELD(prpsinfo_t, pr_addr, 0); 317 SCALAR_FIELD(prpsinfo_t, pr_size, 0); 318 SCALAR_FIELD(prpsinfo_t, pr_rssize, 0); 319 SCALAR_FIELD(prpsinfo_t, pr_wchan, 0); 320 SCALAR_FIELD(prpsinfo_t, pr_start, 0); 321 SCALAR_FIELD(prpsinfo_t, pr_time, 0); 322 SCALAR_FIELD(prpsinfo_t, pr_pri, 1); 323 SCALAR_FIELD(prpsinfo_t, pr_oldpri, 0); 324 SCALAR_FIELD(prpsinfo_t, pr_cpu, 0); 325 SCALAR_FIELD(prpsinfo_t, pr_ottydev, 0); 326 SCALAR_FIELD(prpsinfo_t, pr_lttydev, 0); 327 ARRAY_FIELD(prpsinfo_t, pr_clname, 0); 328 ARRAY_FIELD(prpsinfo_t, pr_fname, 0); 329 ARRAY_FIELD(prpsinfo_t, pr_psargs, 0); 330 SCALAR_FIELD(prpsinfo_t, pr_syscall, 1); 331 SCALAR_FIELD(prpsinfo_t, pr_ctime, 0); 332 SCALAR_FIELD(prpsinfo_t, pr_bysize, 0); 333 SCALAR_FIELD(prpsinfo_t, pr_byrssize, 0); 334 SCALAR_FIELD(prpsinfo_t, pr_argc, 1); 335 SCALAR_FIELD(prpsinfo_t, pr_argv, 0); 336 SCALAR_FIELD(prpsinfo_t, pr_envp, 0); 337 SCALAR_FIELD(prpsinfo_t, pr_wstat, 1); 338 SCALAR_FIELD(prpsinfo_t, pr_pctcpu, 0); 339 SCALAR_FIELD(prpsinfo_t, pr_pctmem, 0); 340 SCALAR_FIELD(prpsinfo_t, pr_euid, 0); 341 SCALAR_FIELD(prpsinfo_t, pr_egid, 0); 342 SCALAR_FIELD(prpsinfo_t, pr_aslwpid, 0); 343 SCALAR_FIELD(prpsinfo_t, pr_dmodel, 0); 344 345 END; 346 } 347 348 /* lwpsinfo_t, <sys/procfs.h> */ 349 static void 350 gen_lwpsinfo(void) 351 { 352 START(lwpsinfo, lwpsinfo_t); 353 354 SCALAR_FIELD(lwpsinfo_t, pr_flag, 1); 355 SCALAR_FIELD(lwpsinfo_t, pr_lwpid, 0); 356 SCALAR_FIELD(lwpsinfo_t, pr_addr, 0); 357 SCALAR_FIELD(lwpsinfo_t, pr_wchan, 0); 358 SCALAR_FIELD(lwpsinfo_t, pr_stype, 0); 359 SCALAR_FIELD(lwpsinfo_t, pr_state, 0); 360 SCALAR_FIELD(lwpsinfo_t, pr_sname, 0); 361 SCALAR_FIELD(lwpsinfo_t, pr_nice, 0); 362 SCALAR_FIELD(lwpsinfo_t, pr_syscall, 0); 363 SCALAR_FIELD(lwpsinfo_t, pr_oldpri, 0); 364 SCALAR_FIELD(lwpsinfo_t, pr_cpu, 0); 365 SCALAR_FIELD(lwpsinfo_t, pr_pri, 1); 366 SCALAR_FIELD(lwpsinfo_t, pr_pctcpu, 0); 367 SCALAR_FIELD(lwpsinfo_t, pr_start, 0); 368 SCALAR_FIELD(lwpsinfo_t, pr_time, 0); 369 ARRAY_FIELD(lwpsinfo_t, pr_clname, 0); 370 ARRAY_FIELD(lwpsinfo_t, pr_name, 0); 371 SCALAR_FIELD(lwpsinfo_t, pr_onpro, 1); 372 SCALAR_FIELD(lwpsinfo_t, pr_bindpro, 1); 373 SCALAR_FIELD(lwpsinfo_t, pr_bindpset, 1); 374 SCALAR_FIELD(lwpsinfo_t, pr_lgrp, 1); 375 376 END; 377 } 378 379 /* prcred_t, <sys/procfs.h> */ 380 static void 381 gen_prcred(void) 382 { 383 START(prcred, prcred_t); 384 385 SCALAR_FIELD(prcred_t, pr_euid, 0); 386 SCALAR_FIELD(prcred_t, pr_ruid, 0); 387 SCALAR_FIELD(prcred_t, pr_suid, 0); 388 SCALAR_FIELD(prcred_t, pr_egid, 0); 389 SCALAR_FIELD(prcred_t, pr_rgid, 0); 390 SCALAR_FIELD(prcred_t, pr_sgid, 0); 391 SCALAR_FIELD(prcred_t, pr_ngroups, 1); 392 ARRAY_FIELD(prcred_t, pr_groups, 0); 393 394 END; 395 } 396 397 /* prpriv_t, <sys/procfs.h> */ 398 static void 399 gen_prpriv(void) 400 { 401 START(prpriv, prpriv_t); 402 403 SCALAR_FIELD(prpriv_t, pr_nsets, 0); 404 SCALAR_FIELD(prpriv_t, pr_setsize, 0); 405 SCALAR_FIELD(prpriv_t, pr_infosize, 0); 406 ARRAY_FIELD(prpriv_t, pr_sets, 0); 407 408 END; 409 } 410 411 412 /* priv_impl_info_t, <sys/priv.h> */ 413 static void 414 gen_priv_impl_info(void) 415 { 416 START(priv_impl_info, priv_impl_info_t); 417 418 SCALAR_FIELD(priv_impl_info_t, priv_headersize, 0); 419 SCALAR_FIELD(priv_impl_info_t, priv_flags, 0); 420 SCALAR_FIELD(priv_impl_info_t, priv_nsets, 0); 421 SCALAR_FIELD(priv_impl_info_t, priv_setsize, 0); 422 SCALAR_FIELD(priv_impl_info_t, priv_max, 0); 423 SCALAR_FIELD(priv_impl_info_t, priv_infosize, 0); 424 SCALAR_FIELD(priv_impl_info_t, priv_globalinfosize, 0); 425 426 END; 427 } 428 429 430 /* fltset_t, <sys/fault.h> */ 431 static void 432 gen_fltset(void) 433 { 434 START(fltset, fltset_t); 435 436 ARRAY_FIELD(fltset_t, word, 0); 437 438 END; 439 } 440 441 /* 442 * Layout description of siginfo_t, <sys/siginfo.h> 443 * 444 * Note: many siginfo_t members are #defines mapping to 445 * long dotted members of sub-structs or unions, and 446 * we need the full member spec (with dots) for those. 447 */ 448 static void 449 gen_siginfo(void) 450 { 451 START(siginfo, siginfo_t); 452 453 SCALAR_FIELD(siginfo_t, si_signo, 0); 454 SCALAR_FIELD(siginfo_t, si_errno, 0); 455 SCALAR_FIELD(siginfo_t, si_code, 1); 456 457 SCALAR_FIELD4(siginfo_t, si_value.sival_int, 0, 458 "__data.__proc.__pdata.__kill.__value.sival_int"); 459 460 SCALAR_FIELD4(siginfo_t, si_value.sival_ptr, 0, 461 "__data.__proc.__pdata.__kill.__value.sival_ptr"); 462 463 SCALAR_FIELD4(siginfo_t, si_pid, 0, 464 "__data.__proc.__pid"); 465 466 SCALAR_FIELD4(siginfo_t, si_uid, 0, 467 "__data.__proc.__pdata.__kill.__uid"); 468 469 SCALAR_FIELD4(siginfo_t, si_ctid, 0, 470 "__data.__proc.__ctid"); 471 472 SCALAR_FIELD4(siginfo_t, si_zoneid, 0, 473 "__data.__proc.__zoneid"); 474 475 SCALAR_FIELD4(siginfo_t, si_entity, 0, 476 "__data.__rctl.__entity"); 477 478 SCALAR_FIELD4(siginfo_t, si_addr, 0, 479 "__data.__fault.__addr"); 480 481 SCALAR_FIELD4(siginfo_t, si_status, 0, 482 "__data.__proc.__pdata.__cld.__status"); 483 484 SCALAR_FIELD4(siginfo_t, si_band, 0, 485 "__data.__file.__band"); 486 487 END; 488 } 489 490 /* sigset_t, <sys/signal.h> */ 491 static void 492 gen_sigset(void) 493 { 494 START(sigset, sigset_t); 495 496 ARRAY_FIELD(sigset_t, __sigbits, 0); 497 498 END; 499 } 500 501 502 /* struct sigaction, <sys/signal.h> */ 503 static void 504 gen_sigaction(void) 505 { 506 START(sigaction, struct sigaction); 507 508 SCALAR_FIELD(struct sigaction, sa_flags, 0); 509 510 SCALAR_FIELD4(struct sigaction, sa_handler, 0, 511 "_funcptr._handler"); 512 513 SCALAR_FIELD4(struct sigaction, sa_sigaction, 0, 514 "_funcptr._sigaction"); 515 516 SCALAR_FIELD(struct sigaction, sa_mask, 0); 517 518 END; 519 } 520 521 /* stack_t, <sys/signal.h> */ 522 static void 523 gen_stack(void) 524 { 525 START(stack, stack_t); 526 527 SCALAR_FIELD(stack_t, ss_sp, 0); 528 SCALAR_FIELD(stack_t, ss_size, 0); 529 SCALAR_FIELD(stack_t, ss_flags, 0); 530 531 END; 532 } 533 534 /* sysset_t, <sys/syscall.h> */ 535 static void 536 gen_sysset(void) 537 { 538 START(sysset, sysset_t); 539 540 ARRAY_FIELD(sysset_t, word, 0); 541 542 END; 543 } 544 545 /* timestruc_t, <sys/time_impl.h> */ 546 static void 547 gen_timestruc(void) 548 { 549 START(timestruc, timestruc_t); 550 551 SCALAR_FIELD(timestruc_t, tv_sec, 0); 552 SCALAR_FIELD(timestruc_t, tv_nsec, 0); 553 554 END; 555 } 556 557 /* struct utsname, <sys/utsname.h> */ 558 static void 559 gen_utsname(void) 560 { 561 START(utsname, struct utsname); 562 563 ARRAY_FIELD(struct utsname, sysname, 0); 564 ARRAY_FIELD(struct utsname, nodename, 0); 565 ARRAY_FIELD(struct utsname, release, 0); 566 ARRAY_FIELD(struct utsname, version, 0); 567 ARRAY_FIELD(struct utsname, machine, 0); 568 569 END; 570 } 571 572 static void 573 gen_prfdinfo(void) 574 { 575 START(prfdinfo, prfdinfo_core_t); 576 577 SCALAR_FIELD(prfdinfo_core_t, pr_fd, 0); 578 SCALAR_FIELD(prfdinfo_core_t, pr_mode, 0); 579 SCALAR_FIELD(prfdinfo_core_t, pr_uid, 0); 580 SCALAR_FIELD(prfdinfo_core_t, pr_gid, 0); 581 SCALAR_FIELD(prfdinfo_core_t, pr_major, 0); 582 SCALAR_FIELD(prfdinfo_core_t, pr_minor, 0); 583 SCALAR_FIELD(prfdinfo_core_t, pr_rmajor, 0); 584 SCALAR_FIELD(prfdinfo_core_t, pr_rminor, 0); 585 SCALAR_FIELD(prfdinfo_core_t, pr_ino, 0); 586 SCALAR_FIELD(prfdinfo_core_t, pr_offset, 0); 587 SCALAR_FIELD(prfdinfo_core_t, pr_size, 0); 588 SCALAR_FIELD(prfdinfo_core_t, pr_fileflags, 0); 589 SCALAR_FIELD(prfdinfo_core_t, pr_fdflags, 0); 590 ARRAY_FIELD(prfdinfo_core_t, pr_path, 0); 591 592 END; 593 } 594 595 static void 596 gen_prsecflags(void) 597 { 598 START(prsecflags, prsecflags_t); 599 SCALAR_FIELD(prsecflags_t, pr_version, 0); 600 SCALAR_FIELD(prsecflags_t, pr_effective, 0); 601 SCALAR_FIELD(prsecflags_t, pr_inherit, 0); 602 SCALAR_FIELD(prsecflags_t, pr_lower, 0); 603 SCALAR_FIELD(prsecflags_t, pr_upper, 0); 604 END; 605 } 606 607 static void 608 gen_prlwpname(void) 609 { 610 START(prlwpname, prlwpname_t); 611 SCALAR_FIELD(prlwpname_t, pr_lwpid, 0); 612 ARRAY_FIELD(prlwpname_t, pr_lwpname, 0); 613 END; 614 } 615 616 static void 617 gen_prupanic(void) 618 { 619 START(prupanic, prupanic_t); 620 SCALAR_FIELD(prupanic_t, pru_version, 0); 621 SCALAR_FIELD(prupanic_t, pru_flags, 0); 622 ARRAY_FIELD(prupanic_t, pru_data, 0); 623 END; 624 } 625 626 static void 627 gen_prcwd(void) 628 { 629 START(prcwd, prcwd_t); 630 SCALAR_FIELD(prcwd_t, prcwd_fsid, 0); 631 ARRAY_FIELD(prcwd_t, prcwd_fsname, 0); 632 ARRAY_FIELD(prcwd_t, prcwd_mntpt, 0); 633 ARRAY_FIELD(prcwd_t, prcwd_mntspec, 0); 634 ARRAY_FIELD(prcwd_t, prcwd_cwd, 0); 635 END; 636 } 637 638 /*ARGSUSED*/ 639 int 640 main(int argc, char *argv[]) 641 { 642 const char *fmt = "\t&%s_layout,\n"; 643 644 /* get obj file for input */ 645 if (argc < 3) { 646 (void) fprintf(stderr, 647 "usage: %s {object_file} {MACH}\n", argv[0]); 648 exit(1); 649 } 650 651 objfile = argv[1]; 652 machname = argv[2]; 653 654 get_ctf_file(objfile); 655 656 (void) printf("#include <struct_layout.h>\n"); 657 658 gen_auxv(); 659 gen_prgregset(); 660 gen_lwpstatus(); 661 gen_pstatus(); 662 gen_prstatus(); 663 gen_psinfo(); 664 gen_prpsinfo(); 665 gen_lwpsinfo(); 666 gen_prcred(); 667 gen_prpriv(); 668 gen_priv_impl_info(); 669 gen_fltset(); 670 gen_siginfo(); 671 gen_sigset(); 672 gen_sigaction(); 673 gen_stack(); 674 gen_sysset(); 675 gen_timestruc(); 676 gen_utsname(); 677 gen_prfdinfo(); 678 gen_prsecflags(); 679 gen_prlwpname(); 680 gen_prupanic(); 681 gen_prcwd(); 682 683 /* 684 * Generate the full arch_layout description 685 */ 686 (void) printf( 687 "\n\n\n\nstatic const sl_arch_layout_t layout_%s = {\n", 688 machname); 689 (void) printf(fmt, "auxv"); 690 (void) printf(fmt, "fltset"); 691 (void) printf(fmt, "lwpsinfo"); 692 (void) printf(fmt, "lwpstatus"); 693 (void) printf(fmt, "prcred"); 694 (void) printf(fmt, "priv_impl_info"); 695 (void) printf(fmt, "prpriv"); 696 (void) printf(fmt, "psinfo"); 697 (void) printf(fmt, "pstatus"); 698 (void) printf(fmt, "prgregset"); 699 (void) printf(fmt, "prpsinfo"); 700 (void) printf(fmt, "prstatus"); 701 (void) printf(fmt, "sigaction"); 702 (void) printf(fmt, "siginfo"); 703 (void) printf(fmt, "sigset"); 704 (void) printf(fmt, "stack"); 705 (void) printf(fmt, "sysset"); 706 (void) printf(fmt, "timestruc"); 707 (void) printf(fmt, "utsname"); 708 (void) printf(fmt, "prfdinfo"); 709 (void) printf(fmt, "prsecflags"); 710 (void) printf(fmt, "prlwpname"); 711 (void) printf(fmt, "prupanic"); 712 (void) printf(fmt, "prcwd"); 713 (void) printf("};\n"); 714 715 /* 716 * A public function, to make the information available 717 */ 718 (void) printf("\n\nconst sl_arch_layout_t *\n"); 719 (void) printf("struct_layout_%s(void)\n", machname); 720 (void) printf("{\n\treturn (&layout_%s);\n}\n", machname); 721 722 return (0); 723 } 724 725 /* 726 * Helper functions using the CTF library to get type info. 727 */ 728 729 static void 730 get_ctf_file(char *fname) 731 { 732 int ctferr; 733 734 objfile = fname; 735 if ((ctf = ctf_open(objfile, &ctferr)) == NULL) { 736 errx(1, "Couldn't open object file %s: %s\n", objfile, 737 ctf_errmsg(ctferr)); 738 } 739 } 740 741 static void 742 print_row(int boff, int eltlen, int nelts, int issigned, char *comment) 743 { 744 (void) printf("\t{ %d,\t%d,\t%d,\t%d },\t\t/* %s */\n", 745 boff, eltlen, nelts, issigned, comment); 746 } 747 748 static void 749 do_start(char *sname, char *tname) 750 { 751 do_start_name(sname); 752 do_start_sizeof(tname, NULL); 753 } 754 755 static void 756 do_start_name(char *sname) 757 { 758 (void) printf("\n\nstatic const sl_%s_layout_t %s_layout = {\n", 759 sname, sname); 760 } 761 762 static void 763 do_end(void) 764 { 765 (void) printf("};\n"); 766 } 767 768 static void 769 do_start_sizeof(char *tname, char *rtname) 770 { 771 char comment[100]; 772 ctf_id_t stype; 773 int sz; 774 775 if (rtname == NULL) 776 rtname = tname; 777 778 if ((stype = ctf_lookup_by_name(ctf, rtname)) == CTF_ERR) 779 errx(1, "Couldn't find type %s", rtname); 780 if ((stype = ctf_type_resolve(ctf, stype)) == CTF_ERR) 781 errx(1, "Couldn't resolve type %s", tname); 782 783 if ((sz = (int)ctf_type_size(ctf, stype)) < 0) { 784 errx(1, "Couldn't get size for type %s", tname); 785 } else if (sz == 0) { 786 errx(1, "Invalid type size 0 for %s", tname); 787 } 788 789 (void) snprintf(comment, sizeof (comment), "sizeof (%s)", tname); 790 print_row(0, sz, 0, 0, comment); 791 } 792 793 static void 794 do_scalar_field(char *tname, char *fname, int _sign, char *dotfield) 795 { 796 int rc, off, sz, ftype; 797 798 rc = get_field_info(tname, fname, dotfield, &off, &ftype); 799 if (rc < 0) 800 errx(1, "Can't get field info for %s->%s", tname, fname); 801 802 if ((ftype = ctf_type_resolve(ctf, ftype)) == CTF_ERR) 803 errx(1, "Couldn't resolve type of %s->%s", tname, fname); 804 805 if ((sz = (int)ctf_type_size(ctf, ftype)) < 0) { 806 errx(1, "Couldn't get size for type ID %d", ftype); 807 } else if (sz == 0) { 808 errx(1, "Invalid type size 0 for type ID %d", ftype); 809 } 810 811 print_row(off, sz, 0, _sign, fname); 812 } 813 814 static void 815 do_array_field(char *tname, char *fname, 816 int _sign, char *dotfield) 817 { 818 char comment[100]; 819 ctf_arinfo_t ai; 820 int typekind; 821 int esz, rc, off, ftype; 822 823 rc = get_field_info(tname, fname, dotfield, &off, &ftype); 824 if (rc < 0) 825 errx(1, "Can't get field info for %s->%s", tname, fname); 826 827 if ((ftype = ctf_type_resolve(ctf, ftype)) == CTF_ERR) 828 errx(1, "Couldn't resolve type of %s->%s", tname, fname); 829 830 typekind = ctf_type_kind(ctf, ftype); 831 if (typekind != CTF_K_ARRAY) 832 errx(1, "Wrong type for %s->%s", tname, fname); 833 834 rc = ctf_array_info(ctf, ftype, &ai); 835 if (rc != 0) 836 errx(1, "Can't get array info for %s->%s\n", tname, fname); 837 esz = ctf_type_size(ctf, ai.ctr_contents); 838 if (esz < 0) 839 errx(1, "Can't get element size for %s->%s\n", tname, fname); 840 841 (void) snprintf(comment, sizeof (comment), "%s[]", fname); 842 print_row(off, esz, ai.ctr_nelems, _sign, comment); 843 } 844 845 static void 846 do_array_type(char *tname, char *fname, int _sign) 847 { 848 ctf_arinfo_t ai; 849 int stype, typekind; 850 int esz, rc; 851 852 if ((stype = ctf_lookup_by_name(ctf, tname)) == CTF_ERR) 853 errx(1, "Couldn't find type %s", tname); 854 if ((stype = ctf_type_resolve(ctf, stype)) == CTF_ERR) 855 errx(1, "Couldn't resolve type %s", tname); 856 857 typekind = ctf_type_kind(ctf, stype); 858 if (typekind != CTF_K_ARRAY) 859 errx(1, "Wrong type for %s->%s", tname, fname); 860 861 rc = ctf_array_info(ctf, stype, &ai); 862 if (rc != 0) 863 errx(1, "Can't get array info for %s->%s\n", tname, fname); 864 esz = ctf_type_size(ctf, ai.ctr_contents); 865 if (esz < 0) 866 errx(1, "Can't get element size for %s->%s\n", tname, fname); 867 868 print_row(0, esz, ai.ctr_nelems, _sign, fname); 869 } 870 871 872 struct gfinfo { 873 char *tname; /* top type name, i.e. the struct */ 874 char *fname; /* field name */ 875 char *dotname; /* full field name with dots (optional) */ 876 char *prefix; /* current field search prefix */ 877 int base_off; 878 int fld_off; 879 int fld_type; 880 }; 881 882 static int gfi_iter(const char *fname, ctf_id_t mbrtid, 883 ulong_t off, void *varg); 884 885 /* 886 * Lookup field "fname" in type "tname". If "dotname" is non-NULL, 887 * that's the full field name with dots, i.e. a_un.un_foo, which 888 * we must search for by walking the struct CTF recursively. 889 */ 890 static int 891 get_field_info(char *tname, char *fname, char *dotname, 892 int *offp, int *tidp) 893 { 894 struct gfinfo gfi; 895 ctf_id_t stype; 896 int typekind; 897 int rc; 898 899 if ((stype = ctf_lookup_by_name(ctf, tname)) == CTF_ERR) 900 errx(1, "Couldn't find type %s", tname); 901 if ((stype = ctf_type_resolve(ctf, stype)) == CTF_ERR) 902 errx(1, "Couldn't resolve type %s", tname); 903 904 /* If fname has a dot, use it as dotname too. */ 905 if (dotname == NULL && strchr(fname, '.') != NULL) 906 dotname = fname; 907 908 gfi.tname = tname; 909 gfi.fname = fname; 910 gfi.dotname = dotname; 911 gfi.prefix = ""; 912 gfi.base_off = 0; 913 gfi.fld_off = 0; 914 gfi.fld_type = 0; 915 916 typekind = ctf_type_kind(ctf, stype); 917 switch (typekind) { 918 919 case CTF_K_STRUCT: 920 case CTF_K_UNION: 921 rc = ctf_member_iter(ctf, stype, gfi_iter, &gfi); 922 break; 923 924 default: 925 errx(1, "Unexpected top-level type for %s", tname); 926 break; 927 } 928 929 if (rc < 0) 930 errx(1, "Error getting info for %s.%s", tname, fname); 931 if (rc == 0) 932 errx(1, "Did not find %s.%s", tname, fname); 933 934 *offp = gfi.fld_off; 935 *tidp = gfi.fld_type; 936 937 return (0); 938 } 939 940 /* 941 * Iteration callback for ctf_member_iter 942 * Return <0 on error, 0 to keep looking, >0 for found. 943 * 944 * If no dotname, simple search for fieldname. 945 * If we're asked to search with dotname, we need to do a full 946 * recursive walk of the types under the dotname. 947 */ 948 int 949 gfi_iter(const char *fieldname, ctf_id_t mbrtid, ulong_t off, void *varg) 950 { 951 char namebuf[100]; 952 struct gfinfo *gfi = varg; 953 char *saveprefix; 954 int saveoff; 955 int typekind; 956 int byteoff; 957 int len, rc; 958 959 byteoff = gfi->base_off + (int)(off >> 3); 960 961 /* Easy cases first: no dotname */ 962 if (gfi->dotname == NULL) { 963 if (strcmp(gfi->fname, fieldname) == 0) { 964 gfi->fld_off = byteoff; 965 gfi->fld_type = mbrtid; 966 return (1); 967 } 968 return (0); 969 } 970 971 /* Exact match on the dotname? */ 972 (void) snprintf(namebuf, sizeof (namebuf), "%s%s", 973 gfi->prefix, fieldname); 974 if (strcmp(gfi->dotname, namebuf) == 0) { 975 gfi->fld_off = byteoff; 976 gfi->fld_type = mbrtid; 977 return (1); 978 } 979 980 /* 981 * May need to recurse under this field, but 982 * only if there's a match through '.' 983 */ 984 (void) strlcat(namebuf, ".", sizeof (namebuf)); 985 len = strlen(namebuf); 986 if (strncmp(gfi->dotname, namebuf, len) != 0) 987 return (0); 988 989 typekind = ctf_type_kind(ctf, mbrtid); 990 switch (typekind) { 991 case CTF_K_STRUCT: 992 case CTF_K_UNION: 993 break; 994 default: 995 return (0); 996 } 997 998 /* Recursively walk members */ 999 saveprefix = gfi->prefix; 1000 saveoff = gfi->base_off; 1001 gfi->prefix = namebuf; 1002 gfi->base_off = byteoff; 1003 rc = ctf_member_iter(ctf, mbrtid, gfi_iter, gfi); 1004 gfi->prefix = saveprefix; 1005 gfi->base_off = saveoff; 1006 1007 return (rc); 1008 } 1009