static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf) { Dwarf_Die die_mem; int ret; pr_debug("Converting variable %s into trace event.\n", dwarf_diename(vr_die)); ret = convert_variable_location(vr_die, pf->addr, pf->fb_ops, pf->tvar); if (ret == -ENOENT) pr_err("Failed to find the location of %s at this address.\n" " Perhaps, it has been optimized out.\n", pf->pvar->var); else if (ret == -ENOTSUP) pr_err("Sorry, we don't support this variable location yet.\n"); else if (pf->pvar->field) { ret = convert_variable_fields(vr_die, pf->pvar->var, pf->pvar->field, &pf->tvar->ref, &die_mem); vr_die = &die_mem; } if (ret == 0) ret = convert_variable_type(vr_die, pf->tvar, pf->pvar->type); return ret; }
/* Show a variables in kprobe event format */ static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf) { Dwarf_Attribute attr; Dwarf_Die die_mem; Dwarf_Op *expr; size_t nexpr; int ret; if (dwarf_attr(vr_die, DW_AT_location, &attr) == NULL) goto error; /* TODO: handle more than 1 exprs */ ret = dwarf_getlocation_addr(&attr, pf->addr, &expr, &nexpr, 1); if (ret <= 0 || nexpr == 0) goto error; ret = convert_location(expr, pf); if (ret == 0 && pf->pvar->field) { ret = convert_variable_fields(vr_die, pf->pvar->var, pf->pvar->field, &pf->tvar->ref, &die_mem); vr_die = &die_mem; } if (ret == 0) { if (pf->pvar->type) { pf->tvar->type = strdup(pf->pvar->type); if (pf->tvar->type == NULL) ret = -ENOMEM; } else ret = convert_variable_type(vr_die, pf->tvar); } /* *expr will be cached in libdw. Don't free it. */ return ret; error: /* TODO: Support const_value */ pr_err("Failed to find the location of %s at this address.\n" " Perhaps, it has been optimized out.\n", pf->pvar->var); return -ENOENT; }