aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/probe-finder.c
diff options
context:
space:
mode:
authorMasami Hiramatsu <mhiramat@redhat.com>2010-04-14 18:40:07 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2010-04-14 16:45:39 -0400
commitf6c903f5856ffa75ae19dcee4dbb5093e320d45c (patch)
tree47d375e530c208166baa04941f5e1be984a67640 /tools/perf/util/probe-finder.c
parentde1439d8a521d22c3219fc007a570fcf944ac789 (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.c74
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 */
1131static 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 */
1144static 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
1163static 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, &param, 0);
1167 return param.retval;
1168}
1130 1169
1131/* Find line range from its line number */ 1170/* Find line range from its line number */
1132static int find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf) 1171static 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
1188static int line_range_inline_cb(Dwarf_Die *in_die, void *data) 1240static int line_range_inline_cb(Dwarf_Die *in_die, void *data)