10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 50Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 60Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 70Sstevel@tonic-gate * with the License. 80Sstevel@tonic-gate * 90Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 100Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 110Sstevel@tonic-gate * See the License for the specific language governing permissions 120Sstevel@tonic-gate * and limitations under the License. 130Sstevel@tonic-gate * 140Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 150Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 160Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 170Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 180Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 190Sstevel@tonic-gate * 200Sstevel@tonic-gate * CDDL HEADER END 210Sstevel@tonic-gate */ 22*1222Smws 230Sstevel@tonic-gate /* 24*1222Smws * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 250Sstevel@tonic-gate * Use is subject to license terms. 260Sstevel@tonic-gate */ 270Sstevel@tonic-gate 280Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 290Sstevel@tonic-gate 300Sstevel@tonic-gate #include <ctf_impl.h> 310Sstevel@tonic-gate #include <sys/mman.h> 320Sstevel@tonic-gate #include <sys/zmod.h> 330Sstevel@tonic-gate 340Sstevel@tonic-gate static const ctf_dmodel_t _libctf_models[] = { 350Sstevel@tonic-gate { "ILP32", CTF_MODEL_ILP32, 4, 1, 2, 4, 4 }, 360Sstevel@tonic-gate { "LP64", CTF_MODEL_LP64, 8, 1, 2, 4, 8 }, 370Sstevel@tonic-gate { NULL, 0, 0, 0, 0, 0, 0 } 380Sstevel@tonic-gate }; 390Sstevel@tonic-gate 400Sstevel@tonic-gate const char _CTF_SECTION[] = ".SUNW_ctf"; 410Sstevel@tonic-gate const char _CTF_NULLSTR[] = ""; 420Sstevel@tonic-gate 430Sstevel@tonic-gate int _libctf_version = CTF_VERSION; /* library client version */ 440Sstevel@tonic-gate int _libctf_debug = 0; /* debugging messages enabled */ 450Sstevel@tonic-gate 460Sstevel@tonic-gate static ushort_t 470Sstevel@tonic-gate get_kind_v1(ushort_t info) 480Sstevel@tonic-gate { 490Sstevel@tonic-gate return (CTF_INFO_KIND_V1(info)); 500Sstevel@tonic-gate } 510Sstevel@tonic-gate 520Sstevel@tonic-gate static ushort_t 530Sstevel@tonic-gate get_kind_v2(ushort_t info) 540Sstevel@tonic-gate { 550Sstevel@tonic-gate return (CTF_INFO_KIND(info)); 560Sstevel@tonic-gate } 570Sstevel@tonic-gate 580Sstevel@tonic-gate static ushort_t 590Sstevel@tonic-gate get_root_v1(ushort_t info) 600Sstevel@tonic-gate { 610Sstevel@tonic-gate return (CTF_INFO_ISROOT_V1(info)); 620Sstevel@tonic-gate } 630Sstevel@tonic-gate 640Sstevel@tonic-gate static ushort_t 650Sstevel@tonic-gate get_root_v2(ushort_t info) 660Sstevel@tonic-gate { 670Sstevel@tonic-gate return (CTF_INFO_ISROOT(info)); 680Sstevel@tonic-gate } 690Sstevel@tonic-gate 700Sstevel@tonic-gate static ushort_t 710Sstevel@tonic-gate get_vlen_v1(ushort_t info) 720Sstevel@tonic-gate { 730Sstevel@tonic-gate return (CTF_INFO_VLEN_V1(info)); 740Sstevel@tonic-gate } 750Sstevel@tonic-gate 760Sstevel@tonic-gate static ushort_t 770Sstevel@tonic-gate get_vlen_v2(ushort_t info) 780Sstevel@tonic-gate { 790Sstevel@tonic-gate return (CTF_INFO_VLEN(info)); 800Sstevel@tonic-gate } 810Sstevel@tonic-gate 820Sstevel@tonic-gate static const ctf_fileops_t ctf_fileops[] = { 830Sstevel@tonic-gate { NULL, NULL }, 840Sstevel@tonic-gate { get_kind_v1, get_root_v1, get_vlen_v1 }, 850Sstevel@tonic-gate { get_kind_v2, get_root_v2, get_vlen_v2 }, 860Sstevel@tonic-gate }; 870Sstevel@tonic-gate 880Sstevel@tonic-gate /* 890Sstevel@tonic-gate * Convert a 32-bit ELF symbol into GElf (Elf64) and return a pointer to it. 900Sstevel@tonic-gate */ 910Sstevel@tonic-gate static Elf64_Sym * 920Sstevel@tonic-gate sym_to_gelf(const Elf32_Sym *src, Elf64_Sym *dst) 930Sstevel@tonic-gate { 940Sstevel@tonic-gate dst->st_name = src->st_name; 950Sstevel@tonic-gate dst->st_value = src->st_value; 960Sstevel@tonic-gate dst->st_size = src->st_size; 970Sstevel@tonic-gate dst->st_info = src->st_info; 980Sstevel@tonic-gate dst->st_other = src->st_other; 990Sstevel@tonic-gate dst->st_shndx = src->st_shndx; 1000Sstevel@tonic-gate 1010Sstevel@tonic-gate return (dst); 1020Sstevel@tonic-gate } 1030Sstevel@tonic-gate 1040Sstevel@tonic-gate /* 1050Sstevel@tonic-gate * Initialize the symtab translation table by filling each entry with the 1060Sstevel@tonic-gate * offset of the CTF type or function data corresponding to each STT_FUNC or 1070Sstevel@tonic-gate * STT_OBJECT entry in the symbol table. 1080Sstevel@tonic-gate */ 1090Sstevel@tonic-gate static int 1100Sstevel@tonic-gate init_symtab(ctf_file_t *fp, const ctf_header_t *hp, 1110Sstevel@tonic-gate const ctf_sect_t *sp, const ctf_sect_t *strp) 1120Sstevel@tonic-gate { 1130Sstevel@tonic-gate const uchar_t *symp = sp->cts_data; 1140Sstevel@tonic-gate uint_t *xp = fp->ctf_sxlate; 1150Sstevel@tonic-gate uint_t *xend = xp + fp->ctf_nsyms; 1160Sstevel@tonic-gate 1170Sstevel@tonic-gate uint_t objtoff = hp->cth_objtoff; 1180Sstevel@tonic-gate uint_t funcoff = hp->cth_funcoff; 1190Sstevel@tonic-gate 1200Sstevel@tonic-gate ushort_t info, vlen; 1210Sstevel@tonic-gate Elf64_Sym sym, *gsp; 1220Sstevel@tonic-gate const char *name; 1230Sstevel@tonic-gate 1240Sstevel@tonic-gate /* 1250Sstevel@tonic-gate * The CTF data object and function type sections are ordered to match 1260Sstevel@tonic-gate * the relative order of the respective symbol types in the symtab. 1270Sstevel@tonic-gate * If no type information is available for a symbol table entry, a 1280Sstevel@tonic-gate * pad is inserted in the CTF section. As a further optimization, 1290Sstevel@tonic-gate * anonymous or undefined symbols are omitted from the CTF data. 1300Sstevel@tonic-gate */ 1310Sstevel@tonic-gate for (; xp < xend; xp++, symp += sp->cts_entsize) { 1320Sstevel@tonic-gate if (sp->cts_entsize == sizeof (Elf32_Sym)) 1330Sstevel@tonic-gate gsp = sym_to_gelf((Elf32_Sym *)(uintptr_t)symp, &sym); 1340Sstevel@tonic-gate else 1350Sstevel@tonic-gate gsp = (Elf64_Sym *)(uintptr_t)symp; 1360Sstevel@tonic-gate 1370Sstevel@tonic-gate if (gsp->st_name < strp->cts_size) 1380Sstevel@tonic-gate name = (const char *)strp->cts_data + gsp->st_name; 1390Sstevel@tonic-gate else 1400Sstevel@tonic-gate name = _CTF_NULLSTR; 1410Sstevel@tonic-gate 1420Sstevel@tonic-gate if (gsp->st_name == 0 || gsp->st_shndx == SHN_UNDEF || 1430Sstevel@tonic-gate strcmp(name, "_START_") == 0 || 1440Sstevel@tonic-gate strcmp(name, "_END_") == 0) { 1450Sstevel@tonic-gate *xp = -1u; 1460Sstevel@tonic-gate continue; 1470Sstevel@tonic-gate } 1480Sstevel@tonic-gate 1490Sstevel@tonic-gate switch (ELF64_ST_TYPE(gsp->st_info)) { 1500Sstevel@tonic-gate case STT_OBJECT: 1510Sstevel@tonic-gate if (objtoff >= hp->cth_funcoff || 1520Sstevel@tonic-gate (gsp->st_shndx == SHN_ABS && gsp->st_value == 0)) { 1530Sstevel@tonic-gate *xp = -1u; 1540Sstevel@tonic-gate break; 1550Sstevel@tonic-gate } 1560Sstevel@tonic-gate 1570Sstevel@tonic-gate *xp = objtoff; 1580Sstevel@tonic-gate objtoff += sizeof (ushort_t); 1590Sstevel@tonic-gate break; 1600Sstevel@tonic-gate 1610Sstevel@tonic-gate case STT_FUNC: 1620Sstevel@tonic-gate if (funcoff >= hp->cth_typeoff) { 1630Sstevel@tonic-gate *xp = -1u; 1640Sstevel@tonic-gate break; 1650Sstevel@tonic-gate } 1660Sstevel@tonic-gate 1670Sstevel@tonic-gate *xp = funcoff; 1680Sstevel@tonic-gate 1690Sstevel@tonic-gate info = *(ushort_t *)((uintptr_t)fp->ctf_buf + funcoff); 1700Sstevel@tonic-gate vlen = LCTF_INFO_VLEN(fp, info); 1710Sstevel@tonic-gate 1720Sstevel@tonic-gate /* 1730Sstevel@tonic-gate * If we encounter a zero pad at the end, just skip it. 1740Sstevel@tonic-gate * Otherwise skip over the function and its return type 1750Sstevel@tonic-gate * (+2) and the argument list (vlen). 1760Sstevel@tonic-gate */ 1770Sstevel@tonic-gate if (LCTF_INFO_KIND(fp, info) == CTF_K_UNKNOWN && 1780Sstevel@tonic-gate vlen == 0) 1790Sstevel@tonic-gate funcoff += sizeof (ushort_t); /* skip pad */ 1800Sstevel@tonic-gate else 1810Sstevel@tonic-gate funcoff += sizeof (ushort_t) * (vlen + 2); 1820Sstevel@tonic-gate break; 1830Sstevel@tonic-gate 1840Sstevel@tonic-gate default: 1850Sstevel@tonic-gate *xp = -1u; 1860Sstevel@tonic-gate break; 1870Sstevel@tonic-gate } 1880Sstevel@tonic-gate } 1890Sstevel@tonic-gate 1900Sstevel@tonic-gate ctf_dprintf("loaded %lu symtab entries\n", fp->ctf_nsyms); 1910Sstevel@tonic-gate return (0); 1920Sstevel@tonic-gate } 1930Sstevel@tonic-gate 1940Sstevel@tonic-gate /* 1950Sstevel@tonic-gate * Initialize the type ID translation table with the byte offset of each type, 1960Sstevel@tonic-gate * and initialize the hash tables of each named type. 1970Sstevel@tonic-gate */ 1980Sstevel@tonic-gate static int 199*1222Smws init_types(ctf_file_t *fp, const ctf_header_t *cth) 2000Sstevel@tonic-gate { 2010Sstevel@tonic-gate /* LINTED - pointer alignment */ 202*1222Smws const ctf_type_t *tbuf = (ctf_type_t *)(fp->ctf_buf + cth->cth_typeoff); 2030Sstevel@tonic-gate /* LINTED - pointer alignment */ 204*1222Smws const ctf_type_t *tend = (ctf_type_t *)(fp->ctf_buf + cth->cth_stroff); 2050Sstevel@tonic-gate 2060Sstevel@tonic-gate ulong_t pop[CTF_K_MAX + 1] = { 0 }; 2070Sstevel@tonic-gate const ctf_type_t *tp; 208*1222Smws ctf_hash_t *hp; 2090Sstevel@tonic-gate ushort_t id, dst; 2100Sstevel@tonic-gate uint_t *xp; 2110Sstevel@tonic-gate 2120Sstevel@tonic-gate /* 2130Sstevel@tonic-gate * We initially determine whether the container is a child or a parent 2140Sstevel@tonic-gate * based on the value of cth_parname. To support containers that pre- 2150Sstevel@tonic-gate * date cth_parname, we also scan the types themselves for references 2160Sstevel@tonic-gate * to values in the range reserved for child types in our first pass. 2170Sstevel@tonic-gate */ 218*1222Smws int child = cth->cth_parname != 0; 2190Sstevel@tonic-gate int nlstructs = 0, nlunions = 0; 2200Sstevel@tonic-gate int err; 2210Sstevel@tonic-gate 2220Sstevel@tonic-gate /* 2230Sstevel@tonic-gate * We make two passes through the entire type section. In this first 2240Sstevel@tonic-gate * pass, we count the number of each type and the total number of types. 2250Sstevel@tonic-gate */ 2260Sstevel@tonic-gate for (tp = tbuf; tp < tend; fp->ctf_typemax++) { 2270Sstevel@tonic-gate ushort_t kind = LCTF_INFO_KIND(fp, tp->ctt_info); 2280Sstevel@tonic-gate ulong_t vlen = LCTF_INFO_VLEN(fp, tp->ctt_info); 2290Sstevel@tonic-gate ssize_t size, increment; 2300Sstevel@tonic-gate 2310Sstevel@tonic-gate size_t vbytes; 2320Sstevel@tonic-gate uint_t n; 2330Sstevel@tonic-gate 2340Sstevel@tonic-gate (void) ctf_get_ctt_size(fp, tp, &size, &increment); 2350Sstevel@tonic-gate 2360Sstevel@tonic-gate switch (kind) { 2370Sstevel@tonic-gate case CTF_K_INTEGER: 2380Sstevel@tonic-gate case CTF_K_FLOAT: 2390Sstevel@tonic-gate vbytes = sizeof (uint_t); 2400Sstevel@tonic-gate break; 2410Sstevel@tonic-gate case CTF_K_ARRAY: 2420Sstevel@tonic-gate vbytes = sizeof (ctf_array_t); 2430Sstevel@tonic-gate break; 2440Sstevel@tonic-gate case CTF_K_FUNCTION: 2450Sstevel@tonic-gate vbytes = sizeof (ushort_t) * (vlen + (vlen & 1)); 2460Sstevel@tonic-gate break; 2470Sstevel@tonic-gate case CTF_K_STRUCT: 2480Sstevel@tonic-gate case CTF_K_UNION: 2490Sstevel@tonic-gate if (fp->ctf_version == CTF_VERSION_1 || 2500Sstevel@tonic-gate size < CTF_LSTRUCT_THRESH) { 2510Sstevel@tonic-gate ctf_member_t *mp = (ctf_member_t *) 2520Sstevel@tonic-gate ((uintptr_t)tp + increment); 2530Sstevel@tonic-gate 2540Sstevel@tonic-gate vbytes = sizeof (ctf_member_t) * vlen; 2550Sstevel@tonic-gate for (n = vlen; n != 0; n--, mp++) 2560Sstevel@tonic-gate child |= CTF_TYPE_ISCHILD(mp->ctm_type); 2570Sstevel@tonic-gate } else { 2580Sstevel@tonic-gate ctf_lmember_t *lmp = (ctf_lmember_t *) 2590Sstevel@tonic-gate ((uintptr_t)tp + increment); 2600Sstevel@tonic-gate 2610Sstevel@tonic-gate vbytes = sizeof (ctf_lmember_t) * vlen; 2620Sstevel@tonic-gate for (n = vlen; n != 0; n--, lmp++) 2630Sstevel@tonic-gate child |= 2640Sstevel@tonic-gate CTF_TYPE_ISCHILD(lmp->ctlm_type); 2650Sstevel@tonic-gate } 2660Sstevel@tonic-gate break; 2670Sstevel@tonic-gate case CTF_K_ENUM: 2680Sstevel@tonic-gate vbytes = sizeof (ctf_enum_t) * vlen; 2690Sstevel@tonic-gate break; 2700Sstevel@tonic-gate case CTF_K_FORWARD: 271*1222Smws /* 272*1222Smws * For forward declarations, ctt_type is the CTF_K_* 273*1222Smws * kind for the tag, so bump that population count too. 274*1222Smws * If ctt_type is unknown, treat the tag as a struct. 275*1222Smws */ 276*1222Smws if (tp->ctt_type == CTF_K_UNKNOWN || 277*1222Smws tp->ctt_type >= CTF_K_MAX) 278*1222Smws pop[CTF_K_STRUCT]++; 279*1222Smws else 280*1222Smws pop[tp->ctt_type]++; 281*1222Smws /*FALLTHRU*/ 2820Sstevel@tonic-gate case CTF_K_UNKNOWN: 2830Sstevel@tonic-gate vbytes = 0; 2840Sstevel@tonic-gate break; 2850Sstevel@tonic-gate case CTF_K_POINTER: 2860Sstevel@tonic-gate case CTF_K_TYPEDEF: 2870Sstevel@tonic-gate case CTF_K_VOLATILE: 2880Sstevel@tonic-gate case CTF_K_CONST: 2890Sstevel@tonic-gate case CTF_K_RESTRICT: 2900Sstevel@tonic-gate child |= CTF_TYPE_ISCHILD(tp->ctt_type); 2910Sstevel@tonic-gate vbytes = 0; 2920Sstevel@tonic-gate break; 2930Sstevel@tonic-gate default: 2940Sstevel@tonic-gate ctf_dprintf("detected invalid CTF kind -- %u\n", kind); 2950Sstevel@tonic-gate return (ECTF_CORRUPT); 2960Sstevel@tonic-gate } 2970Sstevel@tonic-gate tp = (ctf_type_t *)((uintptr_t)tp + increment + vbytes); 2980Sstevel@tonic-gate pop[kind]++; 2990Sstevel@tonic-gate } 3000Sstevel@tonic-gate 3010Sstevel@tonic-gate /* 3020Sstevel@tonic-gate * If we detected a reference to a child type ID, then we know this 3030Sstevel@tonic-gate * container is a child and may have a parent's types imported later. 3040Sstevel@tonic-gate */ 3050Sstevel@tonic-gate if (child) { 3060Sstevel@tonic-gate ctf_dprintf("CTF container %p is a child\n", (void *)fp); 3070Sstevel@tonic-gate fp->ctf_flags |= LCTF_CHILD; 3080Sstevel@tonic-gate } else 3090Sstevel@tonic-gate ctf_dprintf("CTF container %p is a parent\n", (void *)fp); 3100Sstevel@tonic-gate 3110Sstevel@tonic-gate /* 3120Sstevel@tonic-gate * Now that we've counted up the number of each type, we can allocate 3130Sstevel@tonic-gate * the hash tables, type translation table, and pointer table. 3140Sstevel@tonic-gate */ 315*1222Smws if ((err = ctf_hash_create(&fp->ctf_structs, pop[CTF_K_STRUCT])) != 0) 3160Sstevel@tonic-gate return (err); 3170Sstevel@tonic-gate 3180Sstevel@tonic-gate if ((err = ctf_hash_create(&fp->ctf_unions, pop[CTF_K_UNION])) != 0) 3190Sstevel@tonic-gate return (err); 3200Sstevel@tonic-gate 3210Sstevel@tonic-gate if ((err = ctf_hash_create(&fp->ctf_enums, pop[CTF_K_ENUM])) != 0) 3220Sstevel@tonic-gate return (err); 3230Sstevel@tonic-gate 3240Sstevel@tonic-gate if ((err = ctf_hash_create(&fp->ctf_names, 3250Sstevel@tonic-gate pop[CTF_K_INTEGER] + pop[CTF_K_FLOAT] + pop[CTF_K_FUNCTION] + 3260Sstevel@tonic-gate pop[CTF_K_TYPEDEF] + pop[CTF_K_POINTER] + pop[CTF_K_VOLATILE] + 3270Sstevel@tonic-gate pop[CTF_K_CONST] + pop[CTF_K_RESTRICT])) != 0) 3280Sstevel@tonic-gate return (err); 3290Sstevel@tonic-gate 3300Sstevel@tonic-gate fp->ctf_txlate = ctf_alloc(sizeof (uint_t) * (fp->ctf_typemax + 1)); 3310Sstevel@tonic-gate fp->ctf_ptrtab = ctf_alloc(sizeof (ushort_t) * (fp->ctf_typemax + 1)); 3320Sstevel@tonic-gate 3330Sstevel@tonic-gate if (fp->ctf_txlate == NULL || fp->ctf_ptrtab == NULL) 3340Sstevel@tonic-gate return (EAGAIN); /* memory allocation failed */ 3350Sstevel@tonic-gate 3360Sstevel@tonic-gate xp = fp->ctf_txlate; 3370Sstevel@tonic-gate *xp++ = 0; /* type id 0 is used as a sentinel value */ 3380Sstevel@tonic-gate 3390Sstevel@tonic-gate bzero(fp->ctf_txlate, sizeof (uint_t) * (fp->ctf_typemax + 1)); 3400Sstevel@tonic-gate bzero(fp->ctf_ptrtab, sizeof (ushort_t) * (fp->ctf_typemax + 1)); 3410Sstevel@tonic-gate 3420Sstevel@tonic-gate /* 3430Sstevel@tonic-gate * In the second pass through the types, we fill in each entry of the 3440Sstevel@tonic-gate * type and pointer tables and add names to the appropriate hashes. 3450Sstevel@tonic-gate */ 3460Sstevel@tonic-gate for (id = 1, tp = tbuf; tp < tend; xp++, id++) { 3470Sstevel@tonic-gate ushort_t kind = LCTF_INFO_KIND(fp, tp->ctt_info); 3480Sstevel@tonic-gate ulong_t vlen = LCTF_INFO_VLEN(fp, tp->ctt_info); 3490Sstevel@tonic-gate ssize_t size, increment; 3500Sstevel@tonic-gate 3510Sstevel@tonic-gate const char *name; 3520Sstevel@tonic-gate size_t vbytes; 3530Sstevel@tonic-gate ctf_helem_t *hep; 3540Sstevel@tonic-gate ctf_encoding_t cte; 3550Sstevel@tonic-gate 3560Sstevel@tonic-gate (void) ctf_get_ctt_size(fp, tp, &size, &increment); 3570Sstevel@tonic-gate name = ctf_strptr(fp, tp->ctt_name); 3580Sstevel@tonic-gate 3590Sstevel@tonic-gate switch (kind) { 3600Sstevel@tonic-gate case CTF_K_INTEGER: 3610Sstevel@tonic-gate case CTF_K_FLOAT: 3620Sstevel@tonic-gate /* 3630Sstevel@tonic-gate * Only insert a new integer base type definition if 3640Sstevel@tonic-gate * this type name has not been defined yet. We re-use 3650Sstevel@tonic-gate * the names with different encodings for bit-fields. 3660Sstevel@tonic-gate */ 3670Sstevel@tonic-gate if ((hep = ctf_hash_lookup(&fp->ctf_names, fp, 3680Sstevel@tonic-gate name, strlen(name))) == NULL) { 3690Sstevel@tonic-gate err = ctf_hash_insert(&fp->ctf_names, fp, 3700Sstevel@tonic-gate CTF_INDEX_TO_TYPE(id, child), tp->ctt_name); 3710Sstevel@tonic-gate if (err != 0 && err != ECTF_STRTAB) 3720Sstevel@tonic-gate return (err); 3730Sstevel@tonic-gate } else if (ctf_type_encoding(fp, hep->h_type, 3740Sstevel@tonic-gate &cte) == 0 && cte.cte_bits == 0) { 3750Sstevel@tonic-gate /* 3760Sstevel@tonic-gate * Work-around SOS8 stabs bug: replace existing 3770Sstevel@tonic-gate * intrinsic w/ same name if it was zero bits. 3780Sstevel@tonic-gate */ 3790Sstevel@tonic-gate hep->h_type = CTF_INDEX_TO_TYPE(id, child); 3800Sstevel@tonic-gate } 3810Sstevel@tonic-gate vbytes = sizeof (uint_t); 3820Sstevel@tonic-gate break; 3830Sstevel@tonic-gate 3840Sstevel@tonic-gate case CTF_K_ARRAY: 3850Sstevel@tonic-gate vbytes = sizeof (ctf_array_t); 3860Sstevel@tonic-gate break; 3870Sstevel@tonic-gate 3880Sstevel@tonic-gate case CTF_K_FUNCTION: 3890Sstevel@tonic-gate err = ctf_hash_insert(&fp->ctf_names, fp, 3900Sstevel@tonic-gate CTF_INDEX_TO_TYPE(id, child), tp->ctt_name); 3910Sstevel@tonic-gate if (err != 0 && err != ECTF_STRTAB) 3920Sstevel@tonic-gate return (err); 3930Sstevel@tonic-gate vbytes = sizeof (ushort_t) * (vlen + (vlen & 1)); 3940Sstevel@tonic-gate break; 3950Sstevel@tonic-gate 3960Sstevel@tonic-gate case CTF_K_STRUCT: 397*1222Smws err = ctf_hash_define(&fp->ctf_structs, fp, 398*1222Smws CTF_INDEX_TO_TYPE(id, child), tp->ctt_name); 399*1222Smws 400*1222Smws if (err != 0 && err != ECTF_STRTAB) 401*1222Smws return (err); 4020Sstevel@tonic-gate 4030Sstevel@tonic-gate if (fp->ctf_version == CTF_VERSION_1 || 4040Sstevel@tonic-gate size < CTF_LSTRUCT_THRESH) 4050Sstevel@tonic-gate vbytes = sizeof (ctf_member_t) * vlen; 4060Sstevel@tonic-gate else { 4070Sstevel@tonic-gate vbytes = sizeof (ctf_lmember_t) * vlen; 4080Sstevel@tonic-gate nlstructs++; 4090Sstevel@tonic-gate } 4100Sstevel@tonic-gate break; 4110Sstevel@tonic-gate 4120Sstevel@tonic-gate case CTF_K_UNION: 413*1222Smws err = ctf_hash_define(&fp->ctf_unions, fp, 4140Sstevel@tonic-gate CTF_INDEX_TO_TYPE(id, child), tp->ctt_name); 415*1222Smws 4160Sstevel@tonic-gate if (err != 0 && err != ECTF_STRTAB) 4170Sstevel@tonic-gate return (err); 4180Sstevel@tonic-gate 4190Sstevel@tonic-gate if (fp->ctf_version == CTF_VERSION_1 || 4200Sstevel@tonic-gate size < CTF_LSTRUCT_THRESH) 4210Sstevel@tonic-gate vbytes = sizeof (ctf_member_t) * vlen; 4220Sstevel@tonic-gate else { 4230Sstevel@tonic-gate vbytes = sizeof (ctf_lmember_t) * vlen; 4240Sstevel@tonic-gate nlunions++; 4250Sstevel@tonic-gate } 4260Sstevel@tonic-gate break; 4270Sstevel@tonic-gate 4280Sstevel@tonic-gate case CTF_K_ENUM: 429*1222Smws err = ctf_hash_define(&fp->ctf_enums, fp, 4300Sstevel@tonic-gate CTF_INDEX_TO_TYPE(id, child), tp->ctt_name); 431*1222Smws 4320Sstevel@tonic-gate if (err != 0 && err != ECTF_STRTAB) 4330Sstevel@tonic-gate return (err); 434*1222Smws 4350Sstevel@tonic-gate vbytes = sizeof (ctf_enum_t) * vlen; 4360Sstevel@tonic-gate break; 4370Sstevel@tonic-gate 4380Sstevel@tonic-gate case CTF_K_TYPEDEF: 4390Sstevel@tonic-gate err = ctf_hash_insert(&fp->ctf_names, fp, 4400Sstevel@tonic-gate CTF_INDEX_TO_TYPE(id, child), tp->ctt_name); 4410Sstevel@tonic-gate if (err != 0 && err != ECTF_STRTAB) 4420Sstevel@tonic-gate return (err); 4430Sstevel@tonic-gate vbytes = 0; 4440Sstevel@tonic-gate break; 4450Sstevel@tonic-gate 4460Sstevel@tonic-gate case CTF_K_FORWARD: 4470Sstevel@tonic-gate /* 448*1222Smws * Only insert forward tags into the given hash if the 449*1222Smws * type or tag name is not already present. 4500Sstevel@tonic-gate */ 451*1222Smws switch (tp->ctt_type) { 452*1222Smws case CTF_K_STRUCT: 453*1222Smws hp = &fp->ctf_structs; 454*1222Smws break; 455*1222Smws case CTF_K_UNION: 456*1222Smws hp = &fp->ctf_unions; 457*1222Smws break; 458*1222Smws case CTF_K_ENUM: 459*1222Smws hp = &fp->ctf_enums; 460*1222Smws break; 461*1222Smws default: 462*1222Smws hp = &fp->ctf_structs; 463*1222Smws } 464*1222Smws 465*1222Smws if (ctf_hash_lookup(hp, fp, 4660Sstevel@tonic-gate name, strlen(name)) == NULL) { 467*1222Smws err = ctf_hash_insert(hp, fp, 4680Sstevel@tonic-gate CTF_INDEX_TO_TYPE(id, child), tp->ctt_name); 4690Sstevel@tonic-gate if (err != 0 && err != ECTF_STRTAB) 4700Sstevel@tonic-gate return (err); 4710Sstevel@tonic-gate } 4720Sstevel@tonic-gate vbytes = 0; 4730Sstevel@tonic-gate break; 4740Sstevel@tonic-gate 4750Sstevel@tonic-gate case CTF_K_POINTER: 4760Sstevel@tonic-gate /* 4770Sstevel@tonic-gate * If the type referenced by the pointer is in this CTF 4780Sstevel@tonic-gate * container, then store the index of the pointer type 4790Sstevel@tonic-gate * in fp->ctf_ptrtab[ index of referenced type ]. 4800Sstevel@tonic-gate */ 4810Sstevel@tonic-gate if (CTF_TYPE_ISCHILD(tp->ctt_type) == child && 4820Sstevel@tonic-gate CTF_TYPE_TO_INDEX(tp->ctt_type) <= fp->ctf_typemax) 4830Sstevel@tonic-gate fp->ctf_ptrtab[ 4840Sstevel@tonic-gate CTF_TYPE_TO_INDEX(tp->ctt_type)] = id; 4850Sstevel@tonic-gate /*FALLTHRU*/ 4860Sstevel@tonic-gate 4870Sstevel@tonic-gate case CTF_K_VOLATILE: 4880Sstevel@tonic-gate case CTF_K_CONST: 4890Sstevel@tonic-gate case CTF_K_RESTRICT: 4900Sstevel@tonic-gate err = ctf_hash_insert(&fp->ctf_names, fp, 4910Sstevel@tonic-gate CTF_INDEX_TO_TYPE(id, child), tp->ctt_name); 4920Sstevel@tonic-gate if (err != 0 && err != ECTF_STRTAB) 4930Sstevel@tonic-gate return (err); 4940Sstevel@tonic-gate /*FALLTHRU*/ 4950Sstevel@tonic-gate 4960Sstevel@tonic-gate default: 4970Sstevel@tonic-gate vbytes = 0; 4980Sstevel@tonic-gate break; 4990Sstevel@tonic-gate } 5000Sstevel@tonic-gate 5010Sstevel@tonic-gate *xp = (uint_t)((uintptr_t)tp - (uintptr_t)fp->ctf_buf); 5020Sstevel@tonic-gate tp = (ctf_type_t *)((uintptr_t)tp + increment + vbytes); 5030Sstevel@tonic-gate } 5040Sstevel@tonic-gate 5050Sstevel@tonic-gate ctf_dprintf("%lu total types processed\n", fp->ctf_typemax); 5060Sstevel@tonic-gate ctf_dprintf("%u enum names hashed\n", ctf_hash_size(&fp->ctf_enums)); 5070Sstevel@tonic-gate ctf_dprintf("%u struct names hashed (%d long)\n", 5080Sstevel@tonic-gate ctf_hash_size(&fp->ctf_structs), nlstructs); 5090Sstevel@tonic-gate ctf_dprintf("%u union names hashed (%d long)\n", 5100Sstevel@tonic-gate ctf_hash_size(&fp->ctf_unions), nlunions); 5110Sstevel@tonic-gate ctf_dprintf("%u base type names hashed\n", 5120Sstevel@tonic-gate ctf_hash_size(&fp->ctf_names)); 5130Sstevel@tonic-gate 5140Sstevel@tonic-gate /* 5150Sstevel@tonic-gate * Make an additional pass through the pointer table to find pointers 5160Sstevel@tonic-gate * that point to anonymous typedef nodes. If we find one, modify the 5170Sstevel@tonic-gate * pointer table so that the pointer is also known to point to the 5180Sstevel@tonic-gate * node that is referenced by the anonymous typedef node. 5190Sstevel@tonic-gate */ 5200Sstevel@tonic-gate for (id = 1; id <= fp->ctf_typemax; id++) { 5210Sstevel@tonic-gate if ((dst = fp->ctf_ptrtab[id]) != 0) { 5220Sstevel@tonic-gate tp = LCTF_INDEX_TO_TYPEPTR(fp, id); 5230Sstevel@tonic-gate 5240Sstevel@tonic-gate if (LCTF_INFO_KIND(fp, tp->ctt_info) == CTF_K_TYPEDEF && 5250Sstevel@tonic-gate strcmp(ctf_strptr(fp, tp->ctt_name), "") == 0 && 5260Sstevel@tonic-gate CTF_TYPE_ISCHILD(tp->ctt_type) == child && 5270Sstevel@tonic-gate CTF_TYPE_TO_INDEX(tp->ctt_type) <= fp->ctf_typemax) 5280Sstevel@tonic-gate fp->ctf_ptrtab[ 5290Sstevel@tonic-gate CTF_TYPE_TO_INDEX(tp->ctt_type)] = dst; 5300Sstevel@tonic-gate } 5310Sstevel@tonic-gate } 5320Sstevel@tonic-gate 5330Sstevel@tonic-gate return (0); 5340Sstevel@tonic-gate } 5350Sstevel@tonic-gate 5360Sstevel@tonic-gate /* 5370Sstevel@tonic-gate * Decode the specified CTF buffer and optional symbol table and create a new 5380Sstevel@tonic-gate * CTF container representing the symbolic debugging information. This code 5390Sstevel@tonic-gate * can be used directly by the debugger, or it can be used as the engine for 5400Sstevel@tonic-gate * ctf_fdopen() or ctf_open(), below. 5410Sstevel@tonic-gate */ 5420Sstevel@tonic-gate ctf_file_t * 5430Sstevel@tonic-gate ctf_bufopen(const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, 5440Sstevel@tonic-gate const ctf_sect_t *strsect, int *errp) 5450Sstevel@tonic-gate { 5460Sstevel@tonic-gate const ctf_preamble_t *pp; 5470Sstevel@tonic-gate ctf_header_t hp; 5480Sstevel@tonic-gate ctf_file_t *fp; 5490Sstevel@tonic-gate void *buf, *base; 5500Sstevel@tonic-gate size_t size, hdrsz; 5510Sstevel@tonic-gate int err; 5520Sstevel@tonic-gate 5530Sstevel@tonic-gate if (ctfsect == NULL || ((symsect == NULL) != (strsect == NULL))) 5540Sstevel@tonic-gate return (ctf_set_open_errno(errp, EINVAL)); 5550Sstevel@tonic-gate 5560Sstevel@tonic-gate if (symsect != NULL && symsect->cts_entsize != sizeof (Elf32_Sym) && 5570Sstevel@tonic-gate symsect->cts_entsize != sizeof (Elf64_Sym)) 5580Sstevel@tonic-gate return (ctf_set_open_errno(errp, ECTF_SYMTAB)); 5590Sstevel@tonic-gate 5600Sstevel@tonic-gate if (symsect != NULL && symsect->cts_data == NULL) 5610Sstevel@tonic-gate return (ctf_set_open_errno(errp, ECTF_SYMBAD)); 5620Sstevel@tonic-gate 5630Sstevel@tonic-gate if (strsect != NULL && strsect->cts_data == NULL) 5640Sstevel@tonic-gate return (ctf_set_open_errno(errp, ECTF_STRBAD)); 5650Sstevel@tonic-gate 5660Sstevel@tonic-gate if (ctfsect->cts_size < sizeof (ctf_preamble_t)) 5670Sstevel@tonic-gate return (ctf_set_open_errno(errp, ECTF_NOCTFBUF)); 5680Sstevel@tonic-gate 5690Sstevel@tonic-gate pp = (const ctf_preamble_t *)ctfsect->cts_data; 5700Sstevel@tonic-gate 5710Sstevel@tonic-gate ctf_dprintf("ctf_bufopen: magic=0x%x version=%u\n", 5720Sstevel@tonic-gate pp->ctp_magic, pp->ctp_version); 5730Sstevel@tonic-gate 5740Sstevel@tonic-gate /* 5750Sstevel@tonic-gate * Validate each part of the CTF header (either V1 or V2). 5760Sstevel@tonic-gate * First, we validate the preamble (common to all versions). At that 5770Sstevel@tonic-gate * point, we know specific header version, and can validate the 5780Sstevel@tonic-gate * version-specific parts including section offsets and alignments. 5790Sstevel@tonic-gate */ 5800Sstevel@tonic-gate if (pp->ctp_magic != CTF_MAGIC) 5810Sstevel@tonic-gate return (ctf_set_open_errno(errp, ECTF_NOCTFBUF)); 5820Sstevel@tonic-gate 5830Sstevel@tonic-gate if (pp->ctp_version == CTF_VERSION_2) { 5840Sstevel@tonic-gate if (ctfsect->cts_size < sizeof (ctf_header_t)) 5850Sstevel@tonic-gate return (ctf_set_open_errno(errp, ECTF_NOCTFBUF)); 5860Sstevel@tonic-gate 5870Sstevel@tonic-gate bcopy(ctfsect->cts_data, &hp, sizeof (hp)); 5880Sstevel@tonic-gate hdrsz = sizeof (ctf_header_t); 5890Sstevel@tonic-gate 5900Sstevel@tonic-gate } else if (pp->ctp_version == CTF_VERSION_1) { 5910Sstevel@tonic-gate const ctf_header_v1_t *h1p = 5920Sstevel@tonic-gate (const ctf_header_v1_t *)ctfsect->cts_data; 5930Sstevel@tonic-gate 5940Sstevel@tonic-gate if (ctfsect->cts_size < sizeof (ctf_header_v1_t)) 5950Sstevel@tonic-gate return (ctf_set_open_errno(errp, ECTF_NOCTFBUF)); 5960Sstevel@tonic-gate 5970Sstevel@tonic-gate bzero(&hp, sizeof (hp)); 5980Sstevel@tonic-gate hp.cth_preamble = h1p->cth_preamble; 5990Sstevel@tonic-gate hp.cth_objtoff = h1p->cth_objtoff; 6000Sstevel@tonic-gate hp.cth_funcoff = h1p->cth_funcoff; 6010Sstevel@tonic-gate hp.cth_typeoff = h1p->cth_typeoff; 6020Sstevel@tonic-gate hp.cth_stroff = h1p->cth_stroff; 6030Sstevel@tonic-gate hp.cth_strlen = h1p->cth_strlen; 6040Sstevel@tonic-gate 6050Sstevel@tonic-gate hdrsz = sizeof (ctf_header_v1_t); 6060Sstevel@tonic-gate } else 6070Sstevel@tonic-gate return (ctf_set_open_errno(errp, ECTF_CTFVERS)); 6080Sstevel@tonic-gate 6090Sstevel@tonic-gate size = hp.cth_stroff + hp.cth_strlen; 6100Sstevel@tonic-gate 6110Sstevel@tonic-gate ctf_dprintf("ctf_bufopen: uncompressed size=%lu\n", (ulong_t)size); 6120Sstevel@tonic-gate 6130Sstevel@tonic-gate if (hp.cth_lbloff > size || hp.cth_objtoff > size || 6140Sstevel@tonic-gate hp.cth_funcoff > size || hp.cth_typeoff > size || 6150Sstevel@tonic-gate hp.cth_stroff > size) 6160Sstevel@tonic-gate return (ctf_set_open_errno(errp, ECTF_CORRUPT)); 6170Sstevel@tonic-gate 6180Sstevel@tonic-gate if (hp.cth_lbloff > hp.cth_objtoff || 6190Sstevel@tonic-gate hp.cth_objtoff > hp.cth_funcoff || 6200Sstevel@tonic-gate hp.cth_funcoff > hp.cth_typeoff || 6210Sstevel@tonic-gate hp.cth_typeoff > hp.cth_stroff) 6220Sstevel@tonic-gate return (ctf_set_open_errno(errp, ECTF_CORRUPT)); 6230Sstevel@tonic-gate 6240Sstevel@tonic-gate if ((hp.cth_lbloff & 3) || (hp.cth_objtoff & 1) || 6250Sstevel@tonic-gate (hp.cth_funcoff & 1) || (hp.cth_typeoff & 3)) 6260Sstevel@tonic-gate return (ctf_set_open_errno(errp, ECTF_CORRUPT)); 6270Sstevel@tonic-gate 6280Sstevel@tonic-gate /* 6290Sstevel@tonic-gate * Once everything is determined to be valid, attempt to decompress 6300Sstevel@tonic-gate * the CTF data buffer if it is compressed. Otherwise we just put 6310Sstevel@tonic-gate * the data section's buffer pointer into ctf_buf, below. 6320Sstevel@tonic-gate */ 6330Sstevel@tonic-gate if (hp.cth_flags & CTF_F_COMPRESS) { 6340Sstevel@tonic-gate size_t srclen, dstlen; 6350Sstevel@tonic-gate const void *src; 6360Sstevel@tonic-gate int rc = Z_OK; 6370Sstevel@tonic-gate 6380Sstevel@tonic-gate if (ctf_zopen(errp) == NULL) 6390Sstevel@tonic-gate return (NULL); /* errp is set for us */ 6400Sstevel@tonic-gate 6410Sstevel@tonic-gate if ((base = ctf_data_alloc(size + hdrsz)) == MAP_FAILED) 6420Sstevel@tonic-gate return (ctf_set_open_errno(errp, ECTF_ZALLOC)); 6430Sstevel@tonic-gate 6440Sstevel@tonic-gate bcopy(ctfsect->cts_data, base, hdrsz); 6450Sstevel@tonic-gate ((ctf_preamble_t *)base)->ctp_flags &= ~CTF_F_COMPRESS; 6460Sstevel@tonic-gate buf = (uchar_t *)base + hdrsz; 6470Sstevel@tonic-gate 6480Sstevel@tonic-gate src = (uchar_t *)ctfsect->cts_data + hdrsz; 6490Sstevel@tonic-gate srclen = ctfsect->cts_size - hdrsz; 6500Sstevel@tonic-gate dstlen = size; 6510Sstevel@tonic-gate 6520Sstevel@tonic-gate if ((rc = z_uncompress(buf, &dstlen, src, srclen)) != Z_OK) { 6530Sstevel@tonic-gate ctf_dprintf("zlib inflate err: %s\n", z_strerror(rc)); 6540Sstevel@tonic-gate ctf_data_free(base, size + hdrsz); 6550Sstevel@tonic-gate return (ctf_set_open_errno(errp, ECTF_DECOMPRESS)); 6560Sstevel@tonic-gate } 6570Sstevel@tonic-gate 6580Sstevel@tonic-gate if (dstlen != size) { 6590Sstevel@tonic-gate ctf_dprintf("zlib inflate short -- got %lu of %lu " 6600Sstevel@tonic-gate "bytes\n", (ulong_t)dstlen, (ulong_t)size); 6610Sstevel@tonic-gate ctf_data_free(base, size + hdrsz); 6620Sstevel@tonic-gate return (ctf_set_open_errno(errp, ECTF_CORRUPT)); 6630Sstevel@tonic-gate } 6640Sstevel@tonic-gate 6650Sstevel@tonic-gate ctf_data_protect(base, size + hdrsz); 6660Sstevel@tonic-gate 6670Sstevel@tonic-gate } else { 6680Sstevel@tonic-gate base = (void *)ctfsect->cts_data; 6690Sstevel@tonic-gate buf = (uchar_t *)base + hdrsz; 6700Sstevel@tonic-gate } 6710Sstevel@tonic-gate 6720Sstevel@tonic-gate /* 6730Sstevel@tonic-gate * Once we have uncompressed and validated the CTF data buffer, we can 6740Sstevel@tonic-gate * proceed with allocating a ctf_file_t and initializing it. 6750Sstevel@tonic-gate */ 6760Sstevel@tonic-gate if ((fp = ctf_alloc(sizeof (ctf_file_t))) == NULL) 6770Sstevel@tonic-gate return (ctf_set_open_errno(errp, EAGAIN)); 6780Sstevel@tonic-gate 6790Sstevel@tonic-gate bzero(fp, sizeof (ctf_file_t)); 6800Sstevel@tonic-gate fp->ctf_version = hp.cth_version; 6810Sstevel@tonic-gate fp->ctf_fileops = &ctf_fileops[hp.cth_version]; 6820Sstevel@tonic-gate bcopy(ctfsect, &fp->ctf_data, sizeof (ctf_sect_t)); 6830Sstevel@tonic-gate 6840Sstevel@tonic-gate if (symsect != NULL) { 6850Sstevel@tonic-gate bcopy(symsect, &fp->ctf_symtab, sizeof (ctf_sect_t)); 6860Sstevel@tonic-gate bcopy(strsect, &fp->ctf_strtab, sizeof (ctf_sect_t)); 6870Sstevel@tonic-gate } 6880Sstevel@tonic-gate 6890Sstevel@tonic-gate if (fp->ctf_data.cts_name != NULL) 6900Sstevel@tonic-gate fp->ctf_data.cts_name = ctf_strdup(fp->ctf_data.cts_name); 6910Sstevel@tonic-gate if (fp->ctf_symtab.cts_name != NULL) 6920Sstevel@tonic-gate fp->ctf_symtab.cts_name = ctf_strdup(fp->ctf_symtab.cts_name); 6930Sstevel@tonic-gate if (fp->ctf_strtab.cts_name != NULL) 6940Sstevel@tonic-gate fp->ctf_strtab.cts_name = ctf_strdup(fp->ctf_strtab.cts_name); 6950Sstevel@tonic-gate 6960Sstevel@tonic-gate if (fp->ctf_data.cts_name == NULL) 6970Sstevel@tonic-gate fp->ctf_data.cts_name = _CTF_NULLSTR; 6980Sstevel@tonic-gate if (fp->ctf_symtab.cts_name == NULL) 6990Sstevel@tonic-gate fp->ctf_symtab.cts_name = _CTF_NULLSTR; 7000Sstevel@tonic-gate if (fp->ctf_strtab.cts_name == NULL) 7010Sstevel@tonic-gate fp->ctf_strtab.cts_name = _CTF_NULLSTR; 7020Sstevel@tonic-gate 7030Sstevel@tonic-gate fp->ctf_str[CTF_STRTAB_0].cts_strs = (const char *)buf + hp.cth_stroff; 7040Sstevel@tonic-gate fp->ctf_str[CTF_STRTAB_0].cts_len = hp.cth_strlen; 7050Sstevel@tonic-gate 7060Sstevel@tonic-gate if (strsect != NULL) { 7070Sstevel@tonic-gate fp->ctf_str[CTF_STRTAB_1].cts_strs = strsect->cts_data; 7080Sstevel@tonic-gate fp->ctf_str[CTF_STRTAB_1].cts_len = strsect->cts_size; 7090Sstevel@tonic-gate } 7100Sstevel@tonic-gate 7110Sstevel@tonic-gate fp->ctf_base = base; 7120Sstevel@tonic-gate fp->ctf_buf = buf; 7130Sstevel@tonic-gate fp->ctf_size = size + hdrsz; 7140Sstevel@tonic-gate 7150Sstevel@tonic-gate /* 7160Sstevel@tonic-gate * If we have a parent container name and label, store the relocated 7170Sstevel@tonic-gate * string pointers in the CTF container for easy access later. 7180Sstevel@tonic-gate */ 7190Sstevel@tonic-gate if (hp.cth_parlabel != 0) 7200Sstevel@tonic-gate fp->ctf_parlabel = ctf_strptr(fp, hp.cth_parlabel); 7210Sstevel@tonic-gate if (hp.cth_parname != 0) 7220Sstevel@tonic-gate fp->ctf_parname = ctf_strptr(fp, hp.cth_parname); 7230Sstevel@tonic-gate 7240Sstevel@tonic-gate ctf_dprintf("ctf_bufopen: parent name %s (label %s)\n", 7250Sstevel@tonic-gate fp->ctf_parname ? fp->ctf_parname : "<NULL>", 7260Sstevel@tonic-gate fp->ctf_parlabel ? fp->ctf_parlabel : "<NULL>"); 7270Sstevel@tonic-gate 7280Sstevel@tonic-gate /* 7290Sstevel@tonic-gate * If we have a symbol table section, allocate and initialize 7300Sstevel@tonic-gate * the symtab translation table, pointed to by ctf_sxlate. 7310Sstevel@tonic-gate */ 7320Sstevel@tonic-gate if (symsect != NULL) { 7330Sstevel@tonic-gate fp->ctf_nsyms = symsect->cts_size / symsect->cts_entsize; 7340Sstevel@tonic-gate fp->ctf_sxlate = ctf_alloc(fp->ctf_nsyms * sizeof (uint_t)); 7350Sstevel@tonic-gate 7360Sstevel@tonic-gate if (fp->ctf_sxlate == NULL) { 7370Sstevel@tonic-gate (void) ctf_set_open_errno(errp, EAGAIN); 7380Sstevel@tonic-gate goto bad; 7390Sstevel@tonic-gate } 7400Sstevel@tonic-gate 7410Sstevel@tonic-gate if ((err = init_symtab(fp, &hp, symsect, strsect)) != 0) { 7420Sstevel@tonic-gate (void) ctf_set_open_errno(errp, err); 7430Sstevel@tonic-gate goto bad; 7440Sstevel@tonic-gate } 7450Sstevel@tonic-gate } 7460Sstevel@tonic-gate 7470Sstevel@tonic-gate if ((err = init_types(fp, &hp)) != 0) { 7480Sstevel@tonic-gate (void) ctf_set_open_errno(errp, err); 7490Sstevel@tonic-gate goto bad; 7500Sstevel@tonic-gate } 7510Sstevel@tonic-gate 7520Sstevel@tonic-gate /* 7530Sstevel@tonic-gate * Initialize the ctf_lookup_by_name top-level dictionary. We keep an 7540Sstevel@tonic-gate * array of type name prefixes and the corresponding ctf_hash to use. 7550Sstevel@tonic-gate * NOTE: This code must be kept in sync with the code in ctf_update(). 7560Sstevel@tonic-gate */ 7570Sstevel@tonic-gate fp->ctf_lookups[0].ctl_prefix = "struct"; 7580Sstevel@tonic-gate fp->ctf_lookups[0].ctl_len = strlen(fp->ctf_lookups[0].ctl_prefix); 7590Sstevel@tonic-gate fp->ctf_lookups[0].ctl_hash = &fp->ctf_structs; 7600Sstevel@tonic-gate fp->ctf_lookups[1].ctl_prefix = "union"; 7610Sstevel@tonic-gate fp->ctf_lookups[1].ctl_len = strlen(fp->ctf_lookups[1].ctl_prefix); 7620Sstevel@tonic-gate fp->ctf_lookups[1].ctl_hash = &fp->ctf_unions; 7630Sstevel@tonic-gate fp->ctf_lookups[2].ctl_prefix = "enum"; 7640Sstevel@tonic-gate fp->ctf_lookups[2].ctl_len = strlen(fp->ctf_lookups[2].ctl_prefix); 7650Sstevel@tonic-gate fp->ctf_lookups[2].ctl_hash = &fp->ctf_enums; 7660Sstevel@tonic-gate fp->ctf_lookups[3].ctl_prefix = _CTF_NULLSTR; 7670Sstevel@tonic-gate fp->ctf_lookups[3].ctl_len = strlen(fp->ctf_lookups[3].ctl_prefix); 7680Sstevel@tonic-gate fp->ctf_lookups[3].ctl_hash = &fp->ctf_names; 7690Sstevel@tonic-gate fp->ctf_lookups[4].ctl_prefix = NULL; 7700Sstevel@tonic-gate fp->ctf_lookups[4].ctl_len = 0; 7710Sstevel@tonic-gate fp->ctf_lookups[4].ctl_hash = NULL; 7720Sstevel@tonic-gate 7730Sstevel@tonic-gate if (symsect != NULL) { 7740Sstevel@tonic-gate if (symsect->cts_entsize == sizeof (Elf64_Sym)) 7750Sstevel@tonic-gate (void) ctf_setmodel(fp, CTF_MODEL_LP64); 7760Sstevel@tonic-gate else 7770Sstevel@tonic-gate (void) ctf_setmodel(fp, CTF_MODEL_ILP32); 7780Sstevel@tonic-gate } else 7790Sstevel@tonic-gate (void) ctf_setmodel(fp, CTF_MODEL_NATIVE); 7800Sstevel@tonic-gate 7810Sstevel@tonic-gate fp->ctf_refcnt = 1; 7820Sstevel@tonic-gate return (fp); 7830Sstevel@tonic-gate 7840Sstevel@tonic-gate bad: 7850Sstevel@tonic-gate ctf_close(fp); 7860Sstevel@tonic-gate return (NULL); 7870Sstevel@tonic-gate } 7880Sstevel@tonic-gate 7890Sstevel@tonic-gate /* 7900Sstevel@tonic-gate * Close the specified CTF container and free associated data structures. Note 7910Sstevel@tonic-gate * that ctf_close() is a reference counted operation: if the specified file is 7920Sstevel@tonic-gate * the parent of other active containers, its reference count will be greater 7930Sstevel@tonic-gate * than one and it will be freed later when no active children exist. 7940Sstevel@tonic-gate */ 7950Sstevel@tonic-gate void 7960Sstevel@tonic-gate ctf_close(ctf_file_t *fp) 7970Sstevel@tonic-gate { 7980Sstevel@tonic-gate ctf_dtdef_t *dtd, *ntd; 7990Sstevel@tonic-gate 8000Sstevel@tonic-gate if (fp == NULL) 8010Sstevel@tonic-gate return; /* allow ctf_close(NULL) to simplify caller code */ 8020Sstevel@tonic-gate 8030Sstevel@tonic-gate ctf_dprintf("ctf_close(%p) refcnt=%u\n", (void *)fp, fp->ctf_refcnt); 8040Sstevel@tonic-gate 8050Sstevel@tonic-gate if (fp->ctf_refcnt > 1) { 8060Sstevel@tonic-gate fp->ctf_refcnt--; 8070Sstevel@tonic-gate return; 8080Sstevel@tonic-gate } 8090Sstevel@tonic-gate 810*1222Smws if (fp->ctf_parent != NULL) 811*1222Smws ctf_close(fp->ctf_parent); 812*1222Smws 8130Sstevel@tonic-gate for (dtd = ctf_list_next(&fp->ctf_dtdefs); dtd != NULL; dtd = ntd) { 8140Sstevel@tonic-gate ntd = ctf_list_next(dtd); 815*1222Smws ctf_dtd_delete(fp, dtd); 8160Sstevel@tonic-gate } 8170Sstevel@tonic-gate 818*1222Smws ctf_free(fp->ctf_dthash, fp->ctf_dthashlen * sizeof (ctf_dtdef_t *)); 8190Sstevel@tonic-gate 8200Sstevel@tonic-gate if (fp->ctf_flags & LCTF_MMAP) { 8210Sstevel@tonic-gate if (fp->ctf_data.cts_data != NULL) 8220Sstevel@tonic-gate ctf_sect_munmap(&fp->ctf_data); 8230Sstevel@tonic-gate if (fp->ctf_symtab.cts_data != NULL) 8240Sstevel@tonic-gate ctf_sect_munmap(&fp->ctf_symtab); 8250Sstevel@tonic-gate if (fp->ctf_strtab.cts_data != NULL) 8260Sstevel@tonic-gate ctf_sect_munmap(&fp->ctf_strtab); 8270Sstevel@tonic-gate } 8280Sstevel@tonic-gate 8290Sstevel@tonic-gate if (fp->ctf_data.cts_name != _CTF_NULLSTR && 8300Sstevel@tonic-gate fp->ctf_data.cts_name != NULL) { 8310Sstevel@tonic-gate ctf_free((char *)fp->ctf_data.cts_name, 8320Sstevel@tonic-gate strlen(fp->ctf_data.cts_name) + 1); 8330Sstevel@tonic-gate } 8340Sstevel@tonic-gate 8350Sstevel@tonic-gate if (fp->ctf_symtab.cts_name != _CTF_NULLSTR && 8360Sstevel@tonic-gate fp->ctf_symtab.cts_name != NULL) { 8370Sstevel@tonic-gate ctf_free((char *)fp->ctf_symtab.cts_name, 8380Sstevel@tonic-gate strlen(fp->ctf_symtab.cts_name) + 1); 8390Sstevel@tonic-gate } 8400Sstevel@tonic-gate 8410Sstevel@tonic-gate if (fp->ctf_strtab.cts_name != _CTF_NULLSTR && 8420Sstevel@tonic-gate fp->ctf_strtab.cts_name != NULL) { 8430Sstevel@tonic-gate ctf_free((char *)fp->ctf_strtab.cts_name, 8440Sstevel@tonic-gate strlen(fp->ctf_strtab.cts_name) + 1); 8450Sstevel@tonic-gate } 8460Sstevel@tonic-gate 8470Sstevel@tonic-gate if (fp->ctf_base != fp->ctf_data.cts_data && fp->ctf_base != NULL) 8480Sstevel@tonic-gate ctf_data_free((void *)fp->ctf_base, fp->ctf_size); 8490Sstevel@tonic-gate 8500Sstevel@tonic-gate if (fp->ctf_sxlate != NULL) 8510Sstevel@tonic-gate ctf_free(fp->ctf_sxlate, sizeof (uint_t) * fp->ctf_nsyms); 8520Sstevel@tonic-gate 8530Sstevel@tonic-gate if (fp->ctf_txlate != NULL) { 8540Sstevel@tonic-gate ctf_free(fp->ctf_txlate, 8550Sstevel@tonic-gate sizeof (uint_t) * (fp->ctf_typemax + 1)); 8560Sstevel@tonic-gate } 8570Sstevel@tonic-gate 8580Sstevel@tonic-gate if (fp->ctf_ptrtab != NULL) { 8590Sstevel@tonic-gate ctf_free(fp->ctf_ptrtab, 8600Sstevel@tonic-gate sizeof (ushort_t) * (fp->ctf_typemax + 1)); 8610Sstevel@tonic-gate } 8620Sstevel@tonic-gate 8630Sstevel@tonic-gate ctf_hash_destroy(&fp->ctf_structs); 8640Sstevel@tonic-gate ctf_hash_destroy(&fp->ctf_unions); 8650Sstevel@tonic-gate ctf_hash_destroy(&fp->ctf_enums); 8660Sstevel@tonic-gate ctf_hash_destroy(&fp->ctf_names); 8670Sstevel@tonic-gate 8680Sstevel@tonic-gate ctf_free(fp, sizeof (ctf_file_t)); 8690Sstevel@tonic-gate } 8700Sstevel@tonic-gate 8710Sstevel@tonic-gate /* 8720Sstevel@tonic-gate * Return the CTF handle for the parent CTF container, if one exists. 8730Sstevel@tonic-gate * Otherwise return NULL to indicate this container has no imported parent. 8740Sstevel@tonic-gate */ 8750Sstevel@tonic-gate ctf_file_t * 8760Sstevel@tonic-gate ctf_parent_file(ctf_file_t *fp) 8770Sstevel@tonic-gate { 8780Sstevel@tonic-gate return (fp->ctf_parent); 8790Sstevel@tonic-gate } 8800Sstevel@tonic-gate 8810Sstevel@tonic-gate /* 8820Sstevel@tonic-gate * Return the name of the parent CTF container, if one exists. Otherwise 8830Sstevel@tonic-gate * return NULL to indicate this container is a root container. 8840Sstevel@tonic-gate */ 8850Sstevel@tonic-gate const char * 8860Sstevel@tonic-gate ctf_parent_name(ctf_file_t *fp) 8870Sstevel@tonic-gate { 8880Sstevel@tonic-gate return (fp->ctf_parname); 8890Sstevel@tonic-gate } 8900Sstevel@tonic-gate 8910Sstevel@tonic-gate /* 8920Sstevel@tonic-gate * Import the types from the specified parent container by storing a pointer 8930Sstevel@tonic-gate * to it in ctf_parent and incrementing its reference count. Only one parent 8940Sstevel@tonic-gate * is allowed: if a parent already exists, it is replaced by the new parent. 8950Sstevel@tonic-gate */ 8960Sstevel@tonic-gate int 8970Sstevel@tonic-gate ctf_import(ctf_file_t *fp, ctf_file_t *pfp) 8980Sstevel@tonic-gate { 8990Sstevel@tonic-gate if (fp == NULL || fp == pfp || (pfp != NULL && pfp->ctf_refcnt == 0)) 9000Sstevel@tonic-gate return (ctf_set_errno(fp, EINVAL)); 9010Sstevel@tonic-gate 9020Sstevel@tonic-gate if (pfp != NULL && pfp->ctf_dmodel != fp->ctf_dmodel) 9030Sstevel@tonic-gate return (ctf_set_errno(fp, ECTF_DMODEL)); 9040Sstevel@tonic-gate 9050Sstevel@tonic-gate if (fp->ctf_parent != NULL) 9060Sstevel@tonic-gate ctf_close(fp->ctf_parent); 9070Sstevel@tonic-gate 9080Sstevel@tonic-gate if (pfp != NULL) { 9090Sstevel@tonic-gate fp->ctf_flags |= LCTF_CHILD; 9100Sstevel@tonic-gate pfp->ctf_refcnt++; 9110Sstevel@tonic-gate } 9120Sstevel@tonic-gate 9130Sstevel@tonic-gate fp->ctf_parent = pfp; 9140Sstevel@tonic-gate return (0); 9150Sstevel@tonic-gate } 9160Sstevel@tonic-gate 9170Sstevel@tonic-gate /* 9180Sstevel@tonic-gate * Set the data model constant for the CTF container. 9190Sstevel@tonic-gate */ 9200Sstevel@tonic-gate int 9210Sstevel@tonic-gate ctf_setmodel(ctf_file_t *fp, int model) 9220Sstevel@tonic-gate { 9230Sstevel@tonic-gate const ctf_dmodel_t *dp; 9240Sstevel@tonic-gate 9250Sstevel@tonic-gate for (dp = _libctf_models; dp->ctd_name != NULL; dp++) { 9260Sstevel@tonic-gate if (dp->ctd_code == model) { 9270Sstevel@tonic-gate fp->ctf_dmodel = dp; 9280Sstevel@tonic-gate return (0); 9290Sstevel@tonic-gate } 9300Sstevel@tonic-gate } 9310Sstevel@tonic-gate 9320Sstevel@tonic-gate return (ctf_set_errno(fp, EINVAL)); 9330Sstevel@tonic-gate } 9340Sstevel@tonic-gate 9350Sstevel@tonic-gate /* 9360Sstevel@tonic-gate * Return the data model constant for the CTF container. 9370Sstevel@tonic-gate */ 9380Sstevel@tonic-gate int 9390Sstevel@tonic-gate ctf_getmodel(ctf_file_t *fp) 9400Sstevel@tonic-gate { 9410Sstevel@tonic-gate return (fp->ctf_dmodel->ctd_code); 9420Sstevel@tonic-gate } 9430Sstevel@tonic-gate 9440Sstevel@tonic-gate void 9450Sstevel@tonic-gate ctf_setspecific(ctf_file_t *fp, void *data) 9460Sstevel@tonic-gate { 9470Sstevel@tonic-gate fp->ctf_specific = data; 9480Sstevel@tonic-gate } 9490Sstevel@tonic-gate 9500Sstevel@tonic-gate void * 9510Sstevel@tonic-gate ctf_getspecific(ctf_file_t *fp) 9520Sstevel@tonic-gate { 9530Sstevel@tonic-gate return (fp->ctf_specific); 9540Sstevel@tonic-gate } 955