xref: /illumos-gate/usr/src/lib/libtnf/libtnf.h (revision 78b6ed60)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 
23 /*
24  * Copyright 1994 Sun Microsystems, Inc.  All rights reserved.
25  * Use is subject to license terms.
26  */
27 
28 #ifndef _LIBTNF_H
29 #define	_LIBTNF_H
30 
31 #pragma ident	"%Z%%M%	%I%	%E% SMI"
32 
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <stdarg.h>
36 #include <string.h>
37 #include <unistd.h>
38 
39 #include "tnf/tnf.h"
40 #include "machlibtnf.h"
41 
42 #ifdef __cplusplus
43 extern "C" {
44 #endif
45 
46 /*
47  * Info flags
48  */
49 
50 typedef unsigned long	tag_props_t;
51 
52 #define	TAG_PROP_INLINE		(1<<0)
53 #define	TAG_PROP_TAGGED		(1<<1)
54 #define	TAG_PROP_SCALAR		(1<<2)
55 #define	TAG_PROP_DERIVED	(1<<3)
56 #define	TAG_PROP_ARRAY		(1<<4)
57 #define	TAG_PROP_STRING		(1<<5)
58 #define	TAG_PROP_STRUCT		(1<<6)
59 #define	TAG_PROP_TYPE		(1<<7)
60 
61 /*
62  * Type tag information
63  */
64 
65 struct taginfo {
66 	struct taginfo	*link;		/* hash link */
67 #define	INFO_MEMBER_0	link
68 	TNF		*tnf;		/* TNF handle */
69 	tnf_ref32_t	*tag;		/* tag record in file */
70 	char		*name;		/* chars in file */
71 	tnf_kind_t	kind;		/* data classification */
72 	tag_props_t	props;		/* tag property flags */
73 	struct taginfo	*meta;		/* meta tag info */
74 	struct taginfo	*base;		/* last derived base or elttype */
75 	size_t		size;		/* storage size or -1 */
76 	size_t		align;		/* slot alignment */
77 	size_t		hdrsize;	/* array header size */
78 	struct slotinfo {		/* aggregate slot information */
79 		unsigned	slot_count;
80 		/* Embedded array */
81 		struct slot {
82 			struct taginfo	*slot_type;
83 			char		*slot_name;
84 			unsigned	slot_offset;
85 		} slots[1];
86 	} *slotinfo;
87 };
88 
89 #define	INFO_PROP(ip, p)	((ip)->props & (p))
90 
91 #define	INFO_INLINE(ip)		INFO_PROP(ip, TAG_PROP_INLINE)
92 #define	INFO_TAGGED(ip)		INFO_PROP(ip, TAG_PROP_TAGGED)
93 #define	INFO_SCALAR(ip)		INFO_PROP(ip, TAG_PROP_SCALAR)
94 #define	INFO_DERIVED(ip)	INFO_PROP(ip, TAG_PROP_DERIVED)
95 #define	INFO_ARRAY(ip)		INFO_PROP(ip, TAG_PROP_ARRAY)
96 #define	INFO_STRING(ip)		INFO_PROP(ip, TAG_PROP_STRING)
97 #define	INFO_STRUCT(ip)		INFO_PROP(ip, TAG_PROP_STRUCT)
98 #define	INFO_TYPE(ip)		INFO_PROP(ip, TAG_PROP_TYPE)
99 
100 #define	INFO_REF_SIZE(ip)	(INFO_TAGGED(ip)? 4: (ip)->size)
101 #define	INFO_ELEMENT_SIZE(ip)	INFO_REF_SIZE(ip)
102 
103 /* Alignment is stored for all but records and derivations thereof */
104 #define	INFO_ALIGN(ip)		(INFO_TAGGED(ip)? 4: (ip)->align)
105 
106 #define	ALIGN(n, a)		\
107 	(((a) == 0) ? (n) : (((n) + (a) - 1) & ~((a) - 1)))
108 
109 /*
110  * Tag lookup
111  */
112 
113 /* Number of directory entries */
114 #define	TAGDIRCNT(x) 	((x) / sizeof (tnf_ref32_t))
115 
116 /* Number of hash table buckets */
117 #define	TAGTABCNT	1024
118 #define	TAGTABMASK	(TAGTABCNT-1)
119 
120 /* A tag is at least 32 bytes; with strings & props, assume 128 bytes */
121 #define	TAGTABSHIFT	7
122 
123 /* Hash tag by bits 17:7 of offset within data area */
124 #define	TAGOFF(tnf, p)	((unsigned)((caddr_t)(p) - (tnf)->data_start))
125 #define	TAGHASH(tnf, p)	((TAGOFF(tnf, p) >> TAGTABSHIFT) & TAGTABMASK)
126 
127 /*
128  * TNF handle
129  */
130 
131 struct TNF {
132 	/*
133 	 * Client-supplied bounds
134 	 */
135 	caddr_t		file_start;
136 	size_t		file_size;
137 	caddr_t		file_end;	/* file_start + file_size */
138 
139 	/*
140 	 * File information
141 	 */
142 	unsigned	file_magic;	/* magic number of file */
143 	int		file_native;	/* endian flag */
144 
145 	/* file header */
146 	tnf_ref32_t	*file_header;	/* first record in file */
147 	size_t		block_size;	/* size of a block */
148 	size_t		directory_size;	/* size of directory area */
149 
150 	unsigned	block_count;	/* number of data blocks */
151 	caddr_t		data_start;	/* file_start + 64KB */
152 
153 	unsigned	generation_shift;
154 	unsigned	address_mask;
155 
156 	/* block headers */
157 	unsigned	block_shift;	/* index -> bhdr */
158 	unsigned	block_mask;	/* ptr -> bhdr */
159 	unsigned	block_generation_offset;
160 	unsigned	block_bytes_valid_offset;
161 
162 	/* root tag */
163 	tnf_ref32_t	*root_tag;
164 
165 	/* important taginfo */
166 	struct taginfo	*file_header_info;
167 	struct taginfo	*block_header_info;
168 
169 	/* tag lookup tables */
170 	struct taginfo	**tag_table;	/* by address */
171 	struct taginfo	**tag_directory; /* by index */
172 
173 };
174 
175 /*
176  * File operations for reading integers
177  */
178 
179 #define	_GET_UINT32(tnf, ptr)				\
180 	((tnf)->file_native ?				\
181 		*(tnf_uint32_t *)(ptr) :		\
182 		_tnf_swap32(*(tnf_uint32_t *)(ptr)))
183 
184 #define	_GET_INT32(tnf, ptr)				\
185 	((tnf_int32_t)_GET_UINT32(tnf, ptr))
186 
187 #define	_GET_UINT16(tnf, ptr)				\
188 	((tnf)->file_native ?				\
189 		*(tnf_uint16_t *)(ptr) :		\
190 		_tnf_swap16(*(tnf_uint16_t *)(ptr)))
191 
192 #define	_GET_INT16(tnf, ptr)				\
193 	((tnf_int16_t)_GET_UINT16(tnf, ptr))
194 
195 /*
196  * TNF reference-chasing operations
197  */
198 
199 tnf_ref32_t * _tnf_get_ref32(TNF *, tnf_ref32_t *);
200 tnf_ref32_t * _tnf_get_ref16(TNF *, tnf_ref32_t *);
201 
202 #define	_GET_REF32(tnf, ptr)	_tnf_get_ref32(tnf, ptr)
203 #define	_GET_REF16(tnf, ptr)	_tnf_get_ref16(tnf, ptr)
204 
205 /*
206  * Block header record operations
207  * Only applicable in data area
208  */
209 
210 #define	_GET_BLOCK(tnf, ptr)					\
211 	((tnf_ref32_t *)((unsigned)(ptr) & (tnf)->block_mask))
212 
213 #define	_GET_BLOCK_INDEX(tnf, bhdr)				\
214 	(((caddr_t)(bhdr) - (tnf)->data_start) >> (tnf)->block_shift)
215 
216 #define	_GET_INDEX_BLOCK(tnf, index)				\
217 	((tnf_ref32_t *)((tnf)->data_start + ((index) << (tnf)->block_shift)))
218 
219 #define	_GET_BLOCK_GENERATION(tnf, bhdr)			\
220 	_GET_UINT32(tnf, (caddr_t)bhdr + tnf->block_generation_offset)
221 
222 #define	_GET_BLOCK_BYTES_VALID(tnf, bhdr)			\
223 	(!(bhdr) ? 0 : _GET_UINT16(tnf, (caddr_t)bhdr +		\
224 				tnf->block_bytes_valid_offset))
225 
226 /*
227  * Datum operations
228  */
229 
230 #ifndef	_DATUM_MACROS
231 
232 tnf_datum_t _tnf_datum(struct taginfo *, caddr_t);
233 struct taginfo * _tnf_datum_info(tnf_datum_t);
234 caddr_t	_tnf_datum_val(tnf_datum_t);
235 
236 #define	DATUM(x, y)	_tnf_datum(x, y)
237 #define	DATUM_INFO(x)	_tnf_datum_info(x)
238 #define	DATUM_VAL(x)	_tnf_datum_val(x)
239 
240 #else  /* _DATUM_MACROS */
241 
242 /* Some degree of type safety: */
243 #define	DATUM(x, y)	_DATUM((uintptr_t)&(x)->INFO_MEMBER_0, y)
244 #define	DATUM_INFO(d)	((struct taginfo *)_DATUM_HI(d))
245 #define	DATUM_VAL(d)	((caddr_t)_DATUM_LO(d))
246 
247 #endif /* _DATUM_MACROS */
248 
249 #define	_DATUM(hi, lo)	(((unsigned long long)(hi) << 32) | (unsigned)(lo))
250 #define	_DATUM_HI(x) 	((unsigned) ((x) >> 32))
251 #define	_DATUM_LO(x) 	((unsigned) (x))
252 
253 #define	DATUM_RECORD(x)		\
254 	((tnf_ref32_t *)DATUM_VAL(x))
255 
256 #define	RECORD_DATUM(tnf, rec)	\
257 	DATUM(_tnf_record_info(tnf, rec), (caddr_t)rec)
258 
259 #define	DATUM_TNF(x)		DATUM_INFO(x)->tnf
260 #define	DATUM_TAG(x)		DATUM_INFO(x)->tag
261 
262 /*
263  * Type checking operations
264  */
265 
266 void _tnf_check_datum(tnf_datum_t);
267 #define	CHECK_DATUM(x)	_tnf_check_datum(x)
268 
269 void _tnf_check_record(tnf_datum_t);
270 #define	CHECK_RECORD(x)	_tnf_check_record(x)
271 
272 void _tnf_check_slots(tnf_datum_t);
273 #define	CHECK_SLOTS(x)	_tnf_check_slots(x)
274 
275 void _tnf_check_array(tnf_datum_t);
276 #define	CHECK_ARRAY(x)	_tnf_check_array(x)
277 
278 void _tnf_check_type(tnf_datum_t);
279 #define	CHECK_TYPE(x)	_tnf_check_type(x)
280 
281 /*
282  * Operations based on ABI layouts and bootstrap assumptions
283  */
284 
285 tnf_ref32_t * _tnf_get_tag(TNF *, tnf_ref32_t *);
286 tnf_ref32_t * _tnf_get_tag_arg(TNF *, tnf_ref32_t *);
287 size_t _tnf_get_self_size(TNF *, tnf_ref32_t *);
288 unsigned _tnf_get_element_count(TNF *, tnf_ref32_t *, unsigned);
289 caddr_t _tnf_get_elements(TNF *, tnf_ref32_t *);
290 char * _tnf_get_chars(TNF *, tnf_ref32_t *);
291 char * _tnf_get_name(TNF *, tnf_ref32_t *);
292 tnf_ref32_t * _tnf_get_properties(TNF *, tnf_ref32_t *);
293 tnf_ref32_t * _tnf_get_slot_types(TNF *, tnf_ref32_t *);
294 size_t _tnf_get_header_size(TNF *, tnf_ref32_t *);
295 tnf_ref32_t * _tnf_get_derived_base(TNF *, tnf_ref32_t *);
296 
297 tnf_ref32_t * _tnf_get_root_tag(TNF *, tnf_ref32_t *);
298 tnf_ref32_t * _tnf_get_property(TNF *, tnf_ref32_t *, char *);
299 tnf_ref32_t * _tnf_get_element_named(TNF *, tnf_ref32_t *, char *);
300 tnf_ref32_t * _tnf_get_base_tag(TNF *, tnf_ref32_t *);
301 
302 size_t _tnf_get_storage_size(TNF *, tnf_ref32_t *);
303 size_t _tnf_get_ref_size(TNF *, tnf_ref32_t *);
304 
305 unsigned _tnf_get_align(TNF *, tnf_ref32_t *);
306 
307 caddr_t	_tnf_get_slot_typed(TNF *, tnf_ref32_t *, char *);
308 caddr_t	_tnf_get_slot_named(TNF *, tnf_ref32_t *, char *);
309 
310 #define	HAS_PROPERTY(tnf, tag, name)	\
311 	(_tnf_get_property(tnf, tag, name) != TNF_NULL)
312 
313 /*
314  * Call the installed error handler with installed arg
315  */
316 
317 void _tnf_error(TNF *, tnf_errcode_t);
318 
319 /*
320  * Tag lookup operations
321  */
322 
323 struct taginfo * _tnf_get_info(TNF *, tnf_ref32_t *);
324 struct taginfo * _tnf_record_info(TNF *, tnf_ref32_t *);
325 
326 tnf_errcode_t _tnf_init_tags(TNF *);
327 tnf_errcode_t _tnf_fini_tags(TNF *);
328 
329 /*
330  * Classify a tag into its props and data kind
331  */
332 
333 tag_props_t _tnf_get_props(TNF *, tnf_ref32_t *);
334 tnf_kind_t _tnf_get_kind(TNF *, tnf_ref32_t *);
335 
336 caddr_t	_tnf_get_member(TNF *, caddr_t, struct taginfo *);
337 
338 #ifdef __cplusplus
339 }
340 #endif
341 
342 #endif /* _LIBTNF_H */
343