8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22
23 /*
24 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
26 */
27
28 #pragma ident "%Z%%M% %I% %E% SMI"
29
30 #include <ctf_impl.h>
31
32 ssize_t
33 ctf_get_ctt_size(const ctf_file_t *fp, const ctf_type_t *tp, ssize_t *sizep,
34 ssize_t *incrementp)
35 {
36 ssize_t size, increment;
37
38 if (fp->ctf_version > CTF_VERSION_1 &&
39 tp->ctt_size == CTF_LSIZE_SENT) {
40 size = CTF_TYPE_LSIZE(tp);
41 increment = sizeof (ctf_type_t);
42 } else {
43 size = tp->ctt_size;
44 increment = sizeof (ctf_stype_t);
45 }
46
47 if (sizep)
48 *sizep = size;
49 if (incrementp)
182 if (tp->ctt_type == type || tp->ctt_type == otype ||
183 tp->ctt_type == prev) {
184 ctf_dprintf("type %ld cycle detected\n", otype);
185 return (ctf_set_errno(ofp, ECTF_CORRUPT));
186 }
187 prev = type;
188 type = tp->ctt_type;
189 break;
190 default:
191 return (type);
192 }
193 }
194
195 return (CTF_ERR); /* errno is set for us */
196 }
197
198 /*
199 * Lookup the given type ID and print a string name for it into buf. Return
200 * the actual number of bytes (not including \0) needed to format the name.
201 */
202 ssize_t
203 ctf_type_lname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
204 {
205 ctf_decl_t cd;
206 ctf_decl_node_t *cdp;
207 ctf_decl_prec_t prec, lp, rp;
208 int ptr, arr;
209 uint_t k;
210
211 if (fp == NULL && type == CTF_ERR)
212 return (-1); /* simplify caller code by permitting CTF_ERR */
213
214 ctf_decl_init(&cd, buf, len);
215 ctf_decl_push(&cd, fp, type);
216
217 if (cd.cd_err != 0) {
218 ctf_decl_fini(&cd);
219 return (ctf_set_errno(fp, cd.cd_err));
220 }
221
222 /*
223 * If the type graph's order conflicts with lexical precedence order
238 for (cdp = ctf_list_next(&cd.cd_nodes[prec]);
239 cdp != NULL; cdp = ctf_list_next(cdp)) {
240
241 ctf_file_t *rfp = fp;
242 const ctf_type_t *tp =
243 ctf_lookup_by_id(&rfp, cdp->cd_type);
244 const char *name = ctf_strptr(rfp, tp->ctt_name);
245
246 if (k != CTF_K_POINTER && k != CTF_K_ARRAY)
247 ctf_decl_sprintf(&cd, " ");
248
249 if (lp == prec) {
250 ctf_decl_sprintf(&cd, "(");
251 lp = -1;
252 }
253
254 switch (cdp->cd_kind) {
255 case CTF_K_INTEGER:
256 case CTF_K_FLOAT:
257 case CTF_K_TYPEDEF:
258 ctf_decl_sprintf(&cd, "%s", name);
259 break;
260 case CTF_K_POINTER:
261 ctf_decl_sprintf(&cd, "*");
262 break;
263 case CTF_K_ARRAY:
264 ctf_decl_sprintf(&cd, "[%u]", cdp->cd_n);
265 break;
266 case CTF_K_FUNCTION:
267 ctf_decl_sprintf(&cd, "()");
268 break;
269 case CTF_K_STRUCT:
270 case CTF_K_FORWARD:
271 ctf_decl_sprintf(&cd, "struct %s", name);
272 break;
273 case CTF_K_UNION:
274 ctf_decl_sprintf(&cd, "union %s", name);
275 break;
276 case CTF_K_ENUM:
277 ctf_decl_sprintf(&cd, "enum %s", name);
278 break;
279 case CTF_K_VOLATILE:
280 ctf_decl_sprintf(&cd, "volatile");
281 break;
282 case CTF_K_CONST:
283 ctf_decl_sprintf(&cd, "const");
284 break;
285 case CTF_K_RESTRICT:
286 ctf_decl_sprintf(&cd, "restrict");
287 break;
288 }
289
290 k = cdp->cd_kind;
291 }
292
293 if (rp == prec)
294 ctf_decl_sprintf(&cd, ")");
295 }
296
297 if (cd.cd_len >= len)
298 (void) ctf_set_errno(fp, ECTF_NAMELEN);
299
300 ctf_decl_fini(&cd);
301 return (cd.cd_len);
302 }
303
304 /*
305 * Lookup the given type ID and print a string name for it into buf. If buf
306 * is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us.
307 */
308 char *
309 ctf_type_name(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
310 {
311 ssize_t rv = ctf_type_lname(fp, type, buf, len);
312 return (rv >= 0 && rv < len ? buf : NULL);
313 }
314
315 /*
316 * Resolve the type down to a base type node, and then return the size
317 * of the type storage in bytes.
318 */
319 ssize_t
320 ctf_type_size(ctf_file_t *fp, ctf_id_t type)
321 {
322 const ctf_type_t *tp;
323 ssize_t size;
324 ctf_arinfo_t ar;
325
326 if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
327 return (-1); /* errno is set for us */
328
329 if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
330 return (-1); /* errno is set for us */
331
332 switch (LCTF_INFO_KIND(fp, tp->ctt_info)) {
333 case CTF_K_POINTER:
334 return (fp->ctf_dmodel->ctd_pointer);
|
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22
23 /*
24 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
26 */
27
28 #include <ctf_impl.h>
29
30 ssize_t
31 ctf_get_ctt_size(const ctf_file_t *fp, const ctf_type_t *tp, ssize_t *sizep,
32 ssize_t *incrementp)
33 {
34 ssize_t size, increment;
35
36 if (fp->ctf_version > CTF_VERSION_1 &&
37 tp->ctt_size == CTF_LSIZE_SENT) {
38 size = CTF_TYPE_LSIZE(tp);
39 increment = sizeof (ctf_type_t);
40 } else {
41 size = tp->ctt_size;
42 increment = sizeof (ctf_stype_t);
43 }
44
45 if (sizep)
46 *sizep = size;
47 if (incrementp)
180 if (tp->ctt_type == type || tp->ctt_type == otype ||
181 tp->ctt_type == prev) {
182 ctf_dprintf("type %ld cycle detected\n", otype);
183 return (ctf_set_errno(ofp, ECTF_CORRUPT));
184 }
185 prev = type;
186 type = tp->ctt_type;
187 break;
188 default:
189 return (type);
190 }
191 }
192
193 return (CTF_ERR); /* errno is set for us */
194 }
195
196 /*
197 * Lookup the given type ID and print a string name for it into buf. Return
198 * the actual number of bytes (not including \0) needed to format the name.
199 */
200 static ssize_t
201 ctf_type_qlname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len,
202 const char *qname)
203 {
204 ctf_decl_t cd;
205 ctf_decl_node_t *cdp;
206 ctf_decl_prec_t prec, lp, rp;
207 int ptr, arr;
208 uint_t k;
209
210 if (fp == NULL && type == CTF_ERR)
211 return (-1); /* simplify caller code by permitting CTF_ERR */
212
213 ctf_decl_init(&cd, buf, len);
214 ctf_decl_push(&cd, fp, type);
215
216 if (cd.cd_err != 0) {
217 ctf_decl_fini(&cd);
218 return (ctf_set_errno(fp, cd.cd_err));
219 }
220
221 /*
222 * If the type graph's order conflicts with lexical precedence order
237 for (cdp = ctf_list_next(&cd.cd_nodes[prec]);
238 cdp != NULL; cdp = ctf_list_next(cdp)) {
239
240 ctf_file_t *rfp = fp;
241 const ctf_type_t *tp =
242 ctf_lookup_by_id(&rfp, cdp->cd_type);
243 const char *name = ctf_strptr(rfp, tp->ctt_name);
244
245 if (k != CTF_K_POINTER && k != CTF_K_ARRAY)
246 ctf_decl_sprintf(&cd, " ");
247
248 if (lp == prec) {
249 ctf_decl_sprintf(&cd, "(");
250 lp = -1;
251 }
252
253 switch (cdp->cd_kind) {
254 case CTF_K_INTEGER:
255 case CTF_K_FLOAT:
256 case CTF_K_TYPEDEF:
257 if (qname != NULL)
258 ctf_decl_sprintf(&cd, "%s`", qname);
259 ctf_decl_sprintf(&cd, "%s", name);
260 break;
261 case CTF_K_POINTER:
262 ctf_decl_sprintf(&cd, "*");
263 break;
264 case CTF_K_ARRAY:
265 ctf_decl_sprintf(&cd, "[%u]", cdp->cd_n);
266 break;
267 case CTF_K_FUNCTION:
268 ctf_decl_sprintf(&cd, "()");
269 break;
270 case CTF_K_STRUCT:
271 case CTF_K_FORWARD:
272 ctf_decl_sprintf(&cd, "struct ");
273 if (qname != NULL)
274 ctf_decl_sprintf(&cd, "%s`", qname);
275 ctf_decl_sprintf(&cd, "%s", name);
276 break;
277 case CTF_K_UNION:
278 ctf_decl_sprintf(&cd, "union ");
279 if (qname != NULL)
280 ctf_decl_sprintf(&cd, "%s`", qname);
281 ctf_decl_sprintf(&cd, "%s", name);
282 break;
283 case CTF_K_ENUM:
284 ctf_decl_sprintf(&cd, "enum ");
285 if (qname != NULL)
286 ctf_decl_sprintf(&cd, "%s`", qname);
287 ctf_decl_sprintf(&cd, "%s", name);
288 break;
289 case CTF_K_VOLATILE:
290 ctf_decl_sprintf(&cd, "volatile");
291 break;
292 case CTF_K_CONST:
293 ctf_decl_sprintf(&cd, "const");
294 break;
295 case CTF_K_RESTRICT:
296 ctf_decl_sprintf(&cd, "restrict");
297 break;
298 }
299
300 k = cdp->cd_kind;
301 }
302
303 if (rp == prec)
304 ctf_decl_sprintf(&cd, ")");
305 }
306
307 if (cd.cd_len >= len)
308 (void) ctf_set_errno(fp, ECTF_NAMELEN);
309
310 ctf_decl_fini(&cd);
311 return (cd.cd_len);
312 }
313
314 ssize_t
315 ctf_type_lname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
316 {
317 return (ctf_type_qlname(fp, type, buf, len, NULL));
318 }
319
320 /*
321 * Lookup the given type ID and print a string name for it into buf. If buf
322 * is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us.
323 */
324 char *
325 ctf_type_name(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
326 {
327 ssize_t rv = ctf_type_qlname(fp, type, buf, len, NULL);
328 return (rv >= 0 && rv < len ? buf : NULL);
329 }
330
331 char *
332 ctf_type_qname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len,
333 const char *qname)
334 {
335 ssize_t rv = ctf_type_qlname(fp, type, buf, len, qname);
336 return (rv >= 0 && rv < len ? buf : NULL);
337 }
338
339
340 /*
341 * Resolve the type down to a base type node, and then return the size
342 * of the type storage in bytes.
343 */
344 ssize_t
345 ctf_type_size(ctf_file_t *fp, ctf_id_t type)
346 {
347 const ctf_type_t *tp;
348 ssize_t size;
349 ctf_arinfo_t ar;
350
351 if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
352 return (-1); /* errno is set for us */
353
354 if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
355 return (-1); /* errno is set for us */
356
357 switch (LCTF_INFO_KIND(fp, tp->ctt_info)) {
358 case CTF_K_POINTER:
359 return (fp->ctf_dmodel->ctd_pointer);
|