Path: blob/main/cddl/contrib/opensolaris/common/ctf/ctf_labels.c
39507 views
/*1* CDDL HEADER START2*3* The contents of this file are subject to the terms of the4* Common Development and Distribution License, Version 1.0 only5* (the "License"). You may not use this file except in compliance6* with the License.7*8* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE9* or http://www.opensolaris.org/os/licensing.10* See the License for the specific language governing permissions11* and limitations under the License.12*13* When distributing Covered Code, include this CDDL HEADER in each14* file and include the License file at usr/src/OPENSOLARIS.LICENSE.15* If applicable, add the following below this CDDL HEADER, with the16* fields enclosed by brackets "[]" replaced with your own identifying17* information: Portions Copyright [yyyy] [name of copyright owner]18*19* CDDL HEADER END20*/21/*22* Copyright 2002-2003 Sun Microsystems, Inc. All rights reserved.23* Use is subject to license terms.24*/2526#pragma ident "%Z%%M% %I% %E% SMI"2728#include <ctf_impl.h>2930static int31extract_label_info(ctf_file_t *fp, const ctf_lblent_t **ctl, uint_t *num_labels)32{33const ctf_header_t *h;3435/*36* Labels are only supported in V2 or later37*/38if (fp->ctf_version < CTF_VERSION_2)39return (ctf_set_errno(fp, ECTF_NOTSUP));4041h = (const ctf_header_t *)fp->ctf_data.cts_data;4243/* LINTED - pointer alignment */44*ctl = (const ctf_lblent_t *)(fp->ctf_buf + h->cth_lbloff);45*num_labels = (h->cth_objtoff - h->cth_lbloff) / sizeof (ctf_lblent_t);4647return (0);48}4950/*51* Returns the topmost label, or NULL if any errors are encountered52*/53const char *54ctf_label_topmost(ctf_file_t *fp)55{56const ctf_lblent_t *ctlp;57const char *s;58uint_t num_labels;5960if (extract_label_info(fp, &ctlp, &num_labels) == CTF_ERR)61return (NULL); /* errno is set */6263if (num_labels == 0) {64(void) ctf_set_errno(fp, ECTF_NOLABELDATA);65return (NULL);66}6768if ((s = ctf_strraw(fp, (ctlp + num_labels - 1)->ctl_label)) == NULL)69(void) ctf_set_errno(fp, ECTF_CORRUPT);7071return (s);72}7374/*75* Iterate over all labels. We pass the label string and the lblinfo_t struct76* to the specified callback function.77*/78int79ctf_label_iter(ctf_file_t *fp, ctf_label_f *func, void *arg)80{81const ctf_lblent_t *ctlp;82uint_t i, num_labels;83ctf_lblinfo_t linfo;84const char *lname;85int rc;8687if (extract_label_info(fp, &ctlp, &num_labels) == CTF_ERR)88return (CTF_ERR); /* errno is set */8990if (num_labels == 0)91return (ctf_set_errno(fp, ECTF_NOLABELDATA));9293for (i = 0; i < num_labels; i++, ctlp++) {94if ((lname = ctf_strraw(fp, ctlp->ctl_label)) == NULL) {95ctf_dprintf("failed to decode label %u with "96"typeidx %u\n", ctlp->ctl_label, ctlp->ctl_typeidx);97return (ctf_set_errno(fp, ECTF_CORRUPT));98}99100linfo.ctb_typeidx = ctlp->ctl_typeidx;101if ((rc = func(lname, &linfo, arg)) != 0)102return (rc);103}104105return (0);106}107108typedef struct linfo_cb_arg {109const char *lca_name; /* Label we want to retrieve info for */110ctf_lblinfo_t *lca_info; /* Where to store the info about the label */111} linfo_cb_arg_t;112113static int114label_info_cb(const char *lname, const ctf_lblinfo_t *linfo, void *arg)115{116/*117* If lname matches the label we are looking for, copy the118* lblinfo_t struct for the caller.119*/120if (strcmp(lname, ((linfo_cb_arg_t *)arg)->lca_name) == 0) {121/*122* Allow caller not to allocate storage to test if label exists123*/124if (((linfo_cb_arg_t *)arg)->lca_info != NULL)125bcopy(linfo, ((linfo_cb_arg_t *)arg)->lca_info,126sizeof (ctf_lblinfo_t));127return (1); /* Indicate we found a match */128}129130return (0);131}132133/*134* Retrieve information about the label with name "lname"135*/136int137ctf_label_info(ctf_file_t *fp, const char *lname, ctf_lblinfo_t *linfo)138{139linfo_cb_arg_t cb_arg;140int rc;141142cb_arg.lca_name = lname;143cb_arg.lca_info = linfo;144145if ((rc = ctf_label_iter(fp, label_info_cb, &cb_arg)) == CTF_ERR)146return (rc);147148if (rc != 1)149return (ctf_set_errno(fp, ECTF_NOLABEL));150151return (0);152}153154155