1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * probe-finder.c : C expression to kprobe event converter 4 * 5 * Written by Masami Hiramatsu <mhiramat@redhat.com> 6 */ 7 8 #include <inttypes.h> 9 #include <sys/utsname.h> 10 #include <sys/types.h> 11 #include <sys/stat.h> 12 #include <fcntl.h> 13 #include <errno.h> 14 #include <stdio.h> 15 #include <unistd.h> 16 #include <stdlib.h> 17 #include <string.h> 18 #include <stdarg.h> 19 #include <dwarf-regs.h> 20 21 #include <linux/bitops.h> 22 #include <linux/zalloc.h> 23 #include "event.h" 24 #include "dso.h" 25 #include "debug.h" 26 #include "debuginfo.h" 27 #include "intlist.h" 28 #include "strbuf.h" 29 #include "strlist.h" 30 #include "symbol.h" 31 #include "probe-finder.h" 32 #include "probe-file.h" 33 #include "string2.h" 34 35 /* Kprobe tracer basic type is up to u64 */ 36 #define MAX_BASIC_TYPE_BITS 64 37 38 /* 39 * Probe finder related functions 40 */ 41 42 static struct probe_trace_arg_ref *alloc_trace_arg_ref(long offs) 43 { 44 struct probe_trace_arg_ref *ref; 45 ref = zalloc(sizeof(struct probe_trace_arg_ref)); 46 if (ref != NULL) 47 ref->offset = offs; 48 return ref; 49 } 50 51 /* 52 * Convert a location into trace_arg. 53 * If tvar == NULL, this just checks variable can be converted. 54 * If fentry == true and vr_die is a parameter, do heuristic search 55 * for the location fuzzed by function entry mcount. 56 */ 57 static int convert_variable_location(Dwarf_Die *vr_die, Dwarf_Addr addr, 58 Dwarf_Op *fb_ops, Dwarf_Die *sp_die, 59 unsigned int machine, 60 struct probe_trace_arg *tvar) 61 { 62 Dwarf_Attribute attr; 63 Dwarf_Addr tmp = 0; 64 Dwarf_Op *op; 65 size_t nops; 66 unsigned int regn; 67 Dwarf_Word offs = 0; 68 bool ref = false; 69 const char *regs; 70 int ret, ret2 = 0; 71 72 if (dwarf_attr(vr_die, DW_AT_external, &attr) != NULL) 73 goto static_var; 74 75 /* Constant value */ 76 if (dwarf_attr(vr_die, DW_AT_const_value, &attr) && 77 immediate_value_is_supported()) { 78 Dwarf_Sword snum; 79 80 if (!tvar) 81 return 0; 82 83 dwarf_formsdata(&attr, &snum); 84 ret = asprintf(&tvar->value, "\\%ld", (long)snum); 85 86 return ret < 0 ? -ENOMEM : 0; 87 } 88 89 /* TODO: handle more than 1 exprs */ 90 if (dwarf_attr(vr_die, DW_AT_location, &attr) == NULL) 91 return -EINVAL; /* Broken DIE ? */ 92 if (dwarf_getlocation_addr(&attr, addr, &op, &nops, 1) <= 0) { 93 ret = dwarf_entrypc(sp_die, &tmp); 94 if (ret) 95 return -ENOENT; 96 97 if (probe_conf.show_location_range && 98 (dwarf_tag(vr_die) == DW_TAG_variable)) { 99 ret2 = -ERANGE; 100 } else if (addr != tmp || 101 dwarf_tag(vr_die) != DW_TAG_formal_parameter) { 102 return -ENOENT; 103 } 104 105 ret = dwarf_highpc(sp_die, &tmp); 106 if (ret) 107 return -ENOENT; 108 /* 109 * This is fuzzed by fentry mcount. We try to find the 110 * parameter location at the earliest address. 111 */ 112 for (addr += 1; addr <= tmp; addr++) { 113 if (dwarf_getlocation_addr(&attr, addr, &op, 114 &nops, 1) > 0) 115 goto found; 116 } 117 return -ENOENT; 118 } 119 found: 120 if (nops == 0) 121 /* TODO: Support const_value */ 122 return -ENOENT; 123 124 if (op->atom == DW_OP_addr) { 125 static_var: 126 if (!tvar) 127 return ret2; 128 /* Static variables on memory (not stack), make @varname */ 129 ret = strlen(dwarf_diename(vr_die)); 130 tvar->value = zalloc(ret + 2); 131 if (tvar->value == NULL) 132 return -ENOMEM; 133 snprintf(tvar->value, ret + 2, "@%s", dwarf_diename(vr_die)); 134 tvar->ref = alloc_trace_arg_ref((long)offs); 135 if (tvar->ref == NULL) 136 return -ENOMEM; 137 return ret2; 138 } 139 140 /* If this is based on frame buffer, set the offset */ 141 if (op->atom == DW_OP_fbreg) { 142 if (fb_ops == NULL) 143 return -ENOTSUP; 144 ref = true; 145 offs = op->number; 146 op = &fb_ops[0]; 147 } 148 149 if (op->atom >= DW_OP_breg0 && op->atom <= DW_OP_breg31) { 150 regn = op->atom - DW_OP_breg0; 151 offs += op->number; 152 ref = true; 153 } else if (op->atom >= DW_OP_reg0 && op->atom <= DW_OP_reg31) { 154 regn = op->atom - DW_OP_reg0; 155 } else if (op->atom == DW_OP_bregx) { 156 regn = op->number; 157 offs += op->number2; 158 ref = true; 159 } else if (op->atom == DW_OP_regx) { 160 regn = op->number; 161 } else { 162 pr_debug("DW_OP %x is not supported.\n", op->atom); 163 return -ENOTSUP; 164 } 165 166 if (!tvar) 167 return ret2; 168 169 regs = get_dwarf_regstr(regn, machine); 170 if (!regs) { 171 /* This should be a bug in DWARF or this tool */ 172 pr_warning("Mapping for the register number %u " 173 "missing on this architecture.\n", regn); 174 return -ENOTSUP; 175 } 176 177 tvar->value = strdup(regs); 178 if (tvar->value == NULL) 179 return -ENOMEM; 180 181 if (ref) { 182 tvar->ref = alloc_trace_arg_ref((long)offs); 183 if (tvar->ref == NULL) 184 return -ENOMEM; 185 } 186 return ret2; 187 } 188 189 #define BYTES_TO_BITS(nb) ((nb) * BITS_PER_LONG / sizeof(long)) 190 191 static int convert_variable_type(Dwarf_Die *vr_die, 192 struct probe_trace_arg *tvar, 193 const char *cast, bool user_access) 194 { 195 struct probe_trace_arg_ref **ref_ptr = &tvar->ref; 196 Dwarf_Die type; 197 char buf[16]; 198 char sbuf[STRERR_BUFSIZE]; 199 int bsize, boffs, total; 200 int ret; 201 char prefix; 202 203 /* TODO: check all types */ 204 if (cast && strcmp(cast, "string") != 0 && strcmp(cast, "ustring") && 205 strcmp(cast, "x") != 0 && 206 strcmp(cast, "s") != 0 && strcmp(cast, "u") != 0) { 207 /* Non string type is OK */ 208 /* and respect signedness/hexadecimal cast */ 209 tvar->type = strdup(cast); 210 return (tvar->type == NULL) ? -ENOMEM : 0; 211 } 212 213 bsize = dwarf_bitsize(vr_die); 214 if (bsize > 0) { 215 /* This is a bitfield */ 216 boffs = dwarf_bitoffset(vr_die); 217 total = dwarf_bytesize(vr_die); 218 if (boffs < 0 || total < 0) 219 return -ENOENT; 220 ret = snprintf(buf, 16, "b%d@%d/%zd", bsize, boffs, 221 BYTES_TO_BITS(total)); 222 goto formatted; 223 } 224 225 if (die_get_real_type(vr_die, &type) == NULL) { 226 pr_warning("Failed to get a type information of %s.\n", 227 dwarf_diename(vr_die)); 228 return -ENOENT; 229 } 230 231 pr_debug("%s type is %s.\n", 232 dwarf_diename(vr_die), dwarf_diename(&type)); 233 234 if (cast && (!strcmp(cast, "string") || !strcmp(cast, "ustring"))) { 235 /* String type */ 236 ret = dwarf_tag(&type); 237 if (ret != DW_TAG_pointer_type && 238 ret != DW_TAG_array_type) { 239 pr_warning("Failed to cast into string: " 240 "%s(%s) is not a pointer nor array.\n", 241 dwarf_diename(vr_die), dwarf_diename(&type)); 242 return -EINVAL; 243 } 244 if (die_get_real_type(&type, &type) == NULL) { 245 pr_warning("Failed to get a type" 246 " information.\n"); 247 return -ENOENT; 248 } 249 if (ret == DW_TAG_pointer_type) { 250 while (*ref_ptr) 251 ref_ptr = &(*ref_ptr)->next; 252 /* Add new reference with offset +0 */ 253 *ref_ptr = zalloc(sizeof(struct probe_trace_arg_ref)); 254 if (*ref_ptr == NULL) { 255 pr_warning("Out of memory error\n"); 256 return -ENOMEM; 257 } 258 (*ref_ptr)->user_access = user_access; 259 } 260 if (!die_compare_name(&type, "char") && 261 !die_compare_name(&type, "unsigned char")) { 262 pr_warning("Failed to cast into string: " 263 "%s is not (unsigned) char *.\n", 264 dwarf_diename(vr_die)); 265 return -EINVAL; 266 } 267 tvar->type = strdup(cast); 268 return (tvar->type == NULL) ? -ENOMEM : 0; 269 } 270 271 if (cast && (strcmp(cast, "u") == 0)) 272 prefix = 'u'; 273 else if (cast && (strcmp(cast, "s") == 0)) 274 prefix = 's'; 275 else if (cast && (strcmp(cast, "x") == 0) && 276 probe_type_is_available(PROBE_TYPE_X)) 277 prefix = 'x'; 278 else 279 prefix = die_is_signed_type(&type) ? 's' : 280 probe_type_is_available(PROBE_TYPE_X) ? 'x' : 'u'; 281 282 ret = dwarf_bytesize(&type); 283 if (ret <= 0) 284 /* No size ... try to use default type */ 285 return 0; 286 ret = BYTES_TO_BITS(ret); 287 288 /* Check the bitwidth */ 289 if (ret > MAX_BASIC_TYPE_BITS) { 290 pr_info("%s exceeds max-bitwidth. Cut down to %d bits.\n", 291 dwarf_diename(&type), MAX_BASIC_TYPE_BITS); 292 ret = MAX_BASIC_TYPE_BITS; 293 } 294 ret = snprintf(buf, 16, "%c%d", prefix, ret); 295 296 formatted: 297 if (ret < 0 || ret >= 16) { 298 if (ret >= 16) 299 ret = -E2BIG; 300 pr_warning("Failed to convert variable type: %s\n", 301 str_error_r(-ret, sbuf, sizeof(sbuf))); 302 return ret; 303 } 304 tvar->type = strdup(buf); 305 if (tvar->type == NULL) 306 return -ENOMEM; 307 return 0; 308 } 309 310 static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname, 311 struct perf_probe_arg_field *field, 312 struct probe_trace_arg_ref **ref_ptr, 313 Dwarf_Die *die_mem, bool user_access) 314 { 315 struct probe_trace_arg_ref *ref = *ref_ptr; 316 Dwarf_Die type; 317 Dwarf_Word offs; 318 int ret, tag; 319 320 pr_debug("converting %s in %s\n", field->name, varname); 321 if (die_get_real_type(vr_die, &type) == NULL) { 322 pr_warning("Failed to get the type of %s.\n", varname); 323 return -ENOENT; 324 } 325 pr_debug2("Var real type: %s (%x)\n", dwarf_diename(&type), 326 (unsigned)dwarf_dieoffset(&type)); 327 tag = dwarf_tag(&type); 328 329 if (field->name[0] == '[' && 330 (tag == DW_TAG_array_type || tag == DW_TAG_pointer_type)) { 331 /* Save original type for next field or type */ 332 memcpy(die_mem, &type, sizeof(*die_mem)); 333 /* Get the type of this array */ 334 if (die_get_real_type(&type, &type) == NULL) { 335 pr_warning("Failed to get the type of %s.\n", varname); 336 return -ENOENT; 337 } 338 pr_debug2("Array real type: %s (%x)\n", dwarf_diename(&type), 339 (unsigned)dwarf_dieoffset(&type)); 340 if (tag == DW_TAG_pointer_type) { 341 ref = zalloc(sizeof(struct probe_trace_arg_ref)); 342 if (ref == NULL) 343 return -ENOMEM; 344 if (*ref_ptr) 345 (*ref_ptr)->next = ref; 346 else 347 *ref_ptr = ref; 348 } 349 ref->offset += dwarf_bytesize(&type) * field->index; 350 ref->user_access = user_access; 351 goto next; 352 } else if (tag == DW_TAG_pointer_type) { 353 /* Check the pointer and dereference */ 354 if (!field->ref) { 355 pr_err("Semantic error: %s must be referred by '->'\n", 356 field->name); 357 return -EINVAL; 358 } 359 /* Get the type pointed by this pointer */ 360 if (die_get_real_type(&type, &type) == NULL) { 361 pr_warning("Failed to get the type of %s.\n", varname); 362 return -ENOENT; 363 } 364 /* Verify it is a data structure */ 365 tag = dwarf_tag(&type); 366 if (tag != DW_TAG_structure_type && tag != DW_TAG_union_type) { 367 pr_warning("%s is not a data structure nor a union.\n", 368 varname); 369 return -EINVAL; 370 } 371 372 ref = zalloc(sizeof(struct probe_trace_arg_ref)); 373 if (ref == NULL) 374 return -ENOMEM; 375 if (*ref_ptr) 376 (*ref_ptr)->next = ref; 377 else 378 *ref_ptr = ref; 379 } else { 380 /* Verify it is a data structure */ 381 if (tag != DW_TAG_structure_type && tag != DW_TAG_union_type) { 382 pr_warning("%s is not a data structure nor a union.\n", 383 varname); 384 return -EINVAL; 385 } 386 if (field->name[0] == '[') { 387 pr_err("Semantic error: %s is not a pointer" 388 " nor array.\n", varname); 389 return -EINVAL; 390 } 391 /* While processing unnamed field, we don't care about this */ 392 if (field->ref && dwarf_diename(vr_die)) { 393 pr_err("Semantic error: %s must be referred by '.'\n", 394 field->name); 395 return -EINVAL; 396 } 397 if (!ref) { 398 pr_warning("Structure on a register is not " 399 "supported yet.\n"); 400 return -ENOTSUP; 401 } 402 } 403 404 if (die_find_member(&type, field->name, die_mem) == NULL) { 405 pr_warning("%s(type:%s) has no member %s.\n", varname, 406 dwarf_diename(&type), field->name); 407 return -EINVAL; 408 } 409 410 /* Get the offset of the field */ 411 if (tag == DW_TAG_union_type) { 412 offs = 0; 413 } else { 414 ret = die_get_data_member_location(die_mem, &offs); 415 if (ret < 0) { 416 pr_warning("Failed to get the offset of %s.\n", 417 field->name); 418 return ret; 419 } 420 } 421 ref->offset += (long)offs; 422 ref->user_access = user_access; 423 424 /* If this member is unnamed, we need to reuse this field */ 425 if (!dwarf_diename(die_mem)) 426 return convert_variable_fields(die_mem, varname, field, 427 &ref, die_mem, user_access); 428 429 next: 430 /* Converting next field */ 431 if (field->next) 432 return convert_variable_fields(die_mem, field->name, 433 field->next, &ref, die_mem, user_access); 434 else 435 return 0; 436 } 437 438 static void print_var_not_found(const char *varname) 439 { 440 pr_err("Failed to find the location of the '%s' variable at this address.\n" 441 " Perhaps it has been optimized out.\n" 442 " Use -V with the --range option to show '%s' location range.\n", 443 varname, varname); 444 } 445 446 /* Show a variables in kprobe event format */ 447 static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf) 448 { 449 Dwarf_Die die_mem; 450 int ret; 451 452 pr_debug("Converting variable %s into trace event.\n", 453 dwarf_diename(vr_die)); 454 455 ret = convert_variable_location(vr_die, pf->addr, pf->fb_ops, 456 &pf->sp_die, pf->machine, pf->tvar); 457 if (ret == -ENOENT && pf->skip_empty_arg) 458 /* This can be found in other place. skip it */ 459 return 0; 460 if (ret == -ENOENT || ret == -EINVAL) { 461 print_var_not_found(pf->pvar->var); 462 } else if (ret == -ENOTSUP) 463 pr_err("Sorry, we don't support this variable location yet.\n"); 464 else if (ret == 0 && pf->pvar->field) { 465 ret = convert_variable_fields(vr_die, pf->pvar->var, 466 pf->pvar->field, &pf->tvar->ref, 467 &die_mem, pf->pvar->user_access); 468 vr_die = &die_mem; 469 } 470 if (ret == 0) 471 ret = convert_variable_type(vr_die, pf->tvar, pf->pvar->type, 472 pf->pvar->user_access); 473 /* *expr will be cached in libdw. Don't free it. */ 474 return ret; 475 } 476 477 /* Find a variable in a scope DIE */ 478 static int find_variable(Dwarf_Die *sc_die, struct probe_finder *pf) 479 { 480 Dwarf_Die vr_die; 481 char *buf, *ptr; 482 int ret = 0; 483 484 /* Copy raw parameters */ 485 if (!is_c_varname(pf->pvar->var)) 486 return copy_to_probe_trace_arg(pf->tvar, pf->pvar); 487 488 if (pf->pvar->name) 489 pf->tvar->name = strdup(pf->pvar->name); 490 else { 491 buf = synthesize_perf_probe_arg(pf->pvar); 492 if (!buf) 493 return -ENOMEM; 494 ptr = strchr(buf, ':'); /* Change type separator to _ */ 495 if (ptr) 496 *ptr = '_'; 497 pf->tvar->name = buf; 498 } 499 if (pf->tvar->name == NULL) 500 return -ENOMEM; 501 502 pr_debug("Searching '%s' variable in context.\n", pf->pvar->var); 503 /* Search child die for local variables and parameters. */ 504 if (!die_find_variable_at(sc_die, pf->pvar->var, pf->addr, &vr_die)) { 505 /* Search again in global variables */ 506 if (!die_find_variable_at(&pf->cu_die, pf->pvar->var, 507 0, &vr_die)) { 508 if (pf->skip_empty_arg) 509 return 0; 510 pr_warning("Failed to find '%s' in this function.\n", 511 pf->pvar->var); 512 ret = -ENOENT; 513 } 514 } 515 if (ret >= 0) 516 ret = convert_variable(&vr_die, pf); 517 518 return ret; 519 } 520 521 /* Convert subprogram DIE to trace point */ 522 static int convert_to_trace_point(Dwarf_Die *sp_die, Dwfl_Module *mod, 523 Dwarf_Addr paddr, bool retprobe, 524 const char *function, 525 struct probe_trace_point *tp) 526 { 527 Dwarf_Addr eaddr; 528 GElf_Sym sym; 529 const char *symbol; 530 531 /* Verify the address is correct */ 532 if (!dwarf_haspc(sp_die, paddr)) { 533 pr_warning("Specified offset is out of %s\n", 534 dwarf_diename(sp_die)); 535 return -EINVAL; 536 } 537 538 if (dwarf_entrypc(sp_die, &eaddr) == 0) { 539 /* If the DIE has entrypc, use it. */ 540 symbol = dwarf_diename(sp_die); 541 } else { 542 /* Try to get actual symbol name and address from symtab */ 543 symbol = dwfl_module_addrsym(mod, paddr, &sym, NULL); 544 eaddr = sym.st_value; 545 } 546 if (!symbol) { 547 pr_warning("Failed to find symbol at 0x%lx\n", 548 (unsigned long)paddr); 549 return -ENOENT; 550 } 551 552 tp->offset = (unsigned long)(paddr - eaddr); 553 tp->address = paddr; 554 tp->symbol = strdup(symbol); 555 if (!tp->symbol) 556 return -ENOMEM; 557 558 /* Return probe must be on the head of a subprogram */ 559 if (retprobe) { 560 if (eaddr != paddr) { 561 pr_warning("Failed to find \"%s%%return\",\n" 562 " because %s is an inlined function and" 563 " has no return point.\n", function, 564 function); 565 return -EINVAL; 566 } 567 tp->retprobe = true; 568 } 569 570 return 0; 571 } 572 573 /* Call probe_finder callback with scope DIE */ 574 static int call_probe_finder(Dwarf_Die *sc_die, struct probe_finder *pf) 575 { 576 Dwarf_Attribute fb_attr; 577 Dwarf_Frame *frame = NULL; 578 size_t nops; 579 int ret; 580 581 if (!sc_die) { 582 pr_err("Caller must pass a scope DIE. Program error.\n"); 583 return -EINVAL; 584 } 585 586 /* If not a real subprogram, find a real one */ 587 if (!die_is_func_def(sc_die)) { 588 if (!die_find_realfunc(&pf->cu_die, pf->addr, &pf->sp_die)) { 589 if (die_find_tailfunc(&pf->cu_die, pf->addr, &pf->sp_die)) { 590 pr_warning("Ignoring tail call from %s\n", 591 dwarf_diename(&pf->sp_die)); 592 return 0; 593 } else { 594 pr_warning("Failed to find probe point in any " 595 "functions.\n"); 596 return -ENOENT; 597 } 598 } 599 } else 600 memcpy(&pf->sp_die, sc_die, sizeof(Dwarf_Die)); 601 602 /* Get the frame base attribute/ops from subprogram */ 603 dwarf_attr(&pf->sp_die, DW_AT_frame_base, &fb_attr); 604 ret = dwarf_getlocation_addr(&fb_attr, pf->addr, &pf->fb_ops, &nops, 1); 605 if (ret <= 0 || nops == 0) { 606 pf->fb_ops = NULL; 607 #ifdef HAVE_DWARF_CFI_SUPPORT 608 } else if (nops == 1 && pf->fb_ops[0].atom == DW_OP_call_frame_cfa && 609 (pf->cfi_eh != NULL || pf->cfi_dbg != NULL)) { 610 if ((dwarf_cfi_addrframe(pf->cfi_eh, pf->addr, &frame) != 0 && 611 (dwarf_cfi_addrframe(pf->cfi_dbg, pf->addr, &frame) != 0)) || 612 dwarf_frame_cfa(frame, &pf->fb_ops, &nops) != 0) { 613 pr_warning("Failed to get call frame on 0x%jx\n", 614 (uintmax_t)pf->addr); 615 free(frame); 616 return -ENOENT; 617 } 618 #endif /* HAVE_DWARF_CFI_SUPPORT */ 619 } 620 621 /* Call finder's callback handler */ 622 ret = pf->callback(sc_die, pf); 623 624 /* Since *pf->fb_ops can be a part of frame. we should free it here. */ 625 free(frame); 626 pf->fb_ops = NULL; 627 628 return ret; 629 } 630 631 struct find_scope_param { 632 const char *function; 633 const char *file; 634 int line; 635 int diff; 636 Dwarf_Die *die_mem; 637 bool found; 638 }; 639 640 static int find_best_scope_cb(Dwarf_Die *fn_die, void *data) 641 { 642 struct find_scope_param *fsp = data; 643 const char *file; 644 int lno; 645 646 /* Skip if declared file name does not match */ 647 if (fsp->file) { 648 file = die_get_decl_file(fn_die); 649 if (!file || strcmp(fsp->file, file) != 0) 650 return 0; 651 } 652 /* If the function name is given, that's what user expects */ 653 if (fsp->function) { 654 if (die_match_name(fn_die, fsp->function)) { 655 memcpy(fsp->die_mem, fn_die, sizeof(Dwarf_Die)); 656 fsp->found = true; 657 return 1; 658 } 659 } else { 660 /* With the line number, find the nearest declared DIE */ 661 dwarf_decl_line(fn_die, &lno); 662 if (lno < fsp->line && fsp->diff > fsp->line - lno) { 663 /* Keep a candidate and continue */ 664 fsp->diff = fsp->line - lno; 665 memcpy(fsp->die_mem, fn_die, sizeof(Dwarf_Die)); 666 fsp->found = true; 667 } 668 } 669 return 0; 670 } 671 672 /* Return innermost DIE */ 673 static int find_inner_scope_cb(Dwarf_Die *fn_die, void *data) 674 { 675 struct find_scope_param *fsp = data; 676 677 memcpy(fsp->die_mem, fn_die, sizeof(Dwarf_Die)); 678 fsp->found = true; 679 return 1; 680 } 681 682 /* Find an appropriate scope fits to given conditions */ 683 static Dwarf_Die *find_best_scope(struct probe_finder *pf, Dwarf_Die *die_mem) 684 { 685 struct find_scope_param fsp = { 686 .function = pf->pev->point.function, 687 .file = pf->fname, 688 .line = pf->lno, 689 .diff = INT_MAX, 690 .die_mem = die_mem, 691 .found = false, 692 }; 693 int ret; 694 695 ret = cu_walk_functions_at(&pf->cu_die, pf->addr, find_best_scope_cb, 696 &fsp); 697 if (!ret && !fsp.found) 698 cu_walk_functions_at(&pf->cu_die, pf->addr, 699 find_inner_scope_cb, &fsp); 700 701 return fsp.found ? die_mem : NULL; 702 } 703 704 static int verify_representive_line(struct probe_finder *pf, const char *fname, 705 int lineno, Dwarf_Addr addr) 706 { 707 const char *__fname, *__func = NULL; 708 Dwarf_Die die_mem; 709 int __lineno; 710 711 /* Verify line number and address by reverse search */ 712 if (cu_find_lineinfo(&pf->cu_die, addr, &__fname, &__lineno) < 0) 713 return 0; 714 715 pr_debug2("Reversed line: %s:%d\n", __fname, __lineno); 716 if (strcmp(fname, __fname) || lineno == __lineno) 717 return 0; 718 719 pr_warning("This line is sharing the address with other lines.\n"); 720 721 if (pf->pev->point.function) { 722 /* Find best match function name and lines */ 723 pf->addr = addr; 724 if (find_best_scope(pf, &die_mem) 725 && die_match_name(&die_mem, pf->pev->point.function) 726 && dwarf_decl_line(&die_mem, &lineno) == 0) { 727 __func = dwarf_diename(&die_mem); 728 __lineno -= lineno; 729 } 730 } 731 pr_warning("Please try to probe at %s:%d instead.\n", 732 __func ? : __fname, __lineno); 733 734 return -ENOENT; 735 } 736 737 static int probe_point_line_walker(const char *fname, int lineno, 738 Dwarf_Addr addr, void *data) 739 { 740 struct probe_finder *pf = data; 741 Dwarf_Die *sc_die, die_mem; 742 int ret; 743 744 if (lineno != pf->lno || strtailcmp(fname, pf->fname) != 0) 745 return 0; 746 747 if (verify_representive_line(pf, fname, lineno, addr)) 748 return -ENOENT; 749 750 pf->addr = addr; 751 sc_die = find_best_scope(pf, &die_mem); 752 if (!sc_die) { 753 pr_warning("Failed to find scope of probe point.\n"); 754 return -ENOENT; 755 } 756 757 ret = call_probe_finder(sc_die, pf); 758 759 /* Continue if no error, because the line will be in inline function */ 760 return ret < 0 ? ret : 0; 761 } 762 763 /* Find probe point from its line number */ 764 static int find_probe_point_by_line(struct probe_finder *pf) 765 { 766 return die_walk_lines(&pf->cu_die, probe_point_line_walker, pf); 767 } 768 769 /* Find lines which match lazy pattern */ 770 static int find_lazy_match_lines(struct intlist *list, 771 const char *fname, const char *pat) 772 { 773 FILE *fp; 774 char *line = NULL; 775 size_t line_len; 776 ssize_t len; 777 int count = 0, linenum = 1; 778 char sbuf[STRERR_BUFSIZE]; 779 780 fp = fopen(fname, "r"); 781 if (!fp) { 782 pr_warning("Failed to open %s: %s\n", fname, 783 str_error_r(errno, sbuf, sizeof(sbuf))); 784 return -errno; 785 } 786 787 while ((len = getline(&line, &line_len, fp)) > 0) { 788 789 if (line[len - 1] == '\n') 790 line[len - 1] = '\0'; 791 792 if (strlazymatch(line, pat)) { 793 intlist__add(list, linenum); 794 count++; 795 } 796 linenum++; 797 } 798 799 if (ferror(fp)) 800 count = -errno; 801 free(line); 802 fclose(fp); 803 804 if (count == 0) 805 pr_debug("No matched lines found in %s.\n", fname); 806 return count; 807 } 808 809 static int probe_point_lazy_walker(const char *fname, int lineno, 810 Dwarf_Addr addr, void *data) 811 { 812 struct probe_finder *pf = data; 813 Dwarf_Die *sc_die, die_mem; 814 int ret; 815 816 if (!intlist__has_entry(pf->lcache, lineno) || 817 strtailcmp(fname, pf->fname) != 0) 818 return 0; 819 820 pr_debug("Probe line found: line:%d addr:0x%llx\n", 821 lineno, (unsigned long long)addr); 822 pf->addr = addr; 823 pf->lno = lineno; 824 sc_die = find_best_scope(pf, &die_mem); 825 if (!sc_die) { 826 pr_warning("Failed to find scope of probe point.\n"); 827 return -ENOENT; 828 } 829 830 ret = call_probe_finder(sc_die, pf); 831 832 /* 833 * Continue if no error, because the lazy pattern will match 834 * to other lines 835 */ 836 return ret < 0 ? ret : 0; 837 } 838 839 /* Find probe points from lazy pattern */ 840 static int find_probe_point_lazy(Dwarf_Die *sp_die, struct probe_finder *pf) 841 { 842 struct build_id bid; 843 char sbuild_id[SBUILD_ID_SIZE] = ""; 844 int ret = 0; 845 char *fpath; 846 847 if (intlist__empty(pf->lcache)) { 848 const char *comp_dir; 849 850 comp_dir = cu_get_comp_dir(&pf->cu_die); 851 if (pf->dbg->build_id) { 852 build_id__init(&bid, pf->dbg->build_id, BUILD_ID_SIZE); 853 build_id__sprintf(&bid, sbuild_id); 854 } 855 ret = find_source_path(pf->fname, sbuild_id, comp_dir, &fpath); 856 if (ret < 0) { 857 pr_warning("Failed to find source file path.\n"); 858 return ret; 859 } 860 861 /* Matching lazy line pattern */ 862 ret = find_lazy_match_lines(pf->lcache, fpath, 863 pf->pev->point.lazy_line); 864 free(fpath); 865 if (ret <= 0) 866 return ret; 867 } 868 869 return die_walk_lines(sp_die, probe_point_lazy_walker, pf); 870 } 871 872 static void skip_prologue(Dwarf_Die *sp_die, struct probe_finder *pf) 873 { 874 struct perf_probe_point *pp = &pf->pev->point; 875 876 /* Not uprobe? */ 877 if (!pf->pev->uprobes) 878 return; 879 880 /* Compiled with optimization? */ 881 if (die_is_optimized_target(&pf->cu_die)) 882 return; 883 884 /* Don't know entrypc? */ 885 if (!pf->addr) 886 return; 887 888 /* Only FUNC and FUNC@SRC are eligible. */ 889 if (!pp->function || pp->line || pp->retprobe || pp->lazy_line || 890 pp->offset || pp->abs_address) 891 return; 892 893 /* Not interested in func parameter? */ 894 if (!perf_probe_with_var(pf->pev)) 895 return; 896 897 pr_info("Target program is compiled without optimization. Skipping prologue.\n" 898 "Probe on address 0x%" PRIx64 " to force probing at the function entry.\n\n", 899 pf->addr); 900 901 die_skip_prologue(sp_die, &pf->cu_die, &pf->addr); 902 } 903 904 static int probe_point_inline_cb(Dwarf_Die *in_die, void *data) 905 { 906 struct probe_finder *pf = data; 907 struct perf_probe_point *pp = &pf->pev->point; 908 Dwarf_Addr addr; 909 int ret; 910 911 if (pp->lazy_line) 912 ret = find_probe_point_lazy(in_die, pf); 913 else { 914 /* Get probe address */ 915 if (die_entrypc(in_die, &addr) != 0) { 916 pr_warning("Failed to get entry address of %s.\n", 917 dwarf_diename(in_die)); 918 return -ENOENT; 919 } 920 if (addr == 0) { 921 pr_debug("%s has no valid entry address. skipped.\n", 922 dwarf_diename(in_die)); 923 return -ENOENT; 924 } 925 pf->addr = addr; 926 pf->addr += pp->offset; 927 pr_debug("found inline addr: 0x%jx\n", 928 (uintmax_t)pf->addr); 929 930 ret = call_probe_finder(in_die, pf); 931 } 932 933 return ret; 934 } 935 936 /* Callback parameter with return value for libdw */ 937 struct dwarf_callback_param { 938 void *data; 939 int retval; 940 }; 941 942 /* Search function from function name */ 943 static int probe_point_search_cb(Dwarf_Die *sp_die, void *data) 944 { 945 struct dwarf_callback_param *param = data; 946 struct probe_finder *pf = param->data; 947 struct perf_probe_point *pp = &pf->pev->point; 948 const char *fname; 949 950 /* Check tag and diename */ 951 if (!die_is_func_def(sp_die) || 952 !die_match_name(sp_die, pp->function)) 953 return DWARF_CB_OK; 954 955 /* Check declared file */ 956 fname = die_get_decl_file(sp_die); 957 if (!fname) { 958 pr_warning("A function DIE doesn't have decl_line. Maybe broken DWARF?\n"); 959 return DWARF_CB_OK; 960 } 961 if (pp->file && fname && strtailcmp(pp->file, fname)) 962 return DWARF_CB_OK; 963 964 pr_debug("Matched function: %s [%lx]\n", dwarf_diename(sp_die), 965 (unsigned long)dwarf_dieoffset(sp_die)); 966 pf->fname = fname; 967 if (pp->line) { /* Function relative line */ 968 dwarf_decl_line(sp_die, &pf->lno); 969 pf->lno += pp->line; 970 param->retval = find_probe_point_by_line(pf); 971 } else if (die_is_func_instance(sp_die)) { 972 /* Instances always have the entry address */ 973 die_entrypc(sp_die, &pf->addr); 974 /* But in some case the entry address is 0 */ 975 if (pf->addr == 0) { 976 pr_debug("%s has no entry PC. Skipped\n", 977 dwarf_diename(sp_die)); 978 param->retval = 0; 979 /* Real function */ 980 } else if (pp->lazy_line) 981 param->retval = find_probe_point_lazy(sp_die, pf); 982 else { 983 skip_prologue(sp_die, pf); 984 pf->addr += pp->offset; 985 /* TODO: Check the address in this function */ 986 param->retval = call_probe_finder(sp_die, pf); 987 } 988 } else if (!probe_conf.no_inlines) { 989 /* Inlined function: search instances */ 990 param->retval = die_walk_instances(sp_die, 991 probe_point_inline_cb, (void *)pf); 992 /* This could be a non-existed inline definition */ 993 if (param->retval == -ENOENT) 994 param->retval = 0; 995 } 996 997 /* We need to find other candidates */ 998 if (strisglob(pp->function) && param->retval >= 0) { 999 param->retval = 0; /* We have to clear the result */ 1000 return DWARF_CB_OK; 1001 } 1002 1003 return DWARF_CB_ABORT; /* Exit; no same symbol in this CU. */ 1004 } 1005 1006 static int find_probe_point_by_func(struct probe_finder *pf) 1007 { 1008 struct dwarf_callback_param _param = {.data = (void *)pf, 1009 .retval = 0}; 1010 dwarf_getfuncs(&pf->cu_die, probe_point_search_cb, &_param, 0); 1011 return _param.retval; 1012 } 1013 1014 struct pubname_callback_param { 1015 char *function; 1016 char *file; 1017 Dwarf_Die *cu_die; 1018 Dwarf_Die *sp_die; 1019 int found; 1020 }; 1021 1022 static int pubname_search_cb(Dwarf *dbg, Dwarf_Global *gl, void *data) 1023 { 1024 struct pubname_callback_param *param = data; 1025 const char *fname; 1026 1027 if (dwarf_offdie(dbg, gl->die_offset, param->sp_die)) { 1028 if (dwarf_tag(param->sp_die) != DW_TAG_subprogram) 1029 return DWARF_CB_OK; 1030 1031 if (die_match_name(param->sp_die, param->function)) { 1032 if (!dwarf_offdie(dbg, gl->cu_offset, param->cu_die)) 1033 return DWARF_CB_OK; 1034 1035 if (param->file) { 1036 fname = die_get_decl_file(param->sp_die); 1037 if (!fname || strtailcmp(param->file, fname)) 1038 return DWARF_CB_OK; 1039 } 1040 1041 param->found = 1; 1042 return DWARF_CB_ABORT; 1043 } 1044 } 1045 1046 return DWARF_CB_OK; 1047 } 1048 1049 static int debuginfo__find_probe_location(struct debuginfo *dbg, 1050 struct probe_finder *pf) 1051 { 1052 struct perf_probe_point *pp = &pf->pev->point; 1053 Dwarf_Off off, noff; 1054 size_t cuhl; 1055 Dwarf_Die *diep; 1056 int ret = 0; 1057 1058 off = 0; 1059 pf->lcache = intlist__new(NULL); 1060 if (!pf->lcache) 1061 return -ENOMEM; 1062 1063 /* Fastpath: lookup by function name from .debug_pubnames section */ 1064 if (pp->function && !strisglob(pp->function)) { 1065 struct pubname_callback_param pubname_param = { 1066 .function = pp->function, 1067 .file = pp->file, 1068 .cu_die = &pf->cu_die, 1069 .sp_die = &pf->sp_die, 1070 .found = 0, 1071 }; 1072 struct dwarf_callback_param probe_param = { 1073 .data = pf, 1074 }; 1075 1076 dwarf_getpubnames(dbg->dbg, pubname_search_cb, 1077 &pubname_param, 0); 1078 if (pubname_param.found) { 1079 ret = probe_point_search_cb(&pf->sp_die, &probe_param); 1080 if (ret) 1081 goto found; 1082 } 1083 } 1084 1085 /* Loop on CUs (Compilation Unit) */ 1086 while (!dwarf_nextcu(dbg->dbg, off, &noff, &cuhl, NULL, NULL, NULL)) { 1087 /* Get the DIE(Debugging Information Entry) of this CU */ 1088 diep = dwarf_offdie(dbg->dbg, off + cuhl, &pf->cu_die); 1089 if (!diep) { 1090 off = noff; 1091 continue; 1092 } 1093 1094 /* Check if target file is included. */ 1095 if (pp->file) 1096 pf->fname = cu_find_realpath(&pf->cu_die, pp->file); 1097 else 1098 pf->fname = NULL; 1099 1100 if (!pp->file || pf->fname) { 1101 if (pp->function) 1102 ret = find_probe_point_by_func(pf); 1103 else if (pp->lazy_line) 1104 ret = find_probe_point_lazy(&pf->cu_die, pf); 1105 else { 1106 pf->lno = pp->line; 1107 ret = find_probe_point_by_line(pf); 1108 } 1109 if (ret < 0) 1110 break; 1111 } 1112 off = noff; 1113 } 1114 1115 found: 1116 intlist__delete(pf->lcache); 1117 pf->lcache = NULL; 1118 1119 return ret; 1120 } 1121 1122 /* Find probe points from debuginfo */ 1123 static int debuginfo__find_probes(struct debuginfo *dbg, 1124 struct probe_finder *pf) 1125 { 1126 int ret = 0; 1127 Elf *elf; 1128 GElf_Ehdr ehdr; 1129 1130 if (pf->cfi_eh || pf->cfi_dbg) 1131 return debuginfo__find_probe_location(dbg, pf); 1132 1133 /* Get the call frame information from this dwarf */ 1134 elf = dwarf_getelf(dbg->dbg); 1135 if (elf == NULL) 1136 return -EINVAL; 1137 1138 if (gelf_getehdr(elf, &ehdr) == NULL) 1139 return -EINVAL; 1140 1141 pf->machine = ehdr.e_machine; 1142 1143 #ifdef HAVE_DWARF_CFI_SUPPORT 1144 do { 1145 GElf_Shdr shdr; 1146 1147 if (elf_section_by_name(elf, &ehdr, &shdr, ".eh_frame", NULL) && 1148 shdr.sh_type == SHT_PROGBITS) 1149 pf->cfi_eh = dwarf_getcfi_elf(elf); 1150 1151 pf->cfi_dbg = dwarf_getcfi(dbg->dbg); 1152 } while (0); 1153 #endif /* HAVE_DWARF_CFI_SUPPORT */ 1154 1155 ret = debuginfo__find_probe_location(dbg, pf); 1156 return ret; 1157 } 1158 1159 struct local_vars_finder { 1160 struct probe_finder *pf; 1161 struct perf_probe_arg *args; 1162 bool vars; 1163 int max_args; 1164 int nargs; 1165 int ret; 1166 }; 1167 1168 /* Collect available variables in this scope */ 1169 static int copy_variables_cb(Dwarf_Die *die_mem, void *data) 1170 { 1171 struct local_vars_finder *vf = data; 1172 struct probe_finder *pf = vf->pf; 1173 int tag; 1174 1175 tag = dwarf_tag(die_mem); 1176 if (tag == DW_TAG_formal_parameter || 1177 (tag == DW_TAG_variable && vf->vars)) { 1178 if (convert_variable_location(die_mem, vf->pf->addr, 1179 vf->pf->fb_ops, &pf->sp_die, 1180 pf->machine, NULL) == 0) { 1181 vf->args[vf->nargs].var = (char *)dwarf_diename(die_mem); 1182 if (vf->args[vf->nargs].var == NULL) { 1183 vf->ret = -ENOMEM; 1184 return DIE_FIND_CB_END; 1185 } 1186 pr_debug(" %s", vf->args[vf->nargs].var); 1187 vf->nargs++; 1188 } 1189 } 1190 1191 if (dwarf_haspc(die_mem, vf->pf->addr)) 1192 return DIE_FIND_CB_CONTINUE; 1193 else 1194 return DIE_FIND_CB_SIBLING; 1195 } 1196 1197 static int expand_probe_args(Dwarf_Die *sc_die, struct probe_finder *pf, 1198 struct perf_probe_arg *args) 1199 { 1200 Dwarf_Die die_mem; 1201 int i; 1202 int n = 0; 1203 struct local_vars_finder vf = {.pf = pf, .args = args, .vars = false, 1204 .max_args = MAX_PROBE_ARGS, .ret = 0}; 1205 1206 for (i = 0; i < pf->pev->nargs; i++) { 1207 /* var never be NULL */ 1208 if (strcmp(pf->pev->args[i].var, PROBE_ARG_VARS) == 0) 1209 vf.vars = true; 1210 else if (strcmp(pf->pev->args[i].var, PROBE_ARG_PARAMS) != 0) { 1211 /* Copy normal argument */ 1212 args[n] = pf->pev->args[i]; 1213 n++; 1214 continue; 1215 } 1216 pr_debug("Expanding %s into:", pf->pev->args[i].var); 1217 vf.nargs = n; 1218 /* Special local variables */ 1219 die_find_child(sc_die, copy_variables_cb, (void *)&vf, 1220 &die_mem); 1221 pr_debug(" (%d)\n", vf.nargs - n); 1222 if (vf.ret < 0) 1223 return vf.ret; 1224 n = vf.nargs; 1225 } 1226 return n; 1227 } 1228 1229 static bool trace_event_finder_overlap(struct trace_event_finder *tf) 1230 { 1231 int i; 1232 1233 for (i = 0; i < tf->ntevs; i++) { 1234 if (tf->pf.addr == tf->tevs[i].point.address) 1235 return true; 1236 } 1237 return false; 1238 } 1239 1240 /* Add a found probe point into trace event list */ 1241 static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf) 1242 { 1243 struct trace_event_finder *tf = 1244 container_of(pf, struct trace_event_finder, pf); 1245 struct perf_probe_point *pp = &pf->pev->point; 1246 struct probe_trace_event *tev; 1247 struct perf_probe_arg *args = NULL; 1248 int ret, i; 1249 1250 /* 1251 * For some reason (e.g. different column assigned to same address) 1252 * This callback can be called with the address which already passed. 1253 * Ignore it first. 1254 */ 1255 if (trace_event_finder_overlap(tf)) 1256 return 0; 1257 1258 /* Check number of tevs */ 1259 if (tf->ntevs == tf->max_tevs) { 1260 pr_warning("Too many( > %d) probe point found.\n", 1261 tf->max_tevs); 1262 return -ERANGE; 1263 } 1264 tev = &tf->tevs[tf->ntevs++]; 1265 1266 /* Trace point should be converted from subprogram DIE */ 1267 ret = convert_to_trace_point(&pf->sp_die, tf->mod, pf->addr, 1268 pp->retprobe, pp->function, &tev->point); 1269 if (ret < 0) 1270 goto end; 1271 1272 tev->point.realname = strdup(dwarf_diename(sc_die)); 1273 if (!tev->point.realname) { 1274 ret = -ENOMEM; 1275 goto end; 1276 } 1277 1278 pr_debug("Probe point found: %s+%lu\n", tev->point.symbol, 1279 tev->point.offset); 1280 1281 /* Expand special probe argument if exist */ 1282 args = zalloc(sizeof(struct perf_probe_arg) * MAX_PROBE_ARGS); 1283 if (args == NULL) { 1284 ret = -ENOMEM; 1285 goto end; 1286 } 1287 1288 ret = expand_probe_args(sc_die, pf, args); 1289 if (ret < 0) 1290 goto end; 1291 1292 tev->nargs = ret; 1293 tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs); 1294 if (tev->args == NULL) { 1295 ret = -ENOMEM; 1296 goto end; 1297 } 1298 1299 /* Find each argument */ 1300 for (i = 0; i < tev->nargs; i++) { 1301 pf->pvar = &args[i]; 1302 pf->tvar = &tev->args[i]; 1303 /* Variable should be found from scope DIE */ 1304 ret = find_variable(sc_die, pf); 1305 if (ret != 0) 1306 break; 1307 } 1308 1309 end: 1310 if (ret) { 1311 clear_probe_trace_event(tev); 1312 tf->ntevs--; 1313 } 1314 free(args); 1315 return ret; 1316 } 1317 1318 static int fill_empty_trace_arg(struct perf_probe_event *pev, 1319 struct probe_trace_event *tevs, int ntevs) 1320 { 1321 char **valp; 1322 char *type; 1323 int i, j, ret; 1324 1325 if (!ntevs) 1326 return -ENOENT; 1327 1328 for (i = 0; i < pev->nargs; i++) { 1329 type = NULL; 1330 for (j = 0; j < ntevs; j++) { 1331 if (tevs[j].args[i].value) { 1332 type = tevs[j].args[i].type; 1333 break; 1334 } 1335 } 1336 if (j == ntevs) { 1337 print_var_not_found(pev->args[i].var); 1338 return -ENOENT; 1339 } 1340 for (j = 0; j < ntevs; j++) { 1341 valp = &tevs[j].args[i].value; 1342 if (*valp) 1343 continue; 1344 1345 ret = asprintf(valp, "\\%lx", probe_conf.magic_num); 1346 if (ret < 0) 1347 return -ENOMEM; 1348 /* Note that type can be NULL */ 1349 if (type) { 1350 tevs[j].args[i].type = strdup(type); 1351 if (!tevs[j].args[i].type) 1352 return -ENOMEM; 1353 } 1354 } 1355 } 1356 return 0; 1357 } 1358 1359 /* Find probe_trace_events specified by perf_probe_event from debuginfo */ 1360 int debuginfo__find_trace_events(struct debuginfo *dbg, 1361 struct perf_probe_event *pev, 1362 struct probe_trace_event **tevs) 1363 { 1364 struct trace_event_finder tf = { 1365 .pf = {.pev = pev, .dbg = dbg, .callback = add_probe_trace_event}, 1366 .max_tevs = probe_conf.max_probes, .mod = dbg->mod}; 1367 int ret, i; 1368 1369 /* Allocate result tevs array */ 1370 *tevs = zalloc(sizeof(struct probe_trace_event) * tf.max_tevs); 1371 if (*tevs == NULL) 1372 return -ENOMEM; 1373 1374 tf.tevs = *tevs; 1375 tf.ntevs = 0; 1376 1377 if (pev->nargs != 0 && immediate_value_is_supported()) 1378 tf.pf.skip_empty_arg = true; 1379 1380 ret = debuginfo__find_probes(dbg, &tf.pf); 1381 if (ret >= 0 && tf.pf.skip_empty_arg) 1382 ret = fill_empty_trace_arg(pev, tf.tevs, tf.ntevs); 1383 1384 if (ret < 0 || tf.ntevs == 0) { 1385 for (i = 0; i < tf.ntevs; i++) 1386 clear_probe_trace_event(&tf.tevs[i]); 1387 zfree(tevs); 1388 return ret; 1389 } 1390 1391 return (ret < 0) ? ret : tf.ntevs; 1392 } 1393 1394 /* Collect available variables in this scope */ 1395 static int collect_variables_cb(Dwarf_Die *die_mem, void *data) 1396 { 1397 struct available_var_finder *af = data; 1398 struct variable_list *vl; 1399 struct strbuf buf = STRBUF_INIT; 1400 int tag, ret; 1401 1402 vl = &af->vls[af->nvls - 1]; 1403 1404 tag = dwarf_tag(die_mem); 1405 if (tag == DW_TAG_formal_parameter || 1406 tag == DW_TAG_variable) { 1407 ret = convert_variable_location(die_mem, af->pf.addr, 1408 af->pf.fb_ops, &af->pf.sp_die, 1409 af->pf.machine, NULL); 1410 if (ret == 0 || ret == -ERANGE) { 1411 int ret2; 1412 bool externs = !af->child; 1413 1414 if (strbuf_init(&buf, 64) < 0) 1415 goto error; 1416 1417 if (probe_conf.show_location_range) { 1418 if (!externs) 1419 ret2 = strbuf_add(&buf, 1420 ret ? "[INV]\t" : "[VAL]\t", 6); 1421 else 1422 ret2 = strbuf_add(&buf, "[EXT]\t", 6); 1423 if (ret2) 1424 goto error; 1425 } 1426 1427 ret2 = die_get_varname(die_mem, &buf); 1428 1429 if (!ret2 && probe_conf.show_location_range && 1430 !externs) { 1431 if (strbuf_addch(&buf, '\t') < 0) 1432 goto error; 1433 ret2 = die_get_var_range(&af->pf.sp_die, 1434 die_mem, &buf); 1435 } 1436 1437 pr_debug("Add new var: %s\n", buf.buf); 1438 if (ret2 == 0) { 1439 strlist__add(vl->vars, 1440 strbuf_detach(&buf, NULL)); 1441 } 1442 strbuf_release(&buf); 1443 } 1444 } 1445 1446 if (af->child && dwarf_haspc(die_mem, af->pf.addr)) 1447 return DIE_FIND_CB_CONTINUE; 1448 else 1449 return DIE_FIND_CB_SIBLING; 1450 error: 1451 strbuf_release(&buf); 1452 pr_debug("Error in strbuf\n"); 1453 return DIE_FIND_CB_END; 1454 } 1455 1456 static bool available_var_finder_overlap(struct available_var_finder *af) 1457 { 1458 int i; 1459 1460 for (i = 0; i < af->nvls; i++) { 1461 if (af->pf.addr == af->vls[i].point.address) 1462 return true; 1463 } 1464 return false; 1465 1466 } 1467 1468 /* Add a found vars into available variables list */ 1469 static int add_available_vars(Dwarf_Die *sc_die, struct probe_finder *pf) 1470 { 1471 struct available_var_finder *af = 1472 container_of(pf, struct available_var_finder, pf); 1473 struct perf_probe_point *pp = &pf->pev->point; 1474 struct variable_list *vl; 1475 Dwarf_Die die_mem; 1476 int ret; 1477 1478 /* 1479 * For some reason (e.g. different column assigned to same address), 1480 * this callback can be called with the address which already passed. 1481 * Ignore it first. 1482 */ 1483 if (available_var_finder_overlap(af)) 1484 return 0; 1485 1486 /* Check number of tevs */ 1487 if (af->nvls == af->max_vls) { 1488 pr_warning("Too many( > %d) probe point found.\n", af->max_vls); 1489 return -ERANGE; 1490 } 1491 vl = &af->vls[af->nvls++]; 1492 1493 /* Trace point should be converted from subprogram DIE */ 1494 ret = convert_to_trace_point(&pf->sp_die, af->mod, pf->addr, 1495 pp->retprobe, pp->function, &vl->point); 1496 if (ret < 0) 1497 return ret; 1498 1499 pr_debug("Probe point found: %s+%lu\n", vl->point.symbol, 1500 vl->point.offset); 1501 1502 /* Find local variables */ 1503 vl->vars = strlist__new(NULL, NULL); 1504 if (vl->vars == NULL) 1505 return -ENOMEM; 1506 af->child = true; 1507 die_find_child(sc_die, collect_variables_cb, (void *)af, &die_mem); 1508 1509 /* Find external variables */ 1510 if (!probe_conf.show_ext_vars) 1511 goto out; 1512 /* Don't need to search child DIE for external vars. */ 1513 af->child = false; 1514 die_find_child(&pf->cu_die, collect_variables_cb, (void *)af, &die_mem); 1515 1516 out: 1517 if (strlist__empty(vl->vars)) { 1518 strlist__delete(vl->vars); 1519 vl->vars = NULL; 1520 } 1521 1522 return ret; 1523 } 1524 1525 /* 1526 * Find available variables at given probe point 1527 * Return the number of found probe points. Return 0 if there is no 1528 * matched probe point. Return <0 if an error occurs. 1529 */ 1530 int debuginfo__find_available_vars_at(struct debuginfo *dbg, 1531 struct perf_probe_event *pev, 1532 struct variable_list **vls) 1533 { 1534 struct available_var_finder af = { 1535 .pf = {.pev = pev, .dbg = dbg, .callback = add_available_vars}, 1536 .mod = dbg->mod, 1537 .max_vls = probe_conf.max_probes}; 1538 int ret; 1539 1540 /* Allocate result vls array */ 1541 *vls = zalloc(sizeof(struct variable_list) * af.max_vls); 1542 if (*vls == NULL) 1543 return -ENOMEM; 1544 1545 af.vls = *vls; 1546 af.nvls = 0; 1547 1548 ret = debuginfo__find_probes(dbg, &af.pf); 1549 if (ret < 0) { 1550 /* Free vlist for error */ 1551 while (af.nvls--) { 1552 zfree(&af.vls[af.nvls].point.symbol); 1553 strlist__delete(af.vls[af.nvls].vars); 1554 } 1555 zfree(vls); 1556 return ret; 1557 } 1558 1559 return (ret < 0) ? ret : af.nvls; 1560 } 1561 1562 /* Reverse search */ 1563 int debuginfo__find_probe_point(struct debuginfo *dbg, u64 addr, 1564 struct perf_probe_point *ppt) 1565 { 1566 Dwarf_Die cudie, spdie, indie; 1567 Dwarf_Addr _addr = 0, baseaddr = 0; 1568 const char *fname = NULL, *func = NULL, *basefunc = NULL, *tmp; 1569 int baseline = 0, lineno = 0, ret = 0; 1570 1571 /* We always need to relocate the address for aranges */ 1572 if (debuginfo__get_text_offset(dbg, &baseaddr, false) == 0) 1573 addr += baseaddr; 1574 /* Find cu die */ 1575 if (!dwarf_addrdie(dbg->dbg, (Dwarf_Addr)addr, &cudie)) { 1576 pr_warning("Failed to find debug information for address %#" PRIx64 "\n", 1577 addr); 1578 ret = -EINVAL; 1579 goto end; 1580 } 1581 1582 /* Find a corresponding line (filename and lineno) */ 1583 cu_find_lineinfo(&cudie, (Dwarf_Addr)addr, &fname, &lineno); 1584 /* Don't care whether it failed or not */ 1585 1586 /* Find a corresponding function (name, baseline and baseaddr) */ 1587 if (die_find_realfunc(&cudie, (Dwarf_Addr)addr, &spdie)) { 1588 /* Get function entry information */ 1589 func = basefunc = dwarf_diename(&spdie); 1590 if (!func || 1591 die_entrypc(&spdie, &baseaddr) != 0 || 1592 dwarf_decl_line(&spdie, &baseline) != 0) { 1593 lineno = 0; 1594 goto post; 1595 } 1596 1597 fname = die_get_decl_file(&spdie); 1598 if (addr == baseaddr) { 1599 /* Function entry - Relative line number is 0 */ 1600 lineno = baseline; 1601 goto post; 1602 } 1603 1604 /* Track down the inline functions step by step */ 1605 while (die_find_top_inlinefunc(&spdie, (Dwarf_Addr)addr, 1606 &indie)) { 1607 /* There is an inline function */ 1608 if (die_entrypc(&indie, &_addr) == 0 && 1609 _addr == addr) { 1610 /* 1611 * addr is at an inline function entry. 1612 * In this case, lineno should be the call-site 1613 * line number. (overwrite lineinfo) 1614 */ 1615 lineno = die_get_call_lineno(&indie); 1616 fname = die_get_call_file(&indie); 1617 break; 1618 } else { 1619 /* 1620 * addr is in an inline function body. 1621 * Since lineno points one of the lines 1622 * of the inline function, baseline should 1623 * be the entry line of the inline function. 1624 */ 1625 tmp = dwarf_diename(&indie); 1626 if (!tmp || 1627 dwarf_decl_line(&indie, &baseline) != 0) 1628 break; 1629 func = tmp; 1630 spdie = indie; 1631 } 1632 } 1633 /* Verify the lineno and baseline are in a same file */ 1634 tmp = die_get_decl_file(&spdie); 1635 if (!tmp || (fname && strcmp(tmp, fname) != 0)) 1636 lineno = 0; 1637 } 1638 1639 post: 1640 /* Make a relative line number or an offset */ 1641 if (lineno) 1642 ppt->line = lineno - baseline; 1643 else if (basefunc) { 1644 ppt->offset = addr - baseaddr; 1645 func = basefunc; 1646 } 1647 1648 /* Duplicate strings */ 1649 if (func) { 1650 ppt->function = strdup(func); 1651 if (ppt->function == NULL) { 1652 ret = -ENOMEM; 1653 goto end; 1654 } 1655 } 1656 if (fname) { 1657 ppt->file = strdup(fname); 1658 if (ppt->file == NULL) { 1659 zfree(&ppt->function); 1660 ret = -ENOMEM; 1661 goto end; 1662 } 1663 } 1664 end: 1665 if (ret == 0 && (fname || func)) 1666 ret = 1; /* Found a point */ 1667 return ret; 1668 } 1669 1670 /* Add a line and store the src path */ 1671 static int line_range_add_line(const char *src, unsigned int lineno, 1672 struct line_range *lr) 1673 { 1674 /* Copy source path */ 1675 if (!lr->path) { 1676 lr->path = strdup(src); 1677 if (lr->path == NULL) 1678 return -ENOMEM; 1679 } 1680 return intlist__add(lr->line_list, lineno); 1681 } 1682 1683 static int line_range_walk_cb(const char *fname, int lineno, 1684 Dwarf_Addr addr, void *data) 1685 { 1686 struct line_finder *lf = data; 1687 const char *__fname; 1688 int __lineno; 1689 int err; 1690 1691 if ((strtailcmp(fname, lf->fname) != 0) || 1692 (lf->lno_s > lineno || lf->lno_e < lineno)) 1693 return 0; 1694 1695 /* Make sure this line can be reversible */ 1696 if (cu_find_lineinfo(&lf->cu_die, addr, &__fname, &__lineno) > 0 1697 && (lineno != __lineno || strcmp(fname, __fname))) 1698 return 0; 1699 1700 err = line_range_add_line(fname, lineno, lf->lr); 1701 if (err < 0 && err != -EEXIST) 1702 return err; 1703 1704 return 0; 1705 } 1706 1707 /* Find line range from its line number */ 1708 static int find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf) 1709 { 1710 int ret; 1711 1712 ret = die_walk_lines(sp_die ?: &lf->cu_die, line_range_walk_cb, lf); 1713 1714 /* Update status */ 1715 if (ret >= 0) 1716 if (!intlist__empty(lf->lr->line_list)) 1717 ret = lf->found = 1; 1718 else 1719 ret = 0; /* Lines are not found */ 1720 else { 1721 zfree(&lf->lr->path); 1722 } 1723 return ret; 1724 } 1725 1726 static int line_range_inline_cb(Dwarf_Die *in_die, void *data) 1727 { 1728 int ret = find_line_range_by_line(in_die, data); 1729 1730 /* 1731 * We have to check all instances of inlined function, because 1732 * some execution paths can be optimized out depends on the 1733 * function argument of instances. However, if an error occurs, 1734 * it should be handled by the caller. 1735 */ 1736 return ret < 0 ? ret : 0; 1737 } 1738 1739 /* Search function definition from function name */ 1740 static int line_range_search_cb(Dwarf_Die *sp_die, void *data) 1741 { 1742 struct dwarf_callback_param *param = data; 1743 struct line_finder *lf = param->data; 1744 struct line_range *lr = lf->lr; 1745 const char *fname; 1746 1747 /* Check declared file */ 1748 if (lr->file) { 1749 fname = die_get_decl_file(sp_die); 1750 if (!fname || strtailcmp(lr->file, fname)) 1751 return DWARF_CB_OK; 1752 } 1753 1754 if (die_match_name(sp_die, lr->function) && die_is_func_def(sp_die)) { 1755 lf->fname = die_get_decl_file(sp_die); 1756 dwarf_decl_line(sp_die, &lr->offset); 1757 pr_debug("fname: %s, lineno:%d\n", lf->fname, lr->offset); 1758 lf->lno_s = lr->offset + lr->start; 1759 if (lf->lno_s < 0) /* Overflow */ 1760 lf->lno_s = INT_MAX; 1761 lf->lno_e = lr->offset + lr->end; 1762 if (lf->lno_e < 0) /* Overflow */ 1763 lf->lno_e = INT_MAX; 1764 pr_debug("New line range: %d to %d\n", lf->lno_s, lf->lno_e); 1765 lr->start = lf->lno_s; 1766 lr->end = lf->lno_e; 1767 if (!die_is_func_instance(sp_die)) 1768 param->retval = die_walk_instances(sp_die, 1769 line_range_inline_cb, lf); 1770 else 1771 param->retval = find_line_range_by_line(sp_die, lf); 1772 return DWARF_CB_ABORT; 1773 } 1774 return DWARF_CB_OK; 1775 } 1776 1777 static int find_line_range_by_func(struct line_finder *lf) 1778 { 1779 struct dwarf_callback_param param = {.data = (void *)lf, .retval = 0}; 1780 dwarf_getfuncs(&lf->cu_die, line_range_search_cb, ¶m, 0); 1781 return param.retval; 1782 } 1783 1784 int debuginfo__find_line_range(struct debuginfo *dbg, struct line_range *lr) 1785 { 1786 struct line_finder lf = {.lr = lr, .found = 0}; 1787 int ret = 0; 1788 Dwarf_Off off = 0, noff; 1789 size_t cuhl; 1790 Dwarf_Die *diep; 1791 const char *comp_dir; 1792 1793 /* Fastpath: lookup by function name from .debug_pubnames section */ 1794 if (lr->function) { 1795 struct pubname_callback_param pubname_param = { 1796 .function = lr->function, .file = lr->file, 1797 .cu_die = &lf.cu_die, .sp_die = &lf.sp_die, .found = 0}; 1798 struct dwarf_callback_param line_range_param = { 1799 .data = (void *)&lf, .retval = 0}; 1800 1801 dwarf_getpubnames(dbg->dbg, pubname_search_cb, 1802 &pubname_param, 0); 1803 if (pubname_param.found) { 1804 line_range_search_cb(&lf.sp_die, &line_range_param); 1805 if (lf.found) 1806 goto found; 1807 } 1808 } 1809 1810 /* Loop on CUs (Compilation Unit) */ 1811 while (!lf.found && ret >= 0) { 1812 if (dwarf_nextcu(dbg->dbg, off, &noff, &cuhl, 1813 NULL, NULL, NULL) != 0) 1814 break; 1815 1816 /* Get the DIE(Debugging Information Entry) of this CU */ 1817 diep = dwarf_offdie(dbg->dbg, off + cuhl, &lf.cu_die); 1818 if (!diep) { 1819 off = noff; 1820 continue; 1821 } 1822 1823 /* Check if target file is included. */ 1824 if (lr->file) 1825 lf.fname = cu_find_realpath(&lf.cu_die, lr->file); 1826 else 1827 lf.fname = 0; 1828 1829 if (!lr->file || lf.fname) { 1830 if (lr->function) 1831 ret = find_line_range_by_func(&lf); 1832 else { 1833 lf.lno_s = lr->start; 1834 lf.lno_e = lr->end; 1835 ret = find_line_range_by_line(NULL, &lf); 1836 } 1837 } 1838 off = noff; 1839 } 1840 1841 found: 1842 /* Store comp_dir */ 1843 if (lf.found) { 1844 comp_dir = cu_get_comp_dir(&lf.cu_die); 1845 if (comp_dir) { 1846 lr->comp_dir = strdup(comp_dir); 1847 if (!lr->comp_dir) 1848 ret = -ENOMEM; 1849 } 1850 } 1851 1852 pr_debug("path: %s\n", lr->path); 1853 return (ret < 0) ? ret : lf.found; 1854 } 1855 1856 /* 1857 * Find a src file from a DWARF tag path. Prepend optional source path prefix 1858 * and chop off leading directories that do not exist. Result is passed back as 1859 * a newly allocated path on success. 1860 * Return 0 if file was found and readable, -errno otherwise. 1861 */ 1862 int find_source_path(const char *raw_path, const char *sbuild_id, 1863 const char *comp_dir, char **new_path) 1864 { 1865 const char *prefix = symbol_conf.source_prefix; 1866 1867 if (sbuild_id && !prefix) { 1868 if (!get_source_from_debuginfod(raw_path, sbuild_id, new_path)) 1869 return 0; 1870 } 1871 1872 if (!prefix) { 1873 if (raw_path[0] != '/' && comp_dir) 1874 /* If not an absolute path, try to use comp_dir */ 1875 prefix = comp_dir; 1876 else { 1877 if (access(raw_path, R_OK) == 0) { 1878 *new_path = strdup(raw_path); 1879 return *new_path ? 0 : -ENOMEM; 1880 } else 1881 return -errno; 1882 } 1883 } 1884 1885 *new_path = malloc((strlen(prefix) + strlen(raw_path) + 2)); 1886 if (!*new_path) 1887 return -ENOMEM; 1888 1889 for (;;) { 1890 sprintf(*new_path, "%s/%s", prefix, raw_path); 1891 1892 if (access(*new_path, R_OK) == 0) 1893 return 0; 1894 1895 if (!symbol_conf.source_prefix) { 1896 /* In case of searching comp_dir, don't retry */ 1897 zfree(new_path); 1898 return -errno; 1899 } 1900 1901 switch (errno) { 1902 case ENAMETOOLONG: 1903 case ENOENT: 1904 case EROFS: 1905 case EFAULT: 1906 raw_path = strchr(++raw_path, '/'); 1907 if (!raw_path) { 1908 zfree(new_path); 1909 return -ENOENT; 1910 } 1911 continue; 1912 1913 default: 1914 zfree(new_path); 1915 return -errno; 1916 } 1917 } 1918 } 1919