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