1*fc256490SJason Beloro /* 2*fc256490SJason Beloro * CDDL HEADER START 3*fc256490SJason Beloro * 4*fc256490SJason Beloro * The contents of this file are subject to the terms of the 5*fc256490SJason Beloro * Common Development and Distribution License (the "License"). 6*fc256490SJason Beloro * You may not use this file except in compliance with the License. 7*fc256490SJason Beloro * 8*fc256490SJason Beloro * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*fc256490SJason Beloro * or http://www.opensolaris.org/os/licensing. 10*fc256490SJason Beloro * See the License for the specific language governing permissions 11*fc256490SJason Beloro * and limitations under the License. 12*fc256490SJason Beloro * 13*fc256490SJason Beloro * When distributing Covered Code, include this CDDL HEADER in each 14*fc256490SJason Beloro * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*fc256490SJason Beloro * If applicable, add the following below this CDDL HEADER, with the 16*fc256490SJason Beloro * fields enclosed by brackets "[]" replaced with your own identifying 17*fc256490SJason Beloro * information: Portions Copyright [yyyy] [name of copyright owner] 18*fc256490SJason Beloro * 19*fc256490SJason Beloro * CDDL HEADER END 20*fc256490SJason Beloro */ 21*fc256490SJason Beloro 22*fc256490SJason Beloro /* 23*fc256490SJason Beloro * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 24*fc256490SJason Beloro * Use is subject to license terms. 25*fc256490SJason Beloro */ 26*fc256490SJason Beloro 27*fc256490SJason Beloro #include <strings.h> 28*fc256490SJason Beloro #include <stdio.h> 29*fc256490SJason Beloro #include <unistd.h> 30*fc256490SJason Beloro #include <stdlib.h> 31*fc256490SJason Beloro #include <strings.h> 32*fc256490SJason Beloro #include <note.h> 33*fc256490SJason Beloro #include <errno.h> 34*fc256490SJason Beloro #include <sys/mdesc.h> 35*fc256490SJason Beloro #include <sys/mdesc_impl.h> 36*fc256490SJason Beloro #include <sys/sysmacros.h> 37*fc256490SJason Beloro #include "mdesc_mutable.h" 38*fc256490SJason Beloro 39*fc256490SJason Beloro static void md_free_prop(mmd_t *mdp, md_prop_t *propp); 40*fc256490SJason Beloro static void md_free_string(mmd_t *mdp, md_string_t *msp); 41*fc256490SJason Beloro static void md_free_data_block(mmd_t *mdp, md_data_block_t *mdbp); 42*fc256490SJason Beloro 43*fc256490SJason Beloro static uint32_t 44*fc256490SJason Beloro md_byte_hash(uint8_t *bp, int len) 45*fc256490SJason Beloro { 46*fc256490SJason Beloro uint32_t hash = 0; 47*fc256490SJason Beloro int i; 48*fc256490SJason Beloro 49*fc256490SJason Beloro for (i = 0; i < len; i++) { 50*fc256490SJason Beloro /* 5 bit rotation */ 51*fc256490SJason Beloro hash = (hash >> 27) | (hash << 5) | bp[i]; 52*fc256490SJason Beloro } 53*fc256490SJason Beloro 54*fc256490SJason Beloro return (hash); 55*fc256490SJason Beloro } 56*fc256490SJason Beloro 57*fc256490SJason Beloro static md_string_t * 58*fc256490SJason Beloro md_find_string(mmd_t *mdp, char *strp, uint32_t *hashp) 59*fc256490SJason Beloro { 60*fc256490SJason Beloro md_string_t *msp; 61*fc256490SJason Beloro uint32_t hash; 62*fc256490SJason Beloro 63*fc256490SJason Beloro hash = md_byte_hash((uint8_t *)strp, strlen(strp)); 64*fc256490SJason Beloro 65*fc256490SJason Beloro if (hashp != NULL) 66*fc256490SJason Beloro *hashp = hash; 67*fc256490SJason Beloro 68*fc256490SJason Beloro CHAIN_ITER(mdp->string_list, msp) { 69*fc256490SJason Beloro if (msp->hash == hash && strcmp(msp->strp, strp) == 0) 70*fc256490SJason Beloro return (msp); 71*fc256490SJason Beloro } 72*fc256490SJason Beloro 73*fc256490SJason Beloro return (NULL); 74*fc256490SJason Beloro } 75*fc256490SJason Beloro 76*fc256490SJason Beloro static md_string_t * 77*fc256490SJason Beloro md_new_string(mmd_t *mdp, char *strp) 78*fc256490SJason Beloro { 79*fc256490SJason Beloro md_string_t *msp; 80*fc256490SJason Beloro uint32_t hash; 81*fc256490SJason Beloro 82*fc256490SJason Beloro msp = md_find_string(mdp, strp, &hash); 83*fc256490SJason Beloro if (msp == NULL) { 84*fc256490SJason Beloro msp = calloc(1, sizeof (md_string_t)); 85*fc256490SJason Beloro if (msp == NULL) 86*fc256490SJason Beloro return (NULL); 87*fc256490SJason Beloro msp->strp = strdup(strp); 88*fc256490SJason Beloro if (msp->strp == NULL) { 89*fc256490SJason Beloro free(msp); 90*fc256490SJason Beloro return (NULL); 91*fc256490SJason Beloro } 92*fc256490SJason Beloro msp->size = strlen(strp) + 1; 93*fc256490SJason Beloro msp->hash = hash; 94*fc256490SJason Beloro msp->ref_cnt = 0; 95*fc256490SJason Beloro msp->build_offset = MD_OFFSET_UNDEF; 96*fc256490SJason Beloro CHAIN_ADD(mdp->string_list, msp); 97*fc256490SJason Beloro } 98*fc256490SJason Beloro msp->ref_cnt++; 99*fc256490SJason Beloro 100*fc256490SJason Beloro return (msp); 101*fc256490SJason Beloro } 102*fc256490SJason Beloro 103*fc256490SJason Beloro static md_data_block_t * 104*fc256490SJason Beloro md_find_data_block(mmd_t *mdp, uint8_t *datap, int len, uint32_t *hashp) 105*fc256490SJason Beloro { 106*fc256490SJason Beloro md_data_block_t *dbp; 107*fc256490SJason Beloro uint32_t hash; 108*fc256490SJason Beloro 109*fc256490SJason Beloro hash = md_byte_hash(datap, len); 110*fc256490SJason Beloro 111*fc256490SJason Beloro if (hashp != NULL) 112*fc256490SJason Beloro *hashp = hash; 113*fc256490SJason Beloro 114*fc256490SJason Beloro CHAIN_ITER(mdp->data_block_list, dbp) { 115*fc256490SJason Beloro if (dbp->size == len && 116*fc256490SJason Beloro dbp->hash == hash && bcmp(dbp->datap, datap, len) == 0) 117*fc256490SJason Beloro return (dbp); 118*fc256490SJason Beloro } 119*fc256490SJason Beloro 120*fc256490SJason Beloro return (NULL); 121*fc256490SJason Beloro } 122*fc256490SJason Beloro 123*fc256490SJason Beloro static md_data_block_t * 124*fc256490SJason Beloro md_new_data_block(mmd_t *mdp, uint8_t *bufp, int len) 125*fc256490SJason Beloro { 126*fc256490SJason Beloro md_data_block_t *dbp; 127*fc256490SJason Beloro uint32_t hash; 128*fc256490SJason Beloro 129*fc256490SJason Beloro dbp = md_find_data_block(mdp, bufp, len, &hash); 130*fc256490SJason Beloro if (dbp == NULL) { 131*fc256490SJason Beloro dbp = calloc(1, sizeof (md_data_block_t)); 132*fc256490SJason Beloro if (dbp == NULL) 133*fc256490SJason Beloro return (NULL); 134*fc256490SJason Beloro dbp->datap = malloc(len); 135*fc256490SJason Beloro if (dbp->datap == NULL) { 136*fc256490SJason Beloro free(dbp); 137*fc256490SJason Beloro return (NULL); 138*fc256490SJason Beloro } 139*fc256490SJason Beloro (void) memcpy(dbp->datap, bufp, len); 140*fc256490SJason Beloro dbp->size = len; 141*fc256490SJason Beloro dbp->hash = hash; 142*fc256490SJason Beloro dbp->ref_cnt = 0; 143*fc256490SJason Beloro dbp->build_offset = MD_OFFSET_UNDEF; 144*fc256490SJason Beloro CHAIN_ADD(mdp->data_block_list, dbp); 145*fc256490SJason Beloro } 146*fc256490SJason Beloro dbp->ref_cnt++; 147*fc256490SJason Beloro 148*fc256490SJason Beloro return (dbp); 149*fc256490SJason Beloro } 150*fc256490SJason Beloro 151*fc256490SJason Beloro md_node_t * 152*fc256490SJason Beloro md_new_node(mmd_t *mdp, char *sp) 153*fc256490SJason Beloro { 154*fc256490SJason Beloro md_node_t *nodep; 155*fc256490SJason Beloro 156*fc256490SJason Beloro nodep = calloc(1, sizeof (md_node_t)); 157*fc256490SJason Beloro if (nodep == NULL) 158*fc256490SJason Beloro return (NULL); 159*fc256490SJason Beloro nodep->typep = md_new_string(mdp, sp); 160*fc256490SJason Beloro if (nodep->typep == NULL) { 161*fc256490SJason Beloro free(nodep); 162*fc256490SJason Beloro return (NULL); 163*fc256490SJason Beloro } 164*fc256490SJason Beloro CHAIN_ADD(mdp->node_list, nodep); 165*fc256490SJason Beloro 166*fc256490SJason Beloro return (nodep); 167*fc256490SJason Beloro } 168*fc256490SJason Beloro 169*fc256490SJason Beloro static md_prop_t * 170*fc256490SJason Beloro md_new_property(mmd_t *mdp, md_node_t *nodep, uint8_t type, char *sp) 171*fc256490SJason Beloro { 172*fc256490SJason Beloro md_prop_t *propp; 173*fc256490SJason Beloro 174*fc256490SJason Beloro propp = calloc(1, sizeof (md_prop_t)); 175*fc256490SJason Beloro if (propp == NULL) 176*fc256490SJason Beloro return (NULL); 177*fc256490SJason Beloro propp->type = type; 178*fc256490SJason Beloro propp->sp = md_new_string(mdp, sp); 179*fc256490SJason Beloro if (propp->sp == NULL) { 180*fc256490SJason Beloro free(propp); 181*fc256490SJason Beloro return (NULL); 182*fc256490SJason Beloro } 183*fc256490SJason Beloro 184*fc256490SJason Beloro CHAIN_ADD(nodep->prop_list, propp); 185*fc256490SJason Beloro 186*fc256490SJason Beloro return (propp); 187*fc256490SJason Beloro } 188*fc256490SJason Beloro 189*fc256490SJason Beloro int 190*fc256490SJason Beloro md_add_value_property(mmd_t *mdp, md_node_t *nodep, char *sp, uint64_t value) 191*fc256490SJason Beloro { 192*fc256490SJason Beloro md_prop_t *propp; 193*fc256490SJason Beloro 194*fc256490SJason Beloro propp = md_new_property(mdp, nodep, MDET_PROP_VAL, sp); 195*fc256490SJason Beloro if (propp == NULL) 196*fc256490SJason Beloro return (ENOMEM); 197*fc256490SJason Beloro propp->d.value = value; 198*fc256490SJason Beloro return (0); 199*fc256490SJason Beloro } 200*fc256490SJason Beloro 201*fc256490SJason Beloro int 202*fc256490SJason Beloro md_add_string_property(mmd_t *mdp, md_node_t *nodep, char *sp, char *bufp) 203*fc256490SJason Beloro { 204*fc256490SJason Beloro md_prop_t *propp; 205*fc256490SJason Beloro md_data_block_t *dbp; 206*fc256490SJason Beloro 207*fc256490SJason Beloro dbp = md_new_data_block(mdp, (uint8_t *)bufp, strlen(bufp) + 1); 208*fc256490SJason Beloro if (dbp == NULL) 209*fc256490SJason Beloro return (ENOMEM); 210*fc256490SJason Beloro propp = md_new_property(mdp, nodep, MDET_PROP_STR, sp); 211*fc256490SJason Beloro if (propp == NULL) { 212*fc256490SJason Beloro md_free_data_block(mdp, dbp); 213*fc256490SJason Beloro return (NULL); 214*fc256490SJason Beloro } 215*fc256490SJason Beloro propp->d.dbp = dbp; 216*fc256490SJason Beloro return (0); 217*fc256490SJason Beloro } 218*fc256490SJason Beloro 219*fc256490SJason Beloro int 220*fc256490SJason Beloro md_add_data_property(mmd_t *mdp, md_node_t *nodep, char *sp, int len, 221*fc256490SJason Beloro uint8_t *bufp) 222*fc256490SJason Beloro { 223*fc256490SJason Beloro md_prop_t *propp; 224*fc256490SJason Beloro md_data_block_t *dbp; 225*fc256490SJason Beloro 226*fc256490SJason Beloro dbp = md_new_data_block(mdp, bufp, len); 227*fc256490SJason Beloro if (dbp == NULL) 228*fc256490SJason Beloro return (ENOMEM); 229*fc256490SJason Beloro 230*fc256490SJason Beloro propp = md_new_property(mdp, nodep, MDET_PROP_DAT, sp); 231*fc256490SJason Beloro if (propp == NULL) { 232*fc256490SJason Beloro md_free_data_block(mdp, dbp); 233*fc256490SJason Beloro return (ENOMEM); 234*fc256490SJason Beloro } 235*fc256490SJason Beloro propp->d.dbp = dbp; 236*fc256490SJason Beloro return (0); 237*fc256490SJason Beloro } 238*fc256490SJason Beloro 239*fc256490SJason Beloro static int 240*fc256490SJason Beloro md_add_arc_property(mmd_t *mdp, md_node_t *nodep, char *arcnamep, 241*fc256490SJason Beloro md_node_t *tgtnodep) 242*fc256490SJason Beloro { 243*fc256490SJason Beloro md_prop_t *propp; 244*fc256490SJason Beloro 245*fc256490SJason Beloro propp = md_new_property(mdp, nodep, MDET_PROP_ARC, arcnamep); 246*fc256490SJason Beloro if (propp == NULL) 247*fc256490SJason Beloro return (ENOMEM); 248*fc256490SJason Beloro propp->d.arc.is_ptr = B_TRUE; 249*fc256490SJason Beloro propp->d.arc.val.nodep = tgtnodep; 250*fc256490SJason Beloro return (0); 251*fc256490SJason Beloro } 252*fc256490SJason Beloro 253*fc256490SJason Beloro md_node_t * 254*fc256490SJason Beloro md_link_new_node(mmd_t *mdp, char *nodenamep, md_node_t *parentnodep, 255*fc256490SJason Beloro char *linktonewp, char *linkbackp) 256*fc256490SJason Beloro { 257*fc256490SJason Beloro md_node_t *nodep; 258*fc256490SJason Beloro 259*fc256490SJason Beloro nodep = md_new_node(mdp, nodenamep); 260*fc256490SJason Beloro if (nodep == NULL) 261*fc256490SJason Beloro return (NULL); 262*fc256490SJason Beloro 263*fc256490SJason Beloro ASSERT(linktonewp != NULL); 264*fc256490SJason Beloro ASSERT(parentnodep != NULL && !parentnodep->deleted); 265*fc256490SJason Beloro 266*fc256490SJason Beloro if (md_add_arc_property(mdp, parentnodep, linktonewp, nodep) != 0) { 267*fc256490SJason Beloro return (NULL); 268*fc256490SJason Beloro } 269*fc256490SJason Beloro 270*fc256490SJason Beloro if (linkbackp != NULL) { 271*fc256490SJason Beloro if (md_add_arc_property(mdp, 272*fc256490SJason Beloro nodep, linkbackp, parentnodep) != 0) { 273*fc256490SJason Beloro return (NULL); 274*fc256490SJason Beloro } 275*fc256490SJason Beloro } 276*fc256490SJason Beloro 277*fc256490SJason Beloro return (nodep); 278*fc256490SJason Beloro } 279*fc256490SJason Beloro 280*fc256490SJason Beloro void 281*fc256490SJason Beloro md_destroy(mmd_t *mdp) 282*fc256490SJason Beloro { 283*fc256490SJason Beloro md_node_t *nodep; 284*fc256490SJason Beloro 285*fc256490SJason Beloro for (nodep = CHAIN_START(mdp->node_list); nodep != NULL; ) { 286*fc256490SJason Beloro md_node_t *tmp_nodep; 287*fc256490SJason Beloro 288*fc256490SJason Beloro tmp_nodep = nodep->nextp; 289*fc256490SJason Beloro md_free_node(mdp, nodep); 290*fc256490SJason Beloro 291*fc256490SJason Beloro nodep = tmp_nodep; 292*fc256490SJason Beloro } 293*fc256490SJason Beloro 294*fc256490SJason Beloro /* should have deleted all the string refs by here */ 295*fc256490SJason Beloro ASSERT(CHAIN_LENGTH(mdp->string_list) == 0); 296*fc256490SJason Beloro free(mdp); 297*fc256490SJason Beloro } 298*fc256490SJason Beloro 299*fc256490SJason Beloro void 300*fc256490SJason Beloro md_free_node(mmd_t *mdp, md_node_t *nodep) 301*fc256490SJason Beloro { 302*fc256490SJason Beloro md_prop_t *propp; 303*fc256490SJason Beloro 304*fc256490SJason Beloro if (nodep->typep != NULL) 305*fc256490SJason Beloro md_free_string(mdp, nodep->typep); 306*fc256490SJason Beloro 307*fc256490SJason Beloro for (propp = CHAIN_START(nodep->prop_list); propp != NULL; ) { 308*fc256490SJason Beloro md_prop_t *tmp_propp; 309*fc256490SJason Beloro 310*fc256490SJason Beloro tmp_propp = propp->nextp; 311*fc256490SJason Beloro md_free_prop(mdp, propp); 312*fc256490SJason Beloro 313*fc256490SJason Beloro propp = tmp_propp; 314*fc256490SJason Beloro } 315*fc256490SJason Beloro 316*fc256490SJason Beloro free(nodep); 317*fc256490SJason Beloro } 318*fc256490SJason Beloro 319*fc256490SJason Beloro static void 320*fc256490SJason Beloro md_free_prop(mmd_t *mdp, md_prop_t *propp) 321*fc256490SJason Beloro { 322*fc256490SJason Beloro if (propp->sp != NULL) 323*fc256490SJason Beloro md_free_string(mdp, propp->sp); 324*fc256490SJason Beloro 325*fc256490SJason Beloro switch (propp->type) { 326*fc256490SJason Beloro case MDET_PROP_VAL: 327*fc256490SJason Beloro break; 328*fc256490SJason Beloro 329*fc256490SJason Beloro case MDET_PROP_ARC: 330*fc256490SJason Beloro break; 331*fc256490SJason Beloro 332*fc256490SJason Beloro case MDET_PROP_STR: 333*fc256490SJason Beloro case MDET_PROP_DAT: 334*fc256490SJason Beloro md_free_data_block(mdp, propp->d.dbp); 335*fc256490SJason Beloro break; 336*fc256490SJason Beloro 337*fc256490SJason Beloro default: 338*fc256490SJason Beloro ASSERT(B_FALSE); 339*fc256490SJason Beloro } 340*fc256490SJason Beloro 341*fc256490SJason Beloro free(propp); 342*fc256490SJason Beloro } 343*fc256490SJason Beloro 344*fc256490SJason Beloro static void 345*fc256490SJason Beloro md_free_string(mmd_t *mdp, md_string_t *msp) 346*fc256490SJason Beloro { 347*fc256490SJason Beloro ASSERT(msp->ref_cnt > 0); 348*fc256490SJason Beloro 349*fc256490SJason Beloro msp->ref_cnt--; 350*fc256490SJason Beloro 351*fc256490SJason Beloro if (msp->ref_cnt == 0) { 352*fc256490SJason Beloro free(msp->strp); 353*fc256490SJason Beloro mdp->string_list.startp = msp->nextp; 354*fc256490SJason Beloro free(msp); 355*fc256490SJason Beloro } 356*fc256490SJason Beloro } 357*fc256490SJason Beloro 358*fc256490SJason Beloro static void 359*fc256490SJason Beloro md_free_data_block(mmd_t *mdp, md_data_block_t *mdbp) 360*fc256490SJason Beloro { 361*fc256490SJason Beloro ASSERT(mdbp->ref_cnt > 0); 362*fc256490SJason Beloro 363*fc256490SJason Beloro mdbp->ref_cnt--; 364*fc256490SJason Beloro 365*fc256490SJason Beloro if (mdbp->ref_cnt == 0) { 366*fc256490SJason Beloro free(mdbp->datap); 367*fc256490SJason Beloro mdp->data_block_list.startp = mdbp->nextp; 368*fc256490SJason Beloro free(mdbp); 369*fc256490SJason Beloro } 370*fc256490SJason Beloro } 371*fc256490SJason Beloro 372*fc256490SJason Beloro mmd_t * 373*fc256490SJason Beloro md_new_md(void) 374*fc256490SJason Beloro { 375*fc256490SJason Beloro return ((mmd_t *)calloc(1, sizeof (mmd_t))); 376*fc256490SJason Beloro } 377*fc256490SJason Beloro 378*fc256490SJason Beloro static void 379*fc256490SJason Beloro md_fix_name(md_element_t *mdep, md_prop_t *propp) 380*fc256490SJason Beloro { 381*fc256490SJason Beloro mdep->name_len = htomd8(propp->sp->size - 1); 382*fc256490SJason Beloro mdep->name_offset = htomd32(propp->sp->build_offset); 383*fc256490SJason Beloro } 384*fc256490SJason Beloro 385*fc256490SJason Beloro void 386*fc256490SJason Beloro create_mde(md_element_t *mdep, int type, md_node_t *nodep, md_prop_t *propp) 387*fc256490SJason Beloro { 388*fc256490SJason Beloro (void) memset(mdep, 0, MD_ELEMENT_SIZE); 389*fc256490SJason Beloro mdep->tag = htomd8(type); 390*fc256490SJason Beloro 391*fc256490SJason Beloro switch (type) { 392*fc256490SJason Beloro case MDET_NODE: 393*fc256490SJason Beloro mdep->d.prop_idx = htomd32(nodep->next_index); 394*fc256490SJason Beloro mdep->name_len = htomd8(nodep->typep->size - 1); 395*fc256490SJason Beloro mdep->name_offset = htomd32(nodep->typep->build_offset); 396*fc256490SJason Beloro break; 397*fc256490SJason Beloro 398*fc256490SJason Beloro case MDET_PROP_ARC: 399*fc256490SJason Beloro ASSERT(propp->d.arc.is_ptr); 400*fc256490SJason Beloro mdep->d.prop_idx = htomd64(propp->d.arc.val.nodep->build_index); 401*fc256490SJason Beloro md_fix_name(mdep, propp); 402*fc256490SJason Beloro break; 403*fc256490SJason Beloro 404*fc256490SJason Beloro case MDET_PROP_VAL: 405*fc256490SJason Beloro mdep->d.prop_val = htomd64(propp->d.value); 406*fc256490SJason Beloro md_fix_name(mdep, propp); 407*fc256490SJason Beloro break; 408*fc256490SJason Beloro 409*fc256490SJason Beloro case MDET_PROP_STR: 410*fc256490SJason Beloro case MDET_PROP_DAT: 411*fc256490SJason Beloro mdep->d.prop_data.offset = htomd32(propp->d.dbp->build_offset); 412*fc256490SJason Beloro mdep->d.prop_data.len = htomd32(propp->d.dbp->size); 413*fc256490SJason Beloro md_fix_name(mdep, propp); 414*fc256490SJason Beloro break; 415*fc256490SJason Beloro 416*fc256490SJason Beloro case MDET_NULL: 417*fc256490SJason Beloro case MDET_NODE_END: 418*fc256490SJason Beloro case MDET_LIST_END: 419*fc256490SJason Beloro break; 420*fc256490SJason Beloro 421*fc256490SJason Beloro default: 422*fc256490SJason Beloro ASSERT(B_FALSE); 423*fc256490SJason Beloro } 424*fc256490SJason Beloro } 425*fc256490SJason Beloro 426*fc256490SJason Beloro int 427*fc256490SJason Beloro md_gen_bin(mmd_t *mdp, uint8_t **bufvalp) 428*fc256490SJason Beloro { 429*fc256490SJason Beloro uint32_t offset; 430*fc256490SJason Beloro md_node_t *nodep; 431*fc256490SJason Beloro md_data_block_t *mdbp; 432*fc256490SJason Beloro md_string_t *msp; 433*fc256490SJason Beloro md_header_t *mdhp; 434*fc256490SJason Beloro md_element_t *mdep; 435*fc256490SJason Beloro uint32_t strings_size; 436*fc256490SJason Beloro uint32_t data_block_size; 437*fc256490SJason Beloro int total_size; 438*fc256490SJason Beloro uint8_t *bufferp; 439*fc256490SJason Beloro uint8_t *string_bufferp; 440*fc256490SJason Beloro uint8_t *data_block_bufferp; 441*fc256490SJason Beloro 442*fc256490SJason Beloro /* 443*fc256490SJason Beloro * Skip through strings to compute offsets. 444*fc256490SJason Beloro */ 445*fc256490SJason Beloro offset = 0; 446*fc256490SJason Beloro for (msp = CHAIN_START(mdp->string_list); msp != NULL; 447*fc256490SJason Beloro msp = msp->nextp) { 448*fc256490SJason Beloro msp->build_offset = offset; 449*fc256490SJason Beloro offset += msp->size; 450*fc256490SJason Beloro } 451*fc256490SJason Beloro strings_size = P2ROUNDUP(offset, MD_ALIGNMENT_SIZE); 452*fc256490SJason Beloro 453*fc256490SJason Beloro /* 454*fc256490SJason Beloro * Skip through data blocks to compute offsets. 455*fc256490SJason Beloro */ 456*fc256490SJason Beloro 457*fc256490SJason Beloro offset = 0; 458*fc256490SJason Beloro for (mdbp = CHAIN_START(mdp->data_block_list); mdbp != NULL; 459*fc256490SJason Beloro mdbp = mdbp->nextp) { 460*fc256490SJason Beloro mdbp->build_offset = offset; 461*fc256490SJason Beloro offset += mdbp->size; 462*fc256490SJason Beloro offset = P2ROUNDUP(offset, MD_ALIGNMENT_SIZE); 463*fc256490SJason Beloro } 464*fc256490SJason Beloro data_block_size = P2ROUNDUP(offset, MD_ALIGNMENT_SIZE); 465*fc256490SJason Beloro 466*fc256490SJason Beloro /* 467*fc256490SJason Beloro * Compute the MD elements required to build the element list. 468*fc256490SJason Beloro * For each node there is a node start and end, and one 469*fc256490SJason Beloro * element for each property. 470*fc256490SJason Beloro */ 471*fc256490SJason Beloro 472*fc256490SJason Beloro offset = 0; 473*fc256490SJason Beloro for (nodep = CHAIN_START(mdp->node_list); nodep != NULL; 474*fc256490SJason Beloro nodep = nodep->nextp) { 475*fc256490SJason Beloro nodep->build_index = offset; 476*fc256490SJason Beloro offset += 2 + CHAIN_LENGTH(nodep->prop_list); 477*fc256490SJason Beloro nodep->next_index = offset; 478*fc256490SJason Beloro } 479*fc256490SJason Beloro offset += 1; /* add the LIST_END element */ 480*fc256490SJason Beloro 481*fc256490SJason Beloro total_size = MD_HEADER_SIZE + offset * MD_ELEMENT_SIZE + 482*fc256490SJason Beloro strings_size + data_block_size; 483*fc256490SJason Beloro 484*fc256490SJason Beloro /* 485*fc256490SJason Beloro * Allocate output buffer. 486*fc256490SJason Beloro */ 487*fc256490SJason Beloro 488*fc256490SJason Beloro bufferp = calloc(total_size, sizeof (uint8_t)); 489*fc256490SJason Beloro if (bufferp == NULL) 490*fc256490SJason Beloro return (0); 491*fc256490SJason Beloro 492*fc256490SJason Beloro /* LINTED */ 493*fc256490SJason Beloro mdhp = (md_header_t *)bufferp; 494*fc256490SJason Beloro 495*fc256490SJason Beloro string_bufferp = bufferp + MD_HEADER_SIZE + offset * MD_ELEMENT_SIZE; 496*fc256490SJason Beloro data_block_bufferp = string_bufferp + strings_size; 497*fc256490SJason Beloro 498*fc256490SJason Beloro mdhp->transport_version = htomd32(MD_TRANSPORT_VERSION); 499*fc256490SJason Beloro mdhp->node_blk_sz = htomd32(offset * MD_ELEMENT_SIZE); 500*fc256490SJason Beloro mdhp->name_blk_sz = htomd32(strings_size); 501*fc256490SJason Beloro mdhp->data_blk_sz = htomd32(data_block_size); 502*fc256490SJason Beloro 503*fc256490SJason Beloro /* 504*fc256490SJason Beloro * Build the element list. 505*fc256490SJason Beloro * For each node there is a node start and end, and one 506*fc256490SJason Beloro * element for each property. 507*fc256490SJason Beloro */ 508*fc256490SJason Beloro 509*fc256490SJason Beloro offset = 0; 510*fc256490SJason Beloro /* LINTED */ 511*fc256490SJason Beloro mdep = (md_element_t *)(bufferp + MD_HEADER_SIZE); 512*fc256490SJason Beloro for (nodep = CHAIN_START(mdp->node_list); nodep != NULL; 513*fc256490SJason Beloro nodep = nodep->nextp) { 514*fc256490SJason Beloro md_prop_t *propp; 515*fc256490SJason Beloro 516*fc256490SJason Beloro create_mde(mdep, MDET_NODE, nodep, NULL); 517*fc256490SJason Beloro mdep++; 518*fc256490SJason Beloro 519*fc256490SJason Beloro for (propp = CHAIN_START(nodep->prop_list); propp != NULL; 520*fc256490SJason Beloro propp = propp->nextp) { 521*fc256490SJason Beloro create_mde(mdep, propp->type, nodep, propp); 522*fc256490SJason Beloro mdep++; 523*fc256490SJason Beloro } 524*fc256490SJason Beloro 525*fc256490SJason Beloro create_mde(mdep, MDET_NODE_END, NULL, NULL); 526*fc256490SJason Beloro mdep++; 527*fc256490SJason Beloro } 528*fc256490SJason Beloro 529*fc256490SJason Beloro create_mde(mdep, MDET_LIST_END, NULL, NULL); 530*fc256490SJason Beloro mdep++; 531*fc256490SJason Beloro 532*fc256490SJason Beloro /* 533*fc256490SJason Beloro * Quick sanity check. 534*fc256490SJason Beloro */ 535*fc256490SJason Beloro 536*fc256490SJason Beloro ASSERT(((uint8_t *)mdep) == ((uint8_t *)string_bufferp)); 537*fc256490SJason Beloro 538*fc256490SJason Beloro /* 539*fc256490SJason Beloro * Skip through strings and stash them.. 540*fc256490SJason Beloro */ 541*fc256490SJason Beloro 542*fc256490SJason Beloro offset = 0; 543*fc256490SJason Beloro for (msp = CHAIN_START(mdp->string_list); msp != NULL; 544*fc256490SJason Beloro msp = msp->nextp) { 545*fc256490SJason Beloro (void) memcpy(string_bufferp + msp->build_offset, msp->strp, 546*fc256490SJason Beloro msp->size); 547*fc256490SJason Beloro } 548*fc256490SJason Beloro 549*fc256490SJason Beloro /* 550*fc256490SJason Beloro * Skip through data blocks and stash them. 551*fc256490SJason Beloro */ 552*fc256490SJason Beloro 553*fc256490SJason Beloro offset = 0; 554*fc256490SJason Beloro for (mdbp = CHAIN_START(mdp->data_block_list); mdbp != NULL; 555*fc256490SJason Beloro mdbp = mdbp->nextp) { 556*fc256490SJason Beloro (void) memcpy(data_block_bufferp + mdbp->build_offset, 557*fc256490SJason Beloro mdbp->datap, mdbp->size); 558*fc256490SJason Beloro } 559*fc256490SJason Beloro 560*fc256490SJason Beloro *bufvalp = bufferp; 561*fc256490SJason Beloro return (total_size); 562*fc256490SJason Beloro } 563