aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/probe-finder.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/probe-finder.c')
-rw-r--r--tools/perf/util/probe-finder.c981
1 files changed, 243 insertions, 738 deletions
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 3b9d0b800d5..5d732621a46 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -43,21 +43,6 @@
43/* Kprobe tracer basic type is up to u64 */ 43/* Kprobe tracer basic type is up to u64 */
44#define MAX_BASIC_TYPE_BITS 64 44#define MAX_BASIC_TYPE_BITS 64
45 45
46/*
47 * Compare the tail of two strings.
48 * Return 0 if whole of either string is same as another's tail part.
49 */
50static int strtailcmp(const char *s1, const char *s2)
51{
52 int i1 = strlen(s1);
53 int i2 = strlen(s2);
54 while (--i1 >= 0 && --i2 >= 0) {
55 if (s1[i1] != s2[i2])
56 return s1[i1] - s2[i2];
57 }
58 return 0;
59}
60
61/* Line number list operations */ 46/* Line number list operations */
62 47
63/* Add a line to line number list */ 48/* Add a line to line number list */
@@ -131,29 +116,37 @@ static const Dwfl_Callbacks offline_callbacks = {
131}; 116};
132 117
133/* Get a Dwarf from offline image */ 118/* Get a Dwarf from offline image */
134static Dwarf *dwfl_init_offline_dwarf(int fd, Dwfl **dwflp, Dwarf_Addr *bias) 119static int debuginfo__init_offline_dwarf(struct debuginfo *self,
120 const char *path)
135{ 121{
136 Dwfl_Module *mod; 122 Dwfl_Module *mod;
137 Dwarf *dbg = NULL; 123 int fd;
138 124
139 if (!dwflp) 125 fd = open(path, O_RDONLY);
140 return NULL; 126 if (fd < 0)
127 return fd;
141 128
142 *dwflp = dwfl_begin(&offline_callbacks); 129 self->dwfl = dwfl_begin(&offline_callbacks);
143 if (!*dwflp) 130 if (!self->dwfl)
144 return NULL; 131 goto error;
145 132
146 mod = dwfl_report_offline(*dwflp, "", "", fd); 133 mod = dwfl_report_offline(self->dwfl, "", "", fd);
147 if (!mod) 134 if (!mod)
148 goto error; 135 goto error;
149 136
150 dbg = dwfl_module_getdwarf(mod, bias); 137 self->dbg = dwfl_module_getdwarf(mod, &self->bias);
151 if (!dbg) { 138 if (!self->dbg)
139 goto error;
140
141 return 0;
152error: 142error:
153 dwfl_end(*dwflp); 143 if (self->dwfl)
154 *dwflp = NULL; 144 dwfl_end(self->dwfl);
155 } 145 else
156 return dbg; 146 close(fd);
147 memset(self, 0, sizeof(*self));
148
149 return -ENOENT;
157} 150}
158 151
159#if _ELFUTILS_PREREQ(0, 148) 152#if _ELFUTILS_PREREQ(0, 148)
@@ -189,597 +182,81 @@ static const Dwfl_Callbacks kernel_callbacks = {
189}; 182};
190 183
191/* Get a Dwarf from live kernel image */ 184/* Get a Dwarf from live kernel image */
192static Dwarf *dwfl_init_live_kernel_dwarf(Dwarf_Addr addr, Dwfl **dwflp, 185static int debuginfo__init_online_kernel_dwarf(struct debuginfo *self,
193 Dwarf_Addr *bias) 186 Dwarf_Addr addr)
194{ 187{
195 Dwarf *dbg; 188 self->dwfl = dwfl_begin(&kernel_callbacks);
196 189 if (!self->dwfl)
197 if (!dwflp) 190 return -EINVAL;
198 return NULL;
199
200 *dwflp = dwfl_begin(&kernel_callbacks);
201 if (!*dwflp)
202 return NULL;
203 191
204 /* Load the kernel dwarves: Don't care the result here */ 192 /* Load the kernel dwarves: Don't care the result here */
205 dwfl_linux_kernel_report_kernel(*dwflp); 193 dwfl_linux_kernel_report_kernel(self->dwfl);
206 dwfl_linux_kernel_report_modules(*dwflp); 194 dwfl_linux_kernel_report_modules(self->dwfl);
207 195
208 dbg = dwfl_addrdwarf(*dwflp, addr, bias); 196 self->dbg = dwfl_addrdwarf(self->dwfl, addr, &self->bias);
209 /* Here, check whether we could get a real dwarf */ 197 /* Here, check whether we could get a real dwarf */
210 if (!dbg) { 198 if (!self->dbg) {
211 pr_debug("Failed to find kernel dwarf at %lx\n", 199 pr_debug("Failed to find kernel dwarf at %lx\n",
212 (unsigned long)addr); 200 (unsigned long)addr);
213 dwfl_end(*dwflp); 201 dwfl_end(self->dwfl);
214 *dwflp = NULL; 202 memset(self, 0, sizeof(*self));
203 return -ENOENT;
215 } 204 }
216 return dbg; 205
206 return 0;
217} 207}
218#else 208#else
219/* With older elfutils, this just support kernel module... */ 209/* With older elfutils, this just support kernel module... */
220static Dwarf *dwfl_init_live_kernel_dwarf(Dwarf_Addr addr __used, Dwfl **dwflp, 210static int debuginfo__init_online_kernel_dwarf(struct debuginfo *self,
221 Dwarf_Addr *bias) 211 Dwarf_Addr addr __used)
222{ 212{
223 int fd;
224 const char *path = kernel_get_module_path("kernel"); 213 const char *path = kernel_get_module_path("kernel");
225 214
226 if (!path) { 215 if (!path) {
227 pr_err("Failed to find vmlinux path\n"); 216 pr_err("Failed to find vmlinux path\n");
228 return NULL; 217 return -ENOENT;
229 } 218 }
230 219
231 pr_debug2("Use file %s for debuginfo\n", path); 220 pr_debug2("Use file %s for debuginfo\n", path);
232 fd = open(path, O_RDONLY); 221 return debuginfo__init_offline_dwarf(self, path);
233 if (fd < 0)
234 return NULL;
235
236 return dwfl_init_offline_dwarf(fd, dwflp, bias);
237} 222}
238#endif 223#endif
239 224
240/* Dwarf wrappers */ 225struct debuginfo *debuginfo__new(const char *path)
241
242/* Find the realpath of the target file. */
243static const char *cu_find_realpath(Dwarf_Die *cu_die, const char *fname)
244{ 226{
245 Dwarf_Files *files; 227 struct debuginfo *self = zalloc(sizeof(struct debuginfo));
246 size_t nfiles, i; 228 if (!self)
247 const char *src = NULL;
248 int ret;
249
250 if (!fname)
251 return NULL; 229 return NULL;
252 230
253 ret = dwarf_getsrcfiles(cu_die, &files, &nfiles); 231 if (debuginfo__init_offline_dwarf(self, path) < 0) {
254 if (ret != 0) 232 free(self);
255 return NULL; 233 self = NULL;
256
257 for (i = 0; i < nfiles; i++) {
258 src = dwarf_filesrc(files, i, NULL, NULL);
259 if (strtailcmp(src, fname) == 0)
260 break;
261 } 234 }
262 if (i == nfiles)
263 return NULL;
264 return src;
265}
266 235
267/* Get DW_AT_comp_dir (should be NULL with older gcc) */ 236 return self;
268static const char *cu_get_comp_dir(Dwarf_Die *cu_die)
269{
270 Dwarf_Attribute attr;
271 if (dwarf_attr(cu_die, DW_AT_comp_dir, &attr) == NULL)
272 return NULL;
273 return dwarf_formstring(&attr);
274} 237}
275 238
276/* Get a line number and file name for given address */ 239struct debuginfo *debuginfo__new_online_kernel(unsigned long addr)
277static int cu_find_lineinfo(Dwarf_Die *cudie, unsigned long addr,
278 const char **fname, int *lineno)
279{ 240{
280 Dwarf_Line *line; 241 struct debuginfo *self = zalloc(sizeof(struct debuginfo));
281 Dwarf_Addr laddr; 242 if (!self)
282
283 line = dwarf_getsrc_die(cudie, (Dwarf_Addr)addr);
284 if (line && dwarf_lineaddr(line, &laddr) == 0 &&
285 addr == (unsigned long)laddr && dwarf_lineno(line, lineno) == 0) {
286 *fname = dwarf_linesrc(line, NULL, NULL);
287 if (!*fname)
288 /* line number is useless without filename */
289 *lineno = 0;
290 }
291
292 return *lineno ?: -ENOENT;
293}
294
295/* Compare diename and tname */
296static bool die_compare_name(Dwarf_Die *dw_die, const char *tname)
297{
298 const char *name;
299 name = dwarf_diename(dw_die);
300 return name ? (strcmp(tname, name) == 0) : false;
301}
302
303/* Get callsite line number of inline-function instance */
304static int die_get_call_lineno(Dwarf_Die *in_die)
305{
306 Dwarf_Attribute attr;
307 Dwarf_Word ret;
308
309 if (!dwarf_attr(in_die, DW_AT_call_line, &attr))
310 return -ENOENT;
311
312 dwarf_formudata(&attr, &ret);
313 return (int)ret;
314}
315
316/* Get type die */
317static Dwarf_Die *die_get_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem)
318{
319 Dwarf_Attribute attr;
320
321 if (dwarf_attr_integrate(vr_die, DW_AT_type, &attr) &&
322 dwarf_formref_die(&attr, die_mem))
323 return die_mem;
324 else
325 return NULL; 243 return NULL;
326}
327
328/* Get a type die, but skip qualifiers */
329static Dwarf_Die *__die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem)
330{
331 int tag;
332
333 do {
334 vr_die = die_get_type(vr_die, die_mem);
335 if (!vr_die)
336 break;
337 tag = dwarf_tag(vr_die);
338 } while (tag == DW_TAG_const_type ||
339 tag == DW_TAG_restrict_type ||
340 tag == DW_TAG_volatile_type ||
341 tag == DW_TAG_shared_type);
342
343 return vr_die;
344}
345
346/* Get a type die, but skip qualifiers and typedef */
347static Dwarf_Die *die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem)
348{
349 do {
350 vr_die = __die_get_real_type(vr_die, die_mem);
351 } while (vr_die && dwarf_tag(vr_die) == DW_TAG_typedef);
352
353 return vr_die;
354}
355
356static int die_get_attr_udata(Dwarf_Die *tp_die, unsigned int attr_name,
357 Dwarf_Word *result)
358{
359 Dwarf_Attribute attr;
360
361 if (dwarf_attr(tp_die, attr_name, &attr) == NULL ||
362 dwarf_formudata(&attr, result) != 0)
363 return -ENOENT;
364
365 return 0;
366}
367 244
368static bool die_is_signed_type(Dwarf_Die *tp_die) 245 if (debuginfo__init_online_kernel_dwarf(self, (Dwarf_Addr)addr) < 0) {
369{ 246 free(self);
370 Dwarf_Word ret; 247 self = NULL;
371
372 if (die_get_attr_udata(tp_die, DW_AT_encoding, &ret))
373 return false;
374
375 return (ret == DW_ATE_signed_char || ret == DW_ATE_signed ||
376 ret == DW_ATE_signed_fixed);
377}
378
379static int die_get_byte_size(Dwarf_Die *tp_die)
380{
381 Dwarf_Word ret;
382
383 if (die_get_attr_udata(tp_die, DW_AT_byte_size, &ret))
384 return 0;
385
386 return (int)ret;
387}
388
389static int die_get_bit_size(Dwarf_Die *tp_die)
390{
391 Dwarf_Word ret;
392
393 if (die_get_attr_udata(tp_die, DW_AT_bit_size, &ret))
394 return 0;
395
396 return (int)ret;
397}
398
399static int die_get_bit_offset(Dwarf_Die *tp_die)
400{
401 Dwarf_Word ret;
402
403 if (die_get_attr_udata(tp_die, DW_AT_bit_offset, &ret))
404 return 0;
405
406 return (int)ret;
407}
408
409/* Get data_member_location offset */
410static int die_get_data_member_location(Dwarf_Die *mb_die, Dwarf_Word *offs)
411{
412 Dwarf_Attribute attr;
413 Dwarf_Op *expr;
414 size_t nexpr;
415 int ret;
416
417 if (dwarf_attr(mb_die, DW_AT_data_member_location, &attr) == NULL)
418 return -ENOENT;
419
420 if (dwarf_formudata(&attr, offs) != 0) {
421 /* DW_AT_data_member_location should be DW_OP_plus_uconst */
422 ret = dwarf_getlocation(&attr, &expr, &nexpr);
423 if (ret < 0 || nexpr == 0)
424 return -ENOENT;
425
426 if (expr[0].atom != DW_OP_plus_uconst || nexpr != 1) {
427 pr_debug("Unable to get offset:Unexpected OP %x (%zd)\n",
428 expr[0].atom, nexpr);
429 return -ENOTSUP;
430 }
431 *offs = (Dwarf_Word)expr[0].number;
432 }
433 return 0;
434}
435
436/* Return values for die_find callbacks */
437enum {
438 DIE_FIND_CB_FOUND = 0, /* End of Search */
439 DIE_FIND_CB_CHILD = 1, /* Search only children */
440 DIE_FIND_CB_SIBLING = 2, /* Search only siblings */
441 DIE_FIND_CB_CONTINUE = 3, /* Search children and siblings */
442};
443
444/* Search a child die */
445static Dwarf_Die *die_find_child(Dwarf_Die *rt_die,
446 int (*callback)(Dwarf_Die *, void *),
447 void *data, Dwarf_Die *die_mem)
448{
449 Dwarf_Die child_die;
450 int ret;
451
452 ret = dwarf_child(rt_die, die_mem);
453 if (ret != 0)
454 return NULL;
455
456 do {
457 ret = callback(die_mem, data);
458 if (ret == DIE_FIND_CB_FOUND)
459 return die_mem;
460
461 if ((ret & DIE_FIND_CB_CHILD) &&
462 die_find_child(die_mem, callback, data, &child_die)) {
463 memcpy(die_mem, &child_die, sizeof(Dwarf_Die));
464 return die_mem;
465 }
466 } while ((ret & DIE_FIND_CB_SIBLING) &&
467 dwarf_siblingof(die_mem, die_mem) == 0);
468
469 return NULL;
470}
471
472struct __addr_die_search_param {
473 Dwarf_Addr addr;
474 Dwarf_Die *die_mem;
475};
476
477static int __die_search_func_cb(Dwarf_Die *fn_die, void *data)
478{
479 struct __addr_die_search_param *ad = data;
480
481 if (dwarf_tag(fn_die) == DW_TAG_subprogram &&
482 dwarf_haspc(fn_die, ad->addr)) {
483 memcpy(ad->die_mem, fn_die, sizeof(Dwarf_Die));
484 return DWARF_CB_ABORT;
485 } 248 }
486 return DWARF_CB_OK;
487}
488 249
489/* Search a real subprogram including this line, */ 250 return self;
490static Dwarf_Die *die_find_real_subprogram(Dwarf_Die *cu_die, Dwarf_Addr addr,
491 Dwarf_Die *die_mem)
492{
493 struct __addr_die_search_param ad;
494 ad.addr = addr;
495 ad.die_mem = die_mem;
496 /* dwarf_getscopes can't find subprogram. */
497 if (!dwarf_getfuncs(cu_die, __die_search_func_cb, &ad, 0))
498 return NULL;
499 else
500 return die_mem;
501} 251}
502 252
503/* die_find callback for inline function search */ 253void debuginfo__delete(struct debuginfo *self)
504static int __die_find_inline_cb(Dwarf_Die *die_mem, void *data)
505{ 254{
506 Dwarf_Addr *addr = data; 255 if (self) {
507 256 if (self->dwfl)
508 if (dwarf_tag(die_mem) == DW_TAG_inlined_subroutine && 257 dwfl_end(self->dwfl);
509 dwarf_haspc(die_mem, *addr)) 258 free(self);
510 return DIE_FIND_CB_FOUND;
511
512 return DIE_FIND_CB_CONTINUE;
513}
514
515/* Similar to dwarf_getfuncs, but returns inlined_subroutine if exists. */
516static Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
517 Dwarf_Die *die_mem)
518{
519 Dwarf_Die tmp_die;
520
521 sp_die = die_find_child(sp_die, __die_find_inline_cb, &addr, &tmp_die);
522 if (!sp_die)
523 return NULL;
524
525 /* Inlined function could be recursive. Trace it until fail */
526 while (sp_die) {
527 memcpy(die_mem, sp_die, sizeof(Dwarf_Die));
528 sp_die = die_find_child(sp_die, __die_find_inline_cb, &addr,
529 &tmp_die);
530 }
531
532 return die_mem;
533}
534
535/* Walker on lines (Note: line number will not be sorted) */
536typedef int (* line_walk_handler_t) (const char *fname, int lineno,
537 Dwarf_Addr addr, void *data);
538
539struct __line_walk_param {
540 const char *fname;
541 line_walk_handler_t handler;
542 void *data;
543 int retval;
544};
545
546static int __die_walk_funclines_cb(Dwarf_Die *in_die, void *data)
547{
548 struct __line_walk_param *lw = data;
549 Dwarf_Addr addr;
550 int lineno;
551
552 if (dwarf_tag(in_die) == DW_TAG_inlined_subroutine) {
553 lineno = die_get_call_lineno(in_die);
554 if (lineno > 0 && dwarf_entrypc(in_die, &addr) == 0) {
555 lw->retval = lw->handler(lw->fname, lineno, addr,
556 lw->data);
557 if (lw->retval != 0)
558 return DIE_FIND_CB_FOUND;
559 }
560 } 259 }
561 return DIE_FIND_CB_SIBLING;
562}
563
564/* Walk on lines of blocks included in given DIE */
565static int __die_walk_funclines(Dwarf_Die *sp_die,
566 line_walk_handler_t handler, void *data)
567{
568 struct __line_walk_param lw = {
569 .handler = handler,
570 .data = data,
571 .retval = 0,
572 };
573 Dwarf_Die die_mem;
574 Dwarf_Addr addr;
575 int lineno;
576
577 /* Handle function declaration line */
578 lw.fname = dwarf_decl_file(sp_die);
579 if (lw.fname && dwarf_decl_line(sp_die, &lineno) == 0 &&
580 dwarf_entrypc(sp_die, &addr) == 0) {
581 lw.retval = handler(lw.fname, lineno, addr, data);
582 if (lw.retval != 0)
583 goto done;
584 }
585 die_find_child(sp_die, __die_walk_funclines_cb, &lw, &die_mem);
586done:
587 return lw.retval;
588}
589
590static int __die_walk_culines_cb(Dwarf_Die *sp_die, void *data)
591{
592 struct __line_walk_param *lw = data;
593
594 lw->retval = __die_walk_funclines(sp_die, lw->handler, lw->data);
595 if (lw->retval != 0)
596 return DWARF_CB_ABORT;
597
598 return DWARF_CB_OK;
599}
600
601/*
602 * Walk on lines inside given PDIE. If the PDIE is subprogram, walk only on
603 * the lines inside the subprogram, otherwise PDIE must be a CU DIE.
604 */
605static int die_walk_lines(Dwarf_Die *pdie, line_walk_handler_t handler,
606 void *data)
607{
608 Dwarf_Lines *lines;
609 Dwarf_Line *line;
610 Dwarf_Addr addr;
611 const char *fname;
612 int lineno, ret = 0;
613 Dwarf_Die die_mem, *cu_die;
614 size_t nlines, i;
615
616 /* Get the CU die */
617 if (dwarf_tag(pdie) == DW_TAG_subprogram)
618 cu_die = dwarf_diecu(pdie, &die_mem, NULL, NULL);
619 else
620 cu_die = pdie;
621 if (!cu_die) {
622 pr_debug2("Failed to get CU from subprogram\n");
623 return -EINVAL;
624 }
625
626 /* Get lines list in the CU */
627 if (dwarf_getsrclines(cu_die, &lines, &nlines) != 0) {
628 pr_debug2("Failed to get source lines on this CU.\n");
629 return -ENOENT;
630 }
631 pr_debug2("Get %zd lines from this CU\n", nlines);
632
633 /* Walk on the lines on lines list */
634 for (i = 0; i < nlines; i++) {
635 line = dwarf_onesrcline(lines, i);
636 if (line == NULL ||
637 dwarf_lineno(line, &lineno) != 0 ||
638 dwarf_lineaddr(line, &addr) != 0) {
639 pr_debug2("Failed to get line info. "
640 "Possible error in debuginfo.\n");
641 continue;
642 }
643 /* Filter lines based on address */
644 if (pdie != cu_die)
645 /*
646 * Address filtering
647 * The line is included in given function, and
648 * no inline block includes it.
649 */
650 if (!dwarf_haspc(pdie, addr) ||
651 die_find_inlinefunc(pdie, addr, &die_mem))
652 continue;
653 /* Get source line */
654 fname = dwarf_linesrc(line, NULL, NULL);
655
656 ret = handler(fname, lineno, addr, data);
657 if (ret != 0)
658 return ret;
659 }
660
661 /*
662 * Dwarf lines doesn't include function declarations and inlined
663 * subroutines. We have to check functions list or given function.
664 */
665 if (pdie != cu_die)
666 ret = __die_walk_funclines(pdie, handler, data);
667 else {
668 struct __line_walk_param param = {
669 .handler = handler,
670 .data = data,
671 .retval = 0,
672 };
673 dwarf_getfuncs(cu_die, __die_walk_culines_cb, &param, 0);
674 ret = param.retval;
675 }
676
677 return ret;
678}
679
680struct __find_variable_param {
681 const char *name;
682 Dwarf_Addr addr;
683};
684
685static int __die_find_variable_cb(Dwarf_Die *die_mem, void *data)
686{
687 struct __find_variable_param *fvp = data;
688 int tag;
689
690 tag = dwarf_tag(die_mem);
691 if ((tag == DW_TAG_formal_parameter ||
692 tag == DW_TAG_variable) &&
693 die_compare_name(die_mem, fvp->name))
694 return DIE_FIND_CB_FOUND;
695
696 if (dwarf_haspc(die_mem, fvp->addr))
697 return DIE_FIND_CB_CONTINUE;
698 else
699 return DIE_FIND_CB_SIBLING;
700}
701
702/* Find a variable called 'name' at given address */
703static Dwarf_Die *die_find_variable_at(Dwarf_Die *sp_die, const char *name,
704 Dwarf_Addr addr, Dwarf_Die *die_mem)
705{
706 struct __find_variable_param fvp = { .name = name, .addr = addr};
707
708 return die_find_child(sp_die, __die_find_variable_cb, (void *)&fvp,
709 die_mem);
710}
711
712static int __die_find_member_cb(Dwarf_Die *die_mem, void *data)
713{
714 const char *name = data;
715
716 if ((dwarf_tag(die_mem) == DW_TAG_member) &&
717 die_compare_name(die_mem, name))
718 return DIE_FIND_CB_FOUND;
719
720 return DIE_FIND_CB_SIBLING;
721}
722
723/* Find a member called 'name' */
724static Dwarf_Die *die_find_member(Dwarf_Die *st_die, const char *name,
725 Dwarf_Die *die_mem)
726{
727 return die_find_child(st_die, __die_find_member_cb, (void *)name,
728 die_mem);
729}
730
731/* Get the name of given variable DIE */
732static int die_get_typename(Dwarf_Die *vr_die, char *buf, int len)
733{
734 Dwarf_Die type;
735 int tag, ret, ret2;
736 const char *tmp = "";
737
738 if (__die_get_real_type(vr_die, &type) == NULL)
739 return -ENOENT;
740
741 tag = dwarf_tag(&type);
742 if (tag == DW_TAG_array_type || tag == DW_TAG_pointer_type)
743 tmp = "*";
744 else if (tag == DW_TAG_subroutine_type) {
745 /* Function pointer */
746 ret = snprintf(buf, len, "(function_type)");
747 return (ret >= len) ? -E2BIG : ret;
748 } else {
749 if (!dwarf_diename(&type))
750 return -ENOENT;
751 if (tag == DW_TAG_union_type)
752 tmp = "union ";
753 else if (tag == DW_TAG_structure_type)
754 tmp = "struct ";
755 /* Write a base name */
756 ret = snprintf(buf, len, "%s%s", tmp, dwarf_diename(&type));
757 return (ret >= len) ? -E2BIG : ret;
758 }
759 ret = die_get_typename(&type, buf, len);
760 if (ret > 0) {
761 ret2 = snprintf(buf + ret, len - ret, "%s", tmp);
762 ret = (ret2 >= len - ret) ? -E2BIG : ret2 + ret;
763 }
764 return ret;
765}
766
767/* Get the name and type of given variable DIE, stored as "type\tname" */
768static int die_get_varname(Dwarf_Die *vr_die, char *buf, int len)
769{
770 int ret, ret2;
771
772 ret = die_get_typename(vr_die, buf, len);
773 if (ret < 0) {
774 pr_debug("Failed to get type, make it unknown.\n");
775 ret = snprintf(buf, len, "(unknown_type)");
776 }
777 if (ret > 0) {
778 ret2 = snprintf(buf + ret, len - ret, "\t%s",
779 dwarf_diename(vr_die));
780 ret = (ret2 >= len - ret) ? -E2BIG : ret2 + ret;
781 }
782 return ret;
783} 260}
784 261
785/* 262/*
@@ -897,6 +374,7 @@ static int convert_variable_type(Dwarf_Die *vr_die,
897 struct probe_trace_arg_ref **ref_ptr = &tvar->ref; 374 struct probe_trace_arg_ref **ref_ptr = &tvar->ref;
898 Dwarf_Die type; 375 Dwarf_Die type;
899 char buf[16]; 376 char buf[16];
377 int bsize, boffs, total;
900 int ret; 378 int ret;
901 379
902 /* TODO: check all types */ 380 /* TODO: check all types */
@@ -906,11 +384,15 @@ static int convert_variable_type(Dwarf_Die *vr_die,
906 return (tvar->type == NULL) ? -ENOMEM : 0; 384 return (tvar->type == NULL) ? -ENOMEM : 0;
907 } 385 }
908 386
909 if (die_get_bit_size(vr_die) != 0) { 387 bsize = dwarf_bitsize(vr_die);
388 if (bsize > 0) {
910 /* This is a bitfield */ 389 /* This is a bitfield */
911 ret = snprintf(buf, 16, "b%d@%d/%zd", die_get_bit_size(vr_die), 390 boffs = dwarf_bitoffset(vr_die);
912 die_get_bit_offset(vr_die), 391 total = dwarf_bytesize(vr_die);
913 BYTES_TO_BITS(die_get_byte_size(vr_die))); 392 if (boffs < 0 || total < 0)
393 return -ENOENT;
394 ret = snprintf(buf, 16, "b%d@%d/%zd", bsize, boffs,
395 BYTES_TO_BITS(total));
914 goto formatted; 396 goto formatted;
915 } 397 }
916 398
@@ -958,10 +440,11 @@ static int convert_variable_type(Dwarf_Die *vr_die,
958 return (tvar->type == NULL) ? -ENOMEM : 0; 440 return (tvar->type == NULL) ? -ENOMEM : 0;
959 } 441 }
960 442
961 ret = BYTES_TO_BITS(die_get_byte_size(&type)); 443 ret = dwarf_bytesize(&type);
962 if (!ret) 444 if (ret <= 0)
963 /* No size ... try to use default type */ 445 /* No size ... try to use default type */
964 return 0; 446 return 0;
447 ret = BYTES_TO_BITS(ret);
965 448
966 /* Check the bitwidth */ 449 /* Check the bitwidth */
967 if (ret > MAX_BASIC_TYPE_BITS) { 450 if (ret > MAX_BASIC_TYPE_BITS) {
@@ -1025,7 +508,7 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
1025 else 508 else
1026 *ref_ptr = ref; 509 *ref_ptr = ref;
1027 } 510 }
1028 ref->offset += die_get_byte_size(&type) * field->index; 511 ref->offset += dwarf_bytesize(&type) * field->index;
1029 if (!field->next) 512 if (!field->next)
1030 /* Save vr_die for converting types */ 513 /* Save vr_die for converting types */
1031 memcpy(die_mem, vr_die, sizeof(*die_mem)); 514 memcpy(die_mem, vr_die, sizeof(*die_mem));
@@ -1129,12 +612,12 @@ static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
1129 return ret; 612 return ret;
1130} 613}
1131 614
1132/* Find a variable in a subprogram die */ 615/* Find a variable in a scope DIE */
1133static int find_variable(Dwarf_Die *sp_die, struct probe_finder *pf) 616static int find_variable(Dwarf_Die *sc_die, struct probe_finder *pf)
1134{ 617{
1135 Dwarf_Die vr_die, *scopes; 618 Dwarf_Die vr_die;
1136 char buf[32], *ptr; 619 char buf[32], *ptr;
1137 int ret, nscopes; 620 int ret = 0;
1138 621
1139 if (!is_c_varname(pf->pvar->var)) { 622 if (!is_c_varname(pf->pvar->var)) {
1140 /* Copy raw parameters */ 623 /* Copy raw parameters */
@@ -1169,30 +652,16 @@ static int find_variable(Dwarf_Die *sp_die, struct probe_finder *pf)
1169 if (pf->tvar->name == NULL) 652 if (pf->tvar->name == NULL)
1170 return -ENOMEM; 653 return -ENOMEM;
1171 654
1172 pr_debug("Searching '%s' variable in context.\n", 655 pr_debug("Searching '%s' variable in context.\n", pf->pvar->var);
1173 pf->pvar->var);
1174 /* Search child die for local variables and parameters. */ 656 /* Search child die for local variables and parameters. */
1175 if (die_find_variable_at(sp_die, pf->pvar->var, pf->addr, &vr_die)) 657 if (!die_find_variable_at(sc_die, pf->pvar->var, pf->addr, &vr_die)) {
1176 ret = convert_variable(&vr_die, pf); 658 /* Search again in global variables */
1177 else { 659 if (!die_find_variable_at(&pf->cu_die, pf->pvar->var, 0, &vr_die))
1178 /* Search upper class */ 660 ret = -ENOENT;
1179 nscopes = dwarf_getscopes_die(sp_die, &scopes);
1180 while (nscopes-- > 1) {
1181 pr_debug("Searching variables in %s\n",
1182 dwarf_diename(&scopes[nscopes]));
1183 /* We should check this scope, so give dummy address */
1184 if (die_find_variable_at(&scopes[nscopes],
1185 pf->pvar->var, 0,
1186 &vr_die)) {
1187 ret = convert_variable(&vr_die, pf);
1188 goto found;
1189 }
1190 }
1191 if (scopes)
1192 free(scopes);
1193 ret = -ENOENT;
1194 } 661 }
1195found: 662 if (ret >= 0)
663 ret = convert_variable(&vr_die, pf);
664
1196 if (ret < 0) 665 if (ret < 0)
1197 pr_warning("Failed to find '%s' in this function.\n", 666 pr_warning("Failed to find '%s' in this function.\n",
1198 pf->pvar->var); 667 pf->pvar->var);
@@ -1235,27 +704,30 @@ static int convert_to_trace_point(Dwarf_Die *sp_die, Dwarf_Addr paddr,
1235 return 0; 704 return 0;
1236} 705}
1237 706
1238/* Call probe_finder callback with real subprogram DIE */ 707/* Call probe_finder callback with scope DIE */
1239static int call_probe_finder(Dwarf_Die *sp_die, struct probe_finder *pf) 708static int call_probe_finder(Dwarf_Die *sc_die, struct probe_finder *pf)
1240{ 709{
1241 Dwarf_Die die_mem;
1242 Dwarf_Attribute fb_attr; 710 Dwarf_Attribute fb_attr;
1243 size_t nops; 711 size_t nops;
1244 int ret; 712 int ret;
1245 713
1246 /* If no real subprogram, find a real one */ 714 if (!sc_die) {
1247 if (!sp_die || dwarf_tag(sp_die) != DW_TAG_subprogram) { 715 pr_err("Caller must pass a scope DIE. Program error.\n");
1248 sp_die = die_find_real_subprogram(&pf->cu_die, 716 return -EINVAL;
1249 pf->addr, &die_mem); 717 }
1250 if (!sp_die) { 718
719 /* If not a real subprogram, find a real one */
720 if (dwarf_tag(sc_die) != DW_TAG_subprogram) {
721 if (!die_find_realfunc(&pf->cu_die, pf->addr, &pf->sp_die)) {
1251 pr_warning("Failed to find probe point in any " 722 pr_warning("Failed to find probe point in any "
1252 "functions.\n"); 723 "functions.\n");
1253 return -ENOENT; 724 return -ENOENT;
1254 } 725 }
1255 } 726 } else
727 memcpy(&pf->sp_die, sc_die, sizeof(Dwarf_Die));
1256 728
1257 /* Get the frame base attribute/ops */ 729 /* Get the frame base attribute/ops from subprogram */
1258 dwarf_attr(sp_die, DW_AT_frame_base, &fb_attr); 730 dwarf_attr(&pf->sp_die, DW_AT_frame_base, &fb_attr);
1259 ret = dwarf_getlocation_addr(&fb_attr, pf->addr, &pf->fb_ops, &nops, 1); 731 ret = dwarf_getlocation_addr(&fb_attr, pf->addr, &pf->fb_ops, &nops, 1);
1260 if (ret <= 0 || nops == 0) { 732 if (ret <= 0 || nops == 0) {
1261 pf->fb_ops = NULL; 733 pf->fb_ops = NULL;
@@ -1273,7 +745,7 @@ static int call_probe_finder(Dwarf_Die *sp_die, struct probe_finder *pf)
1273 } 745 }
1274 746
1275 /* Call finder's callback handler */ 747 /* Call finder's callback handler */
1276 ret = pf->callback(sp_die, pf); 748 ret = pf->callback(sc_die, pf);
1277 749
1278 /* *pf->fb_ops will be cached in libdw. Don't free it. */ 750 /* *pf->fb_ops will be cached in libdw. Don't free it. */
1279 pf->fb_ops = NULL; 751 pf->fb_ops = NULL;
@@ -1281,17 +753,82 @@ static int call_probe_finder(Dwarf_Die *sp_die, struct probe_finder *pf)
1281 return ret; 753 return ret;
1282} 754}
1283 755
756struct find_scope_param {
757 const char *function;
758 const char *file;
759 int line;
760 int diff;
761 Dwarf_Die *die_mem;
762 bool found;
763};
764
765static int find_best_scope_cb(Dwarf_Die *fn_die, void *data)
766{
767 struct find_scope_param *fsp = data;
768 const char *file;
769 int lno;
770
771 /* Skip if declared file name does not match */
772 if (fsp->file) {
773 file = dwarf_decl_file(fn_die);
774 if (!file || strcmp(fsp->file, file) != 0)
775 return 0;
776 }
777 /* If the function name is given, that's what user expects */
778 if (fsp->function) {
779 if (die_compare_name(fn_die, fsp->function)) {
780 memcpy(fsp->die_mem, fn_die, sizeof(Dwarf_Die));
781 fsp->found = true;
782 return 1;
783 }
784 } else {
785 /* With the line number, find the nearest declared DIE */
786 dwarf_decl_line(fn_die, &lno);
787 if (lno < fsp->line && fsp->diff > fsp->line - lno) {
788 /* Keep a candidate and continue */
789 fsp->diff = fsp->line - lno;
790 memcpy(fsp->die_mem, fn_die, sizeof(Dwarf_Die));
791 fsp->found = true;
792 }
793 }
794 return 0;
795}
796
797/* Find an appropriate scope fits to given conditions */
798static Dwarf_Die *find_best_scope(struct probe_finder *pf, Dwarf_Die *die_mem)
799{
800 struct find_scope_param fsp = {
801 .function = pf->pev->point.function,
802 .file = pf->fname,
803 .line = pf->lno,
804 .diff = INT_MAX,
805 .die_mem = die_mem,
806 .found = false,
807 };
808
809 cu_walk_functions_at(&pf->cu_die, pf->addr, find_best_scope_cb, &fsp);
810
811 return fsp.found ? die_mem : NULL;
812}
813
1284static int probe_point_line_walker(const char *fname, int lineno, 814static int probe_point_line_walker(const char *fname, int lineno,
1285 Dwarf_Addr addr, void *data) 815 Dwarf_Addr addr, void *data)
1286{ 816{
1287 struct probe_finder *pf = data; 817 struct probe_finder *pf = data;
818 Dwarf_Die *sc_die, die_mem;
1288 int ret; 819 int ret;
1289 820
1290 if (lineno != pf->lno || strtailcmp(fname, pf->fname) != 0) 821 if (lineno != pf->lno || strtailcmp(fname, pf->fname) != 0)
1291 return 0; 822 return 0;
1292 823
1293 pf->addr = addr; 824 pf->addr = addr;
1294 ret = call_probe_finder(NULL, pf); 825 sc_die = find_best_scope(pf, &die_mem);
826 if (!sc_die) {
827 pr_warning("Failed to find scope of probe point.\n");
828 return -ENOENT;
829 }
830
831 ret = call_probe_finder(sc_die, pf);
1295 832
1296 /* Continue if no error, because the line will be in inline function */ 833 /* Continue if no error, because the line will be in inline function */
1297 return ret < 0 ? ret : 0; 834 return ret < 0 ? ret : 0;
@@ -1345,6 +882,7 @@ static int probe_point_lazy_walker(const char *fname, int lineno,
1345 Dwarf_Addr addr, void *data) 882 Dwarf_Addr addr, void *data)
1346{ 883{
1347 struct probe_finder *pf = data; 884 struct probe_finder *pf = data;
885 Dwarf_Die *sc_die, die_mem;
1348 int ret; 886 int ret;
1349 887
1350 if (!line_list__has_line(&pf->lcache, lineno) || 888 if (!line_list__has_line(&pf->lcache, lineno) ||
@@ -1354,7 +892,14 @@ static int probe_point_lazy_walker(const char *fname, int lineno,
1354 pr_debug("Probe line found: line:%d addr:0x%llx\n", 892 pr_debug("Probe line found: line:%d addr:0x%llx\n",
1355 lineno, (unsigned long long)addr); 893 lineno, (unsigned long long)addr);
1356 pf->addr = addr; 894 pf->addr = addr;
1357 ret = call_probe_finder(NULL, pf); 895 pf->lno = lineno;
896 sc_die = find_best_scope(pf, &die_mem);
897 if (!sc_die) {
898 pr_warning("Failed to find scope of probe point.\n");
899 return -ENOENT;
900 }
901
902 ret = call_probe_finder(sc_die, pf);
1358 903
1359 /* 904 /*
1360 * Continue if no error, because the lazy pattern will match 905 * Continue if no error, because the lazy pattern will match
@@ -1379,42 +924,39 @@ static int find_probe_point_lazy(Dwarf_Die *sp_die, struct probe_finder *pf)
1379 return die_walk_lines(sp_die, probe_point_lazy_walker, pf); 924 return die_walk_lines(sp_die, probe_point_lazy_walker, pf);
1380} 925}
1381 926
1382/* Callback parameter with return value */
1383struct dwarf_callback_param {
1384 void *data;
1385 int retval;
1386};
1387
1388static int probe_point_inline_cb(Dwarf_Die *in_die, void *data) 927static int probe_point_inline_cb(Dwarf_Die *in_die, void *data)
1389{ 928{
1390 struct dwarf_callback_param *param = data; 929 struct probe_finder *pf = data;
1391 struct probe_finder *pf = param->data;
1392 struct perf_probe_point *pp = &pf->pev->point; 930 struct perf_probe_point *pp = &pf->pev->point;
1393 Dwarf_Addr addr; 931 Dwarf_Addr addr;
932 int ret;
1394 933
1395 if (pp->lazy_line) 934 if (pp->lazy_line)
1396 param->retval = find_probe_point_lazy(in_die, pf); 935 ret = find_probe_point_lazy(in_die, pf);
1397 else { 936 else {
1398 /* Get probe address */ 937 /* Get probe address */
1399 if (dwarf_entrypc(in_die, &addr) != 0) { 938 if (dwarf_entrypc(in_die, &addr) != 0) {
1400 pr_warning("Failed to get entry address of %s.\n", 939 pr_warning("Failed to get entry address of %s.\n",
1401 dwarf_diename(in_die)); 940 dwarf_diename(in_die));
1402 param->retval = -ENOENT; 941 return -ENOENT;
1403 return DWARF_CB_ABORT;
1404 } 942 }
1405 pf->addr = addr; 943 pf->addr = addr;
1406 pf->addr += pp->offset; 944 pf->addr += pp->offset;
1407 pr_debug("found inline addr: 0x%jx\n", 945 pr_debug("found inline addr: 0x%jx\n",
1408 (uintmax_t)pf->addr); 946 (uintmax_t)pf->addr);
1409 947
1410 param->retval = call_probe_finder(in_die, pf); 948 ret = call_probe_finder(in_die, pf);
1411 if (param->retval < 0)
1412 return DWARF_CB_ABORT;
1413 } 949 }
1414 950
1415 return DWARF_CB_OK; 951 return ret;
1416} 952}
1417 953
954/* Callback parameter with return value for libdw */
955struct dwarf_callback_param {
956 void *data;
957 int retval;
958};
959
1418/* Search function from function name */ 960/* Search function from function name */
1419static int probe_point_search_cb(Dwarf_Die *sp_die, void *data) 961static int probe_point_search_cb(Dwarf_Die *sp_die, void *data)
1420{ 962{
@@ -1451,14 +993,10 @@ static int probe_point_search_cb(Dwarf_Die *sp_die, void *data)
1451 /* TODO: Check the address in this function */ 993 /* TODO: Check the address in this function */
1452 param->retval = call_probe_finder(sp_die, pf); 994 param->retval = call_probe_finder(sp_die, pf);
1453 } 995 }
1454 } else { 996 } else
1455 struct dwarf_callback_param _param = {.data = (void *)pf,
1456 .retval = 0};
1457 /* Inlined function: search instances */ 997 /* Inlined function: search instances */
1458 dwarf_func_inline_instances(sp_die, probe_point_inline_cb, 998 param->retval = die_walk_instances(sp_die,
1459 &_param); 999 probe_point_inline_cb, (void *)pf);
1460 param->retval = _param.retval;
1461 }
1462 1000
1463 return DWARF_CB_ABORT; /* Exit; no same symbol in this CU. */ 1001 return DWARF_CB_ABORT; /* Exit; no same symbol in this CU. */
1464} 1002}
@@ -1504,28 +1042,18 @@ static int pubname_search_cb(Dwarf *dbg, Dwarf_Global *gl, void *data)
1504} 1042}
1505 1043
1506/* Find probe points from debuginfo */ 1044/* Find probe points from debuginfo */
1507static int find_probes(int fd, struct probe_finder *pf) 1045static int debuginfo__find_probes(struct debuginfo *self,
1046 struct probe_finder *pf)
1508{ 1047{
1509 struct perf_probe_point *pp = &pf->pev->point; 1048 struct perf_probe_point *pp = &pf->pev->point;
1510 Dwarf_Off off, noff; 1049 Dwarf_Off off, noff;
1511 size_t cuhl; 1050 size_t cuhl;
1512 Dwarf_Die *diep; 1051 Dwarf_Die *diep;
1513 Dwarf *dbg = NULL;
1514 Dwfl *dwfl;
1515 Dwarf_Addr bias; /* Currently ignored */
1516 int ret = 0; 1052 int ret = 0;
1517 1053
1518 dbg = dwfl_init_offline_dwarf(fd, &dwfl, &bias);
1519 if (!dbg) {
1520 pr_warning("No debug information found in the vmlinux - "
1521 "please rebuild with CONFIG_DEBUG_INFO=y.\n");
1522 close(fd); /* Without dwfl_end(), fd isn't closed. */
1523 return -EBADF;
1524 }
1525
1526#if _ELFUTILS_PREREQ(0, 142) 1054#if _ELFUTILS_PREREQ(0, 142)
1527 /* Get the call frame information from this dwarf */ 1055 /* Get the call frame information from this dwarf */
1528 pf->cfi = dwarf_getcfi(dbg); 1056 pf->cfi = dwarf_getcfi(self->dbg);
1529#endif 1057#endif
1530 1058
1531 off = 0; 1059 off = 0;
@@ -1544,7 +1072,8 @@ static int find_probes(int fd, struct probe_finder *pf)
1544 .data = pf, 1072 .data = pf,
1545 }; 1073 };
1546 1074
1547 dwarf_getpubnames(dbg, pubname_search_cb, &pubname_param, 0); 1075 dwarf_getpubnames(self->dbg, pubname_search_cb,
1076 &pubname_param, 0);
1548 if (pubname_param.found) { 1077 if (pubname_param.found) {
1549 ret = probe_point_search_cb(&pf->sp_die, &probe_param); 1078 ret = probe_point_search_cb(&pf->sp_die, &probe_param);
1550 if (ret) 1079 if (ret)
@@ -1553,9 +1082,9 @@ static int find_probes(int fd, struct probe_finder *pf)
1553 } 1082 }
1554 1083
1555 /* Loop on CUs (Compilation Unit) */ 1084 /* Loop on CUs (Compilation Unit) */
1556 while (!dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL)) { 1085 while (!dwarf_nextcu(self->dbg, off, &noff, &cuhl, NULL, NULL, NULL)) {
1557 /* Get the DIE(Debugging Information Entry) of this CU */ 1086 /* Get the DIE(Debugging Information Entry) of this CU */
1558 diep = dwarf_offdie(dbg, off + cuhl, &pf->cu_die); 1087 diep = dwarf_offdie(self->dbg, off + cuhl, &pf->cu_die);
1559 if (!diep) 1088 if (!diep)
1560 continue; 1089 continue;
1561 1090
@@ -1582,14 +1111,12 @@ static int find_probes(int fd, struct probe_finder *pf)
1582 1111
1583found: 1112found:
1584 line_list__free(&pf->lcache); 1113 line_list__free(&pf->lcache);
1585 if (dwfl)
1586 dwfl_end(dwfl);
1587 1114
1588 return ret; 1115 return ret;
1589} 1116}
1590 1117
1591/* Add a found probe point into trace event list */ 1118/* Add a found probe point into trace event list */
1592static int add_probe_trace_event(Dwarf_Die *sp_die, struct probe_finder *pf) 1119static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)
1593{ 1120{
1594 struct trace_event_finder *tf = 1121 struct trace_event_finder *tf =
1595 container_of(pf, struct trace_event_finder, pf); 1122 container_of(pf, struct trace_event_finder, pf);
@@ -1604,8 +1131,9 @@ static int add_probe_trace_event(Dwarf_Die *sp_die, struct probe_finder *pf)
1604 } 1131 }
1605 tev = &tf->tevs[tf->ntevs++]; 1132 tev = &tf->tevs[tf->ntevs++];
1606 1133
1607 ret = convert_to_trace_point(sp_die, pf->addr, pf->pev->point.retprobe, 1134 /* Trace point should be converted from subprogram DIE */
1608 &tev->point); 1135 ret = convert_to_trace_point(&pf->sp_die, pf->addr,
1136 pf->pev->point.retprobe, &tev->point);
1609 if (ret < 0) 1137 if (ret < 0)
1610 return ret; 1138 return ret;
1611 1139
@@ -1620,7 +1148,8 @@ static int add_probe_trace_event(Dwarf_Die *sp_die, struct probe_finder *pf)
1620 for (i = 0; i < pf->pev->nargs; i++) { 1148 for (i = 0; i < pf->pev->nargs; i++) {
1621 pf->pvar = &pf->pev->args[i]; 1149 pf->pvar = &pf->pev->args[i];
1622 pf->tvar = &tev->args[i]; 1150 pf->tvar = &tev->args[i];
1623 ret = find_variable(sp_die, pf); 1151 /* Variable should be found from scope DIE */
1152 ret = find_variable(sc_die, pf);
1624 if (ret != 0) 1153 if (ret != 0)
1625 return ret; 1154 return ret;
1626 } 1155 }
@@ -1629,8 +1158,9 @@ static int add_probe_trace_event(Dwarf_Die *sp_die, struct probe_finder *pf)
1629} 1158}
1630 1159
1631/* Find probe_trace_events specified by perf_probe_event from debuginfo */ 1160/* Find probe_trace_events specified by perf_probe_event from debuginfo */
1632int find_probe_trace_events(int fd, struct perf_probe_event *pev, 1161int debuginfo__find_trace_events(struct debuginfo *self,
1633 struct probe_trace_event **tevs, int max_tevs) 1162 struct perf_probe_event *pev,
1163 struct probe_trace_event **tevs, int max_tevs)
1634{ 1164{
1635 struct trace_event_finder tf = { 1165 struct trace_event_finder tf = {
1636 .pf = {.pev = pev, .callback = add_probe_trace_event}, 1166 .pf = {.pev = pev, .callback = add_probe_trace_event},
@@ -1645,7 +1175,7 @@ int find_probe_trace_events(int fd, struct perf_probe_event *pev,
1645 tf.tevs = *tevs; 1175 tf.tevs = *tevs;
1646 tf.ntevs = 0; 1176 tf.ntevs = 0;
1647 1177
1648 ret = find_probes(fd, &tf.pf); 1178 ret = debuginfo__find_probes(self, &tf.pf);
1649 if (ret < 0) { 1179 if (ret < 0) {
1650 free(*tevs); 1180 free(*tevs);
1651 *tevs = NULL; 1181 *tevs = NULL;
@@ -1687,13 +1217,13 @@ static int collect_variables_cb(Dwarf_Die *die_mem, void *data)
1687} 1217}
1688 1218
1689/* Add a found vars into available variables list */ 1219/* Add a found vars into available variables list */
1690static int add_available_vars(Dwarf_Die *sp_die, struct probe_finder *pf) 1220static int add_available_vars(Dwarf_Die *sc_die, struct probe_finder *pf)
1691{ 1221{
1692 struct available_var_finder *af = 1222 struct available_var_finder *af =
1693 container_of(pf, struct available_var_finder, pf); 1223 container_of(pf, struct available_var_finder, pf);
1694 struct variable_list *vl; 1224 struct variable_list *vl;
1695 Dwarf_Die die_mem, *scopes = NULL; 1225 Dwarf_Die die_mem;
1696 int ret, nscopes; 1226 int ret;
1697 1227
1698 /* Check number of tevs */ 1228 /* Check number of tevs */
1699 if (af->nvls == af->max_vls) { 1229 if (af->nvls == af->max_vls) {
@@ -1702,8 +1232,9 @@ static int add_available_vars(Dwarf_Die *sp_die, struct probe_finder *pf)
1702 } 1232 }
1703 vl = &af->vls[af->nvls++]; 1233 vl = &af->vls[af->nvls++];
1704 1234
1705 ret = convert_to_trace_point(sp_die, pf->addr, pf->pev->point.retprobe, 1235 /* Trace point should be converted from subprogram DIE */
1706 &vl->point); 1236 ret = convert_to_trace_point(&pf->sp_die, pf->addr,
1237 pf->pev->point.retprobe, &vl->point);
1707 if (ret < 0) 1238 if (ret < 0)
1708 return ret; 1239 return ret;
1709 1240
@@ -1715,19 +1246,14 @@ static int add_available_vars(Dwarf_Die *sp_die, struct probe_finder *pf)
1715 if (vl->vars == NULL) 1246 if (vl->vars == NULL)
1716 return -ENOMEM; 1247 return -ENOMEM;
1717 af->child = true; 1248 af->child = true;
1718 die_find_child(sp_die, collect_variables_cb, (void *)af, &die_mem); 1249 die_find_child(sc_die, collect_variables_cb, (void *)af, &die_mem);
1719 1250
1720 /* Find external variables */ 1251 /* Find external variables */
1721 if (!af->externs) 1252 if (!af->externs)
1722 goto out; 1253 goto out;
1723 /* Don't need to search child DIE for externs. */ 1254 /* Don't need to search child DIE for externs. */
1724 af->child = false; 1255 af->child = false;
1725 nscopes = dwarf_getscopes_die(sp_die, &scopes); 1256 die_find_child(&pf->cu_die, collect_variables_cb, (void *)af, &die_mem);
1726 while (nscopes-- > 1)
1727 die_find_child(&scopes[nscopes], collect_variables_cb,
1728 (void *)af, &die_mem);
1729 if (scopes)
1730 free(scopes);
1731 1257
1732out: 1258out:
1733 if (strlist__empty(vl->vars)) { 1259 if (strlist__empty(vl->vars)) {
@@ -1739,9 +1265,10 @@ out:
1739} 1265}
1740 1266
1741/* Find available variables at given probe point */ 1267/* Find available variables at given probe point */
1742int find_available_vars_at(int fd, struct perf_probe_event *pev, 1268int debuginfo__find_available_vars_at(struct debuginfo *self,
1743 struct variable_list **vls, int max_vls, 1269 struct perf_probe_event *pev,
1744 bool externs) 1270 struct variable_list **vls,
1271 int max_vls, bool externs)
1745{ 1272{
1746 struct available_var_finder af = { 1273 struct available_var_finder af = {
1747 .pf = {.pev = pev, .callback = add_available_vars}, 1274 .pf = {.pev = pev, .callback = add_available_vars},
@@ -1756,7 +1283,7 @@ int find_available_vars_at(int fd, struct perf_probe_event *pev,
1756 af.vls = *vls; 1283 af.vls = *vls;
1757 af.nvls = 0; 1284 af.nvls = 0;
1758 1285
1759 ret = find_probes(fd, &af.pf); 1286 ret = debuginfo__find_probes(self, &af.pf);
1760 if (ret < 0) { 1287 if (ret < 0) {
1761 /* Free vlist for error */ 1288 /* Free vlist for error */
1762 while (af.nvls--) { 1289 while (af.nvls--) {
@@ -1774,28 +1301,19 @@ int find_available_vars_at(int fd, struct perf_probe_event *pev,
1774} 1301}
1775 1302
1776/* Reverse search */ 1303/* Reverse search */
1777int find_perf_probe_point(unsigned long addr, struct perf_probe_point *ppt) 1304int debuginfo__find_probe_point(struct debuginfo *self, unsigned long addr,
1305 struct perf_probe_point *ppt)
1778{ 1306{
1779 Dwarf_Die cudie, spdie, indie; 1307 Dwarf_Die cudie, spdie, indie;
1780 Dwarf *dbg = NULL; 1308 Dwarf_Addr _addr, baseaddr;
1781 Dwfl *dwfl = NULL;
1782 Dwarf_Addr _addr, baseaddr, bias = 0;
1783 const char *fname = NULL, *func = NULL, *tmp; 1309 const char *fname = NULL, *func = NULL, *tmp;
1784 int baseline = 0, lineno = 0, ret = 0; 1310 int baseline = 0, lineno = 0, ret = 0;
1785 1311
1786 /* Open the live linux kernel */
1787 dbg = dwfl_init_live_kernel_dwarf(addr, &dwfl, &bias);
1788 if (!dbg) {
1789 pr_warning("No debug information found in the vmlinux - "
1790 "please rebuild with CONFIG_DEBUG_INFO=y.\n");
1791 ret = -EINVAL;
1792 goto end;
1793 }
1794
1795 /* Adjust address with bias */ 1312 /* Adjust address with bias */
1796 addr += bias; 1313 addr += self->bias;
1314
1797 /* Find cu die */ 1315 /* Find cu die */
1798 if (!dwarf_addrdie(dbg, (Dwarf_Addr)addr - bias, &cudie)) { 1316 if (!dwarf_addrdie(self->dbg, (Dwarf_Addr)addr - self->bias, &cudie)) {
1799 pr_warning("Failed to find debug information for address %lx\n", 1317 pr_warning("Failed to find debug information for address %lx\n",
1800 addr); 1318 addr);
1801 ret = -EINVAL; 1319 ret = -EINVAL;
@@ -1807,7 +1325,7 @@ int find_perf_probe_point(unsigned long addr, struct perf_probe_point *ppt)
1807 /* Don't care whether it failed or not */ 1325 /* Don't care whether it failed or not */
1808 1326
1809 /* Find a corresponding function (name, baseline and baseaddr) */ 1327 /* Find a corresponding function (name, baseline and baseaddr) */
1810 if (die_find_real_subprogram(&cudie, (Dwarf_Addr)addr, &spdie)) { 1328 if (die_find_realfunc(&cudie, (Dwarf_Addr)addr, &spdie)) {
1811 /* Get function entry information */ 1329 /* Get function entry information */
1812 tmp = dwarf_diename(&spdie); 1330 tmp = dwarf_diename(&spdie);
1813 if (!tmp || 1331 if (!tmp ||
@@ -1871,8 +1389,6 @@ post:
1871 } 1389 }
1872 } 1390 }
1873end: 1391end:
1874 if (dwfl)
1875 dwfl_end(dwfl);
1876 if (ret == 0 && (fname || func)) 1392 if (ret == 0 && (fname || func))
1877 ret = 1; /* Found a point */ 1393 ret = 1; /* Found a point */
1878 return ret; 1394 return ret;
@@ -1929,10 +1445,14 @@ static int find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf)
1929 1445
1930static int line_range_inline_cb(Dwarf_Die *in_die, void *data) 1446static int line_range_inline_cb(Dwarf_Die *in_die, void *data)
1931{ 1447{
1932 struct dwarf_callback_param *param = data; 1448 find_line_range_by_line(in_die, data);
1933 1449
1934 param->retval = find_line_range_by_line(in_die, param->data); 1450 /*
1935 return DWARF_CB_ABORT; /* No need to find other instances */ 1451 * We have to check all instances of inlined function, because
1452 * some execution paths can be optimized out depends on the
1453 * function argument of instances
1454 */
1455 return 0;
1936} 1456}
1937 1457
1938/* Search function from function name */ 1458/* Search function from function name */
@@ -1960,15 +1480,10 @@ static int line_range_search_cb(Dwarf_Die *sp_die, void *data)
1960 pr_debug("New line range: %d to %d\n", lf->lno_s, lf->lno_e); 1480 pr_debug("New line range: %d to %d\n", lf->lno_s, lf->lno_e);
1961 lr->start = lf->lno_s; 1481 lr->start = lf->lno_s;
1962 lr->end = lf->lno_e; 1482 lr->end = lf->lno_e;
1963 if (dwarf_func_inline(sp_die)) { 1483 if (dwarf_func_inline(sp_die))
1964 struct dwarf_callback_param _param; 1484 param->retval = die_walk_instances(sp_die,
1965 _param.data = (void *)lf; 1485 line_range_inline_cb, lf);
1966 _param.retval = 0; 1486 else
1967 dwarf_func_inline_instances(sp_die,
1968 line_range_inline_cb,
1969 &_param);
1970 param->retval = _param.retval;
1971 } else
1972 param->retval = find_line_range_by_line(sp_die, lf); 1487 param->retval = find_line_range_by_line(sp_die, lf);
1973 return DWARF_CB_ABORT; 1488 return DWARF_CB_ABORT;
1974 } 1489 }
@@ -1982,26 +1497,15 @@ static int find_line_range_by_func(struct line_finder *lf)
1982 return param.retval; 1497 return param.retval;
1983} 1498}
1984 1499
1985int find_line_range(int fd, struct line_range *lr) 1500int debuginfo__find_line_range(struct debuginfo *self, struct line_range *lr)
1986{ 1501{
1987 struct line_finder lf = {.lr = lr, .found = 0}; 1502 struct line_finder lf = {.lr = lr, .found = 0};
1988 int ret = 0; 1503 int ret = 0;
1989 Dwarf_Off off = 0, noff; 1504 Dwarf_Off off = 0, noff;
1990 size_t cuhl; 1505 size_t cuhl;
1991 Dwarf_Die *diep; 1506 Dwarf_Die *diep;
1992 Dwarf *dbg = NULL;
1993 Dwfl *dwfl;
1994 Dwarf_Addr bias; /* Currently ignored */
1995 const char *comp_dir; 1507 const char *comp_dir;
1996 1508
1997 dbg = dwfl_init_offline_dwarf(fd, &dwfl, &bias);
1998 if (!dbg) {
1999 pr_warning("No debug information found in the vmlinux - "
2000 "please rebuild with CONFIG_DEBUG_INFO=y.\n");
2001 close(fd); /* Without dwfl_end(), fd isn't closed. */
2002 return -EBADF;
2003 }
2004
2005 /* Fastpath: lookup by function name from .debug_pubnames section */ 1509 /* Fastpath: lookup by function name from .debug_pubnames section */
2006 if (lr->function) { 1510 if (lr->function) {
2007 struct pubname_callback_param pubname_param = { 1511 struct pubname_callback_param pubname_param = {
@@ -2010,7 +1514,8 @@ int find_line_range(int fd, struct line_range *lr)
2010 struct dwarf_callback_param line_range_param = { 1514 struct dwarf_callback_param line_range_param = {
2011 .data = (void *)&lf, .retval = 0}; 1515 .data = (void *)&lf, .retval = 0};
2012 1516
2013 dwarf_getpubnames(dbg, pubname_search_cb, &pubname_param, 0); 1517 dwarf_getpubnames(self->dbg, pubname_search_cb,
1518 &pubname_param, 0);
2014 if (pubname_param.found) { 1519 if (pubname_param.found) {
2015 line_range_search_cb(&lf.sp_die, &line_range_param); 1520 line_range_search_cb(&lf.sp_die, &line_range_param);
2016 if (lf.found) 1521 if (lf.found)
@@ -2020,11 +1525,12 @@ int find_line_range(int fd, struct line_range *lr)
2020 1525
2021 /* Loop on CUs (Compilation Unit) */ 1526 /* Loop on CUs (Compilation Unit) */
2022 while (!lf.found && ret >= 0) { 1527 while (!lf.found && ret >= 0) {
2023 if (dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL) != 0) 1528 if (dwarf_nextcu(self->dbg, off, &noff, &cuhl,
1529 NULL, NULL, NULL) != 0)
2024 break; 1530 break;
2025 1531
2026 /* Get the DIE(Debugging Information Entry) of this CU */ 1532 /* Get the DIE(Debugging Information Entry) of this CU */
2027 diep = dwarf_offdie(dbg, off + cuhl, &lf.cu_die); 1533 diep = dwarf_offdie(self->dbg, off + cuhl, &lf.cu_die);
2028 if (!diep) 1534 if (!diep)
2029 continue; 1535 continue;
2030 1536
@@ -2058,7 +1564,6 @@ found:
2058 } 1564 }
2059 1565
2060 pr_debug("path: %s\n", lr->path); 1566 pr_debug("path: %s\n", lr->path);
2061 dwfl_end(dwfl);
2062 return (ret < 0) ? ret : lf.found; 1567 return (ret < 0) ? ret : lf.found;
2063} 1568}
2064 1569