/* Target-dependent code for GNU/Linux on s390.
- Copyright (C) 2001-2018 Free Software Foundation, Inc.
+ Copyright (C) 2001-2019 Free Software Foundation, Inc.
Contributed by D.J. Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
for IBM Deutschland Entwicklung GmbH, IBM Corporation.
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
-#include "arch-utils.h"
-#include "frame.h"
-#include "inferior.h"
-#include "infrun.h"
-#include "symtab.h"
-#include "target.h"
+
+#include "auxv.h"
+#include "elf/common.h"
+#include "frame-base.h"
+#include "frame-unwind.h"
+#include "gdbarch.h"
#include "gdbcore.h"
-#include "gdbcmd.h"
+#include "linux-record.h"
+#include "linux-tdep.h"
#include "objfiles.h"
#include "osabi.h"
#include "regcache.h"
-#include "trad-frame.h"
-#include "frame-base.h"
-#include "frame-unwind.h"
-#include "dwarf2-frame.h"
-#include "reggroups.h"
+#include "record-full.h"
#include "regset.h"
-#include "value.h"
-#include "dis-asm.h"
-#include "solib-svr4.h"
-#include "prologue-value.h"
-#include "linux-tdep.h"
#include "s390-tdep.h"
#include "s390-linux-tdep.h"
-#include "linux-record.h"
-#include "record-full.h"
-#include "auxv.h"
+#include "solib-svr4.h"
+#include "target.h"
+#include "trad-frame.h"
#include "xml-syscall.h"
-#include "stap-probe.h"
-#include "ax.h"
-#include "ax-gdb.h"
-#include "user-regs.h"
-#include "cli/cli-utils.h"
-#include <ctype.h>
-#include "elf/common.h"
-#include "elf/s390.h"
-#include "elf-bfd.h"
-#include <algorithm>
-
-#include "features/s390-linux32.c"
#include "features/s390-linux32v1.c"
#include "features/s390-linux32v2.c"
#include "features/s390-linux64.c"
#include "features/s390-vx-linux64.c"
#include "features/s390-tevx-linux64.c"
#include "features/s390-gs-linux64.c"
-#include "features/s390x-linux64.c"
#include "features/s390x-linux64v1.c"
#include "features/s390x-linux64v2.c"
#include "features/s390x-te-linux64.c"
#define XML_SYSCALL_FILENAME_S390 "syscalls/s390-linux.xml"
#define XML_SYSCALL_FILENAME_S390X "syscalls/s390x-linux.xml"
+
+/* Register handling. */
+
+/* Implement cannot_store_register gdbarch method. */
+
static int
s390_cannot_store_register (struct gdbarch *gdbarch, int regnum)
{
return regnum == S390_LAST_BREAK_REGNUM;
}
+/* Implement write_pc gdbarch method. */
+
static void
s390_write_pc (struct regcache *regcache, CORE_ADDR pc)
{
{ 0 }
};
-
/* Supply the TDB regset. Like regcache_supply_regset, but invalidate
the TDB registers unless the TDB format field is valid. */
const int gregset_size = (tdep->abi == ABI_LINUX_S390 ?
s390_sizeof_gregset : s390x_sizeof_gregset);
- cb (".reg", gregset_size, &s390_gregset, NULL, cb_data);
- cb (".reg2", s390_sizeof_fpregset, &s390_fpregset, NULL, cb_data);
+ cb (".reg", gregset_size, gregset_size, &s390_gregset, NULL, cb_data);
+ cb (".reg2", s390_sizeof_fpregset, s390_sizeof_fpregset, &s390_fpregset, NULL,
+ cb_data);
if (tdep->abi == ABI_LINUX_S390 && tdep->gpr_full_regnum != -1)
- cb (".reg-s390-high-gprs", 16 * 4, &s390_upper_regset,
+ cb (".reg-s390-high-gprs", 16 * 4, 16 * 4, &s390_upper_regset,
"s390 GPR upper halves", cb_data);
if (tdep->have_linux_v1)
- cb (".reg-s390-last-break", 8,
+ cb (".reg-s390-last-break", 8, 8,
(gdbarch_ptr_bit (gdbarch) == 32
? &s390_last_break_regset : &s390x_last_break_regset),
"s390 last-break address", cb_data);
if (tdep->have_linux_v2)
- cb (".reg-s390-system-call", 4, &s390_system_call_regset,
+ cb (".reg-s390-system-call", 4, 4, &s390_system_call_regset,
"s390 system-call", cb_data);
/* If regcache is set, we are in "write" (gcore) mode. In this
available. */
if (tdep->have_tdb
&& (regcache == NULL
- || REG_VALID == regcache_register_status (regcache,
- S390_TDB_DWORD0_REGNUM)))
- cb (".reg-s390-tdb", s390_sizeof_tdbregset, &s390_tdb_regset,
- "s390 TDB", cb_data);
+ || (REG_VALID
+ == regcache->get_register_status (S390_TDB_DWORD0_REGNUM))))
+ cb (".reg-s390-tdb", s390_sizeof_tdbregset, s390_sizeof_tdbregset,
+ &s390_tdb_regset, "s390 TDB", cb_data);
if (tdep->v0_full_regnum != -1)
{
- cb (".reg-s390-vxrs-low", 16 * 8, &s390_vxrs_low_regset,
+ cb (".reg-s390-vxrs-low", 16 * 8, 16 * 8, &s390_vxrs_low_regset,
"s390 vector registers 0-15 lower half", cb_data);
- cb (".reg-s390-vxrs-high", 16 * 16, &s390_vxrs_high_regset,
+ cb (".reg-s390-vxrs-high", 16 * 16, 16 * 16, &s390_vxrs_high_regset,
"s390 vector registers 16-31", cb_data);
}
if (tdep->have_gs)
{
if (regcache == NULL
- || REG_VALID == regcache_register_status (regcache,
- S390_GSD_REGNUM))
- cb (".reg-s390-gs-cb", 4 * 8, &s390_gs_regset,
+ || REG_VALID == regcache->get_register_status (S390_GSD_REGNUM))
+ cb (".reg-s390-gs-cb", 4 * 8, 4 * 8, &s390_gs_regset,
"s390 guarded-storage registers", cb_data);
if (regcache == NULL
- || REG_VALID == regcache_register_status (regcache,
- S390_BC_GSD_REGNUM))
- cb (".reg-s390-gs-bc", 4 * 8, &s390_gsbc_regset,
+ || REG_VALID == regcache->get_register_status (S390_BC_GSD_REGNUM))
+ cb (".reg-s390-gs-bc", 4 * 8, 4 * 8, &s390_gsbc_regset,
"s390 guarded-storage broadcast control", cb_data);
}
}
+/* Implement core_read_description gdbarch method. */
+
static const struct target_desc *
s390_core_read_description (struct gdbarch *gdbarch,
struct target_ops *target, bfd *abfd)
{
asection *section = bfd_get_section_by_name (abfd, ".reg");
- CORE_ADDR hwcap = 0;
+ CORE_ADDR hwcap = linux_get_hwcap (target);
bool high_gprs, v1, v2, te, vx, gs;
- target_auxv_search (target, AT_HWCAP, &hwcap);
if (!section)
return NULL;
}
}
+/* Frame unwinding. */
+
/* Signal trampoline stack frames. */
struct s390_sigtramp_unwind_cache {
struct trad_frame_saved_reg *saved_regs;
};
+/* Unwind THIS_FRAME and return the corresponding unwind cache for
+ s390_sigtramp_frame_unwind. */
+
static struct s390_sigtramp_unwind_cache *
s390_sigtramp_frame_unwind_cache (struct frame_info *this_frame,
void **this_prologue_cache)
return info;
}
+/* Implement this_id frame_unwind method for s390_sigtramp_frame_unwind. */
+
static void
s390_sigtramp_frame_this_id (struct frame_info *this_frame,
void **this_prologue_cache,
*this_id = frame_id_build (info->frame_base, get_frame_pc (this_frame));
}
+/* Implement prev_register frame_unwind method for sigtramp frames. */
+
static struct value *
s390_sigtramp_frame_prev_register (struct frame_info *this_frame,
void **this_prologue_cache, int regnum)
return s390_trad_frame_prev_register (this_frame, info->saved_regs, regnum);
}
+/* Implement sniffer frame_unwind method for sigtramp frames. */
+
static int
s390_sigtramp_frame_sniffer (const struct frame_unwind *self,
struct frame_info *this_frame,
return 1;
}
+/* S390 sigtramp frame unwinder. */
+
static const struct frame_unwind s390_sigtramp_frame_unwind = {
SIGTRAMP_FRAME,
default_frame_unwind_stop_reason,
s390_sigtramp_frame_sniffer
};
+/* Syscall handling. */
+
/* Retrieve the syscall number at a ptrace syscall-stop. Return -1
upon error. */
static LONGEST
s390_linux_get_syscall_number (struct gdbarch *gdbarch,
- ptid_t ptid)
+ thread_info *thread)
{
- struct regcache *regs = get_thread_regcache (ptid);
+ struct regcache *regs = get_thread_regcache (thread);
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
ULONGEST pc;
return 0;
}
+/* Canonicalize system call SYSCALL belonging to ABI. Helper for
+ s390_linux_syscall_record. */
+
static enum gdb_syscall
s390_canonicalize_syscall (int syscall, enum s390_abi_kind abi)
{
}
}
+/* Record a system call. Returns 0 on success, -1 otherwise.
+ Helper function for s390_process_record. */
+
static int
s390_linux_syscall_record (struct regcache *regcache, LONGEST syscall_native)
{
return 0;
}
+/* Implement process_record_signal gdbarch method. */
+
static int
s390_linux_record_signal (struct gdbarch *gdbarch, struct regcache *regcache,
enum gdb_signal signal)
static void
s390_linux_init_abi_31 (struct gdbarch_info info, struct gdbarch *gdbarch)
{
- const struct target_desc *tdesc = info.target_desc;
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
tdep->abi = ABI_LINUX_S390;
- if (!tdesc_has_registers (tdesc))
- tdesc = tdesc_s390_linux32;
- tdep->tdesc = tdesc;
s390_linux_init_abi_any (info, gdbarch);
static void
s390_linux_init_abi_64 (struct gdbarch_info info, struct gdbarch *gdbarch)
{
- const struct target_desc *tdesc = info.target_desc;
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
tdep->abi = ABI_LINUX_ZSERIES;
- if (!tdesc_has_registers (tdesc))
- tdesc = tdesc_s390x_linux64;
- tdep->tdesc = tdesc;
s390_linux_init_abi_any (info, gdbarch);
s390_linux_init_abi_64);
/* Initialize the GNU/Linux target descriptions. */
- initialize_tdesc_s390_linux32 ();
initialize_tdesc_s390_linux32v1 ();
initialize_tdesc_s390_linux32v2 ();
initialize_tdesc_s390_linux64 ();
initialize_tdesc_s390_vx_linux64 ();
initialize_tdesc_s390_tevx_linux64 ();
initialize_tdesc_s390_gs_linux64 ();
- initialize_tdesc_s390x_linux64 ();
initialize_tdesc_s390x_linux64v1 ();
initialize_tdesc_s390x_linux64v2 ();
initialize_tdesc_s390x_te_linux64 ();