diff options
author | Ulrich Weigand <uweigand@de.ibm.com> | 2010-01-04 15:03:01 +0000 |
---|---|---|
committer | Ulrich Weigand <uweigand@de.ibm.com> | 2010-01-04 15:03:01 +0000 |
commit | 7803799a0fb31a9d332cd3bf3547309debea010b (patch) | |
tree | 25069dfa82ff65c3340e823fc26a45de7ab2dd2a /gdb/s390-nat.c | |
parent | 1b1818e443eb8f134e0bc2f5ec950c8a16df6883 (diff) | |
download | gdb-7803799a0fb31a9d332cd3bf3547309debea010b.zip gdb-7803799a0fb31a9d332cd3bf3547309debea010b.tar.gz gdb-7803799a0fb31a9d332cd3bf3547309debea010b.tar.bz2 |
* 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.c | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/gdb/s390-nat.c b/gdb/s390-nat.c index c67777e..3af42ff 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 (¤t_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); |