1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright (c) 1994, by Sun Microsytems, Inc. 24*7c478bd9Sstevel@tonic-gate */ 25*7c478bd9Sstevel@tonic-gate 26*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 27*7c478bd9Sstevel@tonic-gate 28*7c478bd9Sstevel@tonic-gate #ifndef DEBUG 29*7c478bd9Sstevel@tonic-gate #define NDEBUG 1 30*7c478bd9Sstevel@tonic-gate #endif 31*7c478bd9Sstevel@tonic-gate 32*7c478bd9Sstevel@tonic-gate #include "tnf_trace.h" 33*7c478bd9Sstevel@tonic-gate #include "tnf_types.h" 34*7c478bd9Sstevel@tonic-gate #include "tnf_args.h" 35*7c478bd9Sstevel@tonic-gate #include <string.h> 36*7c478bd9Sstevel@tonic-gate #include <assert.h> 37*7c478bd9Sstevel@tonic-gate 38*7c478bd9Sstevel@tonic-gate /* 39*7c478bd9Sstevel@tonic-gate * tnf_probe_get_num_args: returns the number of arguments at probe site 40*7c478bd9Sstevel@tonic-gate * probe_p. This includes the first 2 args (tag and time delta) in the return 41*7c478bd9Sstevel@tonic-gate * value. 42*7c478bd9Sstevel@tonic-gate */ 43*7c478bd9Sstevel@tonic-gate int 44*7c478bd9Sstevel@tonic-gate tnf_probe_get_num_args(tnf_probe_control_t *probe_p) 45*7c478bd9Sstevel@tonic-gate { 46*7c478bd9Sstevel@tonic-gate int count = 0; 47*7c478bd9Sstevel@tonic-gate tnf_tag_data_t ***tag_p; 48*7c478bd9Sstevel@tonic-gate 49*7c478bd9Sstevel@tonic-gate tag_p = probe_p->slot_types; 50*7c478bd9Sstevel@tonic-gate while (*tag_p) { 51*7c478bd9Sstevel@tonic-gate count++; 52*7c478bd9Sstevel@tonic-gate tag_p++; 53*7c478bd9Sstevel@tonic-gate } 54*7c478bd9Sstevel@tonic-gate return (count); 55*7c478bd9Sstevel@tonic-gate } 56*7c478bd9Sstevel@tonic-gate 57*7c478bd9Sstevel@tonic-gate /* 58*7c478bd9Sstevel@tonic-gate * tnf_probe_get_arg_indexed: returns a pointer into the buffer where 59*7c478bd9Sstevel@tonic-gate * argument i is stored. Returns NULL on error. Argument numbering is 60*7c478bd9Sstevel@tonic-gate * zero based i.e. to get the 3rd argument, the input value should be 2. 61*7c478bd9Sstevel@tonic-gate */ 62*7c478bd9Sstevel@tonic-gate 63*7c478bd9Sstevel@tonic-gate /* ALIGN_ROUNDUP: y has to be one less than a power of 2 eg. 3, 7, 15, etc. */ 64*7c478bd9Sstevel@tonic-gate #define ALIGN_ROUNDUP(x, y) (((x) + (y)) & ~(y)) 65*7c478bd9Sstevel@tonic-gate 66*7c478bd9Sstevel@tonic-gate void * 67*7c478bd9Sstevel@tonic-gate tnf_probe_get_arg_indexed(tnf_probe_control_t *probe_p, int index, void *buffer) 68*7c478bd9Sstevel@tonic-gate { 69*7c478bd9Sstevel@tonic-gate int count = 0; 70*7c478bd9Sstevel@tonic-gate size_t align; 71*7c478bd9Sstevel@tonic-gate size_t elem_size = 0; 72*7c478bd9Sstevel@tonic-gate tnf_tag_data_t ***tag_ppp; 73*7c478bd9Sstevel@tonic-gate tnf_tag_data_t *tag_p; 74*7c478bd9Sstevel@tonic-gate unsigned long offset = 0; 75*7c478bd9Sstevel@tonic-gate 76*7c478bd9Sstevel@tonic-gate tag_ppp = probe_p->slot_types; 77*7c478bd9Sstevel@tonic-gate if (!tag_ppp) 78*7c478bd9Sstevel@tonic-gate return (NULL); 79*7c478bd9Sstevel@tonic-gate 80*7c478bd9Sstevel@tonic-gate while (count <= index) { 81*7c478bd9Sstevel@tonic-gate /* error checking. REMIND: Do we need it ? */ 82*7c478bd9Sstevel@tonic-gate if (!(*tag_ppp)) 83*7c478bd9Sstevel@tonic-gate return (NULL); 84*7c478bd9Sstevel@tonic-gate tag_p = **tag_ppp; 85*7c478bd9Sstevel@tonic-gate if (!tag_p) 86*7c478bd9Sstevel@tonic-gate return (NULL); 87*7c478bd9Sstevel@tonic-gate 88*7c478bd9Sstevel@tonic-gate offset = offset + elem_size; 89*7c478bd9Sstevel@tonic-gate align = tag_p->tag_align - 1; 90*7c478bd9Sstevel@tonic-gate assert(align != 0); 91*7c478bd9Sstevel@tonic-gate offset = ALIGN_ROUNDUP(offset, align); 92*7c478bd9Sstevel@tonic-gate /* get size of current element */ 93*7c478bd9Sstevel@tonic-gate elem_size = tag_p->tag_ref_size; 94*7c478bd9Sstevel@tonic-gate tag_ppp++; 95*7c478bd9Sstevel@tonic-gate count++; 96*7c478bd9Sstevel@tonic-gate } 97*7c478bd9Sstevel@tonic-gate 98*7c478bd9Sstevel@tonic-gate return ((void *)((char *)buffer + offset)); 99*7c478bd9Sstevel@tonic-gate } 100*7c478bd9Sstevel@tonic-gate 101*7c478bd9Sstevel@tonic-gate /* 102*7c478bd9Sstevel@tonic-gate * tnf_probe_get_type_indexed: returns the type of the ith argument. 103*7c478bd9Sstevel@tonic-gate * returns TNF_UNKNOWN on error. Argument numbering is zero based 104*7c478bd9Sstevel@tonic-gate * i.e. to get the 3rd argument, the input value should be 2. 105*7c478bd9Sstevel@tonic-gate */ 106*7c478bd9Sstevel@tonic-gate 107*7c478bd9Sstevel@tonic-gate tnf_arg_kind_t 108*7c478bd9Sstevel@tonic-gate tnf_probe_get_type_indexed(tnf_probe_control_t *probe_p, int index) 109*7c478bd9Sstevel@tonic-gate { 110*7c478bd9Sstevel@tonic-gate tnf_tag_data_t ***tag_ppp; 111*7c478bd9Sstevel@tonic-gate tnf_tag_data_t *tag_p; 112*7c478bd9Sstevel@tonic-gate 113*7c478bd9Sstevel@tonic-gate tag_ppp = probe_p->slot_types + index; 114*7c478bd9Sstevel@tonic-gate if (!tag_ppp) 115*7c478bd9Sstevel@tonic-gate return (TNF_UNKNOWN); 116*7c478bd9Sstevel@tonic-gate if (!(*tag_ppp)) 117*7c478bd9Sstevel@tonic-gate return (TNF_UNKNOWN); 118*7c478bd9Sstevel@tonic-gate tag_p = **tag_ppp; 119*7c478bd9Sstevel@tonic-gate if (!tag_p) 120*7c478bd9Sstevel@tonic-gate return (TNF_UNKNOWN); 121*7c478bd9Sstevel@tonic-gate return (tag_p->tag_kind); 122*7c478bd9Sstevel@tonic-gate } 123*7c478bd9Sstevel@tonic-gate 124*7c478bd9Sstevel@tonic-gate 125*7c478bd9Sstevel@tonic-gate /* 126*7c478bd9Sstevel@tonic-gate * tnf_probe_get_value: returns the start of the value string that is 127*7c478bd9Sstevel@tonic-gate * associated with the input attribute. The number of characters in the 128*7c478bd9Sstevel@tonic-gate * value is also returned as the final argument. The size return value 129*7c478bd9Sstevel@tonic-gate * indicates the length of the string that is valid. Returns NULL on no 130*7c478bd9Sstevel@tonic-gate * match or error. 131*7c478bd9Sstevel@tonic-gate */ 132*7c478bd9Sstevel@tonic-gate 133*7c478bd9Sstevel@tonic-gate const char * 134*7c478bd9Sstevel@tonic-gate tnf_probe_get_value(tnf_probe_control_t *probe_p, char *attribute, 135*7c478bd9Sstevel@tonic-gate ulong_t *size) 136*7c478bd9Sstevel@tonic-gate { 137*7c478bd9Sstevel@tonic-gate 138*7c478bd9Sstevel@tonic-gate const char *attr_start, *attr_end, *str_end; 139*7c478bd9Sstevel@tonic-gate const char *val_start; 140*7c478bd9Sstevel@tonic-gate int separator; 141*7c478bd9Sstevel@tonic-gate uint_t attr_len; 142*7c478bd9Sstevel@tonic-gate size_t input_len; 143*7c478bd9Sstevel@tonic-gate 144*7c478bd9Sstevel@tonic-gate input_len = strlen(attribute); 145*7c478bd9Sstevel@tonic-gate attr_start = probe_p->attrs; 146*7c478bd9Sstevel@tonic-gate assert(attr_start); 147*7c478bd9Sstevel@tonic-gate str_end = attr_start + strlen(attr_start); 148*7c478bd9Sstevel@tonic-gate separator = ATTR_SEPARATOR; 149*7c478bd9Sstevel@tonic-gate while (attr_start < str_end) { 150*7c478bd9Sstevel@tonic-gate attr_end = strchr(attr_start, separator); 151*7c478bd9Sstevel@tonic-gate if (!attr_end) { 152*7c478bd9Sstevel@tonic-gate /* last attribute */ 153*7c478bd9Sstevel@tonic-gate attr_end = str_end; 154*7c478bd9Sstevel@tonic-gate } 155*7c478bd9Sstevel@tonic-gate /* LINTED - result <= string length */ 156*7c478bd9Sstevel@tonic-gate attr_len = attr_end - attr_start; 157*7c478bd9Sstevel@tonic-gate 158*7c478bd9Sstevel@tonic-gate /* skip over leading white space */ 159*7c478bd9Sstevel@tonic-gate while (*attr_start && ((*attr_start == ' ') || 160*7c478bd9Sstevel@tonic-gate (*attr_start == '\t'))) { 161*7c478bd9Sstevel@tonic-gate attr_start++; 162*7c478bd9Sstevel@tonic-gate } 163*7c478bd9Sstevel@tonic-gate /* search for match on attribute */ 164*7c478bd9Sstevel@tonic-gate if (strncmp(attr_start, attribute, input_len) == 0) { 165*7c478bd9Sstevel@tonic-gate /* make sure next char is a space or semicolon */ 166*7c478bd9Sstevel@tonic-gate val_start = attr_start + input_len; 167*7c478bd9Sstevel@tonic-gate if (*val_start == ATTR_SEPARATOR) { 168*7c478bd9Sstevel@tonic-gate *size = 0; 169*7c478bd9Sstevel@tonic-gate return (val_start); 170*7c478bd9Sstevel@tonic-gate } else if (*val_start == VAL_SEPARATOR) { 171*7c478bd9Sstevel@tonic-gate /* +1 for val separator */ 172*7c478bd9Sstevel@tonic-gate *size = attr_len - (input_len + 1); 173*7c478bd9Sstevel@tonic-gate return (val_start + 1); 174*7c478bd9Sstevel@tonic-gate } 175*7c478bd9Sstevel@tonic-gate /* a false match - just continue */ 176*7c478bd9Sstevel@tonic-gate } 177*7c478bd9Sstevel@tonic-gate /* skip to next attribute */ 178*7c478bd9Sstevel@tonic-gate attr_start = attr_end + 1; 179*7c478bd9Sstevel@tonic-gate } 180*7c478bd9Sstevel@tonic-gate 181*7c478bd9Sstevel@tonic-gate /* no match */ 182*7c478bd9Sstevel@tonic-gate return (NULL); 183*7c478bd9Sstevel@tonic-gate } 184*7c478bd9Sstevel@tonic-gate 185*7c478bd9Sstevel@tonic-gate /* used by in-process argument reader */ 186*7c478bd9Sstevel@tonic-gate char * 187*7c478bd9Sstevel@tonic-gate tnf_probe_get_chars(void *slot) 188*7c478bd9Sstevel@tonic-gate { 189*7c478bd9Sstevel@tonic-gate tnf_reference_t ref; 190*7c478bd9Sstevel@tonic-gate char *str_p; 191*7c478bd9Sstevel@tonic-gate 192*7c478bd9Sstevel@tonic-gate ref = *((tnf_reference_t *)slot); 193*7c478bd9Sstevel@tonic-gate assert(TNF_REF32_IS_FWD(ref)); 194*7c478bd9Sstevel@tonic-gate str_p = (char *)slot + TNF_REF32_VALUE(ref); 195*7c478bd9Sstevel@tonic-gate str_p += ARRAY_HDR_SIZE; 196*7c478bd9Sstevel@tonic-gate return (str_p); 197*7c478bd9Sstevel@tonic-gate } 198