Home | History | Annotate | Line # | Download | only in cvt
ctftools.h revision 1.8.14.1
      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  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #ifndef _CTFTOOLS_H
     27 #define	_CTFTOOLS_H
     28 
     29 /*
     30  * Functions and data structures used in the manipulation of stabs and CTF data
     31  */
     32 
     33 #include <stdio.h>
     34 #include <stdlib.h>
     35 #include <stdarg.h>
     36 #include <libelf.h>
     37 #include <gelf.h>
     38 #include <pthread.h>
     39 
     40 #include <sys/ccompile.h>
     41 
     42 #ifdef __cplusplus
     43 extern "C" {
     44 #endif
     45 
     46 #include "list.h"
     47 #include "hash.h"
     48 
     49 #ifndef DEBUG_LEVEL
     50 #define	DEBUG_LEVEL 0
     51 #endif
     52 #ifndef DEBUG_PARSE
     53 #define	DEBUG_PARSE 0
     54 #endif
     55 
     56 #ifndef DEBUG_STREAM
     57 #define	DEBUG_STREAM stderr
     58 #endif
     59 
     60 #ifndef MAX
     61 #define	MAX(a, b) 		((a) < (b) ? (b) : (a))
     62 #endif
     63 
     64 #ifndef MIN
     65 #define	MIN(a, b) 		((a) > (b) ? (b) : (a))
     66 #endif
     67 
     68 /* Sanity check for cross-build bootstrap tools */
     69 #if !defined(BYTE_ORDER)
     70 #error "Missing BYTE_ORDER defines"
     71 #elif !defined(LITTLE_ENDIAN)
     72 #error "Missing LITTLE_ENDIAN defines"
     73 #elif !defined(BIG_ENDIAN)
     74 #error "Missing BIG_ENDIAN defines"
     75 #endif
     76 
     77 #ifndef TRUE
     78 #define	TRUE	1
     79 #endif
     80 #ifndef FALSE
     81 #define	FALSE	0
     82 #endif
     83 
     84 #define	CTF_ELF_SCN_NAME	".SUNW_ctf"
     85 
     86 #define	CTF_LABEL_LASTIDX	-1
     87 
     88 #define	CTF_DEFAULT_LABEL	"*** No Label Provided ***"
     89 
     90 /*
     91  * Default hash sizes
     92  */
     93 #define	TDATA_LAYOUT_HASH_SIZE	8191	/* A tdesc hash based on layout */
     94 #define	TDATA_ID_HASH_SIZE	997	/* A tdesc hash based on type id */
     95 #define	IIDESC_HASH_SIZE	8191	/* Hash of iidesc's */
     96 
     97 /*
     98  * The default function argument array size.  We'll realloc the array larger
     99  * if we need to, but we want a default value that will allow us to avoid
    100  * reallocation in the common case.
    101  */
    102 #define	FUNCARG_DEF	5
    103 
    104 extern const char *progname;
    105 extern int debug_level;
    106 extern int debug_parse;
    107 extern char *curhdr;
    108 
    109 /*
    110  * This is a partial copy of the stab.h that DevPro includes with their
    111  * compiler.
    112  */
    113 typedef struct stab {
    114 	uint32_t	n_strx;
    115 	uint8_t		n_type;
    116 	int8_t		n_other;
    117 	int16_t		n_desc;
    118 	uint32_t	n_value;
    119 } stab_t;
    120 
    121 #define	N_GSYM	0x20	/* global symbol: name,,0,type,0 */
    122 #define	N_FUN	0x24	/* procedure: name,,0,linenumber,0 */
    123 #define	N_STSYM	0x26	/* static symbol: name,,0,type,0 or section relative */
    124 #define	N_LCSYM	0x28	/* .lcomm symbol: name,,0,type,0 or section relative */
    125 #define	N_ROSYM	0x2c	/* ro_data: name,,0,type,0 or section relative */
    126 #define	N_OPT	0x3c	/* compiler options */
    127 #define	N_RSYM	0x40	/* register sym: name,,0,type,register */
    128 #define	N_SO	0x64	/* source file name: name,,0,0,0 */
    129 #define	N_LSYM	0x80	/* local sym: name,,0,type,offset */
    130 #define	N_SOL	0x84	/* #included file name: name,,0,0,0 */
    131 #define	N_PSYM	0xa0	/* parameter: name,,0,type,offset */
    132 #define	N_LBRAC	0xc0	/* left bracket: 0,,0,nesting level,function relative */
    133 #define	N_RBRAC	0xe0	/* right bracket: 0,,0,nesting level,func relative */
    134 #define	N_BINCL 0x82	/* header file: name,,0,0,0 */
    135 #define	N_EINCL 0xa2	/* end of include file */
    136 
    137 /*
    138  * Nodes in the type tree
    139  *
    140  * Each node consists of a single tdesc_t, with one of several auxiliary
    141  * structures linked in via the `data' union.
    142  */
    143 
    144 /* The type of tdesc_t node */
    145 typedef enum stabtype {
    146 	STABTYPE_FIRST, /* do not use */
    147 	INTRINSIC,
    148 	POINTER,
    149 	REFERENCE,
    150 	ARRAY,
    151 	FUNCTION,
    152 	STRUCT,
    153 	UNION,
    154 	CLASS,
    155 	ENUM,
    156 	FORWARD,
    157 	TYPEDEF,
    158 	TYPEDEF_UNRES,
    159 	VOLATILE,
    160 	CONST,
    161 	RESTRICT,
    162 	STABTYPE_LAST /* do not use */
    163 } stabtype_t;
    164 
    165 typedef struct tdesc tdesc_t;
    166 
    167 /* Auxiliary structure for array tdesc_t */
    168 typedef struct ardef {
    169 	tdesc_t	*ad_contents;
    170 	tdesc_t *ad_idxtype;
    171 	uint_t	ad_nelems;
    172 } ardef_t;
    173 
    174 /* Auxiliary structure for structure/union tdesc_t */
    175 typedef struct mlist {
    176 	int	ml_offset;	/* Offset from start of structure (in bits) */
    177 	uint_t	ml_size;	/* Member size (in bits) */
    178 	char	*ml_name;	/* Member name */
    179 	struct	tdesc *ml_type;	/* Member type */
    180 	struct	mlist *ml_next;	/* Next member */
    181 } mlist_t;
    182 
    183 /* Auxiliary structure for enum tdesc_t */
    184 typedef struct elist {
    185 	char	*el_name;
    186 	int	el_number;
    187 	struct elist *el_next;
    188 } elist_t;
    189 
    190 /* Auxiliary structure for intrinsics (integers and reals) */
    191 typedef enum {
    192 	INTR_INT,
    193 	INTR_REAL
    194 } intrtype_t;
    195 
    196 typedef struct intr {
    197 	intrtype_t	intr_type;
    198 	int		intr_signed;
    199 	union {
    200 			char _iformat;
    201 			int _fformat;
    202 	} _u;
    203 	int		intr_offset;
    204 	int		intr_nbits;
    205 } intr_t;
    206 
    207 #define	intr_iformat _u._iformat
    208 #define	intr_fformat _u._fformat
    209 
    210 typedef struct fnarg {
    211 	char *fna_name;
    212 	struct tdesc *fna_type;
    213 } fnarg_t;
    214 
    215 #define	FN_F_GLOBAL	0x1
    216 #define	FN_F_VARARGS	0x2
    217 
    218 typedef struct fndef {
    219 	struct tdesc *fn_ret;
    220 	uint_t fn_nargs;
    221 	tdesc_t **fn_args;
    222 	uint_t fn_vargs;
    223 } fndef_t;
    224 
    225 typedef int32_t tid_t;
    226 
    227 /*
    228  * The tdesc_t (Type DESCription) is the basic node type used in the stabs data
    229  * structure.  Each data node gets a tdesc structure.  Each node is linked into
    230  * a directed graph (think of it as a tree with multiple roots and multiple
    231  * leaves), with the root nodes at the top, and intrinsics at the bottom.  The
    232  * root nodes, which are pointed to by iidesc nodes, correspond to the types,
    233  * globals, and statics defined by the stabs.
    234  */
    235 struct tdesc {
    236 	char	*t_name;
    237 	tdesc_t *t_next;	/* Name hash next pointer */
    238 
    239 	tid_t t_id;
    240 	tdesc_t *t_hash;	/* ID hash next pointer */
    241 
    242 	stabtype_t t_type;
    243 	int	t_size;	/* Size in bytes of object represented by this node */
    244 
    245 	union {
    246 		intr_t	*intr;		/* int, real */
    247 		tdesc_t *tdesc;		/* ptr, typedef, vol, const, restr */
    248 		ardef_t *ardef;		/* array */
    249 		mlist_t *members;	/* struct, union */
    250 		elist_t *emem;		/* enum */
    251 		fndef_t *fndef;		/* function - first is return type */
    252 	} t_data;
    253 
    254 	int t_flags;
    255 	int t_vgen;	/* Visitation generation (see traverse.c) */
    256 	int t_emark;	/* Equality mark (see equiv_cb() in merge.c) */
    257 };
    258 
    259 #define	t_intr		t_data.intr
    260 #define	t_tdesc		t_data.tdesc
    261 #define	t_ardef		t_data.ardef
    262 #define	t_members	t_data.members
    263 #define	t_emem		t_data.emem
    264 #define	t_fndef		t_data.fndef
    265 
    266 #define	TDESC_F_ISROOT		0x1	/* Has an iidesc_t (see below) */
    267 #define	TDESC_F_GLOBAL		0x2
    268 #define	TDESC_F_RESOLVED	0x4
    269 
    270 /*
    271  * iidesc_t (Interesting Item DESCription) nodes point to tdesc_t nodes that
    272  * correspond to "interesting" stabs.  A stab is interesting if it defines a
    273  * global or static variable, a global or static function, or a data type.
    274  */
    275 typedef enum iitype {
    276 	II_NOT = 0,
    277 	II_GFUN,	/* Global function */
    278 	II_SFUN,	/* Static function */
    279 	II_GVAR,	/* Global variable */
    280 	II_SVAR,	/* Static variable */
    281 	II_PSYM,	/* Function argument */
    282 	II_SOU,		/* Struct or union */
    283 	II_TYPE		/* Type (typedef) */
    284 } iitype_t;
    285 
    286 typedef struct iidesc {
    287 	iitype_t	ii_type;
    288 	char		*ii_name;
    289 	tdesc_t 	*ii_dtype;
    290 	char		*ii_owner;	/* File that defined this node */
    291 	int		ii_flags;
    292 
    293 	/* Function arguments (if any) */
    294 	int		ii_nargs;
    295 	tdesc_t 	**ii_args;
    296 	int		ii_vargs;	/* Function uses varargs */
    297 } iidesc_t;
    298 
    299 #define	IIDESC_F_USED	0x1	/* Write this iidesc out */
    300 
    301 /*
    302  * labelent_t nodes identify labels and corresponding type ranges associated
    303  * with them.  The label in a given labelent_t is associated with types with
    304  * ids <= le_idx.
    305  */
    306 typedef struct labelent {
    307 	char *le_name;
    308 	int le_idx;
    309 } labelent_t;
    310 
    311 /*
    312  * The tdata_t (Type DATA) structure contains or references all type data for
    313  * a given file or, during merging, several files.
    314  */
    315 typedef struct tdata {
    316 	int	td_curemark;	/* Equality mark (see merge.c) */
    317 	int	td_curvgen;	/* Visitation generation (see traverse.c) */
    318 	int	td_nextid;	/* The ID for the next tdesc_t created */
    319 	hash_t	*td_iihash;	/* The iidesc_t nodes for this file */
    320 
    321 	hash_t	*td_layouthash;	/* The tdesc nodes, hashed by structure */
    322 	hash_t	*td_idhash;	/* The tdesc nodes, hashed by type id */
    323 	list_t	*td_fwdlist;	/* All forward declaration tdesc nodes */
    324 
    325 	char	*td_parlabel;	/* Top label uniq'd against in parent */
    326 	char	*td_parname;	/* Basename of parent */
    327 	list_t	*td_labels;	/* Labels and their type ranges */
    328 
    329 	pthread_mutex_t td_mergelock;
    330 
    331 	int	td_ref;
    332 } tdata_t;
    333 
    334 /*
    335  * By design, the iidesc hash is heterogeneous.  The CTF emitter, on the
    336  * other hand, needs to be able to access the elements of the list by type,
    337  * and in a specific sorted order.  An iiburst holds these elements in that
    338  * order.  (A burster is a machine that separates carbon-copy forms)
    339  */
    340 typedef struct iiburst {
    341 	int iib_nfuncs;
    342 	int iib_curfunc;
    343 	iidesc_t **iib_funcs;
    344 
    345 	int iib_nobjts;
    346 	int iib_curobjt;
    347 	iidesc_t **iib_objts;
    348 
    349 	list_t *iib_types;
    350 	int iib_maxtypeid;
    351 
    352 	tdata_t *iib_td;
    353 	struct tdtrav_data *iib_tdtd; /* tdtrav_data_t */
    354 } iiburst_t;
    355 
    356 typedef struct ctf_buf ctf_buf_t;
    357 
    358 typedef struct symit_data symit_data_t;
    359 
    360 /* fixup_tdescs.c */
    361 void cvt_fixstabs(tdata_t *);
    362 void cvt_fixups(tdata_t *, size_t);
    363 
    364 /* ctf.c */
    365 caddr_t ctf_gen(iiburst_t *, size_t *, int);
    366 tdata_t *ctf_load(char *, caddr_t, size_t, symit_data_t *, char *);
    367 
    368 /* iidesc.c */
    369 iidesc_t *iidesc_new(char *);
    370 int iidesc_hash(int, void *);
    371 void iter_iidescs_by_name(tdata_t *, const char *,
    372     int (*)(void *, void *), void *);
    373 iidesc_t *iidesc_dup(iidesc_t *);
    374 iidesc_t *iidesc_dup_rename(iidesc_t *, char const *, char const *);
    375 void iidesc_add(hash_t *, iidesc_t *);
    376 void iidesc_free(void *, void *);
    377 int iidesc_count_type(void *, void *);
    378 void iidesc_stats(hash_t *);
    379 int iidesc_dump(iidesc_t *);
    380 
    381 /* input.c */
    382 typedef enum source_types {
    383 	SOURCE_NONE 	= 0,
    384 	SOURCE_UNKNOWN	= 1,
    385 	SOURCE_C	= 2,
    386 	SOURCE_S	= 4
    387 } source_types_t;
    388 
    389 source_types_t built_source_types(Elf *, const char *);
    390 int count_files(char **, int);
    391 int read_ctf(char **, int, char *, int (*)(tdata_t *, char *, void *),
    392     void *, int);
    393 int read_ctf_save_cb(tdata_t *, char *, void *);
    394 symit_data_t *symit_new(Elf *, const char *);
    395 void symit_reset(symit_data_t *);
    396 char *symit_curfile(symit_data_t *);
    397 GElf_Sym *symit_next(symit_data_t *, int);
    398 char *symit_name(symit_data_t *);
    399 void symit_free(symit_data_t *);
    400 
    401 /* merge.c */
    402 void merge_into_master(tdata_t *, tdata_t *, tdata_t *, int);
    403 
    404 /* output.c */
    405 #define	CTF_FUZZY_MATCH	0x1 /* match local symbols to global CTF */
    406 #define	CTF_USE_DYNSYM	0x2 /* use .dynsym not .symtab */
    407 #define	CTF_COMPRESS	0x4 /* compress CTF output */
    408 #define	CTF_KEEP_STABS	0x8 /* keep .stabs sections */
    409 #define	CTF_SWAP_BYTES	0x10 /* target byte order is different from host */
    410 
    411 void write_ctf(tdata_t *, const char *, const char *, int);
    412 
    413 /* parse.c */
    414 void parse_init(tdata_t *);
    415 void parse_finish(tdata_t *);
    416 int parse_stab(stab_t *, char *, iidesc_t **);
    417 tdesc_t *lookup(int);
    418 tdesc_t *lookupname(const char *);
    419 void check_hash(void);
    420 void resolve_typed_bitfields(void);
    421 
    422 /* stabs.c */
    423 int stabs_read(tdata_t *, Elf *, char *);
    424 
    425 /* dwarf.c */
    426 int dw_read(tdata_t *, Elf *, char *);
    427 const char *dw_tag2str(uint_t);
    428 
    429 /* tdata.c */
    430 tdata_t *tdata_new(void);
    431 void tdata_free(tdata_t *);
    432 void tdata_build_hashes(tdata_t *td);
    433 const char *tdesc_name(tdesc_t *);
    434 int tdesc_idhash(int, void *);
    435 int tdesc_idcmp(void *, void *);
    436 int tdesc_namehash(int, void *);
    437 int tdesc_namecmp(void *, void *);
    438 int tdesc_layouthash(int, void *);
    439 int tdesc_layoutcmp(void *, void *);
    440 void tdesc_free(tdesc_t *);
    441 void tdata_label_add(tdata_t *, const char *, int);
    442 labelent_t *tdata_label_top(tdata_t *);
    443 int tdata_label_find(tdata_t *, char *);
    444 void tdata_label_free(tdata_t *);
    445 void tdata_merge(tdata_t *, tdata_t *);
    446 void tdata_label_newmax(tdata_t *, int);
    447 
    448 /* util.c */
    449 int streq(const char *, const char *);
    450 int findelfsecidx(Elf *, const char *, const char *);
    451 size_t elf_ptrsz(Elf *);
    452 char *mktmpname(const char *, const char *);
    453 void terminate(const char *, ...) __printflike(1, 2) __dead;
    454 void aborterr(const char *, ...) __printflike(1, 2) __dead;
    455 void set_terminate_cleanup(void (*)(void));
    456 void elfterminate(const char *, const char *, ...) __printflike(2, 3) __dead;
    457 void warning(const char *, ...) __printflike(1, 2);
    458 void vadebug(int, const char *, va_list) __printflike(2, 0);
    459 void debug(int, const char *, ...) __printflike(2, 3);
    460 
    461 
    462 void watch_dump(int);
    463 void watch_set(void *, int);
    464 
    465 #ifdef __cplusplus
    466 }
    467 #endif
    468 
    469 #endif /* _CTFTOOLS_H */
    470