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