]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - cddl/contrib/opensolaris/tools/ctf/cvt/ctftools.h
Fix cddl tools bootstrapping on macOS and Linux
[FreeBSD/FreeBSD.git] / cddl / contrib / opensolaris / tools / ctf / cvt / ctftools.h
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 */