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 unsigned int i; 253 int cutoff; 254 char *p; 255 256 if ((flags & PF_FAILED) || valuesonly || addr == 0 || size < 0) { 257 if (flags & PF_LOCADDR) 258 put_field(proc, name, "&.."); 259 else 260 put_ptr(proc, name, addr); 261 262 return; 263 } 264 265 if (size == 0) { 266 put_field(proc, name, "\"\""); 267 268 return; 269 } 270 271 /* 272 * TODO: the maximum says nothing about the size of the printed text. 273 * Escaped-character printing can make the output much longer. Does it 274 * make more sense to apply a limit after the escape transformation? 275 */ 276 if (verbose == 0) max = 32; 277 else if (verbose == 1) max = 256; 278 else max = SIZE_MAX; 279 280 /* 281 * If the output is cut off, we put two dots after the closing quote. 282 * For non-string buffers, the output is cut off if the size exceeds 283 * our limit or we run into a copying error somewhere in the middle. 284 * For strings, the output is cut off unless we find a null terminator. 285 */ 286 cutoff = !!(flags & PF_STRING); 287 len = (size_t)size; 288 if (!(flags & PF_FULL) && len > max) { 289 len = max; 290 cutoff = TRUE; 291 } 292 293 for (off = 0; off < len; off += chunk) { 294 chunk = len - off; 295 if (chunk > sizeof(formatbuf) - 1) 296 chunk = sizeof(formatbuf) - 1; 297 298 if (!(flags & PF_LOCADDR)) { 299 if (mem_get_data(proc->pid, addr + off, formatbuf, 300 chunk) < 0) { 301 if (off == 0) { 302 put_ptr(proc, name, addr); 303 304 return; 305 } 306 307 cutoff = TRUE; 308 break; 309 } 310 } else 311 memcpy(formatbuf, (void *)addr, chunk); 312 313 if (off == 0) 314 put_field(proc, name, "\""); 315 316 /* In strings, look for the terminating null character. */ 317 if ((flags & PF_STRING) && 318 (p = memchr(formatbuf, '\0', chunk)) != NULL) { 319 chunk = (size_t)(p - formatbuf); 320 cutoff = FALSE; 321 } 322 323 /* Print the buffer contents using escaped characters. */ 324 for (i = 0; i < chunk; i++) { 325 escaped = get_escape(formatbuf[i]); 326 327 put_text(proc, escaped); 328 } 329 330 /* Stop if we found the end of the string. */ 331 if ((flags & PF_STRING) && !cutoff) 332 break; 333 } 334 335 if (cutoff) 336 put_text(proc, "\".."); 337 else 338 put_text(proc, "\""); 339 } 340 341 /* 342 * Print a flags field, using known flag names. The name of the whole field is 343 * given as 'name' and may be NULL. The caller must supply an array of known 344 * flags as 'fp' (with 'num' entries). Each entry in the array has a mask, a 345 * value, and a name. If the given flags 'value', bitwise-ANDed with the mask 346 * of an entry, yields the value of that entry, then the name is printed. This 347 * means that certain zero bits may also be printed as actual flags, and that 348 * by supplying an all-bits-set mask can print a flag name for a zero value, 349 * for example F_OK for access(). See the FLAG macros and their usage for 350 * examples. All matching flag names are printed with a "|" separator, and if 351 * after evaluating all 'num' entries in 'fp' there are still bits in 'value' 352 * for which nothing has been printed, the remaining bits will be printed with 353 * the 'fmt' format string for an integer (generally "%d" should be used). 354 */ 355 void 356 put_flags(struct trace_proc * proc, const char * name, const struct flags * fp, 357 unsigned int num, const char * fmt, unsigned int value) 358 { 359 unsigned int left; 360 int first; 361 362 if (valuesonly) { 363 put_value(proc, name, fmt, value); 364 365 return; 366 } 367 368 put_field(proc, name, ""); 369 370 for (first = TRUE, left = value; num > 0; fp++, num--) { 371 if ((value & fp->mask) == fp->value) { 372 if (first) 373 first = FALSE; 374 else 375 put_text(proc, "|"); 376 put_text(proc, fp->name); 377 378 left -= fp->value; 379 } 380 } 381 382 if (left != 0) { 383 if (first) 384 first = FALSE; 385 else 386 put_text(proc, "|"); 387 388 put_fmt(proc, fmt, left); 389 } 390 391 /* 392 * If nothing has been printed so far, simply print a zero. Ignoring 393 * the given format in this case is intentional: a simple 0 looks 394 * better than 0x0 or 00 etc. 395 */ 396 if (first) 397 put_text(proc, "0"); 398 } 399 400 /* 401 * Print a tail field at the end of an array. The given 'count' value is the 402 * total number of elements in the array, or 0 to indicate that an error 403 * occurred. The given 'printed' value is the number of fields printed so far. 404 * If some fields have been printed already, the number of fields not printed 405 * will be shown as "..(+N)". If no fields have been printed already, the 406 * (total) number of fields not printed will be shown as "..(N)". An error 407 * will print "..(?)". 408 * 409 * The rules for printing an array are as follows. In principle, arrays should 410 * be enclosed in "[]". However, if a copy error occurs immediately, a pointer 411 * to the array should be printed instead. An empty array should be printed as 412 * "[]" (not "[..(0)]"). If a copy error occurs in the middle of the array, 413 * put_tail should be used with count == 0. Only if not all fields in the 414 * array are printed, put_tail should be used with count > 0. The value of 415 * 'printed' is typically the result of an arbitrary limit set based on the 416 * verbosity level. 417 */ 418 void 419 put_tail(struct trace_proc * proc, unsigned int count, unsigned int printed) 420 { 421 422 if (count == 0) 423 put_field(proc, NULL, "..(?)"); 424 else 425 put_value(proc, NULL, "..(%s%u)", 426 (printed > 0) ? "+" : "", count - printed); 427 } 428