* [PATCH] S/390 port modernization 1/4
@ 2003-12-04 20:06 Ulrich Weigand
2003-12-04 21:01 ` Jim Blandy
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Ulrich Weigand @ 2003-12-04 20:06 UTC (permalink / raw)
To: gdb-patches; +Cc: uweigand
Hello,
this is patch 1/4 to update the s390 backend.
The main focus of this patch is to get register handling switched to the
new methods. The changes in particular:
- Remove the gdbarch calls to:
set_gdbarch_deprecated_max_register_raw_size,
set_gdbarch_deprecated_max_register_virtual_size,
set_gdbarch_deprecated_register_byte,
set_gdbarch_deprecated_register_size,
set_gdbarch_deprecated_register_raw_size,
set_gdbarch_deprecated_register_virtual_size,
set_gdbarch_deprecated_register_virtual_type,
set_gdbarch_deprecated_register_bytes.
and replace them by a new register_type and an updated register_name
gdbarch function.
- Completely remove all mention of control registers, as these are not
accessible from user space anyway. This allows us to get rid of the
cannot_fetch_register / cannot_store_register calls.
This change also affects gdbserver.
- Implement the pseudo-register mechanism to break out the two user-
visible components of the Program Status Word, namely the PC and the
condition code, into separate pseudo registers.
- Implement the register-group mechanism to restrict the default
display of 'info reg' to the important registers: the general
purpose registers, PC and condition code.
- Implement convert_register_p, register_to_value, and value_to_register
in order to correctly access 'float' values in the *high-order* part
of floating point registers.
- Implement regset_from_core_section to replace the core-regset.o method.
- Implement in_function_epilogue_p to fix watch point test case regressions.
- Update the gdb.base/float.exp test case to work on s390*-*-*.
- Implement fetch_inferior_registers and store_inferior_registers in
s390-nat.c, replacing the core-aout.o mechanism. This also allows
for more efficient ptrace access by retrieving registers in a
single ptrace call.
In addition, the patch implements some cleanups to the build process that
became possible by the above changes:
- Merge s390-*-* and s390x-*-* into a single target in configure.tgt
and remove the s390x.mt fragment.
- Completely remove the tm-s390.h header file; all values defined there
are either no longer used or moved to s390-tdep.c.
Tested on s390-ibm-linux and s390x-ibm-linux with no new regressions.
Fixes 5 unexpected failures on s390 and 52 unexpected failures on s390x.
Bye,
Ulrich
ChangeLog:
* config/s390/nm-linux.h: Update comments. Do not include "solib.h".
(KERNEL_U_ADDR, REGISTER_U_ADDR, U_REGS_OFFSET): Remove.
(FETCH_INFERIOR_REGISTERS): Define.
* config/s390/s390.mh (NATDEPFILES): Remove core-aout.o and
core-regset.o.
* config/s390/s390x.mt: Remove.
* config/s390/tm-s390.h: Remove.
* config/s390/tm-linux.h: Do not include "s390/tm-s390.h".
(TARGET_ELF64): Remove.
* configure.tgt [s390-*-*, s390x-*-*]: Merge into single
s390*-*-* case; always set gdb_target to s390.
* regformats/reg-s390.dat: Remove control registers.
* regformats/reg-s390x.dat: Likewise.
* s390-nat.c: Do not include <asm/processor.h> or <value.h>.
Include "inferior.h", <string.h>, and <stdlib.h>. Remove
private definition of offsetof.
(s390_register_u_addr): Remove.
(s390_gregset_regmap, s390_gregset_regmap_len): New variables.
(s390_fpregset_regmap, s390_fpregset_regmap_len): Likewise.
(supply_gregset, fill_gregset): Reimplement.
(supply_fpregset, fill_fpregset): Likewise.
(s390_inferior_tid): New function.
(fetch_regs, store_regs, fetch_fpregs, store_fpregs): Likewise.
(fetch_inferior_registers, store_inferior_registers): Likewise.
* s390-tdep.c: Do not define S390_TDEP. Include "defs.h" instead
of <defs.h>. Include "reggroups.h" and "regset.h".
(struct gdbarch_tdep): Define.
(S390_PSWM_REGNUM, S390_PSWA_REGNUM, S390_R0_REGNUM-S390_R15_REGNUM,
S390_A0_REGNUM-S390_A15_REGNUM, S390_F0_REGNUM-S390_F15_REGNUM,
S390_FPC_REGNUM, S390_NUM_REGS): Define.
(S390_PC_REGNUM, S390_CC_REGNUM, S390_NUM_PSEUDO_REGS,
S390_NUM_TOTAL_REGS): Define.
(S390_SP_REGNUM, S390_RETADDR_REGNUM, S390_FRAME_REGNUM): Define.
Global replace of S390_GP0_REGNUM by S390_R0_REGNUM.
Global replace of S390_FP0_REGNUM by S390_F0_REGNUM.
(struct s390_register_info): Define.
(s390_register_info): New variable.
(s390_register_name): Reimplement.
(s390_register_type): New function.
(s390_register_raw_size, s390x_register_raw_size): Remove.
(s390_cannot_fetch_register): Remove.
(s390_register_byte): Remove.
(s390_register_virtual_type, s390x_register_virtual_type): Remove.
(s390_dwarf_regmap, s390_dwarf_regmap_len): New variables.
(s390_dwarf_reg_to_regnum): New function.
(s390_stab_reg_to_regnum): Remove.
(s390_pseudo_register_read, s390_pseudo_register_write): New functions.
(s390x_pseudo_register_read, s390x_pseudo_register_write): Likewise.
(s390_convert_register_p): Likewise.
(s390_register_to_value, s390_value_to_register): Likewise.
(s390_register_reggroup_p): Likewise.
(s390_sizeof_gregset, s390x_sizeof_gregset): Define.
(s390_regmap_gregset, s390x_regmap_gregset): New variables.
(s390_sizeof_fpregset): Define.
(s390_regmap_fpregset): New variable.
(s390_supply_regset, s390_regset_from_core_section): New functions.
(GDB_TARGET_IS_ESAME): Move here from tm-s390.h.
(S390_FPR_SIZE): Likewise.
(S390_GPR_SIZE): Likewise. Redefine in terms of GDB_TARGET_IS_ESAME.
Global replace of DEPRECATED_REGISTER_SIZE by S390_GPR_SIZE.
(S390_NUM_GPRS): Move here from tm-s390.h.
(S390_NUM_FPRS): Likewise.
(s390_in_function_epilogue_p): New function.
(s390_is_sigreturn): Replace S390_PSW_ADDR_SIZE by S390_GPR_SIZE.
Replace S390_PC_REGNUM by S390_PSWA_REGNUM.
(s390_gdbarch_init): Allocate and set up gdbarch_tdep structure.
Replace s390_stab_reg_to_regnum by s390_dwarf_reg_to_regnum.
Replace S390_FP_REGNUM by S390_SP_REGNUM.
Remove calls to:
set_gdbarch_deprecated_max_register_raw_size,
set_gdbarch_deprecated_max_register_virtual_size,
set_gdbarch_deprecated_register_byte,
set_gdbarch_cannot_fetch_register,
set_gdbarch_cannot_store_register,
set_gdbarch_deprecated_register_size,
set_gdbarch_deprecated_register_raw_size,
set_gdbarch_deprecated_register_virtual_size,
set_gdbarch_deprecated_register_virtual_type,
set_gdbarch_deprecated_register_bytes.
Add calls to:
set_gdbarch_num_pseudo_regs,
set_gdbarch_register_type,
set_gdbarch_convert_register_p,
set_gdbarch_register_to_value,
set_gdbarch_value_to_register,
set_gdbarch_register_reggroup_p,
set_gdbarch_regset_from_core_section,
set_gdbarch_pseudo_register_read,
set_gdbarch_pseudo_register_write,
set_gdbarch_in_function_epilogue_p.
* Makefile.in (s390-nat.o, s390-tdep.o): Update dependencies.
gdbserver/ChangeLog:
* linux-s390-low.c (s390_num_regs): Update.
(s390_regmap): Remove control registers. Use __s390x__ predefine
instead of GPR_SIZE to distiguish s390 and s390x targets.
testsuite/ChangeLog:
* gdb.base/float.exp: Support s390*-*-* targets.
diff -c -p -r -N gdb-head/gdb/Makefile.in gdb-head-new/gdb/Makefile.in
*** gdb-head/gdb/Makefile.in Tue Dec 2 17:47:36 2003
--- gdb-head-new/gdb/Makefile.in Tue Dec 2 16:36:15 2003
*************** rs6000-tdep.o: rs6000-tdep.c $(defs_h) $
*** 2249,2259 ****
$(parser_defs_h) $(osabi_h) $(libbfd_h) $(coff_internal_h) \
$(libcoff_h) $(coff_xcoff_h) $(libxcoff_h) $(elf_bfd_h) \
$(solib_svr4_h) $(ppc_tdep_h) $(gdb_assert_h) $(dis_asm_h)
! s390-nat.o: s390-nat.c $(defs_h) $(tm_h) $(regcache_h)
! s390-tdep.o: s390-tdep.c $(arch_utils_h) $(frame_h) $(inferior_h) \
$(symtab_h) $(target_h) $(gdbcore_h) $(gdbcmd_h) $(symfile_h) \
$(objfiles_h) $(tm_h) $(__bfd_bfd_h) $(floatformat_h) $(regcache_h) \
! $(value_h) $(gdb_assert_h) $(dis_asm_h)
scm-exp.o: scm-exp.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(expression_h) \
$(parser_defs_h) $(language_h) $(value_h) $(c_lang_h) $(scm_lang_h) \
$(scm_tags_h)
--- 2249,2259 ----
$(parser_defs_h) $(osabi_h) $(libbfd_h) $(coff_internal_h) \
$(libcoff_h) $(coff_xcoff_h) $(libxcoff_h) $(elf_bfd_h) \
$(solib_svr4_h) $(ppc_tdep_h) $(gdb_assert_h) $(dis_asm_h)
! s390-nat.o: s390-nat.c $(defs_h) $(tm_h) $(regcache_h) $(inferior_h)
! s390-tdep.o: s390-tdep.c $(defs_h) $(arch_utils_h) $(frame_h) $(inferior_h) \
$(symtab_h) $(target_h) $(gdbcore_h) $(gdbcmd_h) $(symfile_h) \
$(objfiles_h) $(tm_h) $(__bfd_bfd_h) $(floatformat_h) $(regcache_h) \
! $(reggroups_h) $(regset_h) $(value_h) $(gdb_assert_h) $(dis_asm_h)
scm-exp.o: scm-exp.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(expression_h) \
$(parser_defs_h) $(language_h) $(value_h) $(c_lang_h) $(scm_lang_h) \
$(scm_tags_h)
diff -c -p -r -N gdb-head/gdb/config/s390/nm-linux.h gdb-head-new/gdb/config/s390/nm-linux.h
*** gdb-head/gdb/config/s390/nm-linux.h Tue Dec 2 17:47:36 2003
--- gdb-head-new/gdb/config/s390/nm-linux.h Tue Dec 2 16:36:15 2003
***************
*** 27,55 ****
#include "config/nm-linux.h"
- /* 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 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 */
--- 27,42 ----
#include "config/nm-linux.h"
! /* ptrace access. */
+ #define PTRACE_ARG3_TYPE long
+ #define PTRACE_XFER_TYPE long
! #define FETCH_INFERIOR_REGISTERS
! #define KERNEL_U_SIZE kernel_u_size()
! extern int kernel_u_size (void);
/* WATCHPOINT SPECIFIC STUFF */
*************** extern int s390_remove_watchpoint (int p
*** 81,88 ****
((type) == bp_read_watchpoint) || \
((type) == bp_access_watchpoint))
-
- /* Needed for s390x */
- #define PTRACE_ARG3_TYPE long
- #define PTRACE_XFER_TYPE long
#endif /* nm_linux.h */
--- 68,71 ----
diff -c -p -r -N gdb-head/gdb/config/s390/s390.mh gdb-head-new/gdb/config/s390/s390.mh
*** gdb-head/gdb/config/s390/s390.mh Tue Dec 2 17:47:36 2003
--- gdb-head-new/gdb/config/s390/s390.mh Tue Dec 2 16:36:15 2003
***************
*** 1,6 ****
# Host: S390, running Linux
NAT_FILE= nm-linux.h
NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o s390-nat.o \
! core-aout.o core-regset.o linux-proc.o gcore.o thread-db.o lin-lwp.o \
! proc-service.o linux-nat.o
LOADLIBES = -ldl -rdynamic
--- 1,5 ----
# Host: S390, running Linux
NAT_FILE= nm-linux.h
NATDEPFILES= infptrace.o inftarg.o fork-child.o corelow.o s390-nat.o \
! linux-proc.o gcore.o thread-db.o lin-lwp.o proc-service.o linux-nat.o
LOADLIBES = -ldl -rdynamic
diff -c -p -r -N gdb-head/gdb/config/s390/s390x.mt gdb-head-new/gdb/config/s390/s390x.mt
*** gdb-head/gdb/config/s390/s390x.mt Tue Dec 2 17:47:36 2003
--- gdb-head-new/gdb/config/s390/s390x.mt Thu Jan 1 01:00:00 1970
***************
*** 1,8 ****
- # 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
-
- # needed for gdbserver.
- MT_CFLAGS= -DCONFIG_ARCH_S390X
--- 0 ----
diff -c -p -r -N gdb-head/gdb/config/s390/tm-linux.h gdb-head-new/gdb/config/s390/tm-linux.h
*** gdb-head/gdb/config/s390/tm-linux.h Tue Dec 2 17:47:36 2003
--- gdb-head-new/gdb/config/s390/tm-linux.h Tue Dec 2 16:36:15 2003
***************
*** 25,42 ****
#ifndef TM_LINUX_H
#define TM_LINUX_H
- #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 */
--- 25,30 ----
diff -c -p -r -N gdb-head/gdb/config/s390/tm-s390.h gdb-head-new/gdb/config/s390/tm-s390.h
*** gdb-head/gdb/config/s390/tm-s390.h Tue Dec 2 17:47:36 2003
--- gdb-head-new/gdb/config/s390/tm-s390.h Thu Jan 1 01:00:00 1970
***************
*** 1,78 ****
- /* 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 DEPRECATED_REGISTER_SIZE
- #define S390_PSW_MASK_SIZE DEPRECATED_REGISTER_SIZE
- #define S390_PSW_ADDR_SIZE DEPRECATED_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 DEPRECATED_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))
-
- #define GDB_TARGET_IS_ESAME (TARGET_ARCHITECTURE->mach == bfd_mach_s390_64)
-
- #endif /* ifndef TM_S390_H */
--- 0 ----
diff -c -p -r -N gdb-head/gdb/configure.tgt gdb-head-new/gdb/configure.tgt
*** gdb-head/gdb/configure.tgt Tue Dec 2 17:47:36 2003
--- gdb-head-new/gdb/configure.tgt Tue Dec 2 16:36:15 2003
*************** rs6000-*-lynxos*) gdb_target=rs6000lynx
*** 167,176 ****
rs6000-*-aix4*) gdb_target=aix4 ;;
rs6000-*-*) gdb_target=rs6000 ;;
! s390-*-*) gdb_target=s390
! build_gdbserver=yes
! ;;
! s390x-*-*) gdb_target=s390x
build_gdbserver=yes
;;
--- 167,173 ----
rs6000-*-aix4*) gdb_target=aix4 ;;
rs6000-*-*) gdb_target=rs6000 ;;
! s390*-*-*) gdb_target=s390
build_gdbserver=yes
;;
diff -c -p -r -N gdb-head/gdb/gdbserver/linux-s390-low.c gdb-head-new/gdb/gdbserver/linux-s390-low.c
*** gdb-head/gdb/gdbserver/linux-s390-low.c Tue Dec 2 17:47:36 2003
--- gdb-head-new/gdb/gdbserver/linux-s390-low.c Tue Dec 2 16:36:15 2003
***************
*** 27,33 ****
#include <asm/ptrace.h>
! #define s390_num_regs 67
static int s390_regmap[] = {
PT_PSWMASK, PT_PSWADDR,
--- 27,33 ----
#include <asm/ptrace.h>
! #define s390_num_regs 51
static int s390_regmap[] = {
PT_PSWMASK, PT_PSWADDR,
*************** static int s390_regmap[] = {
*** 42,56 ****
PT_ACR8, PT_ACR9, PT_ACR10, PT_ACR11,
PT_ACR12, PT_ACR13, PT_ACR14, PT_ACR15,
- -1, -1, -1, -1,
- -1, -1, -1, -1,
- -1, PT_CR_9, PT_CR_10, PT_CR_11,
- -1, -1, -1, -1,
-
PT_FPC,
! /* <asm/ptrace.h> defines GPR_SIZE. */
! #if GPR_SIZE == 4
PT_FPR0_HI, PT_FPR1_HI, PT_FPR2_HI, PT_FPR3_HI,
PT_FPR4_HI, PT_FPR5_HI, PT_FPR6_HI, PT_FPR7_HI,
PT_FPR8_HI, PT_FPR9_HI, PT_FPR10_HI, PT_FPR11_HI,
--- 42,50 ----
PT_ACR8, PT_ACR9, PT_ACR10, PT_ACR11,
PT_ACR12, PT_ACR13, PT_ACR14, PT_ACR15,
PT_FPC,
! #ifndef __s390x__
PT_FPR0_HI, PT_FPR1_HI, PT_FPR2_HI, PT_FPR3_HI,
PT_FPR4_HI, PT_FPR5_HI, PT_FPR6_HI, PT_FPR7_HI,
PT_FPR8_HI, PT_FPR9_HI, PT_FPR10_HI, PT_FPR11_HI,
diff -c -p -r -N gdb-head/gdb/regformats/reg-s390.dat gdb-head-new/gdb/regformats/reg-s390.dat
*** gdb-head/gdb/regformats/reg-s390.dat Tue Dec 2 17:47:36 2003
--- gdb-head-new/gdb/regformats/reg-s390.dat Tue Dec 2 16:36:15 2003
*************** expedite:r14,r15,pswa
*** 34,55 ****
32:acr13
32:acr14
32:acr15
- 32:cr0
- 32:cr1
- 32:cr2
- 32:cr3
- 32:cr4
- 32:cr5
- 32:cr6
- 32:cr7
- 32:cr8
- 32:cr9
- 32:cr10
- 32:cr11
- 32:cr12
- 32:cr13
- 32:cr14
- 32:cr15
32:fpc
64:f0
64:f1
--- 34,39 ----
diff -c -p -r -N gdb-head/gdb/regformats/reg-s390x.dat gdb-head-new/gdb/regformats/reg-s390x.dat
*** gdb-head/gdb/regformats/reg-s390x.dat Tue Dec 2 17:47:36 2003
--- gdb-head-new/gdb/regformats/reg-s390x.dat Tue Dec 2 16:36:15 2003
*************** expedite:r14,r15,pswa
*** 34,55 ****
32:acr13
32:acr14
32:acr15
- 64:cr0
- 64:cr1
- 64:cr2
- 64:cr3
- 64:cr4
- 64:cr5
- 64:cr6
- 64:cr7
- 64:cr8
- 64:cr9
- 64:cr10
- 64:cr11
- 64:cr12
- 64:cr13
- 64:cr14
- 64:cr15
32:fpc
64:f0
64:f1
--- 34,39 ----
diff -c -p -r -N gdb-head/gdb/s390-nat.c gdb-head-new/gdb/s390-nat.c
*** gdb-head/gdb/s390-nat.c Tue Dec 2 17:47:36 2003
--- gdb-head-new/gdb/s390-nat.c Tue Dec 2 16:36:15 2003
***************
*** 22,73 ****
#include "defs.h"
#include "tm.h"
#include "regcache.h"
#include <asm/ptrace.h>
#include <sys/ptrace.h>
- #include <asm/processor.h>
#include <asm/types.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
! {
! internal_error (__FILE__, __LINE__,
! "s390_register_u_addr invalid regnum regnum=%d",
! 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.
--- 22,280 ----
#include "defs.h"
#include "tm.h"
#include "regcache.h"
+ #include "inferior.h"
+ #include <stdlib.h>
+ #include <string.h>
#include <asm/ptrace.h>
#include <sys/ptrace.h>
#include <asm/types.h>
#include <sys/procfs.h>
#include <sys/user.h>
#include <sys/ucontext.h>
! /* Map registers to gregset/ptrace offsets. */
!
! /* NOTE: The register ordering here must correspond to the
! gdb-internal register numbers defined in s390-tdep.c. */
! static int s390_gregset_regmap[] =
! {
! #ifndef __s390x__
! /* Program Status Word. */
! 0x00, 0x04,
! /* General Purpose Registers. */
! 0x08, 0x0C, 0x10, 0x14,
! 0x18, 0x1C, 0x20, 0x24,
! 0x28, 0x2C, 0x30, 0x34,
! 0x38, 0x3C, 0x40, 0x44,
! /* Access Registers. */
! 0x48, 0x4C, 0x50, 0x54,
! 0x58, 0x5C, 0x60, 0x64,
! 0x68, 0x6C, 0x70, 0x74,
! 0x78, 0x7C, 0x80, 0x84,
! /* Floating Point Control Word. */
! -1,
! /* Floating Point Registers. */
! -1, -1, -1, -1, -1, -1, -1, -1,
! -1, -1, -1, -1, -1, -1, -1, -1,
#else
! 0x00, 0x08,
! /* General Purpose Registers. */
! 0x10, 0x18, 0x20, 0x28,
! 0x30, 0x38, 0x40, 0x48,
! 0x50, 0x58, 0x60, 0x68,
! 0x70, 0x78, 0x80, 0x88,
! /* Access Registers. */
! 0x90, 0x94, 0x98, 0x9c,
! 0xa0, 0xa4, 0xa8, 0xac,
! 0xb0, 0xb4, 0xb8, 0xbc,
! 0xc0, 0xc4, 0xc8, 0xcc,
! /* Floating Point Control Word. */
! -1,
! /* Floating Point Registers. */
! -1, -1, -1, -1, -1, -1, -1, -1,
! -1, -1, -1, -1, -1, -1, -1, -1,
#endif
! };
!
! static const int s390_gregset_regmap_len =
! (sizeof (s390_gregset_regmap) / sizeof (s390_gregset_regmap[0]));
!
! static int s390_fpregset_regmap[] =
! {
! /* Program Status Word. */
! -1, -1,
! /* General Purpose Registers. */
! -1, -1, -1, -1, -1, -1, -1, -1,
! -1, -1, -1, -1, -1, -1, -1, -1,
! /* Access Registers. */
! -1, -1, -1, -1, -1, -1, -1, -1,
! -1, -1, -1, -1, -1, -1, -1, -1,
! /* Floating Point Control Word. */
! 0x00,
! /* Floating Point Registers. */
! 0x08, 0x10, 0x18, 0x20,
! 0x28, 0x30, 0x38, 0x40,
! 0x48, 0x50, 0x58, 0x60,
! 0x68, 0x70, 0x78, 0x80,
! };
!
! static const int s390_fpregset_regmap_len =
! (sizeof (s390_fpregset_regmap) / sizeof (s390_fpregset_regmap[0]));
!
!
! /* Fill GDB's register array with the general-purpose register values
! in *REGP. */
! void
! supply_gregset (gregset_t *regp)
! {
! int i;
! for (i = 0; i < s390_gregset_regmap_len; i++)
! if (s390_gregset_regmap[i] != -1)
! supply_register (i, (char *)regp + s390_gregset_regmap[i]);
! }
!
! /* Fill register REGNO (if it is a general-purpose register) in
! *REGP with the value in GDB's register array. If REGNO is -1,
! do this for all registers. */
! void
! fill_gregset (gregset_t *regp, int regno)
! {
! int i;
! for (i = 0; i < s390_gregset_regmap_len; i++)
! if (s390_gregset_regmap[i] != -1)
! if (regno == -1 || regno == i)
! regcache_collect (i, (char *)regp + s390_gregset_regmap[i]);
! }
!
! /* Fill GDB's register array with the floating-point register values
! in *REGP. */
! void
! supply_fpregset (fpregset_t *regp)
! {
! int i;
! for (i = 0; i < s390_fpregset_regmap_len; i++)
! if (s390_fpregset_regmap[i] != -1)
! supply_register (i, ((char *)regp) + s390_fpregset_regmap[i]);
! }
!
! /* Fill register REGNO (if it is a general-purpose register) in
! *REGP with the value in GDB's register array. If REGNO is -1,
! do this for all registers. */
! void
! fill_fpregset (fpregset_t *regp, int regno)
! {
! int i;
! for (i = 0; i < s390_fpregset_regmap_len; i++)
! if (s390_fpregset_regmap[i] != -1)
! if (regno == -1 || regno == i)
! regcache_collect (i, ((char *)regp) + s390_fpregset_regmap[i]);
! }
!
! /* Find the TID for the current inferior thread to use with ptrace. */
! static int
! s390_inferior_tid (void)
! {
! /* GNU/Linux LWP ID's are process ID's. */
! int tid = TIDGET (inferior_ptid);
! if (tid == 0)
! tid = PIDGET (inferior_ptid); /* Not a threaded program. */
!
! return tid;
! }
!
! /* Fetch all general-purpose registers from process/thread TID and
! store their values in GDB's register cache. */
! static void
! fetch_regs (int tid)
! {
! gregset_t regs;
! ptrace_area parea;
!
! parea.len = sizeof (regs);
! parea.process_addr = (addr_t) ®s;
! parea.kernel_addr = offsetof (struct user_regs_struct, psw);
! if (ptrace (PTRACE_PEEKUSR_AREA, tid, (long) &parea) < 0)
! perror_with_name ("Couldn't get registers");
!
! supply_gregset (®s);
! }
!
! /* Store all valid general-purpose registers in GDB's register cache
! into the process/thread specified by TID. */
! static void
! store_regs (int tid, int regnum)
! {
! gregset_t regs;
! ptrace_area parea;
!
! parea.len = sizeof (regs);
! parea.process_addr = (addr_t) ®s;
! parea.kernel_addr = offsetof (struct user_regs_struct, psw);
! if (ptrace (PTRACE_PEEKUSR_AREA, tid, (long) &parea) < 0)
! perror_with_name ("Couldn't get registers");
!
! fill_gregset (®s, regnum);
!
! if (ptrace (PTRACE_POKEUSR_AREA, tid, (long) &parea) < 0)
! perror_with_name ("Couldn't write registers");
! }
!
! /* Fetch all floating-point registers from process/thread TID and store
! their values in GDB's register cache. */
! static void
! fetch_fpregs (int tid)
! {
! fpregset_t fpregs;
! ptrace_area parea;
!
! parea.len = sizeof (fpregs);
! parea.process_addr = (addr_t) &fpregs;
! parea.kernel_addr = offsetof (struct user_regs_struct, fp_regs);
! if (ptrace (PTRACE_PEEKUSR_AREA, tid, (long) &parea) < 0)
! perror_with_name ("Couldn't get floating point status");
!
! supply_fpregset (&fpregs);
! }
!
! /* Store all valid floating-point registers in GDB's register cache
! into the process/thread specified by TID. */
! static void
! store_fpregs (int tid, int regnum)
! {
! fpregset_t fpregs;
! ptrace_area parea;
!
! parea.len = sizeof (fpregs);
! parea.process_addr = (addr_t) &fpregs;
! parea.kernel_addr = offsetof (struct user_regs_struct, fp_regs);
! if (ptrace (PTRACE_PEEKUSR_AREA, tid, (long) &parea) < 0)
! perror_with_name ("Couldn't get floating point status");
!
! fill_fpregset (&fpregs, regnum);
!
! if (ptrace (PTRACE_POKEUSR_AREA, tid, (long) &parea) < 0)
! perror_with_name ("Couldn't write floating point status");
! }
!
! /* Fetch register REGNUM from the child process. If REGNUM is -1, do
! this for all registers. */
! void
! fetch_inferior_registers (int regnum)
! {
! int tid = s390_inferior_tid ();
!
! if (regnum == -1
! || (regnum < s390_gregset_regmap_len
! && s390_gregset_regmap[regnum] != -1))
! fetch_regs (tid);
!
! if (regnum == -1
! || (regnum < s390_fpregset_regmap_len
! && s390_fpregset_regmap[regnum] != -1))
! fetch_fpregs (tid);
! }
!
! /* Store register REGNUM back into the child process. If REGNUM is
! -1, do this for all registers. */
! void
! store_inferior_registers (int regnum)
! {
! int tid = s390_inferior_tid ();
!
! if (regnum == -1
! || (regnum < s390_gregset_regmap_len
! && s390_gregset_regmap[regnum] != -1))
! store_regs (tid, regnum);
!
! if (regnum == -1
! || (regnum < s390_fpregset_regmap_len
! && s390_fpregset_regmap[regnum] != -1))
! store_fpregs (tid, regnum);
}
+
/* 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.
*************** kernel_u_size (void)
*** 232,358 ****
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]);
-
- #if defined (CONFIG_ARCH_S390X)
- /* On the s390x, each element of gregset_t is 8 bytes long, but
- each access register is still only 32 bits long. So they're
- packed two per element. It's apparently traditional that
- gregset_t must be an array, so when the registers it provides
- have different sizes, something has to get strange
- somewhere. */
- {
- unsigned int *acrs = (unsigned int *) &gregp[S390_FIRST_ACR];
-
- for (regi = 0; regi < S390_NUM_ACRS; regi++)
- supply_register (S390_FIRST_ACR + regi, (char *) &acrs[regi]);
- }
- #else
- for (regi = 0; regi < S390_NUM_ACRS; regi++)
- supply_register (S390_FIRST_ACR + regi,
- (char *) &gregp[S390_FIRST_ACR + regi]);
- #endif
-
- /* 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)
- {
- int regi;
- greg_t *gregp = (greg_t *) gregsetp;
-
- if (regno < 0)
- {
- regcache_collect (S390_PSWM_REGNUM, &gregp[S390_PSWM_REGNUM]);
- regcache_collect (S390_PC_REGNUM, &gregp[S390_PC_REGNUM]);
- for (regi = 0; regi < S390_NUM_GPRS; regi++)
- regcache_collect (S390_GP0_REGNUM + regi,
- &gregp[S390_GP0_REGNUM + regi]);
- #if defined (CONFIG_ARCH_S390X)
- /* See the comments about the access registers in
- supply_gregset, above. */
- {
- unsigned int *acrs = (unsigned int *) &gregp[S390_FIRST_ACR];
-
- for (regi = 0; regi < S390_NUM_ACRS; regi++)
- regcache_collect (S390_FIRST_ACR + regi, &acrs[regi]);
- }
- #else
- for (regi = 0; regi < S390_NUM_ACRS; regi++)
- regcache_collect (S390_FIRST_ACR + regi,
- &gregp[S390_FIRST_ACR + regi]);
- #endif
- }
- else if (regno >= S390_PSWM_REGNUM && regno < S390_FIRST_ACR)
- regcache_collect (regno, &gregp[regno]);
- else if (regno >= S390_FIRST_ACR && regno <= S390_LAST_ACR)
- {
- #if defined (CONFIG_ARCH_S390X)
- /* See the comments about the access registers in
- supply_gregset, above. */
- unsigned int *acrs = (unsigned int *) &gregp[S390_FIRST_ACR];
-
- regcache_collect (regno, &acrs[regno - S390_FIRST_ACR]);
- #else
- regcache_collect (regno, &gregp[regno]);
- #endif
- }
- }
-
- /* 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)
- {
- int regi;
-
- if (regno < 0)
- {
- regcache_collect (S390_FPC_REGNUM, &fpregsetp->fpc);
- for (regi = 0; regi < S390_NUM_FPRS; regi++)
- regcache_collect (S390_FP0_REGNUM + regi, &fpregsetp->fprs[regi]);
- }
- else if (regno == S390_FPC_REGNUM)
- regcache_collect (S390_FPC_REGNUM, &fpregsetp->fpc);
- else if (regno >= S390_FP0_REGNUM && regno <= S390_FPLAST_REGNUM)
- regcache_collect (regno, &fpregsetp->fprs[regno - S390_FP0_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
--- 439,441 ----
diff -c -p -r -N gdb-head/gdb/s390-tdep.c gdb-head-new/gdb/s390-tdep.c
*** gdb-head/gdb/s390-tdep.c Tue Dec 2 17:47:50 2003
--- gdb-head-new/gdb/s390-tdep.c Tue Dec 2 17:44:36 2003
***************
*** 22,29 ****
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"
--- 22,28 ----
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
! #include "defs.h"
#include "arch-utils.h"
#include "frame.h"
#include "inferior.h"
***************
*** 37,89 ****
#include "../bfd/bfd.h"
#include "floatformat.h"
#include "regcache.h"
#include "value.h"
#include "gdb_assert.h"
#include "dis-asm.h"
! /* Number of bytes of storage in the actual machine representation
! for register N. */
! static int
! s390_register_raw_size (int reg_nr)
{
! if (S390_FP0_REGNUM <= reg_nr
! && reg_nr < S390_FP0_REGNUM + S390_NUM_FPRS)
! return S390_FPR_SIZE;
! else
! return 4;
}
static 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;
}
static 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);
}
static int
! s390_register_byte (int reg_nr)
{
! if (reg_nr <= S390_GP_LAST_REGNUM)
! return reg_nr * S390_GPR_SIZE;
! if (reg_nr <= S390_LAST_ACR)
! return S390_ACR0_OFFSET + (((reg_nr) - S390_FIRST_ACR) * S390_ACR_SIZE);
! if (reg_nr <= S390_LAST_CR)
! return S390_CR0_OFFSET + (((reg_nr) - S390_FIRST_CR) * S390_CR_SIZE);
! if (reg_nr == S390_FPC_REGNUM)
! return S390_FPC_OFFSET;
! else
! return S390_FP0_OFFSET + (((reg_nr) - S390_FP0_REGNUM) * S390_FPR_SIZE);
}
#define S390_MAX_INSTR_SIZE (6)
#define S390_SYSCALL_OPCODE (0x0a)
#define S390_SYSCALL_SIZE (2)
--- 36,556 ----
#include "../bfd/bfd.h"
#include "floatformat.h"
#include "regcache.h"
+ #include "reggroups.h"
+ #include "regset.h"
#include "value.h"
#include "gdb_assert.h"
#include "dis-asm.h"
! /* The tdep structure. */
!
! struct gdbarch_tdep
{
! /* Core file register sets. */
! struct regset *gregset;
! int sizeof_gregset;
! int *regmap_gregset;
!
! struct regset *fpregset;
! int sizeof_fpregset;
! int *regmap_fpregset;
! };
!
!
! /* Register information. */
!
! /* Program Status Word. */
! #define S390_PSWM_REGNUM 0
! #define S390_PSWA_REGNUM 1
! /* General Purpose Registers. */
! #define S390_R0_REGNUM 2
! #define S390_R1_REGNUM 3
! #define S390_R2_REGNUM 4
! #define S390_R3_REGNUM 5
! #define S390_R4_REGNUM 6
! #define S390_R5_REGNUM 7
! #define S390_R6_REGNUM 8
! #define S390_R7_REGNUM 9
! #define S390_R8_REGNUM 10
! #define S390_R9_REGNUM 11
! #define S390_R10_REGNUM 12
! #define S390_R11_REGNUM 13
! #define S390_R12_REGNUM 14
! #define S390_R13_REGNUM 15
! #define S390_R14_REGNUM 16
! #define S390_R15_REGNUM 17
! /* Access Registers. */
! #define S390_A0_REGNUM 18
! #define S390_A1_REGNUM 19
! #define S390_A2_REGNUM 20
! #define S390_A3_REGNUM 21
! #define S390_A4_REGNUM 22
! #define S390_A5_REGNUM 23
! #define S390_A6_REGNUM 24
! #define S390_A7_REGNUM 25
! #define S390_A8_REGNUM 26
! #define S390_A9_REGNUM 27
! #define S390_A10_REGNUM 28
! #define S390_A11_REGNUM 29
! #define S390_A12_REGNUM 30
! #define S390_A13_REGNUM 31
! #define S390_A14_REGNUM 32
! #define S390_A15_REGNUM 33
! /* Floating Point Control Word. */
! #define S390_FPC_REGNUM 34
! /* Floating Point Registers. */
! #define S390_F0_REGNUM 35
! #define S390_F1_REGNUM 36
! #define S390_F2_REGNUM 37
! #define S390_F3_REGNUM 38
! #define S390_F4_REGNUM 39
! #define S390_F5_REGNUM 40
! #define S390_F6_REGNUM 41
! #define S390_F7_REGNUM 42
! #define S390_F8_REGNUM 43
! #define S390_F9_REGNUM 44
! #define S390_F10_REGNUM 45
! #define S390_F11_REGNUM 46
! #define S390_F12_REGNUM 47
! #define S390_F13_REGNUM 48
! #define S390_F14_REGNUM 49
! #define S390_F15_REGNUM 50
! /* Total. */
! #define S390_NUM_REGS 51
!
! /* Pseudo registers -- PC and condition code. */
! #define S390_PC_REGNUM S390_NUM_REGS
! #define S390_CC_REGNUM (S390_NUM_REGS+1)
! #define S390_NUM_PSEUDO_REGS 2
! #define S390_NUM_TOTAL_REGS (S390_NUM_REGS+2)
!
! /* Special register usage. */
! #define S390_SP_REGNUM S390_R15_REGNUM
! #define S390_RETADDR_REGNUM S390_R14_REGNUM
! #define S390_FRAME_REGNUM S390_R11_REGNUM
!
! struct s390_register_info
! {
! char *name;
! struct type **type;
! };
!
! static struct s390_register_info s390_register_info[S390_NUM_TOTAL_REGS] =
! {
! /* Program Status Word. */
! { "pswm", &builtin_type_long },
! { "pswa", &builtin_type_long },
!
! /* General Purpose Registers. */
! { "r0", &builtin_type_long },
! { "r1", &builtin_type_long },
! { "r2", &builtin_type_long },
! { "r3", &builtin_type_long },
! { "r4", &builtin_type_long },
! { "r5", &builtin_type_long },
! { "r6", &builtin_type_long },
! { "r7", &builtin_type_long },
! { "r8", &builtin_type_long },
! { "r9", &builtin_type_long },
! { "r10", &builtin_type_long },
! { "r11", &builtin_type_long },
! { "r12", &builtin_type_long },
! { "r13", &builtin_type_long },
! { "r14", &builtin_type_long },
! { "r15", &builtin_type_long },
!
! /* Access Registers. */
! { "acr0", &builtin_type_int },
! { "acr1", &builtin_type_int },
! { "acr2", &builtin_type_int },
! { "acr3", &builtin_type_int },
! { "acr4", &builtin_type_int },
! { "acr5", &builtin_type_int },
! { "acr6", &builtin_type_int },
! { "acr7", &builtin_type_int },
! { "acr8", &builtin_type_int },
! { "acr9", &builtin_type_int },
! { "acr10", &builtin_type_int },
! { "acr11", &builtin_type_int },
! { "acr12", &builtin_type_int },
! { "acr13", &builtin_type_int },
! { "acr14", &builtin_type_int },
! { "acr15", &builtin_type_int },
!
! /* Floating Point Control Word. */
! { "fpc", &builtin_type_int },
!
! /* Floating Point Registers. */
! { "f0", &builtin_type_double },
! { "f1", &builtin_type_double },
! { "f2", &builtin_type_double },
! { "f3", &builtin_type_double },
! { "f4", &builtin_type_double },
! { "f5", &builtin_type_double },
! { "f6", &builtin_type_double },
! { "f7", &builtin_type_double },
! { "f8", &builtin_type_double },
! { "f9", &builtin_type_double },
! { "f10", &builtin_type_double },
! { "f11", &builtin_type_double },
! { "f12", &builtin_type_double },
! { "f13", &builtin_type_double },
! { "f14", &builtin_type_double },
! { "f15", &builtin_type_double },
!
! /* Pseudo registers. */
! { "pc", &builtin_type_void_func_ptr },
! { "cc", &builtin_type_int },
! };
!
! /* Return the name of register REGNUM. */
! static const char *
! s390_register_name (int regnum)
! {
! gdb_assert (regnum >= 0 && regnum < S390_NUM_TOTAL_REGS);
! return s390_register_info[regnum].name;
}
+ /* Return the GDB type object for the "standard" data type of data in
+ register REGNUM. */
+ static struct type *
+ s390_register_type (struct gdbarch *gdbarch, int regnum)
+ {
+ gdb_assert (regnum >= 0 && regnum < S390_NUM_TOTAL_REGS);
+ return *s390_register_info[regnum].type;
+ }
+
+ /* DWARF Register Mapping. */
+
+ static int s390_dwarf_regmap[] =
+ {
+ /* General Purpose Registers. */
+ S390_R0_REGNUM, S390_R1_REGNUM, S390_R2_REGNUM, S390_R3_REGNUM,
+ S390_R4_REGNUM, S390_R5_REGNUM, S390_R6_REGNUM, S390_R7_REGNUM,
+ S390_R8_REGNUM, S390_R9_REGNUM, S390_R10_REGNUM, S390_R11_REGNUM,
+ S390_R12_REGNUM, S390_R13_REGNUM, S390_R14_REGNUM, S390_R15_REGNUM,
+
+ /* Floating Point Registers. */
+ S390_F0_REGNUM, S390_F2_REGNUM, S390_F4_REGNUM, S390_F6_REGNUM,
+ S390_F1_REGNUM, S390_F3_REGNUM, S390_F5_REGNUM, S390_F7_REGNUM,
+ S390_F8_REGNUM, S390_F10_REGNUM, S390_F12_REGNUM, S390_F14_REGNUM,
+ S390_F9_REGNUM, S390_F11_REGNUM, S390_F13_REGNUM, S390_F15_REGNUM,
+
+ /* Control Registers (not mapped). */
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+
+ /* Access Registers. */
+ S390_A0_REGNUM, S390_A1_REGNUM, S390_A2_REGNUM, S390_A3_REGNUM,
+ S390_A4_REGNUM, S390_A5_REGNUM, S390_A6_REGNUM, S390_A7_REGNUM,
+ S390_A8_REGNUM, S390_A9_REGNUM, S390_A10_REGNUM, S390_A11_REGNUM,
+ S390_A12_REGNUM, S390_A13_REGNUM, S390_A14_REGNUM, S390_A15_REGNUM,
+
+ /* Program Status Word. */
+ S390_PSWM_REGNUM,
+ S390_PSWA_REGNUM
+ };
+
+ static const int s390_dwarf_regmap_len =
+ (sizeof (s390_dwarf_regmap) / sizeof (s390_dwarf_regmap[0]));
+
+ /* Convert DWARF register number REG to the appropriate register
+ number used by GDB. */
static int
! s390_dwarf_reg_to_regnum (int reg)
! {
! int regnum = -1;
!
! if (reg >= 0 || reg < s390_dwarf_regmap_len)
! regnum = s390_dwarf_regmap[reg];
!
! if (regnum == -1)
! warning ("Unmapped DWARF Register #%d encountered\n", reg);
!
! return regnum;
! }
!
! /* Pseudo registers - PC and condition code. */
!
! static void
! s390_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
! int regnum, void *buf)
! {
! ULONGEST val;
!
! switch (regnum)
! {
! case S390_PC_REGNUM:
! regcache_raw_read_unsigned (regcache, S390_PSWA_REGNUM, &val);
! store_unsigned_integer (buf, 4, val & 0x7fffffff);
! break;
!
! case S390_CC_REGNUM:
! regcache_raw_read_unsigned (regcache, S390_PSWM_REGNUM, &val);
! store_unsigned_integer (buf, 4, (val >> 12) & 3);
! break;
!
! default:
! abort ();
! }
! }
!
! static void
! s390_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
! int regnum, const void *buf)
{
! ULONGEST val, psw;
!
! switch (regnum)
! {
! case S390_PC_REGNUM:
! val = extract_unsigned_integer (buf, 4);
! regcache_raw_read_unsigned (regcache, S390_PSWA_REGNUM, &psw);
! psw = (psw & 0x80000000) | (val & 0x7fffffff);
! regcache_raw_write_unsigned (regcache, S390_PSWA_REGNUM, psw);
! break;
!
! case S390_CC_REGNUM:
! val = extract_unsigned_integer (buf, 4);
! regcache_raw_read_unsigned (regcache, S390_PSWM_REGNUM, &psw);
! psw = (psw & ~((ULONGEST)3 << 12)) | ((val & 3) << 12);
! regcache_raw_write_unsigned (regcache, S390_PSWM_REGNUM, psw);
! break;
!
! default:
! abort ();
! }
}
+ static void
+ s390x_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
+ int regnum, void *buf)
+ {
+ ULONGEST val;
+
+ switch (regnum)
+ {
+ case S390_PC_REGNUM:
+ regcache_raw_read (regcache, S390_PSWA_REGNUM, buf);
+ break;
+
+ case S390_CC_REGNUM:
+ regcache_raw_read_unsigned (regcache, S390_PSWM_REGNUM, &val);
+ store_unsigned_integer (buf, 4, (val >> 44) & 3);
+ break;
+
+ default:
+ abort ();
+ }
+ }
+
+ static void
+ s390x_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
+ int regnum, const void *buf)
+ {
+ ULONGEST val, psw;
+
+ switch (regnum)
+ {
+ case S390_PC_REGNUM:
+ regcache_raw_write (regcache, S390_PSWA_REGNUM, buf);
+ break;
+
+ case S390_CC_REGNUM:
+ val = extract_unsigned_integer (buf, 4);
+ regcache_raw_read_unsigned (regcache, S390_PSWM_REGNUM, &psw);
+ psw = (psw & ~((ULONGEST)3 << 44)) | ((val & 3) << 44);
+ regcache_raw_write_unsigned (regcache, S390_PSWM_REGNUM, psw);
+ break;
+
+ default:
+ abort ();
+ }
+ }
+
+ /* 'float' values are stored in the upper half of floating-point
+ registers, even though we are otherwise a big-endian platform. */
+
static int
! s390_convert_register_p (int regno, struct type *type)
{
! return (regno >= S390_F0_REGNUM && regno <= S390_F15_REGNUM)
! && TYPE_LENGTH (type) < 8;
}
+ static void
+ s390_register_to_value (struct frame_info *frame, int regnum,
+ struct type *valtype, void *out)
+ {
+ char in[8];
+ int len = TYPE_LENGTH (valtype);
+ gdb_assert (len < 8);
+
+ frame_register_read (frame, regnum, in);
+ memcpy (out, in, len);
+ }
+
+ static void
+ s390_value_to_register (struct frame_info *frame, int regnum,
+ struct type *valtype, const void *in)
+ {
+ char out[8];
+ int len = TYPE_LENGTH (valtype);
+ gdb_assert (len < 8);
+
+ memset (out, 0, 8);
+ memcpy (out, in, len);
+ put_frame_register (frame, regnum, out);
+ }
+
+ /* Register groups. */
+
static int
! s390_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
! struct reggroup *group)
{
! struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
!
! /* Registers displayed via 'info regs'. */
! if (group == general_reggroup)
! return (regnum >= S390_R0_REGNUM && regnum <= S390_R15_REGNUM)
! || regnum == S390_PC_REGNUM
! || regnum == S390_CC_REGNUM;
!
! /* Registers displayed via 'info float'. */
! if (group == float_reggroup)
! return (regnum >= S390_F0_REGNUM && regnum <= S390_F15_REGNUM)
! || regnum == S390_FPC_REGNUM;
!
! /* Registers that need to be saved/restored in order to
! push or pop frames. */
! if (group == save_reggroup || group == restore_reggroup)
! return regnum != S390_PSWM_REGNUM && regnum != S390_PSWA_REGNUM;
!
! return default_register_reggroup_p (gdbarch, regnum, group);
}
+
+ /* Core file register sets. */
+
+ #define s390_sizeof_gregset 0x90
+ static int s390_regmap_gregset[S390_NUM_REGS] =
+ {
+ /* Program Status Word. */
+ 0x00, 0x04,
+ /* General Purpose Registers. */
+ 0x08, 0x0C, 0x10, 0x14,
+ 0x18, 0x1C, 0x20, 0x24,
+ 0x28, 0x2C, 0x30, 0x34,
+ 0x38, 0x3C, 0x40, 0x44,
+ /* Access Registers. */
+ 0x48, 0x4C, 0x50, 0x54,
+ 0x58, 0x5C, 0x60, 0x64,
+ 0x68, 0x6C, 0x70, 0x74,
+ 0x78, 0x7C, 0x80, 0x84,
+ /* Floating Point Control Word. */
+ -1,
+ /* Floating Point Registers. */
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ };
+
+ #define s390x_sizeof_gregset 0xd8
+ static int s390x_regmap_gregset[S390_NUM_REGS] =
+ {
+ 0x00, 0x08,
+ /* General Purpose Registers. */
+ 0x10, 0x18, 0x20, 0x28,
+ 0x30, 0x38, 0x40, 0x48,
+ 0x50, 0x58, 0x60, 0x68,
+ 0x70, 0x78, 0x80, 0x88,
+ /* Access Registers. */
+ 0x90, 0x94, 0x98, 0x9c,
+ 0xa0, 0xa4, 0xa8, 0xac,
+ 0xb0, 0xb4, 0xb8, 0xbc,
+ 0xc0, 0xc4, 0xc8, 0xcc,
+ /* Floating Point Control Word. */
+ -1,
+ /* Floating Point Registers. */
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ };
+
+ #define s390_sizeof_fpregset 0x88
+ static int s390_regmap_fpregset[S390_NUM_REGS] =
+ {
+ /* Program Status Word. */
+ -1, -1,
+ /* General Purpose Registers. */
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ /* Access Registers. */
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ /* Floating Point Control Word. */
+ 0x00,
+ /* Floating Point Registers. */
+ 0x08, 0x10, 0x18, 0x20,
+ 0x28, 0x30, 0x38, 0x40,
+ 0x48, 0x50, 0x58, 0x60,
+ 0x68, 0x70, 0x78, 0x80,
+ };
+
+ /* Supply register REGNUM from the register set REGSET to register cache
+ REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
+ static void
+ s390_supply_regset (const struct regset *regset, struct regcache *regcache,
+ int regnum, const void *regs, size_t len)
+ {
+ const int *offset = regset->descr;
+ int i;
+
+ for (i = 0; i < S390_NUM_REGS; i++)
+ {
+ if ((regnum == i || regnum == -1) && offset[i] != -1)
+ regcache_raw_supply (regcache, i, (const char *)regs + offset[i]);
+ }
+ }
+
+ /* Return the appropriate register set for the core section identified
+ by SECT_NAME and SECT_SIZE. */
+ const struct regset *
+ s390_regset_from_core_section (struct gdbarch *gdbarch,
+ const char *sect_name, size_t sect_size)
+ {
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ if (strcmp (sect_name, ".reg") == 0 && sect_size == tdep->sizeof_gregset)
+ {
+ if (tdep->gregset == NULL)
+ {
+ tdep->gregset = XMALLOC (struct regset);
+ tdep->gregset->descr = tdep->regmap_gregset;
+ tdep->gregset->supply_regset = s390_supply_regset;
+ }
+ return tdep->gregset;
+ }
+
+ if (strcmp (sect_name, ".reg2") == 0 && sect_size == tdep->sizeof_fpregset)
+ {
+ if (tdep->fpregset == NULL)
+ {
+ tdep->fpregset = XMALLOC (struct regset);
+ tdep->fpregset->descr = tdep->regmap_fpregset;
+ tdep->fpregset->supply_regset = s390_supply_regset;
+ }
+ return tdep->fpregset;
+ }
+
+ return NULL;
+ }
+
+
+ #define GDB_TARGET_IS_ESAME (TARGET_ARCHITECTURE->mach == bfd_mach_s390_64)
+ #define S390_GPR_SIZE (GDB_TARGET_IS_ESAME ? 8 : 4)
+ #define S390_FPR_SIZE (8)
#define S390_MAX_INSTR_SIZE (6)
#define S390_SYSCALL_OPCODE (0x0a)
#define S390_SYSCALL_SIZE (2)
*************** s390_register_byte (int reg_nr)
*** 93,100 ****
#define S390X_SIGREGS_FP0_OFFSET (216)
#define S390_UC_MCONTEXT_OFFSET (256)
#define S390X_UC_MCONTEXT_OFFSET (344)
! #define S390_STACK_FRAME_OVERHEAD 16*DEPRECATED_REGISTER_SIZE+32
! #define S390_STACK_PARAMETER_ALIGNMENT DEPRECATED_REGISTER_SIZE
#define S390_NUM_FP_PARAMETER_REGISTERS (GDB_TARGET_IS_ESAME ? 4:2)
#define S390_SIGNAL_FRAMESIZE (GDB_TARGET_IS_ESAME ? 160:96)
#define s390_NR_sigreturn 119
--- 560,567 ----
#define S390X_SIGREGS_FP0_OFFSET (216)
#define S390_UC_MCONTEXT_OFFSET (256)
#define S390X_UC_MCONTEXT_OFFSET (344)
! #define S390_STACK_FRAME_OVERHEAD 16*S390_GPR_SIZE+32
! #define S390_STACK_PARAMETER_ALIGNMENT S390_GPR_SIZE
#define S390_NUM_FP_PARAMETER_REGISTERS (GDB_TARGET_IS_ESAME ? 4:2)
#define S390_SIGNAL_FRAMESIZE (GDB_TARGET_IS_ESAME ? 160:96)
#define s390_NR_sigreturn 119
*************** s390_memset_extra_info (struct frame_ext
*** 150,193 ****
}
-
- static const char *
- s390_register_name (int reg_nr)
- {
- static char *register_names[] = {
- "pswm", "pswa",
- "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
- "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
- "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",
- "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
- "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15"
- };
-
- if (reg_nr <= S390_LAST_REGNUM)
- return register_names[reg_nr];
- else
- return NULL;
- }
-
-
-
-
- static 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);
- }
-
-
/* Prologue analysis. */
/* When we analyze a prologue, we're really doing 'abstract
--- 617,622 ----
*************** enum
*** 599,604 ****
--- 1028,1035 ----
op1_stg = 0xe3, op2_stg = 0x24,
op_stm = 0x90,
op1_stmg = 0xeb, op2_stmg = 0x24,
+ op_lm = 0x98,
+ op1_lmg = 0xeb, op2_lmg = 0x04,
op_svc = 0x0a,
};
*************** compute_x_addr (struct prologue_value *a
*** 787,792 ****
--- 1218,1225 ----
track general-purpose registers r2 -- r15, and floating-point
registers f0, f2, f4, and f6. */
#define S390_NUM_SPILL_SLOTS (14 + 4)
+ #define S390_NUM_GPRS 16
+ #define S390_NUM_FPRS 16
/* If the SIZE bytes at ADDR are a stack slot we're actually tracking,
*************** s390_on_stack (struct prologue_value *ad
*** 820,826 ****
/* Construct the addresses of the spill arrays and the back chain. */
pv_set_to_register (&gpr_spill_addr, S390_SP_REGNUM, 2 * S390_GPR_SIZE);
pv_set_to_register (&fpr_spill_addr, S390_SP_REGNUM, 16 * S390_GPR_SIZE);
! back_chain_addr = gpr[S390_SP_REGNUM - S390_GP0_REGNUM];
/* We have to check for GPR and FPR references using two separate
calls to pv_is_array_ref, since the GPR and FPR spill slots are
--- 1253,1259 ----
/* Construct the addresses of the spill arrays and the back chain. */
pv_set_to_register (&gpr_spill_addr, S390_SP_REGNUM, 2 * S390_GPR_SIZE);
pv_set_to_register (&fpr_spill_addr, S390_SP_REGNUM, 16 * S390_GPR_SIZE);
! back_chain_addr = gpr[S390_SP_REGNUM - S390_R0_REGNUM];
/* We have to check for GPR and FPR references using two separate
calls to pv_is_array_ref, since the GPR and FPR spill slots are
*************** s390_get_signal_frame_info (struct frame
*** 903,914 ****
/* We're definitely backtracing from a signal handler. */
CORE_ADDR *saved_regs = deprecated_get_frame_saved_regs (fi);
CORE_ADDR save_reg_addr = (get_frame_extra_info (next_frame)->sigcontext
! + DEPRECATED_REGISTER_BYTE (S390_GP0_REGNUM));
int reg;
for (reg = 0; reg < S390_NUM_GPRS; reg++)
{
! saved_regs[S390_GP0_REGNUM + reg] = save_reg_addr;
save_reg_addr += S390_GPR_SIZE;
}
--- 1336,1347 ----
/* We're definitely backtracing from a signal handler. */
CORE_ADDR *saved_regs = deprecated_get_frame_saved_regs (fi);
CORE_ADDR save_reg_addr = (get_frame_extra_info (next_frame)->sigcontext
! + DEPRECATED_REGISTER_BYTE (S390_R0_REGNUM));
int reg;
for (reg = 0; reg < S390_NUM_GPRS; reg++)
{
! saved_regs[S390_R0_REGNUM + reg] = save_reg_addr;
save_reg_addr += S390_GPR_SIZE;
}
*************** s390_get_signal_frame_info (struct frame
*** 917,923 ****
S390_SIGREGS_FP0_OFFSET));
for (reg = 0; reg < S390_NUM_FPRS; reg++)
{
! saved_regs[S390_FP0_REGNUM + reg] = save_reg_addr;
save_reg_addr += S390_FPR_SIZE;
}
}
--- 1350,1356 ----
S390_SIGREGS_FP0_OFFSET));
for (reg = 0; reg < S390_NUM_FPRS; reg++)
{
! saved_regs[S390_F0_REGNUM + reg] = save_reg_addr;
save_reg_addr += S390_FPR_SIZE;
}
}
*************** s390_get_frame_info (CORE_ADDR start_pc,
*** 967,976 ****
int i;
for (i = 0; i < S390_NUM_GPRS; i++)
! pv_set_to_register (&gpr[i], S390_GP0_REGNUM + i, 0);
for (i = 0; i < S390_NUM_FPRS; i++)
! pv_set_to_register (&fpr[i], S390_FP0_REGNUM + i, 0);
for (i = 0; i < S390_NUM_SPILL_SLOTS; i++)
pv_set_to_unknown (&spill[i]);
--- 1400,1409 ----
int i;
for (i = 0; i < S390_NUM_GPRS; i++)
! pv_set_to_register (&gpr[i], S390_R0_REGNUM + i, 0);
for (i = 0; i < S390_NUM_FPRS; i++)
! pv_set_to_register (&fpr[i], S390_F0_REGNUM + i, 0);
for (i = 0; i < S390_NUM_SPILL_SLOTS; i++)
pv_set_to_unknown (&spill[i]);
*************** s390_get_frame_info (CORE_ADDR start_pc,
*** 1004,1011 ****
next_pc = pc + insn_len;
! pre_insn_sp = gpr[S390_SP_REGNUM - S390_GP0_REGNUM];
! pre_insn_fp = gpr[S390_FRAME_REGNUM - S390_GP0_REGNUM];
pre_insn_back_chain = back_chain;
/* A special case, first --- only recognized as the very first
--- 1437,1444 ----
next_pc = pc + insn_len;
! pre_insn_sp = gpr[S390_SP_REGNUM - S390_R0_REGNUM];
! pre_insn_fp = gpr[S390_FRAME_REGNUM - S390_R0_REGNUM];
pre_insn_back_chain = back_chain;
/* A special case, first --- only recognized as the very first
*************** s390_get_frame_info (CORE_ADDR start_pc,
*** 1287,1294 ****
restore instructions. (The back chain is never restored,
just popped.) */
{
! struct prologue_value *sp = &gpr[S390_SP_REGNUM - S390_GP0_REGNUM];
! struct prologue_value *fp = &gpr[S390_FRAME_REGNUM - S390_GP0_REGNUM];
if ((! pv_is_identical (&pre_insn_sp, sp)
&& ! pv_is_register (sp, S390_SP_REGNUM, 0))
--- 1720,1727 ----
restore instructions. (The back chain is never restored,
just popped.) */
{
! struct prologue_value *sp = &gpr[S390_SP_REGNUM - S390_R0_REGNUM];
! struct prologue_value *fp = &gpr[S390_FRAME_REGNUM - S390_R0_REGNUM];
if ((! pv_is_identical (&pre_insn_sp, sp)
&& ! pv_is_register (sp, S390_SP_REGNUM, 0))
*************** s390_get_frame_info (CORE_ADDR start_pc,
*** 1318,1324 ****
that strongly suggests that we're going to use that as our
frame pointer register, not the SP. */
{
! struct prologue_value *fp = &gpr[S390_FRAME_REGNUM - S390_GP0_REGNUM];
if (fp->kind == pv_register
&& fp->reg == S390_SP_REGNUM)
--- 1751,1757 ----
that strongly suggests that we're going to use that as our
frame pointer register, not the SP. */
{
! struct prologue_value *fp = &gpr[S390_FRAME_REGNUM - S390_R0_REGNUM];
if (fp->kind == pv_register
&& fp->reg == S390_SP_REGNUM)
*************** s390_get_frame_info (CORE_ADDR start_pc,
*** 1349,1355 ****
else
frame_base_regno = S390_SP_REGNUM;
! frame_base = &gpr[frame_base_regno - S390_GP0_REGNUM];
/* We know the frame base address; if the value of whatever
register it came from is a constant offset from the
--- 1782,1788 ----
else
frame_base_regno = S390_SP_REGNUM;
! frame_base = &gpr[frame_base_regno - S390_R0_REGNUM];
/* We know the frame base address; if the value of whatever
register it came from is a constant offset from the
*************** s390_get_frame_info (CORE_ADDR start_pc,
*** 1363,1369 ****
/* If the analysis said that the current SP value is the original
value less some constant, then that constant is the frame size. */
{
! struct prologue_value *sp = &gpr[S390_SP_REGNUM - S390_GP0_REGNUM];
if (sp->kind == pv_register
&& sp->reg == S390_SP_REGNUM)
--- 1796,1802 ----
/* If the analysis said that the current SP value is the original
value less some constant, then that constant is the frame size. */
{
! struct prologue_value *sp = &gpr[S390_SP_REGNUM - S390_R0_REGNUM];
if (sp->kind == pv_register
&& sp->reg == S390_SP_REGNUM)
*************** s390_get_frame_info (CORE_ADDR start_pc,
*** 1476,1481 ****
--- 1909,1958 ----
return result;
}
+ /* Return true if we are in the functin's epilogue, i.e. after the
+ instruction that destroyed the function's stack frame. */
+ static int
+ s390_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
+ {
+ int word_size = gdbarch_ptr_bit (gdbarch) / 8;
+
+ /* In frameless functions, there's not frame to destroy and thus
+ we don't care about the epilogue.
+
+ In functions with frame, the epilogue sequence is a pair of
+ a LM-type instruction that restores (amongst others) the
+ return register %r14 and the stack pointer %r15, followed
+ by a branch 'br %r14' --or equivalent-- that effects the
+ actual return.
+
+ In that situation, this function needs to return 'true' in
+ exactly one case: when pc points to that branch instruction.
+
+ Thus we try to disassemble the one instructions immediately
+ preceeding pc and check whether it is an LM-type instruction
+ modifying the stack pointer.
+
+ Note that disassembling backwards is not reliable, so there
+ is a slight chance of false positives here ... */
+
+ bfd_byte insn[6];
+ unsigned int r1, r3, b2;
+ int d2;
+
+ if (word_size == 4
+ && !read_memory_nobpt (pc - 4, insn, 4)
+ && is_rs (insn, op_lm, &r1, &r3, &d2, &b2)
+ && r3 == S390_SP_REGNUM - S390_R0_REGNUM)
+ return 1;
+
+ if (word_size == 8
+ && !read_memory_nobpt (pc - 6, insn, 6)
+ && is_rse (insn, op1_lmg, op2_lmg, &r1, &r3, &d2, &b2)
+ && r3 == S390_SP_REGNUM - S390_R0_REGNUM)
+ return 1;
+
+ return 0;
+ }
static int
s390_check_function_end (CORE_ADDR pc)
*************** s390_is_sigreturn (CORE_ADDR pc, struct
*** 1662,1669 ****
*sigcaller_pc =
ADDR_BITS_REMOVE ((CORE_ADDR)
read_memory_integer (temp_sregs +
! DEPRECATED_REGISTER_BYTE (S390_PC_REGNUM),
! S390_PSW_ADDR_SIZE));
}
}
retval = 1;
--- 2139,2146 ----
*sigcaller_pc =
ADDR_BITS_REMOVE ((CORE_ADDR)
read_memory_integer (temp_sregs +
! DEPRECATED_REGISTER_BYTE (S390_PSWA_REGNUM),
! S390_GPR_SIZE));
}
}
retval = 1;
*************** s390_frame_chain (struct frame_info *thi
*** 1832,1838 ****
{
/* read sigregs,regs.gprs[11 or 15] */
prev_fp = read_memory_integer (sregs +
! DEPRECATED_REGISTER_BYTE (S390_GP0_REGNUM +
(prev_fextra_info.
frame_pointer_saved_pc
? 11 : 15)),
--- 2309,2315 ----
{
/* read sigregs,regs.gprs[11 or 15] */
prev_fp = read_memory_integer (sregs +
! DEPRECATED_REGISTER_BYTE (S390_R0_REGNUM +
(prev_fextra_info.
frame_pointer_saved_pc
? 11 : 15)),
*************** s390_extract_return_value (struct type *
*** 1894,1900 ****
int len = TYPE_LENGTH (valtype);
if (TYPE_CODE (valtype) == TYPE_CODE_FLT)
! memcpy (valbuf, ®buf[DEPRECATED_REGISTER_BYTE (S390_FP0_REGNUM)], len);
else
{
int offset = 0;
--- 2371,2377 ----
int len = TYPE_LENGTH (valtype);
if (TYPE_CODE (valtype) == TYPE_CODE_FLT)
! memcpy (valbuf, ®buf[DEPRECATED_REGISTER_BYTE (S390_F0_REGNUM)], len);
else
{
int offset = 0;
*************** s390_extract_return_value (struct type *
*** 1902,1908 ****
if (TYPE_LENGTH (valtype) < S390_GPR_SIZE)
offset = S390_GPR_SIZE - TYPE_LENGTH (valtype);
memcpy (valbuf,
! regbuf + DEPRECATED_REGISTER_BYTE (S390_GP0_REGNUM + 2) + offset,
TYPE_LENGTH (valtype));
}
}
--- 2379,2385 ----
if (TYPE_LENGTH (valtype) < S390_GPR_SIZE)
offset = S390_GPR_SIZE - TYPE_LENGTH (valtype);
memcpy (valbuf,
! regbuf + DEPRECATED_REGISTER_BYTE (S390_R0_REGNUM + 2) + offset,
TYPE_LENGTH (valtype));
}
}
*************** static void
*** 1947,1959 ****
s390_store_return_value (struct type *valtype, char *valbuf)
{
int arglen;
! char *reg_buff = alloca (max (S390_FPR_SIZE, DEPRECATED_REGISTER_SIZE)), *value;
if (TYPE_CODE (valtype) == TYPE_CODE_FLT)
{
if (TYPE_LENGTH (valtype) == 4
|| TYPE_LENGTH (valtype) == 8)
! deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (S390_FP0_REGNUM),
valbuf, TYPE_LENGTH (valtype));
else
error ("GDB is unable to return `long double' values "
--- 2424,2436 ----
s390_store_return_value (struct type *valtype, char *valbuf)
{
int arglen;
! char *reg_buff = alloca (max (S390_FPR_SIZE, S390_GPR_SIZE)), *value;
if (TYPE_CODE (valtype) == TYPE_CODE_FLT)
{
if (TYPE_LENGTH (valtype) == 4
|| TYPE_LENGTH (valtype) == 8)
! deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (S390_F0_REGNUM),
valbuf, TYPE_LENGTH (valtype));
else
error ("GDB is unable to return `long double' values "
*************** s390_store_return_value (struct type *va
*** 1964,1970 ****
value =
s390_promote_integer_argument (valtype, valbuf, reg_buff, &arglen);
/* Everything else is returned in GPR2 and up. */
! deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (S390_GP0_REGNUM + 2),
value, arglen);
}
}
--- 2441,2447 ----
value =
s390_promote_integer_argument (valtype, valbuf, reg_buff, &arglen);
/* Everything else is returned in GPR2 and up. */
! deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (S390_R0_REGNUM + 2),
value, arglen);
}
}
*************** is_simple_arg (struct type *type)
*** 2171,2177 ****
/* This is almost a direct translation of the ABI's language, except
that we have to exclude 8-byte structs; those are DOUBLE_ARGs. */
! return ((is_integer_like (type) && length <= DEPRECATED_REGISTER_SIZE)
|| is_pointer_like (type)
|| (is_struct_like (type) && !is_double_arg (type)));
}
--- 2648,2654 ----
/* This is almost a direct translation of the ABI's language, except
that we have to exclude 8-byte structs; those are DOUBLE_ARGs. */
! return ((is_integer_like (type) && length <= S390_GPR_SIZE)
|| is_pointer_like (type)
|| (is_struct_like (type) && !is_double_arg (type)));
}
*************** pass_by_copy_ref (struct type *type)
*** 2192,2198 ****
unsigned length = TYPE_LENGTH (type);
return (is_struct_like (type)
! && !(is_power_of_two (length) && length <= DEPRECATED_REGISTER_SIZE));
}
--- 2669,2675 ----
unsigned length = TYPE_LENGTH (type);
return (is_struct_like (type)
! && !(is_power_of_two (length) && length <= S390_GPR_SIZE));
}
*************** s390_push_arguments (int nargs, struct v
*** 2312,2320 ****
sp = align_down (sp, alignment_of (type));
! /* SIMPLE_ARG values get extended to DEPRECATED_REGISTER_SIZE bytes.
Assume every argument is. */
! if (length < DEPRECATED_REGISTER_SIZE) length = DEPRECATED_REGISTER_SIZE;
sp -= length;
}
}
--- 2789,2797 ----
sp = align_down (sp, alignment_of (type));
! /* SIMPLE_ARG values get extended to S390_GPR_SIZE bytes.
Assume every argument is. */
! if (length < S390_GPR_SIZE) length = S390_GPR_SIZE;
sp -= length;
}
}
*************** s390_push_arguments (int nargs, struct v
*** 2349,2355 ****
{
/* When we store a single-precision value in an FP register,
it occupies the leftmost bits. */
! deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (S390_FP0_REGNUM + fr),
VALUE_CONTENTS (arg),
TYPE_LENGTH (type));
fr += 2;
--- 2826,2832 ----
{
/* When we store a single-precision value in an FP register,
it occupies the leftmost bits. */
! deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (S390_F0_REGNUM + fr),
VALUE_CONTENTS (arg),
TYPE_LENGTH (type));
fr += 2;
*************** s390_push_arguments (int nargs, struct v
*** 2360,2378 ****
/* Do we need to pass a pointer to our copy of this
argument? */
if (pass_by_copy_ref (type))
! write_register (S390_GP0_REGNUM + gr, copy_addr[i]);
else
! write_register (S390_GP0_REGNUM + gr, extend_simple_arg (arg));
gr++;
}
else if (is_double_arg (type)
&& gr <= 5)
{
! deprecated_write_register_gen (S390_GP0_REGNUM + gr,
VALUE_CONTENTS (arg));
! deprecated_write_register_gen (S390_GP0_REGNUM + gr + 1,
! VALUE_CONTENTS (arg) + DEPRECATED_REGISTER_SIZE);
gr += 2;
}
else
--- 2837,2855 ----
/* Do we need to pass a pointer to our copy of this
argument? */
if (pass_by_copy_ref (type))
! write_register (S390_R0_REGNUM + gr, copy_addr[i]);
else
! write_register (S390_R0_REGNUM + gr, extend_simple_arg (arg));
gr++;
}
else if (is_double_arg (type)
&& gr <= 5)
{
! deprecated_write_register_gen (S390_R0_REGNUM + gr,
VALUE_CONTENTS (arg));
! deprecated_write_register_gen (S390_R0_REGNUM + gr + 1,
! VALUE_CONTENTS (arg) + S390_GPR_SIZE);
gr += 2;
}
else
*************** s390_push_arguments (int nargs, struct v
*** 2389,2396 ****
if (is_simple_arg (type))
{
/* Simple args are always extended to
! DEPRECATED_REGISTER_SIZE bytes. */
! starg = align_up (starg, DEPRECATED_REGISTER_SIZE);
/* Do we need to pass a pointer to our copy of this
argument? */
--- 2866,2873 ----
if (is_simple_arg (type))
{
/* Simple args are always extended to
! S390_GPR_SIZE bytes. */
! starg = align_up (starg, S390_GPR_SIZE);
/* Do we need to pass a pointer to our copy of this
argument? */
*************** s390_push_arguments (int nargs, struct v
*** 2399,2408 ****
copy_addr[i]);
else
/* Simple args are always extended to
! DEPRECATED_REGISTER_SIZE bytes. */
! write_memory_signed_integer (starg, DEPRECATED_REGISTER_SIZE,
extend_simple_arg (arg));
! starg += DEPRECATED_REGISTER_SIZE;
}
else
{
--- 2876,2885 ----
copy_addr[i]);
else
/* Simple args are always extended to
! S390_GPR_SIZE bytes. */
! write_memory_signed_integer (starg, S390_GPR_SIZE,
extend_simple_arg (arg));
! starg += S390_GPR_SIZE;
}
else
{
*************** s390_use_struct_convention (int gcc_p, s
*** 2451,2483 ****
|| code == TYPE_CODE_UNION);
}
-
- /* Return the GDB type object for the "standard" data type
- of data in register N. */
- static struct type *
- s390_register_virtual_type (int regno)
- {
- if (S390_FP0_REGNUM <= regno && regno < S390_FP0_REGNUM + S390_NUM_FPRS)
- return builtin_type_double;
- else
- return builtin_type_int;
- }
-
-
- static 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;
- }
-
-
-
static void
s390_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
{
! write_register (S390_GP0_REGNUM + 2, addr);
}
--- 2928,2937 ----
|| code == TYPE_CODE_UNION);
}
static void
s390_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
{
! write_register (S390_R0_REGNUM + 2, addr);
}
*************** s390_gdbarch_init (struct gdbarch_info i
*** 2575,2581 ****
return NULL; /* No; then it's not for us. */
/* Yes: create a new gdbarch for the specified machine type. */
! gdbarch = gdbarch_alloc (&info, NULL);
/* NOTE: cagney/2002-12-06: This can be deleted when this arch is
ready to unwind the PC first (see frame.c:get_prev_frame()). */
--- 3029,3036 ----
return NULL; /* No; then it's not for us. */
/* Yes: create a new gdbarch for the specified machine type. */
! tdep = XCALLOC (1, struct gdbarch_tdep);
! gdbarch = gdbarch_alloc (&info, tdep);
/* NOTE: cagney/2002-12-06: This can be deleted when this arch is
ready to unwind the PC first (see frame.c:get_prev_frame()). */
*************** s390_gdbarch_init (struct gdbarch_info i
*** 2600,2612 ****
/* Offset from address of function to start of its code.
Zero on most machines. */
set_gdbarch_function_start_offset (gdbarch, 0);
- set_gdbarch_deprecated_max_register_raw_size (gdbarch, 8);
- set_gdbarch_deprecated_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_deprecated_init_extra_frame_info (gdbarch, s390_init_extra_frame_info);
set_gdbarch_deprecated_init_frame_pc_first (gdbarch, s390_init_frame_pc_first);
set_gdbarch_deprecated_target_read_fp (gdbarch, s390_read_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. */
--- 3055,3066 ----
/* Offset from address of function to start of its code.
Zero on most machines. */
set_gdbarch_function_start_offset (gdbarch, 0);
set_gdbarch_breakpoint_from_pc (gdbarch, s390_breakpoint_from_pc);
set_gdbarch_skip_prologue (gdbarch, s390_skip_prologue);
set_gdbarch_deprecated_init_extra_frame_info (gdbarch, s390_init_extra_frame_info);
set_gdbarch_deprecated_init_frame_pc_first (gdbarch, s390_init_frame_pc_first);
set_gdbarch_deprecated_target_read_fp (gdbarch, s390_read_fp);
+ set_gdbarch_in_function_epilogue_p (gdbarch, s390_in_function_epilogue_p);
/* 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. */
*************** s390_gdbarch_init (struct gdbarch_info i
*** 2618,2636 ****
produces the frame's chain-pointer. */
set_gdbarch_deprecated_frame_chain (gdbarch, s390_frame_chain);
set_gdbarch_deprecated_saved_pc_after_call (gdbarch, s390_saved_pc_after_call);
- set_gdbarch_deprecated_register_byte (gdbarch, s390_register_byte);
set_gdbarch_pc_regnum (gdbarch, S390_PC_REGNUM);
set_gdbarch_sp_regnum (gdbarch, S390_SP_REGNUM);
! set_gdbarch_deprecated_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_use_struct_convention (gdbarch, s390_use_struct_convention);
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);
set_gdbarch_extract_struct_value_address (gdbarch, s390_cannot_extract_struct_value_address);
/* Parameters for inferior function calls. */
--- 3072,3095 ----
produces the frame's chain-pointer. */
set_gdbarch_deprecated_frame_chain (gdbarch, s390_frame_chain);
set_gdbarch_deprecated_saved_pc_after_call (gdbarch, s390_saved_pc_after_call);
set_gdbarch_pc_regnum (gdbarch, S390_PC_REGNUM);
set_gdbarch_sp_regnum (gdbarch, S390_SP_REGNUM);
! set_gdbarch_deprecated_fp_regnum (gdbarch, S390_SP_REGNUM);
! set_gdbarch_fp0_regnum (gdbarch, S390_F0_REGNUM);
set_gdbarch_num_regs (gdbarch, S390_NUM_REGS);
! set_gdbarch_num_pseudo_regs (gdbarch, S390_NUM_PSEUDO_REGS);
set_gdbarch_use_struct_convention (gdbarch, s390_use_struct_convention);
set_gdbarch_register_name (gdbarch, s390_register_name);
! set_gdbarch_register_type (gdbarch, s390_register_type);
! set_gdbarch_stab_reg_to_regnum (gdbarch, s390_dwarf_reg_to_regnum);
! set_gdbarch_dwarf_reg_to_regnum (gdbarch, s390_dwarf_reg_to_regnum);
! set_gdbarch_dwarf2_reg_to_regnum (gdbarch, s390_dwarf_reg_to_regnum);
! set_gdbarch_convert_register_p (gdbarch, s390_convert_register_p);
! set_gdbarch_register_to_value (gdbarch, s390_register_to_value);
! set_gdbarch_value_to_register (gdbarch, s390_value_to_register);
! set_gdbarch_register_reggroup_p (gdbarch, s390_register_reggroup_p);
! set_gdbarch_regset_from_core_section (gdbarch,
! s390_regset_from_core_section);
set_gdbarch_extract_struct_value_address (gdbarch, s390_cannot_extract_struct_value_address);
/* Parameters for inferior function calls. */
*************** s390_gdbarch_init (struct gdbarch_info i
*** 2646,2669 ****
switch (info.bfd_arch_info->mach)
{
case bfd_mach_s390_31:
! set_gdbarch_deprecated_register_size (gdbarch, 4);
! set_gdbarch_deprecated_register_raw_size (gdbarch, s390_register_raw_size);
! set_gdbarch_deprecated_register_virtual_size (gdbarch, s390_register_raw_size);
! set_gdbarch_deprecated_register_virtual_type (gdbarch, s390_register_virtual_type);
set_gdbarch_addr_bits_remove (gdbarch, s390_addr_bits_remove);
! set_gdbarch_deprecated_register_bytes (gdbarch, S390_REGISTER_BYTES);
break;
case bfd_mach_s390_64:
! set_gdbarch_deprecated_register_size (gdbarch, 8);
! set_gdbarch_deprecated_register_raw_size (gdbarch, s390x_register_raw_size);
! set_gdbarch_deprecated_register_virtual_size (gdbarch, s390x_register_raw_size);
! set_gdbarch_deprecated_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_deprecated_register_bytes (gdbarch, S390X_REGISTER_BYTES);
set_gdbarch_address_class_type_flags (gdbarch,
s390_address_class_type_flags);
set_gdbarch_address_class_type_flags_to_name (gdbarch,
--- 3105,3130 ----
switch (info.bfd_arch_info->mach)
{
case bfd_mach_s390_31:
! tdep->sizeof_gregset = s390_sizeof_gregset;
! tdep->regmap_gregset = s390_regmap_gregset;
! tdep->sizeof_fpregset = s390_sizeof_fpregset;
! tdep->regmap_fpregset = s390_regmap_fpregset;
set_gdbarch_addr_bits_remove (gdbarch, s390_addr_bits_remove);
! set_gdbarch_pseudo_register_read (gdbarch, s390_pseudo_register_read);
! set_gdbarch_pseudo_register_write (gdbarch, s390_pseudo_register_write);
break;
case bfd_mach_s390_64:
! tdep->sizeof_gregset = s390x_sizeof_gregset;
! tdep->regmap_gregset = s390x_regmap_gregset;
! tdep->sizeof_fpregset = s390_sizeof_fpregset;
! tdep->regmap_fpregset = s390_regmap_fpregset;
set_gdbarch_long_bit (gdbarch, 64);
set_gdbarch_long_long_bit (gdbarch, 64);
set_gdbarch_ptr_bit (gdbarch, 64);
! set_gdbarch_pseudo_register_read (gdbarch, s390x_pseudo_register_read);
! set_gdbarch_pseudo_register_write (gdbarch, s390x_pseudo_register_write);
set_gdbarch_address_class_type_flags (gdbarch,
s390_address_class_type_flags);
set_gdbarch_address_class_type_flags_to_name (gdbarch,
diff -c -p -r -N gdb-head/gdb/testsuite/gdb.base/float.exp gdb-head-new/gdb/testsuite/gdb.base/float.exp
*** gdb-head/gdb/testsuite/gdb.base/float.exp Tue Dec 2 17:47:36 2003
--- gdb-head-new/gdb/testsuite/gdb.base/float.exp Tue Dec 2 16:36:15 2003
*************** if { [istarget "alpha*-*-*"] } then {
*** 63,68 ****
--- 63,70 ----
gdb_test "info float" "f0.*f1.*f127.*" "info float"
} elseif [istarget "m68k-*-*"] then {
gdb_test "info float" "fp0.*fp1.*fp7.*" "info float"
+ } elseif [istarget "s390*-*-*"] then {
+ gdb_test "info float" "fpc.*f0.*f1.*f15.*" "info float"
} elseif [istarget "sh*-*"] then {
# SH may or may not have an FPU
gdb_test_multiple "info float" "info float" {
--
Dr. Ulrich Weigand
weigand@informatik.uni-erlangen.de
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH] S/390 port modernization 1/4
2003-12-04 20:06 [PATCH] S/390 port modernization 1/4 Ulrich Weigand
@ 2003-12-04 21:01 ` Jim Blandy
2003-12-04 21:56 ` Ulrich Weigand
2003-12-04 21:18 ` Jim Blandy
2003-12-04 21:43 ` Jim Blandy
2 siblings, 1 reply; 10+ messages in thread
From: Jim Blandy @ 2003-12-04 21:01 UTC (permalink / raw)
To: Ulrich Weigand; +Cc: gdb-patches, uweigand
Ulrich Weigand <weigand@i1.informatik.uni-erlangen.de> writes:
> *** gdb-head/gdb/config/s390/tm-linux.h Tue Dec 2 17:47:36 2003
> --- gdb-head-new/gdb/config/s390/tm-linux.h Tue Dec 2 16:36:15 2003
> ***************
> *** 25,42 ****
> #ifndef TM_LINUX_H
> #define TM_LINUX_H
>
> - #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 */
> --- 25,30 ----
The deletion of the #undefinition of SKIP_TRAMPOLINE_CODE isn't
mentioned in the ChangeLog entries; was it intentional? If I'm
following the code right, the effect is to change the method from
using generic_skip_trampoline_code (the gdbarch default) to using
find_solib_trampoline_target (#defined in config/tm-sysv4.h, #included
from config/tm-linux.h, #included from config/s390/tm-linux.h), so it
seems like something that deserves mention.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] S/390 port modernization 1/4
2003-12-04 21:01 ` Jim Blandy
@ 2003-12-04 21:56 ` Ulrich Weigand
2003-12-05 4:21 ` Jim Blandy
0 siblings, 1 reply; 10+ messages in thread
From: Ulrich Weigand @ 2003-12-04 21:56 UTC (permalink / raw)
To: Jim Blandy; +Cc: Ulrich Weigand, gdb-patches, uweigand
Jim Blandy wrote:
> The deletion of the #undefinition of SKIP_TRAMPOLINE_CODE isn't
> mentioned in the ChangeLog entries; was it intentional? If I'm
> following the code right, the effect is to change the method from
> using generic_skip_trampoline_code (the gdbarch default) to using
> find_solib_trampoline_target (#defined in config/tm-sysv4.h, #included
> from config/tm-linux.h, #included from config/s390/tm-linux.h), so it
> seems like something that deserves mention.
Hmm, I probably misinterpreted the comment above that line ...
In any case, looking at the code, it certainly seems the right
thing to do to use the same SKIP_TRAMPOLINE_CODE as other Linux
ports, since everything related to PLTs works the same on s390
as elsewhere.
So I'd suggest to leave the patch as is in that regard, and simply
add a ChangeLog line.
Bye,
Ulrich
--
Dr. Ulrich Weigand
weigand@informatik.uni-erlangen.de
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] S/390 port modernization 1/4
2003-12-04 20:06 [PATCH] S/390 port modernization 1/4 Ulrich Weigand
2003-12-04 21:01 ` Jim Blandy
@ 2003-12-04 21:18 ` Jim Blandy
2003-12-04 21:45 ` Ulrich Weigand
2003-12-04 21:43 ` Jim Blandy
2 siblings, 1 reply; 10+ messages in thread
From: Jim Blandy @ 2003-12-04 21:18 UTC (permalink / raw)
To: Ulrich Weigand; +Cc: gdb-patches, uweigand
The rearrangement of the register code looks great. I did core file
register handling in Not The Right Fashion, and your new code seems to
fix that. And it's more legible.
It seems like s390-nat.c's s390_gregset_regmap and
s390_fpregset_regmap are essentially the same information as
s390-tdep.c's s390_regmap_gregset, s390x_regmap_gregset, and
s390_regmap_fpregset, except that the s390 / s390x distinction is
static in s390-nat.c, and dynamic in s390-tdep.c. But if I recall
correctly, the way the types in the kernel header files work out, the
core dump format is always the same as the PTRACE uarea format.
Would it be possible to have s390-nat.c simply use the structures from
s390-tdep.c? There's nothing wrong with having an s390-tdep.h file in
the gdb directory; that's the usual arrangement for native systems.
But this is a minor issue. Given the nature of the IBM / FSF process,
feel free to either revise this patch, or submit it as a separate
patch, whichever is easiest for you.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] S/390 port modernization 1/4
2003-12-04 21:18 ` Jim Blandy
@ 2003-12-04 21:45 ` Ulrich Weigand
2003-12-05 4:29 ` Jim Blandy
0 siblings, 1 reply; 10+ messages in thread
From: Ulrich Weigand @ 2003-12-04 21:45 UTC (permalink / raw)
To: Jim Blandy; +Cc: Ulrich Weigand, gdb-patches, uweigand
Jim Blandy wrote:
> Would it be possible to have s390-nat.c simply use the structures from
> s390-tdep.c? There's nothing wrong with having an s390-tdep.h file in
> the gdb directory; that's the usual arrangement for native systems.
As these offsets are core kernel ABI that will never change, I hadn't
thought it necessary to avoid this duplication -- in particular as
one of my goals was to disentangle the various components as much as
possible ...
But if you prefer a s390-tdep.h file, I can certainly do that.
Bye,
Ulrich
--
Dr. Ulrich Weigand
weigand@informatik.uni-erlangen.de
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] S/390 port modernization 1/4
2003-12-04 21:45 ` Ulrich Weigand
@ 2003-12-05 4:29 ` Jim Blandy
0 siblings, 0 replies; 10+ messages in thread
From: Jim Blandy @ 2003-12-05 4:29 UTC (permalink / raw)
To: Ulrich Weigand; +Cc: gdb-patches, uweigand
Ulrich Weigand <weigand@i1.informatik.uni-erlangen.de> writes:
> Jim Blandy wrote:
>
> > Would it be possible to have s390-nat.c simply use the structures from
> > s390-tdep.c? There's nothing wrong with having an s390-tdep.h file in
> > the gdb directory; that's the usual arrangement for native systems.
>
> As these offsets are core kernel ABI that will never change, I hadn't
> thought it necessary to avoid this duplication -- in particular as
> one of my goals was to disentangle the various components as much as
> possible ...
>
> But if you prefer a s390-tdep.h file, I can certainly do that.
I see. It's my feeling that -nat.c files are always, in some sense,
dependent on -tdep.c files anyway (although the reverse is not true).
And it seems to me that using exactly the same table in both places
does clarify the intent.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] S/390 port modernization 1/4
2003-12-04 20:06 [PATCH] S/390 port modernization 1/4 Ulrich Weigand
2003-12-04 21:01 ` Jim Blandy
2003-12-04 21:18 ` Jim Blandy
@ 2003-12-04 21:43 ` Jim Blandy
2003-12-04 22:11 ` Ulrich Weigand
2 siblings, 1 reply; 10+ messages in thread
From: Jim Blandy @ 2003-12-04 21:43 UTC (permalink / raw)
To: Ulrich Weigand; +Cc: gdb-patches, uweigand
The regset_from_core_section stuff is done exactly the way the i386
and x86-64 do it, so I won't criticize it. But there are two things I
wonder about:
- Since core file formats are really OS-specific (ABI's often don't
specify them), wouldn't it make more sense for the *-nat.c file to
register an OS/ABI handler, and have that handler register the
regset_from_core_section method?
- Why does everyone allocate the 'struct regset' objects dynamically?
The regset layouts are structures in header files, so there's only a
static set of them; one could simply define initialized instances of
'struct regset', and the regset_from_core_section method could
return them. That seems simpler than allocating them dynamically,
and caching them in the tdep structure.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] S/390 port modernization 1/4
2003-12-04 21:43 ` Jim Blandy
@ 2003-12-04 22:11 ` Ulrich Weigand
2003-12-05 4:30 ` Jim Blandy
0 siblings, 1 reply; 10+ messages in thread
From: Ulrich Weigand @ 2003-12-04 22:11 UTC (permalink / raw)
To: Jim Blandy; +Cc: Ulrich Weigand, gdb-patches, uweigand
Jim Blandy wrote:
> The regset_from_core_section stuff is done exactly the way the i386
> and x86-64 do it, so I won't criticize it. But there are two things I
> wonder about:
>
> - Since core file formats are really OS-specific (ABI's often don't
> specify them), wouldn't it make more sense for the *-nat.c file to
> register an OS/ABI handler, and have that handler register the
> regset_from_core_section method?
Defining the core file format in *-nat.c would mean that a cross-gdb
wouldn't understand core files, right?
> - Why does everyone allocate the 'struct regset' objects dynamically?
> The regset layouts are structures in header files, so there's only a
> static set of them; one could simply define initialized instances of
> 'struct regset', and the regset_from_core_section method could
> return them. That seems simpler than allocating them dynamically,
> and caching them in the tdep structure.
OK, I'll change that.
Bye,
Ulrich
--
Dr. Ulrich Weigand
weigand@informatik.uni-erlangen.de
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] S/390 port modernization 1/4
2003-12-04 22:11 ` Ulrich Weigand
@ 2003-12-05 4:30 ` Jim Blandy
0 siblings, 0 replies; 10+ messages in thread
From: Jim Blandy @ 2003-12-05 4:30 UTC (permalink / raw)
To: Ulrich Weigand; +Cc: gdb-patches, uweigand
Ulrich Weigand <weigand@i1.informatik.uni-erlangen.de> writes:
> Jim Blandy wrote:
>
> > The regset_from_core_section stuff is done exactly the way the i386
> > and x86-64 do it, so I won't criticize it. But there are two things I
> > wonder about:
> >
> > - Since core file formats are really OS-specific (ABI's often don't
> > specify them), wouldn't it make more sense for the *-nat.c file to
> > register an OS/ABI handler, and have that handler register the
> > regset_from_core_section method?
>
> Defining the core file format in *-nat.c would mean that a cross-gdb
> wouldn't understand core files, right?
I think you're right. I guess that answers my question.
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2003-12-05 4:30 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-12-04 20:06 [PATCH] S/390 port modernization 1/4 Ulrich Weigand
2003-12-04 21:01 ` Jim Blandy
2003-12-04 21:56 ` Ulrich Weigand
2003-12-05 4:21 ` Jim Blandy
2003-12-04 21:18 ` Jim Blandy
2003-12-04 21:45 ` Ulrich Weigand
2003-12-05 4:29 ` Jim Blandy
2003-12-04 21:43 ` Jim Blandy
2003-12-04 22:11 ` Ulrich Weigand
2003-12-05 4:30 ` Jim Blandy
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox