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