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
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.
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]
24 * Copyright 1994 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
31 #pragma ident "%Z%%M% %I% %E% SMI"
40 #include "machlibtnf.h"
50 typedef unsigned long tag_props_t
;
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)
62 * Type tag information
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 */
82 struct taginfo
*slot_type
;
89 #define INFO_PROP(ip, p) ((ip)->props & (p))
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)
100 #define INFO_REF_SIZE(ip) (INFO_TAGGED(ip)? 4: (ip)->size)
101 #define INFO_ELEMENT_SIZE(ip) INFO_REF_SIZE(ip)
103 /* Alignment is stored for all but records and derivations thereof */
104 #define INFO_ALIGN(ip) (INFO_TAGGED(ip)? 4: (ip)->align)
106 #define ALIGN(n, a) \
107 (((a) == 0) ? (n) : (((n) + (a) - 1) & ~((a) - 1)))
113 /* Number of directory entries */
114 #define TAGDIRCNT(x) ((x) / sizeof (tnf_ref32_t))
116 /* Number of hash table buckets */
117 #define TAGTABCNT 1024
118 #define TAGTABMASK (TAGTABCNT-1)
120 /* A tag is at least 32 bytes; with strings & props, assume 128 bytes */
121 #define TAGTABSHIFT 7
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)
133 * Client-supplied bounds
137 caddr_t file_end
; /* file_start + file_size */
142 unsigned file_magic
; /* magic number of file */
143 int file_native
; /* endian flag */
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 */
150 unsigned block_count
; /* number of data blocks */
151 caddr_t data_start
; /* file_start + 64KB */
153 unsigned generation_shift
;
154 unsigned address_mask
;
157 unsigned block_shift
; /* index -> bhdr */
158 unsigned block_mask
; /* ptr -> bhdr */
159 unsigned block_generation_offset
;
160 unsigned block_bytes_valid_offset
;
163 tnf_ref32_t
*root_tag
;
165 /* important taginfo */
166 struct taginfo
*file_header_info
;
167 struct taginfo
*block_header_info
;
169 /* tag lookup tables */
170 struct taginfo
**tag_table
; /* by address */
171 struct taginfo
**tag_directory
; /* by index */
176 * File operations for reading integers
179 #define _GET_UINT32(tnf, ptr) \
180 ((tnf)->file_native ? \
181 *(tnf_uint32_t *)(ptr) : \
182 _tnf_swap32(*(tnf_uint32_t *)(ptr)))
184 #define _GET_INT32(tnf, ptr) \
185 ((tnf_int32_t)_GET_UINT32(tnf, ptr))
187 #define _GET_UINT16(tnf, ptr) \
188 ((tnf)->file_native ? \
189 *(tnf_uint16_t *)(ptr) : \
190 _tnf_swap16(*(tnf_uint16_t *)(ptr)))
192 #define _GET_INT16(tnf, ptr) \
193 ((tnf_int16_t)_GET_UINT16(tnf, ptr))
196 * TNF reference-chasing operations
199 tnf_ref32_t
* _tnf_get_ref32(TNF
*, tnf_ref32_t
*);
200 tnf_ref32_t
* _tnf_get_ref16(TNF
*, tnf_ref32_t
*);
202 #define _GET_REF32(tnf, ptr) _tnf_get_ref32(tnf, ptr)
203 #define _GET_REF16(tnf, ptr) _tnf_get_ref16(tnf, ptr)
206 * Block header record operations
207 * Only applicable in data area
210 #define _GET_BLOCK(tnf, ptr) \
211 ((tnf_ref32_t *)((unsigned)(ptr) & (tnf)->block_mask))
213 #define _GET_BLOCK_INDEX(tnf, bhdr) \
214 (((caddr_t)(bhdr) - (tnf)->data_start) >> (tnf)->block_shift)
216 #define _GET_INDEX_BLOCK(tnf, index) \
217 ((tnf_ref32_t *)((tnf)->data_start + ((index) << (tnf)->block_shift)))
219 #define _GET_BLOCK_GENERATION(tnf, bhdr) \
220 _GET_UINT32(tnf, (caddr_t)bhdr + tnf->block_generation_offset)
222 #define _GET_BLOCK_BYTES_VALID(tnf, bhdr) \
223 (!(bhdr) ? 0 : _GET_UINT16(tnf, (caddr_t)bhdr + \
224 tnf->block_bytes_valid_offset))
230 #ifndef _DATUM_MACROS
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
);
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)
240 #else /* _DATUM_MACROS */
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))
247 #endif /* _DATUM_MACROS */
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))
253 #define DATUM_RECORD(x) \
254 ((tnf_ref32_t *)DATUM_VAL(x))
256 #define RECORD_DATUM(tnf, rec) \
257 DATUM(_tnf_record_info(tnf, rec), (caddr_t)rec)
259 #define DATUM_TNF(x) DATUM_INFO(x)->tnf
260 #define DATUM_TAG(x) DATUM_INFO(x)->tag
263 * Type checking operations
266 void _tnf_check_datum(tnf_datum_t
);
267 #define CHECK_DATUM(x) _tnf_check_datum(x)
269 void _tnf_check_record(tnf_datum_t
);
270 #define CHECK_RECORD(x) _tnf_check_record(x)
272 void _tnf_check_slots(tnf_datum_t
);
273 #define CHECK_SLOTS(x) _tnf_check_slots(x)
275 void _tnf_check_array(tnf_datum_t
);
276 #define CHECK_ARRAY(x) _tnf_check_array(x)
278 void _tnf_check_type(tnf_datum_t
);
279 #define CHECK_TYPE(x) _tnf_check_type(x)
282 * Operations based on ABI layouts and bootstrap assumptions
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
*);
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
*);
302 size_t _tnf_get_storage_size(TNF
*, tnf_ref32_t
*);
303 size_t _tnf_get_ref_size(TNF
*, tnf_ref32_t
*);
305 unsigned _tnf_get_align(TNF
*, tnf_ref32_t
*);
307 caddr_t
_tnf_get_slot_typed(TNF
*, tnf_ref32_t
*, char *);
308 caddr_t
_tnf_get_slot_named(TNF
*, tnf_ref32_t
*, char *);
310 #define HAS_PROPERTY(tnf, tag, name) \
311 (_tnf_get_property(tnf, tag, name) != TNF_NULL)
314 * Call the installed error handler with installed arg
317 void _tnf_error(TNF
*, tnf_errcode_t
);
320 * Tag lookup operations
323 struct taginfo
* _tnf_get_info(TNF
*, tnf_ref32_t
*);
324 struct taginfo
* _tnf_record_info(TNF
*, tnf_ref32_t
*);
326 tnf_errcode_t
_tnf_init_tags(TNF
*);
327 tnf_errcode_t
_tnf_fini_tags(TNF
*);
330 * Classify a tag into its props and data kind
333 tag_props_t
_tnf_get_props(TNF
*, tnf_ref32_t
*);
334 tnf_kind_t
_tnf_get_kind(TNF
*, tnf_ref32_t
*);
336 caddr_t
_tnf_get_member(TNF
*, caddr_t
, struct taginfo
*);
342 #endif /* _LIBTNF_H */