All of lore.kernel.org
 help / color / mirror / Atom feed
* Magic numbers about stack layout
@ 2001-08-22  5:45 Atsushi Nemoto
  2001-08-22  6:46   ` Hartvig Ekner
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Atsushi Nemoto @ 2001-08-22  5:45 UTC (permalink / raw)
  To: linux-mips, linux-mips; +Cc: Ralf Baechle

[-- Attachment #1: Type: Text/Plain, Size: 320 bytes --]

There are some magic constant numbers about stack layout in
thread_saved_pc() and get_wchan() function.

I made a patch to eliminate these magic numbers.  This patch analyzes
some functions prologue codes in heuristic way at run-time.  "ps -l"
(and "MAGIC SYSRQ" feature) works fine with this patch.

---
Atsushi Nemoto

[-- Attachment #2: get_wchan.patch --]
[-- Type: Text/Plain, Size: 5226 bytes --]

diff -ur linux.sgi/arch/mips/kernel/process.c linux/arch/mips/kernel/process.c
--- linux.sgi/arch/mips/kernel/process.c	Sun Aug  5 23:39:09 2001
+++ linux/arch/mips/kernel/process.c	Wed Aug 22 14:14:29 2001
@@ -19,6 +19,7 @@
 #include <linux/sys.h>
 #include <linux/user.h>
 #include <linux/a.out.h>
+#include <linux/init.h>
 
 #include <asm/bootinfo.h>
 #include <asm/cpu.h>
@@ -31,6 +32,7 @@
 #include <asm/io.h>
 #include <asm/elf.h>
 #include <asm/isadep.h>
+#include <asm/inst.h>
 
 void cpu_idle(void)
 {
@@ -196,6 +198,59 @@
 #define first_sched	((unsigned long) scheduling_functions_start_here)
 #define last_sched	((unsigned long) scheduling_functions_end_here)
 
+struct mips_frame_info schedule_frame;
+static struct mips_frame_info schedule_timeout_frame;
+static struct mips_frame_info sleep_on_frame;
+static struct mips_frame_info sleep_on_timeout_frame;
+static int mips_frame_info_initialized;
+static int __init get_frame_info(struct mips_frame_info *info, void *func)
+{
+	int i;
+	union mips_instruction *ip = (union mips_instruction *)func;
+	info->pc_offset = -1;
+	info->frame_offset = -1;
+	for (i = 0; i < 128; i++, ip++) {
+		/* if jal, jalr, jr, stop. */
+		if (ip->j_format.opcode == jal_op ||
+		    (ip->r_format.opcode == spec_op &&
+		     (ip->r_format.func == jalr_op ||
+		      ip->r_format.func == jr_op)))
+			break;
+		if (ip->i_format.opcode == sw_op &&
+		    ip->i_format.rs == 29) {
+			/* sw $ra, offset($sp) */
+			if (ip->i_format.rt == 31) {
+				if (info->pc_offset != -1)
+					break;
+				info->pc_offset =
+					ip->i_format.simmediate / sizeof(long);
+			}
+			/* sw $s8, offset($sp) */
+			if (ip->i_format.rt == 30) {
+				if (info->frame_offset != -1)
+					break;
+				info->frame_offset =
+					ip->i_format.simmediate / sizeof(long);
+			}
+		}
+	}
+	if (info->pc_offset == -1 || info->frame_offset == -1) {
+		printk("Can't analize prologue code at %p\n", func);
+		info->pc_offset = -1;
+		info->frame_offset = -1;
+		return -1;
+	}
+	return 0;
+}
+void __init frame_info_init(void)
+{
+	mips_frame_info_initialized =
+		!get_frame_info(&schedule_frame, schedule) &&
+		!get_frame_info(&schedule_timeout_frame, schedule_timeout) &&
+		!get_frame_info(&sleep_on_frame, sleep_on) &&
+		!get_frame_info(&sleep_on_timeout_frame, sleep_on_timeout);
+}
+
 /* get_wchan - a maintenance nightmare ...  */
 unsigned long get_wchan(struct task_struct *p)
 {
@@ -204,6 +259,8 @@
 	if (!p || p == current || p->state == TASK_RUNNING)
 		return 0;
 
+	if (!mips_frame_info_initialized)
+		return 0;
 	pc = thread_saved_pc(&p->thread);
 	if (pc < first_sched || pc >= last_sched) {
 		return pc;
@@ -220,23 +277,24 @@
 	goto schedule_timeout_caller;
 
 schedule_caller:
-	frame = ((unsigned long *)p->thread.reg30)[9];
-	pc    = ((unsigned long *)frame)[11];
+	/* schedule_timeout called by interruptible_sleep_on or sleep_on */
+	frame = ((unsigned long *)p->thread.reg30)[schedule_frame.frame_offset];
+	pc    = ((unsigned long *)frame)[sleep_on_frame.pc_offset];
 	return pc;
 
 schedule_timeout_caller:
 	/* Must be schedule_timeout ...  */
-	pc    = ((unsigned long *)p->thread.reg30)[10];
-	frame = ((unsigned long *)p->thread.reg30)[9];
+	pc    = ((unsigned long *)p->thread.reg30)[schedule_frame.pc_offset];
+	frame = ((unsigned long *)p->thread.reg30)[schedule_frame.frame_offset];
 
 	/* The schedule_timeout frame ...  */
-	pc    = ((unsigned long *)frame)[14];
-	frame = ((unsigned long *)frame)[13];
+	pc    = ((unsigned long *)frame)[schedule_timeout_frame.pc_offset];
+	frame = ((unsigned long *)frame)[schedule_timeout_frame.frame_offset];
 
 	if (pc >= first_sched && pc < last_sched) {
 		/* schedule_timeout called by interruptible_sleep_on_timeout */
-		pc    = ((unsigned long *)frame)[11];
-		frame = ((unsigned long *)frame)[10];
+		pc    = ((unsigned long *)frame)[sleep_on_timeout_frame.pc_offset];
+		frame = ((unsigned long *)frame)[sleep_on_timeout_frame.frame_offset];
 	}
 
 	return pc;
diff -ur linux.sgi/arch/mips/kernel/setup.c linux/arch/mips/kernel/setup.c
--- linux.sgi/arch/mips/kernel/setup.c	Sun Aug  5 23:39:15 2001
+++ linux/arch/mips/kernel/setup.c	Wed Aug 22 14:26:19 2001
@@ -518,12 +518,14 @@
 	void malta_setup(void);
 	void momenco_ocelot_setup(void);
 	void nino_setup(void);
+	void frame_info_init(void);
 
 	unsigned long bootmap_size;
 	unsigned long start_pfn, max_pfn, first_usable_pfn;
 
 	int i;
 
+	frame_info_init();
 #ifdef CONFIG_BLK_DEV_FD
 	fd_ops = &no_fd_ops;
 #endif
diff -ur linux.sgi/include/asm-mips/processor.h linux/include/asm-mips/processor.h
--- linux.sgi/include/asm-mips/processor.h	Sun Aug  5 23:41:29 2001
+++ linux/include/asm-mips/processor.h	Wed Aug 22 14:14:59 2001
@@ -217,6 +217,11 @@
 #define copy_segments(p, mm) do { } while(0)
 #define release_segments(mm) do { } while(0)
 
+struct mips_frame_info {
+	int frame_offset;
+	int pc_offset;
+};
+extern struct mips_frame_info schedule_frame;
 /*
  * Return saved PC of a blocked thread.
  */
@@ -228,7 +233,9 @@
 	if (t->reg31 == (unsigned long) ret_from_fork)
 		return t->reg31;
 
-	return ((unsigned long *)t->reg29)[10];
+	if (schedule_frame.pc_offset < 0)
+		return 0;
+	return ((unsigned long *)t->reg29)[schedule_frame.pc_offset];
 }
 
 /*

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2002-05-28  8:25 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2001-08-22  5:45 Magic numbers about stack layout Atsushi Nemoto
2001-08-22  6:46 ` Hartvig Ekner
2001-08-22  6:46   ` Hartvig Ekner
2001-08-22  7:15   ` Atsushi Nemoto
2001-08-22 11:40 ` Ralf Baechle
     [not found] ` <200205280611.g4S6BuEj006804@oss.sgi.com>
2002-05-28  8:26   ` Magic numbers about stack layout (again) Atsushi Nemoto

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.