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 static void
 591 gen_prsecflags(void)
 592 {
 593         START(prsecflags, prsecflags_t);
 594         SCALAR_FIELD(prsecflags_t, pr_version, 0);
 595         SCALAR_FIELD(prsecflags_t, pr_effective, 0);
 596         SCALAR_FIELD(prsecflags_t, pr_inherit, 0);
 597         SCALAR_FIELD(prsecflags_t, pr_lower, 0);
 598         SCALAR_FIELD(prsecflags_t, pr_upper, 0);
 599         END;
 600 }
 601 
 602 /*ARGSUSED*/
 603 int
 604 main(int argc, char *argv[])
 605 {
 606         const char *fmt = "\t&%s_layout,\n";
 607 
 608         /* get obj file for input */
 609         if (argc < 3) {
 610                 (void) fprintf(stderr,
 611                     "usage: %s {object_file} {MACH}\n", argv[0]);
 612                 exit(1);
 613         }
 614 
 615         objfile = argv[1];
 616         machname = argv[2];
 617 
 618         get_ctf_file(objfile);
 619 
 620         (void) printf("#include <struct_layout.h>\n");
 621 
 622         gen_auxv();
 623         gen_prgregset();
 624         gen_lwpstatus();
 625         gen_pstatus();
 626         gen_prstatus();
 627         gen_psinfo();
 628         gen_prpsinfo();
 629         gen_lwpsinfo();
 630         gen_prcred();
 631         gen_prpriv();
 632         gen_priv_impl_info();
 633         gen_fltset();
 634         gen_siginfo();
 635         gen_sigset();
 636         gen_sigaction();
 637         gen_stack();
 638         gen_sysset();
 639         gen_timestruc();
 640         gen_utsname();
 641         gen_prfdinfo();
 642         gen_prsecflags();
 643 
 644         /*
 645          * Generate the full arch_layout description
 646          */
 647         (void) printf(
 648             "\n\n\n\nstatic const sl_arch_layout_t layout_%s = {\n",
 649             machname);
 650         (void) printf(fmt, "auxv");
 651         (void) printf(fmt, "fltset");
 652         (void) printf(fmt, "lwpsinfo");
 653         (void) printf(fmt, "lwpstatus");
 654         (void) printf(fmt, "prcred");
 655         (void) printf(fmt, "priv_impl_info");
 656         (void) printf(fmt, "prpriv");
 657         (void) printf(fmt, "psinfo");
 658         (void) printf(fmt, "pstatus");
 659         (void) printf(fmt, "prgregset");
 660         (void) printf(fmt, "prpsinfo");
 661         (void) printf(fmt, "prstatus");
 662         (void) printf(fmt, "sigaction");
 663         (void) printf(fmt, "siginfo");
 664         (void) printf(fmt, "sigset");
 665         (void) printf(fmt, "stack");
 666         (void) printf(fmt, "sysset");
 667         (void) printf(fmt, "timestruc");
 668         (void) printf(fmt, "utsname");
 669         (void) printf(fmt, "prfdinfo");
 670         (void) printf(fmt, "prsecflags");
 671         (void) printf("};\n");
 672 
 673         /*
 674          * A public function, to make the information available
 675          */
 676         (void) printf("\n\nconst sl_arch_layout_t *\n");
 677         (void) printf("struct_layout_%s(void)\n", machname);
 678         (void) printf("{\n\treturn (&layout_%s);\n}\n", machname);
 679 
 680         return (0);
 681 }
 682 
 683 /*
 684  * Helper functions using the CTF library to get type info.
 685  */
 686 
 687 static void
 688 get_ctf_file(char *fname)
 689 {
 690         int ctferr;
 691 
 692         objfile = fname;
 693         if ((ctf = ctf_open(objfile, &ctferr)) == NULL) {
 694                 errx(1, "Couldn't open object file %s: %s\n", objfile,
 695                     ctf_errmsg(ctferr));
 696         }
 697 }
 698 
 699 static void
 700 print_row(int boff, int eltlen, int nelts, int issigned, char *comment)
 701 {
 702         (void) printf("\t{ %d,\t%d,\t%d,\t%d },\t\t/* %s */\n",
 703             boff, eltlen, nelts, issigned, comment);
 704 }
 705 
 706 static void
 707 do_start(char *sname, char *tname)
 708 {
 709         do_start_name(sname);
 710         do_start_sizeof(tname, NULL);
 711 }
 712 
 713 static void
 714 do_start_name(char *sname)
 715 {
 716         (void) printf("\n\nstatic const sl_%s_layout_t %s_layout = {\n",
 717             sname, sname);
 718 }
 719 
 720 static void
 721 do_end(void)
 722 {
 723         (void) printf("};\n");
 724 }
 725 
 726 static void
 727 do_start_sizeof(char *tname, char *rtname)
 728 {
 729         char comment[100];
 730         ctf_id_t stype;
 731         int sz;
 732 
 733         if (rtname == NULL)
 734                 rtname = tname;
 735 
 736         if ((stype = ctf_lookup_by_name(ctf, rtname)) == CTF_ERR)
 737                 errx(1, "Couldn't find type %s", rtname);
 738         if ((stype = ctf_type_resolve(ctf, stype)) == CTF_ERR)
 739                 errx(1, "Couldn't resolve type %s", tname);
 740 
 741         if ((sz = (int)ctf_type_size(ctf, stype)) < 0) {
 742                 errx(1, "Couldn't get size for type %s", tname);
 743         } else if (sz == 0) {
 744                 errx(1, "Invalid type size 0 for %s", tname);
 745         }
 746 
 747         (void) snprintf(comment, sizeof (comment), "sizeof (%s)", tname);
 748         print_row(0, sz, 0, 0, comment);
 749 }
 750 
 751 static void
 752 do_scalar_field(char *tname, char *fname, int _sign, char *dotfield)
 753 {
 754         int rc, off, sz, ftype;
 755 
 756         rc = get_field_info(tname, fname, dotfield, &off, &ftype);
 757         if (rc < 0)
 758                 errx(1, "Can't get field info for %s->%s", tname, fname);
 759 
 760         if ((ftype = ctf_type_resolve(ctf, ftype)) == CTF_ERR)
 761                 errx(1, "Couldn't resolve type of %s->%s", tname, fname);
 762 
 763         if ((sz = (int)ctf_type_size(ctf, ftype)) < 0) {
 764                 errx(1, "Couldn't get size for type ID %d", ftype);
 765         } else if (sz == 0) {
 766                 errx(1, "Invalid type size 0 for type ID %d", ftype);
 767         }
 768 
 769         print_row(off, sz, 0, _sign, fname);
 770 }
 771 
 772 static void
 773 do_array_field(char *tname, char *fname,
 774     int _sign, char *dotfield)
 775 {
 776         char comment[100];
 777         ctf_arinfo_t ai;
 778         int typekind;
 779         int esz, rc, off, ftype;
 780 
 781         rc = get_field_info(tname, fname, dotfield, &off, &ftype);
 782         if (rc < 0)
 783                 errx(1, "Can't get field info for %s->%s", tname, fname);
 784 
 785         if ((ftype = ctf_type_resolve(ctf, ftype)) == CTF_ERR)
 786                 errx(1, "Couldn't resolve type of %s->%s", tname, fname);
 787 
 788         typekind = ctf_type_kind(ctf, ftype);
 789         if (typekind != CTF_K_ARRAY)
 790                 errx(1, "Wrong type for %s->%s", tname, fname);
 791 
 792         rc = ctf_array_info(ctf, ftype, &ai);
 793         if (rc != 0)
 794                 errx(1, "Can't get array info for %s->%s\n", tname, fname);
 795         esz = ctf_type_size(ctf, ai.ctr_contents);
 796         if (esz < 0)
 797                 errx(1, "Can't get element size for %s->%s\n", tname, fname);
 798 
 799         (void) snprintf(comment, sizeof (comment), "%s[]", fname);
 800         print_row(off, esz, ai.ctr_nelems, _sign, comment);
 801 }
 802 
 803 static void
 804 do_array_type(char *tname, char *fname, int _sign)
 805 {
 806         ctf_arinfo_t ai;
 807         int stype, typekind;
 808         int esz, rc;
 809 
 810         if ((stype = ctf_lookup_by_name(ctf, tname)) == CTF_ERR)
 811                 errx(1, "Couldn't find type %s", tname);
 812         if ((stype = ctf_type_resolve(ctf, stype)) == CTF_ERR)
 813                 errx(1, "Couldn't resolve type %s", tname);
 814 
 815         typekind = ctf_type_kind(ctf, stype);
 816         if (typekind != CTF_K_ARRAY)
 817                 errx(1, "Wrong type for %s->%s", tname, fname);
 818 
 819         rc = ctf_array_info(ctf, stype, &ai);
 820         if (rc != 0)
 821                 errx(1, "Can't get array info for %s->%s\n", tname, fname);
 822         esz = ctf_type_size(ctf, ai.ctr_contents);
 823         if (esz < 0)
 824                 errx(1, "Can't get element size for %s->%s\n", tname, fname);
 825 
 826         print_row(0, esz, ai.ctr_nelems, _sign, fname);
 827 }
 828 
 829 
 830 struct gfinfo {
 831         char *tname;    /* top type name, i.e. the struct */
 832         char *fname;    /* field name */
 833         char *dotname;  /* full field name with dots (optional) */
 834         char *prefix;   /* current field search prefix */
 835         int base_off;
 836         int fld_off;
 837         int fld_type;
 838 };
 839 
 840 static int gfi_iter(const char *fname, ctf_id_t mbrtid,
 841         ulong_t off, void *varg);
 842 
 843 /*
 844  * Lookup field "fname" in type "tname".  If "dotname" is non-NULL,
 845  * that's the full field name with dots, i.e. a_un.un_foo, which
 846  * we must search for by walking the struct CTF recursively.
 847  */
 848 static int
 849 get_field_info(char *tname, char *fname, char *dotname,
 850     int *offp, int *tidp)
 851 {
 852         struct gfinfo gfi;
 853         ctf_id_t stype;
 854         int typekind;
 855         int rc;
 856 
 857         if ((stype = ctf_lookup_by_name(ctf, tname)) == CTF_ERR)
 858                 errx(1, "Couldn't find type %s", tname);
 859         if ((stype = ctf_type_resolve(ctf, stype)) == CTF_ERR)
 860                 errx(1, "Couldn't resolve type %s", tname);
 861 
 862         /* If fname has a dot, use it as dotname too. */
 863         if (dotname == NULL && strchr(fname, '.') != NULL)
 864                 dotname = fname;
 865 
 866         gfi.tname = tname;
 867         gfi.fname = fname;
 868         gfi.dotname = dotname;
 869         gfi.prefix = "";
 870         gfi.base_off = 0;
 871         gfi.fld_off = 0;
 872         gfi.fld_type = 0;
 873 
 874         typekind = ctf_type_kind(ctf, stype);
 875         switch (typekind) {
 876 
 877         case CTF_K_STRUCT:
 878         case CTF_K_UNION:
 879                 rc = ctf_member_iter(ctf, stype, gfi_iter, &gfi);
 880                 break;
 881 
 882         default:
 883                 errx(1, "Unexpected top-level type for %s", tname);
 884                 break;
 885         }
 886 
 887         if (rc < 0)
 888                 errx(1, "Error getting info for %s.%s", stype, fname);
 889         if (rc == 0)
 890                 errx(1, "Did not find %s.%s", tname, fname);
 891 
 892         *offp = gfi.fld_off;
 893         *tidp = gfi.fld_type;
 894 
 895         return (0);
 896 }
 897 
 898 /*
 899  * Iteration callback for ctf_member_iter
 900  * Return <0 on error, 0 to keep looking, >0 for found.
 901  *
 902  * If no dotname, simple search for fieldname.
 903  * If we're asked to search with dotname, we need to do a full
 904  * recursive walk of the types under the dotname.
 905  */
 906 int
 907 gfi_iter(const char *fieldname, ctf_id_t mbrtid, ulong_t off, void *varg)
 908 {
 909         char namebuf[100];
 910         struct gfinfo *gfi = varg;
 911         char *saveprefix;
 912         int saveoff;
 913         int typekind;
 914         int byteoff;
 915         int len, rc;
 916 
 917         byteoff = gfi->base_off + (int)(off >> 3);
 918 
 919         /* Easy cases first: no dotname */
 920         if (gfi->dotname == NULL) {
 921                 if (strcmp(gfi->fname, fieldname) == 0) {
 922                         gfi->fld_off = byteoff;
 923                         gfi->fld_type = mbrtid;
 924                         return (1);
 925                 }
 926                 return (0);
 927         }
 928 
 929         /* Exact match on the dotname? */
 930         (void) snprintf(namebuf, sizeof (namebuf), "%s%s",
 931             gfi->prefix, fieldname);
 932         if (strcmp(gfi->dotname, namebuf) == 0) {
 933                 gfi->fld_off = byteoff;
 934                 gfi->fld_type = mbrtid;
 935                 return (1);
 936         }
 937 
 938         /*
 939          * May need to recurse under this field, but
 940          * only if there's a match through '.'
 941          */
 942         (void) strlcat(namebuf, ".", sizeof (namebuf));
 943         len = strlen(namebuf);
 944         if (strncmp(gfi->dotname, namebuf, len) != 0)
 945                 return (0);
 946 
 947         typekind = ctf_type_kind(ctf, mbrtid);
 948         switch (typekind) {
 949         case CTF_K_STRUCT:
 950         case CTF_K_UNION:
 951                 break;
 952         default:
 953                 return (0);
 954         }
 955 
 956         /* Recursively walk members */
 957         saveprefix = gfi->prefix;
 958         saveoff = gfi->base_off;
 959         gfi->prefix = namebuf;
 960         gfi->base_off = byteoff;
 961         rc = ctf_member_iter(ctf, mbrtid, gfi_iter, gfi);
 962         gfi->prefix = saveprefix;
 963         gfi->base_off = saveoff;
 964 
 965         return (rc);
 966 }