summaryrefslogtreecommitdiff
path: root/gdb/s390-nat.c
diff options
context:
space:
mode:
authorUlrich Weigand <uweigand@de.ibm.com>2010-01-04 15:02:55 +0000
committerUlrich Weigand <uweigand@de.ibm.com>2010-01-04 15:02:55 +0000
commit458c3aedcb159b3389fb171221719c8b05e9ef43 (patch)
tree7501cb8581652d5a5b0ef51ca4fcf3e918f04f84 /gdb/s390-nat.c
parente3677eede2324b389b8a94b298a7e69ac737b731 (diff)
downloadgdb-458c3aedcb159b3389fb171221719c8b05e9ef43.tar.gz
* features/Makefile (WHICH): Add s390-linux32, s390-linux64,
and s390x-linux64. (s390-linux32-expedite): Define. (s390-linux64-expedite): Define. (s390x-linux64-expedite): Define. * features/s390-acr.xml: New file. * features/s390-fpr.xml: New file. * features/s390-core32.xml: New file. * features/s390-core64.xml: New file. * features/s390x-core64.xml: New file. * features/s390-linux32.xml: New file. * features/s390-linux64.xml: New file. * features/s390x-linux64.xml: New file. * features/s390-linux32.c: New generated file. * features/s390-linux64.c: New generated file. * features/s390x-linux64.c: New generated file. * regformats/s390-linux32.dat: New generated file. * regformats/s390-linux64.dat: New generated file. * regformats/s390x-linux64.dat: New generated file. * regformats/reg-s390.dat: Remove. * regformats/reg-s390x.dat: Remove. * s390-nat.c: Include "auxv.h" and <elf.h>. (HWCAP_S390_HIGH_GPRS): Define if undefined. (s390_target_wordsize): New function. (s390_auxv_parse): Likewise. (s390_get_hwcap): Likewise. (s390_read_description): Likewise. (_initialize_s390_nat): Install s390_auxv_parse and s390_read_description. * s390-tdep.c: Include "features/s390-linux32.c", "features/s390-linux64.c", and "features/s390x-linux64.c". (struct gdbarch_tdep): Add gpr_full_regnum, pc_regnum, and cc_regnum. (s390_register_call_saved): New function. (s390_register_name): Remove. (s390_register_type): Remove. (s390_dwarf_regmap): Add lower half GPR pseudo DWARF CFI regnums. (s390_dwarf_reg_to_regnum): Remap GPR regnums to full GPRs. (s390_adjust_frame_regnum): Remap GPR regnums to lower halves for CFI. (s390_pseudo_register_name): New function. (s390_pseudo_register_type): New function. (s390_pseudo_register_read): Handle both 32-bit and 64-bit cases. Handle full GPR pesudos and varying pseudo register numbers. (s390_pseudo_register_write): Likewise (s390x_pseudo_register_read): Remove. (s390x_pseudo_register_write): Likewise. (s390_register_group): Remove. (s390_pseudo_register_group): New function. (s390_regmap_gregset): Add GPR upper halves. (s390x_regmap_gregset): Likewise. (s390_regmap_fpregset): Likewise. (s390_regmap_upper): New global variable. (s390_upper_regset): New global variable. (s390_upper_regset_sections): New global variable. (s390_regset_from_core_section): Handle GPR upper halves. (s390_core_read_description): New function. (s390_prologue_frame_unwind_cache): Set up ABI call-saved/clobbered register information. Handle varying pseudo register numbers. (s390_backchain_frame_unwind_cache): Likewise. (s390_frame_prev_register): Unwind full GPRs to show lower halves. (s390_stub_frame_unwind_cache): Handle varying pseudo register numbers. (s390_sigtramp_frame_unwind_cache): Unwind PSWM and PSWA as well as PC and CC pseudos. Unwind upper halves and full GPRs as appropriate. Handle varying pseudo register numbers. (s390_unwind_pc): Handle varying pseudo register numbers. (s390_dwarf2_prev_register): New function. (s390_dwarf2_frame_init_reg): Set up ABI call-saved/clobbered register information. Handle varying pseudo register numbers. Install s390_dwarf2_prev_register to unwind full GPRs. (s390_gdbarch_init): Handle target descriptions. Assign varying pseudo register numbers. Install s390_adjust_frame_regnum. (_initialize_s390_tdep): Initialize target descriptions. * s390-tdep.h (S390_R0_UPPER_REGNUM .. S390_R15_UPPER_REGNUM): Define. (S390_NUM_REGS): Redefine to include upper half registers. (S390_PC_REGNUM, S390_CC_REGNUM): Remove. (S390_NUM_PSEUDO_REGS, S390_NUM_TOTAL_REGS): Likewise. (tdesc_s390_linux32): Add declaration. (tdesc_s390_linux64): Likewise. (tdesc_s390x_linux64): Likewise. gdb/testsuite/ * gdb.xml/tdesc-regs.exp: Support s390*-*-* targets. gdbserver/ * Makefile.in (clean): Remove new generated files. (reg-s390.o, reg-s390.c): Remove rules. (reg-s390x.o, reg-s390x.c): Likewise. (s390-linux32.o, s390-linux32.c): Add rules. (s390-linux64.o, s390-linux64.c): Likewise. (s390x-linux64.o, s390x-linux64.c): Likewise. * configure.srv (s390*-*-linux*): Update srv_regobj and srv_xmlfiles. * linux-s390-low.c: Include <elf.h>. (HWCAP_S390_HIGH_GPRS): Define if undefined. (init_registers_s390): Remove prototype. (init_registers_s390x): Likewise. (init_registers_s390_linux32): Add prototype. (init_registers_s390_linux64): Likewise. (init_registers_s390x_linux64): Likewise. (s390_num_regs_3264): New define. (s390_regmap_3264): New global variable. (s390_cannot_fetch_register): Remove obsolete check. (s390_cannot_store_register): Likewise. (s390_collect_ptrace_register): Handle upper/lower register halves. (s390_supply_ptrace_register): Likewise. (s390_fill_gregset): Update to register number changes. (s390_get_hwcap): New routine. (s390_arch_setup): Detect 32-bit process running on 64-bit system. Install appropriate regmap and register set.
Diffstat (limited to 'gdb/s390-nat.c')
-rw-r--r--gdb/s390-nat.c87
1 files changed, 87 insertions, 0 deletions
diff --git a/gdb/s390-nat.c b/gdb/s390-nat.c
index c67777e929a..3af42ff80df 100644
--- a/gdb/s390-nat.c
+++ b/gdb/s390-nat.c
@@ -25,6 +25,7 @@
#include "inferior.h"
#include "target.h"
#include "linux-nat.h"
+#include "auxv.h"
#include "s390-tdep.h"
@@ -33,6 +34,11 @@
#include <asm/types.h>
#include <sys/procfs.h>
#include <sys/ucontext.h>
+#include <elf.h>
+
+#ifndef HWCAP_S390_HIGH_GPRS
+#define HWCAP_S390_HIGH_GPRS 512
+#endif
/* Map registers to gregset/ptrace offsets.
@@ -389,6 +395,83 @@ s390_region_ok_for_hw_watchpoint (CORE_ADDR addr, int cnt)
return 1;
}
+static int
+s390_target_wordsize (void)
+{
+ int wordsize = 4;
+
+ /* Check for 64-bit inferior process. This is the case when the host is
+ 64-bit, and in addition bit 32 of the PSW mask is set. */
+#ifdef __s390x__
+ long pswm;
+
+ errno = 0;
+ pswm = (long) ptrace (PTRACE_PEEKUSER, s390_inferior_tid (), PT_PSWMASK, 0);
+ if (errno == 0 && (pswm & 0x100000000ul) != 0)
+ wordsize = 8;
+#endif
+
+ return wordsize;
+}
+
+static int
+s390_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
+ gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
+{
+ int sizeof_auxv_field = s390_target_wordsize ();
+ enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
+ gdb_byte *ptr = *readptr;
+
+ if (endptr == ptr)
+ return 0;
+
+ if (endptr - ptr < sizeof_auxv_field * 2)
+ return -1;
+
+ *typep = extract_unsigned_integer (ptr, sizeof_auxv_field, byte_order);
+ ptr += sizeof_auxv_field;
+ *valp = extract_unsigned_integer (ptr, sizeof_auxv_field, byte_order);
+ ptr += sizeof_auxv_field;
+
+ *readptr = ptr;
+ return 1;
+}
+
+#ifdef __s390x__
+static unsigned long
+s390_get_hwcap (void)
+{
+ CORE_ADDR field;
+
+ if (target_auxv_search (&current_target, AT_HWCAP, &field))
+ return (unsigned long) field;
+
+ return 0;
+}
+#endif
+
+static const struct target_desc *
+s390_read_description (struct target_ops *ops)
+{
+#ifdef __s390x__
+ /* If GDB itself is compiled as 64-bit, we are running on a machine in
+ z/Architecture mode. If the target is running in 64-bit addressing
+ mode, report s390x architecture. If the target is running in 31-bit
+ addressing mode, but the kernel supports using 64-bit registers in
+ that mode, report s390 architecture with 64-bit GPRs. */
+
+ if (s390_target_wordsize () == 8)
+ return tdesc_s390x_linux64;
+
+ if (s390_get_hwcap () & HWCAP_S390_HIGH_GPRS)
+ return tdesc_s390_linux64;
+#endif
+
+ /* If GDB itself is compiled as 31-bit, or if we're running a 31-bit inferior
+ on a 64-bit kernel that does not support using 64-bit registers in 31-bit
+ mode, report s390 architecture with 32-bit GPRs. */
+ return tdesc_s390_linux32;
+}
void _initialize_s390_nat (void);
@@ -412,6 +495,10 @@ _initialize_s390_nat (void)
t->to_insert_watchpoint = s390_insert_watchpoint;
t->to_remove_watchpoint = s390_remove_watchpoint;
+ /* Detect target architecture. */
+ t->to_read_description = s390_read_description;
+ t->to_auxv_parse = s390_auxv_parse;
+
/* Register the target. */
linux_nat_add_target (t);
linux_nat_set_new_thread (t, s390_fix_watch_points);