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