All of lore.kernel.org
 help / color / mirror / Atom feed
From: Pavel Machek <pavel@ucw.cz>
To: kernel list <linux-kernel@vger.kernel.org>,
	Andrew Morton <akpm@zip.com.au>
Subject: kgdb cleanups
Date: Fri, 9 Jan 2004 19:38:26 +0100	[thread overview]
Message-ID: <20040109183826.GA795@elf.ucw.cz> (raw)

Hi!

No real code changes, but cleanups all over the place. What about
applying?

Ouch and arch-dependend code is moved to kernel/kgdb.c. I'll probably
do x86-64 version so that is rather important.

								Pavel


--- tmp/linux/Documentation/i386/kgdb/kgdb.txt	2004-01-09 19:04:43.000000000 +0100
+++ linux/Documentation/i386/kgdb/kgdb.txt	2003-12-25 15:11:19.000000000 +0100
@@ -1,242 +1,9 @@
-Last edit: <20030806.1637.12>
-This file has information specific to the i386 kgdb option.  Other
-platforms with the kgdb option may behave in a similar fashion.
-
-New features:
-============
-20030806.1557.37
-This version was made against the 2.6.0-test2 kernel. We have made the
-following changes:
-
-- The getthread() code in the stub calls find_task_by_pid().  It fails
-  if we are early in the bring up such that the pid arrays have yet to
-  be allocated.  We have added a line to kernel/pid.c to make
-  "kgdb_pid_init_done" true once the arrays are allocated.  This way the
-  getthread() code knows not to call.  This is only used by the thread
-  debugging stuff and threads will not yet exist at this point in the
-  boot.
-
-- For some reason, gdb was not asking for a new thread list when the
-  "info thread" command was given.  We changed to the newer version of
-  the thread info command and gdb now seems to ask when needed.  Result,
-  we now get all threads in the thread list.
-
-- We now respond to the ThreadExtraInfo request from gdb with the thread
-  name from task_struct .comm.  This then appears in the thread list.
-  Thoughts on additional options for this are welcome.  Things such as
-  "has BKL" and "Preempted" come to mind.  I think we could have a flag
-  word that could enable different bits of info here.
-
-- We now honor, sort of, the C and S commands.  These are continue and
-  single set after delivering a signal.  We ignore the signal and do the
-  requested action.  This only happens when we told gdb that a signal
-  was the reason for entry, which is only done on memory faults.  The
-  result is that you can now continue into the Oops.
-
-- We changed the -g to -gdwarf-2.  This seems to be the same as -ggdb,
-  but it is more exact on what language to use.
-
-- We added two dwarf2 include files and a bit of code at the end of
-  entry.S.  This does not yet work, so it is disabled.  Still we want to
-  keep track of the code and "maybe" someone out there can fix it.
-
-- Randy Dunlap sent some fix ups for this file which are now merged.
-
-- Hugh Dickins sent a fix to a bit of code in traps.c that prevents a
-  compiler warning if CONFIG_KGDB is off (now who would do that :).
-
-- Andrew Morton sent a fix for the serial driver which is now merged.
-
-- Andrew also sent a change to the stub around the cpu managment code
-  which is also merged.
-
-- Andrew also sent a patch to make "f" as well as "g" work as SysRq
-  commands to enter kgdb, merged.
-
-- If CONFIG_KGDB and CONFIG_DEBUG_SPINLOCKS are both set we added a
-  "who" field to the spinlock data struct.  This is filled with
-  "current" when ever the spinlock suceeds.  Useful if you want to know
-  who has the lock.
-
-_ And last, but not least, we fixed the "get_cu" macro to properly get
-  the current value of "current".
-
-New features:
-============
-20030505.1827.27
-We are starting to align with the sourceforge version, at least in
-commands.  To this end, the boot command string to start kgdb at
-boot time has been changed from "kgdb" to "gdb".
-
-Andrew Morton sent a couple of patches which are now included as follows:
-1.) We now return a flag to the interrupt handler.
-2.) We no longer use smp_num_cpus (a conflict with the lock meter).
-3.) And from William Lee Irwin III <wli@holomorphy.com> code to make
-    sure high-mem is set up before we attempt to register our interrupt
-    handler.
-We now include asm/kgdb.h from config.h so you will most likely never
-have to include it.  It also 'NULLS' the kgdb macros you might have in
-your code when CONFIG_KGDB is not defined.  This allows you to just
-turn off CONFIG_KGDB to turn off all the kgdb_ts() calls and such.
-This include is conditioned on the machine being an x86 so as to not
-mess with other archs.
-
-20020801.1129.03
-This is currently the version for the 2.4.18 (and beyond?) kernel.
-
-We have several new "features" beginning with this version:
-
-1.) Kgdb now syncs the "other" CPUs with a cross-CPU NMI.  No more
-    waiting and it will pull that guy out of an IRQ off spin lock :)
-
-2.) We doctored up the code that tells where a task is waiting and
-    included it so that the "info thread" command will show a bit more
-    than "schedule()".  Try it...
-
-3.) Added the ability to call a function from gdb.  All the standard gdb
-    issues apply, i.e. if you hit a breakpoint in the function, you are
-    not allowed to call another (gdb limitation, not kgdb).  To help
-    this capability we added a memory allocation function.  Gdb does not
-    return this memory (it is used for strings that you pass to that function
-    you are calling from gdb) so we fixed up a way to allow you to
-    manually return the memory (see below).
-
-4.) Kgdb time stamps (kgdb_ts()) are enhanced to expand what was the
-    interrupt flag to now also include the preemption count and the
-    "in_interrupt" info.  The flag is now called "with_pif" to indicate
-    the order, preempt_count, in_interrupt, flag.  The preempt_count is
-    shifted left by 4 bits so you can read the count in hex by dropping
-    the low order digit.  In_interrupt is in bit 1, and the flag is in
-    bit 0.
-
-5.) The command: "p kgdb_info" is now expanded and prints something
-    like:
-(gdb) p kgdb_info
-$2 = {used_malloc = 0, called_from = 0xc0107506, entry_tsc = 67468627259,
-  errcode = 0, vector = 3, print_debug_info = 0, hold_on_sstep = 1,
-  cpus_waiting = {{task = 0xc027a000, pid = 32768, hold = 0,
-      regs = 0xc027bf84}, {task = 0x0, pid = 0, hold = 0, regs = 0x0}}}
-
-    Things to note here: a.) used_malloc is the amount of memory that
-    has been malloc'ed to do calls from gdb.  You can reclaim this
-    memory like this: "p kgdb_info.used_malloc=0" Cool, huh?  b.)
-    cpus_waiting is now "sized" by the number of CPUs you enter at
-    configure time in the kgdb configure section.  This is NOT used
-    anywhere else in the system, but it is "nice" here.  c.)  The task's
-    "pid" is now in the structure.  This is the pid you will need to use
-    to decode to the thread id to get gdb to look at that thread.
-    Remember that the "info thread" command prints a list of threads
-    wherein it numbers each thread with its reference number followed
-    by the thread's pid.  Note that the per-CPU idle threads actually
-    have pids of 0 (yes, there is more than one pid 0 in an SMP system).
-    To avoid confusion, kgdb numbers these threads with numbers beyond
-    the MAX_PID.  That is why you see 32768 and above.
-
-6.) A subtle change, we now provide the complete register set for tasks
-    that are active on the other CPUs.  This allows better trace back on
-    those tasks.
-
-    And, let's mention what we could not fix.  Back-trace from all but the
-    thread that we trapped will, most likely, have a bogus entry in it.
-    The problem is that gdb does not recognize the entry code for
-    functions that use "current" near (at all?) the entry.  The compiler
-    is putting the "current" decode as the first two instructions of the
-    function where gdb expects to find %ebp changing code.  Back trace
-    also has trouble with interrupt frames.  I am talking with Daniel
-    Jacobowitz about some way to fix this, but don't hold your breath.
-
-20011220.0050.35
-Major enhancement with this version is the ability to hold one or more
-CPUs in an SMP system while allowing the others to continue.  Also, by
-default only the current CPU is enabled on single-step commands (please
-note that gdb issues single-step commands at times other than when you
-use the si command).
-
-Another change is to collect some useful information in
-a global structure called "kgdb_info".  You should be able to just:
-
-p kgdb_info
-
-although I have seen cases where the first time this is done gdb just
-prints the first member but prints the whole structure if you then enter
-CR (carriage return or enter).  This also works:
-
-p *&kgdb_info
-
-Here is a sample:
-(gdb) p kgdb_info
-$4 = {called_from = 0xc010732c, entry_tsc = 32804123790856, errcode = 0,
-  vector = 3, print_debug_info = 0}
-
-"Called_from" is the return address from the current entry into kgdb.
-Sometimes it is useful to know why you are in kgdb, for example, was
-it an NMI or a real breakpoint?  The simple way to interrogate this
-return address is:
-
-l *0xc010732c
-
-which will print the surrounding few lines of source code.
-
-"Entry_tsc" is the CPU TSC on entry to kgdb (useful to compare to the
-kgdb_ts entries).
-
-"errcode" and "vector" are other entry parameters which may be helpful on
-some traps.
-
-"print_debug_info" is the internal debugging kgdb print enable flag.  Yes,
-you can modify it.
-
-In SMP systems kgdb_info also includes the "cpus_waiting" structure and
-"hold_on_step":
-
-(gdb) p kgdb_info
-$7 = {called_from = 0xc0112739, entry_tsc = 1034936624074, errcode = 0,
-  vector = 2, print_debug_info = 0, hold_on_sstep = 1, cpus_waiting = {{
-      task = 0x0, hold = 0, regs = 0x0}, {task = 0xc71b8000, hold = 0,
-      regs = 0xc71b9f70}, {task = 0x0, hold = 0, regs = 0x0}, {task = 0x0,
-      hold = 0, regs = 0x0}, {task = 0x0, hold = 0, regs = 0x0}, {task = 0x0,
-      hold = 0, regs = 0x0}, {task = 0x0, hold = 0, regs = 0x0}, {task = 0x0,
-      hold = 0, regs = 0x0}}}
-
-"Cpus_waiting" has an entry for each CPU other than the current one that
-has been stopped.  Each entry contains the task_struct address for that
-CPU, the address of the regs for that task and a hold flag.  All these
-have the proper typing so that, for example:
-
-p *kgdb_info.cpus_waiting[1].regs
-
-will print the registers for CPU 1.
-
-"Hold_on_sstep" is a new feature with this version and comes up set or
-true.  What this means is that whenever kgdb is asked to single-step all
-other CPUs are held (i.e. not allowed to execute).  The flag applies to
-all but the current CPU and, again, can be changed:
-
-p kgdb_info.hold_on_sstep=0
-
-restores the old behavior of letting all CPUs run during single-stepping.
-
-Likewise, each CPU has a "hold" flag, which if set, locks that CPU out
-of execution.  Note that this has some risk in cases where the CPUs need
-to communicate with each other.  If kgdb finds no CPU available on exit,
-it will push a message thru gdb and stay in kgdb.  Note that it is legal
-to hold the current CPU as long as at least one CPU can execute.
-
-20010621.1117.09
-This version implements an event queue.  Events are signaled by calling
-a function in the kgdb stub and may be examined from gdb.  See EVENTS
-below for details.  This version also tightens up the interrupt and SMP
-handling to not allow interrupts on the way to kgdb from a breakpoint
-trap.  It is fine to allow these interrupts for user code, but not
-system debugging.
-
 Version
 =======
 
-This version of the kgdb package was developed and tested on
-kernel version 2.4.16.  It will not install on any earlier kernels.
-It is possible that it will continue to work on later versions
-of 2.4 and then versions of 2.5 (I hope).
+This version of the kgdb package was developed and tested on kernel
+version 2.6.0.  It is possible that it will continue to work on later
+versions of 2.6.
 
 
 Debugging Setup
@@ -314,7 +81,7 @@
 set up after any serial drivers, it is possible that this command will
 work when the control-C will not.
 
-Save and exit the Xconfig program.  Then do "make clean" , "make dep"
+Save and exit the Xconfig program.  Then do "make clean"
 and "make bzImage" (or whatever target you want to make).  This gets the
 kernel compiled with the "-g" option set -- necessary for debugging.
 
diff -ur -x '.dep*' -x '.hdep*' -x '*.[oas]' -x '*~' -x '#*' -x '*CVS*' -x '*.orig' -x '*.rej' -x '*.old' -x '.menu*' -x asm -x local.h -x System.map -x autoconf.h -x compile.h -x version.h -x .version -x defkeymap.c -x uni_hash.tbl -x zImage -x vmlinux -x vmlinuz -x TAGS -x bootsect -x '*RCS*' -x conmakehash -x map -x build -x build -x configure -x '*target*' -x '*.flags' -x '*.bak' -x '*.cmd' tmp/linux/Documentation/i386/kgdb/kgdbeth.txt linux/Documentation/i386/kgdb/kgdbeth.txt
--- tmp/linux/Documentation/i386/kgdb/kgdbeth.txt	2004-01-09 19:04:43.000000000 +0100
+++ linux/Documentation/i386/kgdb/kgdbeth.txt	2003-12-25 14:55:58.000000000 +0100
@@ -33,8 +33,8 @@
 
   gdbeth=DEVICENUM
   gdbeth_remoteip=HOSTIPADDR
-  gdbeth_remotemac=REMOTEMAC
-  gdbeth_localmac=LOCALMAC
+  gdbeth_remotemac=HOSTMAC
+  gdbeth_localmac=TARGETMAC
 
 kgdbeth=DEVICENUM sets the ethernet device number to listen on for
 debugging packets.  e.g. kgdbeth=0 listens on eth0.
@@ -43,10 +43,10 @@
 Only packets originating from this IP address will be accepted by the
 debugger.  e.g. kgdbeth_remoteip=192.168.2.2
 
-kgdbeth_remotemac=REMOTEMAC sets the ethernet address of the HOST machine.
+kgdbeth_remotemac=HOSTMAC sets the ethernet address of the HOST machine.
 e.g. kgdbeth_remotemac=00:07:70:12:4E:F5
 
-kgdbeth_localmac=LOCALMAC sets the ethernet address of the TARGET machine.
+kgdbeth_localmac=TARGETMAC sets the ethernet address of the TARGET machine.
 e.g. kgdbeth_localmac=00:10:9F:18:21:3C
 
 You can also set the following command-line option on the TARGET kernel:
--- tmp/linux/arch/i386/kernel/entry.S	2004-01-09 19:04:43.000000000 +0100
+++ linux/arch/i386/kernel/entry.S	2003-12-27 17:08:29.000000000 +0100
@@ -71,51 +71,6 @@
 #	location or end up with a return address pointing at the
 #	location, we don't need a correct call frame for it.
 
-#if 0
-
-#include <linux/dwarf2-lang.h>
-/*
- * The register numbers as known by gdb
- */
-#define _EAX 0
-#define _ECX 1
-#define _EDX 2
-#define _EBX 3
-#define _ESP 4
-#define _EBP 5
-#define _ESI 6
-#define _EDI 7
-#define _PC  8
-#define _EIP 8
-#define _PS  9
-#define _EFLAGS  9
-#define _CS 10
-#define _SS 11
-#define _DS 12
-#define _ES 13
-#define _FS 14
-#define _GS 15
-
-	CFI_preamble(c1,_PC,1,1)
-	CFA_define_reference(_ESP,OLDESP)
-	CFA_define_offset(_EIP,EIP)
-	CFA_define_offset(_EBX,EBX)
-	CFA_define_offset(_ECX,ECX)
-	CFA_define_offset(_EDX,EDX)
-	CFA_define_offset(_ESI,ESI)
-	CFA_define_offset(_EDI,EDI)
-	CFA_define_offset(_EBP,EBP)
-	CFA_define_offset(_EAX,EAX)
-	CFA_define_offset(_EFLAGS,EFLAGS)
-	CFA_define_offset(_CS,CS)
-	CFA_define_offset(_DS,DS)
-	CFA_define_offset(_ES,ES)
-	CFI_postamble(c1)
-
-	FDE_preamble(c1,f1,ret_from_intr,(divide_error - ret_from_intr))
-	FDE_postamble(f1)
-#endif
-
 EBX		= 0x00
 ECX		= 0x04
 EDX		= 0x08
@@ -366,19 +321,6 @@
 	testw $_TIF_ALLWORK_MASK, %cx	# current->work
 	jne syscall_exit_work
 restore_all:
-#ifdef CONFIG_TRAP_BAD_SYSCALL_EXITS
-	movl EFLAGS(%esp), %eax		# mix EFLAGS and CS
-	movb CS(%esp), %al
-	testl $(VM_MASK | 3), %eax
-	jz resume_kernelX		# returning to kernel or vm86-space
-
-	cmpl $0,TI_PRE_COUNT(%ebx)	# non-zero preempt_count ?
-	jz resume_kernelX
-
-        int $3
-
-resume_kernelX:
-#endif
 	RESTORE_ALL
 
 	# perform work that needs to be done immediately before resumption
--- tmp/linux/arch/i386/kernel/kgdb_stub.c	2004-01-09 19:04:43.000000000 +0100
+++ linux/arch/i386/kernel/kgdb_stub.c	2003-12-28 21:40:20.000000000 +0100
@@ -1,4 +1,8 @@
 /*
+ * Kernel gdb stub, arch-dependend part
+ *
+ * Copyright (c) 2000 VERITAS Software Corporation.
+ * Copyright (c) 2003 Pavel Machek <pavel@suse.cz>
  *
  * 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
@@ -12,98 +16,7 @@
  *
  */
 
-/*
- * Copyright (c) 2000 VERITAS Software Corporation.
- *
- */
-/****************************************************************************
- *  Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
- *
- *  Module name: remcom.c $
- *  Revision: 1.34 $
- *  Date: 91/03/09 12:29:49 $
- *  Contributor:     Lake Stevens Instrument Division$
- *
- *  Description:     low level support for gdb debugger. $
- *
- *  Considerations:  only works on target hardware $
- *
- *  Written by:	     Glenn Engel $
- *  Updated by:	     David Grothe <dave@gcom.com>
- *  Updated by:	     Robert Walsh <rjwalsh@durables.org>
- *  Updated by:	     wangdi <wangdi@clusterfs.com>
- *  ModuleState:     Experimental $
- *
- *  NOTES:	     See Below $
- *
- *  Modified for 386 by Jim Kingdon, Cygnus Support.
- *  Compatibility with 2.1.xx kernel by David Grothe <dave@gcom.com>
- *
- *  Changes to allow auto initilization.  All that is needed is that it
- *  be linked with the kernel and a break point (int 3) be executed.
- *  The header file <asm/kgdb.h> defines BREAKPOINT to allow one to do
- *  this. It should also be possible, once the interrupt system is up, to
- *  call putDebugChar("+").  Once this is done, the remote debugger should
- *  get our attention by sending a ^C in a packet. George Anzinger
- *  <george@mvista.com>
- *  Integrated into 2.2.5 kernel by Tigran Aivazian <tigran@sco.com>
- *  Added thread support, support for multiple processors,
- *	support for ia-32(x86) hardware debugging.
- *	Amit S. Kale ( akale@veritas.com )
- *
- *  Modified to support debugging over ethernet by Robert Walsh
- *  <rjwalsh@durables.org> and wangdi <wangdi@clusterfs.com>, based on
- *  code by San Mehat.
- *
- *
- *  To enable debugger support, two things need to happen.  One, a
- *  call to set_debug_traps() is necessary in order to allow any breakpoints
- *  or error conditions to be properly intercepted and reported to gdb.
- *  Two, a breakpoint needs to be generated to begin communication.  This
- *  is most easily accomplished by a call to breakpoint().  Breakpoint()
- *  simulates a breakpoint by executing an int 3.
- *
- *************
- *
- *    The following gdb commands are supported:
- *
- * command	    function				   Return value
- *
- *    g		    return the value of the CPU registers  hex data or ENN
- *    G		    set the value of the CPU registers	   OK or ENN
- *
- *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA	   hex data or ENN
- *    MAA..AA,LLLL: Write LLLL bytes at address AA.AA	   OK or ENN
- *
- *    c		    Resume at current address		   SNN	 ( signal NN)
- *    cAA..AA	    Continue at address AA..AA		   SNN
- *
- *    s		    Step one instruction		   SNN
- *    sAA..AA	    Step one instruction from AA..AA	   SNN
- *
- *    k		    kill
- *
- *    ?		    What was the last sigval ?		   SNN	 (signal NN)
- *
- * All commands and responses are sent with a packet which includes a
- * checksum.  A packet consists of
- *
- * $<packet info>#<checksum>.
- *
- * where
- * <packet info> :: <characters representing the command or response>
- * <checksum>	 :: < two hex digits computed as modulo 256 sum of <packetinfo>>
- *
- * When a packet is received, it is first acknowledged with either '+' or '-'.
- * '+' indicates a successful transfer.	 '-' indicates a failed transfer.
- *
- * Example:
- *
- * Host:		  Reply:
- * $m0,10#2a		   +$00010203040506070809101112131415#42
- *
- ****************************************************************************/
-#define KGDB_VERSION "<20030915.1651.33>"
+#define KGDB_VERSION "2.6.0"
 #include <linux/config.h>
 #include <linux/types.h>
 #include <asm/string.h>		/* for strcpy */
@@ -121,41 +34,11 @@
 #include <linux/inet.h>
 #include <linux/kallsyms.h>
 
-/************************************************************************
- *
- * external low-level support routines
- */
-typedef void (*Function) (void);	/* pointer to a function */
-
-/* Thread reference */
-typedef unsigned char threadref[8];
-
-extern int tty_putDebugChar(int);     /* write a single character      */
-extern int tty_getDebugChar(void);    /* read and return a single char */
-extern void tty_flushDebugChar(void); /* flush pending characters      */
-extern int eth_putDebugChar(int);     /* write a single character      */
-extern int eth_getDebugChar(void);    /* read and return a single char */
-extern void eth_flushDebugChar(void); /* flush pending characters      */
-extern void kgdb_eth_set_trapmode(int);
-extern void kgdb_eth_reply_arp(void);   /*send arp request */
-extern volatile int kgdb_eth_is_initializing;
-
-
-/************************************************************************/
-/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
-/* at least NUMREGBYTES*2 are needed for register packets */
-/* Longer buffer is needed to list all threads */
-#define BUFMAX 400
-
-char *kgdb_version = KGDB_VERSION;
-
-/*  debug >  0 prints ill-formed commands in valid packets & checksum errors */
-int debug_regs = 0;		/* set to non-zero to print registers */
-
-/* filled in by an external module */
-char *gdb_module_offsets;
+#if __GNUC__ < 3
+#error Sorry, your GCC is too old to work with kgdb. (It works with 3.3.2)
+#endif
 
-static const char hexchars[] = "0123456789abcdef";
+#include "../../../kernel/kgdb.c"
 
 /* Number of bytes of registers.  */
 #define NUMREGBYTES 64
@@ -184,135 +67,11 @@
 	_GS			/* 15 */
 };
 
-/***************************  ASSEMBLY CODE MACROS *************************/
-/*
- * Put the error code here just in case the user cares.
- * Likewise, the vector number here (since GDB only gets the signal
- * number through the usual means, and that's not very specific).
- * The called_from is the return address so he can tell how we entered kgdb.
- * This will allow him to seperate out the various possible entries.
- */
-#define REMOTE_DEBUG 0		/* set != to turn on printing (also available in info) */
-
-#define PID_MAX PID_MAX_DEFAULT
-
-#ifdef CONFIG_SMP
-void smp_send_nmi_allbutself(void);
-#define IF_SMP(x) x
-#undef MAX_NO_CPUS
-#ifndef CONFIG_NO_KGDB_CPUS
-#define CONFIG_NO_KGDB_CPUS 2
-#endif
-#if CONFIG_NO_KGDB_CPUS > NR_CPUS
-#define MAX_NO_CPUS NR_CPUS
-#else
-#define MAX_NO_CPUS CONFIG_NO_KGDB_CPUS
-#endif
-#define hold_init hold_on_sstep: 1,
-#define MAX_CPU_MASK (unsigned long)((1LL << MAX_NO_CPUS) - 1LL)
-#define NUM_CPUS num_online_cpus()
-#else
-#define IF_SMP(x)
-#define hold_init
-#undef MAX_NO_CPUS
-#define MAX_NO_CPUS 1
-#define NUM_CPUS 1
-#endif
-#define NOCPU (struct task_struct *)0xbad1fbad
-/* *INDENT-OFF*	 */
-struct kgdb_info {
-	int used_malloc;
-	void *called_from;
-	long long entry_tsc;
-	int errcode;
-	int vector;
-	int print_debug_info;
-#ifdef CONFIG_SMP
-	int hold_on_sstep;
-	struct {
-		volatile struct task_struct *task;
-		int pid;
-		int hold;
-		struct pt_regs *regs;
-	} cpus_waiting[MAX_NO_CPUS];
-#endif
-} kgdb_info = {hold_init print_debug_info:REMOTE_DEBUG, vector:-1};
-
-/* *INDENT-ON*	*/
-
-#define used_m kgdb_info.used_malloc
-/*
- * This is little area we set aside to contain the stack we
- * need to build to allow gdb to call functions.  We use one
- * per cpu to avoid locking issues.  We will do all this work
- * with interrupts off so that should take care of the protection
- * issues.
- */
-#define LOOKASIDE_SIZE 200	/* should be more than enough */
-#define MALLOC_MAX   200	/* Max malloc size */
-struct {
-	unsigned int esp;
-	int array[LOOKASIDE_SIZE];
-} fn_call_lookaside[MAX_NO_CPUS];
-
-static int trap_cpu;
 static unsigned int OLD_esp;
 
-#define END_OF_LOOKASIDE  &fn_call_lookaside[trap_cpu].array[LOOKASIDE_SIZE]
 #define IF_BIT 0x200
 #define TF_BIT 0x100
 
-#define MALLOC_ROUND 8-1
-
-static char malloc_array[MALLOC_MAX];
-IF_SMP(static void to_gdb(const char *mess));
-void *
-malloc(int size)
-{
-
-	if (size <= (MALLOC_MAX - used_m)) {
-		int old_used = used_m;
-		used_m += ((size + MALLOC_ROUND) & (~MALLOC_ROUND));
-		return &malloc_array[old_used];
-	} else {
-		return NULL;
-	}
-}
-
-/*
- * I/O dispatch functions...
- * Based upon kgdb_eth, either call the ethernet
- * handler or the serial one..
- */
-void
-putDebugChar(int c)
-{
-	if (kgdb_eth == -1) {
-		tty_putDebugChar(c);
-	} else {
-		eth_putDebugChar(c);
-	}
-}
-
-int
-getDebugChar(void)
-{
-	if (kgdb_eth == -1) {
-		return tty_getDebugChar();
-	} else {
-		return eth_getDebugChar();
-	}
-}
-
-void
-flushDebugChar(void)
-{
-	if (kgdb_eth == -1) {
-		tty_flushDebugChar();
-	} else {
-		eth_flushDebugChar();
-	}
-}
 
 /*
  * Gdb calls functions by pushing agruments, including a return address
@@ -345,7 +104,7 @@
  */
 extern asmlinkage void fn_call_stub(void);
 extern asmlinkage void fn_rtn_stub(void);
-/*					   *INDENT-OFF*	 */
+
 __asm__("fn_rtn_stub:\n\t"
 	"movl %eax,%esp\n\t"
 	"fn_call_stub:\n\t"
@@ -359,213 +118,11 @@
 	"popl %ebx\n\t"
 	"popl %ecx\n\t"
 	"iret \n\t");
-/*					     *INDENT-ON*  */
+
 #define gdb_i386vector	kgdb_info.vector
 #define gdb_i386errcode kgdb_info.errcode
-#define waiting_cpus	kgdb_info.cpus_waiting
-#define remote_debug	kgdb_info.print_debug_info
-#define hold_cpu(cpu)	kgdb_info.cpus_waiting[cpu].hold
-/* gdb locks */
-
-#ifdef CONFIG_SMP
-static int in_kgdb_called;
-static spinlock_t waitlocks[MAX_NO_CPUS] =
-    {[0 ... MAX_NO_CPUS - 1] = SPIN_LOCK_UNLOCKED };
-/*
- * The following array has the thread pointer of each of the "other"
- * cpus.  We make it global so it can be seen by gdb.
- */
-volatile int in_kgdb_entry_log[MAX_NO_CPUS];
-volatile struct pt_regs *in_kgdb_here_log[MAX_NO_CPUS];
-/*
-static spinlock_t continuelocks[MAX_NO_CPUS];
-*/
-spinlock_t kgdb_spinlock = SPIN_LOCK_UNLOCKED;
-/* waiters on our spinlock plus us */
-static atomic_t spinlock_waiters = ATOMIC_INIT(1);
-static int spinlock_count = 0;
-static int spinlock_cpu = 0;
-/*
- * Note we use nested spin locks to account for the case where a break
- * point is encountered when calling a function by user direction from
- * kgdb. Also there is the memory exception recursion to account for.
- * Well, yes, but this lets other cpus thru too.  Lets add a
- * cpu id to the lock.
- */
-#define KGDB_SPIN_LOCK(x) if( spinlock_count == 0 || \
-			      spinlock_cpu != smp_processor_id()){\
-				      atomic_inc(&spinlock_waiters); \
-				      while (! spin_trylock(x)) {\
-					    in_kgdb(&regs);\
-				      }\
-				      atomic_dec(&spinlock_waiters); \
-				      spinlock_count = 1; \
-				      spinlock_cpu = smp_processor_id(); \
-			  }else{  \
-				      spinlock_count++; \
-			  }
-#define KGDB_SPIN_UNLOCK(x) if( --spinlock_count == 0) spin_unlock(x)
-#else
-unsigned kgdb_spinlock = 0;
-#define KGDB_SPIN_LOCK(x) --*x
-#define KGDB_SPIN_UNLOCK(x) ++*x
-#endif
-
-int
-hex(char ch)
-{
-	if ((ch >= 'a') && (ch <= 'f'))
-		return (ch - 'a' + 10);
-	if ((ch >= '0') && (ch <= '9'))
-		return (ch - '0');
-	if ((ch >= 'A') && (ch <= 'F'))
-		return (ch - 'A' + 10);
-	return (-1);
-}
 
-/* scan for the sequence $<data>#<checksum>	*/
-void
-getpacket(char *buffer)
-{
-	unsigned char checksum;
-	unsigned char xmitcsum;
-	int i;
-	int count;
-	char ch;
 
-	do {
-		/* wait around for the start character, ignore all other characters */
-		while ((ch = (getDebugChar() & 0x7f)) != '$') ;
-		checksum = 0;
-		xmitcsum = -1;
-
-		count = 0;
-
-		/* now, read until a # or end of buffer is found */
-		while (count < BUFMAX) {
-			ch = getDebugChar() & 0x7f;
-			if (ch == '#')
-				break;
-			checksum = checksum + ch;
-			buffer[count] = ch;
-			count = count + 1;
-		}
-		buffer[count] = 0;
-
-		if (ch == '#') {
-			xmitcsum = hex(getDebugChar() & 0x7f) << 4;
-			xmitcsum += hex(getDebugChar() & 0x7f);
-			if ((remote_debug) && (checksum != xmitcsum)) {
-				printk
-				    ("bad checksum.	My count = 0x%x, sent=0x%x. buf=%s\n",
-				     checksum, xmitcsum, buffer);
-			}
-
-			if (checksum != xmitcsum)
-				putDebugChar('-');	/* failed checksum */
-			else {
-				putDebugChar('+');	/* successful transfer */
-				/* if a sequence char is present, reply the sequence ID */
-				if (buffer[2] == ':') {
-					putDebugChar(buffer[0]);
-					putDebugChar(buffer[1]);
-					/* remove sequence chars from buffer */
-					count = strlen(buffer);
-					for (i = 3; i <= count; i++)
-						buffer[i - 3] = buffer[i];
-				}
-			}
-		}
-	} while (checksum != xmitcsum);
-
-	if (remote_debug)
-		printk("R:%s\n", buffer);
-	flushDebugChar();
-}
-
-/* send the packet in buffer.  */
-
-void
-putpacket(char *buffer)
-{
-	unsigned char checksum;
-	int count;
-	char ch;
-
-	/*  $<packet info>#<checksum>. */
-
-	if (kgdb_eth == -1) {
-		do {
-			if (remote_debug)
-				printk("T:%s\n", buffer);
-			putDebugChar('$');
-			checksum = 0;
-			count = 0;
-
-			while ((ch = buffer[count])) {
-				putDebugChar(ch);
-				checksum += ch;
-				count += 1;
-			}
-
-			putDebugChar('#');
-			putDebugChar(hexchars[checksum >> 4]);
-			putDebugChar(hexchars[checksum % 16]);
-			flushDebugChar();
-
-		} while ((getDebugChar() & 0x7f) != '+');
-	} else {
-		/*
-		 * For udp, we can not transfer too much bytes once.
-		 * We only transfer MAX_SEND_COUNT size bytes each time
-		 */
-
-#define MAX_SEND_COUNT 30
-
-		int send_count = 0, i = 0;
-		char send_buf[MAX_SEND_COUNT];
-
-		do {
-			if (remote_debug)
-				printk("T:%s\n", buffer);
-			putDebugChar('$');
-			checksum = 0;
-			count = 0;
-			send_count = 0;
-			while ((ch = buffer[count])) {
-				if (send_count >= MAX_SEND_COUNT) {
-					for(i = 0; i < MAX_SEND_COUNT; i++) {
-						putDebugChar(send_buf[i]);
-					}
-					flushDebugChar();
-					send_count = 0;
-				} else {
-					send_buf[send_count] = ch;
-					checksum += ch;
-					count ++;
-					send_count++;
-				}
-			}
-			for(i = 0; i < send_count; i++)
-				putDebugChar(send_buf[i]);
-			putDebugChar('#');
-			putDebugChar(hexchars[checksum >> 4]);
-			putDebugChar(hexchars[checksum % 16]);
-			flushDebugChar();
-		} while ((getDebugChar() & 0x7f) != '+');
-	}
-}
-
-static char remcomInBuffer[BUFMAX];
-static char remcomOutBuffer[BUFMAX];
-static short error;
-
-void
-debug_error(char *format, char *parm)
-{
-	if (remote_debug)
-		printk(format, parm);
-}
 
 static void
 print_regs(struct pt_regs *regs)
@@ -658,14 +215,10 @@
 #endif
 
 }				/* gdb_regs_to_regs */
-extern void scheduling_functions_start_here(void);
-extern void scheduling_functions_end_here(void);
-#define first_sched	((unsigned long) scheduling_functions_start_here)
-#define last_sched	((unsigned long) scheduling_functions_end_here)
 
 int thread_list = 0;
 
-void
+static void
 get_gdb_regs(struct task_struct *p, struct pt_regs *regs, int *gdb_regs)
 {
 	unsigned long stack_page;
@@ -727,20 +280,7 @@
 	return;
 }
 
-/* Indicate to caller of mem2hex or hex2mem that there has been an
-   error.  */
-static volatile int mem_err = 0;
-static volatile int mem_err_expected = 0;
-static volatile int mem_err_cnt = 0;
-static int garbage_loc = -1;
-
-int
-get_char(char *addr)
-{
-	return *addr;
-}
-
-void
+static void
 set_char(char *addr, int val, int may_fault)
 {
 	/*
@@ -756,260 +296,7 @@
 	*addr = val;
 }
 
-/* convert the memory pointed to by mem into hex, placing result in buf */
-/* return a pointer to the last char put in buf (null) */
-/* If MAY_FAULT is non-zero, then we should set mem_err in response to
-   a fault; if zero treat a fault like any other fault in the stub.  */
-char *
-mem2hex(char *mem, char *buf, int count, int may_fault)
-{
-	int i;
-	unsigned char ch;
-
-	if (may_fault) {
-		mem_err_expected = 1;
-		mem_err = 0;
-	}
-	for (i = 0; i < count; i++) {
-		/* printk("%lx = ", mem) ; */
-
-		ch = get_char(mem++);
-
-		/* printk("%02x\n", ch & 0xFF) ; */
-		if (may_fault && mem_err) {
-			if (remote_debug)
-				printk("Mem fault fetching from addr %lx\n",
-				       (long) (mem - 1));
-			*buf = 0;	/* truncate buffer */
-			return (buf);
-		}
-		*buf++ = hexchars[ch >> 4];
-		*buf++ = hexchars[ch % 16];
-	}
-	*buf = 0;
-	if (may_fault)
-		mem_err_expected = 0;
-	return (buf);
-}
-
-/* convert the hex array pointed to by buf into binary to be placed in mem */
-/* return a pointer to the character AFTER the last byte written */
-/* NOTE: We use the may fault flag to also indicate if the write is to
- * the registers (0) or "other" memory (!=0)
- */
-char *
-hex2mem(char *buf, char *mem, int count, int may_fault)
-{
-	int i;
-	unsigned char ch;
-
-	if (may_fault) {
-		mem_err_expected = 1;
-		mem_err = 0;
-	}
-	for (i = 0; i < count; i++) {
-		ch = hex(*buf++) << 4;
-		ch = ch + hex(*buf++);
-		set_char(mem++, ch, may_fault);
-
-		if (may_fault && mem_err) {
-			if (remote_debug)
-				printk("Mem fault storing to addr %lx\n",
-				       (long) (mem - 1));
-			return (mem);
-		}
-	}
-	if (may_fault)
-		mem_err_expected = 0;
-	return (mem);
-}
-
-/**********************************************/
-/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */
-/* RETURN NUMBER OF CHARS PROCESSED	      */
-/**********************************************/
-int
-hexToInt(char **ptr, int *intValue)
-{
-	int numChars = 0;
-	int hexValue;
 
-	*intValue = 0;
-
-	while (**ptr) {
-		hexValue = hex(**ptr);
-		if (hexValue >= 0) {
-			*intValue = (*intValue << 4) | hexValue;
-			numChars++;
-		} else
-			break;
-
-		(*ptr)++;
-	}
-
-	return (numChars);
-}
-
-#define stubhex(h) hex(h)
-#ifdef old_thread_list
-
-static int
-stub_unpack_int(char *buff, int fieldlength)
-{
-	int nibble;
-	int retval = 0;
-
-	while (fieldlength) {
-		nibble = stubhex(*buff++);
-		retval |= nibble;
-		fieldlength--;
-		if (fieldlength)
-			retval = retval << 4;
-	}
-	return retval;
-}
-#endif
-static char *
-pack_hex_byte(char *pkt, int byte)
-{
-	*pkt++ = hexchars[(byte >> 4) & 0xf];
-	*pkt++ = hexchars[(byte & 0xf)];
-	return pkt;
-}
-
-#define BUF_THREAD_ID_SIZE 16
-
-static char *
-pack_threadid(char *pkt, threadref * id)
-{
-	char *limit;
-	unsigned char *altid;
-
-	altid = (unsigned char *) id;
-	limit = pkt + BUF_THREAD_ID_SIZE;
-	while (pkt < limit)
-		pkt = pack_hex_byte(pkt, *altid++);
-	return pkt;
-}
-
-#ifdef old_thread_list
-static char *
-unpack_byte(char *buf, int *value)
-{
-	*value = stub_unpack_int(buf, 2);
-	return buf + 2;
-}
-
-static char *
-unpack_threadid(char *inbuf, threadref * id)
-{
-	char *altref;
-	char *limit = inbuf + BUF_THREAD_ID_SIZE;
-	int x, y;
-
-	altref = (char *) id;
-
-	while (inbuf < limit) {
-		x = stubhex(*inbuf++);
-		y = stubhex(*inbuf++);
-		*altref++ = (x << 4) | y;
-	}
-	return inbuf;
-}
-#endif
-void
-int_to_threadref(threadref * id, int value)
-{
-	unsigned char *scan;
-
-	scan = (unsigned char *) id;
-	{
-		int i = 4;
-		while (i--)
-			*scan++ = 0;
-	}
-	*scan++ = (value >> 24) & 0xff;
-	*scan++ = (value >> 16) & 0xff;
-	*scan++ = (value >> 8) & 0xff;
-	*scan++ = (value & 0xff);
-}
-int
-int_to_hex_v(unsigned char * id, int value)
-{
-	unsigned char *start = id;
-	int shift;
-	int ch;
-
-	for (shift = 28; shift >= 0; shift -= 4) {
-		if ((ch = (value >> shift) & 0xf) || (id != start)) {
-			*id = hexchars[ch];
-			id++;
-		}
-	}
-	if (id == start)
-		*id++ = '0';
-	return id - start;
-}
-#ifdef old_thread_list
-
-static int
-threadref_to_int(threadref * ref)
-{
-	int i, value = 0;
-	unsigned char *scan;
-
-	scan = (char *) ref;
-	scan += 4;
-	i = 4;
-	while (i-- > 0)
-		value = (value << 8) | ((*scan++) & 0xff);
-	return value;
-}
-#endif
-static int
-cmp_str(char *s1, char *s2, int count)
-{
-	while (count--) {
-		if (*s1++ != *s2++)
-			return 0;
-	}
-	return 1;
-}
-
-#if 1				/* this is a hold over from 2.4 where O(1) was "sometimes" */
-extern struct task_struct *kgdb_get_idle(int cpu);
-#define idle_task(cpu) kgdb_get_idle(cpu)
-#else
-#define idle_task(cpu) init_tasks[cpu]
-#endif
-
-extern int kgdb_pid_init_done;
-
-struct task_struct *
-getthread(int pid)
-{
-	struct task_struct *thread;
-	if (pid >= PID_MAX && pid <= (PID_MAX + MAX_NO_CPUS)) {
-
-		return idle_task(pid - PID_MAX);
-	} else {
-		/*
-		 * find_task_by_pid is relatively safe all the time
-		 * Other pid functions require lock downs which imply
-		 * that we may be interrupting them (as we get here
-		 * in the middle of most any lock down).
-		 * Still we don't want to call until the table exists!
-		 */
-		if (kgdb_pid_init_done){
-			thread = find_task_by_pid(pid);
-			if (thread) {
-				return thread;
-			}
-		}
-	}
-	return NULL;
-}
-/* *INDENT-OFF*	 */
 struct hw_breakpoint {
 	unsigned enabled;
 	unsigned type;
@@ -1019,7 +306,7 @@
 		   {enabled:0},
 		   {enabled:0},
 		   {enabled:0}};
-/* *INDENT-ON*	*/
+
 unsigned hw_breakpoint_status;
 void
 correct_hw_break(void)
@@ -1031,7 +318,7 @@
 
 	asm volatile ("movl %%db7, %0\n":"=r" (dr7)
 		      :);
-	/* *INDENT-OFF*	 */
+
 	do {
 		unsigned addr0, addr1, addr2, addr3;
 		asm volatile ("movl %%db0, %0\n"
@@ -1042,7 +329,7 @@
 			      "=r"(addr2), "=r"(addr3)
 			      :);
 	} while (0);
-	/* *INDENT-ON*	*/
+
 	correctit = 0;
 	for (breakno = 0; breakno < 3; breakno++) {
 		breakbit = 2 << (breakno << 1);
@@ -1095,7 +382,7 @@
 	return 0;
 }
 
-int
+static int
 set_hw_break(unsigned breakno, unsigned type, unsigned len, unsigned addr)
 {
 	if (breakinfo[breakno].enabled) {
@@ -1174,9 +461,6 @@
 	in_kgdb_here_log[cpu] = 0;
 	kgdb_local_irq_restore(flags);
 	return 1;
-	/*
-	   spin_unlock(continuelocks + smp_processor_id());
-	 */
 }
 
 void
@@ -1298,16 +582,6 @@
 	 * released.
 	 */
 #ifdef CONFIG_SMP
-
-#if 0
-	if (cpu_callout_map & ~MAX_CPU_MASK) {
-		printk("kgdb : too many cpus, possibly not mapped"
-		       " in contiguous space, change MAX_NO_CPUS"
-		       " in kgdb_stub and make new kernel.\n"
-		       " cpu_callout_map is %lx\n", cpu_callout_map);
-		goto exit_just_unlock;
-	}
-#endif
 	if (spinlock_count == 1) {
 		int time, end_time, dum;
 		int i;
@@ -1388,25 +662,7 @@
 			if (i < num_online_cpus()) {
 				printk
 				    ("kgdb : time out, proceeding without sync\n");
-#if 0
-				printk("kgdb : Waiting_cpus: 0 = %d, 1 = %d\n",
-				       waiting_cpus[0].task != 0,
-				       waiting_cpus[1].task != 0);
-				printk("kgdb : Cpu_logged in: 0 = %d, 1 = %d\n",
-				       cpu_logged_in[0], cpu_logged_in[1]);
-				printk
-				    ("kgdb : in_kgdb_here_log in: 0 = %d, 1 = %d\n",
-				     in_kgdb_here_log[0] != 0,
-				     in_kgdb_here_log[1] != 0);
-#endif
 				entry_state = NO_SYNC;
-			} else {
-#if 0
-				int ent =
-				    in_kgdb_entry_log[smp_processor_id()] -
-				    me_in_kgdb;
-				printk("kgdb : sync after %d entries\n", ent);
-#endif
 			}
 		} else {
 			if (remote_debug) {
@@ -1434,7 +690,7 @@
 
 	/* Disable hardware debugging while we are in kgdb */
 	/* Get the debug register status register */
-/*				       *INDENT-OFF*  */
+
       __asm__("movl %0,%%db7"
 	      :	/* no output */
 	      :"r"(0));
@@ -1443,7 +699,6 @@
 		      :"=r" (hw_breakpoint_status)
 		      :);
 
-/*				       *INDENT-ON*  */
 	switch (exceptionVector) {
 	case 0:		/* divide error */
 	case 1:		/* debug exception */
@@ -1533,7 +788,7 @@
 	}
 
 	kgdb_eth_reply_arp();
-	while (1 == 1) {
+	while (1) {
 		error = 0;
 		remcomOutBuffer[0] = 0;
 		getpacket(remcomInBuffer);
@@ -1989,11 +1244,8 @@
 
 		/* reply to the request */
 		putpacket(remcomOutBuffer);
-	}			/* while(1==1) */
-	/*
-	 *  reached by goto only.
-	 */
-      exit_kgdb:
+	} /* while(1) */
+exit_kgdb: /* reached by goto only. */
 	/*
 	 * Here is where we set up to trap a gdb function call.	 NEW_esp
 	 * will be changed if we are trying to do this.	 We handle both
@@ -2072,9 +1324,6 @@
 		kgdb_local_irq_restore(flags);
 		return (0);
 	}
-#if 0
-exit_just_unlock:
-#endif
 #endif
 	/* Release kgdb spinlock */
 	KGDB_SPIN_UNLOCK(&kgdb_spinlock);
@@ -2106,7 +1355,7 @@
 
 	/* In case GDB is started before us, ack any packets (presumably
 	   "$?#xx") sitting there.
-	   putDebugChar ('+');
+	   put_debug_char ('+');
 
 	   initialized = 1;
 	 */
@@ -2119,27 +1368,7 @@
 /* But really, just use the BREAKPOINT macro.  We will handle the int stuff
  */
 
-#ifdef later
-/*
- * possibly we should not go thru the traps.c code at all?  Someday.
- */
-void
-do_kgdb_int3(struct pt_regs *regs, long error_code)
-{
-	kgdb_handle_exception(3, 5, error_code, regs);
-	return;
-}
-#endif
 #undef regs
-#ifdef CONFIG_TRAP_BAD_SYSCALL_EXITS
-asmlinkage void
-bad_sys_call_exit(int stuff)
-{
-	struct pt_regs *regs = (struct pt_regs *) &stuff;
-	printk("Sys call %d return with %x preempt_count\n",
-	       (int) regs->orig_eax, preempt_count());
-}
-#endif
 #ifdef CONFIG_STACK_OVERFLOW_TEST
 #include <asm/kgdb.h>
 asmlinkage void
@@ -2150,8 +1379,7 @@
 #else
 	printk("Kernel stack overflow, looping forever\n");
 #endif
-	while (1) {
-	}
+	while (1) ;
 }
 #endif
 
@@ -2420,9 +1648,6 @@
 	kgdb_and_then = &kgdb_data[++kgdb_and_then_count & INDEX_MASK];
 	spin_unlock(&ts_spin);
 	kgdb_local_irq_restore(flags);
-#ifdef CONFIG_PREEMPT
-
-#endif
 	return;
 }
 #endif
@@ -2483,7 +1708,6 @@
 	return parse_hw_addr(str, kgdb_localmac);
 }
 
-
 __setup("gdbeth=", kgdb_opt_kgdbeth);
 __setup("gdbeth_remoteip=", kgdb_opt_kgdbeth_remoteip);
 __setup("gdbeth_listenport=", kgdb_opt_kgdbeth_listenport);
--- tmp/linux/drivers/net/kgdb_eth.c	2004-01-09 19:04:43.000000000 +0100
+++ linux/drivers/net/kgdb_eth.c	2003-12-28 21:00:24.000000000 +0100
@@ -39,12 +39,12 @@
 
 #define	GDB_BUF_SIZE	512		/* power of 2, please */
 
-static char	kgdb_buf[GDB_BUF_SIZE] ;
-static int	kgdb_buf_in_inx ;
-static atomic_t	kgdb_buf_in_cnt ;
-static int	kgdb_buf_out_inx ;
+static char	kgdb_buf[GDB_BUF_SIZE];
+static int	kgdb_buf_in_inx;
+static atomic_t	kgdb_buf_in_cnt;
+static int	kgdb_buf_out_inx;
 
-extern void	set_debug_traps(void) ;		/* GDB routine */
+extern void	set_debug_traps(void);		/* GDB routine */
 extern void	breakpoint(void);
 
 unsigned int	kgdb_remoteip = 0;
@@ -479,8 +479,7 @@
 put_char_on_queue(int chr)
 {
 	eth_queue[outgoing_queue++] = chr;
-	if(outgoing_queue == ETH_QUEUE_SIZE)
-	{
+	if(outgoing_queue == ETH_QUEUE_SIZE) {
 		eth_flushDebugChar();
 	}
 }
--- tmp/linux/include/asm-i386/kgdb_local.h	2004-01-09 19:04:44.000000000 +0100
+++ linux/include/asm-i386/kgdb_local.h	2003-12-28 21:21:55.000000000 +0100
@@ -83,7 +83,7 @@
       tty:   (struct tty_struct *)&state, \
       IER:   SB_IER,       \
       MCR:   SB_MCR}
-extern void putDebugChar(int);
+extern void put_debug_char(int);
 /* RTAI support needs us to really stop/start interrupts */
 
 #define kgdb_sti() __asm__ __volatile__("sti": : :"memory")
@@ -98,5 +98,5 @@
 #ifdef CONFIG_SERIAL
 extern void shutdown_for_kgdb(struct async_struct *info);
 #endif
-#define INIT_KDEBUG putDebugChar("+");
+#define INIT_KDEBUG put_debug_char("+");	/* WTF is this? it expects integer! */
 #endif				/* __KGDB_LOCAL */
--- tmp/linux/include/linux/dwarf2-lang.h	2004-01-09 19:04:44.000000000 +0100
+++ linux/include/linux/dwarf2-lang.h	2003-12-27 17:12:38.000000000 +0100
@@ -1,132 +0,0 @@
-#ifndef DWARF2_LANG
-#define DWARF2_LANG
-#include <linux/dwarf2.h>
-
-/*
- * This is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2, or (at your option) any later
- * version.
- */
-/*
- * This file defines macros that allow generation of DWARF debug records
- * for asm files.  This file is platform independent.  Register numbers
- * (which are about the only thing that is platform dependent) are to be
- * supplied by a platform defined file.
- */
-#define DWARF_preamble()	.section	.debug_frame,"",@progbits
-/*
- * This macro starts a debug frame section.  The debug_frame describes
- * where to find the registers that the enclosing function saved on
- * entry.
- *
- * ORD is use by the label generator and should be the same as what is
- * passed to CFI_postamble.
- *
- * pc,	pc register gdb ordinal.
- *
- * code_align this is the factor used to define locations or regions
- * where the given definitions apply.  If you use labels to define these
- * this should be 1.
- *
- * data_align this is the factor used to define register offsets.  If
- * you use struct offset, this should be the size of the register in
- * bytes or the negative of that.  This is how it is used: you will
- * define a register as the reference register, say the stack pointer,
- * then you will say where a register is located relative to this
- * reference registers value, say 40 for register 3 (the gdb register
- * number).  The <40> will be multiplied by <data_align> to define the
- * byte offset of the given register (3, in this example).  So if your
- * <40> is the byte offset and the reference register points at the
- * begining, you would want 1 for the data_offset.  If <40> was the 40th
- * 4-byte element in that structure you would want 4.  And if your
- * reference register points at the end of the structure you would want
- * a negative data_align value(and you would have to do other math as
- * well).
- */
-
-#define CFI_preamble(ORD, pc, code_align, data_align)	\
-.section	.debug_frame,"",@progbits ;		\
-frame/**/_/**/ORD:						\
-	.long end/**/_/**/ORD-start/**/_/**/ORD;			\
-start/**/_/**/ORD:						\
-	.long	DW_CIE_ID;				\
-	.byte	DW_CIE_VERSION;			\
-	.byte 0	 ;				\
-	.uleb128 code_align;				\
-	.sleb128 data_align;				\
-	.byte pc;
-
-/*
- * After the above macro and prior to the CFI_postamble, you need to
- * define the initial state.  This starts with defining the reference
- * register and, usually the pc.  Here are some helper macros:
- */
-
-#define CFA_define_reference(reg, offset)	\
-	.byte DW_CFA_def_cfa;			\
-	.uleb128 reg;				\
-	.uleb128 (offset);
-
-#define CFA_define_offset(reg, offset)		\
-	.byte (DW_CFA_offset + reg);		\
-	.uleb128 (offset);
-
-#define CFI_postamble(ORD)			\
-	.align 4;				\
-end/**/_/**/ORD:
-/*
- * So now your code pushs stuff on the stack, you need a new location
- * and the rules for what to do.  This starts a running description of
- * the call frame.  You need to describe what changes with respect to
- * the call registers as the location of the pc moves through the code.
- * The following builds an FDE (fram descriptor entry?).  Like the
- * above, it has a preamble and a postamble.  It also is tied to the CFI
- * above.
- * The first entry after the preamble must be the location in the code
- * that the call frame is being described for.
- */
-#define FDE_preamble(ORD, fde_no, initial_address, length)	\
-	.long FDE_end/**/_/**/fde_no-FDE_start/**/_/**/fde_no;		\
-FDE_start/**/_/**/fde_no:						\
-	.long frame/**/_/**/ORD;					\
-	.long initial_address;					\
-	.long length;
-
-#define FDE_postamble(fde_no)			\
-	.align 4;				\
-FDE_end/**/_/**/fde_no:
-/*
- * That done, you can now add registers, subtract registers, move the
- * reference and even change the reference.  You can also define a new
- * area of code the info applies to.  For discontinuous bits you should
- * start a new FDE.  You may have as many as you like.
- */
-
-/*
- * To advance the address by <bytes>
- */
-
-#define FDE_advance(bytes)			\
-	.byte DW_CFA_advance_loc4		\
-	.long bytes
-
-
-
-/*
- * With the above you can define all the register locations.  But
- * suppose the reference register moves... Takes the new offset NOT an
- * increment.  This is how esp is tracked if it is not saved.
- */
-
-#define CFA_define_cfa_offset(offset) \
-	.byte $DW_CFA_def_cfa_offset; \
-	.uleb128 (offset);
-/*
- * Or suppose you want to use a different reference register...
- */
-#define CFA_define_cfa_register(reg)		\
-	.byte DW_CFA_def_cfa_register;		\
-	.uleb128 reg;
-
-#endif
--- tmp/linux/include/linux/dwarf2.h	2004-01-09 19:04:44.000000000 +0100
+++ linux/include/linux/dwarf2.h	2003-12-27 17:12:40.000000000 +0100
@@ -1,738 +0,0 @@
-/* Declarations and definitions of codes relating to the DWARF2 symbolic
-   debugging information format.
-   Copyright (C) 1992, 1993, 1995, 1996, 1997, 1999, 2000, 2001, 2002
-   Free Software Foundation, Inc.
-
-   Written by Gary Funck (gary@intrepid.com) The Ada Joint Program
-   Office (AJPO), Florida State Unviversity and Silicon Graphics Inc.
-   provided support for this effort -- June 21, 1995.
-
-   Derived from the DWARF 1 implementation written by Ron Guilmette
-   (rfg@netcom.com), November 1990.
-
-   This file is part of GCC.
-
-   GCC is free software; you can redistribute it and/or modify it under
-   the terms of the GNU General Public License as published by the Free
-   Software Foundation; either version 2, or (at your option) any later
-   version.
-
-   GCC is distributed in the hope that it will be useful, but WITHOUT
-   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
-   License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with GCC; see the file COPYING.  If not, write to the Free
-   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA.  */
-
-/* This file is derived from the DWARF specification (a public document)
-   Revision 2.0.0 (July 27, 1993) developed by the UNIX International
-   Programming Languages Special Interest Group (UI/PLSIG) and distributed
-   by UNIX International.  Copies of this specification are available from
-   UNIX International, 20 Waterview Boulevard, Parsippany, NJ, 07054.
-
-   This file also now contains definitions from the DWARF 3 specification.  */
-
-/* This file is shared between GCC and GDB, and should not contain
-   prototypes.	*/
-
-#ifndef _ELF_DWARF2_H
-#define _ELF_DWARF2_H
-
-/* Structure found in the .debug_line section.	*/
-#ifndef __ASSEMBLY__
-typedef struct
-{
-  unsigned char li_length	   [4];
-  unsigned char li_version	   [2];
-  unsigned char li_prologue_length [4];
-  unsigned char li_min_insn_length [1];
-  unsigned char li_default_is_stmt [1];
-  unsigned char li_line_base	   [1];
-  unsigned char li_line_range	   [1];
-  unsigned char li_opcode_base	   [1];
-}
-DWARF2_External_LineInfo;
-
-typedef struct
-{
-  unsigned long  li_length;
-  unsigned short li_version;
-  unsigned int	 li_prologue_length;
-  unsigned char  li_min_insn_length;
-  unsigned char  li_default_is_stmt;
-  int		 li_line_base;
-  unsigned char  li_line_range;
-  unsigned char  li_opcode_base;
-}
-DWARF2_Internal_LineInfo;
-
-/* Structure found in .debug_pubnames section.	*/
-typedef struct
-{
-  unsigned char pn_length  [4];
-  unsigned char pn_version [2];
-  unsigned char pn_offset  [4];
-  unsigned char pn_size    [4];
-}
-DWARF2_External_PubNames;
-
-typedef struct
-{
-  unsigned long  pn_length;
-  unsigned short pn_version;
-  unsigned long  pn_offset;
-  unsigned long  pn_size;
-}
-DWARF2_Internal_PubNames;
-
-/* Structure found in .debug_info section.  */
-typedef struct
-{
-  unsigned char  cu_length	  [4];
-  unsigned char  cu_version	  [2];
-  unsigned char  cu_abbrev_offset [4];
-  unsigned char  cu_pointer_size  [1];
-}
-DWARF2_External_CompUnit;
-
-typedef struct
-{
-  unsigned long  cu_length;
-  unsigned short cu_version;
-  unsigned long  cu_abbrev_offset;
-  unsigned char  cu_pointer_size;
-}
-DWARF2_Internal_CompUnit;
-
-typedef struct
-{
-  unsigned char  ar_length	 [4];
-  unsigned char  ar_version	 [2];
-  unsigned char  ar_info_offset  [4];
-  unsigned char  ar_pointer_size [1];
-  unsigned char  ar_segment_size [1];
-}
-DWARF2_External_ARange;
-
-typedef struct
-{
-  unsigned long  ar_length;
-  unsigned short ar_version;
-  unsigned long  ar_info_offset;
-  unsigned char  ar_pointer_size;
-  unsigned char  ar_segment_size;
-}
-DWARF2_Internal_ARange;
-
-#define ENUM(name) enum name {
-#define IF_NOT_ASM(a) a
-#define COMMA ,
-#else
-#define ENUM(name)
-#define IF_NOT_ASM(a)
-#define COMMA
-
-#endif
-
-/* Tag names and codes.  */
-ENUM(dwarf_tag)
-
-    DW_TAG_padding = 0x00 COMMA
-    DW_TAG_array_type = 0x01 COMMA
-    DW_TAG_class_type = 0x02 COMMA
-    DW_TAG_entry_point = 0x03 COMMA
-    DW_TAG_enumeration_type = 0x04 COMMA
-    DW_TAG_formal_parameter = 0x05 COMMA
-    DW_TAG_imported_declaration = 0x08 COMMA
-    DW_TAG_label = 0x0a COMMA
-    DW_TAG_lexical_block = 0x0b COMMA
-    DW_TAG_member = 0x0d COMMA
-    DW_TAG_pointer_type = 0x0f COMMA
-    DW_TAG_reference_type = 0x10 COMMA
-    DW_TAG_compile_unit = 0x11 COMMA
-    DW_TAG_string_type = 0x12 COMMA
-    DW_TAG_structure_type = 0x13 COMMA
-    DW_TAG_subroutine_type = 0x15 COMMA
-    DW_TAG_typedef = 0x16 COMMA
-    DW_TAG_union_type = 0x17 COMMA
-    DW_TAG_unspecified_parameters = 0x18 COMMA
-    DW_TAG_variant = 0x19 COMMA
-    DW_TAG_common_block = 0x1a COMMA
-    DW_TAG_common_inclusion = 0x1b COMMA
-    DW_TAG_inheritance = 0x1c COMMA
-    DW_TAG_inlined_subroutine = 0x1d COMMA
-    DW_TAG_module = 0x1e COMMA
-    DW_TAG_ptr_to_member_type = 0x1f COMMA
-    DW_TAG_set_type = 0x20 COMMA
-    DW_TAG_subrange_type = 0x21 COMMA
-    DW_TAG_with_stmt = 0x22 COMMA
-    DW_TAG_access_declaration = 0x23 COMMA
-    DW_TAG_base_type = 0x24 COMMA
-    DW_TAG_catch_block = 0x25 COMMA
-    DW_TAG_const_type = 0x26 COMMA
-    DW_TAG_constant = 0x27 COMMA
-    DW_TAG_enumerator = 0x28 COMMA
-    DW_TAG_file_type = 0x29 COMMA
-    DW_TAG_friend = 0x2a COMMA
-    DW_TAG_namelist = 0x2b COMMA
-    DW_TAG_namelist_item = 0x2c COMMA
-    DW_TAG_packed_type = 0x2d COMMA
-    DW_TAG_subprogram = 0x2e COMMA
-    DW_TAG_template_type_param = 0x2f COMMA
-    DW_TAG_template_value_param = 0x30 COMMA
-    DW_TAG_thrown_type = 0x31 COMMA
-    DW_TAG_try_block = 0x32 COMMA
-    DW_TAG_variant_part = 0x33 COMMA
-    DW_TAG_variable = 0x34 COMMA
-    DW_TAG_volatile_type = 0x35 COMMA
-    /* DWARF 3.  */
-    DW_TAG_dwarf_procedure = 0x36 COMMA
-    DW_TAG_restrict_type = 0x37 COMMA
-    DW_TAG_interface_type = 0x38 COMMA
-    DW_TAG_namespace = 0x39 COMMA
-    DW_TAG_imported_module = 0x3a COMMA
-    DW_TAG_unspecified_type = 0x3b COMMA
-    DW_TAG_partial_unit = 0x3c COMMA
-    DW_TAG_imported_unit = 0x3d COMMA
-    /* SGI/MIPS Extensions.  */
-    DW_TAG_MIPS_loop = 0x4081 COMMA
-    /* GNU extensions.	*/
-    DW_TAG_format_label = 0x4101 COMMA	/* For FORTRAN 77 and Fortran 90.  */
-    DW_TAG_function_template = 0x4102 COMMA	/* For C++.  */
-    DW_TAG_class_template = 0x4103 COMMA	/* For C++.  */
-    DW_TAG_GNU_BINCL = 0x4104 COMMA
-    DW_TAG_GNU_EINCL = 0x4105 COMMA
-    /* Extensions for UPC.  See: http://upc.gwu.edu/~upc.  */
-    DW_TAG_upc_shared_type = 0x8765 COMMA
-    DW_TAG_upc_strict_type = 0x8766 COMMA
-    DW_TAG_upc_relaxed_type = 0x8767
-IF_NOT_ASM(};)
-
-#define DW_TAG_lo_user	0x4080
-#define DW_TAG_hi_user	0xffff
-
-/* Flag that tells whether entry has a child or not.  */
-#define DW_children_no	 0
-#define	DW_children_yes  1
-
-/* Form names and codes.  */
-ENUM(dwarf_form)
-
-    DW_FORM_addr = 0x01 COMMA
-    DW_FORM_block2 = 0x03 COMMA
-    DW_FORM_block4 = 0x04 COMMA
-    DW_FORM_data2 = 0x05 COMMA
-    DW_FORM_data4 = 0x06 COMMA
-    DW_FORM_data8 = 0x07 COMMA
-    DW_FORM_string = 0x08 COMMA
-    DW_FORM_block = 0x09 COMMA
-    DW_FORM_block1 = 0x0a COMMA
-    DW_FORM_data1 = 0x0b COMMA
-    DW_FORM_flag = 0x0c COMMA
-    DW_FORM_sdata = 0x0d COMMA
-    DW_FORM_strp = 0x0e COMMA
-    DW_FORM_udata = 0x0f COMMA
-    DW_FORM_ref_addr = 0x10 COMMA
-    DW_FORM_ref1 = 0x11 COMMA
-    DW_FORM_ref2 = 0x12 COMMA
-    DW_FORM_ref4 = 0x13 COMMA
-    DW_FORM_ref8 = 0x14 COMMA
-    DW_FORM_ref_udata = 0x15 COMMA
-    DW_FORM_indirect = 0x16
-IF_NOT_ASM(};)
-
-/* Attribute names and codes.  */
-
-ENUM(dwarf_attribute)
-
-    DW_AT_sibling = 0x01 COMMA
-    DW_AT_location = 0x02 COMMA
-    DW_AT_name = 0x03 COMMA
-    DW_AT_ordering = 0x09 COMMA
-    DW_AT_subscr_data = 0x0a COMMA
-    DW_AT_byte_size = 0x0b COMMA
-    DW_AT_bit_offset = 0x0c COMMA
-    DW_AT_bit_size = 0x0d COMMA
-    DW_AT_element_list = 0x0f COMMA
-    DW_AT_stmt_list = 0x10 COMMA
-    DW_AT_low_pc = 0x11 COMMA
-    DW_AT_high_pc = 0x12 COMMA
-    DW_AT_language = 0x13 COMMA
-    DW_AT_member = 0x14 COMMA
-    DW_AT_discr = 0x15 COMMA
-    DW_AT_discr_value = 0x16 COMMA
-    DW_AT_visibility = 0x17 COMMA
-    DW_AT_import = 0x18 COMMA
-    DW_AT_string_length = 0x19 COMMA
-    DW_AT_common_reference = 0x1a COMMA
-    DW_AT_comp_dir = 0x1b COMMA
-    DW_AT_const_value = 0x1c COMMA
-    DW_AT_containing_type = 0x1d COMMA
-    DW_AT_default_value = 0x1e COMMA
-    DW_AT_inline = 0x20 COMMA
-    DW_AT_is_optional = 0x21 COMMA
-    DW_AT_lower_bound = 0x22 COMMA
-    DW_AT_producer = 0x25 COMMA
-    DW_AT_prototyped = 0x27 COMMA
-    DW_AT_return_addr = 0x2a COMMA
-    DW_AT_start_scope = 0x2c COMMA
-    DW_AT_stride_size = 0x2e COMMA
-    DW_AT_upper_bound = 0x2f COMMA
-    DW_AT_abstract_origin = 0x31 COMMA
-    DW_AT_accessibility = 0x32 COMMA
-    DW_AT_address_class = 0x33 COMMA
-    DW_AT_artificial = 0x34 COMMA
-    DW_AT_base_types = 0x35 COMMA
-    DW_AT_calling_convention = 0x36 COMMA
-    DW_AT_count = 0x37 COMMA
-    DW_AT_data_member_location = 0x38 COMMA
-    DW_AT_decl_column = 0x39 COMMA
-    DW_AT_decl_file = 0x3a COMMA
-    DW_AT_decl_line = 0x3b COMMA
-    DW_AT_declaration = 0x3c COMMA
-    DW_AT_discr_list = 0x3d COMMA
-    DW_AT_encoding = 0x3e COMMA
-    DW_AT_external = 0x3f COMMA
-    DW_AT_frame_base = 0x40 COMMA
-    DW_AT_friend = 0x41 COMMA
-    DW_AT_identifier_case = 0x42 COMMA
-    DW_AT_macro_info = 0x43 COMMA
-    DW_AT_namelist_items = 0x44 COMMA
-    DW_AT_priority = 0x45 COMMA
-    DW_AT_segment = 0x46 COMMA
-    DW_AT_specification = 0x47 COMMA
-    DW_AT_static_link = 0x48 COMMA
-    DW_AT_type = 0x49 COMMA
-    DW_AT_use_location = 0x4a COMMA
-    DW_AT_variable_parameter = 0x4b COMMA
-    DW_AT_virtuality = 0x4c COMMA
-    DW_AT_vtable_elem_location = 0x4d COMMA
-    /* DWARF 3 values.	*/
-    DW_AT_allocated	= 0x4e COMMA
-    DW_AT_associated	= 0x4f COMMA
-    DW_AT_data_location = 0x50 COMMA
-    DW_AT_stride	= 0x51 COMMA
-    DW_AT_entry_pc	= 0x52 COMMA
-    DW_AT_use_UTF8	= 0x53 COMMA
-    DW_AT_extension	= 0x54 COMMA
-    DW_AT_ranges	= 0x55 COMMA
-    DW_AT_trampoline	= 0x56 COMMA
-    DW_AT_call_column	= 0x57 COMMA
-    DW_AT_call_file	= 0x58 COMMA
-    DW_AT_call_line	= 0x59 COMMA
-    /* SGI/MIPS extensions.  */
-    DW_AT_MIPS_fde = 0x2001 COMMA
-    DW_AT_MIPS_loop_begin = 0x2002 COMMA
-    DW_AT_MIPS_tail_loop_begin = 0x2003 COMMA
-    DW_AT_MIPS_epilog_begin = 0x2004 COMMA
-    DW_AT_MIPS_loop_unroll_factor = 0x2005 COMMA
-    DW_AT_MIPS_software_pipeline_depth = 0x2006 COMMA
-    DW_AT_MIPS_linkage_name = 0x2007 COMMA
-    DW_AT_MIPS_stride = 0x2008 COMMA
-    DW_AT_MIPS_abstract_name = 0x2009 COMMA
-    DW_AT_MIPS_clone_origin = 0x200a COMMA
-    DW_AT_MIPS_has_inlines = 0x200b COMMA
-    /* GNU extensions.	*/
-    DW_AT_sf_names   = 0x2101 COMMA
-    DW_AT_src_info   = 0x2102 COMMA
-    DW_AT_mac_info   = 0x2103 COMMA
-    DW_AT_src_coords = 0x2104 COMMA
-    DW_AT_body_begin = 0x2105 COMMA
-    DW_AT_body_end   = 0x2106 COMMA
-    DW_AT_GNU_vector = 0x2107 COMMA
-    /* VMS extensions.	*/
-    DW_AT_VMS_rtnbeg_pd_address = 0x2201 COMMA
-    /* UPC extension.  */
-    DW_AT_upc_threads_scaled = 0x3210
-IF_NOT_ASM(};)
-
-#define DW_AT_lo_user	0x2000	/* Implementation-defined range start.	*/
-#define DW_AT_hi_user	0x3ff0	/* Implementation-defined range end.  */
-
-/* Location atom names and codes.  */
-ENUM(dwarf_location_atom)
-
-    DW_OP_addr = 0x03 COMMA
-    DW_OP_deref = 0x06 COMMA
-    DW_OP_const1u = 0x08 COMMA
-    DW_OP_const1s = 0x09 COMMA
-    DW_OP_const2u = 0x0a COMMA
-    DW_OP_const2s = 0x0b COMMA
-    DW_OP_const4u = 0x0c COMMA
-    DW_OP_const4s = 0x0d COMMA
-    DW_OP_const8u = 0x0e COMMA
-    DW_OP_const8s = 0x0f COMMA
-    DW_OP_constu = 0x10 COMMA
-    DW_OP_consts = 0x11 COMMA
-    DW_OP_dup = 0x12 COMMA
-    DW_OP_drop = 0x13 COMMA
-    DW_OP_over = 0x14 COMMA
-    DW_OP_pick = 0x15 COMMA
-    DW_OP_swap = 0x16 COMMA
-    DW_OP_rot = 0x17 COMMA
-    DW_OP_xderef = 0x18 COMMA
-    DW_OP_abs = 0x19 COMMA
-    DW_OP_and = 0x1a COMMA
-    DW_OP_div = 0x1b COMMA
-    DW_OP_minus = 0x1c COMMA
-    DW_OP_mod = 0x1d COMMA
-    DW_OP_mul = 0x1e COMMA
-    DW_OP_neg = 0x1f COMMA
-    DW_OP_not = 0x20 COMMA
-    DW_OP_or = 0x21 COMMA
-    DW_OP_plus = 0x22 COMMA
-    DW_OP_plus_uconst = 0x23 COMMA
-    DW_OP_shl = 0x24 COMMA
-    DW_OP_shr = 0x25 COMMA
-    DW_OP_shra = 0x26 COMMA
-    DW_OP_xor = 0x27 COMMA
-    DW_OP_bra = 0x28 COMMA
-    DW_OP_eq = 0x29 COMMA
-    DW_OP_ge = 0x2a COMMA
-    DW_OP_gt = 0x2b COMMA
-    DW_OP_le = 0x2c COMMA
-    DW_OP_lt = 0x2d COMMA
-    DW_OP_ne = 0x2e COMMA
-    DW_OP_skip = 0x2f COMMA
-    DW_OP_lit0 = 0x30 COMMA
-    DW_OP_lit1 = 0x31 COMMA
-    DW_OP_lit2 = 0x32 COMMA
-    DW_OP_lit3 = 0x33 COMMA
-    DW_OP_lit4 = 0x34 COMMA
-    DW_OP_lit5 = 0x35 COMMA
-    DW_OP_lit6 = 0x36 COMMA
-    DW_OP_lit7 = 0x37 COMMA
-    DW_OP_lit8 = 0x38 COMMA
-    DW_OP_lit9 = 0x39 COMMA
-    DW_OP_lit10 = 0x3a COMMA
-    DW_OP_lit11 = 0x3b COMMA
-    DW_OP_lit12 = 0x3c COMMA
-    DW_OP_lit13 = 0x3d COMMA
-    DW_OP_lit14 = 0x3e COMMA
-    DW_OP_lit15 = 0x3f COMMA
-    DW_OP_lit16 = 0x40 COMMA
-    DW_OP_lit17 = 0x41 COMMA
-    DW_OP_lit18 = 0x42 COMMA
-    DW_OP_lit19 = 0x43 COMMA
-    DW_OP_lit20 = 0x44 COMMA
-    DW_OP_lit21 = 0x45 COMMA
-    DW_OP_lit22 = 0x46 COMMA
-    DW_OP_lit23 = 0x47 COMMA
-    DW_OP_lit24 = 0x48 COMMA
-    DW_OP_lit25 = 0x49 COMMA
-    DW_OP_lit26 = 0x4a COMMA
-    DW_OP_lit27 = 0x4b COMMA
-    DW_OP_lit28 = 0x4c COMMA
-    DW_OP_lit29 = 0x4d COMMA
-    DW_OP_lit30 = 0x4e COMMA
-    DW_OP_lit31 = 0x4f COMMA
-    DW_OP_reg0 = 0x50 COMMA
-    DW_OP_reg1 = 0x51 COMMA
-    DW_OP_reg2 = 0x52 COMMA
-    DW_OP_reg3 = 0x53 COMMA
-    DW_OP_reg4 = 0x54 COMMA
-    DW_OP_reg5 = 0x55 COMMA
-    DW_OP_reg6 = 0x56 COMMA
-    DW_OP_reg7 = 0x57 COMMA
-    DW_OP_reg8 = 0x58 COMMA
-    DW_OP_reg9 = 0x59 COMMA
-    DW_OP_reg10 = 0x5a COMMA
-    DW_OP_reg11 = 0x5b COMMA
-    DW_OP_reg12 = 0x5c COMMA
-    DW_OP_reg13 = 0x5d COMMA
-    DW_OP_reg14 = 0x5e COMMA
-    DW_OP_reg15 = 0x5f COMMA
-    DW_OP_reg16 = 0x60 COMMA
-    DW_OP_reg17 = 0x61 COMMA
-    DW_OP_reg18 = 0x62 COMMA
-    DW_OP_reg19 = 0x63 COMMA
-    DW_OP_reg20 = 0x64 COMMA
-    DW_OP_reg21 = 0x65 COMMA
-    DW_OP_reg22 = 0x66 COMMA
-    DW_OP_reg23 = 0x67 COMMA
-    DW_OP_reg24 = 0x68 COMMA
-    DW_OP_reg25 = 0x69 COMMA
-    DW_OP_reg26 = 0x6a COMMA
-    DW_OP_reg27 = 0x6b COMMA
-    DW_OP_reg28 = 0x6c COMMA
-    DW_OP_reg29 = 0x6d COMMA
-    DW_OP_reg30 = 0x6e COMMA
-    DW_OP_reg31 = 0x6f COMMA
-    DW_OP_breg0 = 0x70 COMMA
-    DW_OP_breg1 = 0x71 COMMA
-    DW_OP_breg2 = 0x72 COMMA
-    DW_OP_breg3 = 0x73 COMMA
-    DW_OP_breg4 = 0x74 COMMA
-    DW_OP_breg5 = 0x75 COMMA
-    DW_OP_breg6 = 0x76 COMMA
-    DW_OP_breg7 = 0x77 COMMA
-    DW_OP_breg8 = 0x78 COMMA
-    DW_OP_breg9 = 0x79 COMMA
-    DW_OP_breg10 = 0x7a COMMA
-    DW_OP_breg11 = 0x7b COMMA
-    DW_OP_breg12 = 0x7c COMMA
-    DW_OP_breg13 = 0x7d COMMA
-    DW_OP_breg14 = 0x7e COMMA
-    DW_OP_breg15 = 0x7f COMMA
-    DW_OP_breg16 = 0x80 COMMA
-    DW_OP_breg17 = 0x81 COMMA
-    DW_OP_breg18 = 0x82 COMMA
-    DW_OP_breg19 = 0x83 COMMA
-    DW_OP_breg20 = 0x84 COMMA
-    DW_OP_breg21 = 0x85 COMMA
-    DW_OP_breg22 = 0x86 COMMA
-    DW_OP_breg23 = 0x87 COMMA
-    DW_OP_breg24 = 0x88 COMMA
-    DW_OP_breg25 = 0x89 COMMA
-    DW_OP_breg26 = 0x8a COMMA
-    DW_OP_breg27 = 0x8b COMMA
-    DW_OP_breg28 = 0x8c COMMA
-    DW_OP_breg29 = 0x8d COMMA
-    DW_OP_breg30 = 0x8e COMMA
-    DW_OP_breg31 = 0x8f COMMA
-    DW_OP_regx = 0x90 COMMA
-    DW_OP_fbreg = 0x91 COMMA
-    DW_OP_bregx = 0x92 COMMA
-    DW_OP_piece = 0x93 COMMA
-    DW_OP_deref_size = 0x94 COMMA
-    DW_OP_xderef_size = 0x95 COMMA
-    DW_OP_nop = 0x96 COMMA
-    /* DWARF 3 extensions.  */
-    DW_OP_push_object_address = 0x97 COMMA
-    DW_OP_call2 = 0x98 COMMA
-    DW_OP_call4 = 0x99 COMMA
-    DW_OP_call_ref = 0x9a COMMA
-    /* GNU extensions.	*/
-    DW_OP_GNU_push_tls_address = 0xe0
-IF_NOT_ASM(};)
-
-#define DW_OP_lo_user	0xe0	/* Implementation-defined range start.	*/
-#define DW_OP_hi_user	0xff	/* Implementation-defined range end.  */
-
-/* Type encodings.  */
-ENUM(dwarf_type)
-
-    DW_ATE_void = 0x0 COMMA
-    DW_ATE_address = 0x1 COMMA
-    DW_ATE_boolean = 0x2 COMMA
-    DW_ATE_complex_float = 0x3 COMMA
-    DW_ATE_float = 0x4 COMMA
-    DW_ATE_signed = 0x5 COMMA
-    DW_ATE_signed_char = 0x6 COMMA
-    DW_ATE_unsigned = 0x7 COMMA
-    DW_ATE_unsigned_char = 0x8 COMMA
-    /* DWARF 3.  */
-    DW_ATE_imaginary_float = 0x9
-IF_NOT_ASM(};)
-
-#define	DW_ATE_lo_user 0x80
-#define	DW_ATE_hi_user 0xff
-
-/* Array ordering names and codes.  */
-ENUM(dwarf_array_dim_ordering)
-
-    DW_ORD_row_major = 0 COMMA
-    DW_ORD_col_major = 1
-IF_NOT_ASM(};)
-
-/* Access attribute.  */
-ENUM(dwarf_access_attribute)
-
-    DW_ACCESS_public = 1 COMMA
-    DW_ACCESS_protected = 2 COMMA
-    DW_ACCESS_private = 3
-IF_NOT_ASM(};)
-
-/* Visibility.	*/
-ENUM(dwarf_visibility_attribute)
-
-    DW_VIS_local = 1 COMMA
-    DW_VIS_exported = 2 COMMA
-    DW_VIS_qualified = 3
-IF_NOT_ASM(};)
-
-/* Virtuality.	*/
-ENUM(dwarf_virtuality_attribute)
-
-    DW_VIRTUALITY_none = 0 COMMA
-    DW_VIRTUALITY_virtual = 1 COMMA
-    DW_VIRTUALITY_pure_virtual = 2
-IF_NOT_ASM(};)
-
-/* Case sensitivity.  */
-ENUM(dwarf_id_case)
-
-    DW_ID_case_sensitive = 0 COMMA
-    DW_ID_up_case = 1 COMMA
-    DW_ID_down_case = 2 COMMA
-    DW_ID_case_insensitive = 3
-IF_NOT_ASM(};)
-
-/* Calling convention.	*/
-ENUM(dwarf_calling_convention)
-
-    DW_CC_normal = 0x1 COMMA
-    DW_CC_program = 0x2 COMMA
-    DW_CC_nocall = 0x3
-IF_NOT_ASM(};)
-
-#define DW_CC_lo_user 0x40
-#define DW_CC_hi_user 0xff
-
-/* Inline attribute.  */
-ENUM(dwarf_inline_attribute)
-
-    DW_INL_not_inlined = 0 COMMA
-    DW_INL_inlined = 1 COMMA
-    DW_INL_declared_not_inlined = 2 COMMA
-    DW_INL_declared_inlined = 3
-IF_NOT_ASM(};)
-
-/* Discriminant lists.	*/
-ENUM(dwarf_discrim_list)
-
-    DW_DSC_label = 0 COMMA
-    DW_DSC_range = 1
-IF_NOT_ASM(};)
-
-/* Line number opcodes.  */
-ENUM(dwarf_line_number_ops)
-
-    DW_LNS_extended_op = 0 COMMA
-    DW_LNS_copy = 1 COMMA
-    DW_LNS_advance_pc = 2 COMMA
-    DW_LNS_advance_line = 3 COMMA
-    DW_LNS_set_file = 4 COMMA
-    DW_LNS_set_column = 5 COMMA
-    DW_LNS_negate_stmt = 6 COMMA
-    DW_LNS_set_basic_block = 7 COMMA
-    DW_LNS_const_add_pc = 8 COMMA
-    DW_LNS_fixed_advance_pc = 9 COMMA
-    /* DWARF 3.  */
-    DW_LNS_set_prologue_end = 10 COMMA
-    DW_LNS_set_epilogue_begin = 11 COMMA
-    DW_LNS_set_isa = 12
-IF_NOT_ASM(};)
-
-/* Line number extended opcodes.  */
-ENUM(dwarf_line_number_x_ops)
-
-    DW_LNE_end_sequence = 1 COMMA
-    DW_LNE_set_address = 2 COMMA
-    DW_LNE_define_file = 3
-IF_NOT_ASM(};)
-
-/* Call frame information.  */
-ENUM(dwarf_call_frame_info)
-
-    DW_CFA_advance_loc = 0x40 COMMA
-    DW_CFA_offset = 0x80 COMMA
-    DW_CFA_restore = 0xc0 COMMA
-    DW_CFA_nop = 0x00 COMMA
-    DW_CFA_set_loc = 0x01 COMMA
-    DW_CFA_advance_loc1 = 0x02 COMMA
-    DW_CFA_advance_loc2 = 0x03 COMMA
-    DW_CFA_advance_loc4 = 0x04 COMMA
-    DW_CFA_offset_extended = 0x05 COMMA
-    DW_CFA_restore_extended = 0x06 COMMA
-    DW_CFA_undefined = 0x07 COMMA
-    DW_CFA_same_value = 0x08 COMMA
-    DW_CFA_register = 0x09 COMMA
-    DW_CFA_remember_state = 0x0a COMMA
-    DW_CFA_restore_state = 0x0b COMMA
-    DW_CFA_def_cfa = 0x0c COMMA
-    DW_CFA_def_cfa_register = 0x0d COMMA
-    DW_CFA_def_cfa_offset = 0x0e COMMA
-
-    /* DWARF 3.  */
-    DW_CFA_def_cfa_expression = 0x0f COMMA
-    DW_CFA_expression = 0x10 COMMA
-    DW_CFA_offset_extended_sf = 0x11 COMMA
-    DW_CFA_def_cfa_sf = 0x12 COMMA
-    DW_CFA_def_cfa_offset_sf = 0x13 COMMA
-
-    /* SGI/MIPS specific.  */
-    DW_CFA_MIPS_advance_loc8 = 0x1d COMMA
-
-    /* GNU extensions.	*/
-    DW_CFA_GNU_window_save = 0x2d COMMA
-    DW_CFA_GNU_args_size = 0x2e COMMA
-    DW_CFA_GNU_negative_offset_extended = 0x2f
-IF_NOT_ASM(};)
-
-#define DW_CIE_ID	  0xffffffff
-#define DW_CIE_VERSION	  1
-
-#define DW_CFA_extended   0
-#define DW_CFA_lo_user	  0x1c
-#define DW_CFA_hi_user	  0x3f
-
-#define DW_CHILDREN_no		     0x00
-#define DW_CHILDREN_yes		     0x01
-
-#define DW_ADDR_none		0
-
-/* Source language names and codes.  */
-ENUM(dwarf_source_language)
-
-    DW_LANG_C89 = 0x0001 COMMA
-    DW_LANG_C = 0x0002 COMMA
-    DW_LANG_Ada83 = 0x0003 COMMA
-    DW_LANG_C_plus_plus = 0x0004 COMMA
-    DW_LANG_Cobol74 = 0x0005 COMMA
-    DW_LANG_Cobol85 = 0x0006 COMMA
-    DW_LANG_Fortran77 = 0x0007 COMMA
-    DW_LANG_Fortran90 = 0x0008 COMMA
-    DW_LANG_Pascal83 = 0x0009 COMMA
-    DW_LANG_Modula2 = 0x000a COMMA
-    DW_LANG_Java = 0x000b COMMA
-    /* DWARF 3.  */
-    DW_LANG_C99 = 0x000c COMMA
-    DW_LANG_Ada95 = 0x000d COMMA
-    DW_LANG_Fortran95 = 0x000e COMMA
-    /* MIPS.  */
-    DW_LANG_Mips_Assembler = 0x8001 COMMA
-    /* UPC.  */
-    DW_LANG_Upc = 0x8765
-IF_NOT_ASM(};)
-
-#define DW_LANG_lo_user 0x8000	/* Implementation-defined range start.	*/
-#define DW_LANG_hi_user 0xffff	/* Implementation-defined range start.	*/
-
-/* Names and codes for macro information.  */
-ENUM(dwarf_macinfo_record_type)
-
-    DW_MACINFO_define = 1 COMMA
-    DW_MACINFO_undef = 2 COMMA
-    DW_MACINFO_start_file = 3 COMMA
-    DW_MACINFO_end_file = 4 COMMA
-    DW_MACINFO_vendor_ext = 255
-IF_NOT_ASM(};)
-\f
-/* @@@ For use with GNU frame unwind information.  */
-
-#define DW_EH_PE_absptr		0x00
-#define DW_EH_PE_omit		0xff
-
-#define DW_EH_PE_uleb128	0x01
-#define DW_EH_PE_udata2		0x02
-#define DW_EH_PE_udata4		0x03
-#define DW_EH_PE_udata8		0x04
-#define DW_EH_PE_sleb128	0x09
-#define DW_EH_PE_sdata2		0x0A
-#define DW_EH_PE_sdata4		0x0B
-#define DW_EH_PE_sdata8		0x0C
-#define DW_EH_PE_signed		0x08
-
-#define DW_EH_PE_pcrel		0x10
-#define DW_EH_PE_textrel	0x20
-#define DW_EH_PE_datarel	0x30
-#define DW_EH_PE_funcrel	0x40
-#define DW_EH_PE_aligned	0x50
-
-#define DW_EH_PE_indirect	0x80
-
-#endif /* _ELF_DWARF2_H */
--- tmp/linux/kernel/kgdb.c	2003-12-28 21:06:03.000000000 +0100
+++ linux/kernel/kgdb.c	2003-12-28 21:40:19.000000000 +0100
@@ -0,0 +1,750 @@
+/*
+ * Kernel gdb stub, arch-independend part
+ *
+ * Copyright (c) 2000 VERITAS Software Corporation.
+ * Copyright (c) 2003 Pavel Machek <pavel@suse.cz>
+ *
+ * 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.
+ *
+ */
+/****************************************************************************
+ *  Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $
+ *
+ *  Module name: remcom.c $
+ *  Revision: 1.34 $
+ *  Date: 91/03/09 12:29:49 $
+ *  Contributor:     Lake Stevens Instrument Division$
+ *
+ *  Description:     low level support for gdb debugger. $
+ *
+ *  Considerations:  only works on target hardware $
+ *
+ *  Written by:	     Glenn Engel $
+ *  Updated by:	     David Grothe <dave@gcom.com>
+ *  Updated by:	     Robert Walsh <rjwalsh@durables.org>
+ *  Updated by:	     wangdi <wangdi@clusterfs.com>
+ *  ModuleState:     Experimental $
+ *
+ *  NOTES:	     See Below $
+ *
+ *  Modified for 386 by Jim Kingdon, Cygnus Support.
+ *  Compatibility with 2.1.xx kernel by David Grothe <dave@gcom.com>
+ *
+ *  Changes to allow auto initilization.  All that is needed is that it
+ *  be linked with the kernel and a break point (int 3) be executed.
+ *  The header file <asm/kgdb.h> defines BREAKPOINT to allow one to do
+ *  this. It should also be possible, once the interrupt system is up, to
+ *  call putDebugChar("+").  Once this is done, the remote debugger should
+ *  get our attention by sending a ^C in a packet. George Anzinger
+ *  <george@mvista.com>
+ *  Integrated into 2.2.5 kernel by Tigran Aivazian <tigran@sco.com>
+ *  Added thread support, support for multiple processors,
+ *	support for ia-32(x86) hardware debugging.
+ *	Amit S. Kale ( akale@veritas.com )
+ *
+ *  Modified to support debugging over ethernet by Robert Walsh
+ *  <rjwalsh@durables.org> and wangdi <wangdi@clusterfs.com>, based on
+ *  code by San Mehat.
+ *
+ *
+ *  To enable debugger support, two things need to happen.  One, a
+ *  call to set_debug_traps() is necessary in order to allow any breakpoints
+ *  or error conditions to be properly intercepted and reported to gdb.
+ *  Two, a breakpoint needs to be generated to begin communication.  This
+ *  is most easily accomplished by a call to breakpoint().  Breakpoint()
+ *  simulates a breakpoint by executing an int 3.
+ *
+ *************
+ *
+ *    The following gdb commands are supported:
+ *
+ * command	    function				   Return value
+ *
+ *    g		    return the value of the CPU registers  hex data or ENN
+ *    G		    set the value of the CPU registers	   OK or ENN
+ *
+ *    mAA..AA,LLLL  Read LLLL bytes at address AA..AA	   hex data or ENN
+ *    MAA..AA,LLLL: Write LLLL bytes at address AA.AA	   OK or ENN
+ *
+ *    c		    Resume at current address		   SNN	 ( signal NN)
+ *    cAA..AA	    Continue at address AA..AA		   SNN
+ *
+ *    s		    Step one instruction		   SNN
+ *    sAA..AA	    Step one instruction from AA..AA	   SNN
+ *
+ *    k		    kill
+ *
+ *    ?		    What was the last sigval ?		   SNN	 (signal NN)
+ *
+ * All commands and responses are sent with a packet which includes a
+ * checksum.  A packet consists of
+ *
+ * $<packet info>#<checksum>.
+ *
+ * where
+ * <packet info> :: <characters representing the command or response>
+ * <checksum>	 :: < two hex digits computed as modulo 256 sum of <packetinfo>>
+ *
+ * When a packet is received, it is first acknowledged with either '+' or '-'.
+ * '+' indicates a successful transfer.	 '-' indicates a failed transfer.
+ *
+ * Example:
+ *
+ * Host:		  Reply:
+ * $m0,10#2a		   +$00010203040506070809101112131415#42
+ *
+ ****************************************************************************/
+
+/*
+ * external low-level support routines
+ */
+typedef void (*Function) (void);	/* pointer to a function */
+
+/* Thread reference */
+typedef unsigned char threadref[8];
+
+extern int tty_putDebugChar(int);     /* write a single character      */
+extern int tty_getDebugChar(void);    /* read and return a single char */
+extern void tty_flushDebugChar(void); /* flush pending characters      */
+extern int eth_putDebugChar(int);     /* write a single character      */
+extern int eth_getDebugChar(void);    /* read and return a single char */
+extern void eth_flushDebugChar(void); /* flush pending characters      */
+extern void kgdb_eth_set_trapmode(int);
+extern void kgdb_eth_reply_arp(void);   /* send arp request */
+extern volatile int kgdb_eth_is_initializing;
+
+
+/************************************************************************/
+/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/
+/* at least NUMREGBYTES*2 are needed for register packets */
+/* Longer buffer is needed to list all threads */
+#define BUFMAX 400
+
+char *kgdb_version = KGDB_VERSION;
+
+/*  debug >  0 prints ill-formed commands in valid packets & checksum errors */
+int debug_regs = 0;		/* set to non-zero to print registers */
+
+/* filled in by an external module */
+char *gdb_module_offsets;
+
+static const char hexchars[] = "0123456789abcdef";
+
+
+/***************************  ASSEMBLY CODE MACROS *************************/
+/*
+ * Put the error code here just in case the user cares.
+ * Likewise, the vector number here (since GDB only gets the signal
+ * number through the usual means, and that's not very specific).
+ * The called_from is the return address so he can tell how we entered kgdb.
+ * This will allow him to seperate out the various possible entries.
+ */
+#define REMOTE_DEBUG 0		/* set != to turn on printing (also available in info) */
+
+#define PID_MAX PID_MAX_DEFAULT
+
+#ifdef CONFIG_SMP
+void smp_send_nmi_allbutself(void);
+#define IF_SMP(x) x
+#undef MAX_NO_CPUS
+#ifndef CONFIG_NO_KGDB_CPUS
+#define CONFIG_NO_KGDB_CPUS 2
+#endif
+#if CONFIG_NO_KGDB_CPUS > NR_CPUS
+#define MAX_NO_CPUS NR_CPUS
+#else
+#define MAX_NO_CPUS CONFIG_NO_KGDB_CPUS
+#endif
+#define hold_init hold_on_sstep: 1,
+#define MAX_CPU_MASK (unsigned long)((1LL << MAX_NO_CPUS) - 1LL)
+#define NUM_CPUS num_online_cpus()
+#else
+#define IF_SMP(x)
+#define hold_init
+#undef MAX_NO_CPUS
+#define MAX_NO_CPUS 1
+#define NUM_CPUS 1
+#endif
+#define NOCPU (struct task_struct *)0xbad1fbad
+
+struct kgdb_info {
+	int used_malloc;
+	void *called_from;
+	long long entry_tsc;
+	int errcode;
+	int vector;
+	int print_debug_info;
+#ifdef CONFIG_SMP
+	int hold_on_sstep;
+	struct {
+		volatile struct task_struct *task;
+		int pid;
+		int hold;
+		struct pt_regs *regs;
+	} cpus_waiting[MAX_NO_CPUS];
+#endif
+} kgdb_info = { hold_init print_debug_info:REMOTE_DEBUG, vector:-1 };
+
+/*
+ * This is little area we set aside to contain the stack we
+ * need to build to allow gdb to call functions.  We use one
+ * per cpu to avoid locking issues.  We will do all this work
+ * with interrupts off so that should take care of the protection
+ * issues.
+ */
+#define LOOKASIDE_SIZE 200	/* should be more than enough */
+#define MALLOC_MAX   200	/* Max malloc size */
+struct {
+	unsigned int esp;
+	int array[LOOKASIDE_SIZE];
+} fn_call_lookaside[MAX_NO_CPUS];
+
+static int trap_cpu;
+
+#define END_OF_LOOKASIDE  &fn_call_lookaside[trap_cpu].array[LOOKASIDE_SIZE]
+
+
+#define MALLOC_ROUND 8-1
+
+static char malloc_array[MALLOC_MAX];
+IF_SMP(static void to_gdb(const char *mess));
+
+/*
+ * Ouch. Apparently, gdb sometimes want to do malloc. It is not used
+ * by the kernel, but do not kill it.
+ */
+void *
+malloc(int size)
+{
+	if (size <= (MALLOC_MAX - kgdb_info.used_malloc)) {
+		int old_used = kgdb_info.used_malloc;
+		kgdb_info.used_malloc += ((size + MALLOC_ROUND) & (~MALLOC_ROUND));
+		return &malloc_array[old_used];
+	} else {
+		return NULL;
+	}
+}
+
+/*
+ * I/O dispatch functions...
+ * Based upon kgdb_eth, either call the ethernet
+ * handler or the serial one..
+ */
+void
+put_debug_char(int c)
+{
+	if (kgdb_eth == -1) {
+		tty_putDebugChar(c);
+	} else {
+		eth_putDebugChar(c);
+	}
+}
+
+static int
+get_debug_char(void)
+{
+	if (kgdb_eth == -1) {
+		return tty_getDebugChar();
+	} else {
+		return eth_getDebugChar();
+	}
+}
+
+static void
+flush_debug_char(void)
+{
+	if (kgdb_eth == -1) {
+		tty_flushDebugChar();
+	} else {
+		eth_flushDebugChar();
+	}
+}
+
+#define waiting_cpus	kgdb_info.cpus_waiting
+#define remote_debug	kgdb_info.print_debug_info
+#define hold_cpu(cpu)	kgdb_info.cpus_waiting[cpu].hold
+/* gdb locks */
+
+#ifdef CONFIG_SMP
+static int in_kgdb_called;
+static spinlock_t waitlocks[MAX_NO_CPUS] =
+    {[0 ... MAX_NO_CPUS - 1] = SPIN_LOCK_UNLOCKED };
+/*
+ * The following array has the thread pointer of each of the "other"
+ * cpus.  We make it global so it can be seen by gdb.
+ */
+volatile int in_kgdb_entry_log[MAX_NO_CPUS];
+volatile struct pt_regs *in_kgdb_here_log[MAX_NO_CPUS];
+/*
+static spinlock_t continuelocks[MAX_NO_CPUS];
+*/
+spinlock_t kgdb_spinlock = SPIN_LOCK_UNLOCKED;
+/* waiters on our spinlock plus us */
+static atomic_t spinlock_waiters = ATOMIC_INIT(1);
+static int spinlock_count = 0;
+static int spinlock_cpu = 0;
+/*
+ * Note we use nested spin locks to account for the case where a break
+ * point is encountered when calling a function by user direction from
+ * kgdb. Also there is the memory exception recursion to account for.
+ * Well, yes, but this lets other cpus thru too.  Lets add a
+ * cpu id to the lock.
+ */
+#define KGDB_SPIN_LOCK(x) if (spinlock_count == 0 || \
+			      spinlock_cpu != smp_processor_id()) {\
+				      atomic_inc(&spinlock_waiters); \
+				      while (! spin_trylock(x)) {\
+					    in_kgdb(&regs);\
+				      }\
+				      atomic_dec(&spinlock_waiters); \
+				      spinlock_count = 1; \
+				      spinlock_cpu = smp_processor_id(); \
+			  }else{  \
+				      spinlock_count++; \
+			  }
+#define KGDB_SPIN_UNLOCK(x) if (--spinlock_count == 0) spin_unlock(x)
+#else
+unsigned kgdb_spinlock = 0;
+#define KGDB_SPIN_LOCK(x) --*x
+#define KGDB_SPIN_UNLOCK(x) ++*x
+#endif
+
+static int
+hex(char ch)
+{
+	if ((ch >= 'a') && (ch <= 'f'))
+		return (ch - 'a' + 10);
+	if ((ch >= '0') && (ch <= '9'))
+		return (ch - '0');
+	if ((ch >= 'A') && (ch <= 'F'))
+		return (ch - 'A' + 10);
+	return (-1);
+}
+
+/* scan for the sequence $<data>#<checksum>	*/
+static void
+getpacket(char *buffer)
+{
+	unsigned char checksum;
+	unsigned char xmitcsum;
+	int i;
+	int count;
+	char ch;
+
+	do {
+		/* wait around for the start character, ignore all other characters */
+		while ((ch = (get_debug_char() & 0x7f)) != '$') ;
+		checksum = 0;
+		xmitcsum = -1;
+
+		count = 0;
+
+		/* now, read until a # or end of buffer is found */
+		while (count < BUFMAX) {
+			ch = get_debug_char() & 0x7f;
+			if (ch == '#')
+				break;
+			checksum = checksum + ch;
+			buffer[count] = ch;
+			count = count + 1;
+		}
+		buffer[count] = 0;
+
+		if (ch == '#') {
+			xmitcsum = hex(get_debug_char() & 0x7f) << 4;
+			xmitcsum += hex(get_debug_char() & 0x7f);
+			if ((remote_debug) && (checksum != xmitcsum)) {
+				printk
+				    ("bad checksum.	My count = 0x%x, sent=0x%x. buf=%s\n",
+				     checksum, xmitcsum, buffer);
+			}
+
+			if (checksum != xmitcsum)
+				put_debug_char('-');	/* failed checksum */
+			else {
+				put_debug_char('+');	/* successful transfer */
+				/* if a sequence char is present, reply the sequence ID */
+				if (buffer[2] == ':') {
+					put_debug_char(buffer[0]);
+					put_debug_char(buffer[1]);
+					/* remove sequence chars from buffer */
+					count = strlen(buffer);
+					for (i = 3; i <= count; i++)
+						buffer[i - 3] = buffer[i];
+				}
+			}
+		}
+	} while (checksum != xmitcsum);
+
+	if (remote_debug)
+		printk("R:%s\n", buffer);
+	flush_debug_char();
+}
+
+/* send the packet in buffer.  */
+
+static void
+putpacket(char *buffer)
+{
+	unsigned char checksum;
+	int count;
+	char ch;
+
+	/*  $<packet info>#<checksum>. */
+
+	if (kgdb_eth == -1) {
+		do {
+			if (remote_debug)
+				printk("T:%s\n", buffer);
+			put_debug_char('$');
+			checksum = 0;
+			count = 0;
+
+			while ((ch = buffer[count])) {
+				put_debug_char(ch);
+				checksum += ch;
+				count += 1;
+			}
+
+			put_debug_char('#');
+			put_debug_char(hexchars[checksum >> 4]);
+			put_debug_char(hexchars[checksum % 16]);
+			flush_debug_char();
+
+		} while ((get_debug_char() & 0x7f) != '+');
+	} else {
+		/*
+		 * For udp, we can not transfer too much bytes once.
+		 * We only transfer MAX_SEND_COUNT size bytes each time
+		 */
+
+#define MAX_SEND_COUNT 30
+
+		int send_count = 0, i = 0;
+		char send_buf[MAX_SEND_COUNT];
+
+		do {
+			if (remote_debug)
+				printk("T:%s\n", buffer);
+			put_debug_char('$');
+			checksum = 0;
+			count = 0;
+			send_count = 0;
+			while ((ch = buffer[count])) {
+				if (send_count >= MAX_SEND_COUNT) {
+					for(i = 0; i < MAX_SEND_COUNT; i++) {
+						put_debug_char(send_buf[i]);
+					}
+					flush_debug_char();
+					send_count = 0;
+				} else {
+					send_buf[send_count] = ch;
+					checksum += ch;
+					count ++;
+					send_count++;
+				}
+			}
+			for(i = 0; i < send_count; i++)
+				put_debug_char(send_buf[i]);
+			put_debug_char('#');
+			put_debug_char(hexchars[checksum >> 4]);
+			put_debug_char(hexchars[checksum % 16]);
+			flush_debug_char();
+		} while ((get_debug_char() & 0x7f) != '+');
+	}
+}
+
+static char remcomInBuffer[BUFMAX];
+static char remcomOutBuffer[BUFMAX];
+static short error;
+
+static void
+debug_error(char *format, char *parm)
+{
+	if (remote_debug)
+		printk(format, parm);
+}
+
+extern void scheduling_functions_start_here(void);
+extern void scheduling_functions_end_here(void);
+#define first_sched	((unsigned long) scheduling_functions_start_here)
+#define last_sched	((unsigned long) scheduling_functions_end_here)
+
+/* Indicate to caller of mem2hex or hex2mem that there has been an
+   error.  */
+static volatile int mem_err = 0;
+static volatile int mem_err_expected = 0;
+static volatile int mem_err_cnt = 0;
+static int garbage_loc = -1;
+
+/* FIXME: WTF? */
+static int
+get_char(char *addr)
+{
+	return *addr;
+}
+
+static void set_char(char *addr, int val, int may_fault);
+
+/* convert the memory pointed to by mem into hex, placing result in buf */
+/* return a pointer to the last char put in buf (null) */
+/* If MAY_FAULT is non-zero, then we should set mem_err in response to
+   a fault; if zero treat a fault like any other fault in the stub.  */
+static char *
+mem2hex(char *mem, char *buf, int count, int may_fault)
+{
+	int i;
+	unsigned char ch;
+
+	if (may_fault) {
+		mem_err_expected = 1;
+		mem_err = 0;
+	}
+	for (i = 0; i < count; i++) {
+		/* printk("%lx = ", mem) ; */
+
+		ch = get_char(mem++);
+
+		/* printk("%02x\n", ch & 0xFF) ; */
+		if (may_fault && mem_err) {
+			if (remote_debug)
+				printk("Mem fault fetching from addr %lx\n",
+				       (long) (mem - 1));
+			*buf = 0;	/* truncate buffer */
+			return (buf);
+		}
+		*buf++ = hexchars[ch >> 4];
+		*buf++ = hexchars[ch % 16];
+	}
+	*buf = 0;
+	if (may_fault)
+		mem_err_expected = 0;
+	return (buf);
+}
+
+/* convert the hex array pointed to by buf into binary to be placed in mem */
+/* return a pointer to the character AFTER the last byte written */
+/* NOTE: We use the may fault flag to also indicate if the write is to
+ * the registers (0) or "other" memory (!=0)
+ */
+static char *
+hex2mem(char *buf, char *mem, int count, int may_fault)
+{
+	int i;
+	unsigned char ch;
+
+	if (may_fault) {
+		mem_err_expected = 1;
+		mem_err = 0;
+	}
+	for (i = 0; i < count; i++) {
+		ch = hex(*buf++) << 4;
+		ch = ch + hex(*buf++);
+		set_char(mem++, ch, may_fault);
+
+		if (may_fault && mem_err) {
+			if (remote_debug)
+				printk("Mem fault storing to addr %lx\n",
+				       (long) (mem - 1));
+			return (mem);
+		}
+	}
+	if (may_fault)
+		mem_err_expected = 0;
+	return (mem);
+}
+
+/*
+ * While we find nice hex chars, build an int
+ * return number of chars processed	     
+ */
+int
+hexToInt(char **ptr, int *intValue)
+{
+	int numChars = 0;
+	int hexValue;
+
+	*intValue = 0;
+
+	while (**ptr) {
+		hexValue = hex(**ptr);
+		if (hexValue >= 0) {
+			*intValue = (*intValue << 4) | hexValue;
+			numChars++;
+		} else
+			break;
+
+		(*ptr)++;
+	}
+
+	return (numChars);
+}
+
+#define stubhex(h) hex(h)
+#ifdef old_thread_list
+
+static int
+stub_unpack_int(char *buff, int fieldlength)
+{
+	int nibble;
+	int retval = 0;
+
+	while (fieldlength) {
+		nibble = stubhex(*buff++);
+		retval |= nibble;
+		fieldlength--;
+		if (fieldlength)
+			retval = retval << 4;
+	}
+	return retval;
+}
+#endif
+static char *
+pack_hex_byte(char *pkt, int byte)
+{
+	*pkt++ = hexchars[(byte >> 4) & 0xf];
+	*pkt++ = hexchars[(byte & 0xf)];
+	return pkt;
+}
+
+#define BUF_THREAD_ID_SIZE 16
+
+static char *
+pack_threadid(char *pkt, threadref * id)
+{
+	char *limit;
+	unsigned char *altid;
+
+	altid = (unsigned char *) id;
+	limit = pkt + BUF_THREAD_ID_SIZE;
+	while (pkt < limit)
+		pkt = pack_hex_byte(pkt, *altid++);
+	return pkt;
+}
+
+#ifdef old_thread_list
+static char *
+unpack_byte(char *buf, int *value)
+{
+	*value = stub_unpack_int(buf, 2);
+	return buf + 2;
+}
+
+static char *
+unpack_threadid(char *inbuf, threadref * id)
+{
+	char *altref;
+	char *limit = inbuf + BUF_THREAD_ID_SIZE;
+	int x, y;
+
+	altref = (char *) id;
+
+	while (inbuf < limit) {
+		x = stubhex(*inbuf++);
+		y = stubhex(*inbuf++);
+		*altref++ = (x << 4) | y;
+	}
+	return inbuf;
+}
+#endif
+
+static void
+int_to_threadref(threadref * id, int value)
+{
+	unsigned char *scan;
+
+	scan = (unsigned char *) id;
+	{
+		int i = 4;
+		while (i--)
+			*scan++ = 0;
+	}
+	*scan++ = (value >> 24) & 0xff;
+	*scan++ = (value >> 16) & 0xff;
+	*scan++ = (value >> 8) & 0xff;
+	*scan++ = (value & 0xff);
+}
+
+static int
+int_to_hex_v(unsigned char * id, int value)
+{
+	unsigned char *start = id;
+	int shift;
+	int ch;
+
+	for (shift = 28; shift >= 0; shift -= 4) {
+		if ((ch = (value >> shift) & 0xf) || (id != start)) {
+			*id = hexchars[ch];
+			id++;
+		}
+	}
+	if (id == start)
+		*id++ = '0';
+	return id - start;
+}
+
+
+#ifdef old_thread_list
+static int
+threadref_to_int(threadref * ref)
+{
+	int i, value = 0;
+	unsigned char *scan;
+
+	scan = (char *) ref;
+	scan += 4;
+	i = 4;
+	while (i-- > 0)
+		value = (value << 8) | ((*scan++) & 0xff);
+	return value;
+}
+#endif
+
+/* FIXME: WTF?! */
+static int
+cmp_str(char *s1, char *s2, int count)
+{
+	while (count--) {
+		if (*s1++ != *s2++)
+			return 0;
+	}
+	return 1;
+}
+
+extern struct task_struct *kgdb_get_idle(int cpu);
+#define idle_task(cpu) kgdb_get_idle(cpu)
+
+extern int kgdb_pid_init_done;
+
+struct task_struct *
+getthread(int pid)
+{
+	struct task_struct *thread;
+	if (pid >= PID_MAX && pid <= (PID_MAX + MAX_NO_CPUS)) {
+
+		return idle_task(pid - PID_MAX);
+	} else {
+		/*
+		 * find_task_by_pid is relatively safe all the time
+		 * Other pid functions require lock downs which imply
+		 * that we may be interrupting them (as we get here
+		 * in the middle of most any lock down).
+		 * Still we don't want to call until the table exists!
+		 */
+		if (kgdb_pid_init_done) {
+			thread = find_task_by_pid(pid);
+			if (thread) {
+				return thread;
+			}
+		}
+	}
+	return NULL;
+}

-- 
When do you have a heart between your knees?
[Johanka's followup: and *two* hearts?]

             reply	other threads:[~2004-01-09 18:41 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-01-09 18:38 Pavel Machek [this message]
2004-01-09 21:41 ` kgdb cleanups Andrew Morton
2004-01-09 21:54 ` George Anzinger
2004-01-10  4:47   ` Matt Mackall
2004-01-10  8:12     ` George Anzinger
2004-01-10 17:56       ` Matt Mackall
2004-01-10 19:34         ` Pavel Machek
2004-01-10 19:37           ` Matt Mackall
2004-01-12  5:41         ` George Anzinger
2004-01-12  6:49           ` Matt Mackall
2004-01-12  9:45             ` Pavel Machek
2004-01-13 20:54               ` George Anzinger
2004-01-13 21:00                 ` Pavel Machek
2004-01-12 13:53             ` Amit S. Kale
2004-01-13 21:20               ` George Anzinger
2004-01-14 13:20                 ` Amit S. Kale
2004-01-14 20:40                   ` George Anzinger
2004-01-13 20:53             ` George Anzinger
2004-01-14 13:04               ` Amit S. Kale
2004-01-14 20:35                 ` George Anzinger
2004-01-10 15:15   ` Pavel Machek
  -- strict thread matches above, loose matches on Subject: below --
2003-12-28 14:13 Pavel Machek
2003-12-28 20:14 ` Robert Walsh

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20040109183826.GA795@elf.ucw.cz \
    --to=pavel@ucw.cz \
    --cc=akpm@zip.com.au \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.