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