Subject: Re: Compiling gdb 4.14
To: None <current-users@NetBSD.ORG>
From: Christos Zoulas <christos@deshaw.com>
List: current-users
Date: 07/02/1995 00:16:07
In article <199507012205.SAA10181@pain.lcs.mit.edu> Chris_G_Demetriou@lagavulin.pdl.cs.cmu.edu (Chris G Demetriou) writes:
>
>you should change infptrace.c to use the new functions.  (If you do
>so, you might mail the list with a copy of the diffs.)
>

The following diffs:
- Fix so that gdb can compile without mmalloc
- copies the relevant changes from gdb on the current netbsd tree to 4.14
  [I have tested the changes only on NetBSD/i386]
- Fixes struct member printing on cfront mangled files
- Fixes demangling of cfront templates that contain literal constants,
  i.e. template<const unsigned int T>. Before the fix, the demangler
  would go into an infinite loop eating all the memory of the machine.

I have not tested kernel debugging with this.
Someone should forward at least the last 2 fixes to the gdb maintainers.

christos


Index: gdb/defs.h
===================================================================
RCS file: /src/gnu/repository/gdb/gdb/defs.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -c -r1.1 -r1.2
*** 1.1	1995/06/01 23:36:07
--- 1.2	1995/06/28 20:56:17
***************
*** 35,41 ****
--- 35,43 ----
  
  #include "progress.h"
  
+ #ifndef NO_MMALLOC
  #include "mmalloc.h"
+ #endif
  
  /* For BFD64 and bfd_vma.  */
  #include "bfd.h"
Index: gdb/i386b-nat.c
===================================================================
RCS file: /src/gnu/repository/gdb/gdb/i386b-nat.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -c -r1.1 -r1.2
*** 1.1	1995/06/01 23:36:12
--- 1.2	1995/06/28 20:56:18
***************
*** 22,34 ****
  
  /* this table must line up with REGISTER_NAMES in tm-i386.h */
  /* symbols like 'tEAX' come from <machine/reg.h> */
! static int tregmap[] = 
  {
    tEAX, tECX, tEDX, tEBX,
    tESP, tEBP, tESI, tEDI,
!   tEIP, tEFLAGS, tCS, tSS
  };
  
  #ifdef sEAX
  static int sregmap[] = 
  {
--- 22,36 ----
  
  /* this table must line up with REGISTER_NAMES in tm-i386.h */
  /* symbols like 'tEAX' come from <machine/reg.h> */
! int tregmap[] = 
  {
    tEAX, tECX, tEDX, tEBX,
    tESP, tEBP, tESI, tEDI,
!   tEIP, tEFLAGS, tCS, tSS,
!   tDS, tES
  };
  
+ 
  #ifdef sEAX
  static int sregmap[] = 
  {
***************
*** 45,51 ****
  {
    tEAX, tECX, tEDX, tEBX,
    tESP, tEBP, tESI, tEDI,
!   tEIP, tEFLAGS, tCS, tSS
  };
  #endif /* No sEAX */
  
--- 47,54 ----
  {
    tEAX, tECX, tEDX, tEBX,
    tESP, tEBP, tESI, tEDI,
!   tEIP, tEFLAGS, tCS, tSS,
!   tDS, tES
  };
  #endif /* No sEAX */
  
***************
*** 221,225 ****
--- 224,260 ----
    
    print_387_status (0, (struct env387 *)buf);
  }
+ #endif
+ 
+ #if defined(FETCH_INFERIOR_REGISTERS)
+ #ifndef PT_GETREGS
+ #include <sys/ptrace.h>
+ #endif
+ #include "inferior.h"
+ 
+ void
+ fetch_inferior_registers (regno)
+      int regno;
+ {
+   struct reg inferior_registers;
+ 
+   ptrace (PT_GETREGS, inferior_pid,
+ 	  (PTRACE_ARG3_TYPE) &inferior_registers, 0);
  
+   memcpy (&registers[REGISTER_BYTE (0)], &inferior_registers, 4*14);
+ 
+   registers_fetched ();
+ }
+ 
+ void
+ store_inferior_registers (regno)
+      int regno;
+ {
+   struct reg inferior_registers;
+ 
+   memcpy (&inferior_registers, &registers[REGISTER_BYTE (0)], 4*14);
+ 
+   ptrace (PT_SETREGS, inferior_pid,
+ 	  (PTRACE_ARG3_TYPE) &inferior_registers, 0);
+ }
  #endif
Index: gdb/infptrace.c
===================================================================
RCS file: /src/gnu/repository/gdb/gdb/infptrace.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -c -r1.1 -r1.2
*** 1.1	1995/06/01 23:36:13
--- 1.2	1995/06/28 20:56:20
***************
*** 151,158 ****
--- 151,162 ----
       instructions), so we don't have to worry about that here.  */
  
    if (step)
+ #ifdef PT_STEP
      ptrace (PT_STEP,     pid, (PTRACE_ARG3_TYPE) 1,
  	    target_signal_to_host (signal));
+ #else
+     printf("Single step attempted\n");
+ #endif
    else
      ptrace (PT_CONTINUE, pid, (PTRACE_ARG3_TYPE) 1,
  	    target_signal_to_host (signal));
***************
*** 213,219 ****
--- 217,227 ----
  
    names[0].n_un.n_name = "_u";
    names[1].n_un.n_name = NULL;
+ #if __NetBSD__
+   if (nlist ("/netbsd", names) == 0)
+ #else
    if (nlist ("/vmunix", names) == 0)
+ #endif
      kernel_u_addr = names[0].n_value;
    else
      fatal ("Unable to get kernel u area address.");
Index: gdb/valops.c
===================================================================
RCS file: /src/gnu/repository/gdb/gdb/valops.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -c -r1.1 -r1.2
*** 1.1	1995/06/01 23:36:22
--- 1.2	1995/06/28 20:56:23
***************
*** 57,62 ****
--- 57,65 ----
  
  #define VALUE_SUBSTRING_START(VAL) VALUE_FRAME(VAL)
  
+ static char *
+ mangle_cfront_struct_field PARAMS((struct type *, const char *));
+ 
  
  /* Allocate NBYTES of space in the inferior using the inferior's malloc
     and return a value that is a pointer to the allocated space. */
***************
*** 1497,1502 ****
--- 1500,1549 ----
  				 looking_for_baseclass);
        if (v) return v;
      }
+   if (current_language->la_language == language_cplus && !looking_for_baseclass)
+     {
+       /*
+        * christos@deshaw.com:
+        * Mangle the field name and try again in case it was a cfront 
+        * generated field.
+        */
+       char *newname = mangle_cfront_struct_field(type, name);
+ 
+       for (i = TYPE_NFIELDS (type) - 1; i >= TYPE_N_BASECLASSES (type); i--)
+ 	{
+ 	  char *t_field_name = TYPE_FIELD_NAME (type, i);
+ 
+ 	  if (t_field_name && !strcmp (t_field_name, newname))
+ 	    {
+ 	      value_ptr v;
+ 	      if (TYPE_FIELD_STATIC (type, i))
+ 		{
+ 		  char *phys_name = TYPE_FIELD_STATIC_PHYSNAME (type, i);
+ 		  struct symbol *sym =
+ 		    lookup_symbol (phys_name, 0, VAR_NAMESPACE, 0, NULL);
+ 		  if (! sym) 
+ 		     {
+ 		       free(newname);
+ 		     error (
+ 	    "Internal error: could not find physical static variable named %s",
+ 				    phys_name);
+ 		     }
+ 		  v = value_at (TYPE_FIELD_TYPE (type, i),
+ 				(CORE_ADDR)SYMBOL_BLOCK_VALUE (sym));
+ 		}
+ 	      else
+ 		v = value_primitive_field (arg1, offset, i, type);
+ 	      if (v == 0) {
+ 		free(newname);
+ 		error("there is no field named %s", name);
+ 	      }
+ 	      free(newname);
+ 	      return v;
+ 	    }
+ 	}
+       free(newname);
+     }
+ 
    return NULL;
  }
  
***************
*** 1772,1777 ****
--- 1819,1843 ----
  }
  
  
+ /*
+  * christos@deshaw.com: Return a mangled name for a struct + field pair
+  */
+ static char *
+ mangle_cfront_struct_field(t, name)
+     struct type *t;
+     const char *name;
+ {
+   char *tname = type_name_no_tag(t);
+   int tl = strlen(tname);
+   char *newname = malloc(tl + strlen(name) + 64); 
+   (void) sprintf(newname, "%s__%u%s", name, tl, tname);
+ 
+ #ifdef DEBUGMANGLE
+   fprintf(stderr, "%s::%s -> %s\n", tname, name, newname);
+ #endif
+   return newname;
+ }
+ 
  /* C++: Given ARG1, a value of type (pointer to a)* structure/union,
     return 1 if the component named NAME from the ultimate
     target structure/union is defined, otherwise, return 0.  */
***************
*** 1944,1949 ****
--- 2010,2034 ----
        if (v)
  	return v;
      }
+ 
+   if (current_language->la_language == language_cplus)
+     {
+       /*
+        * christos@deshaw.com: Mangle the name and try again
+        */
+       extern struct block *expression_context_block;
+       char* mname = mangle_cfront_struct_field(t, name);
+       struct symbol *sym = lookup_symbol (mname, 0, VAR_NAMESPACE, 0, NULL);
+       if (sym == NULL)
+ 	  sym = lookup_symbol (mname, 
+ 			expression_context_block, VAR_NAMESPACE, 0, NULL);
+       free(mname);
+ 
+       if (sym)
+ 	return value_at (SYMBOL_TYPE (sym),
+ 			 (CORE_ADDR)SYMBOL_BLOCK_VALUE (sym));
+     }
+ 
    return 0;
  }
  
Index: gdb/config/xm-nbsd.h
===================================================================
RCS file: /src/gnu/repository/gdb/gdb/config/xm-nbsd.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -c -r1.1 -r1.2
*** 1.1	1995/06/01 23:36:29
--- 1.2	1995/06/28 20:59:27
***************
*** 33,35 ****
--- 33,42 ----
  
  /* psignal() is in <signal.h>.  */
  #define PSIGNAL_IN_SIGNAL_H
+ 
+ #include <machine/limits.h>		/* for INT_MIN, to avoid "INT_MIN
+ 					   redefined" warnings from defs.h */
+ 
+ /* Get rid of any system-imposed stack limit if possible.  */
+ 
+ #define SET_STACK_LIMIT_HUGE
Index: gdb/config/i386/nm-nbsd.h
===================================================================
RCS file: /src/gnu/repository/gdb/gdb/config/i386/nm-nbsd.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -c -r1.1 -r1.2
*** 1.1	1995/06/01 23:36:35
--- 1.2	1995/06/28 20:59:33
***************
*** 1,5 ****
! /* Native-dependent definitions for Intel 386 running NetBSD, for GDB.
!    Copyright 1986, 1987, 1989, 1992, 1994 Free Software Foundation, Inc.
  
  This file is part of GDB.
  
--- 1,5 ----
! /* Native-dependent definitions for Intel 386 running BSD Unix, for GDB.
!    Copyright 1986, 1987, 1989, 1992 Free Software Foundation, Inc.
  
  This file is part of GDB.
  
***************
*** 15,34 ****
  
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
! Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  
! #ifndef NM_NBSD_H
! #define NM_NBSD_H
  
! /* Get generic NetBSD native definitions. */
! #include "nm-nbsd.h"
  
! #define FLOAT_INFO	{ i386_float_info(); }
  
! #define REGISTER_U_ADDR(addr, blockend, regno) \
! 	(addr) = i386_register_u_addr ((blockend),(regno));
  
! extern int
! i386_register_u_addr PARAMS ((int, int));
  
! #endif /* NM_NBSD_H */
--- 15,36 ----
  
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
! Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  
! 	$Id: nm-nbsd.h,v 1.2 1995/06/28 20:59:33 christos Exp $
! */
  
! #ifndef NM_I386BSD_H
! #define NM_I386BSD_H
  
! #include "nm-nbsd.h"
  
! #include <machine/vmparam.h>
  
! #define	REGISTER_U_ADDR(addr, blockend, regno)				\
! {									\
!   extern int tregmap[];							\
!   addr = blockend + 4 * tregmap[regno];					\
! }
  
! #endif /* NM_I386BSD_H */
Index: gdb/config/i386/tm-nbsd.h
===================================================================
RCS file: /src/gnu/repository/gdb/gdb/config/i386/tm-nbsd.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -c -r1.1 -r1.2
*** 1.1	1995/06/01 23:36:37
--- 1.2	1995/06/28 20:59:34
***************
*** 1,5 ****
! /* Macro definitions for i386 running under NetBSD.
!    Copyright 1994 Free Software Foundation, Inc.
  
  This file is part of GDB.
  
--- 1,5 ----
! /* Macro definitions for i386 running under BSD Unix.
!    Copyright 1986, 1987, 1989, 1991, 1992, 1993 Free Software Foundation, Inc.
  
  This file is part of GDB.
  
***************
*** 15,39 ****
  
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
! Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  
! #ifndef TM_NBSD_H
! #define TM_NBSD_H
  
! #include "i386/tm-i386bsd.h"
! #include "tm-nbsd.h"
! 
! #define JB_ELEMENT_SIZE sizeof(int)	/* jmp_buf[_JBLEN] is array of ints */
! #define JB_PC	0			/* Setjmp()'s return PC saved here */
  
! /* Figure out where the longjmp will land.  Slurp the args out of the stack.
!    We expect the first arg to be a pointer to the jmp_buf structure from which
!    we extract the pc (JB_PC) that we will land at.  The pc is copied into ADDR.
!    This routine returns true on success */
! 
! extern int
! get_longjmp_target PARAMS ((CORE_ADDR *));
  
! #define GET_LONGJMP_TARGET(ADDR) get_longjmp_target(ADDR)
  
! #endif /* TM_NBSD_H */
--- 15,86 ----
  
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
! Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  
! 	$Id: tm-nbsd.h,v 1.2 1995/06/28 20:59:34 christos Exp $
! */
  
! /* Override number of expected traps from sysv. */
! #define START_INFERIOR_TRAPS_EXPECTED 2
  
! /* Most definitions from sysv could be used. */
! #include "i386/tm-i386v.h"
! #include "tm-nbsd.h"
  
! /* Shared library code */
! #include "solib.h"
  
! /* We can't yet read %fs and %gs. */
! #undef NUM_REGS
! #define NUM_REGS 14
! 
! /* We define our own fetch and store methods. */
! #define FETCH_INFERIOR_REGISTERS
! 
! /* On 386 bsd, sigtramp is above the user stack and immediately below
!    the user area. Using constants here allows for cross debugging.
!    These are tested for BSDI but should work on 386BSD.
!    XXX - Changed to new kernel VA, not tested */
! #define SIGTRAMP_START	0xf7bfdfc0
! #define SIGTRAMP_END	0xf7bfe000
! 
! /* The following redefines make backtracing through sigtramp work.
!    They manufacture a fake sigtramp frame and obtain the saved pc in sigtramp
!    from the sigcontext structure which is pushed by the kernel on the
!    user stack, along with a pointer to it.  */
! 
! /* FRAME_CHAIN takes a frame's nominal address and produces the frame's
!    chain-pointer.
!    In the case of the i386, the frame's nominal address
!    is the address of a 4-byte word containing the calling frame's address.  */
! #undef FRAME_CHAIN
! #define FRAME_CHAIN(thisframe)  \
!   (thisframe->signal_handler_caller \
!    ? thisframe->frame \
!    : (!inside_entry_file ((thisframe)->pc) \
!       ? read_memory_integer ((thisframe)->frame, 4) \
!       : 0))
! 
! /* A macro that tells us whether the function invocation represented
!    by FI does not have a frame on the stack associated with it.  If it
!    does not, FRAMELESS is set to 1, else 0.  */
! #undef FRAMELESS_FUNCTION_INVOCATION
! #define FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS) \
!   do { \
!     if ((FI)->signal_handler_caller) \
!       (FRAMELESS) = 0; \
!     else \
!       (FRAMELESS) = frameless_look_for_prologue(FI); \
!   } while (0)
! 
! /* Saved Pc.  Get it from sigcontext if within sigtramp.  */
! 
! /* Offset to saved PC in sigcontext, from <sys/signal.h>.  */
! #define SIGCONTEXT_PC_OFFSET 44
! 
! #undef FRAME_SAVED_PC(FRAME)
! #define FRAME_SAVED_PC(FRAME) \
!   (((FRAME)->signal_handler_caller \
!     ? sigtramp_saved_pc (FRAME) \
!     : read_memory_integer ((FRAME)->frame + 4, 4)) \
!    )
Index: gdb/config/i386/xm-nbsd.h
===================================================================
RCS file: /src/gnu/repository/gdb/gdb/config/i386/xm-nbsd.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -c -r1.1 -r1.2
*** 1.1	1995/06/01 23:36:38
--- 1.2	1995/06/28 20:59:36
***************
*** 1,5 ****
! /* Parameters for execution on a i386 running NetBSD, for GDB.
!    Copyright 1994 Free Software Foundation, Inc.
  
  This file is part of GDB.
  
--- 1,5 ----
! /* Host-dependent definitions for Intel 386 running BSD Unix, for GDB.
!    Copyright 1986, 1987, 1989, 1992 Free Software Foundation, Inc.
  
  This file is part of GDB.
  
***************
*** 15,21 ****
  
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
! Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  
- /* Get generic NetBSD host definitions. */
  #include "xm-nbsd.h"
--- 15,23 ----
  
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
! Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
! 
! 	$Id: xm-nbsd.h,v 1.2 1995/06/28 20:59:36 christos Exp $
! */
  
  #include "xm-nbsd.h"
Index: gdb/config/ns32k/nm-nbsd.h
===================================================================
RCS file: /src/gnu/repository/gdb/gdb/config/ns32k/nm-nbsd.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -c -r1.1 -r1.2
*** 1.1	1995/06/01 23:37:03
--- 1.2	1995/06/28 20:59:42
***************
*** 1,5 ****
! /* Native-dependent definitions for ns32k running NetBSD, for GDB.
!    Copyright 1986, 1987, 1989, 1992, 1994 Free Software Foundation, Inc.
  
  This file is part of GDB.
  
--- 1,5 ----
! /* Native-dependent definitions for ns32k running BSD Unix, for GDB.
!    Copyright 1986, 1987, 1989, 1992 Free Software Foundation, Inc.
  
  This file is part of GDB.
  
***************
*** 15,31 ****
  
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
! Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  
! #ifndef NM_NBSD_H
! #define NM_NBSD_H
  
! /* Get generic NetBSD native definitions. */
! #include "nm-nbsd.h"
  
! #if 0
! #define FLOAT_INFO	{ extern ns32k_float_info(); ns32k_float_info(); }
! #endif
  
  #define REGISTER_U_ADDR(addr, blockend, regno) \
  	(addr) = ns32k_register_u_addr ((blockend),(regno));
--- 15,30 ----
  
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
! Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  
! 	$Id: nm-nbsd.h,v 1.2 1995/06/28 20:59:42 christos Exp $
! */
  
! #ifndef NM_I386BSD_H
! #define NM_I386BSD_H
  
! #include "nm-nbsd.h"
! #include <machine/vmparam.h>
  
  #define REGISTER_U_ADDR(addr, blockend, regno) \
  	(addr) = ns32k_register_u_addr ((blockend),(regno));
***************
*** 33,36 ****
  extern int
  ns32k_register_u_addr PARAMS ((int, int));
  
! #endif /* NM_NBSD_H */
--- 32,35 ----
  extern int
  ns32k_register_u_addr PARAMS ((int, int));
  
! #endif /* NM_I386BSD_H */
Index: gdb/config/ns32k/xm-nbsd.h
===================================================================
RCS file: /src/gnu/repository/gdb/gdb/config/ns32k/xm-nbsd.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -c -r1.1 -r1.2
*** 1.1	1995/06/01 23:37:04
--- 1.2	1995/06/28 20:59:43
***************
*** 1,5 ****
! /* Parameters for execution on a ns32k running NetBSD, for GDB.
!    Copyright 1994 Free Software Foundation, Inc.
  
  This file is part of GDB.
  
--- 1,5 ----
! /* Host-dependent definitions for ns32k running BSD Unix, for GDB.
!    Copyright 1986, 1987, 1989, 1992 Free Software Foundation, Inc.
  
  This file is part of GDB.
  
***************
*** 15,21 ****
  
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
! Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  
- /* Get generic NetBSD host definitions. */
  #include "xm-nbsd.h"
--- 15,23 ----
  
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
! Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
! 
! 	$Id: xm-nbsd.h,v 1.2 1995/06/28 20:59:43 christos Exp $
! */
  
  #include "xm-nbsd.h"
Index: gdb/config/sparc/nm-nbsd.h
===================================================================
RCS file: /src/gnu/repository/gdb/gdb/config/sparc/nm-nbsd.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -c -r1.1 -r1.2
*** 1.1	1995/06/01 23:37:12
--- 1.2	1995/06/28 20:59:55
***************
*** 1,4 ****
! /* Native-dependent definitions for Sparc running NetBSD, for GDB.
     Copyright 1986, 1987, 1989, 1992 Free Software Foundation, Inc.
  
  This file is part of GDB.
--- 1,4 ----
! /* Native-dependent definitions for Intel 386 running BSD Unix, for GDB.
     Copyright 1986, 1987, 1989, 1992 Free Software Foundation, Inc.
  
  This file is part of GDB.
***************
*** 15,28 ****
  
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
! Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  
! #ifndef NM_NBSD_H
! #define NM_NBSD_H
  
- /* Get generic NetBSD native definitions. */
  #include "nm-nbsd.h"
  
  #define FETCH_INFERIOR_REGISTERS
  
! #endif /* NM_NBSD_H */
--- 15,35 ----
  
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
! Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  
! 	$Id: nm-nbsd.h,v 1.2 1995/06/28 20:59:55 christos Exp $
! */
! 
! #ifndef NM_SPARC_H
! #define NM_SPARC_H
  
  #include "nm-nbsd.h"
  
+ /* This is the amount to subtract from u.u_ar0
+    to get the offset in the core file of the register values.  */
+ 
+ #include <machine/vmparam.h>
+ 
  #define FETCH_INFERIOR_REGISTERS
  
! #endif /* NM_SPARC_H */
Index: gdb/config/sparc/xm-nbsd.h
===================================================================
RCS file: /src/gnu/repository/gdb/gdb/config/sparc/xm-nbsd.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -c -r1.1 -r1.2
*** 1.1	1995/06/01 23:37:14
--- 1.2	1995/06/28 20:59:56
***************
*** 1,5 ****
! /* Parameters for execution on a Sparc running NetBSD, for GDB.
!    Copyright 1994 Free Software Foundation, Inc.
  
  This file is part of GDB.
  
--- 1,6 ----
! /* Parameters for execution on a Sun 4, for GDB, the GNU debugger.
!    Copyright 1986, 1987, 1989, 1991, 1992 Free Software Foundation, Inc.
!    Contributed by Michael Tiemann (tiemann@mcc.com).
  
  This file is part of GDB.
  
***************
*** 15,24 ****
  
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
! Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  
! /* Get generic NetBSD host definitions. */
! #include "xm-nbsd.h"
  
! /* Before storing, we need to read all the registers. */
  #define CHILD_PREPARE_TO_STORE() read_register_bytes (0, NULL, REGISTER_BYTES)
--- 16,28 ----
  
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
! Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  
! 	$Id: xm-nbsd.h,v 1.2 1995/06/28 20:59:56 christos Exp $
! */
  
! /* Before storing, we need to read all the registers.  */
  #define CHILD_PREPARE_TO_STORE() read_register_bytes (0, NULL, REGISTER_BYTES)
+ 
+ /* It does have a wait structure, and it might help things out . . . */
+ #define HAVE_WAIT_STRUCT
Index: libiberty/cplus-dem.c
===================================================================
RCS file: /src/gnu/repository/gdb/libiberty/cplus-dem.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -c -r1.1 -r1.2
*** 1.1	1995/06/01 23:38:17
--- 1.2	1995/06/28 21:00:36
***************
*** 199,204 ****
--- 199,207 ----
  #endif
  
  static int
+ do_value PARAMS ((string *tname, CONST char **old_p, CONST char **mangled));
+ 
+ static int
  demangle_template PARAMS ((struct work_stuff *work, CONST char **, string *,
  			   string *));
  
***************
*** 761,769 ****
  	      }
  	    break;
  	}
! /*
        if (AUTO_DEMANGLING || GNU_DEMANGLING)
! */
  	{
  	  if (success && expect_func)
  	    {
--- 764,772 ----
  	      }
  	    break;
  	}
! #if 0
        if (AUTO_DEMANGLING || GNU_DEMANGLING)
! #endif
  	{
  	  if (success && expect_func)
  	    {
***************
*** 821,826 ****
--- 824,975 ----
  
  #endif
  
+ 
+ 
+ static int
+ do_value(tname, old_p, mangled)
+      string *tname;
+      CONST char **old_p;
+      CONST char **mangled;
+ {
+   int symbol_len;
+   int is_pointer = 0;
+   int is_real = 0;
+   int is_integral = 0;
+   int done = 0;
+   int is_char = 0;
+ 
+ #if 0
+   string_append (tname, "=");
+ #endif
+   while (*old_p && !done)
+     {	
+       switch (**old_p)
+ 	{
+ 	  case 'P':
+ 	  case 'p':
+ 	  case 'R':
+ 	    done = is_pointer = 1;
+ 	    break;
+ 	  case 'C':	/* const */
+ 	  case 'S':	/* explicitly signed [char] */
+ 	  case 'U':	/* unsigned */
+ 	  case 'V':	/* volatile */
+ 	  case 'F':	/* function */
+ 	  case 'M':	/* member function */
+ 	  case 'O':	/* ??? */
+ 	    (*old_p)++;
+ 	    continue;
+ 	  case 'Q':	/* qualified name */
+             done = is_integral = 1;
+             break;
+ 	  case 'T':	/* remembered type */
+ 	    abort ();
+ 	    break;
+ 	  case 'v':	/* void */
+ 	    abort ();
+ 	    break;
+ 	  case 'x':	/* long long */
+ 	  case 'l':	/* long */
+ 	  case 'i':	/* int */
+ 	  case 's':	/* short */
+ 	  case 'w':	/* wchar_t */
+ 	    done = is_integral = 1;
+ 	    break;
+ 	  case 'c':	/* char */
+ 	    done = is_char = 1;
+ 	    break;
+ 	  case 'r':	/* long double */
+ 	  case 'd':	/* double */
+ 	  case 'f':	/* float */
+ 	    done = is_real = 1;
+ 	    break;
+ 	  default:
+ 	    /* it's probably user defined type, let's assume
+ 	       it's integeral, it seems hard to figure out
+ 	       what it really is */
+ 	    done = is_integral = 1;
+ 	}
+     }
+   if (is_integral)
+     {
+       if (**mangled == 'm')
+ 	{
+ 	  string_appendn (tname, "-", 1);
+ 	  (*mangled)++;
+ 	}
+       while (isdigit (**mangled))	
+ 	{
+ 	  string_appendn (tname, *mangled, 1);
+ 	  (*mangled)++;
+ 	}
+     }
+   else if (is_char)
+     {
+     char tmp[2];
+     int val;
+       if (**mangled == 'm')
+ 	{
+ 	  string_appendn (tname, "-", 1);
+ 	  (*mangled)++;
+ 	}
+       string_appendn (tname, "'", 1);
+       val = consume_count(mangled);
+       if (val == 0)
+ 	{
+ 	  return 0;
+ 	}
+       tmp[0] = (char)val;
+       tmp[1] = '\0';
+       string_appendn (tname, &tmp[0], 1);
+       string_appendn (tname, "'", 1);
+     }
+   else if (is_real)
+     {
+       if (**mangled == 'm')
+ 	{
+ 	  string_appendn (tname, "-", 1);
+ 	  (*mangled)++;
+ 	}
+       while (isdigit (**mangled))	
+ 	{
+ 	  string_appendn (tname, *mangled, 1);
+ 	  (*mangled)++;
+ 	}
+       if (**mangled == '.') /* fraction */
+ 	{
+ 	  string_appendn (tname, ".", 1);
+ 	  (*mangled)++;
+ 	  while (isdigit (**mangled))	
+ 	    {
+ 	      string_appendn (tname, *mangled, 1);
+ 	      (*mangled)++;
+ 	    }
+ 	}
+       if (**mangled == 'e') /* exponent */
+ 	{
+ 	  string_appendn (tname, "e", 1);
+ 	  (*mangled)++;
+ 	  while (isdigit (**mangled))	
+ 	    {
+ 	      string_appendn (tname, *mangled, 1);
+ 	      (*mangled)++;
+ 	    }
+ 	}
+     }
+   else if (is_pointer)
+     {
+       if (!get_count (mangled, &symbol_len))
+ 	{
+ 	  return 0;
+ 	}
+       string_appendn (tname, *mangled, symbol_len);
+       *mangled += symbol_len;
+     }
+     return 1;
+ }
+ 
+ 
  static int
  demangle_template (work, mangled, tname, trawname)
       struct work_stuff *work;
***************
*** 829,845 ****
       string *trawname;
  {
    int i;
-   int is_pointer;
-   int is_real;
-   int is_integral;
-   int is_char;
    int r;
    int need_comma = 0;
    int success = 0;
-   int done;
    CONST char *old_p;
    CONST char *start;
-   int symbol_len;
    string temp;
  
    (*mangled)++;
--- 978,988 ----
***************
*** 885,1036 ****
  	{
  	  /* otherwise, value parameter */
  	  old_p  = *mangled;
- 	  is_pointer = 0;
- 	  is_real = 0;
- 	  is_integral = 0;
-           is_char = 0;
- 	  done = 0;
  	  /* temp is initialized in do_type */
  	  success = do_type (work, mangled, &temp);
! /*
  	  if (success)
  	    {
  	      string_appends (tname, &temp);
  	    }
! */
  	  string_delete(&temp);
  	  if (!success)
  	    {
  	      break;
  	    }
! /*
! 	  string_append (tname, "=");
! */
! 	  while (*old_p && !done)
! 	    {	
! 	      switch (*old_p)
! 		{
! 		  case 'P':
! 		  case 'p':
! 		  case 'R':
! 		    done = is_pointer = 1;
! 		    break;
! 		  case 'C':	/* const */
! 		  case 'S':	/* explicitly signed [char] */
! 		  case 'U':	/* unsigned */
! 		  case 'V':	/* volatile */
! 		  case 'F':	/* function */
! 		  case 'M':	/* member function */
! 		  case 'O':	/* ??? */
! 		    old_p++;
! 		    continue;
! 		  case 'Q':	/* qualified name */
!                     done = is_integral = 1;
!                     break;
! 		  case 'T':	/* remembered type */
! 		    abort ();
! 		    break;
! 		  case 'v':	/* void */
! 		    abort ();
! 		    break;
! 		  case 'x':	/* long long */
! 		  case 'l':	/* long */
! 		  case 'i':	/* int */
! 		  case 's':	/* short */
! 		  case 'w':	/* wchar_t */
! 		    done = is_integral = 1;
! 		    break;
! 		  case 'c':	/* char */
! 		    done = is_char = 1;
! 		    break;
! 		  case 'r':	/* long double */
! 		  case 'd':	/* double */
! 		  case 'f':	/* float */
! 		    done = is_real = 1;
! 		    break;
! 		  default:
! 		    /* it's probably user defined type, let's assume
! 		       it's integeral, it seems hard to figure out
! 		       what it really is */
! 		    done = is_integral = 1;
! 		}
! 	    }
! 	  if (is_integral)
! 	    {
! 	      if (**mangled == 'm')
! 		{
! 		  string_appendn (tname, "-", 1);
! 		  (*mangled)++;
! 		}
! 	      while (isdigit (**mangled))	
! 		{
! 		  string_appendn (tname, *mangled, 1);
! 		  (*mangled)++;
! 		}
! 	    }
! 	  else if (is_char)
! 	    {
!             char tmp[2];
!             int val;
!               if (**mangled == 'm')
!                 {
!                   string_appendn (tname, "-", 1);
!                   (*mangled)++;
!                 }
! 	      string_appendn (tname, "'", 1);
!               val = consume_count(mangled);
! 	      if (val == 0)
! 		{
! 		  success = 0;
! 		  break;
!                 }
!               tmp[0] = (char)val;
!               tmp[1] = '\0';
!               string_appendn (tname, &tmp[0], 1);
! 	      string_appendn (tname, "'", 1);
! 	    }
! 	  else if (is_real)
! 	    {
! 	      if (**mangled == 'm')
! 		{
! 		  string_appendn (tname, "-", 1);
! 		  (*mangled)++;
! 		}
! 	      while (isdigit (**mangled))	
! 		{
! 		  string_appendn (tname, *mangled, 1);
! 		  (*mangled)++;
! 		}
! 	      if (**mangled == '.') /* fraction */
! 		{
! 		  string_appendn (tname, ".", 1);
! 		  (*mangled)++;
! 		  while (isdigit (**mangled))	
! 		    {
! 		      string_appendn (tname, *mangled, 1);
! 		      (*mangled)++;
! 		    }
! 		}
! 	      if (**mangled == 'e') /* exponent */
! 		{
! 		  string_appendn (tname, "e", 1);
! 		  (*mangled)++;
! 		  while (isdigit (**mangled))	
! 		    {
! 		      string_appendn (tname, *mangled, 1);
! 		      (*mangled)++;
! 		    }
! 		}
! 	    }
! 	  else if (is_pointer)
  	    {
! 	      if (!get_count (mangled, &symbol_len))
! 		{
! 		  success = 0;
! 		  break;
! 		}
! 	      string_appendn (tname, *mangled, symbol_len);
! 	      *mangled += symbol_len;
  	    }
  	}
        need_comma = 1;
--- 1028,1050 ----
  	{
  	  /* otherwise, value parameter */
  	  old_p  = *mangled;
  	  /* temp is initialized in do_type */
  	  success = do_type (work, mangled, &temp);
! #if 0
  	  if (success)
  	    {
  	      string_appends (tname, &temp);
  	    }
! #endif
  	  string_delete(&temp);
  	  if (!success)
  	    {
  	      break;
  	    }
! 	  success = do_value(tname, &old_p, mangled);
! 	  if (!success)
  	    {
! 	      break;
  	    }
  	}
        need_comma = 1;
***************
*** 1039,1045 ****
      string_append (tname, " ");
    string_append (tname, ">");
    
! /*
        if (work -> static_type)
  	{
  	  string_append (declp, *mangled + 1);
--- 1053,1059 ----
      string_append (tname, " ");
    string_append (tname, ">");
    
! #if 0
        if (work -> static_type)
  	{
  	  string_append (declp, *mangled + 1);
***************
*** 1051,1057 ****
  	  success = demangle_args (work, mangled, declp);
  	}
      }
! */
    return (success);
  }
  
--- 1065,1071 ----
  	  success = demangle_args (work, mangled, declp);
  	}
      }
! #endif
    return (success);
  }
  
***************
*** 1071,1076 ****
--- 1085,1093 ----
          if (*args + len == mangled + n && **args == '_')
  	  {
  	    ++*args;
+ 	    /* Arm mangling, template expression formal */
+ 	    if (**args == 'X')
+ 	      ++*args;
  	    return 1;
  	  }
      }
***************
*** 1098,1104 ****
      /* should do error checking here */
      while (args < e) {
        string_clear (&arg);
!       do_type (work, &args, &arg);
        string_appends (declp, &arg);
        string_append (declp, ",");
      }
--- 1115,1136 ----
      /* should do error checking here */
      while (args < e) {
        string_clear (&arg);
!       p = args;
!       if (!do_type (work, &args, &arg))
! 	{
! 	  fprintf (stderr, "\nBad arm template type argument %s\n", p);
! 	  break;
! 	}
!       /* arm literal argument */
!       if (*args == 'L')
! 	{
! 	  ++args;
! 	  if (!do_value (&arg, &p, &args))
! 	    {
! 	      fprintf (stderr, "\nBad arm template literal argument %s\n", p);
! 	      break;
! 	    }
!         } 
        string_appends (declp, &arg);
        string_append (declp, ",");
      }
***************
*** 2017,2026 ****
  
  	case 'C':
  	  (*mangled)++;
! /*
  	  if ((*mangled)[1] == 'P')
  	    {
! */
  	      if (PRINT_ANSI_QUALIFIERS)
  		{
  		  if (!STRING_EMPTY (&decl))
--- 2049,2058 ----
  
  	case 'C':
  	  (*mangled)++;
! #if 0
  	  if ((*mangled)[1] == 'P')
  	    {
! #endif
  	      if (PRINT_ANSI_QUALIFIERS)
  		{
  		  if (!STRING_EMPTY (&decl))
***************
*** 2030,2038 ****
  		  string_prepend (&decl, "const");
  		}
  	      break;
! /*
  	    }
! */
  
  	  /* fall through */
  	default:
--- 2062,2070 ----
  		  string_prepend (&decl, "const");
  		}
  	      break;
! #if 0
  	    }
! #endif
  
  	  /* fall through */
  	default: