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 "%Z%%M% %I% %E% 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