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