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