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
ctf_list_append(ctf_list_t * lp,void * new)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
ctf_list_prepend(ctf_list_t * lp,void * new)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
ctf_list_delete(ctf_list_t * lp,void * existing)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 *
ctf_strraw(ctf_file_t * fp,uint_t name)102 ctf_strraw(ctf_file_t *fp, uint_t name)
103 {
104 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 *
ctf_strptr(ctf_file_t * fp,uint_t name)114 ctf_strptr(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 *
ctf_strdup(const char * s1)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 *
ctf_set_open_errno(int * errp,int error)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
ctf_set_errno(ctf_file_t * fp,int err)151 ctf_set_errno(ctf_file_t *fp, int err)
152 {
153 fp->ctf_errno = err;
154 return (CTF_ERR);
155 }
156