public inbox for linux-kernel@vger.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox