• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * probe-finder.c : C expression to kprobe event converter
3  *
4  * Written by Masami Hiramatsu <mhiramat@redhat.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  *
20  */
21 
22 #include <sys/utsname.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <fcntl.h>
26 #include <errno.h>
27 #include <stdio.h>
28 #include <unistd.h>
29 #include <getopt.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <stdarg.h>
33 #include <ctype.h>
34 /* ANDROID_CHANGE_BEGIN */
35 #if 0
36 #include <dwarf-regs.h>
37 #include <linux/bitops.h>
38 #else
39 #include "include/dwarf-regs.h"
40 #include "include/linux/bitops.h"
41 #endif
42 /* ANDROID_CHANGE_END */
43 
44 #include "event.h"
45 #include "debug.h"
46 #include "util.h"
47 #include "symbol.h"
48 #include "probe-finder.h"
49 
50 /* Kprobe tracer basic type is up to u64 */
51 #define MAX_BASIC_TYPE_BITS	64
52 
53 /*
54  * Compare the tail of two strings.
55  * Return 0 if whole of either string is same as another's tail part.
56  */
strtailcmp(const char * s1,const char * s2)57 static int strtailcmp(const char *s1, const char *s2)
58 {
59 	int i1 = strlen(s1);
60 	int i2 = strlen(s2);
61 	while (--i1 >= 0 && --i2 >= 0) {
62 		if (s1[i1] != s2[i2])
63 			return s1[i1] - s2[i2];
64 	}
65 	return 0;
66 }
67 
68 /* Line number list operations */
69 
70 /* Add a line to line number list */
line_list__add_line(struct list_head * head,int line)71 static int line_list__add_line(struct list_head *head, int line)
72 {
73 	struct line_node *ln;
74 	struct list_head *p;
75 
76 	/* Reverse search, because new line will be the last one */
77 	list_for_each_entry_reverse(ln, head, list) {
78 		if (ln->line < line) {
79 			p = &ln->list;
80 			goto found;
81 		} else if (ln->line == line)	/* Already exist */
82 			return 1;
83 	}
84 	/* List is empty, or the smallest entry */
85 	p = head;
86 found:
87 	pr_debug("line list: add a line %u\n", line);
88 	ln = zalloc(sizeof(struct line_node));
89 	if (ln == NULL)
90 		return -ENOMEM;
91 	ln->line = line;
92 	INIT_LIST_HEAD(&ln->list);
93 	list_add(&ln->list, p);
94 	return 0;
95 }
96 
97 /* Check if the line in line number list */
line_list__has_line(struct list_head * head,int line)98 static int line_list__has_line(struct list_head *head, int line)
99 {
100 	struct line_node *ln;
101 
102 	/* Reverse search, because new line will be the last one */
103 	list_for_each_entry(ln, head, list)
104 		if (ln->line == line)
105 			return 1;
106 
107 	return 0;
108 }
109 
110 /* Init line number list */
line_list__init(struct list_head * head)111 static void line_list__init(struct list_head *head)
112 {
113 	INIT_LIST_HEAD(head);
114 }
115 
116 /* Free line number list */
line_list__free(struct list_head * head)117 static void line_list__free(struct list_head *head)
118 {
119 	struct line_node *ln;
120 	while (!list_empty(head)) {
121 		ln = list_first_entry(head, struct line_node, list);
122 		list_del(&ln->list);
123 		free(ln);
124 	}
125 }
126 
127 /* Dwarf FL wrappers */
128 static char *debuginfo_path;	/* Currently dummy */
129 
130 static const Dwfl_Callbacks offline_callbacks = {
131 	.find_debuginfo = dwfl_standard_find_debuginfo,
132 	.debuginfo_path = &debuginfo_path,
133 
134 	.section_address = dwfl_offline_section_address,
135 
136 	/* We use this table for core files too.  */
137 	.find_elf = dwfl_build_id_find_elf,
138 };
139 
140 /* Get a Dwarf from offline image */
dwfl_init_offline_dwarf(int fd,Dwfl ** dwflp,Dwarf_Addr * bias)141 static Dwarf *dwfl_init_offline_dwarf(int fd, Dwfl **dwflp, Dwarf_Addr *bias)
142 {
143 	Dwfl_Module *mod;
144 	Dwarf *dbg = NULL;
145 
146 	if (!dwflp)
147 		return NULL;
148 
149 	*dwflp = dwfl_begin(&offline_callbacks);
150 	if (!*dwflp)
151 		return NULL;
152 
153 	mod = dwfl_report_offline(*dwflp, "", "", fd);
154 	if (!mod)
155 		goto error;
156 
157 	dbg = dwfl_module_getdwarf(mod, bias);
158 	if (!dbg) {
159 error:
160 		dwfl_end(*dwflp);
161 		*dwflp = NULL;
162 	}
163 	return dbg;
164 }
165 
166 #if _ELFUTILS_PREREQ(0, 148)
167 /* This method is buggy if elfutils is older than 0.148 */
__linux_kernel_find_elf(Dwfl_Module * mod,void ** userdata,const char * module_name,Dwarf_Addr base,char ** file_name,Elf ** elfp)168 static int __linux_kernel_find_elf(Dwfl_Module *mod,
169 				   void **userdata,
170 				   const char *module_name,
171 				   Dwarf_Addr base,
172 				   char **file_name, Elf **elfp)
173 {
174 	int fd;
175 	const char *path = kernel_get_module_path(module_name);
176 
177 	pr_debug2("Use file %s for %s\n", path, module_name);
178 	if (path) {
179 		fd = open(path, O_RDONLY);
180 		if (fd >= 0) {
181 			*file_name = strdup(path);
182 			return fd;
183 		}
184 	}
185 	/* If failed, try to call standard method */
186 	return dwfl_linux_kernel_find_elf(mod, userdata, module_name, base,
187 					  file_name, elfp);
188 }
189 
190 static const Dwfl_Callbacks kernel_callbacks = {
191 	.find_debuginfo = dwfl_standard_find_debuginfo,
192 	.debuginfo_path = &debuginfo_path,
193 
194 	.find_elf = __linux_kernel_find_elf,
195 	.section_address = dwfl_linux_kernel_module_section_address,
196 };
197 
198 /* Get a Dwarf from live kernel image */
dwfl_init_live_kernel_dwarf(Dwarf_Addr addr,Dwfl ** dwflp,Dwarf_Addr * bias)199 static Dwarf *dwfl_init_live_kernel_dwarf(Dwarf_Addr addr, Dwfl **dwflp,
200 					  Dwarf_Addr *bias)
201 {
202 	Dwarf *dbg;
203 
204 	if (!dwflp)
205 		return NULL;
206 
207 	*dwflp = dwfl_begin(&kernel_callbacks);
208 	if (!*dwflp)
209 		return NULL;
210 
211 	/* Load the kernel dwarves: Don't care the result here */
212 	dwfl_linux_kernel_report_kernel(*dwflp);
213 	dwfl_linux_kernel_report_modules(*dwflp);
214 
215 	dbg = dwfl_addrdwarf(*dwflp, addr, bias);
216 	/* Here, check whether we could get a real dwarf */
217 	if (!dbg) {
218 		pr_debug("Failed to find kernel dwarf at %lx\n",
219 			 (unsigned long)addr);
220 		dwfl_end(*dwflp);
221 		*dwflp = NULL;
222 	}
223 	return dbg;
224 }
225 #else
226 /* With older elfutils, this just support kernel module... */
dwfl_init_live_kernel_dwarf(Dwarf_Addr addr __used,Dwfl ** dwflp,Dwarf_Addr * bias)227 static Dwarf *dwfl_init_live_kernel_dwarf(Dwarf_Addr addr __used, Dwfl **dwflp,
228 					  Dwarf_Addr *bias)
229 {
230 	int fd;
231 	const char *path = kernel_get_module_path("kernel");
232 
233 	if (!path) {
234 		pr_err("Failed to find vmlinux path\n");
235 		return NULL;
236 	}
237 
238 	pr_debug2("Use file %s for debuginfo\n", path);
239 	fd = open(path, O_RDONLY);
240 	if (fd < 0)
241 		return NULL;
242 
243 	return dwfl_init_offline_dwarf(fd, dwflp, bias);
244 }
245 #endif
246 
247 /* Dwarf wrappers */
248 
249 /* Find the realpath of the target file. */
cu_find_realpath(Dwarf_Die * cu_die,const char * fname)250 static const char *cu_find_realpath(Dwarf_Die *cu_die, const char *fname)
251 {
252 	Dwarf_Files *files;
253 	size_t nfiles, i;
254 	const char *src = NULL;
255 	int ret;
256 
257 	if (!fname)
258 		return NULL;
259 
260 	ret = dwarf_getsrcfiles(cu_die, &files, &nfiles);
261 	if (ret != 0)
262 		return NULL;
263 
264 	for (i = 0; i < nfiles; i++) {
265 		src = dwarf_filesrc(files, i, NULL, NULL);
266 		if (strtailcmp(src, fname) == 0)
267 			break;
268 	}
269 	if (i == nfiles)
270 		return NULL;
271 	return src;
272 }
273 
274 /* Get DW_AT_comp_dir (should be NULL with older gcc) */
cu_get_comp_dir(Dwarf_Die * cu_die)275 static const char *cu_get_comp_dir(Dwarf_Die *cu_die)
276 {
277 	Dwarf_Attribute attr;
278 	if (dwarf_attr(cu_die, DW_AT_comp_dir, &attr) == NULL)
279 		return NULL;
280 	return dwarf_formstring(&attr);
281 }
282 
283 /* Get a line number and file name for given address */
cu_find_lineinfo(Dwarf_Die * cudie,unsigned long addr,const char ** fname,int * lineno)284 static int cu_find_lineinfo(Dwarf_Die *cudie, unsigned long addr,
285 			    const char **fname, int *lineno)
286 {
287 	Dwarf_Line *line;
288 	Dwarf_Addr laddr;
289 
290 	line = dwarf_getsrc_die(cudie, (Dwarf_Addr)addr);
291 	if (line && dwarf_lineaddr(line, &laddr) == 0 &&
292 	    addr == (unsigned long)laddr && dwarf_lineno(line, lineno) == 0) {
293 		*fname = dwarf_linesrc(line, NULL, NULL);
294 		if (!*fname)
295 			/* line number is useless without filename */
296 			*lineno = 0;
297 	}
298 
299 	return *lineno ?: -ENOENT;
300 }
301 
302 /* Compare diename and tname */
die_compare_name(Dwarf_Die * dw_die,const char * tname)303 static bool die_compare_name(Dwarf_Die *dw_die, const char *tname)
304 {
305 	const char *name;
306 	name = dwarf_diename(dw_die);
307 	return name ? (strcmp(tname, name) == 0) : false;
308 }
309 
310 /* Get callsite line number of inline-function instance */
die_get_call_lineno(Dwarf_Die * in_die)311 static int die_get_call_lineno(Dwarf_Die *in_die)
312 {
313 	Dwarf_Attribute attr;
314 	Dwarf_Word ret;
315 
316 	if (!dwarf_attr(in_die, DW_AT_call_line, &attr))
317 		return -ENOENT;
318 
319 	dwarf_formudata(&attr, &ret);
320 	return (int)ret;
321 }
322 
323 /* Get type die */
die_get_type(Dwarf_Die * vr_die,Dwarf_Die * die_mem)324 static Dwarf_Die *die_get_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem)
325 {
326 	Dwarf_Attribute attr;
327 
328 	if (dwarf_attr_integrate(vr_die, DW_AT_type, &attr) &&
329 	    dwarf_formref_die(&attr, die_mem))
330 		return die_mem;
331 	else
332 		return NULL;
333 }
334 
335 /* Get a type die, but skip qualifiers */
__die_get_real_type(Dwarf_Die * vr_die,Dwarf_Die * die_mem)336 static Dwarf_Die *__die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem)
337 {
338 	int tag;
339 
340 	do {
341 		vr_die = die_get_type(vr_die, die_mem);
342 		if (!vr_die)
343 			break;
344 		tag = dwarf_tag(vr_die);
345 	} while (tag == DW_TAG_const_type ||
346 		 tag == DW_TAG_restrict_type ||
347 		 tag == DW_TAG_volatile_type ||
348 		 tag == DW_TAG_shared_type);
349 
350 	return vr_die;
351 }
352 
353 /* Get a type die, but skip qualifiers and typedef */
die_get_real_type(Dwarf_Die * vr_die,Dwarf_Die * die_mem)354 static Dwarf_Die *die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem)
355 {
356 	do {
357 		vr_die = __die_get_real_type(vr_die, die_mem);
358 	} while (vr_die && dwarf_tag(vr_die) == DW_TAG_typedef);
359 
360 	return vr_die;
361 }
362 
die_get_attr_udata(Dwarf_Die * tp_die,unsigned int attr_name,Dwarf_Word * result)363 static int die_get_attr_udata(Dwarf_Die *tp_die, unsigned int attr_name,
364 			      Dwarf_Word *result)
365 {
366 	Dwarf_Attribute attr;
367 
368 	if (dwarf_attr(tp_die, attr_name, &attr) == NULL ||
369 	    dwarf_formudata(&attr, result) != 0)
370 		return -ENOENT;
371 
372 	return 0;
373 }
374 
die_is_signed_type(Dwarf_Die * tp_die)375 static bool die_is_signed_type(Dwarf_Die *tp_die)
376 {
377 	Dwarf_Word ret;
378 
379 	if (die_get_attr_udata(tp_die, DW_AT_encoding, &ret))
380 		return false;
381 
382 	return (ret == DW_ATE_signed_char || ret == DW_ATE_signed ||
383 		ret == DW_ATE_signed_fixed);
384 }
385 
die_get_byte_size(Dwarf_Die * tp_die)386 static int die_get_byte_size(Dwarf_Die *tp_die)
387 {
388 	Dwarf_Word ret;
389 
390 	if (die_get_attr_udata(tp_die, DW_AT_byte_size, &ret))
391 		return 0;
392 
393 	return (int)ret;
394 }
395 
die_get_bit_size(Dwarf_Die * tp_die)396 static int die_get_bit_size(Dwarf_Die *tp_die)
397 {
398 	Dwarf_Word ret;
399 
400 	if (die_get_attr_udata(tp_die, DW_AT_bit_size, &ret))
401 		return 0;
402 
403 	return (int)ret;
404 }
405 
die_get_bit_offset(Dwarf_Die * tp_die)406 static int die_get_bit_offset(Dwarf_Die *tp_die)
407 {
408 	Dwarf_Word ret;
409 
410 	if (die_get_attr_udata(tp_die, DW_AT_bit_offset, &ret))
411 		return 0;
412 
413 	return (int)ret;
414 }
415 
416 /* Get data_member_location offset */
die_get_data_member_location(Dwarf_Die * mb_die,Dwarf_Word * offs)417 static int die_get_data_member_location(Dwarf_Die *mb_die, Dwarf_Word *offs)
418 {
419 	Dwarf_Attribute attr;
420 	Dwarf_Op *expr;
421 	size_t nexpr;
422 	int ret;
423 
424 	if (dwarf_attr(mb_die, DW_AT_data_member_location, &attr) == NULL)
425 		return -ENOENT;
426 
427 	if (dwarf_formudata(&attr, offs) != 0) {
428 		/* DW_AT_data_member_location should be DW_OP_plus_uconst */
429 		ret = dwarf_getlocation(&attr, &expr, &nexpr);
430 		if (ret < 0 || nexpr == 0)
431 			return -ENOENT;
432 
433 		if (expr[0].atom != DW_OP_plus_uconst || nexpr != 1) {
434 			pr_debug("Unable to get offset:Unexpected OP %x (%zd)\n",
435 				 expr[0].atom, nexpr);
436 			return -ENOTSUP;
437 		}
438 		*offs = (Dwarf_Word)expr[0].number;
439 	}
440 	return 0;
441 }
442 
443 /* Return values for die_find callbacks */
444 enum {
445 	DIE_FIND_CB_FOUND = 0,		/* End of Search */
446 	DIE_FIND_CB_CHILD = 1,		/* Search only children */
447 	DIE_FIND_CB_SIBLING = 2,	/* Search only siblings */
448 	DIE_FIND_CB_CONTINUE = 3,	/* Search children and siblings */
449 };
450 
451 /* Search a child die */
die_find_child(Dwarf_Die * rt_die,int (* callback)(Dwarf_Die *,void *),void * data,Dwarf_Die * die_mem)452 static Dwarf_Die *die_find_child(Dwarf_Die *rt_die,
453 				 int (*callback)(Dwarf_Die *, void *),
454 				 void *data, Dwarf_Die *die_mem)
455 {
456 	Dwarf_Die child_die;
457 	int ret;
458 
459 	ret = dwarf_child(rt_die, die_mem);
460 	if (ret != 0)
461 		return NULL;
462 
463 	do {
464 		ret = callback(die_mem, data);
465 		if (ret == DIE_FIND_CB_FOUND)
466 			return die_mem;
467 
468 		if ((ret & DIE_FIND_CB_CHILD) &&
469 		    die_find_child(die_mem, callback, data, &child_die)) {
470 			memcpy(die_mem, &child_die, sizeof(Dwarf_Die));
471 			return die_mem;
472 		}
473 	} while ((ret & DIE_FIND_CB_SIBLING) &&
474 		 dwarf_siblingof(die_mem, die_mem) == 0);
475 
476 	return NULL;
477 }
478 
479 struct __addr_die_search_param {
480 	Dwarf_Addr	addr;
481 	Dwarf_Die	*die_mem;
482 };
483 
__die_search_func_cb(Dwarf_Die * fn_die,void * data)484 static int __die_search_func_cb(Dwarf_Die *fn_die, void *data)
485 {
486 	struct __addr_die_search_param *ad = data;
487 
488 	if (dwarf_tag(fn_die) == DW_TAG_subprogram &&
489 	    dwarf_haspc(fn_die, ad->addr)) {
490 		memcpy(ad->die_mem, fn_die, sizeof(Dwarf_Die));
491 		return DWARF_CB_ABORT;
492 	}
493 	return DWARF_CB_OK;
494 }
495 
496 /* Search a real subprogram including this line, */
die_find_real_subprogram(Dwarf_Die * cu_die,Dwarf_Addr addr,Dwarf_Die * die_mem)497 static Dwarf_Die *die_find_real_subprogram(Dwarf_Die *cu_die, Dwarf_Addr addr,
498 					   Dwarf_Die *die_mem)
499 {
500 	struct __addr_die_search_param ad;
501 	ad.addr = addr;
502 	ad.die_mem = die_mem;
503 	/* dwarf_getscopes can't find subprogram. */
504 	if (!dwarf_getfuncs(cu_die, __die_search_func_cb, &ad, 0))
505 		return NULL;
506 	else
507 		return die_mem;
508 }
509 
510 /* die_find callback for inline function search */
__die_find_inline_cb(Dwarf_Die * die_mem,void * data)511 static int __die_find_inline_cb(Dwarf_Die *die_mem, void *data)
512 {
513 	Dwarf_Addr *addr = data;
514 
515 	if (dwarf_tag(die_mem) == DW_TAG_inlined_subroutine &&
516 	    dwarf_haspc(die_mem, *addr))
517 		return DIE_FIND_CB_FOUND;
518 
519 	return DIE_FIND_CB_CONTINUE;
520 }
521 
522 /* Similar to dwarf_getfuncs, but returns inlined_subroutine if exists. */
die_find_inlinefunc(Dwarf_Die * sp_die,Dwarf_Addr addr,Dwarf_Die * die_mem)523 static Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
524 				      Dwarf_Die *die_mem)
525 {
526 	Dwarf_Die tmp_die;
527 
528 	sp_die = die_find_child(sp_die, __die_find_inline_cb, &addr, &tmp_die);
529 	if (!sp_die)
530 		return NULL;
531 
532 	/* Inlined function could be recursive. Trace it until fail */
533 	while (sp_die) {
534 		memcpy(die_mem, sp_die, sizeof(Dwarf_Die));
535 		sp_die = die_find_child(sp_die, __die_find_inline_cb, &addr,
536 					&tmp_die);
537 	}
538 
539 	return die_mem;
540 }
541 
542 /* Walker on lines (Note: line number will not be sorted) */
543 typedef int (* line_walk_handler_t) (const char *fname, int lineno,
544 				     Dwarf_Addr addr, void *data);
545 
546 struct __line_walk_param {
547 	const char *fname;
548 	line_walk_handler_t handler;
549 	void *data;
550 	int retval;
551 };
552 
__die_walk_funclines_cb(Dwarf_Die * in_die,void * data)553 static int __die_walk_funclines_cb(Dwarf_Die *in_die, void *data)
554 {
555 	struct __line_walk_param *lw = data;
556 	Dwarf_Addr addr;
557 	int lineno;
558 
559 	if (dwarf_tag(in_die) == DW_TAG_inlined_subroutine) {
560 		lineno = die_get_call_lineno(in_die);
561 		if (lineno > 0 && dwarf_entrypc(in_die, &addr) == 0) {
562 			lw->retval = lw->handler(lw->fname, lineno, addr,
563 						 lw->data);
564 			if (lw->retval != 0)
565 				return DIE_FIND_CB_FOUND;
566 		}
567 	}
568 	return DIE_FIND_CB_SIBLING;
569 }
570 
571 /* Walk on lines of blocks included in given DIE */
__die_walk_funclines(Dwarf_Die * sp_die,line_walk_handler_t handler,void * data)572 static int __die_walk_funclines(Dwarf_Die *sp_die,
573 				line_walk_handler_t handler, void *data)
574 {
575 	struct __line_walk_param lw = {
576 		.handler = handler,
577 		.data = data,
578 		.retval = 0,
579 	};
580 	Dwarf_Die die_mem;
581 	Dwarf_Addr addr;
582 	int lineno;
583 
584 	/* Handle function declaration line */
585 	lw.fname = dwarf_decl_file(sp_die);
586 	if (lw.fname && dwarf_decl_line(sp_die, &lineno) == 0 &&
587 	    dwarf_entrypc(sp_die, &addr) == 0) {
588 		lw.retval = handler(lw.fname, lineno, addr, data);
589 		if (lw.retval != 0)
590 			goto done;
591 	}
592 	die_find_child(sp_die, __die_walk_funclines_cb, &lw, &die_mem);
593 done:
594 	return lw.retval;
595 }
596 
__die_walk_culines_cb(Dwarf_Die * sp_die,void * data)597 static int __die_walk_culines_cb(Dwarf_Die *sp_die, void *data)
598 {
599 	struct __line_walk_param *lw = data;
600 
601 	lw->retval = __die_walk_funclines(sp_die, lw->handler, lw->data);
602 	if (lw->retval != 0)
603 		return DWARF_CB_ABORT;
604 
605 	return DWARF_CB_OK;
606 }
607 
608 /*
609  * Walk on lines inside given PDIE. If the PDIE is subprogram, walk only on
610  * the lines inside the subprogram, otherwise PDIE must be a CU DIE.
611  */
die_walk_lines(Dwarf_Die * pdie,line_walk_handler_t handler,void * data)612 static int die_walk_lines(Dwarf_Die *pdie, line_walk_handler_t handler,
613 			  void *data)
614 {
615 	Dwarf_Lines *lines;
616 	Dwarf_Line *line;
617 	Dwarf_Addr addr;
618 	const char *fname;
619 	int lineno, ret = 0;
620 	Dwarf_Die die_mem, *cu_die;
621 	size_t nlines, i;
622 
623 	/* Get the CU die */
624 	if (dwarf_tag(pdie) == DW_TAG_subprogram)
625 		cu_die = dwarf_diecu(pdie, &die_mem, NULL, NULL);
626 	else
627 		cu_die = pdie;
628 	if (!cu_die) {
629 		pr_debug2("Failed to get CU from subprogram\n");
630 		return -EINVAL;
631 	}
632 
633 	/* Get lines list in the CU */
634 	if (dwarf_getsrclines(cu_die, &lines, &nlines) != 0) {
635 		pr_debug2("Failed to get source lines on this CU.\n");
636 		return -ENOENT;
637 	}
638 	pr_debug2("Get %zd lines from this CU\n", nlines);
639 
640 	/* Walk on the lines on lines list */
641 	for (i = 0; i < nlines; i++) {
642 		line = dwarf_onesrcline(lines, i);
643 		if (line == NULL ||
644 		    dwarf_lineno(line, &lineno) != 0 ||
645 		    dwarf_lineaddr(line, &addr) != 0) {
646 			pr_debug2("Failed to get line info. "
647 				  "Possible error in debuginfo.\n");
648 			continue;
649 		}
650 		/* Filter lines based on address */
651 		if (pdie != cu_die)
652 			/*
653 			 * Address filtering
654 			 * The line is included in given function, and
655 			 * no inline block includes it.
656 			 */
657 			if (!dwarf_haspc(pdie, addr) ||
658 			    die_find_inlinefunc(pdie, addr, &die_mem))
659 				continue;
660 		/* Get source line */
661 		fname = dwarf_linesrc(line, NULL, NULL);
662 
663 		ret = handler(fname, lineno, addr, data);
664 		if (ret != 0)
665 			return ret;
666 	}
667 
668 	/*
669 	 * Dwarf lines doesn't include function declarations and inlined
670 	 * subroutines. We have to check functions list or given function.
671 	 */
672 	if (pdie != cu_die)
673 		ret = __die_walk_funclines(pdie, handler, data);
674 	else {
675 		struct __line_walk_param param = {
676 			.handler = handler,
677 			.data = data,
678 			.retval = 0,
679 		};
680 		dwarf_getfuncs(cu_die, __die_walk_culines_cb, &param, 0);
681 		ret = param.retval;
682 	}
683 
684 	return ret;
685 }
686 
687 struct __find_variable_param {
688 	const char *name;
689 	Dwarf_Addr addr;
690 };
691 
__die_find_variable_cb(Dwarf_Die * die_mem,void * data)692 static int __die_find_variable_cb(Dwarf_Die *die_mem, void *data)
693 {
694 	struct __find_variable_param *fvp = data;
695 	int tag;
696 
697 	tag = dwarf_tag(die_mem);
698 	if ((tag == DW_TAG_formal_parameter ||
699 	     tag == DW_TAG_variable) &&
700 	    die_compare_name(die_mem, fvp->name))
701 		return DIE_FIND_CB_FOUND;
702 
703 	if (dwarf_haspc(die_mem, fvp->addr))
704 		return DIE_FIND_CB_CONTINUE;
705 	else
706 		return DIE_FIND_CB_SIBLING;
707 }
708 
709 /* Find a variable called 'name' at given address */
die_find_variable_at(Dwarf_Die * sp_die,const char * name,Dwarf_Addr addr,Dwarf_Die * die_mem)710 static Dwarf_Die *die_find_variable_at(Dwarf_Die *sp_die, const char *name,
711 				       Dwarf_Addr addr, Dwarf_Die *die_mem)
712 {
713 	struct __find_variable_param fvp = { .name = name, .addr = addr};
714 
715 	return die_find_child(sp_die, __die_find_variable_cb, (void *)&fvp,
716 			      die_mem);
717 }
718 
__die_find_member_cb(Dwarf_Die * die_mem,void * data)719 static int __die_find_member_cb(Dwarf_Die *die_mem, void *data)
720 {
721 	const char *name = data;
722 
723 	if ((dwarf_tag(die_mem) == DW_TAG_member) &&
724 	    die_compare_name(die_mem, name))
725 		return DIE_FIND_CB_FOUND;
726 
727 	return DIE_FIND_CB_SIBLING;
728 }
729 
730 /* Find a member called 'name' */
die_find_member(Dwarf_Die * st_die,const char * name,Dwarf_Die * die_mem)731 static Dwarf_Die *die_find_member(Dwarf_Die *st_die, const char *name,
732 				  Dwarf_Die *die_mem)
733 {
734 	return die_find_child(st_die, __die_find_member_cb, (void *)name,
735 			      die_mem);
736 }
737 
738 /* Get the name of given variable DIE */
die_get_typename(Dwarf_Die * vr_die,char * buf,int len)739 static int die_get_typename(Dwarf_Die *vr_die, char *buf, int len)
740 {
741 	Dwarf_Die type;
742 	int tag, ret, ret2;
743 	const char *tmp = "";
744 
745 	if (__die_get_real_type(vr_die, &type) == NULL)
746 		return -ENOENT;
747 
748 	tag = dwarf_tag(&type);
749 	if (tag == DW_TAG_array_type || tag == DW_TAG_pointer_type)
750 		tmp = "*";
751 	else if (tag == DW_TAG_subroutine_type) {
752 		/* Function pointer */
753 		ret = snprintf(buf, len, "(function_type)");
754 		return (ret >= len) ? -E2BIG : ret;
755 	} else {
756 		if (!dwarf_diename(&type))
757 			return -ENOENT;
758 		if (tag == DW_TAG_union_type)
759 			tmp = "union ";
760 		else if (tag == DW_TAG_structure_type)
761 			tmp = "struct ";
762 		/* Write a base name */
763 		ret = snprintf(buf, len, "%s%s", tmp, dwarf_diename(&type));
764 		return (ret >= len) ? -E2BIG : ret;
765 	}
766 	ret = die_get_typename(&type, buf, len);
767 	if (ret > 0) {
768 		ret2 = snprintf(buf + ret, len - ret, "%s", tmp);
769 		ret = (ret2 >= len - ret) ? -E2BIG : ret2 + ret;
770 	}
771 	return ret;
772 }
773 
774 /* Get the name and type of given variable DIE, stored as "type\tname" */
die_get_varname(Dwarf_Die * vr_die,char * buf,int len)775 static int die_get_varname(Dwarf_Die *vr_die, char *buf, int len)
776 {
777 	int ret, ret2;
778 
779 	ret = die_get_typename(vr_die, buf, len);
780 	if (ret < 0) {
781 		pr_debug("Failed to get type, make it unknown.\n");
782 		ret = snprintf(buf, len, "(unknown_type)");
783 	}
784 	if (ret > 0) {
785 		ret2 = snprintf(buf + ret, len - ret, "\t%s",
786 				dwarf_diename(vr_die));
787 		ret = (ret2 >= len - ret) ? -E2BIG : ret2 + ret;
788 	}
789 	return ret;
790 }
791 
792 /*
793  * Probe finder related functions
794  */
795 
alloc_trace_arg_ref(long offs)796 static struct probe_trace_arg_ref *alloc_trace_arg_ref(long offs)
797 {
798 	struct probe_trace_arg_ref *ref;
799 	ref = zalloc(sizeof(struct probe_trace_arg_ref));
800 	if (ref != NULL)
801 		ref->offset = offs;
802 	return ref;
803 }
804 
805 /*
806  * Convert a location into trace_arg.
807  * If tvar == NULL, this just checks variable can be converted.
808  */
convert_variable_location(Dwarf_Die * vr_die,Dwarf_Addr addr,Dwarf_Op * fb_ops,struct probe_trace_arg * tvar)809 static int convert_variable_location(Dwarf_Die *vr_die, Dwarf_Addr addr,
810 				     Dwarf_Op *fb_ops,
811 				     struct probe_trace_arg *tvar)
812 {
813 	Dwarf_Attribute attr;
814 	Dwarf_Op *op;
815 	size_t nops;
816 	unsigned int regn;
817 	Dwarf_Word offs = 0;
818 	bool ref = false;
819 	const char *regs;
820 	int ret;
821 
822 	if (dwarf_attr(vr_die, DW_AT_external, &attr) != NULL)
823 		goto static_var;
824 
825 	/* TODO: handle more than 1 exprs */
826 	if (dwarf_attr(vr_die, DW_AT_location, &attr) == NULL ||
827 	    dwarf_getlocation_addr(&attr, addr, &op, &nops, 1) <= 0 ||
828 	    nops == 0) {
829 		/* TODO: Support const_value */
830 		return -ENOENT;
831 	}
832 
833 	if (op->atom == DW_OP_addr) {
834 static_var:
835 		if (!tvar)
836 			return 0;
837 		/* Static variables on memory (not stack), make @varname */
838 		ret = strlen(dwarf_diename(vr_die));
839 		tvar->value = zalloc(ret + 2);
840 		if (tvar->value == NULL)
841 			return -ENOMEM;
842 		snprintf(tvar->value, ret + 2, "@%s", dwarf_diename(vr_die));
843 		tvar->ref = alloc_trace_arg_ref((long)offs);
844 		if (tvar->ref == NULL)
845 			return -ENOMEM;
846 		return 0;
847 	}
848 
849 	/* If this is based on frame buffer, set the offset */
850 	if (op->atom == DW_OP_fbreg) {
851 		if (fb_ops == NULL)
852 			return -ENOTSUP;
853 		ref = true;
854 		offs = op->number;
855 		op = &fb_ops[0];
856 	}
857 
858 	if (op->atom >= DW_OP_breg0 && op->atom <= DW_OP_breg31) {
859 		regn = op->atom - DW_OP_breg0;
860 		offs += op->number;
861 		ref = true;
862 	} else if (op->atom >= DW_OP_reg0 && op->atom <= DW_OP_reg31) {
863 		regn = op->atom - DW_OP_reg0;
864 	} else if (op->atom == DW_OP_bregx) {
865 		regn = op->number;
866 		offs += op->number2;
867 		ref = true;
868 	} else if (op->atom == DW_OP_regx) {
869 		regn = op->number;
870 	} else {
871 		pr_debug("DW_OP %x is not supported.\n", op->atom);
872 		return -ENOTSUP;
873 	}
874 
875 	if (!tvar)
876 		return 0;
877 
878 	regs = get_arch_regstr(regn);
879 	if (!regs) {
880 		/* This should be a bug in DWARF or this tool */
881 		pr_warning("Mapping for the register number %u "
882 			   "missing on this architecture.\n", regn);
883 		return -ERANGE;
884 	}
885 
886 	tvar->value = strdup(regs);
887 	if (tvar->value == NULL)
888 		return -ENOMEM;
889 
890 	if (ref) {
891 		tvar->ref = alloc_trace_arg_ref((long)offs);
892 		if (tvar->ref == NULL)
893 			return -ENOMEM;
894 	}
895 	return 0;
896 }
897 
898 #define BYTES_TO_BITS(nb)	((nb) * BITS_PER_LONG / sizeof(long))
899 
convert_variable_type(Dwarf_Die * vr_die,struct probe_trace_arg * tvar,const char * cast)900 static int convert_variable_type(Dwarf_Die *vr_die,
901 				 struct probe_trace_arg *tvar,
902 				 const char *cast)
903 {
904 	struct probe_trace_arg_ref **ref_ptr = &tvar->ref;
905 	Dwarf_Die type;
906 	char buf[16];
907 	int ret;
908 
909 	/* TODO: check all types */
910 	if (cast && strcmp(cast, "string") != 0) {
911 		/* Non string type is OK */
912 		tvar->type = strdup(cast);
913 		return (tvar->type == NULL) ? -ENOMEM : 0;
914 	}
915 
916 	if (die_get_bit_size(vr_die) != 0) {
917 		/* This is a bitfield */
918 		ret = snprintf(buf, 16, "b%d@%d/%zd", die_get_bit_size(vr_die),
919 				die_get_bit_offset(vr_die),
920 				BYTES_TO_BITS(die_get_byte_size(vr_die)));
921 		goto formatted;
922 	}
923 
924 	if (die_get_real_type(vr_die, &type) == NULL) {
925 		pr_warning("Failed to get a type information of %s.\n",
926 			   dwarf_diename(vr_die));
927 		return -ENOENT;
928 	}
929 
930 	pr_debug("%s type is %s.\n",
931 		 dwarf_diename(vr_die), dwarf_diename(&type));
932 
933 	if (cast && strcmp(cast, "string") == 0) {	/* String type */
934 		ret = dwarf_tag(&type);
935 		if (ret != DW_TAG_pointer_type &&
936 		    ret != DW_TAG_array_type) {
937 			pr_warning("Failed to cast into string: "
938 				   "%s(%s) is not a pointer nor array.\n",
939 				   dwarf_diename(vr_die), dwarf_diename(&type));
940 			return -EINVAL;
941 		}
942 		if (ret == DW_TAG_pointer_type) {
943 			if (die_get_real_type(&type, &type) == NULL) {
944 				pr_warning("Failed to get a type"
945 					   " information.\n");
946 				return -ENOENT;
947 			}
948 			while (*ref_ptr)
949 				ref_ptr = &(*ref_ptr)->next;
950 			/* Add new reference with offset +0 */
951 			*ref_ptr = zalloc(sizeof(struct probe_trace_arg_ref));
952 			if (*ref_ptr == NULL) {
953 				pr_warning("Out of memory error\n");
954 				return -ENOMEM;
955 			}
956 		}
957 		if (!die_compare_name(&type, "char") &&
958 		    !die_compare_name(&type, "unsigned char")) {
959 			pr_warning("Failed to cast into string: "
960 				   "%s is not (unsigned) char *.\n",
961 				   dwarf_diename(vr_die));
962 			return -EINVAL;
963 		}
964 		tvar->type = strdup(cast);
965 		return (tvar->type == NULL) ? -ENOMEM : 0;
966 	}
967 
968 	ret = BYTES_TO_BITS(die_get_byte_size(&type));
969 	if (!ret)
970 		/* No size ... try to use default type */
971 		return 0;
972 
973 	/* Check the bitwidth */
974 	if (ret > MAX_BASIC_TYPE_BITS) {
975 		pr_info("%s exceeds max-bitwidth. Cut down to %d bits.\n",
976 			dwarf_diename(&type), MAX_BASIC_TYPE_BITS);
977 		ret = MAX_BASIC_TYPE_BITS;
978 	}
979 	ret = snprintf(buf, 16, "%c%d",
980 		       die_is_signed_type(&type) ? 's' : 'u', ret);
981 
982 formatted:
983 	if (ret < 0 || ret >= 16) {
984 		if (ret >= 16)
985 			ret = -E2BIG;
986 		pr_warning("Failed to convert variable type: %s\n",
987 			   strerror(-ret));
988 		return ret;
989 	}
990 	tvar->type = strdup(buf);
991 	if (tvar->type == NULL)
992 		return -ENOMEM;
993 	return 0;
994 }
995 
convert_variable_fields(Dwarf_Die * vr_die,const char * varname,struct perf_probe_arg_field * field,struct probe_trace_arg_ref ** ref_ptr,Dwarf_Die * die_mem)996 static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
997 				    struct perf_probe_arg_field *field,
998 				    struct probe_trace_arg_ref **ref_ptr,
999 				    Dwarf_Die *die_mem)
1000 {
1001 	struct probe_trace_arg_ref *ref = *ref_ptr;
1002 	Dwarf_Die type;
1003 	Dwarf_Word offs;
1004 	int ret, tag;
1005 
1006 	pr_debug("converting %s in %s\n", field->name, varname);
1007 	if (die_get_real_type(vr_die, &type) == NULL) {
1008 		pr_warning("Failed to get the type of %s.\n", varname);
1009 		return -ENOENT;
1010 	}
1011 	pr_debug2("Var real type: (%x)\n", (unsigned)dwarf_dieoffset(&type));
1012 	tag = dwarf_tag(&type);
1013 
1014 	if (field->name[0] == '[' &&
1015 	    (tag == DW_TAG_array_type || tag == DW_TAG_pointer_type)) {
1016 		if (field->next)
1017 			/* Save original type for next field */
1018 			memcpy(die_mem, &type, sizeof(*die_mem));
1019 		/* Get the type of this array */
1020 		if (die_get_real_type(&type, &type) == NULL) {
1021 			pr_warning("Failed to get the type of %s.\n", varname);
1022 			return -ENOENT;
1023 		}
1024 		pr_debug2("Array real type: (%x)\n",
1025 			 (unsigned)dwarf_dieoffset(&type));
1026 		if (tag == DW_TAG_pointer_type) {
1027 			ref = zalloc(sizeof(struct probe_trace_arg_ref));
1028 			if (ref == NULL)
1029 				return -ENOMEM;
1030 			if (*ref_ptr)
1031 				(*ref_ptr)->next = ref;
1032 			else
1033 				*ref_ptr = ref;
1034 		}
1035 		ref->offset += die_get_byte_size(&type) * field->index;
1036 		if (!field->next)
1037 			/* Save vr_die for converting types */
1038 			memcpy(die_mem, vr_die, sizeof(*die_mem));
1039 		goto next;
1040 	} else if (tag == DW_TAG_pointer_type) {
1041 		/* Check the pointer and dereference */
1042 		if (!field->ref) {
1043 			pr_err("Semantic error: %s must be referred by '->'\n",
1044 			       field->name);
1045 			return -EINVAL;
1046 		}
1047 		/* Get the type pointed by this pointer */
1048 		if (die_get_real_type(&type, &type) == NULL) {
1049 			pr_warning("Failed to get the type of %s.\n", varname);
1050 			return -ENOENT;
1051 		}
1052 		/* Verify it is a data structure  */
1053 		if (dwarf_tag(&type) != DW_TAG_structure_type) {
1054 			pr_warning("%s is not a data structure.\n", varname);
1055 			return -EINVAL;
1056 		}
1057 
1058 		ref = zalloc(sizeof(struct probe_trace_arg_ref));
1059 		if (ref == NULL)
1060 			return -ENOMEM;
1061 		if (*ref_ptr)
1062 			(*ref_ptr)->next = ref;
1063 		else
1064 			*ref_ptr = ref;
1065 	} else {
1066 		/* Verify it is a data structure  */
1067 		if (tag != DW_TAG_structure_type) {
1068 			pr_warning("%s is not a data structure.\n", varname);
1069 			return -EINVAL;
1070 		}
1071 		if (field->name[0] == '[') {
1072 			pr_err("Semantic error: %s is not a pointor"
1073 			       " nor array.\n", varname);
1074 			return -EINVAL;
1075 		}
1076 		if (field->ref) {
1077 			pr_err("Semantic error: %s must be referred by '.'\n",
1078 			       field->name);
1079 			return -EINVAL;
1080 		}
1081 		if (!ref) {
1082 			pr_warning("Structure on a register is not "
1083 				   "supported yet.\n");
1084 			return -ENOTSUP;
1085 		}
1086 	}
1087 
1088 	if (die_find_member(&type, field->name, die_mem) == NULL) {
1089 		pr_warning("%s(tyep:%s) has no member %s.\n", varname,
1090 			   dwarf_diename(&type), field->name);
1091 		return -EINVAL;
1092 	}
1093 
1094 	/* Get the offset of the field */
1095 	ret = die_get_data_member_location(die_mem, &offs);
1096 	if (ret < 0) {
1097 		pr_warning("Failed to get the offset of %s.\n", field->name);
1098 		return ret;
1099 	}
1100 	ref->offset += (long)offs;
1101 
1102 next:
1103 	/* Converting next field */
1104 	if (field->next)
1105 		return convert_variable_fields(die_mem, field->name,
1106 					field->next, &ref, die_mem);
1107 	else
1108 		return 0;
1109 }
1110 
1111 /* Show a variables in kprobe event format */
convert_variable(Dwarf_Die * vr_die,struct probe_finder * pf)1112 static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
1113 {
1114 	Dwarf_Die die_mem;
1115 	int ret;
1116 
1117 	pr_debug("Converting variable %s into trace event.\n",
1118 		 dwarf_diename(vr_die));
1119 
1120 	ret = convert_variable_location(vr_die, pf->addr, pf->fb_ops,
1121 					pf->tvar);
1122 	if (ret == -ENOENT)
1123 		pr_err("Failed to find the location of %s at this address.\n"
1124 		       " Perhaps, it has been optimized out.\n", pf->pvar->var);
1125 	else if (ret == -ENOTSUP)
1126 		pr_err("Sorry, we don't support this variable location yet.\n");
1127 	else if (pf->pvar->field) {
1128 		ret = convert_variable_fields(vr_die, pf->pvar->var,
1129 					      pf->pvar->field, &pf->tvar->ref,
1130 					      &die_mem);
1131 		vr_die = &die_mem;
1132 	}
1133 	if (ret == 0)
1134 		ret = convert_variable_type(vr_die, pf->tvar, pf->pvar->type);
1135 	/* *expr will be cached in libdw. Don't free it. */
1136 	return ret;
1137 }
1138 
1139 /* Find a variable in a subprogram die */
find_variable(Dwarf_Die * sp_die,struct probe_finder * pf)1140 static int find_variable(Dwarf_Die *sp_die, struct probe_finder *pf)
1141 {
1142 	Dwarf_Die vr_die, *scopes;
1143 	char buf[32], *ptr;
1144 	int ret, nscopes;
1145 
1146 	if (!is_c_varname(pf->pvar->var)) {
1147 		/* Copy raw parameters */
1148 		pf->tvar->value = strdup(pf->pvar->var);
1149 		if (pf->tvar->value == NULL)
1150 			return -ENOMEM;
1151 		if (pf->pvar->type) {
1152 			pf->tvar->type = strdup(pf->pvar->type);
1153 			if (pf->tvar->type == NULL)
1154 				return -ENOMEM;
1155 		}
1156 		if (pf->pvar->name) {
1157 			pf->tvar->name = strdup(pf->pvar->name);
1158 			if (pf->tvar->name == NULL)
1159 				return -ENOMEM;
1160 		} else
1161 			pf->tvar->name = NULL;
1162 		return 0;
1163 	}
1164 
1165 	if (pf->pvar->name)
1166 		pf->tvar->name = strdup(pf->pvar->name);
1167 	else {
1168 		ret = synthesize_perf_probe_arg(pf->pvar, buf, 32);
1169 		if (ret < 0)
1170 			return ret;
1171 		ptr = strchr(buf, ':');	/* Change type separator to _ */
1172 		if (ptr)
1173 			*ptr = '_';
1174 		pf->tvar->name = strdup(buf);
1175 	}
1176 	if (pf->tvar->name == NULL)
1177 		return -ENOMEM;
1178 
1179 	pr_debug("Searching '%s' variable in context.\n",
1180 		 pf->pvar->var);
1181 	/* Search child die for local variables and parameters. */
1182 	if (die_find_variable_at(sp_die, pf->pvar->var, pf->addr, &vr_die))
1183 		ret = convert_variable(&vr_die, pf);
1184 	else {
1185 		/* Search upper class */
1186 		nscopes = dwarf_getscopes_die(sp_die, &scopes);
1187 		while (nscopes-- > 1) {
1188 			pr_debug("Searching variables in %s\n",
1189 				 dwarf_diename(&scopes[nscopes]));
1190 			/* We should check this scope, so give dummy address */
1191 			if (die_find_variable_at(&scopes[nscopes],
1192 						 pf->pvar->var, 0,
1193 						 &vr_die)) {
1194 				ret = convert_variable(&vr_die, pf);
1195 				goto found;
1196 			}
1197 		}
1198 		if (scopes)
1199 			free(scopes);
1200 		ret = -ENOENT;
1201 	}
1202 found:
1203 	if (ret < 0)
1204 		pr_warning("Failed to find '%s' in this function.\n",
1205 			   pf->pvar->var);
1206 	return ret;
1207 }
1208 
1209 /* Convert subprogram DIE to trace point */
convert_to_trace_point(Dwarf_Die * sp_die,Dwarf_Addr paddr,bool retprobe,struct probe_trace_point * tp)1210 static int convert_to_trace_point(Dwarf_Die *sp_die, Dwarf_Addr paddr,
1211 				  bool retprobe, struct probe_trace_point *tp)
1212 {
1213 	Dwarf_Addr eaddr;
1214 	const char *name;
1215 
1216 	/* Copy the name of probe point */
1217 	name = dwarf_diename(sp_die);
1218 	if (name) {
1219 		if (dwarf_entrypc(sp_die, &eaddr) != 0) {
1220 			pr_warning("Failed to get entry address of %s\n",
1221 				   dwarf_diename(sp_die));
1222 			return -ENOENT;
1223 		}
1224 		tp->symbol = strdup(name);
1225 		if (tp->symbol == NULL)
1226 			return -ENOMEM;
1227 		tp->offset = (unsigned long)(paddr - eaddr);
1228 	} else
1229 		/* This function has no name. */
1230 		tp->offset = (unsigned long)paddr;
1231 
1232 	/* Return probe must be on the head of a subprogram */
1233 	if (retprobe) {
1234 		if (eaddr != paddr) {
1235 			pr_warning("Return probe must be on the head of"
1236 				   " a real function.\n");
1237 			return -EINVAL;
1238 		}
1239 		tp->retprobe = true;
1240 	}
1241 
1242 	return 0;
1243 }
1244 
1245 /* Call probe_finder callback with real subprogram DIE */
call_probe_finder(Dwarf_Die * sp_die,struct probe_finder * pf)1246 static int call_probe_finder(Dwarf_Die *sp_die, struct probe_finder *pf)
1247 {
1248 	Dwarf_Die die_mem;
1249 	Dwarf_Attribute fb_attr;
1250 	size_t nops;
1251 	int ret;
1252 
1253 	/* If no real subprogram, find a real one */
1254 	if (!sp_die || dwarf_tag(sp_die) != DW_TAG_subprogram) {
1255 		sp_die = die_find_real_subprogram(&pf->cu_die,
1256 						  pf->addr, &die_mem);
1257 		if (!sp_die) {
1258 			pr_warning("Failed to find probe point in any "
1259 				   "functions.\n");
1260 			return -ENOENT;
1261 		}
1262 	}
1263 
1264 	/* Get the frame base attribute/ops */
1265 	dwarf_attr(sp_die, DW_AT_frame_base, &fb_attr);
1266 	ret = dwarf_getlocation_addr(&fb_attr, pf->addr, &pf->fb_ops, &nops, 1);
1267 	if (ret <= 0 || nops == 0) {
1268 		pf->fb_ops = NULL;
1269 #if _ELFUTILS_PREREQ(0, 142)
1270 	} else if (nops == 1 && pf->fb_ops[0].atom == DW_OP_call_frame_cfa &&
1271 		   pf->cfi != NULL) {
1272 		Dwarf_Frame *frame;
1273 		if (dwarf_cfi_addrframe(pf->cfi, pf->addr, &frame) != 0 ||
1274 		    dwarf_frame_cfa(frame, &pf->fb_ops, &nops) != 0) {
1275 			pr_warning("Failed to get call frame on 0x%jx\n",
1276 				   (uintmax_t)pf->addr);
1277 			return -ENOENT;
1278 		}
1279 #endif
1280 	}
1281 
1282 	/* Call finder's callback handler */
1283 	ret = pf->callback(sp_die, pf);
1284 
1285 	/* *pf->fb_ops will be cached in libdw. Don't free it. */
1286 	pf->fb_ops = NULL;
1287 
1288 	return ret;
1289 }
1290 
probe_point_line_walker(const char * fname,int lineno,Dwarf_Addr addr,void * data)1291 static int probe_point_line_walker(const char *fname, int lineno,
1292 				   Dwarf_Addr addr, void *data)
1293 {
1294 	struct probe_finder *pf = data;
1295 	int ret;
1296 
1297 	if (lineno != pf->lno || strtailcmp(fname, pf->fname) != 0)
1298 		return 0;
1299 
1300 	pf->addr = addr;
1301 	ret = call_probe_finder(NULL, pf);
1302 
1303 	/* Continue if no error, because the line will be in inline function */
1304 	return ret < 0 ? ret : 0;
1305 }
1306 
1307 /* Find probe point from its line number */
find_probe_point_by_line(struct probe_finder * pf)1308 static int find_probe_point_by_line(struct probe_finder *pf)
1309 {
1310 	return die_walk_lines(&pf->cu_die, probe_point_line_walker, pf);
1311 }
1312 
1313 /* Find lines which match lazy pattern */
find_lazy_match_lines(struct list_head * head,const char * fname,const char * pat)1314 static int find_lazy_match_lines(struct list_head *head,
1315 				 const char *fname, const char *pat)
1316 {
1317 	FILE *fp;
1318 	char *line = NULL;
1319 	size_t line_len;
1320 	ssize_t len;
1321 	int count = 0, linenum = 1;
1322 
1323 	fp = fopen(fname, "r");
1324 	if (!fp) {
1325 		pr_warning("Failed to open %s: %s\n", fname, strerror(errno));
1326 		return -errno;
1327 	}
1328 
1329 	while ((len = getline(&line, &line_len, fp)) > 0) {
1330 
1331 		if (line[len - 1] == '\n')
1332 			line[len - 1] = '\0';
1333 
1334 		if (strlazymatch(line, pat)) {
1335 			line_list__add_line(head, linenum);
1336 			count++;
1337 		}
1338 		linenum++;
1339 	}
1340 
1341 	if (ferror(fp))
1342 		count = -errno;
1343 	free(line);
1344 	fclose(fp);
1345 
1346 	if (count == 0)
1347 		pr_debug("No matched lines found in %s.\n", fname);
1348 	return count;
1349 }
1350 
probe_point_lazy_walker(const char * fname,int lineno,Dwarf_Addr addr,void * data)1351 static int probe_point_lazy_walker(const char *fname, int lineno,
1352 				   Dwarf_Addr addr, void *data)
1353 {
1354 	struct probe_finder *pf = data;
1355 	int ret;
1356 
1357 	if (!line_list__has_line(&pf->lcache, lineno) ||
1358 	    strtailcmp(fname, pf->fname) != 0)
1359 		return 0;
1360 
1361 	pr_debug("Probe line found: line:%d addr:0x%llx\n",
1362 		 lineno, (unsigned long long)addr);
1363 	pf->addr = addr;
1364 	ret = call_probe_finder(NULL, pf);
1365 
1366 	/*
1367 	 * Continue if no error, because the lazy pattern will match
1368 	 * to other lines
1369 	 */
1370 	return ret < 0 ? ret : 0;
1371 }
1372 
1373 /* Find probe points from lazy pattern  */
find_probe_point_lazy(Dwarf_Die * sp_die,struct probe_finder * pf)1374 static int find_probe_point_lazy(Dwarf_Die *sp_die, struct probe_finder *pf)
1375 {
1376 	int ret = 0;
1377 
1378 	if (list_empty(&pf->lcache)) {
1379 		/* Matching lazy line pattern */
1380 		ret = find_lazy_match_lines(&pf->lcache, pf->fname,
1381 					    pf->pev->point.lazy_line);
1382 		if (ret <= 0)
1383 			return ret;
1384 	}
1385 
1386 	return die_walk_lines(sp_die, probe_point_lazy_walker, pf);
1387 }
1388 
1389 /* Callback parameter with return value */
1390 struct dwarf_callback_param {
1391 	void *data;
1392 	int retval;
1393 };
1394 
probe_point_inline_cb(Dwarf_Die * in_die,void * data)1395 static int probe_point_inline_cb(Dwarf_Die *in_die, void *data)
1396 {
1397 	struct dwarf_callback_param *param = data;
1398 	struct probe_finder *pf = param->data;
1399 	struct perf_probe_point *pp = &pf->pev->point;
1400 	Dwarf_Addr addr;
1401 
1402 	if (pp->lazy_line)
1403 		param->retval = find_probe_point_lazy(in_die, pf);
1404 	else {
1405 		/* Get probe address */
1406 		if (dwarf_entrypc(in_die, &addr) != 0) {
1407 			pr_warning("Failed to get entry address of %s.\n",
1408 				   dwarf_diename(in_die));
1409 			param->retval = -ENOENT;
1410 			return DWARF_CB_ABORT;
1411 		}
1412 		pf->addr = addr;
1413 		pf->addr += pp->offset;
1414 		pr_debug("found inline addr: 0x%jx\n",
1415 			 (uintmax_t)pf->addr);
1416 
1417 		param->retval = call_probe_finder(in_die, pf);
1418 		if (param->retval < 0)
1419 			return DWARF_CB_ABORT;
1420 	}
1421 
1422 	return DWARF_CB_OK;
1423 }
1424 
1425 /* Search function from function name */
probe_point_search_cb(Dwarf_Die * sp_die,void * data)1426 static int probe_point_search_cb(Dwarf_Die *sp_die, void *data)
1427 {
1428 	struct dwarf_callback_param *param = data;
1429 	struct probe_finder *pf = param->data;
1430 	struct perf_probe_point *pp = &pf->pev->point;
1431 
1432 	/* Check tag and diename */
1433 	if (dwarf_tag(sp_die) != DW_TAG_subprogram ||
1434 	    !die_compare_name(sp_die, pp->function))
1435 		return DWARF_CB_OK;
1436 
1437 	/* Check declared file */
1438 	if (pp->file && strtailcmp(pp->file, dwarf_decl_file(sp_die)))
1439 		return DWARF_CB_OK;
1440 
1441 	pf->fname = dwarf_decl_file(sp_die);
1442 	if (pp->line) { /* Function relative line */
1443 		dwarf_decl_line(sp_die, &pf->lno);
1444 		pf->lno += pp->line;
1445 		param->retval = find_probe_point_by_line(pf);
1446 	} else if (!dwarf_func_inline(sp_die)) {
1447 		/* Real function */
1448 		if (pp->lazy_line)
1449 			param->retval = find_probe_point_lazy(sp_die, pf);
1450 		else {
1451 			if (dwarf_entrypc(sp_die, &pf->addr) != 0) {
1452 				pr_warning("Failed to get entry address of "
1453 					   "%s.\n", dwarf_diename(sp_die));
1454 				param->retval = -ENOENT;
1455 				return DWARF_CB_ABORT;
1456 			}
1457 			pf->addr += pp->offset;
1458 			/* TODO: Check the address in this function */
1459 			param->retval = call_probe_finder(sp_die, pf);
1460 		}
1461 	} else {
1462 		struct dwarf_callback_param _param = {.data = (void *)pf,
1463 						      .retval = 0};
1464 		/* Inlined function: search instances */
1465 		dwarf_func_inline_instances(sp_die, probe_point_inline_cb,
1466 					    &_param);
1467 		param->retval = _param.retval;
1468 	}
1469 
1470 	return DWARF_CB_ABORT; /* Exit; no same symbol in this CU. */
1471 }
1472 
find_probe_point_by_func(struct probe_finder * pf)1473 static int find_probe_point_by_func(struct probe_finder *pf)
1474 {
1475 	struct dwarf_callback_param _param = {.data = (void *)pf,
1476 					      .retval = 0};
1477 	dwarf_getfuncs(&pf->cu_die, probe_point_search_cb, &_param, 0);
1478 	return _param.retval;
1479 }
1480 
1481 struct pubname_callback_param {
1482 	char *function;
1483 	char *file;
1484 	Dwarf_Die *cu_die;
1485 	Dwarf_Die *sp_die;
1486 	int found;
1487 };
1488 
pubname_search_cb(Dwarf * dbg,Dwarf_Global * gl,void * data)1489 static int pubname_search_cb(Dwarf *dbg, Dwarf_Global *gl, void *data)
1490 {
1491 	struct pubname_callback_param *param = data;
1492 
1493 	if (dwarf_offdie(dbg, gl->die_offset, param->sp_die)) {
1494 		if (dwarf_tag(param->sp_die) != DW_TAG_subprogram)
1495 			return DWARF_CB_OK;
1496 
1497 		if (die_compare_name(param->sp_die, param->function)) {
1498 			if (!dwarf_offdie(dbg, gl->cu_offset, param->cu_die))
1499 				return DWARF_CB_OK;
1500 
1501 			if (param->file &&
1502 			    strtailcmp(param->file, dwarf_decl_file(param->sp_die)))
1503 				return DWARF_CB_OK;
1504 
1505 			param->found = 1;
1506 			return DWARF_CB_ABORT;
1507 		}
1508 	}
1509 
1510 	return DWARF_CB_OK;
1511 }
1512 
1513 /* Find probe points from debuginfo */
find_probes(int fd,struct probe_finder * pf)1514 static int find_probes(int fd, struct probe_finder *pf)
1515 {
1516 	struct perf_probe_point *pp = &pf->pev->point;
1517 	Dwarf_Off off, noff;
1518 	size_t cuhl;
1519 	Dwarf_Die *diep;
1520 	Dwarf *dbg = NULL;
1521 	Dwfl *dwfl;
1522 	Dwarf_Addr bias;	/* Currently ignored */
1523 	int ret = 0;
1524 
1525 	dbg = dwfl_init_offline_dwarf(fd, &dwfl, &bias);
1526 	if (!dbg) {
1527 		pr_warning("No debug information found in the vmlinux - "
1528 			"please rebuild with CONFIG_DEBUG_INFO=y.\n");
1529 		close(fd);	/* Without dwfl_end(), fd isn't closed. */
1530 		return -EBADF;
1531 	}
1532 
1533 #if _ELFUTILS_PREREQ(0, 142)
1534 	/* Get the call frame information from this dwarf */
1535 	pf->cfi = dwarf_getcfi(dbg);
1536 #endif
1537 
1538 	off = 0;
1539 	line_list__init(&pf->lcache);
1540 
1541 	/* Fastpath: lookup by function name from .debug_pubnames section */
1542 	if (pp->function) {
1543 		struct pubname_callback_param pubname_param = {
1544 			.function = pp->function,
1545 			.file	  = pp->file,
1546 			.cu_die	  = &pf->cu_die,
1547 			.sp_die	  = &pf->sp_die,
1548 			.found	  = 0,
1549 		};
1550 		struct dwarf_callback_param probe_param = {
1551 			.data = pf,
1552 		};
1553 
1554 		dwarf_getpubnames(dbg, pubname_search_cb, &pubname_param, 0);
1555 		if (pubname_param.found) {
1556 			ret = probe_point_search_cb(&pf->sp_die, &probe_param);
1557 			if (ret)
1558 				goto found;
1559 		}
1560 	}
1561 
1562 	/* Loop on CUs (Compilation Unit) */
1563 	while (!dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL)) {
1564 		/* Get the DIE(Debugging Information Entry) of this CU */
1565 		diep = dwarf_offdie(dbg, off + cuhl, &pf->cu_die);
1566 		if (!diep)
1567 			continue;
1568 
1569 		/* Check if target file is included. */
1570 		if (pp->file)
1571 			pf->fname = cu_find_realpath(&pf->cu_die, pp->file);
1572 		else
1573 			pf->fname = NULL;
1574 
1575 		if (!pp->file || pf->fname) {
1576 			if (pp->function)
1577 				ret = find_probe_point_by_func(pf);
1578 			else if (pp->lazy_line)
1579 				ret = find_probe_point_lazy(NULL, pf);
1580 			else {
1581 				pf->lno = pp->line;
1582 				ret = find_probe_point_by_line(pf);
1583 			}
1584 			if (ret < 0)
1585 				break;
1586 		}
1587 		off = noff;
1588 	}
1589 
1590 found:
1591 	line_list__free(&pf->lcache);
1592 	if (dwfl)
1593 		dwfl_end(dwfl);
1594 
1595 	return ret;
1596 }
1597 
1598 /* Add a found probe point into trace event list */
add_probe_trace_event(Dwarf_Die * sp_die,struct probe_finder * pf)1599 static int add_probe_trace_event(Dwarf_Die *sp_die, struct probe_finder *pf)
1600 {
1601 	struct trace_event_finder *tf =
1602 			container_of(pf, struct trace_event_finder, pf);
1603 	struct probe_trace_event *tev;
1604 	int ret, i;
1605 
1606 	/* Check number of tevs */
1607 	if (tf->ntevs == tf->max_tevs) {
1608 		pr_warning("Too many( > %d) probe point found.\n",
1609 			   tf->max_tevs);
1610 		return -ERANGE;
1611 	}
1612 	tev = &tf->tevs[tf->ntevs++];
1613 
1614 	ret = convert_to_trace_point(sp_die, pf->addr, pf->pev->point.retprobe,
1615 				     &tev->point);
1616 	if (ret < 0)
1617 		return ret;
1618 
1619 	pr_debug("Probe point found: %s+%lu\n", tev->point.symbol,
1620 		 tev->point.offset);
1621 
1622 	/* Find each argument */
1623 	tev->nargs = pf->pev->nargs;
1624 	tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs);
1625 	if (tev->args == NULL)
1626 		return -ENOMEM;
1627 	for (i = 0; i < pf->pev->nargs; i++) {
1628 		pf->pvar = &pf->pev->args[i];
1629 		pf->tvar = &tev->args[i];
1630 		ret = find_variable(sp_die, pf);
1631 		if (ret != 0)
1632 			return ret;
1633 	}
1634 
1635 	return 0;
1636 }
1637 
1638 /* Find probe_trace_events specified by perf_probe_event from debuginfo */
find_probe_trace_events(int fd,struct perf_probe_event * pev,struct probe_trace_event ** tevs,int max_tevs)1639 int find_probe_trace_events(int fd, struct perf_probe_event *pev,
1640 			    struct probe_trace_event **tevs, int max_tevs)
1641 {
1642 	struct trace_event_finder tf = {
1643 			.pf = {.pev = pev, .callback = add_probe_trace_event},
1644 			.max_tevs = max_tevs};
1645 	int ret;
1646 
1647 	/* Allocate result tevs array */
1648 	*tevs = zalloc(sizeof(struct probe_trace_event) * max_tevs);
1649 	if (*tevs == NULL)
1650 		return -ENOMEM;
1651 
1652 	tf.tevs = *tevs;
1653 	tf.ntevs = 0;
1654 
1655 	ret = find_probes(fd, &tf.pf);
1656 	if (ret < 0) {
1657 		free(*tevs);
1658 		*tevs = NULL;
1659 		return ret;
1660 	}
1661 
1662 	return (ret < 0) ? ret : tf.ntevs;
1663 }
1664 
1665 #define MAX_VAR_LEN 64
1666 
1667 /* Collect available variables in this scope */
collect_variables_cb(Dwarf_Die * die_mem,void * data)1668 static int collect_variables_cb(Dwarf_Die *die_mem, void *data)
1669 {
1670 	struct available_var_finder *af = data;
1671 	struct variable_list *vl;
1672 	char buf[MAX_VAR_LEN];
1673 	int tag, ret;
1674 
1675 	vl = &af->vls[af->nvls - 1];
1676 
1677 	tag = dwarf_tag(die_mem);
1678 	if (tag == DW_TAG_formal_parameter ||
1679 	    tag == DW_TAG_variable) {
1680 		ret = convert_variable_location(die_mem, af->pf.addr,
1681 						af->pf.fb_ops, NULL);
1682 		if (ret == 0) {
1683 			ret = die_get_varname(die_mem, buf, MAX_VAR_LEN);
1684 			pr_debug2("Add new var: %s\n", buf);
1685 			if (ret > 0)
1686 				strlist__add(vl->vars, buf);
1687 		}
1688 	}
1689 
1690 	if (af->child && dwarf_haspc(die_mem, af->pf.addr))
1691 		return DIE_FIND_CB_CONTINUE;
1692 	else
1693 		return DIE_FIND_CB_SIBLING;
1694 }
1695 
1696 /* Add a found vars into available variables list */
add_available_vars(Dwarf_Die * sp_die,struct probe_finder * pf)1697 static int add_available_vars(Dwarf_Die *sp_die, struct probe_finder *pf)
1698 {
1699 	struct available_var_finder *af =
1700 			container_of(pf, struct available_var_finder, pf);
1701 	struct variable_list *vl;
1702 	Dwarf_Die die_mem, *scopes = NULL;
1703 	int ret, nscopes;
1704 
1705 	/* Check number of tevs */
1706 	if (af->nvls == af->max_vls) {
1707 		pr_warning("Too many( > %d) probe point found.\n", af->max_vls);
1708 		return -ERANGE;
1709 	}
1710 	vl = &af->vls[af->nvls++];
1711 
1712 	ret = convert_to_trace_point(sp_die, pf->addr, pf->pev->point.retprobe,
1713 				     &vl->point);
1714 	if (ret < 0)
1715 		return ret;
1716 
1717 	pr_debug("Probe point found: %s+%lu\n", vl->point.symbol,
1718 		 vl->point.offset);
1719 
1720 	/* Find local variables */
1721 	vl->vars = strlist__new(true, NULL);
1722 	if (vl->vars == NULL)
1723 		return -ENOMEM;
1724 	af->child = true;
1725 	die_find_child(sp_die, collect_variables_cb, (void *)af, &die_mem);
1726 
1727 	/* Find external variables */
1728 	if (!af->externs)
1729 		goto out;
1730 	/* Don't need to search child DIE for externs. */
1731 	af->child = false;
1732 	nscopes = dwarf_getscopes_die(sp_die, &scopes);
1733 	while (nscopes-- > 1)
1734 		die_find_child(&scopes[nscopes], collect_variables_cb,
1735 			       (void *)af, &die_mem);
1736 	if (scopes)
1737 		free(scopes);
1738 
1739 out:
1740 	if (strlist__empty(vl->vars)) {
1741 		strlist__delete(vl->vars);
1742 		vl->vars = NULL;
1743 	}
1744 
1745 	return ret;
1746 }
1747 
1748 /* Find available variables at given probe point */
find_available_vars_at(int fd,struct perf_probe_event * pev,struct variable_list ** vls,int max_vls,bool externs)1749 int find_available_vars_at(int fd, struct perf_probe_event *pev,
1750 			   struct variable_list **vls, int max_vls,
1751 			   bool externs)
1752 {
1753 	struct available_var_finder af = {
1754 			.pf = {.pev = pev, .callback = add_available_vars},
1755 			.max_vls = max_vls, .externs = externs};
1756 	int ret;
1757 
1758 	/* Allocate result vls array */
1759 	*vls = zalloc(sizeof(struct variable_list) * max_vls);
1760 	if (*vls == NULL)
1761 		return -ENOMEM;
1762 
1763 	af.vls = *vls;
1764 	af.nvls = 0;
1765 
1766 	ret = find_probes(fd, &af.pf);
1767 	if (ret < 0) {
1768 		/* Free vlist for error */
1769 		while (af.nvls--) {
1770 			if (af.vls[af.nvls].point.symbol)
1771 				free(af.vls[af.nvls].point.symbol);
1772 			if (af.vls[af.nvls].vars)
1773 				strlist__delete(af.vls[af.nvls].vars);
1774 		}
1775 		free(af.vls);
1776 		*vls = NULL;
1777 		return ret;
1778 	}
1779 
1780 	return (ret < 0) ? ret : af.nvls;
1781 }
1782 
1783 /* Reverse search */
find_perf_probe_point(unsigned long addr,struct perf_probe_point * ppt)1784 int find_perf_probe_point(unsigned long addr, struct perf_probe_point *ppt)
1785 {
1786 	Dwarf_Die cudie, spdie, indie;
1787 	Dwarf *dbg = NULL;
1788 	Dwfl *dwfl = NULL;
1789 	Dwarf_Addr _addr, baseaddr, bias = 0;
1790 	const char *fname = NULL, *func = NULL, *tmp;
1791 	int baseline = 0, lineno = 0, ret = 0;
1792 
1793 	/* Open the live linux kernel */
1794 	dbg = dwfl_init_live_kernel_dwarf(addr, &dwfl, &bias);
1795 	if (!dbg) {
1796 		pr_warning("No debug information found in the vmlinux - "
1797 			"please rebuild with CONFIG_DEBUG_INFO=y.\n");
1798 		ret = -EINVAL;
1799 		goto end;
1800 	}
1801 
1802 	/* Adjust address with bias */
1803 	addr += bias;
1804 	/* Find cu die */
1805 	if (!dwarf_addrdie(dbg, (Dwarf_Addr)addr - bias, &cudie)) {
1806 		pr_warning("Failed to find debug information for address %lx\n",
1807 			   addr);
1808 		ret = -EINVAL;
1809 		goto end;
1810 	}
1811 
1812 	/* Find a corresponding line (filename and lineno) */
1813 	cu_find_lineinfo(&cudie, addr, &fname, &lineno);
1814 	/* Don't care whether it failed or not */
1815 
1816 	/* Find a corresponding function (name, baseline and baseaddr) */
1817 	if (die_find_real_subprogram(&cudie, (Dwarf_Addr)addr, &spdie)) {
1818 		/* Get function entry information */
1819 		tmp = dwarf_diename(&spdie);
1820 		if (!tmp ||
1821 		    dwarf_entrypc(&spdie, &baseaddr) != 0 ||
1822 		    dwarf_decl_line(&spdie, &baseline) != 0)
1823 			goto post;
1824 		func = tmp;
1825 
1826 		if (addr == (unsigned long)baseaddr)
1827 			/* Function entry - Relative line number is 0 */
1828 			lineno = baseline;
1829 		else if (die_find_inlinefunc(&spdie, (Dwarf_Addr)addr,
1830 					     &indie)) {
1831 			if (dwarf_entrypc(&indie, &_addr) == 0 &&
1832 			    _addr == addr)
1833 				/*
1834 				 * addr is at an inline function entry.
1835 				 * In this case, lineno should be the call-site
1836 				 * line number.
1837 				 */
1838 				lineno = die_get_call_lineno(&indie);
1839 			else {
1840 				/*
1841 				 * addr is in an inline function body.
1842 				 * Since lineno points one of the lines
1843 				 * of the inline function, baseline should
1844 				 * be the entry line of the inline function.
1845 				 */
1846 				tmp = dwarf_diename(&indie);
1847 				if (tmp &&
1848 				    dwarf_decl_line(&spdie, &baseline) == 0)
1849 					func = tmp;
1850 			}
1851 		}
1852 	}
1853 
1854 post:
1855 	/* Make a relative line number or an offset */
1856 	if (lineno)
1857 		ppt->line = lineno - baseline;
1858 	else if (func)
1859 		ppt->offset = addr - (unsigned long)baseaddr;
1860 
1861 	/* Duplicate strings */
1862 	if (func) {
1863 		ppt->function = strdup(func);
1864 		if (ppt->function == NULL) {
1865 			ret = -ENOMEM;
1866 			goto end;
1867 		}
1868 	}
1869 	if (fname) {
1870 		ppt->file = strdup(fname);
1871 		if (ppt->file == NULL) {
1872 			if (ppt->function) {
1873 				free(ppt->function);
1874 				ppt->function = NULL;
1875 			}
1876 			ret = -ENOMEM;
1877 			goto end;
1878 		}
1879 	}
1880 end:
1881 	if (dwfl)
1882 		dwfl_end(dwfl);
1883 	if (ret == 0 && (fname || func))
1884 		ret = 1;	/* Found a point */
1885 	return ret;
1886 }
1887 
1888 /* Add a line and store the src path */
line_range_add_line(const char * src,unsigned int lineno,struct line_range * lr)1889 static int line_range_add_line(const char *src, unsigned int lineno,
1890 			       struct line_range *lr)
1891 {
1892 	/* Copy source path */
1893 	if (!lr->path) {
1894 		lr->path = strdup(src);
1895 		if (lr->path == NULL)
1896 			return -ENOMEM;
1897 	}
1898 	return line_list__add_line(&lr->line_list, lineno);
1899 }
1900 
line_range_walk_cb(const char * fname,int lineno,Dwarf_Addr addr __used,void * data)1901 static int line_range_walk_cb(const char *fname, int lineno,
1902 			      Dwarf_Addr addr __used,
1903 			      void *data)
1904 {
1905 	struct line_finder *lf = data;
1906 
1907 	if ((strtailcmp(fname, lf->fname) != 0) ||
1908 	    (lf->lno_s > lineno || lf->lno_e < lineno))
1909 		return 0;
1910 
1911 	if (line_range_add_line(fname, lineno, lf->lr) < 0)
1912 		return -EINVAL;
1913 
1914 	return 0;
1915 }
1916 
1917 /* Find line range from its line number */
find_line_range_by_line(Dwarf_Die * sp_die,struct line_finder * lf)1918 static int find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf)
1919 {
1920 	int ret;
1921 
1922 	ret = die_walk_lines(sp_die ?: &lf->cu_die, line_range_walk_cb, lf);
1923 
1924 	/* Update status */
1925 	if (ret >= 0)
1926 		if (!list_empty(&lf->lr->line_list))
1927 			ret = lf->found = 1;
1928 		else
1929 			ret = 0;	/* Lines are not found */
1930 	else {
1931 		free(lf->lr->path);
1932 		lf->lr->path = NULL;
1933 	}
1934 	return ret;
1935 }
1936 
line_range_inline_cb(Dwarf_Die * in_die,void * data)1937 static int line_range_inline_cb(Dwarf_Die *in_die, void *data)
1938 {
1939 	struct dwarf_callback_param *param = data;
1940 
1941 	param->retval = find_line_range_by_line(in_die, param->data);
1942 	return DWARF_CB_ABORT;	/* No need to find other instances */
1943 }
1944 
1945 /* Search function from function name */
line_range_search_cb(Dwarf_Die * sp_die,void * data)1946 static int line_range_search_cb(Dwarf_Die *sp_die, void *data)
1947 {
1948 	struct dwarf_callback_param *param = data;
1949 	struct line_finder *lf = param->data;
1950 	struct line_range *lr = lf->lr;
1951 
1952 	/* Check declared file */
1953 	if (lr->file && strtailcmp(lr->file, dwarf_decl_file(sp_die)))
1954 		return DWARF_CB_OK;
1955 
1956 	if (dwarf_tag(sp_die) == DW_TAG_subprogram &&
1957 	    die_compare_name(sp_die, lr->function)) {
1958 		lf->fname = dwarf_decl_file(sp_die);
1959 		dwarf_decl_line(sp_die, &lr->offset);
1960 		pr_debug("fname: %s, lineno:%d\n", lf->fname, lr->offset);
1961 		lf->lno_s = lr->offset + lr->start;
1962 		if (lf->lno_s < 0)	/* Overflow */
1963 			lf->lno_s = INT_MAX;
1964 		lf->lno_e = lr->offset + lr->end;
1965 		if (lf->lno_e < 0)	/* Overflow */
1966 			lf->lno_e = INT_MAX;
1967 		pr_debug("New line range: %d to %d\n", lf->lno_s, lf->lno_e);
1968 		lr->start = lf->lno_s;
1969 		lr->end = lf->lno_e;
1970 		if (dwarf_func_inline(sp_die)) {
1971 			struct dwarf_callback_param _param;
1972 			_param.data = (void *)lf;
1973 			_param.retval = 0;
1974 			dwarf_func_inline_instances(sp_die,
1975 						    line_range_inline_cb,
1976 						    &_param);
1977 			param->retval = _param.retval;
1978 		} else
1979 			param->retval = find_line_range_by_line(sp_die, lf);
1980 		return DWARF_CB_ABORT;
1981 	}
1982 	return DWARF_CB_OK;
1983 }
1984 
find_line_range_by_func(struct line_finder * lf)1985 static int find_line_range_by_func(struct line_finder *lf)
1986 {
1987 	struct dwarf_callback_param param = {.data = (void *)lf, .retval = 0};
1988 	dwarf_getfuncs(&lf->cu_die, line_range_search_cb, &param, 0);
1989 	return param.retval;
1990 }
1991 
find_line_range(int fd,struct line_range * lr)1992 int find_line_range(int fd, struct line_range *lr)
1993 {
1994 	struct line_finder lf = {.lr = lr, .found = 0};
1995 	int ret = 0;
1996 	Dwarf_Off off = 0, noff;
1997 	size_t cuhl;
1998 	Dwarf_Die *diep;
1999 	Dwarf *dbg = NULL;
2000 	Dwfl *dwfl;
2001 	Dwarf_Addr bias;	/* Currently ignored */
2002 	const char *comp_dir;
2003 
2004 	dbg = dwfl_init_offline_dwarf(fd, &dwfl, &bias);
2005 	if (!dbg) {
2006 		pr_warning("No debug information found in the vmlinux - "
2007 			"please rebuild with CONFIG_DEBUG_INFO=y.\n");
2008 		close(fd);	/* Without dwfl_end(), fd isn't closed. */
2009 		return -EBADF;
2010 	}
2011 
2012 	/* Fastpath: lookup by function name from .debug_pubnames section */
2013 	if (lr->function) {
2014 		struct pubname_callback_param pubname_param = {
2015 			.function = lr->function, .file = lr->file,
2016 			.cu_die = &lf.cu_die, .sp_die = &lf.sp_die, .found = 0};
2017 		struct dwarf_callback_param line_range_param = {
2018 			.data = (void *)&lf, .retval = 0};
2019 
2020 		dwarf_getpubnames(dbg, pubname_search_cb, &pubname_param, 0);
2021 		if (pubname_param.found) {
2022 			line_range_search_cb(&lf.sp_die, &line_range_param);
2023 			if (lf.found)
2024 				goto found;
2025 		}
2026 	}
2027 
2028 	/* Loop on CUs (Compilation Unit) */
2029 	while (!lf.found && ret >= 0) {
2030 		if (dwarf_nextcu(dbg, off, &noff, &cuhl, NULL, NULL, NULL) != 0)
2031 			break;
2032 
2033 		/* Get the DIE(Debugging Information Entry) of this CU */
2034 		diep = dwarf_offdie(dbg, off + cuhl, &lf.cu_die);
2035 		if (!diep)
2036 			continue;
2037 
2038 		/* Check if target file is included. */
2039 		if (lr->file)
2040 			lf.fname = cu_find_realpath(&lf.cu_die, lr->file);
2041 		else
2042 			lf.fname = 0;
2043 
2044 		if (!lr->file || lf.fname) {
2045 			if (lr->function)
2046 				ret = find_line_range_by_func(&lf);
2047 			else {
2048 				lf.lno_s = lr->start;
2049 				lf.lno_e = lr->end;
2050 				ret = find_line_range_by_line(NULL, &lf);
2051 			}
2052 		}
2053 		off = noff;
2054 	}
2055 
2056 found:
2057 	/* Store comp_dir */
2058 	if (lf.found) {
2059 		comp_dir = cu_get_comp_dir(&lf.cu_die);
2060 		if (comp_dir) {
2061 			lr->comp_dir = strdup(comp_dir);
2062 			if (!lr->comp_dir)
2063 				ret = -ENOMEM;
2064 		}
2065 	}
2066 
2067 	pr_debug("path: %s\n", lr->path);
2068 	dwfl_end(dwfl);
2069 	return (ret < 0) ? ret : lf.found;
2070 }
2071