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
tnf_ref32_1(tnf_ops_t * ops,tnf_record_p item,tnf_record_p reference)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
tnf_ref32_1(tnf_ops_t * ops,tnf_record_p item,tnf_record_p reference)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
tnf_abstract_tag_1(tnf_ops_t * ops,tnf_tag_data_t * tag_data)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
tnf_scalar_tag_1(tnf_ops_t * ops,tnf_tag_data_t * tag_data)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
tnf_derived_tag_1(tnf_ops_t * ops,tnf_tag_data_t * tag_data)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
tnf_struct_tag_1(tnf_ops_t * ops,tnf_tag_data_t * tag_data)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
tnf_array_tag_1(tnf_ops_t * ops,tnf_tag_data_t * tag_data)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
tnf_root_tag_1(tnf_ops_t * ops,tnf_tag_data_t * tag_data)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
tnf_string_1(tnf_ops_t * ops,const char * string,tnf_record_p reference,tnf_tag_data_t * tag_data)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
tnf_string_array_1(tnf_ops_t * ops,char ** strings,tnf_record_p reference,tnf_tag_data_t * tag_data)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
tnf_tag_element_1(tnf_ops_t * ops,tnf_tag_data_t ** tag_data_p,tnf_record_p reference,tnf_tag_data_t * aux_tag_data)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
tnf_tag_array_1(tnf_ops_t * ops,tnf_tag_data_t *** tag_data_array,tnf_record_p reference,tnf_tag_data_t * tag_data)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
tnf_tag_properties_1(tnf_ops_t * ops,tnf_tag_data_t **** tag_data_array,tnf_record_p reference,tnf_tag_data_t * tag_data)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
tnf_tag_core_init(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