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.c1453
1 files changed, 1030 insertions, 423 deletions
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 32b81f707ff5..3b9d0b800d5c 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -33,6 +33,7 @@
33#include <ctype.h> 33#include <ctype.h>
34#include <dwarf-regs.h> 34#include <dwarf-regs.h>
35 35
36#include <linux/bitops.h>
36#include "event.h" 37#include "event.h"
37#include "debug.h" 38#include "debug.h"
38#include "util.h" 39#include "util.h"
@@ -116,6 +117,126 @@ static void line_list__free(struct list_head *head)
116 } 117 }
117} 118}
118 119
120/* Dwarf FL wrappers */
121static char *debuginfo_path; /* Currently dummy */
122
123static const Dwfl_Callbacks offline_callbacks = {
124 .find_debuginfo = dwfl_standard_find_debuginfo,
125 .debuginfo_path = &debuginfo_path,
126
127 .section_address = dwfl_offline_section_address,
128
129 /* We use this table for core files too. */
130 .find_elf = dwfl_build_id_find_elf,
131};
132
133/* Get a Dwarf from offline image */
134static Dwarf *dwfl_init_offline_dwarf(int fd, Dwfl **dwflp, Dwarf_Addr *bias)
135{
136 Dwfl_Module *mod;
137 Dwarf *dbg = NULL;
138
139 if (!dwflp)
140 return NULL;
141
142 *dwflp = dwfl_begin(&offline_callbacks);
143 if (!*dwflp)
144 return NULL;
145
146 mod = dwfl_report_offline(*dwflp, "", "", fd);
147 if (!mod)
148 goto error;
149
150 dbg = dwfl_module_getdwarf(mod, bias);
151 if (!dbg) {
152error:
153 dwfl_end(*dwflp);
154 *dwflp = NULL;
155 }
156 return dbg;
157}
158
159#if _ELFUTILS_PREREQ(0, 148)
160/* This method is buggy if elfutils is older than 0.148 */
161static int __linux_kernel_find_elf(Dwfl_Module *mod,
162 void **userdata,
163 const char *module_name,
164 Dwarf_Addr base,
165 char **file_name, Elf **elfp)
166{
167 int fd;
168 const char *path = kernel_get_module_path(module_name);
169
170 pr_debug2("Use file %s for %s\n", path, module_name);
171 if (path) {
172 fd = open(path, O_RDONLY);
173 if (fd >= 0) {
174 *file_name = strdup(path);
175 return fd;
176 }
177 }
178 /* If failed, try to call standard method */
179 return dwfl_linux_kernel_find_elf(mod, userdata, module_name, base,
180 file_name, elfp);
181}
182
183static const Dwfl_Callbacks kernel_callbacks = {
184 .find_debuginfo = dwfl_standard_find_debuginfo,
185 .debuginfo_path = &debuginfo_path,
186
187 .find_elf = __linux_kernel_find_elf,
188 .section_address = dwfl_linux_kernel_module_section_address,
189};
190
191/* Get a Dwarf from live kernel image */
192static Dwarf *dwfl_init_live_kernel_dwarf(Dwarf_Addr addr, Dwfl **dwflp,
193 Dwarf_Addr *bias)
194{
195 Dwarf *dbg;
196
197 if (!dwflp)
198 return NULL;
199
200 *dwflp = dwfl_begin(&kernel_callbacks);
201 if (!*dwflp)
202 return NULL;
203
204 /* Load the kernel dwarves: Don't care the result here */
205 dwfl_linux_kernel_report_kernel(*dwflp);
206 dwfl_linux_kernel_report_modules(*dwflp);
207
208 dbg = dwfl_addrdwarf(*dwflp, addr, bias);
209 /* Here, check whether we could get a real dwarf */
210 if (!dbg) {
211 pr_debug("Failed to find kernel dwarf at %lx\n",
212 (unsigned long)addr);
213 dwfl_end(*dwflp);
214 *dwflp = NULL;
215 }
216 return dbg;
217}
218#else
219/* With older elfutils, this just support kernel module... */
220static Dwarf *dwfl_init_live_kernel_dwarf(Dwarf_Addr addr __used, Dwfl **dwflp,
221 Dwarf_Addr *bias)
222{
223 int fd;
224 const char *path = kernel_get_module_path("kernel");
225
226 if (!path) {
227 pr_err("Failed to find vmlinux path\n");
228 return NULL;
229 }
230
231 pr_debug2("Use file %s for debuginfo\n", path);
232 fd = open(path, O_RDONLY);
233 if (fd < 0)
234 return NULL;
235
236 return dwfl_init_offline_dwarf(fd, dwflp, bias);
237}
238#endif
239
119/* Dwarf wrappers */ 240/* Dwarf wrappers */
120 241
121/* Find the realpath of the target file. */ 242/* Find the realpath of the target file. */
@@ -152,6 +273,25 @@ static const char *cu_get_comp_dir(Dwarf_Die *cu_die)
152 return dwarf_formstring(&attr); 273 return dwarf_formstring(&attr);
153} 274}
154 275
276/* Get a line number and file name for given address */
277static int cu_find_lineinfo(Dwarf_Die *cudie, unsigned long addr,
278 const char **fname, int *lineno)
279{
280 Dwarf_Line *line;
281 Dwarf_Addr laddr;
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
155/* Compare diename and tname */ 295/* Compare diename and tname */
156static bool die_compare_name(Dwarf_Die *dw_die, const char *tname) 296static bool die_compare_name(Dwarf_Die *dw_die, const char *tname)
157{ 297{
@@ -160,35 +300,76 @@ static bool die_compare_name(Dwarf_Die *dw_die, const char *tname)
160 return name ? (strcmp(tname, name) == 0) : false; 300 return name ? (strcmp(tname, name) == 0) : false;
161} 301}
162 302
163/* Get type die, but skip qualifiers and typedef */ 303/* Get callsite line number of inline-function instance */
164static Dwarf_Die *die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem) 304static int die_get_call_lineno(Dwarf_Die *in_die)
165{ 305{
166 Dwarf_Attribute attr; 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;
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{
167 int tag; 331 int tag;
168 332
169 do { 333 do {
170 if (dwarf_attr(vr_die, DW_AT_type, &attr) == NULL || 334 vr_die = die_get_type(vr_die, die_mem);
171 dwarf_formref_die(&attr, die_mem) == NULL) 335 if (!vr_die)
172 return NULL; 336 break;
173 337 tag = dwarf_tag(vr_die);
174 tag = dwarf_tag(die_mem);
175 vr_die = die_mem;
176 } while (tag == DW_TAG_const_type || 338 } while (tag == DW_TAG_const_type ||
177 tag == DW_TAG_restrict_type || 339 tag == DW_TAG_restrict_type ||
178 tag == DW_TAG_volatile_type || 340 tag == DW_TAG_volatile_type ||
179 tag == DW_TAG_shared_type || 341 tag == DW_TAG_shared_type);
180 tag == DW_TAG_typedef);
181 342
182 return die_mem; 343 return vr_die;
183} 344}
184 345
185static bool die_is_signed_type(Dwarf_Die *tp_die) 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)
186{ 358{
187 Dwarf_Attribute attr; 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
368static bool die_is_signed_type(Dwarf_Die *tp_die)
369{
188 Dwarf_Word ret; 370 Dwarf_Word ret;
189 371
190 if (dwarf_attr(tp_die, DW_AT_encoding, &attr) == NULL || 372 if (die_get_attr_udata(tp_die, DW_AT_encoding, &ret))
191 dwarf_formudata(&attr, &ret) != 0)
192 return false; 373 return false;
193 374
194 return (ret == DW_ATE_signed_char || ret == DW_ATE_signed || 375 return (ret == DW_ATE_signed_char || ret == DW_ATE_signed ||
@@ -197,11 +378,29 @@ static bool die_is_signed_type(Dwarf_Die *tp_die)
197 378
198static int die_get_byte_size(Dwarf_Die *tp_die) 379static int die_get_byte_size(Dwarf_Die *tp_die)
199{ 380{
200 Dwarf_Attribute attr;
201 Dwarf_Word ret; 381 Dwarf_Word ret;
202 382
203 if (dwarf_attr(tp_die, DW_AT_byte_size, &attr) == NULL || 383 if (die_get_attr_udata(tp_die, DW_AT_byte_size, &ret))
204 dwarf_formudata(&attr, &ret) != 0) 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))
205 return 0; 404 return 0;
206 405
207 return (int)ret; 406 return (int)ret;
@@ -317,28 +516,196 @@ static int __die_find_inline_cb(Dwarf_Die *die_mem, void *data)
317static Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, 516static Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
318 Dwarf_Die *die_mem) 517 Dwarf_Die *die_mem)
319{ 518{
320 return die_find_child(sp_die, __die_find_inline_cb, &addr, die_mem); 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 }
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;
321} 599}
322 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
323static int __die_find_variable_cb(Dwarf_Die *die_mem, void *data) 685static int __die_find_variable_cb(Dwarf_Die *die_mem, void *data)
324{ 686{
325 const char *name = data; 687 struct __find_variable_param *fvp = data;
326 int tag; 688 int tag;
327 689
328 tag = dwarf_tag(die_mem); 690 tag = dwarf_tag(die_mem);
329 if ((tag == DW_TAG_formal_parameter || 691 if ((tag == DW_TAG_formal_parameter ||
330 tag == DW_TAG_variable) && 692 tag == DW_TAG_variable) &&
331 die_compare_name(die_mem, name)) 693 die_compare_name(die_mem, fvp->name))
332 return DIE_FIND_CB_FOUND; 694 return DIE_FIND_CB_FOUND;
333 695
334 return DIE_FIND_CB_CONTINUE; 696 if (dwarf_haspc(die_mem, fvp->addr))
697 return DIE_FIND_CB_CONTINUE;
698 else
699 return DIE_FIND_CB_SIBLING;
335} 700}
336 701
337/* Find a variable called 'name' */ 702/* Find a variable called 'name' at given address */
338static Dwarf_Die *die_find_variable(Dwarf_Die *sp_die, const char *name, 703static Dwarf_Die *die_find_variable_at(Dwarf_Die *sp_die, const char *name,
339 Dwarf_Die *die_mem) 704 Dwarf_Addr addr, Dwarf_Die *die_mem)
340{ 705{
341 return die_find_child(sp_die, __die_find_variable_cb, (void *)name, 706 struct __find_variable_param fvp = { .name = name, .addr = addr};
707
708 return die_find_child(sp_die, __die_find_variable_cb, (void *)&fvp,
342 die_mem); 709 die_mem);
343} 710}
344 711
@@ -361,6 +728,60 @@ static Dwarf_Die *die_find_member(Dwarf_Die *st_die, const char *name,
361 die_mem); 728 die_mem);
362} 729}
363 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}
784
364/* 785/*
365 * Probe finder related functions 786 * Probe finder related functions
366 */ 787 */
@@ -374,8 +795,13 @@ static struct probe_trace_arg_ref *alloc_trace_arg_ref(long offs)
374 return ref; 795 return ref;
375} 796}
376 797
377/* Show a location */ 798/*
378static int convert_variable_location(Dwarf_Die *vr_die, struct probe_finder *pf) 799 * Convert a location into trace_arg.
800 * If tvar == NULL, this just checks variable can be converted.
801 */
802static int convert_variable_location(Dwarf_Die *vr_die, Dwarf_Addr addr,
803 Dwarf_Op *fb_ops,
804 struct probe_trace_arg *tvar)
379{ 805{
380 Dwarf_Attribute attr; 806 Dwarf_Attribute attr;
381 Dwarf_Op *op; 807 Dwarf_Op *op;
@@ -384,20 +810,23 @@ static int convert_variable_location(Dwarf_Die *vr_die, struct probe_finder *pf)
384 Dwarf_Word offs = 0; 810 Dwarf_Word offs = 0;
385 bool ref = false; 811 bool ref = false;
386 const char *regs; 812 const char *regs;
387 struct probe_trace_arg *tvar = pf->tvar;
388 int ret; 813 int ret;
389 814
815 if (dwarf_attr(vr_die, DW_AT_external, &attr) != NULL)
816 goto static_var;
817
390 /* TODO: handle more than 1 exprs */ 818 /* TODO: handle more than 1 exprs */
391 if (dwarf_attr(vr_die, DW_AT_location, &attr) == NULL || 819 if (dwarf_attr(vr_die, DW_AT_location, &attr) == NULL ||
392 dwarf_getlocation_addr(&attr, pf->addr, &op, &nops, 1) <= 0 || 820 dwarf_getlocation_addr(&attr, addr, &op, &nops, 1) <= 0 ||
393 nops == 0) { 821 nops == 0) {
394 /* TODO: Support const_value */ 822 /* TODO: Support const_value */
395 pr_err("Failed to find the location of %s at this address.\n"
396 " Perhaps, it has been optimized out.\n", pf->pvar->var);
397 return -ENOENT; 823 return -ENOENT;
398 } 824 }
399 825
400 if (op->atom == DW_OP_addr) { 826 if (op->atom == DW_OP_addr) {
827static_var:
828 if (!tvar)
829 return 0;
401 /* Static variables on memory (not stack), make @varname */ 830 /* Static variables on memory (not stack), make @varname */
402 ret = strlen(dwarf_diename(vr_die)); 831 ret = strlen(dwarf_diename(vr_die));
403 tvar->value = zalloc(ret + 2); 832 tvar->value = zalloc(ret + 2);
@@ -412,14 +841,11 @@ static int convert_variable_location(Dwarf_Die *vr_die, struct probe_finder *pf)
412 841
413 /* If this is based on frame buffer, set the offset */ 842 /* If this is based on frame buffer, set the offset */
414 if (op->atom == DW_OP_fbreg) { 843 if (op->atom == DW_OP_fbreg) {
415 if (pf->fb_ops == NULL) { 844 if (fb_ops == NULL)
416 pr_warning("The attribute of frame base is not "
417 "supported.\n");
418 return -ENOTSUP; 845 return -ENOTSUP;
419 }
420 ref = true; 846 ref = true;
421 offs = op->number; 847 offs = op->number;
422 op = &pf->fb_ops[0]; 848 op = &fb_ops[0];
423 } 849 }
424 850
425 if (op->atom >= DW_OP_breg0 && op->atom <= DW_OP_breg31) { 851 if (op->atom >= DW_OP_breg0 && op->atom <= DW_OP_breg31) {
@@ -435,13 +861,18 @@ static int convert_variable_location(Dwarf_Die *vr_die, struct probe_finder *pf)
435 } else if (op->atom == DW_OP_regx) { 861 } else if (op->atom == DW_OP_regx) {
436 regn = op->number; 862 regn = op->number;
437 } else { 863 } else {
438 pr_warning("DW_OP %x is not supported.\n", op->atom); 864 pr_debug("DW_OP %x is not supported.\n", op->atom);
439 return -ENOTSUP; 865 return -ENOTSUP;
440 } 866 }
441 867
868 if (!tvar)
869 return 0;
870
442 regs = get_arch_regstr(regn); 871 regs = get_arch_regstr(regn);
443 if (!regs) { 872 if (!regs) {
444 pr_warning("Mapping for DWARF register number %u missing on this architecture.", regn); 873 /* This should be a bug in DWARF or this tool */
874 pr_warning("Mapping for the register number %u "
875 "missing on this architecture.\n", regn);
445 return -ERANGE; 876 return -ERANGE;
446 } 877 }
447 878
@@ -457,6 +888,8 @@ static int convert_variable_location(Dwarf_Die *vr_die, struct probe_finder *pf)
457 return 0; 888 return 0;
458} 889}
459 890
891#define BYTES_TO_BITS(nb) ((nb) * BITS_PER_LONG / sizeof(long))
892
460static int convert_variable_type(Dwarf_Die *vr_die, 893static int convert_variable_type(Dwarf_Die *vr_die,
461 struct probe_trace_arg *tvar, 894 struct probe_trace_arg *tvar,
462 const char *cast) 895 const char *cast)
@@ -473,6 +906,14 @@ static int convert_variable_type(Dwarf_Die *vr_die,
473 return (tvar->type == NULL) ? -ENOMEM : 0; 906 return (tvar->type == NULL) ? -ENOMEM : 0;
474 } 907 }
475 908
909 if (die_get_bit_size(vr_die) != 0) {
910 /* This is a bitfield */
911 ret = snprintf(buf, 16, "b%d@%d/%zd", die_get_bit_size(vr_die),
912 die_get_bit_offset(vr_die),
913 BYTES_TO_BITS(die_get_byte_size(vr_die)));
914 goto formatted;
915 }
916
476 if (die_get_real_type(vr_die, &type) == NULL) { 917 if (die_get_real_type(vr_die, &type) == NULL) {
477 pr_warning("Failed to get a type information of %s.\n", 918 pr_warning("Failed to get a type information of %s.\n",
478 dwarf_diename(vr_die)); 919 dwarf_diename(vr_die));
@@ -487,13 +928,14 @@ static int convert_variable_type(Dwarf_Die *vr_die,
487 if (ret != DW_TAG_pointer_type && 928 if (ret != DW_TAG_pointer_type &&
488 ret != DW_TAG_array_type) { 929 ret != DW_TAG_array_type) {
489 pr_warning("Failed to cast into string: " 930 pr_warning("Failed to cast into string: "
490 "%s(%s) is not a pointer nor array.", 931 "%s(%s) is not a pointer nor array.\n",
491 dwarf_diename(vr_die), dwarf_diename(&type)); 932 dwarf_diename(vr_die), dwarf_diename(&type));
492 return -EINVAL; 933 return -EINVAL;
493 } 934 }
494 if (ret == DW_TAG_pointer_type) { 935 if (ret == DW_TAG_pointer_type) {
495 if (die_get_real_type(&type, &type) == NULL) { 936 if (die_get_real_type(&type, &type) == NULL) {
496 pr_warning("Failed to get a type information."); 937 pr_warning("Failed to get a type"
938 " information.\n");
497 return -ENOENT; 939 return -ENOENT;
498 } 940 }
499 while (*ref_ptr) 941 while (*ref_ptr)
@@ -508,7 +950,7 @@ static int convert_variable_type(Dwarf_Die *vr_die,
508 if (!die_compare_name(&type, "char") && 950 if (!die_compare_name(&type, "char") &&
509 !die_compare_name(&type, "unsigned char")) { 951 !die_compare_name(&type, "unsigned char")) {
510 pr_warning("Failed to cast into string: " 952 pr_warning("Failed to cast into string: "
511 "%s is not (unsigned) char *.", 953 "%s is not (unsigned) char *.\n",
512 dwarf_diename(vr_die)); 954 dwarf_diename(vr_die));
513 return -EINVAL; 955 return -EINVAL;
514 } 956 }
@@ -516,29 +958,31 @@ static int convert_variable_type(Dwarf_Die *vr_die,
516 return (tvar->type == NULL) ? -ENOMEM : 0; 958 return (tvar->type == NULL) ? -ENOMEM : 0;
517 } 959 }
518 960
519 ret = die_get_byte_size(&type) * 8; 961 ret = BYTES_TO_BITS(die_get_byte_size(&type));
520 if (ret) { 962 if (!ret)
521 /* Check the bitwidth */ 963 /* No size ... try to use default type */
522 if (ret > MAX_BASIC_TYPE_BITS) { 964 return 0;
523 pr_info("%s exceeds max-bitwidth."
524 " Cut down to %d bits.\n",
525 dwarf_diename(&type), MAX_BASIC_TYPE_BITS);
526 ret = MAX_BASIC_TYPE_BITS;
527 }
528 965
529 ret = snprintf(buf, 16, "%c%d", 966 /* Check the bitwidth */
530 die_is_signed_type(&type) ? 's' : 'u', ret); 967 if (ret > MAX_BASIC_TYPE_BITS) {
531 if (ret < 0 || ret >= 16) { 968 pr_info("%s exceeds max-bitwidth. Cut down to %d bits.\n",
532 if (ret >= 16) 969 dwarf_diename(&type), MAX_BASIC_TYPE_BITS);
533 ret = -E2BIG; 970 ret = MAX_BASIC_TYPE_BITS;
534 pr_warning("Failed to convert variable type: %s\n",
535 strerror(-ret));
536 return ret;
537 }
538 tvar->type = strdup(buf);
539 if (tvar->type == NULL)
540 return -ENOMEM;
541 } 971 }
972 ret = snprintf(buf, 16, "%c%d",
973 die_is_signed_type(&type) ? 's' : 'u', ret);
974
975formatted:
976 if (ret < 0 || ret >= 16) {
977 if (ret >= 16)
978 ret = -E2BIG;
979 pr_warning("Failed to convert variable type: %s\n",
980 strerror(-ret));
981 return ret;
982 }
983 tvar->type = strdup(buf);
984 if (tvar->type == NULL)
985 return -ENOMEM;
542 return 0; 986 return 0;
543} 987}
544 988
@@ -618,8 +1062,8 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
618 return -EINVAL; 1062 return -EINVAL;
619 } 1063 }
620 if (field->name[0] == '[') { 1064 if (field->name[0] == '[') {
621 pr_err("Semantic error: %s is not a pointor nor array.", 1065 pr_err("Semantic error: %s is not a pointor"
622 varname); 1066 " nor array.\n", varname);
623 return -EINVAL; 1067 return -EINVAL;
624 } 1068 }
625 if (field->ref) { 1069 if (field->ref) {
@@ -666,8 +1110,14 @@ static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
666 pr_debug("Converting variable %s into trace event.\n", 1110 pr_debug("Converting variable %s into trace event.\n",
667 dwarf_diename(vr_die)); 1111 dwarf_diename(vr_die));
668 1112
669 ret = convert_variable_location(vr_die, pf); 1113 ret = convert_variable_location(vr_die, pf->addr, pf->fb_ops,
670 if (ret == 0 && pf->pvar->field) { 1114 pf->tvar);
1115 if (ret == -ENOENT)
1116 pr_err("Failed to find the location of %s at this address.\n"
1117 " Perhaps, it has been optimized out.\n", pf->pvar->var);
1118 else if (ret == -ENOTSUP)
1119 pr_err("Sorry, we don't support this variable location yet.\n");
1120 else if (pf->pvar->field) {
671 ret = convert_variable_fields(vr_die, pf->pvar->var, 1121 ret = convert_variable_fields(vr_die, pf->pvar->var,
672 pf->pvar->field, &pf->tvar->ref, 1122 pf->pvar->field, &pf->tvar->ref,
673 &die_mem); 1123 &die_mem);
@@ -722,85 +1172,87 @@ static int find_variable(Dwarf_Die *sp_die, struct probe_finder *pf)
722 pr_debug("Searching '%s' variable in context.\n", 1172 pr_debug("Searching '%s' variable in context.\n",
723 pf->pvar->var); 1173 pf->pvar->var);
724 /* Search child die for local variables and parameters. */ 1174 /* Search child die for local variables and parameters. */
725 if (die_find_variable(sp_die, pf->pvar->var, &vr_die)) 1175 if (die_find_variable_at(sp_die, pf->pvar->var, pf->addr, &vr_die))
726 ret = convert_variable(&vr_die, pf); 1176 ret = convert_variable(&vr_die, pf);
727 else { 1177 else {
728 /* Search upper class */ 1178 /* Search upper class */
729 nscopes = dwarf_getscopes_die(sp_die, &scopes); 1179 nscopes = dwarf_getscopes_die(sp_die, &scopes);
730 if (nscopes > 0) { 1180 while (nscopes-- > 1) {
731 ret = dwarf_getscopevar(scopes, nscopes, pf->pvar->var, 1181 pr_debug("Searching variables in %s\n",
732 0, NULL, 0, 0, &vr_die); 1182 dwarf_diename(&scopes[nscopes]));
733 if (ret >= 0) 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)) {
734 ret = convert_variable(&vr_die, pf); 1187 ret = convert_variable(&vr_die, pf);
735 else 1188 goto found;
736 ret = -ENOENT; 1189 }
1190 }
1191 if (scopes)
737 free(scopes); 1192 free(scopes);
738 } else 1193 ret = -ENOENT;
739 ret = -ENOENT;
740 } 1194 }
1195found:
741 if (ret < 0) 1196 if (ret < 0)
742 pr_warning("Failed to find '%s' in this function.\n", 1197 pr_warning("Failed to find '%s' in this function.\n",
743 pf->pvar->var); 1198 pf->pvar->var);
744 return ret; 1199 return ret;
745} 1200}
746 1201
747/* Show a probe point to output buffer */ 1202/* Convert subprogram DIE to trace point */
748static int convert_probe_point(Dwarf_Die *sp_die, struct probe_finder *pf) 1203static int convert_to_trace_point(Dwarf_Die *sp_die, Dwarf_Addr paddr,
1204 bool retprobe, struct probe_trace_point *tp)
749{ 1205{
750 struct probe_trace_event *tev;
751 Dwarf_Addr eaddr; 1206 Dwarf_Addr eaddr;
752 Dwarf_Die die_mem;
753 const char *name; 1207 const char *name;
754 int ret, i;
755 Dwarf_Attribute fb_attr;
756 size_t nops;
757
758 if (pf->ntevs == pf->max_tevs) {
759 pr_warning("Too many( > %d) probe point found.\n",
760 pf->max_tevs);
761 return -ERANGE;
762 }
763 tev = &pf->tevs[pf->ntevs++];
764
765 /* If no real subprogram, find a real one */
766 if (!sp_die || dwarf_tag(sp_die) != DW_TAG_subprogram) {
767 sp_die = die_find_real_subprogram(&pf->cu_die,
768 pf->addr, &die_mem);
769 if (!sp_die) {
770 pr_warning("Failed to find probe point in any "
771 "functions.\n");
772 return -ENOENT;
773 }
774 }
775 1208
776 /* Copy the name of probe point */ 1209 /* Copy the name of probe point */
777 name = dwarf_diename(sp_die); 1210 name = dwarf_diename(sp_die);
778 if (name) { 1211 if (name) {
779 if (dwarf_entrypc(sp_die, &eaddr) != 0) { 1212 if (dwarf_entrypc(sp_die, &eaddr) != 0) {
780 pr_warning("Failed to get entry pc of %s\n", 1213 pr_warning("Failed to get entry address of %s\n",
781 dwarf_diename(sp_die)); 1214 dwarf_diename(sp_die));
782 return -ENOENT; 1215 return -ENOENT;
783 } 1216 }
784 tev->point.symbol = strdup(name); 1217 tp->symbol = strdup(name);
785 if (tev->point.symbol == NULL) 1218 if (tp->symbol == NULL)
786 return -ENOMEM; 1219 return -ENOMEM;
787 tev->point.offset = (unsigned long)(pf->addr - eaddr); 1220 tp->offset = (unsigned long)(paddr - eaddr);
788 } else 1221 } else
789 /* This function has no name. */ 1222 /* This function has no name. */
790 tev->point.offset = (unsigned long)pf->addr; 1223 tp->offset = (unsigned long)paddr;
791 1224
792 /* Return probe must be on the head of a subprogram */ 1225 /* Return probe must be on the head of a subprogram */
793 if (pf->pev->point.retprobe) { 1226 if (retprobe) {
794 if (tev->point.offset != 0) { 1227 if (eaddr != paddr) {
795 pr_warning("Return probe must be on the head of" 1228 pr_warning("Return probe must be on the head of"
796 " a real function\n"); 1229 " a real function.\n");
797 return -EINVAL; 1230 return -EINVAL;
798 } 1231 }
799 tev->point.retprobe = true; 1232 tp->retprobe = true;
800 } 1233 }
801 1234
802 pr_debug("Probe point found: %s+%lu\n", tev->point.symbol, 1235 return 0;
803 tev->point.offset); 1236}
1237
1238/* Call probe_finder callback with real subprogram DIE */
1239static int call_probe_finder(Dwarf_Die *sp_die, struct probe_finder *pf)
1240{
1241 Dwarf_Die die_mem;
1242 Dwarf_Attribute fb_attr;
1243 size_t nops;
1244 int ret;
1245
1246 /* If no real subprogram, find a real one */
1247 if (!sp_die || dwarf_tag(sp_die) != DW_TAG_subprogram) {
1248 sp_die = die_find_real_subprogram(&pf->cu_die,
1249 pf->addr, &die_mem);
1250 if (!sp_die) {
1251 pr_warning("Failed to find probe point in any "
1252 "functions.\n");
1253 return -ENOENT;
1254 }
1255 }
804 1256
805 /* Get the frame base attribute/ops */ 1257 /* Get the frame base attribute/ops */
806 dwarf_attr(sp_die, DW_AT_frame_base, &fb_attr); 1258 dwarf_attr(sp_die, DW_AT_frame_base, &fb_attr);
@@ -813,182 +1265,118 @@ static int convert_probe_point(Dwarf_Die *sp_die, struct probe_finder *pf)
813 Dwarf_Frame *frame; 1265 Dwarf_Frame *frame;
814 if (dwarf_cfi_addrframe(pf->cfi, pf->addr, &frame) != 0 || 1266 if (dwarf_cfi_addrframe(pf->cfi, pf->addr, &frame) != 0 ||
815 dwarf_frame_cfa(frame, &pf->fb_ops, &nops) != 0) { 1267 dwarf_frame_cfa(frame, &pf->fb_ops, &nops) != 0) {
816 pr_warning("Failed to get CFA on 0x%jx\n", 1268 pr_warning("Failed to get call frame on 0x%jx\n",
817 (uintmax_t)pf->addr); 1269 (uintmax_t)pf->addr);
818 return -ENOENT; 1270 return -ENOENT;
819 } 1271 }
820#endif 1272#endif
821 } 1273 }
822 1274
823 /* Find each argument */ 1275 /* Call finder's callback handler */
824 tev->nargs = pf->pev->nargs; 1276 ret = pf->callback(sp_die, pf);
825 tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs);
826 if (tev->args == NULL)
827 return -ENOMEM;
828 for (i = 0; i < pf->pev->nargs; i++) {
829 pf->pvar = &pf->pev->args[i];
830 pf->tvar = &tev->args[i];
831 ret = find_variable(sp_die, pf);
832 if (ret != 0)
833 return ret;
834 }
835 1277
836 /* *pf->fb_ops will be cached in libdw. Don't free it. */ 1278 /* *pf->fb_ops will be cached in libdw. Don't free it. */
837 pf->fb_ops = NULL; 1279 pf->fb_ops = NULL;
838 return 0; 1280
1281 return ret;
839} 1282}
840 1283
841/* Find probe point from its line number */ 1284static int probe_point_line_walker(const char *fname, int lineno,
842static int find_probe_point_by_line(struct probe_finder *pf) 1285 Dwarf_Addr addr, void *data)
843{ 1286{
844 Dwarf_Lines *lines; 1287 struct probe_finder *pf = data;
845 Dwarf_Line *line; 1288 int ret;
846 size_t nlines, i;
847 Dwarf_Addr addr;
848 int lineno;
849 int ret = 0;
850
851 if (dwarf_getsrclines(&pf->cu_die, &lines, &nlines) != 0) {
852 pr_warning("No source lines found in this CU.\n");
853 return -ENOENT;
854 }
855 1289
856 for (i = 0; i < nlines && ret == 0; i++) { 1290 if (lineno != pf->lno || strtailcmp(fname, pf->fname) != 0)
857 line = dwarf_onesrcline(lines, i); 1291 return 0;
858 if (dwarf_lineno(line, &lineno) != 0 ||
859 lineno != pf->lno)
860 continue;
861 1292
862 /* TODO: Get fileno from line, but how? */ 1293 pf->addr = addr;
863 if (strtailcmp(dwarf_linesrc(line, NULL, NULL), pf->fname) != 0) 1294 ret = call_probe_finder(NULL, pf);
864 continue;
865 1295
866 if (dwarf_lineaddr(line, &addr) != 0) { 1296 /* Continue if no error, because the line will be in inline function */
867 pr_warning("Failed to get the address of the line.\n"); 1297 return ret < 0 ? ret : 0;
868 return -ENOENT; 1298}
869 }
870 pr_debug("Probe line found: line[%d]:%d addr:0x%jx\n",
871 (int)i, lineno, (uintmax_t)addr);
872 pf->addr = addr;
873 1299
874 ret = convert_probe_point(NULL, pf); 1300/* Find probe point from its line number */
875 /* Continuing, because target line might be inlined. */ 1301static int find_probe_point_by_line(struct probe_finder *pf)
876 } 1302{
877 return ret; 1303 return die_walk_lines(&pf->cu_die, probe_point_line_walker, pf);
878} 1304}
879 1305
880/* Find lines which match lazy pattern */ 1306/* Find lines which match lazy pattern */
881static int find_lazy_match_lines(struct list_head *head, 1307static int find_lazy_match_lines(struct list_head *head,
882 const char *fname, const char *pat) 1308 const char *fname, const char *pat)
883{ 1309{
884 char *fbuf, *p1, *p2; 1310 FILE *fp;
885 int fd, line, nlines = -1; 1311 char *line = NULL;
886 struct stat st; 1312 size_t line_len;
887 1313 ssize_t len;
888 fd = open(fname, O_RDONLY); 1314 int count = 0, linenum = 1;
889 if (fd < 0) { 1315
890 pr_warning("Failed to open %s: %s\n", fname, strerror(-fd)); 1316 fp = fopen(fname, "r");
1317 if (!fp) {
1318 pr_warning("Failed to open %s: %s\n", fname, strerror(errno));
891 return -errno; 1319 return -errno;
892 } 1320 }
893 1321
894 if (fstat(fd, &st) < 0) { 1322 while ((len = getline(&line, &line_len, fp)) > 0) {
895 pr_warning("Failed to get the size of %s: %s\n", 1323
896 fname, strerror(errno)); 1324 if (line[len - 1] == '\n')
897 nlines = -errno; 1325 line[len - 1] = '\0';
898 goto out_close; 1326
899 } 1327 if (strlazymatch(line, pat)) {
900 1328 line_list__add_line(head, linenum);
901 nlines = -ENOMEM; 1329 count++;
902 fbuf = malloc(st.st_size + 2);
903 if (fbuf == NULL)
904 goto out_close;
905 if (read(fd, fbuf, st.st_size) < 0) {
906 pr_warning("Failed to read %s: %s\n", fname, strerror(errno));
907 nlines = -errno;
908 goto out_free_fbuf;
909 }
910 fbuf[st.st_size] = '\n'; /* Dummy line */
911 fbuf[st.st_size + 1] = '\0';
912 p1 = fbuf;
913 line = 1;
914 nlines = 0;
915 while ((p2 = strchr(p1, '\n')) != NULL) {
916 *p2 = '\0';
917 if (strlazymatch(p1, pat)) {
918 line_list__add_line(head, line);
919 nlines++;
920 } 1330 }
921 line++; 1331 linenum++;
922 p1 = p2 + 1;
923 } 1332 }
924out_free_fbuf: 1333
925 free(fbuf); 1334 if (ferror(fp))
926out_close: 1335 count = -errno;
927 close(fd); 1336 free(line);
928 return nlines; 1337 fclose(fp);
1338
1339 if (count == 0)
1340 pr_debug("No matched lines found in %s.\n", fname);
1341 return count;
1342}
1343
1344static int probe_point_lazy_walker(const char *fname, int lineno,
1345 Dwarf_Addr addr, void *data)
1346{
1347 struct probe_finder *pf = data;
1348 int ret;
1349
1350 if (!line_list__has_line(&pf->lcache, lineno) ||
1351 strtailcmp(fname, pf->fname) != 0)
1352 return 0;
1353
1354 pr_debug("Probe line found: line:%d addr:0x%llx\n",
1355 lineno, (unsigned long long)addr);
1356 pf->addr = addr;
1357 ret = call_probe_finder(NULL, pf);
1358
1359 /*
1360 * Continue if no error, because the lazy pattern will match
1361 * to other lines
1362 */
1363 return ret < 0 ? ret : 0;
929} 1364}
930 1365
931/* Find probe points from lazy pattern */ 1366/* Find probe points from lazy pattern */
932static int find_probe_point_lazy(Dwarf_Die *sp_die, struct probe_finder *pf) 1367static int find_probe_point_lazy(Dwarf_Die *sp_die, struct probe_finder *pf)
933{ 1368{
934 Dwarf_Lines *lines;
935 Dwarf_Line *line;
936 size_t nlines, i;
937 Dwarf_Addr addr;
938 Dwarf_Die die_mem;
939 int lineno;
940 int ret = 0; 1369 int ret = 0;
941 1370
942 if (list_empty(&pf->lcache)) { 1371 if (list_empty(&pf->lcache)) {
943 /* Matching lazy line pattern */ 1372 /* Matching lazy line pattern */
944 ret = find_lazy_match_lines(&pf->lcache, pf->fname, 1373 ret = find_lazy_match_lines(&pf->lcache, pf->fname,
945 pf->pev->point.lazy_line); 1374 pf->pev->point.lazy_line);
946 if (ret == 0) { 1375 if (ret <= 0)
947 pr_debug("No matched lines found in %s.\n", pf->fname);
948 return 0;
949 } else if (ret < 0)
950 return ret; 1376 return ret;
951 } 1377 }
952 1378
953 if (dwarf_getsrclines(&pf->cu_die, &lines, &nlines) != 0) { 1379 return die_walk_lines(sp_die, probe_point_lazy_walker, pf);
954 pr_warning("No source lines found in this CU.\n");
955 return -ENOENT;
956 }
957
958 for (i = 0; i < nlines && ret >= 0; i++) {
959 line = dwarf_onesrcline(lines, i);
960
961 if (dwarf_lineno(line, &lineno) != 0 ||
962 !line_list__has_line(&pf->lcache, lineno))
963 continue;
964
965 /* TODO: Get fileno from line, but how? */
966 if (strtailcmp(dwarf_linesrc(line, NULL, NULL), pf->fname) != 0)
967 continue;
968
969 if (dwarf_lineaddr(line, &addr) != 0) {
970 pr_debug("Failed to get the address of line %d.\n",
971 lineno);
972 continue;
973 }
974 if (sp_die) {
975 /* Address filtering 1: does sp_die include addr? */
976 if (!dwarf_haspc(sp_die, addr))
977 continue;
978 /* Address filtering 2: No child include addr? */
979 if (die_find_inlinefunc(sp_die, addr, &die_mem))
980 continue;
981 }
982
983 pr_debug("Probe line found: line[%d]:%d addr:0x%llx\n",
984 (int)i, lineno, (unsigned long long)addr);
985 pf->addr = addr;
986
987 ret = convert_probe_point(sp_die, pf);
988 /* Continuing, because target line might be inlined. */
989 }
990 /* TODO: deallocate lines, but how? */
991 return ret;
992} 1380}
993 1381
994/* Callback parameter with return value */ 1382/* Callback parameter with return value */
@@ -1009,7 +1397,7 @@ static int probe_point_inline_cb(Dwarf_Die *in_die, void *data)
1009 else { 1397 else {
1010 /* Get probe address */ 1398 /* Get probe address */
1011 if (dwarf_entrypc(in_die, &addr) != 0) { 1399 if (dwarf_entrypc(in_die, &addr) != 0) {
1012 pr_warning("Failed to get entry pc of %s.\n", 1400 pr_warning("Failed to get entry address of %s.\n",
1013 dwarf_diename(in_die)); 1401 dwarf_diename(in_die));
1014 param->retval = -ENOENT; 1402 param->retval = -ENOENT;
1015 return DWARF_CB_ABORT; 1403 return DWARF_CB_ABORT;
@@ -1019,7 +1407,7 @@ static int probe_point_inline_cb(Dwarf_Die *in_die, void *data)
1019 pr_debug("found inline addr: 0x%jx\n", 1407 pr_debug("found inline addr: 0x%jx\n",
1020 (uintmax_t)pf->addr); 1408 (uintmax_t)pf->addr);
1021 1409
1022 param->retval = convert_probe_point(in_die, pf); 1410 param->retval = call_probe_finder(in_die, pf);
1023 if (param->retval < 0) 1411 if (param->retval < 0)
1024 return DWARF_CB_ABORT; 1412 return DWARF_CB_ABORT;
1025 } 1413 }
@@ -1039,6 +1427,10 @@ static int probe_point_search_cb(Dwarf_Die *sp_die, void *data)
1039 !die_compare_name(sp_die, pp->function)) 1427 !die_compare_name(sp_die, pp->function))
1040 return DWARF_CB_OK; 1428 return DWARF_CB_OK;
1041 1429
1430 /* Check declared file */
1431 if (pp->file && strtailcmp(pp->file, dwarf_decl_file(sp_die)))
1432 return DWARF_CB_OK;
1433
1042 pf->fname = dwarf_decl_file(sp_die); 1434 pf->fname = dwarf_decl_file(sp_die);
1043 if (pp->line) { /* Function relative line */ 1435 if (pp->line) { /* Function relative line */
1044 dwarf_decl_line(sp_die, &pf->lno); 1436 dwarf_decl_line(sp_die, &pf->lno);
@@ -1050,14 +1442,14 @@ static int probe_point_search_cb(Dwarf_Die *sp_die, void *data)
1050 param->retval = find_probe_point_lazy(sp_die, pf); 1442 param->retval = find_probe_point_lazy(sp_die, pf);
1051 else { 1443 else {
1052 if (dwarf_entrypc(sp_die, &pf->addr) != 0) { 1444 if (dwarf_entrypc(sp_die, &pf->addr) != 0) {
1053 pr_warning("Failed to get entry pc of %s.\n", 1445 pr_warning("Failed to get entry address of "
1054 dwarf_diename(sp_die)); 1446 "%s.\n", dwarf_diename(sp_die));
1055 param->retval = -ENOENT; 1447 param->retval = -ENOENT;
1056 return DWARF_CB_ABORT; 1448 return DWARF_CB_ABORT;
1057 } 1449 }
1058 pf->addr += pp->offset; 1450 pf->addr += pp->offset;
1059 /* TODO: Check the address in this function */ 1451 /* TODO: Check the address in this function */
1060 param->retval = convert_probe_point(sp_die, pf); 1452 param->retval = call_probe_finder(sp_die, pf);
1061 } 1453 }
1062 } else { 1454 } else {
1063 struct dwarf_callback_param _param = {.data = (void *)pf, 1455 struct dwarf_callback_param _param = {.data = (void *)pf,
@@ -1079,155 +1471,410 @@ static int find_probe_point_by_func(struct probe_finder *pf)
1079 return _param.retval; 1471 return _param.retval;
1080} 1472}
1081 1473
1082/* Find probe_trace_events specified by perf_probe_event from debuginfo */ 1474struct pubname_callback_param {
1083int find_probe_trace_events(int fd, struct perf_probe_event *pev, 1475 char *function;
1084 struct probe_trace_event **tevs, int max_tevs) 1476 char *file;
1477 Dwarf_Die *cu_die;
1478 Dwarf_Die *sp_die;
1479 int found;
1480};
1481
1482static int pubname_search_cb(Dwarf *dbg, Dwarf_Global *gl, void *data)
1483{
1484 struct pubname_callback_param *param = data;
1485
1486 if (dwarf_offdie(dbg, gl->die_offset, param->sp_die)) {
1487 if (dwarf_tag(param->sp_die) != DW_TAG_subprogram)
1488 return DWARF_CB_OK;
1489
1490 if (die_compare_name(param->sp_die, param->function)) {
1491 if (!dwarf_offdie(dbg, gl->cu_offset, param->cu_die))
1492 return DWARF_CB_OK;
1493
1494 if (param->file &&
1495 strtailcmp(param->file, dwarf_decl_file(param->sp_die)))
1496 return DWARF_CB_OK;
1497
1498 param->found = 1;
1499 return DWARF_CB_ABORT;
1500 }
1501 }
1502
1503 return DWARF_CB_OK;
1504}
1505
1506/* Find probe points from debuginfo */
1507static int find_probes(int fd, struct probe_finder *pf)
1085{ 1508{
1086 struct probe_finder pf = {.pev = pev, .max_tevs = max_tevs}; 1509 struct perf_probe_point *pp = &pf->pev->point;
1087 struct perf_probe_point *pp = &pev->point;
1088 Dwarf_Off off, noff; 1510 Dwarf_Off off, noff;
1089 size_t cuhl; 1511 size_t cuhl;
1090 Dwarf_Die *diep; 1512 Dwarf_Die *diep;
1091 Dwarf *dbg; 1513 Dwarf *dbg = NULL;
1514 Dwfl *dwfl;
1515 Dwarf_Addr bias; /* Currently ignored */
1092 int ret = 0; 1516 int ret = 0;
1093 1517
1094 pf.tevs = zalloc(sizeof(struct probe_trace_event) * max_tevs); 1518 dbg = dwfl_init_offline_dwarf(fd, &dwfl, &bias);
1095 if (pf.tevs == NULL)
1096 return -ENOMEM;
1097 *tevs = pf.tevs;
1098 pf.ntevs = 0;
1099
1100 dbg = dwarf_begin(fd, DWARF_C_READ);
1101 if (!dbg) { 1519 if (!dbg) {
1102 pr_warning("No dwarf info found in the vmlinux - " 1520 pr_warning("No debug information found in the vmlinux - "
1103 "please rebuild with CONFIG_DEBUG_INFO=y.\n"); 1521 "please rebuild with CONFIG_DEBUG_INFO=y.\n");
1104 free(pf.tevs); 1522 close(fd); /* Without dwfl_end(), fd isn't closed. */
1105 *tevs = NULL;
1106 return -EBADF; 1523 return -EBADF;
1107 } 1524 }
1108 1525
1109#if _ELFUTILS_PREREQ(0, 142) 1526#if _ELFUTILS_PREREQ(0, 142)
1110 /* Get the call frame information from this dwarf */ 1527 /* Get the call frame information from this dwarf */
1111 pf.cfi = dwarf_getcfi(dbg); 1528 pf->cfi = dwarf_getcfi(dbg);
1112#endif 1529#endif
1113 1530
1114 off = 0; 1531 off = 0;
1115 line_list__init(&pf.lcache); 1532 line_list__init(&pf->lcache);
1533
1534 /* Fastpath: lookup by function name from .debug_pubnames section */
1535 if (pp->function) {
1536 struct pubname_callback_param pubname_param = {
1537 .function = pp->function,
1538 .file = pp->file,
1539 .cu_die = &pf->cu_die,
1540 .sp_die = &pf->sp_die,
1541 .found = 0,
1542 };
1543 struct dwarf_callback_param probe_param = {
1544 .data = pf,
1545 };
1546
1547 dwarf_getpubnames(dbg, pubname_search_cb, &pubname_param, 0);
1548 if (pubname_param.found) {
1549 ret = probe_point_search_cb(&pf->sp_die, &probe_param);
1550 if (ret)
1551 goto found;
1552 }
1553 }
1554
1116 /* Loop on CUs (Compilation Unit) */ 1555 /* Loop on CUs (Compilation Unit) */
1117 while (!dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL) && 1556 while (!dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL)) {
1118 ret >= 0) {
1119 /* Get the DIE(Debugging Information Entry) of this CU */ 1557 /* Get the DIE(Debugging Information Entry) of this CU */
1120 diep = dwarf_offdie(dbg, off + cuhl, &pf.cu_die); 1558 diep = dwarf_offdie(dbg, off + cuhl, &pf->cu_die);
1121 if (!diep) 1559 if (!diep)
1122 continue; 1560 continue;
1123 1561
1124 /* Check if target file is included. */ 1562 /* Check if target file is included. */
1125 if (pp->file) 1563 if (pp->file)
1126 pf.fname = cu_find_realpath(&pf.cu_die, pp->file); 1564 pf->fname = cu_find_realpath(&pf->cu_die, pp->file);
1127 else 1565 else
1128 pf.fname = NULL; 1566 pf->fname = NULL;
1129 1567
1130 if (!pp->file || pf.fname) { 1568 if (!pp->file || pf->fname) {
1131 if (pp->function) 1569 if (pp->function)
1132 ret = find_probe_point_by_func(&pf); 1570 ret = find_probe_point_by_func(pf);
1133 else if (pp->lazy_line) 1571 else if (pp->lazy_line)
1134 ret = find_probe_point_lazy(NULL, &pf); 1572 ret = find_probe_point_lazy(NULL, pf);
1135 else { 1573 else {
1136 pf.lno = pp->line; 1574 pf->lno = pp->line;
1137 ret = find_probe_point_by_line(&pf); 1575 ret = find_probe_point_by_line(pf);
1138 } 1576 }
1577 if (ret < 0)
1578 break;
1139 } 1579 }
1140 off = noff; 1580 off = noff;
1141 } 1581 }
1142 line_list__free(&pf.lcache);
1143 dwarf_end(dbg);
1144 1582
1145 return (ret < 0) ? ret : pf.ntevs; 1583found:
1584 line_list__free(&pf->lcache);
1585 if (dwfl)
1586 dwfl_end(dwfl);
1587
1588 return ret;
1589}
1590
1591/* Add a found probe point into trace event list */
1592static int add_probe_trace_event(Dwarf_Die *sp_die, struct probe_finder *pf)
1593{
1594 struct trace_event_finder *tf =
1595 container_of(pf, struct trace_event_finder, pf);
1596 struct probe_trace_event *tev;
1597 int ret, i;
1598
1599 /* Check number of tevs */
1600 if (tf->ntevs == tf->max_tevs) {
1601 pr_warning("Too many( > %d) probe point found.\n",
1602 tf->max_tevs);
1603 return -ERANGE;
1604 }
1605 tev = &tf->tevs[tf->ntevs++];
1606
1607 ret = convert_to_trace_point(sp_die, pf->addr, pf->pev->point.retprobe,
1608 &tev->point);
1609 if (ret < 0)
1610 return ret;
1611
1612 pr_debug("Probe point found: %s+%lu\n", tev->point.symbol,
1613 tev->point.offset);
1614
1615 /* Find each argument */
1616 tev->nargs = pf->pev->nargs;
1617 tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs);
1618 if (tev->args == NULL)
1619 return -ENOMEM;
1620 for (i = 0; i < pf->pev->nargs; i++) {
1621 pf->pvar = &pf->pev->args[i];
1622 pf->tvar = &tev->args[i];
1623 ret = find_variable(sp_die, pf);
1624 if (ret != 0)
1625 return ret;
1626 }
1627
1628 return 0;
1629}
1630
1631/* Find probe_trace_events specified by perf_probe_event from debuginfo */
1632int find_probe_trace_events(int fd, struct perf_probe_event *pev,
1633 struct probe_trace_event **tevs, int max_tevs)
1634{
1635 struct trace_event_finder tf = {
1636 .pf = {.pev = pev, .callback = add_probe_trace_event},
1637 .max_tevs = max_tevs};
1638 int ret;
1639
1640 /* Allocate result tevs array */
1641 *tevs = zalloc(sizeof(struct probe_trace_event) * max_tevs);
1642 if (*tevs == NULL)
1643 return -ENOMEM;
1644
1645 tf.tevs = *tevs;
1646 tf.ntevs = 0;
1647
1648 ret = find_probes(fd, &tf.pf);
1649 if (ret < 0) {
1650 free(*tevs);
1651 *tevs = NULL;
1652 return ret;
1653 }
1654
1655 return (ret < 0) ? ret : tf.ntevs;
1656}
1657
1658#define MAX_VAR_LEN 64
1659
1660/* Collect available variables in this scope */
1661static int collect_variables_cb(Dwarf_Die *die_mem, void *data)
1662{
1663 struct available_var_finder *af = data;
1664 struct variable_list *vl;
1665 char buf[MAX_VAR_LEN];
1666 int tag, ret;
1667
1668 vl = &af->vls[af->nvls - 1];
1669
1670 tag = dwarf_tag(die_mem);
1671 if (tag == DW_TAG_formal_parameter ||
1672 tag == DW_TAG_variable) {
1673 ret = convert_variable_location(die_mem, af->pf.addr,
1674 af->pf.fb_ops, NULL);
1675 if (ret == 0) {
1676 ret = die_get_varname(die_mem, buf, MAX_VAR_LEN);
1677 pr_debug2("Add new var: %s\n", buf);
1678 if (ret > 0)
1679 strlist__add(vl->vars, buf);
1680 }
1681 }
1682
1683 if (af->child && dwarf_haspc(die_mem, af->pf.addr))
1684 return DIE_FIND_CB_CONTINUE;
1685 else
1686 return DIE_FIND_CB_SIBLING;
1687}
1688
1689/* Add a found vars into available variables list */
1690static int add_available_vars(Dwarf_Die *sp_die, struct probe_finder *pf)
1691{
1692 struct available_var_finder *af =
1693 container_of(pf, struct available_var_finder, pf);
1694 struct variable_list *vl;
1695 Dwarf_Die die_mem, *scopes = NULL;
1696 int ret, nscopes;
1697
1698 /* Check number of tevs */
1699 if (af->nvls == af->max_vls) {
1700 pr_warning("Too many( > %d) probe point found.\n", af->max_vls);
1701 return -ERANGE;
1702 }
1703 vl = &af->vls[af->nvls++];
1704
1705 ret = convert_to_trace_point(sp_die, pf->addr, pf->pev->point.retprobe,
1706 &vl->point);
1707 if (ret < 0)
1708 return ret;
1709
1710 pr_debug("Probe point found: %s+%lu\n", vl->point.symbol,
1711 vl->point.offset);
1712
1713 /* Find local variables */
1714 vl->vars = strlist__new(true, NULL);
1715 if (vl->vars == NULL)
1716 return -ENOMEM;
1717 af->child = true;
1718 die_find_child(sp_die, collect_variables_cb, (void *)af, &die_mem);
1719
1720 /* Find external variables */
1721 if (!af->externs)
1722 goto out;
1723 /* Don't need to search child DIE for externs. */
1724 af->child = false;
1725 nscopes = dwarf_getscopes_die(sp_die, &scopes);
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
1732out:
1733 if (strlist__empty(vl->vars)) {
1734 strlist__delete(vl->vars);
1735 vl->vars = NULL;
1736 }
1737
1738 return ret;
1739}
1740
1741/* Find available variables at given probe point */
1742int find_available_vars_at(int fd, struct perf_probe_event *pev,
1743 struct variable_list **vls, int max_vls,
1744 bool externs)
1745{
1746 struct available_var_finder af = {
1747 .pf = {.pev = pev, .callback = add_available_vars},
1748 .max_vls = max_vls, .externs = externs};
1749 int ret;
1750
1751 /* Allocate result vls array */
1752 *vls = zalloc(sizeof(struct variable_list) * max_vls);
1753 if (*vls == NULL)
1754 return -ENOMEM;
1755
1756 af.vls = *vls;
1757 af.nvls = 0;
1758
1759 ret = find_probes(fd, &af.pf);
1760 if (ret < 0) {
1761 /* Free vlist for error */
1762 while (af.nvls--) {
1763 if (af.vls[af.nvls].point.symbol)
1764 free(af.vls[af.nvls].point.symbol);
1765 if (af.vls[af.nvls].vars)
1766 strlist__delete(af.vls[af.nvls].vars);
1767 }
1768 free(af.vls);
1769 *vls = NULL;
1770 return ret;
1771 }
1772
1773 return (ret < 0) ? ret : af.nvls;
1146} 1774}
1147 1775
1148/* Reverse search */ 1776/* Reverse search */
1149int find_perf_probe_point(int fd, unsigned long addr, 1777int find_perf_probe_point(unsigned long addr, struct perf_probe_point *ppt)
1150 struct perf_probe_point *ppt)
1151{ 1778{
1152 Dwarf_Die cudie, spdie, indie; 1779 Dwarf_Die cudie, spdie, indie;
1153 Dwarf *dbg; 1780 Dwarf *dbg = NULL;
1154 Dwarf_Line *line; 1781 Dwfl *dwfl = NULL;
1155 Dwarf_Addr laddr, eaddr; 1782 Dwarf_Addr _addr, baseaddr, bias = 0;
1156 const char *tmp; 1783 const char *fname = NULL, *func = NULL, *tmp;
1157 int lineno, ret = 0; 1784 int baseline = 0, lineno = 0, ret = 0;
1158 bool found = false; 1785
1159 1786 /* Open the live linux kernel */
1160 dbg = dwarf_begin(fd, DWARF_C_READ); 1787 dbg = dwfl_init_live_kernel_dwarf(addr, &dwfl, &bias);
1161 if (!dbg) 1788 if (!dbg) {
1162 return -EBADF; 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 }
1163 1794
1795 /* Adjust address with bias */
1796 addr += bias;
1164 /* Find cu die */ 1797 /* Find cu die */
1165 if (!dwarf_addrdie(dbg, (Dwarf_Addr)addr, &cudie)) { 1798 if (!dwarf_addrdie(dbg, (Dwarf_Addr)addr - bias, &cudie)) {
1799 pr_warning("Failed to find debug information for address %lx\n",
1800 addr);
1166 ret = -EINVAL; 1801 ret = -EINVAL;
1167 goto end; 1802 goto end;
1168 } 1803 }
1169 1804
1170 /* Find a corresponding line */ 1805 /* Find a corresponding line (filename and lineno) */
1171 line = dwarf_getsrc_die(&cudie, (Dwarf_Addr)addr); 1806 cu_find_lineinfo(&cudie, addr, &fname, &lineno);
1172 if (line) { 1807 /* Don't care whether it failed or not */
1173 if (dwarf_lineaddr(line, &laddr) == 0 &&
1174 (Dwarf_Addr)addr == laddr &&
1175 dwarf_lineno(line, &lineno) == 0) {
1176 tmp = dwarf_linesrc(line, NULL, NULL);
1177 if (tmp) {
1178 ppt->line = lineno;
1179 ppt->file = strdup(tmp);
1180 if (ppt->file == NULL) {
1181 ret = -ENOMEM;
1182 goto end;
1183 }
1184 found = true;
1185 }
1186 }
1187 }
1188 1808
1189 /* Find a corresponding function */ 1809 /* Find a corresponding function (name, baseline and baseaddr) */
1190 if (die_find_real_subprogram(&cudie, (Dwarf_Addr)addr, &spdie)) { 1810 if (die_find_real_subprogram(&cudie, (Dwarf_Addr)addr, &spdie)) {
1811 /* Get function entry information */
1191 tmp = dwarf_diename(&spdie); 1812 tmp = dwarf_diename(&spdie);
1192 if (!tmp || dwarf_entrypc(&spdie, &eaddr) != 0) 1813 if (!tmp ||
1193 goto end; 1814 dwarf_entrypc(&spdie, &baseaddr) != 0 ||
1194 1815 dwarf_decl_line(&spdie, &baseline) != 0)
1195 if (ppt->line) { 1816 goto post;
1196 if (die_find_inlinefunc(&spdie, (Dwarf_Addr)addr, 1817 func = tmp;
1197 &indie)) { 1818
1198 /* addr in an inline function */ 1819 if (addr == (unsigned long)baseaddr)
1820 /* Function entry - Relative line number is 0 */
1821 lineno = baseline;
1822 else if (die_find_inlinefunc(&spdie, (Dwarf_Addr)addr,
1823 &indie)) {
1824 if (dwarf_entrypc(&indie, &_addr) == 0 &&
1825 _addr == addr)
1826 /*
1827 * addr is at an inline function entry.
1828 * In this case, lineno should be the call-site
1829 * line number.
1830 */
1831 lineno = die_get_call_lineno(&indie);
1832 else {
1833 /*
1834 * addr is in an inline function body.
1835 * Since lineno points one of the lines
1836 * of the inline function, baseline should
1837 * be the entry line of the inline function.
1838 */
1199 tmp = dwarf_diename(&indie); 1839 tmp = dwarf_diename(&indie);
1200 if (!tmp) 1840 if (tmp &&
1201 goto end; 1841 dwarf_decl_line(&spdie, &baseline) == 0)
1202 ret = dwarf_decl_line(&indie, &lineno); 1842 func = tmp;
1203 } else {
1204 if (eaddr == addr) { /* Function entry */
1205 lineno = ppt->line;
1206 ret = 0;
1207 } else
1208 ret = dwarf_decl_line(&spdie, &lineno);
1209 }
1210 if (ret == 0) {
1211 /* Make a relative line number */
1212 ppt->line -= lineno;
1213 goto found;
1214 } 1843 }
1215 } 1844 }
1216 /* We don't have a line number, let's use offset */ 1845 }
1217 ppt->offset = addr - (unsigned long)eaddr; 1846
1218found: 1847post:
1219 ppt->function = strdup(tmp); 1848 /* Make a relative line number or an offset */
1849 if (lineno)
1850 ppt->line = lineno - baseline;
1851 else if (func)
1852 ppt->offset = addr - (unsigned long)baseaddr;
1853
1854 /* Duplicate strings */
1855 if (func) {
1856 ppt->function = strdup(func);
1220 if (ppt->function == NULL) { 1857 if (ppt->function == NULL) {
1221 ret = -ENOMEM; 1858 ret = -ENOMEM;
1222 goto end; 1859 goto end;
1223 } 1860 }
1224 found = true;
1225 } 1861 }
1226 1862 if (fname) {
1863 ppt->file = strdup(fname);
1864 if (ppt->file == NULL) {
1865 if (ppt->function) {
1866 free(ppt->function);
1867 ppt->function = NULL;
1868 }
1869 ret = -ENOMEM;
1870 goto end;
1871 }
1872 }
1227end: 1873end:
1228 dwarf_end(dbg); 1874 if (dwfl)
1229 if (ret >= 0) 1875 dwfl_end(dwfl);
1230 ret = found ? 1 : 0; 1876 if (ret == 0 && (fname || func))
1877 ret = 1; /* Found a point */
1231 return ret; 1878 return ret;
1232} 1879}
1233 1880
@@ -1244,91 +1891,28 @@ static int line_range_add_line(const char *src, unsigned int lineno,
1244 return line_list__add_line(&lr->line_list, lineno); 1891 return line_list__add_line(&lr->line_list, lineno);
1245} 1892}
1246 1893
1247/* Search function declaration lines */ 1894static int line_range_walk_cb(const char *fname, int lineno,
1248static int line_range_funcdecl_cb(Dwarf_Die *sp_die, void *data) 1895 Dwarf_Addr addr __used,
1896 void *data)
1249{ 1897{
1250 struct dwarf_callback_param *param = data; 1898 struct line_finder *lf = data;
1251 struct line_finder *lf = param->data;
1252 const char *src;
1253 int lineno;
1254 1899
1255 src = dwarf_decl_file(sp_die); 1900 if ((strtailcmp(fname, lf->fname) != 0) ||
1256 if (src && strtailcmp(src, lf->fname) != 0)
1257 return DWARF_CB_OK;
1258
1259 if (dwarf_decl_line(sp_die, &lineno) != 0 ||
1260 (lf->lno_s > lineno || lf->lno_e < lineno)) 1901 (lf->lno_s > lineno || lf->lno_e < lineno))
1261 return DWARF_CB_OK; 1902 return 0;
1262 1903
1263 param->retval = line_range_add_line(src, lineno, lf->lr); 1904 if (line_range_add_line(fname, lineno, lf->lr) < 0)
1264 if (param->retval < 0) 1905 return -EINVAL;
1265 return DWARF_CB_ABORT;
1266 return DWARF_CB_OK;
1267}
1268 1906
1269static int find_line_range_func_decl_lines(struct line_finder *lf) 1907 return 0;
1270{
1271 struct dwarf_callback_param param = {.data = (void *)lf, .retval = 0};
1272 dwarf_getfuncs(&lf->cu_die, line_range_funcdecl_cb, &param, 0);
1273 return param.retval;
1274} 1908}
1275 1909
1276/* Find line range from its line number */ 1910/* Find line range from its line number */
1277static int find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf) 1911static int find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf)
1278{ 1912{
1279 Dwarf_Lines *lines; 1913 int ret;
1280 Dwarf_Line *line;
1281 size_t nlines, i;
1282 Dwarf_Addr addr;
1283 int lineno, ret = 0;
1284 const char *src;
1285 Dwarf_Die die_mem;
1286
1287 line_list__init(&lf->lr->line_list);
1288 if (dwarf_getsrclines(&lf->cu_die, &lines, &nlines) != 0) {
1289 pr_warning("No source lines found in this CU.\n");
1290 return -ENOENT;
1291 }
1292
1293 /* Search probable lines on lines list */
1294 for (i = 0; i < nlines; i++) {
1295 line = dwarf_onesrcline(lines, i);
1296 if (dwarf_lineno(line, &lineno) != 0 ||
1297 (lf->lno_s > lineno || lf->lno_e < lineno))
1298 continue;
1299
1300 if (sp_die) {
1301 /* Address filtering 1: does sp_die include addr? */
1302 if (dwarf_lineaddr(line, &addr) != 0 ||
1303 !dwarf_haspc(sp_die, addr))
1304 continue;
1305
1306 /* Address filtering 2: No child include addr? */
1307 if (die_find_inlinefunc(sp_die, addr, &die_mem))
1308 continue;
1309 }
1310
1311 /* TODO: Get fileno from line, but how? */
1312 src = dwarf_linesrc(line, NULL, NULL);
1313 if (strtailcmp(src, lf->fname) != 0)
1314 continue;
1315 1914
1316 ret = line_range_add_line(src, lineno, lf->lr); 1915 ret = die_walk_lines(sp_die ?: &lf->cu_die, line_range_walk_cb, lf);
1317 if (ret < 0)
1318 return ret;
1319 }
1320
1321 /*
1322 * Dwarf lines doesn't include function declarations. We have to
1323 * check functions list or given function.
1324 */
1325 if (sp_die) {
1326 src = dwarf_decl_file(sp_die);
1327 if (src && dwarf_decl_line(sp_die, &lineno) == 0 &&
1328 (lf->lno_s <= lineno && lf->lno_e >= lineno))
1329 ret = line_range_add_line(src, lineno, lf->lr);
1330 } else
1331 ret = find_line_range_func_decl_lines(lf);
1332 1916
1333 /* Update status */ 1917 /* Update status */
1334 if (ret >= 0) 1918 if (ret >= 0)
@@ -1358,6 +1942,10 @@ static int line_range_search_cb(Dwarf_Die *sp_die, void *data)
1358 struct line_finder *lf = param->data; 1942 struct line_finder *lf = param->data;
1359 struct line_range *lr = lf->lr; 1943 struct line_range *lr = lf->lr;
1360 1944
1945 /* Check declared file */
1946 if (lr->file && strtailcmp(lr->file, dwarf_decl_file(sp_die)))
1947 return DWARF_CB_OK;
1948
1361 if (dwarf_tag(sp_die) == DW_TAG_subprogram && 1949 if (dwarf_tag(sp_die) == DW_TAG_subprogram &&
1362 die_compare_name(sp_die, lr->function)) { 1950 die_compare_name(sp_die, lr->function)) {
1363 lf->fname = dwarf_decl_file(sp_die); 1951 lf->fname = dwarf_decl_file(sp_die);
@@ -1401,16 +1989,35 @@ int find_line_range(int fd, struct line_range *lr)
1401 Dwarf_Off off = 0, noff; 1989 Dwarf_Off off = 0, noff;
1402 size_t cuhl; 1990 size_t cuhl;
1403 Dwarf_Die *diep; 1991 Dwarf_Die *diep;
1404 Dwarf *dbg; 1992 Dwarf *dbg = NULL;
1993 Dwfl *dwfl;
1994 Dwarf_Addr bias; /* Currently ignored */
1405 const char *comp_dir; 1995 const char *comp_dir;
1406 1996
1407 dbg = dwarf_begin(fd, DWARF_C_READ); 1997 dbg = dwfl_init_offline_dwarf(fd, &dwfl, &bias);
1408 if (!dbg) { 1998 if (!dbg) {
1409 pr_warning("No dwarf info found in the vmlinux - " 1999 pr_warning("No debug information found in the vmlinux - "
1410 "please rebuild with CONFIG_DEBUG_INFO=y.\n"); 2000 "please rebuild with CONFIG_DEBUG_INFO=y.\n");
2001 close(fd); /* Without dwfl_end(), fd isn't closed. */
1411 return -EBADF; 2002 return -EBADF;
1412 } 2003 }
1413 2004
2005 /* Fastpath: lookup by function name from .debug_pubnames section */
2006 if (lr->function) {
2007 struct pubname_callback_param pubname_param = {
2008 .function = lr->function, .file = lr->file,
2009 .cu_die = &lf.cu_die, .sp_die = &lf.sp_die, .found = 0};
2010 struct dwarf_callback_param line_range_param = {
2011 .data = (void *)&lf, .retval = 0};
2012
2013 dwarf_getpubnames(dbg, pubname_search_cb, &pubname_param, 0);
2014 if (pubname_param.found) {
2015 line_range_search_cb(&lf.sp_die, &line_range_param);
2016 if (lf.found)
2017 goto found;
2018 }
2019 }
2020
1414 /* Loop on CUs (Compilation Unit) */ 2021 /* Loop on CUs (Compilation Unit) */
1415 while (!lf.found && ret >= 0) { 2022 while (!lf.found && ret >= 0) {
1416 if (dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL) != 0) 2023 if (dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL) != 0)
@@ -1439,6 +2046,7 @@ int find_line_range(int fd, struct line_range *lr)
1439 off = noff; 2046 off = noff;
1440 } 2047 }
1441 2048
2049found:
1442 /* Store comp_dir */ 2050 /* Store comp_dir */
1443 if (lf.found) { 2051 if (lf.found) {
1444 comp_dir = cu_get_comp_dir(&lf.cu_die); 2052 comp_dir = cu_get_comp_dir(&lf.cu_die);
@@ -1450,8 +2058,7 @@ int find_line_range(int fd, struct line_range *lr)
1450 } 2058 }
1451 2059
1452 pr_debug("path: %s\n", lr->path); 2060 pr_debug("path: %s\n", lr->path);
1453 dwarf_end(dbg); 2061 dwfl_end(dwfl);
1454
1455 return (ret < 0) ? ret : lf.found; 2062 return (ret < 0) ? ret : lf.found;
1456} 2063}
1457 2064