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