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 }