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