summaryrefslogtreecommitdiff
path: root/tools/perf/util/unwind-libunwind-local.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/unwind-libunwind-local.c')
-rw-r--r--tools/perf/util/unwind-libunwind-local.c67
1 files changed, 36 insertions, 31 deletions
diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unwind-libunwind-local.c
index 6a5ac0faa6f4..0b037e7389a0 100644
--- a/tools/perf/util/unwind-libunwind-local.c
+++ b/tools/perf/util/unwind-libunwind-local.c
@@ -329,27 +329,26 @@ static int read_unwind_spec_eh_frame(struct dso *dso, struct unwind_info *ui,
};
int ret, fd;
- if (dso->data.eh_frame_hdr_offset == 0) {
- fd = dso__data_get_fd(dso, ui->machine);
- if (fd < 0)
+ if (dso__data(dso)->eh_frame_hdr_offset == 0) {
+ if (!dso__data_get_fd(dso, ui->machine, &fd))
return -EINVAL;
/* Check the .eh_frame section for unwinding info */
ret = elf_section_address_and_offset(fd, ".eh_frame_hdr",
- &dso->data.eh_frame_hdr_addr,
- &dso->data.eh_frame_hdr_offset);
- dso->data.elf_base_addr = elf_base_address(fd);
+ &dso__data(dso)->eh_frame_hdr_addr,
+ &dso__data(dso)->eh_frame_hdr_offset);
+ dso__data(dso)->elf_base_addr = elf_base_address(fd);
dso__data_put_fd(dso);
- if (ret || dso->data.eh_frame_hdr_offset == 0)
+ if (ret || dso__data(dso)->eh_frame_hdr_offset == 0)
return -EINVAL;
}
maps__for_each_map(thread__maps(ui->thread), read_unwind_spec_eh_frame_maps_cb, &args);
- args.base_addr -= dso->data.elf_base_addr;
+ args.base_addr -= dso__data(dso)->elf_base_addr;
/* Address of .eh_frame_hdr */
- *segbase = args.base_addr + dso->data.eh_frame_hdr_addr;
- ret = unwind_spec_ehframe(dso, ui->machine, dso->data.eh_frame_hdr_offset,
+ *segbase = args.base_addr + dso__data(dso)->eh_frame_hdr_addr;
+ ret = unwind_spec_ehframe(dso, ui->machine, dso__data(dso)->eh_frame_hdr_offset,
table_data, fde_count);
if (ret)
return ret;
@@ -363,7 +362,7 @@ static int read_unwind_spec_debug_frame(struct dso *dso,
struct machine *machine, u64 *offset)
{
int fd;
- u64 ofs = dso->data.debug_frame_offset;
+ u64 ofs = dso__data(dso)->debug_frame_offset;
/* debug_frame can reside in:
* - dso
@@ -372,14 +371,13 @@ static int read_unwind_spec_debug_frame(struct dso *dso,
* has to be pointed by symsrc_filename
*/
if (ofs == 0) {
- fd = dso__data_get_fd(dso, machine);
- if (fd >= 0) {
+ if (dso__data_get_fd(dso, machine, &fd)) {
ofs = elf_section_offset(fd, ".debug_frame");
dso__data_put_fd(dso);
}
if (ofs <= 0) {
- fd = open(dso->symsrc_filename, O_RDONLY);
+ fd = open(dso__symsrc_filename(dso), O_RDONLY);
if (fd >= 0) {
ofs = elf_section_offset(fd, ".debug_frame");
close(fd);
@@ -390,6 +388,11 @@ static int read_unwind_spec_debug_frame(struct dso *dso,
char *debuglink = malloc(PATH_MAX);
int ret = 0;
+ if (debuglink == NULL) {
+ pr_err("unwind: Can't read unwind spec debug frame.\n");
+ return -ENOMEM;
+ }
+
ret = dso__read_binary_type_filename(
dso, DSO_BINARY_TYPE__DEBUGLINK,
machine->root_dir, debuglink, PATH_MAX);
@@ -402,21 +405,21 @@ static int read_unwind_spec_debug_frame(struct dso *dso,
}
}
if (ofs > 0) {
- if (dso->symsrc_filename != NULL) {
+ if (dso__symsrc_filename(dso) != NULL) {
pr_warning(
"%s: overwrite symsrc(%s,%s)\n",
__func__,
- dso->symsrc_filename,
+ dso__symsrc_filename(dso),
debuglink);
- zfree(&dso->symsrc_filename);
+ dso__free_symsrc_filename(dso);
}
- dso->symsrc_filename = debuglink;
+ dso__set_symsrc_filename(dso, debuglink);
} else {
free(debuglink);
}
}
- dso->data.debug_frame_offset = ofs;
+ dso__data(dso)->debug_frame_offset = ofs;
}
*offset = ofs;
@@ -460,7 +463,7 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
return -EINVAL;
}
- pr_debug("unwind: find_proc_info dso %s\n", dso->name);
+ pr_debug("unwind: find_proc_info dso %s\n", dso__name(dso));
/* Check the .eh_frame section for unwinding info */
if (!read_unwind_spec_eh_frame(dso, ui, &table_data, &segbase, &fde_count)) {
@@ -480,16 +483,18 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
/* Check the .debug_frame section for unwinding info */
if (ret < 0 &&
!read_unwind_spec_debug_frame(dso, ui->machine, &segbase)) {
- int fd = dso__data_get_fd(dso, ui->machine);
- int is_exec = elf_is_exec(fd, dso->name);
+ int fd;
u64 start = map__start(map);
- unw_word_t base = is_exec ? 0 : start;
+ unw_word_t base = start;
const char *symfile;
- if (fd >= 0)
+ if (dso__data_get_fd(dso, ui->machine, &fd)) {
+ if (elf_is_exec(fd, dso__name(dso)))
+ base = 0;
dso__data_put_fd(dso);
+ }
- symfile = dso->symsrc_filename ?: dso->name;
+ symfile = dso__symsrc_filename(dso) ?: dso__name(dso);
memset(&di, 0, sizeof(di));
if (dwarf_find_debug_frame(0, &di, ip, base, symfile, start, map__end(map)))
@@ -574,12 +579,12 @@ static int access_mem(unw_addr_space_t __maybe_unused as,
int ret;
/* Don't support write, probably not needed. */
- if (__write || !stack || !ui->sample->user_regs.regs) {
+ if (__write || !stack || !ui->sample->user_regs || !ui->sample->user_regs->regs) {
*valp = 0;
return 0;
}
- ret = perf_reg_value(&start, &ui->sample->user_regs,
+ ret = perf_reg_value(&start, perf_sample__user_regs(ui->sample),
perf_arch_reg_sp(arch));
if (ret)
return ret;
@@ -623,7 +628,7 @@ static int access_reg(unw_addr_space_t __maybe_unused as,
return 0;
}
- if (!ui->sample->user_regs.regs) {
+ if (!ui->sample->user_regs || !ui->sample->user_regs->regs) {
*valp = 0;
return 0;
}
@@ -632,7 +637,7 @@ static int access_reg(unw_addr_space_t __maybe_unused as,
if (id < 0)
return -EINVAL;
- ret = perf_reg_value(&val, &ui->sample->user_regs, id);
+ ret = perf_reg_value(&val, perf_sample__user_regs(ui->sample), id);
if (ret) {
if (!ui->best_effort)
pr_err("unwind: can't read reg %d\n", regnum);
@@ -736,7 +741,7 @@ static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb,
unw_cursor_t c;
int ret, i = 0;
- ret = perf_reg_value(&val, &ui->sample->user_regs,
+ ret = perf_reg_value(&val, perf_sample__user_regs(ui->sample),
perf_arch_reg_ip(arch));
if (ret)
return ret;
@@ -803,7 +808,7 @@ static int _unwind__get_entries(unwind_entry_cb_t cb, void *arg,
.best_effort = best_effort
};
- if (!data->user_regs.regs)
+ if (!data->user_regs || !data->user_regs->regs)
return -EINVAL;
if (max_stack <= 0)