/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
*/
#include <ctf_impl.h>
{ NULL, 0, 0, 0, 0, 0, 0 }
};
static ushort_t
{
return (CTF_INFO_KIND_V1(info));
}
static ushort_t
{
return (CTF_INFO_KIND(info));
}
static ushort_t
{
return (CTF_INFO_ISROOT_V1(info));
}
static ushort_t
{
return (CTF_INFO_ISROOT(info));
}
static ushort_t
{
return (CTF_INFO_VLEN_V1(info));
}
static ushort_t
{
return (CTF_INFO_VLEN(info));
}
};
/*
* Convert a 32-bit ELF symbol into GElf (Elf64) and return a pointer to it.
*/
static Elf64_Sym *
{
return (dst);
}
/*
* Initialize the symtab translation table by filling each entry with the
* offset of the CTF type or function data corresponding to each STT_FUNC or
* STT_OBJECT entry in the symbol table.
*/
static int
{
const char *name;
/*
* The CTF data object and function type sections are ordered to match
* the relative order of the respective symbol types in the symtab.
* If no type information is available for a symbol table entry, a
* pad is inserted in the CTF section. As a further optimization,
* anonymous or undefined symbols are omitted from the CTF data.
*/
else
else
name = _CTF_NULLSTR;
*xp = -1u;
continue;
}
case STT_OBJECT:
*xp = -1u;
break;
}
break;
case STT_FUNC:
*xp = -1u;
break;
}
/*
* If we encounter a zero pad at the end, just skip it.
* Otherwise skip over the function and its return type
* (+2) and the argument list (vlen).
*/
vlen == 0)
else
break;
default:
*xp = -1u;
break;
}
}
return (0);
}
/*
* Initialize the type ID translation table with the byte offset of each type,
* and initialize the hash tables of each named type.
*/
static int
{
/* LINTED - pointer alignment */
/* LINTED - pointer alignment */
/*
* We initially determine whether the container is a child or a parent
* based on the value of cth_parname. To support containers that pre-
* date cth_parname, we also scan the types themselves for references
* to values in the range reserved for child types in our first pass.
*/
int err;
/*
* We make two passes through the entire type section. In this first
* pass, we count the number of each type and the total number of types.
*/
uint_t n;
switch (kind) {
case CTF_K_INTEGER:
case CTF_K_FLOAT:
break;
case CTF_K_ARRAY:
vbytes = sizeof (ctf_array_t);
break;
case CTF_K_FUNCTION:
break;
case CTF_K_STRUCT:
case CTF_K_UNION:
size < CTF_LSTRUCT_THRESH) {
} else {
child |=
}
break;
case CTF_K_ENUM:
break;
case CTF_K_FORWARD:
/*
* For forward declarations, ctt_type is the CTF_K_*
* kind for the tag, so bump that population count too.
* If ctt_type is unknown, treat the tag as a struct.
*/
pop[CTF_K_STRUCT]++;
else
/*FALLTHRU*/
case CTF_K_UNKNOWN:
vbytes = 0;
break;
case CTF_K_POINTER:
case CTF_K_TYPEDEF:
case CTF_K_VOLATILE:
case CTF_K_CONST:
case CTF_K_RESTRICT:
vbytes = 0;
break;
default:
return (ECTF_CORRUPT);
}
}
/*
* If we detected a reference to a child type ID, then we know this
* container is a child and may have a parent's types imported later.
*/
if (child) {
} else
/*
* Now that we've counted up the number of each type, we can allocate
* the hash tables, type translation table, and pointer table.
*/
return (err);
return (err);
return (err);
return (err);
return (EAGAIN); /* memory allocation failed */
*xp++ = 0; /* type id 0 is used as a sentinel value */
/*
* In the second pass through the types, we fill in each entry of the
* type and pointer tables and add names to the appropriate hashes.
*/
const char *name;
switch (kind) {
case CTF_K_INTEGER:
case CTF_K_FLOAT:
/*
* Only insert a new integer base type definition if
* this type name has not been defined yet. We re-use
* the names with different encodings for bit-fields.
*/
return (err);
/*
* Work-around SOS8 stabs bug: replace existing
* intrinsic w/ same name if it was zero bits.
*/
}
break;
case CTF_K_ARRAY:
vbytes = sizeof (ctf_array_t);
break;
case CTF_K_FUNCTION:
return (err);
break;
case CTF_K_STRUCT:
return (err);
else {
nlstructs++;
}
break;
case CTF_K_UNION:
return (err);
else {
nlunions++;
}
break;
case CTF_K_ENUM:
return (err);
break;
case CTF_K_TYPEDEF:
return (err);
vbytes = 0;
break;
case CTF_K_FORWARD:
/*
* Only insert forward tags into the given hash if the
* type or tag name is not already present.
*/
case CTF_K_STRUCT:
break;
case CTF_K_UNION:
break;
case CTF_K_ENUM:
break;
default:
}
return (err);
}
vbytes = 0;
break;
case CTF_K_POINTER:
/*
* If the type referenced by the pointer is in this CTF
* container, then store the index of the pointer type
* in fp->ctf_ptrtab[ index of referenced type ].
*/
fp->ctf_ptrtab[
/*FALLTHRU*/
case CTF_K_VOLATILE:
case CTF_K_CONST:
case CTF_K_RESTRICT:
return (err);
/*FALLTHRU*/
default:
vbytes = 0;
break;
}
}
ctf_dprintf("%u struct names hashed (%d long)\n",
ctf_dprintf("%u union names hashed (%d long)\n",
ctf_dprintf("%u base type names hashed\n",
/*
* Make an additional pass through the pointer table to find pointers
* that point to anonymous typedef nodes. If we find one, modify the
* pointer table so that the pointer is also known to point to the
* node that is referenced by the anonymous typedef node.
*/
fp->ctf_ptrtab[
}
}
return (0);
}
/*
* Decode the specified CTF buffer and optional symbol table and create a new
* CTF container representing the symbolic debugging information. This code
* can be used directly by the debugger, or it can be used as the engine for
* ctf_fdopen() or ctf_open(), below.
*/
{
int err;
ctf_dprintf("ctf_bufopen: magic=0x%x version=%u\n",
/*
* Validate each part of the CTF header (either V1 or V2).
* First, we validate the preamble (common to all versions). At that
* point, we know specific header version, and can validate the
* version-specific parts including section offsets and alignments.
*/
hdrsz = sizeof (ctf_header_t);
hdrsz = sizeof (ctf_header_v1_t);
} else
/*
* Once everything is determined to be valid, attempt to decompress
* the CTF data buffer if it is compressed. Otherwise we just put
* the data section's buffer pointer into ctf_buf, below.
*/
const void *src;
return (NULL); /* errp is set for us */
}
ctf_dprintf("zlib inflate short -- got %lu of %lu "
}
} else {
}
/*
* Once we have uncompressed and validated the CTF data buffer, we can
* proceed with allocating a ctf_file_t and initializing it.
*/
}
}
/*
* If we have a parent container name and label, store the relocated
* string pointers in the CTF container for easy access later.
*/
if (hp.cth_parlabel != 0)
if (hp.cth_parname != 0)
ctf_dprintf("ctf_bufopen: parent name %s (label %s)\n",
/*
* If we have a symbol table section, allocate and initialize
* the symtab translation table, pointed to by ctf_sxlate.
*/
goto bad;
}
goto bad;
}
}
goto bad;
}
/*
* Initialize the ctf_lookup_by_name top-level dictionary. We keep an
* array of type name prefixes and the corresponding ctf_hash to use.
* NOTE: This code must be kept in sync with the code in ctf_update().
*/
else
} else
return (fp);
bad:
return (NULL);
}
/*
* Dupliate a ctf_file_t and its underlying section information into a new
* container. This works by copying the three ctf_sect_t's of the original
* container if they exist and passing those into ctf_bufopen. To copy those, we
* mmap anonymous memory with ctf_data_alloc and bcopy the data across. It's not
* the cheapest thing, but it's what we've got.
*/
{
int err;
/*
* The ctfsect isn't allowed to not exist, but the symbol and string
* section might not. We only need to copy the data of the section, not
* the name, as ctf_bufopen will take care of that.
*/
return (NULL);
}
ctfsect.cts_offset = 0;
goto err;
}
symsect.cts_offset = 0;
} else {
}
goto err;
}
strsect.cts_offset = 0;
} else {
}
goto err;
}
return (fp);
err:
return (NULL);
}
/*
* Close the specified CTF container and free associated data structures. Note
* that ctf_close() is a reference counted operation: if the specified file is
* the parent of other active containers, its reference count will be greater
* than one and it will be freed later when no active children exist.
*/
void
{
return; /* allow ctf_close(NULL) to simplify caller code */
fp->ctf_refcnt--;
return;
}
/*
* Note, to work properly with reference counting on the dynamic
* section, we must delete the list in reverse.
*/
}
}
}
}
}
}
}
}
/*
* Return the CTF handle for the parent CTF container, if one exists.
* Otherwise return NULL to indicate this container has no imported parent.
*/
{
return (fp->ctf_parent);
}
/*
* Return the name of the parent CTF container, if one exists. Otherwise
* return NULL to indicate this container is a root container.
*/
const char *
{
return (fp->ctf_parname);
}
/*
* Import the types from the specified parent container by storing a pointer
* to it in ctf_parent and incrementing its reference count. Only one parent
* is allowed: if a parent already exists, it is replaced by the new parent.
*/
int
{
pfp->ctf_refcnt++;
}
return (0);
}
/*
* Set the data model constant for the CTF container.
*/
int
{
return (0);
}
}
}
/*
* Return the data model constant for the CTF container.
*/
int
{
}
void
{
}
void *
{
return (fp->ctf_specific);
}