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