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