/* * 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 * or http://www.opensolaris.org/os/licensing. * 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 (c) 1994, by Sun Microsytems, Inc. */ #pragma ident "%Z%%M% %I% %E% SMI" #ifndef DEBUG #define NDEBUG 1 #endif #include "tnf_trace.h" #include "tnf_types.h" #include "tnf_args.h" #include #include /* * tnf_probe_get_num_args: returns the number of arguments at probe site * probe_p. This includes the first 2 args (tag and time delta) in the return * value. */ int tnf_probe_get_num_args(tnf_probe_control_t *probe_p) { int count = 0; tnf_tag_data_t ***tag_p; tag_p = probe_p->slot_types; while (*tag_p) { count++; tag_p++; } return (count); } /* * tnf_probe_get_arg_indexed: returns a pointer into the buffer where * argument i is stored. Returns NULL on error. Argument numbering is * zero based i.e. to get the 3rd argument, the input value should be 2. */ /* ALIGN_ROUNDUP: y has to be one less than a power of 2 eg. 3, 7, 15, etc. */ #define ALIGN_ROUNDUP(x, y) (((x) + (y)) & ~(y)) void * tnf_probe_get_arg_indexed(tnf_probe_control_t *probe_p, int index, void *buffer) { int count = 0; size_t align; size_t elem_size = 0; tnf_tag_data_t ***tag_ppp; tnf_tag_data_t *tag_p; unsigned long offset = 0; tag_ppp = probe_p->slot_types; if (!tag_ppp) return (NULL); while (count <= index) { /* error checking. REMIND: Do we need it ? */ if (!(*tag_ppp)) return (NULL); tag_p = **tag_ppp; if (!tag_p) return (NULL); offset = offset + elem_size; align = tag_p->tag_align - 1; assert(align != 0); offset = ALIGN_ROUNDUP(offset, align); /* get size of current element */ elem_size = tag_p->tag_ref_size; tag_ppp++; count++; } return ((void *)((char *)buffer + offset)); } /* * tnf_probe_get_type_indexed: returns the type of the ith argument. * returns TNF_UNKNOWN on error. Argument numbering is zero based * i.e. to get the 3rd argument, the input value should be 2. */ tnf_arg_kind_t tnf_probe_get_type_indexed(tnf_probe_control_t *probe_p, int index) { tnf_tag_data_t ***tag_ppp; tnf_tag_data_t *tag_p; tag_ppp = probe_p->slot_types + index; if (!tag_ppp) return (TNF_UNKNOWN); if (!(*tag_ppp)) return (TNF_UNKNOWN); tag_p = **tag_ppp; if (!tag_p) return (TNF_UNKNOWN); return (tag_p->tag_kind); } /* * tnf_probe_get_value: returns the start of the value string that is * associated with the input attribute. The number of characters in the * value is also returned as the final argument. The size return value * indicates the length of the string that is valid. Returns NULL on no * match or error. */ const char * tnf_probe_get_value(tnf_probe_control_t *probe_p, char *attribute, ulong_t *size) { const char *attr_start, *attr_end, *str_end; const char *val_start; int separator; uint_t attr_len; size_t input_len; input_len = strlen(attribute); attr_start = probe_p->attrs; assert(attr_start); str_end = attr_start + strlen(attr_start); separator = ATTR_SEPARATOR; while (attr_start < str_end) { attr_end = strchr(attr_start, separator); if (!attr_end) { /* last attribute */ attr_end = str_end; } /* LINTED - result <= string length */ attr_len = attr_end - attr_start; /* skip over leading white space */ while (*attr_start && ((*attr_start == ' ') || (*attr_start == '\t'))) { attr_start++; } /* search for match on attribute */ if (strncmp(attr_start, attribute, input_len) == 0) { /* make sure next char is a space or semicolon */ val_start = attr_start + input_len; if (*val_start == ATTR_SEPARATOR) { *size = 0; return (val_start); } else if (*val_start == VAL_SEPARATOR) { /* +1 for val separator */ *size = attr_len - (input_len + 1); return (val_start + 1); } /* a false match - just continue */ } /* skip to next attribute */ attr_start = attr_end + 1; } /* no match */ return (NULL); } /* used by in-process argument reader */ char * tnf_probe_get_chars(void *slot) { tnf_reference_t ref; char *str_p; ref = *((tnf_reference_t *)slot); assert(TNF_REF32_IS_FWD(ref)); str_p = (char *)slot + TNF_REF32_VALUE(ref); str_p += ARRAY_HDR_SIZE; return (str_p); }