1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate *
4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate * with the License.
8*7c478bd9Sstevel@tonic-gate *
9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate *
14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate *
20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate * Copyright (c) 1994, by Sun Microsytems, Inc.
24*7c478bd9Sstevel@tonic-gate */
25*7c478bd9Sstevel@tonic-gate
26*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
27*7c478bd9Sstevel@tonic-gate
28*7c478bd9Sstevel@tonic-gate #include "libtnf.h"
29*7c478bd9Sstevel@tonic-gate
30*7c478bd9Sstevel@tonic-gate /*
31*7c478bd9Sstevel@tonic-gate * Operations based on ABI bootstrap assumptions
32*7c478bd9Sstevel@tonic-gate */
33*7c478bd9Sstevel@tonic-gate
34*7c478bd9Sstevel@tonic-gate #define _GET_TAG(tnf, p) \
35*7c478bd9Sstevel@tonic-gate _GET_REF32(tnf, p)
36*7c478bd9Sstevel@tonic-gate
37*7c478bd9Sstevel@tonic-gate #define _GET_TAG_ARG(tnf, p) \
38*7c478bd9Sstevel@tonic-gate _GET_REF16(tnf, p)
39*7c478bd9Sstevel@tonic-gate
40*7c478bd9Sstevel@tonic-gate #define _GET_SELF_SIZE(tnf, p) \
41*7c478bd9Sstevel@tonic-gate _GET_UINT32(tnf, &((struct tnf_array_hdr *)(p))->self_size)
42*7c478bd9Sstevel@tonic-gate
43*7c478bd9Sstevel@tonic-gate #define _GET_NAME(tnf, p) \
44*7c478bd9Sstevel@tonic-gate _GET_REF32(tnf, &((struct tnf_type_hdr *)(p))->name)
45*7c478bd9Sstevel@tonic-gate
46*7c478bd9Sstevel@tonic-gate #define _GET_PROPERTIES(tnf, p) \
47*7c478bd9Sstevel@tonic-gate _GET_REF32(tnf, &((struct tnf_type_hdr *)(p))->properties)
48*7c478bd9Sstevel@tonic-gate
49*7c478bd9Sstevel@tonic-gate #define _GET_SLOT_TYPES(tnf, p) \
50*7c478bd9Sstevel@tonic-gate _GET_REF32(tnf, &((struct tnf_struct_type_hdr *)(p))->slot_types)
51*7c478bd9Sstevel@tonic-gate
52*7c478bd9Sstevel@tonic-gate #define _GET_TYPE_SIZE(tnf, p) \
53*7c478bd9Sstevel@tonic-gate _GET_UINT32(tnf, &((struct tnf_struct_type_hdr *)(p))->type_size)
54*7c478bd9Sstevel@tonic-gate
55*7c478bd9Sstevel@tonic-gate #define _GET_HEADER_SIZE(tnf, p) \
56*7c478bd9Sstevel@tonic-gate _GET_UINT32(tnf, &((struct tnf_array_type_hdr *)(p))->header_size)
57*7c478bd9Sstevel@tonic-gate
58*7c478bd9Sstevel@tonic-gate #define _GET_DERIVED_BASE(tnf, p) \
59*7c478bd9Sstevel@tonic-gate _GET_REF32(tnf, &((struct tnf_derived_type_hdr *)(p))->derived_base)
60*7c478bd9Sstevel@tonic-gate
61*7c478bd9Sstevel@tonic-gate /*
62*7c478bd9Sstevel@tonic-gate * Static declarations
63*7c478bd9Sstevel@tonic-gate */
64*7c478bd9Sstevel@tonic-gate
65*7c478bd9Sstevel@tonic-gate static caddr_t fetch_slot(TNF *, caddr_t, tnf_ref32_t *);
66*7c478bd9Sstevel@tonic-gate
67*7c478bd9Sstevel@tonic-gate /*
68*7c478bd9Sstevel@tonic-gate * retrieve tag slot from a record
69*7c478bd9Sstevel@tonic-gate */
70*7c478bd9Sstevel@tonic-gate
71*7c478bd9Sstevel@tonic-gate tnf_ref32_t *
_tnf_get_tag(TNF * tnf,tnf_ref32_t * record)72*7c478bd9Sstevel@tonic-gate _tnf_get_tag(TNF *tnf, tnf_ref32_t *record)
73*7c478bd9Sstevel@tonic-gate {
74*7c478bd9Sstevel@tonic-gate return (_GET_TAG(tnf, record));
75*7c478bd9Sstevel@tonic-gate }
76*7c478bd9Sstevel@tonic-gate
77*7c478bd9Sstevel@tonic-gate /*
78*7c478bd9Sstevel@tonic-gate * Retrieve tag_arg from tag slot of a record
79*7c478bd9Sstevel@tonic-gate */
80*7c478bd9Sstevel@tonic-gate
81*7c478bd9Sstevel@tonic-gate tnf_ref32_t *
_tnf_get_tag_arg(TNF * tnf,tnf_ref32_t * record)82*7c478bd9Sstevel@tonic-gate _tnf_get_tag_arg(TNF *tnf, tnf_ref32_t *record)
83*7c478bd9Sstevel@tonic-gate {
84*7c478bd9Sstevel@tonic-gate return (_GET_TAG_ARG(tnf, record));
85*7c478bd9Sstevel@tonic-gate }
86*7c478bd9Sstevel@tonic-gate
87*7c478bd9Sstevel@tonic-gate /*
88*7c478bd9Sstevel@tonic-gate * Retrieve the self_size slot of an ABI array record
89*7c478bd9Sstevel@tonic-gate */
90*7c478bd9Sstevel@tonic-gate
91*7c478bd9Sstevel@tonic-gate size_t
_tnf_get_self_size(TNF * tnf,tnf_ref32_t * array)92*7c478bd9Sstevel@tonic-gate _tnf_get_self_size(TNF *tnf, tnf_ref32_t *array)
93*7c478bd9Sstevel@tonic-gate {
94*7c478bd9Sstevel@tonic-gate return (_GET_SELF_SIZE(tnf, array));
95*7c478bd9Sstevel@tonic-gate }
96*7c478bd9Sstevel@tonic-gate
97*7c478bd9Sstevel@tonic-gate /*
98*7c478bd9Sstevel@tonic-gate * Calculate the number of elements in ABI array record
99*7c478bd9Sstevel@tonic-gate */
100*7c478bd9Sstevel@tonic-gate
101*7c478bd9Sstevel@tonic-gate unsigned
_tnf_get_element_count(TNF * tnf,tnf_ref32_t * array,unsigned eltsize)102*7c478bd9Sstevel@tonic-gate _tnf_get_element_count(TNF *tnf, tnf_ref32_t *array, unsigned eltsize)
103*7c478bd9Sstevel@tonic-gate {
104*7c478bd9Sstevel@tonic-gate size_t size, hdrsize;
105*7c478bd9Sstevel@tonic-gate #ifdef INFINITE_RECURSION_ARRAY
106*7c478bd9Sstevel@tonic-gate tnf_ref32_t *base_tag;
107*7c478bd9Sstevel@tonic-gate
108*7c478bd9Sstevel@tonic-gate size = _tnf_get_self_size(tnf, array);
109*7c478bd9Sstevel@tonic-gate base_tag = _tnf_get_base_tag(tnf, _tnf_get_tag(tnf, array));
110*7c478bd9Sstevel@tonic-gate hdrsize = _tnf_get_header_size(tnf, base_tag);
111*7c478bd9Sstevel@tonic-gate return (((size - hdrsize) / eltsize));
112*7c478bd9Sstevel@tonic-gate #else
113*7c478bd9Sstevel@tonic-gate size = _tnf_get_self_size(tnf, array);
114*7c478bd9Sstevel@tonic-gate hdrsize = sizeof (struct tnf_array_hdr);
115*7c478bd9Sstevel@tonic-gate return (((size - hdrsize) / eltsize));
116*7c478bd9Sstevel@tonic-gate #endif
117*7c478bd9Sstevel@tonic-gate }
118*7c478bd9Sstevel@tonic-gate
119*7c478bd9Sstevel@tonic-gate /*
120*7c478bd9Sstevel@tonic-gate * Retrieve the base pointer of an ABI array record
121*7c478bd9Sstevel@tonic-gate */
122*7c478bd9Sstevel@tonic-gate
123*7c478bd9Sstevel@tonic-gate caddr_t
124*7c478bd9Sstevel@tonic-gate /* ARGSUSED */
_tnf_get_elements(TNF * tnf,tnf_ref32_t * array)125*7c478bd9Sstevel@tonic-gate _tnf_get_elements(TNF *tnf, tnf_ref32_t *array)
126*7c478bd9Sstevel@tonic-gate {
127*7c478bd9Sstevel@tonic-gate #ifdef INFINITE_RECURSION_ARRAY
128*7c478bd9Sstevel@tonic-gate size_t hdrsize;
129*7c478bd9Sstevel@tonic-gate tnf_ref32_t *base_tag;
130*7c478bd9Sstevel@tonic-gate
131*7c478bd9Sstevel@tonic-gate base_tag = _tnf_get_base_tag(tnf, _tnf_get_tag(tnf, array));
132*7c478bd9Sstevel@tonic-gate hdrsize = _tnf_get_header_size(tnf, base_tag);
133*7c478bd9Sstevel@tonic-gate return ((caddr_t)((char *)array + hdrsize));
134*7c478bd9Sstevel@tonic-gate #else
135*7c478bd9Sstevel@tonic-gate return ((caddr_t)((char *)array + sizeof (struct tnf_array_hdr)));
136*7c478bd9Sstevel@tonic-gate #endif
137*7c478bd9Sstevel@tonic-gate }
138*7c478bd9Sstevel@tonic-gate
139*7c478bd9Sstevel@tonic-gate /*
140*7c478bd9Sstevel@tonic-gate * Retrieve the chars in an ABI string record
141*7c478bd9Sstevel@tonic-gate */
142*7c478bd9Sstevel@tonic-gate
143*7c478bd9Sstevel@tonic-gate char *
_tnf_get_chars(TNF * tnf,tnf_ref32_t * string)144*7c478bd9Sstevel@tonic-gate _tnf_get_chars(TNF *tnf, tnf_ref32_t *string)
145*7c478bd9Sstevel@tonic-gate {
146*7c478bd9Sstevel@tonic-gate return ((char *)_tnf_get_elements(tnf, string));
147*7c478bd9Sstevel@tonic-gate }
148*7c478bd9Sstevel@tonic-gate
149*7c478bd9Sstevel@tonic-gate /*
150*7c478bd9Sstevel@tonic-gate * Retrieve the string in the name slot of a type record
151*7c478bd9Sstevel@tonic-gate */
152*7c478bd9Sstevel@tonic-gate
153*7c478bd9Sstevel@tonic-gate char *
_tnf_get_name(TNF * tnf,tnf_ref32_t * tag)154*7c478bd9Sstevel@tonic-gate _tnf_get_name(TNF *tnf, tnf_ref32_t *tag)
155*7c478bd9Sstevel@tonic-gate {
156*7c478bd9Sstevel@tonic-gate return (_tnf_get_chars(tnf, _GET_NAME(tnf, tag)));
157*7c478bd9Sstevel@tonic-gate }
158*7c478bd9Sstevel@tonic-gate
159*7c478bd9Sstevel@tonic-gate /*
160*7c478bd9Sstevel@tonic-gate * Retrieve the properties array slot of a type record
161*7c478bd9Sstevel@tonic-gate */
162*7c478bd9Sstevel@tonic-gate
163*7c478bd9Sstevel@tonic-gate tnf_ref32_t *
_tnf_get_properties(TNF * tnf,tnf_ref32_t * tag)164*7c478bd9Sstevel@tonic-gate _tnf_get_properties(TNF *tnf, tnf_ref32_t *tag)
165*7c478bd9Sstevel@tonic-gate {
166*7c478bd9Sstevel@tonic-gate return (_GET_PROPERTIES(tnf, tag));
167*7c478bd9Sstevel@tonic-gate }
168*7c478bd9Sstevel@tonic-gate
169*7c478bd9Sstevel@tonic-gate /*
170*7c478bd9Sstevel@tonic-gate * Retrieve the slot_types slot of struct_type or array_type record
171*7c478bd9Sstevel@tonic-gate */
172*7c478bd9Sstevel@tonic-gate
173*7c478bd9Sstevel@tonic-gate tnf_ref32_t *
_tnf_get_slot_types(TNF * tnf,tnf_ref32_t * tag)174*7c478bd9Sstevel@tonic-gate _tnf_get_slot_types(TNF *tnf, tnf_ref32_t *tag)
175*7c478bd9Sstevel@tonic-gate {
176*7c478bd9Sstevel@tonic-gate return (_GET_SLOT_TYPES(tnf, tag));
177*7c478bd9Sstevel@tonic-gate }
178*7c478bd9Sstevel@tonic-gate
179*7c478bd9Sstevel@tonic-gate /*
180*7c478bd9Sstevel@tonic-gate * Retrieve the header_size slot of an array_type record
181*7c478bd9Sstevel@tonic-gate */
182*7c478bd9Sstevel@tonic-gate
183*7c478bd9Sstevel@tonic-gate size_t
_tnf_get_header_size(TNF * tnf,tnf_ref32_t * tag)184*7c478bd9Sstevel@tonic-gate _tnf_get_header_size(TNF *tnf, tnf_ref32_t *tag)
185*7c478bd9Sstevel@tonic-gate {
186*7c478bd9Sstevel@tonic-gate return (_GET_HEADER_SIZE(tnf, tag));
187*7c478bd9Sstevel@tonic-gate }
188*7c478bd9Sstevel@tonic-gate
189*7c478bd9Sstevel@tonic-gate /*
190*7c478bd9Sstevel@tonic-gate * Retrieve the derived_base slot of a derived_type record
191*7c478bd9Sstevel@tonic-gate */
192*7c478bd9Sstevel@tonic-gate
193*7c478bd9Sstevel@tonic-gate tnf_ref32_t *
_tnf_get_derived_base(TNF * tnf,tnf_ref32_t * tag)194*7c478bd9Sstevel@tonic-gate _tnf_get_derived_base(TNF *tnf, tnf_ref32_t *tag)
195*7c478bd9Sstevel@tonic-gate {
196*7c478bd9Sstevel@tonic-gate return (_GET_DERIVED_BASE(tnf, tag));
197*7c478bd9Sstevel@tonic-gate }
198*7c478bd9Sstevel@tonic-gate
199*7c478bd9Sstevel@tonic-gate
200*7c478bd9Sstevel@tonic-gate /*
201*7c478bd9Sstevel@tonic-gate * Find the root (self-tagged) type record
202*7c478bd9Sstevel@tonic-gate */
203*7c478bd9Sstevel@tonic-gate
204*7c478bd9Sstevel@tonic-gate tnf_ref32_t *
_tnf_get_root_tag(TNF * tnf,tnf_ref32_t * record)205*7c478bd9Sstevel@tonic-gate _tnf_get_root_tag(TNF *tnf, tnf_ref32_t *record)
206*7c478bd9Sstevel@tonic-gate {
207*7c478bd9Sstevel@tonic-gate if (tnf->root_tag)
208*7c478bd9Sstevel@tonic-gate return (tnf->root_tag);
209*7c478bd9Sstevel@tonic-gate else {
210*7c478bd9Sstevel@tonic-gate tnf_ref32_t *p1, *p2;
211*7c478bd9Sstevel@tonic-gate p1 = record;
212*7c478bd9Sstevel@tonic-gate while ((p2 = _tnf_get_tag(tnf, p1)) != p1)
213*7c478bd9Sstevel@tonic-gate p1 = p2;
214*7c478bd9Sstevel@tonic-gate tnf->root_tag = p2;
215*7c478bd9Sstevel@tonic-gate return (p2);
216*7c478bd9Sstevel@tonic-gate }
217*7c478bd9Sstevel@tonic-gate }
218*7c478bd9Sstevel@tonic-gate
219*7c478bd9Sstevel@tonic-gate /*
220*7c478bd9Sstevel@tonic-gate * Search ABI type array for a type named name
221*7c478bd9Sstevel@tonic-gate */
222*7c478bd9Sstevel@tonic-gate
223*7c478bd9Sstevel@tonic-gate tnf_ref32_t *
_tnf_get_element_named(TNF * tnf,tnf_ref32_t * array,char * name)224*7c478bd9Sstevel@tonic-gate _tnf_get_element_named(TNF *tnf, tnf_ref32_t *array, char *name)
225*7c478bd9Sstevel@tonic-gate {
226*7c478bd9Sstevel@tonic-gate unsigned count, i;
227*7c478bd9Sstevel@tonic-gate tnf_ref32_t *elts;
228*7c478bd9Sstevel@tonic-gate
229*7c478bd9Sstevel@tonic-gate count = _tnf_get_element_count(tnf, array, sizeof (tnf_ref32_t));
230*7c478bd9Sstevel@tonic-gate /* LINTED pointer cast may result in improper alignment */
231*7c478bd9Sstevel@tonic-gate elts = (tnf_ref32_t *)_tnf_get_elements(tnf, array);
232*7c478bd9Sstevel@tonic-gate
233*7c478bd9Sstevel@tonic-gate for (i = 0; i < count; i++) {
234*7c478bd9Sstevel@tonic-gate tnf_ref32_t *type_elt;
235*7c478bd9Sstevel@tonic-gate
236*7c478bd9Sstevel@tonic-gate if ((type_elt = _GET_REF32(tnf, &elts[i])) == TNF_NULL) {
237*7c478bd9Sstevel@tonic-gate /* Can't have missing type records */
238*7c478bd9Sstevel@tonic-gate _tnf_error(tnf, TNF_ERR_BADTNF);
239*7c478bd9Sstevel@tonic-gate return (TNF_NULL);
240*7c478bd9Sstevel@tonic-gate }
241*7c478bd9Sstevel@tonic-gate
242*7c478bd9Sstevel@tonic-gate if (strcmp(name, _tnf_get_name(tnf, type_elt)) == 0)
243*7c478bd9Sstevel@tonic-gate /* Found a type record named name */
244*7c478bd9Sstevel@tonic-gate return (type_elt);
245*7c478bd9Sstevel@tonic-gate }
246*7c478bd9Sstevel@tonic-gate return (TNF_NULL);
247*7c478bd9Sstevel@tonic-gate }
248*7c478bd9Sstevel@tonic-gate
249*7c478bd9Sstevel@tonic-gate /*
250*7c478bd9Sstevel@tonic-gate * Look in type record's properties for named type.
251*7c478bd9Sstevel@tonic-gate * Recursively look at derived_base properties as well.
252*7c478bd9Sstevel@tonic-gate */
253*7c478bd9Sstevel@tonic-gate
254*7c478bd9Sstevel@tonic-gate tnf_ref32_t *
_tnf_get_property(TNF * tnf,tnf_ref32_t * tag,char * name)255*7c478bd9Sstevel@tonic-gate _tnf_get_property(TNF *tnf, tnf_ref32_t *tag, char *name)
256*7c478bd9Sstevel@tonic-gate {
257*7c478bd9Sstevel@tonic-gate tnf_ref32_t *properties, *property;
258*7c478bd9Sstevel@tonic-gate
259*7c478bd9Sstevel@tonic-gate if (strcmp(name, _tnf_get_name(tnf, tag)) == 0)
260*7c478bd9Sstevel@tonic-gate /* name is type name */
261*7c478bd9Sstevel@tonic-gate return (tag);
262*7c478bd9Sstevel@tonic-gate
263*7c478bd9Sstevel@tonic-gate if ((properties = _tnf_get_properties(tnf, tag)) == TNF_NULL)
264*7c478bd9Sstevel@tonic-gate /* no properties */
265*7c478bd9Sstevel@tonic-gate return (TNF_NULL);
266*7c478bd9Sstevel@tonic-gate
267*7c478bd9Sstevel@tonic-gate if ((property = _tnf_get_element_named(tnf, properties, name))
268*7c478bd9Sstevel@tonic-gate != TNF_NULL)
269*7c478bd9Sstevel@tonic-gate /* found property named name */
270*7c478bd9Sstevel@tonic-gate return (property);
271*7c478bd9Sstevel@tonic-gate
272*7c478bd9Sstevel@tonic-gate /*
273*7c478bd9Sstevel@tonic-gate * Recursively check base type of derived types
274*7c478bd9Sstevel@tonic-gate */
275*7c478bd9Sstevel@tonic-gate if (_tnf_get_element_named(tnf, properties, TNF_N_DERIVED)
276*7c478bd9Sstevel@tonic-gate != TNF_NULL) {
277*7c478bd9Sstevel@tonic-gate /* tag is a derived type: check its derived_base */
278*7c478bd9Sstevel@tonic-gate tnf_ref32_t *base_tag;
279*7c478bd9Sstevel@tonic-gate
280*7c478bd9Sstevel@tonic-gate base_tag = _tnf_get_derived_base(tnf, tag);
281*7c478bd9Sstevel@tonic-gate /* tnf_derived has derived_base == TNF_NULL */
282*7c478bd9Sstevel@tonic-gate if (base_tag != TNF_NULL)
283*7c478bd9Sstevel@tonic-gate return (_tnf_get_property(tnf, base_tag, name));
284*7c478bd9Sstevel@tonic-gate }
285*7c478bd9Sstevel@tonic-gate
286*7c478bd9Sstevel@tonic-gate return (TNF_NULL);
287*7c478bd9Sstevel@tonic-gate }
288*7c478bd9Sstevel@tonic-gate
289*7c478bd9Sstevel@tonic-gate /*
290*7c478bd9Sstevel@tonic-gate * Get the ultimate base type of a type record
291*7c478bd9Sstevel@tonic-gate */
292*7c478bd9Sstevel@tonic-gate
293*7c478bd9Sstevel@tonic-gate tnf_ref32_t *
_tnf_get_base_tag(TNF * tnf,tnf_ref32_t * tag)294*7c478bd9Sstevel@tonic-gate _tnf_get_base_tag(TNF *tnf, tnf_ref32_t *tag)
295*7c478bd9Sstevel@tonic-gate {
296*7c478bd9Sstevel@tonic-gate tnf_ref32_t *properties;
297*7c478bd9Sstevel@tonic-gate
298*7c478bd9Sstevel@tonic-gate if ((properties = _tnf_get_properties(tnf, tag)) == TNF_NULL)
299*7c478bd9Sstevel@tonic-gate /* no properties */
300*7c478bd9Sstevel@tonic-gate return (tag);
301*7c478bd9Sstevel@tonic-gate
302*7c478bd9Sstevel@tonic-gate if (_tnf_get_element_named(tnf, properties, TNF_N_DERIVED)
303*7c478bd9Sstevel@tonic-gate != TNF_NULL) {
304*7c478bd9Sstevel@tonic-gate tnf_ref32_t *base_tag;
305*7c478bd9Sstevel@tonic-gate
306*7c478bd9Sstevel@tonic-gate if ((base_tag = _tnf_get_derived_base(tnf, tag)) != TNF_NULL)
307*7c478bd9Sstevel@tonic-gate return (_tnf_get_base_tag(tnf, base_tag));
308*7c478bd9Sstevel@tonic-gate }
309*7c478bd9Sstevel@tonic-gate
310*7c478bd9Sstevel@tonic-gate return (tag);
311*7c478bd9Sstevel@tonic-gate }
312*7c478bd9Sstevel@tonic-gate
313*7c478bd9Sstevel@tonic-gate /*
314*7c478bd9Sstevel@tonic-gate * Calculate the reference size of an object with type==tag
315*7c478bd9Sstevel@tonic-gate */
316*7c478bd9Sstevel@tonic-gate
317*7c478bd9Sstevel@tonic-gate size_t
_tnf_get_ref_size(TNF * tnf,tnf_ref32_t * tag)318*7c478bd9Sstevel@tonic-gate _tnf_get_ref_size(TNF *tnf, tnf_ref32_t *tag)
319*7c478bd9Sstevel@tonic-gate {
320*7c478bd9Sstevel@tonic-gate if (HAS_PROPERTY(tnf, tag, TNF_N_TAGGED)) {
321*7c478bd9Sstevel@tonic-gate /* Tagged objects occupy 4 bytes for reference */
322*7c478bd9Sstevel@tonic-gate return ((sizeof (tnf_ref32_t)));
323*7c478bd9Sstevel@tonic-gate } else if (HAS_PROPERTY(tnf, tag, TNF_N_INLINE)) {
324*7c478bd9Sstevel@tonic-gate /* Inline slots cannot be self sized */
325*7c478bd9Sstevel@tonic-gate return (_tnf_get_storage_size(tnf, tag));
326*7c478bd9Sstevel@tonic-gate } else {
327*7c478bd9Sstevel@tonic-gate /* Illegal to have references to abstract objects */
328*7c478bd9Sstevel@tonic-gate _tnf_error(tnf, TNF_ERR_BADTNF);
329*7c478bd9Sstevel@tonic-gate return ((0));
330*7c478bd9Sstevel@tonic-gate }
331*7c478bd9Sstevel@tonic-gate }
332*7c478bd9Sstevel@tonic-gate
333*7c478bd9Sstevel@tonic-gate /*
334*7c478bd9Sstevel@tonic-gate * Calculate storage size of an object with type==tag
335*7c478bd9Sstevel@tonic-gate */
336*7c478bd9Sstevel@tonic-gate
337*7c478bd9Sstevel@tonic-gate size_t
_tnf_get_storage_size(TNF * tnf,tnf_ref32_t * tag)338*7c478bd9Sstevel@tonic-gate _tnf_get_storage_size(TNF *tnf, tnf_ref32_t *tag)
339*7c478bd9Sstevel@tonic-gate {
340*7c478bd9Sstevel@tonic-gate if (_tnf_get_tag(tnf, tag) == _tnf_get_root_tag(tnf, tag))
341*7c478bd9Sstevel@tonic-gate return (_GET_TYPE_SIZE(tnf, tag));
342*7c478bd9Sstevel@tonic-gate else {
343*7c478bd9Sstevel@tonic-gate tnf_ref32_t *base_tag; /* implementation tag */
344*7c478bd9Sstevel@tonic-gate caddr_t sizep;
345*7c478bd9Sstevel@tonic-gate tnf_ref32_t *slot_types;
346*7c478bd9Sstevel@tonic-gate
347*7c478bd9Sstevel@tonic-gate #ifndef INFINITE_RECURSION_SIZE
348*7c478bd9Sstevel@tonic-gate char *base_name;
349*7c478bd9Sstevel@tonic-gate static struct n2s {
350*7c478bd9Sstevel@tonic-gate char *name;
351*7c478bd9Sstevel@tonic-gate size_t size;
352*7c478bd9Sstevel@tonic-gate } n2s[] = {
353*7c478bd9Sstevel@tonic-gate { TNF_N_CHAR, sizeof (tnf_char_t) },
354*7c478bd9Sstevel@tonic-gate { TNF_N_INT8, sizeof (tnf_int8_t) },
355*7c478bd9Sstevel@tonic-gate { TNF_N_INT16, sizeof (tnf_int16_t) },
356*7c478bd9Sstevel@tonic-gate { TNF_N_INT32, sizeof (tnf_int32_t) },
357*7c478bd9Sstevel@tonic-gate { TNF_N_UINT8, sizeof (tnf_uint8_t) },
358*7c478bd9Sstevel@tonic-gate { TNF_N_UINT16, sizeof (tnf_uint16_t) },
359*7c478bd9Sstevel@tonic-gate { TNF_N_UINT32, sizeof (tnf_uint32_t) },
360*7c478bd9Sstevel@tonic-gate { TNF_N_INT64, sizeof (tnf_int64_t) },
361*7c478bd9Sstevel@tonic-gate { TNF_N_UINT64, sizeof (tnf_uint64_t) },
362*7c478bd9Sstevel@tonic-gate { TNF_N_FLOAT32, sizeof (tnf_float32_t) },
363*7c478bd9Sstevel@tonic-gate { TNF_N_FLOAT64, sizeof (tnf_float64_t) },
364*7c478bd9Sstevel@tonic-gate { NULL, 0 }
365*7c478bd9Sstevel@tonic-gate };
366*7c478bd9Sstevel@tonic-gate struct n2s *p;
367*7c478bd9Sstevel@tonic-gate #endif
368*7c478bd9Sstevel@tonic-gate
369*7c478bd9Sstevel@tonic-gate base_tag = _tnf_get_base_tag(tnf, tag);
370*7c478bd9Sstevel@tonic-gate
371*7c478bd9Sstevel@tonic-gate #ifndef INFINITE_RECURSION_SIZE
372*7c478bd9Sstevel@tonic-gate base_name = _tnf_get_name(tnf, base_tag);
373*7c478bd9Sstevel@tonic-gate
374*7c478bd9Sstevel@tonic-gate /* XXX Why are we in this mess? */
375*7c478bd9Sstevel@tonic-gate p = n2s;
376*7c478bd9Sstevel@tonic-gate while (p->name) {
377*7c478bd9Sstevel@tonic-gate if (strcmp(p->name, base_name) == 0)
378*7c478bd9Sstevel@tonic-gate return (p->size);
379*7c478bd9Sstevel@tonic-gate p++;
380*7c478bd9Sstevel@tonic-gate }
381*7c478bd9Sstevel@tonic-gate #endif
382*7c478bd9Sstevel@tonic-gate
383*7c478bd9Sstevel@tonic-gate sizep = _tnf_get_slot_typed(tnf, base_tag, TNF_N_TYPE_SIZE);
384*7c478bd9Sstevel@tonic-gate if (sizep)
385*7c478bd9Sstevel@tonic-gate /* Type sized */
386*7c478bd9Sstevel@tonic-gate /* LINTED pointer cast may result in improper alignment */
387*7c478bd9Sstevel@tonic-gate return (_GET_UINT32(tnf, (tnf_uint32_t *)sizep));
388*7c478bd9Sstevel@tonic-gate
389*7c478bd9Sstevel@tonic-gate slot_types = (tnf_ref32_t *)
390*7c478bd9Sstevel@tonic-gate /* LINTED pointer cast may result in improper alignment */
391*7c478bd9Sstevel@tonic-gate _tnf_get_slot_typed(tnf, base_tag, TNF_N_SLOT_TYPES);
392*7c478bd9Sstevel@tonic-gate if (slot_types &&
393*7c478bd9Sstevel@tonic-gate _tnf_get_element_named(tnf, slot_types, TNF_N_SELF_SIZE))
394*7c478bd9Sstevel@tonic-gate /* Self sized */
395*7c478bd9Sstevel@tonic-gate return ((size_t)-1);
396*7c478bd9Sstevel@tonic-gate else
397*7c478bd9Sstevel@tonic-gate /* Abstract */
398*7c478bd9Sstevel@tonic-gate return (0);
399*7c478bd9Sstevel@tonic-gate }
400*7c478bd9Sstevel@tonic-gate }
401*7c478bd9Sstevel@tonic-gate
402*7c478bd9Sstevel@tonic-gate /*
403*7c478bd9Sstevel@tonic-gate * Return the alignment restriction for any tag
404*7c478bd9Sstevel@tonic-gate */
405*7c478bd9Sstevel@tonic-gate
406*7c478bd9Sstevel@tonic-gate unsigned
_tnf_get_align(TNF * tnf,tnf_ref32_t * tag)407*7c478bd9Sstevel@tonic-gate _tnf_get_align(TNF *tnf, tnf_ref32_t *tag)
408*7c478bd9Sstevel@tonic-gate {
409*7c478bd9Sstevel@tonic-gate if (HAS_PROPERTY(tnf, tag, TNF_N_SCALAR)) {
410*7c478bd9Sstevel@tonic-gate tnf_ref32_t *base_tag;
411*7c478bd9Sstevel@tonic-gate caddr_t alignp;
412*7c478bd9Sstevel@tonic-gate
413*7c478bd9Sstevel@tonic-gate base_tag = _tnf_get_base_tag(tnf, tag);
414*7c478bd9Sstevel@tonic-gate alignp = _tnf_get_slot_typed(tnf, base_tag, TNF_N_ALIGN);
415*7c478bd9Sstevel@tonic-gate if (alignp)
416*7c478bd9Sstevel@tonic-gate /* LINTED pointer cast may result in improper alignment */
417*7c478bd9Sstevel@tonic-gate return (_GET_UINT32(tnf, (tnf_uint32_t *)alignp));
418*7c478bd9Sstevel@tonic-gate }
419*7c478bd9Sstevel@tonic-gate /* default: word alignment */
420*7c478bd9Sstevel@tonic-gate return ((4));
421*7c478bd9Sstevel@tonic-gate }
422*7c478bd9Sstevel@tonic-gate
423*7c478bd9Sstevel@tonic-gate /*
424*7c478bd9Sstevel@tonic-gate * Only works for records
425*7c478bd9Sstevel@tonic-gate * Doesn't check for slot_names in tag
426*7c478bd9Sstevel@tonic-gate * Tag records, for example, never have named slots
427*7c478bd9Sstevel@tonic-gate */
428*7c478bd9Sstevel@tonic-gate
429*7c478bd9Sstevel@tonic-gate caddr_t
_tnf_get_slot_typed(TNF * tnf,tnf_ref32_t * record,char * name)430*7c478bd9Sstevel@tonic-gate _tnf_get_slot_typed(TNF *tnf, tnf_ref32_t *record, char *name)
431*7c478bd9Sstevel@tonic-gate {
432*7c478bd9Sstevel@tonic-gate tnf_ref32_t *tag, *base_tag;
433*7c478bd9Sstevel@tonic-gate tnf_ref32_t *slot_types, *types;
434*7c478bd9Sstevel@tonic-gate unsigned count, i;
435*7c478bd9Sstevel@tonic-gate unsigned offset;
436*7c478bd9Sstevel@tonic-gate
437*7c478bd9Sstevel@tonic-gate tag = _tnf_get_tag(tnf, record);
438*7c478bd9Sstevel@tonic-gate base_tag = _tnf_get_base_tag(tnf, tag);
439*7c478bd9Sstevel@tonic-gate
440*7c478bd9Sstevel@tonic-gate /*
441*7c478bd9Sstevel@tonic-gate * The position of slot_types is ABI fixed
442*7c478bd9Sstevel@tonic-gate * XXX Assume it is present in tag
443*7c478bd9Sstevel@tonic-gate */
444*7c478bd9Sstevel@tonic-gate slot_types = _tnf_get_slot_types(tnf, base_tag);
445*7c478bd9Sstevel@tonic-gate count = _tnf_get_element_count(tnf, slot_types, sizeof (tnf_ref32_t));
446*7c478bd9Sstevel@tonic-gate /* LINTED pointer cast may result in improper alignment */
447*7c478bd9Sstevel@tonic-gate types = (tnf_ref32_t *)_tnf_get_elements(tnf, slot_types);
448*7c478bd9Sstevel@tonic-gate
449*7c478bd9Sstevel@tonic-gate offset = 0;
450*7c478bd9Sstevel@tonic-gate
451*7c478bd9Sstevel@tonic-gate for (i = 0; i < count; i++) {
452*7c478bd9Sstevel@tonic-gate tnf_ref32_t *type_elt;
453*7c478bd9Sstevel@tonic-gate size_t ref_size, align;
454*7c478bd9Sstevel@tonic-gate
455*7c478bd9Sstevel@tonic-gate /* Find the type record for slot */
456*7c478bd9Sstevel@tonic-gate if ((type_elt = _GET_REF32(tnf, &types[i])) == TNF_NULL) {
457*7c478bd9Sstevel@tonic-gate /* Can't have missing type records */
458*7c478bd9Sstevel@tonic-gate _tnf_error(tnf, TNF_ERR_BADTNF);
459*7c478bd9Sstevel@tonic-gate return ((caddr_t)NULL);
460*7c478bd9Sstevel@tonic-gate }
461*7c478bd9Sstevel@tonic-gate
462*7c478bd9Sstevel@tonic-gate /* See similar hack in init_slots() */
463*7c478bd9Sstevel@tonic-gate
464*7c478bd9Sstevel@tonic-gate /* Calculate reference size */
465*7c478bd9Sstevel@tonic-gate ref_size = _tnf_get_ref_size(tnf, type_elt);
466*7c478bd9Sstevel@tonic-gate
467*7c478bd9Sstevel@tonic-gate /*
468*7c478bd9Sstevel@tonic-gate * Calculate alignment
469*7c478bd9Sstevel@tonic-gate * XXX Prevent infinite recursion by assuming that
470*7c478bd9Sstevel@tonic-gate * a reference size of 4 implies word alignment
471*7c478bd9Sstevel@tonic-gate */
472*7c478bd9Sstevel@tonic-gate align = (ref_size == 4)? 4: _tnf_get_align(tnf, type_elt);
473*7c478bd9Sstevel@tonic-gate
474*7c478bd9Sstevel@tonic-gate /* Adjust offset to account for alignment, if needed */
475*7c478bd9Sstevel@tonic-gate offset = ALIGN(offset, align);
476*7c478bd9Sstevel@tonic-gate
477*7c478bd9Sstevel@tonic-gate /* Check whether name corresponds to type name */
478*7c478bd9Sstevel@tonic-gate if (strcmp(name, _tnf_get_name(tnf, type_elt)) == 0)
479*7c478bd9Sstevel@tonic-gate /* Found the slot */
480*7c478bd9Sstevel@tonic-gate return (fetch_slot(tnf, (caddr_t)record + offset,
481*7c478bd9Sstevel@tonic-gate type_elt));
482*7c478bd9Sstevel@tonic-gate
483*7c478bd9Sstevel@tonic-gate /* Bump offset by reference size */
484*7c478bd9Sstevel@tonic-gate offset += ref_size;
485*7c478bd9Sstevel@tonic-gate }
486*7c478bd9Sstevel@tonic-gate
487*7c478bd9Sstevel@tonic-gate return ((caddr_t)NULL);
488*7c478bd9Sstevel@tonic-gate }
489*7c478bd9Sstevel@tonic-gate
490*7c478bd9Sstevel@tonic-gate /*
491*7c478bd9Sstevel@tonic-gate * Only works for records
492*7c478bd9Sstevel@tonic-gate */
493*7c478bd9Sstevel@tonic-gate
494*7c478bd9Sstevel@tonic-gate caddr_t
_tnf_get_slot_named(TNF * tnf,tnf_ref32_t * record,char * name)495*7c478bd9Sstevel@tonic-gate _tnf_get_slot_named(TNF *tnf, tnf_ref32_t *record, char *name)
496*7c478bd9Sstevel@tonic-gate {
497*7c478bd9Sstevel@tonic-gate tnf_ref32_t *tag, *base_tag;
498*7c478bd9Sstevel@tonic-gate tnf_ref32_t *slot_types, *slot_names, *types, *names;
499*7c478bd9Sstevel@tonic-gate unsigned count, i;
500*7c478bd9Sstevel@tonic-gate unsigned offset;
501*7c478bd9Sstevel@tonic-gate
502*7c478bd9Sstevel@tonic-gate tag = _tnf_get_tag(tnf, record);
503*7c478bd9Sstevel@tonic-gate base_tag = _tnf_get_base_tag(tnf, tag);
504*7c478bd9Sstevel@tonic-gate
505*7c478bd9Sstevel@tonic-gate /*
506*7c478bd9Sstevel@tonic-gate * slot_names are optional
507*7c478bd9Sstevel@tonic-gate */
508*7c478bd9Sstevel@tonic-gate slot_names = (tnf_ref32_t *)
509*7c478bd9Sstevel@tonic-gate /* LINTED pointer cast may result in improper alignment */
510*7c478bd9Sstevel@tonic-gate _tnf_get_slot_typed(tnf, base_tag, TNF_N_SLOT_NAMES);
511*7c478bd9Sstevel@tonic-gate
512*7c478bd9Sstevel@tonic-gate /* no slot_names; use _tnf_get_slot_typed() */
513*7c478bd9Sstevel@tonic-gate if (slot_names == TNF_NULL)
514*7c478bd9Sstevel@tonic-gate return (_tnf_get_slot_typed(tnf, record, name));
515*7c478bd9Sstevel@tonic-gate
516*7c478bd9Sstevel@tonic-gate /*
517*7c478bd9Sstevel@tonic-gate * The position of slot_types is ABI fixed
518*7c478bd9Sstevel@tonic-gate * XXX Assume it is present in tag
519*7c478bd9Sstevel@tonic-gate */
520*7c478bd9Sstevel@tonic-gate slot_types = _tnf_get_slot_types(tnf, base_tag);
521*7c478bd9Sstevel@tonic-gate count = _tnf_get_element_count(tnf, slot_types, sizeof (tnf_ref32_t));
522*7c478bd9Sstevel@tonic-gate /* LINTED pointer cast may result in improper alignment */
523*7c478bd9Sstevel@tonic-gate types = (tnf_ref32_t *)_tnf_get_elements(tnf, slot_types);
524*7c478bd9Sstevel@tonic-gate /* LINTED pointer cast may result in improper alignment */
525*7c478bd9Sstevel@tonic-gate names = (tnf_ref32_t *)_tnf_get_elements(tnf, slot_names);
526*7c478bd9Sstevel@tonic-gate
527*7c478bd9Sstevel@tonic-gate offset = 0;
528*7c478bd9Sstevel@tonic-gate
529*7c478bd9Sstevel@tonic-gate for (i = 0; i < count; i++) {
530*7c478bd9Sstevel@tonic-gate tnf_ref32_t *type_elt, *name_elt;
531*7c478bd9Sstevel@tonic-gate size_t ref_size, align;
532*7c478bd9Sstevel@tonic-gate
533*7c478bd9Sstevel@tonic-gate /* Find the type record for slot */
534*7c478bd9Sstevel@tonic-gate if ((type_elt = _GET_REF32(tnf, &types[i])) == TNF_NULL) {
535*7c478bd9Sstevel@tonic-gate /* Can't have missing type records */
536*7c478bd9Sstevel@tonic-gate _tnf_error(tnf, TNF_ERR_BADTNF);
537*7c478bd9Sstevel@tonic-gate return ((caddr_t)NULL);
538*7c478bd9Sstevel@tonic-gate }
539*7c478bd9Sstevel@tonic-gate
540*7c478bd9Sstevel@tonic-gate /* XXX Keep consistent with init_slots() */
541*7c478bd9Sstevel@tonic-gate
542*7c478bd9Sstevel@tonic-gate /* Calculate reference size */
543*7c478bd9Sstevel@tonic-gate ref_size = _tnf_get_ref_size(tnf, type_elt);
544*7c478bd9Sstevel@tonic-gate
545*7c478bd9Sstevel@tonic-gate /*
546*7c478bd9Sstevel@tonic-gate * Calculate alignment
547*7c478bd9Sstevel@tonic-gate * XXX Prevent infinite recursion by assuming that
548*7c478bd9Sstevel@tonic-gate * a reference size of 4 implies word alignment
549*7c478bd9Sstevel@tonic-gate */
550*7c478bd9Sstevel@tonic-gate align = (ref_size == 4)? 4: _tnf_get_align(tnf, type_elt);
551*7c478bd9Sstevel@tonic-gate
552*7c478bd9Sstevel@tonic-gate /* Adjust offset to account for alignment, if needed */
553*7c478bd9Sstevel@tonic-gate offset = ALIGN(offset, align);
554*7c478bd9Sstevel@tonic-gate
555*7c478bd9Sstevel@tonic-gate /* First check slot name, then type name */
556*7c478bd9Sstevel@tonic-gate if ((((name_elt = _GET_REF32(tnf, &names[i])) != TNF_NULL) &&
557*7c478bd9Sstevel@tonic-gate (strcmp(name, _tnf_get_chars(tnf, name_elt)) == 0)) ||
558*7c478bd9Sstevel@tonic-gate (strcmp(name, _tnf_get_name(tnf, type_elt)) == 0))
559*7c478bd9Sstevel@tonic-gate /* Found slot */
560*7c478bd9Sstevel@tonic-gate return (fetch_slot(tnf, (caddr_t)record + offset,
561*7c478bd9Sstevel@tonic-gate type_elt));
562*7c478bd9Sstevel@tonic-gate
563*7c478bd9Sstevel@tonic-gate /* Bump offset by reference size */
564*7c478bd9Sstevel@tonic-gate offset += ref_size;
565*7c478bd9Sstevel@tonic-gate }
566*7c478bd9Sstevel@tonic-gate
567*7c478bd9Sstevel@tonic-gate return ((caddr_t)NULL);
568*7c478bd9Sstevel@tonic-gate }
569*7c478bd9Sstevel@tonic-gate
570*7c478bd9Sstevel@tonic-gate static caddr_t
fetch_slot(TNF * tnf,caddr_t p,tnf_ref32_t * tag)571*7c478bd9Sstevel@tonic-gate fetch_slot(TNF *tnf, caddr_t p, tnf_ref32_t *tag)
572*7c478bd9Sstevel@tonic-gate {
573*7c478bd9Sstevel@tonic-gate if (HAS_PROPERTY(tnf, tag, TNF_N_INLINE))
574*7c478bd9Sstevel@tonic-gate return (p);
575*7c478bd9Sstevel@tonic-gate else /* XXX assume tagged */
576*7c478bd9Sstevel@tonic-gate /* LINTED pointer cast may result in improper alignment */
577*7c478bd9Sstevel@tonic-gate return ((caddr_t)_GET_REF32(tnf, (tnf_ref32_t *)p));
578*7c478bd9Sstevel@tonic-gate }
579