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
md_byte_hash(uint8_t * bp,int len)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 *
md_find_string(mmd_t * mdp,char * strp,uint32_t * hashp)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 *
md_new_string(mmd_t * mdp,char * strp)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 *
md_find_data_block(mmd_t * mdp,uint8_t * datap,int len,uint32_t * hashp)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 *
md_new_data_block(mmd_t * mdp,uint8_t * bufp,int len)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 *
md_new_node(mmd_t * mdp,char * sp)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 *
md_new_property(mmd_t * mdp,md_node_t * nodep,uint8_t type,char * sp)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
md_add_value_property(mmd_t * mdp,md_node_t * nodep,char * sp,uint64_t value)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
md_add_string_property(mmd_t * mdp,md_node_t * nodep,char * sp,char * bufp)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
md_add_data_property(mmd_t * mdp,md_node_t * nodep,char * sp,int len,uint8_t * bufp)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
md_add_arc_property(mmd_t * mdp,md_node_t * nodep,char * arcnamep,md_node_t * tgtnodep)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 *
md_link_new_node(mmd_t * mdp,char * nodenamep,md_node_t * parentnodep,char * linktonewp,char * linkbackp)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
md_destroy(mmd_t * mdp)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
md_free_node(mmd_t * mdp,md_node_t * nodep)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
md_free_prop(mmd_t * mdp,md_prop_t * propp)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
md_free_string(mmd_t * mdp,md_string_t * msp)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
md_free_data_block(mmd_t * mdp,md_data_block_t * mdbp)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 *
md_new_md(void)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
md_fix_name(md_element_t * mdep,md_prop_t * propp)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
create_mde(md_element_t * mdep,int type,md_node_t * nodep,md_prop_t * propp)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
md_gen_bin(mmd_t * mdp,uint8_t ** bufvalp)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