ctf_create.c revision 1.9 1 1.1 darran /*
2 1.1 darran * CDDL HEADER START
3 1.1 darran *
4 1.1 darran * The contents of this file are subject to the terms of the
5 1.1 darran * Common Development and Distribution License, Version 1.0 only
6 1.1 darran * (the "License"). You may not use this file except in compliance
7 1.1 darran * with the License.
8 1.1 darran *
9 1.1 darran * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 1.1 darran * or http://www.opensolaris.org/os/licensing.
11 1.1 darran * See the License for the specific language governing permissions
12 1.1 darran * and limitations under the License.
13 1.1 darran *
14 1.1 darran * When distributing Covered Code, include this CDDL HEADER in each
15 1.1 darran * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 1.1 darran * If applicable, add the following below this CDDL HEADER, with the
17 1.1 darran * fields enclosed by brackets "[]" replaced with your own identifying
18 1.1 darran * information: Portions Copyright [yyyy] [name of copyright owner]
19 1.1 darran *
20 1.1 darran * CDDL HEADER END
21 1.1 darran */
22 1.5 christos #ifdef HAVE_NBTOOL_CONFIG_H
23 1.5 christos #include "nbtool_config.h"
24 1.5 christos #endif
25 1.1 darran
26 1.1 darran /*
27 1.1 darran * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
28 1.1 darran * Use is subject to license terms.
29 1.1 darran */
30 1.4 christos /*
31 1.4 christos * Copyright (c) 2013, Joyent, Inc. All rights reserved.
32 1.4 christos */
33 1.1 darran
34 1.1 darran #include <sys/sysmacros.h>
35 1.1 darran #include <sys/param.h>
36 1.1 darran #include <sys/mman.h>
37 1.1 darran #include <ctf_impl.h>
38 1.4 christos #include <sys/debug.h>
39 1.1 darran
40 1.1 darran /*
41 1.1 darran * This static string is used as the template for initially populating a
42 1.1 darran * dynamic container's string table. We always store \0 in the first byte,
43 1.1 darran * and we use the generic string "PARENT" to mark this container's parent
44 1.1 darran * if one is associated with the container using ctf_import().
45 1.1 darran */
46 1.1 darran static const char _CTF_STRTAB_TEMPLATE[] = "\0PARENT";
47 1.1 darran
48 1.1 darran /*
49 1.1 darran * To create an empty CTF container, we just declare a zeroed header and call
50 1.1 darran * ctf_bufopen() on it. If ctf_bufopen succeeds, we mark the new container r/w
51 1.1 darran * and initialize the dynamic members. We set dtstrlen to 1 to reserve the
52 1.1 darran * first byte of the string table for a \0 byte, and we start assigning type
53 1.1 darran * IDs at 1 because type ID 0 is used as a sentinel.
54 1.1 darran */
55 1.1 darran ctf_file_t *
56 1.1 darran ctf_create(int *errp)
57 1.1 darran {
58 1.3 christos static const ctf_header_t hdr = { .cth_preamble = {
59 1.3 christos .ctp_magic = CTF_MAGIC,
60 1.3 christos .ctp_version = CTF_VERSION,
61 1.3 christos .ctp_flags = 0
62 1.3 christos } };
63 1.1 darran
64 1.1 darran const ulong_t hashlen = 128;
65 1.1 darran ctf_dtdef_t **hash = ctf_alloc(hashlen * sizeof (ctf_dtdef_t *));
66 1.1 darran ctf_sect_t cts;
67 1.1 darran ctf_file_t *fp;
68 1.1 darran
69 1.1 darran if (hash == NULL)
70 1.1 darran return (ctf_set_open_errno(errp, EAGAIN));
71 1.1 darran
72 1.3 christos cts.cts_name = __UNCONST(_CTF_SECTION);
73 1.1 darran cts.cts_type = SHT_PROGBITS;
74 1.1 darran cts.cts_flags = 0;
75 1.3 christos cts.cts_data = __UNCONST(&hdr);
76 1.1 darran cts.cts_size = sizeof (hdr);
77 1.1 darran cts.cts_entsize = 1;
78 1.1 darran cts.cts_offset = 0;
79 1.1 darran
80 1.1 darran if ((fp = ctf_bufopen(&cts, NULL, NULL, errp)) == NULL) {
81 1.1 darran ctf_free(hash, hashlen * sizeof (ctf_dtdef_t *));
82 1.1 darran return (NULL);
83 1.1 darran }
84 1.1 darran
85 1.1 darran fp->ctf_flags |= LCTF_RDWR;
86 1.1 darran fp->ctf_dthashlen = hashlen;
87 1.8 christos memset(hash, 0, hashlen * sizeof (ctf_dtdef_t *));
88 1.1 darran fp->ctf_dthash = hash;
89 1.1 darran fp->ctf_dtstrlen = sizeof (_CTF_STRTAB_TEMPLATE);
90 1.1 darran fp->ctf_dtnextid = 1;
91 1.1 darran fp->ctf_dtoldid = 0;
92 1.1 darran
93 1.1 darran return (fp);
94 1.1 darran }
95 1.1 darran
96 1.1 darran static uchar_t *
97 1.8 christos ctf_copy_smembers(const ctf_file_t *fp, ctf_dtdef_t *dtd, uint_t soff,
98 1.8 christos uchar_t *t)
99 1.1 darran {
100 1.1 darran ctf_dmdef_t *dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
101 1.8 christos size_t sz;
102 1.8 christos uint_t name;
103 1.1 darran
104 1.1 darran for (; dmd != NULL; dmd = ctf_list_next(dmd)) {
105 1.1 darran if (dmd->dmd_name) {
106 1.8 christos name = soff;
107 1.1 darran soff += strlen(dmd->dmd_name) + 1;
108 1.1 darran } else
109 1.8 christos name = 0;
110 1.1 darran
111 1.8 christos if (fp->ctf_version == CTF_VERSION_2) {
112 1.8 christos struct ctf_member_v2 ctm;
113 1.1 darran
114 1.8 christos ctm.ctm_name = name;
115 1.8 christos ctm.ctm_type = (ushort_t)dmd->dmd_type;
116 1.8 christos ctm.ctm_offset = (ushort_t)dmd->dmd_offset;
117 1.8 christos
118 1.8 christos sz = sizeof (ctm);
119 1.8 christos memcpy(t, &ctm, sz);
120 1.8 christos t += sz;
121 1.8 christos } else {
122 1.8 christos struct ctf_member_v3 ctm;
123 1.8 christos
124 1.8 christos ctm.ctm_name = name;
125 1.8 christos ctm.ctm_type = dmd->dmd_type;
126 1.8 christos ctm.ctm_offset = dmd->dmd_offset;
127 1.8 christos
128 1.8 christos sz = sizeof (ctm);
129 1.8 christos memcpy(t, &ctm, sz);
130 1.8 christos t += sz;
131 1.8 christos }
132 1.1 darran }
133 1.1 darran
134 1.1 darran return (t);
135 1.1 darran }
136 1.1 darran
137 1.1 darran static uchar_t *
138 1.8 christos ctf_copy_lmembers(const ctf_file_t *fp, ctf_dtdef_t *dtd, uint_t soff,
139 1.8 christos uchar_t *t)
140 1.1 darran {
141 1.1 darran ctf_dmdef_t *dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
142 1.8 christos size_t sz;
143 1.8 christos uint_t name;
144 1.1 darran
145 1.1 darran for (; dmd != NULL; dmd = ctf_list_next(dmd)) {
146 1.1 darran if (dmd->dmd_name) {
147 1.8 christos name = soff;
148 1.1 darran soff += strlen(dmd->dmd_name) + 1;
149 1.1 darran } else
150 1.8 christos name = 0;
151 1.8 christos
152 1.8 christos if (fp->ctf_version == CTF_VERSION_2) {
153 1.8 christos struct ctf_lmember_v2 ctlm;
154 1.1 darran
155 1.8 christos ctlm.ctlm_name = name;
156 1.8 christos ctlm.ctlm_type = (ushort_t)dmd->dmd_type;
157 1.8 christos ctlm.ctlm_pad = 0;
158 1.8 christos ctlm.ctlm_offsethi = CTF_OFFSET_TO_LMEMHI(dmd->dmd_offset);
159 1.8 christos ctlm.ctlm_offsetlo = CTF_OFFSET_TO_LMEMLO(dmd->dmd_offset);
160 1.8 christos
161 1.8 christos sz = sizeof (ctlm);
162 1.8 christos memcpy(t, &ctlm, sz);
163 1.8 christos t += sz;
164 1.8 christos } else {
165 1.8 christos struct ctf_lmember_v3 ctlm;
166 1.8 christos
167 1.8 christos ctlm.ctlm_name = name;
168 1.8 christos ctlm.ctlm_type = dmd->dmd_type;
169 1.8 christos ctlm.ctlm_offsethi = CTF_OFFSET_TO_LMEMHI(dmd->dmd_offset);
170 1.8 christos ctlm.ctlm_offsetlo = CTF_OFFSET_TO_LMEMLO(dmd->dmd_offset);
171 1.8 christos
172 1.8 christos sz = sizeof (ctlm);
173 1.8 christos memcpy(t, &ctlm, sz);
174 1.8 christos t += sz;
175 1.8 christos }
176 1.1 darran
177 1.1 darran }
178 1.1 darran
179 1.1 darran return (t);
180 1.1 darran }
181 1.1 darran
182 1.1 darran static uchar_t *
183 1.1 darran ctf_copy_emembers(ctf_dtdef_t *dtd, uint_t soff, uchar_t *t)
184 1.1 darran {
185 1.1 darran ctf_dmdef_t *dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
186 1.1 darran ctf_enum_t cte;
187 1.1 darran
188 1.1 darran for (; dmd != NULL; dmd = ctf_list_next(dmd)) {
189 1.1 darran cte.cte_name = soff;
190 1.1 darran cte.cte_value = dmd->dmd_value;
191 1.1 darran soff += strlen(dmd->dmd_name) + 1;
192 1.8 christos memcpy(t, &cte, sizeof (cte));
193 1.1 darran t += sizeof (cte);
194 1.1 darran }
195 1.1 darran
196 1.1 darran return (t);
197 1.1 darran }
198 1.1 darran
199 1.1 darran static uchar_t *
200 1.1 darran ctf_copy_membnames(ctf_dtdef_t *dtd, uchar_t *s)
201 1.1 darran {
202 1.1 darran ctf_dmdef_t *dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
203 1.1 darran size_t len;
204 1.1 darran
205 1.1 darran for (; dmd != NULL; dmd = ctf_list_next(dmd)) {
206 1.1 darran if (dmd->dmd_name == NULL)
207 1.1 darran continue; /* skip anonymous members */
208 1.1 darran len = strlen(dmd->dmd_name) + 1;
209 1.8 christos memcpy(s, dmd->dmd_name, len);
210 1.1 darran s += len;
211 1.1 darran }
212 1.1 darran
213 1.1 darran return (s);
214 1.1 darran }
215 1.1 darran
216 1.1 darran /*
217 1.4 christos * Only types of dyanmic CTF containers contain reference counts. These
218 1.4 christos * containers are marked RD/WR. Because of that we basically make this a no-op
219 1.4 christos * for compatability with non-dynamic CTF sections. This is also a no-op for
220 1.4 christos * types which are not dynamic types. It is the responsibility of the caller to
221 1.4 christos * make sure it is a valid type. We help that caller out on debug builds.
222 1.4 christos *
223 1.4 christos * Note that the reference counts are not maintained for types that are not
224 1.4 christos * within this container. In other words if we have a type in a parent, that
225 1.4 christos * will not have its reference count increased. On the flip side, the parent
226 1.4 christos * will not be allowed to remove dynamic types if it has children.
227 1.4 christos */
228 1.4 christos static void
229 1.4 christos ctf_ref_inc(ctf_file_t *fp, ctf_id_t tid)
230 1.4 christos {
231 1.4 christos ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, tid);
232 1.4 christos
233 1.4 christos if (dtd == NULL)
234 1.4 christos return;
235 1.4 christos
236 1.4 christos if (!(fp->ctf_flags & LCTF_RDWR))
237 1.4 christos return;
238 1.4 christos
239 1.4 christos dtd->dtd_ref++;
240 1.4 christos }
241 1.4 christos
242 1.4 christos /*
243 1.4 christos * Just as with ctf_ref_inc, this is a no-op on non-writeable containers and the
244 1.4 christos * caller should ensure that this is already a valid type.
245 1.4 christos */
246 1.4 christos static void
247 1.4 christos ctf_ref_dec(ctf_file_t *fp, ctf_id_t tid)
248 1.4 christos {
249 1.4 christos ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, tid);
250 1.4 christos
251 1.4 christos if (dtd == NULL)
252 1.4 christos return;
253 1.4 christos
254 1.4 christos if (!(fp->ctf_flags & LCTF_RDWR))
255 1.4 christos return;
256 1.4 christos
257 1.4 christos ASSERT(dtd->dtd_ref >= 1);
258 1.4 christos dtd->dtd_ref--;
259 1.4 christos }
260 1.4 christos
261 1.4 christos /*
262 1.1 darran * If the specified CTF container is writable and has been modified, reload
263 1.1 darran * this container with the updated type definitions. In order to make this
264 1.1 darran * code and the rest of libctf as simple as possible, we perform updates by
265 1.1 darran * taking the dynamic type definitions and creating an in-memory CTF file
266 1.1 darran * containing the definitions, and then call ctf_bufopen() on it. This not
267 1.1 darran * only leverages ctf_bufopen(), but also avoids having to bifurcate the rest
268 1.1 darran * of the library code with different lookup paths for static and dynamic
269 1.1 darran * type definitions. We are therefore optimizing greatly for lookup over
270 1.1 darran * update, which we assume will be an uncommon operation. We perform one
271 1.1 darran * extra trick here for the benefit of callers and to keep our code simple:
272 1.1 darran * ctf_bufopen() will return a new ctf_file_t, but we want to keep the fp
273 1.8 christos * constant for the caller, so after ctf_bufopen() returns, we use memcpy to
274 1.1 darran * swap the interior of the old and new ctf_file_t's, and then free the old.
275 1.4 christos *
276 1.4 christos * Note that the lists of dynamic types stays around and the resulting container
277 1.4 christos * is still writeable. Furthermore, the reference counts that are on the dtd's
278 1.4 christos * are still valid.
279 1.1 darran */
280 1.1 darran int
281 1.1 darran ctf_update(ctf_file_t *fp)
282 1.1 darran {
283 1.1 darran ctf_file_t ofp, *nfp;
284 1.1 darran ctf_header_t hdr;
285 1.1 darran ctf_dtdef_t *dtd;
286 1.1 darran ctf_sect_t cts;
287 1.1 darran
288 1.1 darran uchar_t *s, *s0, *t;
289 1.1 darran size_t size;
290 1.1 darran void *buf;
291 1.1 darran int err;
292 1.1 darran
293 1.1 darran if (!(fp->ctf_flags & LCTF_RDWR))
294 1.1 darran return (ctf_set_errno(fp, ECTF_RDONLY));
295 1.1 darran
296 1.1 darran if (!(fp->ctf_flags & LCTF_DIRTY))
297 1.1 darran return (0); /* no update required */
298 1.1 darran
299 1.1 darran /*
300 1.1 darran * Fill in an initial CTF header. We will leave the label, object,
301 1.1 darran * and function sections empty and only output a header, type section,
302 1.1 darran * and string table. The type section begins at a 4-byte aligned
303 1.1 darran * boundary past the CTF header itself (at relative offset zero).
304 1.1 darran */
305 1.8 christos memset(&hdr, 0, sizeof (hdr));
306 1.1 darran hdr.cth_magic = CTF_MAGIC;
307 1.8 christos hdr.cth_version = fp->ctf_version;
308 1.1 darran
309 1.1 darran if (fp->ctf_flags & LCTF_CHILD)
310 1.1 darran hdr.cth_parname = 1; /* i.e. _CTF_STRTAB_TEMPLATE[1] */
311 1.1 darran
312 1.1 darran /*
313 1.1 darran * Iterate through the dynamic type definition list and compute the
314 1.1 darran * size of the CTF type section we will need to generate.
315 1.1 darran */
316 1.1 darran for (size = 0, dtd = ctf_list_next(&fp->ctf_dtdefs);
317 1.1 darran dtd != NULL; dtd = ctf_list_next(dtd)) {
318 1.1 darran
319 1.8 christos uint_t kind = LCTF_INFO_KIND(fp, dtd->dtd_data.ctt_info);
320 1.8 christos uint_t vlen = LCTF_INFO_VLEN(fp, dtd->dtd_data.ctt_info);
321 1.1 darran
322 1.8 christos if (fp->ctf_version == CTF_VERSION_2) {
323 1.8 christos if (dtd->dtd_data.ctt_size != CTF_V2_LSIZE_SENT)
324 1.8 christos size += sizeof (struct ctf_stype_v2);
325 1.8 christos else
326 1.8 christos size += sizeof (struct ctf_type_v2);
327 1.8 christos } else {
328 1.8 christos if (dtd->dtd_data.ctt_size != LCTF_LSIZE_SENT(fp))
329 1.8 christos size += sizeof (struct ctf_stype_v3);
330 1.8 christos else
331 1.8 christos size += sizeof (struct ctf_type_v3);
332 1.8 christos }
333 1.1 darran
334 1.1 darran switch (kind) {
335 1.1 darran case CTF_K_INTEGER:
336 1.1 darran case CTF_K_FLOAT:
337 1.1 darran size += sizeof (uint_t);
338 1.1 darran break;
339 1.1 darran case CTF_K_ARRAY:
340 1.8 christos size += fp->ctf_version == CTF_VERSION_2 ?
341 1.8 christos sizeof (struct ctf_array_v2) :
342 1.8 christos sizeof (struct ctf_array_v3);
343 1.1 darran break;
344 1.1 darran case CTF_K_FUNCTION:
345 1.8 christos size += roundup2(fp->ctf_idwidth * vlen, 4);
346 1.1 darran break;
347 1.1 darran case CTF_K_STRUCT:
348 1.1 darran case CTF_K_UNION:
349 1.8 christos if (fp->ctf_version == CTF_VERSION_2) {
350 1.8 christos if (dtd->dtd_data.ctt_size <
351 1.8 christos LCTF_LSTRUCT_THRESH(fp))
352 1.8 christos size += sizeof (struct ctf_member_v2) *
353 1.8 christos vlen;
354 1.8 christos else
355 1.8 christos size += sizeof (struct ctf_lmember_v2) *
356 1.8 christos vlen;
357 1.8 christos } else {
358 1.8 christos if (dtd->dtd_data.ctt_size <
359 1.8 christos LCTF_LSTRUCT_THRESH(fp))
360 1.8 christos size += sizeof (struct ctf_member_v3) *
361 1.8 christos vlen;
362 1.8 christos else
363 1.8 christos size += sizeof (struct ctf_lmember_v3) *
364 1.8 christos vlen;
365 1.8 christos }
366 1.1 darran break;
367 1.1 darran case CTF_K_ENUM:
368 1.1 darran size += sizeof (ctf_enum_t) * vlen;
369 1.1 darran break;
370 1.1 darran }
371 1.1 darran }
372 1.1 darran
373 1.1 darran /*
374 1.1 darran * Fill in the string table offset and size, compute the size of the
375 1.1 darran * entire CTF buffer we need, and then allocate a new buffer and
376 1.8 christos * memcpy the finished header to the start of the buffer.
377 1.1 darran */
378 1.1 darran hdr.cth_stroff = hdr.cth_typeoff + size;
379 1.1 darran hdr.cth_strlen = fp->ctf_dtstrlen;
380 1.1 darran size = sizeof (ctf_header_t) + hdr.cth_stroff + hdr.cth_strlen;
381 1.1 darran
382 1.1 darran if ((buf = ctf_data_alloc(size)) == MAP_FAILED)
383 1.1 darran return (ctf_set_errno(fp, EAGAIN));
384 1.1 darran
385 1.8 christos memcpy(buf, &hdr, sizeof (ctf_header_t));
386 1.1 darran t = (uchar_t *)buf + sizeof (ctf_header_t);
387 1.1 darran s = s0 = (uchar_t *)buf + sizeof (ctf_header_t) + hdr.cth_stroff;
388 1.1 darran
389 1.8 christos memcpy(s, _CTF_STRTAB_TEMPLATE, sizeof (_CTF_STRTAB_TEMPLATE));
390 1.1 darran s += sizeof (_CTF_STRTAB_TEMPLATE);
391 1.1 darran
392 1.1 darran /*
393 1.1 darran * We now take a final lap through the dynamic type definition list and
394 1.1 darran * copy the appropriate type records and strings to the output buffer.
395 1.1 darran */
396 1.1 darran for (dtd = ctf_list_next(&fp->ctf_dtdefs);
397 1.1 darran dtd != NULL; dtd = ctf_list_next(dtd)) {
398 1.8 christos void *tp;
399 1.8 christos uint_t kind = LCTF_INFO_KIND(fp, dtd->dtd_data.ctt_info);
400 1.8 christos uint_t vlen = LCTF_INFO_VLEN(fp, dtd->dtd_data.ctt_info);
401 1.8 christos struct ctf_type_v2 ctt;
402 1.1 darran
403 1.1 darran uint_t encoding;
404 1.1 darran size_t len;
405 1.1 darran
406 1.1 darran if (dtd->dtd_name != NULL) {
407 1.1 darran dtd->dtd_data.ctt_name = (uint_t)(s - s0);
408 1.1 darran len = strlen(dtd->dtd_name) + 1;
409 1.8 christos memcpy(s, dtd->dtd_name, len);
410 1.1 darran s += len;
411 1.1 darran } else
412 1.1 darran dtd->dtd_data.ctt_name = 0;
413 1.1 darran
414 1.8 christos if (fp->ctf_version == CTF_VERSION_2) {
415 1.8 christos ctt.ctt_name = dtd->dtd_data.ctt_name;
416 1.8 christos ctt.ctt_info = (ushort_t)dtd->dtd_data.ctt_info;
417 1.8 christos ctt.ctt_size = (ushort_t)dtd->dtd_data.ctt_size;
418 1.8 christos if (dtd->dtd_data.ctt_size != CTF_V2_LSIZE_SENT)
419 1.8 christos len = sizeof (struct ctf_stype_v2);
420 1.8 christos else {
421 1.8 christos len = sizeof (struct ctf_type_v2);
422 1.8 christos ctt.ctt_lsizehi = dtd->dtd_data.ctt_lsizehi;
423 1.8 christos ctt.ctt_lsizelo = dtd->dtd_data.ctt_lsizelo;
424 1.8 christos }
425 1.8 christos tp = &ctt;
426 1.8 christos } else {
427 1.8 christos if (dtd->dtd_data.ctt_size != LCTF_LSIZE_SENT(fp))
428 1.8 christos len = sizeof (struct ctf_stype_v3);
429 1.8 christos else
430 1.8 christos len = sizeof (struct ctf_type_v3);
431 1.8 christos tp = &dtd->dtd_data;
432 1.8 christos }
433 1.1 darran
434 1.8 christos memcpy(t, tp, len);
435 1.1 darran t += len;
436 1.1 darran
437 1.1 darran switch (kind) {
438 1.1 darran case CTF_K_INTEGER:
439 1.1 darran case CTF_K_FLOAT:
440 1.1 darran if (kind == CTF_K_INTEGER) {
441 1.1 darran encoding = CTF_INT_DATA(
442 1.1 darran dtd->dtd_u.dtu_enc.cte_format,
443 1.1 darran dtd->dtd_u.dtu_enc.cte_offset,
444 1.1 darran dtd->dtd_u.dtu_enc.cte_bits);
445 1.1 darran } else {
446 1.1 darran encoding = CTF_FP_DATA(
447 1.1 darran dtd->dtd_u.dtu_enc.cte_format,
448 1.1 darran dtd->dtd_u.dtu_enc.cte_offset,
449 1.1 darran dtd->dtd_u.dtu_enc.cte_bits);
450 1.1 darran }
451 1.8 christos memcpy(t, &encoding, sizeof (encoding));
452 1.1 darran t += sizeof (encoding);
453 1.1 darran break;
454 1.1 darran
455 1.1 darran case CTF_K_ARRAY:
456 1.8 christos if (fp->ctf_version == CTF_VERSION_2) {
457 1.8 christos struct ctf_array_v2 cta;
458 1.8 christos
459 1.8 christos cta.cta_contents =
460 1.8 christos (uint16_t)dtd->dtd_u.dtu_arr.ctr_contents;
461 1.8 christos cta.cta_index =
462 1.8 christos (uint16_t)dtd->dtd_u.dtu_arr.ctr_index;
463 1.8 christos cta.cta_nelems = dtd->dtd_u.dtu_arr.ctr_nelems;
464 1.8 christos
465 1.8 christos memcpy(t, &cta, sizeof (cta));
466 1.8 christos t += sizeof (cta);
467 1.8 christos } else {
468 1.8 christos struct ctf_array_v3 cta;
469 1.8 christos
470 1.8 christos cta.cta_contents =
471 1.8 christos dtd->dtd_u.dtu_arr.ctr_contents;
472 1.8 christos cta.cta_index = dtd->dtd_u.dtu_arr.ctr_index;
473 1.8 christos cta.cta_nelems = dtd->dtd_u.dtu_arr.ctr_nelems;
474 1.8 christos
475 1.8 christos memcpy(t, &cta, sizeof (cta));
476 1.8 christos t += sizeof (cta);
477 1.8 christos }
478 1.1 darran break;
479 1.1 darran
480 1.1 darran case CTF_K_FUNCTION: {
481 1.8 christos char *argv = (char *)(uintptr_t)t;
482 1.1 darran uint_t argc;
483 1.1 darran
484 1.8 christos if (fp->ctf_version == CTF_VERSION_2) {
485 1.8 christos ushort_t arg;
486 1.1 darran
487 1.8 christos for (argc = 0; argc < vlen;
488 1.8 christos argc++, argv += sizeof(arg)) {
489 1.8 christos arg =
490 1.8 christos (ushort_t)dtd->dtd_u.dtu_argv[argc];
491 1.8 christos memcpy(argv, &arg, sizeof(arg));
492 1.8 christos }
493 1.8 christos } else {
494 1.8 christos uint_t arg;
495 1.8 christos
496 1.8 christos for (argc = 0; argc < vlen;
497 1.8 christos argc++, argv += sizeof(arg)) {
498 1.8 christos arg = (uint_t)dtd->dtd_u.dtu_argv[argc];
499 1.8 christos memcpy(argv, &arg, sizeof(arg));
500 1.8 christos }
501 1.8 christos }
502 1.1 darran
503 1.1 darran t = (uchar_t *)argv;
504 1.1 darran break;
505 1.1 darran }
506 1.1 darran
507 1.1 darran case CTF_K_STRUCT:
508 1.1 darran case CTF_K_UNION:
509 1.8 christos if (dtd->dtd_data.ctt_size < LCTF_LSTRUCT_THRESH(fp))
510 1.8 christos t = ctf_copy_smembers(fp, dtd, (uint_t)(s - s0),
511 1.8 christos t);
512 1.1 darran else
513 1.8 christos t = ctf_copy_lmembers(fp, dtd, (uint_t)(s - s0),
514 1.8 christos t);
515 1.1 darran s = ctf_copy_membnames(dtd, s);
516 1.1 darran break;
517 1.1 darran
518 1.1 darran case CTF_K_ENUM:
519 1.1 darran t = ctf_copy_emembers(dtd, (uint_t)(s - s0), t);
520 1.1 darran s = ctf_copy_membnames(dtd, s);
521 1.1 darran break;
522 1.1 darran }
523 1.1 darran }
524 1.1 darran
525 1.1 darran /*
526 1.1 darran * Finally, we are ready to ctf_bufopen() the new container. If this
527 1.1 darran * is successful, we then switch nfp and fp and free the old container.
528 1.1 darran */
529 1.1 darran ctf_data_protect(buf, size);
530 1.4 christos cts.cts_name = _CTF_SECTION;
531 1.1 darran cts.cts_type = SHT_PROGBITS;
532 1.1 darran cts.cts_flags = 0;
533 1.1 darran cts.cts_data = buf;
534 1.1 darran cts.cts_size = size;
535 1.1 darran cts.cts_entsize = 1;
536 1.1 darran cts.cts_offset = 0;
537 1.1 darran
538 1.1 darran if ((nfp = ctf_bufopen(&cts, NULL, NULL, &err)) == NULL) {
539 1.1 darran ctf_data_free(buf, size);
540 1.1 darran return (ctf_set_errno(fp, err));
541 1.1 darran }
542 1.1 darran
543 1.1 darran (void) ctf_setmodel(nfp, ctf_getmodel(fp));
544 1.1 darran (void) ctf_import(nfp, fp->ctf_parent);
545 1.1 darran
546 1.1 darran nfp->ctf_refcnt = fp->ctf_refcnt;
547 1.1 darran nfp->ctf_flags |= fp->ctf_flags & ~LCTF_DIRTY;
548 1.1 darran nfp->ctf_data.cts_data = NULL; /* force ctf_data_free() on close */
549 1.1 darran nfp->ctf_dthash = fp->ctf_dthash;
550 1.1 darran nfp->ctf_dthashlen = fp->ctf_dthashlen;
551 1.1 darran nfp->ctf_dtdefs = fp->ctf_dtdefs;
552 1.1 darran nfp->ctf_dtstrlen = fp->ctf_dtstrlen;
553 1.1 darran nfp->ctf_dtnextid = fp->ctf_dtnextid;
554 1.1 darran nfp->ctf_dtoldid = fp->ctf_dtnextid - 1;
555 1.1 darran nfp->ctf_specific = fp->ctf_specific;
556 1.1 darran
557 1.1 darran fp->ctf_dthash = NULL;
558 1.1 darran fp->ctf_dthashlen = 0;
559 1.8 christos memset(&fp->ctf_dtdefs, 0, sizeof (ctf_list_t));
560 1.1 darran
561 1.8 christos memcpy(&ofp, fp, sizeof (ctf_file_t));
562 1.8 christos memcpy(fp, nfp, sizeof (ctf_file_t));
563 1.8 christos memcpy(nfp, &ofp, sizeof (ctf_file_t));
564 1.1 darran
565 1.1 darran /*
566 1.1 darran * Initialize the ctf_lookup_by_name top-level dictionary. We keep an
567 1.1 darran * array of type name prefixes and the corresponding ctf_hash to use.
568 1.1 darran * NOTE: This code must be kept in sync with the code in ctf_bufopen().
569 1.1 darran */
570 1.1 darran fp->ctf_lookups[0].ctl_hash = &fp->ctf_structs;
571 1.1 darran fp->ctf_lookups[1].ctl_hash = &fp->ctf_unions;
572 1.1 darran fp->ctf_lookups[2].ctl_hash = &fp->ctf_enums;
573 1.1 darran fp->ctf_lookups[3].ctl_hash = &fp->ctf_names;
574 1.1 darran
575 1.1 darran nfp->ctf_refcnt = 1; /* force nfp to be freed */
576 1.1 darran ctf_close(nfp);
577 1.1 darran
578 1.1 darran return (0);
579 1.1 darran }
580 1.1 darran
581 1.1 darran void
582 1.1 darran ctf_dtd_insert(ctf_file_t *fp, ctf_dtdef_t *dtd)
583 1.1 darran {
584 1.1 darran ulong_t h = dtd->dtd_type & (fp->ctf_dthashlen - 1);
585 1.1 darran
586 1.1 darran dtd->dtd_hash = fp->ctf_dthash[h];
587 1.1 darran fp->ctf_dthash[h] = dtd;
588 1.1 darran ctf_list_append(&fp->ctf_dtdefs, dtd);
589 1.1 darran }
590 1.1 darran
591 1.1 darran void
592 1.1 darran ctf_dtd_delete(ctf_file_t *fp, ctf_dtdef_t *dtd)
593 1.1 darran {
594 1.1 darran ulong_t h = dtd->dtd_type & (fp->ctf_dthashlen - 1);
595 1.1 darran ctf_dtdef_t *p, **q = &fp->ctf_dthash[h];
596 1.1 darran ctf_dmdef_t *dmd, *nmd;
597 1.1 darran size_t len;
598 1.4 christos int kind, i;
599 1.1 darran
600 1.1 darran for (p = *q; p != NULL; p = p->dtd_hash) {
601 1.1 darran if (p != dtd)
602 1.1 darran q = &p->dtd_hash;
603 1.1 darran else
604 1.1 darran break;
605 1.1 darran }
606 1.1 darran
607 1.1 darran if (p != NULL)
608 1.1 darran *q = p->dtd_hash;
609 1.1 darran
610 1.8 christos kind = LCTF_INFO_KIND(fp, dtd->dtd_data.ctt_info);
611 1.4 christos switch (kind) {
612 1.1 darran case CTF_K_STRUCT:
613 1.1 darran case CTF_K_UNION:
614 1.1 darran case CTF_K_ENUM:
615 1.1 darran for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
616 1.1 darran dmd != NULL; dmd = nmd) {
617 1.1 darran if (dmd->dmd_name != NULL) {
618 1.1 darran len = strlen(dmd->dmd_name) + 1;
619 1.1 darran ctf_free(dmd->dmd_name, len);
620 1.1 darran fp->ctf_dtstrlen -= len;
621 1.1 darran }
622 1.4 christos if (kind != CTF_K_ENUM)
623 1.4 christos ctf_ref_dec(fp, dmd->dmd_type);
624 1.1 darran nmd = ctf_list_next(dmd);
625 1.1 darran ctf_free(dmd, sizeof (ctf_dmdef_t));
626 1.1 darran }
627 1.1 darran break;
628 1.1 darran case CTF_K_FUNCTION:
629 1.4 christos ctf_ref_dec(fp, dtd->dtd_data.ctt_type);
630 1.8 christos for (i = 0; i < LCTF_INFO_VLEN(fp, dtd->dtd_data.ctt_info); i++)
631 1.4 christos if (dtd->dtd_u.dtu_argv[i] != 0)
632 1.4 christos ctf_ref_dec(fp, dtd->dtd_u.dtu_argv[i]);
633 1.1 darran ctf_free(dtd->dtd_u.dtu_argv, sizeof (ctf_id_t) *
634 1.8 christos LCTF_INFO_VLEN(fp, dtd->dtd_data.ctt_info));
635 1.1 darran break;
636 1.4 christos case CTF_K_ARRAY:
637 1.4 christos ctf_ref_dec(fp, dtd->dtd_u.dtu_arr.ctr_contents);
638 1.4 christos ctf_ref_dec(fp, dtd->dtd_u.dtu_arr.ctr_index);
639 1.4 christos break;
640 1.4 christos case CTF_K_TYPEDEF:
641 1.4 christos ctf_ref_dec(fp, dtd->dtd_data.ctt_type);
642 1.4 christos break;
643 1.4 christos case CTF_K_POINTER:
644 1.4 christos case CTF_K_VOLATILE:
645 1.4 christos case CTF_K_CONST:
646 1.4 christos case CTF_K_RESTRICT:
647 1.4 christos ctf_ref_dec(fp, dtd->dtd_data.ctt_type);
648 1.4 christos break;
649 1.1 darran }
650 1.1 darran
651 1.1 darran if (dtd->dtd_name) {
652 1.1 darran len = strlen(dtd->dtd_name) + 1;
653 1.1 darran ctf_free(dtd->dtd_name, len);
654 1.1 darran fp->ctf_dtstrlen -= len;
655 1.1 darran }
656 1.1 darran
657 1.1 darran ctf_list_delete(&fp->ctf_dtdefs, dtd);
658 1.1 darran ctf_free(dtd, sizeof (ctf_dtdef_t));
659 1.1 darran }
660 1.1 darran
661 1.1 darran ctf_dtdef_t *
662 1.1 darran ctf_dtd_lookup(ctf_file_t *fp, ctf_id_t type)
663 1.1 darran {
664 1.1 darran ulong_t h = type & (fp->ctf_dthashlen - 1);
665 1.1 darran ctf_dtdef_t *dtd;
666 1.1 darran
667 1.1 darran if (fp->ctf_dthash == NULL)
668 1.1 darran return (NULL);
669 1.1 darran
670 1.1 darran for (dtd = fp->ctf_dthash[h]; dtd != NULL; dtd = dtd->dtd_hash) {
671 1.1 darran if (dtd->dtd_type == type)
672 1.1 darran break;
673 1.1 darran }
674 1.1 darran
675 1.1 darran return (dtd);
676 1.1 darran }
677 1.1 darran
678 1.1 darran /*
679 1.1 darran * Discard all of the dynamic type definitions that have been added to the
680 1.1 darran * container since the last call to ctf_update(). We locate such types by
681 1.1 darran * scanning the list and deleting elements that have type IDs greater than
682 1.4 christos * ctf_dtoldid, which is set by ctf_update(), above. Note that to work properly
683 1.4 christos * with our reference counting schemes, we must delete the dynamic list in
684 1.4 christos * reverse.
685 1.1 darran */
686 1.1 darran int
687 1.1 darran ctf_discard(ctf_file_t *fp)
688 1.1 darran {
689 1.4 christos ctf_dtdef_t *dtd, *ntd;
690 1.1 darran
691 1.1 darran if (!(fp->ctf_flags & LCTF_RDWR))
692 1.1 darran return (ctf_set_errno(fp, ECTF_RDONLY));
693 1.1 darran
694 1.1 darran if (!(fp->ctf_flags & LCTF_DIRTY))
695 1.1 darran return (0); /* no update required */
696 1.1 darran
697 1.4 christos for (dtd = ctf_list_prev(&fp->ctf_dtdefs); dtd != NULL; dtd = ntd) {
698 1.4 christos ntd = ctf_list_prev(dtd);
699 1.8 christos if (LCTF_TYPE_TO_INDEX(fp, dtd->dtd_type) <= fp->ctf_dtoldid)
700 1.1 darran continue; /* skip types that have been committed */
701 1.1 darran
702 1.1 darran ctf_dtd_delete(fp, dtd);
703 1.1 darran }
704 1.1 darran
705 1.1 darran fp->ctf_dtnextid = fp->ctf_dtoldid + 1;
706 1.1 darran fp->ctf_flags &= ~LCTF_DIRTY;
707 1.1 darran
708 1.1 darran return (0);
709 1.1 darran }
710 1.1 darran
711 1.1 darran static ctf_id_t
712 1.1 darran ctf_add_generic(ctf_file_t *fp, uint_t flag, const char *name, ctf_dtdef_t **rp)
713 1.1 darran {
714 1.1 darran ctf_dtdef_t *dtd;
715 1.1 darran ctf_id_t type;
716 1.1 darran char *s = NULL;
717 1.1 darran
718 1.1 darran if (flag != CTF_ADD_NONROOT && flag != CTF_ADD_ROOT)
719 1.1 darran return (ctf_set_errno(fp, EINVAL));
720 1.1 darran
721 1.1 darran if (!(fp->ctf_flags & LCTF_RDWR))
722 1.1 darran return (ctf_set_errno(fp, ECTF_RDONLY));
723 1.1 darran
724 1.8 christos if (LCTF_INDEX_TO_TYPE(fp, fp->ctf_dtnextid, 1) > LCTF_MAX_TYPE(fp)) {
725 1.7 christos ctf_dprintf("type id overflow %lu\n", fp->ctf_dtnextid);
726 1.1 darran return (ctf_set_errno(fp, ECTF_FULL));
727 1.7 christos }
728 1.1 darran
729 1.1 darran if ((dtd = ctf_alloc(sizeof (ctf_dtdef_t))) == NULL)
730 1.1 darran return (ctf_set_errno(fp, EAGAIN));
731 1.1 darran
732 1.8 christos if (name != NULL && *name != '\0' && (s = ctf_strdup(name)) == NULL) {
733 1.1 darran ctf_free(dtd, sizeof (ctf_dtdef_t));
734 1.1 darran return (ctf_set_errno(fp, EAGAIN));
735 1.1 darran }
736 1.1 darran
737 1.1 darran type = fp->ctf_dtnextid++;
738 1.8 christos type = LCTF_INDEX_TO_TYPE(fp, type, (fp->ctf_flags & LCTF_CHILD));
739 1.1 darran
740 1.8 christos memset(dtd, 0, sizeof (ctf_dtdef_t));
741 1.1 darran dtd->dtd_name = s;
742 1.1 darran dtd->dtd_type = type;
743 1.1 darran
744 1.1 darran if (s != NULL)
745 1.1 darran fp->ctf_dtstrlen += strlen(s) + 1;
746 1.1 darran
747 1.1 darran ctf_dtd_insert(fp, dtd);
748 1.1 darran fp->ctf_flags |= LCTF_DIRTY;
749 1.1 darran
750 1.1 darran *rp = dtd;
751 1.1 darran return (type);
752 1.1 darran }
753 1.1 darran
754 1.1 darran /*
755 1.1 darran * When encoding integer sizes, we want to convert a byte count in the range
756 1.1 darran * 1-8 to the closest power of 2 (e.g. 3->4, 5->8, etc). The clp2() function
757 1.1 darran * is a clever implementation from "Hacker's Delight" by Henry Warren, Jr.
758 1.1 darran */
759 1.1 darran static size_t
760 1.1 darran clp2(size_t x)
761 1.1 darran {
762 1.1 darran x--;
763 1.1 darran
764 1.1 darran x |= (x >> 1);
765 1.1 darran x |= (x >> 2);
766 1.1 darran x |= (x >> 4);
767 1.1 darran x |= (x >> 8);
768 1.1 darran x |= (x >> 16);
769 1.1 darran
770 1.1 darran return (x + 1);
771 1.1 darran }
772 1.1 darran
773 1.1 darran static ctf_id_t
774 1.1 darran ctf_add_encoded(ctf_file_t *fp, uint_t flag,
775 1.1 darran const char *name, const ctf_encoding_t *ep, uint_t kind)
776 1.1 darran {
777 1.1 darran ctf_dtdef_t *dtd;
778 1.1 darran ctf_id_t type;
779 1.1 darran
780 1.1 darran if (ep == NULL)
781 1.1 darran return (ctf_set_errno(fp, EINVAL));
782 1.1 darran
783 1.1 darran if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR)
784 1.1 darran return (CTF_ERR); /* errno is set for us */
785 1.1 darran
786 1.8 christos dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, kind, flag, 0);
787 1.1 darran dtd->dtd_data.ctt_size = clp2(P2ROUNDUP(ep->cte_bits, NBBY) / NBBY);
788 1.1 darran dtd->dtd_u.dtu_enc = *ep;
789 1.1 darran
790 1.1 darran return (type);
791 1.1 darran }
792 1.1 darran
793 1.1 darran static ctf_id_t
794 1.1 darran ctf_add_reftype(ctf_file_t *fp, uint_t flag, ctf_id_t ref, uint_t kind)
795 1.1 darran {
796 1.1 darran ctf_dtdef_t *dtd;
797 1.1 darran ctf_id_t type;
798 1.1 darran
799 1.9 hannken if (ref == CTF_ERR || ref > LCTF_MAX_TYPE(fp))
800 1.1 darran return (ctf_set_errno(fp, EINVAL));
801 1.1 darran
802 1.1 darran if ((type = ctf_add_generic(fp, flag, NULL, &dtd)) == CTF_ERR)
803 1.1 darran return (CTF_ERR); /* errno is set for us */
804 1.1 darran
805 1.4 christos ctf_ref_inc(fp, ref);
806 1.4 christos
807 1.8 christos dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, kind, flag, 0);
808 1.8 christos dtd->dtd_data.ctt_type = (uint_t)ref;
809 1.1 darran
810 1.1 darran return (type);
811 1.1 darran }
812 1.1 darran
813 1.1 darran ctf_id_t
814 1.1 darran ctf_add_integer(ctf_file_t *fp, uint_t flag,
815 1.1 darran const char *name, const ctf_encoding_t *ep)
816 1.1 darran {
817 1.1 darran return (ctf_add_encoded(fp, flag, name, ep, CTF_K_INTEGER));
818 1.1 darran }
819 1.1 darran
820 1.1 darran ctf_id_t
821 1.1 darran ctf_add_float(ctf_file_t *fp, uint_t flag,
822 1.1 darran const char *name, const ctf_encoding_t *ep)
823 1.1 darran {
824 1.1 darran return (ctf_add_encoded(fp, flag, name, ep, CTF_K_FLOAT));
825 1.1 darran }
826 1.1 darran
827 1.1 darran ctf_id_t
828 1.1 darran ctf_add_pointer(ctf_file_t *fp, uint_t flag, ctf_id_t ref)
829 1.1 darran {
830 1.1 darran return (ctf_add_reftype(fp, flag, ref, CTF_K_POINTER));
831 1.1 darran }
832 1.1 darran
833 1.1 darran ctf_id_t
834 1.1 darran ctf_add_array(ctf_file_t *fp, uint_t flag, const ctf_arinfo_t *arp)
835 1.1 darran {
836 1.1 darran ctf_dtdef_t *dtd;
837 1.1 darran ctf_id_t type;
838 1.4 christos ctf_file_t *fpd;
839 1.1 darran
840 1.1 darran if (arp == NULL)
841 1.1 darran return (ctf_set_errno(fp, EINVAL));
842 1.1 darran
843 1.4 christos fpd = fp;
844 1.4 christos if (ctf_lookup_by_id(&fpd, arp->ctr_contents) == NULL &&
845 1.4 christos ctf_dtd_lookup(fp, arp->ctr_contents) == NULL)
846 1.4 christos return (ctf_set_errno(fp, ECTF_BADID));
847 1.4 christos
848 1.4 christos fpd = fp;
849 1.4 christos if (ctf_lookup_by_id(&fpd, arp->ctr_index) == NULL &&
850 1.4 christos ctf_dtd_lookup(fp, arp->ctr_index) == NULL)
851 1.4 christos return (ctf_set_errno(fp, ECTF_BADID));
852 1.4 christos
853 1.1 darran if ((type = ctf_add_generic(fp, flag, NULL, &dtd)) == CTF_ERR)
854 1.1 darran return (CTF_ERR); /* errno is set for us */
855 1.1 darran
856 1.8 christos dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, CTF_K_ARRAY, flag, 0);
857 1.1 darran dtd->dtd_data.ctt_size = 0;
858 1.1 darran dtd->dtd_u.dtu_arr = *arp;
859 1.4 christos ctf_ref_inc(fp, arp->ctr_contents);
860 1.4 christos ctf_ref_inc(fp, arp->ctr_index);
861 1.1 darran
862 1.1 darran return (type);
863 1.1 darran }
864 1.1 darran
865 1.1 darran int
866 1.1 darran ctf_set_array(ctf_file_t *fp, ctf_id_t type, const ctf_arinfo_t *arp)
867 1.1 darran {
868 1.4 christos ctf_file_t *fpd;
869 1.1 darran ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, type);
870 1.1 darran
871 1.1 darran if (!(fp->ctf_flags & LCTF_RDWR))
872 1.1 darran return (ctf_set_errno(fp, ECTF_RDONLY));
873 1.1 darran
874 1.8 christos if (dtd == NULL ||
875 1.8 christos LCTF_INFO_KIND(fp, dtd->dtd_data.ctt_info) != CTF_K_ARRAY)
876 1.1 darran return (ctf_set_errno(fp, ECTF_BADID));
877 1.1 darran
878 1.4 christos fpd = fp;
879 1.4 christos if (ctf_lookup_by_id(&fpd, arp->ctr_contents) == NULL &&
880 1.4 christos ctf_dtd_lookup(fp, arp->ctr_contents) == NULL)
881 1.4 christos return (ctf_set_errno(fp, ECTF_BADID));
882 1.4 christos
883 1.4 christos fpd = fp;
884 1.4 christos if (ctf_lookup_by_id(&fpd, arp->ctr_index) == NULL &&
885 1.4 christos ctf_dtd_lookup(fp, arp->ctr_index) == NULL)
886 1.4 christos return (ctf_set_errno(fp, ECTF_BADID));
887 1.4 christos
888 1.4 christos ctf_ref_dec(fp, dtd->dtd_u.dtu_arr.ctr_contents);
889 1.4 christos ctf_ref_dec(fp, dtd->dtd_u.dtu_arr.ctr_index);
890 1.1 darran fp->ctf_flags |= LCTF_DIRTY;
891 1.1 darran dtd->dtd_u.dtu_arr = *arp;
892 1.4 christos ctf_ref_inc(fp, arp->ctr_contents);
893 1.4 christos ctf_ref_inc(fp, arp->ctr_index);
894 1.1 darran
895 1.1 darran return (0);
896 1.1 darran }
897 1.1 darran
898 1.1 darran ctf_id_t
899 1.1 darran ctf_add_function(ctf_file_t *fp, uint_t flag,
900 1.1 darran const ctf_funcinfo_t *ctc, const ctf_id_t *argv)
901 1.1 darran {
902 1.1 darran ctf_dtdef_t *dtd;
903 1.1 darran ctf_id_t type;
904 1.1 darran uint_t vlen;
905 1.4 christos int i;
906 1.1 darran ctf_id_t *vdat = NULL;
907 1.4 christos ctf_file_t *fpd;
908 1.1 darran
909 1.1 darran if (ctc == NULL || (ctc->ctc_flags & ~CTF_FUNC_VARARG) != 0 ||
910 1.1 darran (ctc->ctc_argc != 0 && argv == NULL))
911 1.1 darran return (ctf_set_errno(fp, EINVAL));
912 1.1 darran
913 1.1 darran vlen = ctc->ctc_argc;
914 1.1 darran if (ctc->ctc_flags & CTF_FUNC_VARARG)
915 1.1 darran vlen++; /* add trailing zero to indicate varargs (see below) */
916 1.1 darran
917 1.8 christos if (vlen > LCTF_MAX_VLEN(fp))
918 1.1 darran return (ctf_set_errno(fp, EOVERFLOW));
919 1.1 darran
920 1.4 christos fpd = fp;
921 1.4 christos if (ctf_lookup_by_id(&fpd, ctc->ctc_return) == NULL &&
922 1.4 christos ctf_dtd_lookup(fp, ctc->ctc_return) == NULL)
923 1.4 christos return (ctf_set_errno(fp, ECTF_BADID));
924 1.4 christos
925 1.4 christos for (i = 0; i < ctc->ctc_argc; i++) {
926 1.4 christos fpd = fp;
927 1.4 christos if (ctf_lookup_by_id(&fpd, argv[i]) == NULL &&
928 1.4 christos ctf_dtd_lookup(fp, argv[i]) == NULL)
929 1.4 christos return (ctf_set_errno(fp, ECTF_BADID));
930 1.4 christos }
931 1.4 christos
932 1.1 darran if (vlen != 0 && (vdat = ctf_alloc(sizeof (ctf_id_t) * vlen)) == NULL)
933 1.1 darran return (ctf_set_errno(fp, EAGAIN));
934 1.1 darran
935 1.1 darran if ((type = ctf_add_generic(fp, flag, NULL, &dtd)) == CTF_ERR) {
936 1.1 darran ctf_free(vdat, sizeof (ctf_id_t) * vlen);
937 1.1 darran return (CTF_ERR); /* errno is set for us */
938 1.1 darran }
939 1.1 darran
940 1.8 christos dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, CTF_K_FUNCTION, flag, vlen);
941 1.8 christos dtd->dtd_data.ctt_type = ctc->ctc_return;
942 1.1 darran
943 1.4 christos ctf_ref_inc(fp, ctc->ctc_return);
944 1.4 christos for (i = 0; i < ctc->ctc_argc; i++)
945 1.4 christos ctf_ref_inc(fp, argv[i]);
946 1.4 christos
947 1.8 christos memcpy(vdat, argv, sizeof (ctf_id_t) * ctc->ctc_argc);
948 1.1 darran if (ctc->ctc_flags & CTF_FUNC_VARARG)
949 1.1 darran vdat[vlen - 1] = 0; /* add trailing zero to indicate varargs */
950 1.1 darran dtd->dtd_u.dtu_argv = vdat;
951 1.1 darran
952 1.1 darran return (type);
953 1.1 darran }
954 1.1 darran
955 1.1 darran ctf_id_t
956 1.1 darran ctf_add_struct(ctf_file_t *fp, uint_t flag, const char *name)
957 1.1 darran {
958 1.1 darran ctf_hash_t *hp = &fp->ctf_structs;
959 1.1 darran ctf_helem_t *hep = NULL;
960 1.1 darran ctf_dtdef_t *dtd;
961 1.1 darran ctf_id_t type;
962 1.1 darran
963 1.1 darran if (name != NULL)
964 1.1 darran hep = ctf_hash_lookup(hp, fp, name, strlen(name));
965 1.1 darran
966 1.1 darran if (hep != NULL && ctf_type_kind(fp, hep->h_type) == CTF_K_FORWARD)
967 1.1 darran dtd = ctf_dtd_lookup(fp, type = hep->h_type);
968 1.1 darran else if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR)
969 1.1 darran return (CTF_ERR); /* errno is set for us */
970 1.1 darran
971 1.8 christos dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, CTF_K_STRUCT, flag, 0);
972 1.1 darran dtd->dtd_data.ctt_size = 0;
973 1.1 darran
974 1.1 darran return (type);
975 1.1 darran }
976 1.1 darran
977 1.1 darran ctf_id_t
978 1.1 darran ctf_add_union(ctf_file_t *fp, uint_t flag, const char *name)
979 1.1 darran {
980 1.1 darran ctf_hash_t *hp = &fp->ctf_unions;
981 1.1 darran ctf_helem_t *hep = NULL;
982 1.1 darran ctf_dtdef_t *dtd;
983 1.1 darran ctf_id_t type;
984 1.1 darran
985 1.1 darran if (name != NULL)
986 1.1 darran hep = ctf_hash_lookup(hp, fp, name, strlen(name));
987 1.1 darran
988 1.1 darran if (hep != NULL && ctf_type_kind(fp, hep->h_type) == CTF_K_FORWARD)
989 1.1 darran dtd = ctf_dtd_lookup(fp, type = hep->h_type);
990 1.1 darran else if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR)
991 1.1 darran return (CTF_ERR); /* errno is set for us */
992 1.1 darran
993 1.8 christos dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, CTF_K_UNION, flag, 0);
994 1.1 darran dtd->dtd_data.ctt_size = 0;
995 1.1 darran
996 1.1 darran return (type);
997 1.1 darran }
998 1.1 darran
999 1.1 darran ctf_id_t
1000 1.1 darran ctf_add_enum(ctf_file_t *fp, uint_t flag, const char *name)
1001 1.1 darran {
1002 1.1 darran ctf_hash_t *hp = &fp->ctf_enums;
1003 1.1 darran ctf_helem_t *hep = NULL;
1004 1.1 darran ctf_dtdef_t *dtd;
1005 1.1 darran ctf_id_t type;
1006 1.1 darran
1007 1.1 darran if (name != NULL)
1008 1.1 darran hep = ctf_hash_lookup(hp, fp, name, strlen(name));
1009 1.1 darran
1010 1.1 darran if (hep != NULL && ctf_type_kind(fp, hep->h_type) == CTF_K_FORWARD)
1011 1.1 darran dtd = ctf_dtd_lookup(fp, type = hep->h_type);
1012 1.1 darran else if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR)
1013 1.1 darran return (CTF_ERR); /* errno is set for us */
1014 1.1 darran
1015 1.8 christos dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, CTF_K_ENUM, flag, 0);
1016 1.1 darran dtd->dtd_data.ctt_size = fp->ctf_dmodel->ctd_int;
1017 1.1 darran
1018 1.1 darran return (type);
1019 1.1 darran }
1020 1.1 darran
1021 1.1 darran ctf_id_t
1022 1.1 darran ctf_add_forward(ctf_file_t *fp, uint_t flag, const char *name, uint_t kind)
1023 1.1 darran {
1024 1.1 darran ctf_hash_t *hp;
1025 1.1 darran ctf_helem_t *hep;
1026 1.1 darran ctf_dtdef_t *dtd;
1027 1.1 darran ctf_id_t type;
1028 1.1 darran
1029 1.1 darran switch (kind) {
1030 1.1 darran case CTF_K_STRUCT:
1031 1.1 darran hp = &fp->ctf_structs;
1032 1.1 darran break;
1033 1.1 darran case CTF_K_UNION:
1034 1.1 darran hp = &fp->ctf_unions;
1035 1.1 darran break;
1036 1.1 darran case CTF_K_ENUM:
1037 1.1 darran hp = &fp->ctf_enums;
1038 1.1 darran break;
1039 1.1 darran default:
1040 1.1 darran return (ctf_set_errno(fp, ECTF_NOTSUE));
1041 1.1 darran }
1042 1.1 darran
1043 1.1 darran /*
1044 1.1 darran * If the type is already defined or exists as a forward tag, just
1045 1.1 darran * return the ctf_id_t of the existing definition.
1046 1.1 darran */
1047 1.1 darran if (name != NULL && (hep = ctf_hash_lookup(hp,
1048 1.1 darran fp, name, strlen(name))) != NULL)
1049 1.1 darran return (hep->h_type);
1050 1.1 darran
1051 1.1 darran if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR)
1052 1.1 darran return (CTF_ERR); /* errno is set for us */
1053 1.1 darran
1054 1.8 christos dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, CTF_K_FORWARD, flag, 0);
1055 1.1 darran dtd->dtd_data.ctt_type = kind;
1056 1.1 darran
1057 1.1 darran return (type);
1058 1.1 darran }
1059 1.1 darran
1060 1.1 darran ctf_id_t
1061 1.1 darran ctf_add_typedef(ctf_file_t *fp, uint_t flag, const char *name, ctf_id_t ref)
1062 1.1 darran {
1063 1.1 darran ctf_dtdef_t *dtd;
1064 1.1 darran ctf_id_t type;
1065 1.4 christos ctf_file_t *fpd;
1066 1.1 darran
1067 1.4 christos fpd = fp;
1068 1.4 christos if (ref == CTF_ERR || (ctf_lookup_by_id(&fpd, ref) == NULL &&
1069 1.4 christos ctf_dtd_lookup(fp, ref) == NULL))
1070 1.1 darran return (ctf_set_errno(fp, EINVAL));
1071 1.1 darran
1072 1.1 darran if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR)
1073 1.1 darran return (CTF_ERR); /* errno is set for us */
1074 1.1 darran
1075 1.8 christos dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, CTF_K_TYPEDEF, flag, 0);
1076 1.8 christos dtd->dtd_data.ctt_type = ref;
1077 1.4 christos ctf_ref_inc(fp, ref);
1078 1.1 darran
1079 1.1 darran return (type);
1080 1.1 darran }
1081 1.1 darran
1082 1.1 darran ctf_id_t
1083 1.1 darran ctf_add_volatile(ctf_file_t *fp, uint_t flag, ctf_id_t ref)
1084 1.1 darran {
1085 1.1 darran return (ctf_add_reftype(fp, flag, ref, CTF_K_VOLATILE));
1086 1.1 darran }
1087 1.1 darran
1088 1.1 darran ctf_id_t
1089 1.1 darran ctf_add_const(ctf_file_t *fp, uint_t flag, ctf_id_t ref)
1090 1.1 darran {
1091 1.1 darran return (ctf_add_reftype(fp, flag, ref, CTF_K_CONST));
1092 1.1 darran }
1093 1.1 darran
1094 1.1 darran ctf_id_t
1095 1.1 darran ctf_add_restrict(ctf_file_t *fp, uint_t flag, ctf_id_t ref)
1096 1.1 darran {
1097 1.1 darran return (ctf_add_reftype(fp, flag, ref, CTF_K_RESTRICT));
1098 1.1 darran }
1099 1.1 darran
1100 1.1 darran int
1101 1.1 darran ctf_add_enumerator(ctf_file_t *fp, ctf_id_t enid, const char *name, int value)
1102 1.1 darran {
1103 1.1 darran ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, enid);
1104 1.1 darran ctf_dmdef_t *dmd;
1105 1.1 darran
1106 1.1 darran uint_t kind, vlen, root;
1107 1.1 darran char *s;
1108 1.1 darran
1109 1.1 darran if (name == NULL)
1110 1.1 darran return (ctf_set_errno(fp, EINVAL));
1111 1.1 darran
1112 1.1 darran if (!(fp->ctf_flags & LCTF_RDWR))
1113 1.1 darran return (ctf_set_errno(fp, ECTF_RDONLY));
1114 1.1 darran
1115 1.1 darran if (dtd == NULL)
1116 1.1 darran return (ctf_set_errno(fp, ECTF_BADID));
1117 1.1 darran
1118 1.8 christos kind = LCTF_INFO_KIND(fp, dtd->dtd_data.ctt_info);
1119 1.8 christos root = LCTF_INFO_ROOT(fp, dtd->dtd_data.ctt_info);
1120 1.8 christos vlen = LCTF_INFO_VLEN(fp, dtd->dtd_data.ctt_info);
1121 1.1 darran
1122 1.1 darran if (kind != CTF_K_ENUM)
1123 1.1 darran return (ctf_set_errno(fp, ECTF_NOTENUM));
1124 1.1 darran
1125 1.8 christos if (vlen > LCTF_MAX_VLEN(fp))
1126 1.1 darran return (ctf_set_errno(fp, ECTF_DTFULL));
1127 1.1 darran
1128 1.1 darran for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
1129 1.1 darran dmd != NULL; dmd = ctf_list_next(dmd)) {
1130 1.1 darran if (strcmp(dmd->dmd_name, name) == 0)
1131 1.1 darran return (ctf_set_errno(fp, ECTF_DUPMEMBER));
1132 1.1 darran }
1133 1.1 darran
1134 1.1 darran if ((dmd = ctf_alloc(sizeof (ctf_dmdef_t))) == NULL)
1135 1.1 darran return (ctf_set_errno(fp, EAGAIN));
1136 1.1 darran
1137 1.1 darran if ((s = ctf_strdup(name)) == NULL) {
1138 1.1 darran ctf_free(dmd, sizeof (ctf_dmdef_t));
1139 1.1 darran return (ctf_set_errno(fp, EAGAIN));
1140 1.1 darran }
1141 1.1 darran
1142 1.1 darran dmd->dmd_name = s;
1143 1.1 darran dmd->dmd_type = CTF_ERR;
1144 1.1 darran dmd->dmd_offset = 0;
1145 1.1 darran dmd->dmd_value = value;
1146 1.1 darran
1147 1.8 christos dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, kind, root, vlen + 1);
1148 1.1 darran ctf_list_append(&dtd->dtd_u.dtu_members, dmd);
1149 1.1 darran
1150 1.1 darran fp->ctf_dtstrlen += strlen(s) + 1;
1151 1.1 darran fp->ctf_flags |= LCTF_DIRTY;
1152 1.1 darran
1153 1.1 darran return (0);
1154 1.1 darran }
1155 1.1 darran
1156 1.1 darran int
1157 1.1 darran ctf_add_member(ctf_file_t *fp, ctf_id_t souid, const char *name, ctf_id_t type)
1158 1.1 darran {
1159 1.1 darran ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, souid);
1160 1.1 darran ctf_dmdef_t *dmd;
1161 1.1 darran
1162 1.1 darran ssize_t msize, malign, ssize;
1163 1.1 darran uint_t kind, vlen, root;
1164 1.1 darran char *s = NULL;
1165 1.1 darran
1166 1.1 darran if (!(fp->ctf_flags & LCTF_RDWR))
1167 1.1 darran return (ctf_set_errno(fp, ECTF_RDONLY));
1168 1.1 darran
1169 1.1 darran if (dtd == NULL)
1170 1.1 darran return (ctf_set_errno(fp, ECTF_BADID));
1171 1.1 darran
1172 1.8 christos kind = LCTF_INFO_KIND(fp, dtd->dtd_data.ctt_info);
1173 1.8 christos root = LCTF_INFO_ROOT(fp, dtd->dtd_data.ctt_info);
1174 1.8 christos vlen = LCTF_INFO_VLEN(fp, dtd->dtd_data.ctt_info);
1175 1.1 darran
1176 1.1 darran if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1177 1.1 darran return (ctf_set_errno(fp, ECTF_NOTSOU));
1178 1.1 darran
1179 1.8 christos if (vlen > LCTF_MAX_VLEN(fp))
1180 1.1 darran return (ctf_set_errno(fp, ECTF_DTFULL));
1181 1.1 darran
1182 1.1 darran if (name != NULL) {
1183 1.1 darran for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
1184 1.1 darran dmd != NULL; dmd = ctf_list_next(dmd)) {
1185 1.1 darran if (dmd->dmd_name != NULL &&
1186 1.1 darran strcmp(dmd->dmd_name, name) == 0)
1187 1.1 darran return (ctf_set_errno(fp, ECTF_DUPMEMBER));
1188 1.1 darran }
1189 1.1 darran }
1190 1.1 darran
1191 1.1 darran if ((msize = ctf_type_size(fp, type)) == CTF_ERR ||
1192 1.1 darran (malign = ctf_type_align(fp, type)) == CTF_ERR)
1193 1.1 darran return (CTF_ERR); /* errno is set for us */
1194 1.1 darran
1195 1.1 darran if ((dmd = ctf_alloc(sizeof (ctf_dmdef_t))) == NULL)
1196 1.1 darran return (ctf_set_errno(fp, EAGAIN));
1197 1.1 darran
1198 1.1 darran if (name != NULL && (s = ctf_strdup(name)) == NULL) {
1199 1.1 darran ctf_free(dmd, sizeof (ctf_dmdef_t));
1200 1.1 darran return (ctf_set_errno(fp, EAGAIN));
1201 1.1 darran }
1202 1.1 darran
1203 1.1 darran dmd->dmd_name = s;
1204 1.1 darran dmd->dmd_type = type;
1205 1.1 darran dmd->dmd_value = -1;
1206 1.1 darran
1207 1.1 darran if (kind == CTF_K_STRUCT && vlen != 0) {
1208 1.1 darran ctf_dmdef_t *lmd = ctf_list_prev(&dtd->dtd_u.dtu_members);
1209 1.1 darran ctf_id_t ltype = ctf_type_resolve(fp, lmd->dmd_type);
1210 1.1 darran size_t off = lmd->dmd_offset;
1211 1.1 darran
1212 1.1 darran ctf_encoding_t linfo;
1213 1.1 darran ssize_t lsize;
1214 1.1 darran
1215 1.1 darran if (ctf_type_encoding(fp, ltype, &linfo) != CTF_ERR)
1216 1.1 darran off += linfo.cte_bits;
1217 1.1 darran else if ((lsize = ctf_type_size(fp, ltype)) != CTF_ERR)
1218 1.1 darran off += lsize * NBBY;
1219 1.1 darran
1220 1.1 darran /*
1221 1.1 darran * Round up the offset of the end of the last member to the
1222 1.1 darran * next byte boundary, convert 'off' to bytes, and then round
1223 1.1 darran * it up again to the next multiple of the alignment required
1224 1.1 darran * by the new member. Finally, convert back to bits and store
1225 1.1 darran * the result in dmd_offset. Technically we could do more
1226 1.1 darran * efficient packing if the new member is a bit-field, but
1227 1.1 darran * we're the "compiler" and ANSI says we can do as we choose.
1228 1.1 darran */
1229 1.1 darran off = roundup(off, NBBY) / NBBY;
1230 1.1 darran off = roundup(off, MAX(malign, 1));
1231 1.1 darran dmd->dmd_offset = off * NBBY;
1232 1.1 darran ssize = off + msize;
1233 1.1 darran } else {
1234 1.1 darran dmd->dmd_offset = 0;
1235 1.1 darran ssize = ctf_get_ctt_size(fp, &dtd->dtd_data, NULL, NULL);
1236 1.1 darran ssize = MAX(ssize, msize);
1237 1.1 darran }
1238 1.1 darran
1239 1.8 christos if (ssize > LCTF_MAX_SIZE(fp)) {
1240 1.8 christos dtd->dtd_data.ctt_size = LCTF_LSIZE_SENT(fp);
1241 1.1 darran dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(ssize);
1242 1.1 darran dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(ssize);
1243 1.1 darran } else
1244 1.8 christos dtd->dtd_data.ctt_size = ssize;
1245 1.1 darran
1246 1.8 christos dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(fp, kind, root, vlen + 1);
1247 1.1 darran ctf_list_append(&dtd->dtd_u.dtu_members, dmd);
1248 1.1 darran
1249 1.1 darran if (s != NULL)
1250 1.1 darran fp->ctf_dtstrlen += strlen(s) + 1;
1251 1.1 darran
1252 1.4 christos ctf_ref_inc(fp, type);
1253 1.4 christos fp->ctf_flags |= LCTF_DIRTY;
1254 1.4 christos return (0);
1255 1.4 christos }
1256 1.4 christos
1257 1.4 christos /*
1258 1.4 christos * This removes a type from the dynamic section. This will fail if the type is
1259 1.4 christos * referenced by another type. Note that the CTF ID is never reused currently by
1260 1.4 christos * CTF. Note that if this container is a parent container then we just outright
1261 1.4 christos * refuse to remove the type. There currently is no notion of searching for the
1262 1.4 christos * ctf_dtdef_t in parent containers. If there is, then this constraint could
1263 1.4 christos * become finer grained.
1264 1.4 christos */
1265 1.4 christos int
1266 1.4 christos ctf_delete_type(ctf_file_t *fp, ctf_id_t type)
1267 1.4 christos {
1268 1.4 christos ctf_file_t *fpd;
1269 1.4 christos ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, type);
1270 1.4 christos
1271 1.4 christos if (!(fp->ctf_flags & LCTF_RDWR))
1272 1.4 christos return (ctf_set_errno(fp, ECTF_RDONLY));
1273 1.4 christos
1274 1.4 christos /*
1275 1.4 christos * We want to give as useful an errno as possible. That means that we
1276 1.4 christos * want to distinguish between a type which does not exist and one for
1277 1.4 christos * which the type is not dynamic.
1278 1.4 christos */
1279 1.4 christos fpd = fp;
1280 1.4 christos if (ctf_lookup_by_id(&fpd, type) == NULL &&
1281 1.4 christos ctf_dtd_lookup(fp, type) == NULL)
1282 1.4 christos return (CTF_ERR); /* errno is set for us */
1283 1.4 christos
1284 1.4 christos if (dtd == NULL)
1285 1.4 christos return (ctf_set_errno(fp, ECTF_NOTDYN));
1286 1.4 christos
1287 1.4 christos if (dtd->dtd_ref != 0 || fp->ctf_refcnt > 1)
1288 1.4 christos return (ctf_set_errno(fp, ECTF_REFERENCED));
1289 1.4 christos
1290 1.4 christos ctf_dtd_delete(fp, dtd);
1291 1.1 darran fp->ctf_flags |= LCTF_DIRTY;
1292 1.1 darran return (0);
1293 1.1 darran }
1294 1.1 darran
1295 1.1 darran static int
1296 1.1 darran enumcmp(const char *name, int value, void *arg)
1297 1.1 darran {
1298 1.1 darran ctf_bundle_t *ctb = arg;
1299 1.1 darran int bvalue;
1300 1.1 darran
1301 1.1 darran return (ctf_enum_value(ctb->ctb_file, ctb->ctb_type,
1302 1.1 darran name, &bvalue) == CTF_ERR || value != bvalue);
1303 1.1 darran }
1304 1.1 darran
1305 1.1 darran static int
1306 1.1 darran enumadd(const char *name, int value, void *arg)
1307 1.1 darran {
1308 1.1 darran ctf_bundle_t *ctb = arg;
1309 1.1 darran
1310 1.1 darran return (ctf_add_enumerator(ctb->ctb_file, ctb->ctb_type,
1311 1.1 darran name, value) == CTF_ERR);
1312 1.1 darran }
1313 1.1 darran
1314 1.1 darran static int
1315 1.1 darran membadd(const char *name, ctf_id_t type, ulong_t offset, void *arg)
1316 1.1 darran {
1317 1.1 darran ctf_bundle_t *ctb = arg;
1318 1.1 darran ctf_dmdef_t *dmd;
1319 1.1 darran char *s = NULL;
1320 1.1 darran
1321 1.1 darran if ((dmd = ctf_alloc(sizeof (ctf_dmdef_t))) == NULL)
1322 1.1 darran return (ctf_set_errno(ctb->ctb_file, EAGAIN));
1323 1.1 darran
1324 1.8 christos if (name != NULL && *name != '\0' && (s = ctf_strdup(name)) == NULL) {
1325 1.1 darran ctf_free(dmd, sizeof (ctf_dmdef_t));
1326 1.1 darran return (ctf_set_errno(ctb->ctb_file, EAGAIN));
1327 1.1 darran }
1328 1.1 darran
1329 1.1 darran /*
1330 1.1 darran * For now, dmd_type is copied as the src_fp's type; it is reset to an
1331 1.1 darran * equivalent dst_fp type by a final loop in ctf_add_type(), below.
1332 1.1 darran */
1333 1.1 darran dmd->dmd_name = s;
1334 1.1 darran dmd->dmd_type = type;
1335 1.1 darran dmd->dmd_offset = offset;
1336 1.1 darran dmd->dmd_value = -1;
1337 1.1 darran
1338 1.1 darran ctf_list_append(&ctb->ctb_dtd->dtd_u.dtu_members, dmd);
1339 1.1 darran
1340 1.1 darran if (s != NULL)
1341 1.1 darran ctb->ctb_file->ctf_dtstrlen += strlen(s) + 1;
1342 1.1 darran
1343 1.1 darran ctb->ctb_file->ctf_flags |= LCTF_DIRTY;
1344 1.1 darran return (0);
1345 1.1 darran }
1346 1.1 darran
1347 1.8 christos static long
1348 1.8 christos soucmp(ctf_file_t *src_fp, ctf_id_t src_type, ctf_file_t *dst_fp,
1349 1.8 christos ctf_id_t dst_type)
1350 1.8 christos {
1351 1.8 christos const void *src_tp, *dst_tp;
1352 1.8 christos const char *src_name, *dst_name;
1353 1.8 christos ssize_t src_sz, dst_sz, src_inc, dst_inc;
1354 1.8 christos uint_t dst_kind, dst_vlen, src_kind, src_vlen, n;
1355 1.8 christos
1356 1.8 christos if ((src_type = ctf_type_resolve(src_fp, src_type)) == CTF_ERR)
1357 1.8 christos return (CTF_ERR);
1358 1.8 christos if ((dst_type = ctf_type_resolve(dst_fp, dst_type)) == CTF_ERR)
1359 1.8 christos return (CTF_ERR);
1360 1.8 christos
1361 1.8 christos if ((src_tp = ctf_lookup_by_id(&src_fp, src_type)) == NULL)
1362 1.8 christos return (CTF_ERR);
1363 1.8 christos if ((dst_tp = ctf_lookup_by_id(&dst_fp, dst_type)) == NULL)
1364 1.8 christos return (CTF_ERR);
1365 1.8 christos
1366 1.8 christos ctf_get_ctt_info(src_fp, src_tp, &src_kind, &src_vlen, NULL);
1367 1.8 christos ctf_get_ctt_info(dst_fp, dst_tp, &dst_kind, &dst_vlen, NULL);
1368 1.8 christos
1369 1.8 christos if (src_kind != dst_kind)
1370 1.8 christos return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
1371 1.8 christos if (src_kind != CTF_K_STRUCT && src_kind != CTF_K_UNION)
1372 1.8 christos return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
1373 1.8 christos if (src_vlen != dst_vlen)
1374 1.8 christos return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
1375 1.8 christos
1376 1.8 christos (void) ctf_get_ctt_size(src_fp, src_tp, &src_sz, &src_inc);
1377 1.8 christos (void) ctf_get_ctt_size(dst_fp, dst_tp, &dst_sz, &dst_inc);
1378 1.8 christos if (src_sz != dst_sz)
1379 1.8 christos return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
1380 1.8 christos
1381 1.8 christos const char *src_mp, *dst_mp;
1382 1.8 christos ulong_t src_offset, dst_offset;
1383 1.8 christos
1384 1.8 christos src_mp = (const char *)src_tp + src_inc;
1385 1.8 christos dst_mp = (const char *)dst_tp + dst_inc;
1386 1.8 christos for (n = src_vlen; n != 0;
1387 1.8 christos n--, src_mp += src_inc, dst_mp += dst_inc) {
1388 1.8 christos ctf_get_ctm_info(src_fp, src_mp, src_sz, &src_inc, NULL,
1389 1.8 christos &src_offset, &src_name);
1390 1.8 christos ctf_get_ctm_info(dst_fp, dst_mp, dst_sz, &dst_inc, NULL,
1391 1.8 christos &dst_offset, &dst_name);
1392 1.8 christos
1393 1.8 christos if (src_offset != dst_offset)
1394 1.8 christos return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
1395 1.8 christos if (strcmp(src_name, dst_name) != 0)
1396 1.8 christos return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
1397 1.8 christos }
1398 1.8 christos
1399 1.8 christos return (0);
1400 1.8 christos }
1401 1.8 christos
1402 1.1 darran /*
1403 1.1 darran * The ctf_add_type routine is used to copy a type from a source CTF container
1404 1.1 darran * to a dynamic destination container. This routine operates recursively by
1405 1.1 darran * following the source type's links and embedded member types. If the
1406 1.1 darran * destination container already contains a named type which has the same
1407 1.1 darran * attributes, then we succeed and return this type but no changes occur.
1408 1.1 darran */
1409 1.1 darran ctf_id_t
1410 1.1 darran ctf_add_type(ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
1411 1.1 darran {
1412 1.1 darran ctf_id_t dst_type = CTF_ERR;
1413 1.1 darran uint_t dst_kind = CTF_K_UNKNOWN;
1414 1.1 darran
1415 1.8 christos const void *tp;
1416 1.1 darran const char *name;
1417 1.8 christos uint_t type, kind, flag, vlen;
1418 1.1 darran
1419 1.1 darran ctf_bundle_t src, dst;
1420 1.8 christos ctf_encoding_t src_en, main_en, dst_en;
1421 1.1 darran ctf_arinfo_t src_ar, dst_ar;
1422 1.1 darran
1423 1.1 darran ctf_dtdef_t *dtd;
1424 1.1 darran ctf_funcinfo_t ctc;
1425 1.1 darran ssize_t size;
1426 1.1 darran
1427 1.1 darran ctf_hash_t *hp;
1428 1.1 darran ctf_helem_t *hep;
1429 1.1 darran
1430 1.4 christos if (dst_fp == src_fp)
1431 1.4 christos return (src_type);
1432 1.4 christos
1433 1.1 darran if (!(dst_fp->ctf_flags & LCTF_RDWR))
1434 1.1 darran return (ctf_set_errno(dst_fp, ECTF_RDONLY));
1435 1.1 darran
1436 1.1 darran if ((tp = ctf_lookup_by_id(&src_fp, src_type)) == NULL)
1437 1.1 darran return (ctf_set_errno(dst_fp, ctf_errno(src_fp)));
1438 1.1 darran
1439 1.8 christos name = ctf_type_rname(src_fp, tp);
1440 1.8 christos
1441 1.8 christos ctf_get_ctt_info(src_fp, tp, &kind, &vlen, &flag);
1442 1.1 darran
1443 1.1 darran switch (kind) {
1444 1.1 darran case CTF_K_STRUCT:
1445 1.1 darran hp = &dst_fp->ctf_structs;
1446 1.1 darran break;
1447 1.1 darran case CTF_K_UNION:
1448 1.1 darran hp = &dst_fp->ctf_unions;
1449 1.1 darran break;
1450 1.1 darran case CTF_K_ENUM:
1451 1.1 darran hp = &dst_fp->ctf_enums;
1452 1.1 darran break;
1453 1.1 darran default:
1454 1.1 darran hp = &dst_fp->ctf_names;
1455 1.1 darran break;
1456 1.1 darran }
1457 1.1 darran
1458 1.1 darran /*
1459 1.1 darran * If the source type has a name and is a root type (visible at the
1460 1.1 darran * top-level scope), lookup the name in the destination container and
1461 1.1 darran * verify that it is of the same kind before we do anything else.
1462 1.1 darran */
1463 1.1 darran if ((flag & CTF_ADD_ROOT) && name[0] != '\0' &&
1464 1.1 darran (hep = ctf_hash_lookup(hp, dst_fp, name, strlen(name))) != NULL) {
1465 1.1 darran dst_type = (ctf_id_t)hep->h_type;
1466 1.1 darran dst_kind = ctf_type_kind(dst_fp, dst_type);
1467 1.1 darran }
1468 1.1 darran
1469 1.1 darran /*
1470 1.1 darran * If an identically named dst_type exists, fail with ECTF_CONFLICT
1471 1.1 darran * unless dst_type is a forward declaration and src_type is a struct,
1472 1.1 darran * union, or enum (i.e. the definition of the previous forward decl).
1473 1.1 darran */
1474 1.4 christos if (dst_type != CTF_ERR && dst_kind != kind) {
1475 1.4 christos if (dst_kind != CTF_K_FORWARD || (kind != CTF_K_ENUM &&
1476 1.4 christos kind != CTF_K_STRUCT && kind != CTF_K_UNION))
1477 1.4 christos return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
1478 1.4 christos else
1479 1.4 christos dst_type = CTF_ERR;
1480 1.4 christos }
1481 1.1 darran
1482 1.1 darran /*
1483 1.1 darran * If the non-empty name was not found in the appropriate hash, search
1484 1.1 darran * the list of pending dynamic definitions that are not yet committed.
1485 1.1 darran * If a matching name and kind are found, assume this is the type that
1486 1.1 darran * we are looking for. This is necessary to permit ctf_add_type() to
1487 1.1 darran * operate recursively on entities such as a struct that contains a
1488 1.1 darran * pointer member that refers to the same struct type.
1489 1.4 christos *
1490 1.4 christos * In the case of integer and floating point types, we match using the
1491 1.4 christos * type encoding as well - else we may incorrectly return a bitfield
1492 1.4 christos * type, for instance.
1493 1.1 darran */
1494 1.1 darran if (dst_type == CTF_ERR && name[0] != '\0') {
1495 1.1 darran for (dtd = ctf_list_prev(&dst_fp->ctf_dtdefs); dtd != NULL &&
1496 1.8 christos LCTF_TYPE_TO_INDEX(dst_fp, dtd->dtd_type) >
1497 1.8 christos dst_fp->ctf_dtoldid; dtd = ctf_list_prev(dtd)) {
1498 1.8 christos if (LCTF_INFO_KIND(dst_fp, dtd->dtd_data.ctt_info) !=
1499 1.8 christos kind || dtd->dtd_name == NULL ||
1500 1.4 christos strcmp(dtd->dtd_name, name) != 0)
1501 1.4 christos continue;
1502 1.4 christos if (kind == CTF_K_INTEGER || kind == CTF_K_FLOAT) {
1503 1.4 christos if (ctf_type_encoding(src_fp, src_type,
1504 1.4 christos &src_en) != 0)
1505 1.4 christos continue;
1506 1.8 christos if (memcmp(&src_en, &dtd->dtd_u.dtu_enc,
1507 1.4 christos sizeof (ctf_encoding_t)) != 0)
1508 1.4 christos continue;
1509 1.4 christos }
1510 1.4 christos return (dtd->dtd_type);
1511 1.1 darran }
1512 1.1 darran }
1513 1.1 darran
1514 1.1 darran src.ctb_file = src_fp;
1515 1.1 darran src.ctb_type = src_type;
1516 1.1 darran src.ctb_dtd = NULL;
1517 1.1 darran
1518 1.1 darran dst.ctb_file = dst_fp;
1519 1.1 darran dst.ctb_type = dst_type;
1520 1.1 darran dst.ctb_dtd = NULL;
1521 1.1 darran
1522 1.1 darran /*
1523 1.1 darran * Now perform kind-specific processing. If dst_type is CTF_ERR, then
1524 1.1 darran * we add a new type with the same properties as src_type to dst_fp.
1525 1.1 darran * If dst_type is not CTF_ERR, then we verify that dst_type has the
1526 1.1 darran * same attributes as src_type. We recurse for embedded references.
1527 1.1 darran */
1528 1.1 darran switch (kind) {
1529 1.1 darran case CTF_K_INTEGER:
1530 1.1 darran case CTF_K_FLOAT:
1531 1.1 darran if (ctf_type_encoding(src_fp, src_type, &src_en) != 0)
1532 1.1 darran return (ctf_set_errno(dst_fp, ctf_errno(src_fp)));
1533 1.1 darran
1534 1.8 christos /*
1535 1.8 christos * This could be a bitfield, and the CTF library assumes
1536 1.8 christos * intrinsics will appear before bitfields. Therefore,
1537 1.8 christos * try to copy over the intrinsic prior to copying the
1538 1.8 christos * bitfield.
1539 1.8 christos */
1540 1.8 christos if (dst_type == CTF_ERR && name[0] != '\0' &&
1541 1.8 christos (hep = ctf_hash_lookup(&src_fp->ctf_names, src_fp, name,
1542 1.8 christos strlen(name))) != NULL &&
1543 1.8 christos src_type != (ctf_id_t)hep->h_type) {
1544 1.8 christos if (ctf_type_encoding(src_fp, (ctf_id_t)hep->h_type,
1545 1.8 christos &main_en) != 0) {
1546 1.8 christos return (ctf_set_errno(dst_fp,
1547 1.8 christos ctf_errno(src_fp)));
1548 1.8 christos }
1549 1.8 christos if (memcmp(&src_en, &main_en, sizeof (ctf_encoding_t)) &&
1550 1.8 christos ctf_add_type(dst_fp, src_fp,
1551 1.8 christos (ctf_id_t)hep->h_type) == CTF_ERR)
1552 1.8 christos return (CTF_ERR); /* errno is set for us */
1553 1.8 christos }
1554 1.8 christos
1555 1.1 darran if (dst_type != CTF_ERR) {
1556 1.1 darran if (ctf_type_encoding(dst_fp, dst_type, &dst_en) != 0)
1557 1.1 darran return (CTF_ERR); /* errno is set for us */
1558 1.1 darran
1559 1.8 christos if (memcmp(&src_en, &dst_en, sizeof (ctf_encoding_t)))
1560 1.1 darran return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
1561 1.1 darran
1562 1.1 darran } else if (kind == CTF_K_INTEGER) {
1563 1.1 darran dst_type = ctf_add_integer(dst_fp, flag, name, &src_en);
1564 1.1 darran } else
1565 1.1 darran dst_type = ctf_add_float(dst_fp, flag, name, &src_en);
1566 1.1 darran break;
1567 1.1 darran
1568 1.1 darran case CTF_K_POINTER:
1569 1.1 darran case CTF_K_VOLATILE:
1570 1.1 darran case CTF_K_CONST:
1571 1.1 darran case CTF_K_RESTRICT:
1572 1.1 darran src_type = ctf_type_reference(src_fp, src_type);
1573 1.1 darran src_type = ctf_add_type(dst_fp, src_fp, src_type);
1574 1.1 darran
1575 1.1 darran if (src_type == CTF_ERR)
1576 1.1 darran return (CTF_ERR); /* errno is set for us */
1577 1.1 darran
1578 1.1 darran dst_type = ctf_add_reftype(dst_fp, flag, src_type, kind);
1579 1.1 darran break;
1580 1.1 darran
1581 1.1 darran case CTF_K_ARRAY:
1582 1.1 darran if (ctf_array_info(src_fp, src_type, &src_ar) == CTF_ERR)
1583 1.1 darran return (ctf_set_errno(dst_fp, ctf_errno(src_fp)));
1584 1.1 darran
1585 1.1 darran src_ar.ctr_contents =
1586 1.1 darran ctf_add_type(dst_fp, src_fp, src_ar.ctr_contents);
1587 1.1 darran src_ar.ctr_index =
1588 1.1 darran ctf_add_type(dst_fp, src_fp, src_ar.ctr_index);
1589 1.1 darran src_ar.ctr_nelems = src_ar.ctr_nelems;
1590 1.1 darran
1591 1.1 darran if (src_ar.ctr_contents == CTF_ERR ||
1592 1.1 darran src_ar.ctr_index == CTF_ERR)
1593 1.1 darran return (CTF_ERR); /* errno is set for us */
1594 1.1 darran
1595 1.1 darran if (dst_type != CTF_ERR) {
1596 1.1 darran if (ctf_array_info(dst_fp, dst_type, &dst_ar) != 0)
1597 1.1 darran return (CTF_ERR); /* errno is set for us */
1598 1.1 darran
1599 1.8 christos if (memcmp(&src_ar, &dst_ar, sizeof (ctf_arinfo_t)))
1600 1.1 darran return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
1601 1.1 darran } else
1602 1.1 darran dst_type = ctf_add_array(dst_fp, flag, &src_ar);
1603 1.1 darran break;
1604 1.1 darran
1605 1.1 darran case CTF_K_FUNCTION:
1606 1.8 christos ctf_get_ctt_index(src_fp, tp, NULL, &type, NULL);
1607 1.8 christos ctc.ctc_return = ctf_add_type(dst_fp, src_fp, type);
1608 1.1 darran ctc.ctc_argc = 0;
1609 1.1 darran ctc.ctc_flags = 0;
1610 1.1 darran
1611 1.1 darran if (ctc.ctc_return == CTF_ERR)
1612 1.1 darran return (CTF_ERR); /* errno is set for us */
1613 1.1 darran
1614 1.1 darran dst_type = ctf_add_function(dst_fp, flag, &ctc, NULL);
1615 1.1 darran break;
1616 1.1 darran
1617 1.1 darran case CTF_K_STRUCT:
1618 1.1 darran case CTF_K_UNION: {
1619 1.1 darran ctf_dmdef_t *dmd;
1620 1.1 darran int errs = 0;
1621 1.1 darran
1622 1.1 darran if (dst_type != CTF_ERR && dst_kind != CTF_K_FORWARD) {
1623 1.8 christos /*
1624 1.8 christos * Compare the sizes and fields of the two types.
1625 1.8 christos * The field comparisons only check the names and
1626 1.8 christos * offsets, so this is not perfect but is good enough
1627 1.8 christos * for scenarios that we care about.
1628 1.8 christos */
1629 1.8 christos if (soucmp(src_fp, src_type, dst_fp, dst_type) != 0)
1630 1.8 christos return (CTF_ERR); /* errno is set for us */
1631 1.1 darran break;
1632 1.1 darran }
1633 1.1 darran
1634 1.1 darran /*
1635 1.1 darran * Unlike the other cases, copying structs and unions is done
1636 1.1 darran * manually so as to avoid repeated lookups in ctf_add_member
1637 1.1 darran * and to ensure the exact same member offsets as in src_type.
1638 1.1 darran */
1639 1.1 darran dst_type = ctf_add_generic(dst_fp, flag, name, &dtd);
1640 1.1 darran if (dst_type == CTF_ERR)
1641 1.1 darran return (CTF_ERR); /* errno is set for us */
1642 1.1 darran
1643 1.1 darran dst.ctb_type = dst_type;
1644 1.1 darran dst.ctb_dtd = dtd;
1645 1.1 darran
1646 1.1 darran if (ctf_member_iter(src_fp, src_type, membadd, &dst) != 0)
1647 1.1 darran errs++; /* increment errs and fail at bottom of case */
1648 1.1 darran
1649 1.8 christos if ((size = ctf_type_size(src_fp, src_type)) >
1650 1.8 christos LCTF_MAX_SIZE(src_fp)) {
1651 1.8 christos dtd->dtd_data.ctt_size = LCTF_LSIZE_SENT(dst_fp);
1652 1.1 darran dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(size);
1653 1.1 darran dtd->dtd_data.ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(size);
1654 1.1 darran } else
1655 1.8 christos dtd->dtd_data.ctt_size = size;
1656 1.1 darran
1657 1.8 christos dtd->dtd_data.ctt_info = LCTF_TYPE_INFO(dst_fp, kind, flag,
1658 1.8 christos vlen);
1659 1.1 darran
1660 1.1 darran /*
1661 1.1 darran * Make a final pass through the members changing each dmd_type
1662 1.1 darran * (a src_fp type) to an equivalent type in dst_fp. We pass
1663 1.1 darran * through all members, leaving any that fail set to CTF_ERR.
1664 1.1 darran */
1665 1.1 darran for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
1666 1.1 darran dmd != NULL; dmd = ctf_list_next(dmd)) {
1667 1.1 darran if ((dmd->dmd_type = ctf_add_type(dst_fp, src_fp,
1668 1.1 darran dmd->dmd_type)) == CTF_ERR)
1669 1.1 darran errs++;
1670 1.1 darran }
1671 1.1 darran
1672 1.1 darran if (errs)
1673 1.1 darran return (CTF_ERR); /* errno is set for us */
1674 1.4 christos
1675 1.4 christos /*
1676 1.4 christos * Now that we know that we can't fail, we go through and bump
1677 1.4 christos * all the reference counts on the member types.
1678 1.4 christos */
1679 1.4 christos for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
1680 1.4 christos dmd != NULL; dmd = ctf_list_next(dmd))
1681 1.4 christos ctf_ref_inc(dst_fp, dmd->dmd_type);
1682 1.1 darran break;
1683 1.1 darran }
1684 1.1 darran
1685 1.1 darran case CTF_K_ENUM:
1686 1.1 darran if (dst_type != CTF_ERR && dst_kind != CTF_K_FORWARD) {
1687 1.1 darran if (ctf_enum_iter(src_fp, src_type, enumcmp, &dst) ||
1688 1.1 darran ctf_enum_iter(dst_fp, dst_type, enumcmp, &src))
1689 1.1 darran return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
1690 1.1 darran } else {
1691 1.1 darran dst_type = ctf_add_enum(dst_fp, flag, name);
1692 1.1 darran if ((dst.ctb_type = dst_type) == CTF_ERR ||
1693 1.1 darran ctf_enum_iter(src_fp, src_type, enumadd, &dst))
1694 1.1 darran return (CTF_ERR); /* errno is set for us */
1695 1.1 darran }
1696 1.1 darran break;
1697 1.1 darran
1698 1.1 darran case CTF_K_FORWARD:
1699 1.1 darran if (dst_type == CTF_ERR) {
1700 1.1 darran dst_type = ctf_add_forward(dst_fp,
1701 1.1 darran flag, name, CTF_K_STRUCT); /* assume STRUCT */
1702 1.1 darran }
1703 1.1 darran break;
1704 1.1 darran
1705 1.1 darran case CTF_K_TYPEDEF:
1706 1.1 darran src_type = ctf_type_reference(src_fp, src_type);
1707 1.1 darran src_type = ctf_add_type(dst_fp, src_fp, src_type);
1708 1.1 darran
1709 1.1 darran if (src_type == CTF_ERR)
1710 1.1 darran return (CTF_ERR); /* errno is set for us */
1711 1.1 darran
1712 1.1 darran /*
1713 1.1 darran * If dst_type is not CTF_ERR at this point, we should check if
1714 1.1 darran * ctf_type_reference(dst_fp, dst_type) != src_type and if so
1715 1.1 darran * fail with ECTF_CONFLICT. However, this causes problems with
1716 1.1 darran * <sys/types.h> typedefs that vary based on things like if
1717 1.1 darran * _ILP32x then pid_t is int otherwise long. We therefore omit
1718 1.1 darran * this check and assume that if the identically named typedef
1719 1.1 darran * already exists in dst_fp, it is correct or equivalent.
1720 1.1 darran */
1721 1.1 darran if (dst_type == CTF_ERR) {
1722 1.1 darran dst_type = ctf_add_typedef(dst_fp, flag,
1723 1.1 darran name, src_type);
1724 1.1 darran }
1725 1.1 darran break;
1726 1.1 darran
1727 1.1 darran default:
1728 1.1 darran return (ctf_set_errno(dst_fp, ECTF_CORRUPT));
1729 1.1 darran }
1730 1.1 darran
1731 1.1 darran return (dst_type);
1732 1.1 darran }
1733