aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/probe-finder.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/probe-finder.c')
-rw-r--r--tools/perf/util/probe-finder.c250
1 files changed, 177 insertions, 73 deletions
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index c09e0a9fdf4c..ffb657ffd327 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -115,7 +115,7 @@ static const Dwfl_Callbacks offline_callbacks = {
115}; 115};
116 116
117/* Get a Dwarf from offline image */ 117/* Get a Dwarf from offline image */
118static int debuginfo__init_offline_dwarf(struct debuginfo *self, 118static int debuginfo__init_offline_dwarf(struct debuginfo *dbg,
119 const char *path) 119 const char *path)
120{ 120{
121 int fd; 121 int fd;
@@ -124,25 +124,25 @@ static int debuginfo__init_offline_dwarf(struct debuginfo *self,
124 if (fd < 0) 124 if (fd < 0)
125 return fd; 125 return fd;
126 126
127 self->dwfl = dwfl_begin(&offline_callbacks); 127 dbg->dwfl = dwfl_begin(&offline_callbacks);
128 if (!self->dwfl) 128 if (!dbg->dwfl)
129 goto error; 129 goto error;
130 130
131 self->mod = dwfl_report_offline(self->dwfl, "", "", fd); 131 dbg->mod = dwfl_report_offline(dbg->dwfl, "", "", fd);
132 if (!self->mod) 132 if (!dbg->mod)
133 goto error; 133 goto error;
134 134
135 self->dbg = dwfl_module_getdwarf(self->mod, &self->bias); 135 dbg->dbg = dwfl_module_getdwarf(dbg->mod, &dbg->bias);
136 if (!self->dbg) 136 if (!dbg->dbg)
137 goto error; 137 goto error;
138 138
139 return 0; 139 return 0;
140error: 140error:
141 if (self->dwfl) 141 if (dbg->dwfl)
142 dwfl_end(self->dwfl); 142 dwfl_end(dbg->dwfl);
143 else 143 else
144 close(fd); 144 close(fd);
145 memset(self, 0, sizeof(*self)); 145 memset(dbg, 0, sizeof(*dbg));
146 146
147 return -ENOENT; 147 return -ENOENT;
148} 148}
@@ -180,24 +180,24 @@ static const Dwfl_Callbacks kernel_callbacks = {
180}; 180};
181 181
182/* Get a Dwarf from live kernel image */ 182/* Get a Dwarf from live kernel image */
183static int debuginfo__init_online_kernel_dwarf(struct debuginfo *self, 183static int debuginfo__init_online_kernel_dwarf(struct debuginfo *dbg,
184 Dwarf_Addr addr) 184 Dwarf_Addr addr)
185{ 185{
186 self->dwfl = dwfl_begin(&kernel_callbacks); 186 dbg->dwfl = dwfl_begin(&kernel_callbacks);
187 if (!self->dwfl) 187 if (!dbg->dwfl)
188 return -EINVAL; 188 return -EINVAL;
189 189
190 /* Load the kernel dwarves: Don't care the result here */ 190 /* Load the kernel dwarves: Don't care the result here */
191 dwfl_linux_kernel_report_kernel(self->dwfl); 191 dwfl_linux_kernel_report_kernel(dbg->dwfl);
192 dwfl_linux_kernel_report_modules(self->dwfl); 192 dwfl_linux_kernel_report_modules(dbg->dwfl);
193 193
194 self->dbg = dwfl_addrdwarf(self->dwfl, addr, &self->bias); 194 dbg->dbg = dwfl_addrdwarf(dbg->dwfl, addr, &dbg->bias);
195 /* Here, check whether we could get a real dwarf */ 195 /* Here, check whether we could get a real dwarf */
196 if (!self->dbg) { 196 if (!dbg->dbg) {
197 pr_debug("Failed to find kernel dwarf at %lx\n", 197 pr_debug("Failed to find kernel dwarf at %lx\n",
198 (unsigned long)addr); 198 (unsigned long)addr);
199 dwfl_end(self->dwfl); 199 dwfl_end(dbg->dwfl);
200 memset(self, 0, sizeof(*self)); 200 memset(dbg, 0, sizeof(*dbg));
201 return -ENOENT; 201 return -ENOENT;
202 } 202 }
203 203
@@ -205,7 +205,7 @@ static int debuginfo__init_online_kernel_dwarf(struct debuginfo *self,
205} 205}
206#else 206#else
207/* With older elfutils, this just support kernel module... */ 207/* With older elfutils, this just support kernel module... */
208static int debuginfo__init_online_kernel_dwarf(struct debuginfo *self, 208static int debuginfo__init_online_kernel_dwarf(struct debuginfo *dbg,
209 Dwarf_Addr addr __maybe_unused) 209 Dwarf_Addr addr __maybe_unused)
210{ 210{
211 const char *path = kernel_get_module_path("kernel"); 211 const char *path = kernel_get_module_path("kernel");
@@ -216,44 +216,45 @@ static int debuginfo__init_online_kernel_dwarf(struct debuginfo *self,
216 } 216 }
217 217
218 pr_debug2("Use file %s for debuginfo\n", path); 218 pr_debug2("Use file %s for debuginfo\n", path);
219 return debuginfo__init_offline_dwarf(self, path); 219 return debuginfo__init_offline_dwarf(dbg, path);
220} 220}
221#endif 221#endif
222 222
223struct debuginfo *debuginfo__new(const char *path) 223struct debuginfo *debuginfo__new(const char *path)
224{ 224{
225 struct debuginfo *self = zalloc(sizeof(struct debuginfo)); 225 struct debuginfo *dbg = zalloc(sizeof(*dbg));
226 if (!self) 226 if (!dbg)
227 return NULL; 227 return NULL;
228 228
229 if (debuginfo__init_offline_dwarf(self, path) < 0) { 229 if (debuginfo__init_offline_dwarf(dbg, path) < 0) {
230 free(self); 230 free(dbg);
231 self = NULL; 231 dbg = NULL;
232 } 232 }
233 233
234 return self; 234 return dbg;
235} 235}
236 236
237struct debuginfo *debuginfo__new_online_kernel(unsigned long addr) 237struct debuginfo *debuginfo__new_online_kernel(unsigned long addr)
238{ 238{
239 struct debuginfo *self = zalloc(sizeof(struct debuginfo)); 239 struct debuginfo *dbg = zalloc(sizeof(*dbg));
240 if (!self) 240
241 if (!dbg)
241 return NULL; 242 return NULL;
242 243
243 if (debuginfo__init_online_kernel_dwarf(self, (Dwarf_Addr)addr) < 0) { 244 if (debuginfo__init_online_kernel_dwarf(dbg, (Dwarf_Addr)addr) < 0) {
244 free(self); 245 free(dbg);
245 self = NULL; 246 dbg = NULL;
246 } 247 }
247 248
248 return self; 249 return dbg;
249} 250}
250 251
251void debuginfo__delete(struct debuginfo *self) 252void debuginfo__delete(struct debuginfo *dbg)
252{ 253{
253 if (self) { 254 if (dbg) {
254 if (self->dwfl) 255 if (dbg->dwfl)
255 dwfl_end(self->dwfl); 256 dwfl_end(dbg->dwfl);
256 free(self); 257 free(dbg);
257 } 258 }
258} 259}
259 260
@@ -273,12 +274,15 @@ static struct probe_trace_arg_ref *alloc_trace_arg_ref(long offs)
273/* 274/*
274 * Convert a location into trace_arg. 275 * Convert a location into trace_arg.
275 * If tvar == NULL, this just checks variable can be converted. 276 * If tvar == NULL, this just checks variable can be converted.
277 * If fentry == true and vr_die is a parameter, do huristic search
278 * for the location fuzzed by function entry mcount.
276 */ 279 */
277static int convert_variable_location(Dwarf_Die *vr_die, Dwarf_Addr addr, 280static int convert_variable_location(Dwarf_Die *vr_die, Dwarf_Addr addr,
278 Dwarf_Op *fb_ops, 281 Dwarf_Op *fb_ops, Dwarf_Die *sp_die,
279 struct probe_trace_arg *tvar) 282 struct probe_trace_arg *tvar)
280{ 283{
281 Dwarf_Attribute attr; 284 Dwarf_Attribute attr;
285 Dwarf_Addr tmp = 0;
282 Dwarf_Op *op; 286 Dwarf_Op *op;
283 size_t nops; 287 size_t nops;
284 unsigned int regn; 288 unsigned int regn;
@@ -291,12 +295,29 @@ static int convert_variable_location(Dwarf_Die *vr_die, Dwarf_Addr addr,
291 goto static_var; 295 goto static_var;
292 296
293 /* TODO: handle more than 1 exprs */ 297 /* TODO: handle more than 1 exprs */
294 if (dwarf_attr(vr_die, DW_AT_location, &attr) == NULL || 298 if (dwarf_attr(vr_die, DW_AT_location, &attr) == NULL)
295 dwarf_getlocation_addr(&attr, addr, &op, &nops, 1) <= 0 || 299 return -EINVAL; /* Broken DIE ? */
296 nops == 0) { 300 if (dwarf_getlocation_addr(&attr, addr, &op, &nops, 1) <= 0) {
297 /* TODO: Support const_value */ 301 ret = dwarf_entrypc(sp_die, &tmp);
302 if (ret || addr != tmp ||
303 dwarf_tag(vr_die) != DW_TAG_formal_parameter ||
304 dwarf_highpc(sp_die, &tmp))
305 return -ENOENT;
306 /*
307 * This is fuzzed by fentry mcount. We try to find the
308 * parameter location at the earliest address.
309 */
310 for (addr += 1; addr <= tmp; addr++) {
311 if (dwarf_getlocation_addr(&attr, addr, &op,
312 &nops, 1) > 0)
313 goto found;
314 }
298 return -ENOENT; 315 return -ENOENT;
299 } 316 }
317found:
318 if (nops == 0)
319 /* TODO: Support const_value */
320 return -ENOENT;
300 321
301 if (op->atom == DW_OP_addr) { 322 if (op->atom == DW_OP_addr) {
302static_var: 323static_var:
@@ -563,7 +584,7 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
563 } 584 }
564 585
565 if (die_find_member(&type, field->name, die_mem) == NULL) { 586 if (die_find_member(&type, field->name, die_mem) == NULL) {
566 pr_warning("%s(tyep:%s) has no member %s.\n", varname, 587 pr_warning("%s(type:%s) has no member %s.\n", varname,
567 dwarf_diename(&type), field->name); 588 dwarf_diename(&type), field->name);
568 return -EINVAL; 589 return -EINVAL;
569 } 590 }
@@ -600,7 +621,7 @@ static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
600 dwarf_diename(vr_die)); 621 dwarf_diename(vr_die));
601 622
602 ret = convert_variable_location(vr_die, pf->addr, pf->fb_ops, 623 ret = convert_variable_location(vr_die, pf->addr, pf->fb_ops,
603 pf->tvar); 624 &pf->sp_die, pf->tvar);
604 if (ret == -ENOENT) 625 if (ret == -ENOENT)
605 pr_err("Failed to find the location of %s at this address.\n" 626 pr_err("Failed to find the location of %s at this address.\n"
606 " Perhaps, it has been optimized out.\n", pf->pvar->var); 627 " Perhaps, it has been optimized out.\n", pf->pvar->var);
@@ -1063,7 +1084,7 @@ static int pubname_search_cb(Dwarf *dbg, Dwarf_Global *gl, void *data)
1063} 1084}
1064 1085
1065/* Find probe points from debuginfo */ 1086/* Find probe points from debuginfo */
1066static int debuginfo__find_probes(struct debuginfo *self, 1087static int debuginfo__find_probes(struct debuginfo *dbg,
1067 struct probe_finder *pf) 1088 struct probe_finder *pf)
1068{ 1089{
1069 struct perf_probe_point *pp = &pf->pev->point; 1090 struct perf_probe_point *pp = &pf->pev->point;
@@ -1074,7 +1095,7 @@ static int debuginfo__find_probes(struct debuginfo *self,
1074 1095
1075#if _ELFUTILS_PREREQ(0, 142) 1096#if _ELFUTILS_PREREQ(0, 142)
1076 /* Get the call frame information from this dwarf */ 1097 /* Get the call frame information from this dwarf */
1077 pf->cfi = dwarf_getcfi(self->dbg); 1098 pf->cfi = dwarf_getcfi(dbg->dbg);
1078#endif 1099#endif
1079 1100
1080 off = 0; 1101 off = 0;
@@ -1093,7 +1114,7 @@ static int debuginfo__find_probes(struct debuginfo *self,
1093 .data = pf, 1114 .data = pf,
1094 }; 1115 };
1095 1116
1096 dwarf_getpubnames(self->dbg, pubname_search_cb, 1117 dwarf_getpubnames(dbg->dbg, pubname_search_cb,
1097 &pubname_param, 0); 1118 &pubname_param, 0);
1098 if (pubname_param.found) { 1119 if (pubname_param.found) {
1099 ret = probe_point_search_cb(&pf->sp_die, &probe_param); 1120 ret = probe_point_search_cb(&pf->sp_die, &probe_param);
@@ -1103,9 +1124,9 @@ static int debuginfo__find_probes(struct debuginfo *self,
1103 } 1124 }
1104 1125
1105 /* Loop on CUs (Compilation Unit) */ 1126 /* Loop on CUs (Compilation Unit) */
1106 while (!dwarf_nextcu(self->dbg, off, &noff, &cuhl, NULL, NULL, NULL)) { 1127 while (!dwarf_nextcu(dbg->dbg, off, &noff, &cuhl, NULL, NULL, NULL)) {
1107 /* Get the DIE(Debugging Information Entry) of this CU */ 1128 /* Get the DIE(Debugging Information Entry) of this CU */
1108 diep = dwarf_offdie(self->dbg, off + cuhl, &pf->cu_die); 1129 diep = dwarf_offdie(dbg->dbg, off + cuhl, &pf->cu_die);
1109 if (!diep) 1130 if (!diep)
1110 continue; 1131 continue;
1111 1132
@@ -1136,12 +1157,80 @@ found:
1136 return ret; 1157 return ret;
1137} 1158}
1138 1159
1160struct local_vars_finder {
1161 struct probe_finder *pf;
1162 struct perf_probe_arg *args;
1163 int max_args;
1164 int nargs;
1165 int ret;
1166};
1167
1168/* Collect available variables in this scope */
1169static int copy_variables_cb(Dwarf_Die *die_mem, void *data)
1170{
1171 struct local_vars_finder *vf = data;
1172 struct probe_finder *pf = vf->pf;
1173 int tag;
1174
1175 tag = dwarf_tag(die_mem);
1176 if (tag == DW_TAG_formal_parameter ||
1177 tag == DW_TAG_variable) {
1178 if (convert_variable_location(die_mem, vf->pf->addr,
1179 vf->pf->fb_ops, &pf->sp_die,
1180 NULL) == 0) {
1181 vf->args[vf->nargs].var = (char *)dwarf_diename(die_mem);
1182 if (vf->args[vf->nargs].var == NULL) {
1183 vf->ret = -ENOMEM;
1184 return DIE_FIND_CB_END;
1185 }
1186 pr_debug(" %s", vf->args[vf->nargs].var);
1187 vf->nargs++;
1188 }
1189 }
1190
1191 if (dwarf_haspc(die_mem, vf->pf->addr))
1192 return DIE_FIND_CB_CONTINUE;
1193 else
1194 return DIE_FIND_CB_SIBLING;
1195}
1196
1197static int expand_probe_args(Dwarf_Die *sc_die, struct probe_finder *pf,
1198 struct perf_probe_arg *args)
1199{
1200 Dwarf_Die die_mem;
1201 int i;
1202 int n = 0;
1203 struct local_vars_finder vf = {.pf = pf, .args = args,
1204 .max_args = MAX_PROBE_ARGS, .ret = 0};
1205
1206 for (i = 0; i < pf->pev->nargs; i++) {
1207 /* var never be NULL */
1208 if (strcmp(pf->pev->args[i].var, "$vars") == 0) {
1209 pr_debug("Expanding $vars into:");
1210 vf.nargs = n;
1211 /* Special local variables */
1212 die_find_child(sc_die, copy_variables_cb, (void *)&vf,
1213 &die_mem);
1214 pr_debug(" (%d)\n", vf.nargs - n);
1215 if (vf.ret < 0)
1216 return vf.ret;
1217 n = vf.nargs;
1218 } else {
1219 /* Copy normal argument */
1220 args[n] = pf->pev->args[i];
1221 n++;
1222 }
1223 }
1224 return n;
1225}
1226
1139/* Add a found probe point into trace event list */ 1227/* Add a found probe point into trace event list */
1140static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf) 1228static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)
1141{ 1229{
1142 struct trace_event_finder *tf = 1230 struct trace_event_finder *tf =
1143 container_of(pf, struct trace_event_finder, pf); 1231 container_of(pf, struct trace_event_finder, pf);
1144 struct probe_trace_event *tev; 1232 struct probe_trace_event *tev;
1233 struct perf_probe_arg *args;
1145 int ret, i; 1234 int ret, i;
1146 1235
1147 /* Check number of tevs */ 1236 /* Check number of tevs */
@@ -1161,31 +1250,45 @@ static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)
1161 pr_debug("Probe point found: %s+%lu\n", tev->point.symbol, 1250 pr_debug("Probe point found: %s+%lu\n", tev->point.symbol,
1162 tev->point.offset); 1251 tev->point.offset);
1163 1252
1164 /* Find each argument */ 1253 /* Expand special probe argument if exist */
1165 tev->nargs = pf->pev->nargs; 1254 args = zalloc(sizeof(struct perf_probe_arg) * MAX_PROBE_ARGS);
1166 tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs); 1255 if (args == NULL)
1167 if (tev->args == NULL)
1168 return -ENOMEM; 1256 return -ENOMEM;
1169 for (i = 0; i < pf->pev->nargs; i++) { 1257
1170 pf->pvar = &pf->pev->args[i]; 1258 ret = expand_probe_args(sc_die, pf, args);
1259 if (ret < 0)
1260 goto end;
1261
1262 tev->nargs = ret;
1263 tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs);
1264 if (tev->args == NULL) {
1265 ret = -ENOMEM;
1266 goto end;
1267 }
1268
1269 /* Find each argument */
1270 for (i = 0; i < tev->nargs; i++) {
1271 pf->pvar = &args[i];
1171 pf->tvar = &tev->args[i]; 1272 pf->tvar = &tev->args[i];
1172 /* Variable should be found from scope DIE */ 1273 /* Variable should be found from scope DIE */
1173 ret = find_variable(sc_die, pf); 1274 ret = find_variable(sc_die, pf);
1174 if (ret != 0) 1275 if (ret != 0)
1175 return ret; 1276 break;
1176 } 1277 }
1177 1278
1178 return 0; 1279end:
1280 free(args);
1281 return ret;
1179} 1282}
1180 1283
1181/* Find probe_trace_events specified by perf_probe_event from debuginfo */ 1284/* Find probe_trace_events specified by perf_probe_event from debuginfo */
1182int debuginfo__find_trace_events(struct debuginfo *self, 1285int debuginfo__find_trace_events(struct debuginfo *dbg,
1183 struct perf_probe_event *pev, 1286 struct perf_probe_event *pev,
1184 struct probe_trace_event **tevs, int max_tevs) 1287 struct probe_trace_event **tevs, int max_tevs)
1185{ 1288{
1186 struct trace_event_finder tf = { 1289 struct trace_event_finder tf = {
1187 .pf = {.pev = pev, .callback = add_probe_trace_event}, 1290 .pf = {.pev = pev, .callback = add_probe_trace_event},
1188 .mod = self->mod, .max_tevs = max_tevs}; 1291 .mod = dbg->mod, .max_tevs = max_tevs};
1189 int ret; 1292 int ret;
1190 1293
1191 /* Allocate result tevs array */ 1294 /* Allocate result tevs array */
@@ -1196,7 +1299,7 @@ int debuginfo__find_trace_events(struct debuginfo *self,
1196 tf.tevs = *tevs; 1299 tf.tevs = *tevs;
1197 tf.ntevs = 0; 1300 tf.ntevs = 0;
1198 1301
1199 ret = debuginfo__find_probes(self, &tf.pf); 1302 ret = debuginfo__find_probes(dbg, &tf.pf);
1200 if (ret < 0) { 1303 if (ret < 0) {
1201 free(*tevs); 1304 free(*tevs);
1202 *tevs = NULL; 1305 *tevs = NULL;
@@ -1222,7 +1325,8 @@ static int collect_variables_cb(Dwarf_Die *die_mem, void *data)
1222 if (tag == DW_TAG_formal_parameter || 1325 if (tag == DW_TAG_formal_parameter ||
1223 tag == DW_TAG_variable) { 1326 tag == DW_TAG_variable) {
1224 ret = convert_variable_location(die_mem, af->pf.addr, 1327 ret = convert_variable_location(die_mem, af->pf.addr,
1225 af->pf.fb_ops, NULL); 1328 af->pf.fb_ops, &af->pf.sp_die,
1329 NULL);
1226 if (ret == 0) { 1330 if (ret == 0) {
1227 ret = die_get_varname(die_mem, buf, MAX_VAR_LEN); 1331 ret = die_get_varname(die_mem, buf, MAX_VAR_LEN);
1228 pr_debug2("Add new var: %s\n", buf); 1332 pr_debug2("Add new var: %s\n", buf);
@@ -1286,14 +1390,14 @@ out:
1286} 1390}
1287 1391
1288/* Find available variables at given probe point */ 1392/* Find available variables at given probe point */
1289int debuginfo__find_available_vars_at(struct debuginfo *self, 1393int debuginfo__find_available_vars_at(struct debuginfo *dbg,
1290 struct perf_probe_event *pev, 1394 struct perf_probe_event *pev,
1291 struct variable_list **vls, 1395 struct variable_list **vls,
1292 int max_vls, bool externs) 1396 int max_vls, bool externs)
1293{ 1397{
1294 struct available_var_finder af = { 1398 struct available_var_finder af = {
1295 .pf = {.pev = pev, .callback = add_available_vars}, 1399 .pf = {.pev = pev, .callback = add_available_vars},
1296 .mod = self->mod, 1400 .mod = dbg->mod,
1297 .max_vls = max_vls, .externs = externs}; 1401 .max_vls = max_vls, .externs = externs};
1298 int ret; 1402 int ret;
1299 1403
@@ -1305,7 +1409,7 @@ int debuginfo__find_available_vars_at(struct debuginfo *self,
1305 af.vls = *vls; 1409 af.vls = *vls;
1306 af.nvls = 0; 1410 af.nvls = 0;
1307 1411
1308 ret = debuginfo__find_probes(self, &af.pf); 1412 ret = debuginfo__find_probes(dbg, &af.pf);
1309 if (ret < 0) { 1413 if (ret < 0) {
1310 /* Free vlist for error */ 1414 /* Free vlist for error */
1311 while (af.nvls--) { 1415 while (af.nvls--) {
@@ -1323,7 +1427,7 @@ int debuginfo__find_available_vars_at(struct debuginfo *self,
1323} 1427}
1324 1428
1325/* Reverse search */ 1429/* Reverse search */
1326int debuginfo__find_probe_point(struct debuginfo *self, unsigned long addr, 1430int debuginfo__find_probe_point(struct debuginfo *dbg, unsigned long addr,
1327 struct perf_probe_point *ppt) 1431 struct perf_probe_point *ppt)
1328{ 1432{
1329 Dwarf_Die cudie, spdie, indie; 1433 Dwarf_Die cudie, spdie, indie;
@@ -1332,10 +1436,10 @@ int debuginfo__find_probe_point(struct debuginfo *self, unsigned long addr,
1332 int baseline = 0, lineno = 0, ret = 0; 1436 int baseline = 0, lineno = 0, ret = 0;
1333 1437
1334 /* Adjust address with bias */ 1438 /* Adjust address with bias */
1335 addr += self->bias; 1439 addr += dbg->bias;
1336 1440
1337 /* Find cu die */ 1441 /* Find cu die */
1338 if (!dwarf_addrdie(self->dbg, (Dwarf_Addr)addr - self->bias, &cudie)) { 1442 if (!dwarf_addrdie(dbg->dbg, (Dwarf_Addr)addr - dbg->bias, &cudie)) {
1339 pr_warning("Failed to find debug information for address %lx\n", 1443 pr_warning("Failed to find debug information for address %lx\n",
1340 addr); 1444 addr);
1341 ret = -EINVAL; 1445 ret = -EINVAL;
@@ -1357,10 +1461,10 @@ int debuginfo__find_probe_point(struct debuginfo *self, unsigned long addr,
1357 goto post; 1461 goto post;
1358 } 1462 }
1359 1463
1464 fname = dwarf_decl_file(&spdie);
1360 if (addr == (unsigned long)baseaddr) { 1465 if (addr == (unsigned long)baseaddr) {
1361 /* Function entry - Relative line number is 0 */ 1466 /* Function entry - Relative line number is 0 */
1362 lineno = baseline; 1467 lineno = baseline;
1363 fname = dwarf_decl_file(&spdie);
1364 goto post; 1468 goto post;
1365 } 1469 }
1366 1470
@@ -1536,7 +1640,7 @@ static int find_line_range_by_func(struct line_finder *lf)
1536 return param.retval; 1640 return param.retval;
1537} 1641}
1538 1642
1539int debuginfo__find_line_range(struct debuginfo *self, struct line_range *lr) 1643int debuginfo__find_line_range(struct debuginfo *dbg, struct line_range *lr)
1540{ 1644{
1541 struct line_finder lf = {.lr = lr, .found = 0}; 1645 struct line_finder lf = {.lr = lr, .found = 0};
1542 int ret = 0; 1646 int ret = 0;
@@ -1553,7 +1657,7 @@ int debuginfo__find_line_range(struct debuginfo *self, struct line_range *lr)
1553 struct dwarf_callback_param line_range_param = { 1657 struct dwarf_callback_param line_range_param = {
1554 .data = (void *)&lf, .retval = 0}; 1658 .data = (void *)&lf, .retval = 0};
1555 1659
1556 dwarf_getpubnames(self->dbg, pubname_search_cb, 1660 dwarf_getpubnames(dbg->dbg, pubname_search_cb,
1557 &pubname_param, 0); 1661 &pubname_param, 0);
1558 if (pubname_param.found) { 1662 if (pubname_param.found) {
1559 line_range_search_cb(&lf.sp_die, &line_range_param); 1663 line_range_search_cb(&lf.sp_die, &line_range_param);
@@ -1564,12 +1668,12 @@ int debuginfo__find_line_range(struct debuginfo *self, struct line_range *lr)
1564 1668
1565 /* Loop on CUs (Compilation Unit) */ 1669 /* Loop on CUs (Compilation Unit) */
1566 while (!lf.found && ret >= 0) { 1670 while (!lf.found && ret >= 0) {
1567 if (dwarf_nextcu(self->dbg, off, &noff, &cuhl, 1671 if (dwarf_nextcu(dbg->dbg, off, &noff, &cuhl,
1568 NULL, NULL, NULL) != 0) 1672 NULL, NULL, NULL) != 0)
1569 break; 1673 break;
1570 1674
1571 /* Get the DIE(Debugging Information Entry) of this CU */ 1675 /* Get the DIE(Debugging Information Entry) of this CU */
1572 diep = dwarf_offdie(self->dbg, off + cuhl, &lf.cu_die); 1676 diep = dwarf_offdie(dbg->dbg, off + cuhl, &lf.cu_die);
1573 if (!diep) 1677 if (!diep)
1574 continue; 1678 continue;
1575 1679