diff options
author | Masami Hiramatsu <mhiramat@redhat.com> | 2010-04-14 18:40:07 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2010-04-14 16:45:39 -0400 |
commit | f6c903f5856ffa75ae19dcee4dbb5093e320d45c (patch) | |
tree | 47d375e530c208166baa04941f5e1be984a67640 /tools/perf/util/probe-finder.c | |
parent | de1439d8a521d22c3219fc007a570fcf944ac789 (diff) |
perf probe: Show function entry line as probe-able
Function entry line should be shown as probe-able line,
because each function has declared line attribute.
LKML-Reference: <20100414224007.14630.96915.stgit@localhost6.localdomain6>
Signed-off-by: Masami Hiramatsu <mhiramat@redhat.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/probe-finder.c')
-rw-r--r-- | tools/perf/util/probe-finder.c | 74 |
1 files changed, 63 insertions, 11 deletions
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 03b469197a03..3e7977560be5 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c | |||
@@ -1127,6 +1127,45 @@ end: | |||
1127 | return ret; | 1127 | return ret; |
1128 | } | 1128 | } |
1129 | 1129 | ||
1130 | /* Add a line and store the src path */ | ||
1131 | static int line_range_add_line(const char *src, unsigned int lineno, | ||
1132 | struct line_range *lr) | ||
1133 | { | ||
1134 | /* Copy real path */ | ||
1135 | if (!lr->path) { | ||
1136 | lr->path = strdup(src); | ||
1137 | if (lr->path == NULL) | ||
1138 | return -ENOMEM; | ||
1139 | } | ||
1140 | return line_list__add_line(&lr->line_list, lineno); | ||
1141 | } | ||
1142 | |||
1143 | /* Search function declaration lines */ | ||
1144 | static int line_range_funcdecl_cb(Dwarf_Die *sp_die, void *data) | ||
1145 | { | ||
1146 | struct dwarf_callback_param *param = data; | ||
1147 | struct line_finder *lf = param->data; | ||
1148 | const char *src; | ||
1149 | int lineno; | ||
1150 | |||
1151 | src = dwarf_decl_file(sp_die); | ||
1152 | if (src && strtailcmp(src, lf->fname) != 0) | ||
1153 | return DWARF_CB_OK; | ||
1154 | |||
1155 | if (dwarf_decl_line(sp_die, &lineno) != 0 || | ||
1156 | (lf->lno_s > lineno || lf->lno_e < lineno)) | ||
1157 | return DWARF_CB_OK; | ||
1158 | |||
1159 | param->retval = line_range_add_line(src, lineno, lf->lr); | ||
1160 | return DWARF_CB_OK; | ||
1161 | } | ||
1162 | |||
1163 | static int find_line_range_func_decl_lines(struct line_finder *lf) | ||
1164 | { | ||
1165 | struct dwarf_callback_param param = {.data = (void *)lf, .retval = 0}; | ||
1166 | dwarf_getfuncs(&lf->cu_die, line_range_funcdecl_cb, ¶m, 0); | ||
1167 | return param.retval; | ||
1168 | } | ||
1130 | 1169 | ||
1131 | /* Find line range from its line number */ | 1170 | /* Find line range from its line number */ |
1132 | static int find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf) | 1171 | static int find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf) |
@@ -1135,7 +1174,7 @@ static int find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf) | |||
1135 | Dwarf_Line *line; | 1174 | Dwarf_Line *line; |
1136 | size_t nlines, i; | 1175 | size_t nlines, i; |
1137 | Dwarf_Addr addr; | 1176 | Dwarf_Addr addr; |
1138 | int lineno; | 1177 | int lineno, ret = 0; |
1139 | const char *src; | 1178 | const char *src; |
1140 | Dwarf_Die die_mem; | 1179 | Dwarf_Die die_mem; |
1141 | 1180 | ||
@@ -1145,6 +1184,7 @@ static int find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf) | |||
1145 | return -ENOENT; | 1184 | return -ENOENT; |
1146 | } | 1185 | } |
1147 | 1186 | ||
1187 | /* Search probable lines on lines list */ | ||
1148 | for (i = 0; i < nlines; i++) { | 1188 | for (i = 0; i < nlines; i++) { |
1149 | line = dwarf_onesrcline(lines, i); | 1189 | line = dwarf_onesrcline(lines, i); |
1150 | if (dwarf_lineno(line, &lineno) != 0 || | 1190 | if (dwarf_lineno(line, &lineno) != 0 || |
@@ -1167,22 +1207,34 @@ static int find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf) | |||
1167 | if (strtailcmp(src, lf->fname) != 0) | 1207 | if (strtailcmp(src, lf->fname) != 0) |
1168 | continue; | 1208 | continue; |
1169 | 1209 | ||
1170 | /* Copy real path */ | 1210 | ret = line_range_add_line(src, lineno, lf->lr); |
1171 | if (!lf->lr->path) { | 1211 | if (ret < 0) |
1172 | lf->lr->path = strdup(src); | 1212 | return ret; |
1173 | if (lf->lr->path == NULL) | ||
1174 | return -ENOMEM; | ||
1175 | } | ||
1176 | line_list__add_line(&lf->lr->line_list, lineno); | ||
1177 | } | 1213 | } |
1214 | |||
1215 | /* | ||
1216 | * Dwarf lines doesn't include function declarations. We have to | ||
1217 | * check functions list or given function. | ||
1218 | */ | ||
1219 | if (sp_die) { | ||
1220 | src = dwarf_decl_file(sp_die); | ||
1221 | if (src && dwarf_decl_line(sp_die, &lineno) == 0 && | ||
1222 | (lf->lno_s <= lineno && lf->lno_e >= lineno)) | ||
1223 | ret = line_range_add_line(src, lineno, lf->lr); | ||
1224 | } else | ||
1225 | ret = find_line_range_func_decl_lines(lf); | ||
1226 | |||
1178 | /* Update status */ | 1227 | /* Update status */ |
1179 | if (!list_empty(&lf->lr->line_list)) | 1228 | if (ret >= 0) |
1180 | lf->found = 1; | 1229 | if (!list_empty(&lf->lr->line_list)) |
1230 | ret = lf->found = 1; | ||
1231 | else | ||
1232 | ret = 0; /* Lines are not found */ | ||
1181 | else { | 1233 | else { |
1182 | free(lf->lr->path); | 1234 | free(lf->lr->path); |
1183 | lf->lr->path = NULL; | 1235 | lf->lr->path = NULL; |
1184 | } | 1236 | } |
1185 | return lf->found; | 1237 | return ret; |
1186 | } | 1238 | } |
1187 | 1239 | ||
1188 | static int line_range_inline_cb(Dwarf_Die *in_die, void *data) | 1240 | static int line_range_inline_cb(Dwarf_Die *in_die, void *data) |