1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright (c) 1994, by Sun Microsytems, Inc. 24*7c478bd9Sstevel@tonic-gate */ 25*7c478bd9Sstevel@tonic-gate 26*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 27*7c478bd9Sstevel@tonic-gate 28*7c478bd9Sstevel@tonic-gate #include "libtnf.h" 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate #define TAG_INDEX(x) (TNF_TAG16_ABS16(x) / sizeof (tnf_ref32_t)) 31*7c478bd9Sstevel@tonic-gate 32*7c478bd9Sstevel@tonic-gate /* 33*7c478bd9Sstevel@tonic-gate * 34*7c478bd9Sstevel@tonic-gate */ 35*7c478bd9Sstevel@tonic-gate 36*7c478bd9Sstevel@tonic-gate static struct taginfo * add_info(TNF *, tnf_ref32_t *); 37*7c478bd9Sstevel@tonic-gate 38*7c478bd9Sstevel@tonic-gate static struct taginfo * 39*7c478bd9Sstevel@tonic-gate init_abstract_info(TNF *, tnf_ref32_t *, struct taginfo *); 40*7c478bd9Sstevel@tonic-gate 41*7c478bd9Sstevel@tonic-gate static struct taginfo * 42*7c478bd9Sstevel@tonic-gate init_derived_info(TNF *, tnf_ref32_t *, struct taginfo *); 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gate static struct taginfo * 45*7c478bd9Sstevel@tonic-gate init_scalar_info(TNF *, tnf_ref32_t *, struct taginfo *); 46*7c478bd9Sstevel@tonic-gate 47*7c478bd9Sstevel@tonic-gate static struct taginfo * 48*7c478bd9Sstevel@tonic-gate init_struct_info(TNF *, tnf_ref32_t *, struct taginfo *); 49*7c478bd9Sstevel@tonic-gate 50*7c478bd9Sstevel@tonic-gate static struct taginfo * 51*7c478bd9Sstevel@tonic-gate init_array_info(TNF *, tnf_ref32_t *, struct taginfo *); 52*7c478bd9Sstevel@tonic-gate 53*7c478bd9Sstevel@tonic-gate static void init_slots(TNF *, tnf_ref32_t *, struct taginfo *); 54*7c478bd9Sstevel@tonic-gate 55*7c478bd9Sstevel@tonic-gate /* 56*7c478bd9Sstevel@tonic-gate * Allocate tag table and directory 57*7c478bd9Sstevel@tonic-gate */ 58*7c478bd9Sstevel@tonic-gate 59*7c478bd9Sstevel@tonic-gate tnf_errcode_t 60*7c478bd9Sstevel@tonic-gate _tnf_init_tags(TNF *tnf) 61*7c478bd9Sstevel@tonic-gate { 62*7c478bd9Sstevel@tonic-gate if ((tnf->tag_table = calloc(TAGTABCNT, sizeof (struct taginfo *))) 63*7c478bd9Sstevel@tonic-gate == NULL) 64*7c478bd9Sstevel@tonic-gate return (TNF_ERR_ALLOCFAIL); 65*7c478bd9Sstevel@tonic-gate if ((tnf->tag_directory = calloc(TAGDIRCNT(tnf->directory_size), 66*7c478bd9Sstevel@tonic-gate sizeof (struct taginfo *))) 67*7c478bd9Sstevel@tonic-gate == NULL) 68*7c478bd9Sstevel@tonic-gate return (TNF_ERR_ALLOCFAIL); 69*7c478bd9Sstevel@tonic-gate return (TNF_ERR_NONE); 70*7c478bd9Sstevel@tonic-gate } 71*7c478bd9Sstevel@tonic-gate 72*7c478bd9Sstevel@tonic-gate /* 73*7c478bd9Sstevel@tonic-gate * Deallocate all taginfos and tables associated with TNF handle 74*7c478bd9Sstevel@tonic-gate */ 75*7c478bd9Sstevel@tonic-gate 76*7c478bd9Sstevel@tonic-gate tnf_errcode_t 77*7c478bd9Sstevel@tonic-gate _tnf_fini_tags(TNF *tnf) 78*7c478bd9Sstevel@tonic-gate { 79*7c478bd9Sstevel@tonic-gate int i; 80*7c478bd9Sstevel@tonic-gate struct taginfo *info, *link; 81*7c478bd9Sstevel@tonic-gate 82*7c478bd9Sstevel@tonic-gate /* 83*7c478bd9Sstevel@tonic-gate * free taginfos 84*7c478bd9Sstevel@tonic-gate */ 85*7c478bd9Sstevel@tonic-gate for (i = 0; i < TAGTABCNT; i++) { 86*7c478bd9Sstevel@tonic-gate info = tnf->tag_table[i]; 87*7c478bd9Sstevel@tonic-gate while (info) { 88*7c478bd9Sstevel@tonic-gate /* remember link */ 89*7c478bd9Sstevel@tonic-gate link = info->link; 90*7c478bd9Sstevel@tonic-gate /* free slot information */ 91*7c478bd9Sstevel@tonic-gate if (info->slotinfo) 92*7c478bd9Sstevel@tonic-gate free(info->slotinfo); 93*7c478bd9Sstevel@tonic-gate /* free taginfo */ 94*7c478bd9Sstevel@tonic-gate free(info); 95*7c478bd9Sstevel@tonic-gate /* next in hash chain */ 96*7c478bd9Sstevel@tonic-gate info = link; 97*7c478bd9Sstevel@tonic-gate } 98*7c478bd9Sstevel@tonic-gate } 99*7c478bd9Sstevel@tonic-gate /* 100*7c478bd9Sstevel@tonic-gate * free the tables 101*7c478bd9Sstevel@tonic-gate */ 102*7c478bd9Sstevel@tonic-gate free(tnf->tag_table); 103*7c478bd9Sstevel@tonic-gate tnf->tag_table = NULL; 104*7c478bd9Sstevel@tonic-gate free(tnf->tag_directory); 105*7c478bd9Sstevel@tonic-gate tnf->tag_directory = NULL; 106*7c478bd9Sstevel@tonic-gate 107*7c478bd9Sstevel@tonic-gate return (TNF_ERR_NONE); 108*7c478bd9Sstevel@tonic-gate } 109*7c478bd9Sstevel@tonic-gate 110*7c478bd9Sstevel@tonic-gate /* 111*7c478bd9Sstevel@tonic-gate * Get info for supplied tag 112*7c478bd9Sstevel@tonic-gate */ 113*7c478bd9Sstevel@tonic-gate 114*7c478bd9Sstevel@tonic-gate struct taginfo * 115*7c478bd9Sstevel@tonic-gate _tnf_get_info(TNF *tnf, tnf_ref32_t *tag) 116*7c478bd9Sstevel@tonic-gate { 117*7c478bd9Sstevel@tonic-gate struct taginfo *bucket, *info; 118*7c478bd9Sstevel@tonic-gate 119*7c478bd9Sstevel@tonic-gate bucket = tnf->tag_table[TAGHASH(tnf, tag)]; 120*7c478bd9Sstevel@tonic-gate for (info = bucket; info; info = info->link) 121*7c478bd9Sstevel@tonic-gate if (info->tag == tag) 122*7c478bd9Sstevel@tonic-gate return (info); /* found it */ 123*7c478bd9Sstevel@tonic-gate 124*7c478bd9Sstevel@tonic-gate /* default: not there, create */ 125*7c478bd9Sstevel@tonic-gate return (add_info(tnf, tag)); 126*7c478bd9Sstevel@tonic-gate } 127*7c478bd9Sstevel@tonic-gate 128*7c478bd9Sstevel@tonic-gate /* 129*7c478bd9Sstevel@tonic-gate * Get info for supplied record 130*7c478bd9Sstevel@tonic-gate * Use fast lookup, if possible 131*7c478bd9Sstevel@tonic-gate */ 132*7c478bd9Sstevel@tonic-gate 133*7c478bd9Sstevel@tonic-gate struct taginfo * 134*7c478bd9Sstevel@tonic-gate _tnf_record_info(TNF *tnf, tnf_ref32_t *record) 135*7c478bd9Sstevel@tonic-gate { 136*7c478bd9Sstevel@tonic-gate tnf_ref32_t ref32; 137*7c478bd9Sstevel@tonic-gate tnf_ref16_t tag16; 138*7c478bd9Sstevel@tonic-gate tnf_abs16_t index; 139*7c478bd9Sstevel@tonic-gate struct taginfo *info; 140*7c478bd9Sstevel@tonic-gate 141*7c478bd9Sstevel@tonic-gate ref32 = _GET_INT32(tnf, record); 142*7c478bd9Sstevel@tonic-gate 143*7c478bd9Sstevel@tonic-gate index = 0; 144*7c478bd9Sstevel@tonic-gate if (TNF_REF32_IS_PAIR(ref32)) { 145*7c478bd9Sstevel@tonic-gate tag16 = TNF_REF32_TAG16(ref32); 146*7c478bd9Sstevel@tonic-gate if (TNF_TAG16_IS_ABS(tag16)) 147*7c478bd9Sstevel@tonic-gate index = TAG_INDEX(tag16); 148*7c478bd9Sstevel@tonic-gate } 149*7c478bd9Sstevel@tonic-gate 150*7c478bd9Sstevel@tonic-gate if (index) { 151*7c478bd9Sstevel@tonic-gate if ((info = tnf->tag_directory[index]) != NULL) 152*7c478bd9Sstevel@tonic-gate return (info); 153*7c478bd9Sstevel@tonic-gate else { /* not in directory yet */ 154*7c478bd9Sstevel@tonic-gate info = _tnf_get_info(tnf, _tnf_get_tag(tnf, record)); 155*7c478bd9Sstevel@tonic-gate /* enter into tag directory */ 156*7c478bd9Sstevel@tonic-gate return ((tnf->tag_directory[index] = info)); 157*7c478bd9Sstevel@tonic-gate } 158*7c478bd9Sstevel@tonic-gate } 159*7c478bd9Sstevel@tonic-gate 160*7c478bd9Sstevel@tonic-gate /* default: not referenced via index */ 161*7c478bd9Sstevel@tonic-gate return (_tnf_get_info(tnf, _tnf_get_tag(tnf, record))); 162*7c478bd9Sstevel@tonic-gate } 163*7c478bd9Sstevel@tonic-gate 164*7c478bd9Sstevel@tonic-gate /* 165*7c478bd9Sstevel@tonic-gate * Add a new taginfo for tag 166*7c478bd9Sstevel@tonic-gate */ 167*7c478bd9Sstevel@tonic-gate 168*7c478bd9Sstevel@tonic-gate static struct taginfo * 169*7c478bd9Sstevel@tonic-gate add_info(TNF *tnf, tnf_ref32_t *tag) 170*7c478bd9Sstevel@tonic-gate { 171*7c478bd9Sstevel@tonic-gate struct taginfo *info, *bucket; 172*7c478bd9Sstevel@tonic-gate unsigned hash; 173*7c478bd9Sstevel@tonic-gate tnf_ref32_t *meta; 174*7c478bd9Sstevel@tonic-gate 175*7c478bd9Sstevel@tonic-gate info = (struct taginfo *)calloc(1, sizeof (struct taginfo)); 176*7c478bd9Sstevel@tonic-gate 177*7c478bd9Sstevel@tonic-gate /* Initialize members */ 178*7c478bd9Sstevel@tonic-gate info->tnf = tnf; 179*7c478bd9Sstevel@tonic-gate info->tag = tag; 180*7c478bd9Sstevel@tonic-gate info->name = _tnf_get_name(tnf, tag); 181*7c478bd9Sstevel@tonic-gate info->props = _tnf_get_props(tnf, tag); 182*7c478bd9Sstevel@tonic-gate info->kind = _tnf_get_kind(tnf, tag); 183*7c478bd9Sstevel@tonic-gate info->size = _tnf_get_storage_size(tnf, tag); 184*7c478bd9Sstevel@tonic-gate info->align = _tnf_get_align(tnf, tag); 185*7c478bd9Sstevel@tonic-gate 186*7c478bd9Sstevel@tonic-gate /* Add it to table */ 187*7c478bd9Sstevel@tonic-gate hash = TAGHASH(tnf, tag); 188*7c478bd9Sstevel@tonic-gate bucket = tnf->tag_table[hash]; 189*7c478bd9Sstevel@tonic-gate info->link = bucket; 190*7c478bd9Sstevel@tonic-gate tnf->tag_table[hash] = info; 191*7c478bd9Sstevel@tonic-gate 192*7c478bd9Sstevel@tonic-gate /* Ensure meta info is available */ 193*7c478bd9Sstevel@tonic-gate meta = _tnf_get_tag(tnf, tag); 194*7c478bd9Sstevel@tonic-gate info->meta = _tnf_get_info(tnf, meta); 195*7c478bd9Sstevel@tonic-gate 196*7c478bd9Sstevel@tonic-gate /* 197*7c478bd9Sstevel@tonic-gate * Initialize info 198*7c478bd9Sstevel@tonic-gate * Derived must be first clause due to property inheritance 199*7c478bd9Sstevel@tonic-gate */ 200*7c478bd9Sstevel@tonic-gate 201*7c478bd9Sstevel@tonic-gate if (INFO_DERIVED(info)) 202*7c478bd9Sstevel@tonic-gate return (init_derived_info(tnf, tag, info)); 203*7c478bd9Sstevel@tonic-gate else if (INFO_STRUCT(info)) 204*7c478bd9Sstevel@tonic-gate return (init_struct_info(tnf, tag, info)); 205*7c478bd9Sstevel@tonic-gate else if (INFO_ARRAY(info)) 206*7c478bd9Sstevel@tonic-gate return (init_array_info(tnf, tag, info)); 207*7c478bd9Sstevel@tonic-gate else if (INFO_SCALAR(info)) 208*7c478bd9Sstevel@tonic-gate return (init_scalar_info(tnf, tag, info)); 209*7c478bd9Sstevel@tonic-gate else /* XXX assume abstract type */ 210*7c478bd9Sstevel@tonic-gate return (init_abstract_info(tnf, tag, info)); 211*7c478bd9Sstevel@tonic-gate } 212*7c478bd9Sstevel@tonic-gate 213*7c478bd9Sstevel@tonic-gate 214*7c478bd9Sstevel@tonic-gate /* 215*7c478bd9Sstevel@tonic-gate * Initialize info for an abstract tag 216*7c478bd9Sstevel@tonic-gate */ 217*7c478bd9Sstevel@tonic-gate 218*7c478bd9Sstevel@tonic-gate static struct taginfo * 219*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 220*7c478bd9Sstevel@tonic-gate init_abstract_info(TNF *tnf, tnf_ref32_t *tag, struct taginfo *info) 221*7c478bd9Sstevel@tonic-gate { 222*7c478bd9Sstevel@tonic-gate if (INFO_SCALAR(info) || INFO_DERIVED(info) || 223*7c478bd9Sstevel@tonic-gate INFO_STRUCT(info) || INFO_ARRAY(info)) 224*7c478bd9Sstevel@tonic-gate _tnf_error(tnf, TNF_ERR_INTERNAL); 225*7c478bd9Sstevel@tonic-gate if (info->size == (size_t)-1) 226*7c478bd9Sstevel@tonic-gate _tnf_error(tnf, TNF_ERR_BADTNF); 227*7c478bd9Sstevel@tonic-gate return (info); 228*7c478bd9Sstevel@tonic-gate } 229*7c478bd9Sstevel@tonic-gate 230*7c478bd9Sstevel@tonic-gate /* 231*7c478bd9Sstevel@tonic-gate * Initialize info for a derived tag 232*7c478bd9Sstevel@tonic-gate */ 233*7c478bd9Sstevel@tonic-gate 234*7c478bd9Sstevel@tonic-gate static struct taginfo * 235*7c478bd9Sstevel@tonic-gate init_derived_info(TNF *tnf, tnf_ref32_t *tag, struct taginfo *info) 236*7c478bd9Sstevel@tonic-gate { 237*7c478bd9Sstevel@tonic-gate tnf_ref32_t *base_tag; 238*7c478bd9Sstevel@tonic-gate 239*7c478bd9Sstevel@tonic-gate if (!INFO_DERIVED(info)) 240*7c478bd9Sstevel@tonic-gate _tnf_error(tnf, TNF_ERR_INTERNAL); 241*7c478bd9Sstevel@tonic-gate 242*7c478bd9Sstevel@tonic-gate /* Ensure ultimate base information is available */ 243*7c478bd9Sstevel@tonic-gate base_tag = _tnf_get_base_tag(tnf, tag); 244*7c478bd9Sstevel@tonic-gate info->base = _tnf_get_info(tnf, base_tag); 245*7c478bd9Sstevel@tonic-gate 246*7c478bd9Sstevel@tonic-gate return (info); 247*7c478bd9Sstevel@tonic-gate } 248*7c478bd9Sstevel@tonic-gate 249*7c478bd9Sstevel@tonic-gate /* 250*7c478bd9Sstevel@tonic-gate * Initialize info for a scalar tag 251*7c478bd9Sstevel@tonic-gate */ 252*7c478bd9Sstevel@tonic-gate 253*7c478bd9Sstevel@tonic-gate static struct taginfo * 254*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 255*7c478bd9Sstevel@tonic-gate init_scalar_info(TNF *tnf, tnf_ref32_t *tag, struct taginfo *info) 256*7c478bd9Sstevel@tonic-gate { 257*7c478bd9Sstevel@tonic-gate if ((!INFO_SCALAR(info)) || 258*7c478bd9Sstevel@tonic-gate (INFO_DERIVED(info) || INFO_ARRAY(info) || INFO_STRUCT(info))) 259*7c478bd9Sstevel@tonic-gate _tnf_error(tnf, TNF_ERR_INTERNAL); 260*7c478bd9Sstevel@tonic-gate if (info->size == (size_t)-1) 261*7c478bd9Sstevel@tonic-gate _tnf_error(tnf, TNF_ERR_BADTNF); 262*7c478bd9Sstevel@tonic-gate 263*7c478bd9Sstevel@tonic-gate /* XXX alignment already done */ 264*7c478bd9Sstevel@tonic-gate 265*7c478bd9Sstevel@tonic-gate return (info); 266*7c478bd9Sstevel@tonic-gate } 267*7c478bd9Sstevel@tonic-gate 268*7c478bd9Sstevel@tonic-gate /* 269*7c478bd9Sstevel@tonic-gate * Initialize info for a struct tag 270*7c478bd9Sstevel@tonic-gate */ 271*7c478bd9Sstevel@tonic-gate 272*7c478bd9Sstevel@tonic-gate static struct taginfo * 273*7c478bd9Sstevel@tonic-gate init_struct_info(TNF *tnf, tnf_ref32_t *tag, struct taginfo *info) 274*7c478bd9Sstevel@tonic-gate { 275*7c478bd9Sstevel@tonic-gate if ((!INFO_STRUCT(info)) || 276*7c478bd9Sstevel@tonic-gate (INFO_DERIVED(info) || INFO_ARRAY(info) || INFO_SCALAR(info))) 277*7c478bd9Sstevel@tonic-gate _tnf_error(tnf, TNF_ERR_INTERNAL); 278*7c478bd9Sstevel@tonic-gate if (info->size == (size_t)-1) 279*7c478bd9Sstevel@tonic-gate _tnf_error(tnf, TNF_ERR_BADTNF); 280*7c478bd9Sstevel@tonic-gate 281*7c478bd9Sstevel@tonic-gate /* Get slot information */ 282*7c478bd9Sstevel@tonic-gate init_slots(tnf, tag, info); 283*7c478bd9Sstevel@tonic-gate 284*7c478bd9Sstevel@tonic-gate return (info); 285*7c478bd9Sstevel@tonic-gate } 286*7c478bd9Sstevel@tonic-gate 287*7c478bd9Sstevel@tonic-gate /* 288*7c478bd9Sstevel@tonic-gate * Initialize info for an array tag 289*7c478bd9Sstevel@tonic-gate */ 290*7c478bd9Sstevel@tonic-gate 291*7c478bd9Sstevel@tonic-gate static struct taginfo * 292*7c478bd9Sstevel@tonic-gate init_array_info(TNF *tnf, tnf_ref32_t *tag, struct taginfo *info) 293*7c478bd9Sstevel@tonic-gate { 294*7c478bd9Sstevel@tonic-gate tnf_ref32_t *elt_tag; 295*7c478bd9Sstevel@tonic-gate int defeat; 296*7c478bd9Sstevel@tonic-gate 297*7c478bd9Sstevel@tonic-gate if ((!INFO_ARRAY(info)) || 298*7c478bd9Sstevel@tonic-gate (INFO_DERIVED(info) || INFO_STRUCT(info) || INFO_SCALAR(info))) 299*7c478bd9Sstevel@tonic-gate _tnf_error(tnf, TNF_ERR_INTERNAL); 300*7c478bd9Sstevel@tonic-gate 301*7c478bd9Sstevel@tonic-gate /* XXX special-case abstract array tag */ 302*7c478bd9Sstevel@tonic-gate defeat = (strcmp(info->name, TNF_N_ARRAY) == 0); 303*7c478bd9Sstevel@tonic-gate 304*7c478bd9Sstevel@tonic-gate /* Require all arrays to be self-sized records */ 305*7c478bd9Sstevel@tonic-gate if (!(INFO_TAGGED(info) && (info->size == (size_t)-1))) 306*7c478bd9Sstevel@tonic-gate if (!defeat) 307*7c478bd9Sstevel@tonic-gate _tnf_error(tnf, TNF_ERR_BADTNF); 308*7c478bd9Sstevel@tonic-gate 309*7c478bd9Sstevel@tonic-gate /* Store array header size */ 310*7c478bd9Sstevel@tonic-gate info->hdrsize = _tnf_get_header_size(tnf, tag); 311*7c478bd9Sstevel@tonic-gate /* XXX Temporary sanity check */ 312*7c478bd9Sstevel@tonic-gate if (info->hdrsize != sizeof (struct tnf_array_hdr)) 313*7c478bd9Sstevel@tonic-gate if (!defeat) 314*7c478bd9Sstevel@tonic-gate _tnf_error(tnf, TNF_ERR_BADTNF); 315*7c478bd9Sstevel@tonic-gate 316*7c478bd9Sstevel@tonic-gate /* Get slot information */ 317*7c478bd9Sstevel@tonic-gate init_slots(tnf, tag, info); 318*7c478bd9Sstevel@tonic-gate 319*7c478bd9Sstevel@tonic-gate /* Get info for element type */ 320*7c478bd9Sstevel@tonic-gate elt_tag = (tnf_ref32_t *)_tnf_get_slot_typed(tnf, tag, 321*7c478bd9Sstevel@tonic-gate /* LINTED pointer cast may result in improper alignment */ 322*7c478bd9Sstevel@tonic-gate TNF_N_ELEMENT_TYPE); 323*7c478bd9Sstevel@tonic-gate /* XXX tnf_array has element_type == NULL */ 324*7c478bd9Sstevel@tonic-gate info->base = elt_tag ? _tnf_get_info(tnf, elt_tag): NULL; 325*7c478bd9Sstevel@tonic-gate 326*7c478bd9Sstevel@tonic-gate return (info); 327*7c478bd9Sstevel@tonic-gate } 328*7c478bd9Sstevel@tonic-gate 329*7c478bd9Sstevel@tonic-gate /* 330*7c478bd9Sstevel@tonic-gate * Initialize slot information for aggregate tag 331*7c478bd9Sstevel@tonic-gate */ 332*7c478bd9Sstevel@tonic-gate 333*7c478bd9Sstevel@tonic-gate static void 334*7c478bd9Sstevel@tonic-gate init_slots(TNF *tnf, tnf_ref32_t *tag, struct taginfo *info) 335*7c478bd9Sstevel@tonic-gate { 336*7c478bd9Sstevel@tonic-gate tnf_ref32_t *slot_types, *slot_names; 337*7c478bd9Sstevel@tonic-gate tnf_ref32_t *types, *names; 338*7c478bd9Sstevel@tonic-gate unsigned count, i, offset; 339*7c478bd9Sstevel@tonic-gate struct slotinfo *slotinfo; 340*7c478bd9Sstevel@tonic-gate 341*7c478bd9Sstevel@tonic-gate slot_types = (tnf_ref32_t *) 342*7c478bd9Sstevel@tonic-gate /* LINTED pointer cast may result in improper alignment */ 343*7c478bd9Sstevel@tonic-gate _tnf_get_slot_typed(tnf, tag, TNF_N_SLOT_TYPES); 344*7c478bd9Sstevel@tonic-gate slot_names = (tnf_ref32_t *) 345*7c478bd9Sstevel@tonic-gate /* LINTED pointer cast may result in improper alignment */ 346*7c478bd9Sstevel@tonic-gate _tnf_get_slot_typed(tnf, tag, TNF_N_SLOT_NAMES); 347*7c478bd9Sstevel@tonic-gate 348*7c478bd9Sstevel@tonic-gate /* abstract tags have no slots */ 349*7c478bd9Sstevel@tonic-gate if (slot_types == TNF_NULL) 350*7c478bd9Sstevel@tonic-gate return; 351*7c478bd9Sstevel@tonic-gate 352*7c478bd9Sstevel@tonic-gate count = _tnf_get_element_count(tnf, slot_types, sizeof (tnf_ref32_t)); 353*7c478bd9Sstevel@tonic-gate /* LINTED pointer cast may result in improper alignment */ 354*7c478bd9Sstevel@tonic-gate types = (tnf_ref32_t *)_tnf_get_elements(tnf, slot_types); 355*7c478bd9Sstevel@tonic-gate names = ((slot_names == TNF_NULL) ? TNF_NULL : 356*7c478bd9Sstevel@tonic-gate /* LINTED pointer cast may result in improper alignment */ 357*7c478bd9Sstevel@tonic-gate (tnf_ref32_t *)_tnf_get_elements(tnf, slot_names)); 358*7c478bd9Sstevel@tonic-gate 359*7c478bd9Sstevel@tonic-gate slotinfo = (struct slotinfo *) 360*7c478bd9Sstevel@tonic-gate calloc(1, sizeof (unsigned) + (count * sizeof (struct slot))); 361*7c478bd9Sstevel@tonic-gate if (slotinfo == (struct slotinfo *)NULL) 362*7c478bd9Sstevel@tonic-gate _tnf_error(tnf, TNF_ERR_ALLOCFAIL); 363*7c478bd9Sstevel@tonic-gate 364*7c478bd9Sstevel@tonic-gate slotinfo->slot_count = count; 365*7c478bd9Sstevel@tonic-gate offset = 0; 366*7c478bd9Sstevel@tonic-gate 367*7c478bd9Sstevel@tonic-gate for (i = 0; i < count; i++) { 368*7c478bd9Sstevel@tonic-gate tnf_ref32_t *type_elt, *name_elt; 369*7c478bd9Sstevel@tonic-gate struct taginfo *elt_info; 370*7c478bd9Sstevel@tonic-gate size_t ref_size, align; 371*7c478bd9Sstevel@tonic-gate 372*7c478bd9Sstevel@tonic-gate /* XXX No checks here for missing tags */ 373*7c478bd9Sstevel@tonic-gate type_elt = _GET_REF32(tnf, &types[i]); 374*7c478bd9Sstevel@tonic-gate name_elt = names ? _GET_REF32(tnf, &names[i]) : TNF_NULL; 375*7c478bd9Sstevel@tonic-gate 376*7c478bd9Sstevel@tonic-gate /* Resolve slot tag into taginfo */ 377*7c478bd9Sstevel@tonic-gate elt_info = _tnf_get_info(tnf, type_elt); 378*7c478bd9Sstevel@tonic-gate slotinfo->slots[i].slot_type = elt_info; 379*7c478bd9Sstevel@tonic-gate slotinfo->slots[i].slot_name = 380*7c478bd9Sstevel@tonic-gate ((name_elt != TNF_NULL) ? 381*7c478bd9Sstevel@tonic-gate _tnf_get_chars(tnf, name_elt) : 382*7c478bd9Sstevel@tonic-gate _tnf_get_name(tnf, type_elt)); 383*7c478bd9Sstevel@tonic-gate 384*7c478bd9Sstevel@tonic-gate /* Get cached reference size */ 385*7c478bd9Sstevel@tonic-gate ref_size = INFO_REF_SIZE(elt_info); 386*7c478bd9Sstevel@tonic-gate 387*7c478bd9Sstevel@tonic-gate /* Get cached alignment */ 388*7c478bd9Sstevel@tonic-gate align = INFO_ALIGN(elt_info); /* XXX */ 389*7c478bd9Sstevel@tonic-gate 390*7c478bd9Sstevel@tonic-gate /* Adjust offset to account for alignment, if needed */ 391*7c478bd9Sstevel@tonic-gate offset = ALIGN(offset, align); 392*7c478bd9Sstevel@tonic-gate 393*7c478bd9Sstevel@tonic-gate slotinfo->slots[i].slot_offset = offset; 394*7c478bd9Sstevel@tonic-gate 395*7c478bd9Sstevel@tonic-gate /* Bump offset by reference size */ 396*7c478bd9Sstevel@tonic-gate offset += ref_size; 397*7c478bd9Sstevel@tonic-gate } 398*7c478bd9Sstevel@tonic-gate 399*7c478bd9Sstevel@tonic-gate info->slotinfo = slotinfo; 400*7c478bd9Sstevel@tonic-gate } 401