Home | History | Annotate | Line # | 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 #ifdef HAVE_NBTOOL_CONFIG_H
     23 #include "nbtool_config.h"
     24 #endif
     25 /*
     26  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
     27  * Use is subject to license terms.
     28  */
     29 
     30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     31 
     32 #include <ctf_impl.h>
     33 
     34 /*
     35  * Simple doubly-linked list append routine.  This implementation assumes that
     36  * each list element contains an embedded ctf_list_t as the first member.
     37  * An additional ctf_list_t is used to store the head (l_next) and tail
     38  * (l_prev) pointers.  The current head and tail list elements have their
     39  * previous and next pointers set to NULL, respectively.
     40  */
     41 void
     42 ctf_list_append(ctf_list_t *lp, void *new)
     43 {
     44 	ctf_list_t *p = lp->l_prev;	/* p = tail list element */
     45 	ctf_list_t *q = new;		/* q = new list element */
     46 
     47 	lp->l_prev = q;
     48 	q->l_prev = p;
     49 	q->l_next = NULL;
     50 
     51 	if (p != NULL)
     52 		p->l_next = q;
     53 	else
     54 		lp->l_next = q;
     55 }
     56 
     57 /*
     58  * Prepend the specified existing element to the given ctf_list_t.  The
     59  * existing pointer should be pointing at a struct with embedded ctf_list_t.
     60  */
     61 void
     62 ctf_list_prepend(ctf_list_t *lp, void *new)
     63 {
     64 	ctf_list_t *p = new;		/* p = new list element */
     65 	ctf_list_t *q = lp->l_next;	/* q = head list element */
     66 
     67 	lp->l_next = p;
     68 	p->l_prev = NULL;
     69 	p->l_next = q;
     70 
     71 	if (q != NULL)
     72 		q->l_prev = p;
     73 	else
     74 		lp->l_prev = p;
     75 }
     76 
     77 /*
     78  * Delete the specified existing element from the given ctf_list_t.  The
     79  * existing pointer should be pointing at a struct with embedded ctf_list_t.
     80  */
     81 void
     82 ctf_list_delete(ctf_list_t *lp, void *existing)
     83 {
     84 	ctf_list_t *p = existing;
     85 
     86 	if (p->l_prev != NULL)
     87 		p->l_prev->l_next = p->l_next;
     88 	else
     89 		lp->l_next = p->l_next;
     90 
     91 	if (p->l_next != NULL)
     92 		p->l_next->l_prev = p->l_prev;
     93 	else
     94 		lp->l_prev = p->l_prev;
     95 }
     96 
     97 /*
     98  * Convert an encoded CTF string name into a pointer to a C string by looking
     99  * up the appropriate string table buffer and then adding the offset.
    100  */
    101 const char *
    102 ctf_strraw(const ctf_file_t *fp, uint_t name)
    103 {
    104 	const ctf_strs_t *ctsp = &fp->ctf_str[CTF_NAME_STID(name)];
    105 
    106 	if (ctsp->cts_strs != NULL && CTF_NAME_OFFSET(name) < ctsp->cts_len)
    107 		return (ctsp->cts_strs + CTF_NAME_OFFSET(name));
    108 
    109 	/* string table not loaded or corrupt offset */
    110 	return (NULL);
    111 }
    112 
    113 const char *
    114 ctf_strptr(const ctf_file_t *fp, uint_t name)
    115 {
    116 	const char *s = ctf_strraw(fp, name);
    117 	return (s != NULL ? s : "(?)");
    118 }
    119 
    120 /*
    121  * Same strdup(3C), but use ctf_alloc() to do the memory allocation.
    122  */
    123 char *
    124 ctf_strdup(const char *s1)
    125 {
    126 	char *s2 = ctf_alloc(strlen(s1) + 1);
    127 
    128 	if (s2 != NULL)
    129 		(void) strcpy(s2, s1);
    130 
    131 	return (s2);
    132 }
    133 
    134 /*
    135  * Store the specified error code into errp if it is non-NULL, and then
    136  * return NULL for the benefit of the caller.
    137  */
    138 ctf_file_t *
    139 ctf_set_open_errno(int *errp, int error)
    140 {
    141 	if (errp != NULL)
    142 		*errp = error;
    143 	return (NULL);
    144 }
    145 
    146 /*
    147  * Store the specified error code into the CTF container, and then return
    148  * CTF_ERR for the benefit of the caller.
    149  */
    150 long
    151 ctf_set_errno(ctf_file_t *fp, int err)
    152 {
    153 	fp->ctf_errno = err;
    154 	return (CTF_ERR);
    155 }
    156