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