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 #ifdef _KERNEL 29 #include <sys/types.h> 30 #include <sys/param.h> 31 #include <sys/systm.h> 32 #include <sys/ddi.h> /* strchr */ 33 #include <sys/sunddi.h> /* strchr */ 34 #include <sys/tnf_com.h> 35 #include <sys/tnf_writer.h> 36 #include <sys/tnf_probe.h> /* fixed tnf_probe_control_t->index problem */ 37 #include "tnf_types.h" 38 #include "tnf_trace.h" 39 #else /* _KERNEL */ 40 #include <stdlib.h> 41 #include <string.h> 42 #include <tnf/com.h> 43 #include <tnf/writer.h> 44 #include <tnf/probe.h> 45 #include "tnf_types.h" 46 #include <tnf_trace.h> 47 #endif /* _KERNEL */ 48 49 50 /* 51 * Defines 52 */ 53 54 #define NAME_LIMIT 128 55 #define ARRAY_LIMIT 5 56 #define NAME_START 5 57 #define SLOT_OFFSET 7 58 #define CONST_SLOTS 2 59 60 /* 61 * probe version 1 62 */ 63 64 struct tnf_probe_version __tnf_probe_version_1_info = { 65 sizeof (struct tnf_probe_version), 66 sizeof (tnf_probe_control_t) 67 }; 68 69 /* 70 * write instances of tnf_probe_type (i.e probe records) 71 */ 72 73 uintptr_t 74 tnf_probe_tag(tnf_ops_t *ops, tnf_probe_control_t *probe_p) 75 { 76 tnf_tag_data_t *metatag_data; 77 tnf_record_p metatag_index; 78 tnf_probe_prototype_t *buffer; 79 enum tnf_alloc_mode saved_mode; 80 tnf_uint32_t *fwp; 81 char probe_name[NAME_LIMIT]; 82 char slot_array[ARRAY_LIMIT][NAME_LIMIT]; 83 char *slot_args[ARRAY_LIMIT + CONST_SLOTS + 1]; 84 const char *nm_start, *nm_end, *slot_start, *slot_end; 85 int nm_len, separator, count; 86 87 saved_mode = ops->mode; 88 ops->mode = TNF_ALLOC_FIXED; 89 #if defined(_LP64) 90 /* LINTED assignment of 32-bit integer to 8-bit integer */ 91 ALLOC2(ops, sizeof (*buffer), buffer, saved_mode); 92 #else 93 ALLOC2(ops, sizeof (*buffer), buffer, saved_mode); 94 #endif 95 probe_p->index = (uintptr_t)buffer; 96 fwp = tnfw_b_fw_alloc(&(ops->wcb)); 97 if (fwp) { 98 /* REMIND: can make the next call more efficient */ 99 *fwp = tnf_ref32(ops, (tnf_record_p) buffer, 100 (tnf_record_p)fwp); 101 /* fwp - filestart < 64K */ 102 #ifdef _KERNEL 103 probe_p->index = (char *)fwp - tnf_buf; 104 #else 105 probe_p->index = (char *)fwp - _tnfw_b_control->tnf_buffer; 106 #endif 107 probe_p->index |= TNF_TAG16_T_ABS; 108 probe_p->index = probe_p->index << PROBE_INDEX_SHIFT; 109 probe_p->index |= PROBE_INDEX_FILE_PTR; 110 } 111 112 metatag_data = TAG_DATA(tnf_probe_type); 113 metatag_index = metatag_data->tag_index ? 114 metatag_data->tag_index : 115 metatag_data->tag_desc(ops, metatag_data); 116 117 /* find the name of the probe */ 118 nm_start = &(probe_p->attrs[NAME_START]); 119 separator = ATTR_SEPARATOR; 120 nm_end = strchr(probe_p->attrs, separator); 121 #if defined(_LP64) 122 /* LINTED assignment of 64-bit integer to 32-bit integer */ 123 nm_len = nm_end - nm_start; 124 #else 125 nm_len = nm_end - nm_start; 126 #endif 127 slot_start = nm_end + SLOT_OFFSET; 128 nm_len = (nm_len > (NAME_LIMIT - 1)) ? (NAME_LIMIT - 1) : nm_len; 129 (void) strncpy(probe_name, nm_start, nm_len); 130 probe_name[nm_len] = '\0'; 131 132 /* initialize constant part of slot names */ 133 slot_args[0] = TNF_N_TAG; 134 slot_args[1] = TNF_N_TIME_DELTA; 135 136 /* 137 * initialize rest of slot names, if any. This parsing routine is 138 * dependant on a space after "slots" (even for TNF_PROBE_0 and a 139 * space after the last slot name. It truncates any values that 140 * are larger than 127 chars to 127 chars. It handles missing slot 141 * names. 142 */ 143 separator = ATTR_SEPARATOR; 144 slot_end = strchr(slot_start, separator); 145 nm_start = slot_start; 146 separator = VAL_SEPARATOR; 147 for (count = 0; nm_start < slot_end; count++) { 148 nm_end = strchr(nm_start, separator); 149 #if defined(_LP64) 150 /* LINTED assignment of 64-bit integer to 32-bit integer */ 151 nm_len = nm_end - nm_start; 152 #else 153 nm_len = nm_end - nm_start; 154 #endif 155 nm_len = (nm_len > (NAME_LIMIT - 1)) ? (NAME_LIMIT - 1) : 156 nm_len; 157 (void) strncpy(slot_array[count], nm_start, nm_len); 158 slot_array[count][nm_len] = '\0'; 159 slot_args[count+CONST_SLOTS] = slot_array[count]; 160 /* get next name */ 161 nm_start = nm_end + 1; 162 } 163 /* null terminate string vector */ 164 slot_args[count+CONST_SLOTS] = NULL; 165 166 ASSIGN(buffer, tag, metatag_index); 167 ASSIGN(buffer, name, probe_name); 168 /* XXX Fix these properties sometime */ 169 ASSIGN(buffer, properties, &tnf_struct_properties); 170 ASSIGN(buffer, slot_types, probe_p->slot_types); 171 #if defined(_LP64) 172 /* LINTED */ 173 ASSIGN(buffer, type_size, probe_p->tnf_event_size); 174 #else 175 ASSIGN(buffer, type_size, probe_p->tnf_event_size); 176 #endif 177 ASSIGN(buffer, slot_names, slot_args); 178 ASSIGN(buffer, string, (slot_end + 1)); 179 #if defined(_LP64) 180 /* supress lint warning for _KERNEL mode, really need this? */ 181 /* LINTED assignment of 32-bit integer to 8-bit integer */ 182 ops->mode = saved_mode; 183 #else 184 ops->mode = saved_mode; 185 #endif 186 return (probe_p->index); 187 } 188