|
@@ -224,6 +224,9 @@ struct mips_frame_info {
|
|
|
int pc_offset;
|
|
|
};
|
|
|
|
|
|
+#define J_TARGET(pc,target) \
|
|
|
+ (((unsigned long)(pc) & 0xf0000000) | ((target) << 2))
|
|
|
+
|
|
|
static inline int is_ra_save_ins(union mips_instruction *ip)
|
|
|
{
|
|
|
#ifdef CONFIG_CPU_MICROMIPS
|
|
@@ -395,15 +398,42 @@ err:
|
|
|
|
|
|
static struct mips_frame_info schedule_mfi __read_mostly;
|
|
|
|
|
|
+#ifdef CONFIG_KALLSYMS
|
|
|
+static unsigned long get___schedule_addr(void)
|
|
|
+{
|
|
|
+ return kallsyms_lookup_name("__schedule");
|
|
|
+}
|
|
|
+#else
|
|
|
+static unsigned long get___schedule_addr(void)
|
|
|
+{
|
|
|
+ union mips_instruction *ip = (void *)schedule;
|
|
|
+ int max_insns = 8;
|
|
|
+ int i;
|
|
|
+
|
|
|
+ for (i = 0; i < max_insns; i++, ip++) {
|
|
|
+ if (ip->j_format.opcode == j_op)
|
|
|
+ return J_TARGET(ip, ip->j_format.target);
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
static int __init frame_info_init(void)
|
|
|
{
|
|
|
unsigned long size = 0;
|
|
|
#ifdef CONFIG_KALLSYMS
|
|
|
unsigned long ofs;
|
|
|
+#endif
|
|
|
+ unsigned long addr;
|
|
|
|
|
|
- kallsyms_lookup_size_offset((unsigned long)schedule, &size, &ofs);
|
|
|
+ addr = get___schedule_addr();
|
|
|
+ if (!addr)
|
|
|
+ addr = (unsigned long)schedule;
|
|
|
+
|
|
|
+#ifdef CONFIG_KALLSYMS
|
|
|
+ kallsyms_lookup_size_offset(addr, &size, &ofs);
|
|
|
#endif
|
|
|
- schedule_mfi.func = schedule;
|
|
|
+ schedule_mfi.func = (void *)addr;
|
|
|
schedule_mfi.func_size = size;
|
|
|
|
|
|
get_frame_info(&schedule_mfi);
|