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