* 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
* Re: Magic numbers about stack layout
@ 2001-08-22 6:46 ` Hartvig Ekner
0 siblings, 0 replies; 6+ messages in thread
From: Hartvig Ekner @ 2001-08-22 6:46 UTC (permalink / raw)
To: Atsushi Nemoto; +Cc: linux-mips
Hi,
what is the purpose of replacing the magic numbers with code analysis?
And what will happen when you run userland with MIPS16 or MIPS16e code?
We have it on our work-list to eventually clean up all the places in the
kernel that inspect code to allow MIPS16(e) code as well, so adding more
code inspection points is a bad idea unless it really is necessary.
/Hartvig
Atsushi Nemoto writes:
>
> ----Next_Part(Wed_Aug_22_14:45:47_2001_172)--
> Content-Type: Text/Plain; charset=us-ascii
> Content-Transfer-Encoding: 7bit
>
> 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
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Magic numbers about stack layout
@ 2001-08-22 6:46 ` Hartvig Ekner
0 siblings, 0 replies; 6+ messages in thread
From: Hartvig Ekner @ 2001-08-22 6:46 UTC (permalink / raw)
To: Atsushi Nemoto; +Cc: linux-mips
Hi,
what is the purpose of replacing the magic numbers with code analysis?
And what will happen when you run userland with MIPS16 or MIPS16e code?
We have it on our work-list to eventually clean up all the places in the
kernel that inspect code to allow MIPS16(e) code as well, so adding more
code inspection points is a bad idea unless it really is necessary.
/Hartvig
Atsushi Nemoto writes:
>
> ----Next_Part(Wed_Aug_22_14:45:47_2001_172)--
> Content-Type: Text/Plain; charset=us-ascii
> Content-Transfer-Encoding: 7bit
>
> 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
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Magic numbers about stack layout
2001-08-22 6:46 ` Hartvig Ekner
(?)
@ 2001-08-22 7:15 ` Atsushi Nemoto
-1 siblings, 0 replies; 6+ messages in thread
From: Atsushi Nemoto @ 2001-08-22 7:15 UTC (permalink / raw)
To: hartvige; +Cc: linux-mips
>>>>> On Wed, 22 Aug 2001 08:46:01 +0200 (MET DST), Hartvig Ekner <hartvige@mips.com> said:
hartvige> what is the purpose of replacing the magic numbers with code
hartvige> analysis?
The magic numbers are affected by frame size of some kernel functions
such as schedule(), sleep_on(), etc. These values may change for
various reason (code modification, new compiler, more optimize, ...).
hartvige> And what will happen when you run userland with MIPS16 or
hartvige> MIPS16e code?
Nothing. The targets of this analysis are only kernel functions.
---
Atsushi Nemoto
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Magic numbers about stack layout
2001-08-22 5:45 Magic numbers about stack layout Atsushi Nemoto
2001-08-22 6:46 ` Hartvig Ekner
@ 2001-08-22 11:40 ` Ralf Baechle
[not found] ` <200205280611.g4S6BuEj006804@oss.sgi.com>
2 siblings, 0 replies; 6+ messages in thread
From: Ralf Baechle @ 2001-08-22 11:40 UTC (permalink / raw)
To: Atsushi Nemoto; +Cc: linux-mips, linux-mips
On Wed, Aug 22, 2001 at 02:45:47PM +0900, Atsushi Nemoto wrote:
> 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.
Very nice, this part of the kernel used to be rather fragile on all
architectures; when wchan computation broke usually nobody complained
and this looks like a major improvment!
Thanks,
Ralf
^ permalink raw reply [flat|nested] 6+ messages in thread
* Magic numbers about stack layout (again)
[not found] ` <200205280611.g4S6BuEj006804@oss.sgi.com>
@ 2002-05-28 8:26 ` Atsushi Nemoto
0 siblings, 0 replies; 6+ messages in thread
From: Atsushi Nemoto @ 2002-05-28 8:26 UTC (permalink / raw)
To: linux-mips; +Cc: ralf
[-- Attachment #1: Type: Text/Plain, Size: 940 bytes --]
>>>>> On Mon, 27 May 2002 23:11:56 -0700, Ralf Baechle <ralf@oss.sgi.com> said:
ralf> Modified files:
ralf> include/asm-mips: Tag: linux_2_4 processor.h
ralf> Log message:
ralf> Daily fix of get_wchan(), bloddy piece of shit ...
I posted this message (and a patch) 9 month ago. How about this?
>>>>> On Wed, 22 Aug 2001 14:45:47 +0900 (JST), Atsushi Nemoto <nemoto@toshiba-tops.co.jp> said:
nemoto> There are some magic constant numbers about stack layout in
nemoto> thread_saved_pc() and get_wchan() function.
nemoto> I made a patch to eliminate these magic numbers. This patch analyzes
nemoto> some functions prologue codes in heuristic way at run-time. "ps -l"
nemoto> (and "MAGIC SYSRQ" feature) works fine with this patch.
Unfortunately, binutils 2.9.5 generates wrong codes with this patch.
I think this is a bug of the binutils. Newer binutils (I tested 2.12
and 2.12.1) or binutils 2.8.1 seems fine.
---
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.