1 2 #include "inc.h" 3 4 #include <stdarg.h> 5 6 /* 7 * The size of the formatting buffer, which in particular limits the maximum 8 * size of the output from the variadic functions. All printer functions which 9 * are dealing with potentially large or even unbounded output, should be able 10 * to generate their output in smaller chunks. In the end, nothing that is 11 * being printed as a unit should even come close to reaching this limit. 12 */ 13 #define FORMAT_BUFSZ 4096 14 15 /* 16 * The buffer which is used for all intermediate copying and/or formatting. 17 * Care must be taken that only one function uses this buffer at any time. 18 */ 19 static char formatbuf[FORMAT_BUFSZ]; 20 21 /* 22 * Reset the line formatting for the given process. 23 */ 24 void 25 format_reset(struct trace_proc * proc) 26 { 27 28 proc->next_sep = NULL; 29 proc->depth = -1; 30 } 31 32 /* 33 * Set the next separator for the given process. The given separator may be 34 * NULL. 35 */ 36 void 37 format_set_sep(struct trace_proc * proc, const char * sep) 38 { 39 40 proc->next_sep = sep; 41 } 42 43 /* 44 * Print and clear the next separator for the process, if any. 45 */ 46 void 47 format_push_sep(struct trace_proc * proc) 48 { 49 50 if (proc->next_sep != NULL) { 51 put_text(proc, proc->next_sep); 52 53 proc->next_sep = NULL; 54 } 55 } 56 57 /* 58 * Print a field, e.g. a parameter or a field from a structure, separated from 59 * other fields at the same nesting depth as appropriate. If the given field 60 * name is not NULL, it may or may not be printed. The given text is what will 61 * be printed for this field so far, but the caller is allowed to continue 62 * printing text for the same field with e.g. put_text(). As such, the given 63 * text may even be an empty string. 64 */ 65 void 66 put_field(struct trace_proc * proc, const char * name, const char * text) 67 { 68 69 /* 70 * At depth -1 (the basic line level), names are not used. A name 71 * should not be supplied by the caller in that case, but, it happens. 72 */ 73 if (proc->depth < 0) 74 name = NULL; 75 76 format_push_sep(proc); 77 78 if (name != NULL && (proc->depths[proc->depth].name || allnames)) { 79 put_text(proc, name); 80 put_text(proc, "="); 81 } 82 83 put_text(proc, text); 84 85 format_set_sep(proc, proc->depths[proc->depth].sep); 86 } 87 88 /* 89 * Increase the nesting depth with a new block of fields, enclosed within 90 * parentheses, brackets, etcetera. The given name, which may be NULL, is the 91 * name of the entire nested block. In the flags field, PF_NONAME indicates 92 * that the fields within the block should have their names printed or not, 93 * although this may be overridden by setting the allnames variable. The given 94 * string is the block opening string (e.g., an opening parenthesis). The 95 * given separator is used to separate the fields within the nested block, and 96 * should generally be ", " to maintain output consistency. 97 */ 98 void 99 put_open(struct trace_proc * proc, const char * name, int flags, 100 const char * string, const char * sep) 101 { 102 103 put_field(proc, name, string); 104 105 proc->depth++; 106 107 assert(proc->depth < MAX_DEPTH); 108 109 proc->depths[proc->depth].sep = sep; 110 proc->depths[proc->depth].name = !(flags & PF_NONAME); 111 112 format_set_sep(proc, NULL); 113 } 114 115 /* 116 * Decrease the nesting depth by ending a nested block of fields. The given 117 * string is the closing parenthesis, bracket, etcetera. 118 */ 119 void 120 put_close(struct trace_proc * proc, const char * string) 121 { 122 123 assert(proc->depth >= 0); 124 125 put_text(proc, string); 126 127 proc->depth--; 128 129 if (proc->depth >= 0) 130 format_set_sep(proc, proc->depths[proc->depth].sep); 131 else 132 format_set_sep(proc, NULL); 133 } 134 135 /* 136 * Version of put_text with variadic arguments. The given process may be NULL. 137 */ 138 void 139 put_fmt(struct trace_proc * proc, const char * fmt, ...) 140 { 141 va_list ap; 142 143 va_start(ap, fmt); 144 (void)vsnprintf(formatbuf, sizeof(formatbuf), fmt, ap); 145 va_end(ap); 146 147 put_text(proc, formatbuf); 148 } 149 150 /* 151 * Version of put_field with variadic arguments. 152 */ 153 void 154 put_value(struct trace_proc * proc, const char * name, const char * fmt, ...) 155 { 156 va_list ap; 157 158 va_start(ap, fmt); 159 (void)vsnprintf(formatbuf, sizeof(formatbuf), fmt, ap); 160 va_end(ap); 161 162 put_field(proc, name, formatbuf); 163 } 164 165 /* 166 * Start printing a structure. In general, the function copies the contents of 167 * the structure of size 'size' from the traced process at 'addr' into the 168 * local 'ptr' structure, opens a nested block with name 'name' (which may 169 * be NULL) using an opening bracket, and returns TRUE to indicate that the 170 * caller should print fields from the structure. However, if 'flags' contains 171 * PF_FAILED, the structure will be printed as a pointer, no copy will be made, 172 * and the call will return FALSE. Similarly, if the remote copy fails, a 173 * pointer will be printed and the call will return FALSE. If PF_LOCADDR is 174 * given, 'addr' is a local address, and an intraprocess copy will be made. 175 */ 176 int 177 put_open_struct(struct trace_proc * proc, const char * name, int flags, 178 vir_bytes addr, void * ptr, size_t size) 179 { 180 181 if ((flags & PF_FAILED) || valuesonly > 1 || addr == 0) { 182 if (flags & PF_LOCADDR) 183 put_field(proc, name, "&.."); 184 else 185 put_ptr(proc, name, addr); 186 187 return FALSE; 188 } 189 190 if (!(flags & PF_LOCADDR)) { 191 if (mem_get_data(proc->pid, addr, ptr, size) < 0) { 192 put_ptr(proc, name, addr); 193 194 return FALSE; 195 } 196 } else 197 memcpy(ptr, (void *) addr, size); 198 199 put_open(proc, name, flags, "{", ", "); 200 201 return TRUE; 202 } 203 204 /* 205 * End printing a structure. This must be called only to match a successful 206 * call to put_open_struct. The given 'all' flag indicates whether all fields 207 * of the structure have been printed; if not, a ".." continuation text is 208 * printed to show the user that some structure fields have not been printed. 209 */ 210 void 211 put_close_struct(struct trace_proc * proc, int all) 212 { 213 214 if (!all) 215 put_field(proc, NULL, ".."); 216 217 put_close(proc, "}"); 218 } 219 220 /* 221 * Print a pointer. NULL is treated as a special case. 222 */ 223 void 224 put_ptr(struct trace_proc * proc, const char * name, vir_bytes addr) 225 { 226 227 if (addr == 0 && !valuesonly) 228 put_field(proc, name, "NULL"); 229 else 230 put_value(proc, name, "&0x%lx", addr); 231 } 232 233 /* 234 * Print the contents of a buffer, at remote address 'addr' and of 'bytes' 235 * size, as a field using name 'name' (which may be NULL). If the PF_FAILED 236 * flag is given, the buffer address is printed instead, since it is assumed 237 * that the actual buffer contains garbage. If the PF_LOCADDR flag is given, 238 * the given address is a local address and no intraprocess copies are 239 * performed. If the PF_STRING flag is given, the buffer is expected to 240 * contain a null terminator within its size, and the string will be printed 241 * only up to there. Normally, the string is cut off beyond a number of bytes 242 * which depends on the verbosity level; if the PF_FULL flag is given, the full 243 * string will be printed no matter its size (used mainly for path names, which 244 * typically become useless once cut off). 245 */ 246 void 247 put_buf(struct trace_proc * proc, const char * name, int flags, vir_bytes addr, 248 ssize_t size) 249 { 250 const char *escaped; 251 size_t len, off, max, chunk; 252 int i, cutoff; 253 char *p; 254 255 if ((flags & PF_FAILED) || valuesonly || addr == 0 || size < 0) { 256 if (flags & PF_LOCADDR) 257 put_field(proc, name, "&.."); 258 else 259 put_ptr(proc, name, addr); 260 261 return; 262 } 263 264 if (size == 0) { 265 put_field(proc, name, "\"\""); 266 267 return; 268 } 269 270 /* 271 * TODO: the maximum says nothing about the size of the printed text. 272 * Escaped-character printing can make the output much longer. Does it 273 * make more sense to apply a limit after the escape transformation? 274 */ 275 if (verbose == 0) max = 32; 276 else if (verbose == 1) max = 256; 277 else max = SIZE_MAX; 278 279 /* 280 * If the output is cut off, we put two dots after the closing quote. 281 * For non-string buffers, the output is cut off if the size exceeds 282 * our limit or we run into a copying error somewhere in the middle. 283 * For strings, the output is cut off unless we find a null terminator. 284 */ 285 cutoff = !!(flags & PF_STRING); 286 len = (size_t)size; 287 if (!(flags & PF_FULL) && len > max) { 288 len = max; 289 cutoff = TRUE; 290 } 291 292 for (off = 0; off < len; off += chunk) { 293 chunk = len - off; 294 if (chunk > sizeof(formatbuf) - 1) 295 chunk = sizeof(formatbuf) - 1; 296 297 if (!(flags & PF_LOCADDR)) { 298 if (mem_get_data(proc->pid, addr + off, formatbuf, 299 chunk) < 0) { 300 if (off == 0) { 301 put_ptr(proc, name, addr); 302 303 return; 304 } 305 306 cutoff = TRUE; 307 break; 308 } 309 } else 310 memcpy(formatbuf, (void *)addr, chunk); 311 312 if (off == 0) 313 put_field(proc, name, "\""); 314 315 /* In strings, look for the terminating null character. */ 316 if ((flags & PF_STRING) && 317 (p = memchr(formatbuf, '\0', chunk)) != NULL) { 318 chunk = (size_t)(p - formatbuf); 319 cutoff = FALSE; 320 } 321 322 /* Print the buffer contents using escaped characters. */ 323 for (i = 0; i < chunk; i++) { 324 escaped = get_escape(formatbuf[i]); 325 326 put_text(proc, escaped); 327 } 328 329 /* Stop if we found the end of the string. */ 330 if ((flags & PF_STRING) && !cutoff) 331 break; 332 } 333 334 if (cutoff) 335 put_text(proc, "\".."); 336 else 337 put_text(proc, "\""); 338 } 339 340 /* 341 * Print a flags field, using known flag names. The name of the whole field is 342 * given as 'name' and may be NULL. The caller must supply an array of known 343 * flags as 'fp' (with 'num' entries). Each entry in the array has a mask, a 344 * value, and a name. If the given flags 'value', bitwise-ANDed with the mask 345 * of an entry, yields the value of that entry, then the name is printed. This 346 * means that certain zero bits may also be printed as actual flags, and that 347 * by supplying an all-bits-set mask can print a flag name for a zero value, 348 * for example F_OK for access(). See the FLAG macros and their usage for 349 * examples. All matching flag names are printed with a "|" separator, and if 350 * after evaluating all 'num' entries in 'fp' there are still bits in 'value' 351 * for which nothing has been printed, the remaining bits will be printed with 352 * the 'fmt' format string for an integer (generally "%d" should be used). 353 */ 354 void 355 put_flags(struct trace_proc * proc, const char * name, const struct flags * fp, 356 unsigned int num, const char * fmt, unsigned int value) 357 { 358 unsigned int left; 359 int first; 360 361 if (valuesonly) { 362 put_value(proc, name, fmt, value); 363 364 return; 365 } 366 367 put_field(proc, name, ""); 368 369 for (first = TRUE, left = value; num > 0; fp++, num--) { 370 if ((value & fp->mask) == fp->value) { 371 if (first) 372 first = FALSE; 373 else 374 put_text(proc, "|"); 375 put_text(proc, fp->name); 376 377 left -= fp->value; 378 } 379 } 380 381 if (left != 0) { 382 if (first) 383 first = FALSE; 384 else 385 put_text(proc, "|"); 386 387 put_fmt(proc, fmt, left); 388 } 389 390 /* 391 * If nothing has been printed so far, simply print a zero. Ignoring 392 * the given format in this case is intentional: a simple 0 looks 393 * better than 0x0 or 00 etc. 394 */ 395 if (first) 396 put_text(proc, "0"); 397 } 398 399 /* 400 * Print a tail field at the end of an array. The given 'count' value is the 401 * total number of elements in the array, or 0 to indicate that an error 402 * occurred. The given 'printed' value is the number of fields printed so far. 403 * If some fields have been printed already, the number of fields not printed 404 * will be shown as "..(+N)". If no fields have been printed already, the 405 * (total) number of fields not printed will be shown as "..(N)". An error 406 * will print "..(?)". 407 * 408 * The rules for printing an array are as follows. In principle, arrays should 409 * be enclosed in "[]". However, if a copy error occurs immediately, a pointer 410 * to the array should be printed instead. An empty array should be printed as 411 * "[]" (not "[..(0)]"). If a copy error occurs in the middle of the array, 412 * put_tail should be used with count == 0. Only if not all fields in the 413 * array are printed, put_tail should be used with count > 0. The value of 414 * 'printed' is typically the result of an arbitrary limit set based on the 415 * verbosity level. 416 */ 417 void 418 put_tail(struct trace_proc * proc, unsigned int count, unsigned int printed) 419 { 420 421 if (count == 0) 422 put_field(proc, NULL, "..(?)"); 423 else 424 put_value(proc, NULL, "..(%s%u)", 425 (printed > 0) ? "+" : "", count - printed); 426 } 427