aboutsummaryrefslogtreecommitdiff
path: root/cddl/contrib/opensolaris/common/ctf/ctf_impl.h
blob: f56fa6a00548ce65a201fe9dedfb5612915adbd3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */

/*
 * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */
/*
 * Copyright (c) 2012, Joyent, Inc.  All rights reserved.
 */

#ifndef	_CTF_IMPL_H
#define	_CTF_IMPL_H

#include <sys/types.h>
#include <sys/errno.h>
#include <sys/sysmacros.h>
#include <sys/ctf_api.h>

#ifdef _KERNEL

#include <sys/systm.h>
#include <sys/cmn_err.h>
#include <sys/varargs.h>

#define	isspace(c) \
	((c) == ' ' || (c) == '\t' || (c) == '\n' || \
	(c) == '\r' || (c) == '\f' || (c) == '\v')

#define	MAP_FAILED	((void *)-1)

#else	/* _KERNEL */

#include <strings.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <limits.h>
#include <ctype.h>

#endif	/* _KERNEL */

#ifdef	__cplusplus
extern "C" {
#endif

typedef struct ctf_helem {
	uint_t h_name;		/* reference to name in string table */
	ushort_t h_type;	/* corresponding type ID number */
	ushort_t h_next;	/* index of next element in hash chain */
} ctf_helem_t;

typedef struct ctf_hash {
	ushort_t *h_buckets;	/* hash bucket array (chain indices) */
	ctf_helem_t *h_chains;	/* hash chains buffer */
	ushort_t h_nbuckets;	/* number of elements in bucket array */
	ushort_t h_nelems;	/* number of elements in hash table */
	uint_t h_free;		/* index of next free hash element */
} ctf_hash_t;

typedef struct ctf_strs {
	const char *cts_strs;	/* base address of string table */
	size_t cts_len;		/* size of string table in bytes */
} ctf_strs_t;

typedef struct ctf_dmodel {
	const char *ctd_name;	/* data model name */
	int ctd_code;		/* data model code */
	size_t ctd_pointer;	/* size of void * in bytes */
	size_t ctd_char;	/* size of char in bytes */
	size_t ctd_short;	/* size of short in bytes */
	size_t ctd_int;		/* size of int in bytes */
	size_t ctd_long;	/* size of long in bytes */
} ctf_dmodel_t;

typedef struct ctf_lookup {
	const char *ctl_prefix;	/* string prefix for this lookup */
	size_t ctl_len;		/* length of prefix string in bytes */
	ctf_hash_t *ctl_hash;	/* pointer to hash table for lookup */
} ctf_lookup_t;

typedef struct ctf_fileops {
	ushort_t (*ctfo_get_kind)(ushort_t);
	ushort_t (*ctfo_get_root)(ushort_t);
	ushort_t (*ctfo_get_vlen)(ushort_t);
} ctf_fileops_t;

typedef struct ctf_list {
	struct ctf_list *l_prev; /* previous pointer or tail pointer */
	struct ctf_list *l_next; /* next pointer or head pointer */
} ctf_list_t;

typedef enum {
	CTF_PREC_BASE,
	CTF_PREC_POINTER,
	CTF_PREC_ARRAY,
	CTF_PREC_FUNCTION,
	CTF_PREC_MAX
} ctf_decl_prec_t;

typedef struct ctf_decl_node {
	ctf_list_t cd_list;			/* linked list pointers */
	ctf_id_t cd_type;			/* type identifier */
	uint_t cd_kind;				/* type kind */
	uint_t cd_n;				/* type dimension if array */
} ctf_decl_node_t;

typedef struct ctf_decl {
	ctf_list_t cd_nodes[CTF_PREC_MAX];	/* declaration node stacks */
	int cd_order[CTF_PREC_MAX];		/* storage order of decls */
	ctf_decl_prec_t cd_qualp;		/* qualifier precision */
	ctf_decl_prec_t cd_ordp;		/* ordered precision */
	char *cd_buf;				/* buffer for output */
	char *cd_ptr;				/* buffer location */
	char *cd_end;				/* buffer limit */
	size_t cd_len;				/* buffer space required */
	int cd_err;				/* saved error value */
} ctf_decl_t;

typedef struct ctf_dmdef {
	ctf_list_t dmd_list;	/* list forward/back pointers */
	char *dmd_name;		/* name of this member */
	ctf_id_t dmd_type;	/* type of this member (for sou) */
	ulong_t dmd_offset;	/* offset of this member in bits (for sou) */
	int dmd_value;		/* value of this member (for enum) */
} ctf_dmdef_t;

typedef struct ctf_dtdef {
	ctf_list_t dtd_list;	/* list forward/back pointers */
	struct ctf_dtdef *dtd_hash; /* hash chain pointer for ctf_dthash */
	char *dtd_name;		/* name associated with definition (if any) */
	ctf_id_t dtd_type;	/* type identifier for this definition */
	ctf_type_t dtd_data;	/* type node (see <sys/ctf.h>) */
	int dtd_ref;		/* recfount for dyanmic types */
	union {
		ctf_list_t dtu_members;	/* struct, union, or enum */
		ctf_arinfo_t dtu_arr;	/* array */
		ctf_encoding_t dtu_enc;	/* integer or float */
		ctf_id_t *dtu_argv;	/* function */
	} dtd_u;
} ctf_dtdef_t;

typedef struct ctf_bundle {
	ctf_file_t *ctb_file;	/* CTF container handle */
	ctf_id_t ctb_type;	/* CTF type identifier */
	ctf_dtdef_t *ctb_dtd;	/* CTF dynamic type definition (if any) */
} ctf_bundle_t;

/*
 * The ctf_file is the structure used to represent a CTF container to library
 * clients, who see it only as an opaque pointer.  Modifications can therefore
 * be made freely to this structure without regard to client versioning.  The
 * ctf_file_t typedef appears in <sys/ctf_api.h> and declares a forward tag.
 *
 * NOTE: ctf_update() requires that everything inside of ctf_file either be an
 * immediate value, a pointer to dynamically allocated data *outside* of the
 * ctf_file itself, or a pointer to statically allocated data.  If you add a
 * pointer to ctf_file that points to something within the ctf_file itself,
 * you must make corresponding changes to ctf_update().
 */
struct ctf_file {
	const ctf_fileops_t *ctf_fileops; /* version-specific file operations */
	ctf_sect_t ctf_data;	/* CTF data from object file */
	ctf_sect_t ctf_symtab;	/* symbol table from object file */
	ctf_sect_t ctf_strtab;	/* string table from object file */
	ctf_hash_t ctf_structs;	/* hash table of struct types */
	ctf_hash_t ctf_unions;	/* hash table of union types */
	ctf_hash_t ctf_enums;	/* hash table of enum types */
	ctf_hash_t ctf_names;	/* hash table of remaining type names */
	ctf_lookup_t ctf_lookups[5];	/* pointers to hashes for name lookup */
	ctf_strs_t ctf_str[2];	/* array of string table base and bounds */
	const uchar_t *ctf_base; /* base of CTF header + uncompressed buffer */
	const uchar_t *ctf_buf;	/* uncompressed CTF data buffer */
	size_t ctf_size;	/* size of CTF header + uncompressed data */
	uint_t *ctf_sxlate;	/* translation table for symtab entries */
	ulong_t ctf_nsyms;	/* number of entries in symtab xlate table */
	uint_t *ctf_txlate;	/* translation table for type IDs */
	ushort_t *ctf_ptrtab;	/* translation table for pointer-to lookups */
	ulong_t ctf_typemax;	/* maximum valid type ID number */
	const ctf_dmodel_t *ctf_dmodel;	/* data model pointer (see above) */
	struct ctf_file *ctf_parent;	/* parent CTF container (if any) */
	const char *ctf_parlabel;	/* label in parent container (if any) */
	const char *ctf_parname;	/* basename of parent (if any) */
	uint_t ctf_refcnt;	/* reference count (for parent links) */
	uint_t ctf_flags;	/* libctf flags (see below) */
	int ctf_errno;		/* error code for most recent error */
	int ctf_version;	/* CTF data version */
	ctf_dtdef_t **ctf_dthash; /* hash of dynamic type definitions */
	ulong_t ctf_dthashlen;	/* size of dynamic type hash bucket array */
	ctf_list_t ctf_dtdefs;	/* list of dynamic type definitions */
	size_t ctf_dtstrlen;	/* total length of dynamic type strings */
	ulong_t ctf_dtnextid;	/* next dynamic type id to assign */
	ulong_t ctf_dtoldid;	/* oldest id that has been committed */
	void *ctf_specific;	/* data for ctf_get/setspecific */
};

#define	LCTF_INDEX_TO_TYPEPTR(fp, i) \
	((ctf_type_t *)((uintptr_t)(fp)->ctf_buf + (fp)->ctf_txlate[(i)]))

#define	LCTF_INFO_KIND(fp, info)	((fp)->ctf_fileops->ctfo_get_kind(info))
#define	LCTF_INFO_ROOT(fp, info)	((fp)->ctf_fileops->ctfo_get_root(info))
#define	LCTF_INFO_VLEN(fp, info)	((fp)->ctf_fileops->ctfo_get_vlen(info))

#define	LCTF_MMAP	0x0001	/* libctf should munmap buffers on close */
#define	LCTF_CHILD	0x0002	/* CTF container is a child */
#define	LCTF_RDWR	0x0004	/* CTF container is writable */
#define	LCTF_DIRTY	0x0008	/* CTF container has been modified */

#define	ECTF_BASE	1000	/* base value for libctf errnos */

enum {
	ECTF_FMT = ECTF_BASE,	/* file is not in CTF or ELF format */
	ECTF_ELFVERS,		/* ELF version is more recent than libctf */
	ECTF_CTFVERS,		/* CTF version is more recent than libctf */
	ECTF_ENDIAN,		/* data is different endian-ness than lib */
	ECTF_SYMTAB,		/* symbol table uses invalid entry size */
	ECTF_SYMBAD,		/* symbol table data buffer invalid */
	ECTF_STRBAD,		/* string table data buffer invalid */
	ECTF_CORRUPT,		/* file data corruption detected */
	ECTF_NOCTFDATA,		/* ELF file does not contain CTF data */
	ECTF_NOCTFBUF,		/* buffer does not contain CTF data */
	ECTF_NOSYMTAB,		/* symbol table data is not available */
	ECTF_NOPARENT,		/* parent CTF container is not available */
	ECTF_DMODEL,		/* data model mismatch */
	ECTF_MMAP,		/* failed to mmap a data section */
	ECTF_ZMISSING,		/* decompression library not installed */
	ECTF_ZINIT,		/* failed to initialize decompression library */
	ECTF_ZALLOC,		/* failed to allocate decompression buffer */
	ECTF_DECOMPRESS,	/* failed to decompress CTF data */
	ECTF_STRTAB,		/* string table for this string is missing */
	ECTF_BADNAME,		/* string offset is corrupt w.r.t. strtab */
	ECTF_BADID,		/* invalid type ID number */
	ECTF_NOTSOU,		/* type is not a struct or union */
	ECTF_NOTENUM,		/* type is not an enum */
	ECTF_NOTSUE,		/* type is not a struct, union, or enum */
	ECTF_NOTINTFP,		/* type is not an integer or float */
	ECTF_NOTARRAY,		/* type is not an array */
	ECTF_NOTREF,		/* type does not reference another type */
	ECTF_NAMELEN,		/* buffer is too small to hold type name */
	ECTF_NOTYPE,		/* no type found corresponding to name */
	ECTF_SYNTAX,		/* syntax error in type name */
	ECTF_NOTFUNC,		/* symtab entry does not refer to a function */
	ECTF_NOFUNCDAT,		/* no func info available for function */
	ECTF_NOTDATA,		/* symtab entry does not refer to a data obj */
	ECTF_NOTYPEDAT,		/* no type info available for object */
	ECTF_NOLABEL,		/* no label found corresponding to name */
	ECTF_NOLABELDATA,	/* file does not contain any labels */
	ECTF_NOTSUP,		/* feature not supported */
	ECTF_NOENUMNAM,		/* enum element name not found */
	ECTF_NOMEMBNAM,		/* member name not found */
	ECTF_RDONLY,		/* CTF container is read-only */
	ECTF_DTFULL,		/* CTF type is full (no more members allowed) */
	ECTF_FULL,		/* CTF container is full */
	ECTF_DUPMEMBER,		/* duplicate member name definition */
	ECTF_CONFLICT,		/* conflicting type definition present */
	ECTF_REFERENCED,	/* type has outstanding references */
	ECTF_NOTDYN		/* type is not a dynamic type */
};

extern ssize_t ctf_get_ctt_size(const ctf_file_t *, const ctf_type_t *,
    ssize_t *, ssize_t *);

extern const ctf_type_t *ctf_lookup_by_id(ctf_file_t **, ctf_id_t);

extern int ctf_hash_create(ctf_hash_t *, ulong_t);
extern int ctf_hash_insert(ctf_hash_t *, ctf_file_t *, ushort_t, uint_t);
extern int ctf_hash_define(ctf_hash_t *, ctf_file_t *, ushort_t, uint_t);
extern ctf_helem_t *ctf_hash_lookup(ctf_hash_t *, ctf_file_t *,
    const char *, size_t);
extern uint_t ctf_hash_size(const ctf_hash_t *);
extern void ctf_hash_destroy(ctf_hash_t *);

#define	ctf_list_prev(elem)	((void *)(((ctf_list_t *)(elem))->l_prev))
#define	ctf_list_next(elem)	((void *)(((ctf_list_t *)(elem))->l_next))

extern void ctf_list_append(ctf_list_t *, void *);
extern void ctf_list_prepend(ctf_list_t *, void *);
extern void ctf_list_delete(ctf_list_t *, void *);

extern void ctf_dtd_insert(ctf_file_t *, ctf_dtdef_t *);
extern void ctf_dtd_delete(ctf_file_t *, ctf_dtdef_t *);
extern ctf_dtdef_t *ctf_dtd_lookup(ctf_file_t *, ctf_id_t);

extern void ctf_decl_init(ctf_decl_t *, char *, size_t);
extern void ctf_decl_fini(ctf_decl_t *);
extern void ctf_decl_push(ctf_decl_t *, ctf_file_t *, ctf_id_t);
extern void ctf_decl_sprintf(ctf_decl_t *, const char *, ...);

extern const char *ctf_strraw(ctf_file_t *, uint_t);
extern const char *ctf_strptr(ctf_file_t *, uint_t);

extern ctf_file_t *ctf_set_open_errno(int *, int);
extern long ctf_set_errno(ctf_file_t *, int);

extern const void *ctf_sect_mmap(ctf_sect_t *, int);
extern void ctf_sect_munmap(const ctf_sect_t *);

extern void *ctf_data_alloc(size_t);
extern void ctf_data_free(void *, size_t);
extern void ctf_data_protect(void *, size_t);

extern void *ctf_alloc(size_t);
extern void ctf_free(void *, size_t);

extern char *ctf_strdup(const char *);
extern const char *ctf_strerror(int);
extern void ctf_dprintf(const char *, ...);

extern void *ctf_zopen(int *);

extern const char _CTF_SECTION[];	/* name of CTF ELF section */
extern const char _CTF_NULLSTR[];	/* empty string */

extern int _libctf_version;		/* library client version */
extern int _libctf_debug;		/* debugging messages enabled */

#ifdef	__cplusplus
}
#endif

#endif	/* _CTF_IMPL_H */