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