Skip to contentSkip to conversation

PPC KGDB changes and some help?

PATCH New Amit S. Kale 5 participants 42 messages Jan 21, 2004 – Jan 27, 2004 1 message not in the archive Kbuild

lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

#1 lore raw

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.

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.

Review

Quoted 2 lines
(quoted diff) +1 -1
-	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?

Review

Quoted 10 lines
(quoted diff) +10 -0
+        */
+#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.
Hardcoded nip is worse.
Any ideas for a better code?

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.

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.

Quoted 143 lines

Now, when I say that things don't quite work, here's a gdb log:
Remote debugging using /dev/ttyS0
Sending packet: $qPassSignals:0e;10;14;17;1a;1b;1c;21;24;25;4c;#df...Ack Packet received:
Packet qPassSignals (pass-signals) is NOT supported
Sending packet: $Hc-1#09...Ack
Packet received: OK
Sending packet: $qC#b4...Ack
Packet received: QC0000000000000001
Sending packet: $qOffsets#4b...Ack
Packet received:
Sending packet: $?#3f...Ack
Packet received: S05
Sending packet: $Hg1#e0...Ack
Packet received: OK
Sending packet: $g#67...Ack
Packet received:
00000001c3fddfd0c3fdb7400000002d00000448c01d4e7cffff8ae9c01d501c00007548c01 d00000000ea5fc01d00008200002200000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000004000000035303d30000 0000000000000c0003dec0000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000 000000000c002c9580002903242000028c002c9ecc00d5574000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000 0 Sending packet: $mc002c9e8,c#2a...Ack
Packet received: 4bffff513c60c0153863b1d0
0xc002c958 in breakpoint () at kernel/kgdbstub.c:1082
1082 wmb();

<< break show_cpuinfo >>

Sending packet: $qSymbol::#5b...Ack
Packet received:
Packet qSymbol (symbol-lookup) is NOT supported
Sending packet: $mc000be54,4#f0...Ack
Packet received: 9421ffd0
Sending packet: $mc000be58,4#f4...Ack
Packet received: 7c0802a6
Sending packet: $mc000be5c,4#1f...Ack
Packet received: 39600000
Sending packet: $mc000be60,4#ed...Ack
Packet received: bf410018
Sending packet: $mc000be64,4#f1...Ack
Packet received: 90010034
Sending packet: $mc000be68,4#f5...Ack
Packet received: 37e4ffff
Breakpoint 1 at 0xc000be68: file arch/ppc/kernel/setup.c, line 144.

<< continue >>

Continuing.
Sending packet: $Z0,c0000000,4#c9...Ack
Packet received: OK
Packet Z0 (software-breakpoint) is supported
Sending packet: $Z0,c000be68,4#3e...Ack
Packet received: OK
Sending packet: $Hs1#ec...Ack
Packet received:
Sending packet: $Hc0#db...Ack
Packet received: OK
Sending packet: $c#63...Ack
Packet received: S05p0000000000000001
[New Thread 1]
Sending packet: $g#67...Ack
Packet received:
00000001c3fddfd0c3fdb7400000002d00000448c01d4e7cffff8ae9c01d501c00007548c01 d00000000ea5fc01d00008200002200000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000004000000035303d30000 0000000000000c0003dec0000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000 000000000c002c9580002903242000028c002c9ecc00d5574000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000 0

Program received signal SIGTRAP, Trace/breakpoint trap. Sending packet: $mc002c9e8,c#2a...Ack
Packet received: 4bffff513c60c0153863b1d0 Sending packet: $z0,c0000000,4#e9...Ack
Packet received: OK
Sending packet: $z0,c000be68,4#5e...Ack
Packet received: OK
0xc002c958 in breakpoint () at kernel/kgdbstub.c:1082
1082 wmb();

<< continue >>

Continuing.
Sending packet: $Z0,c0000000,4#c9...Ack
Packet received: OK
Sending packet: $Z0,c000be68,4#3e...Ack
Packet received: OK
Sending packet: $c#63...Ack
Packet received: S05p0000000000000001
Sending packet: $g#67...Ack
Packet received:
00000001c3fddfd0c3fdb7400000002d00000448c01d4e7cffff8ae9c01d501c00007548c01 d00000000ea5fc01d00008200002200000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000004000000035303d30000 0000000000000c0003dec0000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000 000000000c002c9580002903242000028c002c9ecc00d5574000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000 0

Program received signal SIGTRAP, Trace/breakpoint trap. Sending packet: $mc002c9e8,c#2a...Ack
Packet received: 4bffff513c60c0153863b1d0 Sending packet: $z0,c0000000,4#e9...Ack
Packet received: OK
Sending packet: $z0,c000be68,4#5e...Ack
Packet received: OK
0xc002c958 in breakpoint () at kernel/kgdbstub.c:1082
1082 wmb();

<< quit >>

The program is running. Exit anyway? (y or n) Sending packet: $k#6b...Ack

Which leads me to wonder, has software breakpoints been tested at all? PPC allows for HW breakpoints, but in general there's only 1 or 2. And, FWIW, I have a much uglier version of things which overrides the linux_debug_hook with the working handle_exception function in ppc-stub.c, and found the same problem. Also, what I'm going to try and do next is to add support for using the HW breakpoints and see if that fixes things, or at least gets me further along.

Quoted 1 line

Any pointers or ideas? Thanks.

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

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

#2 lore raw
Quoted 4 lines · Amit S. Kale

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.

Quoted 10 lines

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.

Review

Quoted 2 lines
(quoted diff) +1 -1
-	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?

Quoted 5 lines

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).

Quoted 5 lines
Quoted 5 lines
(quoted diff) +5 -0
+        */
+#if 0
+       extern atomic_t kgdb_setting_breakpoint;
+       if (atomic_read(&kgdb_setting_breakpoint))
+               regs->nip += 4;
Quoted 8 lines

Review

Quoted 5 lines
(quoted diff) +5 -0
+#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.

Quoted 2 lines

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.

Quoted 5 lines

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.

Quoted 5 lines

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.

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

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

#3 lore raw

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 <[email protected]>
* Changes for coding conventions

2004-01-21 Tom Rini <[email protected]>
* Added a prototype for kgdb8250_add_port.

Quoted 71 lines · Tom Rini
Quoted 4 lines · Amit S. Kale

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.

Quoted 10 lines

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.

Review

Quoted 2 lines
(quoted diff) +1 -1
-	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?

Quoted 3 lines

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).

Quoted 5 lines
Quoted 5 lines
(quoted diff) +5 -0
+        */
+#if 0
+       extern atomic_t kgdb_setting_breakpoint;
+       if (atomic_read(&kgdb_setting_breakpoint))
+               regs->nip += 4;
Quoted 8 lines

Review

Quoted 5 lines
(quoted diff) +5 -0
+#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.

Quoted 2 lines

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.

Quoted 5 lines

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.

Quoted 5 lines

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.

Signature · 3 lines
Amit Kale
EmSysSoft (http://www.emsyssoft.com)
KGDB: Linux Kernel Source Level Debugger (http://kgdb.sourceforge.net)
#4 lore raw
Quoted 7 lines · Amit S. Kale

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 =====

kernel/kgdbstub.c +5 -3
@@ -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.

Signature · 2 lines
Tom Rini
http://gate.crashing.org/~trini/
#5 lore raw
Quoted 11 lines · Tom Rini
Quoted 7 lines · Amit S. Kale

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.

arch/ppc/Kconfig +8 -0
@@ -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)"
arch/ppc/kernel/ppc-stub.c +15 -15
@@ -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;
+	
 }
arch/ppc/kernel/setup.c +0 -13
@@ -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)
arch/ppc/syslib/Makefile +1 -1
@@ -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
arch/ppc/syslib/gen550_dbg.c +2 -0
@@ -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>
arch/ppc/syslib/gen550_kgdb.c +2 -2
@@ -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);
include/asm-ppc/kgdb.h +18 -3
@@ -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 ([email protected])
+ * PPC Mods (C) 2003 John Whitney ([email protected])
  * PPC Mods (C) 1998 Michael Tesch ([email protected])
  *
  * Copyright (C) 1995 David S. Miller ([email protected])
@@ -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);
include/asm-ppc/machdep.h +1 -0
@@ -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);
include/asm-ppc/processor.h +3 -0
@@ -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)
Signature · 2 lines
Tom Rini
http://gate.crashing.org/~trini/
#6 lore raw
Quoted 8 lines · Tom Rini
Quoted 7 lines · Tom Rini
Quoted 5 lines · Amit S. Kale

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

Quoted 7 lines
Quoted 4 lines
Quoted 2 lines

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.

arch/ppc/Kconfig +5 -5
@@ -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)
arch/ppc/platforms/lopec_setup.c +5 -39

62 lines not on this page · raw message

Signature · 2 lines
Tom Rini
http://gate.crashing.org/~trini/
#7 lore raw
Quoted 12 lines · Tom Rini
Quoted 11 lines · Tom Rini
Quoted 10 lines · Tom Rini
Quoted 7 lines · Amit S. Kale

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.

Quoted 7 lines
Quoted 4 lines
Quoted 1 line

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(-)
arch/ppc/kernel/ppc-stub.c +83 -101
@@ -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.

Signature · 2 lines
Tom Rini
http://gate.crashing.org/~trini/
#8 lore raw
Quoted 15 lines · Tom Rini
Quoted 14 lines · Tom Rini
Quoted 13 lines · Tom Rini
Quoted 11 lines · Tom Rini
Quoted 7 lines · Amit S. Kale

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.

Quoted 7 lines
Quoted 5 lines
Quoted 2 lines

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(-)
arch/ppc/kernel/ppc-stub.c +6 -13
@@ -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,
 };
Signature · 2 lines
Tom Rini
http://gate.crashing.org/~trini/
#9 lore raw

On Thu, Jan 22, 2004 at 11:05:55AM -0700, Tom Rini wrote:
[snip]

Quoted 4 lines

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(-)
arch/ppc/kernel/ppc-stub.c +60 -3
@@ -3,6 +3,7 @@
  *
  * PowerPC-specific bits to work with the common KGDB stub.
  *
+ * 1998 (c) Michael AK Tesch ([email protected])
  * 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.

Signature · 2 lines
Tom Rini
http://gate.crashing.org/~trini/
#10 lore raw
Quoted 113 lines · Tom Rini

On Thu, Jan 22, 2004 at 11:05:55AM -0700, Tom Rini wrote:
[snip]

Quoted 4 lines

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(-)
arch/ppc/kernel/ppc-stub.c +60 -3
@@ -3,6 +3,7 @@
  *
  * PowerPC-specific bits to work with the common KGDB stub.
  *
+ * 1998 (c) Michael AK Tesch ([email protected])
  * 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;
 }
 
Quoted 5 lines

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.

Signature · 3 lines
George Anzinger   [email protected]
High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml
#11 lore raw
Quoted 117 lines · George Anzinger
Quoted 116 lines · Tom Rini

On Thu, Jan 22, 2004 at 11:05:55AM -0700, Tom Rini wrote:
[snip]

Quoted 4 lines

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(-)
arch/ppc/kernel/ppc-stub.c +4 -0
@@ -3,6 +3,7 @@
 *
 * PowerPC-specific bits to work with the common KGDB stub.
 *
+ * 1998 (c) Michael AK Tesch ([email protected])
 * 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.
+ */

arch/ppc/kernel/ppc-stub.c +4 -0
+static struct hard_trap_info
+{
+	unsigned int tt;		/* Trap type code for powerpc */
+	unsigned char signo;		/* Signal that we map this trap into 

*/

arch/ppc/kernel/ppc-stub.c +47 -0
+} 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)
{

arch/ppc/kernel/ppc-stub.c +1 -1
-	(*linux_debug_hook) (0, 0, 0, regs);
+	(*linux_debug_hook) (0, computeSignal(regs->trap), 0, regs);
	return;
}
arch/ppc/kernel/ppc-stub.c +0 -0
@@ -52,14 +109,14 @@

int
kgdb_iabr_match(struct pt_regs *regs)
{

arch/ppc/kernel/ppc-stub.c +1 -1
-	(*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)
{

arch/ppc/kernel/ppc-stub.c +1 -1
-	(*linux_debug_hook) (0, 0, 0, regs);
+	(*linux_debug_hook) (0, computeSignal(regs->trap), 0, regs);
	return 1;
}
Quoted 7 lines
Quoted 5 lines

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.

Quoted 5 lines

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?

Signature · 2 lines
Tom Rini
http://gate.crashing.org/~trini/
#12 lore raw
Quoted 133 lines · Tom Rini
Quoted 119 lines · George Anzinger
Quoted 117 lines · Tom Rini

On Thu, Jan 22, 2004 at 11:05:55AM -0700, Tom Rini wrote:
[snip]

Quoted 4 lines

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(-)
arch/ppc/kernel/ppc-stub.c +4 -0
@@ -3,6 +3,7 @@
 *
 * PowerPC-specific bits to work with the common KGDB stub.
 *
+ * 1998 (c) Michael AK Tesch ([email protected])
 * 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.
+ */

arch/ppc/kernel/ppc-stub.c +4 -0
+static struct hard_trap_info
+{
+	unsigned int tt;		/* Trap type code for powerpc */
+	unsigned char signo;		/* Signal that we map this trap into 

*/

arch/ppc/kernel/ppc-stub.c +47 -0
+} 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)
{

arch/ppc/kernel/ppc-stub.c +1 -1
-	(*linux_debug_hook) (0, 0, 0, regs);
+	(*linux_debug_hook) (0, computeSignal(regs->trap), 0, regs);
	return;
}
arch/ppc/kernel/ppc-stub.c +0 -0
@@ -52,14 +109,14 @@

int
kgdb_iabr_match(struct pt_regs *regs)
{

arch/ppc/kernel/ppc-stub.c +1 -1
-	(*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)
{

arch/ppc/kernel/ppc-stub.c +1 -1
-	(*linux_debug_hook) (0, 0, 0, regs);
+	(*linux_debug_hook) (0, computeSignal(regs->trap), 0, regs);
	return 1;
}
Quoted 7 lines
Quoted 5 lines

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.

Quoted 9 lines
Quoted 1 line

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?

Signature · 3 lines
George Anzinger   [email protected]
High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml
#13 lore raw
Quoted 141 lines · George Anzinger
Quoted 140 lines · Tom Rini
Quoted 119 lines · George Anzinger
Quoted 117 lines · Tom Rini

On Thu, Jan 22, 2004 at 11:05:55AM -0700, Tom Rini wrote:
[snip]

Quoted 4 lines

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(-)
arch/ppc/kernel/ppc-stub.c +4 -0
@@ -3,6 +3,7 @@
 *
 * PowerPC-specific bits to work with the common KGDB stub.
 *
+ * 1998 (c) Michael AK Tesch ([email protected])
 * 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.
+ */

arch/ppc/kernel/ppc-stub.c +4 -0
+static struct hard_trap_info
+{
+	unsigned int tt;		/* Trap type code for powerpc */
+	unsigned char signo;		/* Signal that we map this trap into 

*/

arch/ppc/kernel/ppc-stub.c +47 -0
+} 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)
{

arch/ppc/kernel/ppc-stub.c +1 -1
-	(*linux_debug_hook) (0, 0, 0, regs);
+	(*linux_debug_hook) (0, computeSignal(regs->trap), 0, regs);
	return;
}
arch/ppc/kernel/ppc-stub.c +0 -0
@@ -52,14 +109,14 @@

int
kgdb_iabr_match(struct pt_regs *regs)
{

arch/ppc/kernel/ppc-stub.c +1 -1
-	(*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)
{

arch/ppc/kernel/ppc-stub.c +1 -1
-	(*linux_debug_hook) (0, 0, 0, regs);
+	(*linux_debug_hook) (0, computeSignal(regs->trap), 0, regs);
	return 1;
}
Quoted 7 lines
Quoted 5 lines

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.

Quoted 5 lines

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.

Quoted 8 lines
Quoted 6 lines

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.

Signature · 2 lines
Tom Rini
http://gate.crashing.org/~trini/
#14 lore raw
Quoted 64 lines · Tom Rini
Quoted 46 lines
Quoted 46 lines
Quoted 30 lines
Quoted 30 lines

+
/*
* Routines
*/
static void
kgdb_debugger(struct pt_regs *regs)
{

(quoted diff) +1 -1
-	(*linux_debug_hook) (0, 0, 0, regs);
+	(*linux_debug_hook) (0, computeSignal(regs->trap), 0, regs);
	return;
}
(quoted diff) +0 -0
@@ -52,14 +109,14 @@

int
kgdb_iabr_match(struct pt_regs *regs)
{

(quoted diff) +1 -1
-	(*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)
{

(quoted diff) +1 -1
-	(*linux_debug_hook) (0, 0, 0, regs);
+	(*linux_debug_hook) (0, computeSignal(regs->trap), 0, regs);
	return 1;
}
Quoted 7 lines
Quoted 5 lines

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.

Quoted 1 line

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.

Quoted 8 lines
Quoted 6 lines

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.

Quoted 2 lines

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.

Quoted 1 line
Signature · 3 lines
George Anzinger   [email protected]
High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml
#15 lore raw
In reply to Tom Rini
Quoted 10 lines · Tom Rini
Quoted 2 lines

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?

Signature · 3 lines
George Anzinger   [email protected]
High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml
#16 lore raw
Quoted 9 lines · George Anzinger
Quoted 8 lines · Tom Rini
Quoted 6 lines

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.

Quoted 8 lines
Quoted 6 lines

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);

Signature · 2 lines
Tom Rini
http://gate.crashing.org/~trini/
#17 lore raw
Quoted 21 lines · Tom Rini
Quoted 7 lines · George Anzinger
Quoted 6 lines · Tom Rini
Quoted 5 lines

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.

Quoted 8 lines
Quoted 5 lines

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]

Quoted 8 lines

[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.

Quoted 17 lines

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/

Signature · 3 lines
Amit Kale
EmSysSoft (http://www.emsyssoft.com)
KGDB: Linux Kernel Source Level Debugger (http://kgdb.sourceforge.net)
#18 lore raw
In reply to Tom Rini

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.

Signature · 3 lines
George Anzinger   [email protected]
High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml
Makefile +3 -1
diff -urP -I '\$Id:.*Exp \$' -X /usr/src/patch.exclude linux-2.6.0-akgdb/Makefile linux/Makefile
@@ -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

arch/i386/Kconfig +2 -2
diff -urP -I '\$Id:.*Exp \$' -X /usr/src/patch.exclude linux-2.6.0-akgdb/arch/i386/Kconfig linux/arch/i386/Kconfig
@@ -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
arch/i386/Makefile +3 -1
diff -urP -I '\$Id:.*Exp \$' -X /usr/src/patch.exclude linux-2.6.0-akgdb/arch/i386/Makefile linux/arch/i386/Makefile
@@ -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
 
arch/i386/kernel/entry.S +113 -0

116 lines not on this page · raw message

arch/i386/kernel/head.S +10 -0
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
@@ -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.
arch/i386/kernel/smpboot.c +3 -0
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
@@ -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));
include/linux/dwarf2-lang.h +286 -0

286 lines not on this page · raw message

include/linux/dwarf2.h +775 -0

775 lines not on this page · raw message

Binary files linux-2.6.0-akgdb/scripts/bin2c and linux/scripts/bin2c differ

scripts/dwarfh.awk +19 -0
diff -urP -I '\$Id:.*Exp \$' -X /usr/src/patch.exclude linux-2.6.0-akgdb/scripts/dwarfh.awk linux/scripts/dwarfh.awk
@@ -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"
+}
#19 lore raw

PATCH 1/1 Kgdb dwarf2 for asm

In reply to Tom Rini

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.

Signature · 3 lines
George Anzinger   [email protected]
High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml
Makefile +3 -1
diff -urP -I '\$Id:.*Exp \$' -X /usr/src/patch.exclude linux-2.6.0-akgdb/Makefile linux/Makefile
@@ -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

arch/i386/Kconfig +2 -2
diff -urP -I '\$Id:.*Exp \$' -X /usr/src/patch.exclude linux-2.6.0-akgdb/arch/i386/Kconfig linux/arch/i386/Kconfig
@@ -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
arch/i386/Makefile +3 -1
diff -urP -I '\$Id:.*Exp \$' -X /usr/src/patch.exclude linux-2.6.0-akgdb/arch/i386/Makefile linux/arch/i386/Makefile
@@ -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
 
arch/i386/kernel/entry.S +113 -0

116 lines not on this page · raw message

arch/i386/kernel/head.S +10 -0
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
@@ -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.
arch/i386/kernel/smpboot.c +3 -0
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
@@ -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));
include/linux/dwarf2-lang.h +286 -0

286 lines not on this page · raw message

include/linux/dwarf2.h +775 -0

775 lines not on this page · raw message

Binary files linux-2.6.0-akgdb/scripts/bin2c and linux/scripts/bin2c differ

scripts/dwarfh.awk +19 -0
diff -urP -I '\$Id:.*Exp \$' -X /usr/src/patch.exclude linux-2.6.0-akgdb/scripts/dwarfh.awk linux/scripts/dwarfh.awk
@@ -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"
+}
#20 lore raw
In reply to Tom Rini
Quoted 9 lines · Tom Rini

On Thu, Jan 22, 2004 at 11:05:55AM -0700, Tom Rini wrote:
[snip]

Quoted 4 lines

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(-)
arch/ppc/kernel/ppc-stub.c +60 -3
@@ -3,6 +3,7 @@
  *
  * PowerPC-specific bits to work with the common KGDB stub.
  *
+ * 1998 (c) Michael AK Tesch ([email protected])
  * 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;
 }
 
Signature · 2 lines
Tom Rini
http://gate.crashing.org/~trini/
#21 lore raw
In reply to Tom Rini
Quoted 8 lines · Tom Rini
Quoted 7 lines · Tom Rini
Quoted 5 lines · Amit S. Kale

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

Quoted 7 lines
Quoted 4 lines
Quoted 2 lines

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:

arch/ppc/Kconfig +4 -5
@@ -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"
Signature · 2 lines
Tom Rini
http://gate.crashing.org/~trini/
#22 lore raw
In reply to Tom Rini
Quoted 28 lines · Tom Rini
Quoted 11 lines · Tom Rini
Quoted 6 lines · Amit S. Kale

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.

arch/ppc/Kconfig +0 -0
@@ -1405,6 +1405,14 @@
 	  Say Y here only if you plan to use some sort of debugger to

arch/ppc/Kconfig line 1415

Quoted 10 lines
arch/ppc/Kconfig +8 -0
 	  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

Signature · 3 lines
George Anzinger   [email protected]
High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml
#23 lore raw
Quoted 38 lines · George Anzinger
Quoted 37 lines · Tom Rini
Quoted 5 lines · Tom Rini
Quoted 2 lines · Amit S. Kale

Hi,

Quoted 7 lines
Quoted 5 lines

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.

arch/ppc/Kconfig +5 -0
@@ -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

Quoted 8 lines

arch/ppc/Kconfig line 1415

Quoted 4 lines
arch/ppc/Kconfig +2 -0
+	  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

arch/ppc/Kconfig +1 -0
+	  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.

Quoted 5 lines

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.

Signature · 2 lines
Tom Rini
http://gate.crashing.org/~trini/
#24 lore raw
Quoted 10 lines · Tom Rini
Quoted 5 lines · George Anzinger

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...

Signature · 2 lines
Hollis Blanchard
IBM Linux Technology Center
#25 lore raw
Quoted 16 lines · Hollis Blanchard
Quoted 13 lines · Tom Rini
Quoted 9 lines · George Anzinger

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?

Quoted 1 line

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

Quoted 7 lines

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.

Signature · 2 lines
Tom Rini
http://gate.crashing.org/~trini/
#26 lore raw
Quoted 20 lines · Tom Rini
Quoted 19 lines · Hollis Blanchard
Quoted 11 lines · Tom Rini
Quoted 9 lines · George Anzinger

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?

Quoted 1 line

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.

Quoted 7 lines
Quoted 2 lines

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)

Signature · 3 lines
Amit Kale
EmSysSoft (http://www.emsyssoft.com)
KGDB: Linux Kernel Source Level Debugger (http://kgdb.sourceforge.net)
#27 lore raw
Quoted 29 lines · Amit S. Kale
Quoted 20 lines · Tom Rini
Quoted 19 lines · Hollis Blanchard
Quoted 11 lines · Tom Rini
Quoted 9 lines · George Anzinger

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?

Quoted 1 line

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.

Quoted 7 lines
Quoted 2 lines

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.

Quoted 7 lines

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.

Quoted 6 lines

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?

Quoted 8 lines

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.

Signature · 2 lines
Tom Rini
http://gate.crashing.org/~trini/
#28 lore raw
Quoted 10 lines · Tom Rini

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.

Quoted 2 lines

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.

Quoted 5 lines

Which is basically how it goes now, right?

Quoted 1 line

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.

Signature · 3 lines
George Anzinger   [email protected]
High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml
#29 lore raw
Quoted 16 lines · George Anzinger
Quoted 14 lines · Tom Rini

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.

Quoted 7 lines

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).

Quoted 4 lines

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..)

Signature · 2 lines
Tom Rini
http://gate.crashing.org/~trini/
#30 lore raw
Quoted 14 lines · Tom Rini
Quoted 12 lines · George Anzinger
Quoted 9 lines · Tom Rini

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.

Quoted 2 lines

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).

Quoted 7 lines
Quoted 1 line

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.

Signature · 3 lines
George Anzinger   [email protected]
High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml
#31 lore raw
In reply to Amit S. Kale
Quoted 34 lines · Amit S. Kale
Quoted 23 lines · Tom Rini
Quoted 21 lines · Hollis Blanchard
Quoted 12 lines · Tom Rini
Quoted 9 lines · George Anzinger

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?

Quoted 1 line

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.

Quoted 7 lines
Quoted 2 lines

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.

Quoted 6 lines

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.

Quoted 4 lines

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.

Quoted 3 lines

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...

Signature · 3 lines
George Anzinger   [email protected]
High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml
#32 lore raw
In reply to Amit S. Kale
Quoted 24 lines · Amit S. Kale
Quoted 23 lines · Tom Rini
Quoted 21 lines · Hollis Blanchard
Quoted 11 lines · Tom Rini
Quoted 9 lines · George Anzinger

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?

Quoted 1 line

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...

Quoted 8 lines
Quoted 4 lines

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(-)
kgdbstub.c +1 -1
@@ -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;
serial/kgdb_8250.c +1 -3
@@ -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:
ppc/kernel/ppc-stub.c +1 -2
@@ -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.

Signature · 2 lines
Tom Rini
http://gate.crashing.org/~trini/
#33 lore raw
In reply to Tom Rini
Quoted 17 lines · Tom Rini
Quoted 15 lines · Hollis Blanchard
Quoted 10 lines · Tom Rini
Quoted 5 lines · George Anzinger

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.

Quoted 7 lines
Quoted 1 line

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.

Quoted 1 line
Signature · 3 lines
George Anzinger   [email protected]
High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml
#34 lore raw
In reply to Tom Rini
Quoted 8 lines · Tom Rini
Quoted 7 lines · Tom Rini
Quoted 5 lines · Amit S. Kale

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

Quoted 7 lines
Quoted 4 lines
Quoted 2 lines

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(-)
include/asm-i386/kgdb.h +4 -0
@@ -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
 
include/asm-ppc/kgdb.h +3 -0
@@ -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. */
include/asm-x86_64/kgdb.h +4 -0
@@ -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)
 
kernel/kgdbstub.c +34 -36

161 lines not on this page · raw message

Signature · 2 lines
Tom Rini
http://gate.crashing.org/~trini/
#35 lore raw
Quoted 13 lines · Tom Rini
Quoted 12 lines · Tom Rini
Quoted 10 lines · Tom Rini
Quoted 7 lines · Amit S. Kale

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.

Quoted 7 lines
Quoted 2 lines

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.

Quoted 2 lines

- 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.

Quoted 2 lines

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

That's also good.

Quoted 229 lines

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(-)

include/asm-i386/kgdb.h +4 -0
@@ -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
 
include/asm-ppc/kgdb.h +3 -0
@@ -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. */
include/asm-x86_64/kgdb.h +4 -0
@@ -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)
 
kernel/kgdbstub.c +34 -37
@@ -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/

Signature · 3 lines
Amit Kale
EmSysSoft (http://www.emsyssoft.com)
KGDB: Linux Kernel Source Level Debugger (http://kgdb.sourceforge.net)
#36 lore raw
In reply to Tom Rini
Quoted 38 lines · Tom Rini
Quoted 6 lines · Amit S. Kale

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 =====

kernel/kgdbstub.c +5 -3
@@ -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");
Quoted 4 lines

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).

Quoted 1 line
Signature · 3 lines
George Anzinger   [email protected]
High-res-timers:  http://sourceforge.net/projects/high-res-timers/
Preemption patch: http://www.kernel.org/pub/linux/kernel/people/rml
#37 lore raw
Quoted 49 lines · George Anzinger
Quoted 39 lines · Tom Rini
Quoted 7 lines · Amit S. Kale

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 =====

kernel/kgdbstub.c +5 -3
@@ -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");
Quoted 4 lines

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.

Quoted 3 lines

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.

Signature · 2 lines
Tom Rini
http://gate.crashing.org/~trini/
#38 lore raw
In reply to Tom Rini
Quoted 8 lines · Tom Rini
Quoted 4 lines · Amit S. Kale

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.

Done.

Quoted 7 lines
Quoted 2 lines

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.

Stock gdb places a breakpoint to detect loading of shared libraries. Since kernel doesn't have the symbols that ld-linux-* has, it places that at begining of the kernel (or elsewhere I haven't been able to figure out exactly where it places it). This breakpoint corrupts kernel data many a times.

The gdb I maintain at kgdb.sourceforge.net places a breakpoint correctly at module_event and detects loading of modules.

Quoted 9 lines
Quoted 6 lines

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

I thought you could place a breakpoint somewhere and the breakpoint was never hit.

ok. Now I know where it went wrong: nip is instruction pointer, not instruction contents. The change you had done compared nip to breakpoint instruction contents.

Quoted 3 lines

Review

Quoted 3 lines
(quoted diff) +3 -0
+       if (linux_regs->nip == 0x7d821008 )
+               /* Skip over breakpoint trap insn */
+               linux_regs->nip += 4;

Checking for kgdb_setting_breakpoint is better. Following code from my patch is correct.

Quoted 3 lines

Review

Quoted 3 lines
(quoted diff) +3 -0
+       extern atomic_t kgdb_setting_breakpoint;
+       if (atomic_read(&kgdb_setting_breakpoint))
+               regs->nip += 4;

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

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

#39 lore raw
Quoted 21 lines · Amit S. Kale
Quoted 8 lines · Tom Rini
Quoted 4 lines · Amit S. Kale

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.

Done.

Quoted 7 lines
Quoted 2 lines

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.

Quoted 8 lines

Stock gdb places a breakpoint to detect loading of shared libraries. Since kernel doesn't have the symbols that ld-linux-* has, it places that at begining of the kernel (or elsewhere I haven't been able to figure out exactly where it places it). This breakpoint corrupts kernel data many a times.

The gdb I maintain at kgdb.sourceforge.net places a breakpoint correctly at module_event and detects loading of modules.

Ah, ok.

Quoted 16 lines
Quoted 8 lines
Quoted 5 lines

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

I thought you could place a breakpoint somewhere and the breakpoint was never hit.

ok. Now I know where it went wrong: nip is instruction pointer, not instruction contents. The change you had done compared nip to breakpoint instruction contents.

Quoted 11 lines
Quoted 3 lines

Review

Quoted 3 lines
(quoted diff) +3 -0
+       if (linux_regs->nip == 0x7d821008 )
+               /* Skip over breakpoint trap insn */
+               linux_regs->nip += 4;

Checking for kgdb_setting_breakpoint is better. Following code from my patch is correct.

Quoted 3 lines
Quoted 3 lines
(quoted diff) +3 -0
+       extern atomic_t kgdb_setting_breakpoint;
+       if (atomic_read(&kgdb_setting_breakpoint))
+               regs->nip += 4;

I could have sworn I tried a number of combinations of things, including that. But I'm grabbing 2.1.0 now and will get back to you.

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

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

#40 lore raw

FYI: Free Online Book: Inside Linux Kernel and PowerPC

In reply to Amit S. Kale

Hi, team,

I tried to collect some documents related to linux and ppc. And did some document(I'm not yet confident enough to say: kernel analysis) about linux ppc machine dependent part.

It's far away being good. But wish helpful and
meantime get some feedback so that I could make a
better job.

The ToC is:
-------------
Chapter 1 Embedded PowerPC Family
Chapter 2: Programming Model
Chapter 3: PowerPC EABI
Chapter 4: PowerPC Interrupt/Exception
Chapter 5: PowerPC 4xx Reset and Initialization
Chapter 6: Synchronization Requirements
Chapter 7: Linux Kernel Bootup and Initialization
Chapter 8: Kernel Initialization
Chapter 9: Kernel Setup---start_kernel
Chapter 10: Kernel Exception Handler
Chapter 11 Kernel Memory Management
Chapter 12: Kernel Process Management
Chapter 13 Interrupt Handling routines
Chapter 14 System Call handling
Chapter 15: PowerPC EABI Cross Compiler

Regards,

Huailin, Chen
www.xtrj.org

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

#41 lore raw

Re: FYI: Free Online Book: Inside Linux Kernel and PowerPC

Quoted 19 lines · Huailin Chen

I tried to collect some documents related to linux and ppc. And did some document(I'm not yet confident enough to say: kernel analysis) about linux ppc machine dependent part.

It's far away being good. But wish helpful and
meantime get some feedback so that I could make a
better job.

The ToC is:
-------------
Chapter 1 Embedded PowerPC Family
Chapter 2: Programming Model
Chapter 3: PowerPC EABI
Chapter 4: PowerPC Interrupt/Exception
Chapter 5: PowerPC 4xx Reset and Initialization
Chapter 6: Synchronization Requirements
Chapter 7: Linux Kernel Bootup and Initialization

Quoted 8 lines

Chapter 8: Kernel Initialization
Chapter 9: Kernel Setup---start_kernel
Chapter 10: Kernel Exception Handler
Chapter 11 Kernel Memory Management
Chapter 12: Kernel Process Management
Chapter 13 Interrupt Handling routines
Chapter 14 System Call handling
Chapter 15: PowerPC EABI Cross Compiler

Are you saying you intend to write a book, and do we have comments on the proposed ToC? Or that you have begun writing a book, and the content is online somewhere and you'd like comments? Or that it's already written? If there's anything more than a ToC to look at, please provide a URL. :)

--
Hollis Blanchard
IBM Linux Technology Center

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

#42 lore raw

URL: FYI: Free Online Book: Inside Linux Kernel and PowerPC

In reply to Huailin Chen

Faint. I forgot give out the url. Thanks guys for
point me out:-).

----------------
www.xtrj.org/ppc
----------------

Quoted 31 lines · --- Huailin Chen

Hi, team,

I tried to collect some documents related to linux and
ppc. And did some document(I'm not yet confident enough to say: kernel analysis) about linux ppc machine dependent part.

It's far away being good. But wish helpful and
meantime get some feedback so that I could make a
better job.

The ToC is:
-------------
Chapter 1 Embedded PowerPC Family
Chapter 2: Programming Model
Chapter 3: PowerPC EABI
Chapter 4: PowerPC Interrupt/Exception
Chapter 5: PowerPC 4xx Reset and Initialization
Chapter 6: Synchronization Requirements
Chapter 7: Linux Kernel Bootup and Initialization
Chapter 8: Kernel Initialization
Chapter 9: Kernel Setup---start_kernel
Chapter 10: Kernel Exception Handler
Chapter 11 Kernel Memory Management
Chapter 12: Kernel Process Management
Chapter 13 Interrupt Handling routines
Chapter 14 System Call handling
Chapter 15: PowerPC EABI Cross Compiler

Quoted 6 lines

Regards,

Huailin, Chen
www.xtrj.org

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/