Merge branch 'linus' into perf/urgent
Merge dependencies to apply a fix. Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
@@ -39,6 +39,15 @@ UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
|
||||
|
||||
#define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table)
|
||||
|
||||
extern int
|
||||
UNW_OBJ(dwarf_find_debug_frame) (int found, unw_dyn_info_t *di_debug,
|
||||
unw_word_t ip,
|
||||
unw_word_t segbase,
|
||||
const char *obj_name, unw_word_t start,
|
||||
unw_word_t end);
|
||||
|
||||
#define dwarf_find_debug_frame UNW_OBJ(dwarf_find_debug_frame)
|
||||
|
||||
#define DW_EH_PE_FORMAT_MASK 0x0f /* format of the encoded value */
|
||||
#define DW_EH_PE_APPL_MASK 0x70 /* how the value is to be applied */
|
||||
|
||||
@@ -245,8 +254,9 @@ static int unwind_spec_ehframe(struct dso *dso, struct machine *machine,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_unwind_spec(struct dso *dso, struct machine *machine,
|
||||
u64 *table_data, u64 *segbase, u64 *fde_count)
|
||||
static int read_unwind_spec_eh_frame(struct dso *dso, struct machine *machine,
|
||||
u64 *table_data, u64 *segbase,
|
||||
u64 *fde_count)
|
||||
{
|
||||
int ret = -EINVAL, fd;
|
||||
u64 offset;
|
||||
@@ -255,6 +265,7 @@ static int read_unwind_spec(struct dso *dso, struct machine *machine,
|
||||
if (fd < 0)
|
||||
return -EINVAL;
|
||||
|
||||
/* Check the .eh_frame section for unwinding info */
|
||||
offset = elf_section_offset(fd, ".eh_frame_hdr");
|
||||
close(fd);
|
||||
|
||||
@@ -263,10 +274,29 @@ static int read_unwind_spec(struct dso *dso, struct machine *machine,
|
||||
table_data, segbase,
|
||||
fde_count);
|
||||
|
||||
/* TODO .debug_frame check if eh_frame_hdr fails */
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef NO_LIBUNWIND_DEBUG_FRAME
|
||||
static int read_unwind_spec_debug_frame(struct dso *dso,
|
||||
struct machine *machine, u64 *offset)
|
||||
{
|
||||
int fd = dso__data_fd(dso, machine);
|
||||
|
||||
if (fd < 0)
|
||||
return -EINVAL;
|
||||
|
||||
/* Check the .debug_frame section for unwinding info */
|
||||
*offset = elf_section_offset(fd, ".debug_frame");
|
||||
close(fd);
|
||||
|
||||
if (*offset)
|
||||
return 0;
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct map *find_map(unw_word_t ip, struct unwind_info *ui)
|
||||
{
|
||||
struct addr_location al;
|
||||
@@ -291,20 +321,33 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
|
||||
|
||||
pr_debug("unwind: find_proc_info dso %s\n", map->dso->name);
|
||||
|
||||
if (read_unwind_spec(map->dso, ui->machine,
|
||||
&table_data, &segbase, &fde_count))
|
||||
return -EINVAL;
|
||||
/* Check the .eh_frame section for unwinding info */
|
||||
if (!read_unwind_spec_eh_frame(map->dso, ui->machine,
|
||||
&table_data, &segbase, &fde_count)) {
|
||||
memset(&di, 0, sizeof(di));
|
||||
di.format = UNW_INFO_FORMAT_REMOTE_TABLE;
|
||||
di.start_ip = map->start;
|
||||
di.end_ip = map->end;
|
||||
di.u.rti.segbase = map->start + segbase;
|
||||
di.u.rti.table_data = map->start + table_data;
|
||||
di.u.rti.table_len = fde_count * sizeof(struct table_entry)
|
||||
/ sizeof(unw_word_t);
|
||||
return dwarf_search_unwind_table(as, ip, &di, pi,
|
||||
need_unwind_info, arg);
|
||||
}
|
||||
|
||||
memset(&di, 0, sizeof(di));
|
||||
di.format = UNW_INFO_FORMAT_REMOTE_TABLE;
|
||||
di.start_ip = map->start;
|
||||
di.end_ip = map->end;
|
||||
di.u.rti.segbase = map->start + segbase;
|
||||
di.u.rti.table_data = map->start + table_data;
|
||||
di.u.rti.table_len = fde_count * sizeof(struct table_entry)
|
||||
/ sizeof(unw_word_t);
|
||||
return dwarf_search_unwind_table(as, ip, &di, pi,
|
||||
need_unwind_info, arg);
|
||||
#ifndef NO_LIBUNWIND_DEBUG_FRAME
|
||||
/* Check the .debug_frame section for unwinding info */
|
||||
if (!read_unwind_spec_debug_frame(map->dso, ui->machine, &segbase)) {
|
||||
memset(&di, 0, sizeof(di));
|
||||
dwarf_find_debug_frame(0, &di, ip, 0, map->dso->name,
|
||||
map->start, map->end);
|
||||
return dwarf_search_unwind_table(as, ip, &di, pi,
|
||||
need_unwind_info, arg);
|
||||
}
|
||||
#endif
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int access_fpreg(unw_addr_space_t __maybe_unused as,
|
||||
|
Reference in New Issue
Block a user