1d876124dSJohn Birrell /*
2d876124dSJohn Birrell * CDDL HEADER START
3d876124dSJohn Birrell *
4d876124dSJohn Birrell * The contents of this file are subject to the terms of the
5d876124dSJohn Birrell * Common Development and Distribution License, Version 1.0 only
6d876124dSJohn Birrell * (the "License"). You may not use this file except in compliance
7d876124dSJohn Birrell * with the License.
8d876124dSJohn Birrell *
9d876124dSJohn Birrell * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10d876124dSJohn Birrell * or http://www.opensolaris.org/os/licensing.
11d876124dSJohn Birrell * See the License for the specific language governing permissions
12d876124dSJohn Birrell * and limitations under the License.
13d876124dSJohn Birrell *
14d876124dSJohn Birrell * When distributing Covered Code, include this CDDL HEADER in each
15d876124dSJohn Birrell * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16d876124dSJohn Birrell * If applicable, add the following below this CDDL HEADER, with the
17d876124dSJohn Birrell * fields enclosed by brackets "[]" replaced with your own identifying
18d876124dSJohn Birrell * information: Portions Copyright [yyyy] [name of copyright owner]
19d876124dSJohn Birrell *
20d876124dSJohn Birrell * CDDL HEADER END
21d876124dSJohn Birrell */
22d876124dSJohn Birrell /*
23d876124dSJohn Birrell * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24d876124dSJohn Birrell * Use is subject to license terms.
25d876124dSJohn Birrell */
26d876124dSJohn Birrell
27d876124dSJohn Birrell #pragma ident "%Z%%M% %I% %E% SMI"
28d876124dSJohn Birrell
29d876124dSJohn Birrell #include <ctf_impl.h>
30d876124dSJohn Birrell
31d876124dSJohn Birrell /*
32d876124dSJohn Birrell * Simple doubly-linked list append routine. This implementation assumes that
33d876124dSJohn Birrell * each list element contains an embedded ctf_list_t as the first member.
34d876124dSJohn Birrell * An additional ctf_list_t is used to store the head (l_next) and tail
35d876124dSJohn Birrell * (l_prev) pointers. The current head and tail list elements have their
36d876124dSJohn Birrell * previous and next pointers set to NULL, respectively.
37d876124dSJohn Birrell */
38d876124dSJohn Birrell void
ctf_list_append(ctf_list_t * lp,void * new)39d876124dSJohn Birrell ctf_list_append(ctf_list_t *lp, void *new)
40d876124dSJohn Birrell {
41d876124dSJohn Birrell ctf_list_t *p = lp->l_prev; /* p = tail list element */
42d876124dSJohn Birrell ctf_list_t *q = new; /* q = new list element */
43d876124dSJohn Birrell
44d876124dSJohn Birrell lp->l_prev = q;
45d876124dSJohn Birrell q->l_prev = p;
46d876124dSJohn Birrell q->l_next = NULL;
47d876124dSJohn Birrell
48d876124dSJohn Birrell if (p != NULL)
49d876124dSJohn Birrell p->l_next = q;
50d876124dSJohn Birrell else
51d876124dSJohn Birrell lp->l_next = q;
52d876124dSJohn Birrell }
53d876124dSJohn Birrell
54d876124dSJohn Birrell /*
55d876124dSJohn Birrell * Prepend the specified existing element to the given ctf_list_t. The
56d876124dSJohn Birrell * existing pointer should be pointing at a struct with embedded ctf_list_t.
57d876124dSJohn Birrell */
58d876124dSJohn Birrell void
ctf_list_prepend(ctf_list_t * lp,void * new)59d876124dSJohn Birrell ctf_list_prepend(ctf_list_t *lp, void *new)
60d876124dSJohn Birrell {
61d876124dSJohn Birrell ctf_list_t *p = new; /* p = new list element */
62d876124dSJohn Birrell ctf_list_t *q = lp->l_next; /* q = head list element */
63d876124dSJohn Birrell
64d876124dSJohn Birrell lp->l_next = p;
65d876124dSJohn Birrell p->l_prev = NULL;
66d876124dSJohn Birrell p->l_next = q;
67d876124dSJohn Birrell
68d876124dSJohn Birrell if (q != NULL)
69d876124dSJohn Birrell q->l_prev = p;
70d876124dSJohn Birrell else
71d876124dSJohn Birrell lp->l_prev = p;
72d876124dSJohn Birrell }
73d876124dSJohn Birrell
74d876124dSJohn Birrell /*
75d876124dSJohn Birrell * Delete the specified existing element from the given ctf_list_t. The
76d876124dSJohn Birrell * existing pointer should be pointing at a struct with embedded ctf_list_t.
77d876124dSJohn Birrell */
78d876124dSJohn Birrell void
ctf_list_delete(ctf_list_t * lp,void * existing)79d876124dSJohn Birrell ctf_list_delete(ctf_list_t *lp, void *existing)
80d876124dSJohn Birrell {
81d876124dSJohn Birrell ctf_list_t *p = existing;
82d876124dSJohn Birrell
83d876124dSJohn Birrell if (p->l_prev != NULL)
84d876124dSJohn Birrell p->l_prev->l_next = p->l_next;
85d876124dSJohn Birrell else
86d876124dSJohn Birrell lp->l_next = p->l_next;
87d876124dSJohn Birrell
88d876124dSJohn Birrell if (p->l_next != NULL)
89d876124dSJohn Birrell p->l_next->l_prev = p->l_prev;
90d876124dSJohn Birrell else
91d876124dSJohn Birrell lp->l_prev = p->l_prev;
92d876124dSJohn Birrell }
93d876124dSJohn Birrell
94d876124dSJohn Birrell /*
95d876124dSJohn Birrell * Convert an encoded CTF string name into a pointer to a C string by looking
96d876124dSJohn Birrell * up the appropriate string table buffer and then adding the offset.
97d876124dSJohn Birrell */
98d876124dSJohn Birrell const char *
ctf_strraw(const ctf_file_t * fp,uint_t name)9945c23c26SMark Johnston ctf_strraw(const ctf_file_t *fp, uint_t name)
100d876124dSJohn Birrell {
10145c23c26SMark Johnston const ctf_strs_t *ctsp = &fp->ctf_str[CTF_NAME_STID(name)];
102d876124dSJohn Birrell
103d876124dSJohn Birrell if (ctsp->cts_strs != NULL && CTF_NAME_OFFSET(name) < ctsp->cts_len)
104d876124dSJohn Birrell return (ctsp->cts_strs + CTF_NAME_OFFSET(name));
105d876124dSJohn Birrell
106d876124dSJohn Birrell /* string table not loaded or corrupt offset */
107d876124dSJohn Birrell return (NULL);
108d876124dSJohn Birrell }
109d876124dSJohn Birrell
110d876124dSJohn Birrell const char *
ctf_strptr(const ctf_file_t * fp,uint_t name)11145c23c26SMark Johnston ctf_strptr(const ctf_file_t *fp, uint_t name)
112d876124dSJohn Birrell {
113d876124dSJohn Birrell const char *s = ctf_strraw(fp, name);
114d876124dSJohn Birrell return (s != NULL ? s : "(?)");
115d876124dSJohn Birrell }
116d876124dSJohn Birrell
117d876124dSJohn Birrell /*
118d876124dSJohn Birrell * Same strdup(3C), but use ctf_alloc() to do the memory allocation.
119d876124dSJohn Birrell */
120d876124dSJohn Birrell char *
ctf_strdup(const char * s1)121d876124dSJohn Birrell ctf_strdup(const char *s1)
122d876124dSJohn Birrell {
123d876124dSJohn Birrell char *s2 = ctf_alloc(strlen(s1) + 1);
124d876124dSJohn Birrell
125d876124dSJohn Birrell if (s2 != NULL)
126d876124dSJohn Birrell (void) strcpy(s2, s1);
127d876124dSJohn Birrell
128d876124dSJohn Birrell return (s2);
129d876124dSJohn Birrell }
130d876124dSJohn Birrell
131d876124dSJohn Birrell /*
132d876124dSJohn Birrell * Store the specified error code into errp if it is non-NULL, and then
133d876124dSJohn Birrell * return NULL for the benefit of the caller.
134d876124dSJohn Birrell */
135d876124dSJohn Birrell ctf_file_t *
ctf_set_open_errno(int * errp,int error)136d876124dSJohn Birrell ctf_set_open_errno(int *errp, int error)
137d876124dSJohn Birrell {
138d876124dSJohn Birrell if (errp != NULL)
139d876124dSJohn Birrell *errp = error;
140d876124dSJohn Birrell return (NULL);
141d876124dSJohn Birrell }
142d876124dSJohn Birrell
143d876124dSJohn Birrell /*
144d876124dSJohn Birrell * Store the specified error code into the CTF container, and then return
145d876124dSJohn Birrell * CTF_ERR for the benefit of the caller.
146d876124dSJohn Birrell */
147d876124dSJohn Birrell long
ctf_set_errno(ctf_file_t * fp,int err)148d876124dSJohn Birrell ctf_set_errno(ctf_file_t *fp, int err)
149d876124dSJohn Birrell {
150d876124dSJohn Birrell fp->ctf_errno = err;
151d876124dSJohn Birrell return (CTF_ERR);
152d876124dSJohn Birrell }
153