public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* Re: PPC KGDB changes and some help?
       [not found]   ` <20040121153019.GR13454@stop.crashing.org>
@ 2004-01-21 16:53     ` Amit S. Kale
  2004-01-21 18:42       ` Tom Rini
  0 siblings, 1 reply; 35+ messages in thread
From: Amit S. Kale @ 2004-01-21 16:53 UTC (permalink / raw)
  To: Tom Rini, Powerpc Linux, Linux Kernel, KGDB bugreports; +Cc: George Anzinger

Hi,

Here it is: ppc kgdb from timesys kernel is available at
http://kgdb.sourceforge.net/kgdb-2/linux-2.6.1-kgdb-2.1.0.tar.bz2

This is my attempt at extracting kgdb from TimeSys kernel. It works well in 
TimeSys kernel, so blame me if above patch doesn't work.

ChangeLog:
2004-01-21 TimeSys Corporation
	* kgdb on powerpc.

2004-01-21 Pavel Machek <pavel@suse.cz>
	* Changes for coding conventions

2004-01-21 Tom Rini <trini@kernel.crashing.org>
	* Added a prototype for kgdb8250_add_port.


On Wednesday 21 Jan 2004 9:00 pm, Tom Rini wrote:
> On Wed, Jan 21, 2004 at 07:46:17PM +0530, Amit S. Kale wrote:
> > Hi Tom,
> >
> > Yes. Software breakpoints have been tested in the TimeSys ppc kernel
> > source. They work quite well!! I'll be releasing that code soon.
>
> Any chance you can give me what they gave you?  I can try and merge
> and test things.
>
> > Here are a couple of questions from a quick look at this code. I may have
> > more when I do a merge this code with what I have.
> >
> > > -	bl	schedule
> > > +	bl	user_schedule
> >
> > I still have #ifdef CONFIG_KGDB_THREAD here. Threads listing is a
> > necessary feature, agreed. Do you have any ideas on reducing the overhead
> > of the code added by having to push all registers when doing a switch_to?
> >
> > if (kgdb enabled) do a full push of registers else go to usual switch_to
> >
> > Does this sound good?
>
> From what I recall of starting on this around kgdb 2.0.2, I couldn't
> link the kernel w/o this change (KGDB=n).
>
> > > +        */
> > > +#if 0
> > > +       extern atomic_t kgdb_setting_breakpoint;
> > > +       if (atomic_read(&kgdb_setting_breakpoint))
> > > +               regs->nip += 4;
> > > +#else
> > > +       if (linux_regs->nip == 0x7d821008 )
> > > +               /* Skip over breakpoint trap insn */
> > > +               linux_regs->nip += 4;
> > > +#endif
> >
> > Why is kgdb_setting_breakpoint a bad idea?
> > My guess - problems on an smp board.
>
> I don't know how well the current kgdb stub is tested on SMP, but it
> doesn't need any extra locking here.
>
> > Hardcoded nip is worse.
> > Any ideas for a better code?
>
> I've got a feeling that the nip is always the trap instruction, so we
> could always do what the TimeSys code (and before that, the current
> stub) does of skipping over it.  I used the hard-coded value there since
> I hadn't gotten around to re-arranging the code so I could do *(uint
> *)kgdb_ops->gdb_bpt_instr or so.
>
> > In following code, gdb packets and their responses appear correct. kgdb
> > is supposed handle software breakpoints.
> >
> > The breakpoint 0xc0000000 placed by gdb is _evil_ It may clobber data.
> > The gdb at kgdb.sourceforge.net places it correctly at module_event.
>
> I'm not quite sure what you're getting at.   The gdb binary I'm using is
> a good one (It's happy w/ the current kgdb stub, working in tandem w/ a
> BDI2000, etc).  If the breakpoints being set aren't right, I suspect
> that it's related to the other problems I'm seeing.
>
> > Where is the other breakpoint placed? While you would have certainly done
> > that, please confirm that kgdb actually inserts a breakpoint where you
> > have asked it to: a simple printk at the address where the breakpoint is
> > placed should be sufficient. printing from gdb will not work as gdb
> > removes all breakpoints before giving control to a user.
>
> The thing is the kernel gets into an infinite loop of stopping, as far
> as gdb can tell, at the initial breakpoint.

-- 
Amit Kale
EmSysSoft (http://www.emsyssoft.com)
KGDB: Linux Kernel Source Level Debugger (http://kgdb.sourceforge.net)


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

* Re: PPC KGDB changes and some help?
  2004-01-21 16:53     ` PPC KGDB changes and some help? Amit S. Kale
@ 2004-01-21 18:42       ` Tom Rini
  2004-01-21 19:21         ` Tom Rini
  2004-01-21 23:05         ` George Anzinger
  0 siblings, 2 replies; 35+ messages in thread
From: Tom Rini @ 2004-01-21 18:42 UTC (permalink / raw)
  To: Amit S. Kale
  Cc: Powerpc Linux, Linux Kernel, KGDB bugreports, George Anzinger

On Wed, Jan 21, 2004 at 10:23:12PM +0530, Amit S. Kale wrote:

> Hi,
> 
> Here it is: ppc kgdb from timesys kernel is available at
> http://kgdb.sourceforge.net/kgdb-2/linux-2.6.1-kgdb-2.1.0.tar.bz2
> 
> This is my attempt at extracting kgdb from TimeSys kernel. It works well in 
> TimeSys kernel, so blame me if above patch doesn't work.

Okay, here's my first patch against this.
===== kernel/kgdbstub.c 1.1 vs edited =====
--- 1.1/kernel/kgdbstub.c	Wed Jan 21 10:13:17 2004
+++ edited/kernel/kgdbstub.c	Wed Jan 21 10:53:38 2004
@@ -1058,9 +1058,6 @@
 	kgdb_serial->write_char('+');
 
 	linux_debug_hook = kgdb_handle_exception;
-	
-	if (kgdb_ops->kgdb_init)
-		kgdb_ops->kgdb_init();
 
 	/* We can't do much if this fails */
 	register_module_notifier(&kgdb_module_load_nb);
@@ -1104,6 +1101,11 @@
 	if (!kgdb_enter) {
 		return;
 	}
+
+	/* Let the arch do any initalization it needs to */
+	if (kgdb_ops->kgdb_init)
+		kgdb_ops->kgdb_init();
+
 	if (!kgdb_serial) {
 		printk("KGDB: no gdb interface available.\n"
 		       "kgdb can't be enabled\n");

I'm not sure why you were calling the arch-specific init so late in the
process, but since it's a nop on both i386 and x86_64 (so perhaps it
should be removed for both of these?), this change doesn't matter to
them.  But it does make the PPC code cleaner, IMHO.

-- 
Tom Rini
http://gate.crashing.org/~trini/

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

* Re: PPC KGDB changes and some help?
  2004-01-21 18:42       ` Tom Rini
@ 2004-01-21 19:21         ` Tom Rini
  2004-01-21 19:22           ` Tom Rini
                             ` (3 more replies)
  2004-01-21 23:05         ` George Anzinger
  1 sibling, 4 replies; 35+ messages in thread
From: Tom Rini @ 2004-01-21 19:21 UTC (permalink / raw)
  To: Amit S. Kale
  Cc: Powerpc Linux, Linux Kernel, KGDB bugreports, George Anzinger

On Wed, Jan 21, 2004 at 11:42:17AM -0700, Tom Rini wrote:
> On Wed, Jan 21, 2004 at 10:23:12PM +0530, Amit S. Kale wrote:
> 
> > Hi,
> > 
> > Here it is: ppc kgdb from timesys kernel is available at
> > http://kgdb.sourceforge.net/kgdb-2/linux-2.6.1-kgdb-2.1.0.tar.bz2
> > 
> > This is my attempt at extracting kgdb from TimeSys kernel. It works well in 
> > TimeSys kernel, so blame me if above patch doesn't work.
> 
> Okay, here's my first patch against this.

And dependant upon this is a patch to fixup the rest of the common PPC
code, as follows:
- Add FRAME_POINTER
- Put the bits of kgdbppc_init into ppc_kgdb_init.
- None of the gen550 stuffs depend on CONFIG_8250_SERIAL directly,
  remove that constraint.
- Add missing bits like debuggerinfo, BREAKPOINT, etc.
- Add a kgdb_map_scc machdep pointer.

--- 1.48/arch/ppc/Kconfig	Wed Jan 21 10:13:13 2004
+++ edited/arch/ppc/Kconfig	Wed Jan 21 12:18:32 2004
@@ -1405,6 +1405,14 @@
 	  Say Y here only if you plan to use some sort of debugger to
 	  debug the kernel.
 	  If you don't debug the kernel, you can say N.
+
+config FRAME_POINTER
+	bool "Compile the kernel with frame pointers"
+	help
+	  If you say Y here the resulting kernel image will be slightly larger
+	  and slower, but it will give very useful debugging information.
+	  If you don't debug the kernel, you can say N, but we may not be able
+	  to solve problems without frame pointers.
 
 config BOOTX_TEXT
 	bool "Support for early boot text console (BootX or OpenFirmware only)"
--- 1.12/arch/ppc/kernel/ppc-stub.c	Wed Jan 21 10:13:13 2004
+++ edited/arch/ppc/kernel/ppc-stub.c	Wed Jan 21 12:17:34 2004
@@ -20,9 +20,11 @@
 #include <linux/kernel.h>
 #include <linux/config.h>
 #include <linux/kgdb.h>
+
 #include <asm/current.h>
 #include <asm/ptrace.h>
 #include <asm/processor.h>
+#include <asm/machdep.h>
 
 /*
  * Forward prototypes
@@ -81,18 +83,6 @@
 	return 1;
 }
 
-static int ppc_kgdb_init (void)
-{
-	debugger = kgdb_debugger;
-	debugger_bpt = kgdb_breakpoint;
-	debugger_sstep = kgdb_singlestep;
-	debugger_iabr_match = kgdb_iabr_match;
-	debugger_dabr_match = kgdb_dabr_match;
-
-	return 0;
-	
-}
-
 static void ppc_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
 {
 	int reg;
@@ -258,9 +248,10 @@
 	return getDebugChar();
 }
 
-int     kgdbppc_hook(void)
+static int kgdbppc_hook(void)
 {
-	kgdb_map_scc();
+	if (ppc_md.kgdb_map_scc)
+		ppc_md.kgdb_map_scc();
 	return 0;
 }
 
@@ -270,7 +261,16 @@
 	.hook = kgdbppc_hook
 };
 
-void kgdbppc_init(void)
+static int ppc_kgdb_init (void)
 {
+	debugger = kgdb_debugger;
+	debugger_bpt = kgdb_breakpoint;
+	debugger_sstep = kgdb_singlestep;
+	debugger_iabr_match = kgdb_iabr_match;
+	debugger_dabr_match = kgdb_dabr_match;
+
 	kgdb_serial = &kgdbppc_serial;
+
+	return 0;
+	
 }
--- 1.50/arch/ppc/kernel/setup.c	Wed Jan 21 10:13:13 2004
+++ edited/arch/ppc/kernel/setup.c	Wed Jan 21 12:17:34 2004
@@ -37,10 +37,6 @@
 #include <asm/sections.h>
 #include <asm/xmon.h>
 
-#if defined CONFIG_KGDB
-#include <asm/kgdb.h>
-#endif
-
 extern void platform_init(unsigned long r3, unsigned long r4,
 		unsigned long r5, unsigned long r6, unsigned long r7);
 extern void bootx_init(unsigned long r4, unsigned long phys);
@@ -48,11 +44,6 @@
 extern void do_cpu_ftr_fixups(unsigned long offset);
 extern void reloc_got2(unsigned long offset);
 
-
-#ifdef CONFIG_KGDB
-extern void kgdb_map_scc(void);
-#endif
-
 extern void ppc6xx_idle(void);
 extern void power4_idle(void);
 
@@ -631,10 +622,6 @@
 #endif /* CONFIG_XMON */
 	if ( ppc_md.progress ) ppc_md.progress("setup_arch: enter", 0x3eab);
 
-#if defined(CONFIG_KGDB)
-	kgdbppc_init();
-#endif
-
 	/*
 	 * Set cache line size based on type of cpu as a default.
 	 * Systems with OF can look in the properties on the cpu node(s)
--- 1.10/arch/ppc/syslib/Makefile	Wed Sep  3 05:16:34 2003
+++ edited/arch/ppc/syslib/Makefile	Wed Jan 21 12:17:34 2004
@@ -66,7 +66,7 @@
 obj-$(CONFIG_SPRUCE)		+= cpc700_pic.o indirect_pci.o pci_auto.o \
 				   todc_time.o
 obj-$(CONFIG_8260)		+= m8260_setup.o ppc8260_pic.o
-ifeq ($(CONFIG_SERIAL_8250)$(CONFIG_PPC_GEN550),yy)
+ifeq ($(CONFIG_PPC_GEN550),y)
 obj-$(CONFIG_KGDB)		+= gen550_kgdb.o gen550_dbg.o
 obj-$(CONFIG_SERIAL_TEXT_DEBUG)	+= gen550_dbg.o
 endif
--- 1.1/arch/ppc/syslib/gen550_dbg.c	Tue Jul  1 08:34:08 2003
+++ edited/arch/ppc/syslib/gen550_dbg.c	Wed Jan 21 12:17:34 2004
@@ -17,6 +17,8 @@
  */
 
 #include <linux/config.h>
+#include <linux/types.h>
+#include <linux/serial.h>
 #include <linux/tty.h>		/* For linux/serial_core.h */
 #include <linux/serial_core.h>
 #include <linux/serialP.h>
--- 1.2/arch/ppc/syslib/gen550_kgdb.c	Fri Sep 12 09:26:55 2003
+++ edited/arch/ppc/syslib/gen550_kgdb.c	Wed Jan 21 12:17:34 2004
@@ -74,10 +74,10 @@
 
 /*
  * Note: gen550_init() must be called already on the port we are going
- * to use.
+ * to use, or <asm/serial.h> must provide static definitions.
  */
 void
-kgdb_map_scc(void)
+gen550_kgdb_map_scc(void)
 {
 	printk(KERN_DEBUG "kgdb init\n");
 	kgdb_debugport = serial_init(KGDB_PORT, NULL);
--- 1.4/include/asm-ppc/kgdb.h	Sun Sep 15 21:52:04 2002
+++ edited/include/asm-ppc/kgdb.h	Wed Jan 21 12:17:34 2004
@@ -2,6 +2,8 @@
  * kgdb.h: Defines and declarations for serial line source level
  *         remote debugging of the Linux kernel using gdb.
  *
+ * PPC Mods (C) 2004 Tom Rini (trini@mvista.com)
+ * PPC Mods (C) 2003 John Whitney (john.whitney@timesys.com)
  * PPC Mods (C) 1998 Michael Tesch (tesch@cs.wisc.edu)
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -11,10 +13,23 @@
 #define _PPC_KGDB_H
 
 #ifndef __ASSEMBLY__
-/* To initialize the serial, first thing called */
+
+#define BREAK_INSTR_SIZE	4
+#define MAXREG			(PT_FPSCR+1)
+#define NUMREGBYTES		(MAXREG * sizeof(int))
+#define BUFMAX			((NUMREGBYTES * 2) + 512)
+#define OUTBUFMAX		((NUMREGBYTES * 2) + 512)
+#define BREAKPOINT()		asm(".long 0x7d821008") /* twge r2, r2 */
+
+/* Things specific to the gen550 backend. */
+struct uart_port;
+
+extern void gen550_progress(char *, unsigned short);
+extern void gen550_kgdb_map_scc(void);
+extern void gen550_init(int, struct uart_port *);
+
+/* Things specific to the pmac backend. */
 extern void zs_kgdb_hook(int tty_num);
-/* To init the kgdb engine. (called by serial hook)*/
-extern void set_debug_traps(void);
 
 /* To enter the debugger explicitly. */
 extern void breakpoint(void);
--- 1.16/include/asm-ppc/machdep.h	Wed Apr 23 00:49:34 2003
+++ edited/include/asm-ppc/machdep.h	Wed Jan 21 12:17:34 2004
@@ -53,6 +53,7 @@
 	void		(*setup_io_mappings)(void);
 
   	void		(*progress)(char *, unsigned short);
+	void		(*kgdb_map_scc)(void);
 
 	unsigned char 	(*nvram_read_val)(int addr);
 	void		(*nvram_write_val)(int addr, unsigned char val);
--- 1.39/include/asm-ppc/processor.h	Fri Sep 26 16:31:59 2003
+++ edited/include/asm-ppc/processor.h	Wed Jan 21 12:17:34 2004
@@ -119,6 +119,9 @@
 	unsigned long	vrsave;
 	int		used_vr;	/* set if process has used altivec */
 #endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_KGDB
+	void		*debuggerinfo;
+#endif
 };
 
 #define INIT_SP		(sizeof(init_stack) + (unsigned long) &init_stack)

-- 
Tom Rini
http://gate.crashing.org/~trini/

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

* Re: PPC KGDB changes and some help?
  2004-01-21 19:21         ` Tom Rini
@ 2004-01-21 19:22           ` Tom Rini
  2004-01-22 17:44             ` Tom Rini
  2004-01-21 22:03           ` Tom Rini
                             ` (2 subsequent siblings)
  3 siblings, 1 reply; 35+ messages in thread
From: Tom Rini @ 2004-01-21 19:22 UTC (permalink / raw)
  To: Amit S. Kale
  Cc: Powerpc Linux, Linux Kernel, KGDB bugreports, George Anzinger

On Wed, Jan 21, 2004 at 12:21:28PM -0700, Tom Rini wrote:
> On Wed, Jan 21, 2004 at 11:42:17AM -0700, Tom Rini wrote:
> > On Wed, Jan 21, 2004 at 10:23:12PM +0530, Amit S. Kale wrote:
> > 
> > > Hi,
> > > 
> > > Here it is: ppc kgdb from timesys kernel is available at
> > > http://kgdb.sourceforge.net/kgdb-2/linux-2.6.1-kgdb-2.1.0.tar.bz2
> > > 
> > > This is my attempt at extracting kgdb from TimeSys kernel. It works well in 
> > > TimeSys kernel, so blame me if above patch doesn't work.
> > 
> > Okay, here's my first patch against this.
> 
> And dependant upon this is a patch to fixup the rest of the common PPC
> code, as follows:

And on top of all of that is the following, which allows KGDB to work on
the Motorola LoPEC.

--- 1.48/arch/ppc/Kconfig	Wed Jan 21 10:13:13 2004
+++ edited/arch/ppc/Kconfig	Wed Jan 21 10:33:55 2004
@@ -583,11 +583,6 @@
 	depends on PPC_MULTIPLATFORM
 	default y
 
-config PPC_GEN550
-	bool
-	depends on SANDPOINT
-	default y
-
 config PPC_PMAC
 	bool
 	depends on PPC_MULTIPLATFORM
@@ -603,6 +598,11 @@
 	depends on PPC_PMAC || PPC_CHRP
 	default y
 
+config PPC_GEN550
+	bool
+	depends on SANDPOINT || MCPN765 || LOPEC
+	default y
+
 config FORCE
 	bool
 	depends on 6xx && (PCORE || POWERPMC250)
--- 1.20/arch/ppc/platforms/lopec_setup.c	Fri Sep 12 09:26:53 2003
+++ edited/arch/ppc/platforms/lopec_setup.c	Wed Jan 21 10:32:15 2004
@@ -32,6 +32,7 @@
 #include <asm/mpc10x.h>
 #include <asm/hw_irq.h>
 #include <asm/prep_nvram.h>
+#include <asm/kgdb.h>
 
 extern char saved_command_line[];
 extern void lopec_find_bridges(void);
@@ -261,44 +262,6 @@
 		: "=r" (batu), "=r" (batl));
 }
 
-#ifdef  CONFIG_SERIAL_TEXT_DEBUG
-#include <linux/serial.h>
-#include <linux/serialP.h>
-#include <linux/serial_reg.h>
-#include <asm/serial.h>
-
-static struct serial_state rs_table[RS_TABLE_SIZE] = {
-	SERIAL_PORT_DFNS	/* Defined in <asm/serial.h> */
-};
-
-volatile unsigned char *com_port;
-volatile unsigned char *com_port_lsr;
-
-static void
-serial_writechar(char c)
-{
-	while ((*com_port_lsr & UART_LSR_THRE) == 0)
-		;
-	*com_port = c;
-}
-
-void
-lopec_progress(char *s, unsigned short hex)
-{
-	volatile char c;
-
-	com_port = (volatile unsigned char *) rs_table[0].port;
-	com_port_lsr = com_port + UART_LSR;
-
-	while ((c = *s++) != 0)
-		serial_writechar(c);
-
-	/* Most messages don't have a newline in them */
-	serial_writechar('\n');
-	serial_writechar('\r');
-}
-#endif	/* CONFIG_SERIAL_TEXT_DEBUG */
-
 TODC_ALLOC();
 
 static void __init
@@ -383,7 +346,10 @@
 	ppc_ide_md.default_io_base = lopec_ide_default_io_base;
 	ppc_ide_md.ide_init_hwif = lopec_ide_init_hwif_ports;
 #endif
+#ifdef CONFIG_KGDB
+	ppc_md.kgdb_map_scc = gen550_kgdb_map_scc;
+#endif
 #ifdef CONFIG_SERIAL_TEXT_DEBUG
-	ppc_md.progress = lopec_progress;
+	ppc_md.progress = gen550_progress;
 #endif
 }

-- 
Tom Rini
http://gate.crashing.org/~trini/

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

* Re: PPC KGDB changes and some help?
  2004-01-21 19:21         ` Tom Rini
  2004-01-21 19:22           ` Tom Rini
@ 2004-01-21 22:03           ` Tom Rini
  2004-01-21 23:12           ` George Anzinger
  2004-01-26 21:32           ` Tom Rini
  3 siblings, 0 replies; 35+ messages in thread
From: Tom Rini @ 2004-01-21 22:03 UTC (permalink / raw)
  To: Amit S. Kale
  Cc: Powerpc Linux, Linux Kernel, KGDB bugreports, George Anzinger

On Wed, Jan 21, 2004 at 12:21:28PM -0700, Tom Rini wrote:
> On Wed, Jan 21, 2004 at 11:42:17AM -0700, Tom Rini wrote:
> > On Wed, Jan 21, 2004 at 10:23:12PM +0530, Amit S. Kale wrote:
> > 
> > > Hi,
> > > 
> > > Here it is: ppc kgdb from timesys kernel is available at
> > > http://kgdb.sourceforge.net/kgdb-2/linux-2.6.1-kgdb-2.1.0.tar.bz2
> > > 
> > > This is my attempt at extracting kgdb from TimeSys kernel. It works well in 
> > > TimeSys kernel, so blame me if above patch doesn't work.
> > 
> > Okay, here's my first patch against this.
> 
> And dependant upon this is a patch to fixup the rest of the common PPC
> code, as follows:

And this should have also been in this patch:

--- 1.49/arch/ppc/Kconfig	Wed Jan 21 12:21:23 2004
+++ edited/arch/ppc/Kconfig	Wed Jan 21 12:47:52 2004
@@ -1374,12 +1374,11 @@
 	  this option if you do not want to compromise on speed.
 
 config KGDB_CONSOLE
-	bool "Enable serial console thru kgdb port"
-	depends on KGDB && 8xx || 8260
+	bool "KGDB: Console messages through gdb"
+	depends on KGDB
 	help
-	  If you enable this, all serial console messages will be sent
-	  over the gdb stub.
-	  If unsure, say N.
+	  If you say Y here, console messages will appear through gdb.
+	  Other consoles such as tty or ttyS will continue to work as usual.
 
 config XMON
 	bool "Include xmon kernel debugger"

-- 
Tom Rini
http://gate.crashing.org/~trini/

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

* Re: PPC KGDB changes and some help?
  2004-01-21 18:42       ` Tom Rini
  2004-01-21 19:21         ` Tom Rini
@ 2004-01-21 23:05         ` George Anzinger
  2004-01-22 15:03           ` Tom Rini
  1 sibling, 1 reply; 35+ messages in thread
From: George Anzinger @ 2004-01-21 23:05 UTC (permalink / raw)
  To: Tom Rini; +Cc: Amit S. Kale, Powerpc Linux, Linux Kernel, KGDB bugreports

Tom Rini wrote:
> On Wed, Jan 21, 2004 at 10:23:12PM +0530, Amit S. Kale wrote:
> 
> 
>>Hi,
>>
>>Here it is: ppc kgdb from timesys kernel is available at
>>http://kgdb.sourceforge.net/kgdb-2/linux-2.6.1-kgdb-2.1.0.tar.bz2
>>
>>This is my attempt at extracting kgdb from TimeSys kernel. It works well in 
>>TimeSys kernel, so blame me if above patch doesn't work.
> 
> 
> Okay, here's my first patch against this.
> ===== kernel/kgdbstub.c 1.1 vs edited =====
> --- 1.1/kernel/kgdbstub.c	Wed Jan 21 10:13:17 2004
> +++ edited/kernel/kgdbstub.c	Wed Jan 21 10:53:38 2004
> @@ -1058,9 +1058,6 @@
>  	kgdb_serial->write_char('+');
>  
>  	linux_debug_hook = kgdb_handle_exception;
> -	
> -	if (kgdb_ops->kgdb_init)
> -		kgdb_ops->kgdb_init();
>  
>  	/* We can't do much if this fails */
>  	register_module_notifier(&kgdb_module_load_nb);
> @@ -1104,6 +1101,11 @@
>  	if (!kgdb_enter) {
>  		return;
>  	}
> +
> +	/* Let the arch do any initalization it needs to */
> +	if (kgdb_ops->kgdb_init)
> +		kgdb_ops->kgdb_init();
> +
>  	if (!kgdb_serial) {
>  		printk("KGDB: no gdb interface available.\n"
>  		       "kgdb can't be enabled\n");
> 
> I'm not sure why you were calling the arch-specific init so late in the
> process, but since it's a nop on both i386 and x86_64 (so perhaps it
> should be removed for both of these?), this change doesn't matter to
> them.  But it does make the PPC code cleaner, IMHO.

I agree.  Lets dump all the init calls/code.  I have not seen anything yet that 
can not be done as a side effect of the first call, or better yet, at compile time.

I am willing to be shown a valid case, however.  Remember, I want to be able to 
do a breakpoint() as the first line of C code in the kernel.  (works with the mm 
kgdb).
> 

-- 
George Anzinger   george@mvista.com
High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml


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

* Re: PPC KGDB changes and some help?
  2004-01-21 19:21         ` Tom Rini
  2004-01-21 19:22           ` Tom Rini
  2004-01-21 22:03           ` Tom Rini
@ 2004-01-21 23:12           ` George Anzinger
  2004-01-22 15:07             ` Tom Rini
  2004-01-26 21:32           ` Tom Rini
  3 siblings, 1 reply; 35+ messages in thread
From: George Anzinger @ 2004-01-21 23:12 UTC (permalink / raw)
  To: Tom Rini; +Cc: Amit S. Kale, Powerpc Linux, Linux Kernel, KGDB bugreports

Tom Rini wrote:
> On Wed, Jan 21, 2004 at 11:42:17AM -0700, Tom Rini wrote:
> 
>>On Wed, Jan 21, 2004 at 10:23:12PM +0530, Amit S. Kale wrote:
>>
>>
>>>Hi,
>>>
>>>Here it is: ppc kgdb from timesys kernel is available at
>>>http://kgdb.sourceforge.net/kgdb-2/linux-2.6.1-kgdb-2.1.0.tar.bz2
>>>
>>>This is my attempt at extracting kgdb from TimeSys kernel. It works well in 
>>>TimeSys kernel, so blame me if above patch doesn't work.
>>
>>Okay, here's my first patch against this.
> 
> 
> And dependant upon this is a patch to fixup the rest of the common PPC
> code, as follows:
> - Add FRAME_POINTER
> - Put the bits of kgdbppc_init into ppc_kgdb_init.
> - None of the gen550 stuffs depend on CONFIG_8250_SERIAL directly,
>   remove that constraint.
> - Add missing bits like debuggerinfo, BREAKPOINT, etc.
> - Add a kgdb_map_scc machdep pointer.
> 
> --- 1.48/arch/ppc/Kconfig	Wed Jan 21 10:13:13 2004
> +++ edited/arch/ppc/Kconfig	Wed Jan 21 12:18:32 2004
> @@ -1405,6 +1405,14 @@
>  	  Say Y here only if you plan to use some sort of debugger to
>  	  debug the kernel.
>  	  If you don't debug the kernel, you can say N.
> +
> +config FRAME_POINTER
> +	bool "Compile the kernel with frame pointers"
> +	help
> +	  If you say Y here the resulting kernel image will be slightly larger
> +	  and slower, but it will give very useful debugging information.
> +	  If you don't debug the kernel, you can say N, but we may not be able
> +	  to solve problems without frame pointers.

This is fast becoming old hat.  If you compile with dwarf debug info, you not 
only get more reliable frame info, but you do not need frame pointers.  Gdb is 
almost there.  The languages have already arrived.

A question I have been meaning to ask:  Why is the arch/common connection via a 
structure of addresses instead of just calls?  I seems to me that just calling 
is a far cleaner way to do things here.  All the struct seems to offer is a way 
to change the backend on the fly.  I don't thing we ever want to do that.  Am I 
missing something?

-g

-- 
George Anzinger   george@mvista.com
High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml


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

* Re: PPC KGDB changes and some help?
  2004-01-21 23:05         ` George Anzinger
@ 2004-01-22 15:03           ` Tom Rini
  0 siblings, 0 replies; 35+ messages in thread
From: Tom Rini @ 2004-01-22 15:03 UTC (permalink / raw)
  To: George Anzinger
  Cc: Amit S. Kale, Powerpc Linux, Linux Kernel, KGDB bugreports

On Wed, Jan 21, 2004 at 03:05:54PM -0800, George Anzinger wrote:
> Tom Rini wrote:
> >On Wed, Jan 21, 2004 at 10:23:12PM +0530, Amit S. Kale wrote:
> >
> >
> >>Hi,
> >>
> >>Here it is: ppc kgdb from timesys kernel is available at
> >>http://kgdb.sourceforge.net/kgdb-2/linux-2.6.1-kgdb-2.1.0.tar.bz2
> >>
> >>This is my attempt at extracting kgdb from TimeSys kernel. It works well 
> >>in TimeSys kernel, so blame me if above patch doesn't work.
> >
> >
> >Okay, here's my first patch against this.
> >===== kernel/kgdbstub.c 1.1 vs edited =====
> >--- 1.1/kernel/kgdbstub.c	Wed Jan 21 10:13:17 2004
> >+++ edited/kernel/kgdbstub.c	Wed Jan 21 10:53:38 2004
> >@@ -1058,9 +1058,6 @@
> > 	kgdb_serial->write_char('+');
> > 
> > 	linux_debug_hook = kgdb_handle_exception;
> >-	
> >-	if (kgdb_ops->kgdb_init)
> >-		kgdb_ops->kgdb_init();
> > 
> > 	/* We can't do much if this fails */
> > 	register_module_notifier(&kgdb_module_load_nb);
> >@@ -1104,6 +1101,11 @@
> > 	if (!kgdb_enter) {
> > 		return;
> > 	}
> >+
> >+	/* Let the arch do any initalization it needs to */
> >+	if (kgdb_ops->kgdb_init)
> >+		kgdb_ops->kgdb_init();
> >+
> > 	if (!kgdb_serial) {
> > 		printk("KGDB: no gdb interface available.\n"
> > 		       "kgdb can't be enabled\n");
> >
> >I'm not sure why you were calling the arch-specific init so late in the
> >process, but since it's a nop on both i386 and x86_64 (so perhaps it
> >should be removed for both of these?), this change doesn't matter to
> >them.  But it does make the PPC code cleaner, IMHO.
> 
> I agree.  Lets dump all the init calls/code.  I have not seen anything yet 
> that can not be done as a side effect of the first call, or better yet, at 
> compile time.
> 
> I am willing to be shown a valid case, however.  Remember, I want to be 
> able to do a breakpoint() as the first line of C code in the kernel.  
> (works with the mm kgdb).

How would you propose handling what's done in ppc_kgdb_init ?  I could
make it a __setup, ala how kgdb_8250.c works, but that too won't allow
for 'first line of C'.  OTOH,  if breakpoint did:
if (!kgdb_initalized) {
   ... work of kgdb_entry() ...
}
... normal breakpoint() code ...

PPC would be fine, as would other arches which need to do some setup.

-- 
Tom Rini
http://gate.crashing.org/~trini/

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

* Re: PPC KGDB changes and some help?
  2004-01-21 23:12           ` George Anzinger
@ 2004-01-22 15:07             ` Tom Rini
  2004-01-22 15:25               ` Hollis Blanchard
  0 siblings, 1 reply; 35+ messages in thread
From: Tom Rini @ 2004-01-22 15:07 UTC (permalink / raw)
  To: George Anzinger
  Cc: Amit S. Kale, Powerpc Linux, Linux Kernel, KGDB bugreports

On Wed, Jan 21, 2004 at 03:12:25PM -0800, George Anzinger wrote:
> Tom Rini wrote:
> >On Wed, Jan 21, 2004 at 11:42:17AM -0700, Tom Rini wrote:
> >
> >>On Wed, Jan 21, 2004 at 10:23:12PM +0530, Amit S. Kale wrote:
> >>
> >>
> >>>Hi,
> >>>
> >>>Here it is: ppc kgdb from timesys kernel is available at
> >>>http://kgdb.sourceforge.net/kgdb-2/linux-2.6.1-kgdb-2.1.0.tar.bz2
> >>>
> >>>This is my attempt at extracting kgdb from TimeSys kernel. It works well 
> >>>in TimeSys kernel, so blame me if above patch doesn't work.
> >>
> >>Okay, here's my first patch against this.
> >
> >
> >And dependant upon this is a patch to fixup the rest of the common PPC
> >code, as follows:
> >- Add FRAME_POINTER
> >- Put the bits of kgdbppc_init into ppc_kgdb_init.
> >- None of the gen550 stuffs depend on CONFIG_8250_SERIAL directly,
> >  remove that constraint.
> >- Add missing bits like debuggerinfo, BREAKPOINT, etc.
> >- Add a kgdb_map_scc machdep pointer.
> >
> >--- 1.48/arch/ppc/Kconfig	Wed Jan 21 10:13:13 2004
> >+++ edited/arch/ppc/Kconfig	Wed Jan 21 12:18:32 2004
> >@@ -1405,6 +1405,14 @@
> > 	  Say Y here only if you plan to use some sort of debugger to
> > 	  debug the kernel.
> > 	  If you don't debug the kernel, you can say N.
> >+
> >+config FRAME_POINTER
> >+	bool "Compile the kernel with frame pointers"
> >+	help
> >+	  If you say Y here the resulting kernel image will be slightly 
> >larger
> >+	  and slower, but it will give very useful debugging information.
> >+	  If you don't debug the kernel, you can say N, but we may not be 
> >able
> >+	  to solve problems without frame pointers.
> 
> This is fast becoming old hat.  If you compile with dwarf debug info, you 
> not only get more reliable frame info, but you do not need frame pointers.  
> Gdb is almost there.  The languages have already arrived.

My guess would be the miniumum toolchain requirements for i386/ppc (I
don't know x86_64) aren't all that new, so while gcc-3.3 probably gives
everything you describe, gcc-3.0 (which is valid for PPC, iirc) probably
doesn't.

> A question I have been meaning to ask:  Why is the arch/common connection 
> via a structure of addresses instead of just calls?  I seems to me that 
> just calling is a far cleaner way to do things here.  All the struct seems 
> to offer is a way to change the backend on the fly.  I don't thing we ever 
> want to do that.  Am I missing something?

I imagine it's a style thing.  I don't have a preference either way.

-- 
Tom Rini
http://gate.crashing.org/~trini/

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

* Re: PPC KGDB changes and some help?
  2004-01-22 15:07             ` Tom Rini
@ 2004-01-22 15:25               ` Hollis Blanchard
  2004-01-22 15:45                 ` Tom Rini
  0 siblings, 1 reply; 35+ messages in thread
From: Hollis Blanchard @ 2004-01-22 15:25 UTC (permalink / raw)
  To: Tom Rini
  Cc: KGDB bugreports, Linux Kernel, George Anzinger, Powerpc Linux,
	Amit S. Kale

On Jan 22, 2004, at 9:07 AM, Tom Rini wrote:
>
> On Wed, Jan 21, 2004 at 03:12:25PM -0800, George Anzinger wrote:
>
>> A question I have been meaning to ask:  Why is the arch/common 
>> connection
>> via a structure of addresses instead of just calls?  I seems to me 
>> that
>> just calling is a far cleaner way to do things here.  All the struct 
>> seems
>> to offer is a way to change the backend on the fly.  I don't thing we 
>> ever
>> want to do that.  Am I missing something?
>
> I imagine it's a style thing.  I don't have a preference either way.

I think we in PPC land have gotten used to that "style" because we have 
one kernel that supports different "platforms", i.e. it selects the 
appropriate code at runtime as George says. In general that's a little 
bit slower and a little bit bigger.

Unless you need to choose among PPC KGDB functions at runtime, which I 
don't think you do, you don't need it...

-- 
Hollis Blanchard
IBM Linux Technology Center


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

* Re: PPC KGDB changes and some help?
  2004-01-22 15:25               ` Hollis Blanchard
@ 2004-01-22 15:45                 ` Tom Rini
  2004-01-22 16:06                   ` Amit S. Kale
  2004-01-22 21:54                   ` George Anzinger
  0 siblings, 2 replies; 35+ messages in thread
From: Tom Rini @ 2004-01-22 15:45 UTC (permalink / raw)
  To: Hollis Blanchard
  Cc: KGDB bugreports, Linux Kernel, George Anzinger, Powerpc Linux,
	Amit S. Kale

On Thu, Jan 22, 2004 at 09:25:19AM -0600, Hollis Blanchard wrote:
> On Jan 22, 2004, at 9:07 AM, Tom Rini wrote:
> >
> >On Wed, Jan 21, 2004 at 03:12:25PM -0800, George Anzinger wrote:
> >
> >>A question I have been meaning to ask:  Why is the arch/common 
> >>connection
> >>via a structure of addresses instead of just calls?  I seems to me 
> >>that
> >>just calling is a far cleaner way to do things here.  All the struct 
> >>seems
> >>to offer is a way to change the backend on the fly.  I don't thing we 
> >>ever
> >>want to do that.  Am I missing something?
> >
> >I imagine it's a style thing.  I don't have a preference either way.
> 
> I think we in PPC land have gotten used to that "style" because we have 
> one kernel that supports different "platforms", i.e. it selects the 
> appropriate code at runtime as George says. In general that's a little 
> bit slower and a little bit bigger.
> 
> Unless you need to choose among PPC KGDB functions at runtime, which I 
> don't think you do, you don't need it...

That's certainly true, so if (and if I understand Georges question
right) Amit wants to change kgdb_arch into a set of required functions,
with stubs in, say, kernel/kgdbdummy.c, (and just keep the flags / etc
in the struct), that's fine with me.

-- 
Tom Rini
http://gate.crashing.org/~trini/

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

* Re: PPC KGDB changes and some help?
  2004-01-22 15:45                 ` Tom Rini
@ 2004-01-22 16:06                   ` Amit S. Kale
  2004-01-22 16:45                     ` Tom Rini
                                       ` (2 more replies)
  2004-01-22 21:54                   ` George Anzinger
  1 sibling, 3 replies; 35+ messages in thread
From: Amit S. Kale @ 2004-01-22 16:06 UTC (permalink / raw)
  To: Tom Rini, Hollis Blanchard
  Cc: KGDB bugreports, Linux Kernel, George Anzinger, Powerpc Linux

On Thursday 22 Jan 2004 9:15 pm, Tom Rini wrote:
> On Thu, Jan 22, 2004 at 09:25:19AM -0600, Hollis Blanchard wrote:
> > On Jan 22, 2004, at 9:07 AM, Tom Rini wrote:
> > >On Wed, Jan 21, 2004 at 03:12:25PM -0800, George Anzinger wrote:
> > >>A question I have been meaning to ask:  Why is the arch/common
> > >>connection
> > >>via a structure of addresses instead of just calls?  I seems to me
> > >>that
> > >>just calling is a far cleaner way to do things here.  All the struct
> > >>seems
> > >>to offer is a way to change the backend on the fly.  I don't thing we
> > >>ever
> > >>want to do that.  Am I missing something?
> > >
> > >I imagine it's a style thing.  I don't have a preference either way.
> >
> > I think we in PPC land have gotten used to that "style" because we have
> > one kernel that supports different "platforms", i.e. it selects the
> > appropriate code at runtime as George says. In general that's a little
> > bit slower and a little bit bigger.
> >
> > Unless you need to choose among PPC KGDB functions at runtime, which I
> > don't think you do, you don't need it...
>
> That's certainly true, so if (and if I understand Georges question
> right) Amit wants to change kgdb_arch into a set of required functions,
> with stubs in, say, kernel/kgdbdummy.c, (and just keep the flags / etc
> in the struct), that's fine with me.

The penalty of keeping them consolidated in a structure isn't so high. I 
prefer to keep them that way. I'll work on reducing number of initialization 
functions, though.

I have to do something about early connect though. Powerpc kgdb on 8260 is 
definitely capable of starting debugging right at architecture setup time. 
It's just that kgdbstub.c isn't ready yet.

How about changing the code in kgdbstub to allow kgdb to be configured in one 
of the following ways:
Late kgdb - kgdb comes up after smp_init in the kernel boot sequence. kgdb8250 
can be used with more flexibility through kernel command line options. One 
can boot a kgdb kernel without activating kgdb. Works with the interface 
chosen by kernel command line (kgdb8250 and kgdbeth for the moment).

Command line flexibilty is of great help if you have to test on 2-3 servers (I 
used to do that a lot at Veritas). The same kernel can be compiled with 
drivers needed by all of them plus kgdb. Command line options choose port no 
and speeds depending on machine hardware connections. I guess it's of little 
use on embedded systems where usually a new kernel has to be compiled for 
each board.

Early kgdb - kgdb comes up right at the begining of start_kernel at the cost 
of flexibility. It doesn't show any messages such as "waiting for gdb". All 
configurations have to be compiled in through menuconfig. Once a kernel is 
built, it'll always run with kgdb and with 8250 at a fixed port and speed.

i386 architecture will support both kgdb configuration.
KGDB in powerpc 8260 will be of early kgdb type. Other powerpc arches (550 etc 
will depend on whether the interface can be initialized early or later)
-- 
Amit Kale
EmSysSoft (http://www.emsyssoft.com)
KGDB: Linux Kernel Source Level Debugger (http://kgdb.sourceforge.net)


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

* Re: PPC KGDB changes and some help?
  2004-01-22 16:06                   ` Amit S. Kale
@ 2004-01-22 16:45                     ` Tom Rini
  2004-01-22 22:46                       ` George Anzinger
  2004-01-22 22:35                     ` George Anzinger
  2004-01-23 17:08                     ` Tom Rini
  2 siblings, 1 reply; 35+ messages in thread
From: Tom Rini @ 2004-01-22 16:45 UTC (permalink / raw)
  To: Amit S. Kale
  Cc: Hollis Blanchard, KGDB bugreports, Linux Kernel, George Anzinger,
	Powerpc Linux

On Thu, Jan 22, 2004 at 09:36:10PM +0530, Amit S. Kale wrote:
> On Thursday 22 Jan 2004 9:15 pm, Tom Rini wrote:
> > On Thu, Jan 22, 2004 at 09:25:19AM -0600, Hollis Blanchard wrote:
> > > On Jan 22, 2004, at 9:07 AM, Tom Rini wrote:
> > > >On Wed, Jan 21, 2004 at 03:12:25PM -0800, George Anzinger wrote:
> > > >>A question I have been meaning to ask:  Why is the arch/common
> > > >>connection
> > > >>via a structure of addresses instead of just calls?  I seems to me
> > > >>that
> > > >>just calling is a far cleaner way to do things here.  All the struct
> > > >>seems
> > > >>to offer is a way to change the backend on the fly.  I don't thing we
> > > >>ever
> > > >>want to do that.  Am I missing something?
> > > >
> > > >I imagine it's a style thing.  I don't have a preference either way.
> > >
> > > I think we in PPC land have gotten used to that "style" because we have
> > > one kernel that supports different "platforms", i.e. it selects the
> > > appropriate code at runtime as George says. In general that's a little
> > > bit slower and a little bit bigger.
> > >
> > > Unless you need to choose among PPC KGDB functions at runtime, which I
> > > don't think you do, you don't need it...
> >
> > That's certainly true, so if (and if I understand Georges question
> > right) Amit wants to change kgdb_arch into a set of required functions,
> > with stubs in, say, kernel/kgdbdummy.c, (and just keep the flags / etc
> > in the struct), that's fine with me.
> 
> The penalty of keeping them consolidated in a structure isn't so high. I 
> prefer to keep them that way. I'll work on reducing number of initialization 
> functions, though.
> 
> I have to do something about early connect though. Powerpc kgdb on 8260 is 
> definitely capable of starting debugging right at architecture setup time. 
> It's just that kgdbstub.c isn't ready yet.

FWIW, this is true of KGDB on all PPCs.  IIRC, so long as the serial
definitions are filled out statically, the stub currently in kernel.org
for PPC can do first-line-of-C already.

> How about changing the code in kgdbstub to allow kgdb to be configured in one 
> of the following ways:
> Late kgdb - kgdb comes up after smp_init in the kernel boot sequence. kgdb8250 
> can be used with more flexibility through kernel command line options. One 
> can boot a kgdb kernel without activating kgdb. Works with the interface 
> chosen by kernel command line (kgdb8250 and kgdbeth for the moment).

Which is basically how it goes now, right?

> Early kgdb - kgdb comes up right at the begining of start_kernel at the cost 
> of flexibility. It doesn't show any messages such as "waiting for gdb". All 
> configurations have to be compiled in through menuconfig. Once a kernel is 
> built, it'll always run with kgdb and with 8250 at a fixed port and speed.
> 
> i386 architecture will support both kgdb configuration.
> KGDB in powerpc 8260 will be of early kgdb type. Other powerpc arches (550 etc 
> will depend on whether the interface can be initialized early or later)

Again, there is nothing special about KGDB on 82xx (or 8xx for that
matter) over classic PPCs (which tend to have a 550, but this is not
always the case) or 4xx.

-- 
Tom Rini
http://gate.crashing.org/~trini/

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

* Re: PPC KGDB changes and some help?
  2004-01-21 19:22           ` Tom Rini
@ 2004-01-22 17:44             ` Tom Rini
  2004-01-22 18:05               ` Tom Rini
  0 siblings, 1 reply; 35+ messages in thread
From: Tom Rini @ 2004-01-22 17:44 UTC (permalink / raw)
  To: Amit S. Kale
  Cc: Powerpc Linux, Linux Kernel, KGDB bugreports, George Anzinger

On Wed, Jan 21, 2004 at 12:22:30PM -0700, Tom Rini wrote:
> On Wed, Jan 21, 2004 at 12:21:28PM -0700, Tom Rini wrote:
> > On Wed, Jan 21, 2004 at 11:42:17AM -0700, Tom Rini wrote:
> > > On Wed, Jan 21, 2004 at 10:23:12PM +0530, Amit S. Kale wrote:
> > > 
> > > > Hi,
> > > > 
> > > > Here it is: ppc kgdb from timesys kernel is available at
> > > > http://kgdb.sourceforge.net/kgdb-2/linux-2.6.1-kgdb-2.1.0.tar.bz2
> > > > 
> > > > This is my attempt at extracting kgdb from TimeSys kernel. It works well in 
> > > > TimeSys kernel, so blame me if above patch doesn't work.
> > > 
> > > Okay, here's my first patch against this.
> > 
> > And dependant upon this is a patch to fixup the rest of the common PPC
> > code, as follows:
> 
> And on top of all of that is the following, which allows KGDB to work on
> the Motorola LoPEC.

On top of everything from yesterday, here's:

Cleanup ppc-stub.c
 - Lindent
 - Redo boilerplate to match most other PPC files.
 - Rearrange code so that we don't need forward declarations.

 arch/ppc/kernel/ppc-stub.c |  184 ++++++++++++++++++++-------------------------
 1 files changed, 83 insertions(+), 101 deletions(-)
--- 1.13/arch/ppc/kernel/ppc-stub.c	Wed Jan 21 12:21:23 2004
+++ edited/arch/ppc/kernel/ppc-stub.c	Thu Jan 22 10:40:55 2004
@@ -1,20 +1,13 @@
 /*
+ * arch/ppc/kernel/ppc-stub.c
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
+ * PowerPC-specific bits to work with the common KGDB stub.
  *
- */
-
-/*
- * Copyright (C) 2003 Timesys Corporation.
- * KGDB for the PowerPC processor
+ * 2003 (c) TimeSys Corporation
+ * 2004 (c) MontaVista Software, Inc.
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
  */
 
 #include <linux/kernel.h>
@@ -27,68 +20,56 @@
 #include <asm/machdep.h>
 
 /*
- * Forward prototypes
- */
-static void kgdb_debugger (struct pt_regs *regs);
-static int kgdb_breakpoint (struct pt_regs *regs);
-static int kgdb_singlestep (struct pt_regs *regs);
-static int ppc_kgdb_init (void);
-static void ppc_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs);
-static void ppc_sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p);
-static void ppc_gdb_regs_to_regs(unsigned long *gdb_regs, struct pt_regs *regs);
-void ppc_handler_exit (void);
-static int ppc_handle_exception (int            vector,
-                           int            signo,
-                           int            err_code,
-                           char           *remcomInBuffer,
-                           char           *remcomOutBuffer,
-                           struct pt_regs *linux_regs);
-
-/*
  * Routines
  */
-static void kgdb_debugger (struct pt_regs *regs)
+static void
+kgdb_debugger(struct pt_regs *regs)
 {
 	(*linux_debug_hook) (0, 0, 0, regs);
 	return;
 }
 
-static int kgdb_breakpoint (struct pt_regs *regs)
+static int
+kgdb_breakpoint(struct pt_regs *regs)
 {
 	extern atomic_t kgdb_setting_breakpoint;
 
 	(*linux_debug_hook) (0, SIGTRAP, 0, regs);
 
-	if (atomic_read (&kgdb_setting_breakpoint))
+	if (atomic_read(&kgdb_setting_breakpoint))
 		regs->nip += 4;
 
 	return 1;
 }
 
-static int kgdb_singlestep (struct pt_regs *regs)
+static int
+kgdb_singlestep(struct pt_regs *regs)
 {
 	(*linux_debug_hook) (0, SIGTRAP, 0, regs);
 	return 1;
 }
 
-int kgdb_iabr_match(struct pt_regs *regs)
+int
+kgdb_iabr_match(struct pt_regs *regs)
 {
 	(*linux_debug_hook) (0, 0, 0, regs);
 	return 1;
 }
 
-int kgdb_dabr_match(struct pt_regs *regs)
+int
+kgdb_dabr_match(struct pt_regs *regs)
 {
 	(*linux_debug_hook) (0, 0, 0, regs);
 	return 1;
 }
 
-static void ppc_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
+static void
+ppc_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
 {
 	int reg;
 	unsigned long *ptr = gdb_regs;
 
-	memset(gdb_regs, 0, MAXREG*4);
+	memset(gdb_regs, 0, MAXREG * 4);
 
 	for (reg = 0; reg < 32; reg++)
 		*(ptr++) = regs->gpr[reg];
@@ -104,16 +85,17 @@
 	*(ptr++) = regs->xer;
 
 	return;
-}	/* regs_to_gdb_regs */
+}				/* regs_to_gdb_regs */
 
-static void ppc_sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
+static void
+ppc_sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
 {
 	struct pt_regs *regs = (struct pt_regs *) (p->thread.ksp +
-	                                           STACK_FRAME_OVERHEAD);
+						   STACK_FRAME_OVERHEAD);
 	int reg;
 	unsigned long *ptr = gdb_regs;
 
-	memset(gdb_regs, 0, MAXREG*4);
+	memset(gdb_regs, 0, MAXREG * 4);
 
 	/* Regs GPR0-2 */
 	for (reg = 0; reg < 3; reg++)
@@ -140,7 +122,8 @@
 	return;
 }
 
-static void ppc_gdb_regs_to_regs(unsigned long *gdb_regs, struct pt_regs *regs)
+static void
+ppc_gdb_regs_to_regs(unsigned long *gdb_regs, struct pt_regs *regs)
 {
 	int reg;
 	unsigned long *ptr = gdb_regs;
@@ -159,96 +142,81 @@
 	regs->xer = *(ptr++);
 
 	return;
-}	/* gdb_regs_to_regs */
-
+}				/* gdb_regs_to_regs */
 
 /* exit_handler:
  * 
  * This is called by the generic layer when it is about to return from 
  * the exception handler
  */
-void ppc_handler_exit (void)
+void
+ppc_handler_exit(void)
 {
-//	flush_instruction_cache ();
+//      flush_instruction_cache ();
 	return;
 }
 
-
 /*
  * This function does PoerPC specific procesing for interfacing to gdb.
  */
-static int ppc_handle_exception (int            vector,
-                          int            signo,
-                          int            err_code,
-                          char           *remcomInBuffer,
-                          char           *remcomOutBuffer,
-                          struct pt_regs *linux_regs)
+static int
+ppc_handle_exception(int vector,
+		     int signo,
+		     int err_code,
+		     char *remcomInBuffer,
+		     char *remcomOutBuffer, struct pt_regs *linux_regs)
 {
 	char *ptr;
 	unsigned long addr;
-	
-	switch (remcomInBuffer[0])
-		{
+
+	switch (remcomInBuffer[0]) {
 		/*
 		 * sAA..AA   Step one instruction from AA..AA 
 		 * This will return an error to gdb ..
 		 */
-		case 's':
-		case 'c':
-			if (kgdb_contthread && kgdb_contthread != current)
-			{
-				strcpy(remcomOutBuffer, "E00");
-				break;
-			}
-
-			kgdb_contthread = NULL;
-
-			/* handle the optional parameter */
-			ptr = &remcomInBuffer[1];
-			if (kgdb_hexToLong (&ptr, &addr))
-				linux_regs->nip = addr;
-
-			/* set the trace bit if we're stepping */
-			if (remcomInBuffer[0] == 's')
-			{
+	case 's':
+	case 'c':
+		if (kgdb_contthread && kgdb_contthread != current) {
+			strcpy(remcomOutBuffer, "E00");
+			break;
+		}
+
+		kgdb_contthread = NULL;
+
+		/* handle the optional parameter */
+		ptr = &remcomInBuffer[1];
+		if (kgdb_hexToLong(&ptr, &addr))
+			linux_regs->nip = addr;
+
+		/* set the trace bit if we're stepping */
+		if (remcomInBuffer[0] == 's') {
 #if defined (CONFIG_4xx)
-				linux_regs->msr |= MSR_DE;
-				current->thread.dbcr0 |= (DBCR_IDM | DBCR_IC);
+			linux_regs->msr |= MSR_DE;
+			current->thread.dbcr0 |= (DBCR_IDM | DBCR_IC);
 #else
-				linux_regs->msr |= MSR_SE;
+			linux_regs->msr |= MSR_SE;
 #endif
-			}
-			return 0;
+		}
+		return 0;
 	}
 
 	return -1;
 }
 
-/*
- * Global data
- */
-struct kgdb_arch arch_kgdb_ops =
-{
-	.gdb_bpt_instr = { 0x7d, 0x82, 0x10, 0x08 },
-	.kgdb_init = ppc_kgdb_init,
-	.regs_to_gdb_regs = ppc_regs_to_gdb_regs,
-	.sleeping_thread_to_gdb_regs = ppc_sleeping_thread_to_gdb_regs,
-	.gdb_regs_to_regs = ppc_gdb_regs_to_regs,
-	.handle_exception = ppc_handle_exception,
-	.handler_exit = ppc_handler_exit,
-};
-
-static void kgdbppc_write_char(int chr)
+static void
+kgdbppc_write_char(int chr)
 {
 	putDebugChar(chr);
 }
 
-static int kgdbppc_read_char(void)
+static int
+kgdbppc_read_char(void)
 {
 	return getDebugChar();
 }
 
-static int kgdbppc_hook(void)
+static int
+kgdbppc_hook(void)
 {
 	if (ppc_md.kgdb_map_scc)
 		ppc_md.kgdb_map_scc();
@@ -261,7 +229,8 @@
 	.hook = kgdbppc_hook
 };
 
-static int ppc_kgdb_init (void)
+static int
+ppc_kgdb_init(void)
 {
 	debugger = kgdb_debugger;
 	debugger_bpt = kgdb_breakpoint;
@@ -272,5 +241,18 @@
 	kgdb_serial = &kgdbppc_serial;
 
 	return 0;
-	
+
 }
+
+/*
+ * Global data
+ */
+struct kgdb_arch arch_kgdb_ops = {
+	.gdb_bpt_instr = {0x7d, 0x82, 0x10, 0x08},
+	.kgdb_init = ppc_kgdb_init,
+	.regs_to_gdb_regs = ppc_regs_to_gdb_regs,
+	.sleeping_thread_to_gdb_regs = ppc_sleeping_thread_to_gdb_regs,
+	.gdb_regs_to_regs = ppc_gdb_regs_to_regs,
+	.handle_exception = ppc_handle_exception,
+	.handler_exit = ppc_handler_exit,
+};

I'll have some functional changes that apply on top of this soon.

-- 
Tom Rini
http://gate.crashing.org/~trini/

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

* Re: PPC KGDB changes and some help?
  2004-01-22 17:44             ` Tom Rini
@ 2004-01-22 18:05               ` Tom Rini
  2004-01-23 22:46                 ` Tom Rini
  0 siblings, 1 reply; 35+ messages in thread
From: Tom Rini @ 2004-01-22 18:05 UTC (permalink / raw)
  To: Amit S. Kale
  Cc: Powerpc Linux, Linux Kernel, KGDB bugreports, George Anzinger

On Thu, Jan 22, 2004 at 10:44:16AM -0700, Tom Rini wrote:
> On Wed, Jan 21, 2004 at 12:22:30PM -0700, Tom Rini wrote:
> > On Wed, Jan 21, 2004 at 12:21:28PM -0700, Tom Rini wrote:
> > > On Wed, Jan 21, 2004 at 11:42:17AM -0700, Tom Rini wrote:
> > > > On Wed, Jan 21, 2004 at 10:23:12PM +0530, Amit S. Kale wrote:
> > > > 
> > > > > Hi,
> > > > > 
> > > > > Here it is: ppc kgdb from timesys kernel is available at
> > > > > http://kgdb.sourceforge.net/kgdb-2/linux-2.6.1-kgdb-2.1.0.tar.bz2
> > > > > 
> > > > > This is my attempt at extracting kgdb from TimeSys kernel. It works well in 
> > > > > TimeSys kernel, so blame me if above patch doesn't work.
> > > > 
> > > > Okay, here's my first patch against this.
> > > 
> > > And dependant upon this is a patch to fixup the rest of the common PPC
> > > code, as follows:
> > 
> > And on top of all of that is the following, which allows KGDB to work on
> > the Motorola LoPEC.
> 
> On top of everything from yesterday, here's:

First up:
We need to call flush_instruction_cache() on a 'c' or 's' command.
 arch/ppc/kernel/ppc-stub.c |   19 ++++++-------------
 1 files changed, 6 insertions(+), 13 deletions(-)
--- 1.14/arch/ppc/kernel/ppc-stub.c	Thu Jan 22 10:41:58 2004
+++ edited/arch/ppc/kernel/ppc-stub.c	Thu Jan 22 10:49:30 2004
@@ -144,18 +144,6 @@
 	return;
 }				/* gdb_regs_to_regs */
 
-/* exit_handler:
- * 
- * This is called by the generic layer when it is about to return from 
- * the exception handler
- */
-void
-ppc_handler_exit(void)
-{
-//      flush_instruction_cache ();
-	return;
-}
-
 /*
  * This function does PoerPC specific procesing for interfacing to gdb.
  */
@@ -188,6 +176,12 @@
 		if (kgdb_hexToLong(&ptr, &addr))
 			linux_regs->nip = addr;
 
+/* Need to flush the instruction cache here, as we may have deposited a
+ * breakpoint, and the icache probably has no way of knowing that a data ref to
+ * some location may have changed something that is in the instruction cache.
+ */
+		flush_instruction_cache();
+
 		/* set the trace bit if we're stepping */
 		if (remcomInBuffer[0] == 's') {
 #if defined (CONFIG_4xx)
@@ -254,5 +248,4 @@
 	.sleeping_thread_to_gdb_regs = ppc_sleeping_thread_to_gdb_regs,
 	.gdb_regs_to_regs = ppc_gdb_regs_to_regs,
 	.handle_exception = ppc_handle_exception,
-	.handler_exit = ppc_handler_exit,
 };

-- 
Tom Rini
http://gate.crashing.org/~trini/

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

* Re: PPC KGDB changes and some help?
  2004-01-22 15:45                 ` Tom Rini
  2004-01-22 16:06                   ` Amit S. Kale
@ 2004-01-22 21:54                   ` George Anzinger
  1 sibling, 0 replies; 35+ messages in thread
From: George Anzinger @ 2004-01-22 21:54 UTC (permalink / raw)
  To: Tom Rini
  Cc: Hollis Blanchard, KGDB bugreports, Linux Kernel, Powerpc Linux,
	Amit S. Kale

Tom Rini wrote:
> On Thu, Jan 22, 2004 at 09:25:19AM -0600, Hollis Blanchard wrote:
> 
>>On Jan 22, 2004, at 9:07 AM, Tom Rini wrote:
>>
>>>On Wed, Jan 21, 2004 at 03:12:25PM -0800, George Anzinger wrote:
>>>
>>>
>>>>A question I have been meaning to ask:  Why is the arch/common 
>>>>connection
>>>>via a structure of addresses instead of just calls?  I seems to me 
>>>>that
>>>>just calling is a far cleaner way to do things here.  All the struct 
>>>>seems
>>>>to offer is a way to change the backend on the fly.  I don't thing we 
>>>>ever
>>>>want to do that.  Am I missing something?
>>>
>>>I imagine it's a style thing.  I don't have a preference either way.
>>
>>I think we in PPC land have gotten used to that "style" because we have 
>>one kernel that supports different "platforms", i.e. it selects the 
>>appropriate code at runtime as George says. In general that's a little 
>>bit slower and a little bit bigger.
>>
>>Unless you need to choose among PPC KGDB functions at runtime, which I 
>>don't think you do, you don't need it...
> 
> 
> That's certainly true, so if (and if I understand Georges question
> right) Amit wants to change kgdb_arch into a set of required functions,
> with stubs in, say, kernel/kgdbdummy.c, (and just keep the flags / etc
> in the struct), that's fine with me.

Something like that.  I would make use of the weak external to handle the stub 
connection, i.e. the common code would define the stubs as weak functions.  The 
linker will choose a normal over a weak so it makes the right connection.
> 

-- 
George Anzinger   george@mvista.com
High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml


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

* Re: PPC KGDB changes and some help?
  2004-01-22 16:06                   ` Amit S. Kale
  2004-01-22 16:45                     ` Tom Rini
@ 2004-01-22 22:35                     ` George Anzinger
  2004-01-23 17:08                     ` Tom Rini
  2 siblings, 0 replies; 35+ messages in thread
From: George Anzinger @ 2004-01-22 22:35 UTC (permalink / raw)
  To: Amit S. Kale
  Cc: Tom Rini, Hollis Blanchard, KGDB bugreports, Linux Kernel,
	Powerpc Linux

Amit S. Kale wrote:
> On Thursday 22 Jan 2004 9:15 pm, Tom Rini wrote:
> 
>>On Thu, Jan 22, 2004 at 09:25:19AM -0600, Hollis Blanchard wrote:
>>
>>>On Jan 22, 2004, at 9:07 AM, Tom Rini wrote:
>>>
>>>>On Wed, Jan 21, 2004 at 03:12:25PM -0800, George Anzinger wrote:
>>>>
>>>>>A question I have been meaning to ask:  Why is the arch/common
>>>>>connection
>>>>>via a structure of addresses instead of just calls?  I seems to me
>>>>>that
>>>>>just calling is a far cleaner way to do things here.  All the struct
>>>>>seems
>>>>>to offer is a way to change the backend on the fly.  I don't thing we
>>>>>ever
>>>>>want to do that.  Am I missing something?
>>>>
>>>>I imagine it's a style thing.  I don't have a preference either way.
>>>
>>>I think we in PPC land have gotten used to that "style" because we have
>>>one kernel that supports different "platforms", i.e. it selects the
>>>appropriate code at runtime as George says. In general that's a little
>>>bit slower and a little bit bigger.
>>>
>>>Unless you need to choose among PPC KGDB functions at runtime, which I
>>>don't think you do, you don't need it...
>>
>>That's certainly true, so if (and if I understand Georges question
>>right) Amit wants to change kgdb_arch into a set of required functions,
>>with stubs in, say, kernel/kgdbdummy.c, (and just keep the flags / etc
>>in the struct), that's fine with me.
> 
> 
> The penalty of keeping them consolidated in a structure isn't so high. I 
> prefer to keep them that way. I'll work on reducing number of initialization 
> functions, though.
> 
> I have to do something about early connect though. Powerpc kgdb on 8260 is 
> definitely capable of starting debugging right at architecture setup time. 
> It's just that kgdbstub.c isn't ready yet.
> 
> How about changing the code in kgdbstub to allow kgdb to be configured in one 
> of the following ways:
> Late kgdb - kgdb comes up after smp_init in the kernel boot sequence. kgdb8250 
> can be used with more flexibility through kernel command line options. One 
> can boot a kgdb kernel without activating kgdb. Works with the interface 
> chosen by kernel command line (kgdb8250 and kgdbeth for the moment).

If we get to kgdb via a command line, we should be able to have all the command 
line options.  I do recommend that we choose where we put the code, however. 
Some command line options are looked at FAR later in the boot.  The order of the 
command line option dispatch is the same as the link order.  This is why mm kgdb 
has the command line stuff in include/asm/bugs.h  (actually this file is only 
included by one .c file).  This, by the way, is way before the console starts 
spewing boot stuff (or is available) so no messages here.  Usually one would 
only do this by hand so it is real clear what is happening.

Any thing earlier than this should, IMHO, only happen if the user hard codes a 
breakpoint() (which by the way, is not the same as BREAKPOINT, which is an 
instruction, while breakpoint() is a function).  In the x86 kernel with the mm 
kgdb all that this function needs to do is to set up the trap vector for single 
steps and breakpoint instructions.  I think I also set up one or two others just 
to be safe.  This code can be redone, so no test is made to see if it has 
already been done.

I reading some of the comments here, I get the impression that some kgdbs try to 
connect when nothing is wrong and no command line request has been made to do 
so.  I think this should not be done.
> 
> Command line flexibilty is of great help if you have to test on 2-3 servers (I 
> used to do that a lot at Veritas). The same kernel can be compiled with 
> drivers needed by all of them plus kgdb. Command line options choose port no 
> and speeds depending on machine hardware connections. I guess it's of little 
> use on embedded systems where usually a new kernel has to be compiled for 
> each board.
> 
> Early kgdb - kgdb comes up right at the begining of start_kernel at the cost 
> of flexibility. It doesn't show any messages such as "waiting for gdb". All 
> configurations have to be compiled in through menuconfig. Once a kernel is 
> built, it'll always run with kgdb and with 8250 at a fixed port and speed.

But this would only be used if the user hard coded a break point.  It is useful, 
but early command line is, most of the time, good enough.  I guess the concern I 
have here is that you are saying either or and I want both from the same 
configuration.
> 
> i386 architecture will support both kgdb configuration.
> KGDB in powerpc 8260 will be of early kgdb type. Other powerpc arches (550 etc 
> will depend on whether the interface can be initialized early or later)

I would hope that there will always be something we can use.  Most cards have 
serial ports...


-- 
George Anzinger   george@mvista.com
High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml


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

* Re: PPC KGDB changes and some help?
  2004-01-22 16:45                     ` Tom Rini
@ 2004-01-22 22:46                       ` George Anzinger
  2004-01-22 22:52                         ` Tom Rini
  0 siblings, 1 reply; 35+ messages in thread
From: George Anzinger @ 2004-01-22 22:46 UTC (permalink / raw)
  To: Tom Rini
  Cc: Amit S. Kale, Hollis Blanchard, KGDB bugreports, Linux Kernel,
	Powerpc Linux

Tom Rini wrote:
> 
> 
> FWIW, this is true of KGDB on all PPCs.  IIRC, so long as the serial
> definitions are filled out statically, the stub currently in kernel.org
> for PPC can do first-line-of-C already.
> 
> 
>>How about changing the code in kgdbstub to allow kgdb to be configured in one 
>>of the following ways:
>>Late kgdb - kgdb comes up after smp_init in the kernel boot sequence. kgdb8250 
>>can be used with more flexibility through kernel command line options. One 
>>can boot a kgdb kernel without activating kgdb. Works with the interface 
>>chosen by kernel command line (kgdb8250 and kgdbeth for the moment).
> 
A further thought on this.  I think kgdb should take control on oops, panic and 
other bad news things.  This without being anthing but configured in.  Thus the 
command line options to set up the interface, etc, should not automatically 
connect to gdb.
> 
> Which is basically how it goes now, right?
> 
> 
>>Early kgdb - kgdb comes up right at the begining of start_kernel at the cost 
>>of flexibility. It doesn't show any messages such as "waiting for gdb". 

I question the utility of ever using this message.  Either the user has asked 
for the connection, either via a ^C or the command line or a breakpoint was hit. 
  If he asked, why tell him?  If it is a breakpoint, it is foolish and dangerous 
to call any outside function, such as printk.

-- 
George Anzinger   george@mvista.com
High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml


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

* Re: PPC KGDB changes and some help?
  2004-01-22 22:46                       ` George Anzinger
@ 2004-01-22 22:52                         ` Tom Rini
  2004-01-22 23:09                           ` George Anzinger
  0 siblings, 1 reply; 35+ messages in thread
From: Tom Rini @ 2004-01-22 22:52 UTC (permalink / raw)
  To: George Anzinger
  Cc: Amit S. Kale, Hollis Blanchard, KGDB bugreports, Linux Kernel,
	Powerpc Linux

On Thu, Jan 22, 2004 at 02:46:41PM -0800, George Anzinger wrote:
> Tom Rini wrote:
> >
> >
> >FWIW, this is true of KGDB on all PPCs.  IIRC, so long as the serial
> >definitions are filled out statically, the stub currently in kernel.org
> >for PPC can do first-line-of-C already.
> >
> >
> >>How about changing the code in kgdbstub to allow kgdb to be configured in 
> >>one of the following ways:
> >>Late kgdb - kgdb comes up after smp_init in the kernel boot sequence. 
> >>kgdb8250 can be used with more flexibility through kernel command line 
> >>options. One can boot a kgdb kernel without activating kgdb. Works with 
> >>the interface chosen by kernel command line (kgdb8250 and kgdbeth for the 
> >>moment).
>
> A further thought on this.  I think kgdb should take control on oops, panic 
> and other bad news things.  This without being anthing but configured in.  
> Thus the command line options to set up the interface, etc, should not 
> automatically connect to gdb.

*confused look* it doesn't do this already on i386?  I'm fairly certain
that it does on PPC, regardless of the stub (since I've got this wierd
panic happening on my testbox right now, but kgdb is kicking in..)

-- 
Tom Rini
http://gate.crashing.org/~trini/

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

* Re: PPC KGDB changes and some help?
  2004-01-22 22:52                         ` Tom Rini
@ 2004-01-22 23:09                           ` George Anzinger
  0 siblings, 0 replies; 35+ messages in thread
From: George Anzinger @ 2004-01-22 23:09 UTC (permalink / raw)
  To: Tom Rini
  Cc: Amit S. Kale, Hollis Blanchard, KGDB bugreports, Linux Kernel,
	Powerpc Linux

Tom Rini wrote:
> On Thu, Jan 22, 2004 at 02:46:41PM -0800, George Anzinger wrote:
> 
>>Tom Rini wrote:
>>
>>>
>>>FWIW, this is true of KGDB on all PPCs.  IIRC, so long as the serial
>>>definitions are filled out statically, the stub currently in kernel.org
>>>for PPC can do first-line-of-C already.
>>>
>>>
>>>
>>>>How about changing the code in kgdbstub to allow kgdb to be configured in 
>>>>one of the following ways:
>>>>Late kgdb - kgdb comes up after smp_init in the kernel boot sequence. 
>>>>kgdb8250 can be used with more flexibility through kernel command line 
>>>>options. One can boot a kgdb kernel without activating kgdb. Works with 
>>>>the interface chosen by kernel command line (kgdb8250 and kgdbeth for the 
>>>>moment).
>>
>>A further thought on this.  I think kgdb should take control on oops, panic 
>>and other bad news things.  This without being anthing but configured in.  
>>Thus the command line options to set up the interface, etc, should not 
>>automatically connect to gdb.
> 
> 
> *confused look* it doesn't do this already on i386?  I'm fairly certain
> that it does on PPC, regardless of the stub (since I've got this wierd
> panic happening on my testbox right now, but kgdb is kicking in..)
> 
Oh, I think it does, but I have seen code that I thought (possibly incorrectly) 
tried to connect to gdb as part of configuring the interface.  This is what I 
don't want to see.

-- 
George Anzinger   george@mvista.com
High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml


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

* Re: PPC KGDB changes and some help?
  2004-01-22 16:06                   ` Amit S. Kale
  2004-01-22 16:45                     ` Tom Rini
  2004-01-22 22:35                     ` George Anzinger
@ 2004-01-23 17:08                     ` Tom Rini
  2 siblings, 0 replies; 35+ messages in thread
From: Tom Rini @ 2004-01-23 17:08 UTC (permalink / raw)
  To: Amit S. Kale
  Cc: Hollis Blanchard, KGDB bugreports, Linux Kernel, George Anzinger,
	Powerpc Linux

On Thu, Jan 22, 2004 at 09:36:10PM +0530, Amit S. Kale wrote:

> On Thursday 22 Jan 2004 9:15 pm, Tom Rini wrote:
> > On Thu, Jan 22, 2004 at 09:25:19AM -0600, Hollis Blanchard wrote:
> > > On Jan 22, 2004, at 9:07 AM, Tom Rini wrote:
> > > >On Wed, Jan 21, 2004 at 03:12:25PM -0800, George Anzinger wrote:
> > > >>A question I have been meaning to ask:  Why is the arch/common
> > > >>connection
> > > >>via a structure of addresses instead of just calls?  I seems to me
> > > >>that
> > > >>just calling is a far cleaner way to do things here.  All the struct
> > > >>seems
> > > >>to offer is a way to change the backend on the fly.  I don't thing we
> > > >>ever
> > > >>want to do that.  Am I missing something?
> > > >
> > > >I imagine it's a style thing.  I don't have a preference either way.
> > >
> > > I think we in PPC land have gotten used to that "style" because we have
> > > one kernel that supports different "platforms", i.e. it selects the
> > > appropriate code at runtime as George says. In general that's a little
> > > bit slower and a little bit bigger.
> > >
> > > Unless you need to choose among PPC KGDB functions at runtime, which I
> > > don't think you do, you don't need it...
> >
> > That's certainly true, so if (and if I understand Georges question
> > right) Amit wants to change kgdb_arch into a set of required functions,
> > with stubs in, say, kernel/kgdbdummy.c, (and just keep the flags / etc
> > in the struct), that's fine with me.
> 
> The penalty of keeping them consolidated in a structure isn't so high. I 
> prefer to keep them that way. I'll work on reducing number of initialization 
> functions, though.

Ok.  After talking with George off-list, I think most of ppc_kgdb_init
can go.  The only remaining part is the serial plugin, which could be
done ala the kgdb_8250 driver.  But I've got a different idea:

 arch/ppc/kernel/ppc-stub.c |    3 +--
 drivers/serial/kgdb_8250.c |    4 +---
 kernel/kgdbstub.c          |    2 +-
 3 files changed, 3 insertions(+), 6 deletions(-)
--- kernel/kgdbstub.c	2004-01-23 10:03:48.000000000 -0700
+++ kernel/kgdbstub.c	2004-01-23 10:06:19.000000000 -0700
@@ -61,7 +61,7 @@
 gdb_breakpoint_t kgdb_break[MAX_BREAKPOINTS];
 extern int pid_max;
 
-struct kgdb_serial *kgdb_serial;
+struct kgdb_serial *kgdb_serial = &kgdb_serial_driver;
 
 int kgdb_initialized = 0;
 int kgdb_enter = 0;
--- drivers/serial/kgdb_8250.c	2004-01-23 10:04:57.000000000 -0700
+++ drivers/serial/kgdb_8250.c	2004-01-23 09:57:26.000000000 -0700
@@ -370,7 +370,7 @@
 	rs_table[i].regshift = serial_req->regshift;
 }
 
-struct kgdb_serial kgdb8250_serial = {
+struct kgdb_serial kgdb_serial_driver = {
 	.read_char = kgdb8250_read_char,
 	.write_char = kgdb8250_write_char,
 	.hook = kgdb8250_hook
@@ -396,8 +396,6 @@
 	    kgdb8250_baud != 115200)
 		goto errout;
 
-	kgdb_serial = &kgdb8250_serial;
-
 	return 1;
 
 errout:
--- arch/ppc/kernel/ppc-stub.c	2004-01-23 10:04:46.000000000 -0700
+++ arch/ppc/kernel/ppc-stub.c	2004-01-23 09:57:47.000000000 -0700
@@ -264,7 +264,7 @@
 	return 0;
 }
 
-struct kgdb_serial kgdbppc_serial = {
+struct kgdb_serial kgdb_serial_driver = {
 	.read_char = kgdbppc_read_char,
 	.write_char = kgdbppc_write_char,
 	.hook = kgdbppc_hook
@@ -272,5 +272,4 @@
 
 void kgdbppc_init(void)
 {
-	kgdb_serial = &kgdbppc_serial;
 }

This does mean that we can only have one serial driver per kernel, but I
don't see this as a problem.  This also means that i386 would need
something like PPC's CONFIG_KGDB_TTYSx to pick something other than
ttyS0/115200 to use kgdb on, this early.  But, IMHO, that's a small
price to pay.

-- 
Tom Rini
http://gate.crashing.org/~trini/

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

* Re: PPC KGDB changes and some help?
  2004-01-22 18:05               ` Tom Rini
@ 2004-01-23 22:46                 ` Tom Rini
  2004-01-23 23:38                   ` George Anzinger
                                     ` (3 more replies)
  0 siblings, 4 replies; 35+ messages in thread
From: Tom Rini @ 2004-01-23 22:46 UTC (permalink / raw)
  To: Amit S. Kale
  Cc: Powerpc Linux, Linux Kernel, KGDB bugreports, George Anzinger

On Thu, Jan 22, 2004 at 11:05:55AM -0700, Tom Rini wrote:
[snip]
> First up:
> We need to call flush_instruction_cache() on a 'c' or 's' command.
>  arch/ppc/kernel/ppc-stub.c |   19 ++++++-------------
>  1 files changed, 6 insertions(+), 13 deletions(-)

On tpo of this patch, there's the following:
Put back some code to figure out what signal we're dealing with.

 arch/ppc/kernel/ppc-stub.c |   63 ++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 60 insertions(+), 3 deletions(-)
--- 1.15/arch/ppc/kernel/ppc-stub.c	Thu Jan 22 10:53:06 2004
+++ edited/arch/ppc/kernel/ppc-stub.c	Fri Jan 23 15:43:10 2004
@@ -3,6 +3,7 @@
  *
  * PowerPC-specific bits to work with the common KGDB stub.
  *
+ * 1998 (c) Michael AK Tesch (tesch@cs.wisc.edu)
  * 2003 (c) TimeSys Corporation
  * 2004 (c) MontaVista Software, Inc.
  * This file is licensed under the terms of the GNU General Public License
@@ -19,13 +20,69 @@
 #include <asm/processor.h>
 #include <asm/machdep.h>
 
+/* Convert the hardware trap type code to a unix signal number. */
+/*
+ * This table contains the mapping between PowerPC hardware trap types, and
+ * signals, which are primarily what GDB understands.
+ */
+static struct hard_trap_info
+{
+	unsigned int tt;		/* Trap type code for powerpc */
+	unsigned char signo;		/* Signal that we map this trap into */
+} hard_trap_info[] = {
+#if defined(CONFIG_40x)
+	{ 0x100, SIGINT  },		/* critical input interrupt */
+	{ 0x200, SIGSEGV },		/* machine check */
+	{ 0x300, SIGSEGV },		/* data storage */
+	{ 0x400, SIGBUS  },		/* instruction storage */
+	{ 0x500, SIGINT  },		/* interrupt */
+	{ 0x600, SIGBUS  },		/* alignment */
+	{ 0x700, SIGILL  },		/* program */
+	{ 0x800, SIGILL  },		/* reserved */
+	{ 0x900, SIGILL  },		/* reserved */
+	{ 0xa00, SIGILL  },		/* reserved */
+	{ 0xb00, SIGILL  },		/* reserved */
+	{ 0xc00, SIGCHLD },		/* syscall */
+	{ 0xd00, SIGILL  },		/* reserved */
+	{ 0xe00, SIGILL  },		/* reserved */
+	{ 0xf00, SIGILL  },		/* reserved */
+	{ 0x2000, SIGTRAP},		/* debug */
+#else
+	{ 0x200, SIGSEGV },		/* machine check */
+	{ 0x300, SIGSEGV },		/* address error (store) */
+	{ 0x400, SIGBUS },		/* instruction bus error */
+	{ 0x500, SIGINT },		/* interrupt */
+	{ 0x600, SIGBUS },		/* alingment */
+	{ 0x700, SIGTRAP },		/* breakpoint trap */
+	{ 0x800, SIGFPE },		/* fpu unavail */
+	{ 0x900, SIGALRM },		/* decrementer */
+	{ 0xa00, SIGILL },		/* reserved */
+	{ 0xb00, SIGILL },		/* reserved */
+	{ 0xc00, SIGCHLD },		/* syscall */
+	{ 0xd00, SIGTRAP },		/* single-step/watch */
+	{ 0xe00, SIGFPE },		/* fp assist */
+#endif
+	{ 0, 0}				/* Must be last */
+};
+
+static int computeSignal(unsigned int tt)
+{
+	struct hard_trap_info *ht;
+
+	for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
+		if (ht->tt == tt)
+			return ht->signo;
+
+	return SIGHUP; /* default for things we don't know about */
+}
+
 /*
  * Routines
  */
 static void
 kgdb_debugger(struct pt_regs *regs)
 {
-	(*linux_debug_hook) (0, 0, 0, regs);
+	(*linux_debug_hook) (0, computeSignal(regs->trap), 0, regs);
 	return;
 }
 
@@ -52,14 +109,14 @@
 int
 kgdb_iabr_match(struct pt_regs *regs)
 {
-	(*linux_debug_hook) (0, 0, 0, regs);
+	(*linux_debug_hook) (0, computeSignal(regs->trap), 0, regs);
 	return 1;
 }
 
 int
 kgdb_dabr_match(struct pt_regs *regs)
 {
-	(*linux_debug_hook) (0, 0, 0, regs);
+	(*linux_debug_hook) (0, computeSignal(regs->trap), 0, regs);
 	return 1;
 }
 

Now, not being as well versed in all of the debugging infos that can be
passed around, it sounds like this patch could be dropped in the future
for a cleaner method using some of the dwarf2 bits being talked about.
But I don't know, and clarification and pointers (if so) to how to do
this would be appreciated.

-- 
Tom Rini
http://gate.crashing.org/~trini/

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

* Re: PPC KGDB changes and some help?
  2004-01-23 22:46                 ` Tom Rini
@ 2004-01-23 23:38                   ` George Anzinger
  2004-01-26 20:46                     ` Tom Rini
  2004-01-24  0:48                   ` George Anzinger
                                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 35+ messages in thread
From: George Anzinger @ 2004-01-23 23:38 UTC (permalink / raw)
  To: Tom Rini; +Cc: Amit S. Kale, Powerpc Linux, Linux Kernel, KGDB bugreports

Tom Rini wrote:
> On Thu, Jan 22, 2004 at 11:05:55AM -0700, Tom Rini wrote:
> [snip]
> 
>>First up:
>>We need to call flush_instruction_cache() on a 'c' or 's' command.
>> arch/ppc/kernel/ppc-stub.c |   19 ++++++-------------
>> 1 files changed, 6 insertions(+), 13 deletions(-)
> 
> 
> On tpo of this patch, there's the following:
> Put back some code to figure out what signal we're dealing with.
> 
>  arch/ppc/kernel/ppc-stub.c |   63 ++++++++++++++++++++++++++++++++++++++++++---
>  1 files changed, 60 insertions(+), 3 deletions(-)
> --- 1.15/arch/ppc/kernel/ppc-stub.c	Thu Jan 22 10:53:06 2004
> +++ edited/arch/ppc/kernel/ppc-stub.c	Fri Jan 23 15:43:10 2004
> @@ -3,6 +3,7 @@
>   *
>   * PowerPC-specific bits to work with the common KGDB stub.
>   *
> + * 1998 (c) Michael AK Tesch (tesch@cs.wisc.edu)
>   * 2003 (c) TimeSys Corporation
>   * 2004 (c) MontaVista Software, Inc.
>   * This file is licensed under the terms of the GNU General Public License
> @@ -19,13 +20,69 @@
>  #include <asm/processor.h>
>  #include <asm/machdep.h>
>  
> +/* Convert the hardware trap type code to a unix signal number. */
> +/*
> + * This table contains the mapping between PowerPC hardware trap types, and
> + * signals, which are primarily what GDB understands.
> + */
> +static struct hard_trap_info
> +{
> +	unsigned int tt;		/* Trap type code for powerpc */
> +	unsigned char signo;		/* Signal that we map this trap into */
> +} hard_trap_info[] = {
> +#if defined(CONFIG_40x)
> +	{ 0x100, SIGINT  },		/* critical input interrupt */
> +	{ 0x200, SIGSEGV },		/* machine check */
> +	{ 0x300, SIGSEGV },		/* data storage */
> +	{ 0x400, SIGBUS  },		/* instruction storage */
> +	{ 0x500, SIGINT  },		/* interrupt */
> +	{ 0x600, SIGBUS  },		/* alignment */
> +	{ 0x700, SIGILL  },		/* program */
> +	{ 0x800, SIGILL  },		/* reserved */
> +	{ 0x900, SIGILL  },		/* reserved */
> +	{ 0xa00, SIGILL  },		/* reserved */
> +	{ 0xb00, SIGILL  },		/* reserved */
> +	{ 0xc00, SIGCHLD },		/* syscall */
> +	{ 0xd00, SIGILL  },		/* reserved */
> +	{ 0xe00, SIGILL  },		/* reserved */
> +	{ 0xf00, SIGILL  },		/* reserved */
> +	{ 0x2000, SIGTRAP},		/* debug */
> +#else
> +	{ 0x200, SIGSEGV },		/* machine check */
> +	{ 0x300, SIGSEGV },		/* address error (store) */
> +	{ 0x400, SIGBUS },		/* instruction bus error */
> +	{ 0x500, SIGINT },		/* interrupt */
> +	{ 0x600, SIGBUS },		/* alingment */
> +	{ 0x700, SIGTRAP },		/* breakpoint trap */
> +	{ 0x800, SIGFPE },		/* fpu unavail */
> +	{ 0x900, SIGALRM },		/* decrementer */
> +	{ 0xa00, SIGILL },		/* reserved */
> +	{ 0xb00, SIGILL },		/* reserved */
> +	{ 0xc00, SIGCHLD },		/* syscall */
> +	{ 0xd00, SIGTRAP },		/* single-step/watch */
> +	{ 0xe00, SIGFPE },		/* fp assist */
> +#endif
> +	{ 0, 0}				/* Must be last */
> +};
> +
> +static int computeSignal(unsigned int tt)
> +{
> +	struct hard_trap_info *ht;
> +
> +	for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
> +		if (ht->tt == tt)
> +			return ht->signo;
> +
> +	return SIGHUP; /* default for things we don't know about */
> +}
> +
>  /*
>   * Routines
>   */
>  static void
>  kgdb_debugger(struct pt_regs *regs)
>  {
> -	(*linux_debug_hook) (0, 0, 0, regs);
> +	(*linux_debug_hook) (0, computeSignal(regs->trap), 0, regs);
>  	return;
>  }
>  
> @@ -52,14 +109,14 @@
>  int
>  kgdb_iabr_match(struct pt_regs *regs)
>  {
> -	(*linux_debug_hook) (0, 0, 0, regs);
> +	(*linux_debug_hook) (0, computeSignal(regs->trap), 0, regs);
>  	return 1;
>  }
>  
>  int
>  kgdb_dabr_match(struct pt_regs *regs)
>  {
> -	(*linux_debug_hook) (0, 0, 0, regs);
> +	(*linux_debug_hook) (0, computeSignal(regs->trap), 0, regs);
>  	return 1;
>  }
>  
> 
> Now, not being as well versed in all of the debugging infos that can be
> passed around, it sounds like this patch could be dropped in the future
> for a cleaner method using some of the dwarf2 bits being talked about.
> But I don't know, and clarification and pointers (if so) to how to do
> this would be appreciated.

I am not sure what this buys you.  I don't think dwarf2 will help here.

There is a real danger of passing signal info back to gdb as it will want to try 
to deliver the signal which is a non-compute in most kgdbs in the field.  I did 
put code in the mm-kgdb to do just this, but usually the arrival of such a 
signal (other than SIGTRAP) is the end of the kernel.  All that is left is to 
read the tea leaves.

On occasion, because there are traps in a lot of places, one gets to kgdb and 
wants to know just how it happened.  The way I like to do this is with the "l" 
command on the call to the kgdb handler.  In the above case, it would be on the 
return address of the appropiate one of the three functions.  To make this 
information available I defined a global structure (kdgd_info) which the stub 
updates on entry.  From this point of view and looking at the above code, I 
wonder a) why you need three functions, and b) why not just use what ever 
linux_debug_hook points to and let it do the signal decoding.

-- 
George Anzinger   george@mvista.com
High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml


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

* Re: PPC KGDB changes and some help?
  2004-01-23 22:46                 ` Tom Rini
  2004-01-23 23:38                   ` George Anzinger
@ 2004-01-24  0:48                   ` George Anzinger
  2004-01-24  3:47                   ` [PATCH] Kgdb dwarf2 for asm George Anzinger
  2004-01-27 18:22                   ` PPC KGDB changes and some help? Tom Rini
  3 siblings, 0 replies; 35+ messages in thread
From: George Anzinger @ 2004-01-24  0:48 UTC (permalink / raw)
  To: Tom Rini
  Cc: Amit S. Kale, Powerpc Linux, Linux Kernel, KGDB bugreports,
	Andrew Morton, Daniel Jacobowitz

[-- Attachment #1: Type: text/plain, Size: 2104 bytes --]

Here is the dwarf2 patch.  It assumes that mm-kgdb is already there, but there 
are really very few dependencies.  With little effort it should work with Amit's 
version.

What it does:

This patch allows back trace and "up" commands to go smoothly back to the root 
of the stack through interrupt frames, trap frames, you name it.  It also tells 
the asm compile engine to save the temp source as this is what gas builds debug 
records for.  (This is not needed to get the back trace, its just "nice".)

I removed the debug info overlap in kconfig.  Kgdb sets -gdwarf2 while that set 
-g.  Not nice to have both.

There is only one code change and that is to push a "1" on the stack so that it 
looks like the return address for idle tasks other than the cpu 0 idle task. 
This is done so that a "bt" on that task will not go on forever (I had a screen 
with 1000+ levels on it...).

What it is:

The dwarf2.h file from the binutils tree is here as it is there.  There is an 
awk script to build dwarf2-defs.h which is nothing but all the constants, from 
that file, in a form that asm AND c understand.  The script works for this file, 
for other files you are on your own.  This translation is forced in the main 
make file, I suppose this could be done more cleanly, but... I just did not want 
to figure out the make maze.

The dwarf2-lang.h file is a set of macros that make writing dwarf2 half way 
enjoyable and much more understandable.

All most all of the dwaft2 code is at the end of entry.S but for 2 lines in head.S.

Daniel keeps telling me that this should be done in asm, and I suppose one could 
do it there, but it does not support the expression code as yet and that is 
where most of the magic is.

Oh and by the way, you do need call frames (CONFIG option) as without them gdb 
will most likely get lost in the switch code in schedule().  This comes up in 
the "info thread' command so it is not uncommon.

-- 
George Anzinger   george@mvista.com
High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml

[-- Attachment #2: kgdb-dwarf2-2.6.0-1.0.patch --]
[-- Type: text/plain, Size: 39879 bytes --]

diff -urP -I '\$Id:.*Exp \$' -X /usr/src/patch.exclude linux-2.6.0-akgdb/Makefile linux/Makefile
--- linux-2.6.0-akgdb/Makefile	2004-01-08 15:36:35.000000000 -0800
+++ linux/Makefile	2004-01-22 13:01:31.000000000 -0800
@@ -1025,5 +1025,7 @@
 descend =$(Q)$(MAKE) -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj=$(1) $(2)
 
 endif	# skip-makefile
+include/linux/dwarf2-defs.h: include/linux/dwarf2.h scripts/dwarfh.awk
+	awk -f scripts/dwarfh.awk include/linux/dwarf2.h > include/linux/dwarf2-defs.h
 
-FORCE:
+FORCE: include/linux/dwarf2-defs.h
Binary files linux-2.6.0-akgdb/a.out and linux/a.out differ
diff -urP -I '\$Id:.*Exp \$' -X /usr/src/patch.exclude linux-2.6.0-akgdb/arch/i386/Kconfig linux/arch/i386/Kconfig
--- linux-2.6.0-akgdb/arch/i386/Kconfig	2004-01-08 15:39:58.000000000 -0800
+++ linux/arch/i386/Kconfig	2004-01-09 14:50:07.000000000 -0800
@@ -1196,7 +1196,7 @@
 
 config DEBUG_INFO
 	bool "Compile the kernel with debug info"
-	depends on DEBUG_KERNEL
+	depends on DEBUG_KERNEL && !KGDB
 	help
           If you say Y here the resulting kernel image will include
 	  debugging info resulting in a larger kernel image.
@@ -1227,7 +1227,7 @@
 	  will then break as soon as it looks at the boot options.  This
 	  option also installs a breakpoint in panic and sends any
 	  kernel faults to the debugger. For more information see the
-	  Documentation/i386/kgdb.txt file.
+	  Documentation/i386/kgdb/kgdb.txt file.
 
 choice
 	depends on KGDB
diff -urP -I '\$Id:.*Exp \$' -X /usr/src/patch.exclude linux-2.6.0-akgdb/arch/i386/Makefile linux/arch/i386/Makefile
--- linux-2.6.0-akgdb/arch/i386/Makefile	2004-01-08 15:39:58.000000000 -0800
+++ linux/arch/i386/Makefile	2004-01-13 16:04:02.000000000 -0800
@@ -100,7 +100,9 @@
 drivers-$(CONFIG_PM)			+= arch/i386/power/
 
 CFLAGS += $(mflags-y)
-AFLAGS += $(mflags-y)
+aflags-y = $(mflags-y)
+aflags-$(CONFIG_KGDB) += -save-temps
+AFLAGS += $(aflags-y)
 
 boot := arch/i386/boot
 
diff -urP -I '\$Id:.*Exp \$' -X /usr/src/patch.exclude linux-2.6.0-akgdb/arch/i386/kernel/entry.S linux/arch/i386/kernel/entry.S
--- linux-2.6.0-akgdb/arch/i386/kernel/entry.S	2004-01-13 15:53:06.000000000 -0800
+++ linux/arch/i386/kernel/entry.S	2004-01-23 16:03:00.000000000 -0800
@@ -910,3 +910,116 @@
 	.long sys_ni_syscall	/* sys_vserver */
 
 syscall_table_size=(.-sys_call_table)
+
+#	Here we do call frames.  We cheat a bit as we only really need
+#	correct frames at locations we can actually look at from a
+#	debugger.  Since the break instruction trap actually goes thru
+#	some of this code, we don't really need info on those areas, but
+#	only after the fact.  I.e. if we can not step or break in a
+#	location or end up with a return address pointing at the
+#	location, we don't need a correct call frame for it.
+
+#ifdef CONFIG_KGDB
+
+#include <linux/dwarf2-lang.h>
+/*
+ * The register numbers as known by gdb
+ */
+cfa_one: .long 1
+	
+#define _EAX 0
+#define _ECX 1
+#define _EDX 2
+#define _EBX 3
+#define _ESP 4
+#define _EBP 5
+#define _ESI 6
+#define _EDI 7
+#define _PC  8 
+#define _EIP 8 
+#define _PS  9
+#define _EFLAGS  9
+#define _CS 10
+#define _SS 11
+#define _DS 12
+#define _ES 13
+#define _FS 14
+#define _GS 15
+
+	CFI_preamble(c1,_PC,1,1)
+	CFA_def_cfa_expression
+	   CFA_exp_OP_breg(_ESP,OLDESP)		/* push the stack & adjust */
+	   CFA_exp_OP_dup			/* save that */
+ 	   CFA_exp_OP_consts(-8)		/* offset to CS address */
+ 	   CFA_exp_OP_plus			/* should be CS address */
+	   CFA_exp_OP_deref			/* get the CS */
+	   CFA_exp_OP_const4s(VM_MASK|3)	/* prepare to mask it */
+	   CFA_exp_OP_and			/* mask it, zero means kernel */
+	   CFA_exp_OP_bra(cfa_user_rtn)		/* branch if user  (TOS--) */
+	   CFA_exp_OP_skip(cfa_end)		/* done if kernel, skip out */
+cfa_user_rtn:	
+	   CFA_exp_OP_constu(0)			/* user space, set exp to 0 */
+cfa_end:	
+	   CFA_expression_end
+	CFA_expression(_EIP)
+	   CFA_exp_OP_dup			/* copy old esp */
+	   CFA_exp_OP_bra(eip_kernel_rtn)	/* non-zero means kernel */
+	   CFA_exp_OP_addr(cfa_one)		/* for user, pass 1 */
+	   CFA_exp_OP_skip(eip_end)		/* done if kernel, skip out */
+eip_kernel_rtn:	
+	   CFA_exp_OP_const4s(EIP-OLDESP)	/* offset to return address */
+	   CFA_exp_OP_plus
+eip_end:	
+	   CFA_expression_end
+	CFA_define_offset(_EBX,EBX-OLDESP)	
+	CFA_define_offset(_ECX,ECX-OLDESP)	
+	CFA_define_offset(_EDX,EDX-OLDESP)	
+	CFA_define_offset(_ESI,ESI-OLDESP)	
+	CFA_define_offset(_EDI,EDI-OLDESP)	
+	CFA_define_offset(_EBP,EBP-OLDESP)	
+	CFA_define_offset(_EAX,EAX-OLDESP)	
+	CFA_define_offset(_EFLAGS,EFLAGS-OLDESP)	
+	CFI_postamble()
+	
+/*
+ * This is an attempt to provide an unwind for location 0 which is 
+ * identical to the prior frame.  Should stop the unwind.  Note that gdb
+ * uses the pc-1 to look for FDEs so the correct pc is 1 not 0 which,
+ * because of addresses being unsigned, can not be used by man nor beast.
+ */				
+	CFI_preamble(c2,_PC,1,1)
+	CFA_def_cfa_expression
+	   CFA_exp_OP_constu(0)			/* stack end, set exp to 0 */
+	   CFA_expression_end
+	CFI_postamble()
+	
+	FDE_preamble(c2,0,10)
+	FDE_postamble()
+	/*
+         * This is VERY sloppy.  At this point all we want to do is get
+         * the frame right for back tracing.  It will not be good if
+         * you try to single step.  We use already defined labels.
+         * We want to cover all call outs.
+         * We could also recode this as just one FDE, but this works and
+         * I want to get it out.
+	 */
+	FDE_preamble(c1,do_lcall,(ret_from_fork - do_lcall))
+	CFA_define_cfa_offset(OLDESP+8)
+	FDE_postamble()	
+	FDE_preamble(c1,ret_from_fork,(ret_from_exception - ret_from_fork))
+	CFA_define_cfa_offset(OLDESP+4)
+	FDE_postamble()	
+	FDE_preamble(c1,ret_from_exception,(divide_error - ret_from_exception))
+	FDE_postamble()	
+	FDE_preamble(c1,error_code,(device_not_available_emulate - error_code))
+	CFA_define_cfa_offset(OLDESP+8)
+	FDE_postamble()	
+	FDE_preamble(c1,device_not_available_emulate,(debug - device_not_available_emulate))
+	CFA_define_cfa_offset(OLDESP+4)
+	FDE_postamble()	
+	FDE_preamble(c1,nmi,(int3 - nmi))
+	CFA_define_cfa_offset(OLDESP+8)
+	FDE_postamble()
+
+# 
+#endif
diff -urP -I '\$Id:.*Exp \$' -X /usr/src/patch.exclude linux-2.6.0-akgdb/arch/i386/kernel/head.S linux/arch/i386/kernel/head.S
--- linux-2.6.0-akgdb/arch/i386/kernel/head.S	2003-09-08 14:15:17.000000000 -0700
+++ linux/arch/i386/kernel/head.S	2004-01-23 16:19:21.000000000 -0800
@@ -278,6 +278,16 @@
 				# just in case, we know what happens.
 
 ready:	.byte 0
+#ifdef CONFIG_KGDB
+#include <linux/dwarf2-lang.h>
+
+	/* This dwarf code tells gdb that this is the end of the unwind */
+	/* This uses the CFA set up for pc=1 located in entry.S */
+	
+	FDE_preamble(c2,is386,(L6-is386))
+	FDE_postamble()
+
+#endif
 
 /*
  * We depend on ET to be correct. This checks for 287/387.
diff -urP -I '\$Id:.*Exp \$' -X /usr/src/patch.exclude linux-2.6.0-akgdb/arch/i386/kernel/smpboot.c linux/arch/i386/kernel/smpboot.c
--- linux-2.6.0-akgdb/arch/i386/kernel/smpboot.c	2003-11-10 15:59:40.000000000 -0800
+++ linux/arch/i386/kernel/smpboot.c	2004-01-18 00:33:32.000000000 -0800
@@ -476,6 +476,9 @@
 
 	asm volatile(
 		"movl %0,%%esp\n\t"
+#ifdef CONFIG_KGDB
+		"pushl $1\n\t"
+#endif
 		"jmp *%1"
 		:
 		:"r" (current->thread.esp),"r" (current->thread.eip));
diff -urP -I '\$Id:.*Exp \$' -X /usr/src/patch.exclude linux-2.6.0-akgdb/include/linux/dwarf2-lang.h linux/include/linux/dwarf2-lang.h
--- linux-2.6.0-akgdb/include/linux/dwarf2-lang.h	1969-12-31 16:00:00.000000000 -0800
+++ linux/include/linux/dwarf2-lang.h	2004-01-22 13:06:43.000000000 -0800
@@ -0,0 +1,286 @@
+#ifndef DWARF2_LANG
+#define DWARF2_LANG
+
+/*
+ * This is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2, or (at your option) any later
+ * version.
+ */
+/*
+ * This file defines macros that allow generation of DWARF debug records
+ * for asm files.  This file is platform independent.  Register numbers
+ * (which are about the only thing that is platform dependent) are to be
+ * supplied by a platform defined file.
+ */
+/*
+ * We need this to work for both asm and C.  In asm we are using the 
+ * old comment trick to concatenate while C uses the new ANSI thing.
+ * Here we have concat macro...  The multi level thing is to allow and
+ * macros used in the names to be resolved prior to the cat (at which
+ * time they are no longer the same string).
+ */
+#define CAT3(a,b,c) _CAT3(a,b,c)
+#define _CAT3(a,b,c) __CAT3(a,b,c)
+#ifdef __ASSEMBLY__
+#define __CAT3(a,b,c) a/**/b/**/c
+#define IFC(a)
+#define IFN_C(a) a
+#define NL ;
+#define QUOTE_THIS(a) a 
+#define DWARF_preamble .section .debug_frame,"",@progbits;
+#else
+#define __CAT3(a,b,c) a ## b ## c
+#define IFC(a) a 
+#define IFN_C(a)
+#define NL \n\t
+#define QUOTE_THIS(a) _QUOTE_THIS(a)
+#define _QUOTE_THIS(a) #a
+/* Don't let CPP see the " and , \042=" \054=, */
+#define DWARF_preamble .section .debug_frame \054\042\042\054@progbits
+
+#endif
+#include <linux/dwarf2-defs.h>
+/*
+ * This macro starts a debug frame section.  The debug_frame describes
+ * where to find the registers that the enclosing function saved on
+ * entry.
+ *
+ * ORD is use by the label generator and should be the same as what is
+ * passed to CFI_postamble.
+ *
+ * pc,	pc register gdb ordinal.
+ *
+ * code_align this is the factor used to define locations or regions
+ * where the given definitions apply.  If you use labels to define these
+ * this should be 1.
+ *
+ * data_align this is the factor used to define register offsets.  If
+ * you use struct offset, this should be the size of the register in
+ * bytes or the negative of that.  This is how it is used: you will
+ * define a register as the reference register, say the stack pointer,
+ * then you will say where a register is located relative to this
+ * reference registers value, say 40 for register 3 (the gdb register
+ * number).  The <40> will be multiplied by <data_align> to define the
+ * byte offset of the given register (3, in this example).  So if your
+ * <40> is the byte offset and the reference register points at the
+ * begining, you would want 1 for the data_offset.  If <40> was the 40th
+ * 4-byte element in that structure you would want 4.  And if your
+ * reference register points at the end of the structure you would want
+ * a negative data_align value(and you would have to do other math as
+ * well).
+ */
+
+#define CFI_preamble(ORD, pc, code_align, data_align)	\
+         DWARF_preamble	NL				\
+	.align 4 NL					\
+        .globl CAT3(frame,_,ORD) NL			\
+CAT3(frame,_,ORD): NL					\
+	.long 7f-6f NL					\
+6:							\
+	.long	DW_CIE_ID NL				\
+	.byte	DW_CIE_VERSION NL			\
+	.byte 0	 NL					\
+	.uleb128 code_align NL				\
+	.sleb128 data_align NL				\
+	.byte pc NL
+
+/*
+ * After the above macro and prior to the CFI_postamble, you need to
+ * define the initial state.  This starts with defining the reference
+ * register and, usually the pc.  Here are some helper macros:
+ */
+
+#define CFA_define_reference(reg, offset)	\
+	.byte DW_CFA_def_cfa NL			\
+	.uleb128 reg NL				\
+	.uleb128 (offset) NL
+
+#define CFA_define_offset(reg, offset)		\
+	.byte (DW_CFA_offset + reg) NL		\
+	.uleb128 (offset) NL
+
+#define CFA_restore(reg)			\
+        .byte (DW_CFA_restore + reg) NL
+
+#define CFI_postamble()				\
+	.align 4 NL				\
+7: NL						\
+.previous NL
+/*
+ * So now your code pushs stuff on the stack, you need a new location
+ * and the rules for what to do.  This starts a running description of
+ * the call frame.  You need to describe what changes with respect to
+ * the call registers as the location of the pc moves through the code.
+ * The following builds an FDE (fram descriptor entry?).  Like the
+ * above, it has a preamble and a postamble.  It also is tied to the CFI
+ * above.
+ * The preamble macro is tied to the CFI thru the first parameter.  The 
+ * second is the code start address and then the code length.
+ */
+//         DWARF_preamble() NL				
+#define FDE_preamble(ORD, initial_address, length)	\
+        DWARF_preamble NL				\
+	.align 4 NL					\
+	.long 9f-8f NL					\
+8:							\
+	.long CAT3(frame,_,ORD) NL			\
+	.long initial_address NL			\
+	.long length NL
+
+#define FDE_postamble()				\
+	.align 4 NL				\
+9:	 NL					\
+.previous NL
+/*
+ * That done, you can now add registers, subtract registers, move the
+ * reference and even change the reference.  You can also define a new
+ * area of code the info applies to.  For discontinuous bits you should
+ * start a new FDE.  You may have as many as you like.
+ */
+
+/*
+ * To advance the stack address by <bytes> (0x3f max)
+ */
+
+#define CFA_advance_loc(bytes)			\
+	.byte DW_CFA_advance_loc+bytes NL
+
+/*
+ * This one is good for 0xff or 255
+ */
+#define CFA_advance_loc1(bytes)			\
+	.byte DW_CFA_advance_loc1 NL		\
+        .byte bytes NL
+
+
+/*
+ * With the above you can define all the register locations.  But
+ * suppose the reference register moves... Takes the new offset NOT an
+ * increment.  This is how esp is tracked if it is not saved.
+ */
+
+#define CFA_define_cfa_offset(offset)		\
+	.byte DW_CFA_def_cfa_offset NL		\
+	.uleb128 (offset) NL
+/*
+ * Or suppose you want to use a different reference register...
+ */
+#define CFA_define_cfa_register(reg)		\
+	.byte DW_CFA_def_cfa_register NL	\
+	.uleb128 reg NL
+
+/*
+ * If you want to mess with the stack pointer, here is the expression.
+ * The stack starts empty.
+ */
+#define CFA_def_cfa_expression 			\
+        .byte DW_CFA_def_cfa_expression	NL	\
+	.uleb128 20f-10f NL			\
+10:     NL
+/*
+ * This expression is to be used for other regs.  The stack starts with the
+ * stack address.
+ */
+
+#define CFA_expression(reg)			\
+        .byte DW_CFA_expression	 NL		\
+        .uleb128 reg NL				\
+	.uleb128 20f-10f NL			\
+10:     NL
+/*
+ * Here we do the expression stuff.  You should code the above followed
+ *  by expression OPs followed by CFA_expression_end.
+ */
+
+
+#define CFA_expression_end			\
+20:	 NL
+
+#define CFA_exp_OP_const4s(a)			\
+        .byte DW_OP_const4s NL			\
+        .long a NL
+
+#define  CFA_exp_OP_swap  .byte DW_OP_swap NL
+#define  CFA_exp_OP_dup  .byte DW_OP_dup NL
+#define  CFA_exp_OP_drop  .byte DW_OP_drop NL
+/*
+ * All these work on the top two elements on the stack, replacing them
+ * with the result.  Top comes first where it matters.  True is 1, false 0.
+ */
+#define  CFA_exp_OP_deref .byte DW_OP_deref NL
+#define  CFA_exp_OP_and   .byte DW_OP_and NL
+#define  CFA_exp_OP_div   .byte DW_OP_div NL
+#define  CFA_exp_OP_minus .byte DW_OP_minus NL
+#define  CFA_exp_OP_mod   .byte DW_OP_mod NL
+#define  CFA_exp_OP_neg   .byte DW_OP_neg NL
+#define  CFA_exp_OP_plus  .byte DW_OP_plus NL
+#define  CFA_exp_OP_not   .byte DW_OP_not NL
+#define  CFA_exp_OP_or    .byte DW_OP_or NL
+#define  CFA_exp_OP_xor   .byte DW_OP_xor NL
+#define  CFA_exp_OP_le    .byte DW_OP_le NL
+#define  CFA_exp_OP_ge    .byte DW_OP_ge NL
+#define  CFA_exp_OP_eq    .byte DW_OP_eq NL
+#define  CFA_exp_OP_lt    .byte DW_OP_lt NL
+#define  CFA_exp_OP_gt    .byte DW_OP_gt NL
+#define  CFA_exp_OP_ne    .byte DW_OP_ne NL
+/*
+ * These take a parameter as noted
+ */
+/*
+ * Unconditional skip to loc. loc is a label (loc:) 
+ */
+#define CFA_exp_OP_skip(loc)			\
+         .byte DW_OP_skip  NL 			\
+	 .hword  loc-.-2 NL
+/*
+ * Conditional skip to loc (TOS != 0, TOS--) (loc is a label)
+ */
+#define CFA_exp_OP_bra(loc)			\
+         .byte DW_OP_bra NL			\
+	 .hword loc-.-2 NL
+
+/*
+ * TOS += no (an unsigned number)
+ */
+#define CFA_exp_OP_plus_uconst(no)		\
+         .byte DW_OP_plus_uconst NL		\
+         .uleb128 no NL
+
+/*
+ * ++TOS = no (a unsigned number)
+ */
+#define CFA_exp_OP_constu(no)			\
+         .byte DW_OP_constu NL			\
+	 .uleb128 no NL
+/*
+ * ++TOS = no (a signed number)
+ */
+#define CFA_exp_OP_consts(no)			\
+         .byte DW_OP_consts NL			\
+	 .sleb128 no NL
+/*
+ * ++TOS = no (an unsigned byte)
+ */
+#define CFA_exp_OP_const1u(no)			\
+         .byte DW_OP_const1u NL			\
+	 .byte no NL
+
+
+/*
+ * ++TOS = no (a address)
+ */
+#define CFA_exp_OP_addr(no)			\
+         .byte DW_OP_addr NL			\
+	 .long no NL
+
+/*
+ * Push current frames value for "reg" + offset
+ * We take advantage of the opcode assignments to make this a litteral reg
+ * rather than use the DW_OP_bregx opcode.
+ */
+
+#define CFA_exp_OP_breg(reg,offset)		\
+         .byte DW_OP_breg0+reg NL		\
+         .sleb128 offset NL
+#endif
diff -urP -I '\$Id:.*Exp \$' -X /usr/src/patch.exclude linux-2.6.0-akgdb/include/linux/dwarf2.h linux/include/linux/dwarf2.h
--- linux-2.6.0-akgdb/include/linux/dwarf2.h	1969-12-31 16:00:00.000000000 -0800
+++ linux/include/linux/dwarf2.h	2004-01-15 00:26:12.000000000 -0800
@@ -0,0 +1,775 @@
+/* Declarations and definitions of codes relating to the DWARF2 symbolic
+   debugging information format.
+   Copyright (C) 1992, 1993, 1995, 1996, 1997, 1999, 2000, 2001, 2002,
+   2003 Free Software Foundation, Inc.
+
+   Written by Gary Funck (gary@intrepid.com) The Ada Joint Program
+   Office (AJPO), Florida State Unviversity and Silicon Graphics Inc.
+   provided support for this effort -- June 21, 1995.
+
+   Derived from the DWARF 1 implementation written by Ron Guilmette
+   (rfg@netcom.com), November 1990.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it under
+   the terms of the GNU General Public License as published by the Free
+   Software Foundation; either version 2, or (at your option) any later
+   version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING.  If not, write to the Free
+   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+   02111-1307, USA.  */
+
+/* This file is derived from the DWARF specification (a public document)
+   Revision 2.0.0 (July 27, 1993) developed by the UNIX International
+   Programming Languages Special Interest Group (UI/PLSIG) and distributed
+   by UNIX International.  Copies of this specification are available from
+   UNIX International, 20 Waterview Boulevard, Parsippany, NJ, 07054.
+
+   This file also now contains definitions from the DWARF 3 specification.  */
+
+/* This file is shared between GCC and GDB, and should not contain
+   prototypes.  */
+
+#ifndef _ELF_DWARF2_H
+#define _ELF_DWARF2_H
+
+/* Structure found in the .debug_line section.  */
+typedef struct
+{
+  unsigned char li_length          [4];
+  unsigned char li_version         [2];
+  unsigned char li_prologue_length [4];
+  unsigned char li_min_insn_length [1];
+  unsigned char li_default_is_stmt [1];
+  unsigned char li_line_base       [1];
+  unsigned char li_line_range      [1];
+  unsigned char li_opcode_base     [1];
+}
+DWARF2_External_LineInfo;
+
+typedef struct
+{
+  unsigned long  li_length;
+  unsigned short li_version;
+  unsigned int   li_prologue_length;
+  unsigned char  li_min_insn_length;
+  unsigned char  li_default_is_stmt;
+  int            li_line_base;
+  unsigned char  li_line_range;
+  unsigned char  li_opcode_base;
+}
+DWARF2_Internal_LineInfo;
+
+/* Structure found in .debug_pubnames section.  */
+typedef struct
+{
+  unsigned char pn_length  [4];
+  unsigned char pn_version [2];
+  unsigned char pn_offset  [4];
+  unsigned char pn_size    [4];
+}
+DWARF2_External_PubNames;
+
+typedef struct
+{
+  unsigned long  pn_length;
+  unsigned short pn_version;
+  unsigned long  pn_offset;
+  unsigned long  pn_size;
+}
+DWARF2_Internal_PubNames;
+
+/* Structure found in .debug_info section.  */
+typedef struct
+{
+  unsigned char  cu_length        [4];
+  unsigned char  cu_version       [2];
+  unsigned char  cu_abbrev_offset [4];
+  unsigned char  cu_pointer_size  [1];
+}
+DWARF2_External_CompUnit;
+
+typedef struct
+{
+  unsigned long  cu_length;
+  unsigned short cu_version;
+  unsigned long  cu_abbrev_offset;
+  unsigned char  cu_pointer_size;
+}
+DWARF2_Internal_CompUnit;
+
+typedef struct
+{
+  unsigned char  ar_length       [4];
+  unsigned char  ar_version      [2];
+  unsigned char  ar_info_offset  [4];
+  unsigned char  ar_pointer_size [1];
+  unsigned char  ar_segment_size [1];
+}
+DWARF2_External_ARange;
+
+typedef struct
+{
+  unsigned long  ar_length;
+  unsigned short ar_version;
+  unsigned long  ar_info_offset;
+  unsigned char  ar_pointer_size;
+  unsigned char  ar_segment_size;
+}
+DWARF2_Internal_ARange;
+
+
+/* Tag names and codes.  */
+enum dwarf_tag
+  {
+    DW_TAG_padding = 0x00,
+    DW_TAG_array_type = 0x01,
+    DW_TAG_class_type = 0x02,
+    DW_TAG_entry_point = 0x03,
+    DW_TAG_enumeration_type = 0x04,
+    DW_TAG_formal_parameter = 0x05,
+    DW_TAG_imported_declaration = 0x08,
+    DW_TAG_label = 0x0a,
+    DW_TAG_lexical_block = 0x0b,
+    DW_TAG_member = 0x0d,
+    DW_TAG_pointer_type = 0x0f,
+    DW_TAG_reference_type = 0x10,
+    DW_TAG_compile_unit = 0x11,
+    DW_TAG_string_type = 0x12,
+    DW_TAG_structure_type = 0x13,
+    DW_TAG_subroutine_type = 0x15,
+    DW_TAG_typedef = 0x16,
+    DW_TAG_union_type = 0x17,
+    DW_TAG_unspecified_parameters = 0x18,
+    DW_TAG_variant = 0x19,
+    DW_TAG_common_block = 0x1a,
+    DW_TAG_common_inclusion = 0x1b,
+    DW_TAG_inheritance = 0x1c,
+    DW_TAG_inlined_subroutine = 0x1d,
+    DW_TAG_module = 0x1e,
+    DW_TAG_ptr_to_member_type = 0x1f,
+    DW_TAG_set_type = 0x20,
+    DW_TAG_subrange_type = 0x21,
+    DW_TAG_with_stmt = 0x22,
+    DW_TAG_access_declaration = 0x23,
+    DW_TAG_base_type = 0x24,
+    DW_TAG_catch_block = 0x25,
+    DW_TAG_const_type = 0x26,
+    DW_TAG_constant = 0x27,
+    DW_TAG_enumerator = 0x28,
+    DW_TAG_file_type = 0x29,
+    DW_TAG_friend = 0x2a,
+    DW_TAG_namelist = 0x2b,
+    DW_TAG_namelist_item = 0x2c,
+    DW_TAG_packed_type = 0x2d,
+    DW_TAG_subprogram = 0x2e,
+    DW_TAG_template_type_param = 0x2f,
+    DW_TAG_template_value_param = 0x30,
+    DW_TAG_thrown_type = 0x31,
+    DW_TAG_try_block = 0x32,
+    DW_TAG_variant_part = 0x33,
+    DW_TAG_variable = 0x34,
+    DW_TAG_volatile_type = 0x35,
+    /* DWARF 3.  */
+    DW_TAG_dwarf_procedure = 0x36,
+    DW_TAG_restrict_type = 0x37,
+    DW_TAG_interface_type = 0x38,
+    DW_TAG_namespace = 0x39,
+    DW_TAG_imported_module = 0x3a,
+    DW_TAG_unspecified_type = 0x3b,
+    DW_TAG_partial_unit = 0x3c,
+    DW_TAG_imported_unit = 0x3d,
+    /* SGI/MIPS Extensions.  */
+    DW_TAG_MIPS_loop = 0x4081,
+    /* HP extensions.  See: ftp://ftp.hp.com/pub/lang/tools/WDB/wdb-4.0.tar.gz .  */
+    DW_TAG_HP_array_descriptor = 0x4090,
+    /* GNU extensions.  */
+    DW_TAG_format_label = 0x4101,	/* For FORTRAN 77 and Fortran 90.  */
+    DW_TAG_function_template = 0x4102,	/* For C++.  */
+    DW_TAG_class_template = 0x4103,	/* For C++.  */
+    DW_TAG_GNU_BINCL = 0x4104,
+    DW_TAG_GNU_EINCL = 0x4105,
+    /* Extensions for UPC.  See: http://upc.gwu.edu/~upc.  */
+    DW_TAG_upc_shared_type = 0x8765,
+    DW_TAG_upc_strict_type = 0x8766,
+    DW_TAG_upc_relaxed_type = 0x8767,
+    /* PGI (STMicroelectronics) extensions.  No documentation available.  */
+    DW_TAG_PGI_kanji_type      = 0xA000,
+    DW_TAG_PGI_interface_block = 0xA020
+  };
+
+#define DW_TAG_lo_user	0x4080
+#define DW_TAG_hi_user	0xffff
+
+/* Flag that tells whether entry has a child or not.  */
+#define DW_children_no   0
+#define	DW_children_yes  1
+
+/* Form names and codes.  */
+enum dwarf_form
+  {
+    DW_FORM_addr = 0x01,
+    DW_FORM_block2 = 0x03,
+    DW_FORM_block4 = 0x04,
+    DW_FORM_data2 = 0x05,
+    DW_FORM_data4 = 0x06,
+    DW_FORM_data8 = 0x07,
+    DW_FORM_string = 0x08,
+    DW_FORM_block = 0x09,
+    DW_FORM_block1 = 0x0a,
+    DW_FORM_data1 = 0x0b,
+    DW_FORM_flag = 0x0c,
+    DW_FORM_sdata = 0x0d,
+    DW_FORM_strp = 0x0e,
+    DW_FORM_udata = 0x0f,
+    DW_FORM_ref_addr = 0x10,
+    DW_FORM_ref1 = 0x11,
+    DW_FORM_ref2 = 0x12,
+    DW_FORM_ref4 = 0x13,
+    DW_FORM_ref8 = 0x14,
+    DW_FORM_ref_udata = 0x15,
+    DW_FORM_indirect = 0x16
+  };
+
+/* Attribute names and codes.  */
+enum dwarf_attribute
+  {
+    DW_AT_sibling = 0x01,
+    DW_AT_location = 0x02,
+    DW_AT_name = 0x03,
+    DW_AT_ordering = 0x09,
+    DW_AT_subscr_data = 0x0a,
+    DW_AT_byte_size = 0x0b,
+    DW_AT_bit_offset = 0x0c,
+    DW_AT_bit_size = 0x0d,
+    DW_AT_element_list = 0x0f,
+    DW_AT_stmt_list = 0x10,
+    DW_AT_low_pc = 0x11,
+    DW_AT_high_pc = 0x12,
+    DW_AT_language = 0x13,
+    DW_AT_member = 0x14,
+    DW_AT_discr = 0x15,
+    DW_AT_discr_value = 0x16,
+    DW_AT_visibility = 0x17,
+    DW_AT_import = 0x18,
+    DW_AT_string_length = 0x19,
+    DW_AT_common_reference = 0x1a,
+    DW_AT_comp_dir = 0x1b,
+    DW_AT_const_value = 0x1c,
+    DW_AT_containing_type = 0x1d,
+    DW_AT_default_value = 0x1e,
+    DW_AT_inline = 0x20,
+    DW_AT_is_optional = 0x21,
+    DW_AT_lower_bound = 0x22,
+    DW_AT_producer = 0x25,
+    DW_AT_prototyped = 0x27,
+    DW_AT_return_addr = 0x2a,
+    DW_AT_start_scope = 0x2c,
+    DW_AT_stride_size = 0x2e,
+    DW_AT_upper_bound = 0x2f,
+    DW_AT_abstract_origin = 0x31,
+    DW_AT_accessibility = 0x32,
+    DW_AT_address_class = 0x33,
+    DW_AT_artificial = 0x34,
+    DW_AT_base_types = 0x35,
+    DW_AT_calling_convention = 0x36,
+    DW_AT_count = 0x37,
+    DW_AT_data_member_location = 0x38,
+    DW_AT_decl_column = 0x39,
+    DW_AT_decl_file = 0x3a,
+    DW_AT_decl_line = 0x3b,
+    DW_AT_declaration = 0x3c,
+    DW_AT_discr_list = 0x3d,
+    DW_AT_encoding = 0x3e,
+    DW_AT_external = 0x3f,
+    DW_AT_frame_base = 0x40,
+    DW_AT_friend = 0x41,
+    DW_AT_identifier_case = 0x42,
+    DW_AT_macro_info = 0x43,
+    DW_AT_namelist_items = 0x44,
+    DW_AT_priority = 0x45,
+    DW_AT_segment = 0x46,
+    DW_AT_specification = 0x47,
+    DW_AT_static_link = 0x48,
+    DW_AT_type = 0x49,
+    DW_AT_use_location = 0x4a,
+    DW_AT_variable_parameter = 0x4b,
+    DW_AT_virtuality = 0x4c,
+    DW_AT_vtable_elem_location = 0x4d,
+    /* DWARF 3 values.  */
+    DW_AT_allocated     = 0x4e,
+    DW_AT_associated    = 0x4f,
+    DW_AT_data_location = 0x50,
+    DW_AT_stride        = 0x51,
+    DW_AT_entry_pc      = 0x52,
+    DW_AT_use_UTF8      = 0x53,
+    DW_AT_extension     = 0x54,
+    DW_AT_ranges        = 0x55,
+    DW_AT_trampoline    = 0x56,
+    DW_AT_call_column   = 0x57,
+    DW_AT_call_file     = 0x58,
+    DW_AT_call_line     = 0x59,
+    /* SGI/MIPS extensions.  */
+    DW_AT_MIPS_fde = 0x2001,
+    DW_AT_MIPS_loop_begin = 0x2002,
+    DW_AT_MIPS_tail_loop_begin = 0x2003,
+    DW_AT_MIPS_epilog_begin = 0x2004,
+    DW_AT_MIPS_loop_unroll_factor = 0x2005,
+    DW_AT_MIPS_software_pipeline_depth = 0x2006,
+    DW_AT_MIPS_linkage_name = 0x2007,
+    DW_AT_MIPS_stride = 0x2008,
+    DW_AT_MIPS_abstract_name = 0x2009,
+    DW_AT_MIPS_clone_origin = 0x200a,
+    DW_AT_MIPS_has_inlines = 0x200b,
+    /* HP extensions.  */
+    DW_AT_HP_block_index         = 0x2000,
+    DW_AT_HP_unmodifiable        = 0x2001, /* Same as DW_AT_MIPS_fde.  */
+    DW_AT_HP_actuals_stmt_list   = 0x2010,
+    DW_AT_HP_proc_per_section    = 0x2011,
+    DW_AT_HP_raw_data_ptr        = 0x2012,
+    DW_AT_HP_pass_by_reference   = 0x2013,
+    DW_AT_HP_opt_level           = 0x2014,
+    DW_AT_HP_prof_version_id     = 0x2015,
+    DW_AT_HP_opt_flags           = 0x2016,
+    DW_AT_HP_cold_region_low_pc  = 0x2017,
+    DW_AT_HP_cold_region_high_pc = 0x2018,
+    DW_AT_HP_all_variables_modifiable = 0x2019,
+    DW_AT_HP_linkage_name        = 0x201a,
+    DW_AT_HP_prof_flags          = 0x201b,  /* In comp unit of procs_info for -g.  */
+    /* GNU extensions.  */
+    DW_AT_sf_names   = 0x2101,
+    DW_AT_src_info   = 0x2102,
+    DW_AT_mac_info   = 0x2103,
+    DW_AT_src_coords = 0x2104,
+    DW_AT_body_begin = 0x2105,
+    DW_AT_body_end   = 0x2106,
+    DW_AT_GNU_vector = 0x2107,
+    /* VMS extensions.  */
+    DW_AT_VMS_rtnbeg_pd_address = 0x2201,
+    /* UPC extension.  */
+    DW_AT_upc_threads_scaled = 0x3210,
+    /* PGI (STMicroelectronics) extensions.  */
+    DW_AT_PGI_lbase    = 0x3a00,
+    DW_AT_PGI_soffset  = 0x3a01,
+    DW_AT_PGI_lstride  = 0x3a02
+  };
+
+#define DW_AT_lo_user	0x2000	/* Implementation-defined range start.  */
+#define DW_AT_hi_user	0x3ff0	/* Implementation-defined range end.  */
+
+/* Location atom names and codes.  */
+enum dwarf_location_atom
+  {
+    DW_OP_addr = 0x03,
+    DW_OP_deref = 0x06,
+    DW_OP_const1u = 0x08,
+    DW_OP_const1s = 0x09,
+    DW_OP_const2u = 0x0a,
+    DW_OP_const2s = 0x0b,
+    DW_OP_const4u = 0x0c,
+    DW_OP_const4s = 0x0d,
+    DW_OP_const8u = 0x0e,
+    DW_OP_const8s = 0x0f,
+    DW_OP_constu = 0x10,
+    DW_OP_consts = 0x11,
+    DW_OP_dup = 0x12,
+    DW_OP_drop = 0x13,
+    DW_OP_over = 0x14,
+    DW_OP_pick = 0x15,
+    DW_OP_swap = 0x16,
+    DW_OP_rot = 0x17,
+    DW_OP_xderef = 0x18,
+    DW_OP_abs = 0x19,
+    DW_OP_and = 0x1a,
+    DW_OP_div = 0x1b,
+    DW_OP_minus = 0x1c,
+    DW_OP_mod = 0x1d,
+    DW_OP_mul = 0x1e,
+    DW_OP_neg = 0x1f,
+    DW_OP_not = 0x20,
+    DW_OP_or = 0x21,
+    DW_OP_plus = 0x22,
+    DW_OP_plus_uconst = 0x23,
+    DW_OP_shl = 0x24,
+    DW_OP_shr = 0x25,
+    DW_OP_shra = 0x26,
+    DW_OP_xor = 0x27,
+    DW_OP_bra = 0x28,
+    DW_OP_eq = 0x29,
+    DW_OP_ge = 0x2a,
+    DW_OP_gt = 0x2b,
+    DW_OP_le = 0x2c,
+    DW_OP_lt = 0x2d,
+    DW_OP_ne = 0x2e,
+    DW_OP_skip = 0x2f,
+    DW_OP_lit0 = 0x30,
+    DW_OP_lit1 = 0x31,
+    DW_OP_lit2 = 0x32,
+    DW_OP_lit3 = 0x33,
+    DW_OP_lit4 = 0x34,
+    DW_OP_lit5 = 0x35,
+    DW_OP_lit6 = 0x36,
+    DW_OP_lit7 = 0x37,
+    DW_OP_lit8 = 0x38,
+    DW_OP_lit9 = 0x39,
+    DW_OP_lit10 = 0x3a,
+    DW_OP_lit11 = 0x3b,
+    DW_OP_lit12 = 0x3c,
+    DW_OP_lit13 = 0x3d,
+    DW_OP_lit14 = 0x3e,
+    DW_OP_lit15 = 0x3f,
+    DW_OP_lit16 = 0x40,
+    DW_OP_lit17 = 0x41,
+    DW_OP_lit18 = 0x42,
+    DW_OP_lit19 = 0x43,
+    DW_OP_lit20 = 0x44,
+    DW_OP_lit21 = 0x45,
+    DW_OP_lit22 = 0x46,
+    DW_OP_lit23 = 0x47,
+    DW_OP_lit24 = 0x48,
+    DW_OP_lit25 = 0x49,
+    DW_OP_lit26 = 0x4a,
+    DW_OP_lit27 = 0x4b,
+    DW_OP_lit28 = 0x4c,
+    DW_OP_lit29 = 0x4d,
+    DW_OP_lit30 = 0x4e,
+    DW_OP_lit31 = 0x4f,
+    DW_OP_reg0 = 0x50,
+    DW_OP_reg1 = 0x51,
+    DW_OP_reg2 = 0x52,
+    DW_OP_reg3 = 0x53,
+    DW_OP_reg4 = 0x54,
+    DW_OP_reg5 = 0x55,
+    DW_OP_reg6 = 0x56,
+    DW_OP_reg7 = 0x57,
+    DW_OP_reg8 = 0x58,
+    DW_OP_reg9 = 0x59,
+    DW_OP_reg10 = 0x5a,
+    DW_OP_reg11 = 0x5b,
+    DW_OP_reg12 = 0x5c,
+    DW_OP_reg13 = 0x5d,
+    DW_OP_reg14 = 0x5e,
+    DW_OP_reg15 = 0x5f,
+    DW_OP_reg16 = 0x60,
+    DW_OP_reg17 = 0x61,
+    DW_OP_reg18 = 0x62,
+    DW_OP_reg19 = 0x63,
+    DW_OP_reg20 = 0x64,
+    DW_OP_reg21 = 0x65,
+    DW_OP_reg22 = 0x66,
+    DW_OP_reg23 = 0x67,
+    DW_OP_reg24 = 0x68,
+    DW_OP_reg25 = 0x69,
+    DW_OP_reg26 = 0x6a,
+    DW_OP_reg27 = 0x6b,
+    DW_OP_reg28 = 0x6c,
+    DW_OP_reg29 = 0x6d,
+    DW_OP_reg30 = 0x6e,
+    DW_OP_reg31 = 0x6f,
+    DW_OP_breg0 = 0x70,
+    DW_OP_breg1 = 0x71,
+    DW_OP_breg2 = 0x72,
+    DW_OP_breg3 = 0x73,
+    DW_OP_breg4 = 0x74,
+    DW_OP_breg5 = 0x75,
+    DW_OP_breg6 = 0x76,
+    DW_OP_breg7 = 0x77,
+    DW_OP_breg8 = 0x78,
+    DW_OP_breg9 = 0x79,
+    DW_OP_breg10 = 0x7a,
+    DW_OP_breg11 = 0x7b,
+    DW_OP_breg12 = 0x7c,
+    DW_OP_breg13 = 0x7d,
+    DW_OP_breg14 = 0x7e,
+    DW_OP_breg15 = 0x7f,
+    DW_OP_breg16 = 0x80,
+    DW_OP_breg17 = 0x81,
+    DW_OP_breg18 = 0x82,
+    DW_OP_breg19 = 0x83,
+    DW_OP_breg20 = 0x84,
+    DW_OP_breg21 = 0x85,
+    DW_OP_breg22 = 0x86,
+    DW_OP_breg23 = 0x87,
+    DW_OP_breg24 = 0x88,
+    DW_OP_breg25 = 0x89,
+    DW_OP_breg26 = 0x8a,
+    DW_OP_breg27 = 0x8b,
+    DW_OP_breg28 = 0x8c,
+    DW_OP_breg29 = 0x8d,
+    DW_OP_breg30 = 0x8e,
+    DW_OP_breg31 = 0x8f,
+    DW_OP_regx = 0x90,
+    DW_OP_fbreg = 0x91,
+    DW_OP_bregx = 0x92,
+    DW_OP_piece = 0x93,
+    DW_OP_deref_size = 0x94,
+    DW_OP_xderef_size = 0x95,
+    DW_OP_nop = 0x96,
+    /* DWARF 3 extensions.  */
+    DW_OP_push_object_address = 0x97,
+    DW_OP_call2 = 0x98,
+    DW_OP_call4 = 0x99,
+    DW_OP_call_ref = 0x9a,
+    /* GNU extensions.  */
+    DW_OP_GNU_push_tls_address = 0xe0,
+    /* HP extensions.  */
+    DW_OP_HP_unknown     = 0xe0, /* Ouch, the same as GNU_push_tls_address.  */
+    DW_OP_HP_is_value    = 0xe1,
+    DW_OP_HP_fltconst4   = 0xe2,
+    DW_OP_HP_fltconst8   = 0xe3,
+    DW_OP_HP_mod_range   = 0xe4,
+    DW_OP_HP_unmod_range = 0xe5,
+    DW_OP_HP_tls         = 0xe6
+  };
+
+#define DW_OP_lo_user	0xe0	/* Implementation-defined range start.  */
+#define DW_OP_hi_user	0xff	/* Implementation-defined range end.  */
+
+/* Type encodings.  */
+enum dwarf_type
+  {
+    DW_ATE_void = 0x0,
+    DW_ATE_address = 0x1,
+    DW_ATE_boolean = 0x2,
+    DW_ATE_complex_float = 0x3,
+    DW_ATE_float = 0x4,
+    DW_ATE_signed = 0x5,
+    DW_ATE_signed_char = 0x6,
+    DW_ATE_unsigned = 0x7,
+    DW_ATE_unsigned_char = 0x8,
+    /* DWARF 3.  */
+    DW_ATE_imaginary_float = 0x9,
+    /* HP extensions.  */
+    DW_ATE_HP_float80            = 0x80, /* Floating-point (80 bit).  */
+    DW_ATE_HP_complex_float80    = 0x81, /* Complex floating-point (80 bit).  */
+    DW_ATE_HP_float128           = 0x82, /* Floating-point (128 bit).  */
+    DW_ATE_HP_complex_float128   = 0x83, /* Complex floating-point (128 bit).  */
+    DW_ATE_HP_floathpintel       = 0x84, /* Floating-point (82 bit IA64).  */
+    DW_ATE_HP_imaginary_float80  = 0x85,
+    DW_ATE_HP_imaginary_float128 = 0x86
+  };
+
+#define	DW_ATE_lo_user 0x80
+#define	DW_ATE_hi_user 0xff
+
+/* Array ordering names and codes.  */
+enum dwarf_array_dim_ordering
+  {
+    DW_ORD_row_major = 0,
+    DW_ORD_col_major = 1
+  };
+
+/* Access attribute.  */
+enum dwarf_access_attribute
+  {
+    DW_ACCESS_public = 1,
+    DW_ACCESS_protected = 2,
+    DW_ACCESS_private = 3
+  };
+
+/* Visibility.  */
+enum dwarf_visibility_attribute
+  {
+    DW_VIS_local = 1,
+    DW_VIS_exported = 2,
+    DW_VIS_qualified = 3
+  };
+
+/* Virtuality.  */
+enum dwarf_virtuality_attribute
+  {
+    DW_VIRTUALITY_none = 0,
+    DW_VIRTUALITY_virtual = 1,
+    DW_VIRTUALITY_pure_virtual = 2
+  };
+
+/* Case sensitivity.  */
+enum dwarf_id_case
+  {
+    DW_ID_case_sensitive = 0,
+    DW_ID_up_case = 1,
+    DW_ID_down_case = 2,
+    DW_ID_case_insensitive = 3
+  };
+
+/* Calling convention.  */
+enum dwarf_calling_convention
+  {
+    DW_CC_normal = 0x1,
+    DW_CC_program = 0x2,
+    DW_CC_nocall = 0x3
+  };
+
+#define DW_CC_lo_user 0x40
+#define DW_CC_hi_user 0xff
+
+/* Inline attribute.  */
+enum dwarf_inline_attribute
+  {
+    DW_INL_not_inlined = 0,
+    DW_INL_inlined = 1,
+    DW_INL_declared_not_inlined = 2,
+    DW_INL_declared_inlined = 3
+  };
+
+/* Discriminant lists.  */
+enum dwarf_discrim_list
+  {
+    DW_DSC_label = 0,
+    DW_DSC_range = 1
+  };
+
+/* Line number opcodes.  */
+enum dwarf_line_number_ops
+  {
+    DW_LNS_extended_op = 0,
+    DW_LNS_copy = 1,
+    DW_LNS_advance_pc = 2,
+    DW_LNS_advance_line = 3,
+    DW_LNS_set_file = 4,
+    DW_LNS_set_column = 5,
+    DW_LNS_negate_stmt = 6,
+    DW_LNS_set_basic_block = 7,
+    DW_LNS_const_add_pc = 8,
+    DW_LNS_fixed_advance_pc = 9,
+    /* DWARF 3.  */
+    DW_LNS_set_prologue_end = 10,
+    DW_LNS_set_epilogue_begin = 11,
+    DW_LNS_set_isa = 12
+  };
+
+/* Line number extended opcodes.  */
+enum dwarf_line_number_x_ops
+  {
+    DW_LNE_end_sequence = 1,
+    DW_LNE_set_address = 2,
+    DW_LNE_define_file = 3,
+    /* HP extensions.  */
+    DW_LNE_HP_negate_is_UV_update      = 0x11,
+    DW_LNE_HP_push_context             = 0x12,
+    DW_LNE_HP_pop_context              = 0x13,
+    DW_LNE_HP_set_file_line_column     = 0x14,
+    DW_LNE_HP_set_routine_name         = 0x15,
+    DW_LNE_HP_set_sequence             = 0x16,
+    DW_LNE_HP_negate_post_semantics    = 0x17,
+    DW_LNE_HP_negate_function_exit     = 0x18,
+    DW_LNE_HP_negate_front_end_logical = 0x19,
+    DW_LNE_HP_define_proc              = 0x20
+  };
+
+/* Call frame information.  */
+enum dwarf_call_frame_info
+  {
+    DW_CFA_advance_loc = 0x40,
+    DW_CFA_offset = 0x80,
+    DW_CFA_restore = 0xc0,
+    DW_CFA_nop = 0x00,
+    DW_CFA_set_loc = 0x01,
+    DW_CFA_advance_loc1 = 0x02,
+    DW_CFA_advance_loc2 = 0x03,
+    DW_CFA_advance_loc4 = 0x04,
+    DW_CFA_offset_extended = 0x05,
+    DW_CFA_restore_extended = 0x06,
+    DW_CFA_undefined = 0x07,
+    DW_CFA_same_value = 0x08,
+    DW_CFA_register = 0x09,
+    DW_CFA_remember_state = 0x0a,
+    DW_CFA_restore_state = 0x0b,
+    DW_CFA_def_cfa = 0x0c,
+    DW_CFA_def_cfa_register = 0x0d,
+    DW_CFA_def_cfa_offset = 0x0e,
+    /* DWARF 3.  */
+    DW_CFA_def_cfa_expression = 0x0f,
+    DW_CFA_expression = 0x10,
+    DW_CFA_offset_extended_sf = 0x11,
+    DW_CFA_def_cfa_sf = 0x12,
+    DW_CFA_def_cfa_offset_sf = 0x13,
+    /* SGI/MIPS specific.  */
+    DW_CFA_MIPS_advance_loc8 = 0x1d,
+    /* GNU extensions.  */
+    DW_CFA_GNU_window_save = 0x2d,
+    DW_CFA_GNU_args_size = 0x2e,
+    DW_CFA_GNU_negative_offset_extended = 0x2f
+  };
+
+#define DW_CIE_ID	  0xffffffff
+#define DW_CIE_VERSION	  1
+
+#define DW_CFA_extended   0
+#define DW_CFA_lo_user    0x1c
+#define DW_CFA_hi_user    0x3f
+
+#define DW_CHILDREN_no		     0x00
+#define DW_CHILDREN_yes		     0x01
+
+#define DW_ADDR_none		0
+
+/* Source language names and codes.  */
+enum dwarf_source_language
+  {
+    DW_LANG_C89 = 0x0001,
+    DW_LANG_C = 0x0002,
+    DW_LANG_Ada83 = 0x0003,
+    DW_LANG_C_plus_plus = 0x0004,
+    DW_LANG_Cobol74 = 0x0005,
+    DW_LANG_Cobol85 = 0x0006,
+    DW_LANG_Fortran77 = 0x0007,
+    DW_LANG_Fortran90 = 0x0008,
+    DW_LANG_Pascal83 = 0x0009,
+    DW_LANG_Modula2 = 0x000a,
+    DW_LANG_Java = 0x000b,
+    /* DWARF 3.  */
+    DW_LANG_C99 = 0x000c,
+    DW_LANG_Ada95 = 0x000d,
+    DW_LANG_Fortran95 = 0x000e,
+    /* MIPS.  */
+    DW_LANG_Mips_Assembler = 0x8001,
+    /* UPC.  */
+    DW_LANG_Upc = 0x8765
+  };
+
+#define DW_LANG_lo_user 0x8000	/* Implementation-defined range start.  */
+#define DW_LANG_hi_user 0xffff	/* Implementation-defined range start.  */
+
+/* Names and codes for macro information.  */
+enum dwarf_macinfo_record_type
+  {
+    DW_MACINFO_define = 1,
+    DW_MACINFO_undef = 2,
+    DW_MACINFO_start_file = 3,
+    DW_MACINFO_end_file = 4,
+    DW_MACINFO_vendor_ext = 255
+  };
+\f
+/* @@@ For use with GNU frame unwind information.  */
+
+#define DW_EH_PE_absptr		0x00
+#define DW_EH_PE_omit		0xff
+
+#define DW_EH_PE_uleb128	0x01
+#define DW_EH_PE_udata2		0x02
+#define DW_EH_PE_udata4		0x03
+#define DW_EH_PE_udata8		0x04
+#define DW_EH_PE_sleb128	0x09
+#define DW_EH_PE_sdata2		0x0A
+#define DW_EH_PE_sdata4		0x0B
+#define DW_EH_PE_sdata8		0x0C
+#define DW_EH_PE_signed		0x08
+
+#define DW_EH_PE_pcrel		0x10
+#define DW_EH_PE_textrel	0x20
+#define DW_EH_PE_datarel	0x30
+#define DW_EH_PE_funcrel	0x40
+#define DW_EH_PE_aligned	0x50
+
+#define DW_EH_PE_indirect	0x80
+
+#endif /* _ELF_DWARF2_H */
Binary files linux-2.6.0-akgdb/scripts/bin2c and linux/scripts/bin2c differ
diff -urP -I '\$Id:.*Exp \$' -X /usr/src/patch.exclude linux-2.6.0-akgdb/scripts/dwarfh.awk linux/scripts/dwarfh.awk
--- linux-2.6.0-akgdb/scripts/dwarfh.awk	1969-12-31 16:00:00.000000000 -0800
+++ linux/scripts/dwarfh.awk	2004-01-22 12:58:07.000000000 -0800
@@ -0,0 +1,19 @@
+BEGIN {
+	print "#ifndef  _ELF_DWARF_H"
+		print "/* Machine generated from dwarf2.h by scripts/dwarfh.awk */"	
+}
+$2 == "=" {
+	gsub(/,/, "", $3)
+	print "#define " $1 "\t " $3
+}
+$1 == "#define" {
+	print $0
+	while( index($0,"\\") == length($0)){
+		getline
+		print $0
+	}
+}
+/.*/ {}
+END {
+	print "#endif"
+}

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

* [PATCH] Kgdb dwarf2 for asm
  2004-01-23 22:46                 ` Tom Rini
  2004-01-23 23:38                   ` George Anzinger
  2004-01-24  0:48                   ` George Anzinger
@ 2004-01-24  3:47                   ` George Anzinger
  2004-01-27 18:22                   ` PPC KGDB changes and some help? Tom Rini
  3 siblings, 0 replies; 35+ messages in thread
From: George Anzinger @ 2004-01-24  3:47 UTC (permalink / raw)
  To: Tom Rini
  Cc: Amit S. Kale, Powerpc Linux, Linux Kernel, KGDB bugreports,
	Andrew Morton, Daniel Jacobowitz

[-- Attachment #1: Type: text/plain, Size: 2513 bytes --]

This is a second try at this with a different subject and the note on gdb 
version at the end.

Here is the dwarf2 patch.  It assumes that mm-kgdb is already there, but there
are really very few dependencies.  With little effort it should work with Amit's
version.

What it does:

This patch allows back trace and "up" commands to go smoothly back to the root
of the stack through interrupt frames, trap frames, you name it.  It also tells
the asm compile engine to save the temp source as this is what gas builds debug
records for.  (This is not needed to get the back trace, its just "nice".)

I removed the debug info overlap in kconfig.  Kgdb sets -gdwarf2 while that set
-g.  Not nice to have both.

There is only one code change and that is to push a "1" on the stack so that it
looks like the return address for idle tasks other than the cpu 0 idle task.
This is done so that a "bt" on that task will not go on forever (I had a screen
with 1000+ levels on it...).

What it is:

The dwarf2.h file from the binutils tree is here as it is there.  There is an
awk script to build dwarf2-defs.h which is nothing but all the constants, from
that file, in a form that asm AND c understand.  The script works for this file,
for other files you are on your own.  This translation is forced in the main
make file, I suppose this could be done more cleanly, but... I just did not want
to figure out the make maze.

The dwarf2-lang.h file is a set of macros that make writing dwarf2 half way
enjoyable and much more understandable.

All most all of the dwaft2 code is at the end of entry.S but for 2 lines in head.S.

Daniel keeps telling me that this should be done in asm, and I suppose one could
do it there, but it does not support the expression code as yet and that is
where most of the magic is.

Oh and by the way, you do need call frames (CONFIG option) as without them gdb
will most likely get lost in the switch code in schedule().  This comes up in
the "info thread' command so it is not uncommon.

What it needs:

For the dwaft2 expression code to be correctly understood by gdb you will need 
to get the CVS version of gdb as of at least 1/24/04.  Otherwise, the bug in the 
gdb expression code will most likely stop the unwind at the intrerrupt/trap 
frame regardless of having interrupted the kernel and not user space code.

-- 
George Anzinger   george@mvista.com
High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml


[-- Attachment #2: kgdb-dwarf2-2.6.0-1.0.patch --]
[-- Type: text/plain, Size: 39880 bytes --]

diff -urP -I '\$Id:.*Exp \$' -X /usr/src/patch.exclude linux-2.6.0-akgdb/Makefile linux/Makefile
--- linux-2.6.0-akgdb/Makefile	2004-01-08 15:36:35.000000000 -0800
+++ linux/Makefile	2004-01-22 13:01:31.000000000 -0800
@@ -1025,5 +1025,7 @@
 descend =$(Q)$(MAKE) -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj=$(1) $(2)
 
 endif	# skip-makefile
+include/linux/dwarf2-defs.h: include/linux/dwarf2.h scripts/dwarfh.awk
+	awk -f scripts/dwarfh.awk include/linux/dwarf2.h > include/linux/dwarf2-defs.h
 
-FORCE:
+FORCE: include/linux/dwarf2-defs.h
Binary files linux-2.6.0-akgdb/a.out and linux/a.out differ
diff -urP -I '\$Id:.*Exp \$' -X /usr/src/patch.exclude linux-2.6.0-akgdb/arch/i386/Kconfig linux/arch/i386/Kconfig
--- linux-2.6.0-akgdb/arch/i386/Kconfig	2004-01-08 15:39:58.000000000 -0800
+++ linux/arch/i386/Kconfig	2004-01-09 14:50:07.000000000 -0800
@@ -1196,7 +1196,7 @@
 
 config DEBUG_INFO
 	bool "Compile the kernel with debug info"
-	depends on DEBUG_KERNEL
+	depends on DEBUG_KERNEL && !KGDB
 	help
           If you say Y here the resulting kernel image will include
 	  debugging info resulting in a larger kernel image.
@@ -1227,7 +1227,7 @@
 	  will then break as soon as it looks at the boot options.  This
 	  option also installs a breakpoint in panic and sends any
 	  kernel faults to the debugger. For more information see the
-	  Documentation/i386/kgdb.txt file.
+	  Documentation/i386/kgdb/kgdb.txt file.
 
 choice
 	depends on KGDB
diff -urP -I '\$Id:.*Exp \$' -X /usr/src/patch.exclude linux-2.6.0-akgdb/arch/i386/Makefile linux/arch/i386/Makefile
--- linux-2.6.0-akgdb/arch/i386/Makefile	2004-01-08 15:39:58.000000000 -0800
+++ linux/arch/i386/Makefile	2004-01-13 16:04:02.000000000 -0800
@@ -100,7 +100,9 @@
 drivers-$(CONFIG_PM)			+= arch/i386/power/
 
 CFLAGS += $(mflags-y)
-AFLAGS += $(mflags-y)
+aflags-y = $(mflags-y)
+aflags-$(CONFIG_KGDB) += -save-temps
+AFLAGS += $(aflags-y)
 
 boot := arch/i386/boot
 
diff -urP -I '\$Id:.*Exp \$' -X /usr/src/patch.exclude linux-2.6.0-akgdb/arch/i386/kernel/entry.S linux/arch/i386/kernel/entry.S
--- linux-2.6.0-akgdb/arch/i386/kernel/entry.S	2004-01-13 15:53:06.000000000 -0800
+++ linux/arch/i386/kernel/entry.S	2004-01-23 16:03:00.000000000 -0800
@@ -910,3 +910,116 @@
 	.long sys_ni_syscall	/* sys_vserver */
 
 syscall_table_size=(.-sys_call_table)
+
+#	Here we do call frames.  We cheat a bit as we only really need
+#	correct frames at locations we can actually look at from a
+#	debugger.  Since the break instruction trap actually goes thru
+#	some of this code, we don't really need info on those areas, but
+#	only after the fact.  I.e. if we can not step or break in a
+#	location or end up with a return address pointing at the
+#	location, we don't need a correct call frame for it.
+
+#ifdef CONFIG_KGDB
+
+#include <linux/dwarf2-lang.h>
+/*
+ * The register numbers as known by gdb
+ */
+cfa_one: .long 1
+	
+#define _EAX 0
+#define _ECX 1
+#define _EDX 2
+#define _EBX 3
+#define _ESP 4
+#define _EBP 5
+#define _ESI 6
+#define _EDI 7
+#define _PC  8 
+#define _EIP 8 
+#define _PS  9
+#define _EFLAGS  9
+#define _CS 10
+#define _SS 11
+#define _DS 12
+#define _ES 13
+#define _FS 14
+#define _GS 15
+
+	CFI_preamble(c1,_PC,1,1)
+	CFA_def_cfa_expression
+	   CFA_exp_OP_breg(_ESP,OLDESP)		/* push the stack & adjust */
+	   CFA_exp_OP_dup			/* save that */
+ 	   CFA_exp_OP_consts(-8)		/* offset to CS address */
+ 	   CFA_exp_OP_plus			/* should be CS address */
+	   CFA_exp_OP_deref			/* get the CS */
+	   CFA_exp_OP_const4s(VM_MASK|3)	/* prepare to mask it */
+	   CFA_exp_OP_and			/* mask it, zero means kernel */
+	   CFA_exp_OP_bra(cfa_user_rtn)		/* branch if user  (TOS--) */
+	   CFA_exp_OP_skip(cfa_end)		/* done if kernel, skip out */
+cfa_user_rtn:	
+	   CFA_exp_OP_constu(0)			/* user space, set exp to 0 */
+cfa_end:	
+	   CFA_expression_end
+	CFA_expression(_EIP)
+	   CFA_exp_OP_dup			/* copy old esp */
+	   CFA_exp_OP_bra(eip_kernel_rtn)	/* non-zero means kernel */
+	   CFA_exp_OP_addr(cfa_one)		/* for user, pass 1 */
+	   CFA_exp_OP_skip(eip_end)		/* done if kernel, skip out */
+eip_kernel_rtn:	
+	   CFA_exp_OP_const4s(EIP-OLDESP)	/* offset to return address */
+	   CFA_exp_OP_plus
+eip_end:	
+	   CFA_expression_end
+	CFA_define_offset(_EBX,EBX-OLDESP)	
+	CFA_define_offset(_ECX,ECX-OLDESP)	
+	CFA_define_offset(_EDX,EDX-OLDESP)	
+	CFA_define_offset(_ESI,ESI-OLDESP)	
+	CFA_define_offset(_EDI,EDI-OLDESP)	
+	CFA_define_offset(_EBP,EBP-OLDESP)	
+	CFA_define_offset(_EAX,EAX-OLDESP)	
+	CFA_define_offset(_EFLAGS,EFLAGS-OLDESP)	
+	CFI_postamble()
+	
+/*
+ * This is an attempt to provide an unwind for location 0 which is 
+ * identical to the prior frame.  Should stop the unwind.  Note that gdb
+ * uses the pc-1 to look for FDEs so the correct pc is 1 not 0 which,
+ * because of addresses being unsigned, can not be used by man nor beast.
+ */				
+	CFI_preamble(c2,_PC,1,1)
+	CFA_def_cfa_expression
+	   CFA_exp_OP_constu(0)			/* stack end, set exp to 0 */
+	   CFA_expression_end
+	CFI_postamble()
+	
+	FDE_preamble(c2,0,10)
+	FDE_postamble()
+	/*
+         * This is VERY sloppy.  At this point all we want to do is get
+         * the frame right for back tracing.  It will not be good if
+         * you try to single step.  We use already defined labels.
+         * We want to cover all call outs.
+         * We could also recode this as just one FDE, but this works and
+         * I want to get it out.
+	 */
+	FDE_preamble(c1,do_lcall,(ret_from_fork - do_lcall))
+	CFA_define_cfa_offset(OLDESP+8)
+	FDE_postamble()	
+	FDE_preamble(c1,ret_from_fork,(ret_from_exception - ret_from_fork))
+	CFA_define_cfa_offset(OLDESP+4)
+	FDE_postamble()	
+	FDE_preamble(c1,ret_from_exception,(divide_error - ret_from_exception))
+	FDE_postamble()	
+	FDE_preamble(c1,error_code,(device_not_available_emulate - error_code))
+	CFA_define_cfa_offset(OLDESP+8)
+	FDE_postamble()	
+	FDE_preamble(c1,device_not_available_emulate,(debug - device_not_available_emulate))
+	CFA_define_cfa_offset(OLDESP+4)
+	FDE_postamble()	
+	FDE_preamble(c1,nmi,(int3 - nmi))
+	CFA_define_cfa_offset(OLDESP+8)
+	FDE_postamble()
+
+# 
+#endif
diff -urP -I '\$Id:.*Exp \$' -X /usr/src/patch.exclude linux-2.6.0-akgdb/arch/i386/kernel/head.S linux/arch/i386/kernel/head.S
--- linux-2.6.0-akgdb/arch/i386/kernel/head.S	2003-09-08 14:15:17.000000000 -0700
+++ linux/arch/i386/kernel/head.S	2004-01-23 16:19:21.000000000 -0800
@@ -278,6 +278,16 @@
 				# just in case, we know what happens.
 
 ready:	.byte 0
+#ifdef CONFIG_KGDB
+#include <linux/dwarf2-lang.h>
+
+	/* This dwarf code tells gdb that this is the end of the unwind */
+	/* This uses the CFA set up for pc=1 located in entry.S */
+	
+	FDE_preamble(c2,is386,(L6-is386))
+	FDE_postamble()
+
+#endif
 
 /*
  * We depend on ET to be correct. This checks for 287/387.
diff -urP -I '\$Id:.*Exp \$' -X /usr/src/patch.exclude linux-2.6.0-akgdb/arch/i386/kernel/smpboot.c linux/arch/i386/kernel/smpboot.c
--- linux-2.6.0-akgdb/arch/i386/kernel/smpboot.c	2003-11-10 15:59:40.000000000 -0800
+++ linux/arch/i386/kernel/smpboot.c	2004-01-18 00:33:32.000000000 -0800
@@ -476,6 +476,9 @@
 
 	asm volatile(
 		"movl %0,%%esp\n\t"
+#ifdef CONFIG_KGDB
+		"pushl $1\n\t"
+#endif
 		"jmp *%1"
 		:
 		:"r" (current->thread.esp),"r" (current->thread.eip));
diff -urP -I '\$Id:.*Exp \$' -X /usr/src/patch.exclude linux-2.6.0-akgdb/include/linux/dwarf2-lang.h linux/include/linux/dwarf2-lang.h
--- linux-2.6.0-akgdb/include/linux/dwarf2-lang.h	1969-12-31 16:00:00.000000000 -0800
+++ linux/include/linux/dwarf2-lang.h	2004-01-22 13:06:43.000000000 -0800
@@ -0,0 +1,286 @@
+#ifndef DWARF2_LANG
+#define DWARF2_LANG
+
+/*
+ * This is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2, or (at your option) any later
+ * version.
+ */
+/*
+ * This file defines macros that allow generation of DWARF debug records
+ * for asm files.  This file is platform independent.  Register numbers
+ * (which are about the only thing that is platform dependent) are to be
+ * supplied by a platform defined file.
+ */
+/*
+ * We need this to work for both asm and C.  In asm we are using the 
+ * old comment trick to concatenate while C uses the new ANSI thing.
+ * Here we have concat macro...  The multi level thing is to allow and
+ * macros used in the names to be resolved prior to the cat (at which
+ * time they are no longer the same string).
+ */
+#define CAT3(a,b,c) _CAT3(a,b,c)
+#define _CAT3(a,b,c) __CAT3(a,b,c)
+#ifdef __ASSEMBLY__
+#define __CAT3(a,b,c) a/**/b/**/c
+#define IFC(a)
+#define IFN_C(a) a
+#define NL ;
+#define QUOTE_THIS(a) a 
+#define DWARF_preamble .section .debug_frame,"",@progbits;
+#else
+#define __CAT3(a,b,c) a ## b ## c
+#define IFC(a) a 
+#define IFN_C(a)
+#define NL \n\t
+#define QUOTE_THIS(a) _QUOTE_THIS(a)
+#define _QUOTE_THIS(a) #a
+/* Don't let CPP see the " and , \042=" \054=, */
+#define DWARF_preamble .section .debug_frame \054\042\042\054@progbits
+
+#endif
+#include <linux/dwarf2-defs.h>
+/*
+ * This macro starts a debug frame section.  The debug_frame describes
+ * where to find the registers that the enclosing function saved on
+ * entry.
+ *
+ * ORD is use by the label generator and should be the same as what is
+ * passed to CFI_postamble.
+ *
+ * pc,	pc register gdb ordinal.
+ *
+ * code_align this is the factor used to define locations or regions
+ * where the given definitions apply.  If you use labels to define these
+ * this should be 1.
+ *
+ * data_align this is the factor used to define register offsets.  If
+ * you use struct offset, this should be the size of the register in
+ * bytes or the negative of that.  This is how it is used: you will
+ * define a register as the reference register, say the stack pointer,
+ * then you will say where a register is located relative to this
+ * reference registers value, say 40 for register 3 (the gdb register
+ * number).  The <40> will be multiplied by <data_align> to define the
+ * byte offset of the given register (3, in this example).  So if your
+ * <40> is the byte offset and the reference register points at the
+ * begining, you would want 1 for the data_offset.  If <40> was the 40th
+ * 4-byte element in that structure you would want 4.  And if your
+ * reference register points at the end of the structure you would want
+ * a negative data_align value(and you would have to do other math as
+ * well).
+ */
+
+#define CFI_preamble(ORD, pc, code_align, data_align)	\
+         DWARF_preamble	NL				\
+	.align 4 NL					\
+        .globl CAT3(frame,_,ORD) NL			\
+CAT3(frame,_,ORD): NL					\
+	.long 7f-6f NL					\
+6:							\
+	.long	DW_CIE_ID NL				\
+	.byte	DW_CIE_VERSION NL			\
+	.byte 0	 NL					\
+	.uleb128 code_align NL				\
+	.sleb128 data_align NL				\
+	.byte pc NL
+
+/*
+ * After the above macro and prior to the CFI_postamble, you need to
+ * define the initial state.  This starts with defining the reference
+ * register and, usually the pc.  Here are some helper macros:
+ */
+
+#define CFA_define_reference(reg, offset)	\
+	.byte DW_CFA_def_cfa NL			\
+	.uleb128 reg NL				\
+	.uleb128 (offset) NL
+
+#define CFA_define_offset(reg, offset)		\
+	.byte (DW_CFA_offset + reg) NL		\
+	.uleb128 (offset) NL
+
+#define CFA_restore(reg)			\
+        .byte (DW_CFA_restore + reg) NL
+
+#define CFI_postamble()				\
+	.align 4 NL				\
+7: NL						\
+.previous NL
+/*
+ * So now your code pushs stuff on the stack, you need a new location
+ * and the rules for what to do.  This starts a running description of
+ * the call frame.  You need to describe what changes with respect to
+ * the call registers as the location of the pc moves through the code.
+ * The following builds an FDE (fram descriptor entry?).  Like the
+ * above, it has a preamble and a postamble.  It also is tied to the CFI
+ * above.
+ * The preamble macro is tied to the CFI thru the first parameter.  The 
+ * second is the code start address and then the code length.
+ */
+//         DWARF_preamble() NL				
+#define FDE_preamble(ORD, initial_address, length)	\
+        DWARF_preamble NL				\
+	.align 4 NL					\
+	.long 9f-8f NL					\
+8:							\
+	.long CAT3(frame,_,ORD) NL			\
+	.long initial_address NL			\
+	.long length NL
+
+#define FDE_postamble()				\
+	.align 4 NL				\
+9:	 NL					\
+.previous NL
+/*
+ * That done, you can now add registers, subtract registers, move the
+ * reference and even change the reference.  You can also define a new
+ * area of code the info applies to.  For discontinuous bits you should
+ * start a new FDE.  You may have as many as you like.
+ */
+
+/*
+ * To advance the stack address by <bytes> (0x3f max)
+ */
+
+#define CFA_advance_loc(bytes)			\
+	.byte DW_CFA_advance_loc+bytes NL
+
+/*
+ * This one is good for 0xff or 255
+ */
+#define CFA_advance_loc1(bytes)			\
+	.byte DW_CFA_advance_loc1 NL		\
+        .byte bytes NL
+
+
+/*
+ * With the above you can define all the register locations.  But
+ * suppose the reference register moves... Takes the new offset NOT an
+ * increment.  This is how esp is tracked if it is not saved.
+ */
+
+#define CFA_define_cfa_offset(offset)		\
+	.byte DW_CFA_def_cfa_offset NL		\
+	.uleb128 (offset) NL
+/*
+ * Or suppose you want to use a different reference register...
+ */
+#define CFA_define_cfa_register(reg)		\
+	.byte DW_CFA_def_cfa_register NL	\
+	.uleb128 reg NL
+
+/*
+ * If you want to mess with the stack pointer, here is the expression.
+ * The stack starts empty.
+ */
+#define CFA_def_cfa_expression 			\
+        .byte DW_CFA_def_cfa_expression	NL	\
+	.uleb128 20f-10f NL			\
+10:     NL
+/*
+ * This expression is to be used for other regs.  The stack starts with the
+ * stack address.
+ */
+
+#define CFA_expression(reg)			\
+        .byte DW_CFA_expression	 NL		\
+        .uleb128 reg NL				\
+	.uleb128 20f-10f NL			\
+10:     NL
+/*
+ * Here we do the expression stuff.  You should code the above followed
+ *  by expression OPs followed by CFA_expression_end.
+ */
+
+
+#define CFA_expression_end			\
+20:	 NL
+
+#define CFA_exp_OP_const4s(a)			\
+        .byte DW_OP_const4s NL			\
+        .long a NL
+
+#define  CFA_exp_OP_swap  .byte DW_OP_swap NL
+#define  CFA_exp_OP_dup  .byte DW_OP_dup NL
+#define  CFA_exp_OP_drop  .byte DW_OP_drop NL
+/*
+ * All these work on the top two elements on the stack, replacing them
+ * with the result.  Top comes first where it matters.  True is 1, false 0.
+ */
+#define  CFA_exp_OP_deref .byte DW_OP_deref NL
+#define  CFA_exp_OP_and   .byte DW_OP_and NL
+#define  CFA_exp_OP_div   .byte DW_OP_div NL
+#define  CFA_exp_OP_minus .byte DW_OP_minus NL
+#define  CFA_exp_OP_mod   .byte DW_OP_mod NL
+#define  CFA_exp_OP_neg   .byte DW_OP_neg NL
+#define  CFA_exp_OP_plus  .byte DW_OP_plus NL
+#define  CFA_exp_OP_not   .byte DW_OP_not NL
+#define  CFA_exp_OP_or    .byte DW_OP_or NL
+#define  CFA_exp_OP_xor   .byte DW_OP_xor NL
+#define  CFA_exp_OP_le    .byte DW_OP_le NL
+#define  CFA_exp_OP_ge    .byte DW_OP_ge NL
+#define  CFA_exp_OP_eq    .byte DW_OP_eq NL
+#define  CFA_exp_OP_lt    .byte DW_OP_lt NL
+#define  CFA_exp_OP_gt    .byte DW_OP_gt NL
+#define  CFA_exp_OP_ne    .byte DW_OP_ne NL
+/*
+ * These take a parameter as noted
+ */
+/*
+ * Unconditional skip to loc. loc is a label (loc:) 
+ */
+#define CFA_exp_OP_skip(loc)			\
+         .byte DW_OP_skip  NL 			\
+	 .hword  loc-.-2 NL
+/*
+ * Conditional skip to loc (TOS != 0, TOS--) (loc is a label)
+ */
+#define CFA_exp_OP_bra(loc)			\
+         .byte DW_OP_bra NL			\
+	 .hword loc-.-2 NL
+
+/*
+ * TOS += no (an unsigned number)
+ */
+#define CFA_exp_OP_plus_uconst(no)		\
+         .byte DW_OP_plus_uconst NL		\
+         .uleb128 no NL
+
+/*
+ * ++TOS = no (a unsigned number)
+ */
+#define CFA_exp_OP_constu(no)			\
+         .byte DW_OP_constu NL			\
+	 .uleb128 no NL
+/*
+ * ++TOS = no (a signed number)
+ */
+#define CFA_exp_OP_consts(no)			\
+         .byte DW_OP_consts NL			\
+	 .sleb128 no NL
+/*
+ * ++TOS = no (an unsigned byte)
+ */
+#define CFA_exp_OP_const1u(no)			\
+         .byte DW_OP_const1u NL			\
+	 .byte no NL
+
+
+/*
+ * ++TOS = no (a address)
+ */
+#define CFA_exp_OP_addr(no)			\
+         .byte DW_OP_addr NL			\
+	 .long no NL
+
+/*
+ * Push current frames value for "reg" + offset
+ * We take advantage of the opcode assignments to make this a litteral reg
+ * rather than use the DW_OP_bregx opcode.
+ */
+
+#define CFA_exp_OP_breg(reg,offset)		\
+         .byte DW_OP_breg0+reg NL		\
+         .sleb128 offset NL
+#endif
diff -urP -I '\$Id:.*Exp \$' -X /usr/src/patch.exclude linux-2.6.0-akgdb/include/linux/dwarf2.h linux/include/linux/dwarf2.h
--- linux-2.6.0-akgdb/include/linux/dwarf2.h	1969-12-31 16:00:00.000000000 -0800
+++ linux/include/linux/dwarf2.h	2004-01-15 00:26:12.000000000 -0800
@@ -0,0 +1,775 @@
+/* Declarations and definitions of codes relating to the DWARF2 symbolic
+   debugging information format.
+   Copyright (C) 1992, 1993, 1995, 1996, 1997, 1999, 2000, 2001, 2002,
+   2003 Free Software Foundation, Inc.
+
+   Written by Gary Funck (gary@intrepid.com) The Ada Joint Program
+   Office (AJPO), Florida State Unviversity and Silicon Graphics Inc.
+   provided support for this effort -- June 21, 1995.
+
+   Derived from the DWARF 1 implementation written by Ron Guilmette
+   (rfg@netcom.com), November 1990.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it under
+   the terms of the GNU General Public License as published by the Free
+   Software Foundation; either version 2, or (at your option) any later
+   version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING.  If not, write to the Free
+   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+   02111-1307, USA.  */
+
+/* This file is derived from the DWARF specification (a public document)
+   Revision 2.0.0 (July 27, 1993) developed by the UNIX International
+   Programming Languages Special Interest Group (UI/PLSIG) and distributed
+   by UNIX International.  Copies of this specification are available from
+   UNIX International, 20 Waterview Boulevard, Parsippany, NJ, 07054.
+
+   This file also now contains definitions from the DWARF 3 specification.  */
+
+/* This file is shared between GCC and GDB, and should not contain
+   prototypes.  */
+
+#ifndef _ELF_DWARF2_H
+#define _ELF_DWARF2_H
+
+/* Structure found in the .debug_line section.  */
+typedef struct
+{
+  unsigned char li_length          [4];
+  unsigned char li_version         [2];
+  unsigned char li_prologue_length [4];
+  unsigned char li_min_insn_length [1];
+  unsigned char li_default_is_stmt [1];
+  unsigned char li_line_base       [1];
+  unsigned char li_line_range      [1];
+  unsigned char li_opcode_base     [1];
+}
+DWARF2_External_LineInfo;
+
+typedef struct
+{
+  unsigned long  li_length;
+  unsigned short li_version;
+  unsigned int   li_prologue_length;
+  unsigned char  li_min_insn_length;
+  unsigned char  li_default_is_stmt;
+  int            li_line_base;
+  unsigned char  li_line_range;
+  unsigned char  li_opcode_base;
+}
+DWARF2_Internal_LineInfo;
+
+/* Structure found in .debug_pubnames section.  */
+typedef struct
+{
+  unsigned char pn_length  [4];
+  unsigned char pn_version [2];
+  unsigned char pn_offset  [4];
+  unsigned char pn_size    [4];
+}
+DWARF2_External_PubNames;
+
+typedef struct
+{
+  unsigned long  pn_length;
+  unsigned short pn_version;
+  unsigned long  pn_offset;
+  unsigned long  pn_size;
+}
+DWARF2_Internal_PubNames;
+
+/* Structure found in .debug_info section.  */
+typedef struct
+{
+  unsigned char  cu_length        [4];
+  unsigned char  cu_version       [2];
+  unsigned char  cu_abbrev_offset [4];
+  unsigned char  cu_pointer_size  [1];
+}
+DWARF2_External_CompUnit;
+
+typedef struct
+{
+  unsigned long  cu_length;
+  unsigned short cu_version;
+  unsigned long  cu_abbrev_offset;
+  unsigned char  cu_pointer_size;
+}
+DWARF2_Internal_CompUnit;
+
+typedef struct
+{
+  unsigned char  ar_length       [4];
+  unsigned char  ar_version      [2];
+  unsigned char  ar_info_offset  [4];
+  unsigned char  ar_pointer_size [1];
+  unsigned char  ar_segment_size [1];
+}
+DWARF2_External_ARange;
+
+typedef struct
+{
+  unsigned long  ar_length;
+  unsigned short ar_version;
+  unsigned long  ar_info_offset;
+  unsigned char  ar_pointer_size;
+  unsigned char  ar_segment_size;
+}
+DWARF2_Internal_ARange;
+
+
+/* Tag names and codes.  */
+enum dwarf_tag
+  {
+    DW_TAG_padding = 0x00,
+    DW_TAG_array_type = 0x01,
+    DW_TAG_class_type = 0x02,
+    DW_TAG_entry_point = 0x03,
+    DW_TAG_enumeration_type = 0x04,
+    DW_TAG_formal_parameter = 0x05,
+    DW_TAG_imported_declaration = 0x08,
+    DW_TAG_label = 0x0a,
+    DW_TAG_lexical_block = 0x0b,
+    DW_TAG_member = 0x0d,
+    DW_TAG_pointer_type = 0x0f,
+    DW_TAG_reference_type = 0x10,
+    DW_TAG_compile_unit = 0x11,
+    DW_TAG_string_type = 0x12,
+    DW_TAG_structure_type = 0x13,
+    DW_TAG_subroutine_type = 0x15,
+    DW_TAG_typedef = 0x16,
+    DW_TAG_union_type = 0x17,
+    DW_TAG_unspecified_parameters = 0x18,
+    DW_TAG_variant = 0x19,
+    DW_TAG_common_block = 0x1a,
+    DW_TAG_common_inclusion = 0x1b,
+    DW_TAG_inheritance = 0x1c,
+    DW_TAG_inlined_subroutine = 0x1d,
+    DW_TAG_module = 0x1e,
+    DW_TAG_ptr_to_member_type = 0x1f,
+    DW_TAG_set_type = 0x20,
+    DW_TAG_subrange_type = 0x21,
+    DW_TAG_with_stmt = 0x22,
+    DW_TAG_access_declaration = 0x23,
+    DW_TAG_base_type = 0x24,
+    DW_TAG_catch_block = 0x25,
+    DW_TAG_const_type = 0x26,
+    DW_TAG_constant = 0x27,
+    DW_TAG_enumerator = 0x28,
+    DW_TAG_file_type = 0x29,
+    DW_TAG_friend = 0x2a,
+    DW_TAG_namelist = 0x2b,
+    DW_TAG_namelist_item = 0x2c,
+    DW_TAG_packed_type = 0x2d,
+    DW_TAG_subprogram = 0x2e,
+    DW_TAG_template_type_param = 0x2f,
+    DW_TAG_template_value_param = 0x30,
+    DW_TAG_thrown_type = 0x31,
+    DW_TAG_try_block = 0x32,
+    DW_TAG_variant_part = 0x33,
+    DW_TAG_variable = 0x34,
+    DW_TAG_volatile_type = 0x35,
+    /* DWARF 3.  */
+    DW_TAG_dwarf_procedure = 0x36,
+    DW_TAG_restrict_type = 0x37,
+    DW_TAG_interface_type = 0x38,
+    DW_TAG_namespace = 0x39,
+    DW_TAG_imported_module = 0x3a,
+    DW_TAG_unspecified_type = 0x3b,
+    DW_TAG_partial_unit = 0x3c,
+    DW_TAG_imported_unit = 0x3d,
+    /* SGI/MIPS Extensions.  */
+    DW_TAG_MIPS_loop = 0x4081,
+    /* HP extensions.  See: ftp://ftp.hp.com/pub/lang/tools/WDB/wdb-4.0.tar.gz .  */
+    DW_TAG_HP_array_descriptor = 0x4090,
+    /* GNU extensions.  */
+    DW_TAG_format_label = 0x4101,	/* For FORTRAN 77 and Fortran 90.  */
+    DW_TAG_function_template = 0x4102,	/* For C++.  */
+    DW_TAG_class_template = 0x4103,	/* For C++.  */
+    DW_TAG_GNU_BINCL = 0x4104,
+    DW_TAG_GNU_EINCL = 0x4105,
+    /* Extensions for UPC.  See: http://upc.gwu.edu/~upc.  */
+    DW_TAG_upc_shared_type = 0x8765,
+    DW_TAG_upc_strict_type = 0x8766,
+    DW_TAG_upc_relaxed_type = 0x8767,
+    /* PGI (STMicroelectronics) extensions.  No documentation available.  */
+    DW_TAG_PGI_kanji_type      = 0xA000,
+    DW_TAG_PGI_interface_block = 0xA020
+  };
+
+#define DW_TAG_lo_user	0x4080
+#define DW_TAG_hi_user	0xffff
+
+/* Flag that tells whether entry has a child or not.  */
+#define DW_children_no   0
+#define	DW_children_yes  1
+
+/* Form names and codes.  */
+enum dwarf_form
+  {
+    DW_FORM_addr = 0x01,
+    DW_FORM_block2 = 0x03,
+    DW_FORM_block4 = 0x04,
+    DW_FORM_data2 = 0x05,
+    DW_FORM_data4 = 0x06,
+    DW_FORM_data8 = 0x07,
+    DW_FORM_string = 0x08,
+    DW_FORM_block = 0x09,
+    DW_FORM_block1 = 0x0a,
+    DW_FORM_data1 = 0x0b,
+    DW_FORM_flag = 0x0c,
+    DW_FORM_sdata = 0x0d,
+    DW_FORM_strp = 0x0e,
+    DW_FORM_udata = 0x0f,
+    DW_FORM_ref_addr = 0x10,
+    DW_FORM_ref1 = 0x11,
+    DW_FORM_ref2 = 0x12,
+    DW_FORM_ref4 = 0x13,
+    DW_FORM_ref8 = 0x14,
+    DW_FORM_ref_udata = 0x15,
+    DW_FORM_indirect = 0x16
+  };
+
+/* Attribute names and codes.  */
+enum dwarf_attribute
+  {
+    DW_AT_sibling = 0x01,
+    DW_AT_location = 0x02,
+    DW_AT_name = 0x03,
+    DW_AT_ordering = 0x09,
+    DW_AT_subscr_data = 0x0a,
+    DW_AT_byte_size = 0x0b,
+    DW_AT_bit_offset = 0x0c,
+    DW_AT_bit_size = 0x0d,
+    DW_AT_element_list = 0x0f,
+    DW_AT_stmt_list = 0x10,
+    DW_AT_low_pc = 0x11,
+    DW_AT_high_pc = 0x12,
+    DW_AT_language = 0x13,
+    DW_AT_member = 0x14,
+    DW_AT_discr = 0x15,
+    DW_AT_discr_value = 0x16,
+    DW_AT_visibility = 0x17,
+    DW_AT_import = 0x18,
+    DW_AT_string_length = 0x19,
+    DW_AT_common_reference = 0x1a,
+    DW_AT_comp_dir = 0x1b,
+    DW_AT_const_value = 0x1c,
+    DW_AT_containing_type = 0x1d,
+    DW_AT_default_value = 0x1e,
+    DW_AT_inline = 0x20,
+    DW_AT_is_optional = 0x21,
+    DW_AT_lower_bound = 0x22,
+    DW_AT_producer = 0x25,
+    DW_AT_prototyped = 0x27,
+    DW_AT_return_addr = 0x2a,
+    DW_AT_start_scope = 0x2c,
+    DW_AT_stride_size = 0x2e,
+    DW_AT_upper_bound = 0x2f,
+    DW_AT_abstract_origin = 0x31,
+    DW_AT_accessibility = 0x32,
+    DW_AT_address_class = 0x33,
+    DW_AT_artificial = 0x34,
+    DW_AT_base_types = 0x35,
+    DW_AT_calling_convention = 0x36,
+    DW_AT_count = 0x37,
+    DW_AT_data_member_location = 0x38,
+    DW_AT_decl_column = 0x39,
+    DW_AT_decl_file = 0x3a,
+    DW_AT_decl_line = 0x3b,
+    DW_AT_declaration = 0x3c,
+    DW_AT_discr_list = 0x3d,
+    DW_AT_encoding = 0x3e,
+    DW_AT_external = 0x3f,
+    DW_AT_frame_base = 0x40,
+    DW_AT_friend = 0x41,
+    DW_AT_identifier_case = 0x42,
+    DW_AT_macro_info = 0x43,
+    DW_AT_namelist_items = 0x44,
+    DW_AT_priority = 0x45,
+    DW_AT_segment = 0x46,
+    DW_AT_specification = 0x47,
+    DW_AT_static_link = 0x48,
+    DW_AT_type = 0x49,
+    DW_AT_use_location = 0x4a,
+    DW_AT_variable_parameter = 0x4b,
+    DW_AT_virtuality = 0x4c,
+    DW_AT_vtable_elem_location = 0x4d,
+    /* DWARF 3 values.  */
+    DW_AT_allocated     = 0x4e,
+    DW_AT_associated    = 0x4f,
+    DW_AT_data_location = 0x50,
+    DW_AT_stride        = 0x51,
+    DW_AT_entry_pc      = 0x52,
+    DW_AT_use_UTF8      = 0x53,
+    DW_AT_extension     = 0x54,
+    DW_AT_ranges        = 0x55,
+    DW_AT_trampoline    = 0x56,
+    DW_AT_call_column   = 0x57,
+    DW_AT_call_file     = 0x58,
+    DW_AT_call_line     = 0x59,
+    /* SGI/MIPS extensions.  */
+    DW_AT_MIPS_fde = 0x2001,
+    DW_AT_MIPS_loop_begin = 0x2002,
+    DW_AT_MIPS_tail_loop_begin = 0x2003,
+    DW_AT_MIPS_epilog_begin = 0x2004,
+    DW_AT_MIPS_loop_unroll_factor = 0x2005,
+    DW_AT_MIPS_software_pipeline_depth = 0x2006,
+    DW_AT_MIPS_linkage_name = 0x2007,
+    DW_AT_MIPS_stride = 0x2008,
+    DW_AT_MIPS_abstract_name = 0x2009,
+    DW_AT_MIPS_clone_origin = 0x200a,
+    DW_AT_MIPS_has_inlines = 0x200b,
+    /* HP extensions.  */
+    DW_AT_HP_block_index         = 0x2000,
+    DW_AT_HP_unmodifiable        = 0x2001, /* Same as DW_AT_MIPS_fde.  */
+    DW_AT_HP_actuals_stmt_list   = 0x2010,
+    DW_AT_HP_proc_per_section    = 0x2011,
+    DW_AT_HP_raw_data_ptr        = 0x2012,
+    DW_AT_HP_pass_by_reference   = 0x2013,
+    DW_AT_HP_opt_level           = 0x2014,
+    DW_AT_HP_prof_version_id     = 0x2015,
+    DW_AT_HP_opt_flags           = 0x2016,
+    DW_AT_HP_cold_region_low_pc  = 0x2017,
+    DW_AT_HP_cold_region_high_pc = 0x2018,
+    DW_AT_HP_all_variables_modifiable = 0x2019,
+    DW_AT_HP_linkage_name        = 0x201a,
+    DW_AT_HP_prof_flags          = 0x201b,  /* In comp unit of procs_info for -g.  */
+    /* GNU extensions.  */
+    DW_AT_sf_names   = 0x2101,
+    DW_AT_src_info   = 0x2102,
+    DW_AT_mac_info   = 0x2103,
+    DW_AT_src_coords = 0x2104,
+    DW_AT_body_begin = 0x2105,
+    DW_AT_body_end   = 0x2106,
+    DW_AT_GNU_vector = 0x2107,
+    /* VMS extensions.  */
+    DW_AT_VMS_rtnbeg_pd_address = 0x2201,
+    /* UPC extension.  */
+    DW_AT_upc_threads_scaled = 0x3210,
+    /* PGI (STMicroelectronics) extensions.  */
+    DW_AT_PGI_lbase    = 0x3a00,
+    DW_AT_PGI_soffset  = 0x3a01,
+    DW_AT_PGI_lstride  = 0x3a02
+  };
+
+#define DW_AT_lo_user	0x2000	/* Implementation-defined range start.  */
+#define DW_AT_hi_user	0x3ff0	/* Implementation-defined range end.  */
+
+/* Location atom names and codes.  */
+enum dwarf_location_atom
+  {
+    DW_OP_addr = 0x03,
+    DW_OP_deref = 0x06,
+    DW_OP_const1u = 0x08,
+    DW_OP_const1s = 0x09,
+    DW_OP_const2u = 0x0a,
+    DW_OP_const2s = 0x0b,
+    DW_OP_const4u = 0x0c,
+    DW_OP_const4s = 0x0d,
+    DW_OP_const8u = 0x0e,
+    DW_OP_const8s = 0x0f,
+    DW_OP_constu = 0x10,
+    DW_OP_consts = 0x11,
+    DW_OP_dup = 0x12,
+    DW_OP_drop = 0x13,
+    DW_OP_over = 0x14,
+    DW_OP_pick = 0x15,
+    DW_OP_swap = 0x16,
+    DW_OP_rot = 0x17,
+    DW_OP_xderef = 0x18,
+    DW_OP_abs = 0x19,
+    DW_OP_and = 0x1a,
+    DW_OP_div = 0x1b,
+    DW_OP_minus = 0x1c,
+    DW_OP_mod = 0x1d,
+    DW_OP_mul = 0x1e,
+    DW_OP_neg = 0x1f,
+    DW_OP_not = 0x20,
+    DW_OP_or = 0x21,
+    DW_OP_plus = 0x22,
+    DW_OP_plus_uconst = 0x23,
+    DW_OP_shl = 0x24,
+    DW_OP_shr = 0x25,
+    DW_OP_shra = 0x26,
+    DW_OP_xor = 0x27,
+    DW_OP_bra = 0x28,
+    DW_OP_eq = 0x29,
+    DW_OP_ge = 0x2a,
+    DW_OP_gt = 0x2b,
+    DW_OP_le = 0x2c,
+    DW_OP_lt = 0x2d,
+    DW_OP_ne = 0x2e,
+    DW_OP_skip = 0x2f,
+    DW_OP_lit0 = 0x30,
+    DW_OP_lit1 = 0x31,
+    DW_OP_lit2 = 0x32,
+    DW_OP_lit3 = 0x33,
+    DW_OP_lit4 = 0x34,
+    DW_OP_lit5 = 0x35,
+    DW_OP_lit6 = 0x36,
+    DW_OP_lit7 = 0x37,
+    DW_OP_lit8 = 0x38,
+    DW_OP_lit9 = 0x39,
+    DW_OP_lit10 = 0x3a,
+    DW_OP_lit11 = 0x3b,
+    DW_OP_lit12 = 0x3c,
+    DW_OP_lit13 = 0x3d,
+    DW_OP_lit14 = 0x3e,
+    DW_OP_lit15 = 0x3f,
+    DW_OP_lit16 = 0x40,
+    DW_OP_lit17 = 0x41,
+    DW_OP_lit18 = 0x42,
+    DW_OP_lit19 = 0x43,
+    DW_OP_lit20 = 0x44,
+    DW_OP_lit21 = 0x45,
+    DW_OP_lit22 = 0x46,
+    DW_OP_lit23 = 0x47,
+    DW_OP_lit24 = 0x48,
+    DW_OP_lit25 = 0x49,
+    DW_OP_lit26 = 0x4a,
+    DW_OP_lit27 = 0x4b,
+    DW_OP_lit28 = 0x4c,
+    DW_OP_lit29 = 0x4d,
+    DW_OP_lit30 = 0x4e,
+    DW_OP_lit31 = 0x4f,
+    DW_OP_reg0 = 0x50,
+    DW_OP_reg1 = 0x51,
+    DW_OP_reg2 = 0x52,
+    DW_OP_reg3 = 0x53,
+    DW_OP_reg4 = 0x54,
+    DW_OP_reg5 = 0x55,
+    DW_OP_reg6 = 0x56,
+    DW_OP_reg7 = 0x57,
+    DW_OP_reg8 = 0x58,
+    DW_OP_reg9 = 0x59,
+    DW_OP_reg10 = 0x5a,
+    DW_OP_reg11 = 0x5b,
+    DW_OP_reg12 = 0x5c,
+    DW_OP_reg13 = 0x5d,
+    DW_OP_reg14 = 0x5e,
+    DW_OP_reg15 = 0x5f,
+    DW_OP_reg16 = 0x60,
+    DW_OP_reg17 = 0x61,
+    DW_OP_reg18 = 0x62,
+    DW_OP_reg19 = 0x63,
+    DW_OP_reg20 = 0x64,
+    DW_OP_reg21 = 0x65,
+    DW_OP_reg22 = 0x66,
+    DW_OP_reg23 = 0x67,
+    DW_OP_reg24 = 0x68,
+    DW_OP_reg25 = 0x69,
+    DW_OP_reg26 = 0x6a,
+    DW_OP_reg27 = 0x6b,
+    DW_OP_reg28 = 0x6c,
+    DW_OP_reg29 = 0x6d,
+    DW_OP_reg30 = 0x6e,
+    DW_OP_reg31 = 0x6f,
+    DW_OP_breg0 = 0x70,
+    DW_OP_breg1 = 0x71,
+    DW_OP_breg2 = 0x72,
+    DW_OP_breg3 = 0x73,
+    DW_OP_breg4 = 0x74,
+    DW_OP_breg5 = 0x75,
+    DW_OP_breg6 = 0x76,
+    DW_OP_breg7 = 0x77,
+    DW_OP_breg8 = 0x78,
+    DW_OP_breg9 = 0x79,
+    DW_OP_breg10 = 0x7a,
+    DW_OP_breg11 = 0x7b,
+    DW_OP_breg12 = 0x7c,
+    DW_OP_breg13 = 0x7d,
+    DW_OP_breg14 = 0x7e,
+    DW_OP_breg15 = 0x7f,
+    DW_OP_breg16 = 0x80,
+    DW_OP_breg17 = 0x81,
+    DW_OP_breg18 = 0x82,
+    DW_OP_breg19 = 0x83,
+    DW_OP_breg20 = 0x84,
+    DW_OP_breg21 = 0x85,
+    DW_OP_breg22 = 0x86,
+    DW_OP_breg23 = 0x87,
+    DW_OP_breg24 = 0x88,
+    DW_OP_breg25 = 0x89,
+    DW_OP_breg26 = 0x8a,
+    DW_OP_breg27 = 0x8b,
+    DW_OP_breg28 = 0x8c,
+    DW_OP_breg29 = 0x8d,
+    DW_OP_breg30 = 0x8e,
+    DW_OP_breg31 = 0x8f,
+    DW_OP_regx = 0x90,
+    DW_OP_fbreg = 0x91,
+    DW_OP_bregx = 0x92,
+    DW_OP_piece = 0x93,
+    DW_OP_deref_size = 0x94,
+    DW_OP_xderef_size = 0x95,
+    DW_OP_nop = 0x96,
+    /* DWARF 3 extensions.  */
+    DW_OP_push_object_address = 0x97,
+    DW_OP_call2 = 0x98,
+    DW_OP_call4 = 0x99,
+    DW_OP_call_ref = 0x9a,
+    /* GNU extensions.  */
+    DW_OP_GNU_push_tls_address = 0xe0,
+    /* HP extensions.  */
+    DW_OP_HP_unknown     = 0xe0, /* Ouch, the same as GNU_push_tls_address.  */
+    DW_OP_HP_is_value    = 0xe1,
+    DW_OP_HP_fltconst4   = 0xe2,
+    DW_OP_HP_fltconst8   = 0xe3,
+    DW_OP_HP_mod_range   = 0xe4,
+    DW_OP_HP_unmod_range = 0xe5,
+    DW_OP_HP_tls         = 0xe6
+  };
+
+#define DW_OP_lo_user	0xe0	/* Implementation-defined range start.  */
+#define DW_OP_hi_user	0xff	/* Implementation-defined range end.  */
+
+/* Type encodings.  */
+enum dwarf_type
+  {
+    DW_ATE_void = 0x0,
+    DW_ATE_address = 0x1,
+    DW_ATE_boolean = 0x2,
+    DW_ATE_complex_float = 0x3,
+    DW_ATE_float = 0x4,
+    DW_ATE_signed = 0x5,
+    DW_ATE_signed_char = 0x6,
+    DW_ATE_unsigned = 0x7,
+    DW_ATE_unsigned_char = 0x8,
+    /* DWARF 3.  */
+    DW_ATE_imaginary_float = 0x9,
+    /* HP extensions.  */
+    DW_ATE_HP_float80            = 0x80, /* Floating-point (80 bit).  */
+    DW_ATE_HP_complex_float80    = 0x81, /* Complex floating-point (80 bit).  */
+    DW_ATE_HP_float128           = 0x82, /* Floating-point (128 bit).  */
+    DW_ATE_HP_complex_float128   = 0x83, /* Complex floating-point (128 bit).  */
+    DW_ATE_HP_floathpintel       = 0x84, /* Floating-point (82 bit IA64).  */
+    DW_ATE_HP_imaginary_float80  = 0x85,
+    DW_ATE_HP_imaginary_float128 = 0x86
+  };
+
+#define	DW_ATE_lo_user 0x80
+#define	DW_ATE_hi_user 0xff
+
+/* Array ordering names and codes.  */
+enum dwarf_array_dim_ordering
+  {
+    DW_ORD_row_major = 0,
+    DW_ORD_col_major = 1
+  };
+
+/* Access attribute.  */
+enum dwarf_access_attribute
+  {
+    DW_ACCESS_public = 1,
+    DW_ACCESS_protected = 2,
+    DW_ACCESS_private = 3
+  };
+
+/* Visibility.  */
+enum dwarf_visibility_attribute
+  {
+    DW_VIS_local = 1,
+    DW_VIS_exported = 2,
+    DW_VIS_qualified = 3
+  };
+
+/* Virtuality.  */
+enum dwarf_virtuality_attribute
+  {
+    DW_VIRTUALITY_none = 0,
+    DW_VIRTUALITY_virtual = 1,
+    DW_VIRTUALITY_pure_virtual = 2
+  };
+
+/* Case sensitivity.  */
+enum dwarf_id_case
+  {
+    DW_ID_case_sensitive = 0,
+    DW_ID_up_case = 1,
+    DW_ID_down_case = 2,
+    DW_ID_case_insensitive = 3
+  };
+
+/* Calling convention.  */
+enum dwarf_calling_convention
+  {
+    DW_CC_normal = 0x1,
+    DW_CC_program = 0x2,
+    DW_CC_nocall = 0x3
+  };
+
+#define DW_CC_lo_user 0x40
+#define DW_CC_hi_user 0xff
+
+/* Inline attribute.  */
+enum dwarf_inline_attribute
+  {
+    DW_INL_not_inlined = 0,
+    DW_INL_inlined = 1,
+    DW_INL_declared_not_inlined = 2,
+    DW_INL_declared_inlined = 3
+  };
+
+/* Discriminant lists.  */
+enum dwarf_discrim_list
+  {
+    DW_DSC_label = 0,
+    DW_DSC_range = 1
+  };
+
+/* Line number opcodes.  */
+enum dwarf_line_number_ops
+  {
+    DW_LNS_extended_op = 0,
+    DW_LNS_copy = 1,
+    DW_LNS_advance_pc = 2,
+    DW_LNS_advance_line = 3,
+    DW_LNS_set_file = 4,
+    DW_LNS_set_column = 5,
+    DW_LNS_negate_stmt = 6,
+    DW_LNS_set_basic_block = 7,
+    DW_LNS_const_add_pc = 8,
+    DW_LNS_fixed_advance_pc = 9,
+    /* DWARF 3.  */
+    DW_LNS_set_prologue_end = 10,
+    DW_LNS_set_epilogue_begin = 11,
+    DW_LNS_set_isa = 12
+  };
+
+/* Line number extended opcodes.  */
+enum dwarf_line_number_x_ops
+  {
+    DW_LNE_end_sequence = 1,
+    DW_LNE_set_address = 2,
+    DW_LNE_define_file = 3,
+    /* HP extensions.  */
+    DW_LNE_HP_negate_is_UV_update      = 0x11,
+    DW_LNE_HP_push_context             = 0x12,
+    DW_LNE_HP_pop_context              = 0x13,
+    DW_LNE_HP_set_file_line_column     = 0x14,
+    DW_LNE_HP_set_routine_name         = 0x15,
+    DW_LNE_HP_set_sequence             = 0x16,
+    DW_LNE_HP_negate_post_semantics    = 0x17,
+    DW_LNE_HP_negate_function_exit     = 0x18,
+    DW_LNE_HP_negate_front_end_logical = 0x19,
+    DW_LNE_HP_define_proc              = 0x20
+  };
+
+/* Call frame information.  */
+enum dwarf_call_frame_info
+  {
+    DW_CFA_advance_loc = 0x40,
+    DW_CFA_offset = 0x80,
+    DW_CFA_restore = 0xc0,
+    DW_CFA_nop = 0x00,
+    DW_CFA_set_loc = 0x01,
+    DW_CFA_advance_loc1 = 0x02,
+    DW_CFA_advance_loc2 = 0x03,
+    DW_CFA_advance_loc4 = 0x04,
+    DW_CFA_offset_extended = 0x05,
+    DW_CFA_restore_extended = 0x06,
+    DW_CFA_undefined = 0x07,
+    DW_CFA_same_value = 0x08,
+    DW_CFA_register = 0x09,
+    DW_CFA_remember_state = 0x0a,
+    DW_CFA_restore_state = 0x0b,
+    DW_CFA_def_cfa = 0x0c,
+    DW_CFA_def_cfa_register = 0x0d,
+    DW_CFA_def_cfa_offset = 0x0e,
+    /* DWARF 3.  */
+    DW_CFA_def_cfa_expression = 0x0f,
+    DW_CFA_expression = 0x10,
+    DW_CFA_offset_extended_sf = 0x11,
+    DW_CFA_def_cfa_sf = 0x12,
+    DW_CFA_def_cfa_offset_sf = 0x13,
+    /* SGI/MIPS specific.  */
+    DW_CFA_MIPS_advance_loc8 = 0x1d,
+    /* GNU extensions.  */
+    DW_CFA_GNU_window_save = 0x2d,
+    DW_CFA_GNU_args_size = 0x2e,
+    DW_CFA_GNU_negative_offset_extended = 0x2f
+  };
+
+#define DW_CIE_ID	  0xffffffff
+#define DW_CIE_VERSION	  1
+
+#define DW_CFA_extended   0
+#define DW_CFA_lo_user    0x1c
+#define DW_CFA_hi_user    0x3f
+
+#define DW_CHILDREN_no		     0x00
+#define DW_CHILDREN_yes		     0x01
+
+#define DW_ADDR_none		0
+
+/* Source language names and codes.  */
+enum dwarf_source_language
+  {
+    DW_LANG_C89 = 0x0001,
+    DW_LANG_C = 0x0002,
+    DW_LANG_Ada83 = 0x0003,
+    DW_LANG_C_plus_plus = 0x0004,
+    DW_LANG_Cobol74 = 0x0005,
+    DW_LANG_Cobol85 = 0x0006,
+    DW_LANG_Fortran77 = 0x0007,
+    DW_LANG_Fortran90 = 0x0008,
+    DW_LANG_Pascal83 = 0x0009,
+    DW_LANG_Modula2 = 0x000a,
+    DW_LANG_Java = 0x000b,
+    /* DWARF 3.  */
+    DW_LANG_C99 = 0x000c,
+    DW_LANG_Ada95 = 0x000d,
+    DW_LANG_Fortran95 = 0x000e,
+    /* MIPS.  */
+    DW_LANG_Mips_Assembler = 0x8001,
+    /* UPC.  */
+    DW_LANG_Upc = 0x8765
+  };
+
+#define DW_LANG_lo_user 0x8000	/* Implementation-defined range start.  */
+#define DW_LANG_hi_user 0xffff	/* Implementation-defined range start.  */
+
+/* Names and codes for macro information.  */
+enum dwarf_macinfo_record_type
+  {
+    DW_MACINFO_define = 1,
+    DW_MACINFO_undef = 2,
+    DW_MACINFO_start_file = 3,
+    DW_MACINFO_end_file = 4,
+    DW_MACINFO_vendor_ext = 255
+  };
+\f
+/* @@@ For use with GNU frame unwind information.  */
+
+#define DW_EH_PE_absptr		0x00
+#define DW_EH_PE_omit		0xff
+
+#define DW_EH_PE_uleb128	0x01
+#define DW_EH_PE_udata2		0x02
+#define DW_EH_PE_udata4		0x03
+#define DW_EH_PE_udata8		0x04
+#define DW_EH_PE_sleb128	0x09
+#define DW_EH_PE_sdata2		0x0A
+#define DW_EH_PE_sdata4		0x0B
+#define DW_EH_PE_sdata8		0x0C
+#define DW_EH_PE_signed		0x08
+
+#define DW_EH_PE_pcrel		0x10
+#define DW_EH_PE_textrel	0x20
+#define DW_EH_PE_datarel	0x30
+#define DW_EH_PE_funcrel	0x40
+#define DW_EH_PE_aligned	0x50
+
+#define DW_EH_PE_indirect	0x80
+
+#endif /* _ELF_DWARF2_H */
Binary files linux-2.6.0-akgdb/scripts/bin2c and linux/scripts/bin2c differ
diff -urP -I '\$Id:.*Exp \$' -X /usr/src/patch.exclude linux-2.6.0-akgdb/scripts/dwarfh.awk linux/scripts/dwarfh.awk
--- linux-2.6.0-akgdb/scripts/dwarfh.awk	1969-12-31 16:00:00.000000000 -0800
+++ linux/scripts/dwarfh.awk	2004-01-22 12:58:07.000000000 -0800
@@ -0,0 +1,19 @@
+BEGIN {
+	print "#ifndef  _ELF_DWARF_H"
+		print "/* Machine generated from dwarf2.h by scripts/dwarfh.awk */"	
+}
+$2 == "=" {
+	gsub(/,/, "", $3)
+	print "#define " $1 "\t " $3
+}
+$1 == "#define" {
+	print $0
+	while( index($0,"\\") == length($0)){
+		getline
+		print $0
+	}
+}
+/.*/ {}
+END {
+	print "#endif"
+}


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

* Re: PPC KGDB changes and some help?
  2004-01-23 23:38                   ` George Anzinger
@ 2004-01-26 20:46                     ` Tom Rini
  2004-01-26 21:27                       ` George Anzinger
  2004-01-26 21:45                       ` George Anzinger
  0 siblings, 2 replies; 35+ messages in thread
From: Tom Rini @ 2004-01-26 20:46 UTC (permalink / raw)
  To: George Anzinger
  Cc: Amit S. Kale, Powerpc Linux, Linux Kernel, KGDB bugreports

On Fri, Jan 23, 2004 at 03:38:39PM -0800, George Anzinger wrote:
> Tom Rini wrote:
> >On Thu, Jan 22, 2004 at 11:05:55AM -0700, Tom Rini wrote:
> >[snip]
> >
> >>First up:
> >>We need to call flush_instruction_cache() on a 'c' or 's' command.
> >>arch/ppc/kernel/ppc-stub.c |   19 ++++++-------------
> >>1 files changed, 6 insertions(+), 13 deletions(-)
> >
> >
> >On tpo of this patch, there's the following:
> >Put back some code to figure out what signal we're dealing with.
> >
> > arch/ppc/kernel/ppc-stub.c |   63 
> > ++++++++++++++++++++++++++++++++++++++++++---
> > 1 files changed, 60 insertions(+), 3 deletions(-)
> >--- 1.15/arch/ppc/kernel/ppc-stub.c	Thu Jan 22 10:53:06 2004
> >+++ edited/arch/ppc/kernel/ppc-stub.c	Fri Jan 23 15:43:10 2004
> >@@ -3,6 +3,7 @@
> >  *
> >  * PowerPC-specific bits to work with the common KGDB stub.
> >  *
> >+ * 1998 (c) Michael AK Tesch (tesch@cs.wisc.edu)
> >  * 2003 (c) TimeSys Corporation
> >  * 2004 (c) MontaVista Software, Inc.
> >  * This file is licensed under the terms of the GNU General Public License
> >@@ -19,13 +20,69 @@
> > #include <asm/processor.h>
> > #include <asm/machdep.h>
> > 
> >+/* Convert the hardware trap type code to a unix signal number. */
> >+/*
> >+ * This table contains the mapping between PowerPC hardware trap types, 
> >and
> >+ * signals, which are primarily what GDB understands.
> >+ */
> >+static struct hard_trap_info
> >+{
> >+	unsigned int tt;		/* Trap type code for powerpc */
> >+	unsigned char signo;		/* Signal that we map this trap into 
> >*/
> >+} hard_trap_info[] = {
> >+#if defined(CONFIG_40x)
> >+	{ 0x100, SIGINT  },		/* critical input interrupt */
> >+	{ 0x200, SIGSEGV },		/* machine check */
> >+	{ 0x300, SIGSEGV },		/* data storage */
> >+	{ 0x400, SIGBUS  },		/* instruction storage */
> >+	{ 0x500, SIGINT  },		/* interrupt */
> >+	{ 0x600, SIGBUS  },		/* alignment */
> >+	{ 0x700, SIGILL  },		/* program */
> >+	{ 0x800, SIGILL  },		/* reserved */
> >+	{ 0x900, SIGILL  },		/* reserved */
> >+	{ 0xa00, SIGILL  },		/* reserved */
> >+	{ 0xb00, SIGILL  },		/* reserved */
> >+	{ 0xc00, SIGCHLD },		/* syscall */
> >+	{ 0xd00, SIGILL  },		/* reserved */
> >+	{ 0xe00, SIGILL  },		/* reserved */
> >+	{ 0xf00, SIGILL  },		/* reserved */
> >+	{ 0x2000, SIGTRAP},		/* debug */
> >+#else
> >+	{ 0x200, SIGSEGV },		/* machine check */
> >+	{ 0x300, SIGSEGV },		/* address error (store) */
> >+	{ 0x400, SIGBUS },		/* instruction bus error */
> >+	{ 0x500, SIGINT },		/* interrupt */
> >+	{ 0x600, SIGBUS },		/* alingment */
> >+	{ 0x700, SIGTRAP },		/* breakpoint trap */
> >+	{ 0x800, SIGFPE },		/* fpu unavail */
> >+	{ 0x900, SIGALRM },		/* decrementer */
> >+	{ 0xa00, SIGILL },		/* reserved */
> >+	{ 0xb00, SIGILL },		/* reserved */
> >+	{ 0xc00, SIGCHLD },		/* syscall */
> >+	{ 0xd00, SIGTRAP },		/* single-step/watch */
> >+	{ 0xe00, SIGFPE },		/* fp assist */
> >+#endif
> >+	{ 0, 0}				/* Must be last */
> >+};
> >+
> >+static int computeSignal(unsigned int tt)
> >+{
> >+	struct hard_trap_info *ht;
> >+
> >+	for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
> >+		if (ht->tt == tt)
> >+			return ht->signo;
> >+
> >+	return SIGHUP; /* default for things we don't know about */
> >+}
> >+
> > /*
> >  * Routines
> >  */
> > static void
> > kgdb_debugger(struct pt_regs *regs)
> > {
> >-	(*linux_debug_hook) (0, 0, 0, regs);
> >+	(*linux_debug_hook) (0, computeSignal(regs->trap), 0, regs);
> > 	return;
> > }
> > 
> >@@ -52,14 +109,14 @@
> > int
> > kgdb_iabr_match(struct pt_regs *regs)
> > {
> >-	(*linux_debug_hook) (0, 0, 0, regs);
> >+	(*linux_debug_hook) (0, computeSignal(regs->trap), 0, regs);
> > 	return 1;
> > }
> > 
> > int
> > kgdb_dabr_match(struct pt_regs *regs)
> > {
> >-	(*linux_debug_hook) (0, 0, 0, regs);
> >+	(*linux_debug_hook) (0, computeSignal(regs->trap), 0, regs);
> > 	return 1;
> > }
> > 
> >
> >Now, not being as well versed in all of the debugging infos that can be
> >passed around, it sounds like this patch could be dropped in the future
> >for a cleaner method using some of the dwarf2 bits being talked about.
> >But I don't know, and clarification and pointers (if so) to how to do
> >this would be appreciated.
> 
> I am not sure what this buys you.  I don't think dwarf2 will help here.

OK.

> There is a real danger of passing signal info back to gdb as it will want 
> to try to deliver the signal which is a non-compute in most kgdbs in the 
> field.  I did put code in the mm-kgdb to do just this, but usually the 
> arrival of such a signal (other than SIGTRAP) is the end of the kernel.  
> All that is left is to read the tea leaves.

The gdb I've been testing this with knows better than to try and send a
singal back, so that's not a worry.  The motivation behind doing this
however is along the lines of "if it ain't broke, don't remove it".  The
original stub was getting all of this information correctly, so why stop
doing it?

-- 
Tom Rini
http://gate.crashing.org/~trini/

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

* Re: PPC KGDB changes and some help?
  2004-01-26 20:46                     ` Tom Rini
@ 2004-01-26 21:27                       ` George Anzinger
  2004-01-26 21:42                         ` Tom Rini
  2004-01-26 21:45                       ` George Anzinger
  1 sibling, 1 reply; 35+ messages in thread
From: George Anzinger @ 2004-01-26 21:27 UTC (permalink / raw)
  To: Tom Rini; +Cc: Amit S. Kale, Powerpc Linux, Linux Kernel, KGDB bugreports

Tom Rini wrote:
> On Fri, Jan 23, 2004 at 03:38:39PM -0800, George Anzinger wrote:
> 
>>Tom Rini wrote:
>>
>>>On Thu, Jan 22, 2004 at 11:05:55AM -0700, Tom Rini wrote:
>>>[snip]
>>>
>>>
>>>>First up:
>>>>We need to call flush_instruction_cache() on a 'c' or 's' command.
>>>>arch/ppc/kernel/ppc-stub.c |   19 ++++++-------------
>>>>1 files changed, 6 insertions(+), 13 deletions(-)
>>>
>>>
>>>On tpo of this patch, there's the following:
>>>Put back some code to figure out what signal we're dealing with.
>>>
>>>arch/ppc/kernel/ppc-stub.c |   63 
>>>++++++++++++++++++++++++++++++++++++++++++---
>>>1 files changed, 60 insertions(+), 3 deletions(-)
>>>--- 1.15/arch/ppc/kernel/ppc-stub.c	Thu Jan 22 10:53:06 2004
>>>+++ edited/arch/ppc/kernel/ppc-stub.c	Fri Jan 23 15:43:10 2004
>>>@@ -3,6 +3,7 @@
>>> *
>>> * PowerPC-specific bits to work with the common KGDB stub.
>>> *
>>>+ * 1998 (c) Michael AK Tesch (tesch@cs.wisc.edu)
>>> * 2003 (c) TimeSys Corporation
>>> * 2004 (c) MontaVista Software, Inc.
>>> * This file is licensed under the terms of the GNU General Public License
>>>@@ -19,13 +20,69 @@
>>>#include <asm/processor.h>
>>>#include <asm/machdep.h>
>>>
>>>+/* Convert the hardware trap type code to a unix signal number. */
>>>+/*
>>>+ * This table contains the mapping between PowerPC hardware trap types, 
>>>and
>>>+ * signals, which are primarily what GDB understands.
>>>+ */
>>>+static struct hard_trap_info
>>>+{
>>>+	unsigned int tt;		/* Trap type code for powerpc */
>>>+	unsigned char signo;		/* Signal that we map this trap into 
>>>*/
>>>+} hard_trap_info[] = {
>>>+#if defined(CONFIG_40x)
>>>+	{ 0x100, SIGINT  },		/* critical input interrupt */
>>>+	{ 0x200, SIGSEGV },		/* machine check */
>>>+	{ 0x300, SIGSEGV },		/* data storage */
>>>+	{ 0x400, SIGBUS  },		/* instruction storage */
>>>+	{ 0x500, SIGINT  },		/* interrupt */
>>>+	{ 0x600, SIGBUS  },		/* alignment */
>>>+	{ 0x700, SIGILL  },		/* program */
>>>+	{ 0x800, SIGILL  },		/* reserved */
>>>+	{ 0x900, SIGILL  },		/* reserved */
>>>+	{ 0xa00, SIGILL  },		/* reserved */
>>>+	{ 0xb00, SIGILL  },		/* reserved */
>>>+	{ 0xc00, SIGCHLD },		/* syscall */
>>>+	{ 0xd00, SIGILL  },		/* reserved */
>>>+	{ 0xe00, SIGILL  },		/* reserved */
>>>+	{ 0xf00, SIGILL  },		/* reserved */
>>>+	{ 0x2000, SIGTRAP},		/* debug */
>>>+#else
>>>+	{ 0x200, SIGSEGV },		/* machine check */
>>>+	{ 0x300, SIGSEGV },		/* address error (store) */
>>>+	{ 0x400, SIGBUS },		/* instruction bus error */
>>>+	{ 0x500, SIGINT },		/* interrupt */
>>>+	{ 0x600, SIGBUS },		/* alingment */
>>>+	{ 0x700, SIGTRAP },		/* breakpoint trap */
>>>+	{ 0x800, SIGFPE },		/* fpu unavail */
>>>+	{ 0x900, SIGALRM },		/* decrementer */
>>>+	{ 0xa00, SIGILL },		/* reserved */
>>>+	{ 0xb00, SIGILL },		/* reserved */
>>>+	{ 0xc00, SIGCHLD },		/* syscall */
>>>+	{ 0xd00, SIGTRAP },		/* single-step/watch */
>>>+	{ 0xe00, SIGFPE },		/* fp assist */
>>>+#endif
>>>+	{ 0, 0}				/* Must be last */
>>>+};
>>>+
>>>+static int computeSignal(unsigned int tt)
>>>+{
>>>+	struct hard_trap_info *ht;
>>>+
>>>+	for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
>>>+		if (ht->tt == tt)
>>>+			return ht->signo;
>>>+
>>>+	return SIGHUP; /* default for things we don't know about */
>>>+}
>>>+
>>>/*
>>> * Routines
>>> */
>>>static void
>>>kgdb_debugger(struct pt_regs *regs)
>>>{
>>>-	(*linux_debug_hook) (0, 0, 0, regs);
>>>+	(*linux_debug_hook) (0, computeSignal(regs->trap), 0, regs);
>>>	return;
>>>}
>>>
>>>@@ -52,14 +109,14 @@
>>>int
>>>kgdb_iabr_match(struct pt_regs *regs)
>>>{
>>>-	(*linux_debug_hook) (0, 0, 0, regs);
>>>+	(*linux_debug_hook) (0, computeSignal(regs->trap), 0, regs);
>>>	return 1;
>>>}
>>>
>>>int
>>>kgdb_dabr_match(struct pt_regs *regs)
>>>{
>>>-	(*linux_debug_hook) (0, 0, 0, regs);
>>>+	(*linux_debug_hook) (0, computeSignal(regs->trap), 0, regs);
>>>	return 1;
>>>}
>>>
>>>
>>>Now, not being as well versed in all of the debugging infos that can be
>>>passed around, it sounds like this patch could be dropped in the future
>>>for a cleaner method using some of the dwarf2 bits being talked about.
>>>But I don't know, and clarification and pointers (if so) to how to do
>>>this would be appreciated.
>>
>>I am not sure what this buys you.  I don't think dwarf2 will help here.
> 
> 
> OK.
> 
> 
>>There is a real danger of passing signal info back to gdb as it will want 
>>to try to deliver the signal which is a non-compute in most kgdbs in the 
>>field.  I did put code in the mm-kgdb to do just this, but usually the 
>>arrival of such a signal (other than SIGTRAP) is the end of the kernel.  
>>All that is left is to read the tea leaves.
> 
> 
> The gdb I've been testing this with knows better than to try and send a
> singal back, so that's not a worry.  The motivation behind doing this
> however is along the lines of "if it ain't broke, don't remove it".  The
> original stub was getting all of this information correctly, so why stop
> doing it?
> 
OK, but I still don't like losing the return address.  Tell me again, why do you 
need three different functions all doing the same thing?


-- 
George Anzinger   george@mvista.com
High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml


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

* Re: PPC KGDB changes and some help?
  2004-01-21 19:21         ` Tom Rini
                             ` (2 preceding siblings ...)
  2004-01-21 23:12           ` George Anzinger
@ 2004-01-26 21:32           ` Tom Rini
  2004-01-27  8:59             ` Amit S. Kale
  3 siblings, 1 reply; 35+ messages in thread
From: Tom Rini @ 2004-01-26 21:32 UTC (permalink / raw)
  To: Amit S. Kale
  Cc: Powerpc Linux, Linux Kernel, KGDB bugreports, George Anzinger

On Wed, Jan 21, 2004 at 12:21:28PM -0700, Tom Rini wrote:

> On Wed, Jan 21, 2004 at 11:42:17AM -0700, Tom Rini wrote:
> > On Wed, Jan 21, 2004 at 10:23:12PM +0530, Amit S. Kale wrote:
> > 
> > > Hi,
> > > 
> > > Here it is: ppc kgdb from timesys kernel is available at
> > > http://kgdb.sourceforge.net/kgdb-2/linux-2.6.1-kgdb-2.1.0.tar.bz2
> > > 
> > > This is my attempt at extracting kgdb from TimeSys kernel. It works well in 
> > > TimeSys kernel, so blame me if above patch doesn't work.
> > 
> > Okay, here's my first patch against this.
> 
> And dependant upon this is a patch to fixup the rest of the common PPC
> code, as follows:

Relative to this, due to the PPC changes is the following:

- In kgdb_handle_exception, memset remcomOutBuffer twice, instead of
  continiously throwing in NULLs around.
- Remove a KERN_CRIT from the printk while waiting for kgdb to connect
  (it's not needed there).
- Switch the initial packet from an 'S' packet (followed by a p for the
  thread ID) to a 'T' packet.

This is tested on PPC and i386 (lightly).

 include/asm-i386/kgdb.h   |    4 ++
 include/asm-ppc/kgdb.h    |    3 +
 include/asm-x86_64/kgdb.h |    4 ++
 kernel/kgdbstub.c         |   70 ++++++++++++++++++++++------------------------
 4 files changed, 45 insertions(+), 36 deletions(-)

--- 1.1/include/asm-i386/kgdb.h	Wed Jan 21 10:13:15 2004
+++ edited/include/asm-i386/kgdb.h	Mon Jan 26 12:15:22 2004
@@ -43,6 +43,10 @@
 	_GS    /* 15 */
 };
 
+#define PC_REGNUM	_PC	/* Program Counter */
+#define SP_REGNUM	_ESP	/* Stack Pointer */
+#define PTRACE_PC	eip	/* Program Counter, in ptrace regs. */
+
 #define BREAKPOINT() asm("   int $3");
 #define BREAK_INSTR_SIZE       1
 
--- 1.5/include/asm-ppc/kgdb.h	Wed Jan 21 12:21:23 2004
+++ edited/include/asm-ppc/kgdb.h	Mon Jan 26 12:16:39 2004
@@ -19,6 +19,9 @@
 #define NUMREGBYTES		(MAXREG * sizeof(int))
 #define BUFMAX			((NUMREGBYTES * 2) + 512)
 #define OUTBUFMAX		((NUMREGBYTES * 2) + 512)
+#define PC_REGNUM		64
+#define SP_REGNUM		1
+#define PTRACE_PC		nip	/* Program Counter, in ptrace regs. */
 #define BREAKPOINT()		asm(".long 0x7d821008") /* twge r2, r2 */
 
 /* Things specific to the gen550 backend. */
--- 1.1/include/asm-x86_64/kgdb.h	Wed Jan 21 10:13:16 2004
+++ edited/include/asm-x86_64/kgdb.h	Mon Jan 26 12:16:15 2004
@@ -44,6 +44,10 @@
 	       _PS,
 	       _LASTREG=_PS }; 
 
+#define PC_REGNUM	_PC	/* Program Counter */
+#define SP_REGNUM	_RSP	/* Stack Pointer */
+#define PTRACE_PC	rip	/* Program Counter, in ptrace regs. */
+
 /* Number of bytes of registers.  */
 #define NUMREGBYTES (_LASTREG*8)
 
--- 1.2/kernel/kgdbstub.c	Wed Jan 21 12:21:23 2004
+++ edited/kernel/kgdbstub.c	Mon Jan 26 12:17:02 2004
@@ -615,6 +615,9 @@
 	 * need one here */
 	procindebug[smp_processor_id()] = 1;
 
+	/* Clear the out buffer. */
+	memset(remcomOutBuffer, 0, sizeof(remcomOutBuffer));
+
 	/* Master processor is completely in the debugger */
 	if (kgdb_ops->post_master_code)
 		kgdb_ops->post_master_code(linux_regs, exVector, err_code);
@@ -624,9 +627,7 @@
 		if(remcomInBuffer[0] == 'H' && remcomInBuffer[1] =='c') {
 			remove_all_break();
 			atomic_set(&kgdb_killed_or_detached, 0);
-			remcomOutBuffer[0] = 'O';
-			remcomOutBuffer[1] = 'K';
-			remcomOutBuffer[2] = 0;
+			strcpy(remcomOutBuffer, "OK");
 		}
 		else
 			return 1;
@@ -634,13 +635,25 @@
 	else {
 
 		/* reply to host that an exception has occurred */
-		remcomOutBuffer[0] = 'S';
-		remcomOutBuffer[1] = hexchars[signo >> 4];
-		remcomOutBuffer[2] = hexchars[signo % 16];
-		remcomOutBuffer[3] = 'p';
-
+		ptr = remcomOutBuffer;
+		*ptr++ = 'T';
+		*ptr++ = hexchars[(signo >> 4) % 16];
+		*ptr++ = hexchars[signo % 16];
+		*ptr++ = hexchars[(PC_REGNUM >> 4) % 16];
+		*ptr++ = hexchars[PC_REGNUM % 16];
+		*ptr++ = ':';
+		ptr = kgdb_mem2hex((char *)&linux_regs->PTRACE_PC, ptr, 4, 0);
+		*ptr++ = ';';
+		*ptr++ = hexchars[SP_REGNUM >> 4];
+		*ptr++ = hexchars[SP_REGNUM & 0xf];
+		*ptr++ = ':';
+		ptr = kgdb_mem2hex(((char *)linux_regs) + SP_REGNUM * 4, ptr,
+				4, 0);
+		*ptr++ = ';';
+		ptr += strlen(strcpy(ptr, "thread:"));
 		int_to_threadref(&thref, shadow_pid(current->pid));
-		*pack_threadid(remcomOutBuffer + 4, &thref) = 0;
+		ptr = pack_threadid(ptr, &thref);
+		*ptr++ = ';';
 	}		
 	putpacket(remcomOutBuffer, 0);
 	kgdb_connected = 1;
@@ -651,8 +664,10 @@
 	while (1) {
 		int bpt_type = 0;
 		error = 0;
-		remcomOutBuffer[0] = 0;
-		remcomOutBuffer[1] = 0;
+
+		/* Clear the out buffer. */
+		memset(remcomOutBuffer, 0, sizeof(remcomOutBuffer));
+
 		getpacket(remcomInBuffer);
 
 #if KGDB_DEBUG
@@ -666,7 +681,6 @@
 			remcomOutBuffer[0] = 'S';
 			remcomOutBuffer[1] = hexchars[signo >> 4];
 			remcomOutBuffer[2] = hexchars[signo % 16];
-			remcomOutBuffer[3] = 0;
 			break;
 
 		case 'g':	/* return the value of the CPU registers */
@@ -764,9 +778,7 @@
 			 * continue.
 			 */
 		case 'D':
-			remcomOutBuffer[0] = 'O';
-			remcomOutBuffer[1] = 'K';
-			remcomOutBuffer[2] = '\0';
+			strcpy(remcomOutBuffer, "OK");
 			remove_all_break();
 			putpacket(remcomOutBuffer, 0);
 			kgdb_connected = 0;
@@ -804,19 +816,16 @@
 						i++;
 					}
 				}
-				*(--ptr) = '\0';
 				break;
 
 			case 'C':
 				/* Current thread id */
-				remcomOutBuffer[0] = 'Q';
-				remcomOutBuffer[1] = 'C';
+				strcpy(remcomOutBuffer, "QC");
 
 				threadid = shadow_pid(current->pid);
 				
 				int_to_threadref(&thref, threadid);
 				pack_threadid(remcomOutBuffer + 2, &thref);
-				remcomOutBuffer[18] = '\0';
 				break;
 
 			case 'E':
@@ -829,7 +838,6 @@
 			case 'T':
 				if (memcmp(remcomInBuffer+1, "ThreadExtraInfo,",16))
 				{
-					remcomOutBuffer[0] = 0;
 					strcpy(remcomOutBuffer, "E05");
 					break;
 				}
@@ -872,14 +880,11 @@
 				thread = getthread(linux_regs, threadid);
 				if (!thread && threadid > 0) {
 					remcomOutBuffer[0] = 'E';
-					remcomOutBuffer[1] = '\0';
 					break;
 				}
 				kgdb_usethread = thread;
 				kgdb_usethreadid = threadid;
-				remcomOutBuffer[0] = 'O';
-				remcomOutBuffer[1] = 'K';
-				remcomOutBuffer[2] = '\0';
+				strcpy(remcomOutBuffer, "OK");
 				break;
 
 			case 'c':
@@ -892,14 +897,11 @@
 					thread = getthread(linux_regs, threadid);
 					if (!thread && threadid > 0) {
 						remcomOutBuffer[0] = 'E';
-						remcomOutBuffer[1] = '\0';
 						break;
 					}
 					kgdb_contthread = thread;
 				}
-				remcomOutBuffer[0] = 'O';
-				remcomOutBuffer[1] = 'K';
-				remcomOutBuffer[2] = '\0';
+				strcpy(remcomOutBuffer, "OK");
 				break;
 			}
 			break;
@@ -909,14 +911,10 @@
 			ptr = &remcomInBuffer[1];
 			kgdb_hexToLong(&ptr, &threadid);
 			thread = getthread(linux_regs, threadid);
-			if (thread) {
-				remcomOutBuffer[0] = 'O';
-				remcomOutBuffer[1] = 'K';
-				remcomOutBuffer[2] = '\0';
-			} else {
+			if (thread)
+				strcpy(remcomOutBuffer, "OK");
+			else
 				remcomOutBuffer[0] = 'E';
-				remcomOutBuffer[1] = '\0';
-			}
 			break;
 		case 'z':
 		case 'Z':
@@ -1127,7 +1125,7 @@
 	 */
 	printk(KERN_CRIT "Waiting for connection from remote gdb... ");
 	breakpoint() ;
-	printk(KERN_CRIT "Connected.\n");
+	printk("Connected.\n");
 }
 
 #ifdef CONFIG_KGDB_CONSOLE

-- 
Tom Rini
http://gate.crashing.org/~trini/

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

* Re: PPC KGDB changes and some help?
  2004-01-26 21:27                       ` George Anzinger
@ 2004-01-26 21:42                         ` Tom Rini
  2004-01-26 22:35                           ` George Anzinger
  0 siblings, 1 reply; 35+ messages in thread
From: Tom Rini @ 2004-01-26 21:42 UTC (permalink / raw)
  To: George Anzinger
  Cc: Amit S. Kale, Powerpc Linux, Linux Kernel, KGDB bugreports

On Mon, Jan 26, 2004 at 01:27:35PM -0800, George Anzinger wrote:
> Tom Rini wrote:
> >On Fri, Jan 23, 2004 at 03:38:39PM -0800, George Anzinger wrote:
> >
> >>Tom Rini wrote:
> >>
> >>>On Thu, Jan 22, 2004 at 11:05:55AM -0700, Tom Rini wrote:
> >>>[snip]
> >>>
> >>>
> >>>>First up:
> >>>>We need to call flush_instruction_cache() on a 'c' or 's' command.
> >>>>arch/ppc/kernel/ppc-stub.c |   19 ++++++-------------
> >>>>1 files changed, 6 insertions(+), 13 deletions(-)
> >>>
> >>>
> >>>On tpo of this patch, there's the following:
> >>>Put back some code to figure out what signal we're dealing with.
> >>>
> >>>arch/ppc/kernel/ppc-stub.c |   63 
> >>>++++++++++++++++++++++++++++++++++++++++++---
> >>>1 files changed, 60 insertions(+), 3 deletions(-)
> >>>--- 1.15/arch/ppc/kernel/ppc-stub.c	Thu Jan 22 10:53:06 2004
> >>>+++ edited/arch/ppc/kernel/ppc-stub.c	Fri Jan 23 15:43:10 2004
> >>>@@ -3,6 +3,7 @@
> >>>*
> >>>* PowerPC-specific bits to work with the common KGDB stub.
> >>>*
> >>>+ * 1998 (c) Michael AK Tesch (tesch@cs.wisc.edu)
> >>>* 2003 (c) TimeSys Corporation
> >>>* 2004 (c) MontaVista Software, Inc.
> >>>* This file is licensed under the terms of the GNU General Public License
> >>>@@ -19,13 +20,69 @@
> >>>#include <asm/processor.h>
> >>>#include <asm/machdep.h>
> >>>
> >>>+/* Convert the hardware trap type code to a unix signal number. */
> >>>+/*
> >>>+ * This table contains the mapping between PowerPC hardware trap types, 
> >>>and
> >>>+ * signals, which are primarily what GDB understands.
> >>>+ */
> >>>+static struct hard_trap_info
> >>>+{
> >>>+	unsigned int tt;		/* Trap type code for powerpc */
> >>>+	unsigned char signo;		/* Signal that we map this trap into 
> >>>*/
> >>>+} hard_trap_info[] = {
> >>>+#if defined(CONFIG_40x)
> >>>+	{ 0x100, SIGINT  },		/* critical input interrupt */
> >>>+	{ 0x200, SIGSEGV },		/* machine check */
> >>>+	{ 0x300, SIGSEGV },		/* data storage */
> >>>+	{ 0x400, SIGBUS  },		/* instruction storage */
> >>>+	{ 0x500, SIGINT  },		/* interrupt */
> >>>+	{ 0x600, SIGBUS  },		/* alignment */
> >>>+	{ 0x700, SIGILL  },		/* program */
> >>>+	{ 0x800, SIGILL  },		/* reserved */
> >>>+	{ 0x900, SIGILL  },		/* reserved */
> >>>+	{ 0xa00, SIGILL  },		/* reserved */
> >>>+	{ 0xb00, SIGILL  },		/* reserved */
> >>>+	{ 0xc00, SIGCHLD },		/* syscall */
> >>>+	{ 0xd00, SIGILL  },		/* reserved */
> >>>+	{ 0xe00, SIGILL  },		/* reserved */
> >>>+	{ 0xf00, SIGILL  },		/* reserved */
> >>>+	{ 0x2000, SIGTRAP},		/* debug */
> >>>+#else
> >>>+	{ 0x200, SIGSEGV },		/* machine check */
> >>>+	{ 0x300, SIGSEGV },		/* address error (store) */
> >>>+	{ 0x400, SIGBUS },		/* instruction bus error */
> >>>+	{ 0x500, SIGINT },		/* interrupt */
> >>>+	{ 0x600, SIGBUS },		/* alingment */
> >>>+	{ 0x700, SIGTRAP },		/* breakpoint trap */
> >>>+	{ 0x800, SIGFPE },		/* fpu unavail */
> >>>+	{ 0x900, SIGALRM },		/* decrementer */
> >>>+	{ 0xa00, SIGILL },		/* reserved */
> >>>+	{ 0xb00, SIGILL },		/* reserved */
> >>>+	{ 0xc00, SIGCHLD },		/* syscall */
> >>>+	{ 0xd00, SIGTRAP },		/* single-step/watch */
> >>>+	{ 0xe00, SIGFPE },		/* fp assist */
> >>>+#endif
> >>>+	{ 0, 0}				/* Must be last */
> >>>+};
> >>>+
> >>>+static int computeSignal(unsigned int tt)
> >>>+{
> >>>+	struct hard_trap_info *ht;
> >>>+
> >>>+	for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
> >>>+		if (ht->tt == tt)
> >>>+			return ht->signo;
> >>>+
> >>>+	return SIGHUP; /* default for things we don't know about */
> >>>+}
> >>>+
> >>>/*
> >>>* Routines
> >>>*/
> >>>static void
> >>>kgdb_debugger(struct pt_regs *regs)
> >>>{
> >>>-	(*linux_debug_hook) (0, 0, 0, regs);
> >>>+	(*linux_debug_hook) (0, computeSignal(regs->trap), 0, regs);
> >>>	return;
> >>>}
> >>>
> >>>@@ -52,14 +109,14 @@
> >>>int
> >>>kgdb_iabr_match(struct pt_regs *regs)
> >>>{
> >>>-	(*linux_debug_hook) (0, 0, 0, regs);
> >>>+	(*linux_debug_hook) (0, computeSignal(regs->trap), 0, regs);
> >>>	return 1;
> >>>}
> >>>
> >>>int
> >>>kgdb_dabr_match(struct pt_regs *regs)
> >>>{
> >>>-	(*linux_debug_hook) (0, 0, 0, regs);
> >>>+	(*linux_debug_hook) (0, computeSignal(regs->trap), 0, regs);
> >>>	return 1;
> >>>}
> >>>
> >>>
> >>>Now, not being as well versed in all of the debugging infos that can be
> >>>passed around, it sounds like this patch could be dropped in the future
> >>>for a cleaner method using some of the dwarf2 bits being talked about.
> >>>But I don't know, and clarification and pointers (if so) to how to do
> >>>this would be appreciated.
> >>
> >>I am not sure what this buys you.  I don't think dwarf2 will help here.
> >
> >
> >OK.
> >
> >
> >>There is a real danger of passing signal info back to gdb as it will want 
> >>to try to deliver the signal which is a non-compute in most kgdbs in the 
> >>field.  I did put code in the mm-kgdb to do just this, but usually the 
> >>arrival of such a signal (other than SIGTRAP) is the end of the kernel.  
> >>All that is left is to read the tea leaves.
> >
> >
> >The gdb I've been testing this with knows better than to try and send a
> >singal back, so that's not a worry.  The motivation behind doing this
> >however is along the lines of "if it ain't broke, don't remove it".  The
> >original stub was getting all of this information correctly, so why stop
> >doing it?
> >
> OK, but I still don't like losing the return address.  Tell me again, why 
> do you need three different functions all doing the same thing?

You get:
- kgdb_breakpoint => debugger_bpt : This is how the various PPC codes
  drop you into KGDB.
- kgdb_iabr_match => debugger_iabr_match : Called from
  InstructionBreakpoint, exception.
- kgdb_dabr_match => debugger_dabr_match : Called from do_page_fault,
  this is a Data Access Breakpoint Register match.

So we need at least 2 for the KGDB side of things (prototypes) and 3
just to make it clear.

-- 
Tom Rini
http://gate.crashing.org/~trini/

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

* Re: PPC KGDB changes and some help?
  2004-01-26 20:46                     ` Tom Rini
  2004-01-26 21:27                       ` George Anzinger
@ 2004-01-26 21:45                       ` George Anzinger
  2004-01-26 22:06                         ` Tom Rini
  1 sibling, 1 reply; 35+ messages in thread
From: George Anzinger @ 2004-01-26 21:45 UTC (permalink / raw)
  To: Tom Rini; +Cc: Amit S. Kale, Powerpc Linux, Linux Kernel, KGDB bugreports

Tom Rini wrote:
> 
>>There is a real danger of passing signal info back to gdb as it will want 
>>to try to deliver the signal which is a non-compute in most kgdbs in the 
>>field.  I did put code in the mm-kgdb to do just this, but usually the 
>>arrival of such a signal (other than SIGTRAP) is the end of the kernel.  
>>All that is left is to read the tea leaves.
> 
> 
> The gdb I've been testing this with knows better than to try and send a
> singal back, so that's not a worry.  The motivation behind doing this
> however is along the lines of "if it ain't broke, don't remove it".  The
> original stub was getting all of this information correctly, so why stop
> doing it?
> 
You sure.  If so what gdb?  And how does it know?  I suppose you could tell it 
with a script, but then what if one forgets?

-- 
George Anzinger   george@mvista.com
High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml


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

* Re: PPC KGDB changes and some help?
  2004-01-26 21:45                       ` George Anzinger
@ 2004-01-26 22:06                         ` Tom Rini
  2004-01-27  9:05                           ` Amit S. Kale
  0 siblings, 1 reply; 35+ messages in thread
From: Tom Rini @ 2004-01-26 22:06 UTC (permalink / raw)
  To: George Anzinger
  Cc: Amit S. Kale, Powerpc Linux, Linux Kernel, KGDB bugreports

On Mon, Jan 26, 2004 at 01:45:44PM -0800, George Anzinger wrote:

> Tom Rini wrote:
> >
> >>There is a real danger of passing signal info back to gdb as it will want 
> >>to try to deliver the signal which is a non-compute in most kgdbs in the 
> >>field.  I did put code in the mm-kgdb to do just this, but usually the 
> >>arrival of such a signal (other than SIGTRAP) is the end of the kernel.  
> >>All that is left is to read the tea leaves.
> >
> >
> >The gdb I've been testing this with knows better than to try and send a
> >singal back, so that's not a worry.  The motivation behind doing this
> >however is along the lines of "if it ain't broke, don't remove it".  The
> >original stub was getting all of this information correctly, so why stop
> >doing it?
> >
> You sure.  If so what gdb?  And how does it know?  I suppose you could tell 
> it with a script, but then what if one forgets?

GNU gdb 6.0 (MontaVista 6.0-8.0.4.0300532 2003-12-24)
Copyright 2003 Free Software Foundation, Inc.
[snip]

[New Thread 289]

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 289]
0x00000000 in ?? ()
(gdb) c
Continuing.
Can't send signals to this remote system.  SIGSEGV not sent.

Noting that 0x0 is correct as the code that triggered this was:
static void (*dummy)(struct pt_regs *regs);
int drop_kgdb(void) {
        struct pt_regs regs;
        memset(&regs, 0, sizeof(regs));
        dummy(&regs);

        return 0;
}
module_init(drop_kgdb);

-- 
Tom Rini
http://gate.crashing.org/~trini/

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

* Re: PPC KGDB changes and some help?
  2004-01-26 21:42                         ` Tom Rini
@ 2004-01-26 22:35                           ` George Anzinger
  0 siblings, 0 replies; 35+ messages in thread
From: George Anzinger @ 2004-01-26 22:35 UTC (permalink / raw)
  To: Tom Rini; +Cc: Amit S. Kale, Powerpc Linux, Linux Kernel, KGDB bugreports

Tom Rini wrote:
>>>>>+
>>>>>/*
>>>>>* Routines
>>>>>*/
>>>>>static void
>>>>>kgdb_debugger(struct pt_regs *regs)
>>>>>{
>>>>>-	(*linux_debug_hook) (0, 0, 0, regs);
>>>>>+	(*linux_debug_hook) (0, computeSignal(regs->trap), 0, regs);
>>>>>	return;
>>>>>}
>>>>>
>>>>>@@ -52,14 +109,14 @@
>>>>>int
>>>>>kgdb_iabr_match(struct pt_regs *regs)
>>>>>{
>>>>>-	(*linux_debug_hook) (0, 0, 0, regs);
>>>>>+	(*linux_debug_hook) (0, computeSignal(regs->trap), 0, regs);
>>>>>	return 1;
>>>>>}
>>>>>
>>>>>int
>>>>>kgdb_dabr_match(struct pt_regs *regs)
>>>>>{
>>>>>-	(*linux_debug_hook) (0, 0, 0, regs);
>>>>>+	(*linux_debug_hook) (0, computeSignal(regs->trap), 0, regs);
>>>>>	return 1;
>>>>>}
>>>>>
>>>>>
>>>>>Now, not being as well versed in all of the debugging infos that can be
>>>>>passed around, it sounds like this patch could be dropped in the future
>>>>>for a cleaner method using some of the dwarf2 bits being talked about.
>>>>>But I don't know, and clarification and pointers (if so) to how to do
>>>>>this would be appreciated.
>>>>
>>>>I am not sure what this buys you.  I don't think dwarf2 will help here.
>>>
>>>
>>>OK.
>>>
>>>
>>>
>>>>There is a real danger of passing signal info back to gdb as it will want 
>>>>to try to deliver the signal which is a non-compute in most kgdbs in the 
>>>>field.  I did put code in the mm-kgdb to do just this, but usually the 
>>>>arrival of such a signal (other than SIGTRAP) is the end of the kernel.  
>>>>All that is left is to read the tea leaves.
>>>
>>>
>>>The gdb I've been testing this with knows better than to try and send a
>>>singal back, so that's not a worry.  The motivation behind doing this
>>>however is along the lines of "if it ain't broke, don't remove it".  The
>>>original stub was getting all of this information correctly, so why stop
>>>doing it?
>>>
>>
>>OK, but I still don't like losing the return address.  Tell me again, why 
>>do you need three different functions all doing the same thing?
> 
> 
> You get:
> - kgdb_breakpoint => debugger_bpt : This is how the various PPC codes
>   drop you into KGDB.
> - kgdb_iabr_match => debugger_iabr_match : Called from
>   InstructionBreakpoint, exception.
> - kgdb_dabr_match => debugger_dabr_match : Called from do_page_fault,
>   this is a Data Access Breakpoint Register match.
> 
> So we need at least 2 for the KGDB side of things (prototypes) and 3
> just to make it clear.

But they all end up at the exact same place with the same set of parameters. 
The only difference I can see is that some return 1 while the other is void.  It 
seems to me that you could send them all to one of the ones that returns 1. 
Once that is done, then you could just send them all to where ever 
linux_debug_hook points and have it do the signal resolution and return the 1. 
That way that code could look at its return address and see something useful.
> 

-- 
George Anzinger   george@mvista.com
High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml


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

* Re: PPC KGDB changes and some help?
  2004-01-26 21:32           ` Tom Rini
@ 2004-01-27  8:59             ` Amit S. Kale
  0 siblings, 0 replies; 35+ messages in thread
From: Amit S. Kale @ 2004-01-27  8:59 UTC (permalink / raw)
  To: Tom Rini; +Cc: Powerpc Linux, Linux Kernel, KGDB bugreports, George Anzinger

On Tuesday 27 Jan 2004 3:02 am, Tom Rini wrote:
> On Wed, Jan 21, 2004 at 12:21:28PM -0700, Tom Rini wrote:
> > On Wed, Jan 21, 2004 at 11:42:17AM -0700, Tom Rini wrote:
> > > On Wed, Jan 21, 2004 at 10:23:12PM +0530, Amit S. Kale wrote:
> > > > Hi,
> > > >
> > > > Here it is: ppc kgdb from timesys kernel is available at
> > > > http://kgdb.sourceforge.net/kgdb-2/linux-2.6.1-kgdb-2.1.0.tar.bz2
> > > >
> > > > This is my attempt at extracting kgdb from TimeSys kernel. It works
> > > > well in TimeSys kernel, so blame me if above patch doesn't work.
> > >
> > > Okay, here's my first patch against this.
> >
> > And dependant upon this is a patch to fixup the rest of the common PPC
> > code, as follows:
>
> Relative to this, due to the PPC changes is the following:
>
> - In kgdb_handle_exception, memset remcomOutBuffer twice, instead of
>   continiously throwing in NULLs around.

Good.

> - Remove a KERN_CRIT from the printk while waiting for kgdb to connect
>   (it's not needed there).

It's needed for kgdb over ethernet. At present the ethernet comes up really 
late. At that point syslogd has taken over printing of kernel messages, 
KERN_CRIT ensures that a user sees that message regardless of the syslogd 
configuratio.

> - Switch the initial packet from an 'S' packet (followed by a p for the
>   thread ID) to a 'T' packet.

That's also good.

>
> This is tested on PPC and i386 (lightly).
>
>  include/asm-i386/kgdb.h   |    4 ++
>  include/asm-ppc/kgdb.h    |    3 +
>  include/asm-x86_64/kgdb.h |    4 ++
>  kernel/kgdbstub.c         |   70
> ++++++++++++++++++++++------------------------ 4 files changed, 45
> insertions(+), 36 deletions(-)
>
> --- 1.1/include/asm-i386/kgdb.h	Wed Jan 21 10:13:15 2004
> +++ edited/include/asm-i386/kgdb.h	Mon Jan 26 12:15:22 2004
> @@ -43,6 +43,10 @@
>  	_GS    /* 15 */
>  };
>
> +#define PC_REGNUM	_PC	/* Program Counter */
> +#define SP_REGNUM	_ESP	/* Stack Pointer */
> +#define PTRACE_PC	eip	/* Program Counter, in ptrace regs. */
> +
>  #define BREAKPOINT() asm("   int $3");
>  #define BREAK_INSTR_SIZE       1
>
> --- 1.5/include/asm-ppc/kgdb.h	Wed Jan 21 12:21:23 2004
> +++ edited/include/asm-ppc/kgdb.h	Mon Jan 26 12:16:39 2004
> @@ -19,6 +19,9 @@
>  #define NUMREGBYTES		(MAXREG * sizeof(int))
>  #define BUFMAX			((NUMREGBYTES * 2) + 512)
>  #define OUTBUFMAX		((NUMREGBYTES * 2) + 512)
> +#define PC_REGNUM		64
> +#define SP_REGNUM		1
> +#define PTRACE_PC		nip	/* Program Counter, in ptrace regs. */
>  #define BREAKPOINT()		asm(".long 0x7d821008") /* twge r2, r2 */
>
>  /* Things specific to the gen550 backend. */
> --- 1.1/include/asm-x86_64/kgdb.h	Wed Jan 21 10:13:16 2004
> +++ edited/include/asm-x86_64/kgdb.h	Mon Jan 26 12:16:15 2004
> @@ -44,6 +44,10 @@
>  	       _PS,
>  	       _LASTREG=_PS };
>
> +#define PC_REGNUM	_PC	/* Program Counter */
> +#define SP_REGNUM	_RSP	/* Stack Pointer */
> +#define PTRACE_PC	rip	/* Program Counter, in ptrace regs. */
> +
>  /* Number of bytes of registers.  */
>  #define NUMREGBYTES (_LASTREG*8)
>
> --- 1.2/kernel/kgdbstub.c	Wed Jan 21 12:21:23 2004
> +++ edited/kernel/kgdbstub.c	Mon Jan 26 12:17:02 2004
> @@ -615,6 +615,9 @@
>  	 * need one here */
>  	procindebug[smp_processor_id()] = 1;
>
> +	/* Clear the out buffer. */
> +	memset(remcomOutBuffer, 0, sizeof(remcomOutBuffer));
> +
>  	/* Master processor is completely in the debugger */
>  	if (kgdb_ops->post_master_code)
>  		kgdb_ops->post_master_code(linux_regs, exVector, err_code);
> @@ -624,9 +627,7 @@
>  		if(remcomInBuffer[0] == 'H' && remcomInBuffer[1] =='c') {
>  			remove_all_break();
>  			atomic_set(&kgdb_killed_or_detached, 0);
> -			remcomOutBuffer[0] = 'O';
> -			remcomOutBuffer[1] = 'K';
> -			remcomOutBuffer[2] = 0;
> +			strcpy(remcomOutBuffer, "OK");
>  		}
>  		else
>  			return 1;
> @@ -634,13 +635,25 @@
>  	else {
>
>  		/* reply to host that an exception has occurred */
> -		remcomOutBuffer[0] = 'S';
> -		remcomOutBuffer[1] = hexchars[signo >> 4];
> -		remcomOutBuffer[2] = hexchars[signo % 16];
> -		remcomOutBuffer[3] = 'p';
> -
> +		ptr = remcomOutBuffer;
> +		*ptr++ = 'T';
> +		*ptr++ = hexchars[(signo >> 4) % 16];
> +		*ptr++ = hexchars[signo % 16];
> +		*ptr++ = hexchars[(PC_REGNUM >> 4) % 16];
> +		*ptr++ = hexchars[PC_REGNUM % 16];
> +		*ptr++ = ':';
> +		ptr = kgdb_mem2hex((char *)&linux_regs->PTRACE_PC, ptr, 4, 0);
> +		*ptr++ = ';';
> +		*ptr++ = hexchars[SP_REGNUM >> 4];
> +		*ptr++ = hexchars[SP_REGNUM & 0xf];
> +		*ptr++ = ':';
> +		ptr = kgdb_mem2hex(((char *)linux_regs) + SP_REGNUM * 4, ptr,
> +				4, 0);
> +		*ptr++ = ';';
> +		ptr += strlen(strcpy(ptr, "thread:"));
>  		int_to_threadref(&thref, shadow_pid(current->pid));
> -		*pack_threadid(remcomOutBuffer + 4, &thref) = 0;
> +		ptr = pack_threadid(ptr, &thref);
> +		*ptr++ = ';';
>  	}
>  	putpacket(remcomOutBuffer, 0);
>  	kgdb_connected = 1;
> @@ -651,8 +664,10 @@
>  	while (1) {
>  		int bpt_type = 0;
>  		error = 0;
> -		remcomOutBuffer[0] = 0;
> -		remcomOutBuffer[1] = 0;
> +
> +		/* Clear the out buffer. */
> +		memset(remcomOutBuffer, 0, sizeof(remcomOutBuffer));
> +
>  		getpacket(remcomInBuffer);
>
>  #if KGDB_DEBUG
> @@ -666,7 +681,6 @@
>  			remcomOutBuffer[0] = 'S';
>  			remcomOutBuffer[1] = hexchars[signo >> 4];
>  			remcomOutBuffer[2] = hexchars[signo % 16];
> -			remcomOutBuffer[3] = 0;
>  			break;
>
>  		case 'g':	/* return the value of the CPU registers */
> @@ -764,9 +778,7 @@
>  			 * continue.
>  			 */
>  		case 'D':
> -			remcomOutBuffer[0] = 'O';
> -			remcomOutBuffer[1] = 'K';
> -			remcomOutBuffer[2] = '\0';
> +			strcpy(remcomOutBuffer, "OK");
>  			remove_all_break();
>  			putpacket(remcomOutBuffer, 0);
>  			kgdb_connected = 0;
> @@ -804,19 +816,16 @@
>  						i++;
>  					}
>  				}
> -				*(--ptr) = '\0';
>  				break;
>
>  			case 'C':
>  				/* Current thread id */
> -				remcomOutBuffer[0] = 'Q';
> -				remcomOutBuffer[1] = 'C';
> +				strcpy(remcomOutBuffer, "QC");
>
>  				threadid = shadow_pid(current->pid);
>
>  				int_to_threadref(&thref, threadid);
>  				pack_threadid(remcomOutBuffer + 2, &thref);
> -				remcomOutBuffer[18] = '\0';
>  				break;
>
>  			case 'E':
> @@ -829,7 +838,6 @@
>  			case 'T':
>  				if (memcmp(remcomInBuffer+1, "ThreadExtraInfo,",16))
>  				{
> -					remcomOutBuffer[0] = 0;
>  					strcpy(remcomOutBuffer, "E05");
>  					break;
>  				}
> @@ -872,14 +880,11 @@
>  				thread = getthread(linux_regs, threadid);
>  				if (!thread && threadid > 0) {
>  					remcomOutBuffer[0] = 'E';
> -					remcomOutBuffer[1] = '\0';
>  					break;
>  				}
>  				kgdb_usethread = thread;
>  				kgdb_usethreadid = threadid;
> -				remcomOutBuffer[0] = 'O';
> -				remcomOutBuffer[1] = 'K';
> -				remcomOutBuffer[2] = '\0';
> +				strcpy(remcomOutBuffer, "OK");
>  				break;
>
>  			case 'c':
> @@ -892,14 +897,11 @@
>  					thread = getthread(linux_regs, threadid);
>  					if (!thread && threadid > 0) {
>  						remcomOutBuffer[0] = 'E';
> -						remcomOutBuffer[1] = '\0';
>  						break;
>  					}
>  					kgdb_contthread = thread;
>  				}
> -				remcomOutBuffer[0] = 'O';
> -				remcomOutBuffer[1] = 'K';
> -				remcomOutBuffer[2] = '\0';
> +				strcpy(remcomOutBuffer, "OK");
>  				break;
>  			}
>  			break;
> @@ -909,14 +911,10 @@
>  			ptr = &remcomInBuffer[1];
>  			kgdb_hexToLong(&ptr, &threadid);
>  			thread = getthread(linux_regs, threadid);
> -			if (thread) {
> -				remcomOutBuffer[0] = 'O';
> -				remcomOutBuffer[1] = 'K';
> -				remcomOutBuffer[2] = '\0';
> -			} else {
> +			if (thread)
> +				strcpy(remcomOutBuffer, "OK");
> +			else
>  				remcomOutBuffer[0] = 'E';
> -				remcomOutBuffer[1] = '\0';
> -			}
>  			break;
>  		case 'z':
>  		case 'Z':
> @@ -1127,7 +1125,7 @@
>  	 */
>  	printk(KERN_CRIT "Waiting for connection from remote gdb... ");
>  	breakpoint() ;
> -	printk(KERN_CRIT "Connected.\n");
> +	printk("Connected.\n");
>  }
>
>  #ifdef CONFIG_KGDB_CONSOLE
>
> --
> Tom Rini
> http://gate.crashing.org/~trini/
>
> ** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

-- 
Amit Kale
EmSysSoft (http://www.emsyssoft.com)
KGDB: Linux Kernel Source Level Debugger (http://kgdb.sourceforge.net)


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

* Re: PPC KGDB changes and some help?
  2004-01-26 22:06                         ` Tom Rini
@ 2004-01-27  9:05                           ` Amit S. Kale
  0 siblings, 0 replies; 35+ messages in thread
From: Amit S. Kale @ 2004-01-27  9:05 UTC (permalink / raw)
  To: Tom Rini, George Anzinger; +Cc: Powerpc Linux, Linux Kernel, KGDB bugreports

On Tuesday 27 Jan 2004 3:36 am, Tom Rini wrote:
> On Mon, Jan 26, 2004 at 01:45:44PM -0800, George Anzinger wrote:
> > Tom Rini wrote:
> > >>There is a real danger of passing signal info back to gdb as it will
> > >> want to try to deliver the signal which is a non-compute in most kgdbs
> > >> in the field.  I did put code in the mm-kgdb to do just this, but
> > >> usually the arrival of such a signal (other than SIGTRAP) is the end
> > >> of the kernel. All that is left is to read the tea leaves.
> > >
> > >The gdb I've been testing this with knows better than to try and send a
> > >singal back, so that's not a worry.  The motivation behind doing this
> > >however is along the lines of "if it ain't broke, don't remove it".  The
> > >original stub was getting all of this information correctly, so why stop
> > >doing it?
> >
> > You sure.  If so what gdb?  And how does it know?  I suppose you could
> > tell it with a script, but then what if one forgets?
>
> GNU gdb 6.0 (MontaVista 6.0-8.0.4.0300532 2003-12-24)
> Copyright 2003 Free Software Foundation, Inc.
> [snip]
>
> [New Thread 289]
>
> Program received signal SIGSEGV, Segmentation fault.
> [Switching to Thread 289]
> 0x00000000 in ?? ()
> (gdb) c
> Continuing.
> Can't send signals to this remote system.  SIGSEGV not sent.

This is because gdb tries packet "C" first. If that fails, which is the case 
with kgdb, it falls back to packet "c". It doesn't need packet "C" for 
SIGTRAP as it's used for breakpoints and single stepping and shouldn't be 
delivered to a debuggee.

SIGSEGV has to be actually delivered to an application for it to die. A user 
has a choice of correcting a bug on the fly and let the application continue 
without segfaulting. It can tell gdb to continue the debugee without a 
signal. It doesn't apply in case of kernel, so it's not a bug. Kernel anyway 
"delivers" the signal, that is, continues with a panic once kgdb returns. We 
don't offer a user the choice of correcting a segfault on the fly.

>
> Noting that 0x0 is correct as the code that triggered this was:
> static void (*dummy)(struct pt_regs *regs);
> int drop_kgdb(void) {
>         struct pt_regs regs;
>         memset(&regs, 0, sizeof(regs));
>         dummy(&regs);
>
>         return 0;
> }
> module_init(drop_kgdb);
>
> --
> Tom Rini
> http://gate.crashing.org/~trini/
>
> ** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

-- 
Amit Kale
EmSysSoft (http://www.emsyssoft.com)
KGDB: Linux Kernel Source Level Debugger (http://kgdb.sourceforge.net)


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

* Re: PPC KGDB changes and some help?
  2004-01-23 22:46                 ` Tom Rini
                                     ` (2 preceding siblings ...)
  2004-01-24  3:47                   ` [PATCH] Kgdb dwarf2 for asm George Anzinger
@ 2004-01-27 18:22                   ` Tom Rini
  3 siblings, 0 replies; 35+ messages in thread
From: Tom Rini @ 2004-01-27 18:22 UTC (permalink / raw)
  To: Amit S. Kale
  Cc: Powerpc Linux, Linux Kernel, KGDB bugreports, George Anzinger

On Fri, Jan 23, 2004 at 03:46:05PM -0700, Tom Rini wrote:

> On Thu, Jan 22, 2004 at 11:05:55AM -0700, Tom Rini wrote:
> [snip]
> > First up:
> > We need to call flush_instruction_cache() on a 'c' or 's' command.
> >  arch/ppc/kernel/ppc-stub.c |   19 ++++++-------------
> >  1 files changed, 6 insertions(+), 13 deletions(-)
> 
> On tpo of this patch, there's the following:
> Put back some code to figure out what signal we're dealing with.

And here's a version that with some help from Daniel always passes the
correct information back to GDB (the original code did not).

 arch/ppc/kernel/ppc-stub.c |   63 ++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 60 insertions(+), 3 deletions(-)
--- 1.15/arch/ppc/kernel/ppc-stub.c	Thu Jan 22 10:53:06 2004
+++ edited/arch/ppc/kernel/ppc-stub.c	Tue Jan 27 11:08:25 2004
@@ -3,6 +3,7 @@
  *
  * PowerPC-specific bits to work with the common KGDB stub.
  *
+ * 1998 (c) Michael AK Tesch (tesch@cs.wisc.edu)
  * 2003 (c) TimeSys Corporation
  * 2004 (c) MontaVista Software, Inc.
  * This file is licensed under the terms of the GNU General Public License
@@ -19,13 +20,69 @@
 #include <asm/processor.h>
 #include <asm/machdep.h>
 
+/* Convert the hardware trap type code to a unix signal number. */
+/*
+ * This table contains the mapping between PowerPC hardware trap types, and
+ * signals, which are primarily what GDB understands.
+ */
+static struct hard_trap_info
+{
+	unsigned int tt;		/* Trap type code for powerpc */
+	unsigned char signo;		/* Signal that we map this trap into */
+} hard_trap_info[] = {
+#if defined(CONFIG_40x)
+	{ 0x0100, 0x02 /* SIGINT */  },		/* critical input interrupt */
+	{ 0x0200, 0x0b /* SIGSEGV */ },		/* machine check */
+	{ 0x0300, 0x0b /* SIGSEGV */ },		/* data storage */
+	{ 0x0400, 0x0a /* SIGBUS */  },		/* instruction storage */
+	{ 0x0500, 0x02 /* SIGINT */  },		/* interrupt */
+	{ 0x0600, 0x0a /* SIGBUS */  },		/* alignment */
+	{ 0x0700, 0x04 /* SIGILL */  },		/* program */
+	{ 0x0800, 0x04 /* SIGILL */  },		/* reserved */
+	{ 0x0900, 0x04 /* SIGILL */  },		/* reserved */
+	{ 0x0a00, 0x04 /* SIGILL */  },		/* reserved */
+	{ 0x0b00, 0x04 /* SIGILL */  },		/* reserved */
+	{ 0x0c00, 0x14 /* SIGCHLD */ },		/* syscall */
+	{ 0x0d00, 0x04 /* SIGILL */  },		/* reserved */
+	{ 0x0e00, 0x04 /* SIGILL */  },		/* reserved */
+	{ 0x0f00, 0x04 /* SIGILL */  },		/* reserved */
+	{ 0x2000, 0x05 /* SIGTRAP */},		/* debug */
+#else
+	{ 0x0200, 0x0b /* SIGSEGV */ },		/* machine check */
+	{ 0x0300, 0x0b /* SIGSEGV */ },		/* address error (store) */
+	{ 0x0400, 0x0a /* SIGBUS */ },		/* instruction bus error */
+	{ 0x0500, 0x02 /* SIGINT */ },		/* interrupt */
+	{ 0x0600, 0x0a /* SIGBUS */ },		/* alingment */
+	{ 0x0700, 0x05 /* SIGTRAP */ },		/* breakpoint trap */
+	{ 0x0800, 0x08 /* SIGFPE */},		/* fpu unavail */
+	{ 0x0900, 0x0e /* SIGALRM */ },		/* decrementer */
+	{ 0x0a00, 0x04 /* SIGILL */ },		/* reserved */
+	{ 0x0b00, 0x04 /* SIGILL */ },		/* reserved */
+	{ 0x0c00, 0x14 /* SIGCHLD */ },		/* syscall */
+	{ 0x0d00, 0x05 /* SIGTRAP */ },		/* single-step/watch */
+	{ 0x0e00, 0x08 /* SIGFPE */ },		/* fp assist */
+#endif
+	{ 0x0000, 0x000 }			/* Must be last */
+};
+
+static int computeSignal(unsigned int tt)
+{
+	struct hard_trap_info *ht;
+
+	for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
+		if (ht->tt == tt)
+			return ht->signo;
+
+	return SIGHUP; /* default for things we don't know about */
+}
+
 /*
  * Routines
  */
 static void
 kgdb_debugger(struct pt_regs *regs)
 {
-	(*linux_debug_hook) (0, 0, 0, regs);
+	(*linux_debug_hook) (0, computeSignal(regs->trap), 0, regs);
 	return;
 }
 
@@ -52,14 +109,14 @@
 int
 kgdb_iabr_match(struct pt_regs *regs)
 {
-	(*linux_debug_hook) (0, 0, 0, regs);
+	(*linux_debug_hook) (0, computeSignal(regs->trap), 0, regs);
 	return 1;
 }
 
 int
 kgdb_dabr_match(struct pt_regs *regs)
 {
-	(*linux_debug_hook) (0, 0, 0, regs);
+	(*linux_debug_hook) (0, computeSignal(regs->trap), 0, regs);
 	return 1;
 }
 

-- 
Tom Rini
http://gate.crashing.org/~trini/

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

end of thread, other threads:[~2004-01-27 18:22 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <20040120172708.GN13454@stop.crashing.org>
     [not found] ` <200401211946.17969.amitkale@emsyssoft.com>
     [not found]   ` <20040121153019.GR13454@stop.crashing.org>
2004-01-21 16:53     ` PPC KGDB changes and some help? Amit S. Kale
2004-01-21 18:42       ` Tom Rini
2004-01-21 19:21         ` Tom Rini
2004-01-21 19:22           ` Tom Rini
2004-01-22 17:44             ` Tom Rini
2004-01-22 18:05               ` Tom Rini
2004-01-23 22:46                 ` Tom Rini
2004-01-23 23:38                   ` George Anzinger
2004-01-26 20:46                     ` Tom Rini
2004-01-26 21:27                       ` George Anzinger
2004-01-26 21:42                         ` Tom Rini
2004-01-26 22:35                           ` George Anzinger
2004-01-26 21:45                       ` George Anzinger
2004-01-26 22:06                         ` Tom Rini
2004-01-27  9:05                           ` Amit S. Kale
2004-01-24  0:48                   ` George Anzinger
2004-01-24  3:47                   ` [PATCH] Kgdb dwarf2 for asm George Anzinger
2004-01-27 18:22                   ` PPC KGDB changes and some help? Tom Rini
2004-01-21 22:03           ` Tom Rini
2004-01-21 23:12           ` George Anzinger
2004-01-22 15:07             ` Tom Rini
2004-01-22 15:25               ` Hollis Blanchard
2004-01-22 15:45                 ` Tom Rini
2004-01-22 16:06                   ` Amit S. Kale
2004-01-22 16:45                     ` Tom Rini
2004-01-22 22:46                       ` George Anzinger
2004-01-22 22:52                         ` Tom Rini
2004-01-22 23:09                           ` George Anzinger
2004-01-22 22:35                     ` George Anzinger
2004-01-23 17:08                     ` Tom Rini
2004-01-22 21:54                   ` George Anzinger
2004-01-26 21:32           ` Tom Rini
2004-01-27  8:59             ` Amit S. Kale
2004-01-21 23:05         ` George Anzinger
2004-01-22 15:03           ` Tom Rini

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox