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