mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 03:54:41 +08:00
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:
parent
83e6b173e7
commit
5769d3cd7d
@ -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>:
|
||||
|
@ -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
|
||||
|
||||
|
1
gdb/NEWS
1
gdb/NEWS
@ -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
|
||||
|
||||
|
92
gdb/config/s390/nm-linux.h
Normal file
92
gdb/config/s390/nm-linux.h
Normal 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
15
gdb/config/s390/s390.mh
Normal 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
7
gdb/config/s390/s390.mt
Normal 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
9
gdb/config/s390/s390x.mt
Normal 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
|
42
gdb/config/s390/tm-linux.h
Normal file
42
gdb/config/s390/tm-linux.h
Normal 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
115
gdb/config/s390/tm-s390.h
Normal 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 */
|
33
gdb/config/s390/xm-linux.h
Normal file
33
gdb/config/s390/xm-linux.h
Normal 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
308
gdb/s390-nat.c
Normal 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
1504
gdb/s390-tdep.c
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user