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