/* Target-dependent code for s390.
- Copyright (C) 2001-2020 Free Software Foundation, Inc.
+ Copyright (C) 2001-2022 Free Software Foundation, Inc.
This file is part of GDB.
#include "target-descriptions.h"
#include "trad-frame.h"
#include "value.h"
+#include "inferior.h"
#include "features/s390-linux32.c"
#include "features/s390x-linux64.c"
return 0;
}
-typedef buf_displaced_step_closure s390_displaced_step_closure;
+typedef buf_displaced_step_copy_insn_closure
+ s390_displaced_step_copy_insn_closure;
/* Implementation of gdbarch_displaced_step_copy_insn. */
-static displaced_step_closure_up
+static displaced_step_copy_insn_closure_up
s390_displaced_step_copy_insn (struct gdbarch *gdbarch,
CORE_ADDR from, CORE_ADDR to,
struct regcache *regs)
{
size_t len = gdbarch_max_insn_length (gdbarch);
- std::unique_ptr<s390_displaced_step_closure> closure
- (new s390_displaced_step_closure (len));
+ std::unique_ptr<s390_displaced_step_copy_insn_closure> closure
+ (new s390_displaced_step_copy_insn_closure (len));
gdb_byte *buf = closure->buf.data ();
read_memory (from, buf, len);
displaced_step_dump_bytes (buf, len).c_str ());
/* This is a work around for a problem with g++ 4.8. */
- return displaced_step_closure_up (closure.release ());
+ return displaced_step_copy_insn_closure_up (closure.release ());
}
/* Fix up the state of registers and memory after having single-stepped
static void
s390_displaced_step_fixup (struct gdbarch *gdbarch,
- struct displaced_step_closure *closure_,
+ displaced_step_copy_insn_closure *closure_,
CORE_ADDR from, CORE_ADDR to,
struct regcache *regs)
{
/* Our closure is a copy of the instruction. */
- s390_displaced_step_closure *closure
- = (s390_displaced_step_closure *) closure_;
+ s390_displaced_step_copy_insn_closure *closure
+ = (s390_displaced_step_copy_insn_closure *) closure_;
gdb_byte *insn = closure->buf.data ();
static int s390_instrlen[] = { 2, 4, 4, 6 };
int insnlen = s390_instrlen[insn[0] >> 6];
we're analyzing the code to unwind past that frame. */
if (pv_is_constant (addr))
{
- struct target_section *secp;
- secp = target_section_by_addr (current_top_target (), addr.k);
+ const struct target_section *secp
+ = target_section_by_addr (current_inferior ()->top_target (), addr.k);
if (secp != NULL
&& (bfd_section_flags (secp->the_bfd_section) & SEC_READONLY))
return pv_constant (read_memory_integer (addr.k, size,
static int
s390_register_call_saved (struct gdbarch *gdbarch, int regnum)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ s390_gdbarch_tdep *tdep = (s390_gdbarch_tdep *) gdbarch_tdep (gdbarch);
switch (tdep->abi)
{
struct regcache *regcache,
CORE_ADDR addr)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ s390_gdbarch_tdep *tdep = (s390_gdbarch_tdep *) gdbarch_tdep (gdbarch);
int sz = register_size (gdbarch, S390_PSWA_REGNUM);
gdb_byte *reg = (gdb_byte *) alloca (sz);
ULONGEST pswm, pswa;
static int
s390_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ s390_gdbarch_tdep *tdep = (s390_gdbarch_tdep *) gdbarch_tdep (gdbarch);
int gdb_reg = -1;
/* In a 32-on-64 debug scenario, debug info refers to the full
These pseudo-registers are composed of two adjacent gprs. */
static int
-regnum_is_gpr_full (struct gdbarch_tdep *tdep, int regnum)
+regnum_is_gpr_full (s390_gdbarch_tdep *tdep, int regnum)
{
return (tdep->gpr_full_regnum != -1
&& regnum >= tdep->gpr_full_regnum
These pseudo-registers are composed of f0-f15 and v0l-v15l. */
static int
-regnum_is_vxr_full (struct gdbarch_tdep *tdep, int regnum)
+regnum_is_vxr_full (s390_gdbarch_tdep *tdep, int regnum)
{
return (tdep->v0_full_regnum != -1
&& regnum >= tdep->v0_full_regnum
s390_value_from_register (struct gdbarch *gdbarch, struct type *type,
int regnum, struct frame_id frame_id)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ s390_gdbarch_tdep *tdep = (s390_gdbarch_tdep *) gdbarch_tdep (gdbarch);
struct value *value = default_value_from_register (gdbarch, type,
regnum, frame_id);
check_typedef (type);
static const char *
s390_pseudo_register_name (struct gdbarch *gdbarch, int regnum)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ s390_gdbarch_tdep *tdep = (s390_gdbarch_tdep *) gdbarch_tdep (gdbarch);
if (regnum == tdep->pc_regnum)
return "pc";
static struct type *
s390_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ s390_gdbarch_tdep *tdep = (s390_gdbarch_tdep *) gdbarch_tdep (gdbarch);
if (regnum == tdep->pc_regnum)
return builtin_type (gdbarch)->builtin_func_ptr;
s390_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache,
int regnum, gdb_byte *buf)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ s390_gdbarch_tdep *tdep = (s390_gdbarch_tdep *) gdbarch_tdep (gdbarch);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
int regsize = register_size (gdbarch, regnum);
ULONGEST val;
s390_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
int regnum, const gdb_byte *buf)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ s390_gdbarch_tdep *tdep = (s390_gdbarch_tdep *) gdbarch_tdep (gdbarch);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
int regsize = register_size (gdbarch, regnum);
ULONGEST val, psw;
s390_pseudo_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
struct reggroup *group)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ s390_gdbarch_tdep *tdep = (s390_gdbarch_tdep *) gdbarch_tdep (gdbarch);
/* We usually save/restore the whole PSW, which includes PC and CC.
However, some older gdbservers may not support saving/restoring
s390_ax_pseudo_register_collect (struct gdbarch *gdbarch,
struct agent_expr *ax, int regnum)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ s390_gdbarch_tdep *tdep = (s390_gdbarch_tdep *) gdbarch_tdep (gdbarch);
if (regnum == tdep->pc_regnum)
{
ax_reg_mask (ax, S390_PSWA_REGNUM);
s390_ax_pseudo_register_push_stack (struct gdbarch *gdbarch,
struct agent_expr *ax, int regnum)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ s390_gdbarch_tdep *tdep = (s390_gdbarch_tdep *) gdbarch_tdep (gdbarch);
if (regnum == tdep->pc_regnum)
{
ax_reg (ax, S390_PSWA_REGNUM);
static void
s390_handle_arg (struct s390_arg_state *as, struct value *arg,
- struct gdbarch_tdep *tdep, int word_size,
+ s390_gdbarch_tdep *tdep, int word_size,
enum bfd_endian byte_order, int is_unnamed)
{
struct type *type = check_typedef (value_type (arg));
it occupies the leftmost bits. */
if (write_mode)
as->regcache->cooked_write_part (S390_F0_REGNUM + as->fr, 0, length,
- value_contents (arg));
+ value_contents (arg).data ());
as->fr += 2;
}
else
it occupies the rightmost bits. */
as->argp = align_up (as->argp + length, word_size);
if (write_mode)
- write_memory (as->argp - length, value_contents (arg),
+ write_memory (as->argp - length, value_contents (arg).data (),
length);
}
}
if (write_mode)
as->regcache->cooked_write_part (regnum, 0, length,
- value_contents (arg));
+ value_contents (arg).data ());
as->vr++;
}
else
{
if (write_mode)
- write_memory (as->argp, value_contents (arg), length);
+ write_memory (as->argp, value_contents (arg).data (), length);
as->argp = align_up (as->argp + length, word_size);
}
}
memory word and sign- or zero-extend to full word size.
This also applies to a struct or union. */
val = type->is_unsigned ()
- ? extract_unsigned_integer (value_contents (arg),
+ ? extract_unsigned_integer (value_contents (arg).data (),
length, byte_order)
- : extract_signed_integer (value_contents (arg),
+ : extract_signed_integer (value_contents (arg).data (),
length, byte_order);
}
if (write_mode)
{
as->regcache->cooked_write (S390_R0_REGNUM + as->gr,
- value_contents (arg));
- as->regcache->cooked_write (S390_R0_REGNUM + as->gr + 1,
- value_contents (arg) + word_size);
+ value_contents (arg).data ());
+ as->regcache->cooked_write
+ (S390_R0_REGNUM + as->gr + 1,
+ value_contents (arg).data () + word_size);
}
as->gr += 2;
}
as->gr = 7;
if (write_mode)
- write_memory (as->argp, value_contents (arg), length);
+ write_memory (as->argp, value_contents (arg).data (), length);
as->argp += length;
}
}
alignment as a conservative assumption. */
as->copy = align_down (as->copy - length, 8);
if (write_mode)
- write_memory (as->copy, value_contents (arg), length);
+ write_memory (as->copy, value_contents (arg).data (), length);
if (as->gr <= 6)
{
function_call_return_method return_method,
CORE_ADDR struct_addr)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ s390_gdbarch_tdep *tdep = (s390_gdbarch_tdep *) gdbarch_tdep (gdbarch);
int word_size = gdbarch_ptr_bit (gdbarch) / 8;
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
int i;
rvc = RETURN_VALUE_STRUCT_CONVENTION;
break;
case TYPE_CODE_ARRAY:
- rvc = (gdbarch_tdep (gdbarch)->vector_abi == S390_VECTOR_ABI_128
- && TYPE_LENGTH (type) <= 16 && type->is_vector ())
- ? RETURN_VALUE_REGISTER_CONVENTION
- : RETURN_VALUE_STRUCT_CONVENTION;
- break;
+ {
+ s390_gdbarch_tdep *tdep = (s390_gdbarch_tdep *) gdbarch_tdep (gdbarch);
+ rvc = (tdep->vector_abi == S390_VECTOR_ABI_128
+ && TYPE_LENGTH (type) <= 16 && type->is_vector ())
+ ? RETURN_VALUE_REGISTER_CONVENTION
+ : RETURN_VALUE_STRUCT_CONVENTION;
+ break;
+ }
default:
rvc = TYPE_LENGTH (type) <= 8
? RETURN_VALUE_REGISTER_CONVENTION
static CORE_ADDR
s390_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ s390_gdbarch_tdep *tdep = (s390_gdbarch_tdep *) gdbarch_tdep (gdbarch);
ULONGEST pc;
pc = frame_unwind_register_unsigned (next_frame, tdep->pc_regnum);
return gdbarch_addr_bits_remove (gdbarch, pc);
s390_unwind_pseudo_register (struct frame_info *this_frame, int regnum)
{
struct gdbarch *gdbarch = get_frame_arch (this_frame);
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ s390_gdbarch_tdep *tdep = (s390_gdbarch_tdep *) gdbarch_tdep (gdbarch);
struct type *type = register_type (gdbarch, regnum);
/* Unwind PC via PSW address. */
struct value *
s390_trad_frame_prev_register (struct frame_info *this_frame,
- struct trad_frame_saved_reg saved_regs[],
+ trad_frame_saved_reg saved_regs[],
int regnum)
{
if (regnum < S390_NUM_REGS)
CORE_ADDR frame_base;
CORE_ADDR local_base;
- struct trad_frame_saved_reg *saved_regs;
+ trad_frame_saved_reg *saved_regs;
};
/* Unwind THIS_FRAME and write the information into unwind cache INFO using
/* Set up ABI call-saved/call-clobbered registers. */
for (i = 0; i < S390_NUM_REGS; i++)
if (!s390_register_call_saved (gdbarch, i))
- trad_frame_set_unknown (info->saved_regs, i);
+ info->saved_regs[i].set_unknown ();
/* CC is always call-clobbered. */
- trad_frame_set_unknown (info->saved_regs, S390_PSWM_REGNUM);
+ info->saved_regs[S390_PSWM_REGNUM].set_unknown ();
/* Record the addresses of all register spill slots the prologue parser
has recognized. Consider only registers defined as call-saved by the
for (i = 0; i < 16; i++)
if (s390_register_call_saved (gdbarch, S390_R0_REGNUM + i)
&& data.gpr_slot[i] != 0)
- info->saved_regs[S390_R0_REGNUM + i].addr = cfa - data.gpr_slot[i];
+ info->saved_regs[S390_R0_REGNUM + i].set_addr (cfa - data.gpr_slot[i]);
for (i = 0; i < 16; i++)
if (s390_register_call_saved (gdbarch, S390_F0_REGNUM + i)
&& data.fpr_slot[i] != 0)
- info->saved_regs[S390_F0_REGNUM + i].addr = cfa - data.fpr_slot[i];
+ info->saved_regs[S390_F0_REGNUM + i].set_addr (cfa - data.fpr_slot[i]);
/* Function return will set PC to %r14. */
info->saved_regs[S390_PSWA_REGNUM] = info->saved_regs[S390_RETADDR_REGNUM];
save area, use that -- we might only think the function frameless
because we're in the middle of the prologue ... */
if (size == 0
- && !trad_frame_addr_p (info->saved_regs, S390_PSWA_REGNUM))
+ && !info->saved_regs[S390_PSWA_REGNUM].is_addr ())
{
- info->saved_regs[S390_PSWA_REGNUM].realreg = S390_RETADDR_REGNUM;
+ info->saved_regs[S390_PSWA_REGNUM].set_realreg (S390_RETADDR_REGNUM);
}
/* Another sanity check: unless this is a frameless function,
libc's thread_start routine. */
if (size > 0)
{
- if (!trad_frame_addr_p (info->saved_regs, S390_SP_REGNUM)
- || !trad_frame_addr_p (info->saved_regs, S390_PSWA_REGNUM))
+ if (!info->saved_regs[S390_SP_REGNUM].is_addr ()
+ || !info->saved_regs[S390_PSWA_REGNUM].is_addr ())
prev_sp = -1;
}
/* Set up ABI call-saved/call-clobbered registers. */
for (i = 0; i < S390_NUM_REGS; i++)
if (!s390_register_call_saved (gdbarch, i))
- trad_frame_set_unknown (info->saved_regs, i);
+ info->saved_regs[i].set_unknown ();
/* CC is always call-clobbered. */
- trad_frame_set_unknown (info->saved_regs, S390_PSWM_REGNUM);
+ info->saved_regs[S390_PSWM_REGNUM].set_unknown ();
/* Get the backchain. */
reg = get_frame_register_unsigned (this_frame, S390_SP_REGNUM);
/* We don't know which registers were saved, but it will have
to be at least %r14 and %r15. This will allow us to continue
unwinding, but other prev-frame registers may be incorrect ... */
- info->saved_regs[S390_SP_REGNUM].addr = backchain + 15*word_size;
- info->saved_regs[S390_RETADDR_REGNUM].addr = backchain + 14*word_size;
+ info->saved_regs[S390_SP_REGNUM].set_addr (backchain + 15*word_size);
+ info->saved_regs[S390_RETADDR_REGNUM].set_addr (backchain + 14*word_size);
/* Function return will set PC to %r14. */
info->saved_regs[S390_PSWA_REGNUM]
/* Default S390 frame unwinder. */
static const struct frame_unwind s390_frame_unwind = {
+ "s390 prologue",
NORMAL_FRAME,
default_frame_unwind_stop_reason,
s390_frame_this_id,
struct s390_stub_unwind_cache
{
CORE_ADDR frame_base;
- struct trad_frame_saved_reg *saved_regs;
+ trad_frame_saved_reg *saved_regs;
};
/* Unwind THIS_FRAME and return the corresponding unwind cache for
info->saved_regs = trad_frame_alloc_saved_regs (this_frame);
/* The return address is in register %r14. */
- info->saved_regs[S390_PSWA_REGNUM].realreg = S390_RETADDR_REGNUM;
+ info->saved_regs[S390_PSWA_REGNUM].set_realreg (S390_RETADDR_REGNUM);
/* Retrieve stack pointer and determine our frame base. */
reg = get_frame_register_unsigned (this_frame, S390_SP_REGNUM);
/* S390 stub frame unwinder. */
static const struct frame_unwind s390_stub_frame_unwind = {
+ "s390 stub",
NORMAL_FRAME,
default_frame_unwind_stop_reason,
s390_stub_frame_this_id,
s390_record_address_mask (struct gdbarch *gdbarch, struct regcache *regcache,
CORE_ADDR val)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ s390_gdbarch_tdep *tdep = (s390_gdbarch_tdep *) gdbarch_tdep (gdbarch);
ULONGEST pswm, pswa;
int am;
if (tdep->abi == ABI_LINUX_S390)
uint8_t vx, uint8_t el, uint8_t es, uint16_t bd,
int8_t dh, CORE_ADDR *res)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ s390_gdbarch_tdep *tdep = (s390_gdbarch_tdep *) gdbarch_tdep (gdbarch);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
ULONGEST x;
gdb_byte buf[16];
static int
s390_record_gpr_g (struct gdbarch *gdbarch, struct regcache *regcache, int i)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ s390_gdbarch_tdep *tdep = (s390_gdbarch_tdep *) gdbarch_tdep (gdbarch);
if (record_full_arch_list_add_reg (regcache, S390_R0_REGNUM + i))
return -1;
if (tdep->abi == ABI_LINUX_S390)
static int
s390_record_gpr_h (struct gdbarch *gdbarch, struct regcache *regcache, int i)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ s390_gdbarch_tdep *tdep = (s390_gdbarch_tdep *) gdbarch_tdep (gdbarch);
if (tdep->abi == ABI_LINUX_S390)
{
if (record_full_arch_list_add_reg (regcache, S390_R0_UPPER_REGNUM + i))
s390_process_record (struct gdbarch *gdbarch, struct regcache *regcache,
CORE_ADDR addr)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ s390_gdbarch_tdep *tdep = (s390_gdbarch_tdep *) gdbarch_tdep (gdbarch);
uint16_t insn[3] = {0};
/* Instruction as bytes. */
uint8_t ibyte[6];
}
else
{
- printf_unfiltered (_("no syscall record support\n"));
+ fprintf_unfiltered (gdb_stderr, _("no syscall record support\n"));
return -1;
}
break;
tdesc. */
static bool
-s390_tdesc_valid (struct gdbarch_tdep *tdep,
+s390_tdesc_valid (s390_gdbarch_tdep *tdep,
struct tdesc_arch_data *tdesc_data)
{
static const char *const psw[] = {
/* Allocate and initialize new gdbarch_tdep. Caller is responsible to free
memory after use. */
-static struct gdbarch_tdep *
+static s390_gdbarch_tdep *
s390_gdbarch_tdep_alloc ()
{
- struct gdbarch_tdep *tdep = XCNEW (struct gdbarch_tdep);
+ s390_gdbarch_tdep *tdep = new s390_gdbarch_tdep;
tdep->tdesc = NULL;
static const char *const stap_register_indirection_suffixes[] = { ")",
NULL };
- struct gdbarch_tdep *tdep = s390_gdbarch_tdep_alloc ();
+ s390_gdbarch_tdep *tdep = s390_gdbarch_tdep_alloc ();
struct gdbarch *gdbarch = gdbarch_alloc (&info, tdep);
tdesc_arch_data_up tdesc_data = tdesc_data_alloc ();
info.tdesc_data = tdesc_data.get ();
set_gdbarch_displaced_step_copy_insn (gdbarch,
s390_displaced_step_copy_insn);
set_gdbarch_displaced_step_fixup (gdbarch, s390_displaced_step_fixup);
- set_gdbarch_displaced_step_location (gdbarch, linux_displaced_step_location);
set_gdbarch_displaced_step_hw_singlestep (gdbarch, s390_displaced_step_hw_singlestep);
set_gdbarch_software_single_step (gdbarch, s390_software_single_step);
set_gdbarch_max_insn_length (gdbarch, S390_MAX_INSTR_SIZE);
cause GDB to crash with an internal error when the user tries to set
an unsupported OSABI. */
if (!tdesc_has_registers (tdesc))
- {
- if (info.bfd_arch_info->mach == bfd_mach_s390_31)
- tdesc = tdesc_s390_linux32;
- else
- tdesc = tdesc_s390x_linux64;
- }
+ {
+ if (info.bfd_arch_info->mach == bfd_mach_s390_31)
+ tdesc = tdesc_s390_linux32;
+ else
+ tdesc = tdesc_s390x_linux64;
+ }
tdep->tdesc = tdesc;
/* Check any target description for validity. */
if (!s390_tdesc_valid (tdep, tdesc_data.get ()))
{
- xfree (tdep);
+ delete tdep;
gdbarch_free (gdbarch);
return NULL;
}
arches != NULL;
arches = gdbarch_list_lookup_by_info (arches->next, &info))
{
- struct gdbarch_tdep *tmp = gdbarch_tdep (arches->gdbarch);
+ s390_gdbarch_tdep *tmp
+ = (s390_gdbarch_tdep *) gdbarch_tdep (arches->gdbarch);
+
if (!tmp)
continue;
+
/* A program can 'choose' not to use the vector registers when they
are present. Leading to the same tdesc but different tdep and
thereby a different gdbarch. */
if (tmp->vector_abi != tdep->vector_abi)
continue;
- xfree (tdep);
+ delete tdep;
gdbarch_free (gdbarch);
return arches->gdbarch;
}