#include "gdbcmd.h"
#include "regcache.h"
#include "cp-abi.h"
+#include "block.h"
#include <errno.h>
#include "gdb_string.h"
struct value *val;
char *raw_buffer = (char*) alloca (MAX_REGISTER_RAW_SIZE);
int use_buffer = 0;
+ struct frame_id old_frame;
if (!toval->modifiable)
error ("Left operand of assignment is not a modifiable lvalue.");
}
}
+ /* Since modifying a register can trash the frame chain, and modifying memory
+ can trash the frame cache, we save the old frame and then restore the new
+ frame afterwards. */
+ old_frame = get_frame_id (deprecated_selected_frame);
+
switch (VALUE_LVAL (toval))
{
case lval_internalvar:
case lval_reg_frame_relative:
case lval_register:
{
- struct frame_id old_frame;
/* value is stored in a series of registers in the frame
specified by the structure. Copy that value out, modify
it, and copy it back in. */
int regno;
struct frame_info *frame;
- /* Since modifying a register can trash the frame chain, we
- save the old frame and then restore the new frame
- afterwards. */
- old_frame = get_frame_id (deprecated_selected_frame);
-
/* Figure out which frame this is in currently. */
if (VALUE_LVAL (toval) == lval_register)
{
register_changed_hook (-1);
target_changed_event ();
- /* Assigning to the stack pointer, frame pointer, and other
- (architecture and calling convention specific) registers
- may cause the frame cache to be out of date. We just do
- this on all assignments to registers for simplicity; I
- doubt the slowdown matters. */
- reinit_frame_cache ();
-
- /* Having destoroyed the frame cache, restore the selected
- frame. */
- /* FIXME: cagney/2002-11-02: There has to be a better way of
- doing this. Instead of constantly saving/restoring the
- frame. Why not create a get_selected_frame() function
- that, having saved the selected frame's ID can
- automatically re-find the previously selected frame
- automatically. */
- {
- struct frame_info *fi = frame_find_by_id (old_frame);
- if (fi != NULL)
- select_frame (fi);
- }
}
break;
error ("Left operand of assignment is not an lvalue.");
}
+ /* Assigning to the stack pointer, frame pointer, and other
+ (architecture and calling convention specific) registers may
+ cause the frame cache to be out of date. Assigning to memory
+ also can. We just do this on all assignments to registers or
+ memory, for simplicity's sake; I doubt the slowdown matters. */
+ switch (VALUE_LVAL (toval))
+ {
+ case lval_memory:
+ case lval_register:
+ case lval_reg_frame_relative:
+
+ reinit_frame_cache ();
+
+ /* Having destoroyed the frame cache, restore the selected frame. */
+
+ /* FIXME: cagney/2002-11-02: There has to be a better way of
+ doing this. Instead of constantly saving/restoring the
+ frame. Why not create a get_selected_frame() function that,
+ having saved the selected frame's ID can automatically
+ re-find the previously selected frame automatically. */
+
+ {
+ struct frame_info *fi = frame_find_by_id (old_frame);
+ if (fi != NULL)
+ select_frame (fi);
+ }
+
+ break;
+ default:
+ break;
+ }
+
/* If the field does not entirely fill a LONGEST, then zero the sign bits.
If the field is signed, and is negative, then sign extend. */
if ((VALUE_BITSIZE (toval) > 0)
if (!frame)
{
if (BLOCK_FUNCTION (b)
- && SYMBOL_SOURCE_NAME (BLOCK_FUNCTION (b)))
+ && SYMBOL_PRINT_NAME (BLOCK_FUNCTION (b)))
error ("No frame is currently executing in block %s.",
- SYMBOL_SOURCE_NAME (BLOCK_FUNCTION (b)));
+ SYMBOL_PRINT_NAME (BLOCK_FUNCTION (b)));
else
error ("No frame is currently executing in specified block");
}
val = read_var_value (var, frame);
if (!val)
- error ("Address of symbol \"%s\" is unknown.", SYMBOL_SOURCE_NAME (var));
+ error ("Address of symbol \"%s\" is unknown.", SYMBOL_PRINT_NAME (var));
return val;
}
}
CORE_ADDR
-default_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
- int struct_return, CORE_ADDR struct_addr)
+legacy_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
+ int struct_return, CORE_ADDR struct_addr)
{
/* ASSERT ( !struct_return); */
int i;
ARGS is modified to contain coerced values. */
-static struct value *
-hand_function_call (struct value *function, int nargs, struct value **args)
+struct value *
+call_function_by_hand (struct value *function, int nargs, struct value **args)
{
register CORE_ADDR sp;
register int i;
static ULONGEST *dummy;
int sizeof_dummy1;
char *dummy1;
+ CORE_ADDR dummy_addr;
CORE_ADDR old_sp;
struct type *value_type;
unsigned char struct_return;
inf_status = save_inferior_status (1);
inf_status_cleanup = make_cleanup_restore_inferior_status (inf_status);
- /* PUSH_DUMMY_FRAME is responsible for saving the inferior registers
- (and POP_FRAME for restoring them). (At least on most machines)
- they are saved on the stack in the inferior. */
- PUSH_DUMMY_FRAME;
+ if (DEPRECATED_PUSH_DUMMY_FRAME_P ())
+ {
+ /* DEPRECATED_PUSH_DUMMY_FRAME is responsible for saving the
+ inferior registers (and frame_pop() for restoring them). (At
+ least on most machines) they are saved on the stack in the
+ inferior. */
+ DEPRECATED_PUSH_DUMMY_FRAME;
+ }
+ else
+ {
+ /* FIXME: cagney/2003-02-26: Step zero of this little tinker is
+ to extract the generic dummy frame code from the architecture
+ vector. Hence this direct call.
+
+ A follow-on change is to modify this interface so that it takes
+ thread OR frame OR tpid as a parameter, and returns a dummy
+ frame handle. The handle can then be used further down as a
+ parameter SAVE_DUMMY_FRAME_TOS. Hmm, thinking about it, since
+ everything is ment to be using generic dummy frames, why not
+ even use some of the dummy frame code to here - do a regcache
+ dup and then pass the duped regcache, along with all the other
+ stuff, at one single point.
+
+ In fact, you can even save the structure's return address in the
+ dummy frame and fix one of those nasty lost struct return edge
+ conditions. */
+ generic_push_dummy_frame ();
+ }
old_sp = read_sp ();
be able to correctly perform back traces. If a target is
having trouble with backtraces, first thing to do is add
FRAME_ALIGN() to its architecture vector. After that, try
- adding SAVE_DUMMY_FRAME_TOS() and modifying FRAME_CHAIN so that
- when the next outer frame is a generic dummy, it returns the
- current frame's base. */
+ adding SAVE_DUMMY_FRAME_TOS() and modifying
+ DEPRECATED_FRAME_CHAIN so that when the next outer frame is a
+ generic dummy, it returns the current frame's base. */
sp = old_sp;
if (INNER_THAN (1, 2))
real_pc = FIX_CALL_DUMMY (dummy1, start_sp, funaddr, nargs, args,
value_type, using_gcc);
#else
- FIX_CALL_DUMMY (dummy1, start_sp, funaddr, nargs, args,
- value_type, using_gcc);
+ if (FIX_CALL_DUMMY_P ())
+ {
+ /* gdb_assert (CALL_DUMMY_LOCATION == ON_STACK) true? */
+ FIX_CALL_DUMMY (dummy1, start_sp, funaddr, nargs, args, value_type,
+ using_gcc);
+ }
real_pc = start_sp;
#endif
- if (CALL_DUMMY_LOCATION == ON_STACK)
+ switch (CALL_DUMMY_LOCATION)
{
+ case ON_STACK:
+ dummy_addr = start_sp;
write_memory (start_sp, (char *) dummy1, sizeof_dummy1);
if (DEPRECATED_USE_GENERIC_DUMMY_FRAMES)
generic_save_call_dummy_addr (start_sp, start_sp + sizeof_dummy1);
- }
-
- if (CALL_DUMMY_LOCATION == BEFORE_TEXT_END)
- {
- /* Convex Unix prohibits executing in the stack segment. */
- /* Hope there is empty room at the top of the text segment. */
- extern CORE_ADDR text_end;
- static int checked = 0;
- if (!checked)
- for (start_sp = text_end - sizeof_dummy1; start_sp < text_end; ++start_sp)
- if (read_memory_integer (start_sp, 1) != 0)
- error ("text segment full -- no place to put call");
- checked = 1;
- sp = old_sp;
- real_pc = text_end - sizeof_dummy1;
- write_memory (real_pc, (char *) dummy1, sizeof_dummy1);
- if (DEPRECATED_USE_GENERIC_DUMMY_FRAMES)
- generic_save_call_dummy_addr (real_pc, real_pc + sizeof_dummy1);
- }
-
- if (CALL_DUMMY_LOCATION == AFTER_TEXT_END)
- {
- extern CORE_ADDR text_end;
- int errcode;
- sp = old_sp;
- real_pc = text_end;
- errcode = target_write_memory (real_pc, (char *) dummy1, sizeof_dummy1);
- if (errcode != 0)
- error ("Cannot write text segment -- call_function failed");
- if (DEPRECATED_USE_GENERIC_DUMMY_FRAMES)
- generic_save_call_dummy_addr (real_pc, real_pc + sizeof_dummy1);
- }
-
- if (CALL_DUMMY_LOCATION == AT_ENTRY_POINT)
- {
+ break;
+ case AT_ENTRY_POINT:
real_pc = funaddr;
+ dummy_addr = CALL_DUMMY_ADDRESS ();
if (DEPRECATED_USE_GENERIC_DUMMY_FRAMES)
/* NOTE: cagney/2002-04-13: The entry point is going to be
modified with a single breakpoint. */
generic_save_call_dummy_addr (CALL_DUMMY_ADDRESS (),
CALL_DUMMY_ADDRESS () + 1);
+ break;
+ default:
+ internal_error (__FILE__, __LINE__, "bad switch");
}
#ifdef lint
{
int len = TYPE_LENGTH (value_type);
if (STACK_ALIGN_P ())
- /* MVS 11/22/96: I think at least some of this stack_align
- code is really broken. Better to let PUSH_ARGUMENTS adjust
- the stack in a target-defined manner. */
+ /* NOTE: cagney/2003-03-22: Should rely on frame align, rather
+ than stack align to force the alignment of the stack. */
len = STACK_ALIGN (len);
if (INNER_THAN (1, 2))
{
on other architectures. This is because all the alignment is
taken care of in the above code (ifdef REG_STRUCT_HAS_ADDR) and
in hppa_push_arguments */
- if (EXTRA_STACK_ALIGNMENT_NEEDED)
+ /* NOTE: cagney/2003-03-24: The below code is very broken. Given an
+ odd sized parameter the below will mis-align the stack. As was
+ suggested back in '96, better to let PUSH_ARGUMENTS handle it. */
+ if (DEPRECATED_EXTRA_STACK_ALIGNMENT_NEEDED)
{
/* MVS 11/22/96: I think at least some of this stack_align code
- is really broken. Better to let PUSH_ARGUMENTS adjust the
+ is really broken. Better to let push_dummy_call() adjust the
stack in a target-defined manner. */
if (STACK_ALIGN_P () && INNER_THAN (1, 2))
{
for (i = nargs - 1; i >= 0; i--)
len += TYPE_LENGTH (VALUE_ENCLOSING_TYPE (args[i]));
- if (CALL_DUMMY_STACK_ADJUST_P)
- len += CALL_DUMMY_STACK_ADJUST;
+ if (DEPRECATED_CALL_DUMMY_STACK_ADJUST_P ())
+ len += DEPRECATED_CALL_DUMMY_STACK_ADJUST;
sp -= STACK_ALIGN (len) - len;
}
}
- sp = PUSH_ARGUMENTS (nargs, args, sp, struct_return, struct_addr);
+ /* Create the dummy stack frame. Pass in the call dummy address as,
+ presumably, the ABI code knows where, in the call dummy, the
+ return address should be pointed. */
+ if (gdbarch_push_dummy_call_p (current_gdbarch))
+ /* When there is no push_dummy_call method, should this code
+ simply error out. That would the implementation of this method
+ for all ABIs (which is probably a good thing). */
+ sp = gdbarch_push_dummy_call (current_gdbarch, current_regcache,
+ dummy_addr, nargs, args, sp, struct_return,
+ struct_addr);
+ else if (DEPRECATED_PUSH_ARGUMENTS_P ())
+ /* Keep old targets working. */
+ sp = DEPRECATED_PUSH_ARGUMENTS (nargs, args, sp, struct_return,
+ struct_addr);
+ else
+ sp = legacy_push_arguments (nargs, args, sp, struct_return, struct_addr);
- if (PUSH_RETURN_ADDRESS_P ())
+ if (DEPRECATED_PUSH_RETURN_ADDRESS_P ())
/* for targets that use no CALL_DUMMY */
/* There are a number of targets now which actually don't write
any CALL_DUMMY instructions into the target, but instead just
return-address register as appropriate. Formerly this has been
done in PUSH_ARGUMENTS, but that's overloading its
functionality a bit, so I'm making it explicit to do it here. */
- sp = PUSH_RETURN_ADDRESS (real_pc, sp);
+ sp = DEPRECATED_PUSH_RETURN_ADDRESS (real_pc, sp);
- if (STACK_ALIGN_P () && !INNER_THAN (1, 2))
+ /* NOTE: cagney/2003-03-23: Diable this code when there is a
+ push_dummy_call() method. Since that method will have already
+ handled any alignment issues, the code below is entirely
+ redundant. */
+ if (!gdbarch_push_dummy_call_p (current_gdbarch)
+ && STACK_ALIGN_P () && !INNER_THAN (1, 2))
{
/* If stack grows up, we must leave a hole at the bottom, note
that sp already has been advanced for the arguments! */
- if (CALL_DUMMY_STACK_ADJUST_P)
- sp += CALL_DUMMY_STACK_ADJUST;
+ if (DEPRECATED_CALL_DUMMY_STACK_ADJUST_P ())
+ sp += DEPRECATED_CALL_DUMMY_STACK_ADJUST;
sp = STACK_ALIGN (sp);
}
/* MVS 11/22/96: I think at least some of this stack_align code is
really broken. Better to let PUSH_ARGUMENTS adjust the stack in
a target-defined manner. */
- if (CALL_DUMMY_STACK_ADJUST_P)
+ if (DEPRECATED_CALL_DUMMY_STACK_ADJUST_P ())
if (INNER_THAN (1, 2))
{
/* stack grows downward */
- sp -= CALL_DUMMY_STACK_ADJUST;
+ sp -= DEPRECATED_CALL_DUMMY_STACK_ADJUST;
}
/* Store the address at which the structure is supposed to be
- written. Note that this (and the code which reserved the space
- above) assumes that gcc was used to compile this function. Since
- it doesn't cost us anything but space and if the function is pcc
- it will ignore this value, we will make that assumption.
-
- Also note that on some machines (like the sparc) pcc uses a
- convention like gcc's. */
-
- if (struct_return)
- STORE_STRUCT_RETURN (struct_addr, sp);
+ written. */
+ /* NOTE: 2003-03-24: Since PUSH_ARGUMENTS can (and typically does)
+ store the struct return address, this call is entirely redundant. */
+ if (struct_return && DEPRECATED_STORE_STRUCT_RETURN_P ())
+ DEPRECATED_STORE_STRUCT_RETURN (struct_addr, sp);
/* Write the stack pointer. This is here because the statements above
might fool with it. On SPARC, this write also stores the register
window into the right place in the new stack frame, which otherwise
wouldn't happen. (See store_inferior_registers in sparc-nat.c.) */
- write_sp (sp);
+ /* NOTE: cagney/2003-03-23: Disable this code when there is a
+ push_dummy_call() method. Since that method will have already
+ stored the stack pointer (as part of creating the fake call
+ frame), and none of the code following that code adjusts the
+ stack-pointer value, the below call is entirely redundant. */
+ if (DEPRECATED_DUMMY_WRITE_SP_P ())
+ DEPRECATED_DUMMY_WRITE_SP (sp);
if (SAVE_DUMMY_FRAME_TOS_P ())
SAVE_DUMMY_FRAME_TOS (sp);
symbol = find_pc_function (funaddr);
if (symbol)
{
- name = SYMBOL_SOURCE_NAME (symbol);
+ name = SYMBOL_PRINT_NAME (symbol);
}
else
{
if (msymbol)
{
- name = SYMBOL_SOURCE_NAME (msymbol);
+ name = SYMBOL_PRINT_NAME (msymbol);
}
}
if (name == NULL)
}
}
-struct value *
-call_function_by_hand (struct value *function, int nargs, struct value **args)
-{
- if (CALL_DUMMY_P)
- {
- return hand_function_call (function, nargs, args);
- }
- else
- {
- error ("Cannot invoke functions on this machine.");
- }
-}
-\f
-
-
/* Create a value for an array by allocating space in the inferior, copying
the data into that space, and then setting up an array value.
else
{
int i = -1;
- func_name = cplus_demangle (SYMBOL_NAME (fsym), DMGL_NO_OPTS);
+ func_name = cplus_demangle (DEPRECATED_SYMBOL_NAME (fsym), DMGL_NO_OPTS);
/* If the name is NULL this must be a C-style function.
Just return the same symbol. */