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
tnf_probe_get_num_args(tnf_probe_control_t * probe_p)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 *
tnf_probe_get_arg_indexed(tnf_probe_control_t * probe_p,int index,void * buffer)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
tnf_probe_get_type_indexed(tnf_probe_control_t * probe_p,int index)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 *
tnf_probe_get_value(tnf_probe_control_t * probe_p,char * attribute,ulong_t * size)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 *
tnf_probe_get_chars(void * slot)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