Home | History | Annotate | Download | only in tnf
      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 #pragma ident	"@(#)tnf_writer.c	1.20	05/06/08 SMI"
     27 
     28 #ifndef DEBUG
     29 #define	NDEBUG	1
     30 #endif
     31 
     32 #ifdef _KERNEL
     33 #include <sys/param.h>
     34 #include <sys/systm.h>
     35 #include <sys/tnf_com.h>
     36 #include <sys/tnf_writer.h>
     37 #include <sys/debug.h>
     38 #include "tnf_types.h"
     39 #include "tnf_trace.h"
     40 #else	/* _KERNEL */
     41 #include <stdlib.h>
     42 #include <string.h>
     43 #include <tnf/com.h>
     44 #include <tnf/writer.h>
     45 #include <assert.h>
     46 #include "tnf_types.h"
     47 #include <tnf_trace.h>
     48 #endif	/* _KERNEL */
     49 
     50 /*
     51  * Defines
     52  */
     53 
     54 #ifdef _KERNEL
     55 #define	TNF_ASSERT(expr)	ASSERT(expr)
     56 #else
     57 #define	TNF_ASSERT(expr)	assert(expr)
     58 #endif
     59 
     60 /*
     61  * Local functions
     62  */
     63 
     64 static tnf_record_p tnf_root_tag_1(tnf_ops_t *, tnf_tag_data_t *);
     65 
     66 /*
     67  * TNF tag version 1
     68  */
     69 
     70 tnf_tag_version_t __tnf_tag_version_1_info =  {
     71 	sizeof (tnf_tag_version_t),
     72 	sizeof (tnf_tag_data_t)
     73 };
     74 
     75 /*
     76  * Pure abstract types
     77  */
     78 
     79 TNF_ABSTRACT_TAG(tnf_inline);
     80 TNF_ABSTRACT_TAG(tnf_tagged);
     81 
     82 /*
     83  * Scalar types
     84  */
     85 
     86 static tnf_tag_data_t	**std_scalar_properties[] = {
     87 	&TAG_DATA(tnf_inline),
     88 	&TAG_DATA(tnf_scalar),
     89 	0};
     90 
     91 tnf_tag_data_t	***tnf_scalar_properties = std_scalar_properties;
     92 
     93 TNF_SCALAR_TAG(tnf_scalar, 0, 0, TNF_UNKNOWN);
     94 
     95 TNF_STD_SCALAR_TAG(tnf_char, TNF_UNKNOWN); /* XXX */
     96 TNF_STD_SCALAR_TAG(tnf_int8, TNF_INT32);
     97 TNF_STD_SCALAR_TAG(tnf_uint8, TNF_UINT32);
     98 TNF_STD_SCALAR_TAG(tnf_int16, TNF_INT32);
     99 TNF_STD_SCALAR_TAG(tnf_uint16, TNF_UINT32);
    100 TNF_STD_SCALAR_TAG(tnf_int32, TNF_INT32);
    101 TNF_STD_SCALAR_TAG(tnf_uint32, TNF_UINT32);
    102 TNF_STD_SCALAR_TAG(tnf_int64, TNF_INT64);
    103 TNF_STD_SCALAR_TAG(tnf_uint64, TNF_UINT64);
    104 
    105 TNF_STD_SCALAR_TAG(tnf_float32, TNF_FLOAT32);
    106 TNF_STD_SCALAR_TAG(tnf_float64, TNF_FLOAT64);
    107 
    108 /*
    109  * Array types
    110  */
    111 
    112 static tnf_tag_data_t	**array_properties[] = {
    113 	&TAG_DATA(tnf_array),
    114 	0
    115 };
    116 static tnf_tag_data_t	***abstract_array_properties = array_properties;
    117 
    118 static tnf_tag_data_t	**std_array_properties[] = {
    119 	&TAG_DATA(tnf_array),
    120 	&TAG_DATA(tnf_tagged),
    121 	0
    122 };
    123 /* Exported */
    124 tnf_tag_data_t	***tnf_array_properties = std_array_properties;
    125 
    126 /* Exported */
    127 tnf_tag_data_t	**tnf_array_slots[] = {
    128 	&TAG_DATA(tnf_tag),
    129 	&TAG_DATA(tnf_self_size),
    130 	0
    131 };
    132 
    133 TNF_ARRAY_TAG(tnf_array, TNF_NULL, abstract_array_properties,
    134 			TNF_NULL, TNF_UNKNOWN);
    135 
    136 TNF_STD_ARRAY_TAG(tnf_string, tnf_char, TNF_STRING);
    137 TNF_STD_ARRAY_TAG(tnf_type_array, tnf_type, TNF_ARRAY);
    138 TNF_STD_ARRAY_TAG(tnf_name_array, tnf_name, TNF_ARRAY);
    139 
    140 /*
    141  * Derived types
    142  */
    143 
    144 static tnf_tag_data_t	**derived_properties[] = {
    145 	&TAG_DATA(tnf_derived),
    146 	0
    147 };
    148 /* Exported */
    149 tnf_tag_data_t	***tnf_derived_properties = derived_properties;
    150 
    151 TNF_DERIVED_TAG(tnf_derived, TNF_NULL,
    152 		tnf_derived_properties, TNF_NULL, TNF_NULL, TNF_UNKNOWN);
    153 
    154 TNF_STD_DERIVED_TAG(tnf_align, tnf_uint32,
    155 		tnf_derived_properties, TNF_UINT32);
    156 
    157 TNF_STD_DERIVED_TAG(tnf_derived_base, tnf_type,
    158 		tnf_derived_properties, TNF_OPAQUE);
    159 
    160 TNF_STD_DERIVED_TAG(tnf_element_type, tnf_type,
    161 		tnf_derived_properties, TNF_OPAQUE);
    162 
    163 TNF_STD_DERIVED_TAG(tnf_header_size, tnf_uint32,
    164 		tnf_derived_properties, TNF_UINT32);
    165 
    166 TNF_STD_DERIVED_TAG(tnf_name, tnf_string,
    167 		tnf_derived_properties, TNF_STRING);
    168 
    169 #if defined(_LP64)
    170 
    171 TNF_STD_DERIVED_TAG(tnf_opaque, tnf_uint64,
    172 		tnf_derived_properties, TNF_OPAQUE);
    173 
    174 #else
    175 
    176 TNF_STD_DERIVED_TAG(tnf_opaque, tnf_uint32,
    177 		tnf_derived_properties, TNF_OPAQUE);
    178 
    179 #endif /* defined(_LP64) */
    180 
    181 TNF_STD_DERIVED_TAG(tnf_properties, tnf_type_array,
    182 		tnf_derived_properties, TNF_ARRAY);
    183 
    184 TNF_STD_DERIVED_TAG(tnf_self_size, tnf_uint32,
    185 		tnf_derived_properties, TNF_UINT32);
    186 
    187 TNF_STD_DERIVED_TAG(tnf_size, tnf_ulong,
    188 		tnf_derived_properties, TNF_ULONG);
    189 
    190 TNF_STD_DERIVED_TAG(tnf_slot_names, tnf_name_array,
    191 		tnf_derived_properties, TNF_ARRAY);
    192 
    193 TNF_STD_DERIVED_TAG(tnf_slot_types, tnf_type_array,
    194 		tnf_derived_properties, TNF_ARRAY);
    195 
    196 TNF_STD_DERIVED_TAG(tnf_tag, tnf_type,
    197 		tnf_derived_properties, TNF_OPAQUE);
    198 
    199 TNF_STD_DERIVED_TAG(tnf_tag_arg, tnf_tagged,
    200 		tnf_derived_properties, TNF_OPAQUE);
    201 
    202 TNF_STD_DERIVED_TAG(tnf_type_size, tnf_uint32,
    203 		tnf_derived_properties, TNF_UINT32);
    204 
    205 /*
    206  * Struct types
    207  */
    208 
    209 static tnf_tag_data_t	**no_properties[] = { 0 };
    210 tnf_tag_data_t	***tnf_no_properties = no_properties;
    211 
    212 static tnf_tag_data_t	**no_slots[] = { 0 };
    213 
    214 static tnf_tag_data_t	**std_struct_properties[] = {
    215 	&TAG_DATA(tnf_tagged),
    216 	&TAG_DATA(tnf_struct),
    217 	0};
    218 /* Exported */
    219 tnf_tag_data_t	***tnf_struct_properties = std_struct_properties;
    220 
    221 TNF_STRUCT_TAG(tnf_struct, tnf_no_properties, no_slots, 0, 0);
    222 
    223 /*
    224  * File header - CAUTION - has to be in sync with com.h
    225  */
    226 
    227 static char	*file_header_slot_names[] = {
    228 	TNF_N_TAG,
    229 	TNF_N_FILE_VERSION,
    230 	TNF_N_FILE_HEADER_SIZE,
    231 	TNF_N_FILE_LOGICAL_SIZE,
    232 	TNF_N_BLOCK_HEADER_SIZE,
    233 	TNF_N_BLOCK_SIZE,
    234 	TNF_N_DIRECTORY_SIZE,
    235 	TNF_N_BLOCK_COUNT,
    236 	TNF_N_BLOCKS_VALID,
    237 	/* XXX add writer-specific opaque slots here for reader */
    238 	0};
    239 
    240 static tnf_tag_data_t	**file_header_slots[] = {
    241 	&TAG_DATA(tnf_tag),		/* tag			*/
    242 	&TAG_DATA(tnf_uint32),		/* file_version 	*/
    243 	&TAG_DATA(tnf_uint32),		/* file_header_size	*/
    244 	&TAG_DATA(tnf_uint32),		/* file_logical_size	*/
    245 	&TAG_DATA(tnf_uint32),		/* block_header_size 	*/
    246 	&TAG_DATA(tnf_uint32),		/* block_size 		*/
    247 	&TAG_DATA(tnf_uint32),		/* directory_size 	*/
    248 	&TAG_DATA(tnf_uint32),		/* block_count 		*/
    249 	&TAG_DATA(tnf_uint32),		/* blocks_valid 	*/
    250 	/* XXX add writer-specific opaque slots here for reader */
    251 	0};
    252 
    253 /* size of tnf_file_header has the size of the magic number subtracted */
    254 TNF_STD_STRUCT_TAG(tnf_file_header,
    255 		file_header_slots,
    256 		file_header_slot_names,
    257 		sizeof (tnf_buf_file_header_t) - sizeof (tnf_uint32_t));
    258 
    259 /*
    260  * Block header - CAUTION - has to be in sync with com.h
    261  */
    262 
    263 static char	*block_header_slot_names[] = {
    264 	TNF_N_TAG,
    265 	TNF_N_GENERATION,
    266 	TNF_N_BYTES_VALID,
    267 	"A_lock",			/* XXX */
    268 	"B_lock",			/* XXX */
    269 	"next_block",			/* XXX */
    270 	0};
    271 
    272 static tnf_tag_data_t	**block_header_slots[] = {
    273 	&TAG_DATA(tnf_tag),		/* tag			*/
    274 	&TAG_DATA(tnf_uint32),		/* generation		*/
    275 	&TAG_DATA(tnf_uint16),		/* bytes_valid		*/
    276 	&TAG_DATA(tnf_uint8),		/* A_lock 		*/
    277 	&TAG_DATA(tnf_uint8),		/* B_lock		*/
    278 	&TAG_DATA(tnf_opaque),		/* next_block 		*/
    279 	0};
    280 
    281 TNF_STD_STRUCT_TAG(tnf_block_header,
    282 		block_header_slots,
    283 		block_header_slot_names,
    284 		sizeof (tnf_block_header_t));
    285 
    286 /*
    287  * Metatypes
    288  */
    289 
    290 static tnf_tag_data_t	**type_properties[] = {
    291 	&TAG_DATA(tnf_tagged),
    292 	&TAG_DATA(tnf_struct),
    293 	&TAG_DATA(tnf_type),
    294 	0};
    295 /* Exported */
    296 tnf_tag_data_t	***tnf_type_properties = type_properties;
    297 
    298 static tnf_tag_data_t	**type_slots[] = {
    299 	&TAG_DATA(tnf_tag),
    300 	&TAG_DATA(tnf_name),
    301 	&TAG_DATA(tnf_properties),
    302 	0};
    303 
    304 TNF_METATAG(tnf_type, tnf_type_properties, type_slots, tnf_struct_tag_1);
    305 
    306 static tnf_tag_data_t	**array_type_slots[] = {
    307 	&TAG_DATA(tnf_tag),
    308 	&TAG_DATA(tnf_name),
    309 	&TAG_DATA(tnf_properties),
    310 	&TAG_DATA(tnf_slot_types),
    311 	&TAG_DATA(tnf_header_size),
    312 	&TAG_DATA(tnf_element_type),
    313 	0};
    314 
    315 TNF_METATAG(tnf_array_type, tnf_type_properties,
    316 		array_type_slots, tnf_struct_tag_1);
    317 
    318 static tnf_tag_data_t	**derived_type_slots[] = {
    319 	&TAG_DATA(tnf_tag),
    320 	&TAG_DATA(tnf_name),
    321 	&TAG_DATA(tnf_properties),
    322 	&TAG_DATA(tnf_derived_base),
    323 	0};
    324 
    325 TNF_METATAG(tnf_derived_type, tnf_type_properties,
    326 		derived_type_slots, tnf_struct_tag_1);
    327 
    328 static tnf_tag_data_t	**scalar_type_slots[] = {
    329 	&TAG_DATA(tnf_tag),
    330 	&TAG_DATA(tnf_name),
    331 	&TAG_DATA(tnf_properties),
    332 	&TAG_DATA(tnf_type_size),
    333 	&TAG_DATA(tnf_align),
    334 	0};
    335 
    336 TNF_METATAG(tnf_scalar_type, tnf_type_properties,
    337 		scalar_type_slots, tnf_struct_tag_1);
    338 
    339 static tnf_tag_data_t	**struct_type_slots[] = {
    340 	&TAG_DATA(tnf_tag),
    341 	&TAG_DATA(tnf_name),
    342 	&TAG_DATA(tnf_properties),
    343 	&TAG_DATA(tnf_slot_types),
    344 	&TAG_DATA(tnf_type_size),
    345 	&TAG_DATA(tnf_slot_names),
    346 	0};
    347 
    348 TNF_METATAG(tnf_struct_type, tnf_type_properties,
    349 		struct_type_slots, tnf_root_tag_1);
    350 
    351 
    352 /*
    353  * Generic tnf reference - does checking on whether destination is
    354  * a permanent block or not
    355  */
    356 
    357 #ifdef _KERNEL
    358 
    359 /*ARGSUSED0*/
    360 tnf_ref32_t
    361 tnf_ref32_1(tnf_ops_t *ops, tnf_record_p item, tnf_record_p reference)
    362 {
    363 	tnf_ref32_t 		offset_delta, gen_delta;
    364 	tnf_block_header_t	*dest_header_p, *src_header_p;
    365 	tnf_ref32_t		result;
    366 	unsigned int		offset_shift =
    367 		/* LINTED pointer cast may result in improper alignment */
    368 		((tnf_buf_file_header_t *)tnf_buf)->com.file_log_size;
    369 
    370 	dest_header_p = (tnf_block_header_t *)
    371 		((uintptr_t)item & TNF_BLOCK_MASK);
    372 
    373 	if (((char *)dest_header_p < (tnf_buf + TNF_DIRECTORY_SIZE)) ||
    374 	    (dest_header_p->generation == TNF_TAG_GENERATION_NUM)) {
    375 		/* reference to a permanent block */
    376 		/* LINTED ast from 64-bit integer to 32-bit integer */
    377 		offset_delta = (tnf_ref32_t)(item - tnf_buf);
    378 
    379 		return (TNF_REF32_MAKE_PERMANENT(offset_delta));
    380 	} else {
    381 		/* reference to a reclaimable block */
    382 		/* LINTED ast from 64-bit integer to 32-bit integer */
    383 		offset_delta = (tnf_ref32_t)(item - reference);
    384 
    385 		src_header_p =  (tnf_block_header_t *)
    386 			((uintptr_t)reference & TNF_BLOCK_MASK);
    387 		gen_delta = dest_header_p->generation -
    388 			src_header_p->generation;
    389 
    390 		result = (gen_delta << offset_shift) + offset_delta;
    391 		return (TNF_REF32_MAKE_RECLAIMABLE(result));
    392 	}
    393 }
    394 
    395 #else
    396 
    397 /*ARGSUSED0*/
    398 tnf_ref32_t
    399 tnf_ref32_1(tnf_ops_t *ops, tnf_record_p item, tnf_record_p reference)
    400 {
    401 	volatile char 		*file_start = _tnfw_b_control->tnf_buffer;
    402 	tnf_ref32_t 		offset_delta, gen_delta;
    403 	tnf_block_header_t	*dest_header_p, *src_header_p;
    404 	tnf_ref32_t		result;
    405 	unsigned int		offset_shift =
    406 		/* LINTED pointer cast may result in improper alignment */
    407 		((tnf_buf_file_header_t *)file_start)->com.file_log_size;
    408 
    409 	dest_header_p = (tnf_block_header_t *)
    410 		((uintptr_t)item & TNF_BLOCK_MASK);
    411 
    412 	if (((char *)dest_header_p < (file_start + TNFW_B_FW_ZONE)) ||
    413 	    (dest_header_p->generation == TNF_TAG_GENERATION_NUM)) {
    414 		/* reference to a permanent block */
    415 		/* LINTED ast from 64-bit integer to 32-bit integer */
    416 		offset_delta = (tnf_ref32_t)(item - (tnf_record_p) file_start);
    417 
    418 		return (TNF_REF32_MAKE_PERMANENT(offset_delta));
    419 	} else {
    420 		/* reference to a reclaimable block */
    421 		/* LINTED ast from 64-bit integer to 32-bit integer */
    422 		offset_delta = (tnf_ref32_t)(item - reference);
    423 
    424 		src_header_p =  (tnf_block_header_t *)
    425 			((uintptr_t)reference & TNF_BLOCK_MASK);
    426 		gen_delta = dest_header_p->generation -
    427 			src_header_p->generation;
    428 
    429 		result = (gen_delta << offset_shift) + offset_delta;
    430 		return (TNF_REF32_MAKE_RECLAIMABLE(result));
    431 	}
    432 }
    433 
    434 #endif
    435 
    436 /*
    437  * Tag descriptors
    438  */
    439 
    440 /*
    441  * Write instances of tnf_type
    442  */
    443 
    444 tnf_record_p
    445 tnf_abstract_tag_1(tnf_ops_t *ops, tnf_tag_data_t *tag_data)
    446 {
    447 	tnf_tag_data_t		*metatag_data;
    448 	tnf_record_p		metatag_index;
    449 	tnf_type_prototype_t	*buffer;
    450 	enum tnf_alloc_mode	saved_mode;
    451 
    452 	saved_mode = ops->mode;
    453 	ops->mode = TNF_ALLOC_FIXED;
    454 	/* LINTED assignment of 32-bit integer to 8-bit integer */
    455 	ALLOC(ops, sizeof (*buffer), buffer, tag_data->tag_index,
    456 		saved_mode);
    457 
    458 	metatag_data = TAG_DATA(tnf_type);
    459 	metatag_index = metatag_data->tag_index ? metatag_data->tag_index :
    460 		metatag_data->tag_desc(ops, metatag_data);
    461 
    462 	ASSIGN(buffer, tag,		metatag_index);
    463 	ASSIGN(buffer, name, 		tag_data->tag_name);
    464 	ASSIGN(buffer, properties,	tag_data->tag_props);
    465 	/* LINTED assignment of 32-bit integer to 8-bit integer */
    466 	ops->mode = saved_mode;
    467 	return (tag_data->tag_index);
    468 }
    469 
    470 /*
    471  * Write instances of tnf_scalar_type
    472  */
    473 
    474 tnf_record_p
    475 tnf_scalar_tag_1(tnf_ops_t *ops, tnf_tag_data_t *tag_data)
    476 {
    477 	tnf_tag_data_t		*metatag_data;
    478 	tnf_record_p		metatag_index;
    479 	enum tnf_alloc_mode	saved_mode;
    480 	tnf_scalar_type_prototype_t *buffer;
    481 
    482 	saved_mode = ops->mode;
    483 	ops->mode = TNF_ALLOC_FIXED;
    484 	/* LINTED assignment of 32-bit integer to 8-bit integer */
    485 	ALLOC(ops, sizeof (*buffer), buffer, tag_data->tag_index,
    486 	    saved_mode);
    487 
    488 	metatag_data = TAG_DATA(tnf_scalar_type);
    489 	metatag_index = metatag_data->tag_index ? metatag_data->tag_index :
    490 		metatag_data->tag_desc(ops, metatag_data);
    491 
    492 	ASSIGN(buffer, tag, 		metatag_index);
    493 	ASSIGN(buffer, name, 		tag_data->tag_name);
    494 	ASSIGN(buffer, properties, 	tag_data->tag_props);
    495 	/* LINTED assignment of 32-bit integer to 8-bit integer */
    496 	ASSIGN(buffer, type_size, 	tag_data->tag_size);
    497 	/* LINTED assignment of 64-bit integer to 32-bit integer */
    498 	ASSIGN(buffer, align, 		tag_data->tag_align);
    499 
    500 	/* LINTED assignment of 32-bit integer to 8-bit integer */
    501 	ops->mode = saved_mode;
    502 	return (tag_data->tag_index);
    503 }
    504 
    505 /*
    506  * Write instances of tnf_derived_type
    507  */
    508 
    509 tnf_record_p
    510 tnf_derived_tag_1(tnf_ops_t *ops, tnf_tag_data_t *tag_data)
    511 {
    512 	tnf_tag_data_t		*metatag_data;
    513 	tnf_record_p		metatag_index;
    514 	enum tnf_alloc_mode	saved_mode;
    515 	tnf_derived_type_prototype_t *buffer;
    516 
    517 	saved_mode = ops->mode;
    518 	ops->mode = TNF_ALLOC_FIXED;
    519 	/* LINTED assignment of 32-bit integer to 8-bit integer */
    520 	ALLOC(ops, sizeof (*buffer), buffer, tag_data->tag_index,
    521 	    saved_mode);
    522 
    523 	metatag_data = TAG_DATA(tnf_derived_type);
    524 	metatag_index = metatag_data->tag_index ? metatag_data->tag_index:
    525 		metatag_data->tag_desc(ops, metatag_data);
    526 
    527 	ASSIGN(buffer, tag,		metatag_index);
    528 	ASSIGN(buffer, name,		tag_data->tag_name);
    529 	ASSIGN(buffer, properties, 	tag_data->tag_props);
    530 	ASSIGN(buffer, derived_base,	tag_data->tag_base);
    531 	/* LINTED assignment of 32-bit integer to 8-bit integer */
    532 	ops->mode = saved_mode;
    533 	return (tag_data->tag_index);
    534 }
    535 
    536 /*
    537  * Write instances of tnf_struct_type (except root)
    538  */
    539 
    540 tnf_record_p
    541 tnf_struct_tag_1(tnf_ops_t *ops, tnf_tag_data_t *tag_data)
    542 {
    543 	tnf_tag_data_t		*metatag_data;
    544 	tnf_record_p		metatag_index;
    545 	enum tnf_alloc_mode	saved_mode;
    546 	tnf_struct_type_prototype_t *buffer;
    547 
    548 	saved_mode = ops->mode;
    549 	ops->mode = TNF_ALLOC_FIXED;
    550 	/* LINTED assignment of 32-bit integer to 8-bit integer */
    551 	ALLOC(ops, sizeof (*buffer), buffer, tag_data->tag_index,
    552 	    saved_mode);
    553 
    554 	metatag_data = TAG_DATA(tnf_struct_type);
    555 	metatag_index = metatag_data->tag_index ? metatag_data->tag_index:
    556 		metatag_data->tag_desc(ops, metatag_data);
    557 
    558 	ASSIGN(buffer, tag,		metatag_index);
    559 	ASSIGN(buffer, name,		tag_data->tag_name);
    560 	ASSIGN(buffer, properties, 	tag_data->tag_props);
    561 	ASSIGN(buffer, slot_types, 	tag_data->tag_slots);
    562 	/* LINTED assignment of 64-bit integer to 32-bit integer */
    563 	ASSIGN(buffer, type_size, 	tag_data->tag_size);
    564 	ASSIGN(buffer, slot_names, 	tag_data->tag_slot_names);
    565 	/* LINTED assignment of 32-bit integer to 8-bit integer */
    566 	ops->mode = saved_mode;
    567 	return (tag_data->tag_index);
    568 }
    569 
    570 /*
    571  * Write instances of tnf_array_type
    572  */
    573 
    574 tnf_record_p
    575 tnf_array_tag_1(tnf_ops_t *ops, tnf_tag_data_t	*tag_data)
    576 {
    577 	tnf_tag_data_t 		*metatag_data;
    578 	tnf_record_p 		metatag_index;
    579 	enum tnf_alloc_mode	saved_mode;
    580 	tnf_array_type_prototype_t 	*buffer;
    581 
    582 	saved_mode = ops->mode;
    583 	ops->mode = TNF_ALLOC_FIXED;
    584 	/* LINTED assignment of 32-bit integer to 8-bit integer */
    585 	ALLOC(ops, sizeof (*buffer), buffer, tag_data->tag_index,
    586 	    saved_mode);
    587 
    588 	metatag_data = TAG_DATA(tnf_array_type);
    589 	metatag_index = metatag_data->tag_index ? metatag_data->tag_index :
    590 		metatag_data->tag_desc(ops, metatag_data);
    591 
    592 	ASSIGN(buffer, tag, 		metatag_index);
    593 	ASSIGN(buffer, name, 		tag_data->tag_name);
    594 	ASSIGN(buffer, properties, 	tag_data->tag_props);
    595 	ASSIGN(buffer, slot_types, 	tag_data->tag_slots);
    596 	/* LINTED assignment of 64-bit integer to 32-bit integer */
    597 	ASSIGN(buffer, header_size, 	tag_data->tag_size);
    598 	ASSIGN(buffer, element_type, 	tag_data->tag_base);
    599 	/* LINTED assignment of 32-bit integer to 8-bit integer */
    600 	ops->mode = saved_mode;
    601 	return (tag_data->tag_index);
    602 }
    603 
    604 /*
    605  * Write the root metatype, and some critical bootstrap types
    606  */
    607 
    608 static tnf_record_p
    609 tnf_root_tag_1(tnf_ops_t *ops, tnf_tag_data_t *tag_data)
    610 {
    611 	enum tnf_alloc_mode	saved_mode;
    612 	tnf_tag_t		*fw_p;
    613 	tnf_struct_type_prototype_t *buffer;
    614 
    615 	saved_mode = ops->mode;
    616 	ops->mode = TNF_ALLOC_FIXED;
    617 	/* LINTED assignment of 32-bit integer to 8-bit integer */
    618 	ALLOC(ops, sizeof (*buffer), buffer, tag_data->tag_index,
    619 	    saved_mode);
    620 
    621 	/*
    622 	 * update the root forwarding pointer to point to this root
    623 	 * CAUTION: Do this before anything else...
    624 	 */
    625 
    626 #ifdef _KERNEL
    627 	/* LINTED pointer cast may result in improper alignment */
    628 	fw_p = (tnf_tag_t *)(tnf_buf + TNF_DIRENT_ROOT);
    629 	*fw_p = tnf_ref32(ops, tag_data->tag_index, (tnf_record_p)fw_p);
    630 	tag_data->tag_index = (tnf_record_p)fw_p;
    631 #else
    632 	/* LINTED pointer cast may result in improper alignment */
    633 	fw_p = (tnf_tag_t *)_tnf_buf_headers_p->fw_root;
    634 	if (fw_p) {
    635 		*fw_p = tnf_ref32(ops, tag_data->tag_index,
    636 		    (tnf_record_p) fw_p);
    637 		tag_data->tag_index = (tnf_record_p)fw_p;
    638 	}
    639 #endif
    640 
    641 #ifdef _KERNEL
    642 	/* LINTED constant truncated by assignment */
    643 	buffer->tag = TNF_ROOT_TAG;
    644 #else
    645 	ASSIGN(buffer, tag,		tag_data->tag_index); /* ROOT */
    646 #endif
    647 	ASSIGN(buffer, name,		tag_data->tag_name);
    648 	ASSIGN(buffer, properties, 	tag_data->tag_props);
    649 	ASSIGN(buffer, slot_types, 	tag_data->tag_slots);
    650 	/* LINTED assignment of 64-bit integer to 32-bit integer */
    651 	ASSIGN(buffer, type_size, 	tag_data->tag_size);
    652 	ASSIGN(buffer, slot_names, 	tag_data->tag_slot_names);
    653 
    654 	/*
    655 	 * Write some additional bootstrap types
    656 	 */
    657 	{
    658 		static tnf_tag_data_t *bootstrap_types[] = {
    659 			&_TAG_DATA(tnf_uint16),
    660 			&_TAG_DATA(tnf_int32),
    661 			&_TAG_DATA(tnf_tag),
    662 			&_TAG_DATA(tnf_file_header),
    663 			&_TAG_DATA(tnf_block_header),
    664 			0};
    665 		tnf_tag_data_t **list_p, *tag_p;
    666 
    667 		list_p = bootstrap_types;
    668 
    669 		while (tag_p = *list_p++) {
    670 			if (!tag_p->tag_index) /* not written */
    671 				tag_p->tag_desc(ops, tag_p);
    672 		}
    673 	}
    674 
    675 
    676 	/*
    677 	 * fix for circularity in filling in file header tag and block
    678 	 * header tag.  REMIND: should also fix tag_index of
    679 	 * file_header.
    680 	 */
    681 
    682 #ifdef _KERNEL
    683 
    684 	/* LINTED pointer cast may result in improper alignment */
    685 	fw_p = (tnf_tag_t *)(tnf_buf + TNF_DIRENT_FILE_HEADER);
    686 	*fw_p = tnf_ref32(ops, _TAG_DATA(tnf_file_header).tag_index,
    687 	    (tnf_record_p)fw_p);
    688 
    689 	/* LINTED pointer cast may result in improper alignment */
    690 	fw_p = (tnf_tag_t *)(tnf_buf + TNF_DIRENT_BLOCK_HEADER);
    691 	*fw_p = tnf_ref32(ops, _TAG_DATA(tnf_block_header).tag_index,
    692 	    (tnf_record_p)fw_p);
    693 
    694 #else
    695 
    696 	/* LINTED pointer cast may result in improper alignment */
    697 	fw_p = (tnf_tag_t *)_tnf_buf_headers_p->fw_file_header;
    698 	if (fw_p) {
    699 		*fw_p = tnf_ref32(ops, _TAG_DATA(tnf_file_header).tag_index,
    700 		    (tnf_record_p)fw_p);
    701 	}
    702 	/* LINTED pointer cast may result in improper alignment */
    703 	fw_p = (tnf_tag_t *)_tnf_buf_headers_p->fw_block_header;
    704 	if (fw_p) {
    705 		*fw_p = tnf_ref32(ops, _TAG_DATA(tnf_block_header).tag_index,
    706 		    (tnf_record_p) fw_p);
    707 	}
    708 
    709 #endif
    710 
    711 	/* LINTED assignment of 32-bit integer to 8-bit integer */
    712 	ops->mode = saved_mode;
    713 	return (tag_data->tag_index);
    714 }
    715 
    716 
    717 /*
    718  * Data encoders
    719  */
    720 
    721 /*
    722  * Strings and derivatives
    723  */
    724 
    725 tnf_reference_t
    726 tnf_string_1(tnf_ops_t *ops, const char *string, tnf_record_p reference,
    727 		tnf_tag_data_t	*tag_data)
    728 {
    729 	tnf_record_p 	tag_index;
    730 	size_t		string_size, record_size;
    731 	tnf_array_header_t *bufhdr;
    732 
    733 	tag_index = tag_data->tag_index ? tag_data->tag_index :
    734 		tag_data->tag_desc(ops, tag_data);
    735 
    736 	if (!string)
    737 		return ((tnf_reference_t)TNF_NULL);
    738 
    739 	string_size = strlen(string); /* excludes terminating NUL */
    740 	if (string_size > TNF_STRING_LIMIT)
    741 		string_size = TNF_STRING_LIMIT;
    742 	/* Allocate space for terminating NUL as well */
    743 	record_size = sizeof (*bufhdr) + TNF_STRING_ROUNDUP(string_size + 1);
    744 
    745 	ALLOC2(ops, record_size, bufhdr, ops->mode);
    746 
    747 	ASSIGN(bufhdr, tag, 		tag_index);
    748 	/* LINTED assignment of 64-bit integer to 32-bit integer */
    749 	ASSIGN(bufhdr, self_size, 	record_size);
    750 
    751 #ifdef _KERNEL
    752 	(void) bcopy((caddr_t)string, (char *)bufhdr + sizeof (*bufhdr),
    753 	    string_size);
    754 #else
    755 	(void) memcpy((char *)bufhdr + sizeof (*bufhdr), string, string_size);
    756 #endif
    757 	/* NUL-terminate */
    758 	((char *)bufhdr + sizeof (*bufhdr))[string_size] = '\0';
    759 
    760 	return (tnf_ref32(ops, (tnf_record_p)bufhdr, reference));
    761 }
    762 
    763 /*
    764  * Array of strings and derivatives
    765  */
    766 
    767 tnf_reference_t
    768 tnf_string_array_1(tnf_ops_t *ops, char	**strings, tnf_record_p reference,
    769 			tnf_tag_data_t	*tag_data)
    770 {
    771 	tnf_record_p 	tag_index;
    772 	size_t		record_size;
    773 	char		**tmp;
    774 	tnf_reference_t	*ref_p;
    775 	tnf_array_header_t 	*bufhdr;
    776 
    777 	tag_index = tag_data->tag_index ? tag_data->tag_index :
    778 		tag_data->tag_desc(ops, tag_data);
    779 
    780 	if (!strings)
    781 		return ((tnf_reference_t)TNF_NULL);
    782 
    783 	record_size = sizeof (*bufhdr);
    784 	tmp = strings;
    785 	while (*tmp++)
    786 		record_size += sizeof (tnf_string_t);
    787 
    788 	ALLOC2(ops, record_size, bufhdr, ops->mode);
    789 
    790 	ASSIGN(bufhdr, tag, 		tag_index);
    791 	/* LINTED assignment of 64-bit integer to 32-bit integer */
    792 	ASSIGN(bufhdr, self_size, 	record_size);
    793 
    794 	tmp = strings;
    795 	/* LINTED pointer cast may result in improper alignment */
    796 	ref_p = (tnf_reference_t *)((char *)bufhdr + sizeof (*bufhdr));
    797 	while (*tmp) {
    798 		*ref_p = tnf_string(ops, *tmp, (tnf_record_p)ref_p);
    799 		tmp++;
    800 		ref_p++;
    801 	}
    802 
    803 	return (tnf_ref32(ops, (tnf_record_p) bufhdr, reference));
    804 }
    805 
    806 /*
    807  * Type record as generic (not tag) reference
    808  */
    809 
    810 tnf_reference_t
    811 tnf_tag_element_1(tnf_ops_t *ops, tnf_tag_data_t **tag_data_p,
    812 		tnf_record_p reference, tnf_tag_data_t *aux_tag_data)
    813 {
    814 	tnf_tag_data_t	*tag_data;
    815 
    816 	if (aux_tag_data)
    817 		if (!aux_tag_data->tag_index)
    818 			aux_tag_data->tag_desc(ops, aux_tag_data);
    819 
    820 	/* tnf_derived has derived_base == TNF_NULL */
    821 	if (!tag_data_p)
    822 		return ((tnf_reference_t)TNF_NULL);
    823 
    824 	tag_data = *tag_data_p;
    825 	if (!tag_data->tag_index)
    826 		tag_data->tag_desc(ops, tag_data);
    827 
    828 	return (tnf_ref32(ops, tag_data->tag_index, reference));
    829 }
    830 
    831 
    832 /*
    833  * Array of type records as generic (not tag) references
    834  */
    835 
    836 tnf_reference_t
    837 tnf_tag_array_1(tnf_ops_t		*ops,
    838 		tnf_tag_data_t		***tag_data_array,
    839 		tnf_record_p		reference,
    840 		tnf_tag_data_t		*tag_data)
    841 {
    842 	tnf_record_p 	tag_index;
    843 	size_t		record_size;
    844 	tnf_array_header_t 	*bufhdr;
    845 	tnf_tag_data_t	***tmp;
    846 	tnf_reference_t	*ref_p;
    847 
    848 	tag_index = tag_data->tag_index ? tag_data->tag_index :
    849 		tag_data->tag_desc(ops, tag_data);
    850 
    851 	if (!tag_data_array)
    852 		return ((tnf_reference_t)TNF_NULL);
    853 
    854 	record_size = sizeof (*bufhdr);
    855 	tmp = tag_data_array;
    856 	while (*tmp++)
    857 		record_size += sizeof (tnf_reference_t);
    858 
    859 	ALLOC2(ops, record_size, bufhdr, ops->mode);
    860 
    861 	ASSIGN(bufhdr, tag, 		tag_index);
    862 	/* LINTED assignment of 64-bit integer to 32-bit integer */
    863 	ASSIGN(bufhdr, self_size, 	record_size);
    864 
    865 	tmp = tag_data_array;
    866 	/* LINTED pointer cast may result in improper alignment */
    867 	ref_p = (tnf_reference_t *)((char *)bufhdr + sizeof (*bufhdr));
    868 	while (*tmp) {
    869 		*ref_p = tnf_tag_element_1(ops, *tmp, (tnf_record_p)ref_p,
    870 		    TNF_NULL);
    871 		tmp++;
    872 		ref_p++;
    873 	}
    874 
    875 	return (tnf_ref32(ops, (tnf_record_p)bufhdr, reference));
    876 }
    877 
    878 /*
    879  * Array of properties (type records)
    880  */
    881 
    882 tnf_reference_t
    883 tnf_tag_properties_1(tnf_ops_t		*ops,
    884 		tnf_tag_data_t		****tag_data_array,
    885 		tnf_record_p		reference,
    886 		tnf_tag_data_t		*tag_data)
    887 {
    888 	if (!(tag_data->tag_index))
    889 		tag_data->tag_desc(ops, tag_data);
    890 
    891 	if (!tag_data_array)
    892 		return ((tnf_reference_t)TNF_NULL);
    893 
    894 	return (tnf_tag_array_1(ops, *tag_data_array, reference, tag_data));
    895 }
    896 
    897 #ifdef _KERNEL
    898 /*
    899  * Initialize all core tag pointers defined in this file.
    900  * CAUTION: tnf_tag_core_init is a function for kernel compilation.
    901  */
    902 
    903 void
    904 tnf_tag_core_init(void)
    905 {
    906 #endif
    907 	TAG_SET(tnf_inline);
    908 	TAG_SET(tnf_tagged);
    909 
    910 	TAG_SET(tnf_scalar);
    911 	TAG_SET(tnf_char);
    912 	TAG_SET(tnf_int8);
    913 	TAG_SET(tnf_uint8);
    914 	TAG_SET(tnf_int16);
    915 	TAG_SET(tnf_uint16);
    916 	TAG_SET(tnf_int32);
    917 	TAG_SET(tnf_uint32);
    918 	TAG_SET(tnf_int64);
    919 	TAG_SET(tnf_uint64);
    920 
    921 	TAG_SET(tnf_float32);
    922 	TAG_SET(tnf_float64);
    923 
    924 	TAG_SET(tnf_array);
    925 	TAG_SET(tnf_string);
    926 	TAG_SET(tnf_type_array);
    927 	TAG_SET(tnf_name_array);
    928 
    929 	TAG_SET(tnf_derived);
    930 	TAG_SET(tnf_align);
    931 	TAG_SET(tnf_derived_base);
    932 	TAG_SET(tnf_element_type);
    933 	TAG_SET(tnf_header_size);
    934 	TAG_SET(tnf_name);
    935 	TAG_SET(tnf_opaque);
    936 	TAG_SET(tnf_properties);
    937 	TAG_SET(tnf_self_size);
    938 	TAG_SET(tnf_size);
    939 	TAG_SET(tnf_slot_names);
    940 	TAG_SET(tnf_slot_types);
    941 	TAG_SET(tnf_tag);
    942 	TAG_SET(tnf_tag_arg);
    943 	TAG_SET(tnf_type_size);
    944 
    945 	TAG_SET(tnf_struct);
    946 	TAG_SET(tnf_file_header);
    947 	TAG_SET(tnf_block_header);
    948 
    949 	TAG_SET(tnf_type);
    950 	TAG_SET(tnf_array_type);
    951 	TAG_SET(tnf_derived_type);
    952 	TAG_SET(tnf_scalar_type);
    953 	TAG_SET(tnf_struct_type);
    954 
    955 #ifdef _KERNEL
    956 
    957 	/* Snap exported properties */
    958 	tnf_user_struct_properties = std_struct_properties;
    959 
    960 }
    961 
    962 #else	/* _KERNEL */
    963 
    964 tnf_tag_data_t ***tnf_user_struct_properties = std_struct_properties;
    965 
    966 #endif	/* _KERNEL */
    967