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