Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* New gdb 31 & 64 bit patches for S/390
@ 2001-02-27 12:39 DJBARROW
  2001-02-28 16:13 ` Nick Clifton
                   ` (10 more replies)
  0 siblings, 11 replies; 44+ messages in thread
From: DJBARROW @ 2001-02-27 12:39 UTC (permalink / raw)
  To: gdb-patches, s390-patches, Binutils Patches, bash_maintainers
  Cc: schwidefsky, ARENZ

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

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: New gdb 31 & 64 bit patches for S/390
  2001-02-27 12:39 New gdb 31 & 64 bit patches for S/390 DJBARROW
@ 2001-02-28 16:13 ` Nick Clifton
  2001-06-15  8:15 ` s390 readline; Was: " Andrew Cagney
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 44+ messages in thread
From: Nick Clifton @ 2001-02-28 16:13 UTC (permalink / raw)
  To: DJBARROW; +Cc: gdb-patches, s390-patches, Binutils Patches, ARENZ

Hi David,

  Sorry to be picky - but are you the author of these patches, and if
  so, do you have a copyright assignment (for both binutils and GDB)
  on file with the FSF ?

Cheers
        Nick


^ permalink raw reply	[flat|nested] 44+ messages in thread

* s390 readline; Was: New gdb 31 & 64 bit patches for S/390
  2001-02-27 12:39 New gdb 31 & 64 bit patches for S/390 DJBARROW
  2001-02-28 16:13 ` Nick Clifton
@ 2001-06-15  8:15 ` Andrew Cagney
  2001-06-15 10:27   ` Elena Zannoni
  2001-06-15  9:53 ` Andrew Cagney
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 44+ messages in thread
From: Andrew Cagney @ 2001-06-15  8:15 UTC (permalink / raw)
  To: Elena Zannoni; +Cc: DJBARROW, gdb-patches, schwidefsky, ARENZ

Elena,

I found this in the s390 patches for GDB. Given it was CC'd to 
bash_maintainers I guess it, or an equivalent, was merged into the the 
latest readline.

I couldn't find the ChangeLog entry, can you make one up?

	Andrew

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



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: New gdb 31 & 64 bit patches for S/390
  2001-02-27 12:39 New gdb 31 & 64 bit patches for S/390 DJBARROW
  2001-02-28 16:13 ` Nick Clifton
  2001-06-15  8:15 ` s390 readline; Was: " Andrew Cagney
@ 2001-06-15  9:53 ` Andrew Cagney
  2001-06-15 11:46   ` Andreas Jaeger
  2001-06-15 12:18 ` [patch] Add predicate for EXTRACT_STRUCT_VALUE_ADDRESS; Was: " Andrew Cagney
                   ` (7 subsequent siblings)
  10 siblings, 1 reply; 44+ messages in thread
From: Andrew Cagney @ 2001-06-15  9:53 UTC (permalink / raw)
  To: DJBARROW; +Cc: gdb-patches, s390-patches, schwidefsky, ARENZ

Hello,

I intend checking in the attatched (diff) patch.  Before doing it 
though, is the s390 really a 31 bit architecture?

For reference I've also included the original diff and ChangeLog.

	Andrew
From ac131313@cygnus.com Fri Jun 15 09:56:00 2001
From: Andrew Cagney <ac131313@cygnus.com>
To: DJBARROW@de.ibm.com
Cc: gdb-patches@sourceware.cygnus.com, s390-patches@gnu.org, schwidefsky@de.ibm.com, ARENZ@de.ibm.com
Subject: Re: New gdb 31 & 64 bit patches for S/390
Date: Fri, 15 Jun 2001 09:56:00 -0000
Message-id: <3B2A3E33.3000906@cygnus.com>
References: <C1256A00.006F3FCE.00@d12mta09.de.ibm.com>
X-SW-Source: 2001-06/msg00297.html
Content-length: 540

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


I believe this was a bug in the logic that selected the current 
architecture and was recently fixed.

	Andrew



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: s390 readline; Was: New gdb 31 & 64 bit patches for S/390
  2001-06-15  8:15 ` s390 readline; Was: " Andrew Cagney
@ 2001-06-15 10:27   ` Elena Zannoni
  2001-06-15 16:26     ` Elena Zannoni
  0 siblings, 1 reply; 44+ messages in thread
From: Elena Zannoni @ 2001-06-15 10:27 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: Elena Zannoni, DJBARROW, gdb-patches, schwidefsky, ARENZ

Andrew Cagney writes:
 > Elena,
 > 
 > I found this in the s390 patches for GDB. Given it was CC'd to 
 > bash_maintainers I guess it, or an equivalent, was merged into the the 
 > latest readline.
 > 

Yes, I just checked. It is in Readline 4.2.

 > I couldn't find the ChangeLog entry, can you make one up?
 > 

This is what the readline ChangeLog says:

configure.in
        - add -fsigned-char to LOCAL_CFLAGS for Linux running on the IBM
          S/390


Elena


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


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: New gdb 31 & 64 bit patches for S/390
  2001-06-15  9:53 ` Andrew Cagney
@ 2001-06-15 11:46   ` Andreas Jaeger
  2001-06-15 12:22     ` Andrew Cagney
  0 siblings, 1 reply; 44+ messages in thread
From: Andreas Jaeger @ 2001-06-15 11:46 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: DJBARROW, gdb-patches, s390-patches, schwidefsky, ARENZ

Andrew Cagney <ac131313@cygnus.com> writes:

> Hello,
> 
> I intend checking in the attatched (diff) patch.  Before doing it
> though, is the s390 really a 31 bit architecture?

Yes, it is.

AFAIR: It has 32 bits but the most significant bit is used to signal
that the hardware is using the "new" mode which has 31 bit instead of
the "old" mode with 24 (???) bits.  For Linux/S390 only the 31 bit
mode is used.

Andreas

> 
> For reference I've also included the original diff and ChangeLog.
> 
> 	Andrew
> 2001-06-15  Andrew Cagney  <ac131313@redhat.com>
> 
> 	From 2001-02-26  D.J. Barrow <djbarrow@de.ibm.com>:
> 	* configure.tgt: Add S/390 31 & 64 bit target configuration.
> 	* configure.host: Ditto for host.
> 
> Index: configure.host
> ===================================================================
> RCS file: /cvs/src/src/gdb/configure.host,v
> retrieving revision 1.21
> diff -p -r1.21 configure.host
> *** configure.host	2001/06/07 15:57:57	1.21
> --- configure.host	2001/06/15 16:46:05
> *************** m68*)			gdb_host_cpu=m68k ;;
> *** 18,23 ****
> --- 18,24 ----
>   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
> *************** powerpc-*-netbsd*)	gdb_host=nbsd ;;
> *** 138,143 ****
> --- 139,146 ----
>   rs6000-*-lynxos*)	gdb_host=rs6000lynx ;;
>   rs6000-*-aix4*)		gdb_host=aix4 ;;
>   rs6000-*-*)		gdb_host=rs6000 ;;
>+ 
>+ s390*-*-*)		gdb_host=s390 ;;
>   
>   sparc-*-linux*)		gdb_host=linux ;;
>   sparc-*-lynxos*)	gdb_host=sparclynx ;;
> Index: configure.tgt
> ===================================================================
> RCS file: /cvs/src/src/gdb/configure.tgt,v
> retrieving revision 1.29
> diff -p -r1.29 configure.tgt
> *** configure.tgt	2001/06/07 15:57:57	1.29
> --- configure.tgt	2001/06/15 16:46:05
> *************** mips*)			gdb_target_cpu=mips ;;
> *** 23,28 ****
> --- 23,29 ----
>   powerpc*)		gdb_target_cpu=powerpc ;;
>   sparc*)			gdb_target_cpu=sparc ;;
>   thumb*)			gdb_target_cpu=arm ;;
>+ s390*)			gdb_target_cpu=s390 ;;
>   strongarm*)		gdb_target_cpu=arm ;;
>   xscale*)		gdb_target_cpu=arm ;;
>   v850*)			gdb_target_cpu=v850 ;;
> *************** rs6000-*-lynxos*)	gdb_target=rs6000lynx
> *** 255,260 ****
> --- 256,264 ----
>   		configdirs="${configdirs} gdbserver" ;;
>   rs6000-*-aix4*)		gdb_target=aix4 ;;
>   rs6000-*-*)		gdb_target=rs6000 ;;
>+ 
>+ s390-*-*)		gdb_target=s390 ;;
>+ s390x-*-*)		gdb_target=s390x ;;
>   
>   sh*-*-pe)		gdb_target=wince ;;
>   sh-*-hms)		gdb_target=embed ;;
> 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.
> 
> 
> 
> 
> 
> 
> 
> 
> 
> --- 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
>  
>  

-- 
 Andreas Jaeger
  SuSE Labs aj@suse.de
   private aj@arthur.inka.de
    http://www.suse.de/~aj


^ permalink raw reply	[flat|nested] 44+ messages in thread

* [patch] Add predicate for EXTRACT_STRUCT_VALUE_ADDRESS; Was: New gdb 31 & 64 bit patches for S/390
  2001-02-27 12:39 New gdb 31 & 64 bit patches for S/390 DJBARROW
                   ` (2 preceding siblings ...)
  2001-06-15  9:53 ` Andrew Cagney
@ 2001-06-15 12:18 ` Andrew Cagney
  2001-06-15 23:56   ` Eli Zaretskii
  2001-06-15 15:09 ` [patch] multi-arch ADDR_BITS_REMOVE; " Andrew Cagney
                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 44+ messages in thread
From: Andrew Cagney @ 2001-06-15 12:18 UTC (permalink / raw)
  To: DJBARROW; +Cc: gdb-patches, s390-patches, schwidefsky, ARENZ

FYI,

I'm going to check in the attached cleanup.  It converts 
EXTRACT_STRUCT_VALUE_ADDRESS into a function with predicate 
EXTRACT_STRUCT_VALUE_ADDRESS_P.  By doing this, I've eliminated the need 
to add a seprate EXTRACT_STRUCT_VALUE_ADDRESS_P variable to the gdbarch 
vector.

For reference, I've also included the relevant bits of the original patch.

	Andrew


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: New gdb 31 & 64 bit patches for S/390
  2001-06-15 11:46   ` Andreas Jaeger
@ 2001-06-15 12:22     ` Andrew Cagney
  0 siblings, 0 replies; 44+ messages in thread
From: Andrew Cagney @ 2001-06-15 12:22 UTC (permalink / raw)
  To: Andreas Jaeger; +Cc: DJBARROW, gdb-patches, s390-patches, schwidefsky, ARENZ

> Yes, it is.
> 
> AFAIR: It has 32 bits but the most significant bit is used to signal
> that the hardware is using the "new" mode which has 31 bit instead of
> the "old" mode with 24 (???) bits. For Linux/S390 only the 31 bit
> mode is used.
> 

Ah, thanks.  The change is in.

	Andrew


^ permalink raw reply	[flat|nested] 44+ messages in thread

* [patch] multi-arch ADDR_BITS_REMOVE; Was: New gdb 31 & 64 bit patches for S/390
  2001-02-27 12:39 New gdb 31 & 64 bit patches for S/390 DJBARROW
                   ` (3 preceding siblings ...)
  2001-06-15 12:18 ` [patch] Add predicate for EXTRACT_STRUCT_VALUE_ADDRESS; Was: " Andrew Cagney
@ 2001-06-15 15:09 ` Andrew Cagney
  2001-06-15 16:09 ` [patch] multi-arch INIT_FRAME_PC*; " Andrew Cagney
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 44+ messages in thread
From: Andrew Cagney @ 2001-06-15 15:09 UTC (permalink / raw)
  To: DJBARROW; +Cc: gdb-patches, s390-patches, schwidefsky, ARENZ

Hello,

(more s390 fallout) This patch multi-arches the ADDR_BITS_REMOVE 
function.  It uses a generic core_addr_identity() function as the default.

	Andrew
From msnyder@cygnus.com Fri Jun 15 15:42:00 2001
From: Michael Snyder <msnyder@cygnus.com>
To: gdb-patches@sources.redhat.com
Subject: Re: [RFC PATCH] normalize "thread hop" handling
Date: Fri, 15 Jun 2001 15:42:00 -0000
Message-id: <3B2A8F6A.4A6B0D9F@cygnus.com>
References: <3B2573B6.5E444250@cygnus.com>
X-SW-Source: 2001-06/msg00305.html
Content-length: 10029

Michael Snyder wrote:
> 
> This patch normalizes the infrun handling of the "thread hop" event,
> when the wrong thread hits a thread-specific breakpoint and we need to
> singlestep that thread (only) before re-inserting breakpoints.
> 
> The big benefit of this patch is that when we get the subsequent
> singlestep-trap, we process it normally in handle_inferior_event
> instead of just calling resume.  This prevents bad things like
> failing to stop if the step takes us out of a stepping range.
> 
> If nobody yells, I'll check it in in a few days.

Nobody yelled, so I'm committing this patch.

Michael
> 
>   ----------------------------------------------------------------------------------------------------
> 2001-06-11  Michael Snyder  <msnyder@redhat.com>
> 
>         * infrun.c (context_switch): New function.  Abstract the operation
>         of saving and restoring infrun's state when switching threads.
>         (handle_inferior_event): Normalize the handling of the 'thread hop'
>         event (when the wrong thread hits a thread-specific breakpoint,
>         and we need to solo-step that thread past the breakpoint).
>         Call keep_going, instead of target_resume.  Handle the subsequent
>         singlestep-trap as a normal event instead of just resuming.
> 
> Index: infrun.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/infrun.c,v
> retrieving revision 1.35
> diff -c -3 -p -r1.35 infrun.c
> *** infrun.c    2001/06/02 00:36:20     1.35
> --- infrun.c    2001/06/12 01:34:46
> *************** get_last_target_status(ptid_t *ptidp, st
> *** 1433,1438 ****
> --- 1433,1477 ----
>     *status = target_last_waitstatus;
>   }
> 
> + /* Switch thread contexts, maintaining "infrun state". */
> +
> + static void
> + context_switch (struct execution_control_state *ecs)
> + {
> +   /* Caution: it may happen that the new thread (or the old one!)
> +      is not in the thread list.  In this case we must not attempt
> +      to "switch context", or we run the risk that our context may
> +      be lost.  This may happen as a result of the target module
> +      mishandling thread creation.  */
> +
> +   if (in_thread_list (inferior_ptid) && in_thread_list (ecs->ptid))
> +     { /* Perform infrun state context switch: */
> +       /* Save infrun state for the old thread.  */
> +       save_infrun_state (inferior_ptid, prev_pc,
> +                        prev_func_start, prev_func_name,
> +                        trap_expected, step_resume_breakpoint,
> +                        through_sigtramp_breakpoint, step_range_start,
> +                        step_range_end, step_frame_address,
> +                        ecs->handling_longjmp, ecs->another_trap,
> +                        ecs->stepping_through_solib_after_catch,
> +                        ecs->stepping_through_solib_catchpoints,
> +                        ecs->stepping_through_sigtramp);
> +
> +       /* Load infrun state for the new thread.  */
> +       load_infrun_state (ecs->ptid, &prev_pc,
> +                        &prev_func_start, &prev_func_name,
> +                        &trap_expected, &step_resume_breakpoint,
> +                        &through_sigtramp_breakpoint, &step_range_start,
> +                        &step_range_end, &step_frame_address,
> +                        &ecs->handling_longjmp, &ecs->another_trap,
> +                        &ecs->stepping_through_solib_after_catch,
> +                        &ecs->stepping_through_solib_catchpoints,
> +                        &ecs->stepping_through_sigtramp);
> +     }
> +   inferior_ptid = ecs->ptid;
> + }
> +
> +
>   /* Given an execution control state that has been freshly filled in
>      by an event from the inferior, figure out what it means and take
>      appropriate action.  */
> *************** handle_inferior_event (struct execution_
> *** 1451,1456 ****
> --- 1490,1500 ----
>     {
>       switch (ecs->infwait_state)
>         {
> +       case infwait_thread_hop_state:
> +       /* Cancel the waiton_ptid. */
> +       ecs->waiton_ptid = pid_to_ptid (-1);
> +       /* Fall thru to the normal_state case. */
> +
>         case infwait_normal_state:
>         /* Since we've done a wait, we have a new event.  Don't
>            carry over any expectations about needing to step over a
> *************** handle_inferior_event (struct execution_
> *** 1467,1491 ****
>         stepped_after_stopped_by_watchpoint = 0;
>         break;
> 
> -       case infwait_thread_hop_state:
> -       insert_breakpoints ();
> -
> -       /* We need to restart all the threads now,
> -        * unless we're running in scheduler-locked mode.
> -        * Use currently_stepping to determine whether to
> -        * step or continue.
> -        */
> -
> -       if (scheduler_mode == schedlock_on)
> -         target_resume (ecs->ptid,
> -                        currently_stepping (ecs), TARGET_SIGNAL_0);
> -       else
> -         target_resume (RESUME_ALL,
> -                        currently_stepping (ecs), TARGET_SIGNAL_0);
> -       ecs->infwait_state = infwait_normal_state;
> -       prepare_to_wait (ecs);
> -       return;
> -
>         case infwait_nullified_state:
>         break;
> 
> --- 1511,1516 ----
> *************** handle_inferior_event (struct execution_
> *** 1888,1893 ****
> --- 1913,1919 ----
>                      * Use currently_stepping to determine whether to
>                      * step or continue.
>                      */
> +                   /* FIXME MVS: is there any reason not to call resume()? */
>                     if (scheduler_mode == schedlock_on)
>                       target_resume (ecs->ptid,
>                                      currently_stepping (ecs),
> *************** handle_inferior_event (struct execution_
> *** 1901,1914 ****
>                   }
>                 else
>                   {             /* Single step */
> !                   target_resume (ecs->ptid, 1, TARGET_SIGNAL_0);
> !                   /* FIXME: What if a signal arrives instead of the
> !                      single-step happening?  */
> !
>                     ecs->waiton_ptid = ecs->ptid;
>                     ecs->wp = &(ecs->ws);
>                     ecs->infwait_state = infwait_thread_hop_state;
> !                   prepare_to_wait (ecs);
>                     return;
>                   }
>               }
> --- 1927,1949 ----
>                   }
>                 else
>                   {             /* Single step */
> !                   breakpoints_inserted = 0;
> !                   if (!ptid_equal (inferior_ptid, ecs->ptid))
> !                     context_switch (ecs);
>                     ecs->waiton_ptid = ecs->ptid;
>                     ecs->wp = &(ecs->ws);
> +                   thread_step_needed = 1;
> +                   ecs->another_trap = 1;
> +
> +                   /* keep_stepping will call resume, and the
> +                      combination of "thread_step_needed" and
> +                      "ecs->another_trap" will cause resume to
> +                      solo-step the thread.  The subsequent trap
> +                      event will be handled like any other singlestep
> +                      event. */
> +
>                     ecs->infwait_state = infwait_thread_hop_state;
> !                   keep_going (ecs);
>                     return;
>                   }
>               }
> *************** handle_inferior_event (struct execution_
> *** 1983,2022 ****
>         /* It's a SIGTRAP or a signal we're interested in.  Switch threads,
>            and fall into the rest of wait_for_inferior().  */
> 
> !       /* Caution: it may happen that the new thread (or the old one!)
> !          is not in the thread list.  In this case we must not attempt
> !          to "switch context", or we run the risk that our context may
> !          be lost.  This may happen as a result of the target module
> !          mishandling thread creation.  */
> !
> !       if (in_thread_list (inferior_ptid) && in_thread_list (ecs->ptid))
> !         { /* Perform infrun state context switch: */
> !           /* Save infrun state for the old thread.  */
> !           save_infrun_state (inferior_ptid, prev_pc,
> !                              prev_func_start, prev_func_name,
> !                              trap_expected, step_resume_breakpoint,
> !                              through_sigtramp_breakpoint,
> !                              step_range_start, step_range_end,
> !                              step_frame_address, ecs->handling_longjmp,
> !                              ecs->another_trap,
> !                              ecs->stepping_through_solib_after_catch,
> !                              ecs->stepping_through_solib_catchpoints,
> !                              ecs->stepping_through_sigtramp);
> !
> !           /* Load infrun state for the new thread.  */
> !           load_infrun_state (ecs->ptid, &prev_pc,
> !                              &prev_func_start, &prev_func_name,
> !                              &trap_expected, &step_resume_breakpoint,
> !                              &through_sigtramp_breakpoint,
> !                              &step_range_start, &step_range_end,
> !                              &step_frame_address, &ecs->handling_longjmp,
> !                              &ecs->another_trap,
> !                              &ecs->stepping_through_solib_after_catch,
> !                              &ecs->stepping_through_solib_catchpoints,
> !                              &ecs->stepping_through_sigtramp);
> !         }
> !
> !       inferior_ptid = ecs->ptid;
> 
>         if (context_hook)
>           context_hook (pid_to_thread_id (ecs->ptid));
> --- 2018,2024 ----
>         /* It's a SIGTRAP or a signal we're interested in.  Switch threads,
>            and fall into the rest of wait_for_inferior().  */
> 
> !       context_switch (ecs);
> 
>         if (context_hook)
>           context_hook (pid_to_thread_id (ecs->ptid));


^ permalink raw reply	[flat|nested] 44+ messages in thread

* [patch] multi-arch INIT_FRAME_PC*; Was: New gdb 31 & 64 bit patches for S/390
  2001-02-27 12:39 New gdb 31 & 64 bit patches for S/390 DJBARROW
                   ` (4 preceding siblings ...)
  2001-06-15 15:09 ` [patch] multi-arch ADDR_BITS_REMOVE; " Andrew Cagney
@ 2001-06-15 16:09 ` Andrew Cagney
  2001-06-15 16:46 ` [patch] multi-arch CANNOT_^&*^*&_REGISTER(); " Andrew Cagney
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 44+ messages in thread
From: Andrew Cagney @ 2001-06-15 16:09 UTC (permalink / raw)
  To: DJBARROW; +Cc: gdb-patches, schwidefsky, ARENZ

Hello,

I've checked in the attatched, it multi-arches INIT_FRAME_PC_FIRST.  (I 
also got a little carried away and multi-arched INIT_FRAME_PC as well :-)

	Andrew
From msnyder@cygnus.com Fri Jun 15 16:22:00 2001
From: Michael Snyder <msnyder@cygnus.com>
To: "Peter.Schauer" <Peter.Schauer@Regent.E-Technik.TU-Muenchen.DE>, gdb-patches@sources.redhat.com
Subject: [RFC] if (INNER_THAN (read_sp(), step_sp - 16))
Date: Fri, 15 Jun 2001 16:22:00 -0000
Message-id: <3B2A97C7.52A839FD@cygnus.com>
X-SW-Source: 2001-06/msg00307.html
Content-length: 1134

Hellooooooo, Peter Schauer!

Back in April of 1998 a patch from you was checked in (you may have
submitted it some time earlier) for x86 Solaris.  Among other things,
it contained a test in infrun.c (wait_for_inferior) that looked like:

	[stuff...]
	(CURRENTLY_STEPPING ()
	&& prev_pc != stop_pc - DECR_PC_AFTER_BREAK
	&& !(step_range_end
	    && read_sp () INNER_THAN (step_sp - 16)));

A comment explains that the INNER_THAN expression is meant to detect
hitting a breakpoint in a signal handler without an intervening stop
in sigtramp.

The lines have metamorphosed since then, but the expression with
(step_sp - 16) is still in there, and I would really like to get
rid of it.  Especially since I have now found that it can cause
serious bugs in debugging native Linux x86.

But I have no idea how to detect the situation that you are 
trying to test for.  So I'd like to toss it back to you.
Can you find a better way to test for this?  Maybe with 
(ugh) another state variable?

And if not, can you put those two lines into an ifdef, 
so they won't affect targets for which they're not intended?

			Thanks a lot, 
			Michael


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: s390 readline; Was: New gdb 31 & 64 bit patches for S/390
  2001-06-15 10:27   ` Elena Zannoni
@ 2001-06-15 16:26     ` Elena Zannoni
  0 siblings, 0 replies; 44+ messages in thread
From: Elena Zannoni @ 2001-06-15 16:26 UTC (permalink / raw)
  To: Elena Zannoni; +Cc: Andrew Cagney, DJBARROW, gdb-patches, schwidefsky, ARENZ

I just committed this, including a coreresponding change to configure.

2001-06-15  Elena Zannoni  <ezannoni@redhat.com>

       * configure.in: Add -fsigned-char to LOCAL_CFLAGS for Linux
       running on the IBM S/390.
       * configure: Ditto.

Index: configure
===================================================================
RCS file: /cvs/src/src/readline/configure,v
retrieving revision 1.3
diff -u -p -r1.3 configure
--- configure   2000/07/09 17:19:56     1.3
+++ configure   2001/06/15 23:24:03
@@ -2542,6 +2542,7 @@ fi
 
 case "$host_cpu" in
 *cray*)        LOCAL_CFLAGS=-DCRAY ;;
+*s390*)        LOCAL_CFLAGS=-fsigned-char ;;
 esac
 
 case "$host_os" in
Index: configure.in
===================================================================
RCS file: /cvs/src/src/readline/configure.in,v
retrieving revision 1.3
diff -u -p -r1.3 configure.in
--- configure.in        2000/07/09 17:19:56     1.3
+++ configure.in        2001/06/15 23:24:03
@@ -129,6 +129,7 @@ fi
 
 case "$host_cpu" in
 *cray*)        LOCAL_CFLAGS=-DCRAY ;;
+*s390*)        LOCAL_CFLAGS=-fsigned-char ;;
 esac
 
 case "$host_os" in


^ permalink raw reply	[flat|nested] 44+ messages in thread

* [patch] multi-arch CANNOT_^&*^*&_REGISTER(); Was: New gdb 31 & 64 bit patches for S/390
  2001-02-27 12:39 New gdb 31 & 64 bit patches for S/390 DJBARROW
                   ` (5 preceding siblings ...)
  2001-06-15 16:09 ` [patch] multi-arch INIT_FRAME_PC*; " Andrew Cagney
@ 2001-06-15 16:46 ` Andrew Cagney
  2001-07-04 11:25 ` Andrew Cagney
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 44+ messages in thread
From: Andrew Cagney @ 2001-06-15 16:46 UTC (permalink / raw)
  To: DJBARROW; +Cc: gdb-patches, schwidefsky, ARENZ

Hello,

This multi-arches CANNOT_FETCH_REGISTER() and CANNOT_STORE_REGISTER(). 
It should be equivalent to the original s390 gdbarch.sh patch.
I should note that the original s390 patch included a change that added 
the concept of a default expression/values.  I've left that idea for a 
rain day.

	Andrew
From ac131313@cygnus.com Fri Jun 15 16:48:00 2001
From: Andrew Cagney <ac131313@cygnus.com>
To: Michael Snyder <msnyder@cygnus.com>
Cc: "Peter.Schauer" <Peter.Schauer@Regent.E-Technik.TU-Muenchen.DE>, gdb-patches@sources.redhat.com
Subject: Re: [RFC] if (INNER_THAN (read_sp(), step_sp - 16))
Date: Fri, 15 Jun 2001 16:48:00 -0000
Message-id: <3B2A9EC8.7020106@cygnus.com>
References: <3B2A97C7.52A839FD@cygnus.com>
X-SW-Source: 2001-06/msg00312.html
Content-length: 387

> But I have no idea how to detect the situation that you are 
> trying to test for.  So I'd like to toss it back to you.
> Can you find a better way to test for this?  Maybe with 
> (ugh) another state variable?
> 
> And if not, can you put those two lines into an ifdef, 
> so they won't affect targets for which they're not intended?


Well it can't be a (ugh) #ifdef :-)

	Andrew




^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [patch] Add predicate for EXTRACT_STRUCT_VALUE_ADDRESS; Was: New gdb 31 & 64 bit patches for S/390
  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
  0 siblings, 1 reply; 44+ messages in thread
From: Eli Zaretskii @ 2001-06-15 23:56 UTC (permalink / raw)
  To: ac131313; +Cc: DJBARROW, gdb-patches, s390-patches, schwidefsky, ARENZ

> Date: Fri, 15 Jun 2001 15:18:32 -0400
> From: Andrew Cagney <ac131313@cygnus.com>
> 
> 	* gdbarch.sh (EXTRACT_STRUCT_VALUE_ADDRESS_P): Delete definition.
> 	(EXTRACT_STRUCT_VALUE_ADDRESS): Change to a function with
> 	predicate.

Both EXTRACT_STRUCT_VALUE_ADDRESS and EXTRACT_STRUCT_VALUE_ADDRESS_P
are documented in gdbint.texinfo.  So the docs should be changed to
reflect this patch.


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [patch] Add predicate for EXTRACT_STRUCT_VALUE_ADDRESS; Was: New gdb 31 & 64 bit patches for S/390
  2001-06-15 23:56   ` Eli Zaretskii
@ 2001-06-28 16:58     ` Andrew Cagney
  2001-06-28 23:21       ` Eli Zaretskii
  0 siblings, 1 reply; 44+ messages in thread
From: Andrew Cagney @ 2001-06-28 16:58 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: DJBARROW, gdb-patches, s390-patches, schwidefsky, ARENZ

> Date: Fri, 15 Jun 2001 15:18:32 -0400
>> From: Andrew Cagney <ac131313@cygnus.com>
>> 
>> * gdbarch.sh (EXTRACT_STRUCT_VALUE_ADDRESS_P): Delete definition.
>> (EXTRACT_STRUCT_VALUE_ADDRESS): Change to a function with
>> predicate.
> 
> 
> Both EXTRACT_STRUCT_VALUE_ADDRESS and EXTRACT_STRUCT_VALUE_ADDRESS_P
> are documented in gdbint.texinfo.  So the docs should be changed to
> reflect this patch.


How is the attached?

	Andrew




^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [patch] Add predicate for EXTRACT_STRUCT_VALUE_ADDRESS; Was: New gdb 31 & 64 bit patches for S/390
  2001-06-28 16:58     ` Andrew Cagney
@ 2001-06-28 23:21       ` Eli Zaretskii
  0 siblings, 0 replies; 44+ messages in thread
From: Eli Zaretskii @ 2001-06-28 23:21 UTC (permalink / raw)
  To: ac131313; +Cc: DJBARROW, gdb-patches, s390-patches, schwidefsky, ARENZ

> Date: Thu, 28 Jun 2001 19:57:54 -0400
> From: Andrew Cagney <ac131313@cygnus.com>
> > 
> > Both EXTRACT_STRUCT_VALUE_ADDRESS and EXTRACT_STRUCT_VALUE_ADDRESS_P
> > are documented in gdbint.texinfo.  So the docs should be changed to
> > reflect this patch.
> 
> 
> How is the attached?

Fine with me.  Thanks.


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: New gdb 31 & 64 bit patches for S/390
  2001-02-27 12:39 New gdb 31 & 64 bit patches for S/390 DJBARROW
                   ` (6 preceding siblings ...)
  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
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 44+ messages in thread
From: Andrew Cagney @ 2001-07-04 11:25 UTC (permalink / raw)
  To: DJBARROW
  Cc: gdb-patches, s390-patches, Binutils Patches, bash_maintainers,
	schwidefsky, ARENZ

DJB,

The patches included the change:

2001-02-26  D.J. Barrow <djbarrow@de.ibm.com,barrow_dj@yahoo.com>

	* core-aout.c added check for CANNOT_FETCH_REGISTER
	in fetch_core_registers.

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

Can you please expand on this change.  I don't think it is s390 specific.

	Andrew



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: New gdb 31 & 64 bit patches for S/390
  2001-02-27 12:39 New gdb 31 & 64 bit patches for S/390 DJBARROW
                   ` (7 preceding siblings ...)
  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
  10 siblings, 0 replies; 44+ messages in thread
From: Andrew Cagney @ 2001-07-04 21:02 UTC (permalink / raw)
  To: DJBARROW; +Cc: gdb-patches, s390-patches, schwidefsky, ARENZ

Attached are comments on s390-nat.c.  There were very few problems here!

	Andrew
From ac131313@cygnus.com Wed Jul 04 21:02:00 2001
From: Andrew Cagney <ac131313@cygnus.com>
To: DJBARROW@de.ibm.com
Cc: gdb-patches@sourceware.cygnus.com, s390-patches@gnu.org, schwidefsky@de.ibm.com, ARENZ@de.ibm.com
Subject: Re: New gdb 31 & 64 bit patches for S/390
Date: Wed, 04 Jul 2001 21:02:00 -0000
Message-id: <3B43E021.1020502@cygnus.com>
References: <C1256A00.006F3FCE.00@d12mta09.de.ibm.com>
X-SW-Source: 2001-07/msg00074.html
Content-length: 330

The attached are comments on tm-s390.h.  As far as I can tell the file 
could be empty.  This is pretty significant since it means that you've 
managed to pure-multi-arch the s390 target.  Congratulations!

To summarise the comments, my main concern is that it appeared to 
contain many s390-nat.c specific declarations.

	Andrew
From ac131313@cygnus.com Wed Jul 04 21:04:00 2001
From: Andrew Cagney <ac131313@cygnus.com>
To: DJBARROW@de.ibm.com
Cc: gdb-patches@sourceware.cygnus.com, s390-patches@gnu.org, schwidefsky@de.ibm.com, ARENZ@de.ibm.com
Subject: Re: New gdb 31 & 64 bit patches for S/390
Date: Wed, 04 Jul 2001 21:04:00 -0000
Message-id: <3B43E31F.3020302@cygnus.com>
References: <C1256A00.006F3FCE.00@d12mta09.de.ibm.com>
X-SW-Source: 2001-07/msg00076.html
Content-length: 71

Attached are comments on nm-linux.h.  Basicly it is approved.

	Andrew
From ac131313@cygnus.com Wed Jul 04 22:14:00 2001
From: Andrew Cagney <ac131313@cygnus.com>
To: Jim Blandy <jimb@cygnus.com>
Cc: gdb-patches@sources.redhat.com
Subject: Re: RFA: addresses and pointers may be different sizes while printing
Date: Wed, 04 Jul 2001 22:14:00 -0000
Message-id: <3B43F682.1040502@cygnus.com>
References: <20010628223546.BDE7F5E9CB@zwingli.cygnus.com>
X-SW-Source: 2001-07/msg00077.html
Content-length: 1221

Jim,

Would you have an example illustrating the actual affect of this change?

	Andrew


> This is a preparatory patch for removing the D10V dependencies that
> have crept into the core of GDB (for example: value_at in valops.c).
> 
> The D10V uses 16-bit pointers to index 256k code space.  Since all
> D10V instructions are 32 bits long, and naturally aligned, the PC is
> really 18 bits long, and the bottom two bits are always zero.  Within
> GDB, we model this by using 32-bit *addresses*, and converting
> *pointers* (which are 16 bits long) to *addresses* at the appropriate
> points.
> 
> Without this conversion (which is necessary for some other
> architectures as well), the alternative is for GDB to think that
> pointers are 32 bits long, while the program being debugged thinks
> they're 16 bits long.  As you'd expect, chaos results.
> 
> In any case, print_scalar_formatted assumes that pointers and the
> addresses they represent are the same length.  This isn't true for the
> D10V, so we need to remove that assumption.  That's what this patch is
> supposed to do.
> 
> There are probably similar problems elsewhere, but we can fix them as
> we find them.  I found this one, so I'm fixing it.
> 
> 



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: New gdb 31 & 64 bit patches for S/390
  2001-02-27 12:39 New gdb 31 & 64 bit patches for S/390 DJBARROW
                   ` (9 preceding siblings ...)
  2001-07-04 21:02 ` Andrew Cagney
@ 2001-07-04 21:02 ` Andrew Cagney
  10 siblings, 0 replies; 44+ messages in thread
From: Andrew Cagney @ 2001-07-04 21:02 UTC (permalink / raw)
  To: DJBARROW; +Cc: gdb-patches, s390-patches, schwidefsky, ARENZ

Comments on xm-linux.h.  Just one problem (but it came from the other 
linux targets) and one question.

	Andrew
From ac131313@cygnus.com Wed Jul 04 21:02:00 2001
From: Andrew Cagney <ac131313@cygnus.com>
To: DJBARROW@de.ibm.com
Cc: gdb-patches@sourceware.cygnus.com, s390-patches@gnu.org, schwidefsky@de.ibm.com, ARENZ@de.ibm.com
Subject: Re: New gdb 31 & 64 bit patches for S/390
Date: Wed, 04 Jul 2001 21:02:00 -0000
Message-id: <3B43DA08.3000700@cygnus.com>
References: <C1256A00.006F3FCE.00@d12mta09.de.ibm.com>
X-SW-Source: 2001-07/msg00073.html
Content-length: 1046

DJB,

I'm trying to build an s390 cross debugger.  Actually I'm trying to build:

	./configure --target=s390-elf

s390-elf being a a fairly generic s390 target.

The reason for doing this is to ensure that the non linix specific parts 
of the s390 target really are native independant.  If you check the
MAINTAINERS file you'll notice that all targets (with the exception of
the HP/PA, which has no maintainer) can be built as a cross debugger.

Any way, I'm not having much luck.

The configury changes needed for this are very straight forward.
Unfortunatly the tweeks to s390-tdep.c are not.  Sigh.  For the record, 
the problems are not new.

As I suggested last time, I can think of two possible courses of action:

	o	we try to fix the s390 problems
		and then get an IBM copyright transfer

	o	IBM transfer copyright for these files
		to the FSF and then they be included in
		GDB as a patch.  This would free up the
		code so that others can address the problems.

A very detailed commentry on the file s390-tdep.c is attached.

	Andrew


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: New gdb 31 & 64 bit patches for S/390
  2001-02-27 12:39 New gdb 31 & 64 bit patches for S/390 DJBARROW
                   ` (8 preceding siblings ...)
  2001-07-04 21:02 ` Andrew Cagney
@ 2001-07-04 21:02 ` Andrew Cagney
  2001-07-04 21:02 ` Andrew Cagney
  10 siblings, 0 replies; 44+ messages in thread
From: Andrew Cagney @ 2001-07-04 21:02 UTC (permalink / raw)
  To: DJBARROW; +Cc: gdb-patches, s390-patches, schwidefsky, ARENZ

Hello,

I'm trying to understand the code:

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

but don't understand the reason for the call to bfd_lookup_arch().

printcmd.c:print_insn() will set the ->mach to the target architectures 
machine regardless of the above.

	Andrew


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: New gdb 31 & 64 bit patches for S/390
  2001-08-28 16:33 ` Daniel Jacobowitz
@ 2001-09-05 21:45   ` Andrew Cagney
  0 siblings, 0 replies; 44+ messages in thread
From: Andrew Cagney @ 2001-09-05 21:45 UTC (permalink / raw)
  To: Daniel Jacobowitz
  Cc: Denis Joseph Barrow, Martin Schwidefsky, Ulrich Weigand, gdb-patches

> 
> For now, the thing to do seems to be duplicating it in low-linux.c. 

yes. the current consensus is that gdb/gdbserver should be kept as thin 
and independant of gdb as possible.  this means duplicating a few 
consants in low-linux.c.

andrew



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: New gdb 31 & 64 bit patches for S/390
       [not found] <OFEFF0AD94.761C34C1-ONC1256AB6.005503EE@de.ibm.com>
@ 2001-08-28 16:33 ` Daniel Jacobowitz
  2001-09-05 21:45   ` Andrew Cagney
  0 siblings, 1 reply; 44+ messages in thread
From: Daniel Jacobowitz @ 2001-08-28 16:33 UTC (permalink / raw)
  To: Denis Joseph Barrow
  Cc: Andrew Cagney, Martin Schwidefsky, Ulrich Weigand, gdb-patches

On Tue, Aug 28, 2001 at 05:59:46PM +0200, Denis Joseph Barrow wrote:
> Hi Andrew,
> I'm currently looking at porting the gdbserver to s390 on request of a JVM
> developer here at IBM,
> On looking at gdbserver/low-linux.c the gdbserver isn't multiarch
> compatible,
>  It looks like I either have to in the forseeable future put  some non
> multiarch definitions back into tm-s390.h
> & #ifdef  GDB_MULTI_ARCH  them again despite recommendations to move
> everything to s390-tdep.c
> or else duplicate definitions in low-linux.c ( something I don't want to do
> as there is enough stuff in there).

For now, the thing to do seems to be duplicating it in low-linux.c. 
I'm working on a more general solution, but it won't be done for at
least another few months.

-- 
Daniel Jacobowitz                           Carnegie Mellon University
MontaVista Software                         Debian GNU/Linux Developer


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: New gdb 31 & 64 bit patches for S/390
  2001-08-15  2:22 Denis Joseph Barrow
  2001-08-15  9:03 ` Andrew Cagney
@ 2001-08-15  9:54 ` Andrew Cagney
  1 sibling, 0 replies; 44+ messages in thread
From: Andrew Cagney @ 2001-08-15  9:54 UTC (permalink / raw)
  To: Denis Joseph Barrow; +Cc: gdb-patches

> If anything the code quality may be deteriorating owing to being asked to
> move code around so much & possibly being tired of retesting it,
> I currently have 4 versions of the code to support the post 5.0 32 & 64 bit
> patches the 5.0 32 & 64 bit patches & a lot of other work to do
> besides & probably falling back on it, when enthuasism is low my
> productivity deteriorates badly, this crap is pissing me off.
>  I will remove the non multi arch definitions when I don't have to support
> gdb-5.0.

That is your decision.

As things stand, the FSF doesn't own this code and, as a consequence, 
people have strong reservations about working on it.  (IBM will only 
assign the copyright using a letter that cites a digitally signed patch. 
  I understand this process to be slow and complicated.).

This is unfortunate.  As you'll recall, I have, on several occasions, 
suggested that instead of trying to get the source code up-to-scratch, 
it instead be assigned as-is to the FSF.  That way, others (probably me) 
would have been able to more directly help with the task of merging the 
changes in.

Instead, as you note, we've ended up with a slow painful process where 
the code would be submited and then I would eventually (since no one 
else step forward :-) review it.

Could I again suggest that the patches be assigned, as-is, to the FSF.

> We did our first 31 bit gdb drop 20 months ago.
> Even redhat has a experimental 64 bit drop for the last 6 months & it still
> isn't gnu.org the repository .

Yes, isn't this ironic.  I won't go near (and Red Hat can't contribute) 
those changes either since they are also legally owned by IBM :-)

	Andrew



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: New gdb 31 & 64 bit patches for S/390
  2001-08-15  2:22 Denis Joseph Barrow
@ 2001-08-15  9:03 ` Andrew Cagney
  2001-08-15  9:54 ` Andrew Cagney
  1 sibling, 0 replies; 44+ messages in thread
From: Andrew Cagney @ 2001-08-15  9:03 UTC (permalink / raw)
  To: Denis Joseph Barrow; +Cc: gdb-patches

>>> No wonder you lost the HP maintainer

[I wrote in private e-mail]

>> I don't understand what you mean here.
> 
> 
> 
> Ohhhh I'm crossing the politically correct line again, where's the valium.
> 
> What I meant you made probably him jump through so many hoops as you are
> making me you probably just pissed the guy off
> so he went looking for another job ( he probably is back programming
> windows now ).

No.  I simply don't know what your talking about here.

The former HP maintainer, Jeff Law, stepped down because he realised he 
was no longer able to allocate the time and resources needed to respond 
promptly to HP GDB questions, problems and patches.  Keep in mind that 
Jeff is a member of the GCC Steering Committee, a very active GCC 
developer, and one of the sources/gcc.gnu.org maintainers (I believe he 
also manages to hold down a day job :-).

In stepping back from GDB/HP maintainership (never an easy and definitly 
a brave decision) Jeff has opened the way for others to advance the 
GDB-HP code he wrote.

	Andrew



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: New gdb 31 & 64 bit patches for S/390
@ 2001-08-15  2:22 Denis Joseph Barrow
  2001-08-15  9:03 ` Andrew Cagney
  2001-08-15  9:54 ` Andrew Cagney
  0 siblings, 2 replies; 44+ messages in thread
From: Denis Joseph Barrow @ 2001-08-15  2:22 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: gdb-patches

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

Hi Andrew,
>> No wonder you lost the HP maintainer
> I don't understand what you mean here.


Ohhhh I'm crossing the politically correct line again, where's the valium.

What I meant you made probably him jump through so many hoops as you are
making me you probably just pissed the guy off
so he went looking for another job ( he probably is back programming
windows now ).

I'll readily admit to being a hothead ( sometimes justifiably so ).

Some of the stuff I'm being asked to do by you has very little bearing on
code quality bugwise just Andrew's
coding style vs my own.

If anything the code quality may be deteriorating owing to being asked to
move code around so much & possibly being tired of retesting it,
I currently have 4 versions of the code to support the post 5.0 32 & 64 bit
patches the 5.0 32 & 64 bit patches & a lot of other work to do
besides & probably falling back on it, when enthuasism is low my
productivity deteriorates badly, this crap is pissing me off.
 I will remove the non multi arch definitions when I don't have to support
gdb-5.0.

The last patch I posted you took 5 months to come back with comments, Alan
Cox usually takes 30 minutes & he a very busy man
Being overbearing may be stifling gdb.

We did our first 31 bit gdb drop 20 months ago.
Even redhat has a experimental 64 bit drop for the last 6 months & it still
isn't gnu.org the repository .



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


Andrew Cagney <ac131313@cygnus.com> on 15.08.2001 07:51:38

Please respond to Andrew Cagney <ac131313@cygnus.com>

To:   Denis Joseph Barrow/Germany/Contr/IBM@IBMDE
cc:   ac131313@cygnus.com
Subject:  Re: New gdb 31 & 64 bit patches for S/390



> No wonder you lost the HP maintainer.

I don't understand what you mean here.

     Andrew






^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: New gdb 31 & 64 bit patches for S/390
@ 2001-08-13  9:47 Denis Joseph Barrow
  0 siblings, 0 replies; 44+ messages in thread
From: Denis Joseph Barrow @ 2001-08-13  9:47 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: gdb-patches

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

Andrew do you realise I've done over 500 hours work just jumping through
hoops for you & nearly no work on any real improvment to the code.
To be quite honest I'm quite fed up with it.

No wonder you lost the HP maintainer.



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


Andrew Cagney <ac131313@cygnus.com> on 13.08.2001 18:30:55

Please respond to Andrew Cagney <ac131313@cygnus.com>

To:   Denis Joseph Barrow/Germany/Contr/IBM@IBMDE
cc:   gdb-patches@sourceware.cygnus.com
Subject:  Re: New gdb 31 & 64 bit patches for S/390



> Hi Andrew,
> I basically took this stuff from other architectures on gdb-5.0, I
presume
> they knew what they were doing &
> something subtle would break if I didn't do it, I'm using the same source
> base for the latest stuff & gdb-5.0
> as much as possible to avoid maintaining 2 different incomatible source
> bases.


Ah, it is actually much simpler - many of the existing NM and XM files
are wrong.  Their problems, I suspect, date back to when there weren't
NM/XM files and when the need to do the two correctly was less
important.  From there, as with many parts of gdb, the problem just spread.

Anyway, people have been activly cleaning up the problem.


> So some definitions specific to gdb-5.0 ( which isn't multiarch capible )
> will stay in /config/s390 header files
> until gdb-5.1 or whatever is officially released.


Please dont. The GDB trunk shouldn't be used as a holding area for code
only used on old branches.  That is what old branches are for.

     Andrew





^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: New gdb 31 & 64 bit patches for S/390
  2001-08-13  3:06 Denis Joseph Barrow
@ 2001-08-13  9:31 ` Andrew Cagney
  0 siblings, 0 replies; 44+ messages in thread
From: Andrew Cagney @ 2001-08-13  9:31 UTC (permalink / raw)
  To: Denis Joseph Barrow; +Cc: gdb-patches

> Hi Andrew,
> I basically took this stuff from other architectures on gdb-5.0, I presume
> they knew what they were doing &
> something subtle would break if I didn't do it, I'm using the same source
> base for the latest stuff & gdb-5.0
> as much as possible to avoid maintaining 2 different incomatible source
> bases.


Ah, it is actually much simpler - many of the existing NM and XM files 
are wrong.  Their problems, I suspect, date back to when there weren't 
NM/XM files and when the need to do the two correctly was less 
important.  From there, as with many parts of gdb, the problem just spread.

Anyway, people have been activly cleaning up the problem.


> So some definitions specific to gdb-5.0 ( which isn't multiarch capible )
> will stay in /config/s390 header files
> until gdb-5.1 or whatever is officially released.


Please dont. The GDB trunk shouldn't be used as a holding area for code 
only used on old branches.  That is what old branches are for.

	Andrew


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: New gdb 31 & 64 bit patches for S/390
@ 2001-08-13  3:06 Denis Joseph Barrow
  2001-08-13  9:31 ` Andrew Cagney
  0 siblings, 1 reply; 44+ messages in thread
From: Denis Joseph Barrow @ 2001-08-13  3:06 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: gdb-patches

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

Hi Andrew,
I basically took this stuff from other architectures on gdb-5.0, I presume
they knew what they were doing &
something subtle would break if I didn't do it, I'm using the same source
base for the latest stuff & gdb-5.0
as much as possible to avoid maintaining 2 different incomatible source
bases.
So some definitions specific to gdb-5.0 ( which isn't multiarch capible )
will stay in /config/s390 header files
until gdb-5.1 or whatever is officially released.

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


Andrew Cagney <ac131313@cygnus.com> on 05.07.2001 05:56:36

Please respond to Andrew Cagney <ac131313@cygnus.com>

To:   Denis Joseph Barrow/Germany/Contr/IBM@IBMDE
cc:   gdb-patches@sourceware.cygnus.com, s390-patches@gnu.org, Martin
      Schwidefsky/Germany/IBM@IBMDE, Christoph Arenz/Germany/IBM@IBMDE
Subject:  Re: New gdb 31 & 64 bit patches for S/390




Comments on xm-linux.h.  Just one problem (but it came from the other
linux targets) and one question.

     Andrew


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

FYI, This belongs in nm-linux.h (if it is needed at all).  The other
linux targets are wrong.

+
+#define NEED_POSIX_SETPGID

Something that should some day be moved to autoconf.

+
+/* Need R_OK etc, but USG isn't defined.  */
+#include <unistd.h>

Is this needed?

+
+#endif /* #ifndef XM_LINUX_H */





^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: New gdb 31 & 64 bit patches for S/390
  2001-07-08  0:53   ` Eli Zaretskii
@ 2001-07-08 19:23     ` Andrew Cagney
  0 siblings, 0 replies; 44+ messages in thread
From: Andrew Cagney @ 2001-07-08 19:23 UTC (permalink / raw)
  To: Eli Zaretskii
  Cc: Denis Joseph Barrow, gdb-patches, s390-patches, Martin Schwidefsky

> 
> If taken at face value, IMHO this is too harsh to the developers.


Even on a host I think it is wrong for GDB to assume that the compiler 
is going to be GCC.  LCC and a few other free compilers come to mind. 
For what its worth, I don't think __attribute__((packeted)) is even 
needed on the host - the ABI should have specified what the packing 
rules were and, hence, guarenteed, the packing.


> I agree that compiler-specific extensions should be kept at the bare
> minimum, but why are you opposed to __attribute__((packed)) in native
> files?  Some functionality is impossible to get right without that.
> How else can I define a struct which fits some external OS data
> structure which is not under my control?  The only way I know of is to
> use a char array with ugly, hand-computed, error-prone offsets into it
> and lots of type casts to fetch and store data there.  Do we really
> want that kind of ugliness in GDB?


FYI, there are two ways of dealing with it: the first (adopted by the 
shlib code) did memory_read()'s to extract the relevant fields from 
target memory.  The second, adopted by C++, uses GDB's `struct type *' 
describe the data structures it needs to read from memory.

enjoy,
	Andrew


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: New gdb 31 & 64 bit patches for S/390
  2001-07-05 12:46 ` Andrew Cagney
@ 2001-07-08  0:53   ` Eli Zaretskii
  2001-07-08 19:23     ` Andrew Cagney
  0 siblings, 1 reply; 44+ messages in thread
From: Eli Zaretskii @ 2001-07-08  0:53 UTC (permalink / raw)
  To: Andrew Cagney
  Cc: Denis Joseph Barrow, gdb-patches, s390-patches, Martin Schwidefsky

On Thu, 5 Jul 2001, Andrew Cagney wrote:

> > What about using the __attribute__(packed) gcc extension.
> > & add a
> > #ifndef gcc
> > define __attribute__
> > #endif
> 
> No.  So far GDB has managed to avoid a dependency on GCCoteric features, 
> I don't see any reason to change this.
> 
> With regard to the other target specific structures, I suggested moving 
> them to s390-nat.c since (I think) only that file would be using them 
> (?correct). s390-nat.c is very host=target specific - it needs to 
> correctly unpack the data returned from ptrace/procfs.  However, even 
> there, the __attribute__(packed) should be removed.

If taken at face value, IMHO this is too harsh to the developers.

I agree that compiler-specific extensions should be kept at the bare
minimum, but why are you opposed to __attribute__((packed)) in native
files?  Some functionality is impossible to get right without that.
How else can I define a struct which fits some external OS data
structure which is not under my control?  The only way I know of is to
use a char array with ugly, hand-computed, error-prone offsets into it
and lots of type casts to fetch and store data there.  Do we really
want that kind of ugliness in GDB?

For example, here's a definition of an ia32 segment descriptor:

    struct seg_descr {
      unsigned short limit0          __attribute__((packed));
      unsigned short base0           __attribute__((packed));
      unsigned char  base1           __attribute__((packed));
      unsigned       stype:5         __attribute__((packed));
      unsigned       dpl:2           __attribute__((packed));
      unsigned       present:1       __attribute__((packed));
      unsigned       limit1:4        __attribute__((packed));
      unsigned       available:1     __attribute__((packed));
      unsigned       dummy:1         __attribute__((packed));
      unsigned       bit32:1         __attribute__((packed));
      unsigned       page_granular:1 __attribute__((packed));
      unsigned char  base2           __attribute__((packed));
    };

How do I define something like that without packing, and make sure it
works with any version of GCC, past and future?

It's clear that something like this can only be put into a native file
which is only compiled by GCC.  But given that those constraints are
satisfied, what's the problem with having this in GDB?


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: New gdb 31 & 64 bit patches for S/390
@ 2001-07-06  2:31 Denis Joseph Barrow
  0 siblings, 0 replies; 44+ messages in thread
From: Denis Joseph Barrow @ 2001-07-06  2:31 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: gdb-patches, s390-patches, Martin Schwidefsky

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

Hi Andrew,
I've warmed to this idea I'll code in definite offsets instead of
s390_offsetof stuff.
I didn't think about the padding problem previously & all going well I
might be able to remove the asm/types.h stuff.


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


Andrew Cagney <ac131313@cygnus.com> on 05.07.2001 21:46:49

Please respond to Andrew Cagney <ac131313@cygnus.com>

To:   Denis Joseph Barrow/Germany/Contr/IBM@IBMDE
cc:   gdb-patches@sourceware.cygnus.com, s390-patches@gnu.org, Martin
      Schwidefsky/Germany/IBM@IBMDE
Subject:  Re: New gdb 31 & 64 bit patches for S/390




> There are some target specific structures for to find out if I'm in a
> signal handler which I
> currently need see the s390_offsetof stuff in the tm-s390.c.
>
> What about using the __attribute__(packed) gcc extension.
> & add a
> #ifndef gcc
> define __attribute__
> #endif

No.  So far GDB has managed to avoid a dependency on GCCoteric features,
I don't see any reason to change this.

With regard to the other target specific structures, I suggested moving
them to s390-nat.c since (I think) only that file would be using them
(?correct). s390-nat.c is very host=target specific - it needs to
correctly unpack the data returned from ptrace/procfs.  However, even
there, the __attribute__(packed) should be removed.

 > for non gcc compilers this would get around some of the common problems,
 > the only other way is for me to
 > add #defines for all the offsets I need.

Remember s390-tdep.c analizes and implements an ABI.  That ABI is
hopefully publised and defined.  It isn't going to change.  If it does
then the debugger, the compiler and who knows what else will need to be
modified.

Because the ABI is ``set in stone'' constants using enums (not #defines)
are typically used in the *-tdep.c file.

For what its worth, BFD has adopted the strategy of:

     o    having the ABI constants wired in

     o    when host=target=s390-linux,
          verify that those constants havn't
          been changed by someones foobar.

     Andrew







^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: New gdb 31 & 64 bit patches for S/390
  2001-07-05 10:24 Denis Joseph Barrow
@ 2001-07-05 12:46 ` Andrew Cagney
  2001-07-08  0:53   ` Eli Zaretskii
  0 siblings, 1 reply; 44+ messages in thread
From: Andrew Cagney @ 2001-07-05 12:46 UTC (permalink / raw)
  To: Denis Joseph Barrow; +Cc: gdb-patches, s390-patches, Martin Schwidefsky

> There are some target specific structures for to find out if I'm in a
> signal handler which I
> currently need see the s390_offsetof stuff in the tm-s390.c.
> 
> What about using the __attribute__(packed) gcc extension.
> & add a
> #ifndef gcc
> define __attribute__
> #endif

No.  So far GDB has managed to avoid a dependency on GCCoteric features, 
I don't see any reason to change this.

With regard to the other target specific structures, I suggested moving 
them to s390-nat.c since (I think) only that file would be using them 
(?correct). s390-nat.c is very host=target specific - it needs to 
correctly unpack the data returned from ptrace/procfs.  However, even 
there, the __attribute__(packed) should be removed.

 > for non gcc compilers this would get around some of the common problems,
 > the only other way is for me to
 > add #defines for all the offsets I need.

Remember s390-tdep.c analizes and implements an ABI.  That ABI is 
hopefully publised and defined.  It isn't going to change.  If it does 
then the debugger, the compiler and who knows what else will need to be 
modified.

Because the ABI is ``set in stone'' constants using enums (not #defines) 
are typically used in the *-tdep.c file.

For what its worth, BFD has adopted the strategy of:

	o	having the ABI constants wired in

	o	when host=target=s390-linux,
		verify that those constants havn't
		been changed by someones foobar.

	Andrew




^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: New gdb 31 & 64 bit patches for S/390
  2001-07-05  9:19 Denis Joseph Barrow
@ 2001-07-05 12:36 ` Andrew Cagney
  0 siblings, 0 replies; 44+ messages in thread
From: Andrew Cagney @ 2001-07-05 12:36 UTC (permalink / raw)
  To: Denis Joseph Barrow
  Cc: gdb-patches, s390-patches, Martin Schwidefsky, Christoph Arenz

> Why are you trying to build this target ?,
> linux is the only elf abi compatible s390 target at the moment & probably
> will be for the
> forseeable future as OS/390's ABIs are very incompatible with linux'es abi.


Hmm, I tried to explain with:

> The reason for doing this is to ensure that the non linix specific parts
> of the s390 target really are native independant.  If you check the
> MAINTAINERS file you'll notice that all targets (with the exception of
> the HP/PA, which has no maintainer) can be built as a cross debugger.


Ensuring that this remains true is very important.  From the USER's point

of view, it is one of GDB's important features - remote/cross debugging 
just work.  From the GDB developers point of view, it is one of the 
things that make GDB maintanable.  You don't need an s390 to check that 
the change to s390-tdep.c is probably correct.

enjoy,
	Andrew



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: New gdb 31 & 64 bit patches for S/390
@ 2001-07-05 10:24 Denis Joseph Barrow
  2001-07-05 12:46 ` Andrew Cagney
  0 siblings, 1 reply; 44+ messages in thread
From: Denis Joseph Barrow @ 2001-07-05 10:24 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: gdb-patches, s390-patches, Martin Schwidefsky

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

There are some target specific structures for to find out if I'm in a
signal handler which I
currently need see the s390_offsetof stuff in the tm-s390.c.

What about using the __attribute__(packed) gcc extension.
& add a
#ifndef gcc
define __attribute__
#endif
for non gcc compilers this would get around some of the common problems,
the only other way is for me to
add #defines for all the offsets I need.


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


Andrew Cagney <ac131313@cygnus.com> on 05.07.2001 18:50:14

Please respond to Andrew Cagney <ac131313@cygnus.com>

To:   Denis Joseph Barrow/Germany/Contr/IBM@IBMDE
cc:   gdb-patches@sourceware.cygnus.com, s390-patches@gnu.org, Martin
      Schwidefsky/Germany/IBM@IBMDE, Christoph Arenz/Germany/IBM@IBMDE
Subject:  Re: New gdb 31 & 64 bit patches for S/390




> It'll be at least two weeks before I can go & update this stuff owing to
> other commitments.
> The asm/types.h in my opinion is currently needed, Andrew if you think it
> isn't, a
> config/arch/hosttypes.h with definitions for u8 u16 & u32 etc.
definitions
> should be introduced  for all archs
> IMO bfd_btye etc. as per previous suggestion simply doesn't cut mustard.


I don't think u8, u16, ... are needed.  As I noted:


> In the past it has been suggested that types like _u32, _u8 etc would
> allow the user to exactly describe structures and hence allow the
> programmer to exactly describe structure layout.  Unfortunatly, that
> won't work since allignment (and hence packing) also varies between
> hosts.
>
> If you need to read structures from memory you can use functions like:
>
>      LONGEST read_memory_integer (CORE_ADDR memaddr, int len);
>      ULONGEST read_memory_unsigned_integer (CORE_ADDR memaddr, int len);
>
> If you already have the memory local then:
>
>      LONGEST extract_signed_integer (void *, int);
>      ULONGEST extract_unsigned_integer (void *, int);
>
> will do the trick.


All other targets have managed to get things working using just the above.

     Andrew





^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: New gdb 31 & 64 bit patches for S/390
  2001-07-05  3:57 Denis Joseph Barrow
  2001-07-05 10:11 ` Andrew Cagney
@ 2001-07-05 10:11 ` Andrew Cagney
  1 sibling, 0 replies; 44+ messages in thread
From: Andrew Cagney @ 2001-07-05 10:11 UTC (permalink / raw)
  To: Denis Joseph Barrow
  Cc: gdb-patches, s390-patches, Martin Schwidefsky, Christoph Arenz

> As for the  TRUE  / FALSE there is no place in the gnu coding standards
> where this is practice is non condoned
> you are trying to push a personal opinion here.


I'm sorry, but in the case of these coding stubs:

> ++  if (good_prologue == TRUE)
> ++  for (second_pass = FALSE; second_pass <= TRUE; second_pass++)
> ++      if (init_extra_info || fextra_info->initialised == FALSE)
> ++     if (frame_pointer_found == FALSE && regidx == 0xb)
> ++        && fextra_info.good_prologue == FALSE);


I don't consider myself to be pushing an individual opinion.

	Andrew




^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: New gdb 31 & 64 bit patches for S/390
  2001-07-05  3:57 Denis Joseph Barrow
@ 2001-07-05 10:11 ` Andrew Cagney
  2001-07-05 10:11 ` Andrew Cagney
  1 sibling, 0 replies; 44+ messages in thread
From: Andrew Cagney @ 2001-07-05 10:11 UTC (permalink / raw)
  To: Denis Joseph Barrow
  Cc: gdb-patches, s390-patches, Martin Schwidefsky, Christoph Arenz

> It'll be at least two weeks before I can go & update this stuff owing to
> other commitments.
> The asm/types.h in my opinion is currently needed, Andrew if you think it
> isn't, a
> config/arch/hosttypes.h with definitions for u8 u16 & u32 etc. definitions
> should be introduced  for all archs
> IMO bfd_btye etc. as per previous suggestion simply doesn't cut mustard.


I don't think u8, u16, ... are needed.  As I noted:


> In the past it has been suggested that types like _u32, _u8 etc would
> allow the user to exactly describe structures and hence allow the
> programmer to exactly describe structure layout.  Unfortunatly, that
> won't work since allignment (and hence packing) also varies between
> hosts.
> 
> If you need to read structures from memory you can use functions like:
> 
>      LONGEST read_memory_integer (CORE_ADDR memaddr, int len);
>      ULONGEST read_memory_unsigned_integer (CORE_ADDR memaddr, int len);
> 
> If you already have the memory local then:
> 
>      LONGEST extract_signed_integer (void *, int);
>      ULONGEST extract_unsigned_integer (void *, int);
> 
> will do the trick.


All other targets have managed to get things working using just the above.

	Andrew


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: New gdb 31 & 64 bit patches for S/390
@ 2001-07-05  9:19 Denis Joseph Barrow
  2001-07-05 12:36 ` Andrew Cagney
  0 siblings, 1 reply; 44+ messages in thread
From: Denis Joseph Barrow @ 2001-07-05  9:19 UTC (permalink / raw)
  To: Andrew Cagney
  Cc: gdb-patches, s390-patches, Martin Schwidefsky, Christoph Arenz

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

Why are you trying to build this target ?,
linux is the only elf abi compatible s390 target at the moment & probably
will be for the
forseeable future as OS/390's ABIs are very incompatible with linux'es abi.

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

Andrew Cagney <ac131313@cygnus.com> on 05.07.2001 05:07:52

Please respond to Andrew Cagney <ac131313@cygnus.com>

To:   Denis Joseph Barrow/Germany/Contr/IBM@IBMDE
cc:   gdb-patches@sourceware.cygnus.com, s390-patches@gnu.org, Martin
      Schwidefsky/Germany/IBM@IBMDE, Christoph Arenz/Germany/IBM@IBMDE
Subject:  Re: New gdb 31 & 64 bit patches for S/390




DJB,

I'm trying to build an s390 cross debugger.  Actually I'm trying to build:

     ./configure --target=s390-elf

s390-elf being a a fairly generic s390 target.

The reason for doing this is to ensure that the non linix specific parts
of the s390 target really are native independant.  If you check the
MAINTAINERS file you'll notice that all targets (with the exception of
the HP/PA, which has no maintainer) can be built as a cross debugger.

Any way, I'm not having much luck.

The configury changes needed for this are very straight forward.
Unfortunatly the tweeks to s390-tdep.c are not.  Sigh.  For the record,
the problems are not new.

As I suggested last time, I can think of two possible courses of action:

     o    we try to fix the s390 problems
          and then get an IBM copyright transfer

     o    IBM transfer copyright for these files
          to the FSF and then they be included in
          GDB as a patch.  This would free up the
          code so that others can address the problems.

A very detailed commentry on the file s390-tdep.c is attached.

     Andrew



--- /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 */

This is wrong.  tm-s390.h shouldn't be affected by s390-tdep.c.

+#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"

Recent changes to GDB may mean that "tm.h" is no longer be needed for
native targets.  For the moment I'll assume it is.

Thinking about this, I suspect what you really need is ``s390-tdep.h''
(included by s390-tdep.c and s390-nat.c).  That could contain all the
constants that need to be shared between the s390-* files with out
needing to define them globally.

+#include "../bfd/bfd.h"

That should be #include "bfd.h"

+#include "floatformat.h"
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif

See earlier post.  Your code contains constructs such as:

++  if (good_prologue == TRUE)
++  for (second_pass = FALSE; second_pass <= TRUE; second_pass++)
++      if (init_extra_info || fextra_info->initialised == FALSE)
++     if (frame_pointer_found == FALSE && regidx == 0xb)
++        && fextra_info.good_prologue == FALSE);

such expressions should be written as:

     if (good_prologue)
     if (!fextra_info.good_prologue)

With that in mind (and per previous e-mail), i'd fix the conditionals
and replace ``TRUE'' with 1, ``FALSE'' with 0.

+
+#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)

All of these macro's are very unportable.  They assume HOST=TARGET.
The gdbint document goes into some detail on how important it is to
not write code that assumes this.

In the past it has been suggested that types like _u32, _u8 etc would
allow the user to exactly describe structures and hence allow the
programmer to exactly describe structure layout.  Unfortunatly, that
won't work since allignment (and hence packing) also varies between
hosts.

If you need to read structures from memory you can use functions like:

     LONGEST read_memory_integer (CORE_ADDR memaddr, int len);
     ULONGEST read_memory_unsigned_integer (CORE_ADDR memaddr, int len);

If you already have the memory local then:

     LONGEST extract_signed_integer (void *, int);
     ULONGEST extract_unsigned_integer (void *, int);

will do the trick.

+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
*/

See comment above.  This is either going to be small (int) or large
(LONGEST).

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

The function name should be s390_read_instruction (see GNU coding
standard).

The first parameter should be just ``char *insr'' or ``char insr[]''.
Don't use __u8.  Yes, strictly speaking this means that GDB assumes
tha sizeof(char) == one eight bit byte.  However, per the comment in
findvar.c:

#if TARGET_CHAR_BIT != 8 || HOST_CHAR_BIT != 8
  /* 8 bit characters are a pretty safe assumption these days, so we
     assume it throughout all these swapping routines.  If we had to deal
with
     9 bit characters, we would need to make len be in bits and would have
     to re-write these routines...  */
you lose
#endif

The changes below will make the third parameter redundant.

+{
+  int instrlen;
+
+  static int s390_instrlen[] = {
+    2,
+    4,
+    4,
+    6
+  };
+  if ((*info->read_memory_func) (at, &instr[0], 2, info))

Just use the function:

     target_read_memory (at, insr, 2);

see corefile.c:read_memory() for an example of how to check the return
value.

+    return -1;
+  instrlen = s390_instrlen[instr[0] >> 6];
+  if ((*info->read_memory_func) (at + 2, &instr[2], instrlen - 2, info))
+    return -1;

Again, just use:

     target_read_memory (....)

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

The macro S390_REGISTER_NAMES is not needed.  Instead just move the
macro contents to here.

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

See the GNU coding standard.  This expression should be written with
``||'' at the start of a line and indented / parenthesized something
like:

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

Please rewrite this as:

     if (regno >= 64)
       return S390_PSWM_REGNUM - 64;
     else if (regno >= 48)
       return  S390_FIRST_ACR - 48;
     ....

+}
+
+
+
+/* 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

These should be enums.

+  __u8 instr[S390_MAX_INSTR_SIZE];

Per above.  char is sufficient.

+  CORE_ADDR test_pc = pc, test_pc2;

While I have a personal preference for one variable declaraton per
line, one assignment per line, the GNU coding standard does tolerate
this.

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

These state variables need to be implemented as enums and explicit
states.  At the end of the code the expression:

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

put simply, I have no idea what this does (yet I should).

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

Per comments above, ``info'' isn't needed.

+
+  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)
+    {

Take care with the coding standard - indent two spaces vis:

     if (...)
       {
         s390_....

As I suggested earlier, the easiest way to fix this is to put the code
through GNU indent.

+      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 &&

This doesn't need to be a macro. A function like:

     target_is_s390_esame()

or even the test:

     if (TARGET_ARCHITECTURE->mach == bfd_mach_s390_esame)

are sufficient.

+         ((instr[0] == 0xeb) && (instr[5] == 0x24))) ||
+           (instr[0] == 0x90)) && ((instr[2] >> 4) == 0xf))

Again see above about how to write expressions.

+        {
+          regidx = (instr[1] >> 4);
+          if (regidx < 6)
+         varargs_state = 1;
+          offset = ((*((__u16 *) & instr[2])) & 0xfff);

This isn't portable.

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

Again expressions style.

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

Again, portability, probably use:

     extract_unsigned_integer (...);

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

Style.

+        {
+          const_pool_state = 2;
+          test_pc += ((*((__u16 *) & instr[2]) << 1) - instrlen);

Remember, portability.

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

Style.

+    {
+      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))

Style.

+    {
+      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))

Style.

+    {
+      subtract_sp_regidx = instr[1] >> 4;
+      save_link_state = 2;
+      if (fextra_info)
+        target_read_memory (test_pc + instrlen,
+                   (char *) &fextra_info->stack_bought,

The cast isn't needed.

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

Style

+    {
+      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 */

Comments should be formatted vis:

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

and don't forget complete sentences and ``.  '' like I do :-)

+      if (got_state == 0 && const_pool_state == 2 && instr[0] == 0x58
+      && (instr[2] == (CONST_POOL_REGIDX << 4))
+      && ((instr[1] >> 4) == GOT_REGIDX))

style

+    {
+      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;

Indentation.  Other cases occure below.

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

This is better.

+      if (fextra_info.good_prologue)
+    function_start = fextra_info.function_start;
+    }
+  return function_start;
+}
+
+
+
+CORE_ADDR s390_function_start (struct frame_info * fi)

The function name should appear at the start of the line vis:

     CORE_ADDR
     s390_function_start (...)

I suspect it can also be made static like most of the functions in
this file.  Other cases of this occure below.

+{
+  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
+    {

Indentation.

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

Style:  ``CORE_ADDR *sregs'' not ``CORE_ADDR * sregs''.

+{
+  __u8 instr[S390_MAX_INSTR_SIZE];

char

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

Style.

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

Conditional expressions are normally indented as:

     (fextra_info.has_frame_pointer
      ? S390_FRAME_REGNUM
      : S390_SP_REGNUM)

however typically it is better to just use an IF statement vis:

+      /* 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. */

see above on how to write comments.

+
+
+
+/* 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);

Remember, space after commas.

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

Again, expression indentation.  Here, separating the two (er three!)
declarations would also be a good idea.

+      for(idx=0;idx<S390_GPR_SIZE;idx++)
+    {
+      reg_buff[idx] = (idx<diff ? (negative ? 0xff:0x0) :
+                 value[idx-diff] );

indentation

+    }
+      value=reg_buff;
+      *arglen = S390_GPR_SIZE;

Indentation `` = ''.

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

Indentation:
     return value;
or   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);

Indentation.

+      /* 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];

char

+  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.  */

Comment style.

+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 ). */

Comment style.  Suggest a blank line be tween paragraphs.

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

style.

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

Indentation.

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

Indentation and expressons.  No `` '' after ``(''.

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

This #if is not needed.  This code should always be compiled.

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

This isn't portable.  Probably need to use store_...().

+}
+/* 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;

expression style.

+}
+
+/* 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;

expression style

+}
+
+#endif
+
+#if defined(GDB_MULTI_ARCH) || defined(CONFIG_ARCH_S390X)

The #if should not be present, this code should always be compiled.

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

this isn't portable

+}
+
+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 ;

expression style.  I'd change this to a simpler if().

+}
+
+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;

expression style  I'd change this to a simpler if().

+}
+
+#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)

Don't forget, function at start of a line.

+{
+  return ADDR_BITS_REMOVE (read_register (S390_RETADDR_REGNUM));
+}
+
+#if GDB_MULTI_ARCH

The #if isn't needed.

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

Please rewrite this as an if() else if() chain.

+}
+
+#if GDB_MULTI_ARCH

The #if isn't needed.

+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

The #if isn't needed.

+  /* 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");

I don't understand what this is doing.

+}





^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: New gdb 31 & 64 bit patches for S/390
@ 2001-07-05  9:15 Denis Joseph Barrow
  0 siblings, 0 replies; 44+ messages in thread
From: Denis Joseph Barrow @ 2001-07-05  9:15 UTC (permalink / raw)
  To: Andrew Cagney
  Cc: gdb-patches, s390-patches, Martin Schwidefsky, Christoph Arenz

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

Hi Andrew,
+
+#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)

I don't know where you get the idea these are unportable,
they use the definitons u32 u16 etc from the host asm/types.h & if
asm/types is defined
this stuff is portable.

GDB_TARGET_IS_ESAME macro is fine & if not please explain why you think it
isn't.






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

Andrew Cagney <ac131313@cygnus.com> on 05.07.2001 05:07:52

Please respond to Andrew Cagney <ac131313@cygnus.com>

To:   Denis Joseph Barrow/Germany/Contr/IBM@IBMDE
cc:   gdb-patches@sourceware.cygnus.com, s390-patches@gnu.org, Martin
      Schwidefsky/Germany/IBM@IBMDE, Christoph Arenz/Germany/IBM@IBMDE
Subject:  Re: New gdb 31 & 64 bit patches for S/390




DJB,

I'm trying to build an s390 cross debugger.  Actually I'm trying to build:

     ./configure --target=s390-elf

s390-elf being a a fairly generic s390 target.

The reason for doing this is to ensure that the non linix specific parts
of the s390 target really are native independant.  If you check the
MAINTAINERS file you'll notice that all targets (with the exception of
the HP/PA, which has no maintainer) can be built as a cross debugger.

Any way, I'm not having much luck.

The configury changes needed for this are very straight forward.
Unfortunatly the tweeks to s390-tdep.c are not.  Sigh.  For the record,
the problems are not new.

As I suggested last time, I can think of two possible courses of action:

     o    we try to fix the s390 problems
          and then get an IBM copyright transfer

     o    IBM transfer copyright for these files
          to the FSF and then they be included in
          GDB as a patch.  This would free up the
          code so that others can address the problems.

A very detailed commentry on the file s390-tdep.c is attached.

     Andrew



--- /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 */

This is wrong.  tm-s390.h shouldn't be affected by s390-tdep.c.

+#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"

Recent changes to GDB may mean that "tm.h" is no longer be needed for
native targets.  For the moment I'll assume it is.

Thinking about this, I suspect what you really need is ``s390-tdep.h''
(included by s390-tdep.c and s390-nat.c).  That could contain all the
constants that need to be shared between the s390-* files with out
needing to define them globally.

+#include "../bfd/bfd.h"

That should be #include "bfd.h"

+#include "floatformat.h"
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif

See earlier post.  Your code contains constructs such as:

++  if (good_prologue == TRUE)
++  for (second_pass = FALSE; second_pass <= TRUE; second_pass++)
++      if (init_extra_info || fextra_info->initialised == FALSE)
++     if (frame_pointer_found == FALSE && regidx == 0xb)
++        && fextra_info.good_prologue == FALSE);

such expressions should be written as:

     if (good_prologue)
     if (!fextra_info.good_prologue)

With that in mind (and per previous e-mail), i'd fix the conditionals
and replace ``TRUE'' with 1, ``FALSE'' with 0.

+
+#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)

All of these macro's are very unportable.  They assume HOST=TARGET.
The gdbint document goes into some detail on how important it is to
not write code that assumes this.

In the past it has been suggested that types like _u32, _u8 etc would
allow the user to exactly describe structures and hence allow the
programmer to exactly describe structure layout.  Unfortunatly, that
won't work since allignment (and hence packing) also varies between
hosts.

If you need to read structures from memory you can use functions like:

     LONGEST read_memory_integer (CORE_ADDR memaddr, int len);
     ULONGEST read_memory_unsigned_integer (CORE_ADDR memaddr, int len);

If you already have the memory local then:

     LONGEST extract_signed_integer (void *, int);
     ULONGEST extract_unsigned_integer (void *, int);

will do the trick.

+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
*/

See comment above.  This is either going to be small (int) or large
(LONGEST).

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

The function name should be s390_read_instruction (see GNU coding
standard).

The first parameter should be just ``char *insr'' or ``char insr[]''.
Don't use __u8.  Yes, strictly speaking this means that GDB assumes
tha sizeof(char) == one eight bit byte.  However, per the comment in
findvar.c:

#if TARGET_CHAR_BIT != 8 || HOST_CHAR_BIT != 8
  /* 8 bit characters are a pretty safe assumption these days, so we
     assume it throughout all these swapping routines.  If we had to deal
with
     9 bit characters, we would need to make len be in bits and would have
     to re-write these routines...  */
you lose
#endif

The changes below will make the third parameter redundant.

+{
+  int instrlen;
+
+  static int s390_instrlen[] = {
+    2,
+    4,
+    4,
+    6
+  };
+  if ((*info->read_memory_func) (at, &instr[0], 2, info))

Just use the function:

     target_read_memory (at, insr, 2);

see corefile.c:read_memory() for an example of how to check the return
value.

+    return -1;
+  instrlen = s390_instrlen[instr[0] >> 6];
+  if ((*info->read_memory_func) (at + 2, &instr[2], instrlen - 2, info))
+    return -1;

Again, just use:

     target_read_memory (....)

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

The macro S390_REGISTER_NAMES is not needed.  Instead just move the
macro contents to here.

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

See the GNU coding standard.  This expression should be written with
``||'' at the start of a line and indented / parenthesized something
like:

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

Please rewrite this as:

     if (regno >= 64)
       return S390_PSWM_REGNUM - 64;
     else if (regno >= 48)
       return  S390_FIRST_ACR - 48;
     ....

+}
+
+
+
+/* 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

These should be enums.

+  __u8 instr[S390_MAX_INSTR_SIZE];

Per above.  char is sufficient.

+  CORE_ADDR test_pc = pc, test_pc2;

While I have a personal preference for one variable declaraton per
line, one assignment per line, the GNU coding standard does tolerate
this.

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

These state variables need to be implemented as enums and explicit
states.  At the end of the code the expression:

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

put simply, I have no idea what this does (yet I should).

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

Per comments above, ``info'' isn't needed.

+
+  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)
+    {

Take care with the coding standard - indent two spaces vis:

     if (...)
       {
         s390_....

As I suggested earlier, the easiest way to fix this is to put the code
through GNU indent.

+      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 &&

This doesn't need to be a macro. A function like:

     target_is_s390_esame()

or even the test:

     if (TARGET_ARCHITECTURE->mach == bfd_mach_s390_esame)

are sufficient.

+         ((instr[0] == 0xeb) && (instr[5] == 0x24))) ||
+           (instr[0] == 0x90)) && ((instr[2] >> 4) == 0xf))

Again see above about how to write expressions.

+        {
+          regidx = (instr[1] >> 4);
+          if (regidx < 6)
+         varargs_state = 1;
+          offset = ((*((__u16 *) & instr[2])) & 0xfff);

This isn't portable.

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

Again expressions style.

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

Again, portability, probably use:

     extract_unsigned_integer (...);

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

Style.

+        {
+          const_pool_state = 2;
+          test_pc += ((*((__u16 *) & instr[2]) << 1) - instrlen);

Remember, portability.

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

Style.

+    {
+      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))

Style.

+    {
+      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))

Style.

+    {
+      subtract_sp_regidx = instr[1] >> 4;
+      save_link_state = 2;
+      if (fextra_info)
+        target_read_memory (test_pc + instrlen,
+                   (char *) &fextra_info->stack_bought,

The cast isn't needed.

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

Style

+    {
+      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 */

Comments should be formatted vis:

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

and don't forget complete sentences and ``.  '' like I do :-)

+      if (got_state == 0 && const_pool_state == 2 && instr[0] == 0x58
+      && (instr[2] == (CONST_POOL_REGIDX << 4))
+      && ((instr[1] >> 4) == GOT_REGIDX))

style

+    {
+      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;

Indentation.  Other cases occure below.

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

This is better.

+      if (fextra_info.good_prologue)
+    function_start = fextra_info.function_start;
+    }
+  return function_start;
+}
+
+
+
+CORE_ADDR s390_function_start (struct frame_info * fi)

The function name should appear at the start of the line vis:

     CORE_ADDR
     s390_function_start (...)

I suspect it can also be made static like most of the functions in
this file.  Other cases of this occure below.

+{
+  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
+    {

Indentation.

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

Style:  ``CORE_ADDR *sregs'' not ``CORE_ADDR * sregs''.

+{
+  __u8 instr[S390_MAX_INSTR_SIZE];

char

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

Style.

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

Conditional expressions are normally indented as:

     (fextra_info.has_frame_pointer
      ? S390_FRAME_REGNUM
      : S390_SP_REGNUM)

however typically it is better to just use an IF statement vis:

+      /* 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. */

see above on how to write comments.

+
+
+
+/* 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);

Remember, space after commas.

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

Again, expression indentation.  Here, separating the two (er three!)
declarations would also be a good idea.

+      for(idx=0;idx<S390_GPR_SIZE;idx++)
+    {
+      reg_buff[idx] = (idx<diff ? (negative ? 0xff:0x0) :
+                 value[idx-diff] );

indentation

+    }
+      value=reg_buff;
+      *arglen = S390_GPR_SIZE;

Indentation `` = ''.

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

Indentation:
     return value;
or   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);

Indentation.

+      /* 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];

char

+  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.  */

Comment style.

+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 ). */

Comment style.  Suggest a blank line be tween paragraphs.

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

style.

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

Indentation.

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

Indentation and expressons.  No `` '' after ``(''.

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

This #if is not needed.  This code should always be compiled.

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

This isn't portable.  Probably need to use store_...().

+}
+/* 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;

expression style.

+}
+
+/* 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;

expression style

+}
+
+#endif
+
+#if defined(GDB_MULTI_ARCH) || defined(CONFIG_ARCH_S390X)

The #if should not be present, this code should always be compiled.

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

this isn't portable

+}
+
+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 ;

expression style.  I'd change this to a simpler if().

+}
+
+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;

expression style  I'd change this to a simpler if().

+}
+
+#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)

Don't forget, function at start of a line.

+{
+  return ADDR_BITS_REMOVE (read_register (S390_RETADDR_REGNUM));
+}
+
+#if GDB_MULTI_ARCH

The #if isn't needed.

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

Please rewrite this as an if() else if() chain.

+}
+
+#if GDB_MULTI_ARCH

The #if isn't needed.

+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

The #if isn't needed.

+  /* 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");

I don't understand what this is doing.

+}





^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: New gdb 31 & 64 bit patches for S/390
@ 2001-07-05  5:04 Denis Joseph Barrow
  0 siblings, 0 replies; 44+ messages in thread
From: Denis Joseph Barrow @ 2001-07-05  5:04 UTC (permalink / raw)
  To: Andrew Cagney
  Cc: gdb-patches, s390-patches, Binutils Patches, bash_maintainers,
	Martin Schwidefsky, Christoph Arenz

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

The code below was trying to access registers several supervisor/priviliged
mode registers,
which arent accessible from the ptrace syscall or in core files, these
registers do exist & will be used for
kernel debugging.

Its a long time ago & I can't remember the exact symtom but the code caused
incorrect behaviour on s390,
 possibly bad_reg going to 1 & it doing a quick exit.


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


Andrew Cagney <ac131313@cygnus.com> on 04.07.2001 19:13:53

Please respond to Andrew Cagney <ac131313@cygnus.com>

To:   Denis Joseph Barrow/Germany/Contr/IBM@IBMDE
cc:   gdb-patches@sourceware.cygnus.com, s390-patches@gnu.org, Binutils
      Patches <binutils@sourceware.cygnus.com>, bash_maintainers@gnu.org,
      Martin Schwidefsky/Germany/IBM@IBMDE, Christoph
      Arenz/Germany/IBM@IBMDE
Subject:  Re: New gdb 31 & 64 bit patches for S/390




DJB,

The patches included the change:

2001-02-26  D.J. Barrow <djbarrow@de.ibm.com,barrow_dj@yahoo.com>

     * core-aout.c added check for CANNOT_FETCH_REGISTER
     in fetch_core_registers.

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

Can you please expand on this change.  I don't think it is s390 specific.

     Andrew






^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: New gdb 31 & 64 bit patches for S/390
@ 2001-07-05  3:57 Denis Joseph Barrow
  2001-07-05 10:11 ` Andrew Cagney
  2001-07-05 10:11 ` Andrew Cagney
  0 siblings, 2 replies; 44+ messages in thread
From: Denis Joseph Barrow @ 2001-07-05  3:57 UTC (permalink / raw)
  To: Andrew Cagney
  Cc: gdb-patches, s390-patches, Martin Schwidefsky, Christoph Arenz

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

Hi Andrew,
It'll be at least two weeks before I can go & update this stuff owing to
other commitments.
The asm/types.h in my opinion is currently needed, Andrew if you think it
isn't, a
config/arch/hosttypes.h with definitions for u8 u16 & u32 etc. definitions
should be introduced  for all archs
IMO bfd_btye etc. as per previous suggestion simply doesn't cut mustard.

As for the  TRUE  / FALSE there is no place in the gnu coding standards
where this is practice is non condoned
you are trying to push a personal opinion here.


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

Andrew Cagney <ac131313@cygnus.com> on 05.07.2001 05:07:52

Please respond to Andrew Cagney <ac131313@cygnus.com>

To:   Denis Joseph Barrow/Germany/Contr/IBM@IBMDE
cc:   gdb-patches@sourceware.cygnus.com, s390-patches@gnu.org, Martin
      Schwidefsky/Germany/IBM@IBMDE, Christoph Arenz/Germany/IBM@IBMDE
Subject:  Re: New gdb 31 & 64 bit patches for S/390




DJB,

I'm trying to build an s390 cross debugger.  Actually I'm trying to build:

     ./configure --target=s390-elf

s390-elf being a a fairly generic s390 target.

The reason for doing this is to ensure that the non linix specific parts
of the s390 target really are native independant.  If you check the
MAINTAINERS file you'll notice that all targets (with the exception of
the HP/PA, which has no maintainer) can be built as a cross debugger.

Any way, I'm not having much luck.

The configury changes needed for this are very straight forward.
Unfortunatly the tweeks to s390-tdep.c are not.  Sigh.  For the record,
the problems are not new.

As I suggested last time, I can think of two possible courses of action:

     o    we try to fix the s390 problems
          and then get an IBM copyright transfer

     o    IBM transfer copyright for these files
          to the FSF and then they be included in
          GDB as a patch.  This would free up the
          code so that others can address the problems.

A very detailed commentry on the file s390-tdep.c is attached.

     Andrew



--- /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 */

This is wrong.  tm-s390.h shouldn't be affected by s390-tdep.c.

+#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"

Recent changes to GDB may mean that "tm.h" is no longer be needed for
native targets.  For the moment I'll assume it is.

Thinking about this, I suspect what you really need is ``s390-tdep.h''
(included by s390-tdep.c and s390-nat.c).  That could contain all the
constants that need to be shared between the s390-* files with out
needing to define them globally.

+#include "../bfd/bfd.h"

That should be #include "bfd.h"

+#include "floatformat.h"
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif

See earlier post.  Your code contains constructs such as:

++  if (good_prologue == TRUE)
++  for (second_pass = FALSE; second_pass <= TRUE; second_pass++)
++      if (init_extra_info || fextra_info->initialised == FALSE)
++     if (frame_pointer_found == FALSE && regidx == 0xb)
++        && fextra_info.good_prologue == FALSE);

such expressions should be written as:

     if (good_prologue)
     if (!fextra_info.good_prologue)

With that in mind (and per previous e-mail), i'd fix the conditionals
and replace ``TRUE'' with 1, ``FALSE'' with 0.

+
+#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)

All of these macro's are very unportable.  They assume HOST=TARGET.
The gdbint document goes into some detail on how important it is to
not write code that assumes this.

In the past it has been suggested that types like _u32, _u8 etc would
allow the user to exactly describe structures and hence allow the
programmer to exactly describe structure layout.  Unfortunatly, that
won't work since allignment (and hence packing) also varies between
hosts.

If you need to read structures from memory you can use functions like:

     LONGEST read_memory_integer (CORE_ADDR memaddr, int len);
     ULONGEST read_memory_unsigned_integer (CORE_ADDR memaddr, int len);

If you already have the memory local then:

     LONGEST extract_signed_integer (void *, int);
     ULONGEST extract_unsigned_integer (void *, int);

will do the trick.

+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
*/

See comment above.  This is either going to be small (int) or large
(LONGEST).

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

The function name should be s390_read_instruction (see GNU coding
standard).

The first parameter should be just ``char *insr'' or ``char insr[]''.
Don't use __u8.  Yes, strictly speaking this means that GDB assumes
tha sizeof(char) == one eight bit byte.  However, per the comment in
findvar.c:

#if TARGET_CHAR_BIT != 8 || HOST_CHAR_BIT != 8
  /* 8 bit characters are a pretty safe assumption these days, so we
     assume it throughout all these swapping routines.  If we had to deal
with
     9 bit characters, we would need to make len be in bits and would have
     to re-write these routines...  */
you lose
#endif

The changes below will make the third parameter redundant.

+{
+  int instrlen;
+
+  static int s390_instrlen[] = {
+    2,
+    4,
+    4,
+    6
+  };
+  if ((*info->read_memory_func) (at, &instr[0], 2, info))

Just use the function:

     target_read_memory (at, insr, 2);

see corefile.c:read_memory() for an example of how to check the return
value.

+    return -1;
+  instrlen = s390_instrlen[instr[0] >> 6];
+  if ((*info->read_memory_func) (at + 2, &instr[2], instrlen - 2, info))
+    return -1;

Again, just use:

     target_read_memory (....)

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

The macro S390_REGISTER_NAMES is not needed.  Instead just move the
macro contents to here.

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

See the GNU coding standard.  This expression should be written with
``||'' at the start of a line and indented / parenthesized something
like:

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

Please rewrite this as:

     if (regno >= 64)
       return S390_PSWM_REGNUM - 64;
     else if (regno >= 48)
       return  S390_FIRST_ACR - 48;
     ....

+}
+
+
+
+/* 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

These should be enums.

+  __u8 instr[S390_MAX_INSTR_SIZE];

Per above.  char is sufficient.

+  CORE_ADDR test_pc = pc, test_pc2;

While I have a personal preference for one variable declaraton per
line, one assignment per line, the GNU coding standard does tolerate
this.

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

These state variables need to be implemented as enums and explicit
states.  At the end of the code the expression:

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

put simply, I have no idea what this does (yet I should).

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

Per comments above, ``info'' isn't needed.

+
+  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)
+    {

Take care with the coding standard - indent two spaces vis:

     if (...)
       {
         s390_....

As I suggested earlier, the easiest way to fix this is to put the code
through GNU indent.

+      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 &&

This doesn't need to be a macro. A function like:

     target_is_s390_esame()

or even the test:

     if (TARGET_ARCHITECTURE->mach == bfd_mach_s390_esame)

are sufficient.

+         ((instr[0] == 0xeb) && (instr[5] == 0x24))) ||
+           (instr[0] == 0x90)) && ((instr[2] >> 4) == 0xf))

Again see above about how to write expressions.

+        {
+          regidx = (instr[1] >> 4);
+          if (regidx < 6)
+         varargs_state = 1;
+          offset = ((*((__u16 *) & instr[2])) & 0xfff);

This isn't portable.

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

Again expressions style.

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

Again, portability, probably use:

     extract_unsigned_integer (...);

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

Style.

+        {
+          const_pool_state = 2;
+          test_pc += ((*((__u16 *) & instr[2]) << 1) - instrlen);

Remember, portability.

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

Style.

+    {
+      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))

Style.

+    {
+      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))

Style.

+    {
+      subtract_sp_regidx = instr[1] >> 4;
+      save_link_state = 2;
+      if (fextra_info)
+        target_read_memory (test_pc + instrlen,
+                   (char *) &fextra_info->stack_bought,

The cast isn't needed.

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

Style

+    {
+      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 */

Comments should be formatted vis:

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

and don't forget complete sentences and ``.  '' like I do :-)

+      if (got_state == 0 && const_pool_state == 2 && instr[0] == 0x58
+      && (instr[2] == (CONST_POOL_REGIDX << 4))
+      && ((instr[1] >> 4) == GOT_REGIDX))

style

+    {
+      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;

Indentation.  Other cases occure below.

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

This is better.

+      if (fextra_info.good_prologue)
+    function_start = fextra_info.function_start;
+    }
+  return function_start;
+}
+
+
+
+CORE_ADDR s390_function_start (struct frame_info * fi)

The function name should appear at the start of the line vis:

     CORE_ADDR
     s390_function_start (...)

I suspect it can also be made static like most of the functions in
this file.  Other cases of this occure below.

+{
+  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
+    {

Indentation.

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

Style:  ``CORE_ADDR *sregs'' not ``CORE_ADDR * sregs''.

+{
+  __u8 instr[S390_MAX_INSTR_SIZE];

char

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

Style.

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

Conditional expressions are normally indented as:

     (fextra_info.has_frame_pointer
      ? S390_FRAME_REGNUM
      : S390_SP_REGNUM)

however typically it is better to just use an IF statement vis:

+      /* 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. */

see above on how to write comments.

+
+
+
+/* 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);

Remember, space after commas.

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

Again, expression indentation.  Here, separating the two (er three!)
declarations would also be a good idea.

+      for(idx=0;idx<S390_GPR_SIZE;idx++)
+    {
+      reg_buff[idx] = (idx<diff ? (negative ? 0xff:0x0) :
+                 value[idx-diff] );

indentation

+    }
+      value=reg_buff;
+      *arglen = S390_GPR_SIZE;

Indentation `` = ''.

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

Indentation:
     return value;
or   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);

Indentation.

+      /* 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];

char

+  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.  */

Comment style.

+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 ). */

Comment style.  Suggest a blank line be tween paragraphs.

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

style.

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

Indentation.

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

Indentation and expressons.  No `` '' after ``(''.

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

This #if is not needed.  This code should always be compiled.

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

This isn't portable.  Probably need to use store_...().

+}
+/* 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;

expression style.

+}
+
+/* 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;

expression style

+}
+
+#endif
+
+#if defined(GDB_MULTI_ARCH) || defined(CONFIG_ARCH_S390X)

The #if should not be present, this code should always be compiled.

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

this isn't portable

+}
+
+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 ;

expression style.  I'd change this to a simpler if().

+}
+
+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;

expression style  I'd change this to a simpler if().

+}
+
+#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)

Don't forget, function at start of a line.

+{
+  return ADDR_BITS_REMOVE (read_register (S390_RETADDR_REGNUM));
+}
+
+#if GDB_MULTI_ARCH

The #if isn't needed.

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

Please rewrite this as an if() else if() chain.

+}
+
+#if GDB_MULTI_ARCH

The #if isn't needed.

+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

The #if isn't needed.

+  /* 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");

I don't understand what this is doing.

+}





^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: New gdb 31 & 64 bit patches for S/390
@ 2001-07-05  3:12 Denis Joseph Barrow
  0 siblings, 0 replies; 44+ messages in thread
From: Denis Joseph Barrow @ 2001-07-05  3:12 UTC (permalink / raw)
  To: Andrew Cagney
  Cc: gdb-patches, s390-patches, Martin Schwidefsky, Christoph Arenz

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

I don't think you will manage this until I find all the endianness problems
& test them, I haven't tried to build a cross debugger & it almost
certainly will not work.


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

Andrew Cagney <ac131313@cygnus.com> on 05.07.2001 05:07:52

Please respond to Andrew Cagney <ac131313@cygnus.com>

To:   Denis Joseph Barrow/Germany/Contr/IBM@IBMDE
cc:   gdb-patches@sourceware.cygnus.com, s390-patches@gnu.org, Martin
      Schwidefsky/Germany/IBM@IBMDE, Christoph Arenz/Germany/IBM@IBMDE
Subject:  Re: New gdb 31 & 64 bit patches for S/390




DJB,

I'm trying to build an s390 cross debugger.  Actually I'm trying to build:

     ./configure --target=s390-elf

s390-elf being a a fairly generic s390 target.

The reason for doing this is to ensure that the non linix specific parts
of the s390 target really are native independant.  If you check the
MAINTAINERS file you'll notice that all targets (with the exception of
the HP/PA, which has no maintainer) can be built as a cross debugger.

Any way, I'm not having much luck.

The configury changes needed for this are very straight forward.
Unfortunatly the tweeks to s390-tdep.c are not.  Sigh.  For the record,
the problems are not new.

As I suggested last time, I can think of two possible courses of action:

     o    we try to fix the s390 problems
          and then get an IBM copyright transfer

     o    IBM transfer copyright for these files
          to the FSF and then they be included in
          GDB as a patch.  This would free up the
          code so that others can address the problems.

A very detailed commentry on the file s390-tdep.c is attached.

     Andrew



--- /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 */

This is wrong.  tm-s390.h shouldn't be affected by s390-tdep.c.

+#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"

Recent changes to GDB may mean that "tm.h" is no longer be needed for
native targets.  For the moment I'll assume it is.

Thinking about this, I suspect what you really need is ``s390-tdep.h''
(included by s390-tdep.c and s390-nat.c).  That could contain all the
constants that need to be shared between the s390-* files with out
needing to define them globally.

+#include "../bfd/bfd.h"

That should be #include "bfd.h"

+#include "floatformat.h"
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif

See earlier post.  Your code contains constructs such as:

++  if (good_prologue == TRUE)
++  for (second_pass = FALSE; second_pass <= TRUE; second_pass++)
++      if (init_extra_info || fextra_info->initialised == FALSE)
++     if (frame_pointer_found == FALSE && regidx == 0xb)
++        && fextra_info.good_prologue == FALSE);

such expressions should be written as:

     if (good_prologue)
     if (!fextra_info.good_prologue)

With that in mind (and per previous e-mail), i'd fix the conditionals
and replace ``TRUE'' with 1, ``FALSE'' with 0.

+
+#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)

All of these macro's are very unportable.  They assume HOST=TARGET.
The gdbint document goes into some detail on how important it is to
not write code that assumes this.

In the past it has been suggested that types like _u32, _u8 etc would
allow the user to exactly describe structures and hence allow the
programmer to exactly describe structure layout.  Unfortunatly, that
won't work since allignment (and hence packing) also varies between
hosts.

If you need to read structures from memory you can use functions like:

     LONGEST read_memory_integer (CORE_ADDR memaddr, int len);
     ULONGEST read_memory_unsigned_integer (CORE_ADDR memaddr, int len);

If you already have the memory local then:

     LONGEST extract_signed_integer (void *, int);
     ULONGEST extract_unsigned_integer (void *, int);

will do the trick.

+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
*/

See comment above.  This is either going to be small (int) or large
(LONGEST).

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

The function name should be s390_read_instruction (see GNU coding
standard).

The first parameter should be just ``char *insr'' or ``char insr[]''.
Don't use __u8.  Yes, strictly speaking this means that GDB assumes
tha sizeof(char) == one eight bit byte.  However, per the comment in
findvar.c:

#if TARGET_CHAR_BIT != 8 || HOST_CHAR_BIT != 8
  /* 8 bit characters are a pretty safe assumption these days, so we
     assume it throughout all these swapping routines.  If we had to deal
with
     9 bit characters, we would need to make len be in bits and would have
     to re-write these routines...  */
you lose
#endif

The changes below will make the third parameter redundant.

+{
+  int instrlen;
+
+  static int s390_instrlen[] = {
+    2,
+    4,
+    4,
+    6
+  };
+  if ((*info->read_memory_func) (at, &instr[0], 2, info))

Just use the function:

     target_read_memory (at, insr, 2);

see corefile.c:read_memory() for an example of how to check the return
value.

+    return -1;
+  instrlen = s390_instrlen[instr[0] >> 6];
+  if ((*info->read_memory_func) (at + 2, &instr[2], instrlen - 2, info))
+    return -1;

Again, just use:

     target_read_memory (....)

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

The macro S390_REGISTER_NAMES is not needed.  Instead just move the
macro contents to here.

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

See the GNU coding standard.  This expression should be written with
``||'' at the start of a line and indented / parenthesized something
like:

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

Please rewrite this as:

     if (regno >= 64)
       return S390_PSWM_REGNUM - 64;
     else if (regno >= 48)
       return  S390_FIRST_ACR - 48;
     ....

+}
+
+
+
+/* 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

These should be enums.

+  __u8 instr[S390_MAX_INSTR_SIZE];

Per above.  char is sufficient.

+  CORE_ADDR test_pc = pc, test_pc2;

While I have a personal preference for one variable declaraton per
line, one assignment per line, the GNU coding standard does tolerate
this.

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

These state variables need to be implemented as enums and explicit
states.  At the end of the code the expression:

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

put simply, I have no idea what this does (yet I should).

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

Per comments above, ``info'' isn't needed.

+
+  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)
+    {

Take care with the coding standard - indent two spaces vis:

     if (...)
       {
         s390_....

As I suggested earlier, the easiest way to fix this is to put the code
through GNU indent.

+      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 &&

This doesn't need to be a macro. A function like:

     target_is_s390_esame()

or even the test:

     if (TARGET_ARCHITECTURE->mach == bfd_mach_s390_esame)

are sufficient.

+         ((instr[0] == 0xeb) && (instr[5] == 0x24))) ||
+           (instr[0] == 0x90)) && ((instr[2] >> 4) == 0xf))

Again see above about how to write expressions.

+        {
+          regidx = (instr[1] >> 4);
+          if (regidx < 6)
+         varargs_state = 1;
+          offset = ((*((__u16 *) & instr[2])) & 0xfff);

This isn't portable.

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

Again expressions style.

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

Again, portability, probably use:

     extract_unsigned_integer (...);

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

Style.

+        {
+          const_pool_state = 2;
+          test_pc += ((*((__u16 *) & instr[2]) << 1) - instrlen);

Remember, portability.

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

Style.

+    {
+      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))

Style.

+    {
+      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))

Style.

+    {
+      subtract_sp_regidx = instr[1] >> 4;
+      save_link_state = 2;
+      if (fextra_info)
+        target_read_memory (test_pc + instrlen,
+                   (char *) &fextra_info->stack_bought,

The cast isn't needed.

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

Style

+    {
+      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 */

Comments should be formatted vis:

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

and don't forget complete sentences and ``.  '' like I do :-)

+      if (got_state == 0 && const_pool_state == 2 && instr[0] == 0x58
+      && (instr[2] == (CONST_POOL_REGIDX << 4))
+      && ((instr[1] >> 4) == GOT_REGIDX))

style

+    {
+      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;

Indentation.  Other cases occure below.

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

This is better.

+      if (fextra_info.good_prologue)
+    function_start = fextra_info.function_start;
+    }
+  return function_start;
+}
+
+
+
+CORE_ADDR s390_function_start (struct frame_info * fi)

The function name should appear at the start of the line vis:

     CORE_ADDR
     s390_function_start (...)

I suspect it can also be made static like most of the functions in
this file.  Other cases of this occure below.

+{
+  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
+    {

Indentation.

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

Style:  ``CORE_ADDR *sregs'' not ``CORE_ADDR * sregs''.

+{
+  __u8 instr[S390_MAX_INSTR_SIZE];

char

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

Style.

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

Conditional expressions are normally indented as:

     (fextra_info.has_frame_pointer
      ? S390_FRAME_REGNUM
      : S390_SP_REGNUM)

however typically it is better to just use an IF statement vis:

+      /* 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. */

see above on how to write comments.

+
+
+
+/* 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);

Remember, space after commas.

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

Again, expression indentation.  Here, separating the two (er three!)
declarations would also be a good idea.

+      for(idx=0;idx<S390_GPR_SIZE;idx++)
+    {
+      reg_buff[idx] = (idx<diff ? (negative ? 0xff:0x0) :
+                 value[idx-diff] );

indentation

+    }
+      value=reg_buff;
+      *arglen = S390_GPR_SIZE;

Indentation `` = ''.

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

Indentation:
     return value;
or   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);

Indentation.

+      /* 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];

char

+  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.  */

Comment style.

+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 ). */

Comment style.  Suggest a blank line be tween paragraphs.

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

style.

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

Indentation.

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

Indentation and expressons.  No `` '' after ``(''.

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

This #if is not needed.  This code should always be compiled.

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

This isn't portable.  Probably need to use store_...().

+}
+/* 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;

expression style.

+}
+
+/* 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;

expression style

+}
+
+#endif
+
+#if defined(GDB_MULTI_ARCH) || defined(CONFIG_ARCH_S390X)

The #if should not be present, this code should always be compiled.

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

this isn't portable

+}
+
+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 ;

expression style.  I'd change this to a simpler if().

+}
+
+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;

expression style  I'd change this to a simpler if().

+}
+
+#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)

Don't forget, function at start of a line.

+{
+  return ADDR_BITS_REMOVE (read_register (S390_RETADDR_REGNUM));
+}
+
+#if GDB_MULTI_ARCH

The #if isn't needed.

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

Please rewrite this as an if() else if() chain.

+}
+
+#if GDB_MULTI_ARCH

The #if isn't needed.

+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

The #if isn't needed.

+  /* 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");

I don't understand what this is doing.

+}





^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: New gdb 31 & 64 bit patches for S/390
@ 2001-06-18  3:32 DJBARROW
  0 siblings, 0 replies; 44+ messages in thread
From: DJBARROW @ 2001-06-18  3:32 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: gdb-patches

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

Hi Andrew,
It is a 31 bit architecture owing to an addressing mode limitation ( it
never was known as a 32 bit arch though all the registers are 32 bit ).
The 370 was 24 bit & a beautiful design decision was made to signify a 31
bit address to use the hi bit of a 32 bit address.
After recognising their mistake the zSeries is 64 bit clean.




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


Andrew Cagney <ac131313@cygnus.com> on 15.06.2001 18:52:52

Please respond to Andrew Cagney <ac131313@cygnus.com>

To:   Denis Joseph Barrow/Germany/Contr/IBM@IBMDE
cc:   gdb-patches@sourceware.cygnus.com, s390-patches@gnu.org, Martin
      Schwidefsky/Germany/IBM@IBMDE, Christoph Arenz/Germany/IBM@IBMDE
Subject:  Re: New gdb 31 & 64 bit patches for S/390




^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: New gdb 31 & 64 bit patches for S/390
       [not found] <C1256A02.00573066.00@d12mta09.de.ibm.com>
@ 2001-03-01 10:39 ` Nick Clifton
  0 siblings, 0 replies; 44+ messages in thread
From: Nick Clifton @ 2001-03-01 10:39 UTC (permalink / raw)
  To: ARENZ; +Cc: gdb-patches, DJBARROW, s390-patches

Hi Christopher,

> So please let me know if you are going to accept these patches
> (i.e. technically) and if you need a new software letter for them. I
> will then set up the paperwork and help to get it signed quickly.

I have accepted the binutils portion of the patch, and it does not
really need a copyright assignment, since it is so simple and
"obvious".  I have not accepted the other parts of the patch (GDB,
readline, top-level configure) since these are outside of my domain.

Cheers
        Nick


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: New gdb 31 & 64 bit patches for S/390
  2001-03-01  2:50 DJBARROW
@ 2001-03-01 10:37 ` Nick Clifton
  0 siblings, 0 replies; 44+ messages in thread
From: Nick Clifton @ 2001-03-01 10:37 UTC (permalink / raw)
  To: DJBARROW
  Cc: ARENZ, Denis.Joseph.Barrow/Germany/Contr/IBM, gdb-patches,
	s390-patches, Binutils Patches, Christoph.Arenz/Germany/IBM

Hi Denis,

> The name is Denis,

oops - sorry!

> Yup the patches are I've sent in are all contributed/written by me
> on behalf of IBM, IBM has already sent in the copyright assignment
> for the binutils the patch to the binutils is only one line in a
> configure file likewise for readline.

Good point.  The binutils part of the patch is approved and I will
apply it shortly.

Cheers
        Nick


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: New gdb 31 & 64 bit patches for S/390
@ 2001-03-01  2:50 DJBARROW
  2001-03-01 10:37 ` Nick Clifton
  0 siblings, 1 reply; 44+ messages in thread
From: DJBARROW @ 2001-03-01  2:50 UTC (permalink / raw)
  To: Nick Clifton, ARENZ; +Cc: gdb-patches

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

Hi Nick,
The name is Denis, Yup the patches are I've sent in are all
contributed/written by me on behalf of IBM, IBM has already sent in the
copyright assignment
for the binutils the patch to the binutils is only one line in a configure
file likewise for readline. Owing to difficulties of not yet securing a
future assignment
form for gdb from the legal clearance guys.
Christoph Arenz needs to know the patches are accepted before we send in
assignment forms rather than replicate work needlessly for him.
We promise it will be in as soon as possible ( we could fax a copy the day
it is signed & post it afterwards ).


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


Nick Clifton <nickc@redhat.com> on 01.03.2001 01:12:56

Please respond to Nick Clifton <nickc@redhat.com>

To:   Denis Joseph Barrow/Germany/Contr/IBM@IBMDE
cc:   gdb-patches@sourceware.cygnus.com, s390-patches@gnu.org, Binutils
      Patches <binutils@sourceware.cygnus.com>, Christoph
      Arenz/Germany/IBM@IBMDE
Subject:  Re: New gdb 31 & 64 bit patches for S/390




^ permalink raw reply	[flat|nested] 44+ messages in thread

end of thread, other threads:[~2001-09-05 21:45 UTC | newest]

Thread overview: 44+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-02-27 12:39 New gdb 31 & 64 bit patches for S/390 DJBARROW
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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox