Path: blob/main/cddl/contrib/opensolaris/common/ctf/ctf_open.c
39507 views
/*1* CDDL HEADER START2*3* The contents of this file are subject to the terms of the4* Common Development and Distribution License, Version 1.0 only5* (the "License"). You may not use this file except in compliance6* with the License.7*8* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE9* or http://www.opensolaris.org/os/licensing.10* See the License for the specific language governing permissions11* and limitations under the License.12*13* When distributing Covered Code, include this CDDL HEADER in each14* file and include the License file at usr/src/OPENSOLARIS.LICENSE.15* If applicable, add the following below this CDDL HEADER, with the16* fields enclosed by brackets "[]" replaced with your own identifying17* information: Portions Copyright [yyyy] [name of copyright owner]18*19* CDDL HEADER END20*/2122/*23* Copyright 2006 Sun Microsystems, Inc. All rights reserved.24* Use is subject to license terms.25*/26/*27* Copyright (c) 2013, Joyent, Inc. All rights reserved.28*/2930#include <ctf_impl.h>31#include <sys/mman.h>32#include <sys/zmod.h>3334static const ctf_dmodel_t _libctf_models[] = {35{ "ILP32", CTF_MODEL_ILP32, 4, 1, 2, 4, 4 },36{ "LP64", CTF_MODEL_LP64, 8, 1, 2, 4, 8 },37{ NULL, 0, 0, 0, 0, 0, 0 }38};3940const char _CTF_SECTION[] = ".SUNW_ctf";41const char _CTF_NULLSTR[] = "";4243int _libctf_version = CTF_VERSION; /* library client version */44int _libctf_debug = 0; /* debugging messages enabled */4546static uint_t47get_kind_v2(uint_t info)48{49return (CTF_V2_INFO_KIND((ushort_t)info));50}5152static uint_t53get_root_v2(uint_t info)54{55return (CTF_V2_INFO_ISROOT((ushort_t)info));56}5758static uint_t59get_vlen_v2(uint_t info)60{61return (CTF_V2_INFO_VLEN((ushort_t)info));62}6364static uint_t65get_max_vlen_v2(void)66{67return (CTF_V2_MAX_VLEN);68}6970static uint_t71get_max_size_v2(void)72{73return (CTF_V2_MAX_SIZE);74}7576static uint_t77get_max_type_v2(void)78{79return (CTF_V2_MAX_TYPE);80}8182static uint_t83get_lsize_sent_v2(void)84{85return (CTF_V2_LSIZE_SENT);86}8788static uint_t89get_lstruct_thresh_v2(void)90{91return (CTF_V2_LSTRUCT_THRESH);92}9394static uint_t95type_info_v2(uint_t kind, uint_t isroot, uint_t len)96{97return (CTF_V2_TYPE_INFO(kind, isroot, len));98}99100static int101type_isparent_v2(uint_t id)102{103return (CTF_V2_TYPE_ISPARENT(id));104}105106static int107type_ischild_v2(uint_t id)108{109return (CTF_V2_TYPE_ISCHILD(id));110}111112static uint_t113type_to_index_v2(uint_t t)114{115return (CTF_V2_TYPE_TO_INDEX(t));116}117118static uint_t119index_to_type_v2(uint_t id, uint_t child)120{121return (CTF_V2_INDEX_TO_TYPE(id, child));122}123124static uint_t125get_kind_v3(uint_t info)126{127return (CTF_V3_INFO_KIND(info));128}129130static uint_t131get_root_v3(uint_t info)132{133return (CTF_V3_INFO_ISROOT(info));134}135136static uint_t137get_vlen_v3(uint_t info)138{139return (CTF_V3_INFO_VLEN(info));140}141142static uint_t143get_max_vlen_v3(void)144{145return (CTF_V3_MAX_VLEN);146}147148static uint_t149get_max_size_v3(void)150{151return (CTF_V3_MAX_SIZE);152}153154static uint_t155get_max_type_v3(void)156{157return (CTF_V3_MAX_TYPE);158}159160static uint_t161get_lsize_sent_v3(void)162{163return (CTF_V3_LSIZE_SENT);164}165166static uint_t167get_lstruct_thresh_v3(void)168{169return (CTF_V3_LSTRUCT_THRESH);170}171172static uint_t173type_info_v3(uint_t kind, uint_t isroot, uint_t len)174{175return (CTF_V3_TYPE_INFO(kind, isroot, len));176}177178static int179type_isparent_v3(uint_t id)180{181return (CTF_V3_TYPE_ISPARENT(id));182}183184static int185type_ischild_v3(uint_t id)186{187return (CTF_V3_TYPE_ISCHILD(id));188}189190static uint_t191type_to_index_v3(uint_t t)192{193return (CTF_V3_TYPE_TO_INDEX(t));194}195196static uint_t197index_to_type_v3(uint_t id, uint_t child)198{199return (CTF_V3_INDEX_TO_TYPE(id, child));200}201202#define CTF_FILEOPS_ENTRY(v) \203{ \204.ctfo_get_kind = get_kind_v ## v, \205.ctfo_get_root = get_root_v ## v, \206.ctfo_get_vlen = get_vlen_v ## v, \207.ctfo_get_max_vlen = get_max_vlen_v ## v, \208.ctfo_get_max_size = get_max_size_v ## v, \209.ctfo_get_max_type = get_max_type_v ## v, \210.ctfo_get_lsize_sent = get_lsize_sent_v ## v, \211.ctfo_get_lstruct_thresh = get_lstruct_thresh_v ## v, \212.ctfo_type_info = type_info_v ## v, \213.ctfo_type_isparent = type_isparent_v ## v, \214.ctfo_type_ischild = type_ischild_v ## v, \215.ctfo_type_to_index = type_to_index_v ## v, \216.ctfo_index_to_type = index_to_type_v ## v \217}218219static const ctf_fileops_t ctf_fileops[] = {220{ NULL, NULL },221{ NULL, NULL },222CTF_FILEOPS_ENTRY(2),223CTF_FILEOPS_ENTRY(3),224};225226/*227* Convert a 32-bit ELF symbol into GElf (Elf64) and return a pointer to it.228*/229static Elf64_Sym *230sym_to_gelf(const Elf32_Sym *src, Elf64_Sym *dst)231{232dst->st_name = src->st_name;233dst->st_value = src->st_value;234dst->st_size = src->st_size;235dst->st_info = src->st_info;236dst->st_other = src->st_other;237dst->st_shndx = src->st_shndx;238239return (dst);240}241242/*243* Initialize the symtab translation table by filling each entry with the244* offset of the CTF type or function data corresponding to each STT_FUNC or245* STT_OBJECT entry in the symbol table.246*/247static int248init_symtab(ctf_file_t *fp, const ctf_header_t *hp,249const ctf_sect_t *sp, const ctf_sect_t *strp)250{251const uchar_t *symp = sp->cts_data;252uint_t *xp = fp->ctf_sxlate;253uint_t *xend = xp + fp->ctf_nsyms;254255uint_t objtoff = hp->cth_objtoff;256uint_t funcoff = hp->cth_funcoff;257258uint_t info, vlen;259260Elf64_Sym sym, *gsp;261const char *name;262263/*264* The CTF data object and function type sections are ordered to match265* the relative order of the respective symbol types in the symtab.266* If no type information is available for a symbol table entry, a267* pad is inserted in the CTF section. As a further optimization,268* anonymous or undefined symbols are omitted from the CTF data.269*/270for (; xp < xend; xp++, symp += sp->cts_entsize) {271if (sp->cts_entsize == sizeof (Elf32_Sym))272gsp = sym_to_gelf((Elf32_Sym *)(uintptr_t)symp, &sym);273else274gsp = (Elf64_Sym *)(uintptr_t)symp;275276if (gsp->st_name < strp->cts_size)277name = (const char *)strp->cts_data + gsp->st_name;278else279name = _CTF_NULLSTR;280281if (gsp->st_name == 0 || gsp->st_shndx == SHN_UNDEF ||282strcmp(name, "_START_") == 0 ||283strcmp(name, "_END_") == 0) {284*xp = -1u;285continue;286}287288switch (ELF64_ST_TYPE(gsp->st_info)) {289case STT_OBJECT:290if (objtoff >= hp->cth_funcoff ||291(gsp->st_shndx == SHN_ABS && gsp->st_value == 0)) {292*xp = -1u;293break;294}295296*xp = objtoff;297objtoff += fp->ctf_idwidth;298break;299300case STT_FUNC:301if (funcoff >= hp->cth_typeoff) {302*xp = -1u;303break;304}305306*xp = funcoff;307308info = *(uint_t *)((uintptr_t)fp->ctf_buf + funcoff);309vlen = LCTF_INFO_VLEN(fp, info);310311/*312* If we encounter a zero pad at the end, just skip it.313* Otherwise skip over the function and its return type314* (+2) and the argument list (vlen).315*/316if (LCTF_INFO_KIND(fp, info) == CTF_K_UNKNOWN &&317vlen == 0)318funcoff += fp->ctf_idwidth;319else320funcoff +=321roundup2(fp->ctf_idwidth * (vlen + 2), 4);322break;323324default:325*xp = -1u;326break;327}328}329330ctf_dprintf("loaded %lu symtab entries\n", fp->ctf_nsyms);331return (0);332}333334/*335* Initialize the type ID translation table with the byte offset of each type,336* and initialize the hash tables of each named type.337*/338static int339init_types(ctf_file_t *fp, const ctf_header_t *cth)340{341const void *tbuf = (const void *)(fp->ctf_buf + cth->cth_typeoff);342const void *tend = (const void *)(fp->ctf_buf + cth->cth_stroff);343344ulong_t pop[CTF_K_MAX + 1] = { 0 };345const void *tp;346ctf_hash_t *hp;347uint_t id, dst;348uint_t *xp;349350/*351* We initially determine whether the container is a child or a parent352* based on the value of cth_parname. To support containers that pre-353* date cth_parname, we also scan the types themselves for references354* to values in the range reserved for child types in our first pass.355*/356int child = cth->cth_parname != 0;357int nlstructs = 0, nlunions = 0;358int err;359360/*361* We make two passes through the entire type section. In this first362* pass, we count the number of each type and the total number of types.363*/364for (tp = tbuf; tp < tend; fp->ctf_typemax++) {365ssize_t size, increment;366367size_t vbytes;368uint_t kind, n, type, vlen;369370(void) ctf_get_ctt_size(fp, tp, &size, &increment);371ctf_get_ctt_info(fp, tp, &kind, &vlen, NULL);372ctf_get_ctt_index(fp, tp, NULL, &type, NULL);373374switch (kind) {375case CTF_K_INTEGER:376case CTF_K_FLOAT:377vbytes = sizeof (uint_t);378break;379case CTF_K_ARRAY:380if (fp->ctf_version == CTF_VERSION_2)381vbytes = sizeof (struct ctf_array_v2);382else383vbytes = sizeof (struct ctf_array_v3);384break;385case CTF_K_FUNCTION:386vbytes = roundup2(fp->ctf_idwidth * vlen, 4);387break;388case CTF_K_STRUCT:389case CTF_K_UNION: {390size_t increment1;391uint_t type;392const void *mp =393(const void *)((uintptr_t)tp + increment);394395vbytes = 0;396for (n = vlen; n != 0; n--, mp += increment1) {397ctf_get_ctm_info(fp, mp, size, &increment1, &type,398NULL, NULL);399child |= LCTF_TYPE_ISCHILD(fp, type);400vbytes += increment1;401}402break;403}404case CTF_K_ENUM:405vbytes = sizeof (ctf_enum_t) * vlen;406break;407case CTF_K_FORWARD:408/*409* For forward declarations, ctt_type is the CTF_K_*410* kind for the tag, so bump that population count too.411* If ctt_type is unknown, treat the tag as a struct.412*/413if (type == CTF_K_UNKNOWN || type >= CTF_K_MAX)414pop[CTF_K_STRUCT]++;415else416pop[type]++;417/*FALLTHRU*/418case CTF_K_UNKNOWN:419vbytes = 0;420break;421case CTF_K_POINTER:422case CTF_K_TYPEDEF:423case CTF_K_VOLATILE:424case CTF_K_CONST:425case CTF_K_RESTRICT:426child |= LCTF_TYPE_ISCHILD(fp, type);427vbytes = 0;428break;429default:430ctf_dprintf("detected invalid CTF kind -- %u\n", kind);431return (ECTF_CORRUPT);432}433tp = (const void *)((uintptr_t)tp + increment + vbytes);434pop[kind]++;435}436437/*438* If we detected a reference to a child type ID, then we know this439* container is a child and may have a parent's types imported later.440*/441if (child) {442ctf_dprintf("CTF container %p is a child\n", (void *)fp);443fp->ctf_flags |= LCTF_CHILD;444} else445ctf_dprintf("CTF container %p is a parent\n", (void *)fp);446447/*448* Now that we've counted up the number of each type, we can allocate449* the hash tables, type translation table, and pointer table.450*/451if ((err = ctf_hash_create(&fp->ctf_structs, pop[CTF_K_STRUCT])) != 0)452return (err);453454if ((err = ctf_hash_create(&fp->ctf_unions, pop[CTF_K_UNION])) != 0)455return (err);456457if ((err = ctf_hash_create(&fp->ctf_enums, pop[CTF_K_ENUM])) != 0)458return (err);459460if ((err = ctf_hash_create(&fp->ctf_names,461pop[CTF_K_INTEGER] + pop[CTF_K_FLOAT] + pop[CTF_K_FUNCTION] +462pop[CTF_K_TYPEDEF] + pop[CTF_K_POINTER] + pop[CTF_K_VOLATILE] +463pop[CTF_K_CONST] + pop[CTF_K_RESTRICT])) != 0)464return (err);465466fp->ctf_txlate = ctf_alloc(sizeof (uint_t) * (fp->ctf_typemax + 1));467fp->ctf_ptrtab = ctf_alloc(sizeof (uint_t) * (fp->ctf_typemax + 1));468469if (fp->ctf_txlate == NULL || fp->ctf_ptrtab == NULL)470return (EAGAIN); /* memory allocation failed */471472xp = fp->ctf_txlate;473*xp++ = 0; /* type id 0 is used as a sentinel value */474475bzero(fp->ctf_txlate, sizeof (uint_t) * (fp->ctf_typemax + 1));476bzero(fp->ctf_ptrtab, sizeof (uint_t) * (fp->ctf_typemax + 1));477478/*479* In the second pass through the types, we fill in each entry of the480* type and pointer tables and add names to the appropriate hashes.481*/482for (id = 1, tp = tbuf; tp < tend; xp++, id++) {483const struct ctf_type_v3 *ctt = tp;484uint_t kind, type, vlen;485ssize_t size, increment;486487const char *name;488size_t vbytes;489ctf_helem_t *hep;490ctf_encoding_t cte;491492(void) ctf_get_ctt_size(fp, tp, &size, &increment);493ctf_get_ctt_info(fp, tp, &kind, &vlen, NULL);494ctf_get_ctt_index(fp, tp, NULL, &type, NULL);495name = ctf_type_rname(fp, tp);496497switch (kind) {498case CTF_K_INTEGER:499case CTF_K_FLOAT:500/*501* Only insert a new integer base type definition if502* this type name has not been defined yet. We re-use503* the names with different encodings for bit-fields.504*/505if ((hep = ctf_hash_lookup(&fp->ctf_names, fp,506name, strlen(name))) == NULL) {507err = ctf_hash_insert(&fp->ctf_names, fp,508LCTF_INDEX_TO_TYPE(fp, id, child),509ctt->ctt_name);510if (err != 0 && err != ECTF_STRTAB)511return (err);512} else if (ctf_type_encoding(fp, hep->h_type,513&cte) == 0 && cte.cte_bits == 0) {514/*515* Work-around SOS8 stabs bug: replace existing516* intrinsic w/ same name if it was zero bits.517*/518hep->h_type = LCTF_INDEX_TO_TYPE(fp, id, child);519}520vbytes = sizeof (uint_t);521break;522523case CTF_K_ARRAY:524if (fp->ctf_version == CTF_VERSION_2)525vbytes = sizeof (struct ctf_array_v2);526else527vbytes = sizeof (struct ctf_array_v3);528break;529530case CTF_K_FUNCTION:531err = ctf_hash_insert(&fp->ctf_names, fp,532LCTF_INDEX_TO_TYPE(fp, id, child), ctt->ctt_name);533if (err != 0 && err != ECTF_STRTAB)534return (err);535vbytes = roundup2(fp->ctf_idwidth * vlen, 4);536break;537538case CTF_K_STRUCT:539err = ctf_hash_define(&fp->ctf_structs, fp,540LCTF_INDEX_TO_TYPE(fp, id, child), ctt->ctt_name);541542if (err != 0 && err != ECTF_STRTAB)543return (err);544545if (fp->ctf_version == CTF_VERSION_2) {546if (size < LCTF_LSTRUCT_THRESH(fp))547vbytes = sizeof (struct ctf_member_v2) *548vlen;549else {550vbytes =551sizeof (struct ctf_lmember_v2) *552vlen;553nlstructs++;554}555} else {556if (size < LCTF_LSTRUCT_THRESH(fp))557vbytes = sizeof (struct ctf_member_v3) *558vlen;559else {560vbytes =561sizeof (struct ctf_lmember_v3) *562vlen;563nlstructs++;564}565}566break;567568case CTF_K_UNION:569err = ctf_hash_define(&fp->ctf_unions, fp,570LCTF_INDEX_TO_TYPE(fp, id, child), ctt->ctt_name);571572if (err != 0 && err != ECTF_STRTAB)573return (err);574575if (fp->ctf_version == CTF_VERSION_2) {576if (size < LCTF_LSTRUCT_THRESH(fp))577vbytes = sizeof (struct ctf_member_v2) *578vlen;579else {580vbytes =581sizeof (struct ctf_lmember_v2) *582vlen;583nlunions++;584}585} else {586if (size < LCTF_LSTRUCT_THRESH(fp))587vbytes = sizeof (struct ctf_member_v3) *588vlen;589else {590vbytes =591sizeof (struct ctf_lmember_v3) *592vlen;593nlunions++;594}595}596break;597598case CTF_K_ENUM:599err = ctf_hash_define(&fp->ctf_enums, fp,600LCTF_INDEX_TO_TYPE(fp, id, child), ctt->ctt_name);601602if (err != 0 && err != ECTF_STRTAB)603return (err);604605vbytes = sizeof (ctf_enum_t) * vlen;606break;607608case CTF_K_TYPEDEF:609err = ctf_hash_insert(&fp->ctf_names, fp,610LCTF_INDEX_TO_TYPE(fp, id, child), ctt->ctt_name);611if (err != 0 && err != ECTF_STRTAB)612return (err);613vbytes = 0;614break;615616case CTF_K_FORWARD:617/*618* Only insert forward tags into the given hash if the619* type or tag name is not already present.620*/621switch (type) {622case CTF_K_STRUCT:623hp = &fp->ctf_structs;624break;625case CTF_K_UNION:626hp = &fp->ctf_unions;627break;628case CTF_K_ENUM:629hp = &fp->ctf_enums;630break;631default:632hp = &fp->ctf_structs;633}634635if (ctf_hash_lookup(hp, fp,636name, strlen(name)) == NULL) {637err = ctf_hash_insert(hp, fp,638LCTF_INDEX_TO_TYPE(fp, id, child),639ctt->ctt_name);640if (err != 0 && err != ECTF_STRTAB)641return (err);642}643vbytes = 0;644break;645646case CTF_K_POINTER:647/*648* If the type referenced by the pointer is in this CTF649* container, then store the index of the pointer type650* in fp->ctf_ptrtab[ index of referenced type ].651*/652if (LCTF_TYPE_ISCHILD(fp, type) == child &&653LCTF_TYPE_TO_INDEX(fp, type) <= fp->ctf_typemax)654fp->ctf_ptrtab[655LCTF_TYPE_TO_INDEX(fp, type)] = id;656/*FALLTHRU*/657658case CTF_K_VOLATILE:659case CTF_K_CONST:660case CTF_K_RESTRICT:661err = ctf_hash_insert(&fp->ctf_names, fp,662LCTF_INDEX_TO_TYPE(fp, id, child), ctt->ctt_name);663if (err != 0 && err != ECTF_STRTAB)664return (err);665/*FALLTHRU*/666667default:668vbytes = 0;669break;670}671672*xp = (uint_t)((uintptr_t)tp - (uintptr_t)fp->ctf_buf);673tp = (const void *)((uintptr_t)tp + increment + vbytes);674}675676ctf_dprintf("%lu total types processed\n", fp->ctf_typemax);677ctf_dprintf("%u enum names hashed\n", ctf_hash_size(&fp->ctf_enums));678ctf_dprintf("%u struct names hashed (%d long)\n",679ctf_hash_size(&fp->ctf_structs), nlstructs);680ctf_dprintf("%u union names hashed (%d long)\n",681ctf_hash_size(&fp->ctf_unions), nlunions);682ctf_dprintf("%u base type names hashed\n",683ctf_hash_size(&fp->ctf_names));684685/*686* Make an additional pass through the pointer table to find pointers687* that point to anonymous typedef nodes. If we find one, modify the688* pointer table so that the pointer is also known to point to the689* node that is referenced by the anonymous typedef node.690*/691for (id = 1; id <= fp->ctf_typemax; id++) {692if ((dst = fp->ctf_ptrtab[id]) != 0) {693uint_t index, kind;694int ischild;695696tp = LCTF_INDEX_TO_TYPEPTR(fp, id);697ctf_get_ctt_info(fp, tp, &kind, NULL, NULL);698ctf_get_ctt_index(fp, tp, &index, NULL, &ischild);699700if (kind == CTF_K_TYPEDEF &&701strcmp(ctf_type_rname(fp, tp), "") == 0 &&702ischild == child && index <= fp->ctf_typemax)703fp->ctf_ptrtab[index] = dst;704}705}706707return (0);708}709710/*711* Decode the specified CTF buffer and optional symbol table and create a new712* CTF container representing the symbolic debugging information. This code713* can be used directly by the debugger, or it can be used as the engine for714* ctf_fdopen() or ctf_open(), below.715*/716ctf_file_t *717ctf_bufopen(const ctf_sect_t *ctfsect, const ctf_sect_t *symsect,718const ctf_sect_t *strsect, int *errp)719{720const ctf_preamble_t *pp;721ctf_header_t hp;722ctf_file_t *fp;723void *buf, *base;724size_t size, hdrsz;725int err;726727if (ctfsect == NULL || ((symsect == NULL) != (strsect == NULL)))728return (ctf_set_open_errno(errp, EINVAL));729730if (symsect != NULL && symsect->cts_entsize != sizeof (Elf32_Sym) &&731symsect->cts_entsize != sizeof (Elf64_Sym))732return (ctf_set_open_errno(errp, ECTF_SYMTAB));733734if (symsect != NULL && symsect->cts_data == NULL)735return (ctf_set_open_errno(errp, ECTF_SYMBAD));736737if (strsect != NULL && strsect->cts_data == NULL)738return (ctf_set_open_errno(errp, ECTF_STRBAD));739740if (ctfsect->cts_size < sizeof (ctf_preamble_t))741return (ctf_set_open_errno(errp, ECTF_NOCTFBUF));742743pp = (const ctf_preamble_t *)ctfsect->cts_data;744745ctf_dprintf("ctf_bufopen: magic=0x%x version=%u\n",746pp->ctp_magic, pp->ctp_version);747748/*749* Validate each part of the CTF header (either V1 or V2).750* First, we validate the preamble (common to all versions). At that751* point, we know specific header version, and can validate the752* version-specific parts including section offsets and alignments.753*/754if (pp->ctp_magic != CTF_MAGIC)755return (ctf_set_open_errno(errp, ECTF_NOCTFBUF));756757if (pp->ctp_version == CTF_VERSION_2 ||758pp->ctp_version == CTF_VERSION_3) {759if (ctfsect->cts_size < sizeof (ctf_header_t))760return (ctf_set_open_errno(errp, ECTF_NOCTFBUF));761762bcopy(ctfsect->cts_data, &hp, sizeof (hp));763hdrsz = sizeof (ctf_header_t);764765} else766return (ctf_set_open_errno(errp, ECTF_CTFVERS));767768size = hp.cth_stroff + hp.cth_strlen;769770ctf_dprintf("ctf_bufopen: uncompressed size=%lu\n", (ulong_t)size);771772if (hp.cth_lbloff > size || hp.cth_objtoff > size ||773hp.cth_funcoff > size || hp.cth_typeoff > size ||774hp.cth_stroff > size)775return (ctf_set_open_errno(errp, ECTF_CORRUPT));776777if (hp.cth_lbloff > hp.cth_objtoff ||778hp.cth_objtoff > hp.cth_funcoff ||779hp.cth_funcoff > hp.cth_typeoff ||780hp.cth_typeoff > hp.cth_stroff)781return (ctf_set_open_errno(errp, ECTF_CORRUPT));782783if ((hp.cth_lbloff & 3) || (hp.cth_objtoff & 1) ||784(hp.cth_funcoff & 1) || (hp.cth_typeoff & 3))785return (ctf_set_open_errno(errp, ECTF_CORRUPT));786787/*788* Once everything is determined to be valid, attempt to decompress789* the CTF data buffer if it is compressed. Otherwise we just put790* the data section's buffer pointer into ctf_buf, below.791*/792if (hp.cth_flags & CTF_F_COMPRESS) {793size_t srclen, dstlen;794const void *src;795int rc = Z_OK;796797if (ctf_zopen(errp) == NULL)798return (NULL); /* errp is set for us */799800if ((base = ctf_data_alloc(size + hdrsz)) == MAP_FAILED)801return (ctf_set_open_errno(errp, ECTF_ZALLOC));802803bcopy(ctfsect->cts_data, base, hdrsz);804((ctf_preamble_t *)base)->ctp_flags &= ~CTF_F_COMPRESS;805buf = (uchar_t *)base + hdrsz;806807src = (uchar_t *)ctfsect->cts_data + hdrsz;808srclen = ctfsect->cts_size - hdrsz;809dstlen = size;810811if ((rc = z_uncompress(buf, &dstlen, src, srclen)) != Z_OK) {812ctf_dprintf("zlib inflate err: %s\n", z_strerror(rc));813ctf_data_free(base, size + hdrsz);814return (ctf_set_open_errno(errp, ECTF_DECOMPRESS));815}816817if (dstlen != size) {818ctf_dprintf("zlib inflate short -- got %lu of %lu "819"bytes\n", (ulong_t)dstlen, (ulong_t)size);820ctf_data_free(base, size + hdrsz);821return (ctf_set_open_errno(errp, ECTF_CORRUPT));822}823824ctf_data_protect(base, size + hdrsz);825826} else {827base = (void *)ctfsect->cts_data;828buf = (uchar_t *)base + hdrsz;829}830831/*832* Once we have uncompressed and validated the CTF data buffer, we can833* proceed with allocating a ctf_file_t and initializing it.834*/835if ((fp = ctf_alloc(sizeof (ctf_file_t))) == NULL)836return (ctf_set_open_errno(errp, EAGAIN));837838bzero(fp, sizeof (ctf_file_t));839fp->ctf_version = hp.cth_version;840fp->ctf_idwidth = fp->ctf_version == CTF_VERSION_2 ? 2 : 4;841fp->ctf_fileops = &ctf_fileops[hp.cth_version];842bcopy(ctfsect, &fp->ctf_data, sizeof (ctf_sect_t));843844if (symsect != NULL) {845bcopy(symsect, &fp->ctf_symtab, sizeof (ctf_sect_t));846bcopy(strsect, &fp->ctf_strtab, sizeof (ctf_sect_t));847}848849if (fp->ctf_data.cts_name != NULL)850fp->ctf_data.cts_name = ctf_strdup(fp->ctf_data.cts_name);851if (fp->ctf_symtab.cts_name != NULL)852fp->ctf_symtab.cts_name = ctf_strdup(fp->ctf_symtab.cts_name);853if (fp->ctf_strtab.cts_name != NULL)854fp->ctf_strtab.cts_name = ctf_strdup(fp->ctf_strtab.cts_name);855856if (fp->ctf_data.cts_name == NULL)857fp->ctf_data.cts_name = _CTF_NULLSTR;858if (fp->ctf_symtab.cts_name == NULL)859fp->ctf_symtab.cts_name = _CTF_NULLSTR;860if (fp->ctf_strtab.cts_name == NULL)861fp->ctf_strtab.cts_name = _CTF_NULLSTR;862863fp->ctf_str[CTF_STRTAB_0].cts_strs = (const char *)buf + hp.cth_stroff;864fp->ctf_str[CTF_STRTAB_0].cts_len = hp.cth_strlen;865866if (strsect != NULL) {867fp->ctf_str[CTF_STRTAB_1].cts_strs = strsect->cts_data;868fp->ctf_str[CTF_STRTAB_1].cts_len = strsect->cts_size;869}870871fp->ctf_base = base;872fp->ctf_buf = buf;873fp->ctf_size = size + hdrsz;874875/*876* If we have a parent container name and label, store the relocated877* string pointers in the CTF container for easy access later.878*/879if (hp.cth_parlabel != 0)880fp->ctf_parlabel = ctf_strptr(fp, hp.cth_parlabel);881if (hp.cth_parname != 0)882fp->ctf_parname = ctf_strptr(fp, hp.cth_parname);883884ctf_dprintf("ctf_bufopen: parent name %s (label %s)\n",885fp->ctf_parname ? fp->ctf_parname : "<NULL>",886fp->ctf_parlabel ? fp->ctf_parlabel : "<NULL>");887888/*889* If we have a symbol table section, allocate and initialize890* the symtab translation table, pointed to by ctf_sxlate.891*/892if (symsect != NULL) {893fp->ctf_nsyms = symsect->cts_size / symsect->cts_entsize;894fp->ctf_sxlate = ctf_alloc(fp->ctf_nsyms * sizeof (uint_t));895896if (fp->ctf_sxlate == NULL) {897(void) ctf_set_open_errno(errp, EAGAIN);898goto bad;899}900901if ((err = init_symtab(fp, &hp, symsect, strsect)) != 0) {902(void) ctf_set_open_errno(errp, err);903goto bad;904}905}906907if ((err = init_types(fp, &hp)) != 0) {908(void) ctf_set_open_errno(errp, err);909goto bad;910}911912/*913* Initialize the ctf_lookup_by_name top-level dictionary. We keep an914* array of type name prefixes and the corresponding ctf_hash to use.915* NOTE: This code must be kept in sync with the code in ctf_update().916*/917fp->ctf_lookups[0].ctl_prefix = "struct";918fp->ctf_lookups[0].ctl_len = strlen(fp->ctf_lookups[0].ctl_prefix);919fp->ctf_lookups[0].ctl_hash = &fp->ctf_structs;920fp->ctf_lookups[1].ctl_prefix = "union";921fp->ctf_lookups[1].ctl_len = strlen(fp->ctf_lookups[1].ctl_prefix);922fp->ctf_lookups[1].ctl_hash = &fp->ctf_unions;923fp->ctf_lookups[2].ctl_prefix = "enum";924fp->ctf_lookups[2].ctl_len = strlen(fp->ctf_lookups[2].ctl_prefix);925fp->ctf_lookups[2].ctl_hash = &fp->ctf_enums;926fp->ctf_lookups[3].ctl_prefix = _CTF_NULLSTR;927fp->ctf_lookups[3].ctl_len = strlen(fp->ctf_lookups[3].ctl_prefix);928fp->ctf_lookups[3].ctl_hash = &fp->ctf_names;929fp->ctf_lookups[4].ctl_prefix = NULL;930fp->ctf_lookups[4].ctl_len = 0;931fp->ctf_lookups[4].ctl_hash = NULL;932933if (symsect != NULL) {934if (symsect->cts_entsize == sizeof (Elf64_Sym))935(void) ctf_setmodel(fp, CTF_MODEL_LP64);936else937(void) ctf_setmodel(fp, CTF_MODEL_ILP32);938} else939(void) ctf_setmodel(fp, CTF_MODEL_NATIVE);940941fp->ctf_refcnt = 1;942return (fp);943944bad:945ctf_close(fp);946return (NULL);947}948949/*950* Dupliate a ctf_file_t and its underlying section information into a new951* container. This works by copying the three ctf_sect_t's of the original952* container if they exist and passing those into ctf_bufopen. To copy those, we953* mmap anonymous memory with ctf_data_alloc and bcopy the data across. It's not954* the cheapest thing, but it's what we've got.955*/956ctf_file_t *957ctf_dup(ctf_file_t *ofp)958{959ctf_file_t *fp;960ctf_sect_t ctfsect, symsect, strsect;961ctf_sect_t *ctp, *symp, *strp;962void *cbuf, *symbuf, *strbuf;963int err;964965cbuf = symbuf = strbuf = NULL;966/*967* The ctfsect isn't allowed to not exist, but the symbol and string968* section might not. We only need to copy the data of the section, not969* the name, as ctf_bufopen will take care of that.970*/971bcopy(&ofp->ctf_data, &ctfsect, sizeof (ctf_sect_t));972cbuf = ctf_data_alloc(ctfsect.cts_size);973if (cbuf == NULL) {974(void) ctf_set_errno(ofp, ECTF_MMAP);975return (NULL);976}977978bcopy(ctfsect.cts_data, cbuf, ctfsect.cts_size);979ctf_data_protect(cbuf, ctfsect.cts_size);980ctfsect.cts_data = cbuf;981ctfsect.cts_offset = 0;982ctp = &ctfsect;983984if (ofp->ctf_symtab.cts_data != NULL) {985bcopy(&ofp->ctf_symtab, &symsect, sizeof (ctf_sect_t));986symbuf = ctf_data_alloc(symsect.cts_size);987if (symbuf == NULL) {988(void) ctf_set_errno(ofp, ECTF_MMAP);989goto err;990}991bcopy(symsect.cts_data, symbuf, symsect.cts_size);992ctf_data_protect(symbuf, symsect.cts_size);993symsect.cts_data = symbuf;994symsect.cts_offset = 0;995symp = &symsect;996} else {997symp = NULL;998}9991000if (ofp->ctf_strtab.cts_data != NULL) {1001bcopy(&ofp->ctf_strtab, &strsect, sizeof (ctf_sect_t));1002strbuf = ctf_data_alloc(strsect.cts_size);1003if (strbuf == NULL) {1004(void) ctf_set_errno(ofp, ECTF_MMAP);1005goto err;1006}1007bcopy(strsect.cts_data, strbuf, strsect.cts_size);1008ctf_data_protect(strbuf, strsect.cts_size);1009strsect.cts_data = strbuf;1010strsect.cts_offset = 0;1011strp = &strsect;1012} else {1013strp = NULL;1014}10151016fp = ctf_bufopen(ctp, symp, strp, &err);1017if (fp == NULL) {1018(void) ctf_set_errno(ofp, err);1019goto err;1020}10211022fp->ctf_flags |= LCTF_MMAP;10231024return (fp);10251026err:1027ctf_data_free(cbuf, ctfsect.cts_size);1028if (symbuf != NULL)1029ctf_data_free(symbuf, symsect.cts_size);1030if (strbuf != NULL)1031ctf_data_free(strbuf, strsect.cts_size);1032return (NULL);1033}10341035/*1036* Close the specified CTF container and free associated data structures. Note1037* that ctf_close() is a reference counted operation: if the specified file is1038* the parent of other active containers, its reference count will be greater1039* than one and it will be freed later when no active children exist.1040*/1041void1042ctf_close(ctf_file_t *fp)1043{1044ctf_dtdef_t *dtd, *ntd;10451046if (fp == NULL)1047return; /* allow ctf_close(NULL) to simplify caller code */10481049ctf_dprintf("ctf_close(%p) refcnt=%u\n", (void *)fp, fp->ctf_refcnt);10501051if (fp->ctf_refcnt > 1) {1052fp->ctf_refcnt--;1053return;1054}10551056if (fp->ctf_parent != NULL)1057ctf_close(fp->ctf_parent);10581059/*1060* Note, to work properly with reference counting on the dynamic1061* section, we must delete the list in reverse.1062*/1063for (dtd = ctf_list_prev(&fp->ctf_dtdefs); dtd != NULL; dtd = ntd) {1064ntd = ctf_list_prev(dtd);1065ctf_dtd_delete(fp, dtd);1066}10671068ctf_free(fp->ctf_dthash, fp->ctf_dthashlen * sizeof (ctf_dtdef_t *));10691070if (fp->ctf_flags & LCTF_MMAP) {1071if (fp->ctf_data.cts_data != NULL)1072ctf_sect_munmap(&fp->ctf_data);1073if (fp->ctf_symtab.cts_data != NULL)1074ctf_sect_munmap(&fp->ctf_symtab);1075if (fp->ctf_strtab.cts_data != NULL)1076ctf_sect_munmap(&fp->ctf_strtab);1077}10781079if (fp->ctf_data.cts_name != _CTF_NULLSTR &&1080fp->ctf_data.cts_name != NULL) {1081ctf_free((char *)fp->ctf_data.cts_name,1082strlen(fp->ctf_data.cts_name) + 1);1083}10841085if (fp->ctf_symtab.cts_name != _CTF_NULLSTR &&1086fp->ctf_symtab.cts_name != NULL) {1087ctf_free((char *)fp->ctf_symtab.cts_name,1088strlen(fp->ctf_symtab.cts_name) + 1);1089}10901091if (fp->ctf_strtab.cts_name != _CTF_NULLSTR &&1092fp->ctf_strtab.cts_name != NULL) {1093ctf_free((char *)fp->ctf_strtab.cts_name,1094strlen(fp->ctf_strtab.cts_name) + 1);1095}10961097if (fp->ctf_base != fp->ctf_data.cts_data && fp->ctf_base != NULL)1098ctf_data_free((void *)fp->ctf_base, fp->ctf_size);10991100if (fp->ctf_sxlate != NULL)1101ctf_free(fp->ctf_sxlate, sizeof (uint_t) * fp->ctf_nsyms);11021103if (fp->ctf_txlate != NULL) {1104ctf_free(fp->ctf_txlate,1105sizeof (uint_t) * (fp->ctf_typemax + 1));1106}11071108if (fp->ctf_ptrtab != NULL) {1109ctf_free(fp->ctf_ptrtab,1110sizeof (uint_t) * (fp->ctf_typemax + 1));1111}11121113ctf_hash_destroy(&fp->ctf_structs);1114ctf_hash_destroy(&fp->ctf_unions);1115ctf_hash_destroy(&fp->ctf_enums);1116ctf_hash_destroy(&fp->ctf_names);11171118ctf_free(fp, sizeof (ctf_file_t));1119}11201121/*1122* Return the CTF handle for the parent CTF container, if one exists.1123* Otherwise return NULL to indicate this container has no imported parent.1124*/1125ctf_file_t *1126ctf_parent_file(ctf_file_t *fp)1127{1128return (fp->ctf_parent);1129}11301131/*1132* Return the name of the parent CTF container, if one exists. Otherwise1133* return NULL to indicate this container is a root container.1134*/1135const char *1136ctf_parent_name(ctf_file_t *fp)1137{1138return (fp->ctf_parname);1139}11401141/*1142* Import the types from the specified parent container by storing a pointer1143* to it in ctf_parent and incrementing its reference count. Only one parent1144* is allowed: if a parent already exists, it is replaced by the new parent.1145*/1146int1147ctf_import(ctf_file_t *fp, ctf_file_t *pfp)1148{1149if (fp == NULL || fp == pfp || (pfp != NULL && pfp->ctf_refcnt == 0))1150return (ctf_set_errno(fp, EINVAL));11511152if (pfp != NULL && pfp->ctf_dmodel != fp->ctf_dmodel)1153return (ctf_set_errno(fp, ECTF_DMODEL));11541155if (fp->ctf_parent != NULL)1156ctf_close(fp->ctf_parent);11571158if (pfp != NULL) {1159fp->ctf_flags |= LCTF_CHILD;1160pfp->ctf_refcnt++;1161}11621163fp->ctf_parent = pfp;1164return (0);1165}11661167/*1168* Set the data model constant for the CTF container.1169*/1170int1171ctf_setmodel(ctf_file_t *fp, int model)1172{1173const ctf_dmodel_t *dp;11741175for (dp = _libctf_models; dp->ctd_name != NULL; dp++) {1176if (dp->ctd_code == model) {1177fp->ctf_dmodel = dp;1178return (0);1179}1180}11811182return (ctf_set_errno(fp, EINVAL));1183}11841185/*1186* Return the data model constant for the CTF container.1187*/1188int1189ctf_getmodel(ctf_file_t *fp)1190{1191return (fp->ctf_dmodel->ctd_code);1192}11931194void1195ctf_setspecific(ctf_file_t *fp, void *data)1196{1197fp->ctf_specific = data;1198}11991200void *1201ctf_getspecific(ctf_file_t *fp)1202{1203return (fp->ctf_specific);1204}120512061207