1 /* 2 * probe-finder.c : C expression to kprobe event converter 3 * 4 * Written by Masami Hiramatsu <mhiramat@redhat.com> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 * 20 */ 21 22 #include <sys/utsname.h> 23 #include <sys/types.h> 24 #include <sys/stat.h> 25 #include <fcntl.h> 26 #include <errno.h> 27 #include <stdio.h> 28 #include <unistd.h> 29 #include <getopt.h> 30 #include <stdlib.h> 31 #include <string.h> 32 #include <stdarg.h> 33 #include <ctype.h> 34 #include <dwarf-regs.h> 35 36 #include <linux/bitops.h> 37 #include "event.h" 38 #include "debug.h" 39 #include "util.h" 40 #include "symbol.h" 41 #include "probe-finder.h" 42 43 /* Kprobe tracer basic type is up to u64 */ 44 #define MAX_BASIC_TYPE_BITS 64 45 46 /* 47 * Compare the tail of two strings. 48 * Return 0 if whole of either string is same as another's tail part. 49 */ 50 static int strtailcmp(const char *s1, const char *s2) 51 { 52 int i1 = strlen(s1); 53 int i2 = strlen(s2); 54 while (--i1 >= 0 && --i2 >= 0) { 55 if (s1[i1] != s2[i2]) 56 return s1[i1] - s2[i2]; 57 } 58 return 0; 59 } 60 61 /* Line number list operations */ 62 63 /* Add a line to line number list */ 64 static int line_list__add_line(struct list_head *head, int line) 65 { 66 struct line_node *ln; 67 struct list_head *p; 68 69 /* Reverse search, because new line will be the last one */ 70 list_for_each_entry_reverse(ln, head, list) { 71 if (ln->line < line) { 72 p = &ln->list; 73 goto found; 74 } else if (ln->line == line) /* Already exist */ 75 return 1; 76 } 77 /* List is empty, or the smallest entry */ 78 p = head; 79 found: 80 pr_debug("line list: add a line %u\n", line); 81 ln = zalloc(sizeof(struct line_node)); 82 if (ln == NULL) 83 return -ENOMEM; 84 ln->line = line; 85 INIT_LIST_HEAD(&ln->list); 86 list_add(&ln->list, p); 87 return 0; 88 } 89 90 /* Check if the line in line number list */ 91 static int line_list__has_line(struct list_head *head, int line) 92 { 93 struct line_node *ln; 94 95 /* Reverse search, because new line will be the last one */ 96 list_for_each_entry(ln, head, list) 97 if (ln->line == line) 98 return 1; 99 100 return 0; 101 } 102 103 /* Init line number list */ 104 static void line_list__init(struct list_head *head) 105 { 106 INIT_LIST_HEAD(head); 107 } 108 109 /* Free line number list */ 110 static void line_list__free(struct list_head *head) 111 { 112 struct line_node *ln; 113 while (!list_empty(head)) { 114 ln = list_first_entry(head, struct line_node, list); 115 list_del(&ln->list); 116 free(ln); 117 } 118 } 119 120 /* Dwarf FL wrappers */ 121 static char *debuginfo_path; /* Currently dummy */ 122 123 static const Dwfl_Callbacks offline_callbacks = { 124 .find_debuginfo = dwfl_standard_find_debuginfo, 125 .debuginfo_path = &debuginfo_path, 126 127 .section_address = dwfl_offline_section_address, 128 129 /* We use this table for core files too. */ 130 .find_elf = dwfl_build_id_find_elf, 131 }; 132 133 /* Get a Dwarf from offline image */ 134 static Dwarf *dwfl_init_offline_dwarf(int fd, Dwfl **dwflp, Dwarf_Addr *bias) 135 { 136 Dwfl_Module *mod; 137 Dwarf *dbg = NULL; 138 139 if (!dwflp) 140 return NULL; 141 142 *dwflp = dwfl_begin(&offline_callbacks); 143 if (!*dwflp) 144 return NULL; 145 146 mod = dwfl_report_offline(*dwflp, "", "", fd); 147 if (!mod) 148 goto error; 149 150 dbg = dwfl_module_getdwarf(mod, bias); 151 if (!dbg) { 152 error: 153 dwfl_end(*dwflp); 154 *dwflp = NULL; 155 } 156 return dbg; 157 } 158 159 #if _ELFUTILS_PREREQ(0, 148) 160 /* This method is buggy if elfutils is older than 0.148 */ 161 static int __linux_kernel_find_elf(Dwfl_Module *mod, 162 void **userdata, 163 const char *module_name, 164 Dwarf_Addr base, 165 char **file_name, Elf **elfp) 166 { 167 int fd; 168 const char *path = kernel_get_module_path(module_name); 169 170 pr_debug2("Use file %s for %s\n", path, module_name); 171 if (path) { 172 fd = open(path, O_RDONLY); 173 if (fd >= 0) { 174 *file_name = strdup(path); 175 return fd; 176 } 177 } 178 /* If failed, try to call standard method */ 179 return dwfl_linux_kernel_find_elf(mod, userdata, module_name, base, 180 file_name, elfp); 181 } 182 183 static const Dwfl_Callbacks kernel_callbacks = { 184 .find_debuginfo = dwfl_standard_find_debuginfo, 185 .debuginfo_path = &debuginfo_path, 186 187 .find_elf = __linux_kernel_find_elf, 188 .section_address = dwfl_linux_kernel_module_section_address, 189 }; 190 191 /* Get a Dwarf from live kernel image */ 192 static Dwarf *dwfl_init_live_kernel_dwarf(Dwarf_Addr addr, Dwfl **dwflp, 193 Dwarf_Addr *bias) 194 { 195 Dwarf *dbg; 196 197 if (!dwflp) 198 return NULL; 199 200 *dwflp = dwfl_begin(&kernel_callbacks); 201 if (!*dwflp) 202 return NULL; 203 204 /* Load the kernel dwarves: Don't care the result here */ 205 dwfl_linux_kernel_report_kernel(*dwflp); 206 dwfl_linux_kernel_report_modules(*dwflp); 207 208 dbg = dwfl_addrdwarf(*dwflp, addr, bias); 209 /* Here, check whether we could get a real dwarf */ 210 if (!dbg) { 211 pr_debug("Failed to find kernel dwarf at %lx\n", 212 (unsigned long)addr); 213 dwfl_end(*dwflp); 214 *dwflp = NULL; 215 } 216 return dbg; 217 } 218 #else 219 /* With older elfutils, this just support kernel module... */ 220 static Dwarf *dwfl_init_live_kernel_dwarf(Dwarf_Addr addr __used, Dwfl **dwflp, 221 Dwarf_Addr *bias) 222 { 223 int fd; 224 const char *path = kernel_get_module_path("kernel"); 225 226 if (!path) { 227 pr_err("Failed to find vmlinux path\n"); 228 return NULL; 229 } 230 231 pr_debug2("Use file %s for debuginfo\n", path); 232 fd = open(path, O_RDONLY); 233 if (fd < 0) 234 return NULL; 235 236 return dwfl_init_offline_dwarf(fd, dwflp, bias); 237 } 238 #endif 239 240 /* Dwarf wrappers */ 241 242 /* Find the realpath of the target file. */ 243 static const char *cu_find_realpath(Dwarf_Die *cu_die, const char *fname) 244 { 245 Dwarf_Files *files; 246 size_t nfiles, i; 247 const char *src = NULL; 248 int ret; 249 250 if (!fname) 251 return NULL; 252 253 ret = dwarf_getsrcfiles(cu_die, &files, &nfiles); 254 if (ret != 0) 255 return NULL; 256 257 for (i = 0; i < nfiles; i++) { 258 src = dwarf_filesrc(files, i, NULL, NULL); 259 if (strtailcmp(src, fname) == 0) 260 break; 261 } 262 if (i == nfiles) 263 return NULL; 264 return src; 265 } 266 267 /* Get DW_AT_comp_dir (should be NULL with older gcc) */ 268 static const char *cu_get_comp_dir(Dwarf_Die *cu_die) 269 { 270 Dwarf_Attribute attr; 271 if (dwarf_attr(cu_die, DW_AT_comp_dir, &attr) == NULL) 272 return NULL; 273 return dwarf_formstring(&attr); 274 } 275 276 /* Compare diename and tname */ 277 static bool die_compare_name(Dwarf_Die *dw_die, const char *tname) 278 { 279 const char *name; 280 name = dwarf_diename(dw_die); 281 return name ? (strcmp(tname, name) == 0) : false; 282 } 283 284 /* Get callsite line number of inline-function instance */ 285 static int die_get_call_lineno(Dwarf_Die *in_die) 286 { 287 Dwarf_Attribute attr; 288 Dwarf_Word ret; 289 290 if (!dwarf_attr(in_die, DW_AT_call_line, &attr)) 291 return -ENOENT; 292 293 dwarf_formudata(&attr, &ret); 294 return (int)ret; 295 } 296 297 /* Get type die */ 298 static Dwarf_Die *die_get_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem) 299 { 300 Dwarf_Attribute attr; 301 302 if (dwarf_attr_integrate(vr_die, DW_AT_type, &attr) && 303 dwarf_formref_die(&attr, die_mem)) 304 return die_mem; 305 else 306 return NULL; 307 } 308 309 /* Get a type die, but skip qualifiers */ 310 static Dwarf_Die *__die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem) 311 { 312 int tag; 313 314 do { 315 vr_die = die_get_type(vr_die, die_mem); 316 if (!vr_die) 317 break; 318 tag = dwarf_tag(vr_die); 319 } while (tag == DW_TAG_const_type || 320 tag == DW_TAG_restrict_type || 321 tag == DW_TAG_volatile_type || 322 tag == DW_TAG_shared_type); 323 324 return vr_die; 325 } 326 327 /* Get a type die, but skip qualifiers and typedef */ 328 static Dwarf_Die *die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem) 329 { 330 do { 331 vr_die = __die_get_real_type(vr_die, die_mem); 332 } while (vr_die && dwarf_tag(vr_die) == DW_TAG_typedef); 333 334 return vr_die; 335 } 336 337 static int die_get_attr_udata(Dwarf_Die *tp_die, unsigned int attr_name, 338 Dwarf_Word *result) 339 { 340 Dwarf_Attribute attr; 341 342 if (dwarf_attr(tp_die, attr_name, &attr) == NULL || 343 dwarf_formudata(&attr, result) != 0) 344 return -ENOENT; 345 346 return 0; 347 } 348 349 static bool die_is_signed_type(Dwarf_Die *tp_die) 350 { 351 Dwarf_Word ret; 352 353 if (die_get_attr_udata(tp_die, DW_AT_encoding, &ret)) 354 return false; 355 356 return (ret == DW_ATE_signed_char || ret == DW_ATE_signed || 357 ret == DW_ATE_signed_fixed); 358 } 359 360 static int die_get_byte_size(Dwarf_Die *tp_die) 361 { 362 Dwarf_Word ret; 363 364 if (die_get_attr_udata(tp_die, DW_AT_byte_size, &ret)) 365 return 0; 366 367 return (int)ret; 368 } 369 370 static int die_get_bit_size(Dwarf_Die *tp_die) 371 { 372 Dwarf_Word ret; 373 374 if (die_get_attr_udata(tp_die, DW_AT_bit_size, &ret)) 375 return 0; 376 377 return (int)ret; 378 } 379 380 static int die_get_bit_offset(Dwarf_Die *tp_die) 381 { 382 Dwarf_Word ret; 383 384 if (die_get_attr_udata(tp_die, DW_AT_bit_offset, &ret)) 385 return 0; 386 387 return (int)ret; 388 } 389 390 /* Get data_member_location offset */ 391 static int die_get_data_member_location(Dwarf_Die *mb_die, Dwarf_Word *offs) 392 { 393 Dwarf_Attribute attr; 394 Dwarf_Op *expr; 395 size_t nexpr; 396 int ret; 397 398 if (dwarf_attr(mb_die, DW_AT_data_member_location, &attr) == NULL) 399 return -ENOENT; 400 401 if (dwarf_formudata(&attr, offs) != 0) { 402 /* DW_AT_data_member_location should be DW_OP_plus_uconst */ 403 ret = dwarf_getlocation(&attr, &expr, &nexpr); 404 if (ret < 0 || nexpr == 0) 405 return -ENOENT; 406 407 if (expr[0].atom != DW_OP_plus_uconst || nexpr != 1) { 408 pr_debug("Unable to get offset:Unexpected OP %x (%zd)\n", 409 expr[0].atom, nexpr); 410 return -ENOTSUP; 411 } 412 *offs = (Dwarf_Word)expr[0].number; 413 } 414 return 0; 415 } 416 417 /* Return values for die_find callbacks */ 418 enum { 419 DIE_FIND_CB_FOUND = 0, /* End of Search */ 420 DIE_FIND_CB_CHILD = 1, /* Search only children */ 421 DIE_FIND_CB_SIBLING = 2, /* Search only siblings */ 422 DIE_FIND_CB_CONTINUE = 3, /* Search children and siblings */ 423 }; 424 425 /* Search a child die */ 426 static Dwarf_Die *die_find_child(Dwarf_Die *rt_die, 427 int (*callback)(Dwarf_Die *, void *), 428 void *data, Dwarf_Die *die_mem) 429 { 430 Dwarf_Die child_die; 431 int ret; 432 433 ret = dwarf_child(rt_die, die_mem); 434 if (ret != 0) 435 return NULL; 436 437 do { 438 ret = callback(die_mem, data); 439 if (ret == DIE_FIND_CB_FOUND) 440 return die_mem; 441 442 if ((ret & DIE_FIND_CB_CHILD) && 443 die_find_child(die_mem, callback, data, &child_die)) { 444 memcpy(die_mem, &child_die, sizeof(Dwarf_Die)); 445 return die_mem; 446 } 447 } while ((ret & DIE_FIND_CB_SIBLING) && 448 dwarf_siblingof(die_mem, die_mem) == 0); 449 450 return NULL; 451 } 452 453 struct __addr_die_search_param { 454 Dwarf_Addr addr; 455 Dwarf_Die *die_mem; 456 }; 457 458 static int __die_search_func_cb(Dwarf_Die *fn_die, void *data) 459 { 460 struct __addr_die_search_param *ad = data; 461 462 if (dwarf_tag(fn_die) == DW_TAG_subprogram && 463 dwarf_haspc(fn_die, ad->addr)) { 464 memcpy(ad->die_mem, fn_die, sizeof(Dwarf_Die)); 465 return DWARF_CB_ABORT; 466 } 467 return DWARF_CB_OK; 468 } 469 470 /* Search a real subprogram including this line, */ 471 static Dwarf_Die *die_find_real_subprogram(Dwarf_Die *cu_die, Dwarf_Addr addr, 472 Dwarf_Die *die_mem) 473 { 474 struct __addr_die_search_param ad; 475 ad.addr = addr; 476 ad.die_mem = die_mem; 477 /* dwarf_getscopes can't find subprogram. */ 478 if (!dwarf_getfuncs(cu_die, __die_search_func_cb, &ad, 0)) 479 return NULL; 480 else 481 return die_mem; 482 } 483 484 /* die_find callback for inline function search */ 485 static int __die_find_inline_cb(Dwarf_Die *die_mem, void *data) 486 { 487 Dwarf_Addr *addr = data; 488 489 if (dwarf_tag(die_mem) == DW_TAG_inlined_subroutine && 490 dwarf_haspc(die_mem, *addr)) 491 return DIE_FIND_CB_FOUND; 492 493 return DIE_FIND_CB_CONTINUE; 494 } 495 496 /* Similar to dwarf_getfuncs, but returns inlined_subroutine if exists. */ 497 static Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, 498 Dwarf_Die *die_mem) 499 { 500 return die_find_child(sp_die, __die_find_inline_cb, &addr, die_mem); 501 } 502 503 /* Walker on lines (Note: line number will not be sorted) */ 504 typedef int (* line_walk_handler_t) (const char *fname, int lineno, 505 Dwarf_Addr addr, void *data); 506 507 struct __line_walk_param { 508 const char *fname; 509 line_walk_handler_t handler; 510 void *data; 511 int retval; 512 }; 513 514 static int __die_walk_funclines_cb(Dwarf_Die *in_die, void *data) 515 { 516 struct __line_walk_param *lw = data; 517 Dwarf_Addr addr; 518 int lineno; 519 520 if (dwarf_tag(in_die) == DW_TAG_inlined_subroutine) { 521 lineno = die_get_call_lineno(in_die); 522 if (lineno > 0 && dwarf_entrypc(in_die, &addr) == 0) { 523 lw->retval = lw->handler(lw->fname, lineno, addr, 524 lw->data); 525 if (lw->retval != 0) 526 return DIE_FIND_CB_FOUND; 527 } 528 } 529 return DIE_FIND_CB_SIBLING; 530 } 531 532 /* Walk on lines of blocks included in given DIE */ 533 static int __die_walk_funclines(Dwarf_Die *sp_die, 534 line_walk_handler_t handler, void *data) 535 { 536 struct __line_walk_param lw = { 537 .handler = handler, 538 .data = data, 539 .retval = 0, 540 }; 541 Dwarf_Die die_mem; 542 Dwarf_Addr addr; 543 int lineno; 544 545 /* Handle function declaration line */ 546 lw.fname = dwarf_decl_file(sp_die); 547 if (lw.fname && dwarf_decl_line(sp_die, &lineno) == 0 && 548 dwarf_entrypc(sp_die, &addr) == 0) { 549 lw.retval = handler(lw.fname, lineno, addr, data); 550 if (lw.retval != 0) 551 goto done; 552 } 553 die_find_child(sp_die, __die_walk_funclines_cb, &lw, &die_mem); 554 done: 555 return lw.retval; 556 } 557 558 static int __die_walk_culines_cb(Dwarf_Die *sp_die, void *data) 559 { 560 struct __line_walk_param *lw = data; 561 562 lw->retval = __die_walk_funclines(sp_die, lw->handler, lw->data); 563 if (lw->retval != 0) 564 return DWARF_CB_ABORT; 565 566 return DWARF_CB_OK; 567 } 568 569 /* 570 * Walk on lines inside given PDIE. If the PDIE is subprogram, walk only on 571 * the lines inside the subprogram, otherwise PDIE must be a CU DIE. 572 */ 573 static int die_walk_lines(Dwarf_Die *pdie, line_walk_handler_t handler, 574 void *data) 575 { 576 Dwarf_Lines *lines; 577 Dwarf_Line *line; 578 Dwarf_Addr addr; 579 const char *fname; 580 int lineno, ret = 0; 581 Dwarf_Die die_mem, *cu_die; 582 size_t nlines, i; 583 584 /* Get the CU die */ 585 if (dwarf_tag(pdie) == DW_TAG_subprogram) 586 cu_die = dwarf_diecu(pdie, &die_mem, NULL, NULL); 587 else 588 cu_die = pdie; 589 if (!cu_die) { 590 pr_debug2("Failed to get CU from subprogram\n"); 591 return -EINVAL; 592 } 593 594 /* Get lines list in the CU */ 595 if (dwarf_getsrclines(cu_die, &lines, &nlines) != 0) { 596 pr_debug2("Failed to get source lines on this CU.\n"); 597 return -ENOENT; 598 } 599 pr_debug2("Get %zd lines from this CU\n", nlines); 600 601 /* Walk on the lines on lines list */ 602 for (i = 0; i < nlines; i++) { 603 line = dwarf_onesrcline(lines, i); 604 if (line == NULL || 605 dwarf_lineno(line, &lineno) != 0 || 606 dwarf_lineaddr(line, &addr) != 0) { 607 pr_debug2("Failed to get line info. " 608 "Possible error in debuginfo.\n"); 609 continue; 610 } 611 /* Filter lines based on address */ 612 if (pdie != cu_die) 613 /* 614 * Address filtering 615 * The line is included in given function, and 616 * no inline block includes it. 617 */ 618 if (!dwarf_haspc(pdie, addr) || 619 die_find_inlinefunc(pdie, addr, &die_mem)) 620 continue; 621 /* Get source line */ 622 fname = dwarf_linesrc(line, NULL, NULL); 623 624 ret = handler(fname, lineno, addr, data); 625 if (ret != 0) 626 return ret; 627 } 628 629 /* 630 * Dwarf lines doesn't include function declarations and inlined 631 * subroutines. We have to check functions list or given function. 632 */ 633 if (pdie != cu_die) 634 ret = __die_walk_funclines(pdie, handler, data); 635 else { 636 struct __line_walk_param param = { 637 .handler = handler, 638 .data = data, 639 .retval = 0, 640 }; 641 dwarf_getfuncs(cu_die, __die_walk_culines_cb, ¶m, 0); 642 ret = param.retval; 643 } 644 645 return ret; 646 } 647 648 struct __find_variable_param { 649 const char *name; 650 Dwarf_Addr addr; 651 }; 652 653 static int __die_find_variable_cb(Dwarf_Die *die_mem, void *data) 654 { 655 struct __find_variable_param *fvp = data; 656 int tag; 657 658 tag = dwarf_tag(die_mem); 659 if ((tag == DW_TAG_formal_parameter || 660 tag == DW_TAG_variable) && 661 die_compare_name(die_mem, fvp->name)) 662 return DIE_FIND_CB_FOUND; 663 664 if (dwarf_haspc(die_mem, fvp->addr)) 665 return DIE_FIND_CB_CONTINUE; 666 else 667 return DIE_FIND_CB_SIBLING; 668 } 669 670 /* Find a variable called 'name' at given address */ 671 static Dwarf_Die *die_find_variable_at(Dwarf_Die *sp_die, const char *name, 672 Dwarf_Addr addr, Dwarf_Die *die_mem) 673 { 674 struct __find_variable_param fvp = { .name = name, .addr = addr}; 675 676 return die_find_child(sp_die, __die_find_variable_cb, (void *)&fvp, 677 die_mem); 678 } 679 680 static int __die_find_member_cb(Dwarf_Die *die_mem, void *data) 681 { 682 const char *name = data; 683 684 if ((dwarf_tag(die_mem) == DW_TAG_member) && 685 die_compare_name(die_mem, name)) 686 return DIE_FIND_CB_FOUND; 687 688 return DIE_FIND_CB_SIBLING; 689 } 690 691 /* Find a member called 'name' */ 692 static Dwarf_Die *die_find_member(Dwarf_Die *st_die, const char *name, 693 Dwarf_Die *die_mem) 694 { 695 return die_find_child(st_die, __die_find_member_cb, (void *)name, 696 die_mem); 697 } 698 699 /* Get the name of given variable DIE */ 700 static int die_get_typename(Dwarf_Die *vr_die, char *buf, int len) 701 { 702 Dwarf_Die type; 703 int tag, ret, ret2; 704 const char *tmp = ""; 705 706 if (__die_get_real_type(vr_die, &type) == NULL) 707 return -ENOENT; 708 709 tag = dwarf_tag(&type); 710 if (tag == DW_TAG_array_type || tag == DW_TAG_pointer_type) 711 tmp = "*"; 712 else if (tag == DW_TAG_subroutine_type) { 713 /* Function pointer */ 714 ret = snprintf(buf, len, "(function_type)"); 715 return (ret >= len) ? -E2BIG : ret; 716 } else { 717 if (!dwarf_diename(&type)) 718 return -ENOENT; 719 if (tag == DW_TAG_union_type) 720 tmp = "union "; 721 else if (tag == DW_TAG_structure_type) 722 tmp = "struct "; 723 /* Write a base name */ 724 ret = snprintf(buf, len, "%s%s", tmp, dwarf_diename(&type)); 725 return (ret >= len) ? -E2BIG : ret; 726 } 727 ret = die_get_typename(&type, buf, len); 728 if (ret > 0) { 729 ret2 = snprintf(buf + ret, len - ret, "%s", tmp); 730 ret = (ret2 >= len - ret) ? -E2BIG : ret2 + ret; 731 } 732 return ret; 733 } 734 735 /* Get the name and type of given variable DIE, stored as "type\tname" */ 736 static int die_get_varname(Dwarf_Die *vr_die, char *buf, int len) 737 { 738 int ret, ret2; 739 740 ret = die_get_typename(vr_die, buf, len); 741 if (ret < 0) { 742 pr_debug("Failed to get type, make it unknown.\n"); 743 ret = snprintf(buf, len, "(unknown_type)"); 744 } 745 if (ret > 0) { 746 ret2 = snprintf(buf + ret, len - ret, "\t%s", 747 dwarf_diename(vr_die)); 748 ret = (ret2 >= len - ret) ? -E2BIG : ret2 + ret; 749 } 750 return ret; 751 } 752 753 /* 754 * Probe finder related functions 755 */ 756 757 static struct probe_trace_arg_ref *alloc_trace_arg_ref(long offs) 758 { 759 struct probe_trace_arg_ref *ref; 760 ref = zalloc(sizeof(struct probe_trace_arg_ref)); 761 if (ref != NULL) 762 ref->offset = offs; 763 return ref; 764 } 765 766 /* 767 * Convert a location into trace_arg. 768 * If tvar == NULL, this just checks variable can be converted. 769 */ 770 static int convert_variable_location(Dwarf_Die *vr_die, Dwarf_Addr addr, 771 Dwarf_Op *fb_ops, 772 struct probe_trace_arg *tvar) 773 { 774 Dwarf_Attribute attr; 775 Dwarf_Op *op; 776 size_t nops; 777 unsigned int regn; 778 Dwarf_Word offs = 0; 779 bool ref = false; 780 const char *regs; 781 int ret; 782 783 if (dwarf_attr(vr_die, DW_AT_external, &attr) != NULL) 784 goto static_var; 785 786 /* TODO: handle more than 1 exprs */ 787 if (dwarf_attr(vr_die, DW_AT_location, &attr) == NULL || 788 dwarf_getlocation_addr(&attr, addr, &op, &nops, 1) <= 0 || 789 nops == 0) { 790 /* TODO: Support const_value */ 791 return -ENOENT; 792 } 793 794 if (op->atom == DW_OP_addr) { 795 static_var: 796 if (!tvar) 797 return 0; 798 /* Static variables on memory (not stack), make @varname */ 799 ret = strlen(dwarf_diename(vr_die)); 800 tvar->value = zalloc(ret + 2); 801 if (tvar->value == NULL) 802 return -ENOMEM; 803 snprintf(tvar->value, ret + 2, "@%s", dwarf_diename(vr_die)); 804 tvar->ref = alloc_trace_arg_ref((long)offs); 805 if (tvar->ref == NULL) 806 return -ENOMEM; 807 return 0; 808 } 809 810 /* If this is based on frame buffer, set the offset */ 811 if (op->atom == DW_OP_fbreg) { 812 if (fb_ops == NULL) 813 return -ENOTSUP; 814 ref = true; 815 offs = op->number; 816 op = &fb_ops[0]; 817 } 818 819 if (op->atom >= DW_OP_breg0 && op->atom <= DW_OP_breg31) { 820 regn = op->atom - DW_OP_breg0; 821 offs += op->number; 822 ref = true; 823 } else if (op->atom >= DW_OP_reg0 && op->atom <= DW_OP_reg31) { 824 regn = op->atom - DW_OP_reg0; 825 } else if (op->atom == DW_OP_bregx) { 826 regn = op->number; 827 offs += op->number2; 828 ref = true; 829 } else if (op->atom == DW_OP_regx) { 830 regn = op->number; 831 } else { 832 pr_debug("DW_OP %x is not supported.\n", op->atom); 833 return -ENOTSUP; 834 } 835 836 if (!tvar) 837 return 0; 838 839 regs = get_arch_regstr(regn); 840 if (!regs) { 841 /* This should be a bug in DWARF or this tool */ 842 pr_warning("Mapping for the register number %u " 843 "missing on this architecture.\n", regn); 844 return -ERANGE; 845 } 846 847 tvar->value = strdup(regs); 848 if (tvar->value == NULL) 849 return -ENOMEM; 850 851 if (ref) { 852 tvar->ref = alloc_trace_arg_ref((long)offs); 853 if (tvar->ref == NULL) 854 return -ENOMEM; 855 } 856 return 0; 857 } 858 859 #define BYTES_TO_BITS(nb) ((nb) * BITS_PER_LONG / sizeof(long)) 860 861 static int convert_variable_type(Dwarf_Die *vr_die, 862 struct probe_trace_arg *tvar, 863 const char *cast) 864 { 865 struct probe_trace_arg_ref **ref_ptr = &tvar->ref; 866 Dwarf_Die type; 867 char buf[16]; 868 int ret; 869 870 /* TODO: check all types */ 871 if (cast && strcmp(cast, "string") != 0) { 872 /* Non string type is OK */ 873 tvar->type = strdup(cast); 874 return (tvar->type == NULL) ? -ENOMEM : 0; 875 } 876 877 if (die_get_bit_size(vr_die) != 0) { 878 /* This is a bitfield */ 879 ret = snprintf(buf, 16, "b%d@%d/%zd", die_get_bit_size(vr_die), 880 die_get_bit_offset(vr_die), 881 BYTES_TO_BITS(die_get_byte_size(vr_die))); 882 goto formatted; 883 } 884 885 if (die_get_real_type(vr_die, &type) == NULL) { 886 pr_warning("Failed to get a type information of %s.\n", 887 dwarf_diename(vr_die)); 888 return -ENOENT; 889 } 890 891 pr_debug("%s type is %s.\n", 892 dwarf_diename(vr_die), dwarf_diename(&type)); 893 894 if (cast && strcmp(cast, "string") == 0) { /* String type */ 895 ret = dwarf_tag(&type); 896 if (ret != DW_TAG_pointer_type && 897 ret != DW_TAG_array_type) { 898 pr_warning("Failed to cast into string: " 899 "%s(%s) is not a pointer nor array.\n", 900 dwarf_diename(vr_die), dwarf_diename(&type)); 901 return -EINVAL; 902 } 903 if (ret == DW_TAG_pointer_type) { 904 if (die_get_real_type(&type, &type) == NULL) { 905 pr_warning("Failed to get a type" 906 " information.\n"); 907 return -ENOENT; 908 } 909 while (*ref_ptr) 910 ref_ptr = &(*ref_ptr)->next; 911 /* Add new reference with offset +0 */ 912 *ref_ptr = zalloc(sizeof(struct probe_trace_arg_ref)); 913 if (*ref_ptr == NULL) { 914 pr_warning("Out of memory error\n"); 915 return -ENOMEM; 916 } 917 } 918 if (!die_compare_name(&type, "char") && 919 !die_compare_name(&type, "unsigned char")) { 920 pr_warning("Failed to cast into string: " 921 "%s is not (unsigned) char *.\n", 922 dwarf_diename(vr_die)); 923 return -EINVAL; 924 } 925 tvar->type = strdup(cast); 926 return (tvar->type == NULL) ? -ENOMEM : 0; 927 } 928 929 ret = BYTES_TO_BITS(die_get_byte_size(&type)); 930 if (!ret) 931 /* No size ... try to use default type */ 932 return 0; 933 934 /* Check the bitwidth */ 935 if (ret > MAX_BASIC_TYPE_BITS) { 936 pr_info("%s exceeds max-bitwidth. Cut down to %d bits.\n", 937 dwarf_diename(&type), MAX_BASIC_TYPE_BITS); 938 ret = MAX_BASIC_TYPE_BITS; 939 } 940 ret = snprintf(buf, 16, "%c%d", 941 die_is_signed_type(&type) ? 's' : 'u', ret); 942 943 formatted: 944 if (ret < 0 || ret >= 16) { 945 if (ret >= 16) 946 ret = -E2BIG; 947 pr_warning("Failed to convert variable type: %s\n", 948 strerror(-ret)); 949 return ret; 950 } 951 tvar->type = strdup(buf); 952 if (tvar->type == NULL) 953 return -ENOMEM; 954 return 0; 955 } 956 957 static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname, 958 struct perf_probe_arg_field *field, 959 struct probe_trace_arg_ref **ref_ptr, 960 Dwarf_Die *die_mem) 961 { 962 struct probe_trace_arg_ref *ref = *ref_ptr; 963 Dwarf_Die type; 964 Dwarf_Word offs; 965 int ret, tag; 966 967 pr_debug("converting %s in %s\n", field->name, varname); 968 if (die_get_real_type(vr_die, &type) == NULL) { 969 pr_warning("Failed to get the type of %s.\n", varname); 970 return -ENOENT; 971 } 972 pr_debug2("Var real type: (%x)\n", (unsigned)dwarf_dieoffset(&type)); 973 tag = dwarf_tag(&type); 974 975 if (field->name[0] == '[' && 976 (tag == DW_TAG_array_type || tag == DW_TAG_pointer_type)) { 977 if (field->next) 978 /* Save original type for next field */ 979 memcpy(die_mem, &type, sizeof(*die_mem)); 980 /* Get the type of this array */ 981 if (die_get_real_type(&type, &type) == NULL) { 982 pr_warning("Failed to get the type of %s.\n", varname); 983 return -ENOENT; 984 } 985 pr_debug2("Array real type: (%x)\n", 986 (unsigned)dwarf_dieoffset(&type)); 987 if (tag == DW_TAG_pointer_type) { 988 ref = zalloc(sizeof(struct probe_trace_arg_ref)); 989 if (ref == NULL) 990 return -ENOMEM; 991 if (*ref_ptr) 992 (*ref_ptr)->next = ref; 993 else 994 *ref_ptr = ref; 995 } 996 ref->offset += die_get_byte_size(&type) * field->index; 997 if (!field->next) 998 /* Save vr_die for converting types */ 999 memcpy(die_mem, vr_die, sizeof(*die_mem)); 1000 goto next; 1001 } else if (tag == DW_TAG_pointer_type) { 1002 /* Check the pointer and dereference */ 1003 if (!field->ref) { 1004 pr_err("Semantic error: %s must be referred by '->'\n", 1005 field->name); 1006 return -EINVAL; 1007 } 1008 /* Get the type pointed by this pointer */ 1009 if (die_get_real_type(&type, &type) == NULL) { 1010 pr_warning("Failed to get the type of %s.\n", varname); 1011 return -ENOENT; 1012 } 1013 /* Verify it is a data structure */ 1014 if (dwarf_tag(&type) != DW_TAG_structure_type) { 1015 pr_warning("%s is not a data structure.\n", varname); 1016 return -EINVAL; 1017 } 1018 1019 ref = zalloc(sizeof(struct probe_trace_arg_ref)); 1020 if (ref == NULL) 1021 return -ENOMEM; 1022 if (*ref_ptr) 1023 (*ref_ptr)->next = ref; 1024 else 1025 *ref_ptr = ref; 1026 } else { 1027 /* Verify it is a data structure */ 1028 if (tag != DW_TAG_structure_type) { 1029 pr_warning("%s is not a data structure.\n", varname); 1030 return -EINVAL; 1031 } 1032 if (field->name[0] == '[') { 1033 pr_err("Semantic error: %s is not a pointor" 1034 " nor array.\n", varname); 1035 return -EINVAL; 1036 } 1037 if (field->ref) { 1038 pr_err("Semantic error: %s must be referred by '.'\n", 1039 field->name); 1040 return -EINVAL; 1041 } 1042 if (!ref) { 1043 pr_warning("Structure on a register is not " 1044 "supported yet.\n"); 1045 return -ENOTSUP; 1046 } 1047 } 1048 1049 if (die_find_member(&type, field->name, die_mem) == NULL) { 1050 pr_warning("%s(tyep:%s) has no member %s.\n", varname, 1051 dwarf_diename(&type), field->name); 1052 return -EINVAL; 1053 } 1054 1055 /* Get the offset of the field */ 1056 ret = die_get_data_member_location(die_mem, &offs); 1057 if (ret < 0) { 1058 pr_warning("Failed to get the offset of %s.\n", field->name); 1059 return ret; 1060 } 1061 ref->offset += (long)offs; 1062 1063 next: 1064 /* Converting next field */ 1065 if (field->next) 1066 return convert_variable_fields(die_mem, field->name, 1067 field->next, &ref, die_mem); 1068 else 1069 return 0; 1070 } 1071 1072 /* Show a variables in kprobe event format */ 1073 static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf) 1074 { 1075 Dwarf_Die die_mem; 1076 int ret; 1077 1078 pr_debug("Converting variable %s into trace event.\n", 1079 dwarf_diename(vr_die)); 1080 1081 ret = convert_variable_location(vr_die, pf->addr, pf->fb_ops, 1082 pf->tvar); 1083 if (ret == -ENOENT) 1084 pr_err("Failed to find the location of %s at this address.\n" 1085 " Perhaps, it has been optimized out.\n", pf->pvar->var); 1086 else if (ret == -ENOTSUP) 1087 pr_err("Sorry, we don't support this variable location yet.\n"); 1088 else if (pf->pvar->field) { 1089 ret = convert_variable_fields(vr_die, pf->pvar->var, 1090 pf->pvar->field, &pf->tvar->ref, 1091 &die_mem); 1092 vr_die = &die_mem; 1093 } 1094 if (ret == 0) 1095 ret = convert_variable_type(vr_die, pf->tvar, pf->pvar->type); 1096 /* *expr will be cached in libdw. Don't free it. */ 1097 return ret; 1098 } 1099 1100 /* Find a variable in a subprogram die */ 1101 static int find_variable(Dwarf_Die *sp_die, struct probe_finder *pf) 1102 { 1103 Dwarf_Die vr_die, *scopes; 1104 char buf[32], *ptr; 1105 int ret, nscopes; 1106 1107 if (!is_c_varname(pf->pvar->var)) { 1108 /* Copy raw parameters */ 1109 pf->tvar->value = strdup(pf->pvar->var); 1110 if (pf->tvar->value == NULL) 1111 return -ENOMEM; 1112 if (pf->pvar->type) { 1113 pf->tvar->type = strdup(pf->pvar->type); 1114 if (pf->tvar->type == NULL) 1115 return -ENOMEM; 1116 } 1117 if (pf->pvar->name) { 1118 pf->tvar->name = strdup(pf->pvar->name); 1119 if (pf->tvar->name == NULL) 1120 return -ENOMEM; 1121 } else 1122 pf->tvar->name = NULL; 1123 return 0; 1124 } 1125 1126 if (pf->pvar->name) 1127 pf->tvar->name = strdup(pf->pvar->name); 1128 else { 1129 ret = synthesize_perf_probe_arg(pf->pvar, buf, 32); 1130 if (ret < 0) 1131 return ret; 1132 ptr = strchr(buf, ':'); /* Change type separator to _ */ 1133 if (ptr) 1134 *ptr = '_'; 1135 pf->tvar->name = strdup(buf); 1136 } 1137 if (pf->tvar->name == NULL) 1138 return -ENOMEM; 1139 1140 pr_debug("Searching '%s' variable in context.\n", 1141 pf->pvar->var); 1142 /* Search child die for local variables and parameters. */ 1143 if (die_find_variable_at(sp_die, pf->pvar->var, pf->addr, &vr_die)) 1144 ret = convert_variable(&vr_die, pf); 1145 else { 1146 /* Search upper class */ 1147 nscopes = dwarf_getscopes_die(sp_die, &scopes); 1148 while (nscopes-- > 1) { 1149 pr_debug("Searching variables in %s\n", 1150 dwarf_diename(&scopes[nscopes])); 1151 /* We should check this scope, so give dummy address */ 1152 if (die_find_variable_at(&scopes[nscopes], 1153 pf->pvar->var, 0, 1154 &vr_die)) { 1155 ret = convert_variable(&vr_die, pf); 1156 goto found; 1157 } 1158 } 1159 if (scopes) 1160 free(scopes); 1161 ret = -ENOENT; 1162 } 1163 found: 1164 if (ret < 0) 1165 pr_warning("Failed to find '%s' in this function.\n", 1166 pf->pvar->var); 1167 return ret; 1168 } 1169 1170 /* Convert subprogram DIE to trace point */ 1171 static int convert_to_trace_point(Dwarf_Die *sp_die, Dwarf_Addr paddr, 1172 bool retprobe, struct probe_trace_point *tp) 1173 { 1174 Dwarf_Addr eaddr; 1175 const char *name; 1176 1177 /* Copy the name of probe point */ 1178 name = dwarf_diename(sp_die); 1179 if (name) { 1180 if (dwarf_entrypc(sp_die, &eaddr) != 0) { 1181 pr_warning("Failed to get entry address of %s\n", 1182 dwarf_diename(sp_die)); 1183 return -ENOENT; 1184 } 1185 tp->symbol = strdup(name); 1186 if (tp->symbol == NULL) 1187 return -ENOMEM; 1188 tp->offset = (unsigned long)(paddr - eaddr); 1189 } else 1190 /* This function has no name. */ 1191 tp->offset = (unsigned long)paddr; 1192 1193 /* Return probe must be on the head of a subprogram */ 1194 if (retprobe) { 1195 if (eaddr != paddr) { 1196 pr_warning("Return probe must be on the head of" 1197 " a real function.\n"); 1198 return -EINVAL; 1199 } 1200 tp->retprobe = true; 1201 } 1202 1203 return 0; 1204 } 1205 1206 /* Call probe_finder callback with real subprogram DIE */ 1207 static int call_probe_finder(Dwarf_Die *sp_die, struct probe_finder *pf) 1208 { 1209 Dwarf_Die die_mem; 1210 Dwarf_Attribute fb_attr; 1211 size_t nops; 1212 int ret; 1213 1214 /* If no real subprogram, find a real one */ 1215 if (!sp_die || dwarf_tag(sp_die) != DW_TAG_subprogram) { 1216 sp_die = die_find_real_subprogram(&pf->cu_die, 1217 pf->addr, &die_mem); 1218 if (!sp_die) { 1219 pr_warning("Failed to find probe point in any " 1220 "functions.\n"); 1221 return -ENOENT; 1222 } 1223 } 1224 1225 /* Get the frame base attribute/ops */ 1226 dwarf_attr(sp_die, DW_AT_frame_base, &fb_attr); 1227 ret = dwarf_getlocation_addr(&fb_attr, pf->addr, &pf->fb_ops, &nops, 1); 1228 if (ret <= 0 || nops == 0) { 1229 pf->fb_ops = NULL; 1230 #if _ELFUTILS_PREREQ(0, 142) 1231 } else if (nops == 1 && pf->fb_ops[0].atom == DW_OP_call_frame_cfa && 1232 pf->cfi != NULL) { 1233 Dwarf_Frame *frame; 1234 if (dwarf_cfi_addrframe(pf->cfi, pf->addr, &frame) != 0 || 1235 dwarf_frame_cfa(frame, &pf->fb_ops, &nops) != 0) { 1236 pr_warning("Failed to get call frame on 0x%jx\n", 1237 (uintmax_t)pf->addr); 1238 return -ENOENT; 1239 } 1240 #endif 1241 } 1242 1243 /* Call finder's callback handler */ 1244 ret = pf->callback(sp_die, pf); 1245 1246 /* *pf->fb_ops will be cached in libdw. Don't free it. */ 1247 pf->fb_ops = NULL; 1248 1249 return ret; 1250 } 1251 1252 static int probe_point_line_walker(const char *fname, int lineno, 1253 Dwarf_Addr addr, void *data) 1254 { 1255 struct probe_finder *pf = data; 1256 int ret; 1257 1258 if (lineno != pf->lno || strtailcmp(fname, pf->fname) != 0) 1259 return 0; 1260 1261 pf->addr = addr; 1262 ret = call_probe_finder(NULL, pf); 1263 1264 /* Continue if no error, because the line will be in inline function */ 1265 return ret < 0 ? ret : 0; 1266 } 1267 1268 /* Find probe point from its line number */ 1269 static int find_probe_point_by_line(struct probe_finder *pf) 1270 { 1271 return die_walk_lines(&pf->cu_die, probe_point_line_walker, pf); 1272 } 1273 1274 /* Find lines which match lazy pattern */ 1275 static int find_lazy_match_lines(struct list_head *head, 1276 const char *fname, const char *pat) 1277 { 1278 FILE *fp; 1279 char *line = NULL; 1280 size_t line_len; 1281 ssize_t len; 1282 int count = 0, linenum = 1; 1283 1284 fp = fopen(fname, "r"); 1285 if (!fp) { 1286 pr_warning("Failed to open %s: %s\n", fname, strerror(errno)); 1287 return -errno; 1288 } 1289 1290 while ((len = getline(&line, &line_len, fp)) > 0) { 1291 1292 if (line[len - 1] == '\n') 1293 line[len - 1] = '\0'; 1294 1295 if (strlazymatch(line, pat)) { 1296 line_list__add_line(head, linenum); 1297 count++; 1298 } 1299 linenum++; 1300 } 1301 1302 if (ferror(fp)) 1303 count = -errno; 1304 free(line); 1305 fclose(fp); 1306 1307 if (count == 0) 1308 pr_debug("No matched lines found in %s.\n", fname); 1309 return count; 1310 } 1311 1312 static int probe_point_lazy_walker(const char *fname, int lineno, 1313 Dwarf_Addr addr, void *data) 1314 { 1315 struct probe_finder *pf = data; 1316 int ret; 1317 1318 if (!line_list__has_line(&pf->lcache, lineno) || 1319 strtailcmp(fname, pf->fname) != 0) 1320 return 0; 1321 1322 pr_debug("Probe line found: line:%d addr:0x%llx\n", 1323 lineno, (unsigned long long)addr); 1324 pf->addr = addr; 1325 ret = call_probe_finder(NULL, pf); 1326 1327 /* 1328 * Continue if no error, because the lazy pattern will match 1329 * to other lines 1330 */ 1331 return ret < 0 ? ret : 0; 1332 } 1333 1334 /* Find probe points from lazy pattern */ 1335 static int find_probe_point_lazy(Dwarf_Die *sp_die, struct probe_finder *pf) 1336 { 1337 int ret = 0; 1338 1339 if (list_empty(&pf->lcache)) { 1340 /* Matching lazy line pattern */ 1341 ret = find_lazy_match_lines(&pf->lcache, pf->fname, 1342 pf->pev->point.lazy_line); 1343 if (ret <= 0) 1344 return ret; 1345 } 1346 1347 return die_walk_lines(sp_die, probe_point_lazy_walker, pf); 1348 } 1349 1350 /* Callback parameter with return value */ 1351 struct dwarf_callback_param { 1352 void *data; 1353 int retval; 1354 }; 1355 1356 static int probe_point_inline_cb(Dwarf_Die *in_die, void *data) 1357 { 1358 struct dwarf_callback_param *param = data; 1359 struct probe_finder *pf = param->data; 1360 struct perf_probe_point *pp = &pf->pev->point; 1361 Dwarf_Addr addr; 1362 1363 if (pp->lazy_line) 1364 param->retval = find_probe_point_lazy(in_die, pf); 1365 else { 1366 /* Get probe address */ 1367 if (dwarf_entrypc(in_die, &addr) != 0) { 1368 pr_warning("Failed to get entry address of %s.\n", 1369 dwarf_diename(in_die)); 1370 param->retval = -ENOENT; 1371 return DWARF_CB_ABORT; 1372 } 1373 pf->addr = addr; 1374 pf->addr += pp->offset; 1375 pr_debug("found inline addr: 0x%jx\n", 1376 (uintmax_t)pf->addr); 1377 1378 param->retval = call_probe_finder(in_die, pf); 1379 if (param->retval < 0) 1380 return DWARF_CB_ABORT; 1381 } 1382 1383 return DWARF_CB_OK; 1384 } 1385 1386 /* Search function from function name */ 1387 static int probe_point_search_cb(Dwarf_Die *sp_die, void *data) 1388 { 1389 struct dwarf_callback_param *param = data; 1390 struct probe_finder *pf = param->data; 1391 struct perf_probe_point *pp = &pf->pev->point; 1392 1393 /* Check tag and diename */ 1394 if (dwarf_tag(sp_die) != DW_TAG_subprogram || 1395 !die_compare_name(sp_die, pp->function)) 1396 return DWARF_CB_OK; 1397 1398 pf->fname = dwarf_decl_file(sp_die); 1399 if (pp->line) { /* Function relative line */ 1400 dwarf_decl_line(sp_die, &pf->lno); 1401 pf->lno += pp->line; 1402 param->retval = find_probe_point_by_line(pf); 1403 } else if (!dwarf_func_inline(sp_die)) { 1404 /* Real function */ 1405 if (pp->lazy_line) 1406 param->retval = find_probe_point_lazy(sp_die, pf); 1407 else { 1408 if (dwarf_entrypc(sp_die, &pf->addr) != 0) { 1409 pr_warning("Failed to get entry address of " 1410 "%s.\n", dwarf_diename(sp_die)); 1411 param->retval = -ENOENT; 1412 return DWARF_CB_ABORT; 1413 } 1414 pf->addr += pp->offset; 1415 /* TODO: Check the address in this function */ 1416 param->retval = call_probe_finder(sp_die, pf); 1417 } 1418 } else { 1419 struct dwarf_callback_param _param = {.data = (void *)pf, 1420 .retval = 0}; 1421 /* Inlined function: search instances */ 1422 dwarf_func_inline_instances(sp_die, probe_point_inline_cb, 1423 &_param); 1424 param->retval = _param.retval; 1425 } 1426 1427 return DWARF_CB_ABORT; /* Exit; no same symbol in this CU. */ 1428 } 1429 1430 static int find_probe_point_by_func(struct probe_finder *pf) 1431 { 1432 struct dwarf_callback_param _param = {.data = (void *)pf, 1433 .retval = 0}; 1434 dwarf_getfuncs(&pf->cu_die, probe_point_search_cb, &_param, 0); 1435 return _param.retval; 1436 } 1437 1438 /* Find probe points from debuginfo */ 1439 static int find_probes(int fd, struct probe_finder *pf) 1440 { 1441 struct perf_probe_point *pp = &pf->pev->point; 1442 Dwarf_Off off, noff; 1443 size_t cuhl; 1444 Dwarf_Die *diep; 1445 Dwarf *dbg = NULL; 1446 Dwfl *dwfl; 1447 Dwarf_Addr bias; /* Currently ignored */ 1448 int ret = 0; 1449 1450 dbg = dwfl_init_offline_dwarf(fd, &dwfl, &bias); 1451 if (!dbg) { 1452 pr_warning("No debug information found in the vmlinux - " 1453 "please rebuild with CONFIG_DEBUG_INFO=y.\n"); 1454 return -EBADF; 1455 } 1456 1457 #if _ELFUTILS_PREREQ(0, 142) 1458 /* Get the call frame information from this dwarf */ 1459 pf->cfi = dwarf_getcfi(dbg); 1460 #endif 1461 1462 off = 0; 1463 line_list__init(&pf->lcache); 1464 /* Loop on CUs (Compilation Unit) */ 1465 while (!dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL)) { 1466 /* Get the DIE(Debugging Information Entry) of this CU */ 1467 diep = dwarf_offdie(dbg, off + cuhl, &pf->cu_die); 1468 if (!diep) 1469 continue; 1470 1471 /* Check if target file is included. */ 1472 if (pp->file) 1473 pf->fname = cu_find_realpath(&pf->cu_die, pp->file); 1474 else 1475 pf->fname = NULL; 1476 1477 if (!pp->file || pf->fname) { 1478 if (pp->function) 1479 ret = find_probe_point_by_func(pf); 1480 else if (pp->lazy_line) 1481 ret = find_probe_point_lazy(NULL, pf); 1482 else { 1483 pf->lno = pp->line; 1484 ret = find_probe_point_by_line(pf); 1485 } 1486 if (ret < 0) 1487 break; 1488 } 1489 off = noff; 1490 } 1491 line_list__free(&pf->lcache); 1492 if (dwfl) 1493 dwfl_end(dwfl); 1494 1495 return ret; 1496 } 1497 1498 /* Add a found probe point into trace event list */ 1499 static int add_probe_trace_event(Dwarf_Die *sp_die, struct probe_finder *pf) 1500 { 1501 struct trace_event_finder *tf = 1502 container_of(pf, struct trace_event_finder, pf); 1503 struct probe_trace_event *tev; 1504 int ret, i; 1505 1506 /* Check number of tevs */ 1507 if (tf->ntevs == tf->max_tevs) { 1508 pr_warning("Too many( > %d) probe point found.\n", 1509 tf->max_tevs); 1510 return -ERANGE; 1511 } 1512 tev = &tf->tevs[tf->ntevs++]; 1513 1514 ret = convert_to_trace_point(sp_die, pf->addr, pf->pev->point.retprobe, 1515 &tev->point); 1516 if (ret < 0) 1517 return ret; 1518 1519 pr_debug("Probe point found: %s+%lu\n", tev->point.symbol, 1520 tev->point.offset); 1521 1522 /* Find each argument */ 1523 tev->nargs = pf->pev->nargs; 1524 tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs); 1525 if (tev->args == NULL) 1526 return -ENOMEM; 1527 for (i = 0; i < pf->pev->nargs; i++) { 1528 pf->pvar = &pf->pev->args[i]; 1529 pf->tvar = &tev->args[i]; 1530 ret = find_variable(sp_die, pf); 1531 if (ret != 0) 1532 return ret; 1533 } 1534 1535 return 0; 1536 } 1537 1538 /* Find probe_trace_events specified by perf_probe_event from debuginfo */ 1539 int find_probe_trace_events(int fd, struct perf_probe_event *pev, 1540 struct probe_trace_event **tevs, int max_tevs) 1541 { 1542 struct trace_event_finder tf = { 1543 .pf = {.pev = pev, .callback = add_probe_trace_event}, 1544 .max_tevs = max_tevs}; 1545 int ret; 1546 1547 /* Allocate result tevs array */ 1548 *tevs = zalloc(sizeof(struct probe_trace_event) * max_tevs); 1549 if (*tevs == NULL) 1550 return -ENOMEM; 1551 1552 tf.tevs = *tevs; 1553 tf.ntevs = 0; 1554 1555 ret = find_probes(fd, &tf.pf); 1556 if (ret < 0) { 1557 free(*tevs); 1558 *tevs = NULL; 1559 return ret; 1560 } 1561 1562 return (ret < 0) ? ret : tf.ntevs; 1563 } 1564 1565 #define MAX_VAR_LEN 64 1566 1567 /* Collect available variables in this scope */ 1568 static int collect_variables_cb(Dwarf_Die *die_mem, void *data) 1569 { 1570 struct available_var_finder *af = data; 1571 struct variable_list *vl; 1572 char buf[MAX_VAR_LEN]; 1573 int tag, ret; 1574 1575 vl = &af->vls[af->nvls - 1]; 1576 1577 tag = dwarf_tag(die_mem); 1578 if (tag == DW_TAG_formal_parameter || 1579 tag == DW_TAG_variable) { 1580 ret = convert_variable_location(die_mem, af->pf.addr, 1581 af->pf.fb_ops, NULL); 1582 if (ret == 0) { 1583 ret = die_get_varname(die_mem, buf, MAX_VAR_LEN); 1584 pr_debug2("Add new var: %s\n", buf); 1585 if (ret > 0) 1586 strlist__add(vl->vars, buf); 1587 } 1588 } 1589 1590 if (af->child && dwarf_haspc(die_mem, af->pf.addr)) 1591 return DIE_FIND_CB_CONTINUE; 1592 else 1593 return DIE_FIND_CB_SIBLING; 1594 } 1595 1596 /* Add a found vars into available variables list */ 1597 static int add_available_vars(Dwarf_Die *sp_die, struct probe_finder *pf) 1598 { 1599 struct available_var_finder *af = 1600 container_of(pf, struct available_var_finder, pf); 1601 struct variable_list *vl; 1602 Dwarf_Die die_mem, *scopes = NULL; 1603 int ret, nscopes; 1604 1605 /* Check number of tevs */ 1606 if (af->nvls == af->max_vls) { 1607 pr_warning("Too many( > %d) probe point found.\n", af->max_vls); 1608 return -ERANGE; 1609 } 1610 vl = &af->vls[af->nvls++]; 1611 1612 ret = convert_to_trace_point(sp_die, pf->addr, pf->pev->point.retprobe, 1613 &vl->point); 1614 if (ret < 0) 1615 return ret; 1616 1617 pr_debug("Probe point found: %s+%lu\n", vl->point.symbol, 1618 vl->point.offset); 1619 1620 /* Find local variables */ 1621 vl->vars = strlist__new(true, NULL); 1622 if (vl->vars == NULL) 1623 return -ENOMEM; 1624 af->child = true; 1625 die_find_child(sp_die, collect_variables_cb, (void *)af, &die_mem); 1626 1627 /* Find external variables */ 1628 if (!af->externs) 1629 goto out; 1630 /* Don't need to search child DIE for externs. */ 1631 af->child = false; 1632 nscopes = dwarf_getscopes_die(sp_die, &scopes); 1633 while (nscopes-- > 1) 1634 die_find_child(&scopes[nscopes], collect_variables_cb, 1635 (void *)af, &die_mem); 1636 if (scopes) 1637 free(scopes); 1638 1639 out: 1640 if (strlist__empty(vl->vars)) { 1641 strlist__delete(vl->vars); 1642 vl->vars = NULL; 1643 } 1644 1645 return ret; 1646 } 1647 1648 /* Find available variables at given probe point */ 1649 int find_available_vars_at(int fd, struct perf_probe_event *pev, 1650 struct variable_list **vls, int max_vls, 1651 bool externs) 1652 { 1653 struct available_var_finder af = { 1654 .pf = {.pev = pev, .callback = add_available_vars}, 1655 .max_vls = max_vls, .externs = externs}; 1656 int ret; 1657 1658 /* Allocate result vls array */ 1659 *vls = zalloc(sizeof(struct variable_list) * max_vls); 1660 if (*vls == NULL) 1661 return -ENOMEM; 1662 1663 af.vls = *vls; 1664 af.nvls = 0; 1665 1666 ret = find_probes(fd, &af.pf); 1667 if (ret < 0) { 1668 /* Free vlist for error */ 1669 while (af.nvls--) { 1670 if (af.vls[af.nvls].point.symbol) 1671 free(af.vls[af.nvls].point.symbol); 1672 if (af.vls[af.nvls].vars) 1673 strlist__delete(af.vls[af.nvls].vars); 1674 } 1675 free(af.vls); 1676 *vls = NULL; 1677 return ret; 1678 } 1679 1680 return (ret < 0) ? ret : af.nvls; 1681 } 1682 1683 /* Reverse search */ 1684 int find_perf_probe_point(unsigned long addr, struct perf_probe_point *ppt) 1685 { 1686 Dwarf_Die cudie, spdie, indie; 1687 Dwarf *dbg = NULL; 1688 Dwfl *dwfl = NULL; 1689 Dwarf_Line *line; 1690 Dwarf_Addr laddr, eaddr, bias = 0; 1691 const char *tmp; 1692 int lineno, ret = 0; 1693 bool found = false; 1694 1695 /* Open the live linux kernel */ 1696 dbg = dwfl_init_live_kernel_dwarf(addr, &dwfl, &bias); 1697 if (!dbg) { 1698 pr_warning("No debug information found in the vmlinux - " 1699 "please rebuild with CONFIG_DEBUG_INFO=y.\n"); 1700 ret = -EINVAL; 1701 goto end; 1702 } 1703 1704 /* Adjust address with bias */ 1705 addr += bias; 1706 /* Find cu die */ 1707 if (!dwarf_addrdie(dbg, (Dwarf_Addr)addr - bias, &cudie)) { 1708 pr_warning("Failed to find debug information for address %lx\n", 1709 addr); 1710 ret = -EINVAL; 1711 goto end; 1712 } 1713 1714 /* Find a corresponding line */ 1715 line = dwarf_getsrc_die(&cudie, (Dwarf_Addr)addr); 1716 if (line) { 1717 if (dwarf_lineaddr(line, &laddr) == 0 && 1718 (Dwarf_Addr)addr == laddr && 1719 dwarf_lineno(line, &lineno) == 0) { 1720 tmp = dwarf_linesrc(line, NULL, NULL); 1721 if (tmp) { 1722 ppt->line = lineno; 1723 ppt->file = strdup(tmp); 1724 if (ppt->file == NULL) { 1725 ret = -ENOMEM; 1726 goto end; 1727 } 1728 found = true; 1729 } 1730 } 1731 } 1732 1733 /* Find a corresponding function */ 1734 if (die_find_real_subprogram(&cudie, (Dwarf_Addr)addr, &spdie)) { 1735 tmp = dwarf_diename(&spdie); 1736 if (!tmp || dwarf_entrypc(&spdie, &eaddr) != 0) 1737 goto end; 1738 1739 if (ppt->line) { 1740 if (die_find_inlinefunc(&spdie, (Dwarf_Addr)addr, 1741 &indie)) { 1742 /* addr in an inline function */ 1743 tmp = dwarf_diename(&indie); 1744 if (!tmp) 1745 goto end; 1746 ret = dwarf_decl_line(&indie, &lineno); 1747 } else { 1748 if (eaddr == addr) { /* Function entry */ 1749 lineno = ppt->line; 1750 ret = 0; 1751 } else 1752 ret = dwarf_decl_line(&spdie, &lineno); 1753 } 1754 if (ret == 0) { 1755 /* Make a relative line number */ 1756 ppt->line -= lineno; 1757 goto found; 1758 } 1759 } 1760 /* We don't have a line number, let's use offset */ 1761 ppt->offset = addr - (unsigned long)eaddr; 1762 found: 1763 ppt->function = strdup(tmp); 1764 if (ppt->function == NULL) { 1765 ret = -ENOMEM; 1766 goto end; 1767 } 1768 found = true; 1769 } 1770 1771 end: 1772 if (dwfl) 1773 dwfl_end(dwfl); 1774 if (ret >= 0) 1775 ret = found ? 1 : 0; 1776 return ret; 1777 } 1778 1779 /* Add a line and store the src path */ 1780 static int line_range_add_line(const char *src, unsigned int lineno, 1781 struct line_range *lr) 1782 { 1783 /* Copy source path */ 1784 if (!lr->path) { 1785 lr->path = strdup(src); 1786 if (lr->path == NULL) 1787 return -ENOMEM; 1788 } 1789 return line_list__add_line(&lr->line_list, lineno); 1790 } 1791 1792 static int line_range_walk_cb(const char *fname, int lineno, 1793 Dwarf_Addr addr __used, 1794 void *data) 1795 { 1796 struct line_finder *lf = data; 1797 1798 if ((strtailcmp(fname, lf->fname) != 0) || 1799 (lf->lno_s > lineno || lf->lno_e < lineno)) 1800 return 0; 1801 1802 if (line_range_add_line(fname, lineno, lf->lr) < 0) 1803 return -EINVAL; 1804 1805 return 0; 1806 } 1807 1808 /* Find line range from its line number */ 1809 static int find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf) 1810 { 1811 int ret; 1812 1813 ret = die_walk_lines(sp_die ?: &lf->cu_die, line_range_walk_cb, lf); 1814 1815 /* Update status */ 1816 if (ret >= 0) 1817 if (!list_empty(&lf->lr->line_list)) 1818 ret = lf->found = 1; 1819 else 1820 ret = 0; /* Lines are not found */ 1821 else { 1822 free(lf->lr->path); 1823 lf->lr->path = NULL; 1824 } 1825 return ret; 1826 } 1827 1828 static int line_range_inline_cb(Dwarf_Die *in_die, void *data) 1829 { 1830 struct dwarf_callback_param *param = data; 1831 1832 param->retval = find_line_range_by_line(in_die, param->data); 1833 return DWARF_CB_ABORT; /* No need to find other instances */ 1834 } 1835 1836 /* Search function from function name */ 1837 static int line_range_search_cb(Dwarf_Die *sp_die, void *data) 1838 { 1839 struct dwarf_callback_param *param = data; 1840 struct line_finder *lf = param->data; 1841 struct line_range *lr = lf->lr; 1842 1843 if (dwarf_tag(sp_die) == DW_TAG_subprogram && 1844 die_compare_name(sp_die, lr->function)) { 1845 lf->fname = dwarf_decl_file(sp_die); 1846 dwarf_decl_line(sp_die, &lr->offset); 1847 pr_debug("fname: %s, lineno:%d\n", lf->fname, lr->offset); 1848 lf->lno_s = lr->offset + lr->start; 1849 if (lf->lno_s < 0) /* Overflow */ 1850 lf->lno_s = INT_MAX; 1851 lf->lno_e = lr->offset + lr->end; 1852 if (lf->lno_e < 0) /* Overflow */ 1853 lf->lno_e = INT_MAX; 1854 pr_debug("New line range: %d to %d\n", lf->lno_s, lf->lno_e); 1855 lr->start = lf->lno_s; 1856 lr->end = lf->lno_e; 1857 if (dwarf_func_inline(sp_die)) { 1858 struct dwarf_callback_param _param; 1859 _param.data = (void *)lf; 1860 _param.retval = 0; 1861 dwarf_func_inline_instances(sp_die, 1862 line_range_inline_cb, 1863 &_param); 1864 param->retval = _param.retval; 1865 } else 1866 param->retval = find_line_range_by_line(sp_die, lf); 1867 return DWARF_CB_ABORT; 1868 } 1869 return DWARF_CB_OK; 1870 } 1871 1872 static int find_line_range_by_func(struct line_finder *lf) 1873 { 1874 struct dwarf_callback_param param = {.data = (void *)lf, .retval = 0}; 1875 dwarf_getfuncs(&lf->cu_die, line_range_search_cb, ¶m, 0); 1876 return param.retval; 1877 } 1878 1879 int find_line_range(int fd, struct line_range *lr) 1880 { 1881 struct line_finder lf = {.lr = lr, .found = 0}; 1882 int ret = 0; 1883 Dwarf_Off off = 0, noff; 1884 size_t cuhl; 1885 Dwarf_Die *diep; 1886 Dwarf *dbg = NULL; 1887 Dwfl *dwfl; 1888 Dwarf_Addr bias; /* Currently ignored */ 1889 const char *comp_dir; 1890 1891 dbg = dwfl_init_offline_dwarf(fd, &dwfl, &bias); 1892 if (!dbg) { 1893 pr_warning("No debug information found in the vmlinux - " 1894 "please rebuild with CONFIG_DEBUG_INFO=y.\n"); 1895 return -EBADF; 1896 } 1897 1898 /* Loop on CUs (Compilation Unit) */ 1899 while (!lf.found && ret >= 0) { 1900 if (dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL) != 0) 1901 break; 1902 1903 /* Get the DIE(Debugging Information Entry) of this CU */ 1904 diep = dwarf_offdie(dbg, off + cuhl, &lf.cu_die); 1905 if (!diep) 1906 continue; 1907 1908 /* Check if target file is included. */ 1909 if (lr->file) 1910 lf.fname = cu_find_realpath(&lf.cu_die, lr->file); 1911 else 1912 lf.fname = 0; 1913 1914 if (!lr->file || lf.fname) { 1915 if (lr->function) 1916 ret = find_line_range_by_func(&lf); 1917 else { 1918 lf.lno_s = lr->start; 1919 lf.lno_e = lr->end; 1920 ret = find_line_range_by_line(NULL, &lf); 1921 } 1922 } 1923 off = noff; 1924 } 1925 1926 /* Store comp_dir */ 1927 if (lf.found) { 1928 comp_dir = cu_get_comp_dir(&lf.cu_die); 1929 if (comp_dir) { 1930 lr->comp_dir = strdup(comp_dir); 1931 if (!lr->comp_dir) 1932 ret = -ENOMEM; 1933 } 1934 } 1935 1936 pr_debug("path: %s\n", lr->path); 1937 dwfl_end(dwfl); 1938 return (ret < 0) ? ret : lf.found; 1939 } 1940 1941