diff options
Diffstat (limited to 'tools/perf/util/probe-finder.c')
-rw-r--r-- | tools/perf/util/probe-finder.c | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 986027fa495f..a274fd0c143e 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c | |||
@@ -1312,12 +1312,13 @@ static int collect_variables_cb(Dwarf_Die *die_mem, void *data) | |||
1312 | af->pf.fb_ops, NULL); | 1312 | af->pf.fb_ops, NULL); |
1313 | if (ret == 0) { | 1313 | if (ret == 0) { |
1314 | ret = die_get_varname(die_mem, buf, MAX_VAR_LEN); | 1314 | ret = die_get_varname(die_mem, buf, MAX_VAR_LEN); |
1315 | pr_debug2("Add new var: %s\n", buf); | ||
1315 | if (ret > 0) | 1316 | if (ret > 0) |
1316 | strlist__add(vl->vars, buf); | 1317 | strlist__add(vl->vars, buf); |
1317 | } | 1318 | } |
1318 | } | 1319 | } |
1319 | 1320 | ||
1320 | if (dwarf_haspc(die_mem, af->pf.addr)) | 1321 | if (af->child && dwarf_haspc(die_mem, af->pf.addr)) |
1321 | return DIE_FIND_CB_CONTINUE; | 1322 | return DIE_FIND_CB_CONTINUE; |
1322 | else | 1323 | else |
1323 | return DIE_FIND_CB_SIBLING; | 1324 | return DIE_FIND_CB_SIBLING; |
@@ -1329,8 +1330,8 @@ static int add_available_vars(Dwarf_Die *sp_die, struct probe_finder *pf) | |||
1329 | struct available_var_finder *af = | 1330 | struct available_var_finder *af = |
1330 | container_of(pf, struct available_var_finder, pf); | 1331 | container_of(pf, struct available_var_finder, pf); |
1331 | struct variable_list *vl; | 1332 | struct variable_list *vl; |
1332 | Dwarf_Die die_mem; | 1333 | Dwarf_Die die_mem, *scopes = NULL; |
1333 | int ret; | 1334 | int ret, nscopes; |
1334 | 1335 | ||
1335 | /* Check number of tevs */ | 1336 | /* Check number of tevs */ |
1336 | if (af->nvls == af->max_vls) { | 1337 | if (af->nvls == af->max_vls) { |
@@ -1351,8 +1352,22 @@ static int add_available_vars(Dwarf_Die *sp_die, struct probe_finder *pf) | |||
1351 | vl->vars = strlist__new(true, NULL); | 1352 | vl->vars = strlist__new(true, NULL); |
1352 | if (vl->vars == NULL) | 1353 | if (vl->vars == NULL) |
1353 | return -ENOMEM; | 1354 | return -ENOMEM; |
1355 | af->child = true; | ||
1354 | die_find_child(sp_die, collect_variables_cb, (void *)af, &die_mem); | 1356 | die_find_child(sp_die, collect_variables_cb, (void *)af, &die_mem); |
1355 | 1357 | ||
1358 | /* Find external variables */ | ||
1359 | if (!af->externs) | ||
1360 | goto out; | ||
1361 | /* Don't need to search child DIE for externs. */ | ||
1362 | af->child = false; | ||
1363 | nscopes = dwarf_getscopes_die(sp_die, &scopes); | ||
1364 | while (nscopes-- > 1) | ||
1365 | die_find_child(&scopes[nscopes], collect_variables_cb, | ||
1366 | (void *)af, &die_mem); | ||
1367 | if (scopes) | ||
1368 | free(scopes); | ||
1369 | |||
1370 | out: | ||
1356 | if (strlist__empty(vl->vars)) { | 1371 | if (strlist__empty(vl->vars)) { |
1357 | strlist__delete(vl->vars); | 1372 | strlist__delete(vl->vars); |
1358 | vl->vars = NULL; | 1373 | vl->vars = NULL; |
@@ -1363,11 +1378,12 @@ static int add_available_vars(Dwarf_Die *sp_die, struct probe_finder *pf) | |||
1363 | 1378 | ||
1364 | /* Find available variables at given probe point */ | 1379 | /* Find available variables at given probe point */ |
1365 | int find_available_vars_at(int fd, struct perf_probe_event *pev, | 1380 | int find_available_vars_at(int fd, struct perf_probe_event *pev, |
1366 | struct variable_list **vls, int max_vls) | 1381 | struct variable_list **vls, int max_vls, |
1382 | bool externs) | ||
1367 | { | 1383 | { |
1368 | struct available_var_finder af = { | 1384 | struct available_var_finder af = { |
1369 | .pf = {.pev = pev, .callback = add_available_vars}, | 1385 | .pf = {.pev = pev, .callback = add_available_vars}, |
1370 | .max_vls = max_vls}; | 1386 | .max_vls = max_vls, .externs = externs}; |
1371 | int ret; | 1387 | int ret; |
1372 | 1388 | ||
1373 | /* Allocate result vls array */ | 1389 | /* Allocate result vls array */ |