xref: /titanic_41/usr/src/cmd/ldmad/mdesc_lib.c (revision fc256490629fe68815f7e0f23cf9b3545720cfac)
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