/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (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 <sys/sysmacros.h>
#include <assert.h>
#include <limits.h>
#include <strings.h>
#include <stdlib.h>
#include <alloca.h>
#include <unistd.h>
#include <errno.h>
#include <dt_provider.h>
#include <dt_module.h>
#include <dt_string.h>
#include <dt_list.h>
#include <dt_pid.h>
#include <dtrace.h>
static dt_provider_t *
{
return (pvp);
}
{
return (pvp);
}
return (NULL);
}
return (NULL);
}
return (NULL); /* dt_errno is set for us */
return (pvp);
}
{
return (NULL);
return (NULL);
}
}
void
{
uint_t h;
}
int
{
return (-1);
}
return (0);
}
static uint8_t
{
uint8_t i;
break;
else
}
return (i);
}
static dt_node_t *
{
int i;
return (NULL);
else
}
return (args);
}
static size_t
{
}
static char *
{
return (s);
}
/*
* If a probe was discovered from the kernel, ask dtrace(7D) for a description
* of each of its arguments, including native and translated types.
*/
static dt_probe_t *
{
dt_dprintf("discovering probe %s:%s id=%d\n",
adp->dtargd_ndx = i;
return (NULL);
}
break; /* all argument descs have been retrieved */
}
xc = i;
nc++;
/*
* The pid provider believes in giving the kernel a break. No reason to
* give the kernel all the ctf containers that we're keeping ourselves
* just to get it back from it. So if we're coming from a pid provider
* probe and the kernel gave us no argument information we'll get some
* here. If for some crazy reason the kernel knows about our userland
* types then we just ignore this.
*/
}
/*
* Now that we have discovered the number of native and translated
* arguments from the argument descriptions, allocate a new probe ident
* and corresponding dt_probe_t and hash it into the provider.
*/
return (NULL); /* dt_errno is set for us */
return (NULL);
}
return (NULL);
}
/*
* Once our new dt_probe_t is fully constructed, iterate over the
* cached argument descriptions and assign types to prp->pr_nargv[]
* and prp->pr_xargv[] and assign mappings to prp->pr_mapping[].
*/
dt_dprintf("failed to resolve input type %s "
} else {
}
} else if (dtrace_type_strcompile(dtp,
dt_dprintf("failed to resolve output type %s "
} else {
}
}
return (prp);
}
/*
* Lookup a probe declaration based on a known provider and full or partially
* specified module, function, and name. If the probe is not known to us yet,
* ask dtrace(7D) to match the description and then cache any useful results.
*/
{
char *key;
return (NULL); /* dt_errno is set for us */
/*
* If the probe is already declared, then return the dt_probe_t from
* the existing identifier. This could come from a static declaration
* or it could have been cached from an earlier call to this function.
*/
/*
* If the probe isn't known, use the probe description computed above
* to ask dtrace(7D) to find the first matching probe.
*/
else
return (NULL);
}
{
const char *p;
uint_t i;
/*
* If only a single prototype is given, set xargc/s to nargc/s to
* simplify subsequent use. Note that we can have one or both of nargs
* and xargs be specified but set to NULL, indicating a void prototype.
*/
if (protoc < 2) {
}
return (NULL);
return (NULL);
}
else
prp->pr_mapping[i] = i;
else
}
return (prp);
}
void
{
}
void
{
else
}
}
int
{
break;
}
return (-1);
return (-1);
}
return (-1);
}
}
}
pip->pi_nenoffs = 0;
}
if (isenabled) {
} else {
}
return (-1);
}
dt_dprintf("defined probe %s %s:%s %s() +0x%x (%s)\n",
return (0);
}
/*
* Lookup the dynamic translator type tag for the specified probe argument and
* assign the type to the specified node. If the type is not yet defined, add
* it to the "D" module's type container as a typedef for an unknown type.
*/
{
char *tag;
}
}
return (dnp);
}
/*ARGSUSED*/
static int
{
return (0);
}
return (1);
}
{
/*
* Attempt to lookup the probe in our existing cache for this provider.
* If none is found and an explicit probe ID was specified, discover
* that specific probe and cache its description and arguments.
*/
}
/*
* If no probe was found in our cache, convert the caller's partial
* probe description into a fully-formed matching probe description by
* iterating over up to at most two probes that match 'pdp'. We then
* call dt_probe_discover() on the resulting probe identifier.
*/
int m;
/*
* Call dtrace_probe_iter() to find matching probes. Our
* dt_probe_desc() callback will produce the following results:
*
* m < 0 dtrace_probe_iter() found zero matches (or failed).
* m > 0 dtrace_probe_iter() found more than one match.
* m = 0 dtrace_probe_iter() found exactly one match.
*/
return (NULL); /* dt_errno is set for us */
return (NULL); /* dt_errno is set for us */
/*
* If more than one probe was matched, then do not report probe
* information if either of the following conditions is true:
*
* (a) The Arguments Data stability of the matched provider is
* less than Evolving.
*
* (b) Any description component that is at least Evolving is
* empty or is specified using a globbing expression.
*
* These conditions imply that providers that provide Evolving
* or better Arguments Data stability must guarantee that all
* probes with identical field names in a field of Evolving or
* better Name stability have identical argument signatures.
*/
if (m > 0) {
return (NULL);
}
return (NULL);
}
return (NULL);
}
return (NULL);
}
}
/*
* If we matched a probe exported by dtrace(7D), then discover
* the real attributes. Otherwise grab the static declaration.
*/
else
return (NULL); /* dt_errno is set for us */
}
/*
* Compute the probe description attributes by taking the minimum of
* the attributes of the specified fields. If no provider is specified
* or a glob pattern is used for the provider, use Unstable attributes.
*/
pap = &_dtrace_prvdesc;
else
if (!m_is_glob)
if (!f_is_glob)
if (!n_is_glob)
return (prp);
}
int
{
}
/*ARGSUSED*/
static int
{
return (0); /* continue on and examine next probe in hash */
pit->pit_matches++;
}
int
{
continue; /* we'll get these later using dt_ioctl() */
continue;
return (rv);
}
else
for (;;) {
break;
return (rv);
pit.pit_matches++;
}
switch (errno) {
case ESRCH:
case EBADF:
case EINVAL:
default:
}
}