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 */ 27178525Sjb 28178525Sjb#ifndef _CTF_IMPL_H 29178525Sjb#define _CTF_IMPL_H 30178525Sjb 31178525Sjb#pragma ident "%Z%%M% %I% %E% SMI" 32178525Sjb 33178525Sjb#include <sys/types.h> 34178525Sjb#include <sys/errno.h> 35178525Sjb#include <sys/sysmacros.h> 36178525Sjb#include <sys/ctf_api.h> 37178525Sjb 38178525Sjb#ifdef _KERNEL 39178525Sjb 40178525Sjb#include <sys/systm.h> 41178525Sjb#include <sys/cmn_err.h> 42178525Sjb#include <sys/varargs.h> 43178525Sjb 44178525Sjb#define isspace(c) \ 45178525Sjb ((c) == ' ' || (c) == '\t' || (c) == '\n' || \ 46178525Sjb (c) == '\r' || (c) == '\f' || (c) == '\v') 47178525Sjb 48178525Sjb#define MAP_FAILED ((void *)-1) 49178525Sjb 50178525Sjb#else /* _KERNEL */ 51178525Sjb 52178525Sjb#include <strings.h> 53178525Sjb#include <stdlib.h> 54178525Sjb#include <stdarg.h> 55178525Sjb#include <stdio.h> 56178525Sjb#include <limits.h> 57178525Sjb#include <ctype.h> 58178525Sjb 59178525Sjb#endif /* _KERNEL */ 60178525Sjb 61178525Sjb#ifdef __cplusplus 62178525Sjbextern "C" { 63178525Sjb#endif 64178525Sjb 65178525Sjbtypedef struct ctf_helem { 66178525Sjb uint_t h_name; /* reference to name in string table */ 67178525Sjb ushort_t h_type; /* corresponding type ID number */ 68178525Sjb ushort_t h_next; /* index of next element in hash chain */ 69178525Sjb} ctf_helem_t; 70178525Sjb 71178525Sjbtypedef struct ctf_hash { 72178525Sjb ushort_t *h_buckets; /* hash bucket array (chain indices) */ 73178525Sjb ctf_helem_t *h_chains; /* hash chains buffer */ 74178525Sjb ushort_t h_nbuckets; /* number of elements in bucket array */ 75178525Sjb ushort_t h_nelems; /* number of elements in hash table */ 76178525Sjb uint_t h_free; /* index of next free hash element */ 77178525Sjb} ctf_hash_t; 78178525Sjb 79178525Sjbtypedef struct ctf_strs { 80178525Sjb const char *cts_strs; /* base address of string table */ 81178525Sjb size_t cts_len; /* size of string table in bytes */ 82178525Sjb} ctf_strs_t; 83178525Sjb 84178525Sjbtypedef struct ctf_dmodel { 85178525Sjb const char *ctd_name; /* data model name */ 86178525Sjb int ctd_code; /* data model code */ 87178525Sjb size_t ctd_pointer; /* size of void * in bytes */ 88178525Sjb size_t ctd_char; /* size of char in bytes */ 89178525Sjb size_t ctd_short; /* size of short in bytes */ 90178525Sjb size_t ctd_int; /* size of int in bytes */ 91178525Sjb size_t ctd_long; /* size of long in bytes */ 92178525Sjb} ctf_dmodel_t; 93178525Sjb 94178525Sjbtypedef struct ctf_lookup { 95178525Sjb const char *ctl_prefix; /* string prefix for this lookup */ 96178525Sjb size_t ctl_len; /* length of prefix string in bytes */ 97178525Sjb ctf_hash_t *ctl_hash; /* pointer to hash table for lookup */ 98178525Sjb} ctf_lookup_t; 99178525Sjb 100178525Sjbtypedef struct ctf_fileops { 101178525Sjb ushort_t (*ctfo_get_kind)(ushort_t); 102178525Sjb ushort_t (*ctfo_get_root)(ushort_t); 103178525Sjb ushort_t (*ctfo_get_vlen)(ushort_t); 104178525Sjb} ctf_fileops_t; 105178525Sjb 106178525Sjbtypedef struct ctf_list { 107178525Sjb struct ctf_list *l_prev; /* previous pointer or tail pointer */ 108178525Sjb struct ctf_list *l_next; /* next pointer or head pointer */ 109178525Sjb} ctf_list_t; 110178525Sjb 111178525Sjbtypedef enum { 112178525Sjb CTF_PREC_BASE, 113178525Sjb CTF_PREC_POINTER, 114178525Sjb CTF_PREC_ARRAY, 115178525Sjb CTF_PREC_FUNCTION, 116178525Sjb CTF_PREC_MAX 117178525Sjb} ctf_decl_prec_t; 118178525Sjb 119178525Sjbtypedef struct ctf_decl_node { 120178525Sjb ctf_list_t cd_list; /* linked list pointers */ 121178525Sjb ctf_id_t cd_type; /* type identifier */ 122178525Sjb uint_t cd_kind; /* type kind */ 123178525Sjb uint_t cd_n; /* type dimension if array */ 124178525Sjb} ctf_decl_node_t; 125178525Sjb 126178525Sjbtypedef struct ctf_decl { 127178525Sjb ctf_list_t cd_nodes[CTF_PREC_MAX]; /* declaration node stacks */ 128178525Sjb int cd_order[CTF_PREC_MAX]; /* storage order of decls */ 129178525Sjb ctf_decl_prec_t cd_qualp; /* qualifier precision */ 130178525Sjb ctf_decl_prec_t cd_ordp; /* ordered precision */ 131178525Sjb char *cd_buf; /* buffer for output */ 132178525Sjb char *cd_ptr; /* buffer location */ 133178525Sjb char *cd_end; /* buffer limit */ 134178525Sjb size_t cd_len; /* buffer space required */ 135178525Sjb int cd_err; /* saved error value */ 136178525Sjb} ctf_decl_t; 137178525Sjb 138178525Sjbtypedef struct ctf_dmdef { 139178525Sjb ctf_list_t dmd_list; /* list forward/back pointers */ 140178525Sjb char *dmd_name; /* name of this member */ 141178525Sjb ctf_id_t dmd_type; /* type of this member (for sou) */ 142178525Sjb ulong_t dmd_offset; /* offset of this member in bits (for sou) */ 143178525Sjb int dmd_value; /* value of this member (for enum) */ 144178525Sjb} ctf_dmdef_t; 145178525Sjb 146178525Sjbtypedef struct ctf_dtdef { 147178525Sjb ctf_list_t dtd_list; /* list forward/back pointers */ 148178525Sjb struct ctf_dtdef *dtd_hash; /* hash chain pointer for ctf_dthash */ 149178525Sjb char *dtd_name; /* name associated with definition (if any) */ 150178525Sjb ctf_id_t dtd_type; /* type identifier for this definition */ 151178525Sjb ctf_type_t dtd_data; /* type node (see <sys/ctf.h>) */ 152178525Sjb union { 153178525Sjb ctf_list_t dtu_members; /* struct, union, or enum */ 154178525Sjb ctf_arinfo_t dtu_arr; /* array */ 155178525Sjb ctf_encoding_t dtu_enc; /* integer or float */ 156178525Sjb ctf_id_t *dtu_argv; /* function */ 157178525Sjb } dtd_u; 158178525Sjb} ctf_dtdef_t; 159178525Sjb 160178525Sjbtypedef struct ctf_bundle { 161178525Sjb ctf_file_t *ctb_file; /* CTF container handle */ 162178525Sjb ctf_id_t ctb_type; /* CTF type identifier */ 163178525Sjb ctf_dtdef_t *ctb_dtd; /* CTF dynamic type definition (if any) */ 164178525Sjb} ctf_bundle_t; 165178525Sjb 166178525Sjb/* 167178525Sjb * The ctf_file is the structure used to represent a CTF container to library 168178525Sjb * clients, who see it only as an opaque pointer. Modifications can therefore 169178525Sjb * be made freely to this structure without regard to client versioning. The 170178525Sjb * ctf_file_t typedef appears in <sys/ctf_api.h> and declares a forward tag. 171178525Sjb * 172178525Sjb * NOTE: ctf_update() requires that everything inside of ctf_file either be an 173178525Sjb * immediate value, a pointer to dynamically allocated data *outside* of the 174178525Sjb * ctf_file itself, or a pointer to statically allocated data. If you add a 175178525Sjb * pointer to ctf_file that points to something within the ctf_file itself, 176178525Sjb * you must make corresponding changes to ctf_update(). 177178525Sjb */ 178178525Sjbstruct ctf_file { 179178525Sjb const ctf_fileops_t *ctf_fileops; /* version-specific file operations */ 180178525Sjb ctf_sect_t ctf_data; /* CTF data from object file */ 181178525Sjb ctf_sect_t ctf_symtab; /* symbol table from object file */ 182178525Sjb ctf_sect_t ctf_strtab; /* string table from object file */ 183178525Sjb ctf_hash_t ctf_structs; /* hash table of struct types */ 184178525Sjb ctf_hash_t ctf_unions; /* hash table of union types */ 185178525Sjb ctf_hash_t ctf_enums; /* hash table of enum types */ 186178525Sjb ctf_hash_t ctf_names; /* hash table of remaining type names */ 187178525Sjb ctf_lookup_t ctf_lookups[5]; /* pointers to hashes for name lookup */ 188178525Sjb ctf_strs_t ctf_str[2]; /* array of string table base and bounds */ 189178525Sjb const uchar_t *ctf_base; /* base of CTF header + uncompressed buffer */ 190178525Sjb const uchar_t *ctf_buf; /* uncompressed CTF data buffer */ 191178525Sjb size_t ctf_size; /* size of CTF header + uncompressed data */ 192178525Sjb uint_t *ctf_sxlate; /* translation table for symtab entries */ 193178525Sjb ulong_t ctf_nsyms; /* number of entries in symtab xlate table */ 194178525Sjb uint_t *ctf_txlate; /* translation table for type IDs */ 195178525Sjb ushort_t *ctf_ptrtab; /* translation table for pointer-to lookups */ 196178525Sjb ulong_t ctf_typemax; /* maximum valid type ID number */ 197178525Sjb const ctf_dmodel_t *ctf_dmodel; /* data model pointer (see above) */ 198178525Sjb struct ctf_file *ctf_parent; /* parent CTF container (if any) */ 199178525Sjb const char *ctf_parlabel; /* label in parent container (if any) */ 200178525Sjb const char *ctf_parname; /* basename of parent (if any) */ 201178525Sjb uint_t ctf_refcnt; /* reference count (for parent links) */ 202178525Sjb uint_t ctf_flags; /* libctf flags (see below) */ 203178525Sjb int ctf_errno; /* error code for most recent error */ 204178525Sjb int ctf_version; /* CTF data version */ 205178525Sjb ctf_dtdef_t **ctf_dthash; /* hash of dynamic type definitions */ 206178525Sjb ulong_t ctf_dthashlen; /* size of dynamic type hash bucket array */ 207178525Sjb ctf_list_t ctf_dtdefs; /* list of dynamic type definitions */ 208178525Sjb size_t ctf_dtstrlen; /* total length of dynamic type strings */ 209178525Sjb ulong_t ctf_dtnextid; /* next dynamic type id to assign */ 210178525Sjb ulong_t ctf_dtoldid; /* oldest id that has been committed */ 211178525Sjb void *ctf_specific; /* data for ctf_get/setspecific */ 212178525Sjb}; 213178525Sjb 214178525Sjb#define LCTF_INDEX_TO_TYPEPTR(fp, i) \ 215178525Sjb ((ctf_type_t *)((uintptr_t)(fp)->ctf_buf + (fp)->ctf_txlate[(i)])) 216178525Sjb 217178525Sjb#define LCTF_INFO_KIND(fp, info) ((fp)->ctf_fileops->ctfo_get_kind(info)) 218178525Sjb#define LCTF_INFO_ROOT(fp, info) ((fp)->ctf_fileops->ctfo_get_root(info)) 219178525Sjb#define LCTF_INFO_VLEN(fp, info) ((fp)->ctf_fileops->ctfo_get_vlen(info)) 220178525Sjb 221178525Sjb#define LCTF_MMAP 0x0001 /* libctf should munmap buffers on close */ 222178525Sjb#define LCTF_CHILD 0x0002 /* CTF container is a child */ 223178525Sjb#define LCTF_RDWR 0x0004 /* CTF container is writable */ 224178525Sjb#define LCTF_DIRTY 0x0008 /* CTF container has been modified */ 225178525Sjb 226178525Sjb#define ECTF_BASE 1000 /* base value for libctf errnos */ 227178525Sjb 228178525Sjbenum { 229178525Sjb ECTF_FMT = ECTF_BASE, /* file is not in CTF or ELF format */ 230178525Sjb ECTF_ELFVERS, /* ELF version is more recent than libctf */ 231178525Sjb ECTF_CTFVERS, /* CTF version is more recent than libctf */ 232178525Sjb ECTF_ENDIAN, /* data is different endian-ness than lib */ 233178525Sjb ECTF_SYMTAB, /* symbol table uses invalid entry size */ 234178525Sjb ECTF_SYMBAD, /* symbol table data buffer invalid */ 235178525Sjb ECTF_STRBAD, /* string table data buffer invalid */ 236178525Sjb ECTF_CORRUPT, /* file data corruption detected */ 237178525Sjb ECTF_NOCTFDATA, /* ELF file does not contain CTF data */ 238178525Sjb ECTF_NOCTFBUF, /* buffer does not contain CTF data */ 239178525Sjb ECTF_NOSYMTAB, /* symbol table data is not available */ 240178525Sjb ECTF_NOPARENT, /* parent CTF container is not available */ 241178525Sjb ECTF_DMODEL, /* data model mismatch */ 242178525Sjb ECTF_MMAP, /* failed to mmap a data section */ 243178525Sjb ECTF_ZMISSING, /* decompression library not installed */ 244178525Sjb ECTF_ZINIT, /* failed to initialize decompression library */ 245178525Sjb ECTF_ZALLOC, /* failed to allocate decompression buffer */ 246178525Sjb ECTF_DECOMPRESS, /* failed to decompress CTF data */ 247178525Sjb ECTF_STRTAB, /* string table for this string is missing */ 248178525Sjb ECTF_BADNAME, /* string offset is corrupt w.r.t. strtab */ 249178525Sjb ECTF_BADID, /* invalid type ID number */ 250178525Sjb ECTF_NOTSOU, /* type is not a struct or union */ 251178525Sjb ECTF_NOTENUM, /* type is not an enum */ 252178525Sjb ECTF_NOTSUE, /* type is not a struct, union, or enum */ 253178525Sjb ECTF_NOTINTFP, /* type is not an integer or float */ 254178525Sjb ECTF_NOTARRAY, /* type is not an array */ 255178525Sjb ECTF_NOTREF, /* type does not reference another type */ 256178525Sjb ECTF_NAMELEN, /* buffer is too small to hold type name */ 257178525Sjb ECTF_NOTYPE, /* no type found corresponding to name */ 258178525Sjb ECTF_SYNTAX, /* syntax error in type name */ 259178525Sjb ECTF_NOTFUNC, /* symtab entry does not refer to a function */ 260178525Sjb ECTF_NOFUNCDAT, /* no func info available for function */ 261178525Sjb ECTF_NOTDATA, /* symtab entry does not refer to a data obj */ 262178525Sjb ECTF_NOTYPEDAT, /* no type info available for object */ 263178525Sjb ECTF_NOLABEL, /* no label found corresponding to name */ 264178525Sjb ECTF_NOLABELDATA, /* file does not contain any labels */ 265178525Sjb ECTF_NOTSUP, /* feature not supported */ 266178525Sjb ECTF_NOENUMNAM, /* enum element name not found */ 267178525Sjb ECTF_NOMEMBNAM, /* member name not found */ 268178525Sjb ECTF_RDONLY, /* CTF container is read-only */ 269178525Sjb ECTF_DTFULL, /* CTF type is full (no more members allowed) */ 270178525Sjb ECTF_FULL, /* CTF container is full */ 271178525Sjb ECTF_DUPMEMBER, /* duplicate member name definition */ 272178525Sjb ECTF_CONFLICT /* conflicting type definition present */ 273178525Sjb}; 274178525Sjb 275178525Sjbextern ssize_t ctf_get_ctt_size(const ctf_file_t *, const ctf_type_t *, 276178525Sjb ssize_t *, ssize_t *); 277178525Sjb 278178525Sjbextern const ctf_type_t *ctf_lookup_by_id(ctf_file_t **, ctf_id_t); 279178525Sjb 280178525Sjbextern int ctf_hash_create(ctf_hash_t *, ulong_t); 281178525Sjbextern int ctf_hash_insert(ctf_hash_t *, ctf_file_t *, ushort_t, uint_t); 282178525Sjbextern int ctf_hash_define(ctf_hash_t *, ctf_file_t *, ushort_t, uint_t); 283178525Sjbextern ctf_helem_t *ctf_hash_lookup(ctf_hash_t *, ctf_file_t *, 284178525Sjb const char *, size_t); 285178525Sjbextern uint_t ctf_hash_size(const ctf_hash_t *); 286178525Sjbextern void ctf_hash_destroy(ctf_hash_t *); 287178525Sjb 288178525Sjb#define ctf_list_prev(elem) ((void *)(((ctf_list_t *)(elem))->l_prev)) 289178525Sjb#define ctf_list_next(elem) ((void *)(((ctf_list_t *)(elem))->l_next)) 290178525Sjb 291178525Sjbextern void ctf_list_append(ctf_list_t *, void *); 292178525Sjbextern void ctf_list_prepend(ctf_list_t *, void *); 293178525Sjbextern void ctf_list_delete(ctf_list_t *, void *); 294178525Sjb 295178525Sjbextern void ctf_dtd_insert(ctf_file_t *, ctf_dtdef_t *); 296178525Sjbextern void ctf_dtd_delete(ctf_file_t *, ctf_dtdef_t *); 297178525Sjbextern ctf_dtdef_t *ctf_dtd_lookup(ctf_file_t *, ctf_id_t); 298178525Sjb 299178525Sjbextern void ctf_decl_init(ctf_decl_t *, char *, size_t); 300178525Sjbextern void ctf_decl_fini(ctf_decl_t *); 301178525Sjbextern void ctf_decl_push(ctf_decl_t *, ctf_file_t *, ctf_id_t); 302178525Sjbextern void ctf_decl_sprintf(ctf_decl_t *, const char *, ...); 303178525Sjb 304178525Sjbextern const char *ctf_strraw(ctf_file_t *, uint_t); 305178525Sjbextern const char *ctf_strptr(ctf_file_t *, uint_t); 306178525Sjb 307178525Sjbextern ctf_file_t *ctf_set_open_errno(int *, int); 308178525Sjbextern long ctf_set_errno(ctf_file_t *, int); 309178525Sjb 310178525Sjbextern const void *ctf_sect_mmap(ctf_sect_t *, int); 311178525Sjbextern void ctf_sect_munmap(const ctf_sect_t *); 312178525Sjb 313178525Sjbextern void *ctf_data_alloc(size_t); 314178525Sjbextern void ctf_data_free(void *, size_t); 315178525Sjbextern void ctf_data_protect(void *, size_t); 316178525Sjb 317178525Sjbextern void *ctf_alloc(size_t); 318178525Sjbextern void ctf_free(void *, size_t); 319178525Sjb 320178525Sjbextern char *ctf_strdup(const char *); 321178525Sjbextern const char *ctf_strerror(int); 322178525Sjbextern void ctf_dprintf(const char *, ...); 323178525Sjb 324178525Sjbextern void *ctf_zopen(int *); 325178525Sjb 326178525Sjbextern const char _CTF_SECTION[]; /* name of CTF ELF section */ 327178525Sjbextern const char _CTF_NULLSTR[]; /* empty string */ 328178525Sjb 329178525Sjbextern int _libctf_version; /* library client version */ 330178525Sjbextern int _libctf_debug; /* debugging messages enabled */ 331178525Sjb 332178525Sjb#ifdef __cplusplus 333178525Sjb} 334178525Sjb#endif 335178525Sjb 336178525Sjb#endif /* _CTF_IMPL_H */ 337