23 #include <sys/utsname.h> 24 #include <sys/types.h> 35 #include <linux/bitops.h> 48 #define MAX_BASIC_TYPE_BITS 64 54 .find_debuginfo = dwfl_standard_find_debuginfo,
57 .section_address = dwfl_offline_section_address,
60 .find_elf = dwfl_build_id_find_elf,
69 fd = open(path, O_RDONLY);
77 dwfl_report_begin(dbg->dwfl);
78 dbg->mod = dwfl_report_offline(dbg->dwfl,
"",
"", fd);
82 dbg->dbg = dwfl_module_getdwarf(dbg->mod, &dbg->bias);
86 dwfl_report_end(dbg->dwfl, NULL, NULL);
94 memset(dbg, 0,
sizeof(*dbg));
101 struct debuginfo *dbg =
zalloc(
sizeof(*dbg));
108 pr_debug(
"Open Debuginfo file: %s\n", path);
125 struct debuginfo *dinfo = NULL;
176 Dwarf_Op *fb_ops, Dwarf_Die *sp_die,
180 Dwarf_Attribute
attr;
190 if (dwarf_attr(vr_die, DW_AT_external, &attr) != NULL)
194 if (dwarf_attr(vr_die, DW_AT_location, &attr) == NULL)
196 if (dwarf_getlocation_addr(&attr, addr, &op, &nops, 1) <= 0) {
197 ret = dwarf_entrypc(sp_die, &tmp);
202 (dwarf_tag(vr_die) == DW_TAG_variable)) {
204 }
else if (addr != tmp ||
205 dwarf_tag(vr_die) != DW_TAG_formal_parameter) {
209 ret = dwarf_highpc(sp_die, &tmp);
216 for (addr += 1; addr <= tmp; addr++) {
217 if (dwarf_getlocation_addr(&attr, addr, &op,
228 if (op->atom == DW_OP_addr) {
233 ret = strlen(dwarf_diename(vr_die));
235 if (tvar->
value == NULL)
237 snprintf(tvar->
value, ret + 2,
"@%s", dwarf_diename(vr_die));
239 if (tvar->
ref == NULL)
245 if (op->atom == DW_OP_fbreg) {
253 if (op->atom >= DW_OP_breg0 && op->atom <= DW_OP_breg31) {
254 regn = op->atom - DW_OP_breg0;
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) {
263 }
else if (op->atom == DW_OP_regx) {
266 pr_debug(
"DW_OP %x is not supported.\n", op->atom);
276 pr_warning(
"Mapping for the register number %u " 277 "missing on this architecture.\n", regn);
281 tvar->
value = strdup(regs);
282 if (tvar->
value == NULL)
287 if (tvar->
ref == NULL)
293 #define BYTES_TO_BITS(nb) ((nb) * BITS_PER_LONG / sizeof(long)) 303 int bsize, boffs, total;
308 if (cast && strcmp(cast,
"string") != 0 && strcmp(cast,
"x") != 0 &&
309 strcmp(cast,
"s") != 0 && strcmp(cast,
"u") != 0) {
312 tvar->
type = strdup(cast);
313 return (tvar->
type == NULL) ? -ENOMEM : 0;
316 bsize = dwarf_bitsize(vr_die);
319 boffs = dwarf_bitoffset(vr_die);
320 total = dwarf_bytesize(vr_die);
321 if (boffs < 0 || total < 0)
323 ret = snprintf(buf, 16,
"b%d@%d/%zd", bsize, boffs,
329 pr_warning(
"Failed to get a type information of %s.\n",
330 dwarf_diename(vr_die));
335 dwarf_diename(vr_die), dwarf_diename(&type));
337 if (cast && strcmp(cast,
"string") == 0) {
338 ret = dwarf_tag(&type);
339 if (ret != DW_TAG_pointer_type &&
340 ret != DW_TAG_array_type) {
342 "%s(%s) is not a pointer nor array.\n",
343 dwarf_diename(vr_die), dwarf_diename(&type));
351 if (ret == DW_TAG_pointer_type) {
353 ref_ptr = &(*ref_ptr)->
next;
356 if (*ref_ptr == NULL) {
364 "%s is not (unsigned) char *.\n",
365 dwarf_diename(vr_die));
368 tvar->
type = strdup(cast);
369 return (tvar->
type == NULL) ? -ENOMEM : 0;
372 if (cast && (strcmp(cast,
"u") == 0))
374 else if (cast && (strcmp(cast,
"s") == 0))
376 else if (cast && (strcmp(cast,
"x") == 0) &&
383 ret = dwarf_bytesize(&type);
391 pr_info(
"%s exceeds max-bitwidth. Cut down to %d bits.\n",
395 ret = snprintf(buf, 16,
"%c%d", prefix, ret);
398 if (ret < 0 || ret >= 16) {
401 pr_warning(
"Failed to convert variable type: %s\n",
402 str_error_r(-ret, sbuf,
sizeof(sbuf)));
405 tvar->
type = strdup(buf);
406 if (tvar->
type == NULL)
421 pr_debug(
"converting %s in %s\n", field->
name, varname);
423 pr_warning(
"Failed to get the type of %s.\n", varname);
426 pr_debug2(
"Var real type: %s (%x)\n", dwarf_diename(&type),
427 (
unsigned)dwarf_dieoffset(&type));
428 tag = dwarf_tag(&type);
430 if (field->
name[0] ==
'[' &&
431 (tag == DW_TAG_array_type || tag == DW_TAG_pointer_type)) {
433 memcpy(die_mem, &type,
sizeof(*die_mem));
436 pr_warning(
"Failed to get the type of %s.\n", varname);
439 pr_debug2(
"Array real type: %s (%x)\n", dwarf_diename(&type),
440 (
unsigned)dwarf_dieoffset(&type));
441 if (tag == DW_TAG_pointer_type) {
446 (*ref_ptr)->next = ref;
450 ref->
offset += dwarf_bytesize(&type) * field->
index;
452 }
else if (tag == DW_TAG_pointer_type) {
455 pr_err(
"Semantic error: %s must be referred by '->'\n",
461 pr_warning(
"Failed to get the type of %s.\n", varname);
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",
476 (*ref_ptr)->next = ref;
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",
486 if (field->
name[0] ==
'[') {
487 pr_err(
"Semantic error: %s is not a pointer" 488 " nor array.\n", varname);
492 if (field->
ref && dwarf_diename(vr_die)) {
493 pr_err(
"Semantic error: %s must be referred by '.'\n",
505 pr_warning(
"%s(type:%s) has no member %s.\n", varname,
506 dwarf_diename(&type), field->
name);
511 if (tag == DW_TAG_union_type) {
516 pr_warning(
"Failed to get the offset of %s.\n",
521 ref->
offset += (long)offs;
524 if (!dwarf_diename(die_mem))
532 field->
next, &ref, die_mem);
543 pr_debug(
"Converting variable %s into trace event.\n",
544 dwarf_diename(vr_die));
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) {
557 pf->pvar->field, &pf->tvar->ref,
579 pf->tvar->name = strdup(pf->pvar->name);
584 ptr = strchr(buf,
':');
587 pf->tvar->name = buf;
589 if (pf->tvar->name == NULL)
592 pr_debug(
"Searching '%s' variable in context.\n", pf->pvar->var);
598 pr_warning(
"Failed to find '%s' in this function.\n",
611 Dwarf_Addr paddr,
bool retprobe,
612 const char *
function,
615 Dwarf_Addr eaddr, highaddr;
620 if (dwarf_entrypc(sp_die, &eaddr) != 0) {
621 pr_warning(
"Failed to get entry address of %s\n",
622 dwarf_diename(sp_die));
625 if (dwarf_highpc(sp_die, &highaddr) != 0) {
626 pr_warning(
"Failed to get end address of %s\n",
627 dwarf_diename(sp_die));
630 if (paddr > highaddr) {
631 pr_warning(
"Offset specified is greater than size of %s\n",
632 dwarf_diename(sp_die));
636 symbol = dwarf_diename(sp_die);
639 symbol = dwfl_module_addrsym(mod, paddr, &sym, NULL);
641 pr_warning(
"Failed to find symbol at 0x%lx\n",
642 (
unsigned long)paddr);
645 eaddr = sym.st_value;
647 tp->
offset = (
unsigned long)(paddr - eaddr);
648 tp->
address = (
unsigned long)paddr;
649 tp->
symbol = strdup(symbol);
655 if (eaddr != paddr) {
657 " because %s is an inlined function and" 658 " has no return point.\n",
function,
671 Dwarf_Attribute fb_attr;
672 Dwarf_Frame *frame = NULL;
677 pr_err(
"Caller must pass a scope DIE. Program error.\n");
686 dwarf_diename(&pf->sp_die));
689 pr_warning(
"Failed to find probe point in any " 695 memcpy(&pf->sp_die, sc_die,
sizeof(Dwarf_Die));
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) {
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);
717 ret = pf->callback(sc_die, pf);
727 const char *
function;
743 file = dwarf_decl_file(fn_die);
744 if (!file || strcmp(fsp->
file, file) != 0)
756 dwarf_decl_line(fn_die, &lno);
771 .
function = pf->pev->point.function,
785 Dwarf_Addr addr,
void *
data)
787 struct probe_finder *pf =
data;
791 if (lineno != pf->lno ||
strtailcmp(fname, pf->fname) != 0)
797 pr_warning(
"Failed to find scope of probe point.\n");
804 return ret < 0 ? ret : 0;
815 const char *fname,
const char *pat)
821 int count = 0, linenum = 1;
824 fp = fopen(fname,
"r");
827 str_error_r(errno, sbuf,
sizeof(sbuf)));
831 while ((len = getline(&line, &line_len, fp)) > 0) {
833 if (line[len - 1] ==
'\n')
834 line[len - 1] =
'\0';
849 pr_debug(
"No matched lines found in %s.\n", fname);
854 Dwarf_Addr addr,
void *
data)
856 struct probe_finder *pf =
data;
864 pr_debug(
"Probe line found: line:%d addr:0x%llx\n",
865 lineno, (
unsigned long long)addr);
870 pr_warning(
"Failed to find scope of probe point.\n");
880 return ret < 0 ? ret : 0;
890 const char *comp_dir;
895 pr_warning(
"Failed to find source file path.\n");
901 pf->pev->point.lazy_line);
915 if (!pf->pev->uprobes)
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",
944 struct probe_finder *pf =
data;
953 if (dwarf_entrypc(in_die, &addr) != 0) {
954 pr_warning(
"Failed to get entry address of %s.\n",
955 dwarf_diename(in_die));
959 pr_debug(
"%s has no valid entry address. skipped.\n",
960 dwarf_diename(in_die));
965 pr_debug(
"found inline addr: 0x%jx\n",
966 (uintmax_t)pf->addr);
984 struct probe_finder *pf = param->
data;
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);
1000 dwarf_decl_line(sp_die, &pf->lno);
1001 pf->lno += pp->
line;
1005 dwarf_entrypc(sp_die, &pf->addr);
1007 if (pf->addr == 0) {
1008 pr_debug(
"%s has no entry PC. Skipped\n",
1009 dwarf_diename(sp_die));
1025 if (param->
retval == -ENOENT)
1035 return DWARF_CB_ABORT;
1058 if (dwarf_offdie(dbg, gl->die_offset, param->
sp_die)) {
1059 if (dwarf_tag(param->
sp_die) != DW_TAG_subprogram)
1063 if (!dwarf_offdie(dbg, gl->cu_offset, param->
cu_die))
1071 return DWARF_CB_ABORT;
1079 struct probe_finder *pf)
1082 Dwarf_Off off, noff;
1097 .cu_die = &pf->cu_die,
1098 .sp_die = &pf->sp_die,
1107 if (pubname_param.
found) {
1115 while (!dwarf_nextcu(dbg->dbg, off, &noff, &cuhl, NULL, NULL, NULL)) {
1117 diep = dwarf_offdie(dbg->dbg, off + cuhl, &pf->cu_die);
1127 if (!pp->
file || pf->fname) {
1151 struct probe_finder *pf)
1157 if (pf->cfi_eh || pf->cfi_dbg)
1161 elf = dwarf_getelf(dbg->dbg);
1165 if (gelf_getehdr(elf, &ehdr) == NULL)
1168 pf->machine = ehdr.e_machine;
1170 #if _ELFUTILS_PREREQ(0, 142) 1175 shdr.sh_type == SHT_PROGBITS)
1176 pf->cfi_eh = dwarf_getcfi_elf(elf);
1178 pf->cfi_dbg = dwarf_getcfi(dbg->dbg);
1199 struct probe_finder *pf = vf->
pf;
1202 tag = dwarf_tag(die_mem);
1203 if (tag == DW_TAG_formal_parameter ||
1204 (tag == DW_TAG_variable && vf->
vars)) {
1206 vf->
pf->fb_ops, &pf->sp_die,
1207 pf->machine, NULL) == 0) {
1208 vf->
args[vf->
nargs].
var = (
char *)dwarf_diename(die_mem);
1218 if (dwarf_haspc(die_mem, vf->
pf->addr))
1233 for (i = 0; i < pf->pev->nargs; i++) {
1239 args[n] = pf->pev->args[i];
1243 pr_debug(
"Expanding %s into:", pf->pev->args[i].var);
1259 struct trace_event_finder *tf =
1260 container_of(pf,
struct trace_event_finder, pf);
1267 if (tf->ntevs == tf->max_tevs) {
1268 pr_warning(
"Too many( > %d) probe point found.\n",
1272 tev = &tf->tevs[tf->ntevs++];
1302 if (tev->
args == NULL) {
1308 for (i = 0; i < tev->
nargs; i++) {
1309 pf->pvar = &args[i];
1310 pf->tvar = &tev->
args[i];
1331 struct trace_event_finder tf = {
1346 for (i = 0; i < tf.ntevs; i++)
1352 return (ret < 0) ? ret : tf.ntevs;
1358 struct available_var_finder *af =
data;
1363 vl = &af->vls[af->nvls - 1];
1365 tag = dwarf_tag(die_mem);
1366 if (tag == DW_TAG_formal_parameter ||
1367 tag == DW_TAG_variable) {
1369 af->pf.fb_ops, &af->pf.sp_die,
1370 af->pf.machine, NULL);
1371 if (ret == 0 || ret == -ERANGE) {
1373 bool externs = !af->child;
1381 ret ?
"[INV]\t" :
"[VAL]\t", 6);
1407 if (af->child && dwarf_haspc(die_mem, af->pf.addr))
1420 struct available_var_finder *af =
1421 container_of(pf,
struct available_var_finder, pf);
1428 if (af->nvls == af->max_vls) {
1429 pr_warning(
"Too many( > %d) probe point found.\n", af->max_vls);
1432 vl = &af->vls[af->nvls++];
1445 if (vl->
vars == NULL)
1475 struct available_var_finder af = {
1493 zfree(&af.vls[af.nvls].point.symbol);
1500 return (ret < 0) ? ret : af.nvls;
1511 GElf_Shdr
mem, *shdr;
1514 elf = dwfl_module_getelf(dbg->mod, &dbg->bias);
1519 n = dwfl_module_relocations(dbg->mod);
1523 for (i = 0; i < n; i++) {
1524 p = dwfl_module_relocation_info(dbg->mod, i, &shndx);
1525 if (strcmp(p,
".text") == 0) {
1527 scn = elf_getscn(elf, shndx);
1530 shdr = gelf_getshdr(scn, &mem);
1533 *offs = shdr->sh_addr;
1535 *offs -= shdr->sh_offset;
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;
1554 if (!dwarf_addrdie(dbg->dbg, (Dwarf_Addr)addr, &cudie)) {
1555 pr_warning(
"Failed to find debug information for address %lx\n",
1568 func = basefunc = dwarf_diename(&spdie);
1570 dwarf_entrypc(&spdie, &baseaddr) != 0 ||
1571 dwarf_decl_line(&spdie, &baseline) != 0) {
1576 fname = dwarf_decl_file(&spdie);
1577 if (addr == (
unsigned long)baseaddr) {
1587 if (dwarf_entrypc(&indie, &_addr) == 0 &&
1604 tmp = dwarf_diename(&indie);
1606 dwarf_decl_line(&indie, &baseline) != 0)
1613 tmp = dwarf_decl_file(&spdie);
1614 if (!tmp || strcmp(tmp, fname) != 0)
1621 ppt->
line = lineno - baseline;
1622 else if (basefunc) {
1623 ppt->
offset = addr - (
unsigned long)baseaddr;
1636 ppt->
file = strdup(fname);
1637 if (ppt->
file == NULL) {
1644 if (ret == 0 && (fname || func))
1655 lr->
path = strdup(src);
1656 if (lr->
path == NULL)
1663 Dwarf_Addr addr __maybe_unused,
1666 struct line_finder *lf =
data;
1670 (lf->lno_s > lineno || lf->lno_e < lineno))
1674 if (err < 0 && err != -EEXIST)
1690 ret = lf->found = 1;
1694 zfree(&lf->lr->path);
1709 return ret < 0 ? ret : 0;
1716 struct line_finder *lf = param->
data;
1725 lf->fname = dwarf_decl_file(sp_die);
1726 dwarf_decl_line(sp_die, &lr->
offset);
1730 lf->lno_s = INT_MAX;
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;
1742 return DWARF_CB_ABORT;
1756 struct line_finder lf = {.lr = lr, .found = 0};
1758 Dwarf_Off off = 0, noff;
1761 const char *comp_dir;
1767 .cu_die = &lf.cu_die, .sp_die = &lf.sp_die, .found = 0};
1773 if (pubname_param.
found) {
1781 while (!lf.found && ret >= 0) {
1782 if (dwarf_nextcu(dbg->dbg, off, &noff, &cuhl,
1783 NULL, NULL, NULL) != 0)
1787 diep = dwarf_offdie(dbg->dbg, off + cuhl, &lf.cu_die);
1797 if (!lr->
file || lf.fname) {
1801 lf.lno_s = lr->
start;
1821 return (ret < 0) ? ret : lf.found;
1836 if (raw_path[0] !=
'/' && comp_dir)
1840 if (access(raw_path, R_OK) == 0) {
1841 *new_path = strdup(raw_path);
1842 return *new_path ? 0 : -ENOMEM;
1848 *new_path =
malloc((strlen(prefix) + strlen(raw_path) + 2));
1853 sprintf(*new_path,
"%s/%s", prefix, raw_path);
1855 if (access(*new_path, R_OK) == 0)
1869 raw_path = strchr(++raw_path,
'/');
#define MAX_BASIC_TYPE_BITS
int strbuf_init(struct strbuf *sb, ssize_t hint)
int die_get_data_member_location(Dwarf_Die *mb_die, Dwarf_Word *offs)
static int probe_point_line_walker(const char *fname, int lineno, Dwarf_Addr addr, void *data)
bool perf_probe_with_var(struct perf_probe_event *pev)
int debuginfo__find_line_range(struct debuginfo *dbg, struct line_range *lr)
const char * cu_get_comp_dir(Dwarf_Die *cu_die)
void clear_probe_trace_event(struct probe_trace_event *tev)
static int line_range_add_line(const char *src, unsigned int lineno, struct line_range *lr)
const char * source_prefix
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)
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)
Dwarf_Die * die_find_member(Dwarf_Die *st_die, const char *name, Dwarf_Die *die_mem)
static int add_available_vars(Dwarf_Die *sc_die, struct probe_finder *pf)
struct probe_trace_point point
struct perf_probe_arg_field * next
static int find_lazy_match_lines(struct intlist *list, const char *fname, const char *pat)
static bool intlist__empty(const struct intlist *ilist)
void intlist__delete(struct intlist *ilist)
static bool strisglob(const char *str)
int intlist__add(struct intlist *ilist, int i)
Dwarf_Die * die_find_variable_at(Dwarf_Die *sp_die, const char *name, Dwarf_Addr addr, Dwarf_Die *die_mem)
static int probe_point_search_cb(Dwarf_Die *sp_die, void *data)
int strlist__add(struct strlist *slist, const char *new_entry)
#define pr_debug2(fmt,...)
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)
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)
static int debuginfo__find_probe_location(struct debuginfo *dbg, struct probe_finder *pf)
char * synthesize_perf_probe_arg(struct perf_probe_arg *pa)
static int convert_variable_type(Dwarf_Die *vr_die, struct probe_trace_arg *tvar, const char *cast)
int die_walk_lines(Dwarf_Die *rt_die, line_walk_callback_t callback, void *data)
static int find_best_scope_cb(Dwarf_Die *fn_die, void *data)
static Dwarf_Die * find_best_scope(struct probe_finder *pf, Dwarf_Die *die_mem)
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)
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)
static int line_range_inline_cb(Dwarf_Die *in_die, void *data)
bool die_compare_name(Dwarf_Die *dw_die, const char *tname)
bool die_is_func_instance(Dwarf_Die *dw_die)
void dso__put(struct dso *dso)
bool probe_type_is_available(enum probe_type type)
Dwarf_Die * die_find_child(Dwarf_Die *rt_die, int(*callback)(Dwarf_Die *, void *), void *data, Dwarf_Die *die_mem)
struct perf_probe_arg * args
static int find_line_range_by_func(struct line_finder *lf)
static struct probe_trace_arg_ref * alloc_trace_arg_ref(long offs)
static int find_variable(Dwarf_Die *sc_die, struct probe_finder *pf)
static bool intlist__has_entry(struct intlist *ilist, int i)
struct probe_trace_arg_ref * next
Dwarf_Die * die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr, Dwarf_Die *die_mem)
bool die_match_name(Dwarf_Die *dw_die, const char *glob)
#define pr_debug(fmt,...)
#define BYTES_TO_BITS(nb)
static bool strlist__empty(const struct strlist *slist)
int dso__read_binary_type_filename(const struct dso *dso, enum dso_binary_type type, char *root_dir, char *filename, size_t size)
static void skip_prologue(Dwarf_Die *sp_die, struct probe_finder *pf)
static int expand_probe_args(Dwarf_Die *sc_die, struct probe_finder *pf, struct perf_probe_arg *args)
int die_walk_instances(Dwarf_Die *or_die, int(*callback)(Dwarf_Die *, void *), void *data)
Elf_Scn * elf_section_by_name(Elf *elf, GElf_Ehdr *ep, GElf_Shdr *shp, const char *name, size_t *idx)
struct intlist * line_list
int strbuf_add(struct strbuf *sb, const void *data, size_t len)
static int call_probe_finder(Dwarf_Die *sc_die, struct probe_finder *pf)
int get_real_path(const char *raw_path, const char *comp_dir, char **new_path)
static int debuginfo__init_offline_dwarf(struct debuginfo *dbg, const char *path)
int cu_walk_functions_at(Dwarf_Die *cu_die, Dwarf_Addr addr, int(*callback)(Dwarf_Die *, void *), void *data)
struct probe_trace_arg * args
Dwarf_Die * die_find_top_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, Dwarf_Die *die_mem)
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
int cu_find_lineinfo(Dwarf_Die *cu_die, unsigned long addr, const char **fname, int *lineno)
static int find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf)
static int is_c_varname(const char *name)
struct intlist * intlist__new(const char *slist)
struct dso * dso__new(const char *name)
int copy_to_probe_trace_arg(struct probe_trace_arg *tvar, struct perf_probe_arg *pvar)
int strbuf_addch(struct strbuf *sb, int c)
const char * die_get_call_file(Dwarf_Die *in_die)
unsigned long abs_address
static int find_probe_point_by_func(struct probe_finder *pf)
char * strbuf_detach(struct strbuf *sb, size_t *sz)
static struct debuginfo * __debuginfo__new(const char *path)
static int sym(yyscan_t scanner, int type, int config)
bool die_is_signed_type(Dwarf_Die *tp_die)
int strtailcmp(const char *s1, const char *s2)
void strlist__delete(struct strlist *slist)
static int line_range_walk_cb(const char *fname, int lineno, Dwarf_Addr addr __maybe_unused, void *data)
Dwarf_Die * die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem)
static int probe_point_inline_cb(Dwarf_Die *in_die, void *data)
int die_get_varname(Dwarf_Die *vr_die, struct strbuf *buf)
bool strlazymatch(const char *str, const char *pat)
static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)
bool die_is_func_def(Dwarf_Die *dw_die)
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)
static int probe_point_lazy_walker(const char *fname, int lineno, Dwarf_Addr addr, void *data)
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,...)
static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
void debuginfo__delete(struct debuginfo *dbg)
static int find_probe_point_by_line(struct probe_finder *pf)
static const Dwfl_Callbacks offline_callbacks
static char * debuginfo_path
struct strlist * strlist__new(const char *list, const struct strlist_config *config)
void strbuf_release(struct strbuf *sb)
bool die_is_optimized_target(Dwarf_Die *cu_die)
const char * cu_find_realpath(Dwarf_Die *cu_die, const char *fname)
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)
struct debuginfo * debuginfo__new(const char *path)
enum dso_binary_type distro_dwarf_types[]
void static void * zalloc(size_t size)
int die_get_call_lineno(Dwarf_Die *in_die)
struct probe_trace_arg_ref * ref