/* Target-dependent code for GDB, the GNU debugger.
- Copyright 2001 Free Software Foundation, Inc.
+
+ Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
+
Contributed by D.J. Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
for IBM Deutschland Entwicklung GmbH, IBM Corporation.
#include "floatformat.h"
#include "regcache.h"
#include "value.h"
-
+#include "gdb_assert.h"
/* Number of bytes of storage in the actual machine representation
- for register N.
- Note that the unsigned cast here forces the result of the
- subtraction to very high positive values if N < S390_FP0_REGNUM */
+ for register N. */
int
s390_register_raw_size (int reg_nr)
{
- return ((unsigned) reg_nr - S390_FP0_REGNUM) <
- S390_NUM_FPRS ? S390_FPR_SIZE : 4;
+ if (S390_FP0_REGNUM <= reg_nr
+ && reg_nr < S390_FP0_REGNUM + S390_NUM_FPRS)
+ return S390_FPR_SIZE;
+ else
+ return 4;
}
int
if ((*info->read_memory_func) (at, &instr[0], 2, info))
return -1;
instrlen = s390_instrlen[instr[0] >> 6];
- if ((*info->read_memory_func) (at + 2, &instr[2], instrlen - 2, info))
- return -1;
+ if (instrlen > 2)
+ {
+ if ((*info->read_memory_func) (at + 2, &instr[2], instrlen - 2, info))
+ return -1;
+ }
return instrlen;
}
-char *
+const char *
s390_register_name (int reg_nr)
{
static char *register_names[] = {
"pswm", "pswa",
- "gpr0", "gpr1", "gpr2", "gpr3", "gpr4", "gpr5", "gpr6", "gpr7",
- "gpr8", "gpr9", "gpr10", "gpr11", "gpr12", "gpr13", "gpr14", "gpr15",
+ "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",
- "fpr0", "fpr1", "fpr2", "fpr3", "fpr4", "fpr5", "fpr6", "fpr7",
- "fpr8", "fpr9", "fpr10", "fpr11", "fpr12", "fpr13", "fpr14", "fpr15"
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
+ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15"
};
- if (reg_nr >= S390_LAST_REGNUM)
+ if (reg_nr <= S390_LAST_REGNUM)
+ return register_names[reg_nr];
+ else
return NULL;
- return register_names[reg_nr];
}
}
+/* Return true if REGIDX is the number of a register used to pass
+ arguments, false otherwise. */
+static int
+is_arg_reg (int regidx)
+{
+ return 2 <= regidx && regidx <= 6;
+}
+
/* s390_get_frame_info based on Hartmuts
prologue definition in
int gprs_saved[S390_NUM_GPRS];
int fprs_saved[S390_NUM_FPRS];
int regidx, instrlen;
- int save_link_regidx, subtract_sp_regidx;
- int const_pool_state, save_link_state, got_state;
- int frame_pointer_found, varargs_state;
+ int const_pool_state;
+ int varargs_state;
int loop_cnt, gdb_gpr_store, gdb_fpr_store;
- int frame_pointer_regidx = 0xf;
int offset, expected_offset;
int err = 0;
disassemble_info info;
- const_pool_state = save_link_state = got_state = varargs_state = 0;
- frame_pointer_found = 0;
+
+ /* Have we seen an instruction initializing the frame pointer yet?
+ If we've seen an `lr %r11, %r15', then frame_pointer_found is
+ non-zero, and frame_pointer_regidx == 11. Otherwise,
+ frame_pointer_found is zero and frame_pointer_regidx is 15,
+ indicating that we're using the stack pointer as our frame
+ pointer. */
+ int frame_pointer_found = 0;
+ int frame_pointer_regidx = 0xf;
+
+ /* What we've seen so far regarding saving the back chain link:
+ 0 -- nothing yet; sp still has the same value it had at the entry
+ point. Since not all functions allocate frames, this is a
+ valid state for the prologue to finish in.
+ 1 -- We've saved the original sp in some register other than the
+ frame pointer (hard-coded to be %r11, yuck).
+ save_link_regidx is the register we saved it in.
+ 2 -- We've seen the initial `bras' instruction of the sequence for
+ reserving more than 32k of stack:
+ bras %rX, .+8
+ .long N
+ s %r15, 0(%rX)
+ where %rX is not the constant pool register.
+ subtract_sp_regidx is %rX, and fextra_info->stack_bought is N.
+ 3 -- We've reserved space for a new stack frame. This means we
+ either saw a simple `ahi %r15,-N' in state 1, or the final
+ `s %r15, ...' in state 2.
+ 4 -- The frame and link are now fully initialized. We've
+ reserved space for the new stack frame, and stored the old
+ stack pointer captured in the back chain pointer field. */
+ int save_link_state = 0;
+ int save_link_regidx, subtract_sp_regidx;
+
+ /* What we've seen so far regarding r12 --- the GOT (Global Offset
+ Table) pointer. We expect to see `l %r12, N(%r13)', which loads
+ r12 with the offset from the constant pool to the GOT, and then
+ an `ar %r12, %r13', which adds the constant pool address,
+ yielding the GOT's address. Here's what got_state means:
+ 0 -- seen nothing
+ 1 -- seen `l %r12, N(%r13)', but no `ar'
+ 2 -- seen load and add, so GOT pointer is totally initialized
+ When got_state is 1, then got_load_addr is the address of the
+ load instruction, and got_load_len is the length of that
+ instruction. */
+ int got_state= 0;
+ CORE_ADDR got_load_addr = 0, got_load_len = 0;
+
+ const_pool_state = varargs_state = 0;
+
memset (gprs_saved, 0, sizeof (gprs_saved));
memset (fprs_saved, 0, sizeof (fprs_saved));
- info.read_memory_func = dis_asm_read_memory;
+ info.read_memory_func = deprecated_tm_print_insn_info.read_memory_func;
save_link_regidx = subtract_sp_regidx = 0;
if (fextra_info)
{
- if (fi && fi->frame)
+ if (fi && get_frame_base (fi))
{
- orig_sp = fi->frame + fextra_info->stack_bought;
- saved_regs = fi->saved_regs;
+ orig_sp = get_frame_base (fi);
+ if (! init_extra_info && fextra_info->initialised)
+ orig_sp += fextra_info->stack_bought;
+ saved_regs = get_frame_saved_regs (fi);
}
if (init_extra_info || !fextra_info->initialised)
{
if (instr[0] == S390_SYSCALL_OPCODE && test_pc == pc)
{
good_prologue = 1;
- if (saved_regs && fextra_info && fi->next && fi->next->extra_info
- && fi->next->extra_info->sigcontext)
+ if (saved_regs && fextra_info && get_next_frame (fi)
+ && get_frame_extra_info (get_next_frame (fi))
+ && get_frame_extra_info (get_next_frame (fi))->sigcontext)
{
/* We are backtracing from a signal handler */
- save_reg_addr = fi->next->extra_info->sigcontext +
+ save_reg_addr = get_frame_extra_info (get_next_frame (fi))->sigcontext +
REGISTER_BYTE (S390_GP0_REGNUM);
for (regidx = 0; regidx < S390_NUM_GPRS; regidx++)
{
saved_regs[S390_GP0_REGNUM + regidx] = save_reg_addr;
save_reg_addr += S390_GPR_SIZE;
}
- save_reg_addr = fi->next->extra_info->sigcontext +
+ save_reg_addr = get_frame_extra_info (get_next_frame (fi))->sigcontext +
(GDB_TARGET_IS_ESAME ? S390X_SIGREGS_FP0_OFFSET :
S390_SIGREGS_FP0_OFFSET);
for (regidx = 0; regidx < S390_NUM_FPRS; regidx++)
continue;
}
+ /* Check for an fp-relative STG, ST, or STM. This is probably
+ spilling an argument from a register out into a stack slot.
+ This could be a user instruction, but if we haven't included
+ any other suspicious instructions in the prologue, this
+ could only be an initializing store, which isn't too bad to
+ skip. The consequences of not including arg-to-stack spills
+ are more serious, though --- you don't see the proper values
+ of the arguments. */
+ if ((save_link_state == 3 || save_link_state == 4)
+ && ((instr[0] == 0x50 /* st %rA, D(%rX,%rB) */
+ && (instr[1] & 0xf) == 0 /* %rX is zero, no index reg */
+ && is_arg_reg ((instr[1] >> 4) & 0xf)
+ && ((instr[2] >> 4) & 0xf) == frame_pointer_regidx)
+ || (instr[0] == 0x90 /* stm %rA, %rB, D(%rC) */
+ && is_arg_reg ((instr[1] >> 4) & 0xf)
+ && is_arg_reg (instr[1] & 0xf)
+ && ((instr[2] >> 4) & 0xf) == frame_pointer_regidx)))
+ {
+ valid_prologue = 1;
+ continue;
+ }
+
/* check for STD */
if (instr[0] == 0x60 && (instr[2] >> 4) == 0xf)
{
/* Alternatively check for the complex construction for
buying more than 32k of stack
BRAS gprx,.+8
- long vals %r15,0(%gprx) gprx currently r1 */
+ long val
+ s %r15,0(%gprx) gprx currently r1 */
if ((save_link_state == 1) && (instr[0] == 0xa7)
&& ((instr[1] & 0xf) == 0x5) && (instr[2] == 0)
&& (instr[3] == 0x4) && ((instr[1] >> 4) != CONST_POOL_REGIDX))
&& (instr[2] == (CONST_POOL_REGIDX << 4))
&& ((instr[1] >> 4) == GOT_REGIDX))
{
- got_state == 1;
+ got_state = 1;
+ got_load_addr = test_pc;
+ got_load_len = instrlen;
valid_prologue = 1;
continue;
}
while (valid_prologue && good_prologue);
if (good_prologue)
{
- good_prologue = (((got_state == 0) || (got_state == 2)) &&
- ((const_pool_state == 0) || (const_pool_state == 2)) &&
+ /* If this function doesn't reference the global offset table,
+ then the compiler may use r12 for other things. If the last
+ instruction we saw was a load of r12 from the constant pool,
+ with no subsequent add to make the address PC-relative, then
+ the load was probably a genuine body instruction; don't treat
+ it as part of the prologue. */
+ if (got_state == 1
+ && got_load_addr + got_load_len == test_pc)
+ {
+ test_pc = got_load_addr;
+ instrlen = got_load_len;
+ }
+
+ good_prologue = (((const_pool_state == 0) || (const_pool_state == 2)) &&
((save_link_state == 0) || (save_link_state == 4)) &&
((varargs_state == 0) || (varargs_state == 2)));
}
fextra_info->skip_prologue_function_start =
(good_prologue ? test_pc : pc);
}
+ if (saved_regs)
+ /* The SP's element of the saved_regs array holds the old SP,
+ not the address at which it is saved. */
+ saved_regs[S390_SP_REGNUM] = orig_sp;
return err;
}
disassemble_info info;
int regidx, instrlen;
- info.read_memory_func = dis_asm_read_memory;
+ info.read_memory_func = deprecated_tm_print_insn_info.read_memory_func;
instrlen = s390_readinstruction (instr, pc, &info);
if (instrlen < 0)
return -1;
{
CORE_ADDR function_start = 0;
- if (fi->extra_info && fi->extra_info->initialised)
- function_start = fi->extra_info->function_start;
- else if (fi->pc)
- function_start = get_pc_function_start (fi->pc);
+ if (get_frame_extra_info (fi) && get_frame_extra_info (fi)->initialised)
+ function_start = get_frame_extra_info (fi)->function_start;
+ else if (get_frame_pc (fi))
+ function_start = get_frame_func (fi);
return function_start;
}
struct frame_extra_info fextra_info, *fextra_info_ptr;
int frameless = 0;
- if (fi->next == NULL) /* no may be frameless */
+ if (get_next_frame (fi) == NULL) /* no may be frameless */
{
- if (fi->extra_info)
- fextra_info_ptr = fi->extra_info;
+ if (get_frame_extra_info (fi))
+ fextra_info_ptr = get_frame_extra_info (fi);
else
{
fextra_info_ptr = &fextra_info;
- s390_get_frame_info (s390_sniff_pc_function_start (fi->pc, fi),
+ s390_get_frame_info (s390_sniff_pc_function_start (get_frame_pc (fi), fi),
fextra_info_ptr, fi, 1);
}
frameless = ((fextra_info_ptr->stack_bought == 0));
scontext = temp_sregs = 0;
- info.read_memory_func = dis_asm_read_memory;
+ info.read_memory_func = deprecated_tm_print_insn_info.read_memory_func;
instrlen = s390_readinstruction (instr, pc, &info);
if (sigcaller_pc)
*sigcaller_pc = 0;
if (sighandler_fi)
{
if (s390_frameless_function_invocation (sighandler_fi))
- orig_sp = sighandler_fi->frame;
+ orig_sp = get_frame_base (sighandler_fi);
else
orig_sp = ADDR_BITS_REMOVE ((CORE_ADDR)
- read_memory_integer (sighandler_fi->
- frame,
+ read_memory_integer (get_frame_base (sighandler_fi),
S390_GPR_SIZE));
if (orig_sp && sigcaller_pc)
{
for the moment.
For some reason the blockframe.c calls us with fi->next->fromleaf
so this seems of little use to us. */
-void
+CORE_ADDR
s390_init_frame_pc_first (int next_fromleaf, struct frame_info *fi)
{
CORE_ADDR sigcaller_pc;
-
- fi->pc = 0;
+ CORE_ADDR pc = 0;
if (next_fromleaf)
{
- fi->pc = ADDR_BITS_REMOVE (read_register (S390_RETADDR_REGNUM));
+ pc = ADDR_BITS_REMOVE (read_register (S390_RETADDR_REGNUM));
/* fix signal handlers */
}
- else if (fi->next && fi->next->pc)
- fi->pc = s390_frame_saved_pc_nofix (fi->next);
- if (fi->pc && fi->next && fi->next->frame &&
- s390_is_sigreturn (fi->pc, fi->next, NULL, &sigcaller_pc))
+ else if (get_next_frame (fi) && get_frame_pc (get_next_frame (fi)))
+ pc = s390_frame_saved_pc_nofix (get_next_frame (fi));
+ if (pc && get_next_frame (fi) && get_frame_base (get_next_frame (fi))
+ && s390_is_sigreturn (pc, get_next_frame (fi), NULL, &sigcaller_pc))
{
- fi->pc = sigcaller_pc;
+ pc = sigcaller_pc;
}
-
+ return pc;
}
void
s390_init_extra_frame_info (int fromleaf, struct frame_info *fi)
{
- fi->extra_info = frame_obstack_alloc (sizeof (struct frame_extra_info));
- if (fi->pc)
- s390_get_frame_info (s390_sniff_pc_function_start (fi->pc, fi),
- fi->extra_info, fi, 1);
+ frame_extra_info_zalloc (fi, sizeof (struct frame_extra_info));
+ if (get_frame_pc (fi))
+ s390_get_frame_info (s390_sniff_pc_function_start (get_frame_pc (fi), fi),
+ get_frame_extra_info (fi), fi, 1);
else
- s390_memset_extra_info (fi->extra_info);
+ s390_memset_extra_info (get_frame_extra_info (fi));
}
/* If saved registers of frame FI are not known yet, read and cache them.
int quick;
- if (fi->saved_regs == NULL)
+ if (get_frame_saved_regs (fi) == NULL)
{
/* zalloc memsets the saved regs */
frame_saved_regs_zalloc (fi);
- if (fi->pc)
+ if (get_frame_pc (fi))
{
- quick = (fi->extra_info && fi->extra_info->initialised
- && fi->extra_info->good_prologue);
- s390_get_frame_info (quick ? fi->extra_info->function_start :
- s390_sniff_pc_function_start (fi->pc, fi),
- fi->extra_info, fi, !quick);
+ quick = (get_frame_extra_info (fi)
+ && get_frame_extra_info (fi)->initialised
+ && get_frame_extra_info (fi)->good_prologue);
+ s390_get_frame_info (quick
+ ? get_frame_extra_info (fi)->function_start
+ : s390_sniff_pc_function_start (get_frame_pc (fi), fi),
+ get_frame_extra_info (fi), fi, !quick);
}
}
}
{
/* Apparently gdb already knows gdb_args_offset itself */
- return fi->frame;
+ return get_frame_base (fi);
}
static CORE_ADDR
s390_frame_saved_pc_nofix (struct frame_info *fi)
{
- if (fi->extra_info && fi->extra_info->saved_pc_valid)
- return fi->extra_info->saved_pc;
+ if (get_frame_extra_info (fi) && get_frame_extra_info (fi)->saved_pc_valid)
+ return get_frame_extra_info (fi)->saved_pc;
+
+ if (deprecated_generic_find_dummy_frame (get_frame_pc (fi),
+ get_frame_base (fi)))
+ return deprecated_read_register_dummy (get_frame_pc (fi),
+ get_frame_base (fi), S390_PC_REGNUM);
+
s390_frame_init_saved_regs (fi);
- if (fi->extra_info)
+ if (get_frame_extra_info (fi))
{
- fi->extra_info->saved_pc_valid = 1;
- if (fi->extra_info->good_prologue)
- {
- if (fi->saved_regs[S390_RETADDR_REGNUM])
- {
- return (fi->extra_info->saved_pc =
- ADDR_BITS_REMOVE (read_memory_integer
- (fi->saved_regs[S390_RETADDR_REGNUM],
- S390_GPR_SIZE)));
- }
- }
+ get_frame_extra_info (fi)->saved_pc_valid = 1;
+ if (get_frame_extra_info (fi)->good_prologue
+ && get_frame_saved_regs (fi)[S390_RETADDR_REGNUM])
+ get_frame_extra_info (fi)->saved_pc
+ = ADDR_BITS_REMOVE (read_memory_integer
+ (get_frame_saved_regs (fi)[S390_RETADDR_REGNUM],
+ S390_GPR_SIZE));
+ else
+ get_frame_extra_info (fi)->saved_pc
+ = ADDR_BITS_REMOVE (read_register (S390_RETADDR_REGNUM));
+ return get_frame_extra_info (fi)->saved_pc;
}
return 0;
}
{
CORE_ADDR saved_pc = 0, sig_pc;
- if (fi->extra_info && fi->extra_info->sig_fixed_saved_pc_valid)
- return fi->extra_info->sig_fixed_saved_pc;
+ if (get_frame_extra_info (fi)
+ && get_frame_extra_info (fi)->sig_fixed_saved_pc_valid)
+ return get_frame_extra_info (fi)->sig_fixed_saved_pc;
saved_pc = s390_frame_saved_pc_nofix (fi);
- if (fi->extra_info)
+ if (get_frame_extra_info (fi))
{
- fi->extra_info->sig_fixed_saved_pc_valid = 1;
+ get_frame_extra_info (fi)->sig_fixed_saved_pc_valid = 1;
if (saved_pc)
{
if (s390_is_sigreturn (saved_pc, fi, NULL, &sig_pc))
saved_pc = sig_pc;
}
- fi->extra_info->sig_fixed_saved_pc = saved_pc;
+ get_frame_extra_info (fi)->sig_fixed_saved_pc = saved_pc;
}
return saved_pc;
}
-/* We want backtraces out of signal handlers so we don't
- set thisframe->signal_handler_caller to 1 */
+/* We want backtraces out of signal handlers so we don't set
+ (get_frame_type (thisframe) == SIGTRAMP_FRAME) to 1 */
CORE_ADDR
s390_frame_chain (struct frame_info *thisframe)
{
CORE_ADDR prev_fp = 0;
- if (thisframe->prev && thisframe->prev->frame)
- prev_fp = thisframe->prev->frame;
+ if (deprecated_generic_find_dummy_frame (get_frame_pc (thisframe),
+ get_frame_base (thisframe)))
+ return deprecated_read_register_dummy (get_frame_pc (thisframe),
+ get_frame_base (thisframe),
+ S390_SP_REGNUM);
else
{
int sigreturn = 0;
struct frame_extra_info prev_fextra_info;
memset (&prev_fextra_info, 0, sizeof (prev_fextra_info));
- if (thisframe->pc)
+ if (get_frame_pc (thisframe))
{
CORE_ADDR saved_pc, sig_pc;
frame_pointer_saved_pc
? 11 : 15)),
S390_GPR_SIZE);
- thisframe->extra_info->sigcontext = sregs;
+ get_frame_extra_info (thisframe)->sigcontext = sregs;
}
else
{
- if (thisframe->saved_regs)
+ if (get_frame_saved_regs (thisframe))
{
-
int regno;
- regno =
- ((prev_fextra_info.frame_pointer_saved_pc
- && thisframe->
- saved_regs[S390_FRAME_REGNUM]) ? S390_FRAME_REGNUM :
- S390_SP_REGNUM);
- if (thisframe->saved_regs[regno])
- prev_fp =
- read_memory_integer (thisframe->saved_regs[regno],
- S390_GPR_SIZE);
+ if (prev_fextra_info.frame_pointer_saved_pc
+ && get_frame_saved_regs (thisframe)[S390_FRAME_REGNUM])
+ regno = S390_FRAME_REGNUM;
+ else
+ regno = S390_SP_REGNUM;
+
+ if (get_frame_saved_regs (thisframe)[regno])
+ {
+ /* The SP's entry of `saved_regs' is special. */
+ if (regno == S390_SP_REGNUM)
+ prev_fp = get_frame_saved_regs (thisframe)[regno];
+ else
+ prev_fp =
+ read_memory_integer (get_frame_saved_regs (thisframe)[regno],
+ S390_GPR_SIZE);
+ }
}
}
}
int len = TYPE_LENGTH (valtype);
if (TYPE_CODE (valtype) == TYPE_CODE_FLT)
- {
- if (len > (TARGET_FLOAT_BIT >> 3))
- memcpy (valbuf, ®buf[REGISTER_BYTE (S390_FP0_REGNUM)], len);
- else
- {
- /* float */
- DOUBLEST val;
-
- floatformat_to_doublest (&floatformat_ieee_double_big,
- ®buf[REGISTER_BYTE (S390_FP0_REGNUM)],
- &val);
- store_floating (valbuf, len, val);
- }
- }
+ memcpy (valbuf, ®buf[REGISTER_BYTE (S390_FP0_REGNUM)], len);
else
{
int offset = 0;
s390_store_return_value (struct type *valtype, char *valbuf)
{
int arglen;
- char *reg_buff = alloca (max (S390_FPR_SIZE, REGISTER_SIZE)), *value;
+ char *reg_buff = alloca (max (S390_FPR_SIZE, DEPRECATED_REGISTER_SIZE)), *value;
if (TYPE_CODE (valtype) == TYPE_CODE_FLT)
{
- DOUBLEST tempfloat = extract_floating (valbuf, TYPE_LENGTH (valtype));
-
- floatformat_from_doublest (&floatformat_ieee_double_big, &tempfloat,
- reg_buff);
- write_register_bytes (REGISTER_BYTE (S390_FP0_REGNUM), reg_buff,
- S390_FPR_SIZE);
+ if (TYPE_LENGTH (valtype) == 4
+ || TYPE_LENGTH (valtype) == 8)
+ deprecated_write_register_bytes (REGISTER_BYTE (S390_FP0_REGNUM),
+ valbuf, TYPE_LENGTH (valtype));
+ else
+ error ("GDB is unable to return `long double' values "
+ "on this architecture.");
}
else
{
value =
s390_promote_integer_argument (valtype, valbuf, reg_buff, &arglen);
/* Everything else is returned in GPR2 and up. */
- write_register_bytes (REGISTER_BYTE (S390_GP0_REGNUM + 2), value,
- arglen);
+ deprecated_write_register_bytes (REGISTER_BYTE (S390_GP0_REGNUM + 2),
+ value, arglen);
}
}
static int
/* Not the most efficent code in the world */
int
-s390_fp_regnum ()
+s390_fp_regnum (void)
{
int regno = S390_SP_REGNUM;
struct frame_extra_info fextra_info;
}
CORE_ADDR
-s390_read_fp ()
+s390_read_fp (void)
{
return read_register (s390_fp_regnum ());
}
-void
-s390_write_fp (CORE_ADDR val)
+static void
+s390_pop_frame_regular (struct frame_info *frame)
{
- write_register (s390_fp_regnum (), val);
+ int regnum;
+
+ write_register (S390_PC_REGNUM, DEPRECATED_FRAME_SAVED_PC (frame));
+
+ /* Restore any saved registers. */
+ if (get_frame_saved_regs (frame))
+ {
+ for (regnum = 0; regnum < NUM_REGS; regnum++)
+ if (get_frame_saved_regs (frame)[regnum] != 0)
+ {
+ ULONGEST value;
+
+ value = read_memory_unsigned_integer (get_frame_saved_regs (frame)[regnum],
+ REGISTER_RAW_SIZE (regnum));
+ write_register (regnum, value);
+ }
+
+ /* Actually cut back the stack. Remember that the SP's element of
+ saved_regs is the old SP itself, not the address at which it is
+ saved. */
+ write_register (S390_SP_REGNUM, get_frame_saved_regs (frame)[S390_SP_REGNUM]);
+ }
+
+ /* Throw away any cached frame information. */
+ flush_cached_frames ();
}
+/* Destroy the innermost (Top-Of-Stack) stack frame, restoring the
+ machine state that was in effect before the frame was created.
+ Used in the contexts of the "return" command, and of
+ target function calls from the debugger. */
void
-s390_push_dummy_frame ()
+s390_pop_frame (void)
{
- CORE_ADDR orig_sp = read_register (S390_SP_REGNUM), new_sp;
- void *saved_regs = alloca (REGISTER_BYTES);
-
- new_sp = (orig_sp - (REGISTER_BYTES + S390_GPR_SIZE));
- read_register_bytes (0, (char *) saved_regs, REGISTER_BYTES);
- /* Use saved copy instead of orig_sp as this will have the correct endianness */
- write_memory (new_sp, (char *) saved_regs + REGISTER_BYTE (S390_SP_REGNUM),
- S390_GPR_SIZE);
- write_memory (new_sp + S390_GPR_SIZE, (char *) &saved_regs, REGISTER_BYTES);
- write_register (S390_SP_REGNUM, new_sp);
+ /* This function checks for and handles generic dummy frames, and
+ calls back to our function for ordinary frames. */
+ generic_pop_current_frame (s390_pop_frame_regular);
}
-/* pop the innermost frame, go back to the caller.
- Used in `call_function_by_hand' to remove an artificial stack
- frame. */
-void
-s390_pop_frame ()
+
+/* Return non-zero if TYPE is an integer-like type, zero otherwise.
+ "Integer-like" types are those that should be passed the way
+ integers are: integers, enums, ranges, characters, and booleans. */
+static int
+is_integer_like (struct type *type)
+{
+ enum type_code code = TYPE_CODE (type);
+
+ return (code == TYPE_CODE_INT
+ || code == TYPE_CODE_ENUM
+ || code == TYPE_CODE_RANGE
+ || code == TYPE_CODE_CHAR
+ || code == TYPE_CODE_BOOL);
+}
+
+
+/* Return non-zero if TYPE is a pointer-like type, zero otherwise.
+ "Pointer-like" types are those that should be passed the way
+ pointers are: pointers and references. */
+static int
+is_pointer_like (struct type *type)
+{
+ enum type_code code = TYPE_CODE (type);
+
+ return (code == TYPE_CODE_PTR
+ || code == TYPE_CODE_REF);
+}
+
+
+/* Return non-zero if TYPE is a `float singleton' or `double
+ singleton', zero otherwise.
+
+ A `T singleton' is a struct type with one member, whose type is
+ either T or a `T singleton'. So, the following are all float
+ singletons:
+
+ struct { float x };
+ struct { struct { float x; } x; };
+ struct { struct { struct { float x; } x; } x; };
+
+ ... and so on.
+
+ WHY THE HECK DO WE CARE ABOUT THIS??? Well, it turns out that GCC
+ passes all float singletons and double singletons as if they were
+ simply floats or doubles. This is *not* what the ABI says it
+ should do. */
+static int
+is_float_singleton (struct type *type)
+{
+ return (TYPE_CODE (type) == TYPE_CODE_STRUCT
+ && TYPE_NFIELDS (type) == 1
+ && (TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) == TYPE_CODE_FLT
+ || is_float_singleton (TYPE_FIELD_TYPE (type, 0))));
+}
+
+
+/* Return non-zero if TYPE is a struct-like type, zero otherwise.
+ "Struct-like" types are those that should be passed as structs are:
+ structs and unions.
+
+ As an odd quirk, not mentioned in the ABI, GCC passes float and
+ double singletons as if they were a plain float, double, etc. (The
+ corresponding union types are handled normally.) So we exclude
+ those types here. *shrug* */
+static int
+is_struct_like (struct type *type)
+{
+ enum type_code code = TYPE_CODE (type);
+
+ return (code == TYPE_CODE_UNION
+ || (code == TYPE_CODE_STRUCT && ! is_float_singleton (type)));
+}
+
+
+/* Return non-zero if TYPE is a float-like type, zero otherwise.
+ "Float-like" types are those that should be passed as
+ floating-point values are.
+
+ You'd think this would just be floats, doubles, long doubles, etc.
+ But as an odd quirk, not mentioned in the ABI, GCC passes float and
+ double singletons as if they were a plain float, double, etc. (The
+ corresponding union types are handled normally.) So we exclude
+ those types here. *shrug* */
+static int
+is_float_like (struct type *type)
+{
+ return (TYPE_CODE (type) == TYPE_CODE_FLT
+ || is_float_singleton (type));
+}
+
+
+/* Return non-zero if TYPE is considered a `DOUBLE_OR_FLOAT', as
+ defined by the parameter passing conventions described in the
+ "GNU/Linux for S/390 ELF Application Binary Interface Supplement".
+ Otherwise, return zero. */
+static int
+is_double_or_float (struct type *type)
+{
+ return (is_float_like (type)
+ && (TYPE_LENGTH (type) == 4
+ || TYPE_LENGTH (type) == 8));
+}
+
+
+/* Return non-zero if TYPE is considered a `SIMPLE_ARG', as defined by
+ the parameter passing conventions described in the "GNU/Linux for
+ S/390 ELF Application Binary Interface Supplement". Return zero
+ otherwise. */
+static int
+is_simple_arg (struct type *type)
+{
+ unsigned length = TYPE_LENGTH (type);
+
+ /* 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 <= 4)
+ || is_pointer_like (type)
+ || (is_struct_like (type) && length != 8)
+ || (is_float_like (type) && length == 16));
+}
+
+
+/* Return non-zero if TYPE should be passed as a pointer to a copy,
+ zero otherwise. TYPE must be a SIMPLE_ARG, as recognized by
+ `is_simple_arg'. */
+static int
+pass_by_copy_ref (struct type *type)
+{
+ unsigned length = TYPE_LENGTH (type);
+
+ return ((is_struct_like (type) && length != 1 && length != 2 && length != 4)
+ || (is_float_like (type) && length == 16));
+}
+
+
+/* Return ARG, a `SIMPLE_ARG', sign-extended or zero-extended to a full
+ word as required for the ABI. */
+static LONGEST
+extend_simple_arg (struct value *arg)
+{
+ struct type *type = VALUE_TYPE (arg);
+
+ /* Even structs get passed in the least significant bits of the
+ register / memory word. It's not really right to extract them as
+ an integer, but it does take care of the extension. */
+ if (TYPE_UNSIGNED (type))
+ return extract_unsigned_integer (VALUE_CONTENTS (arg),
+ TYPE_LENGTH (type));
+ else
+ return extract_signed_integer (VALUE_CONTENTS (arg),
+ TYPE_LENGTH (type));
+}
+
+
+/* Return non-zero if TYPE is a `DOUBLE_ARG', as defined by the
+ parameter passing conventions described in the "GNU/Linux for S/390
+ ELF Application Binary Interface Supplement". Return zero
+ otherwise. */
+static int
+is_double_arg (struct type *type)
+{
+ unsigned length = TYPE_LENGTH (type);
+
+ return ((is_integer_like (type)
+ || is_struct_like (type))
+ && length == 8);
+}
+
+
+/* Round ADDR up to the next N-byte boundary. N must be a power of
+ two. */
+static CORE_ADDR
+round_up (CORE_ADDR addr, int n)
+{
+ /* Check that N is really a power of two. */
+ gdb_assert (n && (n & (n-1)) == 0);
+ return ((addr + n - 1) & -n);
+}
+
+
+/* Round ADDR down to the next N-byte boundary. N must be a power of
+ two. */
+static CORE_ADDR
+round_down (CORE_ADDR addr, int n)
+{
+ /* Check that N is really a power of two. */
+ gdb_assert (n && (n & (n-1)) == 0);
+ return (addr & -n);
+}
+
+
+/* Return the alignment required by TYPE. */
+static int
+alignment_of (struct type *type)
{
- CORE_ADDR new_sp = read_register (S390_SP_REGNUM), orig_sp;
- void *saved_regs = alloca (REGISTER_BYTES);
+ int alignment;
+
+ if (is_integer_like (type)
+ || is_pointer_like (type)
+ || TYPE_CODE (type) == TYPE_CODE_FLT)
+ alignment = TYPE_LENGTH (type);
+ else if (TYPE_CODE (type) == TYPE_CODE_STRUCT
+ || TYPE_CODE (type) == TYPE_CODE_UNION)
+ {
+ int i;
+
+ alignment = 1;
+ for (i = 0; i < TYPE_NFIELDS (type); i++)
+ {
+ int field_alignment = alignment_of (TYPE_FIELD_TYPE (type, i));
+
+ if (field_alignment > alignment)
+ alignment = field_alignment;
+ }
+ }
+ else
+ alignment = 1;
+ /* Check that everything we ever return is a power of two. Lots of
+ code doesn't want to deal with aligning things to arbitrary
+ boundaries. */
+ gdb_assert ((alignment & (alignment - 1)) == 0);
- read_memory (new_sp + S390_GPR_SIZE, (char *) saved_regs, REGISTER_BYTES);
- write_register_bytes (0, (char *) &saved_regs, REGISTER_BYTES);
+ return alignment;
}
-/* used by call function by hand
- struct_return indicates that this function returns a structure &
- therefore gpr2 stores a pointer to the structure to be returned as
- opposed to the first argument.
- Currently I haven't seen a TYPE_CODE_INT whose size wasn't 2^n or less
- than S390_GPR_SIZE this is good because I don't seem to have to worry
- about sign extending pushed arguments (i.e. a signed char currently
- comes into this code with a size of 4 ). */
+/* Put the actual parameter values pointed to by ARGS[0..NARGS-1] in
+ place to be passed to a function, as specified by the "GNU/Linux
+ for S/390 ELF Application Binary Interface Supplement".
+
+ SP is the current stack pointer. We must put arguments, links,
+ padding, etc. whereever they belong, and return the new stack
+ pointer value.
+
+ If STRUCT_RETURN is non-zero, then the function we're calling is
+ going to return a structure by value; STRUCT_ADDR is the address of
+ a block we've allocated for it on the stack.
+
+ Our caller has taken care of any type promotions needed to satisfy
+ prototypes or the old K&R argument-passing rules. */
CORE_ADDR
s390_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
int struct_return, CORE_ADDR struct_addr)
{
- int num_float_args, num_gpr_args, orig_num_gpr_args, argno;
- int second_pass, len, arglen, gprs_required;
- CORE_ADDR outgoing_args_ptr, outgoing_args_space;
- struct value *arg;
- struct type *type;
- int max_num_gpr_args = 5 - (struct_return ? 1 : 0);
- int arg0_regnum = S390_GP0_REGNUM + 2 + (struct_return ? 1 : 0);
- char *reg_buff = alloca (max (S390_FPR_SIZE, REGISTER_SIZE)), *value;
-
- for (second_pass = 0; second_pass <= 1; second_pass++)
- {
- if (second_pass)
- outgoing_args_ptr = sp + S390_STACK_FRAME_OVERHEAD;
- else
- outgoing_args_ptr = 0;
- num_float_args = 0;
- num_gpr_args = 0;
- for (argno = 0; argno < nargs; argno++)
- {
- arg = args[argno];
- type = check_typedef (VALUE_TYPE (arg));
- len = TYPE_LENGTH (type);
- if (TYPE_CODE (type) == TYPE_CODE_FLT)
- {
- int all_float_registers_used =
- num_float_args > (GDB_TARGET_IS_ESAME ? 3 : 1);
-
- if (second_pass)
- {
- DOUBLEST tempfloat =
- extract_floating (VALUE_CONTENTS (arg), len);
-
-
- floatformat_from_doublest (all_float_registers_used &&
- len == (TARGET_FLOAT_BIT >> 3)
- ? &floatformat_ieee_single_big
- : &floatformat_ieee_double_big,
- &tempfloat, reg_buff);
- if (all_float_registers_used)
- write_memory (outgoing_args_ptr, reg_buff, len);
- else
- write_register_bytes (REGISTER_BYTE ((S390_FP0_REGNUM)
- +
- (2 *
- num_float_args)),
- reg_buff, S390_FPR_SIZE);
- }
- if (all_float_registers_used)
- outgoing_args_ptr += len;
- num_float_args++;
- }
- else
- {
- gprs_required = ((len + (S390_GPR_SIZE - 1)) / S390_GPR_SIZE);
+ int i;
+ int pointer_size = (TARGET_PTR_BIT / TARGET_CHAR_BIT);
- value =
- s390_promote_integer_argument (type, VALUE_CONTENTS (arg),
- reg_buff, &arglen);
+ /* The number of arguments passed by reference-to-copy. */
+ int num_copies;
- orig_num_gpr_args = num_gpr_args;
- num_gpr_args += gprs_required;
- if (num_gpr_args > max_num_gpr_args)
- {
- if (second_pass)
- write_memory (outgoing_args_ptr, value, arglen);
- outgoing_args_ptr += arglen;
- }
- else
- {
- if (second_pass)
- write_register_bytes (REGISTER_BYTE (arg0_regnum)
- +
- (orig_num_gpr_args * S390_GPR_SIZE),
- value, arglen);
- }
- }
- }
- if (!second_pass)
- {
- outgoing_args_space = outgoing_args_ptr;
- /* Align to 16 bytes because because I like alignment &
- some of the kernel code requires 8 byte stack alignment at least. */
- sp = (sp - (S390_STACK_FRAME_OVERHEAD + outgoing_args_ptr)) & (-16);
- }
+ /* If the i'th argument is passed as a reference to a copy, then
+ copy_addr[i] is the address of the copy we made. */
+ CORE_ADDR *copy_addr = alloca (nargs * sizeof (CORE_ADDR));
+ /* Build the reference-to-copy area. */
+ num_copies = 0;
+ for (i = 0; i < nargs; i++)
+ {
+ struct value *arg = args[i];
+ struct type *type = VALUE_TYPE (arg);
+ unsigned length = TYPE_LENGTH (type);
+
+ if (is_simple_arg (type)
+ && pass_by_copy_ref (type))
+ {
+ sp -= length;
+ sp = round_down (sp, alignment_of (type));
+ write_memory (sp, VALUE_CONTENTS (arg), length);
+ copy_addr[i] = sp;
+ num_copies++;
+ }
}
+
+ /* Reserve space for the parameter area. As a conservative
+ simplification, we assume that everything will be passed on the
+ stack. */
+ {
+ int i;
+
+ for (i = 0; i < nargs; i++)
+ {
+ struct value *arg = args[i];
+ struct type *type = VALUE_TYPE (arg);
+ int length = TYPE_LENGTH (type);
+
+ sp = round_down (sp, alignment_of (type));
+
+ /* SIMPLE_ARG values get extended to 32 bits. Assume every
+ argument is. */
+ if (length < 4) length = 4;
+ sp -= length;
+ }
+ }
+
+ /* Include space for any reference-to-copy pointers. */
+ sp = round_down (sp, pointer_size);
+ sp -= num_copies * pointer_size;
+
+ /* After all that, make sure it's still aligned on an eight-byte
+ boundary. */
+ sp = round_down (sp, 8);
+
+ /* Finally, place the actual parameters, working from SP towards
+ higher addresses. The code above is supposed to reserve enough
+ space for this. */
+ {
+ int fr = 0;
+ int gr = 2;
+ CORE_ADDR starg = sp;
+
+ for (i = 0; i < nargs; i++)
+ {
+ struct value *arg = args[i];
+ struct type *type = VALUE_TYPE (arg);
+
+ if (is_double_or_float (type)
+ && fr <= 2)
+ {
+ /* When we store a single-precision value in an FP register,
+ it occupies the leftmost bits. */
+ deprecated_write_register_bytes (REGISTER_BYTE (S390_FP0_REGNUM + fr),
+ VALUE_CONTENTS (arg),
+ TYPE_LENGTH (type));
+ fr += 2;
+ }
+ else if (is_simple_arg (type)
+ && gr <= 6)
+ {
+ /* 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) + 4);
+ gr += 2;
+ }
+ else
+ {
+ /* The `OTHER' case. */
+ enum type_code code = TYPE_CODE (type);
+ unsigned length = TYPE_LENGTH (type);
+
+ /* If we skipped r6 because we couldn't fit a DOUBLE_ARG
+ in it, then don't go back and use it again later. */
+ if (is_double_arg (type) && gr == 6)
+ gr = 7;
+
+ if (is_simple_arg (type))
+ {
+ /* Simple args are always either extended to 32 bits,
+ or pointers. */
+ starg = round_up (starg, 4);
+
+ /* Do we need to pass a pointer to our copy of this
+ argument? */
+ if (pass_by_copy_ref (type))
+ write_memory_signed_integer (starg, pointer_size,
+ copy_addr[i]);
+ else
+ /* Simple args are always extended to 32 bits. */
+ write_memory_signed_integer (starg, 4,
+ extend_simple_arg (arg));
+ starg += 4;
+ }
+ else
+ {
+ /* You'd think we should say:
+ starg = round_up (starg, alignment_of (type));
+ Unfortunately, GCC seems to simply align the stack on
+ a four-byte boundary, even when passing doubles. */
+ starg = round_up (starg, 4);
+ write_memory (starg, VALUE_CONTENTS (arg), length);
+ starg += length;
+ }
+ }
+ }
+ }
+
+ /* Allocate the standard frame areas: the register save area, the
+ word reserved for the compiler (which seems kind of meaningless),
+ and the back chain pointer. */
+ sp -= 96;
+
+ /* Write the back chain pointer into the first word of the stack
+ frame. This will help us get backtraces from within functions
+ called from GDB. */
+ write_memory_unsigned_integer (sp, (TARGET_PTR_BIT / TARGET_CHAR_BIT),
+ deprecated_read_fp ());
+
return sp;
+}
+
+static CORE_ADDR
+s390_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
+{
+ /* Both the 32- and 64-bit ABI's say that the stack pointer should
+ always be aligned on an eight-byte boundary. */
+ return (addr & -8);
}
-void
-s390_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs,
- struct value **args, struct type *value_type,
- int using_gcc)
+
+static int
+s390_use_struct_convention (int gcc_p, struct type *value_type)
{
- store_unsigned_integer (dummy + 4, REGISTER_SIZE, fun);
+ enum type_code code = TYPE_CODE (value_type);
+
+ return (code == TYPE_CODE_STRUCT
+ || code == TYPE_CODE_UNION);
}
struct type *
s390_register_virtual_type (int regno)
{
- return ((unsigned) regno - S390_FPC_REGNUM) <
- S390_NUM_FPRS ? builtin_type_double : builtin_type_int;
+ if (S390_FP0_REGNUM <= regno && regno < S390_FP0_REGNUM + S390_NUM_FPRS)
+ return builtin_type_double;
+ else
+ return builtin_type_int;
}
-static unsigned char *
+const static unsigned char *
s390_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
{
static unsigned char breakpoint[] = { 0x0, 0x1 };
return fextra_info.skip_prologue_function_start;
}
-/* pc_in_call_dummy_on stack may work for us must test this */
-int
-s390_pc_in_call_dummy (CORE_ADDR pc, CORE_ADDR sp, CORE_ADDR frame_address)
-{
- return pc > sp && pc < (sp + 4096);
-}
-
/* Immediately after a function call, return the saved pc.
Can't go through the frames for this because on some machines
the new frame is not set up until the new function executes
static CORE_ADDR
s390_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
{
+ write_register (S390_RETADDR_REGNUM, CALL_DUMMY_ADDRESS ());
return sp;
}
+static int
+s390_address_class_type_flags (int byte_size, int dwarf2_addr_class)
+{
+ if (byte_size == 4)
+ return TYPE_FLAG_ADDRESS_CLASS_1;
+ else
+ return 0;
+}
+
+static const char *
+s390_address_class_type_flags_to_name (struct gdbarch *gdbarch, int type_flags)
+{
+ if (type_flags & TYPE_FLAG_ADDRESS_CLASS_1)
+ return "mode32";
+ else
+ return NULL;
+}
+
+int
+s390_address_class_name_to_type_flags (struct gdbarch *gdbarch, const char *name,
+ int *type_flags_ptr)
+{
+ if (strcmp (name, "mode32") == 0)
+ {
+ *type_flags_ptr = TYPE_FLAG_ADDRESS_CLASS_1;
+ return 1;
+ }
+ else
+ return 0;
+}
+
struct gdbarch *
s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
-
- /* instruction sequence for s390 call dummy is as follows
- bras %r1,.+8 ; 0xA7150004
- long basraddr ; 0x00000000
- l %r1,0(%r1) ; 0x58101000
- basr %r14,%r1 ; 0x0DE1
- breakpoint ; 0x0001 */
- static LONGEST s390_call_dummy_words[] = { 0xA7150004, 0x00000000,
- 0x58101000, 0x0DE10001
- };
- /* instruction sequence for esame call dummy is as follows
- bras %r1,.+12 ; 0xA7150006
- long basraddr ; 0x0000000000000000
- lg %r1,0(%r1) ; 0xE31010000004
- basr %r14,%r1 ; 0x0DE1
- breakpoint ; 0x0001 */
- static LONGEST s390x_call_dummy_words[] = { 0xA715000600000000,
- 0x00000000E3101000,
- 0x00040DE100010000
- };
+ static LONGEST s390_call_dummy_words[] = { 0 };
struct gdbarch *gdbarch;
struct gdbarch_tdep *tdep;
int elf_flags;
/* Yes: create a new gdbarch for the specified machine type. */
gdbarch = gdbarch_alloc (&info, NULL);
- set_gdbarch_believe_pcc_promotion (gdbarch, 0);
+ /* 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()). */
+ set_gdbarch_deprecated_init_frame_pc (gdbarch, init_frame_pc_default);
- /* We don't define set_gdbarch_call_dummy_breakpoint_offset
- as we already have a breakpoint inserted. */
- set_gdbarch_use_generic_dummy_frames (gdbarch, 0);
+ set_gdbarch_believe_pcc_promotion (gdbarch, 0);
+ set_gdbarch_char_signed (gdbarch, 0);
- set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
- set_gdbarch_call_dummy_start_offset (gdbarch, 0);
- set_gdbarch_pc_in_call_dummy (gdbarch, s390_pc_in_call_dummy);
set_gdbarch_frame_args_skip (gdbarch, 0);
set_gdbarch_frame_args_address (gdbarch, s390_frame_args_address);
- set_gdbarch_frame_chain (gdbarch, s390_frame_chain);
- set_gdbarch_frame_init_saved_regs (gdbarch, s390_frame_init_saved_regs);
+ set_gdbarch_deprecated_frame_chain (gdbarch, s390_frame_chain);
+ set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, s390_frame_init_saved_regs);
set_gdbarch_frame_locals_address (gdbarch, s390_frame_args_address);
/* We can't do this */
set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown);
- set_gdbarch_store_struct_return (gdbarch, s390_store_struct_return);
- set_gdbarch_extract_return_value (gdbarch, s390_extract_return_value);
- set_gdbarch_store_return_value (gdbarch, s390_store_return_value);
- /* Amount PC must be decremented by after a breakpoint.
- This is often the number of bytes in BREAKPOINT
- but not always. */
+ set_gdbarch_deprecated_store_struct_return (gdbarch, s390_store_struct_return);
+ set_gdbarch_deprecated_extract_return_value (gdbarch, s390_extract_return_value);
+ set_gdbarch_deprecated_store_return_value (gdbarch, s390_store_return_value);
+ /* Amount PC must be decremented by after a breakpoint. This is
+ often the number of bytes returned by BREAKPOINT_FROM_PC but not
+ always. */
set_gdbarch_decr_pc_after_break (gdbarch, 2);
- set_gdbarch_pop_frame (gdbarch, s390_pop_frame);
- set_gdbarch_push_dummy_frame (gdbarch, s390_push_dummy_frame);
- set_gdbarch_push_arguments (gdbarch, s390_push_arguments);
- set_gdbarch_ieee_float (gdbarch, 1);
+ set_gdbarch_deprecated_pop_frame (gdbarch, s390_pop_frame);
/* Stack grows downward. */
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
/* Offset from address of function to start of its code.
Zero on most machines. */
set_gdbarch_function_start_offset (gdbarch, 0);
- set_gdbarch_max_register_raw_size (gdbarch, 8);
- set_gdbarch_max_register_virtual_size (gdbarch, 8);
+ 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_init_extra_frame_info (gdbarch, s390_init_extra_frame_info);
- set_gdbarch_init_frame_pc_first (gdbarch, s390_init_frame_pc_first);
- set_gdbarch_read_fp (gdbarch, s390_read_fp);
- set_gdbarch_write_fp (gdbarch, s390_write_fp);
+ 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. */
set_gdbarch_frameless_function_invocation (gdbarch,
s390_frameless_function_invocation);
/* Return saved PC from a frame */
- set_gdbarch_frame_saved_pc (gdbarch, s390_frame_saved_pc);
- /* FRAME_CHAIN takes a frame's nominal address
- and produces the frame's chain-pointer. */
- set_gdbarch_frame_chain (gdbarch, s390_frame_chain);
- set_gdbarch_saved_pc_after_call (gdbarch, s390_saved_pc_after_call);
+ set_gdbarch_deprecated_frame_saved_pc (gdbarch, s390_frame_saved_pc);
+ /* DEPRECATED_FRAME_CHAIN takes a frame's nominal address and
+ 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_register_byte (gdbarch, s390_register_byte);
set_gdbarch_pc_regnum (gdbarch, S390_PC_REGNUM);
set_gdbarch_sp_regnum (gdbarch, S390_SP_REGNUM);
- set_gdbarch_fp_regnum (gdbarch, S390_FP_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_get_saved_register (gdbarch, generic_get_saved_register);
- set_gdbarch_use_struct_convention (gdbarch, generic_use_struct_convention);
- set_gdbarch_frame_chain_valid (gdbarch, file_frame_chain_valid);
+ 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);
-
- /* Stuff below here wouldn't be required if gdbarch.sh was a little */
- /* more intelligent */
- set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 0);
- set_gdbarch_call_dummy_p (gdbarch, 1);
- set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
- set_gdbarch_extract_struct_value_address (gdbarch, 0);
- set_gdbarch_fix_call_dummy (gdbarch, s390_fix_call_dummy);
-#ifdef GDB_NM_FILE
- set_gdbarch_prepare_to_proceed (gdbarch, linuxthreads_prepare_to_proceed);
-#endif
- set_gdbarch_push_return_address (gdbarch, s390_push_return_address);
+ set_gdbarch_deprecated_extract_struct_value_address
+ (gdbarch, generic_cannot_extract_struct_value_address);
+
+ /* Parameters for inferior function calls. */
+ set_gdbarch_deprecated_pc_in_call_dummy (gdbarch, deprecated_pc_in_call_dummy_at_entry_point);
+ set_gdbarch_frame_align (gdbarch, s390_frame_align);
+ set_gdbarch_deprecated_push_arguments (gdbarch, s390_push_arguments);
+ set_gdbarch_save_dummy_frame_tos (gdbarch, generic_save_dummy_frame_tos);
+ set_gdbarch_deprecated_push_return_address (gdbarch,
+ s390_push_return_address);
+ set_gdbarch_deprecated_sizeof_call_dummy_words (gdbarch, sizeof (s390_call_dummy_words));
+ set_gdbarch_deprecated_call_dummy_words (gdbarch, s390_call_dummy_words);
switch (info.bfd_arch_info->mach)
{
- case bfd_mach_s390_esa:
- set_gdbarch_register_size (gdbarch, 4);
- set_gdbarch_call_dummy_length (gdbarch, 16);
+ case bfd_mach_s390_31:
+ set_gdbarch_deprecated_register_size (gdbarch, 4);
set_gdbarch_register_raw_size (gdbarch, s390_register_raw_size);
set_gdbarch_register_virtual_size (gdbarch, s390_register_raw_size);
set_gdbarch_register_virtual_type (gdbarch, s390_register_virtual_type);
set_gdbarch_addr_bits_remove (gdbarch, s390_addr_bits_remove);
-
- set_gdbarch_sizeof_call_dummy_words (gdbarch,
- sizeof (s390_call_dummy_words));
- set_gdbarch_call_dummy_words (gdbarch, s390_call_dummy_words);
- set_gdbarch_register_bytes (gdbarch, S390_REGISTER_BYTES);
+ set_gdbarch_deprecated_register_bytes (gdbarch, S390_REGISTER_BYTES);
break;
- case bfd_mach_s390_esame:
- set_gdbarch_register_size (gdbarch, 8);
- set_gdbarch_call_dummy_length (gdbarch, 22);
+ case bfd_mach_s390_64:
+ set_gdbarch_deprecated_register_size (gdbarch, 8);
set_gdbarch_register_raw_size (gdbarch, s390x_register_raw_size);
set_gdbarch_register_virtual_size (gdbarch, s390x_register_raw_size);
set_gdbarch_register_virtual_type (gdbarch,
set_gdbarch_long_bit (gdbarch, 64);
set_gdbarch_long_long_bit (gdbarch, 64);
set_gdbarch_ptr_bit (gdbarch, 64);
- set_gdbarch_sizeof_call_dummy_words (gdbarch,
- sizeof (s390x_call_dummy_words));
- set_gdbarch_call_dummy_words (gdbarch, s390x_call_dummy_words);
- set_gdbarch_register_bytes (gdbarch, S390X_REGISTER_BYTES);
+ 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,
+ s390_address_class_type_flags_to_name);
+ set_gdbarch_address_class_name_to_type_flags (gdbarch,
+ s390_address_class_name_to_type_flags);
break;
}
+ /* Should be using push_dummy_call. */
+ set_gdbarch_deprecated_dummy_write_sp (gdbarch, generic_target_write_sp);
+
return gdbarch;
}
void
-_initialize_s390_tdep ()
+_initialize_s390_tdep (void)
{
/* Hook us into the gdbarch mechanism. */
register_gdbarch_init (bfd_arch_s390, s390_gdbarch_init);
- if (!tm_print_insn) /* Someone may have already set it */
- tm_print_insn = gdb_print_insn_s390;
+ if (!deprecated_tm_print_insn) /* Someone may have already set it */
+ deprecated_tm_print_insn = gdb_print_insn_s390;
}
#endif /* GDBSERVER */