Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: DJBARROW@de.ibm.com
To: gdb-patches@sourceware.cygnus.com, s390-patches@gnu.org,
	Binutils Patches <binutils@sourceware.cygnus.com>,
	bash_maintainers@gnu.org
Cc: schwidefsky@de.ibm.com, ARENZ@de.ibm.com
Subject: New gdb 31 & 64 bit patches for S/390
Date: Tue, 27 Feb 2001 12:39:00 -0000	[thread overview]
Message-ID: <C1256A00.006F3FCE.00@d12mta09.de.ibm.com> (raw)

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1219 bytes --]

Hi All,

Here are the latest gdb patches for S/390, they are against yesterdays
repository ( Feb 26th )
I have spent a lot of time reworking the stuff to get it down to as few
files as possible,
& addressing issues brought up on previous submissions
( a hell of a lot more time than the 64 bit port took :-) ).
& hope it is accepted this time.

The only thing I'm aware of which isn't working properly
is gdb /boot/vmlinux /proc/kcore
when compiled for multiarch

This is because the bfd stuff returns
bfd_arch_unknown

& set_gdbarch_from_file complains because gdbarch_update_p can't fix up
this,
 this however is quite normal for the /proc/kcore file even when compiled
without multi-arch,
the code works fine when compiled without multi-arch.


(See attached file: gdb.s390.270201.binutils.config.diff)(See attached
file: gdb.s390.270201.config.diff)(See attached file:
gdb.s390.270201.core.diff)(See attached file:
gdb.s390.270201.readline.config.diff)(See attached file: S390ChangeLog.gdb)
(See attached file: S390ChangeLog.Root)

D.J. Barrow Gnu/Linux for S/390 kernel developer
eMail: djbarrow@de.ibm.com,barrow_dj@yahoo.com
Phone: +49-(0)7031-16-2583
IBM Germany Lab, Schönaicherstr. 220, 71032 Böblingen

[-- Attachment #2: gdb.s390.270201.binutils.config.diff --]
[-- Type: text/x-diff, Size: 402 bytes --]

--- src.orig/bfd/configure.in	Thu Feb 22 17:38:45 2001
+++ src.new/bfd/configure.in	Mon Feb 26 19:03:16 2001
@@ -151,6 +151,7 @@
   hppa*-*-mpeix*)	COREFILE=hpux-core.lo ;;
   hppa*-*-bsd*)		COREFILE="hpux-core.lo hppabsd-core.lo"
 			COREFLAG="-DHPUX_CORE -DHPPABSD_CORE" ;;
+  s390*-*-*)            COREFILE=trad-core.lo ;;	
   i370-*-*)		
 	COREFILE=trad-core.lo
 	TRAD_HEADER='"hosts/i370linux.h"'

[-- Attachment #3: gdb.s390.270201.config.diff --]
[-- Type: text/x-diff, Size: 1302 bytes --]

--- src.orig/config.sub	Sat Feb 10 01:55:46 2001
+++ src.new/config.sub	Mon Feb 26 17:57:37 2001
@@ -740,6 +740,12 @@
 	rtpc | rtpc-*)
 		basic_machine=romp-ibm
 		;;
+	s390 | s390-* )
+		basic_machine=s390-ibm
+		;;
+	s390x | s390x-* )
+		basic_machine=s390x-ibm
+		;;
 	sa29200)
 		basic_machine=a29k-amd
 		os=-udi
--- src.orig/gdb/configure.host	Thu Feb  8 07:30:23 2001
+++ src.new/gdb/configure.host	Mon Feb 26 17:57:37 2001
@@ -18,6 +18,7 @@
 m88*)			gdb_host_cpu=m88k ;;
 powerpc*)		gdb_host_cpu=powerpc ;;
 sparc64)		gdb_host_cpu=sparc ;;
+s390*)                  gdb_host_cpu=s390 ;;
 *)			gdb_host_cpu=$host_cpu ;;
 
 esac
@@ -158,5 +159,10 @@
 vax-*-bsd*)		gdb_host=vaxbsd ;;
 vax-*-ultrix2*)		gdb_host=vaxult2 ;;
 vax-*-ultrix*)		gdb_host=vaxult ;;
-
+s390*-*-*)               gdb_host=s390 ;;
 esac
+
+
+
+
+
--- src.orig/gdb/configure.tgt	Thu Feb  8 07:30:23 2001
+++ src.new/gdb/configure.tgt	Mon Feb 26 17:57:37 2001
@@ -26,6 +26,7 @@
 strongarm*)		gdb_target_cpu=arm ;;
 xscale*)		gdb_target_cpu=arm ;;
 v850*)			gdb_target_cpu=v850 ;;
+s390*)                  gdb_target_cpu=s390 ;;
 *)			gdb_target_cpu=$target_cpu ;;
 
 esac
@@ -305,6 +306,8 @@
 
 z8k-*-coff*)		gdb_target=z8k ;;
 
+s390-*-*)               gdb_target=s390 ;;
+s390x-*-*)              gdb_target=s390x ;;
 esac
 
 

[-- Attachment #4: gdb.s390.270201.core.diff --]
[-- Type: text/x-diff, Size: 78499 bytes --]

diff -u -r -N src.orig/gdb/config/s390/nm-linux.h src.new/gdb/config/s390/nm-linux.h
--- src.orig/gdb/config/s390/nm-linux.h	Thu Jan  1 01:00:00 1970
+++ src.new/gdb/config/s390/nm-linux.h	Mon Feb 26 17:57:49 2001
@@ -0,0 +1,107 @@
+/* Native support for Linux for S390
+   
+   Copyright 1986, 1987, 1989, 1992, 1996, 1998, 2000
+   Free Software Foundation, Inc.
+   Ported by D.J. Barrow for IBM Deutschland Entwicklung GmbH, IBM Corporation.
+   derived from i390-nmlinux.h
+   This file is part of GDB.
+
+   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 of the License, 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.
+
+   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., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef NM_LINUX_H
+#define NM_LINUX_H
+
+#include "config/nm-linux.h"
+
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+	(addr) = s390_register_u_addr((blockend),(regno));
+extern int s390_register_u_addr (int, int);
+
+/* Return sizeof user struct to callers in less machine dependent routines */
+
+#define KERNEL_U_SIZE kernel_u_size()
+extern int kernel_u_size (void);
+
+#define U_REGS_OFFSET 0
+
+
+/* We define this if link.h is available, because with ELF we use SVR4 style
+   shared libraries. */
+
+#ifdef HAVE_LINK_H
+#define SVR4_SHARED_LIBS
+#include "solib.h"		/* Support for shared libraries. */
+#endif
+
+
+/* WATCHPOINT SPECIFIC STUFF */
+
+#define TARGET_HAS_HARDWARE_WATCHPOINTS
+#define HAVE_CONTINUABLE_WATCHPOINT
+#define HAVE_STEPPABLE_WATCHPOINT
+#define target_insert_watchpoint(addr, len, type)  \
+  s390_insert_watchpoint (inferior_pid, addr, len, type)
+
+#define target_remove_watchpoint(addr, len, type)  \
+  s390_remove_watchpoint (inferior_pid, addr, len)
+
+extern int watch_area_cnt;
+/* gdb if really stupid & calls this all the time without a
+   watchpoint even being set */
+#define STOPPED_BY_WATCHPOINT(W)  \
+  (watch_area_cnt&&s390_stopped_by_watchpoint (inferior_pid))
+
+extern CORE_ADDR s390_stopped_by_watchpoint (int);
+
+/*
+  Type can be 1 for a read_watchpoint or 2 for an access watchpoint.
+ */
+extern int s390_insert_watchpoint (int pid, CORE_ADDR addr, int len, int rw);
+extern int s390_remove_watchpoint (int pid, CORE_ADDR addr, int len);
+#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(type, cnt, ot) \
+	 (((type) == bp_hardware_watchpoint)|| \
+	 ((type) == bp_watchpoint)|| \
+	 ((type) == bp_read_watchpoint) || \
+         ((type) == bp_access_watchpoint))
+
+
+/* FIXME: kettenis/2000-09-03: This should be moved to ../nm-linux.h
+   once we have converted all Linux targets to use the new threads
+   stuff (without the #undef of course).  */
+#undef PREPARE_TO_PROCEED
+
+/* Set to 1 if post 5.0 */
+#if 1
+extern int lin_lwp_prepare_to_proceed (void);
+#define PREPARE_TO_PROCEED(select_it) lin_lwp_prepare_to_proceed ()
+#else
+extern int linuxthreads_prepare_to_proceed (int step);
+#define PREPARE_TO_PROCEED(select_it) linuxthreads_prepare_to_proceed (select_it)
+#endif
+
+
+extern void lin_lwp_attach_lwp (int pid, int verbose);
+#define ATTACH_LWP(pid, verbose) lin_lwp_attach_lwp ((pid), (verbose))
+
+#include <signal.h>
+
+extern void lin_thread_get_thread_signals (sigset_t * mask);
+#define GET_THREAD_SIGNALS(mask) lin_thread_get_thread_signals (mask)
+
+/* Needed for s390x */
+#define PTRACE_ARG3_TYPE long
+#define PTRACE_XFER_TYPE long
+#endif /* nm_linux.h */
diff -u -r -N src.orig/gdb/config/s390/s390.mh src.new/gdb/config/s390/s390.mh
--- src.orig/gdb/config/s390/s390.mh	Thu Jan  1 01:00:00 1970
+++ src.new/gdb/config/s390/s390.mh	Mon Feb 26 17:57:49 2001
@@ -0,0 +1,14 @@
+# Host: S390, running Linux
+
+XM_FILE= xm-linux.h
+XDEPFILES= 
+XM_CLIBS=
+
+NAT_FILE= nm-linux.h
+#NATDEPFILES= infptrace.o solib.o inftarg.o fork-child.o corelow.o \
+#	   s390-nat.o linux-thread.o core-aout.o core-regset.o
+# post 5.0 natdepfiles.
+NATDEPFILES= infptrace.o solib.o inftarg.o fork-child.o corelow.o \
+	   s390-nat.o thread-db.o lin-lwp.o proc-service.o \
+          core-aout.o core-regset.o solib-svr4.o 
+LOADLIBES = -ldl -rdynamic
diff -u -r -N src.orig/gdb/config/s390/s390.mt src.new/gdb/config/s390/s390.mt
--- src.orig/gdb/config/s390/s390.mt	Thu Jan  1 01:00:00 1970
+++ src.new/gdb/config/s390/s390.mt	Mon Feb 26 17:57:49 2001
@@ -0,0 +1,4 @@
+# Target: S390 running Linux
+TM_FILE= tm-linux.h
+TDEPFILES=s390-tdep.o
+GDB_MULTI_ARCH=2
diff -u -r -N src.orig/gdb/config/s390/s390x.mt src.new/gdb/config/s390/s390x.mt
--- src.orig/gdb/config/s390/s390x.mt	Thu Jan  1 01:00:00 1970
+++ src.new/gdb/config/s390/s390x.mt	Mon Feb 26 17:57:49 2001
@@ -0,0 +1,5 @@
+# Target: S390x running Linux
+TM_FILE= tm-linux.h
+MT_CFLAGS= -DCONFIG_ARCH_S390X
+TDEPFILES=s390-tdep.o
+GDB_MULTI_ARCH=2
diff -u -r -N src.orig/gdb/config/s390/tm-linux.h src.new/gdb/config/s390/tm-linux.h
--- src.orig/gdb/config/s390/tm-linux.h	Thu Jan  1 01:00:00 1970
+++ src.new/gdb/config/s390/tm-linux.h	Mon Feb 26 17:57:49 2001
@@ -0,0 +1,66 @@
+/* Target definitions for GDB for a s390 running Linux.
+   Copyright (C) 1999-2001 Free Software Foundation, Inc.
+   Contributed by D.J. Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
+   for IBM Deutschland Entwicklung GmbH, IBM Corporation.
+
+   This file is part of GDB.
+
+   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 of the License, 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.
+
+   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., 59 Temple Place - Suite 330, Boston, MA
+   02111-1307, USA.  */
+
+#ifndef TM_LINUX_H
+#define TM_LINUX_H
+#include "config/tm-linux.h"
+#include "s390/tm-s390.h"
+
+
+#define S390_SIGNAL_FRAMESIZE  (GDB_TARGET_IS_ESAME ? 160:96)
+#define s390_NR_sigreturn          119
+#define s390_NR_rt_sigreturn       173
+#define S390_SIGCONTEXT_NSIG      64
+#define S390_SIGCONTEXT_NSIG_BPW  32
+/* Size of stack frame allocated when calling signal handler. */
+#define S390_SIGCONTEXT_NSIG_WORDS	(S390_SIGCONTEXT_NSIG / S390_SIGCONTEXT_NSIG_BPW)
+
+
+typedef struct
+{
+  __s390_regs_common regs;
+  __s390_fp_regs fpregs;
+}
+s390_sigregs;
+
+typedef struct
+{
+  __u32 oldmask[S390_SIGCONTEXT_NSIG_WORDS];
+  s390_sigregs *sregs;
+}
+s390_sigcontext;
+
+typedef struct
+{
+  __s390x_regs_common regs;
+  __s390_fp_regs fpregs;
+}
+s390x_sigregs;
+
+typedef struct
+{
+  __u32 oldmask[S390_SIGCONTEXT_NSIG_WORDS];
+  s390x_sigregs *sregs;
+}
+s390x_sigcontext;
+
+#endif /* TM_LINUX_H */
diff -u -r -N src.orig/gdb/config/s390/tm-s390.h src.new/gdb/config/s390/tm-s390.h
--- src.orig/gdb/config/s390/tm-s390.h	Thu Jan  1 01:00:00 1970
+++ src.new/gdb/config/s390/tm-s390.h	Tue Feb 27 16:47:03 2001
@@ -0,0 +1,390 @@
+/* Macro definitions for GDB on an S390.
+   Copyright (C) 1999-2001 Free Software Foundation, Inc.
+   Contributed by D.J. Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
+   for IBM Deutschland Entwicklung GmbH, IBM Corporation.
+
+   This file is part of GDB.
+   
+   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 of the License, 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.
+
+   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., 59 Temple Place - Suite 330, Boston, MA
+   02111-1307, USA.  */
+
+#if !defined(TM_S390_H)
+#define TM_S390_H 1
+#include <asm/types.h>
+#if GDB_MULTI_ARCH
+#define GDB_TARGET_IS_ESAME (TARGET_ARCHITECTURE->mach == bfd_mach_s390_esame)
+#else
+#if CONFIG_ARCH_S390X
+#define GDB_TARGET_IS_ESAME (1)
+#else
+#define GDB_TARGET_IS_ESAME (0)
+#endif /* CONFIG_ARCH_S390X */
+#endif /* GDB_MULTI_ARCH */
+
+#if defined(S390_TDEP) && GDB_MULTI_ARCH
+#define S390_REGISTER_SIZE REGISTER_SIZE
+#else
+#if CONFIG_ARCH_S390X
+#define S390_REGISTER_SIZE  (8)
+#else
+#define S390_REGISTER_SIZE  (4)
+#endif /* CONFIG_ARCH_S390X */
+#endif /* defined(S390_TDEP) && GDB_MULTI_ARCH */
+
+
+#define S390_STACK_FRAME_OVERHEAD  (GDB_TARGET_IS_ESAME ? 160:96)
+#define S390_NUM_GPRS      (16)
+#define S390_GPR_SIZE      S390_REGISTER_SIZE
+#define S390_PSW_MASK_SIZE S390_REGISTER_SIZE
+#define S390_PSW_ADDR_SIZE S390_REGISTER_SIZE
+#define S390_NUM_FPRS      (16)
+#define S390_FPR_SIZE      (8)
+#define S390_FPC_SIZE      (4)
+#define S390_FPC_PAD_SIZE  (4)	/* gcc insists on aligning the fpregs */
+#define S390_NUM_CRS       (16)
+#define S390_CR_SIZE       S390_REGISTER_SIZE
+#define S390_NUM_ACRS      (16)
+#define S390_ACR_SIZE      (4)
+
+#define S390_ACR0_OFFSET ((S390_PSW_MASK_SIZE+S390_PSW_ADDR_SIZE)+(S390_GPR_SIZE*S390_NUM_GPRS))
+#define S390_CR0_OFFSET (S390_ACR0_OFFSET+(S390_ACR_SIZE+S390_NUM_ACRS))
+#define S390_FPC_OFFSET (S390_CR0_OFFSET+(S390_CR_SIZE*S390_NUM_CRS))
+#define S390_FP0_OFFSET (S390_FPC_OFFSET+(S390_FPC_SIZE+S390_FPC_PAD_SIZE))
+#define S390_GPR6_STACK_OFFSET (GDB_TARGET_IS_ESAME ? 48:24)
+
+typedef struct
+{
+  __u32 mask;
+  __u32 addr;
+} s390_psw_t __attribute__ ((aligned (8)));
+
+typedef struct
+{
+  __u64 mask;
+  __u64 addr;
+} s390x_psw_t __attribute__ ((aligned (8)));
+
+
+typedef union
+{
+  struct
+  {
+    __u32 hi;
+    __u32 lo;
+  }
+  fp;
+  __u32 f;
+} s390_freg_t;
+
+typedef struct
+{
+  /* The compiler appears to like aligning freg_t on an 8 byte boundary
+     so I always access fpregs, this was causing fun when I was doing
+     coersions. */
+  __u32 fpc;
+  s390_freg_t fprs[S390_NUM_FPRS];
+} __s390_fp_regs;
+
+/* gdb structures & the kernel have this much always in common */
+#define __S390_REGS_COMMON     \
+s390_psw_t psw;                \
+__u32 gprs[S390_NUM_GPRS];     \
+__u32  acrs[S390_NUM_ACRS];
+
+#define __S390X_REGS_COMMON    \
+s390x_psw_t psw;               \
+__u64 gprs[S390_NUM_GPRS];     \
+__u32  acrs[S390_NUM_ACRS];
+
+
+typedef struct
+{
+__S390_REGS_COMMON
+} __s390_regs_common;
+
+typedef struct
+{
+__S390X_REGS_COMMON
+} __s390x_regs_common;
+
+
+
+/* Sequence of bytes for breakpoint illegal instruction.  */
+#define S390_BREAKPOINT {0x0,0x1}
+#define S390_BREAKPOINT_U16 ((__u16)0x0001)
+#define S390_SYSCALL_OPCODE ((__u16)0x0a00)
+#define S390_SYSCALL_SIZE   2
+
+#define S390_MAX_INSTR_SIZE 6
+#define S390_NUM_REGS      (2+S390_NUM_GPRS+S390_NUM_ACRS+S390_NUM_CRS+1+S390_NUM_FPRS)
+#define S390_FIRST_ACR     (2+S390_NUM_GPRS)
+#define S390_LAST_ACR      (S390_FIRST_ACR+S390_NUM_ACRS-1)
+#define S390_FIRST_CR      (S390_FIRST_ACR+S390_NUM_ACRS)
+#define S390_LAST_CR       (S390_FIRST_CR+S390_NUM_CRS-1)
+
+#define S390_PSWM_REGNUM    0
+#define S390_PC_REGNUM      1
+#define	S390_GP0_REGNUM     2	/* GPR register 0 */
+#define S390_GP_LAST_REGNUM (S390_GP0_REGNUM+S390_NUM_GPRS-1)
+/* Usually return address */
+#define S390_RETADDR_REGNUM (S390_GP0_REGNUM+14)
+/* Contains address of top of stack */
+#define S390_SP_REGNUM      (S390_GP0_REGNUM+15)
+/* needed in findvar.c still */	
+#define S390_FP_REGNUM     S390_SP_REGNUM	
+#define S390_FRAME_REGNUM  (S390_GP0_REGNUM+11)
+#define S390_FPC_REGNUM    (S390_GP0_REGNUM+S390_NUM_GPRS+S390_NUM_ACRS+S390_NUM_CRS)
+/* FPR (Floating point) register 0 */
+#define S390_FP0_REGNUM    (S390_FPC_REGNUM+1)
+/* Last floating point register */	
+#define S390_FPLAST_REGNUM (S390_FP0_REGNUM+S390_NUM_FPRS-1)	
+#define S390_LAST_REGNUM   S390_FPLAST_REGNUM
+
+/* The top of this structure is as similar as possible to a 
+   pt_regs structure to simplify code */
+typedef struct
+{
+  __S390_REGS_COMMON 
+  __u32 crs[S390_NUM_CRS];
+  __s390_fp_regs fp_regs;
+} s390_gdb_regs __attribute__ ((packed));
+
+typedef struct
+{
+  __S390X_REGS_COMMON 
+  __u64 crs[S390_NUM_CRS];
+  __s390_fp_regs fp_regs;
+} s390x_gdb_regs __attribute__ ((packed));
+
+
+#define S390_REGISTER_NAMES                                      \
+{                                                                \
+"pswm","pswa",                                                   \
+"gpr0","gpr1","gpr2","gpr3","gpr4","gpr5","gpr6","gpr7",         \
+"gpr8","gpr9","gpr10","gpr11","gpr12","gpr13","gpr14","gpr15",   \
+"acr0","acr1","acr2","acr3","acr4","acr5","acr6","acr7",         \
+"acr8","acr9","acr10","acr11","acr12","acr13","acr14","acr15",   \
+"cr0","cr1","cr2","cr3","cr4","cr5","cr6","cr7",                 \
+"cr8","cr9","cr10","cr11","cr12","cr13","cr14","cr15",           \
+"fpc",                                                           \
+"fpr0","fpr1","fpr2","fpr3","fpr4","fpr5","fpr6","fpr7",         \
+"fpr8","fpr9","fpr10","fpr11","fpr12","fpr13","fpr14","fpr15"    \
+}
+
+
+/* instruction sequence for call dummy is as follows
+   bras %r1,.+8      ; 0xA7150004   
+   long basraddr     ; 0x00000000
+   l    %r1,0(%r1)   ; 0x58101000
+   basr %r14,%r1     ; 0x0DE1
+   breakpoint        ; 0x0001 */
+#define S390_CALL_DUMMY {0xA7150004,0x00000000,0x58101000,0x0DE10000|S390_BREAKPOINT_U16}
+#define S390_CALL_DUMMY_LENGTH 16
+#define S390_CALL_ADDR_OFFSET  4
+
+
+/* instruction sequence for call dummy is as follows
+   bras %r1,.+12     ; 0xA7150006   
+   long basraddr     ; 0x0000000000000000
+   lg   %r1,0(%r1)   ; 0xE31010000004
+   basr %r14,%r1     ; 0x0DE1
+   breakpoint        ; 0x0001 */
+
+#define S390X_CALL_DUMMY {0xA715000600000000,0x00000000E3101000, \
+0x00040DE100000000|S390_BREAKPOINT_U16<<16}
+#define S390X_CALL_DUMMY_LENGTH 22
+
+#define S390_REGISTER_BYTES    \
+((S390_FP0_OFFSET)+(S390_FPR_SIZE*S390_NUM_FPRS))
+
+
+#if !GDB_MULTI_ARCH
+#if CONFIG_ARCH_S390X
+#define CALL_DUMMY         S390X_CALL_DUMMY
+#define CALL_DUMMY_LENGTH  S390X_CALL_DUMMY_LENGTH
+int s390x_register_raw_size (int reg_nr);
+#define REGISTER_RAW_SIZE(reg_nr) s390x_register_raw_size(reg_nr)
+
+struct type *s390x_register_virtual_type (int regno);
+#define REGISTER_VIRTUAL_TYPE(regno) s390x_register_virtual_type(regno)
+
+#define TARGET_LONG_BIT (8 * TARGET_CHAR_BIT)
+#define TARGET_LONG_LONG_BIT (TARGET_LONG_BIT)
+#define TARGET_PTR_BIT (TARGET_LONG_BIT)
+#else
+#define CALL_DUMMY         S390_CALL_DUMMY
+#define CALL_DUMMY_LENGTH  S390_CALL_DUMMY_LENGTH
+int s390_register_raw_size (int reg_nr);
+#define REGISTER_RAW_SIZE(reg_nr) s390_register_raw_size(reg_nr)
+
+struct type *s390_register_virtual_type (int regno);
+#define REGISTER_VIRTUAL_TYPE(regno) s390_register_virtual_type(regno)
+#define ADDR_BITS_REMOVE(addr) ((addr)&0x7fffffff)
+
+#endif /* CONFIG_ARCH_S390X */
+#define BELIEVE_PCC_PROMOTION 0
+#define USE_GENERIC_DUMMY_FRAMES 0
+#define CALL_DUMMY_LOCATION ON_STACK
+#define CALL_DUMMY_START_OFFSET 0
+
+#define REGISTER_BYTES   S390_REGISTER_BYTES
+#define PC_REGNUM        S390_PC_REGNUM
+#define SP_REGNUM        S390_SP_REGNUM
+#define FP_REGNUM        S390_FP_REGNUM
+#define FP0_REGNUM       S390_FP0_REGNUM
+#define NUM_REGS         S390_NUM_REGS
+#define NUM_FPRS         S390_NUM_FPRS
+#define FP0_OFFSET       S390_FP0_OFFSET
+#define FPR_SIZE         S390_FPR_SIZE
+#define REGISTER_SIZE    S390_REGISTER_SIZE
+
+#define REGISTER_VIRTUAL_SIZE(reg_nr) REGISTER_RAW_SIZE(reg_nr)
+
+#define TARGET_BYTE_ORDER BIG_ENDIAN
+
+/* Used for example in valprint.c:print_floating() to enable checking
+   for NaN's */
+#define IEEE_FLOAT (1)
+
+/* Offset from address of function to start of its code.
+   Zero on most machines.  */
+#define FUNCTION_START_OFFSET 0
+
+/* Stack grows downward.  */
+#define INNER_THAN(lhs,rhs) ((lhs) < (rhs))
+
+/* Largest value REGISTER_RAW_SIZE can have.  */
+#define MAX_REGISTER_RAW_SIZE 8
+
+/* Largest value REGISTER_VIRTUAL_SIZE can have.  */
+#define MAX_REGISTER_VIRTUAL_SIZE 8
+
+#define BREAKPOINT S390_BREAKPOINT
+/* Amount PC must be decremented by after a breakpoint.
+   This is often the number of bytes in BREAKPOINT
+   but not always.  */
+#define DECR_PC_AFTER_BREAK 2
+
+void s390_pop_frame (void);
+#define POP_FRAME	s390_pop_frame()
+
+void s390_push_dummy_frame (void);
+#define PUSH_DUMMY_FRAME	s390_push_dummy_frame()
+
+struct value;
+
+CORE_ADDR s390_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
+			       int struct_return, CORE_ADDR struct_addr);
+#define	PUSH_ARGUMENTS(nargs, args, sp, struct_return, struct_addr) \
+  sp = s390_push_arguments((nargs), (args), (sp), (struct_return), (struct_addr))
+
+int s390_pc_in_call_dummy (CORE_ADDR pc, CORE_ADDR sp,
+			   CORE_ADDR frame_address);
+#define PC_IN_CALL_DUMMY(pc, sp, frame_address) \
+s390_pc_in_call_dummy(pc,sp,frame_address)
+
+void s390_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun,
+			  int nargs, struct value **args,
+			  struct type *value_type, int using_gcc);
+#define FIX_CALL_DUMMY(dummy, pc, fun, nargs, args, value_type, using_gcc) \
+s390_fix_call_dummy(dummy,pc,fun,nargs,args,value_type,using_gcc);
+
+
+void s390_store_struct_return (CORE_ADDR addr, CORE_ADDR sp);
+#define STORE_STRUCT_RETURN(addr,sp) \
+s390_store_struct_return(addr,sp);
+
+/* Return number of bytes at start of arglist that are not really args.  */
+#define FRAME_ARGS_SKIP 0
+
+CORE_ADDR s390_skip_prologue (CORE_ADDR pc);
+#define SKIP_PROLOGUE(pc) s390_skip_prologue(pc);
+
+CORE_ADDR s390_frame_args_address (struct frame_info *fi);
+#define FRAME_ARGS_ADDRESS(fi) s390_frame_args_address(fi)
+
+#define FRAME_LOCALS_ADDRESS(fi)	FRAME_ARGS_ADDRESS(fi)
+#define FRAME_NUM_ARGS(fi) (-1)	/* We can't do this */
+void s390_extract_return_value (struct type *valtype, char *regbuf,
+				char *valbuf);
+#define EXTRACT_RETURN_VALUE(valtype,regbuf,valbuf) \
+  s390_extract_return_value(valtype,regbuf,valbuf)
+
+void s390_store_return_value (struct type *valtype, char *valbuf);
+#define STORE_RETURN_VALUE(valtype,valbuf) \
+ s390_store_return_value(valtype,valbuf)
+
+/* Return saved PC from a frame */
+CORE_ADDR s390_frame_saved_pc (struct frame_info *fi);
+#define FRAME_SAVED_PC(fi) s390_frame_saved_pc(fi)
+
+/* FRAME_CHAIN takes a frame's nominal address
+   and produces the frame's chain-pointer. */
+CORE_ADDR s390_frame_chain (struct frame_info *thisframe);
+#define FRAME_CHAIN(thisframe) s390_frame_chain(thisframe)
+
+/* Immediately after a function call, return the saved pc.
+   Can't go through the frames for this because on some machines
+   the new frame is not set up until the new function executes
+   some instructions.  */
+CORE_ADDR s390_saved_pc_after_call (struct frame_info *frame);
+#define	SAVED_PC_AFTER_CALL(frame) s390_saved_pc_after_call(frame)
+
+void s390_write_fp (CORE_ADDR val);
+#define TARGET_WRITE_FP(val) s390_write_fp(val)
+
+CORE_ADDR s390_read_fp ();
+#define TARGET_READ_FP()   s390_read_fp()
+
+void s390_frame_init_saved_regs (struct frame_info *fi);
+#define FRAME_INIT_SAVED_REGS(fi) s390_frame_init_saved_regs(fi);
+
+void s390_init_frame_pc_first (int next_fromleaf, struct frame_info *fi);
+#define	INIT_FRAME_PC_FIRST(fromleaf, fi) s390_init_frame_pc_first((fromleaf),(fi))
+
+void s390_init_extra_frame_info (int fromleaf, struct frame_info *fi);
+#define	INIT_EXTRA_FRAME_INFO(fromleaf, fi) s390_init_extra_frame_info((fromleaf),(fi))
+
+/* 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.  */
+int s390_frameless_function_invocation (struct frame_info *fi);
+#define FRAMELESS_FUNCTION_INVOCATION(fi) \
+  s390_frameless_function_invocation(fi)
+
+/* Obviously ptrace for user program tracing cannot be allowed
+  mess with control registers (except per registers for hardware watchpoints),
+  when we add kernel debugging we may need to alter these macros. */
+int s390_cannot_fetch_register (int regno);
+#define CANNOT_FETCH_REGISTER(regno) s390_cannot_fetch_register(regno)
+#define CANNOT_STORE_REGISTER(regno) s390_cannot_fetch_register(regno)
+
+int s390_register_byte (int reg_nr);
+#define REGISTER_BYTE(reg_nr) s390_register_byte(reg_nr)
+
+
+char *s390_register_name (int reg_nr);
+#define REGISTER_NAME(reg_nr) s390_register_name(reg_nr)
+
+int s390_stab_reg_to_regnum (int regno);
+#define STAB_REG_TO_REGNUM(regno) \
+s390_stab_reg_to_regnum(regno)
+#define DWARF_REG_TO_REGNUM(regno) STAB_REG_TO_REGNUM(regno)
+#define DWARF2_REG_TO_REGNUM(regno) STAB_REG_TO_REGNUM(regno)
+#endif /* !GDB_MULTI_ARCH */
+#endif /* ifndef TM_S390_H */
+
+
+
diff -u -r -N src.orig/gdb/config/s390/xm-linux.h src.new/gdb/config/s390/xm-linux.h
--- src.orig/gdb/config/s390/xm-linux.h	Thu Jan  1 01:00:00 1970
+++ src.new/gdb/config/s390/xm-linux.h	Mon Feb 26 17:57:49 2001
@@ -0,0 +1,38 @@
+/* Native support for GNU/Linux, for GDB, the GNU debugger.
+   Copyright (C) 1999-2001 Free Software Foundation, Inc.
+   Contributed by D.J. Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
+   for IBM Deutschland Entwicklung GmbH, IBM Corporation.
+
+   This file is part of GDB.
+
+   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 of the License, 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.
+
+   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., 59 Temple Place - Suite 330, Boston, MA
+   02111-1307, USA.  */
+
+#ifndef XM_LINUX_H
+#define XM_LINUX_H
+
+#define HOST_BYTE_ORDER BIG_ENDIAN
+
+
+/* This is the amount to subtract from u.u_ar0
+   to get the offset in the core file of the register values.  */
+#define KERNEL_U_ADDR 0x0
+
+#define NEED_POSIX_SETPGID
+
+/* Need R_OK etc, but USG isn't defined.  */
+#include <unistd.h>
+
+#endif /* #ifndef XM_LINUX_H */
--- /dev/null	Tue Jun  1 11:25:19 1999
+++ src.new/gdb/s390-nat.c	Tue Feb 27 16:46:54 2001
@@ -0,0 +1,292 @@
+/* S390 native-dependent code for GDB, the GNU debugger.
+   Copyright 1999-2001 Free Software Foundation, Inc
+   Contributed by D.J. Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
+   for IBM Deutschland Entwicklung GmbH, IBM Corporation.
+   This file is part of GDB.
+
+   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 of the License, 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.
+
+   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., 59 Temple Place - Suite 330, Boston, MA
+   02111-1307, USA.  */
+
+#include "defs.h"
+#include "tm.h"
+#include <asm/ptrace.h>
+#include <sys/ptrace.h>
+#include <asm/processor.h>
+#include <sys/procfs.h>
+#include <sys/user.h>
+#include <value.h>
+
+int
+s390_register_u_addr (int blockend, int regnum)
+{
+  int retval;
+
+  if (regnum >= S390_GP0_REGNUM && regnum <= S390_GP_LAST_REGNUM)
+    retval = PT_GPR0 + ((regnum - S390_GP0_REGNUM) * S390_GPR_SIZE);
+  else if (regnum >= S390_PSWM_REGNUM && regnum <= S390_PC_REGNUM)
+    retval = PT_PSWMASK + ((regnum - S390_PSWM_REGNUM) * S390_PSW_MASK_SIZE);
+  else if (regnum == S390_FPC_REGNUM)
+    retval = PT_FPC;
+  else if (regnum >= S390_FP0_REGNUM && regnum <= S390_FPLAST_REGNUM)
+    retval =
+#if CONFIG_ARCH_S390X
+      PT_FPR0
+#else
+      PT_FPR0_HI
+#endif
+      + ((regnum - S390_FP0_REGNUM) * S390_FPR_SIZE);
+  else if (regnum >= S390_FIRST_ACR && regnum <= S390_LAST_ACR)
+    retval = PT_ACR0 + ((regnum - S390_FIRST_ACR) * S390_ACR_SIZE);
+  else if (regnum >= (S390_FIRST_CR + 9) && regnum <= (S390_FIRST_CR + 11))
+    retval = PT_CR_9 + ((regnum - (S390_FIRST_CR + 9)) * S390_CR_SIZE);
+  else
+    {
+      error ("s390_register_u_addr invalid regnum %s %d regnum=%d", __FILE__,
+	     (int)__LINE__, regnum);
+      retval = 0;
+    }
+  return retval + blockend;
+}
+
+/* watch_areas are required if you put 2 or more watchpoints on the same 
+   address or overlapping areas gdb will call us to delete the watchpoint 
+   more than once when we try to delete them.
+   attempted reference counting to reduce the number of areas unfortunately
+   they didn't shrink when areas had to be split overlapping occurs. */
+struct watch_area;
+typedef struct watch_area watch_area;
+struct watch_area
+{
+  watch_area *next;
+  CORE_ADDR lo_addr;
+  CORE_ADDR hi_addr;
+};
+
+static watch_area *watch_base = NULL;
+int watch_area_cnt = 0;
+static CORE_ADDR watch_lo_addr = 0, watch_hi_addr = 0;
+
+
+
+CORE_ADDR s390_stopped_by_watchpoint (int pid)
+{
+  per_lowcore_bits per_lowcore;
+  ptrace_area parea;
+
+  parea.len = sizeof (per_lowcore);
+  parea.process_addr = (addr_t) & per_lowcore;
+  parea.kernel_addr = pt_off (per_info.lowcore);
+  ptrace (PTRACE_PEEKUSR_AREA, pid, &parea);
+  return ((per_lowcore.perc_storage_alteration == 1) &&
+	   (per_lowcore.perc_store_real_address == 0));
+}
+
+
+void
+s390_fix_watch_points (int pid)
+{
+  per_struct per_info;
+  ptrace_area parea;
+
+  parea.len = sizeof (per_info);
+  parea.process_addr = (addr_t) & per_info;
+  parea.kernel_addr = PT_CR_9;
+  ptrace (PTRACE_PEEKUSR_AREA, pid, &parea);
+  /* The kernel automatically sets the psw for per depending */
+  /* on whether the per control registers are set for event recording */
+  /* & sets cr9 & cr10 appropriately also */
+  if (watch_area_cnt)
+    {
+      per_info.control_regs.bits.em_storage_alteration = 1;
+      per_info.control_regs.bits.storage_alt_space_ctl = 1;
+    }
+  else
+    {
+      per_info.control_regs.bits.em_storage_alteration = 0;
+      per_info.control_regs.bits.storage_alt_space_ctl = 0;
+    }
+  per_info.starting_addr = watch_lo_addr;
+  per_info.ending_addr = watch_hi_addr;
+  ptrace (PTRACE_POKEUSR_AREA, pid, &parea);
+}
+
+int
+s390_insert_watchpoint (int pid, CORE_ADDR addr, int len, int rw)
+{
+  CORE_ADDR hi_addr = addr + len - 1;
+  watch_area *newArea = (watch_area *) malloc (sizeof (watch_area));
+
+
+  if (newArea)
+    {
+      newArea->next = watch_base;
+      watch_base = newArea;
+      watch_lo_addr = min (watch_lo_addr, addr);
+      watch_hi_addr = max (watch_hi_addr, hi_addr);
+      newArea->lo_addr = addr;
+      newArea->hi_addr = hi_addr;
+      if (watch_area_cnt == 0)
+	{
+	  watch_lo_addr = newArea->lo_addr;
+	  watch_hi_addr = newArea->hi_addr;
+	}
+      watch_area_cnt++;
+      s390_fix_watch_points (pid);
+    }
+  return newArea ? 0 : -1 ;
+}
+
+
+int
+s390_remove_watchpoint (int pid, CORE_ADDR addr, int len)
+{
+  watch_area *curr = watch_base, *prev, *matchCurr;
+  CORE_ADDR hi_addr = addr + len - 1;
+  CORE_ADDR watch_second_lo_addr = 0xffffffffUL, watch_second_hi_addr = 0;
+  int lo_addr_ref_cnt, hi_addr_ref_cnt;
+  prev = matchCurr = NULL;
+  lo_addr_ref_cnt = (addr == watch_lo_addr);
+  hi_addr_ref_cnt = (addr == watch_hi_addr);
+  while (curr)
+    {
+      if (matchCurr == NULL)
+	{
+	  if (curr->lo_addr == addr && curr->hi_addr == hi_addr)
+	    {
+	      matchCurr = curr;
+	      if (prev)
+		prev->next = curr->next;
+	      else
+		watch_base = curr->next;
+	    }
+	  prev = curr;
+	}
+      if (lo_addr_ref_cnt)
+	{
+	  if (watch_lo_addr == curr->lo_addr)
+	    lo_addr_ref_cnt++;
+	  if (curr->lo_addr > watch_lo_addr &&
+	      curr->lo_addr < watch_second_lo_addr)
+	    watch_second_lo_addr = curr->lo_addr;
+	}
+      if (hi_addr_ref_cnt)
+	{
+	  if (watch_hi_addr == curr->hi_addr)
+	    hi_addr_ref_cnt++;
+	  if (curr->hi_addr < watch_hi_addr &&
+	      curr->hi_addr > watch_second_hi_addr)
+	    watch_second_hi_addr = curr->hi_addr;
+	}
+      curr = curr->next;
+    }
+  if (matchCurr)
+    {
+      free (matchCurr);
+      watch_area_cnt--;
+      if (watch_area_cnt)
+	{
+	  if (lo_addr_ref_cnt == 2)
+	    watch_lo_addr = watch_second_lo_addr;
+	  if (hi_addr_ref_cnt == 2)
+	    watch_hi_addr = watch_second_hi_addr;
+	}
+      else
+	{
+	  watch_lo_addr = watch_hi_addr = 0;
+	}
+      s390_fix_watch_points (pid);
+      return 0;
+    }
+  else
+    {
+      fprintf_unfiltered (gdb_stderr,
+			  "Attempt to remove nonexistent watchpoint in s390_remove_watchpoint\n");
+      return -1;
+    }
+}
+
+int
+kernel_u_size (void)
+{
+  return sizeof(struct user);
+}
+
+
+#if  (defined (S390_FP0_REGNUM) && defined (HAVE_FPREGSET_T) && defined(HAVE_SYS_PROCFS_H) && defined (HAVE_GREGSET_T))
+void
+supply_gregset (gregset_t * gregsetp)
+{
+  int regi;
+  s390_regs_common *s390regs = (s390_regs_common *) gregsetp;
+
+  for (regi = 0; regi < S390_NUM_GPRS; regi++)
+    supply_register (S390_GP0_REGNUM + regi, (char *) &s390regs->gprs[regi]);
+  supply_register (S390_PSWM_REGNUM, (char *) &s390regs->psw.mask);
+  supply_register (S390_PC_REGNUM, (char *) &s390regs->psw.addr);
+  for (regi = 0; regi < S390_NUM_ACRS; regi++)
+    supply_register (S390_FIRST_ACR + regi, (char *) &s390regs->acrs[regi]);
+  /* unfortunately this isn't in gregsetp */
+  for (regi = 0; regi < S390_NUM_CRS; regi++)
+    supply_register (S390_FIRST_CR + regi, NULL);
+}
+
+
+void
+supply_fpregset (fpregset_t * fpregsetp)
+{
+  int regi;
+
+  supply_register (S390_FPC_REGNUM, (char *) &fpregsetp->fpc);
+  for (regi = 0; regi < S390_NUM_FPRS; regi++)
+    supply_register (S390_FP0_REGNUM + regi, (char *) &fpregsetp->fprs[regi]);
+
+}
+
+void
+fill_gregset (gregset_t * gregsetp, int regno)
+{
+  if (regno >= S390_FIRST_CR && regno <= S390_LAST_CR)
+    memset (&((__u8 *) gregsetp)[REGISTER_BYTE (regno)], 0,
+	    REGISTER_RAW_SIZE (regno));
+  if (regno != -1)
+    supply_register (regno, &((__u8 *) gregsetp)[REGISTER_BYTE (regno)]);
+  else
+    supply_gregset (gregsetp);
+}
+
+/*  Given a pointer to a floating point register set in /proc format
+   (fpregset_t *), update the register specified by REGNO from gdb's idea
+   of the current floating point register set.  If REGNO is -1, update
+   them all. */
+
+void
+fill_fpregset (fpregset_t * fpregsetp, int regno)
+{
+  if (regno == -1)
+    supply_fpregset (fpregsetp);
+  else
+    supply_register (regno,
+		     &((__u8 *) fpregsetp)[REGISTER_BYTE (regno) -
+					   REGISTER_BYTE (S390_FPC_REGNUM)]);
+}
+
+
+#else
+#error "There are a few possibilities here"
+#error "1) You aren't compiling for linux & don't need a core dumps to work."
+#error "2) The header files sys/elf.h sys/user.h sys/ptrace.h & sys/procfs.h"
+#error "libc files are inconsistent with linux/include/asm-s390/"
+#error "3) you didn't do a completely clean build & delete config.cache."
+#endif
--- /dev/null	Tue Jun  1 11:25:19 1999
+++ src.new/gdb/s390-tdep.c	Tue Feb 27 15:10:47 2001
@@ -0,0 +1,1308 @@
+/* Target-dependent code for GDB, the GNU debugger.
+   Copyright 1999 Free Software Foundation, Inc.
+   Contributed by D.J. Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
+   for IBM Deutschland Entwicklung GmbH, IBM Corporation.
+
+   This file is part of GDB.
+
+   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 of the License, 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.
+
+   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., 59 Temple Place - Suite 330, Boston, MA
+   02111-1307, USA.  */
+
+#define S390_TDEP		/* for special macros in tm-s390.h */
+#include <defs.h>
+#include "arch-utils.h"
+#include "frame.h"
+#include "inferior.h"
+#include "symtab.h"
+#include "target.h"
+#include "gdbcore.h"
+#include "gdbcmd.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "tm.h"
+#include "../bfd/bfd.h"
+#include "floatformat.h"
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#undef offsetof
+#define offsetof(type, member) ((CORE_ADDR) & ((type*)0) -> member )
+
+#define s390_offsetof(esame_type,esa_type,member) \
+(GDB_TARGET_IS_ESAME ? offsetof(esame_type,member) : offsetof(esa_type,member))
+
+#define s390_sizeof(esame_type,esa_type) \
+(GDB_TARGET_IS_ESAME ? sizeof(esame_type) : sizeof(esa_type))
+
+#define SIZEOF_S390_GDB_REGS s390_sizeof(s390x_gdb_regs,s390_gdb_regs)
+
+
+struct frame_extra_info
+{
+  int initialised;
+  int good_prologue;
+  CORE_ADDR function_start;
+  CORE_ADDR skip_prologue_function_start;
+  CORE_ADDR saved_pc_valid;
+  CORE_ADDR saved_pc;
+  CORE_ADDR sig_fixed_saved_pc_valid;
+  CORE_ADDR sig_fixed_saved_pc;
+  __u32 stack_bought;		/* amount we decrement the stack pointer by */
+  int has_frame_pointer;	/* frame pointer needed for alloca */
+};
+
+
+static CORE_ADDR s390_frame_saved_pc_nofix (struct frame_info *fi);
+
+int
+s390_readinstruction (__u8 instr[], CORE_ADDR at,
+		      struct disassemble_info *info)
+{
+  int instrlen;
+
+  static int s390_instrlen[] = {
+    2,
+    4,
+    4,
+    6
+  };
+  if ((*info->read_memory_func) (at, &instr[0], 2, info))
+    return -1;
+  instrlen = s390_instrlen[instr[0] >> 6];
+  if ((*info->read_memory_func) (at + 2, &instr[2], instrlen - 2, info))
+    return -1;
+  return instrlen;
+}
+
+static void
+s390_memset_extra_info (struct frame_extra_info *fextra_info)
+{
+  memset (fextra_info, 0, sizeof (struct frame_extra_info));
+}
+
+
+
+char *
+s390_register_name (int reg_nr)
+{
+  static char *register_names[] = S390_REGISTER_NAMES;
+
+  if (reg_nr >= S390_LAST_REGNUM)
+    return NULL;
+  return register_names[reg_nr];
+}
+
+
+
+int
+s390_cannot_fetch_register (int regno)
+{
+  return (regno >= S390_FIRST_CR && regno < (S390_FIRST_CR + 9)) ||
+    (regno >= (S390_FIRST_CR + 12) && regno <= S390_LAST_CR);
+}
+
+int
+s390_stab_reg_to_regnum (int regno)
+{
+  return regno >= 64 ? S390_PSWM_REGNUM - 64 :
+    regno >= 48 ? S390_FIRST_ACR - 48 :
+    regno >= 32 ? S390_FIRST_CR - 32 :
+    regno <= 15 ? (regno + 2) :
+    S390_FP0_REGNUM + ((regno - 16) & 8) + (((regno - 16) & 3) << 1) +
+    (((regno - 16) & 4) >> 2);
+}
+
+
+
+/* s390_get_frame_info based on Hartmuts
+   prologue definition in
+   gcc-2.8.1/config/l390/linux.c 
+
+   It reads one instruction at a time & based on whether
+   it looks like prologue code or not it makes a decision on
+   whether the prologue is over, there are various state machines
+   in the code to determine if the prologue code is possilby valid.
+   
+   This is done to hopefully allow the code survive minor revs of
+   calling conventions.
+
+  fextra_info must be already set up to come in with saved_regs not NULL */
+
+int
+s390_get_frame_info (CORE_ADDR pc, struct frame_extra_info *fextra_info,
+		     struct frame_info *fi, int init_extra_info)
+{
+#define CONST_POOL_REGIDX 13
+#define GOT_REGIDX        12
+  __u8 instr[S390_MAX_INSTR_SIZE];
+  CORE_ADDR test_pc = pc, test_pc2;
+  CORE_ADDR orig_sp = 0, save_reg_addr = 0, *saved_regs = NULL;
+  int valid_prologue, good_prologue = FALSE;
+  int gprs_saved[S390_NUM_GPRS];
+  int fprs_saved[S390_NUM_FPRS];
+  int regidx, instrlen;
+  int save_link_regidx, subtract_sp_regidx;
+  int const_pool_state, save_link_state, got_state;
+  int frame_pointer_found, varargs_state;
+  int loop_cnt, gdb_gpr_store, gdb_fpr_store;
+  int frame_pointer_regidx = 0xf;
+  int offset, expected_offset;
+  int err = 0;
+  disassemble_info info;
+  const_pool_state = save_link_state = got_state = varargs_state = 0;
+  frame_pointer_found = FALSE;
+  memset (gprs_saved, 0, sizeof (gprs_saved));
+  memset (fprs_saved, 0, sizeof (fprs_saved));
+  info.read_memory_func = dis_asm_read_memory;
+
+  save_link_regidx = subtract_sp_regidx = 0;
+  if (fi)
+    {
+      saved_regs = fi->saved_regs;
+      orig_sp = fi->frame + fextra_info->stack_bought;
+    }
+  if (fextra_info)
+    {
+      if (init_extra_info || fextra_info->initialised == FALSE)
+	{
+	  s390_memset_extra_info (fextra_info);
+	  fextra_info->function_start = pc;
+	  fextra_info->initialised = TRUE;
+	}
+    }
+  instrlen = 0;
+  do
+    {
+      valid_prologue = FALSE;
+      test_pc += instrlen;
+      /* add the previous instruction len */
+      instrlen = s390_readinstruction (instr, test_pc, &info);
+      if (instrlen < 0)
+	{
+	  good_prologue = FALSE;
+	  err = -1;
+	  break;
+	}
+      if (save_link_state == 0)
+	{
+	  /* check for a stack relative STMG or STM */
+	  if (((GDB_TARGET_IS_ESAME &&
+		((instr[0] == 0xeb) && (instr[5] == 0x24))) ||
+	       (instr[0] == 0x90)) && ((instr[2] >> 4) == 0xf))
+	    {
+	      regidx = (instr[1] >> 4);
+	      if (regidx < 6)
+		varargs_state = 1;
+	      offset = ((*((__u16 *) & instr[2])) & 0xfff);
+	      expected_offset =
+		S390_GPR6_STACK_OFFSET + (S390_GPR_SIZE * (regidx - 6));
+	      if (offset != expected_offset)
+		{
+		  good_prologue = FALSE;
+		  break;
+		}
+	      if (saved_regs)
+		save_reg_addr = orig_sp + offset;
+	      for (; regidx <= (instr[1] & 0xf); regidx++)
+		{
+		  if (gprs_saved[regidx])
+		    {
+		      good_prologue = FALSE;
+		      break;
+		    }
+		  good_prologue = TRUE;
+		  gprs_saved[regidx] = TRUE;
+		  if (saved_regs)
+		    {
+		      saved_regs[S390_GP0_REGNUM + regidx] = save_reg_addr;
+		      save_reg_addr += S390_GPR_SIZE;
+		    }
+		}
+	      valid_prologue = TRUE;
+	      continue;
+	    }
+	}
+      /* check for a stack relative STG or ST */
+      if ((save_link_state == 0 || save_link_state == 3) &&
+	  ((GDB_TARGET_IS_ESAME &&
+	    ((instr[0] == 0xe3) && (instr[5] == 0x24))) ||
+	   (instr[0] == 0x50)) && ((instr[2] >> 4) == 0xf))
+	{
+	  regidx = instr[1] >> 4;
+	  offset = ((*((__u16 *) & instr[2])) & 0xfff);
+	  if (offset == 0)
+	    {
+	      if (save_link_state == 3 && regidx == save_link_regidx)
+		{
+		  save_link_state = 4;
+		  valid_prologue = TRUE;
+		  continue;
+		}
+	      else
+		break;
+	    }
+	  if (regidx < 6)
+	    varargs_state = 1;
+	  expected_offset =
+	    S390_GPR6_STACK_OFFSET + (S390_GPR_SIZE * (regidx - 6));
+	  if (offset != expected_offset)
+	    {
+	      good_prologue = FALSE;
+	      break;
+	    }
+	  if (gprs_saved[regidx])
+	    {
+	      good_prologue = FALSE;
+	      break;
+	    }
+	  good_prologue = TRUE;
+	  gprs_saved[regidx] = TRUE;
+	  if (saved_regs)
+	    {
+	      save_reg_addr = orig_sp + offset;
+	      saved_regs[S390_GP0_REGNUM + regidx] = save_reg_addr;
+	    }
+	  valid_prologue = TRUE;
+	  continue;
+	}
+
+      /* check for STD */
+      if (instr[0] == 0x60 && (instr[2] >> 4) == 0xf)
+	{
+	  regidx = instr[1] >> 4;
+	  if (regidx == 0 || regidx == 2)
+	    varargs_state = 1;
+	  if (fprs_saved[regidx])
+	    {
+	      good_prologue = FALSE;
+	      break;
+	    }
+	  fprs_saved[regidx] = TRUE;
+	  if (saved_regs)
+	    {
+	      save_reg_addr = orig_sp + ((*((__u16 *) & instr[2])) & 0xfff);
+	      saved_regs[S390_FP0_REGNUM + regidx] = save_reg_addr;
+	    }
+	  valid_prologue = TRUE;
+	  continue;
+	}
+
+
+      if (const_pool_state == 0)
+	{
+	  /* Check for BASR gpr13,gpr0 used to load constant pool pointer to r13 in old compiler */
+	  if (GDB_TARGET_IS_ESAME && instr[0] == 0xd && (instr[1] & 0xf) == 0
+	      && ((instr[1] >> 4) == CONST_POOL_REGIDX))
+	    {
+	      const_pool_state = 1;
+	      valid_prologue = TRUE;
+	      continue;
+	    }
+	  /* Check for new fangled bras %r13,newpc to load new constant pool */
+	  /* embedded in code */
+	  if ((instr[0] == 0xa7) && ((instr[1] & 0xf) == 0x5) &&
+	      ((instr[1] >> 4) == CONST_POOL_REGIDX)
+	      && ((instr[2] & 0x80) == 0))
+	    {
+	      const_pool_state = 2;
+	      test_pc += ((*((__u16 *) & instr[2]) << 1) - instrlen);
+	      valid_prologue = TRUE;
+	      continue;
+	    }
+	}
+      /* Check for AGHI or AHI CONST_POOL_REGIDX,val */
+      if (const_pool_state == 1 && (instr[0] == 0xa7) &&
+	  ((GDB_TARGET_IS_ESAME &&
+	    (instr[1] == ((CONST_POOL_REGIDX << 4) | 0xb))) ||
+	   (instr[1] == ((CONST_POOL_REGIDX << 4) | 0xa))))
+	{
+	  const_pool_state = 2;
+	  valid_prologue = TRUE;
+	  continue;
+	}
+      /* Check for LGR or LR gprx,15 */
+      if ((GDB_TARGET_IS_ESAME &&
+	   instr[0] == 0xb9 && instr[1] == 0x04 && (instr[3] & 0xf) == 0xf) ||
+	  (instr[0] == 0x18 && (instr[1] & 0xf) == 0xf))
+	{
+	  if (GDB_TARGET_IS_ESAME)
+	    regidx = instr[3] >> 4;
+	  else
+	    regidx = instr[1] >> 4;
+	  if (save_link_state == 0 && regidx != 0xb)
+	    {
+	      /* Almost defintely code for
+	         decrementing the stack pointer 
+	         ( i.e. a non leaf function 
+	         or else leaf with locals ) */
+	      save_link_regidx = regidx;
+	      save_link_state = 1;
+	      valid_prologue = TRUE;
+	      continue;
+	    }
+	  /* We use this frame pointer for alloca
+	     unfortunately we need to assume its gpr11
+	     otherwise we would need a smarter prologue
+	     walker. */
+	  if (frame_pointer_found == FALSE && regidx == 0xb)
+	    {
+	      frame_pointer_regidx = 0xb;
+	      frame_pointer_found = TRUE;
+	      if (fextra_info)
+		fextra_info->has_frame_pointer = TRUE;
+	      valid_prologue = TRUE;
+	      continue;
+	    }
+	}
+      /* Check for AHI or AGHI gpr15,val */
+      if (save_link_state == 1 && (instr[0] == 0xa7) &&
+	  ((GDB_TARGET_IS_ESAME && (instr[1] == 0xfb)) || (instr[1] == 0xfa)))
+	{
+	  if (fextra_info)
+	    fextra_info->stack_bought = -(*((__s16 *) & instr[2]));
+	  save_link_state = 3;
+	  valid_prologue = TRUE;
+	  continue;
+	}
+      /* Alternatively check for the complex construction for
+         buying more than 32k of stack
+         BRAS gprx,.+8
+         long vals    %r15,0(%gprx)  gprx currently r1 */
+      if ((save_link_state == 1) && (instr[0] == 0xa7)
+	  && ((instr[1] & 0xf) == 0x5) && (*((__u16 *) & instr[2]) == 0x4)
+	  && ((instr[1] >> 4) != CONST_POOL_REGIDX))
+	{
+	  subtract_sp_regidx = instr[1] >> 4;
+	  save_link_state = 2;
+	  if (fextra_info)
+	    target_read_memory (test_pc + instrlen,
+				(char *) &fextra_info->stack_bought,
+				sizeof (fextra_info->stack_bought));
+	  test_pc += 4;
+	  valid_prologue = TRUE;
+	  continue;
+	}
+      if (save_link_state == 2 && (*((__u16 *) & instr[0]) == 0x5bf0) &&
+	  (*((__u16 *) & instr[2]) == subtract_sp_regidx << 12))
+	{
+	  save_link_state = 3;
+	  valid_prologue = TRUE;
+	  continue;
+	}
+      /* check for LA gprx,offset(15) used for varargs */
+      if (varargs_state == 1 &&
+	  instr[0] == 0x41 && ((instr[1] & 0xf) == 0)
+	  && ((instr[2] >> 4) == 0xf))
+	{
+	  varargs_state = 2;
+	  valid_prologue = TRUE;
+	  continue;
+	}
+      /*
+         Check for a GOT load
+         we might be able to get info like whether we
+         are compiled -fpic to check whether this is valid
+         prologue */
+      if (got_state == 0 && const_pool_state == 2 && instr[0] == 0x58
+	  && (instr[2] == (CONST_POOL_REGIDX << 4))
+	  && ((instr[1] >> 4) == GOT_REGIDX))
+	{
+	  got_state == 1;
+	  valid_prologue = TRUE;
+	  continue;
+	}
+      /* Check for subsequent ar got_regidx,basr_regidx */
+      if (got_state == 1 && instr[0] == 0x1a &&
+	  instr[1] == ((GOT_REGIDX << 4) | CONST_POOL_REGIDX))
+	{
+	  got_state = 2;
+	  valid_prologue = TRUE;
+	  continue;
+	}
+    }
+  while (valid_prologue && good_prologue);
+  if (good_prologue == TRUE)
+    {
+      good_prologue = (((got_state == 0) || (got_state == 2)) &&
+		       ((const_pool_state == 0) || (const_pool_state == 2)) &&
+		       ((save_link_state == 0) || (save_link_state == 4)) &&
+		       ((varargs_state == 0) || (varargs_state == 2)));
+    }
+  if (fextra_info)
+    {
+      fextra_info->good_prologue = good_prologue;
+      fextra_info->skip_prologue_function_start =
+	(good_prologue ? test_pc : pc);
+    }
+  return err;
+}
+
+
+static CORE_ADDR
+s390_sniff_pc_function_start (CORE_ADDR pc)
+{
+  CORE_ADDR function_start, test_function_start, ret_function_start, loop_dec;
+  int loop_cnt, err;
+  struct frame_extra_info fextra_info;
+  function_start = get_pc_function_start (pc);
+
+  if (function_start == 0)
+    {
+      test_function_start = pc;
+      if (test_function_start & 1)
+	loop_dec = 1;		/* This is a suspicious address */
+      else
+	loop_dec = 2;
+      loop_cnt = 0;
+      do
+	{
+	  err =
+	    s390_get_frame_info (test_function_start, &fextra_info, NULL,
+				 TRUE);
+	  loop_cnt++;
+	  test_function_start -= loop_dec;
+	}
+      while (err == 0 && loop_cnt < 4096
+	     && fextra_info.good_prologue == FALSE);
+      if (fextra_info.good_prologue)
+	function_start = fextra_info.function_start;
+    }
+  return function_start;
+}
+
+
+
+CORE_ADDR s390_function_start (struct frame_info * fi)
+{
+  CORE_ADDR function_start = 0;
+
+  if (fi->extra_info && fi->extra_info->initialised)
+    function_start = fi->extra_info->function_start;
+  else if (fi->pc)
+    function_start = get_pc_function_start (fi->pc);
+  return function_start;
+}
+
+
+
+
+int
+s390_frameless_function_invocation (struct frame_info *fi)
+{
+  struct frame_extra_info fextra_info, *fextra_info_ptr;
+  int frameless = 0;
+
+  if (fi->next == NULL)		/* no may be frameless */
+    {
+      if (fi->extra_info)
+	fextra_info_ptr = fi->extra_info;
+      else
+	{
+	  fextra_info_ptr = &fextra_info;
+	  s390_get_frame_info (s390_sniff_pc_function_start (fi->pc),
+			       fextra_info_ptr, NULL, TRUE);
+	}
+      frameless = ((fextra_info_ptr->good_prologue)
+		   && (fextra_info_ptr->stack_bought == 0));
+    }
+  return frameless;
+
+}
+
+
+static int
+s390_is_sigreturn (CORE_ADDR pc, struct frame_info *sighandler_fi,
+		   CORE_ADDR * sregs, CORE_ADDR * sigcaller_pc)
+{
+  __u8 instr[S390_MAX_INSTR_SIZE];
+  disassemble_info info;
+  int instrlen;
+  CORE_ADDR scontext;
+  int retval = FALSE;
+  CORE_ADDR orig_sp;
+  CORE_ADDR temp_sregs;
+
+  scontext = temp_sregs = 0;
+
+  info.read_memory_func = dis_asm_read_memory;
+  instrlen = s390_readinstruction (instr, pc, &info);
+  if (sigcaller_pc)
+    *sigcaller_pc = 0;
+  if ((instrlen == S390_SYSCALL_SIZE) &&
+      ((((S390_SYSCALL_OPCODE | s390_NR_sigreturn)) == *(__u16 *) instr) ||
+       (((S390_SYSCALL_OPCODE | s390_NR_rt_sigreturn)) == *(__u16 *) instr)))
+    {
+      if (sighandler_fi)
+	{
+	  if (s390_frameless_function_invocation (sighandler_fi))
+	    orig_sp = sighandler_fi->frame;
+	  else
+	    orig_sp = ADDR_BITS_REMOVE ((CORE_ADDR)
+					read_memory_integer (sighandler_fi->frame,
+							     S390_GPR_SIZE));
+	  if (orig_sp && sigcaller_pc)
+	    {
+	      scontext = orig_sp + S390_SIGNAL_FRAMESIZE;
+	      temp_sregs = ADDR_BITS_REMOVE((CORE_ADDR)
+					    read_memory_integer (scontext + 
+						s390_offsetof(s390x_sigcontext,s390_sigcontext,sregs),
+						S390_GPR_SIZE));
+	      *sigcaller_pc =
+		ADDR_BITS_REMOVE ((CORE_ADDR)
+				  read_memory_integer (temp_sregs +
+				  s390_offsetof(s390x_sigregs,s390_sigregs,regs.psw.addr),
+				  S390_PSW_ADDR_SIZE));
+	    }
+	}
+      retval = TRUE;
+    }
+  if (sregs)
+    *sregs = temp_sregs;
+  return retval;
+}
+
+/*
+  We need to do something better here but this will keep us out of trouble
+  for the moment.
+  For some reason the blockframe.c calls us with fi->next->fromleaf
+  so this seems of little use to us. */
+void
+s390_init_frame_pc_first (int next_fromleaf, struct frame_info *fi)
+{
+  CORE_ADDR sigcaller_pc;
+
+  fi->pc = 0;
+  if (next_fromleaf)
+    {
+      fi->pc = ADDR_BITS_REMOVE (read_register (S390_RETADDR_REGNUM));
+      /* fix signal handlers */
+    }
+  else if (fi->next && fi->next->pc)
+    fi->pc = s390_frame_saved_pc_nofix (fi->next);
+  if (fi->pc && fi->next && fi->next->frame &&
+      s390_is_sigreturn (fi->pc, fi->next, NULL, &sigcaller_pc))
+    {
+      fi->pc = sigcaller_pc;
+    }
+
+}
+
+void
+s390_init_extra_frame_info (int fromleaf, struct frame_info *fi)
+{
+  fi->extra_info = frame_obstack_alloc (sizeof (struct frame_extra_info));
+  if (fi->pc)
+    s390_get_frame_info (s390_sniff_pc_function_start (fi->pc),
+			 fi->extra_info, NULL, TRUE);
+  else
+    s390_memset_extra_info (fi->extra_info);
+}
+
+/* If saved registers of frame FI are not known yet, read and cache them.
+   &FEXTRA_INFOP contains struct frame_extra_info; TDATAP can be NULL,
+   in which case the framedata are read.  */
+
+void
+s390_frame_init_saved_regs (struct frame_info *fi)
+{
+
+  if (fi->saved_regs == NULL)
+    {
+
+      frame_saved_regs_zalloc (fi);
+      if (fi->extra_info)
+	{
+	  if (!fi->extra_info->initialised && fi->pc)
+	    s390_get_frame_info (s390_sniff_pc_function_start (fi->pc),
+				 fi->extra_info, fi, TRUE);
+	  if (fi->extra_info->good_prologue)
+	    s390_get_frame_info (fi->extra_info->function_start,
+				 fi->extra_info, fi, FALSE);
+	}
+    }
+}
+
+
+
+CORE_ADDR s390_frame_args_address (struct frame_info *fi)
+{
+
+  /* Apparently gdb already knows gdb_args_offset itself */
+  return fi->frame;
+}
+
+
+static CORE_ADDR
+s390_frame_saved_pc_nofix (struct frame_info *fi)
+{
+  if (fi->extra_info && fi->extra_info->saved_pc_valid)
+    return fi->extra_info->saved_pc;
+  s390_frame_init_saved_regs (fi);
+  if (fi->extra_info)
+    {
+      fi->extra_info->saved_pc_valid = TRUE;
+      if (fi->extra_info->good_prologue)
+	{
+	  return (fi->extra_info->saved_pc =
+		  ADDR_BITS_REMOVE(read_memory_integer(fi->saved_regs[S390_RETADDR_REGNUM],
+						       S390_GPR_SIZE)));
+	}
+    }
+  return 0;
+}
+
+CORE_ADDR s390_frame_saved_pc (struct frame_info * fi)
+{
+  CORE_ADDR saved_pc = 0, sig_pc;
+
+  if (fi->extra_info && fi->extra_info->sig_fixed_saved_pc_valid)
+    return fi->extra_info->sig_fixed_saved_pc;
+  saved_pc = s390_frame_saved_pc_nofix (fi);
+
+  if (fi->extra_info)
+    {
+      fi->extra_info->sig_fixed_saved_pc_valid = TRUE;
+      if (saved_pc)
+	{
+	  if (s390_is_sigreturn (saved_pc, fi, NULL, &sig_pc))
+	    saved_pc = sig_pc;
+	}
+      fi->extra_info->sig_fixed_saved_pc = saved_pc;
+    }
+  return saved_pc;
+}
+
+
+
+
+/* We want backtraces out of signal handlers so we don't
+   set thisframe->signal_handler_caller to 1 */
+
+CORE_ADDR s390_frame_chain (struct frame_info * thisframe)
+{
+
+  CORE_ADDR prev_fp = 0;
+  struct frame_extra_info fextra_info;
+  CORE_ADDR saved_pc, sig_pc;
+  int regno;
+  CORE_ADDR sregs;
+  int sigreturn;
+
+  if (thisframe->prev && thisframe->prev->frame)
+    prev_fp = thisframe->prev->frame;
+  else
+    {
+      /* We have to do some work */
+      if (!thisframe->pc)
+	return 0;
+      saved_pc = s390_frame_saved_pc_nofix (thisframe);
+      if (!saved_pc)
+	return 0;
+      if (
+	  (sigreturn =
+	   s390_is_sigreturn (saved_pc, thisframe, &sregs, &sig_pc)))
+	saved_pc = sig_pc;
+      s390_get_frame_info (s390_sniff_pc_function_start (saved_pc),
+			   &fextra_info, NULL, TRUE);
+      if (!fextra_info.good_prologue)
+	return 0;
+      if (sigreturn)
+	prev_fp =
+	  ADDR_BITS_REMOVE ((CORE_ADDR)
+			    read_memory_integer (sregs +
+						 s390_offsetof (s390x_sigregs,
+								s390_sigregs,
+								regs.
+								gprs
+								[fextra_info.
+								 has_frame_pointer
+								 ? 11 : 15]),
+						 S390_GPR_SIZE));
+      else
+	{
+	  regno =
+	    (fextra_info.
+	     has_frame_pointer ? S390_FRAME_REGNUM : S390_SP_REGNUM);
+	  /* if it wasn't saved we must be in the innermost frame */
+	  prev_fp = ADDR_BITS_REMOVE (thisframe->saved_regs[regno] ?
+				      read_memory_integer (thisframe->
+							   saved_regs[regno],
+							   S390_GPR_SIZE) :
+				      read_register (regno));
+	}
+
+
+    }
+  return prev_fp;
+}
+
+/*
+  Whether struct frame_extra_info is actually needed I'll have to figure
+  out as our frames are similar to rs6000 there is a possibility
+  i386 dosen't need it. */
+
+
+
+/* a given return value in `regbuf' with a type `valtype', extract and copy its
+   value into `valbuf' */
+void
+s390_extract_return_value (struct type *valtype, char *regbuf, char *valbuf)
+{
+  /* floats and doubles are returned in fpr0. fpr's have a size of 8 bytes.
+     We need to truncate the return value into float size (4 byte) if
+     necessary. */
+  int len = TYPE_LENGTH (valtype);
+
+  if (TYPE_CODE (valtype) == TYPE_CODE_FLT)
+    {
+      if (len > (TARGET_FLOAT_BIT>>3))
+	memcpy (valbuf,&regbuf[REGISTER_BYTE (S390_FP0_REGNUM)],len);
+      else
+	{
+	  /* float */
+	  DOUBLEST val;
+	  
+	  floatformat_to_doublest (&floatformat_ieee_double_big,
+				   &regbuf[REGISTER_BYTE (S390_FP0_REGNUM)], &val);
+	  store_floating (valbuf,len, val);
+	}
+    }
+  else
+    {
+      int offset = 0;
+      /* return value is copied starting from r2. */
+      if (TYPE_LENGTH (valtype) < S390_GPR_SIZE)
+	offset = S390_GPR_SIZE - TYPE_LENGTH (valtype);
+      memcpy (valbuf,
+	      regbuf + REGISTER_BYTE (S390_GP0_REGNUM + 2) + offset,
+	      TYPE_LENGTH (valtype));
+    }
+}
+
+
+static char *
+s390_promote_integer_argument(struct type *valtype,char *valbuf,char *reg_buff,int *arglen)
+{
+  char *value=valbuf;
+  int len=TYPE_LENGTH (valtype);
+  
+  if (len < S390_GPR_SIZE)
+    {
+      /* We need to upgrade this value to a register to pass it correctly */
+      int idx,diff=S390_GPR_SIZE-len,negative = (!TYPE_UNSIGNED (valtype)&&value[0]&0x80);		  
+      for(idx=0;idx<S390_GPR_SIZE;idx++)
+	{
+	  reg_buff[idx] = (idx<diff ? (negative ? 0xff:0x0) : 
+			   value[idx-diff] );
+	}
+      value=reg_buff;
+      *arglen = S390_GPR_SIZE;
+    }
+  else
+    {
+      if (len & (S390_GPR_SIZE - 1))
+	{
+	  fprintf_unfiltered (gdb_stderr,
+			      "s390_promote_integer_argument detected an argument not "
+			      "a multiple of S390_GPR_SIZE & greater than S390_GPR_SIZE "
+			      "we might not deal with this correctly.\n");
+	}
+      *arglen = len;
+    }
+
+  return(value);
+}
+
+void
+s390_store_return_value (struct type *valtype, char *valbuf)
+{
+  int     arglen;
+  char    *reg_buff=alloca(max(S390_FPR_SIZE,S390_REGISTER_SIZE)),*value;
+
+  if (TYPE_CODE (valtype) == TYPE_CODE_FLT)
+    {
+       DOUBLEST tempfloat = extract_floating (valbuf,TYPE_LENGTH (valtype));
+	      
+       floatformat_from_doublest ( &floatformat_ieee_double_big,&tempfloat, reg_buff);
+       write_register_bytes (REGISTER_BYTE (S390_FP0_REGNUM),reg_buff,S390_FPR_SIZE);
+    }
+  else
+    {
+      value=s390_promote_integer_argument(valtype,valbuf,reg_buff,&arglen);
+      /* Everything else is returned in GPR2 and up. */
+      write_register_bytes (REGISTER_BYTE (S390_GP0_REGNUM + 2), value, arglen);
+    }
+}
+static int
+gdb_print_insn_s390 (bfd_vma memaddr, disassemble_info * info)
+{
+  __u8 instrbuff[S390_MAX_INSTR_SIZE];
+  int instrlen, cnt;
+
+  instrlen = s390_readinstruction (instrbuff, (CORE_ADDR) memaddr, info);
+  if (instrlen < 0)
+    {
+      (*info->memory_error_func) (instrlen, memaddr, info);
+      return -1;
+    }
+  for (cnt = 0; cnt < instrlen; cnt++)
+    info->fprintf_func (info->stream, "%02X ", instrbuff[cnt]);
+  for (cnt = instrlen; cnt < S390_MAX_INSTR_SIZE; cnt++)
+    info->fprintf_func (info->stream, "   ");
+  instrlen = print_insn_s390 (memaddr, info);
+  return instrlen;
+}
+
+
+
+/* Not the most efficent code in the world */
+int
+s390_fp_regnum ()
+{
+  int regno = S390_SP_REGNUM;
+  struct frame_extra_info fextra_info;
+  s390_get_frame_info (s390_sniff_pc_function_start
+		       (read_register (S390_PC_REGNUM)), &fextra_info, NULL,
+		       TRUE);
+  if (fextra_info.good_prologue && fextra_info.has_frame_pointer)
+    regno = S390_FRAME_REGNUM;
+  return regno;
+}
+
+CORE_ADDR s390_read_fp ()
+{
+  return read_register (s390_fp_regnum ());
+}
+
+
+void
+s390_write_fp (CORE_ADDR val)
+{
+  write_register (s390_fp_regnum (), val);
+}
+
+
+void
+s390_push_dummy_frame ()
+{
+  CORE_ADDR orig_sp = read_register (S390_SP_REGNUM), new_sp;
+  void *saved_regs=alloca(SIZEOF_S390_GDB_REGS);
+
+  new_sp = (orig_sp - (SIZEOF_S390_GDB_REGS + S390_GPR_SIZE));
+  read_register_bytes (0, (char *)saved_regs,SIZEOF_S390_GDB_REGS);
+  /* Use saved copy instead of orig_sp as this will have the correct endianness */
+  write_memory (new_sp, (char *)saved_regs+ 
+		s390_offsetof(s390x_gdb_regs,s390_gdb_regs,gprs[S390_SP_REGNUM]),
+		S390_GPR_SIZE);
+  write_memory (new_sp + S390_GPR_SIZE, (char *) &saved_regs,
+		SIZEOF_S390_GDB_REGS);
+  write_register (S390_SP_REGNUM, new_sp);
+}
+
+/* pop the innermost frame, go back to the caller.
+    Used in `call_function_by_hand' to remove an artificial stack
+     frame.  */
+void
+s390_pop_frame ()
+{
+  CORE_ADDR new_sp = read_register (S390_SP_REGNUM), orig_sp;
+  void *saved_regs=alloca(SIZEOF_S390_GDB_REGS);
+
+
+  read_memory (new_sp + S390_GPR_SIZE, (char *)saved_regs,
+	       s390_sizeof(s390x_gdb_regs,s390_gdb_regs));
+  write_register_bytes (0, (char *) &saved_regs,SIZEOF_S390_GDB_REGS);
+}
+
+/* used by call function by hand
+  struct_return indicates that this function returns a structure &
+  therefore gpr2 stores a pointer to the structure to be returned as
+  opposed to the first argument.
+  Currently I haven't seen a TYPE_CODE_INT whose size wasn't 2^n or less
+  than S390_GPR_SIZE this is good because I don't seem to have to worry
+  about sign extending pushed arguments (i.e. a signed char currently
+  comes into this code with a size of 4 ). */
+
+CORE_ADDR
+s390_push_arguments (int nargs, value_ptr * args, CORE_ADDR sp,
+		     int struct_return, CORE_ADDR struct_addr)
+{
+  int num_float_args, num_gpr_args, orig_num_gpr_args, argno;
+  int second_pass, len, arglen, gprs_required;
+  CORE_ADDR outgoing_args_ptr, outgoing_args_space;
+  value_ptr arg;
+  struct type *type;
+  int max_num_gpr_args = 5 - (struct_return ? 1 : 0);
+  int arg0_regnum = S390_GP0_REGNUM + 2 + (struct_return ? 1 : 0);
+  char    *reg_buff=alloca(max(S390_FPR_SIZE,S390_REGISTER_SIZE)),*value;
+
+  for (second_pass = FALSE; second_pass <= TRUE; second_pass++)
+    {
+      if (second_pass)
+	outgoing_args_ptr = sp + S390_STACK_FRAME_OVERHEAD;
+      else
+	outgoing_args_ptr = 0;
+      num_float_args = 0;
+      num_gpr_args = 0;
+      for (argno = 0; argno < nargs; argno++)
+	{
+	  arg = args[argno];
+	  type = check_typedef (VALUE_TYPE (arg));
+	  len = TYPE_LENGTH (type);
+	  if (TYPE_CODE (type) == TYPE_CODE_FLT)
+	    {
+	      int all_float_registers_used=num_float_args > (GDB_TARGET_IS_ESAME ? 3 : 1);
+
+	      if(second_pass)
+		{
+		  DOUBLEST tempfloat = extract_floating (VALUE_CONTENTS(arg),len);
+	      
+
+		  floatformat_from_doublest ( all_float_registers_used && 
+					      len == (TARGET_FLOAT_BIT>>3) 
+					      ? &floatformat_ieee_single_big
+					      : &floatformat_ieee_double_big, 
+					      &tempfloat, reg_buff);
+		  if(all_float_registers_used)
+		    write_memory (outgoing_args_ptr,reg_buff, len);
+		  else
+		    write_register_bytes (REGISTER_BYTE((S390_FP0_REGNUM) 
+					  + (2 * num_float_args)),reg_buff,
+					S390_FPR_SIZE);
+		}
+	      if(all_float_registers_used)
+		outgoing_args_ptr += len;
+	      num_float_args++;
+	    }
+	  else
+	    {
+	      gprs_required = ((len + (S390_GPR_SIZE - 1)) / S390_GPR_SIZE);
+
+	      value=s390_promote_integer_argument(type,VALUE_CONTENTS(arg),reg_buff,&arglen);
+
+	      orig_num_gpr_args = num_gpr_args;
+	      num_gpr_args += gprs_required;
+	      if (num_gpr_args > max_num_gpr_args)
+		{
+		  if (second_pass)
+		    write_memory (outgoing_args_ptr, value, arglen);
+		  outgoing_args_ptr += arglen;
+		}
+	      else
+		{
+		  if (second_pass)
+		    write_register_bytes (REGISTER_BYTE (arg0_regnum)
+					  + (orig_num_gpr_args * S390_GPR_SIZE),
+					  value,arglen);
+		}
+	    }
+	}
+      if (!second_pass)
+	{
+	  outgoing_args_space = outgoing_args_ptr;
+	  /* Align to 16 bytes because because I like alignment & 
+	     some of the kernel code requires 8 byte stack alignment at least. */
+	  sp = (sp - (S390_STACK_FRAME_OVERHEAD + outgoing_args_ptr)) & (-16);
+	}
+
+    }
+  return sp;
+
+}
+
+
+#if defined(GDB_MULTI_ARCH) || !defined(CONFIG_ARCH_S390X)
+void
+s390_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs,
+		     struct value **args, struct type *value_type,
+		     int using_gcc)
+{
+  *(__u32 *) ((char *) &dummy[4]) = fun;
+}
+/* Number of bytes of storage in the actual machine representation
+   for register N. 
+   Note that the unsigned cast here forces the result of the
+   subtraction to very high positive values if N < S390_FP0_REGNUM */
+int
+s390_register_raw_size (int reg_nr)
+{
+  return ((unsigned) reg_nr - S390_FP0_REGNUM) <
+	   S390_NUM_FPRS ? S390_FPR_SIZE : 4;
+}
+
+/* Return the GDB type object for the "standard" data type
+   of data in register N.  */
+struct type *
+s390_register_virtual_type (int regno)
+{
+  return ((unsigned) regno - S390_FPC_REGNUM) <
+    S390_NUM_FPRS ? builtin_type_double : builtin_type_int;
+}
+
+#endif
+
+#if defined(GDB_MULTI_ARCH) || defined(CONFIG_ARCH_S390X)
+void
+s390x_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs,
+		      struct value **args, struct type *value_type,
+		      int using_gcc)
+{
+  *(__u64 *) ((char *) &dummy[4]) = fun;
+}
+
+int
+s390x_register_raw_size (int reg_nr)
+{
+  return (reg_nr == S390_FPC_REGNUM)
+	  || (reg_nr >= S390_FIRST_ACR && reg_nr <= S390_LAST_ACR) ? 4 : 8 ;
+}
+
+struct type *
+s390x_register_virtual_type (int regno)
+{
+  return (regno == S390_FPC_REGNUM) ||
+    (regno >= S390_FIRST_ACR && regno <= S390_LAST_ACR) ? builtin_type_int :
+    (regno >= S390_FP0_REGNUM) ? builtin_type_double : builtin_type_long;
+}
+
+#endif
+
+
+void
+s390_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
+{
+  write_register (S390_GP0_REGNUM + 2, addr);
+}
+
+
+
+static unsigned char *
+s390_breakpoint_from_pc (CORE_ADDR * pcptr, int *lenptr)
+{
+  static unsigned char breakpoint[] = S390_BREAKPOINT;
+
+  *lenptr = sizeof (breakpoint);
+  return breakpoint;
+}
+
+/* Advance PC across any function entry prologue instructions to reach some
+   "real" code.  */
+CORE_ADDR
+s390_skip_prologue (CORE_ADDR pc)
+{
+  struct frame_extra_info fextra_info;
+
+  s390_get_frame_info (pc, &fextra_info, NULL, TRUE);
+  return fextra_info.skip_prologue_function_start;
+}
+
+/* pc_in_call_dummy_on stack may work for us must test this */
+int
+s390_pc_in_call_dummy (CORE_ADDR pc, CORE_ADDR sp, CORE_ADDR frame_address)
+{
+  return pc > sp && pc < (sp + 4096);
+}
+
+/* Immediately after a function call, return the saved pc.
+   Can't go through the frames for this because on some machines
+   the new frame is not set up until the new function executes
+   some instructions.  */
+CORE_ADDR s390_saved_pc_after_call (struct frame_info * frame)
+{
+  return ADDR_BITS_REMOVE (read_register (S390_RETADDR_REGNUM));
+}
+
+#if GDB_MULTI_ARCH
+static CORE_ADDR
+s390_addr_bits_remove (CORE_ADDR addr)
+{
+  return (addr) & 0x7fffffff;
+}
+#endif
+
+int
+s390_register_byte (int reg_nr)
+{
+  return (((reg_nr) <= S390_GP_LAST_REGNUM ? (reg_nr) * S390_GPR_SIZE :
+	   (reg_nr) <=
+	   S390_LAST_ACR ? (S390_ACR0_OFFSET +
+			    (((reg_nr) - S390_FIRST_ACR) *
+			     S390_ACR_SIZE)) : (reg_nr) <=
+	   S390_LAST_CR ? (S390_CR0_OFFSET +
+			   (((reg_nr) - S390_FIRST_CR) *
+			    S390_CR_SIZE)) : (reg_nr) ==
+	   S390_FPC_REGNUM ? S390_FPC_OFFSET : (S390_FP0_OFFSET +
+						(((reg_nr) - S390_FP0_REGNUM)
+						 * S390_FPR_SIZE))));
+}
+
+#if GDB_MULTI_ARCH
+struct gdbarch *
+s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
+{
+  static LONGEST s390_call_dummy_words[] = S390_CALL_DUMMY;
+  static LONGEST s390x_call_dummy_words[] = S390X_CALL_DUMMY;
+  struct gdbarch *gdbarch;
+  struct gdbarch_tdep *tdep;
+  int elf_flags;
+
+  /* First see if there is already a gdbarch that can satisfy the request.  */
+  arches = gdbarch_list_lookup_by_info (arches, &info);
+  if (arches != NULL)
+    return arches->gdbarch;
+
+  /* None found: is the request for a s390 architecture? */
+  if (info.bfd_architecture != bfd_arch_s390)
+    return NULL;		/* No; then it's not for us.  */
+
+  /* Yes: create a new gdbarch for the specified machine type.  */
+  gdbarch = gdbarch_alloc (&info, NULL);
+
+  set_gdbarch_believe_pcc_promotion (gdbarch, 0);
+
+  /* We don't define set_gdbarch_call_dummy_breakpoint_offset 
+     as we already have a breakpoint inserted. */
+  set_gdbarch_use_generic_dummy_frames (gdbarch, 0);
+
+  set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
+  set_gdbarch_call_dummy_start_offset (gdbarch, 0);
+  set_gdbarch_pc_in_call_dummy (gdbarch, s390_pc_in_call_dummy);
+  set_gdbarch_frame_args_skip (gdbarch, 0);
+  set_gdbarch_frame_args_address (gdbarch, s390_frame_args_address);
+  set_gdbarch_frame_chain (gdbarch, s390_frame_chain);
+  set_gdbarch_frame_init_saved_regs (gdbarch, s390_frame_init_saved_regs);
+  set_gdbarch_frame_locals_address (gdbarch, s390_frame_args_address);
+  /* We can't do this */
+  set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown);
+  set_gdbarch_store_struct_return (gdbarch, s390_store_struct_return);
+  set_gdbarch_extract_return_value (gdbarch, s390_extract_return_value);
+  set_gdbarch_store_return_value (gdbarch, s390_store_return_value);
+  /* Amount PC must be decremented by after a breakpoint.
+     This is often the number of bytes in BREAKPOINT
+     but not always.  */
+  set_gdbarch_decr_pc_after_break (gdbarch, 2);
+  set_gdbarch_pop_frame (gdbarch, s390_pop_frame);
+  set_gdbarch_push_dummy_frame (gdbarch, s390_push_dummy_frame);
+  set_gdbarch_push_arguments (gdbarch, s390_push_arguments);
+  set_gdbarch_ieee_float (gdbarch, 1);
+  /* Stack grows downward.  */
+  set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
+  /* Offset from address of function to start of its code.
+     Zero on most machines.  */
+  set_gdbarch_function_start_offset (gdbarch, 0);
+  set_gdbarch_max_register_raw_size (gdbarch, 8);
+  set_gdbarch_max_register_virtual_size (gdbarch, 8);
+  set_gdbarch_breakpoint_from_pc (gdbarch, s390_breakpoint_from_pc);
+  set_gdbarch_skip_prologue (gdbarch, s390_skip_prologue);
+  set_gdbarch_init_extra_frame_info (gdbarch, s390_init_extra_frame_info);
+  set_gdbarch_init_frame_pc_first (gdbarch, s390_init_frame_pc_first);
+  set_gdbarch_read_fp (gdbarch, s390_read_fp);
+  set_gdbarch_write_fp (gdbarch, s390_write_fp);
+  /* This function 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.  */
+  set_gdbarch_frameless_function_invocation (gdbarch,
+					     s390_frameless_function_invocation);
+  /* Return saved PC from a frame */
+  set_gdbarch_frame_saved_pc (gdbarch, s390_frame_saved_pc);
+  /* FRAME_CHAIN takes a frame's nominal address
+     and produces the frame's chain-pointer. */
+  set_gdbarch_frame_chain (gdbarch, s390_frame_chain);
+  set_gdbarch_saved_pc_after_call (gdbarch, s390_saved_pc_after_call);
+  set_gdbarch_register_byte (gdbarch, s390_register_byte);
+  set_gdbarch_pc_regnum (gdbarch, S390_PC_REGNUM);
+  set_gdbarch_sp_regnum (gdbarch, S390_SP_REGNUM);
+  set_gdbarch_fp_regnum (gdbarch, S390_FP_REGNUM);
+  set_gdbarch_fp0_regnum (gdbarch, S390_FP0_REGNUM);
+  set_gdbarch_num_regs (gdbarch, S390_NUM_REGS);
+  set_gdbarch_cannot_fetch_register (gdbarch, s390_cannot_fetch_register);
+  set_gdbarch_cannot_store_register (gdbarch, s390_cannot_fetch_register);
+  set_gdbarch_get_saved_register (gdbarch, generic_get_saved_register);
+  set_gdbarch_use_struct_convention (gdbarch, generic_use_struct_convention);
+  set_gdbarch_frame_chain_valid (gdbarch, file_frame_chain_valid);
+  set_gdbarch_register_name (gdbarch, s390_register_name);
+  set_gdbarch_stab_reg_to_regnum (gdbarch, s390_stab_reg_to_regnum);
+  set_gdbarch_dwarf_reg_to_regnum (gdbarch, s390_stab_reg_to_regnum);
+  set_gdbarch_dwarf2_reg_to_regnum (gdbarch, s390_stab_reg_to_regnum);
+
+
+  /* Stuff below here wouldn't be required if gdbarch.sh was a little */
+  /* more intelligent */
+  set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 0);
+  set_gdbarch_call_dummy_p (gdbarch, 1);
+  set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
+  set_gdbarch_extract_struct_value_address_p (gdbarch, 0);
+  switch (info.bfd_arch_info->mach)
+    {
+    case bfd_mach_s390_esa:
+      set_gdbarch_register_size (gdbarch, 4);
+      set_gdbarch_call_dummy_length (gdbarch, S390_CALL_DUMMY_LENGTH);
+      set_gdbarch_register_raw_size (gdbarch, s390_register_raw_size);
+      set_gdbarch_register_virtual_size (gdbarch, s390_register_raw_size);
+      set_gdbarch_register_virtual_type (gdbarch, s390_register_virtual_type);
+
+      set_gdbarch_addr_bits_remove (gdbarch, s390_addr_bits_remove);
+      set_gdbarch_fix_call_dummy (gdbarch, s390_fix_call_dummy);
+      set_gdbarch_sizeof_call_dummy_words (gdbarch,
+					   sizeof (s390_call_dummy_words));
+      set_gdbarch_call_dummy_words (gdbarch, s390_call_dummy_words);
+      break;
+    case bfd_mach_s390_esame:
+      set_gdbarch_register_size (gdbarch, 8);
+      set_gdbarch_call_dummy_length (gdbarch, S390X_CALL_DUMMY_LENGTH);
+      set_gdbarch_register_raw_size (gdbarch, s390x_register_raw_size);
+      set_gdbarch_register_virtual_size (gdbarch, s390x_register_raw_size);
+      set_gdbarch_register_virtual_type (gdbarch,
+					 s390x_register_virtual_type);
+
+      set_gdbarch_long_bit (gdbarch, 64);
+      set_gdbarch_long_long_bit (gdbarch, 64);
+      set_gdbarch_ptr_bit (gdbarch, 64);
+      set_gdbarch_fix_call_dummy (gdbarch, s390x_fix_call_dummy);
+      set_gdbarch_sizeof_call_dummy_words (gdbarch,
+					   sizeof (s390x_call_dummy_words));
+      set_gdbarch_call_dummy_words (gdbarch, s390x_call_dummy_words);
+      break;
+    }
+  /* REGISTER_SIZE is set up so this is correct here */
+  set_gdbarch_register_bytes (gdbarch, S390_REGISTER_BYTES);
+  return gdbarch;
+}
+#endif
+
+
+void
+_initialize_s390_tdep ()
+{
+  const bfd_arch_info_type *s390_arch_ptr =
+    bfd_lookup_arch (bfd_arch_s390, 0);
+
+#if GDB_MULTI_ARCH
+  /* Hook us into the gdbarch mechanism.  */
+  register_gdbarch_init (bfd_arch_s390, s390_gdbarch_init);
+#endif
+  if (!tm_print_insn)		/* Someone may have already set it */
+    tm_print_insn = gdb_print_insn_s390;
+  if (s390_arch_ptr)
+    tm_print_insn_info.mach = s390_arch_ptr->mach;
+  else
+    internal_error (__FILE__, __LINE__,
+		    "_initialize_s390_tdep: bfd_lookup_arch failed for bfd_arch_s390 recompile.\n");
+}
--- src.orig/gdb/gdbarch.sh	Thu Feb  8 07:03:53 2001
+++ src.new/gdb/gdbarch.sh	Tue Feb 27 20:12:37 2001
@@ -35,7 +35,7 @@
 
 
 # Format of the input table
-read="class level macro returntype function formal actual attrib staticdefault predefault postdefault invalid_p fmt print print_p description"
+read="class level macro returntype function formal actual attrib staticdefault predefault postdefault invalid_p fmt print print_p description allow_null_function null_function_default_retval"
 
 do_read ()
 {
@@ -303,7 +303,14 @@
     description ) : ;;
 
 	# Currently unused.
-
+    allow_null_function ) : ;;
+        # this definition is set to an
+	# non empty string if it is okay for the gdbarch function
+	# to be null.
+    null_function_default_retval ) : ;;
+        # this definiton is the
+	# default return value for a undefined function
+        # (i.e. allow_null_function is defined ).
     *) exit 1;;
   esac
 done
@@ -401,7 +408,7 @@
 v:2:CALL_DUMMY_LOCATION:int:call_dummy_location::::0:0
 f:2:CALL_DUMMY_ADDRESS:CORE_ADDR:call_dummy_address:void:::0:0::gdbarch->call_dummy_location == AT_ENTRY_POINT && gdbarch->call_dummy_address == 0
 v:2:CALL_DUMMY_START_OFFSET:CORE_ADDR:call_dummy_start_offset::::0:-1:::0x%08lx
-v:2:CALL_DUMMY_BREAKPOINT_OFFSET:CORE_ADDR:call_dummy_breakpoint_offset::::0:-1:::0x%08lx::CALL_DUMMY_BREAKPOINT_OFFSET_P
+v:2:CALL_DUMMY_BREAKPOINT_OFFSET:CORE_ADDR:call_dummy_breakpoint_offset::::0:-1::gdbarch->call_dummy_breakpoint_offset_p && gdbarch->call_dummy_breakpoint_offset == -1:0x%08lx::CALL_DUMMY_BREAKPOINT_OFFSET_P
 v:1:CALL_DUMMY_BREAKPOINT_OFFSET_P:int:call_dummy_breakpoint_offset_p::::0:-1
 v:2:CALL_DUMMY_LENGTH:int:call_dummy_length::::0:-1:::::CALL_DUMMY_LOCATION == BEFORE_TEXT_END || CALL_DUMMY_LOCATION == AFTER_TEXT_END
 f:2:PC_IN_CALL_DUMMY:int:pc_in_call_dummy:CORE_ADDR pc, CORE_ADDR sp, CORE_ADDR frame_address:pc, sp, frame_address::0:0
@@ -436,7 +443,7 @@
 f:2:EXTRACT_RETURN_VALUE:void:extract_return_value:struct type *type, char *regbuf, char *valbuf:type, regbuf, valbuf::0:0
 f:1:PUSH_ARGUMENTS:CORE_ADDR:push_arguments:int nargs, struct value **args, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr:nargs, args, sp, struct_return, struct_addr::0:0
 f:2:PUSH_DUMMY_FRAME:void:push_dummy_frame:void:-:::0
-f:1:PUSH_RETURN_ADDRESS:CORE_ADDR:push_return_address:CORE_ADDR pc, CORE_ADDR sp:pc, sp:::0
+f:1:PUSH_RETURN_ADDRESS:CORE_ADDR:push_return_address:CORE_ADDR pc, CORE_ADDR sp:pc, sp:::0::0:::::1:sp
 f:2:POP_FRAME:void:pop_frame:void:-:::0
 #
 # I wish that these would just go away....
@@ -449,7 +456,8 @@
 #
 f:2:STORE_STRUCT_RETURN:void:store_struct_return:CORE_ADDR addr, CORE_ADDR sp:addr, sp:::0
 f:2:STORE_RETURN_VALUE:void:store_return_value:struct type *type, char *valbuf:type, valbuf:::0
-f:2:EXTRACT_STRUCT_VALUE_ADDRESS:CORE_ADDR:extract_struct_value_address:char *regbuf:regbuf:::0
+f:2:EXTRACT_STRUCT_VALUE_ADDRESS:CORE_ADDR:extract_struct_value_address:char *regbuf:regbuf::0:0::gdbarch->extract_struct_value_address_p && gdbarch->extract_struct_value_address == 0
+v:2:EXTRACT_STRUCT_VALUE_ADDRESS_P:int:extract_struct_value_address_p::::0:-1
 f:2:USE_STRUCT_CONVENTION:int:use_struct_convention:int gcc_p, struct type *value_type:gcc_p, value_type:::0
 #
 f:2:FRAME_INIT_SAVED_REGS:void:frame_init_saved_regs:struct frame_info *frame:frame::0:0
@@ -459,6 +467,10 @@
 f:2:PROLOGUE_FRAMELESS_P:int:prologue_frameless_p:CORE_ADDR ip:ip::0:generic_prologue_frameless_p::0
 f:2:INNER_THAN:int:inner_than:CORE_ADDR lhs, CORE_ADDR rhs:lhs, rhs::0:0
 f:2:BREAKPOINT_FROM_PC:unsigned char *:breakpoint_from_pc:CORE_ADDR *pcptr, int *lenptr:pcptr, lenptr:::legacy_breakpoint_from_pc::0
+f:2:INIT_FRAME_PC_FIRST:void:init_frame_pc_first:int fromleaf,struct frame_info *fi:fromleaf,fi::::::::::1
+f:2:CANNOT_STORE_REGISTER:int:cannot_store_register:int regno:regno::::::::::1:0
+f:2:CANNOT_FETCH_REGISTER:int:cannot_fetch_register:int regno:regno::::::::::1:0
+f:2:ADDR_BITS_REMOVE:CORE_ADDR:addr_bits_remove:CORE_ADDR addr:addr::::::::::1:addr
 f:2:MEMORY_INSERT_BREAKPOINT:int:memory_insert_breakpoint:CORE_ADDR addr, char *contents_cache:addr, contents_cache::0:default_memory_insert_breakpoint::0
 f:2:MEMORY_REMOVE_BREAKPOINT:int:memory_remove_breakpoint:CORE_ADDR addr, char *contents_cache:addr, contents_cache::0:default_memory_remove_breakpoint::0
 v:2:DECR_PC_AFTER_BREAK:CORE_ADDR:decr_pc_after_break::::0:-1
@@ -1440,12 +1452,25 @@
 	  printf "gdbarch_${function} (struct gdbarch *gdbarch, ${formal})\n"
 	fi
 	printf "{\n"
-        printf "  if (gdbarch->${function} == 0)\n"
-        printf "    internal_error (__FILE__, __LINE__,\n"
-	printf "                    \"gdbarch: gdbarch_${function} invalid\");\n"
+	if [ "${allow_null_function}" = "" ]
+	then
+	    printf "  if (gdbarch->${function} == 0)\n"
+	    printf "    internal_error (__FILE__, __LINE__,\n"
+	    printf "                    \"gdbarch: gdbarch_${function} invalid\");\n"
+	fi
 	printf "  if (gdbarch_debug >= 2)\n"
 	printf "    fprintf_unfiltered (gdb_stdlog, \"gdbarch_${function} called\\\\n\");\n"
         test "${actual}" = "-" && actual=""
+ 	if [ "${allow_null_function}" ]
+ 	then
+ 	  printf "  if (gdbarch->${function} == 0)\n"
+ 	  if [ "${returntype}" = "void" ]
+ 	  then
+ 	    printf "    return;\n"
+ 	  else
+ 	    printf "    return ${null_function_default_retval};\n"
+            fi
+ 	fi
        	if [ "${returntype}" = "void" ]
 	then
 	  printf "  gdbarch->${function} (${actual});\n"
--- src.orig/gdb/core-aout.c	Sun Jul 30 03:48:24 2000
+++ src.new/gdb/core-aout.c	Tue Feb 27 17:36:35 2001
@@ -81,6 +81,7 @@
   int bad_reg = -1;
   CORE_ADDR reg_ptr = -reg_addr;	/* Original u.u_ar0 is -reg_addr. */
   int numregs = ARCH_NUM_REGS;
+  char *buf=alloca(MAX_REGISTER_RAW_SIZE);
 
   /* If u.u_ar0 was an absolute address in the core file, relativize it now,
      so we can use it as an offset into core_reg_sect.  When we're done,
@@ -93,12 +94,20 @@
 
   for (regno = 0; regno < numregs; regno++)
     {
-      addr = CORE_REGISTER_ADDR (regno, reg_ptr);
-      if (addr >= core_reg_size
-	  && bad_reg < 0)
-	bad_reg = regno;
+       if (CANNOT_FETCH_REGISTER (regno))
+	{
+	  memset (buf, '\0', REGISTER_RAW_SIZE (regno));	/* Supply zeroes */
+	  supply_register (regno, buf);
+	}
       else
-	supply_register (regno, core_reg_sect + addr);
+	{
+	  addr = CORE_REGISTER_ADDR (regno, reg_ptr);
+	  if (addr >= core_reg_size
+	      && bad_reg < 0)
+	    bad_reg = regno;
+	  else
+	    supply_register (regno, core_reg_sect + addr);
+	}
     }
 
   if (bad_reg >= 0)

[-- Attachment #5: gdb.s390.270201.readline.config.diff --]
[-- Type: text/x-diff, Size: 261 bytes --]

--- src.orig/readline/configure.in	Sun Jul  9 19:19:56 2000
+++ src.new/readline/configure.in	Mon Feb 26 17:58:04 2001
@@ -129,6 +129,7 @@
 
 case "$host_cpu" in
 *cray*)	LOCAL_CFLAGS=-DCRAY ;;
+*s390*) LOCAL_CFLAGS=-fsigned-char ;;
 esac
 
 case "$host_os" in

[-- Attachment #6: S390ChangeLog.gdb --]
[-- Type: text/plain, Size: 1444 bytes --]

2001-02-26  D.J. Barrow <djbarrow@de.ibm.com,barrow_dj@yahoo.com>
	* s390-nat.c New file Added for S/390 31 & 64 bit target.
	* s390-tdep.c Likewise.
	* config/s390/nm-linux.h Likewise.	 
	* config/s390/s390x.mt Likewise.
	* config/s390/tm-linux.h  Likewise.  
	* config/s390/xm-linux.h Likewise
	* config/s390/s390.mh Likewise.
	* config/s390/s390.mt Likewise.
	* config/s390/tm-s390.h Likewise.
        * config.in Added definitions for S/390 31 & 64 bit target.
	* configure.host Likewise.
	* configure.in Likewise.
	* configure.tgt  Likewise.

        * gdbarch.sh Added 2 definitions to the input table
	allow_null_function, this definition is set to an
	non empty string if it is okay for the gdbarch function
	to be null.
	null_function_default_retval, this definiton is the
	default return value for a undefined function
	(i.e. allow_null_function is defined ).
	Added new macros required for S/390
	INIT_FRAME_PC_FIRST
	CANNOT_STORE_REGISTER
	CANNOT_FETCH_REGISTER
	ADDR_BITS_REMOVE
	EXTRACT_STRUCT_VALUE_ADDRESS_P        

	Improved the behaviour of the following macros.
	PUSH_RETURN_ADDRESS 
	added allow null function so default behaviour would be correct.
	EXTRACT_STRUCT_VALUE_ADDRESS
	added check for EXTRACT_STRUCT_VALUE_ADDRESS_P
	CALL_DUMMY_BREAKPOINT_OFFSET

	* core-aout.c added check for CANNOT_FETCH_REGISTER
	in fetch_core_registers.
	* arch-utils.c added check for BFD_ENDIAN_UNKNOWN
	in set_endian_from_file.










[-- Attachment #7: S390ChangeLog.Root --]
[-- Type: text/plain, Size: 173 bytes --]

2001-02-26  D.J. Barrow <djbarrow@de.ibm.com,barrow_dj@yahoo.com>
	* config.sub: Added S/390 31 & 64 bit target.
	* configure.in: Likewise.
        * config.guess: Likewise.

             reply	other threads:[~2001-02-27 12:39 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-02-27 12:39 DJBARROW [this message]
2001-02-28 16:13 ` Nick Clifton
2001-06-15  8:15 ` s390 readline; Was: " Andrew Cagney
2001-06-15 10:27   ` Elena Zannoni
2001-06-15 16:26     ` Elena Zannoni
2001-06-15  9:53 ` Andrew Cagney
2001-06-15 11:46   ` Andreas Jaeger
2001-06-15 12:22     ` Andrew Cagney
2001-06-15 12:18 ` [patch] Add predicate for EXTRACT_STRUCT_VALUE_ADDRESS; Was: " Andrew Cagney
2001-06-15 23:56   ` Eli Zaretskii
2001-06-28 16:58     ` Andrew Cagney
2001-06-28 23:21       ` Eli Zaretskii
2001-06-15 15:09 ` [patch] multi-arch ADDR_BITS_REMOVE; " Andrew Cagney
2001-06-15 16:09 ` [patch] multi-arch INIT_FRAME_PC*; " Andrew Cagney
2001-06-15 16:46 ` [patch] multi-arch CANNOT_^&*^*&_REGISTER(); " Andrew Cagney
2001-07-04 11:25 ` Andrew Cagney
2001-07-04 21:02 ` Andrew Cagney
2001-07-04 21:02 ` Andrew Cagney
2001-07-04 21:02 ` Andrew Cagney
2001-03-01  2:50 DJBARROW
2001-03-01 10:37 ` Nick Clifton
     [not found] <C1256A02.00573066.00@d12mta09.de.ibm.com>
2001-03-01 10:39 ` Nick Clifton
2001-06-18  3:32 DJBARROW
2001-07-05  3:12 Denis Joseph Barrow
2001-07-05  3:57 Denis Joseph Barrow
2001-07-05 10:11 ` Andrew Cagney
2001-07-05 10:11 ` Andrew Cagney
2001-07-05  5:04 Denis Joseph Barrow
2001-07-05  9:15 Denis Joseph Barrow
2001-07-05  9:19 Denis Joseph Barrow
2001-07-05 12:36 ` Andrew Cagney
2001-07-05 10:24 Denis Joseph Barrow
2001-07-05 12:46 ` Andrew Cagney
2001-07-08  0:53   ` Eli Zaretskii
2001-07-08 19:23     ` Andrew Cagney
2001-07-06  2:31 Denis Joseph Barrow
2001-08-13  3:06 Denis Joseph Barrow
2001-08-13  9:31 ` Andrew Cagney
2001-08-13  9:47 Denis Joseph Barrow
2001-08-15  2:22 Denis Joseph Barrow
2001-08-15  9:03 ` Andrew Cagney
2001-08-15  9:54 ` Andrew Cagney
     [not found] <OFEFF0AD94.761C34C1-ONC1256AB6.005503EE@de.ibm.com>
2001-08-28 16:33 ` Daniel Jacobowitz
2001-09-05 21:45   ` Andrew Cagney

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=C1256A00.006F3FCE.00@d12mta09.de.ibm.com \
    --to=djbarrow@de.ibm.com \
    --cc=ARENZ@de.ibm.com \
    --cc=bash_maintainers@gnu.org \
    --cc=binutils@sourceware.cygnus.com \
    --cc=gdb-patches@sourceware.cygnus.com \
    --cc=s390-patches@gnu.org \
    --cc=schwidefsky@de.ibm.com \
    /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