Home | History | Annotate | Download | only in ctf
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License, Version 1.0 only
      6  * (the "License").  You may not use this file except in compliance
      7  * with the License.
      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  * Copyright 2002-2003 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     28 
     29 #include <ctf_impl.h>
     30 
     31 static int
     32 extract_label_info(ctf_file_t *fp, const ctf_lblent_t **ctl, uint_t *num_labels)
     33 {
     34 	const ctf_header_t *h;
     35 
     36 	/*
     37 	 * Labels are only supported in V2 or later
     38 	 */
     39 	if (fp->ctf_version < CTF_VERSION_2)
     40 		return (ctf_set_errno(fp, ECTF_NOTSUP));
     41 
     42 	h = (const ctf_header_t *)fp->ctf_data.cts_data;
     43 
     44 	/* LINTED - pointer alignment */
     45 	*ctl = (const ctf_lblent_t *)(fp->ctf_buf + h->cth_lbloff);
     46 	*num_labels = (h->cth_objtoff - h->cth_lbloff) / sizeof (ctf_lblent_t);
     47 
     48 	return (0);
     49 }
     50 
     51 /*
     52  * Returns the topmost label, or NULL if any errors are encountered
     53  */
     54 const char *
     55 ctf_label_topmost(ctf_file_t *fp)
     56 {
     57 	const ctf_lblent_t *ctlp;
     58 	const char *s;
     59 	uint_t num_labels;
     60 
     61 	if (extract_label_info(fp, &ctlp, &num_labels) == CTF_ERR)
     62 		return (NULL); /* errno is set */
     63 
     64 	if (num_labels == 0) {
     65 		(void) ctf_set_errno(fp, ECTF_NOLABELDATA);
     66 		return (NULL);
     67 	}
     68 
     69 	if ((s = ctf_strraw(fp, (ctlp + num_labels - 1)->ctl_label)) == NULL)
     70 		(void) ctf_set_errno(fp, ECTF_CORRUPT);
     71 
     72 	return (s);
     73 }
     74 
     75 /*
     76  * Iterate over all labels.  We pass the label string and the lblinfo_t struct
     77  * to the specified callback function.
     78  */
     79 int
     80 ctf_label_iter(ctf_file_t *fp, ctf_label_f *func, void *arg)
     81 {
     82 	const ctf_lblent_t *ctlp;
     83 	uint_t i, num_labels;
     84 	ctf_lblinfo_t linfo;
     85 	const char *lname;
     86 	int rc;
     87 
     88 	if (extract_label_info(fp, &ctlp, &num_labels) == CTF_ERR)
     89 		return (CTF_ERR); /* errno is set */
     90 
     91 	if (num_labels == 0)
     92 		return (ctf_set_errno(fp, ECTF_NOLABELDATA));
     93 
     94 	for (i = 0; i < num_labels; i++, ctlp++) {
     95 		if ((lname = ctf_strraw(fp, ctlp->ctl_label)) == NULL) {
     96 			ctf_dprintf("failed to decode label %u with "
     97 			    "typeidx %u\n", ctlp->ctl_label, ctlp->ctl_typeidx);
     98 			return (ctf_set_errno(fp, ECTF_CORRUPT));
     99 		}
    100 
    101 		linfo.ctb_typeidx = ctlp->ctl_typeidx;
    102 		if ((rc = func(lname, &linfo, arg)) != 0)
    103 			return (rc);
    104 	}
    105 
    106 	return (0);
    107 }
    108 
    109 typedef struct linfo_cb_arg {
    110 	const char *lca_name;    /* Label we want to retrieve info for */
    111 	ctf_lblinfo_t *lca_info; /* Where to store the info about the label */
    112 } linfo_cb_arg_t;
    113 
    114 static int
    115 label_info_cb(const char *lname, const ctf_lblinfo_t *linfo, void *arg)
    116 {
    117 	/*
    118 	 * If lname matches the label we are looking for, copy the
    119 	 * lblinfo_t struct for the caller.
    120 	 */
    121 	if (strcmp(lname, ((linfo_cb_arg_t *)arg)->lca_name) == 0) {
    122 		/*
    123 		 * Allow caller not to allocate storage to test if label exists
    124 		 */
    125 		if (((linfo_cb_arg_t *)arg)->lca_info != NULL)
    126 			bcopy(linfo, ((linfo_cb_arg_t *)arg)->lca_info,
    127 			    sizeof (ctf_lblinfo_t));
    128 		return (1); /* Indicate we found a match */
    129 	}
    130 
    131 	return (0);
    132 }
    133 
    134 /*
    135  * Retrieve information about the label with name "lname"
    136  */
    137 int
    138 ctf_label_info(ctf_file_t *fp, const char *lname, ctf_lblinfo_t *linfo)
    139 {
    140 	linfo_cb_arg_t cb_arg;
    141 	int rc;
    142 
    143 	cb_arg.lca_name = lname;
    144 	cb_arg.lca_info = linfo;
    145 
    146 	if ((rc = ctf_label_iter(fp, label_info_cb, &cb_arg)) == CTF_ERR)
    147 		return (rc);
    148 
    149 	if (rc != 1)
    150 		return (ctf_set_errno(fp, ECTF_NOLABEL));
    151 
    152 	return (0);
    153 }
    154