S/390 31 & 64 bit target and GNU/Linux native support.

Contributed by D.J. Barrow <djbarrow@de.ibm.com> of IBM.
* s390-nat.c, s390-tdep.c: New file.
* config/s390/nm-linux.h, config/s390/s390.mh: New file.
* config/s390/s390.mt, config/s390/s390x.mt: New file.
* config/s390/tm-linux.h, config/s390/tm-s390.h: New file.
* config/s390/xm-linux.h: New file.
* NEWS: Update.
* MAINTAINERS: Update.
This commit is contained in:
Andrew Cagney 2001-10-13 22:13:35 +00:00
parent 83e6b173e7
commit 5769d3cd7d
12 changed files with 2141 additions and 0 deletions

View File

@ -1,3 +1,15 @@
2001-10-13 Andrew Cagney <ac131313@redhat.com>
S/390 31 & 64 bit target and GNU/Linux native support.
Contributed by D.J. Barrow <djbarrow@de.ibm.com> of IBM.
* s390-nat.c, s390-tdep.c: New file.
* config/s390/nm-linux.h, config/s390/s390.mh: New file.
* config/s390/s390.mt, config/s390/s390x.mt: New file.
* config/s390/tm-linux.h, config/s390/tm-s390.h: New file.
* config/s390/xm-linux.h: New file.
* NEWS: Update.
* MAINTAINERS: Update.
2001-10-13 Andrew Cagney <ac131313@redhat.com>
From 2001-07-09 D.J. Barrow <djbarrow@de.ibm.com>:

View File

@ -128,6 +128,9 @@ maintainer works with the native maintainer when resolving API issues.
rs6000 --target=rs6000-ibm-aix3.2,rs6000-ibm-aix4.1 ,-Werror
(see rs6000 native and ppc target)
s390 --target=s390-linux ,-Werror
(contact DJ Barrow djbarrow@de.ibm.com)
sh --target=sh-hms,sh-elf ,-Werror
Elena Zannoni ezannoni@redhat.com

View File

@ -10,6 +10,7 @@ x86 FreeBSD 3.x and 4.x i[3456]86*-freebsd[34]*
MIPS Linux mips*-*-linux*
MIPS SGI Irix 6.x mips*-sgi-irix6*
ia64 AIX ia64-*-aix*
s390 and s390x Linux {s390,s390x}-*-linux*
* New targets

View File

@ -0,0 +1,92 @@
/* Native support for Linux for S390
Copyright 2001 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 (PIDGET (inferior_ptid), addr, len, type)
#define target_remove_watchpoint(addr, len, type) \
s390_remove_watchpoint (PIDGET (inferior_ptid), 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 (PIDGET(inferior_ptid)))
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))
#undef PREPARE_TO_PROCEED
extern void lin_lwp_attach_lwp (ptid_t ptid, int verbose);
#define ATTACH_LWP(ptid, verbose) lin_lwp_attach_lwp ((ptid), (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 */

15
gdb/config/s390/s390.mh Normal file
View File

@ -0,0 +1,15 @@
# Host: S390, running Linux
XM_FILE= xm-linux.h
XDEPFILES= ser-tcp.o
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+= thread-db.o lin-lwp.o proc-service.o
LOADLIBES = -ldl -rdynamic

7
gdb/config/s390/s390.mt Normal file
View File

@ -0,0 +1,7 @@
# Target: S390 running Linux
TM_FILE= tm-linux.h
TDEPFILES=s390-tdep.o solib.o
# Post 5.0 tdep-files
TDEPFILES+=solib-svr4.o solib-legacy.o
GDB_MULTI_ARCH=GDB_MULTI_ARCH_PARTIAL
GDBSERVER_DEPFILES= low-linux.o s390-tdep.o s390-nat.o

9
gdb/config/s390/s390x.mt Normal file
View File

@ -0,0 +1,9 @@
# Target: S390 running Linux
TM_FILE= tm-linux.h
TDEPFILES=s390-tdep.o solib.o
# Post 5.0 tdep-files
TDEPFILES+=solib-svr4.o solib-legacy.o
GDB_MULTI_ARCH=GDB_MULTI_ARCH_PARTIAL
GDBSERVER_DEPFILES= low-linux.o s390-tdep.o s390-nat.o
# needed for gdbserver.
MT_CFLAGS= -DCONFIG_ARCH_S390X

View File

@ -0,0 +1,42 @@
/* Target definitions for GDB for a s390 running Linux.
Copyright 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
#ifdef GDBSERVER
#define S390_GNULINUX_TARGET
#endif /* GDBSERVER */
#undef TARGET_ELF64
#define TARGET_ELF64 (gdbarch_tdep (current_gdbarch)->intreg_size==8)
#include "config/tm-linux.h"
/* Zap several macros defined in the above header so that multi-arch
can safely re-define them. The ``correct fix'' involves
eliminating either the above include or even this file. */
#undef SKIP_TRAMPOLINE_CODE
#include "s390/tm-s390.h"
#endif /* TM_LINUX_H */

115
gdb/config/s390/tm-s390.h Normal file
View File

@ -0,0 +1,115 @@
/* Macro definitions for GDB on an S390.
Copyright 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
#define S390_NUM_GPRS (16)
#define S390_GPR_SIZE REGISTER_SIZE
#define S390_PSW_MASK_SIZE REGISTER_SIZE
#define S390_PSW_ADDR_SIZE 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 REGISTER_SIZE
#define S390_NUM_ACRS (16)
#define S390_ACR_SIZE (4)
#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
#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)
#define S390_REGISTER_BYTES ((4+4)+(4*S390_NUM_GPRS)+(4*S390_NUM_ACRS)+ \
(4*S390_NUM_CRS)+(S390_FPC_SIZE+S390_FPC_PAD_SIZE)+(S390_FPR_SIZE*S390_NUM_FPRS))
#define S390X_REGISTER_BYTES ((8+8)+(8*S390_NUM_GPRS)+(4*S390_NUM_ACRS)+ \
(8*S390_NUM_CRS)+(S390_FPC_SIZE+S390_FPC_PAD_SIZE)+(S390_FPR_SIZE*S390_NUM_FPRS))
#ifdef GDBSERVER
int s390_register_byte (int reg_nr);
#define REGISTER_BYTE(reg_nr) s390_register_byte(reg_nr)
#define PC_REGNUM S390_PC_REGNUM
#define NUM_REGS S390_NUM_REGS
#define NUM_FREGS S390_NUM_FPRS
#define FP_REGNUM S390_FP_REGNUM
#define SP_REGNUM S390_SP_REGNUM
/* 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)
#if CONFIG_ARCH_S390X
int s390x_register_raw_size (int reg_nr);
#define REGISTER_RAW_SIZE(reg_nr) s390x_register_raw_size(reg_nr)
#define GDB_TARGET_IS_ESAME (1)
#define REGISTER_SIZE (8)
#define REGISTER_BYTES S390X_REGISTER_BYTES
#else /* CONFIG_ARCH_S390X */
int s390_register_raw_size (int reg_nr);
#define REGISTER_RAW_SIZE(reg_nr) s390_register_raw_size(reg_nr)
#define GDB_TARGET_IS_ESAME (0)
#define REGISTER_SIZE (4)
#define REGISTER_BYTES S390_REGISTER_BYTES
#endif /* CONFIG_ARCH_S390X */
#else /* GDBSERVER */
#define GDB_TARGET_IS_ESAME (TARGET_ARCHITECTURE->mach == bfd_mach_s390_esame)
#endif /* GDBSERVER */
#endif /* ifndef TM_S390_H */

View File

@ -0,0 +1,33 @@
/* Native support for GNU/Linux, for GDB, the GNU debugger.
Copyright 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
#endif /* #ifndef XM_LINUX_H */

308
gdb/s390-nat.c Normal file
View File

@ -0,0 +1,308 @@
/* S390 native-dependent code for GDB, the GNU debugger.
Copyright 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>
#include <sys/ucontext.h>
#ifndef offsetof
#define offsetof(type,member) ((size_t) &((type *)0)->member)
#endif
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
{
#ifdef GDBSERVER
error
#else
internal_error
#endif
("s390_register_u_addr invalid regnum %s %d regnum=%d", __FILE__,
(int) __LINE__, regnum);
retval = 0;
}
return retval + blockend;
}
#ifndef GDBSERVER
/* 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 = offsetof (struct user_regs_struct, 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;
greg_t *gregp = (greg_t *) gregsetp;
supply_register (S390_PSWM_REGNUM, (char *) &gregp[S390_PSWM_REGNUM]);
supply_register (S390_PC_REGNUM, (char *) &gregp[S390_PC_REGNUM]);
for (regi = 0; regi < S390_NUM_GPRS; regi++)
supply_register (S390_GP0_REGNUM + regi,
(char *) &gregp[S390_GP0_REGNUM + regi]);
for (regi = 0; regi < S390_NUM_ACRS; regi++)
supply_register (S390_FIRST_ACR + regi,
(char *) &gregp[S390_FIRST_ACR + 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)
{
greg_t *gregp = (greg_t *) gregsetp;
if (regno >= S390_FIRST_CR && regno <= S390_LAST_CR)
supply_register (regno, NULL);
else if (regno != -1)
supply_register (regno, (char *) &gregp[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,
&((char *) 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
#endif /* GDBSERVER */

1504
gdb/s390-tdep.c Normal file

File diff suppressed because it is too large Load Diff