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
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.
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]
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 * Copyright (c) 2015, Joyent, Inc.
31 #include <sys/debug.h>
34 * Simple doubly-linked list append routine. This implementation assumes that
35 * each list element contains an embedded ctf_list_t as the first member.
36 * An additional ctf_list_t is used to store the head (l_next) and tail
37 * (l_prev) pointers. The current head and tail list elements have their
38 * previous and next pointers set to NULL, respectively.
41 ctf_list_append(ctf_list_t
*lp
, void *new)
43 ctf_list_t
*p
= lp
->l_prev
; /* p = tail list element */
44 ctf_list_t
*q
= new; /* q = new list element */
57 * Prepend the specified existing element to the given ctf_list_t. The
58 * existing pointer should be pointing at a struct with embedded ctf_list_t.
61 ctf_list_prepend(ctf_list_t
*lp
, void *new)
63 ctf_list_t
*p
= new; /* p = new list element */
64 ctf_list_t
*q
= lp
->l_next
; /* q = head list element */
77 ctf_list_insert_before(ctf_list_t
*head
, void *item
, void *nitem
)
79 ctf_list_t
*lp
= item
;
80 ctf_list_t
*new = nitem
;
81 ctf_list_t
*prev
= lp
->l_prev
;
89 ASSERT(head
->l_next
== lp
);
95 * Delete the specified existing element from the given ctf_list_t. The
96 * existing pointer should be pointing at a struct with embedded ctf_list_t.
99 ctf_list_delete(ctf_list_t
*lp
, void *existing
)
101 ctf_list_t
*p
= existing
;
103 if (p
->l_prev
!= NULL
)
104 p
->l_prev
->l_next
= p
->l_next
;
106 lp
->l_next
= p
->l_next
;
108 if (p
->l_next
!= NULL
)
109 p
->l_next
->l_prev
= p
->l_prev
;
111 lp
->l_prev
= p
->l_prev
;
115 * Convert an encoded CTF string name into a pointer to a C string by looking
116 * up the appropriate string table buffer and then adding the offset.
119 ctf_strraw(ctf_file_t
*fp
, uint_t name
)
121 ctf_strs_t
*ctsp
= &fp
->ctf_str
[CTF_NAME_STID(name
)];
123 if (ctsp
->cts_strs
!= NULL
&& CTF_NAME_OFFSET(name
) < ctsp
->cts_len
)
124 return (ctsp
->cts_strs
+ CTF_NAME_OFFSET(name
));
126 /* string table not loaded or corrupt offset */
131 ctf_strptr(ctf_file_t
*fp
, uint_t name
)
133 const char *s
= ctf_strraw(fp
, name
);
134 return (s
!= NULL
? s
: "(?)");
138 * Same strdup(3C), but use ctf_alloc() to do the memory allocation.
141 ctf_strdup(const char *s1
)
143 char *s2
= ctf_alloc(strlen(s1
) + 1);
146 (void) strcpy(s2
, s1
);
152 * Store the specified error code into errp if it is non-NULL, and then
153 * return NULL for the benefit of the caller.
156 ctf_set_open_errno(int *errp
, int error
)
164 * Store the specified error code into the CTF container, and then return
165 * CTF_ERR for the benefit of the caller.
168 ctf_set_errno(ctf_file_t
*fp
, int err
)
175 ctf_sym_valid(uintptr_t strbase
, int type
, uint16_t shndx
, uint64_t val
,
180 if (type
!= STT_OBJECT
&& type
!= STT_FUNC
)
182 if (shndx
== SHN_UNDEF
|| noff
== 0)
184 if (type
== STT_OBJECT
&& shndx
== SHN_ABS
&& val
== 0)
186 name
= (char *)(strbase
+ noff
);
187 if (strcmp(name
, "_START_") == 0 || strcmp(name
, "_END_") == 0)