/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*/
/*
* This program is used to generate the contents of the
* struct_layout_XXX.c files that contain per-archtecture
* structure layout information.
*
* Although not part of elfdump, it is built by the makefile
* along with it.
* To use it:
*
* 1) Run it, capturing the output in a file.
* 2) If this is a replacement for an existing file,
* diff the new and old copies to ensure only
* the changes you expected are present.
* 3) Put the new file in the common directory under the name
* struct_layout_XXX.c, where XXX is the name of
* the architecture (i386, amd64, sparc, sparcv9, etc).
* 2) Add any necessary header and copyright comments.
* 3) If this is a new architecture:
* - Add an extern statement for struct_layout_XXX()
* to struct_layout.h
* - Add a case for it to the function sl_struct_layout()
* in struct_layout.c.
*/
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <err.h>
#include <libctf.h>
/*
* This extracts CTF information from a temporary object file.
*
* START and END bracket a struct layout definition. They issue
* the typedef boilerplate, and the standard first element (sizeof)
* which captures the overall size of the structure.
*
* SCALAR_FIELD is for scalar struct fields
*
* ARRAY_FIELD is for array struct fields
*
* ARRAY_TYPE is for plain (non-struct) array types
*/
#define END (void) \
do_end()
static void do_end(void);
static void do_start_name(char *name);
static void get_ctf_file(char *fname);
static char *objfile;
static char *machname;
static void
gen_auxv(void)
{
END;
}
/* prgregset_t, <sys/prgregset.h> */
static void
gen_prgregset(void)
{
ARRAY_TYPE(prgregset_t, 0);
END;
}
static void
gen_lwpstatus(void)
{
END;
}
static void
gen_pstatus(void)
{
END;
}
/* prstatus_t, <sys/old_procfs.h> */
static void
gen_prstatus(void)
{
END;
}
static void
gen_psinfo(void)
{
END;
}
/* prpsinfo_t, <sys/old_procfs.h> */
static void
gen_prpsinfo(void)
{
END;
}
static void
gen_lwpsinfo(void)
{
END;
}
static void
gen_prcred(void)
{
END;
}
static void
gen_prpriv(void)
{
END;
}
static void
gen_priv_impl_info(void)
{
END;
}
static void
gen_fltset(void)
{
END;
}
/*
*
* Note: many siginfo_t members are #defines mapping to
* long dotted members of sub-structs or unions, and
* we need the full member spec (with dots) for those.
*/
static void
gen_siginfo(void)
{
"__data.__proc.__pdata.__kill.__value.sival_int");
"__data.__proc.__pdata.__kill.__value.sival_ptr");
"__data.__proc.__pid");
"__data.__proc.__pdata.__kill.__uid");
"__data.__proc.__ctid");
"__data.__proc.__zoneid");
"__data.__rctl.__entity");
"__data.__fault.__addr");
"__data.__proc.__pdata.__cld.__status");
"__data.__file.__band");
END;
}
static void
gen_sigset(void)
{
END;
}
static void
gen_sigaction(void)
{
"_funcptr._handler");
"_funcptr._sigaction");
END;
}
static void
gen_stack(void)
{
END;
}
static void
gen_sysset(void)
{
END;
}
/* timestruc_t, <sys/time_impl.h> */
static void
gen_timestruc(void)
{
END;
}
static void
gen_utsname(void)
{
END;
}
static void
gen_prfdinfo(void)
{
END;
}
static void
gen_prsecflags(void)
{
END;
}
/*ARGSUSED*/
int
{
/* get obj file for input */
if (argc < 3) {
"usage: %s {object_file} {MACH}\n", argv[0]);
exit(1);
}
(void) printf("#include <struct_layout.h>\n");
gen_auxv();
gen_pstatus();
gen_prstatus();
gen_psinfo();
gen_prpsinfo();
gen_lwpsinfo();
gen_prcred();
gen_prpriv();
gen_fltset();
gen_siginfo();
gen_sigset();
gen_stack();
gen_sysset();
gen_utsname();
gen_prfdinfo();
/*
* Generate the full arch_layout description
*/
(void) printf(
"\n\n\n\nstatic const sl_arch_layout_t layout_%s = {\n",
machname);
(void) printf("};\n");
/*
* A public function, to make the information available
*/
(void) printf("\n\nconst sl_arch_layout_t *\n");
return (0);
}
/*
* Helper functions using the CTF library to get type info.
*/
static void
{
int ctferr;
ctf_errmsg(ctferr));
}
}
static void
{
(void) printf("\t{ %d,\t%d,\t%d,\t%d },\t\t/* %s */\n",
}
static void
{
}
static void
{
(void) printf("\n\nstatic const sl_%s_layout_t %s_layout = {\n",
}
static void
do_end(void)
{
(void) printf("};\n");
}
static void
{
int sz;
} else if (sz == 0) {
}
}
static void
{
if (rc < 0)
} else if (sz == 0) {
}
}
static void
{
int typekind;
if (rc < 0)
if (typekind != CTF_K_ARRAY)
if (rc != 0)
if (esz < 0)
}
static void
{
if (typekind != CTF_K_ARRAY)
if (rc != 0)
if (esz < 0)
}
struct gfinfo {
int base_off;
int fld_off;
int fld_type;
};
/*
* Lookup field "fname" in type "tname". If "dotname" is non-NULL,
* that's the full field name with dots, i.e. a_un.un_foo, which
* we must search for by walking the struct CTF recursively.
*/
static int
{
int typekind;
int rc;
/* If fname has a dot, use it as dotname too. */
switch (typekind) {
case CTF_K_STRUCT:
case CTF_K_UNION:
break;
default:
break;
}
if (rc < 0)
if (rc == 0)
return (0);
}
/*
* Iteration callback for ctf_member_iter
* Return <0 on error, 0 to keep looking, >0 for found.
*
* If no dotname, simple search for fieldname.
* If we're asked to search with dotname, we need to do a full
* recursive walk of the types under the dotname.
*/
int
{
char *saveprefix;
int saveoff;
int typekind;
int byteoff;
/* Easy cases first: no dotname */
return (1);
}
return (0);
}
/* Exact match on the dotname? */
return (1);
}
/*
* May need to recurse under this field, but
* only if there's a match through '.'
*/
return (0);
switch (typekind) {
case CTF_K_STRUCT:
case CTF_K_UNION:
break;
default:
return (0);
}
/* Recursively walk members */
return (rc);
}