summaryrefslogtreecommitdiff
path: root/pctf/ctf.h
blob: 2d1987be459f8b33b31c09ff4469223d3cb020c3 (plain)
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
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
/*
 * 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 2004 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef	_CTF_H
#define	_CTF_H

#if defined(sun)
#pragma ident	"%Z%%M%	%I%	%E% SMI"
#endif

#include <sys/types.h>

#ifdef	__cplusplus
extern "C" {
#endif

/*
 * CTF - Compact ANSI-C Type Format
 *
 * This file format can be used to compactly represent the information needed
 * by a debugger to interpret the ANSI-C types used by a given program.
 * Traditionally, this kind of information is generated by the compiler when
 * invoked with the -g flag and is stored in "stabs" strings or in the more
 * modern DWARF format.  CTF provides a representation of only the information
 * that is relevant to debugging a complex, optimized C program such as the
 * operating system kernel in a form that is significantly more compact than
 * the equivalent stabs or DWARF representation.  The format is data-model
 * independent, so consumers do not need different code depending on whether
 * they are 32-bit or 64-bit programs.  CTF assumes that a standard ELF symbol
 * table is available for use in the debugger, and uses the structure and data
 * of the symbol table to avoid storing redundant information.  The CTF data
 * may be compressed on disk or in memory, indicated by a bit in the header.
 * CTF may be interpreted in a raw disk file, or it may be stored in an ELF
 * section, typically named .SUNW_ctf.  Data structures are aligned so that
 * a raw CTF file or CTF ELF section may be manipulated using mmap(2).
 *
 * The CTF file or section itself has the following structure:
 *
 * +--------+--------+---------+----------+-------+--------+
 * |  file  |  type  |  data   | function | data  | string |
 * | header | labels | objects |   info   | types | table  |
 * +--------+--------+---------+----------+-------+--------+
 *
 * The file header stores a magic number and version information, encoding
 * flags, and the byte offset of each of the sections relative to the end of the
 * header itself.  If the CTF data has been uniquified against another set of
 * CTF data, a reference to that data also appears in the the header.  This
 * reference is the name of the label corresponding to the types uniquified
 * against.
 *
 * Following the header is a list of labels, used to group the types included in
 * the data types section.  Each label is accompanied by a type ID i.  A given
 * label refers to the group of types whose IDs are in the range [0, i].
 *
 * Data object and function records are stored in the same order as they appear
 * in the corresponding symbol table, except that symbols marked SHN_UNDEF are
 * not stored and symbols that have no type data are padded out with zeroes.
 * For each data object, the type ID (a small integer) is recorded.  For each
 * function, the type ID of the return type and argument types is recorded.
 *
 * The data types section is a list of variable size records that represent each
 * type, in order by their ID.  The types themselves form a directed graph,
 * where each node may contain one or more outgoing edges to other type nodes,
 * denoted by their ID.
 *
 * Strings are recorded as a string table ID (0 or 1) and a byte offset into the
 * string table.  String table 0 is the internal CTF string table.  String table
 * 1 is the external string table, which is the string table associated with the
 * ELF symbol table for this object.  CTF does not record any strings that are
 * already in the symbol table, and the CTF string table does not contain any
 * duplicated strings.
 *
 * If the CTF data has been merged with another parent CTF object, some outgoing
 * edges may refer to type nodes that exist in another CTF object.  The debugger
 * and libctf library are responsible for connecting the appropriate objects
 * together so that the full set of types can be explored and manipulated.
 */

#define	CTF_MAX_TYPE	0xffff	/* max type identifier value */
#define	CTF_MAX_NAME 0x7fffffff	/* max offset into a string table */
#define	CTF_MAX_VLEN	0x3ff	/* max struct, union, enum members or args */
#define	CTF_MAX_INTOFF	0xff	/* max offset of intrinsic value in bits */
#define	CTF_MAX_INTBITS	0xffff	/* max size of an intrinsic in bits */

/* See ctf_type_t */
#define	CTF_MAX_SIZE	0xfffe	/* max size of a type in bytes */
#define	CTF_LSIZE_SENT	0xffff	/* sentinel for ctt_size */
#define	CTF_MAX_LSIZE	UINT64_MAX

typedef struct ctf_preamble {
	ushort_t ctp_magic;	/* magic number (CTF_MAGIC) */
	uchar_t ctp_version;	/* data format version number (CTF_VERSION) */
	uchar_t ctp_flags;	/* flags (see below) */
} ctf_preamble_t;

typedef struct ctf_header {
	ctf_preamble_t cth_preamble;
	uint_t cth_parlabel;	/* ref to name of parent lbl uniq'd against */
	uint_t cth_parname;	/* ref to basename of parent */
	uint_t cth_lbloff;	/* offset of label section */
	uint_t cth_objtoff;	/* offset of object section */
	uint_t cth_funcoff;	/* offset of function section */
	uint_t cth_typeoff;	/* offset of type section */
	uint_t cth_stroff;	/* offset of string section */
	uint_t cth_strlen;	/* length of string section in bytes */
} ctf_header_t;

#define	cth_magic   cth_preamble.ctp_magic
#define	cth_version cth_preamble.ctp_version
#define	cth_flags   cth_preamble.ctp_flags

#ifdef CTF_OLD_VERSIONS

typedef struct ctf_header_v1 {
	ctf_preamble_t cth_preamble;
	uint_t cth_objtoff;
	uint_t cth_funcoff;
	uint_t cth_typeoff;
	uint_t cth_stroff;
	uint_t cth_strlen;
} ctf_header_v1_t;

#endif /* CTF_OLD_VERSIONS */

#define	CTF_MAGIC	0xcff1	/* magic number identifying header */

/* data format version number */
#define	CTF_VERSION_1	1
#define	CTF_VERSION_2	2
#define	CTF_VERSION	CTF_VERSION_2	/* current version */

#define	CTF_F_COMPRESS	0x1	/* data buffer is compressed */

typedef struct ctf_lblent {
	uint_t ctl_label;	/* ref to name of label */
	uint_t ctl_typeidx;	/* last type associated with this label */
} ctf_lblent_t;

typedef struct ctf_stype {
	uint_t ctt_name;	/* reference to name in string table */
	ushort_t ctt_info;	/* encoded kind, variant length (see below) */
	union {
		ushort_t _size;	/* size of entire type in bytes */
		ushort_t _type;	/* reference to another type */
	} _u;
} ctf_stype_t;

/*
 * type sizes, measured in bytes, come in two flavors.  99% of them fit within
 * (USHRT_MAX - 1), and thus can be stored in the ctt_size member of a
 * ctf_stype_t.  The maximum value for these sizes is CTF_MAX_SIZE.  The sizes
 * larger than CTF_MAX_SIZE must be stored in the ctt_lsize member of a
 * ctf_type_t.  Use of this member is indicated by the presence of
 * CTF_LSIZE_SENT in ctt_size.
 */
typedef struct ctf_type {
	uint_t ctt_name;	/* reference to name in string table */
	ushort_t ctt_info;	/* encoded kind, variant length (see below) */
	union {
		ushort_t _size;	/* always CTF_LSIZE_SENT */
		ushort_t _type; /* do not use */
	} _u;
	uint_t ctt_lsizehi;	/* high 32 bits of type size in bytes */
	uint_t ctt_lsizelo;	/* low 32 bits of type size in bytes */
} ctf_type_t;

#define	ctt_size _u._size	/* for fundamental types that have a size */
#define	ctt_type _u._type	/* for types that reference another type */

/*
 * The following macros compose and decompose values for ctt_info and
 * ctt_name, as well as other structures that contain name references.
 *
 *             ------------------------
 * ctt_info:   | kind | isroot | vlen |
 *             ------------------------
 *             15   11    10    9     0
 *
 * kind = CTF_INFO_KIND(c.ctt_info);     <-- CTF_K_* value (see below)
 * vlen = CTF_INFO_VLEN(c.ctt_info);     <-- length of variable data list
 *
 * stid = CTF_NAME_STID(c.ctt_name);     <-- string table id number (0 or 1)
 * offset = CTF_NAME_OFFSET(c.ctt_name); <-- string table byte offset
 *
 * c.ctt_info = CTF_TYPE_INFO(kind, vlen);
 * c.ctt_name = CTF_TYPE_NAME(stid, offset);
 */

#define	CTF_INFO_KIND(info)	(((info) & 0xf800) >> 11)
#define	CTF_INFO_ISROOT(info)	(((info) & 0x0400) >> 10)
#define	CTF_INFO_VLEN(info)	(((info) & CTF_MAX_VLEN))

#define	CTF_NAME_STID(name)	((name) >> 31)
#define	CTF_NAME_OFFSET(name)	((name) & 0x7fffffff)

#define	CTF_TYPE_INFO(kind, isroot, vlen) \
	(((kind) << 11) | (((isroot) ? 1 : 0) << 10) | ((vlen) & CTF_MAX_VLEN))

#define	CTF_TYPE_NAME(stid, offset) \
	(((stid) << 31) | ((offset) & 0x7fffffff))

#define	CTF_TYPE_ISPARENT(id)	((id) < 0x8000)
#define	CTF_TYPE_ISCHILD(id)	((id) > 0x7fff)

#define	CTF_TYPE_TO_INDEX(id)		((id) & 0x7fff)
#define	CTF_INDEX_TO_TYPE(id, child)	((child) ? ((id) | 0x8000) : (id))
#define	CTF_PARENT_SHIFT	15

#define	CTF_STRTAB_0	0	/* symbolic define for string table id 0 */
#define	CTF_STRTAB_1	1	/* symbolic define for string table id 1 */

#define	CTF_TYPE_LSIZE(cttp) \
	(((uint64_t)(cttp)->ctt_lsizehi) << 32 | (cttp)->ctt_lsizelo)
#define	CTF_SIZE_TO_LSIZE_HI(size)	((uint32_t)((uint64_t)(size) >> 32))
#define	CTF_SIZE_TO_LSIZE_LO(size)	((uint32_t)(size))

#ifdef CTF_OLD_VERSIONS

#define	CTF_INFO_KIND_V1(info)		(((info) & 0xf000) >> 12)
#define	CTF_INFO_ISROOT_V1(info)	(((info) & 0x0800) >> 11)
#define	CTF_INFO_VLEN_V1(info)		(((info) & 0x07ff))

#define	CTF_TYPE_INFO_V1(kind, isroot, vlen) \
	(((kind) << 12) | (((isroot) ? 1 : 0) << 11) | ((vlen) & 0x07ff))

#endif /* CTF_OLD_VERSIONS */

/*
 * Values for CTF_TYPE_KIND().  If the kind has an associated data list,
 * CTF_INFO_VLEN() will extract the number of elements in the list, and
 * the type of each element is shown in the comments below.
 */
#define	CTF_K_UNKNOWN	0	/* unknown type (used for padding) */
#define	CTF_K_INTEGER	1	/* variant data is CTF_INT_DATA() (see below) */
#define	CTF_K_FLOAT	2	/* variant data is CTF_FP_DATA() (see below) */
#define	CTF_K_POINTER	3	/* ctt_type is referenced type */
#define	CTF_K_ARRAY	4	/* variant data is single ctf_array_t */
#define	CTF_K_FUNCTION	5	/* ctt_type is return type, variant data is */
				/* list of argument types (ushort_t's) */
#define	CTF_K_STRUCT	6	/* variant data is list of ctf_member_t's */
#define	CTF_K_UNION	7	/* variant data is list of ctf_member_t's */
#define	CTF_K_ENUM	8	/* variant data is list of ctf_enum_t's */
#define	CTF_K_FORWARD	9	/* no additional data; ctt_name is tag */
#define	CTF_K_TYPEDEF	10	/* ctt_type is referenced type */
#define	CTF_K_VOLATILE	11	/* ctt_type is base type */
#define	CTF_K_CONST	12	/* ctt_type is base type */
#define	CTF_K_RESTRICT	13	/* ctt_type is base type */

#define	CTF_K_MAX	31	/* Maximum possible CTF_K_* value */

/*
 * Values for ctt_type when kind is CTF_K_INTEGER.  The flags, offset in bits,
 * and size in bits are encoded as a single word using the following macros.
 */
#define	CTF_INT_ENCODING(data)	(((data) & 0xff000000) >> 24)
#define	CTF_INT_OFFSET(data)	(((data) & 0x00ff0000) >> 16)
#define	CTF_INT_BITS(data)	(((data) & 0x0000ffff))

#define	CTF_INT_DATA(encoding, offset, bits) \
	(((encoding) << 24) | ((offset) << 16) | (bits))

#define	CTF_INT_SIGNED	0x01	/* integer is signed (otherwise unsigned) */
#define	CTF_INT_CHAR	0x02	/* character display format */
#define	CTF_INT_BOOL	0x04	/* boolean display format */
#define	CTF_INT_VARARGS	0x08	/* varargs display format */

/*
 * Values for ctt_type when kind is CTF_K_FLOAT.  The encoding, offset in bits,
 * and size in bits are encoded as a single word using the following macros.
 */
#define	CTF_FP_ENCODING(data)	(((data) & 0xff000000) >> 24)
#define	CTF_FP_OFFSET(data)	(((data) & 0x00ff0000) >> 16)
#define	CTF_FP_BITS(data)	(((data) & 0x0000ffff))

#define	CTF_FP_DATA(encoding, offset, bits) \
	(((encoding) << 24) | ((offset) << 16) | (bits))

#define	CTF_FP_SINGLE	1	/* IEEE 32-bit float encoding */
#define	CTF_FP_DOUBLE	2	/* IEEE 64-bit float encoding */
#define	CTF_FP_CPLX	3	/* Complex encoding */
#define	CTF_FP_DCPLX	4	/* Double complex encoding */
#define	CTF_FP_LDCPLX	5	/* Long double complex encoding */
#define	CTF_FP_LDOUBLE	6	/* Long double encoding */
#define	CTF_FP_INTRVL	7	/* Interval (2x32-bit) encoding */
#define	CTF_FP_DINTRVL	8	/* Double interval (2x64-bit) encoding */
#define	CTF_FP_LDINTRVL	9	/* Long double interval (2x128-bit) encoding */
#define	CTF_FP_IMAGRY	10	/* Imaginary (32-bit) encoding */
#define	CTF_FP_DIMAGRY	11	/* Long imaginary (64-bit) encoding */
#define	CTF_FP_LDIMAGRY	12	/* Long double imaginary (128-bit) encoding */

#define	CTF_FP_MAX	12	/* Maximum possible CTF_FP_* value */

typedef struct ctf_array {
	ushort_t cta_contents;	/* reference to type of array contents */
	ushort_t cta_index;	/* reference to type of array index */
	uint_t cta_nelems;	/* number of elements */
} ctf_array_t;

/*
 * Most structure members have bit offsets that can be expressed using a
 * short.  Some don't.  ctf_member_t is used for structs which cannot
 * contain any of these large offsets, whereas ctf_lmember_t is used in the
 * latter case.  If ctt_size for a given struct is >= 8192 bytes, all members
 * will be stored as type ctf_lmember_t.
 */

#define	CTF_LSTRUCT_THRESH	8192

typedef struct ctf_member {
	uint_t ctm_name;	/* reference to name in string table */
	ushort_t ctm_type;	/* reference to type of member */
	ushort_t ctm_offset;	/* offset of this member in bits */
} ctf_member_t;

typedef struct ctf_lmember {
	uint_t ctlm_name;	/* reference to name in string table */
	ushort_t ctlm_type;	/* reference to type of member */
	ushort_t ctlm_pad;	/* padding */
	uint_t ctlm_offsethi;	/* high 32 bits of member offset in bits */
	uint_t ctlm_offsetlo;	/* low 32 bits of member offset in bits */
} ctf_lmember_t;

#define	CTF_LMEM_OFFSET(ctlmp) \
	(((uint64_t)(ctlmp)->ctlm_offsethi) << 32 | (ctlmp)->ctlm_offsetlo)
#define	CTF_OFFSET_TO_LMEMHI(offset)	((uint32_t)((uint64_t)(offset) >> 32))
#define	CTF_OFFSET_TO_LMEMLO(offset)	((uint32_t)(offset))

typedef struct ctf_enum {
	uint_t cte_name;	/* reference to name in string table */
	int cte_value;		/* value associated with this name */
} ctf_enum_t;

#ifdef	__cplusplus
}
#endif

#endif	/* _CTF_H */