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
43extern "C" {
44#endif
45
46/*
47 * Info flags
48 */
49
50typedef 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
65struct 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
131struct 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
199tnf_ref32_t * _tnf_get_ref32(TNF *, tnf_ref32_t *);
200tnf_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
232tnf_datum_t _tnf_datum(struct taginfo *, caddr_t);
233struct taginfo * _tnf_datum_info(tnf_datum_t);
234caddr_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
266void _tnf_check_datum(tnf_datum_t);
267#define	CHECK_DATUM(x)	_tnf_check_datum(x)
268
269void _tnf_check_record(tnf_datum_t);
270#define	CHECK_RECORD(x)	_tnf_check_record(x)
271
272void _tnf_check_slots(tnf_datum_t);
273#define	CHECK_SLOTS(x)	_tnf_check_slots(x)
274
275void _tnf_check_array(tnf_datum_t);
276#define	CHECK_ARRAY(x)	_tnf_check_array(x)
277
278void _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
285tnf_ref32_t * _tnf_get_tag(TNF *, tnf_ref32_t *);
286tnf_ref32_t * _tnf_get_tag_arg(TNF *, tnf_ref32_t *);
287size_t _tnf_get_self_size(TNF *, tnf_ref32_t *);
288unsigned _tnf_get_element_count(TNF *, tnf_ref32_t *, unsigned);
289caddr_t _tnf_get_elements(TNF *, tnf_ref32_t *);
290char * _tnf_get_chars(TNF *, tnf_ref32_t *);
291char * _tnf_get_name(TNF *, tnf_ref32_t *);
292tnf_ref32_t * _tnf_get_properties(TNF *, tnf_ref32_t *);
293tnf_ref32_t * _tnf_get_slot_types(TNF *, tnf_ref32_t *);
294size_t _tnf_get_header_size(TNF *, tnf_ref32_t *);
295tnf_ref32_t * _tnf_get_derived_base(TNF *, tnf_ref32_t *);
296
297tnf_ref32_t * _tnf_get_root_tag(TNF *, tnf_ref32_t *);
298tnf_ref32_t * _tnf_get_property(TNF *, tnf_ref32_t *, char *);
299tnf_ref32_t * _tnf_get_element_named(TNF *, tnf_ref32_t *, char *);
300tnf_ref32_t * _tnf_get_base_tag(TNF *, tnf_ref32_t *);
301
302size_t _tnf_get_storage_size(TNF *, tnf_ref32_t *);
303size_t _tnf_get_ref_size(TNF *, tnf_ref32_t *);
304
305unsigned _tnf_get_align(TNF *, tnf_ref32_t *);
306
307caddr_t	_tnf_get_slot_typed(TNF *, tnf_ref32_t *, char *);
308caddr_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
317void _tnf_error(TNF *, tnf_errcode_t);
318
319/*
320 * Tag lookup operations
321 */
322
323struct taginfo * _tnf_get_info(TNF *, tnf_ref32_t *);
324struct taginfo * _tnf_record_info(TNF *, tnf_ref32_t *);
325
326tnf_errcode_t _tnf_init_tags(TNF *);
327tnf_errcode_t _tnf_fini_tags(TNF *);
328
329/*
330 * Classify a tag into its props and data kind
331 */
332
333tag_props_t _tnf_get_props(TNF *, tnf_ref32_t *);
334tnf_kind_t _tnf_get_kind(TNF *, tnf_ref32_t *);
335
336caddr_t	_tnf_get_member(TNF *, caddr_t, struct taginfo *);
337
338#ifdef __cplusplus
339}
340#endif
341
342#endif /* _LIBTNF_H */
343