/* Target dependent code for CRIS, for GDB, the GNU debugger.
- Copyright 2001 Free Software Foundation, Inc.
+ Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
Contributed by Axis Communications AB.
Written by Hendrik Ruijter, Stefan Andersson, and Orjan Friberg.
/* To get entry_point_address. */
#include "symfile.h"
+#include "solib.h" /* Support for shared libraries. */
+#include "solib-svr4.h" /* For struct link_map_offsets. */
+#include "gdb_string.h"
+
+
enum cris_num_regs
{
/* There are no floating point registers. Used in gdbserver low-linux.c. */
};
/* Register numbers of various important registers.
- FP_REGNUM Contains address of executing stack frame.
+ DEPRECATED_FP_REGNUM Contains address of executing stack frame.
STR_REGNUM Contains the address of structure return values.
RET_REGNUM Contains the return value when shorter than or equal to 32 bits
ARG1_REGNUM Contains the first parameter to a function.
SRP_REGNUM Subroutine return pointer register.
BRP_REGNUM Breakpoint return pointer register. */
-/* FP_REGNUM = 8, SP_REGNUM = 14, and PC_REGNUM = 15 have been incorporated
- into the multi-arch framework. */
+/* DEPRECATED_FP_REGNUM = 8, SP_REGNUM = 14, and PC_REGNUM = 15 have
+ been incorporated into the multi-arch framework. */
enum cris_regnums
{
IRP_REGNUM = 26,
SRP_REGNUM = 27,
BAR_REGNUM = 28,
+ DCCR_REGNUM = 29,
BRP_REGNUM = 30,
USP_REGNUM = 31
};
CORE_ADDR frame
CORE_ADDR pc
- int signal_handler_caller
+ enum frame_type type;
CORE_ADDR return_pc
int leaf_function
of the register PC. All other frames contain the content of the
register PC in the next frame.
- The variable signal_handler_caller is non-zero when the frame is
- associated with the call of a signal handler.
+ The variable `type' indicates the frame's type: normal, SIGTRAMP
+ (associated with a signal handler), dummy (associated with a dummy
+ frame).
The variable return_pc contains the address where execution should be
resumed when the present frame has finished, the return address.
short source_register;
/* This frame is with respect to a leaf until a push srp is found. */
- fi->extra_info->leaf_function = 1;
+ get_frame_extra_info (fi)->leaf_function = 1;
/* This frame is without the FP until a push fp is found. */
have_fp = 0;
/* We only want to know the end of the prologue when fi->saved_regs == 0.
When the saved registers are allocated full information is required. */
- if (fi->saved_regs)
+ if (get_frame_saved_regs (fi))
{
for (regno = 0; regno < NUM_REGS; regno++)
- fi->saved_regs[regno] = 0;
+ get_frame_saved_regs (fi)[regno] = 0;
}
/* Find the prologue instructions. */
insn_next = read_memory_unsigned_integer (ip, sizeof (short));
ip += sizeof (short);
regno = cris_get_operand2 (insn_next);
- if (regno == (SRP_REGNUM - NUM_GENREGS))
+
+ /* This check, meant to recognize srp, used to be regno ==
+ (SRP_REGNUM - NUM_GENREGS), but that covers r11 also. */
+ if (insn_next == 0xBE7E)
{
if (frameless_p)
{
return ip;
}
- fi->extra_info->leaf_function = 0;
+ get_frame_extra_info (fi)->leaf_function = 0;
}
- else if (regno == FP_REGNUM)
+ else if (regno == DEPRECATED_FP_REGNUM)
{
have_fp = 1;
}
return ip;
}
source_register = cris_get_operand1 (insn);
+
+ /* FIXME? In the glibc solibs, the prologue might contain something
+ like (this example taken from relocate_doit):
+ move.d $pc,$r0
+ sub.d 0xfffef426,$r0
+ which isn't covered by the source_register check below. Question
+ is whether to add a check for this combo, or make better use of
+ the limit variable instead. */
if (source_register < ARG1_REGNUM || source_register > ARG4_REGNUM)
{
/* The prologue ended before the limit was reached. */
break;
}
}
- else if (cris_get_operand2 (insn) == FP_REGNUM
+ else if (cris_get_operand2 (insn) == DEPRECATED_FP_REGNUM
/* The size is a fixed-size. */
&& ((insn & 0x0F00) >> 8) == 0x0001
/* A negative offset. */
break;
}
}
- else if (cris_get_operand2 (insn) == FP_REGNUM
+ else if (cris_get_operand2 (insn) == DEPRECATED_FP_REGNUM
/* The size is a fixed-size. */
&& ((insn & 0x0F00) >> 8) == 0x0001
/* A positive offset. */
/* We only want to know the end of the prologue when
fi->saved_regs == 0. */
- if (!fi->saved_regs)
+ if (!get_frame_saved_regs (fi))
return ip;
if (have_fp)
{
- fi->saved_regs[FP_REGNUM] = FRAME_FP (fi);
+ get_frame_saved_regs (fi)[DEPRECATED_FP_REGNUM] = get_frame_base (fi);
/* Calculate the addresses. */
for (regno = regsave; regno >= 0; regno--)
{
- fi->saved_regs[regno] = FRAME_FP (fi) - val;
+ get_frame_saved_regs (fi)[regno] = get_frame_base (fi) - val;
val -= 4;
}
- if (fi->extra_info->leaf_function)
+ if (get_frame_extra_info (fi)->leaf_function)
{
/* Set the register SP to contain the stack pointer of
the caller. */
- fi->saved_regs[SP_REGNUM] = FRAME_FP (fi) + 4;
+ get_frame_saved_regs (fi)[SP_REGNUM] = get_frame_base (fi) + 4;
}
else
{
/* Set the register SP to contain the stack pointer of
the caller. */
- fi->saved_regs[SP_REGNUM] = FRAME_FP (fi) + 8;
+ get_frame_saved_regs (fi)[SP_REGNUM] = get_frame_base (fi) + 8;
/* Set the register SRP to contain the return address of
the caller. */
- fi->saved_regs[SRP_REGNUM] = FRAME_FP (fi) + 4;
+ get_frame_saved_regs (fi)[SRP_REGNUM] = get_frame_base (fi) + 4;
}
}
return ip;
CORE_ADDR
cris_skip_prologue_main (CORE_ADDR pc, int frameless_p)
{
- struct frame_info fi;
- static struct frame_extra_info fei;
+ struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
+ struct frame_info *fi;
struct symtab_and_line sal = find_pc_line (pc, 0);
int best_limit;
CORE_ADDR pc_after_prologue;
- /* frame_info now contains dynamic memory. Since fi is a dummy here,
- I use static memory for extra_info, and don't bother allocating
- memory for saved_regs. */
- fi.saved_regs = 0;
- fi.extra_info = &fei;
+ /* frame_info now contains dynamic memory. Since fi is a dummy
+ here, I don't bother allocating memory for saved_regs. */
+ fi = deprecated_frame_xmalloc_with_cleanup (0, sizeof (struct frame_extra_info));
/* If there is no symbol information then sal.end == 0, and we end up
examining only the first instruction in the function prologue.
else
best_limit = pc + 100;
- pc_after_prologue = cris_examine (pc, best_limit, &fi, frameless_p);
+ pc_after_prologue = cris_examine (pc, best_limit, fi, frameless_p);
+ do_cleanups (old_chain);
return pc_after_prologue;
}
adjusts pcptr (if necessary) to point to the actual memory location where
the breakpoint should be inserted. */
-unsigned char *
+const unsigned char *
cris_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
{
static unsigned char break_insn[] = {0x38, 0xe9};
/* Returns the register SRP (subroutine return pointer) which must contain
the content of the register PC after a function call. */
-CORE_ADDR
-cris_saved_pc_after_call ()
+static CORE_ADDR
+cris_saved_pc_after_call (struct frame_info *frame)
{
return read_register (SRP_REGNUM);
}
{
int len = TYPE_LENGTH (type);
- if (len <= REGISTER_SIZE)
- write_register_bytes (REGISTER_BYTE (RET_REGNUM), valbuf, len);
+ if (len <= DEPRECATED_REGISTER_SIZE)
+ deprecated_write_register_bytes (REGISTER_BYTE (RET_REGNUM), valbuf, len);
else
internal_error (__FILE__, __LINE__, "cris_abi_original_store_return_value: type length too large.");
}
{
int len = TYPE_LENGTH (type);
- if (len <= 2 * REGISTER_SIZE)
+ if (len <= 2 * DEPRECATED_REGISTER_SIZE)
{
/* Note that this works since R10 and R11 are consecutive registers. */
- write_register_bytes (REGISTER_BYTE (RET_REGNUM), valbuf, len);
+ deprecated_write_register_bytes (REGISTER_BYTE (RET_REGNUM), valbuf,
+ len);
}
else
internal_error (__FILE__, __LINE__, "cris_abi_v2_store_return_value: type length too large.");
/* Return the name of register regno as a string. Return NULL for an invalid or
unimplemented register. */
-char *
+const char *
cris_register_name (int regno)
{
static char *cris_genreg_names[] =
int
cris_register_bytes_ok (long bytes)
{
- return (bytes == REGISTER_BYTES);
+ return (bytes == DEPRECATED_REGISTER_BYTES);
}
/* Extract from an array regbuf containing the raw register state a function
{
int len = TYPE_LENGTH (type);
- if (len <= REGISTER_SIZE)
+ if (len <= DEPRECATED_REGISTER_SIZE)
memcpy (valbuf, regbuf + REGISTER_BYTE (RET_REGNUM), len);
else
internal_error (__FILE__, __LINE__, "cris_abi_original_extract_return_value: type length too large");
{
int len = TYPE_LENGTH (type);
- if (len <= 2 * REGISTER_SIZE)
+ if (len <= 2 * DEPRECATED_REGISTER_SIZE)
memcpy (valbuf, regbuf + REGISTER_BYTE (RET_REGNUM), len);
else
internal_error (__FILE__, __LINE__, "cris_abi_v2_extract_return_value: type length too large");
int
cris_frameless_function_invocation (struct frame_info *fi)
{
- if (fi->signal_handler_caller)
+ if ((get_frame_type (fi) == SIGTRAMP_FRAME))
return 0;
else
return frameless_look_for_prologue (fi);
}
-/* See frame.h. Determines the address of all registers in the current stack
- frame storing each in frame->saved_regs. Space for frame->saved_regs shall
- be allocated by FRAME_INIT_SAVED_REGS using either frame_saved_regs_zalloc
- or frame_obstack_alloc. */
+/* See frame.h. Determines the address of all registers in the
+ current stack frame storing each in frame->saved_regs. Space for
+ frame->saved_regs shall be allocated by
+ DEPRECATED_FRAME_INIT_SAVED_REGS using frame_saved_regs_zalloc. */
void
cris_frame_init_saved_regs (struct frame_info *fi)
CORE_ADDR ip;
struct symtab_and_line sal;
int best_limit;
- char *dummy_regs = generic_find_dummy_frame (fi->pc, fi->frame);
+ char *dummy_regs = deprecated_generic_find_dummy_frame (get_frame_pc (fi),
+ get_frame_base (fi));
/* Examine the entire prologue. */
register int frameless_p = 0;
/* Has this frame's registers already been initialized? */
- if (fi->saved_regs)
+ if (get_frame_saved_regs (fi))
return;
frame_saved_regs_zalloc (fi);
/* I don't see this ever happening, considering the context in which
cris_frame_init_saved_regs is called (always when we're not in
a dummy frame). */
- memcpy (&fi->saved_regs, dummy_regs, sizeof (fi->saved_regs));
+ memcpy (get_frame_saved_regs (fi), dummy_regs, SIZEOF_FRAME_SAVED_REGS);
}
else
{
- ip = get_pc_function_start (fi->pc);
+ ip = get_frame_func (fi);
sal = find_pc_line (ip, 0);
/* If there is no symbol information then sal.end == 0, and we end up
void
cris_init_extra_frame_info (int fromleaf, struct frame_info *fi)
{
- if (fi->next)
+ if (get_next_frame (fi))
{
/* Called from get_prev_frame. */
- fi->pc = FRAME_SAVED_PC (fi->next);
+ deprecated_update_frame_pc_hack (fi, DEPRECATED_FRAME_SAVED_PC (get_next_frame (fi)));
}
- fi->extra_info = (struct frame_extra_info *)
- frame_obstack_alloc (sizeof (struct frame_extra_info));
+ frame_extra_info_zalloc (fi, sizeof (struct frame_extra_info));
- fi->extra_info->return_pc = 0;
- fi->extra_info->leaf_function = 0;
+ get_frame_extra_info (fi)->return_pc = 0;
+ get_frame_extra_info (fi)->leaf_function = 0;
- if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi),
+ get_frame_base (fi),
+ get_frame_base (fi)))
{
- /* We need to setup fi->frame here because run_stack_dummy gets it wrong
- by assuming it's always FP. */
- fi->frame = generic_read_register_dummy (fi->pc, fi->frame, SP_REGNUM);
- fi->extra_info->return_pc =
- generic_read_register_dummy (fi->pc, fi->frame, PC_REGNUM);
+ /* We need to setup fi->frame here because call_function_by_hand
+ gets it wrong by assuming it's always FP. */
+ deprecated_update_frame_base_hack (fi, deprecated_read_register_dummy (get_frame_pc (fi), get_frame_base (fi), SP_REGNUM));
+ get_frame_extra_info (fi)->return_pc =
+ deprecated_read_register_dummy (get_frame_pc (fi),
+ get_frame_base (fi), PC_REGNUM);
/* FIXME: Is this necessarily true? */
- fi->extra_info->leaf_function = 0;
+ get_frame_extra_info (fi)->leaf_function = 0;
}
else
{
/* Check fromleaf/frameless_function_invocation. (FIXME) */
- if (fi->saved_regs[SRP_REGNUM] != 0)
+ if (get_frame_saved_regs (fi)[SRP_REGNUM] != 0)
{
/* SRP was saved on the stack; non-leaf function. */
- fi->extra_info->return_pc =
- read_memory_integer (fi->saved_regs[SRP_REGNUM],
+ get_frame_extra_info (fi)->return_pc =
+ read_memory_integer (get_frame_saved_regs (fi)[SRP_REGNUM],
REGISTER_RAW_SIZE (SRP_REGNUM));
}
else
{
/* SRP is still in a register; leaf function. */
- fi->extra_info->return_pc = read_register (SRP_REGNUM);
+ get_frame_extra_info (fi)->return_pc = read_register (SRP_REGNUM);
/* FIXME: Should leaf_function be set to 1 here? */
- fi->extra_info->leaf_function = 1;
+ get_frame_extra_info (fi)->leaf_function = 1;
}
}
}
CORE_ADDR
cris_frame_chain (struct frame_info *fi)
{
- if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi),
+ get_frame_base (fi),
+ get_frame_base (fi)))
{
- return fi->frame;
+ return get_frame_base (fi);
}
- else if (!inside_entry_file (fi->pc))
+ else if (!inside_entry_file (get_frame_pc (fi)))
{
- return read_memory_unsigned_integer (FRAME_FP (fi), 4);
+ return read_memory_unsigned_integer (get_frame_base (fi), 4);
}
else
{
CORE_ADDR
cris_frame_saved_pc (struct frame_info *fi)
{
- return fi->extra_info->return_pc;
-}
-
-/* Return the address of the argument block for the frame described
- by struct frame_info. */
-
-CORE_ADDR
-cris_frame_args_address (struct frame_info *fi)
-{
- return FRAME_FP (fi);
-}
-
-/* Return the address of the locals block for the frame
- described by struct frame_info. */
-
-CORE_ADDR
-cris_frame_locals_address (struct frame_info *fi)
-{
- return FRAME_FP (fi);
+ return get_frame_extra_info (fi)->return_pc;
}
/* Setup the function arguments for calling a function in the inferior. */
/* Make sure there's space on the stack. Allocate space for data and a
parameter to refer to that data. */
for (argnum = 0, stack_alloc = 0; argnum < nargs; argnum++)
- stack_alloc += (TYPE_LENGTH (VALUE_TYPE (args[argnum])) + REGISTER_SIZE);
+ stack_alloc += (TYPE_LENGTH (VALUE_TYPE (args[argnum])) + DEPRECATED_REGISTER_SIZE);
sp -= stack_alloc;
/* We may over-allocate a little here, but that won't hurt anything. */
/* Initialize stack frame pointers. */
fp_params = sp;
- fp_data = sp + (nargs * REGISTER_SIZE);
+ fp_data = sp + (nargs * DEPRECATED_REGISTER_SIZE);
/* Now load as many as possible of the first arguments into
registers, and push the rest onto the stack. */
len = TYPE_LENGTH (type);
val = (char *) VALUE_CONTENTS (args[argnum]);
- if (len <= REGISTER_SIZE && argreg <= ARG4_REGNUM)
+ if (len <= DEPRECATED_REGISTER_SIZE && argreg <= ARG4_REGNUM)
{
/* Data fits in a register; put it in the first available
register. */
write_register (argreg, *(unsigned long *) val);
argreg++;
}
- else if (len > REGISTER_SIZE && argreg <= ARG4_REGNUM)
+ else if (len > DEPRECATED_REGISTER_SIZE && argreg <= ARG4_REGNUM)
{
/* Data does not fit in register; pass it on the stack and
put its address in the first available register. */
fp_data += len;
argreg++;
}
- else if (len > REGISTER_SIZE)
+ else if (len > DEPRECATED_REGISTER_SIZE)
{
/* Data does not fit in register; put both data and
parameter on the stack. */
write_memory (fp_data, val, len);
- write_memory (fp_params, (char *) (&fp_data), REGISTER_SIZE);
+ write_memory (fp_params, (char *) (&fp_data), DEPRECATED_REGISTER_SIZE);
fp_data += len;
- fp_params += REGISTER_SIZE;
+ fp_params += DEPRECATED_REGISTER_SIZE;
}
else
{
/* Data fits in a register, but we are out of registers;
put the parameter on the stack. */
- write_memory (fp_params, val, REGISTER_SIZE);
- fp_params += REGISTER_SIZE;
+ write_memory (fp_params, val, DEPRECATED_REGISTER_SIZE);
+ fp_params += DEPRECATED_REGISTER_SIZE;
}
}
int reg_demand;
len = TYPE_LENGTH (VALUE_TYPE (args[argnum]));
- reg_demand = (len / REGISTER_SIZE) + (len % REGISTER_SIZE != 0 ? 1 : 0);
+ reg_demand = (len / DEPRECATED_REGISTER_SIZE) + (len % DEPRECATED_REGISTER_SIZE != 0 ? 1 : 0);
- /* reg_demand * REGISTER_SIZE is the amount of memory we might need to
- allocate for this argument. 2 * REGISTER_SIZE is the amount of stack
- space we might need to pass the argument itself (either by value or by
+ /* reg_demand * DEPRECATED_REGISTER_SIZE is the amount of memory
+ we might need to allocate for this argument. 2 *
+ DEPRECATED_REGISTER_SIZE is the amount of stack space we
+ might need to pass the argument itself (either by value or by
reference). */
- stack_alloc += (reg_demand * REGISTER_SIZE + 2 * REGISTER_SIZE);
+ stack_alloc += (reg_demand * DEPRECATED_REGISTER_SIZE + 2 * DEPRECATED_REGISTER_SIZE);
}
sp -= stack_alloc;
/* We may over-allocate a little here, but that won't hurt anything. */
/* Initialize frame pointers. */
fp_arg = sp;
- fp_mem = sp + (nargs * (2 * REGISTER_SIZE));
+ fp_mem = sp + (nargs * (2 * DEPRECATED_REGISTER_SIZE));
/* Now load as many as possible of the first arguments into registers,
and push the rest onto the stack. */
val = (char *) VALUE_CONTENTS (args[argnum]);
/* How may registers worth of storage do we need for this argument? */
- reg_demand = (len / REGISTER_SIZE) + (len % REGISTER_SIZE != 0 ? 1 : 0);
+ reg_demand = (len / DEPRECATED_REGISTER_SIZE) + (len % DEPRECATED_REGISTER_SIZE != 0 ? 1 : 0);
- if (len <= (2 * REGISTER_SIZE)
+ if (len <= (2 * DEPRECATED_REGISTER_SIZE)
&& (argreg + reg_demand - 1 <= ARG4_REGNUM))
{
/* Data passed by value. Fits in available register(s). */
{
write_register (argreg, *(unsigned long *) val);
argreg++;
- val += REGISTER_SIZE;
+ val += DEPRECATED_REGISTER_SIZE;
}
}
- else if (len <= (2 * REGISTER_SIZE) && argreg <= ARG4_REGNUM)
+ else if (len <= (2 * DEPRECATED_REGISTER_SIZE) && argreg <= ARG4_REGNUM)
{
/* Data passed by value. Does not fit in available register(s).
Use the register(s) first, then the stack. */
{
write_register (argreg, *(unsigned long *) val);
argreg++;
- val += REGISTER_SIZE;
+ val += DEPRECATED_REGISTER_SIZE;
}
else
{
- /* I guess this memory write could write the remaining data
- all at once instead of in REGISTER_SIZE chunks. */
- write_memory (fp_arg, val, REGISTER_SIZE);
- fp_arg += REGISTER_SIZE;
- val += REGISTER_SIZE;
+ /* I guess this memory write could write the
+ remaining data all at once instead of in
+ DEPRECATED_REGISTER_SIZE chunks. */
+ write_memory (fp_arg, val, DEPRECATED_REGISTER_SIZE);
+ fp_arg += DEPRECATED_REGISTER_SIZE;
+ val += DEPRECATED_REGISTER_SIZE;
}
}
}
- else if (len > (2 * REGISTER_SIZE))
+ else if (len > (2 * DEPRECATED_REGISTER_SIZE))
{
/* Data passed by reference. Put it on the stack. */
write_memory (fp_mem, val, len);
- write_memory (fp_arg, (char *) (&fp_mem), REGISTER_SIZE);
+ write_memory (fp_arg, (char *) (&fp_mem), DEPRECATED_REGISTER_SIZE);
/* fp_mem need not be word-aligned since it's just a chunk of
memory being pointed at. That is, += len would do. */
- fp_mem += reg_demand * REGISTER_SIZE;
- fp_arg += REGISTER_SIZE;
+ fp_mem += reg_demand * DEPRECATED_REGISTER_SIZE;
+ fp_arg += DEPRECATED_REGISTER_SIZE;
}
else
{
/* fp_arg must be word-aligned (i.e., don't += len) to match
the function prologue. */
- fp_arg += reg_demand * REGISTER_SIZE;
+ fp_arg += reg_demand * DEPRECATED_REGISTER_SIZE;
}
}
all saved registers. */
void
-cris_pop_frame ()
+cris_pop_frame (void)
{
register struct frame_info *fi = get_current_frame ();
register int regno;
register int stack_offset = 0;
- if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fi),
+ get_frame_base (fi),
+ get_frame_base (fi)))
{
/* This happens when we hit a breakpoint set at the entry point,
when returning from a dummy frame. */
/* Restore general registers R0 - R7. They were pushed on the stack
after SP was saved. */
- for (regno = 0; regno < FP_REGNUM; regno++)
+ for (regno = 0; regno < DEPRECATED_FP_REGNUM; regno++)
{
- if (fi->saved_regs[regno])
+ if (get_frame_saved_regs (fi)[regno])
{
write_register (regno,
- read_memory_integer (fi->saved_regs[regno], 4));
+ read_memory_integer (get_frame_saved_regs (fi)[regno], 4));
}
}
- if (fi->saved_regs[FP_REGNUM])
+ if (get_frame_saved_regs (fi)[DEPRECATED_FP_REGNUM])
{
/* Pop the frame pointer (R8). It was pushed before SP
was saved. */
- write_register (FP_REGNUM,
- read_memory_integer (fi->saved_regs[FP_REGNUM], 4));
+ write_register (DEPRECATED_FP_REGNUM,
+ read_memory_integer (get_frame_saved_regs (fi)[DEPRECATED_FP_REGNUM], 4));
stack_offset += 4;
/* Not a leaf function. */
- if (fi->saved_regs[SRP_REGNUM])
+ if (get_frame_saved_regs (fi)[SRP_REGNUM])
{
/* SRP was pushed before SP was saved. */
stack_offset += 4;
}
/* Restore the SP and adjust for R8 and (possibly) SRP. */
- write_register (SP_REGNUM, fi->saved_regs[FP_REGNUM] + stack_offset);
+ write_register (SP_REGNUM, get_frame_saved_regs (fi)[DEPRECATED_FP_REGNUM] + stack_offset);
}
else
{
}
/* Restore the PC. */
- write_register (PC_REGNUM, fi->extra_info->return_pc);
+ write_register (PC_REGNUM, get_frame_extra_info (fi)->return_pc);
}
flush_cached_frames ();
}
case 'P':
tmp = (insn >> 0xC) & 0xF;
- for (i = 0; i < NUM_SPECREGS; i++)
- /* Since we match four bits, we will give a value of
- 4 - 1 = 3 in a match. If there is a corresponding
- exact match of a special register in another pattern, it
- will get a value of 4, which will be higher. This should
- be correct in that an exact pattern would match better that
- a general pattern.
- Note that there is a reason for not returning zero; the
- pattern for "clear" is partly matched in the bit-pattern
- (the two lower bits must be zero), while the bit-pattern
- for a move from a special register is matched in the
- register constraint.
- This also means we will will have a race condition if
- there is a partly match in three bits in the bit pattern. */
- if (tmp == cris_spec_regs[i].number)
- {
- retval += 3;
- break;
- }
- if (i == NUM_SPECREGS)
+
+ for (i = 0; cris_spec_regs[i].name != NULL; i++)
+ {
+ /* Since we match four bits, we will give a value of
+ 4 - 1 = 3 in a match. If there is a corresponding
+ exact match of a special register in another pattern, it
+ will get a value of 4, which will be higher. This should
+ be correct in that an exact pattern would match better that
+ a general pattern.
+ Note that there is a reason for not returning zero; the
+ pattern for "clear" is partly matched in the bit-pattern
+ (the two lower bits must be zero), while the bit-pattern
+ for a move from a special register is matched in the
+ register constraint.
+ This also means we will will have a race condition if
+ there is a partly match in three bits in the bit pattern. */
+ if (tmp == cris_spec_regs[i].number)
+ {
+ retval += 3;
+ break;
+ }
+ }
+
+ if (cris_spec_regs[i].name == NULL)
return -1;
break;
}
}
}
+/* Just a forward declaration. */
+
+unsigned long get_data_from_address (unsigned short *inst, CORE_ADDR address);
+
/* Calculates the prefix value for the general case of offset addressing
mode. */
return;
}
- if (cris_get_mode (inst) == AUTOINC_MODE)
- {
- process_autoincrement (cris_get_size (inst), inst, inst_env);
- }
-
+ /* The calculation of prefix_value used to be after process_autoincrement,
+ but that fails for an instruction such as jsr [$r0+12] which is encoded
+ as 5f0d 0c00 30b9 when compiled with -fpic. Since PC is operand1 it
+ mustn't be incremented until we have read it and what it points at. */
inst_env->prefix_value = inst_env->reg[cris_get_operand2 (inst)];
/* The offset is an indirection of the contents of the operand1 register. */
inst_env->prefix_value +=
- read_memory_integer (inst_env->reg[cris_get_operand1 (inst)], cris_get_size (inst));
+ get_data_from_address (&inst, inst_env->reg[cris_get_operand1 (inst)]);
+ if (cris_get_mode (inst) == AUTOINC_MODE)
+ {
+ process_autoincrement (cris_get_size (inst), inst, inst_env);
+ }
+
/* A prefix doesn't change the xflag_found. But the rest of the flags
need updating. */
inst_env->slot_needed = 0;
inst_env->invalid = 1;
return;
}
- /* The increment depends on the size of the special register.
- Register P0 to P3 has the size byte, register P4 to P7 has the
- size word and register P8 to P15 has the size dword. */
- if (cris_get_operand2 (inst) < 4)
+
+ /* The increment depends on the size of the special register. */
+ if (cris_register_size (cris_get_operand2 (inst)) == 1)
{
process_autoincrement (INST_BYTE_SIZE, inst, inst_env);
}
- if (cris_get_operand2 (inst) < 8)
+ else if (cris_register_size (cris_get_operand2 (inst)) == 2)
{
process_autoincrement (INST_WORD_SIZE, inst, inst_env);
}
inst_env->invalid = 1;
return;
}
- /* The increment depends on the size of the special register.
- Register P0 to P3 has the size byte, register P4 to P7 has
- the size word and register P8 to P15 has the size dword. */
- if (cris_get_operand2 (inst) < 4)
+
+ /* The increment depends on the size of the special register. */
+ if (cris_register_size (cris_get_operand2 (inst)) == 1)
{
process_autoincrement (INST_BYTE_SIZE, inst, inst_env);
}
- if (cris_get_operand2 (inst) < 8)
+ else if (cris_register_size (cris_get_operand2 (inst)) == 2)
{
process_autoincrement (INST_WORD_SIZE, inst, inst_env);
}
static int
cris_delayed_get_disassembler (bfd_vma addr, disassemble_info *info)
{
- tm_print_insn = cris_get_disassembler (exec_bfd);
+ deprecated_tm_print_insn = cris_get_disassembler (exec_bfd);
return TARGET_PRINT_INSN (addr, info);
}
+/* Copied from <asm/elf.h>. */
+typedef unsigned long elf_greg_t;
+
+/* Same as user_regs_struct struct in <asm/user.h>. */
+typedef elf_greg_t elf_gregset_t[35];
+
+/* Unpack an elf_gregset_t into GDB's register cache. */
+
+void
+supply_gregset (elf_gregset_t *gregsetp)
+{
+ int i;
+ elf_greg_t *regp = *gregsetp;
+ static char zerobuf[4] = {0};
+
+ /* The kernel dumps all 32 registers as unsigned longs, but supply_register
+ knows about the actual size of each register so that's no problem. */
+ for (i = 0; i < NUM_GENREGS + NUM_SPECREGS; i++)
+ {
+ supply_register (i, (char *)®p[i]);
+ }
+}
+
+/* Use a local version of this function to get the correct types for
+ regsets, until multi-arch core support is ready. */
+
+static void
+fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
+ int which, CORE_ADDR reg_addr)
+{
+ elf_gregset_t gregset;
+
+ switch (which)
+ {
+ case 0:
+ if (core_reg_size != sizeof (gregset))
+ {
+ warning ("wrong size gregset struct in core file");
+ }
+ else
+ {
+ memcpy (&gregset, core_reg_sect, sizeof (gregset));
+ supply_gregset (&gregset);
+ }
+
+ default:
+ /* We've covered all the kinds of registers we know about here,
+ so this must be something we wouldn't know what to do with
+ anyway. Just ignore it. */
+ break;
+ }
+}
+
+static struct core_fns cris_elf_core_fns =
+{
+ bfd_target_elf_flavour, /* core_flavour */
+ default_check_format, /* check_format */
+ default_core_sniffer, /* core_sniffer */
+ fetch_core_registers, /* core_read_registers */
+ NULL /* next */
+};
+
+/* Fetch (and possibly build) an appropriate link_map_offsets
+ structure for native GNU/Linux CRIS targets using the struct
+ offsets defined in link.h (but without actual reference to that
+ file).
+
+ This makes it possible to access GNU/Linux CRIS shared libraries
+ from a GDB that was not built on an GNU/Linux CRIS host (for cross
+ debugging).
+
+ See gdb/solib-svr4.h for an explanation of these fields. */
+
+struct link_map_offsets *
+cris_linux_svr4_fetch_link_map_offsets (void)
+{
+ static struct link_map_offsets lmo;
+ static struct link_map_offsets *lmp = NULL;
+
+ if (lmp == NULL)
+ {
+ lmp = &lmo;
+
+ lmo.r_debug_size = 8; /* The actual size is 20 bytes, but
+ this is all we need. */
+ lmo.r_map_offset = 4;
+ lmo.r_map_size = 4;
+
+ lmo.link_map_size = 20;
+
+ lmo.l_addr_offset = 0;
+ lmo.l_addr_size = 4;
+
+ lmo.l_name_offset = 4;
+ lmo.l_name_size = 4;
+
+ lmo.l_next_offset = 12;
+ lmo.l_next_size = 4;
+
+ lmo.l_prev_offset = 16;
+ lmo.l_prev_size = 4;
+ }
+
+ return lmp;
+}
+
+static void
+cris_fpless_backtrace (char *noargs, int from_tty)
+{
+ /* Points at the instruction after the jsr (except when in innermost frame
+ where it points at the original pc). */
+ CORE_ADDR pc = 0;
+
+ /* Temporary variable, used for parsing from the start of the function that
+ the pc is in, up to the pc. */
+ CORE_ADDR tmp_pc = 0;
+ CORE_ADDR sp = 0;
+
+ /* Information about current frame. */
+ struct symtab_and_line sal;
+ char* func_name;
+
+ /* Present instruction. */
+ unsigned short insn;
+
+ /* Next instruction, lookahead. */
+ unsigned short insn_next;
+
+ /* This is to store the offset between sp at start of function and until we
+ reach push srp (if any). */
+ int sp_add_later = 0;
+ int push_srp_found = 0;
+
+ int val = 0;
+
+ /* Frame counter. */
+ int frame = 0;
+
+ /* For the innermost frame, we want to look at srp in case it's a leaf
+ function (since there's no push srp in that case). */
+ int innermost_frame = 1;
+
+ deprecated_read_register_gen (PC_REGNUM, (char *) &pc);
+ deprecated_read_register_gen (SP_REGNUM, (char *) &sp);
+
+ /* We make an explicit return when we can't find an outer frame. */
+ while (1)
+ {
+ /* Get file name and line number. */
+ sal = find_pc_line (pc, 0);
+
+ /* Get function name. */
+ find_pc_partial_function (pc, &func_name, (CORE_ADDR *) NULL,
+ (CORE_ADDR *) NULL);
+
+ /* Print information about current frame. */
+ printf_unfiltered ("#%i 0x%08lx in %s", frame++, pc, func_name);
+ if (sal.symtab)
+ {
+ printf_unfiltered (" at %s:%i", sal.symtab->filename, sal.line);
+ }
+ printf_unfiltered ("\n");
+
+ /* Get the start address of this function. */
+ tmp_pc = get_pc_function_start (pc);
+
+ /* Mini parser, only meant to find push sp and sub ...,sp from the start
+ of the function, up to the pc. */
+ while (tmp_pc < pc)
+ {
+ insn = read_memory_unsigned_integer (tmp_pc, sizeof (short));
+ tmp_pc += sizeof (short);
+ if (insn == 0xE1FC)
+ {
+ /* push <reg> 32 bit instruction */
+ insn_next = read_memory_unsigned_integer (tmp_pc,
+ sizeof (short));
+ tmp_pc += sizeof (short);
+
+ /* Recognize srp. */
+ if (insn_next == 0xBE7E)
+ {
+ /* For subsequent (not this one though) push or sub which
+ affects sp, adjust sp immediately. */
+ push_srp_found = 1;
+
+ /* Note: this will break if we ever encounter a
+ push vr (1 byte) or push ccr (2 bytes). */
+ sp_add_later += 4;
+ }
+ else
+ {
+ /* Some other register was pushed. */
+ if (push_srp_found)
+ {
+ sp += 4;
+ }
+ else
+ {
+ sp_add_later += 4;
+ }
+ }
+ }
+ else if (cris_get_operand2 (insn) == SP_REGNUM
+ && cris_get_mode (insn) == 0x0000
+ && cris_get_opcode (insn) == 0x000A)
+ {
+ /* subq <val>,sp */
+ val = cris_get_quick_value (insn);
+
+ if (push_srp_found)
+ {
+ sp += val;
+ }
+ else
+ {
+ sp_add_later += val;
+ }
+
+ }
+ else if (cris_get_operand2 (insn) == SP_REGNUM
+ /* Autoincrement addressing mode. */
+ && cris_get_mode (insn) == 0x0003
+ /* Opcode. */
+ && ((insn) & 0x03E0) >> 5 == 0x0004)
+ {
+ /* subu <val>,sp */
+ val = get_data_from_address (&insn, tmp_pc);
+
+ if (push_srp_found)
+ {
+ sp += val;
+ }
+ else
+ {
+ sp_add_later += val;
+ }
+ }
+ else if (cris_get_operand2 (insn) == SP_REGNUM
+ && ((insn & 0x0F00) >> 8) == 0x0001
+ && (cris_get_signed_offset (insn) < 0))
+ {
+ /* Immediate byte offset addressing prefix word with sp as base
+ register. Used for CRIS v8 i.e. ETRAX 100 and newer if <val>
+ is between 64 and 128.
+ movem r<regsave>,[sp=sp-<val>] */
+ val = -cris_get_signed_offset (insn);
+ insn_next = read_memory_unsigned_integer (tmp_pc,
+ sizeof (short));
+ tmp_pc += sizeof (short);
+
+ if (cris_get_mode (insn_next) == PREFIX_ASSIGN_MODE
+ && cris_get_opcode (insn_next) == 0x000F
+ && cris_get_size (insn_next) == 0x0003
+ && cris_get_operand1 (insn_next) == SP_REGNUM)
+ {
+ if (push_srp_found)
+ {
+ sp += val;
+ }
+ else
+ {
+ sp_add_later += val;
+ }
+ }
+ }
+ }
+
+ if (push_srp_found)
+ {
+ /* Reset flag. */
+ push_srp_found = 0;
+
+ /* sp should now point at where srp is stored on the stack. Update
+ the pc to the srp. */
+ pc = read_memory_unsigned_integer (sp, 4);
+ }
+ else if (innermost_frame)
+ {
+ /* We couldn't find a push srp in the prologue, so this must be
+ a leaf function, and thus we use the srp register directly.
+ This should happen at most once, for the innermost function. */
+ deprecated_read_register_gen (SRP_REGNUM, (char *) &pc);
+ }
+ else
+ {
+ /* Couldn't find an outer frame. */
+ return;
+ }
+
+ /* Reset flag. (In case the innermost frame wasn't a leaf, we don't
+ want to look at the srp register later either). */
+ innermost_frame = 0;
+
+ /* Now, add the offset for everything up to, and including push srp,
+ that was held back during the prologue parsing. */
+ sp += sp_add_later;
+ sp_add_later = 0;
+ }
+}
+
void
_initialize_cris_tdep (void)
{
gdbarch_register (bfd_arch_cris, cris_gdbarch_init, cris_dump_tdep);
/* Used in disassembly. */
- tm_print_insn = cris_delayed_get_disassembler;
+ deprecated_tm_print_insn = cris_delayed_get_disassembler;
/* CRIS-specific user-commands. */
c = add_set_cmd ("cris-version", class_support, var_integer,
(char *) &usr_cmd_cris_version,
"Set the current CRIS version.", &setlist);
- c->function.sfunc = cris_version_update;
+ set_cmd_sfunc (c, cris_version_update);
add_show_from_set (c, &showlist);
c = add_set_enum_cmd ("cris-mode", class_support, cris_mode_enums,
&usr_cmd_cris_mode,
"Set the current CRIS mode.", &setlist);
- c->function.sfunc = cris_mode_update;
+ set_cmd_sfunc (c, cris_mode_update);
add_show_from_set (c, &showlist);
c = add_set_enum_cmd ("cris-abi", class_support, cris_abi_enums,
&usr_cmd_cris_abi,
"Set the current CRIS ABI version.", &setlist);
- c->function.sfunc = cris_abi_update;
+ set_cmd_sfunc (c, cris_abi_update);
add_show_from_set (c, &showlist);
+
+ c = add_cmd ("cris-fpless-backtrace", class_support, cris_fpless_backtrace,
+ "Display call chain using the subroutine return pointer.\n"
+ "Note that this displays the address after the jump to the "
+ "subroutine.", &cmdlist);
+
+ add_core_fns (&cris_elf_core_fns);
+
}
/* Prints out all target specific values. */
{
struct gdbarch_info info;
+ /* NOTE: cagney/2002-03-17: The add_show_from_set() function clones
+ the set command passed as a parameter. The clone operation will
+ include (BUG?) any ``set'' command callback, if present.
+ Commands like ``info set'' call all the ``show'' command
+ callbacks. Unfortunatly, for ``show'' commands cloned from
+ ``set'', this includes callbacks belonging to ``set'' commands.
+ Making this worse, this only occures if add_show_from_set() is
+ called after add_cmd_sfunc() (BUG?). */
+
/* From here on, trust the user's CRIS version setting. */
- if (c->type == set_cmd)
+ if (cmd_type (c) == set_cmd)
{
usr_cmd_cris_version_valid = 1;
/* Update the current architecture, if needed. */
- memset (&info, 0, sizeof info);
+ gdbarch_info_init (&info);
if (!gdbarch_update_p (info))
internal_error (__FILE__, __LINE__, "cris_gdbarch_update: failed to update architecture.");
}
{
struct gdbarch_info info;
+ /* NOTE: cagney/2002-03-17: The add_show_from_set() function clones
+ the set command passed as a parameter. The clone operation will
+ include (BUG?) any ``set'' command callback, if present.
+ Commands like ``info set'' call all the ``show'' command
+ callbacks. Unfortunatly, for ``show'' commands cloned from
+ ``set'', this includes callbacks belonging to ``set'' commands.
+ Making this worse, this only occures if add_show_from_set() is
+ called after add_cmd_sfunc() (BUG?). */
+
/* From here on, trust the user's CRIS mode setting. */
- if (c->type == set_cmd)
+ if (cmd_type (c) == set_cmd)
{
usr_cmd_cris_mode_valid = 1;
/* Update the current architecture, if needed. */
- memset (&info, 0, sizeof info);
+ gdbarch_info_init (&info);
if (!gdbarch_update_p (info))
internal_error (__FILE__, __LINE__, "cris_gdbarch_update: failed to update architecture.");
}
{
struct gdbarch_info info;
+ /* NOTE: cagney/2002-03-17: The add_show_from_set() function clones
+ the set command passed as a parameter. The clone operation will
+ include (BUG?) any ``set'' command callback, if present.
+ Commands like ``info set'' call all the ``show'' command
+ callbacks. Unfortunatly, for ``show'' commands cloned from
+ ``set'', this includes callbacks belonging to ``set'' commands.
+ Making this worse, this only occures if add_show_from_set() is
+ called after add_cmd_sfunc() (BUG?). */
+
/* From here on, trust the user's CRIS ABI setting. */
- if (c->type == set_cmd)
+ if (cmd_type (c) == set_cmd)
{
usr_cmd_cris_abi_valid = 1;
/* Update the current architecture, if needed. */
- memset (&info, 0, sizeof info);
+ gdbarch_info_init (&info);
if (!gdbarch_update_p (info))
internal_error (__FILE__, __LINE__, "cris_gdbarch_update: failed to update architecture.");
}
if (storage_needed > 0)
{
symbol_table = (asymbol **) xmalloc (storage_needed);
- back_to = make_cleanup (free, (PTR) symbol_table);
+ back_to = make_cleanup (free, symbol_table);
number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
for (i = 0; i < number_of_symbols; i++)
cris_abi = CRIS_ABI_V2;
}
}
- else if (gdbarch_tdep (current_gdbarch))
+ else if (arches != NULL)
{
- /* No bfd available. Stick with whatever ABI we're currently using.
- (This is to avoid changing the ABI when the user updates the
- architecture with the 'set cris-version' command.) */
- cris_abi = gdbarch_tdep (current_gdbarch)->cris_abi;
+ /* No bfd available. Stick with the ABI from the most recently
+ selected architecture of this same family (the head of arches
+ always points to this). (This is to avoid changing the ABI
+ when the user updates the architecture with the 'set
+ cris-version' command.) */
+ cris_abi = gdbarch_tdep (arches->gdbarch)->cris_abi;
}
else
{
- /* No bfd, and no current architecture available. Assume it's the
- new ABI. */
+ /* No bfd, and no previously selected architecture available.
+ Assume it's the new ABI. */
cris_abi = CRIS_ABI_V2;
}
tdep = (struct gdbarch_tdep *) xmalloc (sizeof (struct gdbarch_tdep));
gdbarch = gdbarch_alloc (&info, tdep);
+ /* 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);
+
tdep->cris_version = cris_version;
tdep->cris_mode = cris_mode;
tdep->cris_abi = cris_abi;
/* INIT shall ensure that the INFO.BYTE_ORDER is non-zero. */
switch (info.byte_order)
{
- case LITTLE_ENDIAN:
+ case BFD_ENDIAN_LITTLE:
/* Ok. */
break;
- case BIG_ENDIAN:
+ case BFD_ENDIAN_BIG:
internal_error (__FILE__, __LINE__, "cris_gdbarch_init: big endian byte order in info");
break;
if (tdep->cris_abi == CRIS_ABI_ORIGINAL)
{
set_gdbarch_double_bit (gdbarch, 32);
- set_gdbarch_push_arguments (gdbarch, cris_abi_original_push_arguments);
- set_gdbarch_store_return_value (gdbarch,
+ set_gdbarch_deprecated_push_arguments (gdbarch, cris_abi_original_push_arguments);
+ set_gdbarch_deprecated_store_return_value (gdbarch,
cris_abi_original_store_return_value);
- set_gdbarch_extract_return_value
+ set_gdbarch_deprecated_extract_return_value
(gdbarch, cris_abi_original_extract_return_value);
set_gdbarch_reg_struct_has_addr
(gdbarch, cris_abi_original_reg_struct_has_addr);
else if (tdep->cris_abi == CRIS_ABI_V2)
{
set_gdbarch_double_bit (gdbarch, 64);
- set_gdbarch_push_arguments (gdbarch, cris_abi_v2_push_arguments);
- set_gdbarch_store_return_value (gdbarch, cris_abi_v2_store_return_value);
- set_gdbarch_extract_return_value (gdbarch,
- cris_abi_v2_extract_return_value);
+ set_gdbarch_deprecated_push_arguments (gdbarch, cris_abi_v2_push_arguments);
+ set_gdbarch_deprecated_store_return_value (gdbarch, cris_abi_v2_store_return_value);
+ set_gdbarch_deprecated_extract_return_value
+ (gdbarch, cris_abi_v2_extract_return_value);
set_gdbarch_reg_struct_has_addr (gdbarch,
cris_abi_v2_reg_struct_has_addr);
}
which means we have to set this explicitly. */
set_gdbarch_long_double_bit (gdbarch, 64);
- /* Floating point is IEEE compatible. */
- set_gdbarch_ieee_float (gdbarch, 1);
-
/* There are 32 registers (some of which may not be implemented). */
set_gdbarch_num_regs (gdbarch, 32);
set_gdbarch_sp_regnum (gdbarch, 14);
- set_gdbarch_fp_regnum (gdbarch, 8);
+ set_gdbarch_deprecated_fp_regnum (gdbarch, 8);
set_gdbarch_pc_regnum (gdbarch, 15);
set_gdbarch_register_name (gdbarch, cris_register_name);
/* Length of ordinary registers used in push_word and a few other places.
REGISTER_RAW_SIZE is the real way to know how big a register is. */
- set_gdbarch_register_size (gdbarch, 4);
+ set_gdbarch_deprecated_register_size (gdbarch, 4);
/* NEW */
set_gdbarch_register_bytes_ok (gdbarch, cris_register_bytes_ok);
internal_error (__FILE__, __LINE__, "cris_gdbarch_init: unknown CRIS version");
}
- set_gdbarch_register_bytes (gdbarch, register_bytes);
+ set_gdbarch_deprecated_register_bytes (gdbarch, register_bytes);
/* Returns the register offset for the first byte of register regno's space
in the saved register state. */
set_gdbarch_register_raw_size (gdbarch, cris_register_size);
/* The largest value REGISTER_RAW_SIZE can have. */
- set_gdbarch_max_register_raw_size (gdbarch, 32);
+ set_gdbarch_deprecated_max_register_raw_size (gdbarch, 32);
/* The length of the registers in the program's representation. */
set_gdbarch_register_virtual_size (gdbarch, cris_register_size);
/* The largest value REGISTER_VIRTUAL_SIZE can have. */
- set_gdbarch_max_register_virtual_size (gdbarch, 32);
+ set_gdbarch_deprecated_max_register_virtual_size (gdbarch, 32);
set_gdbarch_register_virtual_type (gdbarch, cris_register_virtual_type);
/* Use generic dummy frames. */
- set_gdbarch_use_generic_dummy_frames (gdbarch, 1);
-
- /* Where to execute the call in the memory segments. */
- set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
- set_gdbarch_call_dummy_address (gdbarch, entry_point_address);
-
- /* Start execution at the beginning of dummy. */
- set_gdbarch_call_dummy_start_offset (gdbarch, 0);
- set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0);
-
- /* Set to 1 since call_dummy_breakpoint_offset was defined. */
- set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1);
/* Read all about dummy frames in blockframe.c. */
- set_gdbarch_call_dummy_length (gdbarch, 0);
- set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_at_entry_point);
+ set_gdbarch_deprecated_pc_in_call_dummy (gdbarch, deprecated_pc_in_call_dummy_at_entry_point);
/* Defined to 1 to indicate that the target supports inferior function
calls. */
- set_gdbarch_call_dummy_p (gdbarch, 1);
- set_gdbarch_call_dummy_words (gdbarch, 0);
- set_gdbarch_sizeof_call_dummy_words (gdbarch, 0);
+ set_gdbarch_deprecated_call_dummy_words (gdbarch, 0);
+ set_gdbarch_deprecated_sizeof_call_dummy_words (gdbarch, 0);
- /* No stack adjustment needed when peforming an inferior function call. */
- set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
- set_gdbarch_fix_call_dummy (gdbarch, generic_fix_call_dummy);
-
- set_gdbarch_get_saved_register (gdbarch, generic_get_saved_register);
+ set_gdbarch_deprecated_get_saved_register (gdbarch, deprecated_generic_get_saved_register);
/* No register requires conversion from raw format to virtual format. */
set_gdbarch_register_convertible (gdbarch, generic_register_convertible_not);
- set_gdbarch_push_dummy_frame (gdbarch, generic_push_dummy_frame);
- set_gdbarch_push_return_address (gdbarch, cris_push_return_address);
- set_gdbarch_pop_frame (gdbarch, cris_pop_frame);
+ set_gdbarch_deprecated_push_return_address (gdbarch, cris_push_return_address);
+ set_gdbarch_deprecated_pop_frame (gdbarch, cris_pop_frame);
- set_gdbarch_store_struct_return (gdbarch, cris_store_struct_return);
- set_gdbarch_extract_struct_value_address (gdbarch,
- cris_extract_struct_value_address);
+ set_gdbarch_deprecated_store_struct_return (gdbarch, cris_store_struct_return);
+ set_gdbarch_deprecated_extract_struct_value_address
+ (gdbarch, cris_extract_struct_value_address);
set_gdbarch_use_struct_convention (gdbarch, cris_use_struct_convention);
- set_gdbarch_frame_init_saved_regs (gdbarch, cris_frame_init_saved_regs);
- set_gdbarch_init_extra_frame_info (gdbarch, cris_init_extra_frame_info);
+ set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, cris_frame_init_saved_regs);
+ set_gdbarch_deprecated_init_extra_frame_info (gdbarch, cris_init_extra_frame_info);
set_gdbarch_skip_prologue (gdbarch, cris_skip_prologue);
set_gdbarch_prologue_frameless_p (gdbarch, generic_prologue_frameless_p);
set_gdbarch_frame_args_skip (gdbarch, 0);
set_gdbarch_frameless_function_invocation
(gdbarch, cris_frameless_function_invocation);
- set_gdbarch_frame_chain (gdbarch, cris_frame_chain);
- set_gdbarch_frame_chain_valid (gdbarch, generic_file_frame_chain_valid);
+ set_gdbarch_deprecated_frame_chain (gdbarch, cris_frame_chain);
- set_gdbarch_frame_saved_pc (gdbarch, cris_frame_saved_pc);
- set_gdbarch_frame_args_address (gdbarch, cris_frame_args_address);
- set_gdbarch_frame_locals_address (gdbarch, cris_frame_locals_address);
- set_gdbarch_saved_pc_after_call (gdbarch, cris_saved_pc_after_call);
+ set_gdbarch_deprecated_frame_saved_pc (gdbarch, cris_frame_saved_pc);
+ set_gdbarch_deprecated_saved_pc_after_call (gdbarch, cris_saved_pc_after_call);
set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown);
- /* No extra stack alignment needed. Set to 1 by default. */
- set_gdbarch_extra_stack_alignment_needed (gdbarch, 0);
-
/* Helpful for backtracing and returning in a call dummy. */
set_gdbarch_save_dummy_frame_tos (gdbarch, generic_save_dummy_frame_tos);
+ /* Should be using push_dummy_call. */
+ set_gdbarch_deprecated_dummy_write_sp (gdbarch, generic_target_write_sp);
+
+ /* Use target_specific function to define link map offsets. */
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, cris_linux_svr4_fetch_link_map_offsets);
+
return gdbarch;
}