mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
Merge branch 'linus' into perf/urgent
Merge dependencies to apply a fix. Signed-off-by: Ingo Molnar <[email protected]>
This commit is contained in:
commit
555a098af6
3971 changed files with 167218 additions and 77489 deletions
|
|
@ -2,3 +2,6 @@ ifndef NO_DWARF
|
|||
PERF_HAVE_DWARF_REGS := 1
|
||||
LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o
|
||||
endif
|
||||
ifndef NO_LIBUNWIND
|
||||
LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/unwind.o
|
||||
endif
|
||||
|
|
|
|||
54
tools/perf/arch/arm/include/perf_regs.h
Normal file
54
tools/perf/arch/arm/include/perf_regs.h
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
#ifndef ARCH_PERF_REGS_H
|
||||
#define ARCH_PERF_REGS_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "../../util/types.h"
|
||||
#include <asm/perf_regs.h>
|
||||
|
||||
#define PERF_REGS_MASK ((1ULL << PERF_REG_ARM_MAX) - 1)
|
||||
#define PERF_REG_IP PERF_REG_ARM_PC
|
||||
#define PERF_REG_SP PERF_REG_ARM_SP
|
||||
|
||||
static inline const char *perf_reg_name(int id)
|
||||
{
|
||||
switch (id) {
|
||||
case PERF_REG_ARM_R0:
|
||||
return "r0";
|
||||
case PERF_REG_ARM_R1:
|
||||
return "r1";
|
||||
case PERF_REG_ARM_R2:
|
||||
return "r2";
|
||||
case PERF_REG_ARM_R3:
|
||||
return "r3";
|
||||
case PERF_REG_ARM_R4:
|
||||
return "r4";
|
||||
case PERF_REG_ARM_R5:
|
||||
return "r5";
|
||||
case PERF_REG_ARM_R6:
|
||||
return "r6";
|
||||
case PERF_REG_ARM_R7:
|
||||
return "r7";
|
||||
case PERF_REG_ARM_R8:
|
||||
return "r8";
|
||||
case PERF_REG_ARM_R9:
|
||||
return "r9";
|
||||
case PERF_REG_ARM_R10:
|
||||
return "r10";
|
||||
case PERF_REG_ARM_FP:
|
||||
return "fp";
|
||||
case PERF_REG_ARM_IP:
|
||||
return "ip";
|
||||
case PERF_REG_ARM_SP:
|
||||
return "sp";
|
||||
case PERF_REG_ARM_LR:
|
||||
return "lr";
|
||||
case PERF_REG_ARM_PC:
|
||||
return "pc";
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif /* ARCH_PERF_REGS_H */
|
||||
48
tools/perf/arch/arm/util/unwind.c
Normal file
48
tools/perf/arch/arm/util/unwind.c
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
|
||||
#include <errno.h>
|
||||
#include <libunwind.h>
|
||||
#include "perf_regs.h"
|
||||
#include "../../util/unwind.h"
|
||||
|
||||
int unwind__arch_reg_id(int regnum)
|
||||
{
|
||||
switch (regnum) {
|
||||
case UNW_ARM_R0:
|
||||
return PERF_REG_ARM_R0;
|
||||
case UNW_ARM_R1:
|
||||
return PERF_REG_ARM_R1;
|
||||
case UNW_ARM_R2:
|
||||
return PERF_REG_ARM_R2;
|
||||
case UNW_ARM_R3:
|
||||
return PERF_REG_ARM_R3;
|
||||
case UNW_ARM_R4:
|
||||
return PERF_REG_ARM_R4;
|
||||
case UNW_ARM_R5:
|
||||
return PERF_REG_ARM_R5;
|
||||
case UNW_ARM_R6:
|
||||
return PERF_REG_ARM_R6;
|
||||
case UNW_ARM_R7:
|
||||
return PERF_REG_ARM_R7;
|
||||
case UNW_ARM_R8:
|
||||
return PERF_REG_ARM_R8;
|
||||
case UNW_ARM_R9:
|
||||
return PERF_REG_ARM_R9;
|
||||
case UNW_ARM_R10:
|
||||
return PERF_REG_ARM_R10;
|
||||
case UNW_ARM_R11:
|
||||
return PERF_REG_ARM_FP;
|
||||
case UNW_ARM_R12:
|
||||
return PERF_REG_ARM_IP;
|
||||
case UNW_ARM_R13:
|
||||
return PERF_REG_ARM_SP;
|
||||
case UNW_ARM_R14:
|
||||
return PERF_REG_ARM_LR;
|
||||
case UNW_ARM_R15:
|
||||
return PERF_REG_ARM_PC;
|
||||
default:
|
||||
pr_err("unwind: invalid reg id %d\n", regnum);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -31,6 +31,10 @@ ifeq ($(ARCH),x86_64)
|
|||
endif
|
||||
NO_PERF_REGS := 0
|
||||
endif
|
||||
ifeq ($(ARCH),arm)
|
||||
NO_PERF_REGS := 0
|
||||
LIBUNWIND_LIBS = -lunwind -lunwind-arm
|
||||
endif
|
||||
|
||||
ifeq ($(NO_PERF_REGS),0)
|
||||
CFLAGS += -DHAVE_PERF_REGS_SUPPORT
|
||||
|
|
@ -305,8 +309,7 @@ ifndef NO_LIBELF
|
|||
endif # NO_DWARF
|
||||
endif # NO_LIBELF
|
||||
|
||||
# There's only x86 (both 32 and 64) support for CFI unwind so far
|
||||
ifneq ($(ARCH),x86)
|
||||
ifeq ($(LIBUNWIND_LIBS),)
|
||||
NO_LIBUNWIND := 1
|
||||
endif
|
||||
|
||||
|
|
@ -322,8 +325,13 @@ ifndef NO_LIBUNWIND
|
|||
endif
|
||||
|
||||
ifneq ($(feature-libunwind), 1)
|
||||
msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 0.99);
|
||||
msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 1.1);
|
||||
NO_LIBUNWIND := 1
|
||||
else
|
||||
ifneq ($(feature-libunwind-debug-frame), 1)
|
||||
msg := $(warning No debug_frame support found in libunwind);
|
||||
CFLAGS += -DNO_LIBUNWIND_DEBUG_FRAME
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ FILES= \
|
|||
test-libpython-version \
|
||||
test-libslang \
|
||||
test-libunwind \
|
||||
test-libunwind-debug-frame \
|
||||
test-on-exit \
|
||||
test-stackprotector-all \
|
||||
test-stackprotector \
|
||||
|
|
|
|||
|
|
@ -49,6 +49,10 @@
|
|||
# include "test-libunwind.c"
|
||||
#undef main
|
||||
|
||||
#define main main_test_libunwind_debug_frame
|
||||
# include "test-libunwind-debug-frame.c"
|
||||
#undef main
|
||||
|
||||
#define main main_test_libaudit
|
||||
# include "test-libaudit.c"
|
||||
#undef main
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
#include <libunwind.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
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)
|
||||
|
||||
int main(void)
|
||||
{
|
||||
dwarf_find_debug_frame(0, NULL, 0, 0, NULL, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in a new issue