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