--- Begin Message ---
- From: Andrew Cagney <ac131313 at redhat dot com>
- To: gdb-patches at sources dot redhat dot com
- Date: Wed, 09 Apr 2003 21:08:36 -0400
- Subject: [patch rfc] Merge call_function_by_hand & run_stack_dummy; move toinfcall.c?
- Delivery-date: Wed, 09 Apr 2003 21:09:40 -0400
- Envelope-to: cagney@gnu.org
Hello,
This patch inlines run_stack_dummy into it's only caller -
call_function_by_hand (nee hand_function_call). Going by some of the
comments, there were once many callers but that is no more.
This opens the way for more cleanup / rationalization of
call_function_by_hand. For instance:
- rationalize the computation of the the dummy breakpoint address
- ditto for the dummy entry point
- long term, split this in two; move the code handling the return to a
breakpoint callback (just need to add breakpoint callbacks) and thence;
make the expression evaluator async
Question is, should this code be moved to a separate file? It's come up
before:
http://sources.redhat.com/ml/gdb/2002-09/msg00485.html
dummy-frame.c now contains code implementing the `dummy-frame', so
infcall.c.
Andrew
2003-04-09 Andrew Cagney <cagney at redhat dot com>
* infcmd.c (breakpoint_auto_delete_contents): Move from here ...
* valops.c (breakpoint_auto_delete_contents): ... to here.
* inferior.h (run_stack_dummy): Delete declaration.
* infcmd.c (run_stack_dummy): Delete function. Merge code into
call_function_by_hand.
* valops.c: Include "symfile.h".
(call_function_by_hand): Inline run_stack_dummy code.
* Makefile.in (valops.o): Update dependencies.
* v850-tdep.c, target.h: Update comments.
* sparc-tdep.c (sparc_fix_call_dummy): Update comments.
* sh-tdep.c (sh_init_extra_frame_info): Update comments.
(sh64_init_extra_frame_info): Update comments.
* mn10300-tdep.c: Update comments.
* mcore-tdep.c (mcore_init_extra_frame_info): Update comments.
* config/sparc/tm-sparc.h: Update comments.
* breakpoint.h: Update comments.
* avr-tdep.c (avr_init_extra_frame_info): Update comments.
* arm-tdep.c: Update comment.
Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.360
diff -u -r1.360 Makefile.in
--- Makefile.in 6 Apr 2003 01:13:58 -0000 1.360
+++ Makefile.in 10 Apr 2003 00:41:28 -0000
@@ -2305,8 +2305,8 @@
$(doublest_h)
valops.o: valops.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(value_h) $(frame_h) \
$(inferior_h) $(gdbcore_h) $(target_h) $(demangle_h) $(language_h) \
- $(gdbcmd_h) $(regcache_h) $(cp_abi_h) $(gdb_string_h) \
- $(gdb_assert_h) $(block_h)
+ $(gdbcmd_h) $(regcache_h) $(cp_abi_h) $(block_h) $(gdb_string_h) \
+ $(gdb_assert_h) $(symfile_h)
valprint.o: valprint.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \
$(value_h) $(gdbcore_h) $(gdbcmd_h) $(target_h) $(language_h) \
$(annotate_h) $(valprint_h) $(floatformat_h) $(doublest_h)
Index: arm-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/arm-tdep.c,v
retrieving revision 1.128
diff -u -r1.128 arm-tdep.c
--- arm-tdep.c 6 Apr 2003 19:08:17 -0000 1.128
+++ arm-tdep.c 10 Apr 2003 00:41:34 -0000
@@ -1257,8 +1257,8 @@
FIXME rearnsha 2002-02018: Tweeking current_gdbarch is not an
optimal solution, but the call to arm_fix_call_dummy is immediately
- followed by a call to run_stack_dummy, which is the only function
- where call_dummy_breakpoint_offset is actually used. */
+ followed by a call to call_function_by_hand, which is the only
+ function where call_dummy_breakpoint_offset is actually used. */
static void
Index: avr-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/avr-tdep.c,v
retrieving revision 1.41
diff -u -r1.41 avr-tdep.c
--- avr-tdep.c 1 Apr 2003 17:17:27 -0000 1.41
+++ avr-tdep.c 10 Apr 2003 00:41:36 -0000
@@ -753,8 +753,8 @@
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. */
+ /* 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),
AVR_PC_REGNUM));
}
Index: breakpoint.h
===================================================================
RCS file: /cvs/src/src/gdb/breakpoint.h,v
retrieving revision 1.19
diff -u -r1.19 breakpoint.h
--- breakpoint.h 20 Feb 2003 00:01:05 -0000 1.19
+++ breakpoint.h 10 Apr 2003 00:41:36 -0000
@@ -623,7 +623,7 @@
enabled watchpoints. When disabled, the watchpoints are marked
call_disabled. When reenabled, they are marked enabled.
- The intended client of these functions is infcmd.c\run_stack_dummy.
+ The intended client of these functions is call_function_by_hand.
The inferior must be stopped, and all breakpoints removed, when
these functions are used.
Index: cris-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/cris-tdep.c,v
retrieving revision 1.66
diff -u -r1.66 cris-tdep.c
--- cris-tdep.c 5 Apr 2003 18:54:38 -0000 1.66
+++ cris-tdep.c 10 Apr 2003 00:41:41 -0000
@@ -1216,8 +1216,8 @@
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. */
+ /* 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),
Index: infcmd.c
===================================================================
RCS file: /cvs/src/src/gdb/infcmd.c,v
retrieving revision 1.78
diff -u -r1.78 infcmd.c
--- infcmd.c 8 Apr 2003 19:21:14 -0000 1.78
+++ infcmd.c 10 Apr 2003 00:41:47 -0000
@@ -115,8 +115,6 @@
#define GO_USAGE "Usage: go <location>\n"
-static void breakpoint_auto_delete_contents (void *);
-
#define ERROR_NO_INFERIOR \
if (!target_has_execution) error ("The program is not being run.");
@@ -950,112 +948,6 @@
proceed (oursig == TARGET_SIGNAL_0 ? (CORE_ADDR) -1 : stop_pc, oursig, 0);
}
-/* Call breakpoint_auto_delete on the current contents of the bpstat
- pointed to by arg (which is really a bpstat *). */
-
-static void
-breakpoint_auto_delete_contents (void *arg)
-{
- breakpoint_auto_delete (*(bpstat *) arg);
-}
-
-
-/* Execute a "stack dummy", a piece of code stored in the stack
- by the debugger to be executed in the inferior.
-
- To call: first, do PUSH_DUMMY_FRAME.
- Then push the contents of the dummy. It should end with a breakpoint insn.
- Then call here, passing address at which to start the dummy.
-
- The contents of all registers are saved before the dummy frame is popped
- and copied into the buffer BUFFER.
-
- The dummy's frame is automatically popped whenever that break is hit.
- If that is the first time the program stops, run_stack_dummy
- returns to its caller with that frame already gone and returns 0.
-
- Otherwise, run_stack-dummy returns a non-zero value.
- If the called function receives a random signal, we do not allow the user
- to continue executing it as this may not work. The dummy frame is poped
- and we return 1.
- If we hit a breakpoint, we leave the frame in place and return 2 (the frame
- will eventually be popped when we do hit the dummy end breakpoint). */
-
-int
-run_stack_dummy (CORE_ADDR addr, struct regcache *buffer)
-{
- struct cleanup *old_cleanups = make_cleanup (null_cleanup, 0);
- int saved_async = 0;
- struct breakpoint *bpt;
- struct symtab_and_line sal;
-
- /* Now proceed, having reached the desired place. */
- clear_proceed_status ();
-
- init_sal (&sal); /* initialize to zeroes */
- if (CALL_DUMMY_LOCATION == AT_ENTRY_POINT)
- {
- sal.pc = CALL_DUMMY_ADDRESS ();
- }
- else
- {
- /* If defined, CALL_DUMMY_BREAKPOINT_OFFSET is where we need to
- put a breakpoint instruction. If not, the call dummy already
- has the breakpoint instruction in it.
-
- ADDR IS THE ADDRESS of the call dummy plus the
- CALL_DUMMY_START_OFFSET, so we need to subtract the
- CALL_DUMMY_START_OFFSET. */
- sal.pc = addr - CALL_DUMMY_START_OFFSET + CALL_DUMMY_BREAKPOINT_OFFSET;
- }
- sal.section = find_pc_overlay (sal.pc);
-
- {
- /* Set up a frame ID for the dummy frame so we can pass it to
- set_momentary_breakpoint. We need to give the breakpoint a
- frame ID so that the breakpoint code can correctly re-identify
- the dummy breakpoint. */
- struct frame_id frame = frame_id_build (read_fp (), sal.pc);
- /* Create a momentary breakpoint at the return address of the
- inferior. That way it breaks when it returns. */
- bpt = set_momentary_breakpoint (sal, frame, bp_call_dummy);
- bpt->disposition = disp_del;
- }
-
- /* If all error()s out of proceed ended up calling normal_stop (and
- perhaps they should; it already does in the special case of error
- out of resume()), then we wouldn't need this. */
- make_cleanup (breakpoint_auto_delete_contents, &stop_bpstat);
-
- disable_watchpoints_before_interactive_call_start ();
- proceed_to_finish = 1; /* We want stop_registers, please... */
-
- if (target_can_async_p ())
- saved_async = target_async_mask (0);
-
- proceed (addr, TARGET_SIGNAL_0, 0);
-
- if (saved_async)
- target_async_mask (saved_async);
-
- enable_watchpoints_after_interactive_call_stop ();
-
- discard_cleanups (old_cleanups);
-
- /* We can stop during an inferior call because a signal is received. */
- if (stopped_by_random_signal)
- return 1;
-
- /* We may also stop prematurely because we hit a breakpoint in the
- called routine. */
- if (!stop_stack_dummy)
- return 2;
-
- /* On normal return, the stack dummy has been popped already. */
- regcache_cpy_no_passthrough (buffer, stop_registers);
- return 0;
-}
-
/* Proceed until we reach a different source line with pc greater than
our current one or exit the function. We skip calls in both cases.
Index: inferior.h
===================================================================
RCS file: /cvs/src/src/gdb/inferior.h,v
retrieving revision 1.51
diff -u -r1.51 inferior.h
--- inferior.h 8 Apr 2003 19:21:14 -0000 1.51
+++ inferior.h 10 Apr 2003 00:41:47 -0000
@@ -160,8 +160,6 @@
extern void terminal_ours (void);
-extern int run_stack_dummy (CORE_ADDR , struct regcache *);
-
extern CORE_ADDR read_pc (void);
extern CORE_ADDR read_pc_pid (ptid_t);
Index: mcore-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/mcore-tdep.c,v
retrieving revision 1.55
diff -u -r1.55 mcore-tdep.c
--- mcore-tdep.c 1 Apr 2003 17:17:29 -0000 1.55
+++ mcore-tdep.c 10 Apr 2003 00:41:48 -0000
@@ -1058,8 +1058,8 @@
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. */
+ /* 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));
}
else
Index: mn10300-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/mn10300-tdep.c,v
retrieving revision 1.70
diff -u -r1.70 mn10300-tdep.c
--- mn10300-tdep.c 1 Apr 2003 17:17:29 -0000 1.70
+++ mn10300-tdep.c 10 Apr 2003 00:41:49 -0000
@@ -892,9 +892,10 @@
always be correct. mn10300_analyze_prologue will fix fi->frame if
it's not valid.
- We can be called with the PC in the call dummy under two circumstances.
- First, during normal backtracing, second, while figuring out the frame
- pointer just prior to calling the target function (see run_stack_dummy). */
+ We can be called with the PC in the call dummy under two
+ circumstances. First, during normal backtracing, second, while
+ figuring out the frame pointer just prior to calling the target
+ function (see call_function_by_hand). */
static void
mn10300_init_extra_frame_info (int fromleaf, struct frame_info *fi)
Index: sh-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/sh-tdep.c,v
retrieving revision 1.115
diff -u -r1.115 sh-tdep.c
--- sh-tdep.c 5 Apr 2003 18:54:38 -0000 1.115
+++ sh-tdep.c 10 Apr 2003 00:41:53 -0000
@@ -1763,8 +1763,8 @@
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. */
+ /* 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),
@@ -1795,8 +1795,8 @@
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. */
+ /* 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),
Index: sparc-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/sparc-tdep.c,v
retrieving revision 1.87
diff -u -r1.87 sparc-tdep.c
--- sparc-tdep.c 6 Apr 2003 18:36:23 -0000 1.87
+++ sparc-tdep.c 10 Apr 2003 00:42:04 -0000
@@ -2368,10 +2368,11 @@
Adjust the call_dummy_breakpoint_offset for the bp_call_dummy breakpoint
to the proper address in the call dummy, so that `finish' after a stop
in a call dummy works.
- Tweeking current_gdbarch is not an optimal solution, but the call to
- sparc_fix_call_dummy is immediately followed by a call to run_stack_dummy,
- which is the only function where dummy_breakpoint_offset is actually
- used, if it is non-zero. */
+
+ Tweeking current_gdbarch is not an optimal solution, but the call
+ to sparc_fix_call_dummy is immediately followed by a call to
+ call_function_by_hand, which is the only function where
+ dummy_breakpoint_offset is actually used, if it is non-zero. */
if (TYPE_CODE (value_type) == TYPE_CODE_STRUCT
|| TYPE_CODE (value_type) == TYPE_CODE_UNION)
{
Index: target.h
===================================================================
RCS file: /cvs/src/src/gdb/target.h,v
retrieving revision 1.36
diff -u -r1.36 target.h
--- target.h 24 Feb 2003 21:56:50 -0000 1.36
+++ target.h 10 Apr 2003 00:42:05 -0000
@@ -832,15 +832,15 @@
#define target_async(CALLBACK,CONTEXT) \
(current_target.to_async((CALLBACK), (CONTEXT)))
-/* This is to be used ONLY within run_stack_dummy(). It
- provides a workaround, to have inferior function calls done in
- sychronous mode, even though the target is asynchronous. After
+/* This is to be used ONLY within call_function_by_hand(). It provides
+ a workaround, to have inferior function calls done in sychronous
+ mode, even though the target is asynchronous. After
target_async_mask(0) is called, calls to target_can_async_p() will
return FALSE , so that target_resume() will not try to start the
target asynchronously. After the inferior stops, we IMMEDIATELY
restore the previous nature of the target, by calling
target_async_mask(1). After that, target_can_async_p() will return
- TRUE. ANY OTHER USE OF THIS FEATURE IS DEPRECATED.
+ TRUE. ANY OTHER USE OF THIS FEATURE IS DEPRECATED.
FIXME ezannoni 1999-12-13: we won't need this once we move
the turning async on and off to the single execution commands,
Index: v850-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/v850-tdep.c,v
retrieving revision 1.54
diff -u -r1.54 v850-tdep.c
--- v850-tdep.c 1 Apr 2003 17:17:29 -0000 1.54
+++ v850-tdep.c 10 Apr 2003 00:42:05 -0000
@@ -1155,9 +1155,10 @@
be valid only if this routine uses FP. For previous frames, fi-frame will
always be correct (since that is derived from v850_frame_chain ()).
- We can be called with the PC in the call dummy under two circumstances.
- First, during normal backtracing, second, while figuring out the frame
- pointer just prior to calling the target function (see run_stack_dummy). */
+ We can be called with the PC in the call dummy under two
+ circumstances. First, during normal backtracing, second, while
+ figuring out the frame pointer just prior to calling the target
+ function (see call_function_by_hand). */
static void
v850_init_extra_frame_info (int fromleaf, struct frame_info *fi)
Index: valops.c
===================================================================
RCS file: /cvs/src/src/gdb/valops.c,v
retrieving revision 1.104
diff -u -r1.104 valops.c
--- valops.c 31 Mar 2003 23:52:38 -0000 1.104
+++ valops.c 10 Apr 2003 00:42:11 -0000
@@ -38,6 +38,7 @@
#include <errno.h>
#include "gdb_string.h"
#include "gdb_assert.h"
+#include "symfile.h"
/* Flag indicating HP compilers were used; needed to correctly handle some
value operations with HP aCC code/runtime. */
@@ -1222,6 +1223,15 @@
return funaddr;
}
+/* Call breakpoint_auto_delete on the current contents of the bpstat
+ pointed to by arg (which is really a bpstat *). */
+
+static void
+breakpoint_auto_delete_contents (void *arg)
+{
+ breakpoint_auto_delete (*(bpstat *) arg);
+}
+
/* All this stuff with a dummy frame may seem unnecessarily complicated
(why not just save registers in GDB?). The purpose of pushing a dummy
frame which looks just like a real frame is so that if you call a
@@ -1735,10 +1745,100 @@
sprintf (name, format, (unsigned long) funaddr);
}
- /* Execute the stack dummy routine, calling FUNCTION.
- When it is done, discard the empty frame
- after storing the contents of all regs into retbuf. */
- rc = run_stack_dummy (real_pc + CALL_DUMMY_START_OFFSET, retbuf);
+ {
+ /* Execute a "stack dummy", a piece of code stored in the stack
+ by the debugger to be executed in the inferior.
+
+ The dummy's frame is automatically popped whenever that break
+ is hit. If that is the first time the program stops,
+ call_function_by_hand returns to its caller with that frame
+ already gone and sets RC to 0.
+
+ Otherwise, set RC to a non-zero value. If the called
+ function receives a random signal, we do not allow the user
+ to continue executing it as this may not work. The dummy
+ frame is poped and we return 1. If we hit a breakpoint, we
+ leave the frame in place and return 2 (the frame will
+ eventually be popped when we do hit the dummy end
+ breakpoint). */
+
+ CORE_ADDR addr = real_pc + CALL_DUMMY_START_OFFSET;
+ struct regcache *buffer = retbuf;
+ struct cleanup *old_cleanups = make_cleanup (null_cleanup, 0);
+ int saved_async = 0;
+ struct breakpoint *bpt;
+ struct symtab_and_line sal;
+
+ /* Now proceed, having reached the desired place. */
+ clear_proceed_status ();
+
+ init_sal (&sal); /* initialize to zeroes */
+ if (CALL_DUMMY_LOCATION == AT_ENTRY_POINT)
+ {
+ sal.pc = CALL_DUMMY_ADDRESS ();
+ }
+ else
+ {
+ /* If defined, CALL_DUMMY_BREAKPOINT_OFFSET is where we need
+ to put a breakpoint instruction. If not, the call dummy
+ already has the breakpoint instruction in it.
+
+ ADDR IS THE ADDRESS of the call dummy plus the
+ CALL_DUMMY_START_OFFSET, so we need to subtract the
+ CALL_DUMMY_START_OFFSET. */
+ sal.pc = (addr - (CALL_DUMMY_START_OFFSET
+ + CALL_DUMMY_BREAKPOINT_OFFSET));
+ }
+ sal.section = find_pc_overlay (sal.pc);
+
+ {
+ /* Set up a frame ID for the dummy frame so we can pass it to
+ set_momentary_breakpoint. We need to give the breakpoint a
+ frame ID so that the breakpoint code can correctly
+ re-identify the dummy breakpoint. */
+ struct frame_id frame = frame_id_build (read_fp (), sal.pc);
+ /* Create a momentary breakpoint at the return address of the
+ inferior. That way it breaks when it returns. */
+ bpt = set_momentary_breakpoint (sal, frame, bp_call_dummy);
+ bpt->disposition = disp_del;
+ }
+
+ /* If all error()s out of proceed ended up calling normal_stop
+ (and perhaps they should; it already does in the special case
+ of error out of resume()), then we wouldn't need this. */
+ make_cleanup (breakpoint_auto_delete_contents, &stop_bpstat);
+
+ disable_watchpoints_before_interactive_call_start ();
+ proceed_to_finish = 1; /* We want stop_registers, please... */
+
+ if (target_can_async_p ())
+ saved_async = target_async_mask (0);
+
+ proceed (addr, TARGET_SIGNAL_0, 0);
+
+ if (saved_async)
+ target_async_mask (saved_async);
+
+ enable_watchpoints_after_interactive_call_stop ();
+
+ discard_cleanups (old_cleanups);
+
+ if (stopped_by_random_signal)
+ /* We can stop during an inferior call because a signal is
+ received. */
+ rc = 1;
+ else if (!stop_stack_dummy)
+ /* We may also stop prematurely because we hit a breakpoint in
+ the called routine. */
+ rc = 2;
+ else
+ {
+ /* On normal return, the stack dummy has been popped
+ already. */
+ regcache_cpy_no_passthrough (buffer, stop_registers);
+ rc = 0;
+ }
+ }
if (rc == 1)
{
Index: config/sparc/tm-sparc.h
===================================================================
RCS file: /cvs/src/src/gdb/config/sparc/tm-sparc.h,v
retrieving revision 1.44
diff -u -r1.44 tm-sparc.h
--- config/sparc/tm-sparc.h 5 Apr 2003 15:39:34 -0000 1.44
+++ config/sparc/tm-sparc.h 10 Apr 2003 00:42:13 -0000
@@ -545,9 +545,9 @@
*
* call_function then writes CALL_DUMMY, pushes the args onto the
* stack, and adjusts the stack pointer.
- *
- * run_stack_dummy then starts execution (in the middle of
- * CALL_DUMMY, as directed by call_function). */
+
+ call_function_by_hand then starts execution (in the middle of
+ CALL_DUMMY, as directed by call_function). */
#ifndef CALL_DUMMY
/* This sequence of words is the instructions
--- End Message ---