1178525Sjb/*
2178525Sjb * CDDL HEADER START
3178525Sjb *
4178525Sjb * The contents of this file are subject to the terms of the
5178525Sjb * Common Development and Distribution License, Version 1.0 only
6178525Sjb * (the "License").  You may not use this file except in compliance
7178525Sjb * with the License.
8178525Sjb *
9178525Sjb * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10178525Sjb * or http://www.opensolaris.org/os/licensing.
11178525Sjb * See the License for the specific language governing permissions
12178525Sjb * and limitations under the License.
13178525Sjb *
14178525Sjb * When distributing Covered Code, include this CDDL HEADER in each
15178525Sjb * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16178525Sjb * If applicable, add the following below this CDDL HEADER, with the
17178525Sjb * fields enclosed by brackets "[]" replaced with your own identifying
18178525Sjb * information: Portions Copyright [yyyy] [name of copyright owner]
19178525Sjb *
20178525Sjb * CDDL HEADER END
21178525Sjb */
22178525Sjb
23178525Sjb/*
24178525Sjb * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
25178525Sjb * Use is subject to license terms.
26178525Sjb */
27254744Sdelphij/*
28268578Srpaulo * Copyright (c) 2013, Joyent, Inc.  All rights reserved.
29254744Sdelphij */
30178525Sjb
31178525Sjb#include <ctf_impl.h>
32178525Sjb#include <sys/mman.h>
33178525Sjb#include <sys/zmod.h>
34178525Sjb
35178525Sjbstatic const ctf_dmodel_t _libctf_models[] = {
36178525Sjb	{ "ILP32", CTF_MODEL_ILP32, 4, 1, 2, 4, 4 },
37178525Sjb	{ "LP64", CTF_MODEL_LP64, 8, 1, 2, 4, 8 },
38178525Sjb	{ NULL, 0, 0, 0, 0, 0, 0 }
39178525Sjb};
40178525Sjb
41178525Sjbconst char _CTF_SECTION[] = ".SUNW_ctf";
42178525Sjbconst char _CTF_NULLSTR[] = "";
43178525Sjb
44178525Sjbint _libctf_version = CTF_VERSION;	/* library client version */
45178525Sjbint _libctf_debug = 0;			/* debugging messages enabled */
46178525Sjb
47178525Sjbstatic ushort_t
48178525Sjbget_kind_v1(ushort_t info)
49178525Sjb{
50178525Sjb	return (CTF_INFO_KIND_V1(info));
51178525Sjb}
52178525Sjb
53178525Sjbstatic ushort_t
54178525Sjbget_kind_v2(ushort_t info)
55178525Sjb{
56178525Sjb	return (CTF_INFO_KIND(info));
57178525Sjb}
58178525Sjb
59178525Sjbstatic ushort_t
60178525Sjbget_root_v1(ushort_t info)
61178525Sjb{
62178525Sjb	return (CTF_INFO_ISROOT_V1(info));
63178525Sjb}
64178525Sjb
65178525Sjbstatic ushort_t
66178525Sjbget_root_v2(ushort_t info)
67178525Sjb{
68178525Sjb	return (CTF_INFO_ISROOT(info));
69178525Sjb}
70178525Sjb
71178525Sjbstatic ushort_t
72178525Sjbget_vlen_v1(ushort_t info)
73178525Sjb{
74178525Sjb	return (CTF_INFO_VLEN_V1(info));
75178525Sjb}
76178525Sjb
77178525Sjbstatic ushort_t
78178525Sjbget_vlen_v2(ushort_t info)
79178525Sjb{
80178525Sjb	return (CTF_INFO_VLEN(info));
81178525Sjb}
82178525Sjb
83178525Sjbstatic const ctf_fileops_t ctf_fileops[] = {
84178525Sjb	{ NULL, NULL },
85178525Sjb	{ get_kind_v1, get_root_v1, get_vlen_v1 },
86178525Sjb	{ get_kind_v2, get_root_v2, get_vlen_v2 },
87178525Sjb};
88178525Sjb
89178525Sjb/*
90178525Sjb * Convert a 32-bit ELF symbol into GElf (Elf64) and return a pointer to it.
91178525Sjb */
92178525Sjbstatic Elf64_Sym *
93178525Sjbsym_to_gelf(const Elf32_Sym *src, Elf64_Sym *dst)
94178525Sjb{
95178525Sjb	dst->st_name = src->st_name;
96178525Sjb	dst->st_value = src->st_value;
97178525Sjb	dst->st_size = src->st_size;
98178525Sjb	dst->st_info = src->st_info;
99178525Sjb	dst->st_other = src->st_other;
100178525Sjb	dst->st_shndx = src->st_shndx;
101178525Sjb
102178525Sjb	return (dst);
103178525Sjb}
104178525Sjb
105178525Sjb/*
106178525Sjb * Initialize the symtab translation table by filling each entry with the
107178525Sjb * offset of the CTF type or function data corresponding to each STT_FUNC or
108178525Sjb * STT_OBJECT entry in the symbol table.
109178525Sjb */
110178525Sjbstatic int
111178525Sjbinit_symtab(ctf_file_t *fp, const ctf_header_t *hp,
112178525Sjb    const ctf_sect_t *sp, const ctf_sect_t *strp)
113178525Sjb{
114178525Sjb	const uchar_t *symp = sp->cts_data;
115178525Sjb	uint_t *xp = fp->ctf_sxlate;
116178525Sjb	uint_t *xend = xp + fp->ctf_nsyms;
117178525Sjb
118178525Sjb	uint_t objtoff = hp->cth_objtoff;
119178525Sjb	uint_t funcoff = hp->cth_funcoff;
120178525Sjb
121178525Sjb	ushort_t info, vlen;
122178525Sjb	Elf64_Sym sym, *gsp;
123178525Sjb	const char *name;
124178525Sjb
125178525Sjb	/*
126178525Sjb	 * The CTF data object and function type sections are ordered to match
127178525Sjb	 * the relative order of the respective symbol types in the symtab.
128178525Sjb	 * If no type information is available for a symbol table entry, a
129178525Sjb	 * pad is inserted in the CTF section.  As a further optimization,
130178525Sjb	 * anonymous or undefined symbols are omitted from the CTF data.
131178525Sjb	 */
132178525Sjb	for (; xp < xend; xp++, symp += sp->cts_entsize) {
133178525Sjb		if (sp->cts_entsize == sizeof (Elf32_Sym))
134178525Sjb			gsp = sym_to_gelf((Elf32_Sym *)(uintptr_t)symp, &sym);
135178525Sjb		else
136178525Sjb			gsp = (Elf64_Sym *)(uintptr_t)symp;
137178525Sjb
138178525Sjb		if (gsp->st_name < strp->cts_size)
139178525Sjb			name = (const char *)strp->cts_data + gsp->st_name;
140178525Sjb		else
141178525Sjb			name = _CTF_NULLSTR;
142178525Sjb
143178525Sjb		if (gsp->st_name == 0 || gsp->st_shndx == SHN_UNDEF ||
144178525Sjb		    strcmp(name, "_START_") == 0 ||
145178525Sjb		    strcmp(name, "_END_") == 0) {
146178525Sjb			*xp = -1u;
147178525Sjb			continue;
148178525Sjb		}
149178525Sjb
150178525Sjb		switch (ELF64_ST_TYPE(gsp->st_info)) {
151178525Sjb		case STT_OBJECT:
152178525Sjb			if (objtoff >= hp->cth_funcoff ||
153178525Sjb			    (gsp->st_shndx == SHN_ABS && gsp->st_value == 0)) {
154178525Sjb				*xp = -1u;
155178525Sjb				break;
156178525Sjb			}
157178525Sjb
158178525Sjb			*xp = objtoff;
159178525Sjb			objtoff += sizeof (ushort_t);
160178525Sjb			break;
161178525Sjb
162178525Sjb		case STT_FUNC:
163178525Sjb			if (funcoff >= hp->cth_typeoff) {
164178525Sjb				*xp = -1u;
165178525Sjb				break;
166178525Sjb			}
167178525Sjb
168178525Sjb			*xp = funcoff;
169178525Sjb
170178525Sjb			info = *(ushort_t *)((uintptr_t)fp->ctf_buf + funcoff);
171178525Sjb			vlen = LCTF_INFO_VLEN(fp, info);
172178525Sjb
173178525Sjb			/*
174178525Sjb			 * If we encounter a zero pad at the end, just skip it.
175178525Sjb			 * Otherwise skip over the function and its return type
176178525Sjb			 * (+2) and the argument list (vlen).
177178525Sjb			 */
178178525Sjb			if (LCTF_INFO_KIND(fp, info) == CTF_K_UNKNOWN &&
179178525Sjb			    vlen == 0)
180178525Sjb				funcoff += sizeof (ushort_t); /* skip pad */
181178525Sjb			else
182178525Sjb				funcoff += sizeof (ushort_t) * (vlen + 2);
183178525Sjb			break;
184178525Sjb
185178525Sjb		default:
186178525Sjb			*xp = -1u;
187178525Sjb			break;
188178525Sjb		}
189178525Sjb	}
190178525Sjb
191178525Sjb	ctf_dprintf("loaded %lu symtab entries\n", fp->ctf_nsyms);
192178525Sjb	return (0);
193178525Sjb}
194178525Sjb
195178525Sjb/*
196178525Sjb * Initialize the type ID translation table with the byte offset of each type,
197178525Sjb * and initialize the hash tables of each named type.
198178525Sjb */
199178525Sjbstatic int
200178525Sjbinit_types(ctf_file_t *fp, const ctf_header_t *cth)
201178525Sjb{
202178525Sjb	/* LINTED - pointer alignment */
203178525Sjb	const ctf_type_t *tbuf = (ctf_type_t *)(fp->ctf_buf + cth->cth_typeoff);
204178525Sjb	/* LINTED - pointer alignment */
205178525Sjb	const ctf_type_t *tend = (ctf_type_t *)(fp->ctf_buf + cth->cth_stroff);
206178525Sjb
207178525Sjb	ulong_t pop[CTF_K_MAX + 1] = { 0 };
208178525Sjb	const ctf_type_t *tp;
209178525Sjb	ctf_hash_t *hp;
210178525Sjb	ushort_t id, dst;
211178525Sjb	uint_t *xp;
212178525Sjb
213178525Sjb	/*
214178525Sjb	 * We initially determine whether the container is a child or a parent
215178525Sjb	 * based on the value of cth_parname.  To support containers that pre-
216178525Sjb	 * date cth_parname, we also scan the types themselves for references
217178525Sjb	 * to values in the range reserved for child types in our first pass.
218178525Sjb	 */
219178525Sjb	int child = cth->cth_parname != 0;
220178525Sjb	int nlstructs = 0, nlunions = 0;
221178525Sjb	int err;
222178525Sjb
223178525Sjb	/*
224178525Sjb	 * We make two passes through the entire type section.  In this first
225178525Sjb	 * pass, we count the number of each type and the total number of types.
226178525Sjb	 */
227178525Sjb	for (tp = tbuf; tp < tend; fp->ctf_typemax++) {
228178525Sjb		ushort_t kind = LCTF_INFO_KIND(fp, tp->ctt_info);
229178525Sjb		ulong_t vlen = LCTF_INFO_VLEN(fp, tp->ctt_info);
230178525Sjb		ssize_t size, increment;
231178525Sjb
232178525Sjb		size_t vbytes;
233178525Sjb		uint_t n;
234178525Sjb
235178525Sjb		(void) ctf_get_ctt_size(fp, tp, &size, &increment);
236178525Sjb
237178525Sjb		switch (kind) {
238178525Sjb		case CTF_K_INTEGER:
239178525Sjb		case CTF_K_FLOAT:
240178525Sjb			vbytes = sizeof (uint_t);
241178525Sjb			break;
242178525Sjb		case CTF_K_ARRAY:
243178525Sjb			vbytes = sizeof (ctf_array_t);
244178525Sjb			break;
245178525Sjb		case CTF_K_FUNCTION:
246178525Sjb			vbytes = sizeof (ushort_t) * (vlen + (vlen & 1));
247178525Sjb			break;
248178525Sjb		case CTF_K_STRUCT:
249178525Sjb		case CTF_K_UNION:
250178525Sjb			if (fp->ctf_version == CTF_VERSION_1 ||
251178525Sjb			    size < CTF_LSTRUCT_THRESH) {
252178525Sjb				ctf_member_t *mp = (ctf_member_t *)
253178525Sjb				    ((uintptr_t)tp + increment);
254178525Sjb
255178525Sjb				vbytes = sizeof (ctf_member_t) * vlen;
256178525Sjb				for (n = vlen; n != 0; n--, mp++)
257178525Sjb					child |= CTF_TYPE_ISCHILD(mp->ctm_type);
258178525Sjb			} else {
259178525Sjb				ctf_lmember_t *lmp = (ctf_lmember_t *)
260178525Sjb				    ((uintptr_t)tp + increment);
261178525Sjb
262178525Sjb				vbytes = sizeof (ctf_lmember_t) * vlen;
263178525Sjb				for (n = vlen; n != 0; n--, lmp++)
264178525Sjb					child |=
265178525Sjb					    CTF_TYPE_ISCHILD(lmp->ctlm_type);
266178525Sjb			}
267178525Sjb			break;
268178525Sjb		case CTF_K_ENUM:
269178525Sjb			vbytes = sizeof (ctf_enum_t) * vlen;
270178525Sjb			break;
271178525Sjb		case CTF_K_FORWARD:
272178525Sjb			/*
273178525Sjb			 * For forward declarations, ctt_type is the CTF_K_*
274178525Sjb			 * kind for the tag, so bump that population count too.
275178525Sjb			 * If ctt_type is unknown, treat the tag as a struct.
276178525Sjb			 */
277178525Sjb			if (tp->ctt_type == CTF_K_UNKNOWN ||
278178525Sjb			    tp->ctt_type >= CTF_K_MAX)
279178525Sjb				pop[CTF_K_STRUCT]++;
280178525Sjb			else
281178525Sjb				pop[tp->ctt_type]++;
282178525Sjb			/*FALLTHRU*/
283178525Sjb		case CTF_K_UNKNOWN:
284178525Sjb			vbytes = 0;
285178525Sjb			break;
286178525Sjb		case CTF_K_POINTER:
287178525Sjb		case CTF_K_TYPEDEF:
288178525Sjb		case CTF_K_VOLATILE:
289178525Sjb		case CTF_K_CONST:
290178525Sjb		case CTF_K_RESTRICT:
291178525Sjb			child |= CTF_TYPE_ISCHILD(tp->ctt_type);
292178525Sjb			vbytes = 0;
293178525Sjb			break;
294178525Sjb		default:
295178525Sjb			ctf_dprintf("detected invalid CTF kind -- %u\n", kind);
296178525Sjb			return (ECTF_CORRUPT);
297178525Sjb		}
298178525Sjb		tp = (ctf_type_t *)((uintptr_t)tp + increment + vbytes);
299178525Sjb		pop[kind]++;
300178525Sjb	}
301178525Sjb
302178525Sjb	/*
303178525Sjb	 * If we detected a reference to a child type ID, then we know this
304178525Sjb	 * container is a child and may have a parent's types imported later.
305178525Sjb	 */
306178525Sjb	if (child) {
307178525Sjb		ctf_dprintf("CTF container %p is a child\n", (void *)fp);
308178525Sjb		fp->ctf_flags |= LCTF_CHILD;
309178525Sjb	} else
310178525Sjb		ctf_dprintf("CTF container %p is a parent\n", (void *)fp);
311178525Sjb
312178525Sjb	/*
313178525Sjb	 * Now that we've counted up the number of each type, we can allocate
314178525Sjb	 * the hash tables, type translation table, and pointer table.
315178525Sjb	 */
316178525Sjb	if ((err = ctf_hash_create(&fp->ctf_structs, pop[CTF_K_STRUCT])) != 0)
317178525Sjb		return (err);
318178525Sjb
319178525Sjb	if ((err = ctf_hash_create(&fp->ctf_unions, pop[CTF_K_UNION])) != 0)
320178525Sjb		return (err);
321178525Sjb
322178525Sjb	if ((err = ctf_hash_create(&fp->ctf_enums, pop[CTF_K_ENUM])) != 0)
323178525Sjb		return (err);
324178525Sjb
325178525Sjb	if ((err = ctf_hash_create(&fp->ctf_names,
326178525Sjb	    pop[CTF_K_INTEGER] + pop[CTF_K_FLOAT] + pop[CTF_K_FUNCTION] +
327178525Sjb	    pop[CTF_K_TYPEDEF] + pop[CTF_K_POINTER] + pop[CTF_K_VOLATILE] +
328178525Sjb	    pop[CTF_K_CONST] + pop[CTF_K_RESTRICT])) != 0)
329178525Sjb		return (err);
330178525Sjb
331178525Sjb	fp->ctf_txlate = ctf_alloc(sizeof (uint_t) * (fp->ctf_typemax + 1));
332178525Sjb	fp->ctf_ptrtab = ctf_alloc(sizeof (ushort_t) * (fp->ctf_typemax + 1));
333178525Sjb
334178525Sjb	if (fp->ctf_txlate == NULL || fp->ctf_ptrtab == NULL)
335178525Sjb		return (EAGAIN); /* memory allocation failed */
336178525Sjb
337178525Sjb	xp = fp->ctf_txlate;
338178525Sjb	*xp++ = 0; /* type id 0 is used as a sentinel value */
339178525Sjb
340178525Sjb	bzero(fp->ctf_txlate, sizeof (uint_t) * (fp->ctf_typemax + 1));
341178525Sjb	bzero(fp->ctf_ptrtab, sizeof (ushort_t) * (fp->ctf_typemax + 1));
342178525Sjb
343178525Sjb	/*
344178525Sjb	 * In the second pass through the types, we fill in each entry of the
345178525Sjb	 * type and pointer tables and add names to the appropriate hashes.
346178525Sjb	 */
347178525Sjb	for (id = 1, tp = tbuf; tp < tend; xp++, id++) {
348178525Sjb		ushort_t kind = LCTF_INFO_KIND(fp, tp->ctt_info);
349178525Sjb		ulong_t vlen = LCTF_INFO_VLEN(fp, tp->ctt_info);
350178525Sjb		ssize_t size, increment;
351178525Sjb
352178525Sjb		const char *name;
353178525Sjb		size_t vbytes;
354178525Sjb		ctf_helem_t *hep;
355178525Sjb		ctf_encoding_t cte;
356178525Sjb
357178525Sjb		(void) ctf_get_ctt_size(fp, tp, &size, &increment);
358178525Sjb		name = ctf_strptr(fp, tp->ctt_name);
359178525Sjb
360178525Sjb		switch (kind) {
361178525Sjb		case CTF_K_INTEGER:
362178525Sjb		case CTF_K_FLOAT:
363178525Sjb			/*
364178525Sjb			 * Only insert a new integer base type definition if
365178525Sjb			 * this type name has not been defined yet.  We re-use
366178525Sjb			 * the names with different encodings for bit-fields.
367178525Sjb			 */
368178525Sjb			if ((hep = ctf_hash_lookup(&fp->ctf_names, fp,
369178525Sjb			    name, strlen(name))) == NULL) {
370178525Sjb				err = ctf_hash_insert(&fp->ctf_names, fp,
371178525Sjb				    CTF_INDEX_TO_TYPE(id, child), tp->ctt_name);
372178525Sjb				if (err != 0 && err != ECTF_STRTAB)
373178525Sjb					return (err);
374178525Sjb			} else if (ctf_type_encoding(fp, hep->h_type,
375178525Sjb			    &cte) == 0 && cte.cte_bits == 0) {
376178525Sjb				/*
377178525Sjb				 * Work-around SOS8 stabs bug: replace existing
378178525Sjb				 * intrinsic w/ same name if it was zero bits.
379178525Sjb				 */
380178525Sjb				hep->h_type = CTF_INDEX_TO_TYPE(id, child);
381178525Sjb			}
382178525Sjb			vbytes = sizeof (uint_t);
383178525Sjb			break;
384178525Sjb
385178525Sjb		case CTF_K_ARRAY:
386178525Sjb			vbytes = sizeof (ctf_array_t);
387178525Sjb			break;
388178525Sjb
389178525Sjb		case CTF_K_FUNCTION:
390178525Sjb			err = ctf_hash_insert(&fp->ctf_names, fp,
391178525Sjb			    CTF_INDEX_TO_TYPE(id, child), tp->ctt_name);
392178525Sjb			if (err != 0 && err != ECTF_STRTAB)
393178525Sjb				return (err);
394178525Sjb			vbytes = sizeof (ushort_t) * (vlen + (vlen & 1));
395178525Sjb			break;
396178525Sjb
397178525Sjb		case CTF_K_STRUCT:
398178525Sjb			err = ctf_hash_define(&fp->ctf_structs, fp,
399178525Sjb			    CTF_INDEX_TO_TYPE(id, child), tp->ctt_name);
400178525Sjb
401178525Sjb			if (err != 0 && err != ECTF_STRTAB)
402178525Sjb				return (err);
403178525Sjb
404178525Sjb			if (fp->ctf_version == CTF_VERSION_1 ||
405178525Sjb			    size < CTF_LSTRUCT_THRESH)
406178525Sjb				vbytes = sizeof (ctf_member_t) * vlen;
407178525Sjb			else {
408178525Sjb				vbytes = sizeof (ctf_lmember_t) * vlen;
409178525Sjb				nlstructs++;
410178525Sjb			}
411178525Sjb			break;
412178525Sjb
413178525Sjb		case CTF_K_UNION:
414178525Sjb			err = ctf_hash_define(&fp->ctf_unions, fp,
415178525Sjb			    CTF_INDEX_TO_TYPE(id, child), tp->ctt_name);
416178525Sjb
417178525Sjb			if (err != 0 && err != ECTF_STRTAB)
418178525Sjb				return (err);
419178525Sjb
420178525Sjb			if (fp->ctf_version == CTF_VERSION_1 ||
421178525Sjb			    size < CTF_LSTRUCT_THRESH)
422178525Sjb				vbytes = sizeof (ctf_member_t) * vlen;
423178525Sjb			else {
424178525Sjb				vbytes = sizeof (ctf_lmember_t) * vlen;
425178525Sjb				nlunions++;
426178525Sjb			}
427178525Sjb			break;
428178525Sjb
429178525Sjb		case CTF_K_ENUM:
430178525Sjb			err = ctf_hash_define(&fp->ctf_enums, fp,
431178525Sjb			    CTF_INDEX_TO_TYPE(id, child), tp->ctt_name);
432178525Sjb
433178525Sjb			if (err != 0 && err != ECTF_STRTAB)
434178525Sjb				return (err);
435178525Sjb
436178525Sjb			vbytes = sizeof (ctf_enum_t) * vlen;
437178525Sjb			break;
438178525Sjb
439178525Sjb		case CTF_K_TYPEDEF:
440178525Sjb			err = ctf_hash_insert(&fp->ctf_names, fp,
441178525Sjb			    CTF_INDEX_TO_TYPE(id, child), tp->ctt_name);
442178525Sjb			if (err != 0 && err != ECTF_STRTAB)
443178525Sjb				return (err);
444178525Sjb			vbytes = 0;
445178525Sjb			break;
446178525Sjb
447178525Sjb		case CTF_K_FORWARD:
448178525Sjb			/*
449178525Sjb			 * Only insert forward tags into the given hash if the
450178525Sjb			 * type or tag name is not already present.
451178525Sjb			 */
452178525Sjb			switch (tp->ctt_type) {
453178525Sjb			case CTF_K_STRUCT:
454178525Sjb				hp = &fp->ctf_structs;
455178525Sjb				break;
456178525Sjb			case CTF_K_UNION:
457178525Sjb				hp = &fp->ctf_unions;
458178525Sjb				break;
459178525Sjb			case CTF_K_ENUM:
460178525Sjb				hp = &fp->ctf_enums;
461178525Sjb				break;
462178525Sjb			default:
463178525Sjb				hp = &fp->ctf_structs;
464178525Sjb			}
465178525Sjb
466178525Sjb			if (ctf_hash_lookup(hp, fp,
467178525Sjb			    name, strlen(name)) == NULL) {
468178525Sjb				err = ctf_hash_insert(hp, fp,
469178525Sjb				    CTF_INDEX_TO_TYPE(id, child), tp->ctt_name);
470178525Sjb				if (err != 0 && err != ECTF_STRTAB)
471178525Sjb					return (err);
472178525Sjb			}
473178525Sjb			vbytes = 0;
474178525Sjb			break;
475178525Sjb
476178525Sjb		case CTF_K_POINTER:
477178525Sjb			/*
478178525Sjb			 * If the type referenced by the pointer is in this CTF
479178525Sjb			 * container, then store the index of the pointer type
480178525Sjb			 * in fp->ctf_ptrtab[ index of referenced type ].
481178525Sjb			 */
482178525Sjb			if (CTF_TYPE_ISCHILD(tp->ctt_type) == child &&
483178525Sjb			    CTF_TYPE_TO_INDEX(tp->ctt_type) <= fp->ctf_typemax)
484178525Sjb				fp->ctf_ptrtab[
485178525Sjb				    CTF_TYPE_TO_INDEX(tp->ctt_type)] = id;
486178525Sjb			/*FALLTHRU*/
487178525Sjb
488178525Sjb		case CTF_K_VOLATILE:
489178525Sjb		case CTF_K_CONST:
490178525Sjb		case CTF_K_RESTRICT:
491178525Sjb			err = ctf_hash_insert(&fp->ctf_names, fp,
492178525Sjb			    CTF_INDEX_TO_TYPE(id, child), tp->ctt_name);
493178525Sjb			if (err != 0 && err != ECTF_STRTAB)
494178525Sjb				return (err);
495178525Sjb			/*FALLTHRU*/
496178525Sjb
497178525Sjb		default:
498178525Sjb			vbytes = 0;
499178525Sjb			break;
500178525Sjb		}
501178525Sjb
502178525Sjb		*xp = (uint_t)((uintptr_t)tp - (uintptr_t)fp->ctf_buf);
503178525Sjb		tp = (ctf_type_t *)((uintptr_t)tp + increment + vbytes);
504178525Sjb	}
505178525Sjb
506178525Sjb	ctf_dprintf("%lu total types processed\n", fp->ctf_typemax);
507178525Sjb	ctf_dprintf("%u enum names hashed\n", ctf_hash_size(&fp->ctf_enums));
508178525Sjb	ctf_dprintf("%u struct names hashed (%d long)\n",
509178525Sjb	    ctf_hash_size(&fp->ctf_structs), nlstructs);
510178525Sjb	ctf_dprintf("%u union names hashed (%d long)\n",
511178525Sjb	    ctf_hash_size(&fp->ctf_unions), nlunions);
512178525Sjb	ctf_dprintf("%u base type names hashed\n",
513178525Sjb	    ctf_hash_size(&fp->ctf_names));
514178525Sjb
515178525Sjb	/*
516178525Sjb	 * Make an additional pass through the pointer table to find pointers
517178525Sjb	 * that point to anonymous typedef nodes.  If we find one, modify the
518178525Sjb	 * pointer table so that the pointer is also known to point to the
519178525Sjb	 * node that is referenced by the anonymous typedef node.
520178525Sjb	 */
521178525Sjb	for (id = 1; id <= fp->ctf_typemax; id++) {
522178525Sjb		if ((dst = fp->ctf_ptrtab[id]) != 0) {
523178525Sjb			tp = LCTF_INDEX_TO_TYPEPTR(fp, id);
524178525Sjb
525178525Sjb			if (LCTF_INFO_KIND(fp, tp->ctt_info) == CTF_K_TYPEDEF &&
526178525Sjb			    strcmp(ctf_strptr(fp, tp->ctt_name), "") == 0 &&
527178525Sjb			    CTF_TYPE_ISCHILD(tp->ctt_type) == child &&
528178525Sjb			    CTF_TYPE_TO_INDEX(tp->ctt_type) <= fp->ctf_typemax)
529178525Sjb				fp->ctf_ptrtab[
530178525Sjb				    CTF_TYPE_TO_INDEX(tp->ctt_type)] = dst;
531178525Sjb		}
532178525Sjb	}
533178525Sjb
534178525Sjb	return (0);
535178525Sjb}
536178525Sjb
537178525Sjb/*
538178525Sjb * Decode the specified CTF buffer and optional symbol table and create a new
539178525Sjb * CTF container representing the symbolic debugging information.  This code
540178525Sjb * can be used directly by the debugger, or it can be used as the engine for
541178525Sjb * ctf_fdopen() or ctf_open(), below.
542178525Sjb */
543178525Sjbctf_file_t *
544178525Sjbctf_bufopen(const ctf_sect_t *ctfsect, const ctf_sect_t *symsect,
545178525Sjb    const ctf_sect_t *strsect, int *errp)
546178525Sjb{
547178525Sjb	const ctf_preamble_t *pp;
548178525Sjb	ctf_header_t hp;
549178525Sjb	ctf_file_t *fp;
550178525Sjb	void *buf, *base;
551178525Sjb	size_t size, hdrsz;
552178525Sjb	int err;
553178525Sjb
554178525Sjb	if (ctfsect == NULL || ((symsect == NULL) != (strsect == NULL)))
555178525Sjb		return (ctf_set_open_errno(errp, EINVAL));
556178525Sjb
557178525Sjb	if (symsect != NULL && symsect->cts_entsize != sizeof (Elf32_Sym) &&
558178525Sjb	    symsect->cts_entsize != sizeof (Elf64_Sym))
559178525Sjb		return (ctf_set_open_errno(errp, ECTF_SYMTAB));
560178525Sjb
561178525Sjb	if (symsect != NULL && symsect->cts_data == NULL)
562178525Sjb		return (ctf_set_open_errno(errp, ECTF_SYMBAD));
563178525Sjb
564178525Sjb	if (strsect != NULL && strsect->cts_data == NULL)
565178525Sjb		return (ctf_set_open_errno(errp, ECTF_STRBAD));
566178525Sjb
567178525Sjb	if (ctfsect->cts_size < sizeof (ctf_preamble_t))
568178525Sjb		return (ctf_set_open_errno(errp, ECTF_NOCTFBUF));
569178525Sjb
570178525Sjb	pp = (const ctf_preamble_t *)ctfsect->cts_data;
571178525Sjb
572178525Sjb	ctf_dprintf("ctf_bufopen: magic=0x%x version=%u\n",
573178525Sjb	    pp->ctp_magic, pp->ctp_version);
574178525Sjb
575178525Sjb	/*
576178525Sjb	 * Validate each part of the CTF header (either V1 or V2).
577178525Sjb	 * First, we validate the preamble (common to all versions).  At that
578178525Sjb	 * point, we know specific header version, and can validate the
579178525Sjb	 * version-specific parts including section offsets and alignments.
580178525Sjb	 */
581178525Sjb	if (pp->ctp_magic != CTF_MAGIC)
582178525Sjb		return (ctf_set_open_errno(errp, ECTF_NOCTFBUF));
583178525Sjb
584178525Sjb	if (pp->ctp_version == CTF_VERSION_2) {
585178525Sjb		if (ctfsect->cts_size < sizeof (ctf_header_t))
586178525Sjb			return (ctf_set_open_errno(errp, ECTF_NOCTFBUF));
587178525Sjb
588178525Sjb		bcopy(ctfsect->cts_data, &hp, sizeof (hp));
589178525Sjb		hdrsz = sizeof (ctf_header_t);
590178525Sjb
591178525Sjb	} else if (pp->ctp_version == CTF_VERSION_1) {
592178525Sjb		const ctf_header_v1_t *h1p =
593178525Sjb		    (const ctf_header_v1_t *)ctfsect->cts_data;
594178525Sjb
595178525Sjb		if (ctfsect->cts_size < sizeof (ctf_header_v1_t))
596178525Sjb			return (ctf_set_open_errno(errp, ECTF_NOCTFBUF));
597178525Sjb
598178525Sjb		bzero(&hp, sizeof (hp));
599178525Sjb		hp.cth_preamble = h1p->cth_preamble;
600178525Sjb		hp.cth_objtoff = h1p->cth_objtoff;
601178525Sjb		hp.cth_funcoff = h1p->cth_funcoff;
602178525Sjb		hp.cth_typeoff = h1p->cth_typeoff;
603178525Sjb		hp.cth_stroff = h1p->cth_stroff;
604178525Sjb		hp.cth_strlen = h1p->cth_strlen;
605178525Sjb
606178525Sjb		hdrsz = sizeof (ctf_header_v1_t);
607178525Sjb	} else
608178525Sjb		return (ctf_set_open_errno(errp, ECTF_CTFVERS));
609178525Sjb
610178525Sjb	size = hp.cth_stroff + hp.cth_strlen;
611178525Sjb
612178525Sjb	ctf_dprintf("ctf_bufopen: uncompressed size=%lu\n", (ulong_t)size);
613178525Sjb
614178525Sjb	if (hp.cth_lbloff > size || hp.cth_objtoff > size ||
615178525Sjb	    hp.cth_funcoff > size || hp.cth_typeoff > size ||
616178525Sjb	    hp.cth_stroff > size)
617178525Sjb		return (ctf_set_open_errno(errp, ECTF_CORRUPT));
618178525Sjb
619178525Sjb	if (hp.cth_lbloff > hp.cth_objtoff ||
620178525Sjb	    hp.cth_objtoff > hp.cth_funcoff ||
621178525Sjb	    hp.cth_funcoff > hp.cth_typeoff ||
622178525Sjb	    hp.cth_typeoff > hp.cth_stroff)
623178525Sjb		return (ctf_set_open_errno(errp, ECTF_CORRUPT));
624178525Sjb
625178525Sjb	if ((hp.cth_lbloff & 3) || (hp.cth_objtoff & 1) ||
626178525Sjb	    (hp.cth_funcoff & 1) || (hp.cth_typeoff & 3))
627178525Sjb		return (ctf_set_open_errno(errp, ECTF_CORRUPT));
628178525Sjb
629178525Sjb	/*
630178525Sjb	 * Once everything is determined to be valid, attempt to decompress
631178525Sjb	 * the CTF data buffer if it is compressed.  Otherwise we just put
632178525Sjb	 * the data section's buffer pointer into ctf_buf, below.
633178525Sjb	 */
634178525Sjb	if (hp.cth_flags & CTF_F_COMPRESS) {
635178525Sjb		size_t srclen, dstlen;
636178525Sjb		const void *src;
637178525Sjb		int rc = Z_OK;
638178525Sjb
639178525Sjb		if (ctf_zopen(errp) == NULL)
640178525Sjb			return (NULL); /* errp is set for us */
641178525Sjb
642178525Sjb		if ((base = ctf_data_alloc(size + hdrsz)) == MAP_FAILED)
643178525Sjb			return (ctf_set_open_errno(errp, ECTF_ZALLOC));
644178525Sjb
645178525Sjb		bcopy(ctfsect->cts_data, base, hdrsz);
646178525Sjb		((ctf_preamble_t *)base)->ctp_flags &= ~CTF_F_COMPRESS;
647178525Sjb		buf = (uchar_t *)base + hdrsz;
648178525Sjb
649178525Sjb		src = (uchar_t *)ctfsect->cts_data + hdrsz;
650178525Sjb		srclen = ctfsect->cts_size - hdrsz;
651178525Sjb		dstlen = size;
652178525Sjb
653178525Sjb		if ((rc = z_uncompress(buf, &dstlen, src, srclen)) != Z_OK) {
654178525Sjb			ctf_dprintf("zlib inflate err: %s\n", z_strerror(rc));
655178525Sjb			ctf_data_free(base, size + hdrsz);
656178525Sjb			return (ctf_set_open_errno(errp, ECTF_DECOMPRESS));
657178525Sjb		}
658178525Sjb
659178525Sjb		if (dstlen != size) {
660178525Sjb			ctf_dprintf("zlib inflate short -- got %lu of %lu "
661178525Sjb			    "bytes\n", (ulong_t)dstlen, (ulong_t)size);
662178525Sjb			ctf_data_free(base, size + hdrsz);
663178525Sjb			return (ctf_set_open_errno(errp, ECTF_CORRUPT));
664178525Sjb		}
665178525Sjb
666178525Sjb		ctf_data_protect(base, size + hdrsz);
667178525Sjb
668178525Sjb	} else {
669178525Sjb		base = (void *)ctfsect->cts_data;
670178525Sjb		buf = (uchar_t *)base + hdrsz;
671178525Sjb	}
672178525Sjb
673178525Sjb	/*
674178525Sjb	 * Once we have uncompressed and validated the CTF data buffer, we can
675178525Sjb	 * proceed with allocating a ctf_file_t and initializing it.
676178525Sjb	 */
677178525Sjb	if ((fp = ctf_alloc(sizeof (ctf_file_t))) == NULL)
678178525Sjb		return (ctf_set_open_errno(errp, EAGAIN));
679178525Sjb
680178525Sjb	bzero(fp, sizeof (ctf_file_t));
681178525Sjb	fp->ctf_version = hp.cth_version;
682178525Sjb	fp->ctf_fileops = &ctf_fileops[hp.cth_version];
683178525Sjb	bcopy(ctfsect, &fp->ctf_data, sizeof (ctf_sect_t));
684178525Sjb
685178525Sjb	if (symsect != NULL) {
686178525Sjb		bcopy(symsect, &fp->ctf_symtab, sizeof (ctf_sect_t));
687178525Sjb		bcopy(strsect, &fp->ctf_strtab, sizeof (ctf_sect_t));
688178525Sjb	}
689178525Sjb
690178525Sjb	if (fp->ctf_data.cts_name != NULL)
691178525Sjb		fp->ctf_data.cts_name = ctf_strdup(fp->ctf_data.cts_name);
692178525Sjb	if (fp->ctf_symtab.cts_name != NULL)
693178525Sjb		fp->ctf_symtab.cts_name = ctf_strdup(fp->ctf_symtab.cts_name);
694178525Sjb	if (fp->ctf_strtab.cts_name != NULL)
695178525Sjb		fp->ctf_strtab.cts_name = ctf_strdup(fp->ctf_strtab.cts_name);
696178525Sjb
697178525Sjb	if (fp->ctf_data.cts_name == NULL)
698178525Sjb		fp->ctf_data.cts_name = _CTF_NULLSTR;
699178525Sjb	if (fp->ctf_symtab.cts_name == NULL)
700178525Sjb		fp->ctf_symtab.cts_name = _CTF_NULLSTR;
701178525Sjb	if (fp->ctf_strtab.cts_name == NULL)
702178525Sjb		fp->ctf_strtab.cts_name = _CTF_NULLSTR;
703178525Sjb
704178525Sjb	fp->ctf_str[CTF_STRTAB_0].cts_strs = (const char *)buf + hp.cth_stroff;
705178525Sjb	fp->ctf_str[CTF_STRTAB_0].cts_len = hp.cth_strlen;
706178525Sjb
707178525Sjb	if (strsect != NULL) {
708178525Sjb		fp->ctf_str[CTF_STRTAB_1].cts_strs = strsect->cts_data;
709178525Sjb		fp->ctf_str[CTF_STRTAB_1].cts_len = strsect->cts_size;
710178525Sjb	}
711178525Sjb
712178525Sjb	fp->ctf_base = base;
713178525Sjb	fp->ctf_buf = buf;
714178525Sjb	fp->ctf_size = size + hdrsz;
715178525Sjb
716178525Sjb	/*
717178525Sjb	 * If we have a parent container name and label, store the relocated
718178525Sjb	 * string pointers in the CTF container for easy access later.
719178525Sjb	 */
720178525Sjb	if (hp.cth_parlabel != 0)
721178525Sjb		fp->ctf_parlabel = ctf_strptr(fp, hp.cth_parlabel);
722178525Sjb	if (hp.cth_parname != 0)
723178525Sjb		fp->ctf_parname = ctf_strptr(fp, hp.cth_parname);
724178525Sjb
725178525Sjb	ctf_dprintf("ctf_bufopen: parent name %s (label %s)\n",
726178525Sjb	    fp->ctf_parname ? fp->ctf_parname : "<NULL>",
727178525Sjb	    fp->ctf_parlabel ? fp->ctf_parlabel : "<NULL>");
728178525Sjb
729178525Sjb	/*
730178525Sjb	 * If we have a symbol table section, allocate and initialize
731178525Sjb	 * the symtab translation table, pointed to by ctf_sxlate.
732178525Sjb	 */
733178525Sjb	if (symsect != NULL) {
734178525Sjb		fp->ctf_nsyms = symsect->cts_size / symsect->cts_entsize;
735178525Sjb		fp->ctf_sxlate = ctf_alloc(fp->ctf_nsyms * sizeof (uint_t));
736178525Sjb
737178525Sjb		if (fp->ctf_sxlate == NULL) {
738178525Sjb			(void) ctf_set_open_errno(errp, EAGAIN);
739178525Sjb			goto bad;
740178525Sjb		}
741178525Sjb
742178525Sjb		if ((err = init_symtab(fp, &hp, symsect, strsect)) != 0) {
743178525Sjb			(void) ctf_set_open_errno(errp, err);
744178525Sjb			goto bad;
745178525Sjb		}
746178525Sjb	}
747178525Sjb
748178525Sjb	if ((err = init_types(fp, &hp)) != 0) {
749178525Sjb		(void) ctf_set_open_errno(errp, err);
750178525Sjb		goto bad;
751178525Sjb	}
752178525Sjb
753178525Sjb	/*
754178525Sjb	 * Initialize the ctf_lookup_by_name top-level dictionary.  We keep an
755178525Sjb	 * array of type name prefixes and the corresponding ctf_hash to use.
756178525Sjb	 * NOTE: This code must be kept in sync with the code in ctf_update().
757178525Sjb	 */
758178525Sjb	fp->ctf_lookups[0].ctl_prefix = "struct";
759178525Sjb	fp->ctf_lookups[0].ctl_len = strlen(fp->ctf_lookups[0].ctl_prefix);
760178525Sjb	fp->ctf_lookups[0].ctl_hash = &fp->ctf_structs;
761178525Sjb	fp->ctf_lookups[1].ctl_prefix = "union";
762178525Sjb	fp->ctf_lookups[1].ctl_len = strlen(fp->ctf_lookups[1].ctl_prefix);
763178525Sjb	fp->ctf_lookups[1].ctl_hash = &fp->ctf_unions;
764178525Sjb	fp->ctf_lookups[2].ctl_prefix = "enum";
765178525Sjb	fp->ctf_lookups[2].ctl_len = strlen(fp->ctf_lookups[2].ctl_prefix);
766178525Sjb	fp->ctf_lookups[2].ctl_hash = &fp->ctf_enums;
767178525Sjb	fp->ctf_lookups[3].ctl_prefix = _CTF_NULLSTR;
768178525Sjb	fp->ctf_lookups[3].ctl_len = strlen(fp->ctf_lookups[3].ctl_prefix);
769178525Sjb	fp->ctf_lookups[3].ctl_hash = &fp->ctf_names;
770178525Sjb	fp->ctf_lookups[4].ctl_prefix = NULL;
771178525Sjb	fp->ctf_lookups[4].ctl_len = 0;
772178525Sjb	fp->ctf_lookups[4].ctl_hash = NULL;
773178525Sjb
774178525Sjb	if (symsect != NULL) {
775178525Sjb		if (symsect->cts_entsize == sizeof (Elf64_Sym))
776178525Sjb			(void) ctf_setmodel(fp, CTF_MODEL_LP64);
777178525Sjb		else
778178525Sjb			(void) ctf_setmodel(fp, CTF_MODEL_ILP32);
779178525Sjb	} else
780178525Sjb		(void) ctf_setmodel(fp, CTF_MODEL_NATIVE);
781178525Sjb
782178525Sjb	fp->ctf_refcnt = 1;
783178525Sjb	return (fp);
784178525Sjb
785178525Sjbbad:
786178525Sjb	ctf_close(fp);
787178525Sjb	return (NULL);
788178525Sjb}
789178525Sjb
790178525Sjb/*
791268578Srpaulo * Dupliate a ctf_file_t and its underlying section information into a new
792268578Srpaulo * container. This works by copying the three ctf_sect_t's of the original
793268578Srpaulo * container if they exist and passing those into ctf_bufopen. To copy those, we
794268578Srpaulo * mmap anonymous memory with ctf_data_alloc and bcopy the data across. It's not
795268578Srpaulo * the cheapest thing, but it's what we've got.
796268578Srpaulo */
797268578Srpauloctf_file_t *
798268578Srpauloctf_dup(ctf_file_t *ofp)
799268578Srpaulo{
800268578Srpaulo	ctf_file_t *fp;
801268578Srpaulo	ctf_sect_t ctfsect, symsect, strsect;
802268578Srpaulo	ctf_sect_t *ctp, *symp, *strp;
803268578Srpaulo	void *cbuf, *symbuf, *strbuf;
804268578Srpaulo	int err;
805268578Srpaulo
806268578Srpaulo	cbuf = symbuf = strbuf = NULL;
807268578Srpaulo	/*
808268578Srpaulo	 * The ctfsect isn't allowed to not exist, but the symbol and string
809268578Srpaulo	 * section might not. We only need to copy the data of the section, not
810268578Srpaulo	 * the name, as ctf_bufopen will take care of that.
811268578Srpaulo	 */
812268578Srpaulo	bcopy(&ofp->ctf_data, &ctfsect, sizeof (ctf_sect_t));
813268578Srpaulo	cbuf = ctf_data_alloc(ctfsect.cts_size);
814268578Srpaulo	if (cbuf == NULL) {
815268578Srpaulo		(void) ctf_set_errno(ofp, ECTF_MMAP);
816268578Srpaulo		return (NULL);
817268578Srpaulo	}
818268578Srpaulo
819268578Srpaulo	bcopy(ctfsect.cts_data, cbuf, ctfsect.cts_size);
820268578Srpaulo	ctf_data_protect(cbuf, ctfsect.cts_size);
821268578Srpaulo	ctfsect.cts_data = cbuf;
822268578Srpaulo	ctfsect.cts_offset = 0;
823268578Srpaulo	ctp = &ctfsect;
824268578Srpaulo
825268578Srpaulo	if (ofp->ctf_symtab.cts_data != NULL) {
826268578Srpaulo		bcopy(&ofp->ctf_symtab, &symsect, sizeof (ctf_sect_t));
827268578Srpaulo		symbuf = ctf_data_alloc(symsect.cts_size);
828268578Srpaulo		if (symbuf == NULL) {
829268578Srpaulo			(void) ctf_set_errno(ofp, ECTF_MMAP);
830268578Srpaulo			goto err;
831268578Srpaulo		}
832268578Srpaulo		bcopy(symsect.cts_data, symbuf, symsect.cts_size);
833268578Srpaulo		ctf_data_protect(symbuf, symsect.cts_size);
834268578Srpaulo		symsect.cts_data = symbuf;
835268578Srpaulo		symsect.cts_offset = 0;
836268578Srpaulo		symp = &symsect;
837268578Srpaulo	} else {
838268578Srpaulo		symp = NULL;
839268578Srpaulo	}
840268578Srpaulo
841268578Srpaulo	if (ofp->ctf_strtab.cts_data != NULL) {
842268578Srpaulo		bcopy(&ofp->ctf_strtab, &strsect, sizeof (ctf_sect_t));
843268578Srpaulo		strbuf = ctf_data_alloc(strsect.cts_size);
844268578Srpaulo		if (strbuf == NULL) {
845268578Srpaulo			(void) ctf_set_errno(ofp, ECTF_MMAP);
846268578Srpaulo			goto err;
847268578Srpaulo		}
848268578Srpaulo		bcopy(strsect.cts_data, strbuf, strsect.cts_size);
849268578Srpaulo		ctf_data_protect(strbuf, strsect.cts_size);
850268578Srpaulo		strsect.cts_data = strbuf;
851268578Srpaulo		strsect.cts_offset = 0;
852268578Srpaulo		strp = &strsect;
853268578Srpaulo	} else {
854268578Srpaulo		strp = NULL;
855268578Srpaulo	}
856268578Srpaulo
857268578Srpaulo	fp = ctf_bufopen(ctp, symp, strp, &err);
858268578Srpaulo	if (fp == NULL) {
859268578Srpaulo		(void) ctf_set_errno(ofp, err);
860268578Srpaulo		goto err;
861268578Srpaulo	}
862268578Srpaulo
863268578Srpaulo	fp->ctf_flags |= LCTF_MMAP;
864268578Srpaulo
865268578Srpaulo	return (fp);
866268578Srpaulo
867268578Srpauloerr:
868268578Srpaulo	ctf_data_free(cbuf, ctfsect.cts_size);
869268578Srpaulo	if (symbuf != NULL)
870268578Srpaulo		ctf_data_free(symbuf, symsect.cts_size);
871268578Srpaulo	if (strbuf != NULL)
872268578Srpaulo		ctf_data_free(strbuf, strsect.cts_size);
873268578Srpaulo	return (NULL);
874268578Srpaulo}
875268578Srpaulo
876268578Srpaulo/*
877178525Sjb * Close the specified CTF container and free associated data structures.  Note
878178525Sjb * that ctf_close() is a reference counted operation: if the specified file is
879178525Sjb * the parent of other active containers, its reference count will be greater
880178525Sjb * than one and it will be freed later when no active children exist.
881178525Sjb */
882178525Sjbvoid
883178525Sjbctf_close(ctf_file_t *fp)
884178525Sjb{
885178525Sjb	ctf_dtdef_t *dtd, *ntd;
886178525Sjb
887178525Sjb	if (fp == NULL)
888178525Sjb		return; /* allow ctf_close(NULL) to simplify caller code */
889178525Sjb
890178525Sjb	ctf_dprintf("ctf_close(%p) refcnt=%u\n", (void *)fp, fp->ctf_refcnt);
891178525Sjb
892178525Sjb	if (fp->ctf_refcnt > 1) {
893178525Sjb		fp->ctf_refcnt--;
894178525Sjb		return;
895178525Sjb	}
896178525Sjb
897178525Sjb	if (fp->ctf_parent != NULL)
898178525Sjb		ctf_close(fp->ctf_parent);
899178525Sjb
900254744Sdelphij	/*
901254744Sdelphij	 * Note, to work properly with reference counting on the dynamic
902254744Sdelphij	 * section, we must delete the list in reverse.
903254744Sdelphij	 */
904254744Sdelphij	for (dtd = ctf_list_prev(&fp->ctf_dtdefs); dtd != NULL; dtd = ntd) {
905254744Sdelphij		ntd = ctf_list_prev(dtd);
906178525Sjb		ctf_dtd_delete(fp, dtd);
907178525Sjb	}
908178525Sjb
909178525Sjb	ctf_free(fp->ctf_dthash, fp->ctf_dthashlen * sizeof (ctf_dtdef_t *));
910178525Sjb
911178525Sjb	if (fp->ctf_flags & LCTF_MMAP) {
912178525Sjb		if (fp->ctf_data.cts_data != NULL)
913178525Sjb			ctf_sect_munmap(&fp->ctf_data);
914178525Sjb		if (fp->ctf_symtab.cts_data != NULL)
915178525Sjb			ctf_sect_munmap(&fp->ctf_symtab);
916178525Sjb		if (fp->ctf_strtab.cts_data != NULL)
917178525Sjb			ctf_sect_munmap(&fp->ctf_strtab);
918178525Sjb	}
919178525Sjb
920178525Sjb	if (fp->ctf_data.cts_name != _CTF_NULLSTR &&
921178525Sjb	    fp->ctf_data.cts_name != NULL) {
922178525Sjb		ctf_free((char *)fp->ctf_data.cts_name,
923178525Sjb		    strlen(fp->ctf_data.cts_name) + 1);
924178525Sjb	}
925178525Sjb
926178525Sjb	if (fp->ctf_symtab.cts_name != _CTF_NULLSTR &&
927178525Sjb	    fp->ctf_symtab.cts_name != NULL) {
928178525Sjb		ctf_free((char *)fp->ctf_symtab.cts_name,
929178525Sjb		    strlen(fp->ctf_symtab.cts_name) + 1);
930178525Sjb	}
931178525Sjb
932178525Sjb	if (fp->ctf_strtab.cts_name != _CTF_NULLSTR &&
933178525Sjb	    fp->ctf_strtab.cts_name != NULL) {
934178525Sjb		ctf_free((char *)fp->ctf_strtab.cts_name,
935178525Sjb		    strlen(fp->ctf_strtab.cts_name) + 1);
936178525Sjb	}
937178525Sjb
938178525Sjb	if (fp->ctf_base != fp->ctf_data.cts_data && fp->ctf_base != NULL)
939178525Sjb		ctf_data_free((void *)fp->ctf_base, fp->ctf_size);
940178525Sjb
941178525Sjb	if (fp->ctf_sxlate != NULL)
942178525Sjb		ctf_free(fp->ctf_sxlate, sizeof (uint_t) * fp->ctf_nsyms);
943178525Sjb
944178525Sjb	if (fp->ctf_txlate != NULL) {
945178525Sjb		ctf_free(fp->ctf_txlate,
946178525Sjb		    sizeof (uint_t) * (fp->ctf_typemax + 1));
947178525Sjb	}
948178525Sjb
949178525Sjb	if (fp->ctf_ptrtab != NULL) {
950178525Sjb		ctf_free(fp->ctf_ptrtab,
951178525Sjb		    sizeof (ushort_t) * (fp->ctf_typemax + 1));
952178525Sjb	}
953178525Sjb
954178525Sjb	ctf_hash_destroy(&fp->ctf_structs);
955178525Sjb	ctf_hash_destroy(&fp->ctf_unions);
956178525Sjb	ctf_hash_destroy(&fp->ctf_enums);
957178525Sjb	ctf_hash_destroy(&fp->ctf_names);
958178525Sjb
959178525Sjb	ctf_free(fp, sizeof (ctf_file_t));
960178525Sjb}
961178525Sjb
962178525Sjb/*
963178525Sjb * Return the CTF handle for the parent CTF container, if one exists.
964178525Sjb * Otherwise return NULL to indicate this container has no imported parent.
965178525Sjb */
966178525Sjbctf_file_t *
967178525Sjbctf_parent_file(ctf_file_t *fp)
968178525Sjb{
969178525Sjb	return (fp->ctf_parent);
970178525Sjb}
971178525Sjb
972178525Sjb/*
973178525Sjb * Return the name of the parent CTF container, if one exists.  Otherwise
974178525Sjb * return NULL to indicate this container is a root container.
975178525Sjb */
976178525Sjbconst char *
977178525Sjbctf_parent_name(ctf_file_t *fp)
978178525Sjb{
979178525Sjb	return (fp->ctf_parname);
980178525Sjb}
981178525Sjb
982178525Sjb/*
983178525Sjb * Import the types from the specified parent container by storing a pointer
984178525Sjb * to it in ctf_parent and incrementing its reference count.  Only one parent
985178525Sjb * is allowed: if a parent already exists, it is replaced by the new parent.
986178525Sjb */
987178525Sjbint
988178525Sjbctf_import(ctf_file_t *fp, ctf_file_t *pfp)
989178525Sjb{
990178525Sjb	if (fp == NULL || fp == pfp || (pfp != NULL && pfp->ctf_refcnt == 0))
991178525Sjb		return (ctf_set_errno(fp, EINVAL));
992178525Sjb
993178525Sjb	if (pfp != NULL && pfp->ctf_dmodel != fp->ctf_dmodel)
994178525Sjb		return (ctf_set_errno(fp, ECTF_DMODEL));
995178525Sjb
996178525Sjb	if (fp->ctf_parent != NULL)
997178525Sjb		ctf_close(fp->ctf_parent);
998178525Sjb
999178525Sjb	if (pfp != NULL) {
1000178525Sjb		fp->ctf_flags |= LCTF_CHILD;
1001178525Sjb		pfp->ctf_refcnt++;
1002178525Sjb	}
1003178525Sjb
1004178525Sjb	fp->ctf_parent = pfp;
1005178525Sjb	return (0);
1006178525Sjb}
1007178525Sjb
1008178525Sjb/*
1009178525Sjb * Set the data model constant for the CTF container.
1010178525Sjb */
1011178525Sjbint
1012178525Sjbctf_setmodel(ctf_file_t *fp, int model)
1013178525Sjb{
1014178525Sjb	const ctf_dmodel_t *dp;
1015178525Sjb
1016178525Sjb	for (dp = _libctf_models; dp->ctd_name != NULL; dp++) {
1017178525Sjb		if (dp->ctd_code == model) {
1018178525Sjb			fp->ctf_dmodel = dp;
1019178525Sjb			return (0);
1020178525Sjb		}
1021178525Sjb	}
1022178525Sjb
1023178525Sjb	return (ctf_set_errno(fp, EINVAL));
1024178525Sjb}
1025178525Sjb
1026178525Sjb/*
1027178525Sjb * Return the data model constant for the CTF container.
1028178525Sjb */
1029178525Sjbint
1030178525Sjbctf_getmodel(ctf_file_t *fp)
1031178525Sjb{
1032178525Sjb	return (fp->ctf_dmodel->ctd_code);
1033178525Sjb}
1034178525Sjb
1035178525Sjbvoid
1036178525Sjbctf_setspecific(ctf_file_t *fp, void *data)
1037178525Sjb{
1038178525Sjb	fp->ctf_specific = data;
1039178525Sjb}
1040178525Sjb
1041178525Sjbvoid *
1042178525Sjbctf_getspecific(ctf_file_t *fp)
1043178525Sjb{
1044178525Sjb	return (fp->ctf_specific);
1045178525Sjb}
1046