1 /* Branch trace support for GDB, the GNU debugger. 2 3 Copyright (C) 2013 Free Software Foundation, Inc. 4 5 Contributed by Intel Corp. <markus.t.metzger@intel.com> 6 7 This file is part of GDB. 8 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 3 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 21 22 #include "btrace.h" 23 #include "gdbthread.h" 24 #include "exceptions.h" 25 #include "inferior.h" 26 #include "target.h" 27 #include "record.h" 28 #include "symtab.h" 29 #include "disasm.h" 30 #include "source.h" 31 #include "filenames.h" 32 #include "xml-support.h" 33 34 /* Print a record debug message. Use do ... while (0) to avoid ambiguities 35 when used in if statements. */ 36 37 #define DEBUG(msg, args...) \ 38 do \ 39 { \ 40 if (record_debug != 0) \ 41 fprintf_unfiltered (gdb_stdlog, \ 42 "[btrace] " msg "\n", ##args); \ 43 } \ 44 while (0) 45 46 #define DEBUG_FTRACE(msg, args...) DEBUG ("[ftrace] " msg, ##args) 47 48 /* Initialize the instruction iterator. */ 49 50 static void 51 btrace_init_insn_iterator (struct btrace_thread_info *btinfo) 52 { 53 DEBUG ("init insn iterator"); 54 55 btinfo->insn_iterator.begin = 1; 56 btinfo->insn_iterator.end = 0; 57 } 58 59 /* Initialize the function iterator. */ 60 61 static void 62 btrace_init_func_iterator (struct btrace_thread_info *btinfo) 63 { 64 DEBUG ("init func iterator"); 65 66 btinfo->func_iterator.begin = 1; 67 btinfo->func_iterator.end = 0; 68 } 69 70 /* Compute the instruction trace from the block trace. */ 71 72 static VEC (btrace_inst_s) * 73 compute_itrace (VEC (btrace_block_s) *btrace) 74 { 75 VEC (btrace_inst_s) *itrace; 76 struct gdbarch *gdbarch; 77 unsigned int b; 78 79 DEBUG ("compute itrace"); 80 81 itrace = NULL; 82 gdbarch = target_gdbarch (); 83 b = VEC_length (btrace_block_s, btrace); 84 85 while (b-- != 0) 86 { 87 btrace_block_s *block; 88 CORE_ADDR pc; 89 90 block = VEC_index (btrace_block_s, btrace, b); 91 pc = block->begin; 92 93 /* Add instructions for this block. */ 94 for (;;) 95 { 96 btrace_inst_s *inst; 97 int size; 98 99 /* We should hit the end of the block. Warn if we went too far. */ 100 if (block->end < pc) 101 { 102 warning (_("Recorded trace may be corrupted.")); 103 break; 104 } 105 106 inst = VEC_safe_push (btrace_inst_s, itrace, NULL); 107 inst->pc = pc; 108 109 /* We're done once we pushed the instruction at the end. */ 110 if (block->end == pc) 111 break; 112 113 size = gdb_insn_length (gdbarch, pc); 114 115 /* Make sure we terminate if we fail to compute the size. */ 116 if (size <= 0) 117 { 118 warning (_("Recorded trace may be incomplete.")); 119 break; 120 } 121 122 pc += size; 123 } 124 } 125 126 return itrace; 127 } 128 129 /* Return the function name of a recorded function segment for printing. 130 This function never returns NULL. */ 131 132 static const char * 133 ftrace_print_function_name (struct btrace_func *bfun) 134 { 135 struct minimal_symbol *msym; 136 struct symbol *sym; 137 138 msym = bfun->msym; 139 sym = bfun->sym; 140 141 if (sym != NULL) 142 return SYMBOL_PRINT_NAME (sym); 143 144 if (msym != NULL) 145 return SYMBOL_PRINT_NAME (msym); 146 147 return "<unknown>"; 148 } 149 150 /* Return the file name of a recorded function segment for printing. 151 This function never returns NULL. */ 152 153 static const char * 154 ftrace_print_filename (struct btrace_func *bfun) 155 { 156 struct symbol *sym; 157 const char *filename; 158 159 sym = bfun->sym; 160 161 if (sym != NULL) 162 filename = symtab_to_filename_for_display (sym->symtab); 163 else 164 filename = "<unknown>"; 165 166 return filename; 167 } 168 169 /* Print an ftrace debug status message. */ 170 171 static void 172 ftrace_debug (struct btrace_func *bfun, const char *prefix) 173 { 174 DEBUG_FTRACE ("%s: fun = %s, file = %s, lines = [%d; %d], insn = [%u; %u]", 175 prefix, ftrace_print_function_name (bfun), 176 ftrace_print_filename (bfun), bfun->lbegin, bfun->lend, 177 bfun->ibegin, bfun->iend); 178 } 179 180 /* Initialize a recorded function segment. */ 181 182 static void 183 ftrace_init_func (struct btrace_func *bfun, struct minimal_symbol *mfun, 184 struct symbol *fun, unsigned int idx) 185 { 186 bfun->msym = mfun; 187 bfun->sym = fun; 188 bfun->lbegin = INT_MAX; 189 bfun->lend = 0; 190 bfun->ibegin = idx; 191 bfun->iend = idx; 192 } 193 194 /* Check whether the function has changed. */ 195 196 static int 197 ftrace_function_switched (struct btrace_func *bfun, 198 struct minimal_symbol *mfun, struct symbol *fun) 199 { 200 struct minimal_symbol *msym; 201 struct symbol *sym; 202 203 /* The function changed if we did not have one before. */ 204 if (bfun == NULL) 205 return 1; 206 207 msym = bfun->msym; 208 sym = bfun->sym; 209 210 /* If the minimal symbol changed, we certainly switched functions. */ 211 if (mfun != NULL && msym != NULL 212 && strcmp (SYMBOL_LINKAGE_NAME (mfun), SYMBOL_LINKAGE_NAME (msym)) != 0) 213 return 1; 214 215 /* If the symbol changed, we certainly switched functions. */ 216 if (fun != NULL && sym != NULL) 217 { 218 const char *bfname, *fname; 219 220 /* Check the function name. */ 221 if (strcmp (SYMBOL_LINKAGE_NAME (fun), SYMBOL_LINKAGE_NAME (sym)) != 0) 222 return 1; 223 224 /* Check the location of those functions, as well. */ 225 bfname = symtab_to_fullname (sym->symtab); 226 fname = symtab_to_fullname (fun->symtab); 227 if (filename_cmp (fname, bfname) != 0) 228 return 1; 229 } 230 231 return 0; 232 } 233 234 /* Check if we should skip this file when generating the function call 235 history. We would want to do that if, say, a macro that is defined 236 in another file is expanded in this function. */ 237 238 static int 239 ftrace_skip_file (struct btrace_func *bfun, const char *filename) 240 { 241 struct symbol *sym; 242 const char *bfile; 243 244 sym = bfun->sym; 245 246 if (sym != NULL) 247 bfile = symtab_to_fullname (sym->symtab); 248 else 249 bfile = ""; 250 251 if (filename == NULL) 252 filename = ""; 253 254 return (filename_cmp (bfile, filename) != 0); 255 } 256 257 /* Compute the function trace from the instruction trace. */ 258 259 static VEC (btrace_func_s) * 260 compute_ftrace (VEC (btrace_inst_s) *itrace) 261 { 262 VEC (btrace_func_s) *ftrace; 263 struct btrace_inst *binst; 264 struct btrace_func *bfun; 265 unsigned int idx; 266 267 DEBUG ("compute ftrace"); 268 269 ftrace = NULL; 270 bfun = NULL; 271 272 for (idx = 0; VEC_iterate (btrace_inst_s, itrace, idx, binst); ++idx) 273 { 274 struct symtab_and_line sal; 275 struct minimal_symbol *mfun; 276 struct symbol *fun; 277 const char *filename; 278 CORE_ADDR pc; 279 280 pc = binst->pc; 281 282 /* Try to determine the function we're in. We use both types of symbols 283 to avoid surprises when we sometimes get a full symbol and sometimes 284 only a minimal symbol. */ 285 fun = find_pc_function (pc); 286 mfun = lookup_minimal_symbol_by_pc (pc); 287 288 if (fun == NULL && mfun == NULL) 289 { 290 DEBUG_FTRACE ("no symbol at %u, pc=%s", idx, 291 core_addr_to_string_nz (pc)); 292 continue; 293 } 294 295 /* If we're switching functions, we start over. */ 296 if (ftrace_function_switched (bfun, mfun, fun)) 297 { 298 bfun = VEC_safe_push (btrace_func_s, ftrace, NULL); 299 300 ftrace_init_func (bfun, mfun, fun, idx); 301 ftrace_debug (bfun, "init"); 302 } 303 304 /* Update the instruction range. */ 305 bfun->iend = idx; 306 ftrace_debug (bfun, "update insns"); 307 308 /* Let's see if we have source correlation, as well. */ 309 sal = find_pc_line (pc, 0); 310 if (sal.symtab == NULL || sal.line == 0) 311 { 312 DEBUG_FTRACE ("no lines at %u, pc=%s", idx, 313 core_addr_to_string_nz (pc)); 314 continue; 315 } 316 317 /* Check if we switched files. This could happen if, say, a macro that 318 is defined in another file is expanded here. */ 319 filename = symtab_to_fullname (sal.symtab); 320 if (ftrace_skip_file (bfun, filename)) 321 { 322 DEBUG_FTRACE ("ignoring file at %u, pc=%s, file=%s", idx, 323 core_addr_to_string_nz (pc), filename); 324 continue; 325 } 326 327 /* Update the line range. */ 328 bfun->lbegin = min (bfun->lbegin, sal.line); 329 bfun->lend = max (bfun->lend, sal.line); 330 ftrace_debug (bfun, "update lines"); 331 } 332 333 return ftrace; 334 } 335 336 /* See btrace.h. */ 337 338 void 339 btrace_enable (struct thread_info *tp) 340 { 341 if (tp->btrace.target != NULL) 342 return; 343 344 if (!target_supports_btrace ()) 345 error (_("Target does not support branch tracing.")); 346 347 DEBUG ("enable thread %d (%s)", tp->num, target_pid_to_str (tp->ptid)); 348 349 tp->btrace.target = target_enable_btrace (tp->ptid); 350 } 351 352 /* See btrace.h. */ 353 354 void 355 btrace_disable (struct thread_info *tp) 356 { 357 struct btrace_thread_info *btp = &tp->btrace; 358 int errcode = 0; 359 360 if (btp->target == NULL) 361 return; 362 363 DEBUG ("disable thread %d (%s)", tp->num, target_pid_to_str (tp->ptid)); 364 365 target_disable_btrace (btp->target); 366 btp->target = NULL; 367 368 btrace_clear (tp); 369 } 370 371 /* See btrace.h. */ 372 373 void 374 btrace_teardown (struct thread_info *tp) 375 { 376 struct btrace_thread_info *btp = &tp->btrace; 377 int errcode = 0; 378 379 if (btp->target == NULL) 380 return; 381 382 DEBUG ("teardown thread %d (%s)", tp->num, target_pid_to_str (tp->ptid)); 383 384 target_teardown_btrace (btp->target); 385 btp->target = NULL; 386 387 btrace_clear (tp); 388 } 389 390 /* See btrace.h. */ 391 392 void 393 btrace_fetch (struct thread_info *tp) 394 { 395 struct btrace_thread_info *btinfo; 396 VEC (btrace_block_s) *btrace; 397 398 DEBUG ("fetch thread %d (%s)", tp->num, target_pid_to_str (tp->ptid)); 399 400 btinfo = &tp->btrace; 401 if (btinfo->target == NULL) 402 return; 403 404 btrace = target_read_btrace (btinfo->target, btrace_read_new); 405 if (VEC_empty (btrace_block_s, btrace)) 406 return; 407 408 btrace_clear (tp); 409 410 btinfo->btrace = btrace; 411 btinfo->itrace = compute_itrace (btinfo->btrace); 412 btinfo->ftrace = compute_ftrace (btinfo->itrace); 413 414 /* Initialize branch trace iterators. */ 415 btrace_init_insn_iterator (btinfo); 416 btrace_init_func_iterator (btinfo); 417 } 418 419 /* See btrace.h. */ 420 421 void 422 btrace_clear (struct thread_info *tp) 423 { 424 struct btrace_thread_info *btinfo; 425 426 DEBUG ("clear thread %d (%s)", tp->num, target_pid_to_str (tp->ptid)); 427 428 btinfo = &tp->btrace; 429 430 VEC_free (btrace_block_s, btinfo->btrace); 431 VEC_free (btrace_inst_s, btinfo->itrace); 432 VEC_free (btrace_func_s, btinfo->ftrace); 433 434 btinfo->btrace = NULL; 435 btinfo->itrace = NULL; 436 btinfo->ftrace = NULL; 437 } 438 439 /* See btrace.h. */ 440 441 void 442 btrace_free_objfile (struct objfile *objfile) 443 { 444 struct thread_info *tp; 445 446 DEBUG ("free objfile"); 447 448 ALL_THREADS (tp) 449 btrace_clear (tp); 450 } 451 452 #if defined (HAVE_LIBEXPAT) 453 454 /* Check the btrace document version. */ 455 456 static void 457 check_xml_btrace_version (struct gdb_xml_parser *parser, 458 const struct gdb_xml_element *element, 459 void *user_data, VEC (gdb_xml_value_s) *attributes) 460 { 461 const char *version = xml_find_attribute (attributes, "version")->value; 462 463 if (strcmp (version, "1.0") != 0) 464 gdb_xml_error (parser, _("Unsupported btrace version: \"%s\""), version); 465 } 466 467 /* Parse a btrace "block" xml record. */ 468 469 static void 470 parse_xml_btrace_block (struct gdb_xml_parser *parser, 471 const struct gdb_xml_element *element, 472 void *user_data, VEC (gdb_xml_value_s) *attributes) 473 { 474 VEC (btrace_block_s) **btrace; 475 struct btrace_block *block; 476 ULONGEST *begin, *end; 477 478 btrace = user_data; 479 block = VEC_safe_push (btrace_block_s, *btrace, NULL); 480 481 begin = xml_find_attribute (attributes, "begin")->value; 482 end = xml_find_attribute (attributes, "end")->value; 483 484 block->begin = *begin; 485 block->end = *end; 486 } 487 488 static const struct gdb_xml_attribute block_attributes[] = { 489 { "begin", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, 490 { "end", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, 491 { NULL, GDB_XML_AF_NONE, NULL, NULL } 492 }; 493 494 static const struct gdb_xml_attribute btrace_attributes[] = { 495 { "version", GDB_XML_AF_NONE, NULL, NULL }, 496 { NULL, GDB_XML_AF_NONE, NULL, NULL } 497 }; 498 499 static const struct gdb_xml_element btrace_children[] = { 500 { "block", block_attributes, NULL, 501 GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL, parse_xml_btrace_block, NULL }, 502 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } 503 }; 504 505 static const struct gdb_xml_element btrace_elements[] = { 506 { "btrace", btrace_attributes, btrace_children, GDB_XML_EF_NONE, 507 check_xml_btrace_version, NULL }, 508 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } 509 }; 510 511 #endif /* defined (HAVE_LIBEXPAT) */ 512 513 /* See btrace.h. */ 514 515 VEC (btrace_block_s) * 516 parse_xml_btrace (const char *buffer) 517 { 518 VEC (btrace_block_s) *btrace = NULL; 519 struct cleanup *cleanup; 520 int errcode; 521 522 #if defined (HAVE_LIBEXPAT) 523 524 cleanup = make_cleanup (VEC_cleanup (btrace_block_s), &btrace); 525 errcode = gdb_xml_parse_quick (_("btrace"), "btrace.dtd", btrace_elements, 526 buffer, &btrace); 527 if (errcode != 0) 528 { 529 do_cleanups (cleanup); 530 return NULL; 531 } 532 533 /* Keep parse results. */ 534 discard_cleanups (cleanup); 535 536 #else /* !defined (HAVE_LIBEXPAT) */ 537 538 error (_("Cannot process branch trace. XML parsing is not supported.")); 539 540 #endif /* !defined (HAVE_LIBEXPAT) */ 541 542 return btrace; 543 } 544