static int find_variable(Dwarf_Die *sc_die, struct probe_finder *pf) { Dwarf_Die vr_die; char buf[32], *ptr; int ret = 0; if (!is_c_varname(pf->pvar->var)) { pf->tvar->value = strdup(pf->pvar->var); if (pf->tvar->value == NULL) return -ENOMEM; if (pf->pvar->type) { pf->tvar->type = strdup(pf->pvar->type); if (pf->tvar->type == NULL) return -ENOMEM; } if (pf->pvar->name) { pf->tvar->name = strdup(pf->pvar->name); if (pf->tvar->name == NULL) return -ENOMEM; } else pf->tvar->name = NULL; return 0; } if (pf->pvar->name) pf->tvar->name = strdup(pf->pvar->name); else { ret = synthesize_perf_probe_arg(pf->pvar, buf, 32); if (ret < 0) return ret; ptr = strchr(buf, ':'); if (ptr) *ptr = '_'; pf->tvar->name = strdup(buf); } if (pf->tvar->name == NULL) return -ENOMEM; pr_debug("Searching '%s' variable in context.\n", pf->pvar->var); if (!die_find_variable_at(sc_die, pf->pvar->var, pf->addr, &vr_die)) { if (!die_find_variable_at(&pf->cu_die, pf->pvar->var, 0, &vr_die)) ret = -ENOENT; } if (ret >= 0) ret = convert_variable(&vr_die, pf); if (ret < 0) pr_warning("Failed to find '%s' in this function.\n", pf->pvar->var); return ret; }
/* Find a variable in a subprogram die */ static int find_variable(Dwarf_Die *sp_die, struct probe_finder *pf) { Dwarf_Die vr_die, *scopes; char buf[32], *ptr; int ret, nscopes; if (!is_c_varname(pf->pvar->var)) { /* Copy raw parameters */ pf->tvar->value = strdup(pf->pvar->var); if (pf->tvar->value == NULL) return -ENOMEM; if (pf->pvar->type) { pf->tvar->type = strdup(pf->pvar->type); if (pf->tvar->type == NULL) return -ENOMEM; } if (pf->pvar->name) { pf->tvar->name = strdup(pf->pvar->name); if (pf->tvar->name == NULL) return -ENOMEM; } else pf->tvar->name = NULL; return 0; } if (pf->pvar->name) pf->tvar->name = strdup(pf->pvar->name); else { ret = synthesize_perf_probe_arg(pf->pvar, buf, 32); if (ret < 0) return ret; ptr = strchr(buf, ':'); /* Change type separator to _ */ if (ptr) *ptr = '_'; pf->tvar->name = strdup(buf); } if (pf->tvar->name == NULL) return -ENOMEM; pr_debug("Searching '%s' variable in context.\n", pf->pvar->var); /* Search child die for local variables and parameters. */ if (die_find_variable_at(sp_die, pf->pvar->var, pf->addr, &vr_die)) ret = convert_variable(&vr_die, pf); else { /* Search upper class */ nscopes = dwarf_getscopes_die(sp_die, &scopes); while (nscopes-- > 1) { pr_debug("Searching variables in %s\n", dwarf_diename(&scopes[nscopes])); /* We should check this scope, so give dummy address */ if (die_find_variable_at(&scopes[nscopes], pf->pvar->var, 0, &vr_die)) { ret = convert_variable(&vr_die, pf); goto found; } } if (scopes) free(scopes); ret = -ENOENT; } found: if (ret < 0) pr_warning("Failed to find '%s' in this function.\n", pf->pvar->var); return ret; }