#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <err.h>
#include <sys/types.h>
#include <libctf.h>
#define START(_name, _type) \
do_start(#_name, #_type)
#define END (void) \
do_end()
#define SCALAR_FIELD(_type, _field, _sign) \
do_scalar_field(#_type, #_field, _sign, NULL)
#define SCALAR_FIELD4(_type, _field, _sign, _rtype) \
do_scalar_field(#_type, #_field, _sign, _rtype)
#define ARRAY_FIELD(_type, _field, _sign) \
do_array_field(#_type, #_field, _sign, NULL)
#define ARRAY_TYPE(_type, _sign) \
do_array_type(#_type, "elt0", _sign)
static void do_start(char *_name, char *_type);
static void do_end(void);
static void do_start_name(char *name);
static void do_start_sizeof(char *_type, char *realtype);
static void do_scalar_field(char *_type, char *_field,
int _sign, char *dotfield);
static void do_array_field(char *_type, char *_field,
int _sign, char *dotfield);
static void do_array_type(char *_type, char *_field, int _sign);
static void get_ctf_file(char *fname);
static int get_field_info(char *tname, char *fname, char *dotname,
int *offp, int *sizep);
static ctf_file_t *ctf;
static char *objfile;
static char *machname;
static void
gen_auxv(void)
{
START(auxv, auxv_t);
SCALAR_FIELD(auxv_t, a_type, 1);
SCALAR_FIELD(auxv_t, a_un.a_val, 1);
SCALAR_FIELD(auxv_t, a_un.a_ptr, 0);
SCALAR_FIELD(auxv_t, a_un.a_fcn, 0);
END;
}
static void
gen_prgregset(void)
{
START(prgregset, prgregset_t);
ARRAY_TYPE(prgregset_t, 0);
END;
}
static void
gen_lwpstatus(void)
{
START(lwpstatus, lwpstatus_t);
SCALAR_FIELD(lwpstatus_t, pr_flags, 0);
SCALAR_FIELD(lwpstatus_t, pr_lwpid, 0);
SCALAR_FIELD(lwpstatus_t, pr_why, 0);
SCALAR_FIELD(lwpstatus_t, pr_what, 0);
SCALAR_FIELD(lwpstatus_t, pr_cursig, 0);
SCALAR_FIELD(lwpstatus_t, pr_info, 0);
SCALAR_FIELD(lwpstatus_t, pr_lwppend, 0);
SCALAR_FIELD(lwpstatus_t, pr_lwphold, 0);
SCALAR_FIELD(lwpstatus_t, pr_action, 0);
SCALAR_FIELD(lwpstatus_t, pr_altstack, 0);
SCALAR_FIELD(lwpstatus_t, pr_oldcontext, 0);
SCALAR_FIELD(lwpstatus_t, pr_syscall, 0);
SCALAR_FIELD(lwpstatus_t, pr_nsysarg, 0);
SCALAR_FIELD(lwpstatus_t, pr_errno, 0);
ARRAY_FIELD(lwpstatus_t, pr_sysarg, 0);
SCALAR_FIELD(lwpstatus_t, pr_rval1, 0);
SCALAR_FIELD(lwpstatus_t, pr_rval2, 0);
ARRAY_FIELD(lwpstatus_t, pr_clname, 0);
SCALAR_FIELD(lwpstatus_t, pr_tstamp, 0);
SCALAR_FIELD(lwpstatus_t, pr_utime, 0);
SCALAR_FIELD(lwpstatus_t, pr_stime, 0);
SCALAR_FIELD(lwpstatus_t, pr_errpriv, 0);
SCALAR_FIELD(lwpstatus_t, pr_ustack, 0);
SCALAR_FIELD(lwpstatus_t, pr_instr, 0);
SCALAR_FIELD(lwpstatus_t, pr_reg, 0);
SCALAR_FIELD(lwpstatus_t, pr_fpreg, 0);
END;
}
static void
gen_pstatus(void)
{
START(pstatus, pstatus_t);
SCALAR_FIELD(pstatus_t, pr_flags, 1);
SCALAR_FIELD(pstatus_t, pr_nlwp, 1);
SCALAR_FIELD(pstatus_t, pr_pid, 0);
SCALAR_FIELD(pstatus_t, pr_ppid, 0);
SCALAR_FIELD(pstatus_t, pr_pgid, 0);
SCALAR_FIELD(pstatus_t, pr_sid, 0);
SCALAR_FIELD(pstatus_t, pr_aslwpid, 1);
SCALAR_FIELD(pstatus_t, pr_agentid, 1);
SCALAR_FIELD(pstatus_t, pr_sigpend, 0);
SCALAR_FIELD(pstatus_t, pr_brkbase, 0);
SCALAR_FIELD(pstatus_t, pr_brksize, 0);
SCALAR_FIELD(pstatus_t, pr_stkbase, 0);
SCALAR_FIELD(pstatus_t, pr_stksize, 0);
SCALAR_FIELD(pstatus_t, pr_utime, 0);
SCALAR_FIELD(pstatus_t, pr_stime, 0);
SCALAR_FIELD(pstatus_t, pr_cutime, 0);
SCALAR_FIELD(pstatus_t, pr_cstime, 0);
SCALAR_FIELD(pstatus_t, pr_sigtrace, 0);
SCALAR_FIELD(pstatus_t, pr_flttrace, 0);
SCALAR_FIELD(pstatus_t, pr_sysentry, 0);
SCALAR_FIELD(pstatus_t, pr_sysexit, 0);
SCALAR_FIELD(pstatus_t, pr_dmodel, 0);
SCALAR_FIELD(pstatus_t, pr_taskid, 1);
SCALAR_FIELD(pstatus_t, pr_projid, 1);
SCALAR_FIELD(pstatus_t, pr_nzomb, 1);
SCALAR_FIELD(pstatus_t, pr_zoneid, 1);
SCALAR_FIELD(pstatus_t, pr_lwp, 0);
END;
}
static void
gen_prstatus(void)
{
START(prstatus, prstatus_t);
SCALAR_FIELD(prstatus_t, pr_flags, 1);
SCALAR_FIELD(prstatus_t, pr_why, 1);
SCALAR_FIELD(prstatus_t, pr_what, 1);
SCALAR_FIELD(prstatus_t, pr_info, 0);
SCALAR_FIELD(prstatus_t, pr_cursig, 1);
SCALAR_FIELD(prstatus_t, pr_nlwp, 0);
SCALAR_FIELD(prstatus_t, pr_sigpend, 0);
SCALAR_FIELD(prstatus_t, pr_sighold, 0);
SCALAR_FIELD(prstatus_t, pr_altstack, 0);
SCALAR_FIELD(prstatus_t, pr_action, 0);
SCALAR_FIELD(prstatus_t, pr_pid, 0);
SCALAR_FIELD(prstatus_t, pr_ppid, 0);
SCALAR_FIELD(prstatus_t, pr_pgrp, 0);
SCALAR_FIELD(prstatus_t, pr_sid, 0);
SCALAR_FIELD(prstatus_t, pr_utime, 0);
SCALAR_FIELD(prstatus_t, pr_stime, 0);
SCALAR_FIELD(prstatus_t, pr_cutime, 0);
SCALAR_FIELD(prstatus_t, pr_cstime, 0);
ARRAY_FIELD(prstatus_t, pr_clname, 0);
SCALAR_FIELD(prstatus_t, pr_syscall, 1);
SCALAR_FIELD(prstatus_t, pr_nsysarg, 1);
ARRAY_FIELD(prstatus_t, pr_sysarg, 1);
SCALAR_FIELD(prstatus_t, pr_who, 0);
SCALAR_FIELD(prstatus_t, pr_lwppend, 0);
SCALAR_FIELD(prstatus_t, pr_oldcontext, 0);
SCALAR_FIELD(prstatus_t, pr_brkbase, 0);
SCALAR_FIELD(prstatus_t, pr_brksize, 0);
SCALAR_FIELD(prstatus_t, pr_stkbase, 0);
SCALAR_FIELD(prstatus_t, pr_stksize, 0);
SCALAR_FIELD(prstatus_t, pr_processor, 1);
SCALAR_FIELD(prstatus_t, pr_bind, 1);
SCALAR_FIELD(prstatus_t, pr_instr, 1);
SCALAR_FIELD(prstatus_t, pr_reg, 0);
END;
}
static void
gen_psinfo(void)
{
START(psinfo, psinfo_t);
SCALAR_FIELD(psinfo_t, pr_flag, 1);
SCALAR_FIELD(psinfo_t, pr_nlwp, 1);
SCALAR_FIELD(psinfo_t, pr_pid, 0);
SCALAR_FIELD(psinfo_t, pr_ppid, 0);
SCALAR_FIELD(psinfo_t, pr_pgid, 0);
SCALAR_FIELD(psinfo_t, pr_sid, 0);
SCALAR_FIELD(psinfo_t, pr_uid, 0);
SCALAR_FIELD(psinfo_t, pr_euid, 0);
SCALAR_FIELD(psinfo_t, pr_gid, 0);
SCALAR_FIELD(psinfo_t, pr_egid, 0);
SCALAR_FIELD(psinfo_t, pr_addr, 0);
SCALAR_FIELD(psinfo_t, pr_size, 0);
SCALAR_FIELD(psinfo_t, pr_rssize, 0);
SCALAR_FIELD(psinfo_t, pr_ttydev, 0);
SCALAR_FIELD(psinfo_t, pr_pctcpu, 0);
SCALAR_FIELD(psinfo_t, pr_pctmem, 0);
SCALAR_FIELD(psinfo_t, pr_start, 0);
SCALAR_FIELD(psinfo_t, pr_time, 0);
SCALAR_FIELD(psinfo_t, pr_ctime, 0);
ARRAY_FIELD(psinfo_t, pr_fname, 0);
ARRAY_FIELD(psinfo_t, pr_psargs, 0);
SCALAR_FIELD(psinfo_t, pr_wstat, 1);
SCALAR_FIELD(psinfo_t, pr_argc, 1);
SCALAR_FIELD(psinfo_t, pr_argv, 0);
SCALAR_FIELD(psinfo_t, pr_envp, 0);
SCALAR_FIELD(psinfo_t, pr_dmodel, 0);
SCALAR_FIELD(psinfo_t, pr_taskid, 0);
SCALAR_FIELD(psinfo_t, pr_projid, 0);
SCALAR_FIELD(psinfo_t, pr_nzomb, 1);
SCALAR_FIELD(psinfo_t, pr_poolid, 0);
SCALAR_FIELD(psinfo_t, pr_zoneid, 0);
SCALAR_FIELD(psinfo_t, pr_contract, 0);
SCALAR_FIELD(psinfo_t, pr_lwp, 0);
END;
}
static void
gen_prpsinfo(void)
{
START(prpsinfo, prpsinfo_t);
SCALAR_FIELD(prpsinfo_t, pr_state, 0);
SCALAR_FIELD(prpsinfo_t, pr_sname, 0);
SCALAR_FIELD(prpsinfo_t, pr_zomb, 0);
SCALAR_FIELD(prpsinfo_t, pr_nice, 0);
SCALAR_FIELD(prpsinfo_t, pr_flag, 0);
SCALAR_FIELD(prpsinfo_t, pr_uid, 0);
SCALAR_FIELD(prpsinfo_t, pr_gid, 0);
SCALAR_FIELD(prpsinfo_t, pr_pid, 0);
SCALAR_FIELD(prpsinfo_t, pr_ppid, 0);
SCALAR_FIELD(prpsinfo_t, pr_pgrp, 0);
SCALAR_FIELD(prpsinfo_t, pr_sid, 0);
SCALAR_FIELD(prpsinfo_t, pr_addr, 0);
SCALAR_FIELD(prpsinfo_t, pr_size, 0);
SCALAR_FIELD(prpsinfo_t, pr_rssize, 0);
SCALAR_FIELD(prpsinfo_t, pr_wchan, 0);
SCALAR_FIELD(prpsinfo_t, pr_start, 0);
SCALAR_FIELD(prpsinfo_t, pr_time, 0);
SCALAR_FIELD(prpsinfo_t, pr_pri, 1);
SCALAR_FIELD(prpsinfo_t, pr_oldpri, 0);
SCALAR_FIELD(prpsinfo_t, pr_cpu, 0);
SCALAR_FIELD(prpsinfo_t, pr_ottydev, 0);
SCALAR_FIELD(prpsinfo_t, pr_lttydev, 0);
ARRAY_FIELD(prpsinfo_t, pr_clname, 0);
ARRAY_FIELD(prpsinfo_t, pr_fname, 0);
ARRAY_FIELD(prpsinfo_t, pr_psargs, 0);
SCALAR_FIELD(prpsinfo_t, pr_syscall, 1);
SCALAR_FIELD(prpsinfo_t, pr_ctime, 0);
SCALAR_FIELD(prpsinfo_t, pr_bysize, 0);
SCALAR_FIELD(prpsinfo_t, pr_byrssize, 0);
SCALAR_FIELD(prpsinfo_t, pr_argc, 1);
SCALAR_FIELD(prpsinfo_t, pr_argv, 0);
SCALAR_FIELD(prpsinfo_t, pr_envp, 0);
SCALAR_FIELD(prpsinfo_t, pr_wstat, 1);
SCALAR_FIELD(prpsinfo_t, pr_pctcpu, 0);
SCALAR_FIELD(prpsinfo_t, pr_pctmem, 0);
SCALAR_FIELD(prpsinfo_t, pr_euid, 0);
SCALAR_FIELD(prpsinfo_t, pr_egid, 0);
SCALAR_FIELD(prpsinfo_t, pr_aslwpid, 0);
SCALAR_FIELD(prpsinfo_t, pr_dmodel, 0);
END;
}
static void
gen_lwpsinfo(void)
{
START(lwpsinfo, lwpsinfo_t);
SCALAR_FIELD(lwpsinfo_t, pr_flag, 1);
SCALAR_FIELD(lwpsinfo_t, pr_lwpid, 0);
SCALAR_FIELD(lwpsinfo_t, pr_addr, 0);
SCALAR_FIELD(lwpsinfo_t, pr_wchan, 0);
SCALAR_FIELD(lwpsinfo_t, pr_stype, 0);
SCALAR_FIELD(lwpsinfo_t, pr_state, 0);
SCALAR_FIELD(lwpsinfo_t, pr_sname, 0);
SCALAR_FIELD(lwpsinfo_t, pr_nice, 0);
SCALAR_FIELD(lwpsinfo_t, pr_syscall, 0);
SCALAR_FIELD(lwpsinfo_t, pr_oldpri, 0);
SCALAR_FIELD(lwpsinfo_t, pr_cpu, 0);
SCALAR_FIELD(lwpsinfo_t, pr_pri, 1);
SCALAR_FIELD(lwpsinfo_t, pr_pctcpu, 0);
SCALAR_FIELD(lwpsinfo_t, pr_start, 0);
SCALAR_FIELD(lwpsinfo_t, pr_time, 0);
ARRAY_FIELD(lwpsinfo_t, pr_clname, 0);
ARRAY_FIELD(lwpsinfo_t, pr_name, 0);
SCALAR_FIELD(lwpsinfo_t, pr_onpro, 1);
SCALAR_FIELD(lwpsinfo_t, pr_bindpro, 1);
SCALAR_FIELD(lwpsinfo_t, pr_bindpset, 1);
SCALAR_FIELD(lwpsinfo_t, pr_lgrp, 1);
END;
}
static void
gen_prcred(void)
{
START(prcred, prcred_t);
SCALAR_FIELD(prcred_t, pr_euid, 0);
SCALAR_FIELD(prcred_t, pr_ruid, 0);
SCALAR_FIELD(prcred_t, pr_suid, 0);
SCALAR_FIELD(prcred_t, pr_egid, 0);
SCALAR_FIELD(prcred_t, pr_rgid, 0);
SCALAR_FIELD(prcred_t, pr_sgid, 0);
SCALAR_FIELD(prcred_t, pr_ngroups, 1);
ARRAY_FIELD(prcred_t, pr_groups, 0);
END;
}
static void
gen_prpriv(void)
{
START(prpriv, prpriv_t);
SCALAR_FIELD(prpriv_t, pr_nsets, 0);
SCALAR_FIELD(prpriv_t, pr_setsize, 0);
SCALAR_FIELD(prpriv_t, pr_infosize, 0);
ARRAY_FIELD(prpriv_t, pr_sets, 0);
END;
}
static void
gen_priv_impl_info(void)
{
START(priv_impl_info, priv_impl_info_t);
SCALAR_FIELD(priv_impl_info_t, priv_headersize, 0);
SCALAR_FIELD(priv_impl_info_t, priv_flags, 0);
SCALAR_FIELD(priv_impl_info_t, priv_nsets, 0);
SCALAR_FIELD(priv_impl_info_t, priv_setsize, 0);
SCALAR_FIELD(priv_impl_info_t, priv_max, 0);
SCALAR_FIELD(priv_impl_info_t, priv_infosize, 0);
SCALAR_FIELD(priv_impl_info_t, priv_globalinfosize, 0);
END;
}
static void
gen_fltset(void)
{
START(fltset, fltset_t);
ARRAY_FIELD(fltset_t, word, 0);
END;
}
static void
gen_siginfo(void)
{
START(siginfo, siginfo_t);
SCALAR_FIELD(siginfo_t, si_signo, 0);
SCALAR_FIELD(siginfo_t, si_errno, 0);
SCALAR_FIELD(siginfo_t, si_code, 1);
SCALAR_FIELD4(siginfo_t, si_value.sival_int, 0,
"__data.__proc.__pdata.__kill.__value.sival_int");
SCALAR_FIELD4(siginfo_t, si_value.sival_ptr, 0,
"__data.__proc.__pdata.__kill.__value.sival_ptr");
SCALAR_FIELD4(siginfo_t, si_pid, 0,
"__data.__proc.__pid");
SCALAR_FIELD4(siginfo_t, si_uid, 0,
"__data.__proc.__pdata.__kill.__uid");
SCALAR_FIELD4(siginfo_t, si_ctid, 0,
"__data.__proc.__ctid");
SCALAR_FIELD4(siginfo_t, si_zoneid, 0,
"__data.__proc.__zoneid");
SCALAR_FIELD4(siginfo_t, si_entity, 0,
"__data.__rctl.__entity");
SCALAR_FIELD4(siginfo_t, si_addr, 0,
"__data.__fault.__addr");
SCALAR_FIELD4(siginfo_t, si_status, 0,
"__data.__proc.__pdata.__cld.__status");
SCALAR_FIELD4(siginfo_t, si_band, 0,
"__data.__file.__band");
END;
}
static void
gen_sigset(void)
{
START(sigset, sigset_t);
ARRAY_FIELD(sigset_t, __sigbits, 0);
END;
}
static void
gen_sigaction(void)
{
START(sigaction, struct sigaction);
SCALAR_FIELD(struct sigaction, sa_flags, 0);
SCALAR_FIELD4(struct sigaction, sa_handler, 0,
"_funcptr._handler");
SCALAR_FIELD4(struct sigaction, sa_sigaction, 0,
"_funcptr._sigaction");
SCALAR_FIELD(struct sigaction, sa_mask, 0);
END;
}
static void
gen_stack(void)
{
START(stack, stack_t);
SCALAR_FIELD(stack_t, ss_sp, 0);
SCALAR_FIELD(stack_t, ss_size, 0);
SCALAR_FIELD(stack_t, ss_flags, 0);
END;
}
static void
gen_sysset(void)
{
START(sysset, sysset_t);
ARRAY_FIELD(sysset_t, word, 0);
END;
}
static void
gen_timestruc(void)
{
START(timestruc, timestruc_t);
SCALAR_FIELD(timestruc_t, tv_sec, 0);
SCALAR_FIELD(timestruc_t, tv_nsec, 0);
END;
}
static void
gen_utsname(void)
{
START(utsname, struct utsname);
ARRAY_FIELD(struct utsname, sysname, 0);
ARRAY_FIELD(struct utsname, nodename, 0);
ARRAY_FIELD(struct utsname, release, 0);
ARRAY_FIELD(struct utsname, version, 0);
ARRAY_FIELD(struct utsname, machine, 0);
END;
}
static void
gen_prfdinfo(void)
{
START(prfdinfo, prfdinfo_core_t);
SCALAR_FIELD(prfdinfo_core_t, pr_fd, 0);
SCALAR_FIELD(prfdinfo_core_t, pr_mode, 0);
SCALAR_FIELD(prfdinfo_core_t, pr_uid, 0);
SCALAR_FIELD(prfdinfo_core_t, pr_gid, 0);
SCALAR_FIELD(prfdinfo_core_t, pr_major, 0);
SCALAR_FIELD(prfdinfo_core_t, pr_minor, 0);
SCALAR_FIELD(prfdinfo_core_t, pr_rmajor, 0);
SCALAR_FIELD(prfdinfo_core_t, pr_rminor, 0);
SCALAR_FIELD(prfdinfo_core_t, pr_ino, 0);
SCALAR_FIELD(prfdinfo_core_t, pr_offset, 0);
SCALAR_FIELD(prfdinfo_core_t, pr_size, 0);
SCALAR_FIELD(prfdinfo_core_t, pr_fileflags, 0);
SCALAR_FIELD(prfdinfo_core_t, pr_fdflags, 0);
ARRAY_FIELD(prfdinfo_core_t, pr_path, 0);
END;
}
static void
gen_prsecflags(void)
{
START(prsecflags, prsecflags_t);
SCALAR_FIELD(prsecflags_t, pr_version, 0);
SCALAR_FIELD(prsecflags_t, pr_effective, 0);
SCALAR_FIELD(prsecflags_t, pr_inherit, 0);
SCALAR_FIELD(prsecflags_t, pr_lower, 0);
SCALAR_FIELD(prsecflags_t, pr_upper, 0);
END;
}
static void
gen_prlwpname(void)
{
START(prlwpname, prlwpname_t);
SCALAR_FIELD(prlwpname_t, pr_lwpid, 0);
ARRAY_FIELD(prlwpname_t, pr_lwpname, 0);
END;
}
static void
gen_prupanic(void)
{
START(prupanic, prupanic_t);
SCALAR_FIELD(prupanic_t, pru_version, 0);
SCALAR_FIELD(prupanic_t, pru_flags, 0);
ARRAY_FIELD(prupanic_t, pru_data, 0);
END;
}
static void
gen_prcwd(void)
{
START(prcwd, prcwd_t);
SCALAR_FIELD(prcwd_t, prcwd_fsid, 0);
ARRAY_FIELD(prcwd_t, prcwd_fsname, 0);
ARRAY_FIELD(prcwd_t, prcwd_mntpt, 0);
ARRAY_FIELD(prcwd_t, prcwd_mntspec, 0);
ARRAY_FIELD(prcwd_t, prcwd_cwd, 0);
END;
}
int
main(int argc, char *argv[])
{
const char *fmt = "\t&%s_layout,\n";
if (argc < 3) {
(void) fprintf(stderr,
"usage: %s {object_file} {MACH}\n", argv[0]);
exit(1);
}
objfile = argv[1];
machname = argv[2];
get_ctf_file(objfile);
(void) printf("#include <struct_layout.h>\n");
gen_auxv();
gen_prgregset();
gen_lwpstatus();
gen_pstatus();
gen_prstatus();
gen_psinfo();
gen_prpsinfo();
gen_lwpsinfo();
gen_prcred();
gen_prpriv();
gen_priv_impl_info();
gen_fltset();
gen_siginfo();
gen_sigset();
gen_sigaction();
gen_stack();
gen_sysset();
gen_timestruc();
gen_utsname();
gen_prfdinfo();
gen_prsecflags();
gen_prlwpname();
gen_prupanic();
gen_prcwd();
(void) printf(
"\n\n\n\nstatic const sl_arch_layout_t layout_%s = {\n",
machname);
(void) printf(fmt, "auxv");
(void) printf(fmt, "fltset");
(void) printf(fmt, "lwpsinfo");
(void) printf(fmt, "lwpstatus");
(void) printf(fmt, "prcred");
(void) printf(fmt, "priv_impl_info");
(void) printf(fmt, "prpriv");
(void) printf(fmt, "psinfo");
(void) printf(fmt, "pstatus");
(void) printf(fmt, "prgregset");
(void) printf(fmt, "prpsinfo");
(void) printf(fmt, "prstatus");
(void) printf(fmt, "sigaction");
(void) printf(fmt, "siginfo");
(void) printf(fmt, "sigset");
(void) printf(fmt, "stack");
(void) printf(fmt, "sysset");
(void) printf(fmt, "timestruc");
(void) printf(fmt, "utsname");
(void) printf(fmt, "prfdinfo");
(void) printf(fmt, "prsecflags");
(void) printf(fmt, "prlwpname");
(void) printf(fmt, "prupanic");
(void) printf(fmt, "prcwd");
(void) printf("};\n");
(void) printf("\n\nconst sl_arch_layout_t *\n");
(void) printf("struct_layout_%s(void)\n", machname);
(void) printf("{\n\treturn (&layout_%s);\n}\n", machname);
return (0);
}
static void
get_ctf_file(char *fname)
{
int ctferr;
objfile = fname;
if ((ctf = ctf_open(objfile, &ctferr)) == NULL) {
errx(1, "Couldn't open object file %s: %s\n", objfile,
ctf_errmsg(ctferr));
}
}
static void
print_row(int boff, int eltlen, int nelts, int issigned, char *comment)
{
(void) printf("\t{ %d,\t%d,\t%d,\t%d },\t\t/* %s */\n",
boff, eltlen, nelts, issigned, comment);
}
static void
do_start(char *sname, char *tname)
{
do_start_name(sname);
do_start_sizeof(tname, NULL);
}
static void
do_start_name(char *sname)
{
(void) printf("\n\nstatic const sl_%s_layout_t %s_layout = {\n",
sname, sname);
}
static void
do_end(void)
{
(void) printf("};\n");
}
static void
do_start_sizeof(char *tname, char *rtname)
{
char comment[100];
ctf_id_t stype;
int sz;
if (rtname == NULL)
rtname = tname;
if ((stype = ctf_lookup_by_name(ctf, rtname)) == CTF_ERR)
errx(1, "Couldn't find type %s", rtname);
if ((stype = ctf_type_resolve(ctf, stype)) == CTF_ERR)
errx(1, "Couldn't resolve type %s", tname);
if ((sz = (int)ctf_type_size(ctf, stype)) < 0) {
errx(1, "Couldn't get size for type %s", tname);
} else if (sz == 0) {
errx(1, "Invalid type size 0 for %s", tname);
}
(void) snprintf(comment, sizeof (comment), "sizeof (%s)", tname);
print_row(0, sz, 0, 0, comment);
}
static void
do_scalar_field(char *tname, char *fname, int _sign, char *dotfield)
{
int rc, off, sz, ftype;
rc = get_field_info(tname, fname, dotfield, &off, &ftype);
if (rc < 0)
errx(1, "Can't get field info for %s->%s", tname, fname);
if ((ftype = ctf_type_resolve(ctf, ftype)) == CTF_ERR)
errx(1, "Couldn't resolve type of %s->%s", tname, fname);
if ((sz = (int)ctf_type_size(ctf, ftype)) < 0) {
errx(1, "Couldn't get size for type ID %d", ftype);
} else if (sz == 0) {
errx(1, "Invalid type size 0 for type ID %d", ftype);
}
print_row(off, sz, 0, _sign, fname);
}
static void
do_array_field(char *tname, char *fname,
int _sign, char *dotfield)
{
char comment[100];
ctf_arinfo_t ai;
int typekind;
int esz, rc, off, ftype;
rc = get_field_info(tname, fname, dotfield, &off, &ftype);
if (rc < 0)
errx(1, "Can't get field info for %s->%s", tname, fname);
if ((ftype = ctf_type_resolve(ctf, ftype)) == CTF_ERR)
errx(1, "Couldn't resolve type of %s->%s", tname, fname);
typekind = ctf_type_kind(ctf, ftype);
if (typekind != CTF_K_ARRAY)
errx(1, "Wrong type for %s->%s", tname, fname);
rc = ctf_array_info(ctf, ftype, &ai);
if (rc != 0)
errx(1, "Can't get array info for %s->%s\n", tname, fname);
esz = ctf_type_size(ctf, ai.ctr_contents);
if (esz < 0)
errx(1, "Can't get element size for %s->%s\n", tname, fname);
(void) snprintf(comment, sizeof (comment), "%s[]", fname);
print_row(off, esz, ai.ctr_nelems, _sign, comment);
}
static void
do_array_type(char *tname, char *fname, int _sign)
{
ctf_arinfo_t ai;
int stype, typekind;
int esz, rc;
if ((stype = ctf_lookup_by_name(ctf, tname)) == CTF_ERR)
errx(1, "Couldn't find type %s", tname);
if ((stype = ctf_type_resolve(ctf, stype)) == CTF_ERR)
errx(1, "Couldn't resolve type %s", tname);
typekind = ctf_type_kind(ctf, stype);
if (typekind != CTF_K_ARRAY)
errx(1, "Wrong type for %s->%s", tname, fname);
rc = ctf_array_info(ctf, stype, &ai);
if (rc != 0)
errx(1, "Can't get array info for %s->%s\n", tname, fname);
esz = ctf_type_size(ctf, ai.ctr_contents);
if (esz < 0)
errx(1, "Can't get element size for %s->%s\n", tname, fname);
print_row(0, esz, ai.ctr_nelems, _sign, fname);
}
struct gfinfo {
char *tname;
char *fname;
char *dotname;
char *prefix;
int base_off;
int fld_off;
int fld_type;
};
static int gfi_iter(const char *fname, ctf_id_t mbrtid,
ulong_t off, void *varg);
static int
get_field_info(char *tname, char *fname, char *dotname,
int *offp, int *tidp)
{
struct gfinfo gfi;
ctf_id_t stype;
int typekind;
int rc;
if ((stype = ctf_lookup_by_name(ctf, tname)) == CTF_ERR)
errx(1, "Couldn't find type %s", tname);
if ((stype = ctf_type_resolve(ctf, stype)) == CTF_ERR)
errx(1, "Couldn't resolve type %s", tname);
if (dotname == NULL && strchr(fname, '.') != NULL)
dotname = fname;
gfi.tname = tname;
gfi.fname = fname;
gfi.dotname = dotname;
gfi.prefix = "";
gfi.base_off = 0;
gfi.fld_off = 0;
gfi.fld_type = 0;
typekind = ctf_type_kind(ctf, stype);
switch (typekind) {
case CTF_K_STRUCT:
case CTF_K_UNION:
rc = ctf_member_iter(ctf, stype, gfi_iter, &gfi);
break;
default:
errx(1, "Unexpected top-level type for %s", tname);
break;
}
if (rc < 0)
errx(1, "Error getting info for %s.%s", tname, fname);
if (rc == 0)
errx(1, "Did not find %s.%s", tname, fname);
*offp = gfi.fld_off;
*tidp = gfi.fld_type;
return (0);
}
int
gfi_iter(const char *fieldname, ctf_id_t mbrtid, ulong_t off, void *varg)
{
char namebuf[100];
struct gfinfo *gfi = varg;
char *saveprefix;
int saveoff;
int typekind;
int byteoff;
int len, rc;
byteoff = gfi->base_off + (int)(off >> 3);
if (gfi->dotname == NULL) {
if (strcmp(gfi->fname, fieldname) == 0) {
gfi->fld_off = byteoff;
gfi->fld_type = mbrtid;
return (1);
}
return (0);
}
(void) snprintf(namebuf, sizeof (namebuf), "%s%s",
gfi->prefix, fieldname);
if (strcmp(gfi->dotname, namebuf) == 0) {
gfi->fld_off = byteoff;
gfi->fld_type = mbrtid;
return (1);
}
(void) strlcat(namebuf, ".", sizeof (namebuf));
len = strlen(namebuf);
if (strncmp(gfi->dotname, namebuf, len) != 0)
return (0);
typekind = ctf_type_kind(ctf, mbrtid);
switch (typekind) {
case CTF_K_STRUCT:
case CTF_K_UNION:
break;
default:
return (0);
}
saveprefix = gfi->prefix;
saveoff = gfi->base_off;
gfi->prefix = namebuf;
gfi->base_off = byteoff;
rc = ctf_member_iter(ctf, mbrtid, gfi_iter, gfi);
gfi->prefix = saveprefix;
gfi->base_off = saveoff;
return (rc);
}