diff options
Diffstat (limited to 'tools/perf/arch/powerpc/util/skip-callchain-idx.c')
-rw-r--r-- | tools/perf/arch/powerpc/util/skip-callchain-idx.c | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/tools/perf/arch/powerpc/util/skip-callchain-idx.c b/tools/perf/arch/powerpc/util/skip-callchain-idx.c index d73ef8bb08c7..9892b0f0bec4 100644 --- a/tools/perf/arch/powerpc/util/skip-callchain-idx.c +++ b/tools/perf/arch/powerpc/util/skip-callchain-idx.c | |||
@@ -145,7 +145,7 @@ static Dwarf_Frame *get_dwarf_frame(Dwfl_Module *mod, Dwarf_Addr pc) | |||
145 | * yet used) | 145 | * yet used) |
146 | * -1 in case of errors | 146 | * -1 in case of errors |
147 | */ | 147 | */ |
148 | static int check_return_addr(const char *exec_file, Dwarf_Addr pc) | 148 | static int check_return_addr(struct dso *dso, Dwarf_Addr pc) |
149 | { | 149 | { |
150 | int rc = -1; | 150 | int rc = -1; |
151 | Dwfl *dwfl; | 151 | Dwfl *dwfl; |
@@ -156,15 +156,27 @@ static int check_return_addr(const char *exec_file, Dwarf_Addr pc) | |||
156 | Dwarf_Addr end = pc; | 156 | Dwarf_Addr end = pc; |
157 | bool signalp; | 157 | bool signalp; |
158 | 158 | ||
159 | dwfl = dwfl_begin(&offline_callbacks); | 159 | dwfl = dso->dwfl; |
160 | if (!dwfl) { | ||
161 | pr_debug("dwfl_begin() failed: %s\n", dwarf_errmsg(-1)); | ||
162 | return -1; | ||
163 | } | ||
164 | 160 | ||
165 | if (dwfl_report_offline(dwfl, "", exec_file, -1) == NULL) { | 161 | if (!dwfl) { |
166 | pr_debug("dwfl_report_offline() failed %s\n", dwarf_errmsg(-1)); | 162 | dwfl = dwfl_begin(&offline_callbacks); |
167 | goto out; | 163 | if (!dwfl) { |
164 | pr_debug("dwfl_begin() failed: %s\n", dwarf_errmsg(-1)); | ||
165 | return -1; | ||
166 | } | ||
167 | |||
168 | if (dwfl_report_offline(dwfl, "", dso->long_name, -1) == NULL) { | ||
169 | pr_debug("dwfl_report_offline() failed %s\n", | ||
170 | dwarf_errmsg(-1)); | ||
171 | /* | ||
172 | * We normally cache the DWARF debug info and never | ||
173 | * call dwfl_end(). But to prevent fd leak, free in | ||
174 | * case of error. | ||
175 | */ | ||
176 | dwfl_end(dwfl); | ||
177 | goto out; | ||
178 | } | ||
179 | dso->dwfl = dwfl; | ||
168 | } | 180 | } |
169 | 181 | ||
170 | mod = dwfl_addrmodule(dwfl, pc); | 182 | mod = dwfl_addrmodule(dwfl, pc); |
@@ -194,7 +206,6 @@ static int check_return_addr(const char *exec_file, Dwarf_Addr pc) | |||
194 | rc = check_return_reg(ra_regno, frame); | 206 | rc = check_return_reg(ra_regno, frame); |
195 | 207 | ||
196 | out: | 208 | out: |
197 | dwfl_end(dwfl); | ||
198 | return rc; | 209 | return rc; |
199 | } | 210 | } |
200 | 211 | ||
@@ -246,7 +257,7 @@ int arch_skip_callchain_idx(struct machine *machine, struct thread *thread, | |||
246 | return skip_slot; | 257 | return skip_slot; |
247 | } | 258 | } |
248 | 259 | ||
249 | rc = check_return_addr(dso->long_name, ip); | 260 | rc = check_return_addr(dso, ip); |
250 | 261 | ||
251 | pr_debug("DSO %s, nr %" PRIx64 ", ip 0x%" PRIx64 "rc %d\n", | 262 | pr_debug("DSO %s, nr %" PRIx64 ", ip 0x%" PRIx64 "rc %d\n", |
252 | dso->long_name, chain->nr, ip, rc); | 263 | dso->long_name, chain->nr, ip, rc); |