import gdb-1999-07-05 snapshot
This commit is contained in:
parent
f11523b013
commit
43ff13b418
41 changed files with 1885 additions and 789 deletions
201
gdb/ChangeLog
201
gdb/ChangeLog
|
@ -1,3 +1,203 @@
|
||||||
|
1999-07-05 Jason Molenda (jsm@bugshack.cygnus.com)
|
||||||
|
|
||||||
|
* remote.c: Include <sys/select.h> if it exists in order to pick up
|
||||||
|
FD_SET et al defns.
|
||||||
|
* remote-os9k.c: Same.
|
||||||
|
* remote-st.c: Same.
|
||||||
|
* ser-tcp.c: Same.
|
||||||
|
* ser-unix.c: Same.
|
||||||
|
* sparcl-tdep.c: Same.
|
||||||
|
|
||||||
|
Fri Jul 2 19:38:43 1999 Andrew Cagney <cagney@b1.cygnus.com>
|
||||||
|
|
||||||
|
* top.c (target_output_hook): Delete definition.
|
||||||
|
* defs.h (target_output_hook): Delete declaration.
|
||||||
|
|
||||||
|
* remote.c (remote_console_output): Delete call to
|
||||||
|
target_output_hook(). Send target output to gdb_stdtarg using an
|
||||||
|
unfiltered write. Make more robust.
|
||||||
|
|
||||||
|
* remote-sim.c (gdb_os_write_stdout, gdb_os_write_stderr):
|
||||||
|
Ditto. For moment, do not try to separate target stdout and stderr
|
||||||
|
streams.
|
||||||
|
|
||||||
|
* defs.h (gdb_stdtarg): New global. Output from target and
|
||||||
|
simulators.
|
||||||
|
|
||||||
|
1999-07-02 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
|
||||||
|
|
||||||
|
* top.c (return_to_top_level): Do all the exec_cleanups too.
|
||||||
|
|
||||||
|
* event-top.c (command_handler): Set up for a continuation, if we
|
||||||
|
are in the middle of running an execution command which will
|
||||||
|
finish later on. Do cleanups, an display of time/space only if not
|
||||||
|
running with an async target or not running an execution command.
|
||||||
|
(command_line_handler_continuation): New function. Continuation
|
||||||
|
for command_line_handler.
|
||||||
|
|
||||||
|
* utils.c (exec_cleanup_chain): New cleanup chain to be used in
|
||||||
|
async mode for the execution commands.
|
||||||
|
(make_exec_cleanup): New function. Add a cleanup to the
|
||||||
|
exec_cleanup_chain.
|
||||||
|
(do_exec_cleanups): New Function. Do cleanups on the
|
||||||
|
exec_cleanup_chain.
|
||||||
|
(add_continuation): New function. Add a new continuation to the
|
||||||
|
cmd_continuation list.
|
||||||
|
(do_all_continuations): New function. Do all the continuations on
|
||||||
|
the cmd_continuation list.
|
||||||
|
|
||||||
|
* top.h (ALL_CLEANUPS): Move from here to defs.h.
|
||||||
|
|
||||||
|
* defs.h (struct continuation_arg): New structure. Arg to pass to
|
||||||
|
the call to a command continuation.
|
||||||
|
(struct continuation): New structure. Continuation for an
|
||||||
|
execution command.
|
||||||
|
(ALL_CLEANUPS): Move here from top.h.
|
||||||
|
|
||||||
|
* remote.c (remote_async_open_1): Set things up for telling the
|
||||||
|
target we are running the extended protocol, only after the target
|
||||||
|
has stopped.
|
||||||
|
(set_extended_protocol): New function. Tell the target we are
|
||||||
|
using the extended protocol.
|
||||||
|
(remote_async_resume): Set things up for sync execution only if
|
||||||
|
this is the first time we are called.
|
||||||
|
|
||||||
|
* breakpoint.c (until_break_command_continuation): New function.
|
||||||
|
Stuff to be done after the target stops during the 'until'
|
||||||
|
command.
|
||||||
|
(until_break_command): Set things up for completing the 'until'
|
||||||
|
command later on. Do the final cleanups only if not running
|
||||||
|
asynchronously or async execution is not supported by the target.
|
||||||
|
|
||||||
|
* infcmd.c (until_command): Recognize '&' at end of command and
|
||||||
|
handle it properly.
|
||||||
|
(finish_command_continuation): New function. Do whatever is needed
|
||||||
|
after the target has stopped.
|
||||||
|
(finish_command): Recognize '&' at end of command and handle it
|
||||||
|
properly. Don't do stuff needed after target has stopped if
|
||||||
|
running asynchronously and target has async. Use exec_cleanup_chain
|
||||||
|
if running asynchronously and target is asynchronous.
|
||||||
|
|
||||||
|
* infrun.c (cmd_continuation): New gloabl variable. Used to
|
||||||
|
coplete execution commands in async mode, after the target has
|
||||||
|
stoped.
|
||||||
|
(fetch_inferior_event): Use exec_cleanup_chain, instead of
|
||||||
|
cleanup_chain. Do all the exec cleanups at the end. Do all the
|
||||||
|
continuations at the end. Call complete_execution from here,
|
||||||
|
instead of normal_stop.
|
||||||
|
(complete_execution): Cleanup the signals handlers for SIGINT
|
||||||
|
before displaying the prompt.
|
||||||
|
(start_remote): Set target_executing to 1.
|
||||||
|
(normal_stop): Don't call complete_execution from here.
|
||||||
|
|
||||||
|
Thu Jul 1 19:14:30 1999 Andrew Cagney <cagney@b1.cygnus.com>
|
||||||
|
|
||||||
|
* blockframe.c (struct dummy_frame): Add member ``top''.
|
||||||
|
(generic_push_dummy_frame): Initialize top to sp.
|
||||||
|
(generic_save_dummy_frame_tos): New function. Initialize top.
|
||||||
|
(generic_find_dummy_frame): Check for the top of the frame.
|
||||||
|
|
||||||
|
* blockframe.c (generic_push_dummy_frame): Free the dummy_frame
|
||||||
|
registers.
|
||||||
|
|
||||||
|
* config/mn10300/tm-mn10300.h (SAVE_DUMMY_FRAME_TOS): Define.
|
||||||
|
(TARGET_READ_FP): Return the SP as a best guess.
|
||||||
|
|
||||||
|
Wed Jun 30 15:45:48 1999 Jeffrey A Law (law@cygnus.com)
|
||||||
|
|
||||||
|
* configure.host (hppa*-*-hpux11*): Accept any version of hpux11
|
||||||
|
instead of hpux11.0*.
|
||||||
|
|
||||||
|
1999-06-30 Fernando Nasser <fnasser@totem.to.cygnus.com>
|
||||||
|
|
||||||
|
* source.c (directory_command): Add missing test for from_tty.
|
||||||
|
|
||||||
|
1999-06-29 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
|
||||||
|
|
||||||
|
* remote.c: Include event-loop.h.
|
||||||
|
(remote_async_ops, extended_async_remote_ops): Define new target
|
||||||
|
vector structures for asynchronous debugging.
|
||||||
|
(remote_async_open): New function. Asynchronous version of
|
||||||
|
remote_open.
|
||||||
|
(extended_remote_async_open): New function. Asynchronous version
|
||||||
|
of extended_remote_open.
|
||||||
|
(remote_async_open_1): New function. Async version of
|
||||||
|
remote_open_1.
|
||||||
|
(remote_async_detach): New function. Async version of
|
||||||
|
remote_detach.
|
||||||
|
(remote_async_resume): New function. Async version of
|
||||||
|
remote_resume.
|
||||||
|
(initialize_sigint_signal_handler, handle_remote_sigint,
|
||||||
|
handle_remote_sigint_twice, async_remote_interrupt,
|
||||||
|
async_remote_interrupt_twice, cleanup_sigint_signal_handler): New
|
||||||
|
functions. Used for handling ^C while target is running.
|
||||||
|
(remote_async_wait): New function. Async version of remote_wait.
|
||||||
|
(remote_async_kill): New function. Async version of remote_kill.
|
||||||
|
(extended_remote_async_create_inferior): New function. Async
|
||||||
|
version of extended_remote_create_inferior.
|
||||||
|
(init_remote_async_ops): New function. Initialize target vector
|
||||||
|
for target async.
|
||||||
|
(init_extended_async_remote_ops): New function. Initialize target
|
||||||
|
vector for target extended-async.
|
||||||
|
(_initialize_remote): Initialize remote_async_ops and
|
||||||
|
extended_async_remote_ops.
|
||||||
|
|
||||||
|
* infrun.c: Include "event-loop.h".
|
||||||
|
(sync_execution): new global variable.
|
||||||
|
(proceed): Invoke wait_for_inferior and normal_stop only if not
|
||||||
|
running in async mode or if target doesn't support async
|
||||||
|
execution.
|
||||||
|
(start_remote): Don't call wait_for_inferior and normal_stop if
|
||||||
|
not running in async mode or if target not async. If running async
|
||||||
|
and target is async, start the target in simulated synchronous
|
||||||
|
mode.
|
||||||
|
(async_ecss, async_ecs): New global vars, for inferior state.
|
||||||
|
(fetch_inferior_event): New function. Async version of
|
||||||
|
wait_for_inferior.
|
||||||
|
(complete_execution): New function. Reset of gdb prompt and stdin,
|
||||||
|
after inferior execution has completed.
|
||||||
|
(normal_stop): Call complete_execution at end of asynchronous
|
||||||
|
execution.
|
||||||
|
|
||||||
|
* infcmd.c (strip_bg_char): New function to detect the background
|
||||||
|
execution char '&'.
|
||||||
|
(run_command): Modify to support background and foreground
|
||||||
|
execution in async mode.
|
||||||
|
(continue_command): Ditto.
|
||||||
|
(step_1): Ditto.
|
||||||
|
(jump_command): Ditto.
|
||||||
|
(interrupt_target_command): New function. Interrupt the
|
||||||
|
target execution.
|
||||||
|
(_initialize_infcmd): Add new command 'interrupt'.
|
||||||
|
|
||||||
|
* top.c (target_executing): New global variable.
|
||||||
|
(execute_command): Reject commands that cannot be executed while
|
||||||
|
the target is running asynchronously.
|
||||||
|
|
||||||
|
* event-top.c (push_prompt): Make non static.
|
||||||
|
(pop_prompt): Make non static. If the current prompt is empty,
|
||||||
|
don't try to copy it over the previous one.
|
||||||
|
(handle_sigint): Make non static.
|
||||||
|
(command_handler): Do the cleanups only when not executing with an
|
||||||
|
asynchronous target.
|
||||||
|
|
||||||
|
* event-loop.c (delete_async_signal_handler): Pass a pointer to a
|
||||||
|
pointer to a signal handler, so that is can be freed at the end.
|
||||||
|
|
||||||
|
* target.c (update_current_target): Inherit to_has_async_exec.
|
||||||
|
|
||||||
|
* inferior.h: Add global variables target_executing, and
|
||||||
|
sync_execution. Export function fetch_inferior_event.
|
||||||
|
|
||||||
|
* event-loop.h: Add push_prompt, pop_prompt, handle_sigint to the
|
||||||
|
exported functions. Update prototype for delete_signal_handler.
|
||||||
|
|
||||||
|
* target.h (struct target_ops): New target op: to_has_async_exec.
|
||||||
|
(target_has_async): New macro.
|
||||||
|
|
||||||
|
* Makefile.in (infrun.o): Add dependency on event-loop.h.
|
||||||
|
(remote.o): Ditto.
|
||||||
|
|
||||||
1999-06-28 Jim Blandy <jimb@zwingli.cygnus.com>
|
1999-06-28 Jim Blandy <jimb@zwingli.cygnus.com>
|
||||||
|
|
||||||
* solib.c (clear_solib): Don't disable breakpoints if we're
|
* solib.c (clear_solib): Don't disable breakpoints if we're
|
||||||
|
@ -136,6 +336,7 @@ Wed Jun 23 15:30:46 1999 Andrew Cagney <cagney@b1.cygnus.com>
|
||||||
* Makefile.in (top_h): Define.
|
* Makefile.in (top_h): Define.
|
||||||
(event-loop.o): Add dependencies on top.h and defs.h.
|
(event-loop.o): Add dependencies on top.h and defs.h.
|
||||||
(event-top.o): Add dependency on terminal.h.
|
(event-top.o): Add dependency on terminal.h.
|
||||||
|
|
||||||
* event-loop.c: Get rid of #include <readline.h>.
|
* event-loop.c: Get rid of #include <readline.h>.
|
||||||
|
|
||||||
* event-loop.h: Get rid of nested #include's.
|
* event-loop.h: Get rid of nested #include's.
|
||||||
|
|
|
@ -224,7 +224,7 @@ CDEPS = $(XM_CDEPS) $(TM_CDEPS) $(NAT_CDEPS) $(SIM) $(BFD) $(READLINE) \
|
||||||
ADD_FILES = $(REGEX) $(XM_ADD_FILES) $(TM_ADD_FILES) $(NAT_ADD_FILES)
|
ADD_FILES = $(REGEX) $(XM_ADD_FILES) $(TM_ADD_FILES) $(NAT_ADD_FILES)
|
||||||
ADD_DEPS = $(REGEX1) $(XM_ADD_FILES) $(TM_ADD_FILES) $(NAT_ADD_FILES)
|
ADD_DEPS = $(REGEX1) $(XM_ADD_FILES) $(TM_ADD_FILES) $(NAT_ADD_FILES)
|
||||||
|
|
||||||
VERSION = 19990628
|
VERSION = 19990705
|
||||||
DIST=gdb
|
DIST=gdb
|
||||||
|
|
||||||
LINT=/usr/5bin/lint
|
LINT=/usr/5bin/lint
|
||||||
|
@ -1206,7 +1206,7 @@ infptrace.o: infptrace.c $(defs_h) $(gdbcore_h) $(inferior_h) target.h \
|
||||||
gdb_string.h $(wait_h) $(command_h)
|
gdb_string.h $(wait_h) $(command_h)
|
||||||
|
|
||||||
infrun.o: infrun.c $(wait_h) $(defs_h) $(gdbcmd_h) $(gdbcore_h) \
|
infrun.o: infrun.c $(wait_h) $(defs_h) $(gdbcmd_h) $(gdbcore_h) \
|
||||||
$(inferior_h) target.h gdbthread.h gdb_string.h
|
$(inferior_h) target.h gdbthread.h gdb_string.h $(event_loop_h)
|
||||||
|
|
||||||
inftarg.o: inftarg.c $(wait_h) $(defs_h) $(gdbcore_h) $(inferior_h) \
|
inftarg.o: inftarg.c $(wait_h) $(defs_h) $(gdbcore_h) $(inferior_h) \
|
||||||
target.h terminal.h $(command_h)
|
target.h terminal.h $(command_h)
|
||||||
|
@ -1462,7 +1462,8 @@ remote-utils.o: remote-utils.c $(defs_h) $(gdbcmd_h) $(gdbcore_h) \
|
||||||
$(inferior_h) $(remote_utils_h) gdb_string.h
|
$(inferior_h) $(remote_utils_h) gdb_string.h
|
||||||
|
|
||||||
remote.o: remote.c $(bfd_h) $(wait_h) $(defs_h) $(gdbcmd_h) \
|
remote.o: remote.c $(bfd_h) $(wait_h) $(defs_h) $(gdbcmd_h) \
|
||||||
$(inferior_h) $(remote_utils_h) symfile.h terminal.h gdb_string.h
|
$(inferior_h) $(remote_utils_h) symfile.h terminal.h gdb_string.h \
|
||||||
|
$(event_loop_h)
|
||||||
|
|
||||||
remote-nrom.o: remote-nrom.c $(bfd_h) $(wait_h) $(defs_h) $(gdbcmd_h) \
|
remote-nrom.o: remote-nrom.c $(bfd_h) $(wait_h) $(defs_h) $(gdbcmd_h) \
|
||||||
$(inferior_h) $(remote_utils_h) symfile.h terminal.h
|
$(inferior_h) $(remote_utils_h) symfile.h terminal.h
|
||||||
|
|
|
@ -1121,6 +1121,7 @@ struct dummy_frame
|
||||||
CORE_ADDR pc;
|
CORE_ADDR pc;
|
||||||
CORE_ADDR fp;
|
CORE_ADDR fp;
|
||||||
CORE_ADDR sp;
|
CORE_ADDR sp;
|
||||||
|
CORE_ADDR top;
|
||||||
char *registers;
|
char *registers;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1142,7 +1143,9 @@ generic_find_dummy_frame (pc, fp)
|
||||||
|
|
||||||
for (dummyframe = dummy_frame_stack; dummyframe != NULL;
|
for (dummyframe = dummy_frame_stack; dummyframe != NULL;
|
||||||
dummyframe = dummyframe->next)
|
dummyframe = dummyframe->next)
|
||||||
if (fp == dummyframe->fp || fp == dummyframe->sp)
|
if (fp == dummyframe->fp
|
||||||
|
|| fp == dummyframe->sp
|
||||||
|
|| fp == dummyframe->top)
|
||||||
/* The frame in question lies between the saved fp and sp, inclusive */
|
/* The frame in question lies between the saved fp and sp, inclusive */
|
||||||
return dummyframe->registers;
|
return dummyframe->registers;
|
||||||
|
|
||||||
|
@ -1203,6 +1206,7 @@ generic_push_dummy_frame ()
|
||||||
if (INNER_THAN (dummy_frame->fp, fp)) /* stale -- destroy! */
|
if (INNER_THAN (dummy_frame->fp, fp)) /* stale -- destroy! */
|
||||||
{
|
{
|
||||||
dummy_frame_stack = dummy_frame->next;
|
dummy_frame_stack = dummy_frame->next;
|
||||||
|
free (dummy_frame->registers);
|
||||||
free (dummy_frame);
|
free (dummy_frame);
|
||||||
dummy_frame = dummy_frame_stack;
|
dummy_frame = dummy_frame_stack;
|
||||||
}
|
}
|
||||||
|
@ -1214,12 +1218,20 @@ generic_push_dummy_frame ()
|
||||||
|
|
||||||
dummy_frame->pc = read_register (PC_REGNUM);
|
dummy_frame->pc = read_register (PC_REGNUM);
|
||||||
dummy_frame->sp = read_register (SP_REGNUM);
|
dummy_frame->sp = read_register (SP_REGNUM);
|
||||||
|
dummy_frame->top = dummy_frame->sp;
|
||||||
dummy_frame->fp = fp;
|
dummy_frame->fp = fp;
|
||||||
read_register_bytes (0, dummy_frame->registers, REGISTER_BYTES);
|
read_register_bytes (0, dummy_frame->registers, REGISTER_BYTES);
|
||||||
dummy_frame->next = dummy_frame_stack;
|
dummy_frame->next = dummy_frame_stack;
|
||||||
dummy_frame_stack = dummy_frame;
|
dummy_frame_stack = dummy_frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
generic_save_dummy_frame_tos (sp)
|
||||||
|
CORE_ADDR sp;
|
||||||
|
{
|
||||||
|
dummy_frame_stack->top = sp;
|
||||||
|
}
|
||||||
|
|
||||||
/* Function: pop_frame
|
/* Function: pop_frame
|
||||||
Restore the machine state from either the saved dummy stack or a
|
Restore the machine state from either the saved dummy stack or a
|
||||||
real stack frame. */
|
real stack frame. */
|
||||||
|
|
|
@ -2418,7 +2418,33 @@ bpstat_what (bs)
|
||||||
after stopping, the check for whether to step over a breakpoint
|
after stopping, the check for whether to step over a breakpoint
|
||||||
(BPSTAT_WHAT_SINGLE type stuff) is handled in proceed() without
|
(BPSTAT_WHAT_SINGLE type stuff) is handled in proceed() without
|
||||||
reference to how we stopped. We retain separate wp_silent and bp_silent
|
reference to how we stopped. We retain separate wp_silent and bp_silent
|
||||||
codes in case we want to change that someday. */
|
codes in case we want to change that someday.
|
||||||
|
|
||||||
|
Another possibly interesting property of this table is that
|
||||||
|
there's a partial ordering, priority-like, of the actions. Once
|
||||||
|
you've decided that some action is appropriate, you'll never go
|
||||||
|
back and decide something of a lower priority is better. The
|
||||||
|
ordering is:
|
||||||
|
|
||||||
|
kc < clr sgl shl slr sn sr ss ts
|
||||||
|
sgl < clrs shl shlr slr sn sr ss ts
|
||||||
|
slr < err shl shlr sn sr ss ts
|
||||||
|
clr < clrs err shl shlr sn sr ss ts
|
||||||
|
clrs < err shl shlr sn sr ss ts
|
||||||
|
ss < shl shlr sn sr ts
|
||||||
|
sn < shl shlr sr ts
|
||||||
|
sr < shl shlr ts
|
||||||
|
shl < shlr
|
||||||
|
ts <
|
||||||
|
shlr <
|
||||||
|
|
||||||
|
What I think this means is that we don't need a damned table
|
||||||
|
here. If you just put the rows and columns in the right order,
|
||||||
|
it'd look awfully regular. We could simply walk the bpstat list
|
||||||
|
and choose the highest priority action we find, with a little
|
||||||
|
logic to handle the 'err' cases, and the CLEAR_LONGJMP_RESUME/
|
||||||
|
CLEAR_LONGJMP_RESUME_SINGLE distinction (which breakpoint.h says
|
||||||
|
is messy anyway). */
|
||||||
|
|
||||||
/* step_resume entries: a step resume breakpoint overrides another
|
/* step_resume entries: a step resume breakpoint overrides another
|
||||||
breakpoint of signal handling (see comment in wait_for_inferior
|
breakpoint of signal handling (see comment in wait_for_inferior
|
||||||
|
@ -4480,9 +4506,23 @@ static void awatch_command (arg, from_tty)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Helper routine for the until_command routine in infcmd.c. Here
|
/* Helper routines for the until_command routine in infcmd.c. Here
|
||||||
because it uses the mechanisms of breakpoints. */
|
because it uses the mechanisms of breakpoints. */
|
||||||
|
|
||||||
|
/* This function is called by fetch_inferior_event via the
|
||||||
|
cmd_continuation pointer, to complete the until command. It takes
|
||||||
|
care of cleaning up the temporary breakpoints set up by the until
|
||||||
|
command. */
|
||||||
|
void
|
||||||
|
until_break_command_continuation (arg)
|
||||||
|
struct continuation_arg *arg;
|
||||||
|
{
|
||||||
|
/* Do all the exec cleanups, which at this point should only be the
|
||||||
|
one set up in the first part of the until_break_command
|
||||||
|
function. */
|
||||||
|
do_exec_cleanups (ALL_CLEANUPS);
|
||||||
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
void
|
void
|
||||||
until_break_command (arg, from_tty)
|
until_break_command (arg, from_tty)
|
||||||
|
@ -4494,6 +4534,7 @@ until_break_command (arg, from_tty)
|
||||||
struct frame_info *prev_frame = get_prev_frame (selected_frame);
|
struct frame_info *prev_frame = get_prev_frame (selected_frame);
|
||||||
struct breakpoint *breakpoint;
|
struct breakpoint *breakpoint;
|
||||||
struct cleanup *old_chain;
|
struct cleanup *old_chain;
|
||||||
|
struct continuation_arg *arg1, *arg2;
|
||||||
|
|
||||||
clear_proceed_status ();
|
clear_proceed_status ();
|
||||||
|
|
||||||
|
@ -4519,7 +4560,26 @@ until_break_command (arg, from_tty)
|
||||||
|
|
||||||
breakpoint = set_momentary_breakpoint (sal, selected_frame, bp_until);
|
breakpoint = set_momentary_breakpoint (sal, selected_frame, bp_until);
|
||||||
|
|
||||||
old_chain = make_cleanup ((make_cleanup_func) delete_breakpoint, breakpoint);
|
if (!async_p || !target_has_async)
|
||||||
|
old_chain = make_cleanup ((make_cleanup_func) delete_breakpoint, breakpoint);
|
||||||
|
else
|
||||||
|
make_exec_cleanup ((make_cleanup_func) delete_breakpoint, breakpoint);
|
||||||
|
|
||||||
|
/* If we are running asynchronously, and the target supports async
|
||||||
|
execution, we are not waiting for the target to stop, in the call
|
||||||
|
tp proceed, below. This means that we cannot delete the
|
||||||
|
brekpoints until the target has actually stopped. The only place
|
||||||
|
where we get a chance to do that is in fetch_inferior_event, so
|
||||||
|
we must set things up for that. */
|
||||||
|
|
||||||
|
if (async_p && target_has_async)
|
||||||
|
{
|
||||||
|
/* In this case we don't need args for the continuation, because
|
||||||
|
all it needs to do is do the cleanups in the
|
||||||
|
exec_cleanup_chain, which will be only those inserted by this
|
||||||
|
function. We can get away by using ALL_CLEANUPS. */
|
||||||
|
add_continuation (until_break_command_continuation, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/* Keep within the current frame */
|
/* Keep within the current frame */
|
||||||
|
|
||||||
|
@ -4528,11 +4588,17 @@ until_break_command (arg, from_tty)
|
||||||
sal = find_pc_line (prev_frame->pc, 0);
|
sal = find_pc_line (prev_frame->pc, 0);
|
||||||
sal.pc = prev_frame->pc;
|
sal.pc = prev_frame->pc;
|
||||||
breakpoint = set_momentary_breakpoint (sal, prev_frame, bp_until);
|
breakpoint = set_momentary_breakpoint (sal, prev_frame, bp_until);
|
||||||
make_cleanup ((make_cleanup_func) delete_breakpoint, breakpoint);
|
if (!async_p || !target_has_async)
|
||||||
|
make_cleanup ((make_cleanup_func) delete_breakpoint, breakpoint);
|
||||||
|
else
|
||||||
|
make_exec_cleanup ((make_cleanup_func) delete_breakpoint, breakpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
proceed (-1, TARGET_SIGNAL_DEFAULT, 0);
|
proceed (-1, TARGET_SIGNAL_DEFAULT, 0);
|
||||||
do_cleanups(old_chain);
|
/* Do the cleanups now, anly if we are not running asynchronously,
|
||||||
|
of if we are, but the target is still synchronous. */
|
||||||
|
if (!async_p || !target_has_async)
|
||||||
|
do_cleanups(old_chain);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
|
@ -128,10 +128,13 @@ extern void mn10300_pop_frame PARAMS ((struct frame_info *));
|
||||||
#define FIX_CALL_DUMMY(DUMMY, START, FUNADDR, NARGS, ARGS, TYPE, GCCP)
|
#define FIX_CALL_DUMMY(DUMMY, START, FUNADDR, NARGS, ARGS, TYPE, GCCP)
|
||||||
#define CALL_DUMMY_ADDRESS() entry_point_address ()
|
#define CALL_DUMMY_ADDRESS() entry_point_address ()
|
||||||
|
|
||||||
|
#define TARGET_READ_FP() read_sp ()
|
||||||
|
|
||||||
extern CORE_ADDR mn10300_push_return_address PARAMS ((CORE_ADDR, CORE_ADDR));
|
extern CORE_ADDR mn10300_push_return_address PARAMS ((CORE_ADDR, CORE_ADDR));
|
||||||
#define PUSH_RETURN_ADDRESS(PC, SP) mn10300_push_return_address (PC, SP)
|
#define PUSH_RETURN_ADDRESS(PC, SP) mn10300_push_return_address (PC, SP)
|
||||||
|
|
||||||
#define PUSH_DUMMY_FRAME generic_push_dummy_frame ()
|
#define PUSH_DUMMY_FRAME generic_push_dummy_frame ()
|
||||||
|
#define SAVE_DUMMY_FRAME_TOS(SP) generic_save_dummy_frame_tos (SP)
|
||||||
|
|
||||||
extern CORE_ADDR
|
extern CORE_ADDR
|
||||||
mn10300_push_arguments PARAMS ((int, struct value **, CORE_ADDR,
|
mn10300_push_arguments PARAMS ((int, struct value **, CORE_ADDR,
|
||||||
|
|
|
@ -42,7 +42,7 @@ arm-*-*) gdb_host=arm ;;
|
||||||
hppa*-*-bsd*) gdb_host=hppabsd ;;
|
hppa*-*-bsd*) gdb_host=hppabsd ;;
|
||||||
hppa*-*-hiux*) gdb_host=hppahpux ;;
|
hppa*-*-hiux*) gdb_host=hppahpux ;;
|
||||||
hppa*-*-hpux10.20) gdb_host=hpux1020 ;;
|
hppa*-*-hpux10.20) gdb_host=hpux1020 ;;
|
||||||
hppa*-*-hpux11.0*) gdb_host=hpux1100 ;;
|
hppa*-*-hpux11*) gdb_host=hpux1100 ;;
|
||||||
hppa*-*-hpux*) gdb_host=hppahpux ;;
|
hppa*-*-hpux*) gdb_host=hppahpux ;;
|
||||||
hppa*-*-osf*) gdb_host=hppaosf ;;
|
hppa*-*-osf*) gdb_host=hppaosf ;;
|
||||||
|
|
||||||
|
|
39
gdb/defs.h
39
gdb/defs.h
|
@ -272,6 +272,7 @@ extern void do_cleanups PARAMS ((struct cleanup *));
|
||||||
extern void do_final_cleanups PARAMS ((struct cleanup *));
|
extern void do_final_cleanups PARAMS ((struct cleanup *));
|
||||||
extern void do_my_cleanups PARAMS ((struct cleanup **, struct cleanup *));
|
extern void do_my_cleanups PARAMS ((struct cleanup **, struct cleanup *));
|
||||||
extern void do_run_cleanups PARAMS ((struct cleanup *));
|
extern void do_run_cleanups PARAMS ((struct cleanup *));
|
||||||
|
extern void do_exec_cleanups PARAMS ((struct cleanup *));
|
||||||
|
|
||||||
extern void discard_cleanups PARAMS ((struct cleanup *));
|
extern void discard_cleanups PARAMS ((struct cleanup *));
|
||||||
extern void discard_final_cleanups PARAMS ((struct cleanup *));
|
extern void discard_final_cleanups PARAMS ((struct cleanup *));
|
||||||
|
@ -290,6 +291,8 @@ extern struct cleanup *make_my_cleanup PARAMS ((struct cleanup **,
|
||||||
|
|
||||||
extern struct cleanup *make_run_cleanup PARAMS ((make_cleanup_func, void *));
|
extern struct cleanup *make_run_cleanup PARAMS ((make_cleanup_func, void *));
|
||||||
|
|
||||||
|
extern struct cleanup *make_exec_cleanup PARAMS ((make_cleanup_func, void *));
|
||||||
|
|
||||||
extern struct cleanup *save_cleanups PARAMS ((void));
|
extern struct cleanup *save_cleanups PARAMS ((void));
|
||||||
extern struct cleanup *save_final_cleanups PARAMS ((void));
|
extern struct cleanup *save_final_cleanups PARAMS ((void));
|
||||||
extern struct cleanup *save_my_cleanups PARAMS ((struct cleanup **));
|
extern struct cleanup *save_my_cleanups PARAMS ((struct cleanup **));
|
||||||
|
@ -368,6 +371,11 @@ extern GDB_FILE *gdb_stderr;
|
||||||
*_unfiltered. In the very near future that restriction shall be
|
*_unfiltered. In the very near future that restriction shall be
|
||||||
removed - either call shall be unfiltered. (cagney 1999-06-13). */
|
removed - either call shall be unfiltered. (cagney 1999-06-13). */
|
||||||
extern GDB_FILE *gdb_stdlog;
|
extern GDB_FILE *gdb_stdlog;
|
||||||
|
/* Target output that should bypass normal stdout/stderr filtering.
|
||||||
|
For momement, always call this stream using *_unfiltered. In the
|
||||||
|
very near future that restriction shall be removed - either call
|
||||||
|
shall be unfiltered. (cagney 1999-07-02). */
|
||||||
|
extern GDB_FILE *gdb_stdtarg;
|
||||||
|
|
||||||
#if defined(TUI)
|
#if defined(TUI)
|
||||||
#include "tui.h"
|
#include "tui.h"
|
||||||
|
@ -613,6 +621,34 @@ extern struct command_line *read_command_lines PARAMS ((char *, int));
|
||||||
|
|
||||||
extern void free_command_lines PARAMS ((struct command_line **));
|
extern void free_command_lines PARAMS ((struct command_line **));
|
||||||
|
|
||||||
|
/* To continue the execution commands when running gdb asynchronously.
|
||||||
|
A continuation structure contains a pointer to a function to be called
|
||||||
|
to finish the command, once the target has stopped. Such mechanism is
|
||||||
|
used bt the finish and until commands, and in the remote protocol
|
||||||
|
when opening an extended-remote connection. */
|
||||||
|
|
||||||
|
struct continuation_arg
|
||||||
|
{
|
||||||
|
struct continuation_arg *next;
|
||||||
|
PTR data;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct continuation
|
||||||
|
{
|
||||||
|
void (*continuation_hook) PARAMS ((struct continuation_arg *));
|
||||||
|
struct continuation_arg *arg_list;
|
||||||
|
struct continuation *next;
|
||||||
|
}
|
||||||
|
continuation;
|
||||||
|
|
||||||
|
/* In infrun.c. */
|
||||||
|
extern struct continuation *cmd_continuation;
|
||||||
|
|
||||||
|
/* From utils.c */
|
||||||
|
void add_continuation PARAMS ((void (*) PARAMS ((struct continuation_arg *)),
|
||||||
|
struct continuation_arg *));
|
||||||
|
void do_all_continuations PARAMS ((void));
|
||||||
|
|
||||||
/* String containing the current directory (what getwd would return). */
|
/* String containing the current directory (what getwd would return). */
|
||||||
|
|
||||||
extern char *current_directory;
|
extern char *current_directory;
|
||||||
|
@ -794,6 +830,8 @@ enum return_reason {
|
||||||
RETURN_ERROR
|
RETURN_ERROR
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define ALL_CLEANUPS ((struct cleanup *)0)
|
||||||
|
|
||||||
#define RETURN_MASK_QUIT (1 << (int)RETURN_QUIT)
|
#define RETURN_MASK_QUIT (1 << (int)RETURN_QUIT)
|
||||||
#define RETURN_MASK_ERROR (1 << (int)RETURN_ERROR)
|
#define RETURN_MASK_ERROR (1 << (int)RETURN_ERROR)
|
||||||
#define RETURN_MASK_ALL (RETURN_MASK_QUIT | RETURN_MASK_ERROR)
|
#define RETURN_MASK_ALL (RETURN_MASK_QUIT | RETURN_MASK_ERROR)
|
||||||
|
@ -1109,7 +1147,6 @@ extern void (*flush_hook) PARAMS ((GDB_FILE *stream));
|
||||||
extern void (*create_breakpoint_hook) PARAMS ((struct breakpoint *b));
|
extern void (*create_breakpoint_hook) PARAMS ((struct breakpoint *b));
|
||||||
extern void (*delete_breakpoint_hook) PARAMS ((struct breakpoint *bpt));
|
extern void (*delete_breakpoint_hook) PARAMS ((struct breakpoint *bpt));
|
||||||
extern void (*modify_breakpoint_hook) PARAMS ((struct breakpoint *bpt));
|
extern void (*modify_breakpoint_hook) PARAMS ((struct breakpoint *bpt));
|
||||||
extern void (*target_output_hook) PARAMS ((char *));
|
|
||||||
extern void (*interactive_hook) PARAMS ((void));
|
extern void (*interactive_hook) PARAMS ((void));
|
||||||
extern void (*registers_changed_hook) PARAMS ((void));
|
extern void (*registers_changed_hook) PARAMS ((void));
|
||||||
extern void (*readline_begin_hook) PARAMS ((char *, ...));
|
extern void (*readline_begin_hook) PARAMS ((char *, ...));
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
Tue Jun 29 11:43:55 1999 Andrew Cagney <cagney@b1.cygnus.com>
|
||||||
|
|
||||||
|
* gdbint.texinfo (SAVE_DUMMY_FRAME_TOS): Define.
|
||||||
|
|
||||||
Fri Jun 25 11:47:06 1999 Andrew Cagney <cagney@b1.cygnus.com>
|
Fri Jun 25 11:47:06 1999 Andrew Cagney <cagney@b1.cygnus.com>
|
||||||
|
|
||||||
* remote.texi (Communication Protocol): ``v'' is in use. Fix
|
* remote.texi (Communication Protocol): ``v'' is in use. Fix
|
||||||
|
|
|
@ -1573,6 +1573,12 @@ Deprecated in favor of @var{REGISTER_NAME}.
|
||||||
Define this to return 1 if the given type will be passed by pointer
|
Define this to return 1 if the given type will be passed by pointer
|
||||||
rather than directly.
|
rather than directly.
|
||||||
|
|
||||||
|
@item SAVE_DUMMY_FRAME_TOS (sp)
|
||||||
|
Used in @samp{call_function_by_hand} to notify the target dependent code
|
||||||
|
of the top-of-stack value that will be passed to the the inferior code.
|
||||||
|
This is the value of the @var{SP} after both the dummy frame and space
|
||||||
|
for parameters/results have been allocated on the stack.
|
||||||
|
|
||||||
@item SDB_REG_TO_REGNUM
|
@item SDB_REG_TO_REGNUM
|
||||||
Define this to convert sdb register numbers into GDB regnums. If not
|
Define this to convert sdb register numbers into GDB regnums. If not
|
||||||
defined, no conversion will be done.
|
defined, no conversion will be done.
|
||||||
|
|
|
@ -290,6 +290,7 @@ gdb_do_one_event ()
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Start up the event loop. This is the entry point to the event loop
|
/* Start up the event loop. This is the entry point to the event loop
|
||||||
from the command loop. */
|
from the command loop. */
|
||||||
|
@ -752,26 +753,27 @@ invoke_async_signal_handler ()
|
||||||
Free the space allocated for it. */
|
Free the space allocated for it. */
|
||||||
void
|
void
|
||||||
delete_async_signal_handler (async_handler_ptr)
|
delete_async_signal_handler (async_handler_ptr)
|
||||||
async_signal_handler *async_handler_ptr;
|
async_signal_handler **async_handler_ptr;
|
||||||
{
|
{
|
||||||
async_signal_handler *prev_ptr;
|
async_signal_handler *prev_ptr;
|
||||||
|
|
||||||
if (sighandler_list.first_handler == async_handler_ptr)
|
if (sighandler_list.first_handler == (*async_handler_ptr))
|
||||||
{
|
{
|
||||||
sighandler_list.first_handler = async_handler_ptr->next_handler;
|
sighandler_list.first_handler = (*async_handler_ptr)->next_handler;
|
||||||
if (sighandler_list.first_handler == NULL)
|
if (sighandler_list.first_handler == NULL)
|
||||||
sighandler_list.last_handler = NULL;
|
sighandler_list.last_handler = NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
prev_ptr = sighandler_list.first_handler;
|
prev_ptr = sighandler_list.first_handler;
|
||||||
while (prev_ptr->next_handler != async_handler_ptr)
|
while (prev_ptr->next_handler != (*async_handler_ptr) && prev_ptr)
|
||||||
prev_ptr = prev_ptr->next_handler;
|
prev_ptr = prev_ptr->next_handler;
|
||||||
prev_ptr->next_handler = async_handler_ptr->next_handler;
|
prev_ptr->next_handler = (*async_handler_ptr)->next_handler;
|
||||||
if (sighandler_list.last_handler == async_handler_ptr)
|
if (sighandler_list.last_handler == (*async_handler_ptr))
|
||||||
sighandler_list.last_handler = prev_ptr;
|
sighandler_list.last_handler = prev_ptr;
|
||||||
}
|
}
|
||||||
free ((char *) async_handler_ptr);
|
free ((char *) (*async_handler_ptr));
|
||||||
|
(*async_handler_ptr) = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Is it necessary to call invoke_async_signal_handler? */
|
/* Is it necessary to call invoke_async_signal_handler? */
|
||||||
|
|
|
@ -230,7 +230,7 @@ extern void add_file_handler PARAMS ((int, file_handler_func, gdb_client_data));
|
||||||
extern void mark_async_signal_handler PARAMS ((async_signal_handler *));
|
extern void mark_async_signal_handler PARAMS ((async_signal_handler *));
|
||||||
extern async_signal_handler *
|
extern async_signal_handler *
|
||||||
create_async_signal_handler PARAMS ((async_handler_func *, gdb_client_data));
|
create_async_signal_handler PARAMS ((async_handler_func *, gdb_client_data));
|
||||||
extern void delete_async_signal_handler PARAMS ((async_signal_handler *async_handler_ptr));
|
extern void delete_async_signal_handler PARAMS ((async_signal_handler **async_handler_ptr));
|
||||||
|
|
||||||
/* Exported functions from event-top.c.
|
/* Exported functions from event-top.c.
|
||||||
FIXME: these should really go into top.h. */
|
FIXME: these should really go into top.h. */
|
||||||
|
@ -241,6 +241,9 @@ extern void set_async_editing_command PARAMS ((char *, int, struct cmd_list_elem
|
||||||
extern void set_async_annotation_level PARAMS ((char *, int, struct cmd_list_element *));
|
extern void set_async_annotation_level PARAMS ((char *, int, struct cmd_list_element *));
|
||||||
extern void set_async_prompt PARAMS ((char *, int, struct cmd_list_element *));
|
extern void set_async_prompt PARAMS ((char *, int, struct cmd_list_element *));
|
||||||
extern void handle_stop_sig PARAMS ((int));
|
extern void handle_stop_sig PARAMS ((int));
|
||||||
|
extern void handle_sigint PARAMS ((int));
|
||||||
|
extern void pop_prompt PARAMS ((void));
|
||||||
|
extern void push_prompt PARAMS ((char *, char *, char *));
|
||||||
extern void gdb_readline2 PARAMS ((void));
|
extern void gdb_readline2 PARAMS ((void));
|
||||||
|
|
||||||
/* Exported variables from event-top.c.
|
/* Exported variables from event-top.c.
|
||||||
|
|
101
gdb/event-top.c
101
gdb/event-top.c
|
@ -35,15 +35,16 @@
|
||||||
extern void _initialize_event_loop PARAMS ((void));
|
extern void _initialize_event_loop PARAMS ((void));
|
||||||
|
|
||||||
static void command_line_handler PARAMS ((char *));
|
static void command_line_handler PARAMS ((char *));
|
||||||
|
static void command_line_handler_continuation PARAMS ((struct continuation_arg *));
|
||||||
void gdb_readline2 PARAMS ((void));
|
void gdb_readline2 PARAMS ((void));
|
||||||
static void pop_prompt PARAMS ((void));
|
void pop_prompt PARAMS ((void));
|
||||||
static void push_prompt PARAMS ((char *, char *, char *));
|
void push_prompt PARAMS ((char *, char *, char *));
|
||||||
static void change_line_handler PARAMS ((void));
|
static void change_line_handler PARAMS ((void));
|
||||||
static void change_annotation_level PARAMS ((void));
|
static void change_annotation_level PARAMS ((void));
|
||||||
static void command_handler PARAMS ((char *));
|
static void command_handler PARAMS ((char *));
|
||||||
|
|
||||||
/* Signal handlers. */
|
/* Signal handlers. */
|
||||||
static void handle_sigint PARAMS ((int));
|
void handle_sigint PARAMS ((int));
|
||||||
static void handle_sigquit PARAMS ((int));
|
static void handle_sigquit PARAMS ((int));
|
||||||
static void handle_sighup PARAMS ((int));
|
static void handle_sighup PARAMS ((int));
|
||||||
static void handle_sigfpe PARAMS ((int));
|
static void handle_sigfpe PARAMS ((int));
|
||||||
|
@ -331,7 +332,7 @@ change_annotation_level ()
|
||||||
parts: prefix, prompt, suffix. Usually prefix and suffix are empty
|
parts: prefix, prompt, suffix. Usually prefix and suffix are empty
|
||||||
strings, except when the annotation level is 2. Memory is allocated
|
strings, except when the annotation level is 2. Memory is allocated
|
||||||
within savestring for the new prompt. */
|
within savestring for the new prompt. */
|
||||||
static void
|
void
|
||||||
push_prompt (prefix, prompt, suffix)
|
push_prompt (prefix, prompt, suffix)
|
||||||
char *prefix;
|
char *prefix;
|
||||||
char *prompt;
|
char *prompt;
|
||||||
|
@ -340,6 +341,9 @@ push_prompt (prefix, prompt, suffix)
|
||||||
the_prompts.top++;
|
the_prompts.top++;
|
||||||
PREFIX (0) = savestring (prefix, strlen (prefix));
|
PREFIX (0) = savestring (prefix, strlen (prefix));
|
||||||
|
|
||||||
|
/* Note that this function is used by the set annotate 2
|
||||||
|
command. This is why we take care of saving the old prompt
|
||||||
|
in case a new one is not specified. */
|
||||||
if (prompt)
|
if (prompt)
|
||||||
PROMPT (0) = savestring (prompt, strlen (prompt));
|
PROMPT (0) = savestring (prompt, strlen (prompt));
|
||||||
else
|
else
|
||||||
|
@ -349,14 +353,21 @@ push_prompt (prefix, prompt, suffix)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pops the top of the prompt stack, and frees the memory allocated for it. */
|
/* Pops the top of the prompt stack, and frees the memory allocated for it. */
|
||||||
static void
|
void
|
||||||
pop_prompt ()
|
pop_prompt ()
|
||||||
{
|
{
|
||||||
if (strcmp (PROMPT (0), PROMPT (-1)))
|
/* If we are not during a 'synchronous' execution command, in which
|
||||||
{
|
case, the top prompt would be empty. */
|
||||||
free (PROMPT (-1));
|
if (strcmp (PROMPT (0), ""))
|
||||||
PROMPT (-1) = savestring (PROMPT (0), strlen (PROMPT (0)));
|
/* This is for the case in which the prompt is set while the
|
||||||
}
|
annotation level is 2. The top prompt will be changed, but when
|
||||||
|
we return to annotation level < 2, we want that new prompt to be
|
||||||
|
in effect, until the user does another 'set prompt'. */
|
||||||
|
if (strcmp (PROMPT (0), PROMPT (-1)))
|
||||||
|
{
|
||||||
|
free (PROMPT (-1));
|
||||||
|
PROMPT (-1) = savestring (PROMPT (0), strlen (PROMPT (0)));
|
||||||
|
}
|
||||||
|
|
||||||
free (PREFIX (0));
|
free (PREFIX (0));
|
||||||
free (PROMPT (0));
|
free (PROMPT (0));
|
||||||
|
@ -376,6 +387,8 @@ command_handler (command)
|
||||||
{
|
{
|
||||||
struct cleanup *old_chain;
|
struct cleanup *old_chain;
|
||||||
int stdin_is_tty = ISATTY (stdin);
|
int stdin_is_tty = ISATTY (stdin);
|
||||||
|
struct continuation_arg *arg1;
|
||||||
|
struct continuation_arg *arg2;
|
||||||
long time_at_cmd_start;
|
long time_at_cmd_start;
|
||||||
#ifdef HAVE_SBRK
|
#ifdef HAVE_SBRK
|
||||||
long space_at_cmd_start = 0;
|
long space_at_cmd_start = 0;
|
||||||
|
@ -417,9 +430,70 @@ command_handler (command)
|
||||||
|
|
||||||
execute_command (command, instream == stdin);
|
execute_command (command, instream == stdin);
|
||||||
|
|
||||||
/* Do any commands attached to breakpoint we stopped at. */
|
/* Set things up for this function to be compete later, once the
|
||||||
|
executin has completed, if we are doing an execution command,
|
||||||
|
otherwise, just go ahead and finish. */
|
||||||
|
if (target_has_async && target_executing)
|
||||||
|
{
|
||||||
|
arg1 =
|
||||||
|
(struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
|
||||||
|
arg2 =
|
||||||
|
(struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
|
||||||
|
arg1->next = arg2;
|
||||||
|
arg2->next = NULL;
|
||||||
|
arg1->data = (PTR) time_at_cmd_start;
|
||||||
|
arg2->data = (PTR) space_at_cmd_start;
|
||||||
|
add_continuation (command_line_handler_continuation, arg1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do any commands attached to breakpoint we stopped at. Only if we
|
||||||
|
are always running synchronously. Or if we have just executed a
|
||||||
|
command that doesn't start the target. */
|
||||||
|
if (!target_has_async || !target_executing)
|
||||||
|
{
|
||||||
|
bpstat_do_actions (&stop_bpstat);
|
||||||
|
do_cleanups (old_chain);
|
||||||
|
|
||||||
|
if (display_time)
|
||||||
|
{
|
||||||
|
long cmd_time = get_run_time () - time_at_cmd_start;
|
||||||
|
|
||||||
|
printf_unfiltered ("Command execution time: %ld.%06ld\n",
|
||||||
|
cmd_time / 1000000, cmd_time % 1000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (display_space)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_SBRK
|
||||||
|
extern char **environ;
|
||||||
|
char *lim = (char *) sbrk (0);
|
||||||
|
long space_now = lim - (char *) &environ;
|
||||||
|
long space_diff = space_now - space_at_cmd_start;
|
||||||
|
|
||||||
|
printf_unfiltered ("Space used: %ld (%c%ld for this command)\n",
|
||||||
|
space_now,
|
||||||
|
(space_diff >= 0 ? '+' : '-'),
|
||||||
|
space_diff);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do any commands attached to breakpoint we stopped at. Only if we
|
||||||
|
are always running synchronously. Or if we have just executed a
|
||||||
|
command that doesn't start the target. */
|
||||||
|
void
|
||||||
|
command_line_handler_continuation (arg)
|
||||||
|
struct continuation_arg *arg;
|
||||||
|
{
|
||||||
|
extern int display_time;
|
||||||
|
extern int display_space;
|
||||||
|
|
||||||
|
long time_at_cmd_start = (long) arg->data;
|
||||||
|
long space_at_cmd_start = (long) arg->next->data;
|
||||||
|
|
||||||
bpstat_do_actions (&stop_bpstat);
|
bpstat_do_actions (&stop_bpstat);
|
||||||
do_cleanups (old_chain);
|
/*do_cleanups (old_chain);*/ /*?????FIXME?????*/
|
||||||
|
|
||||||
if (display_time)
|
if (display_time)
|
||||||
{
|
{
|
||||||
|
@ -428,7 +502,6 @@ command_handler (command)
|
||||||
printf_unfiltered ("Command execution time: %ld.%06ld\n",
|
printf_unfiltered ("Command execution time: %ld.%06ld\n",
|
||||||
cmd_time / 1000000, cmd_time % 1000000);
|
cmd_time / 1000000, cmd_time % 1000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (display_space)
|
if (display_space)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_SBRK
|
#ifdef HAVE_SBRK
|
||||||
|
@ -797,7 +870,7 @@ mark_async_signal_handler_wrapper (token)
|
||||||
|
|
||||||
/* Tell the event loop what to do if SIGINT is received.
|
/* Tell the event loop what to do if SIGINT is received.
|
||||||
See event-signal.c. */
|
See event-signal.c. */
|
||||||
static void
|
void
|
||||||
handle_sigint (sig)
|
handle_sigint (sig)
|
||||||
int sig;
|
int sig;
|
||||||
{
|
{
|
||||||
|
|
|
@ -134,6 +134,7 @@ extern int default_frame_chain_valid PARAMS ((CORE_ADDR, struct frame_info *));
|
||||||
extern int alternate_frame_chain_valid PARAMS ((CORE_ADDR, struct frame_info *));
|
extern int alternate_frame_chain_valid PARAMS ((CORE_ADDR, struct frame_info *));
|
||||||
extern int nonnull_frame_chain_valid PARAMS ((CORE_ADDR, struct frame_info *));
|
extern int nonnull_frame_chain_valid PARAMS ((CORE_ADDR, struct frame_info *));
|
||||||
extern int generic_frame_chain_valid PARAMS ((CORE_ADDR, struct frame_info *));
|
extern int generic_frame_chain_valid PARAMS ((CORE_ADDR, struct frame_info *));
|
||||||
|
extern void generic_save_dummy_frame_tos PARAMS ((CORE_ADDR sp));
|
||||||
|
|
||||||
#if !defined (FRAME_CHAIN_VALID)
|
#if !defined (FRAME_CHAIN_VALID)
|
||||||
#if !defined (FRAME_CHAIN_VALID_ALTERNATE)
|
#if !defined (FRAME_CHAIN_VALID_ALTERNATE)
|
||||||
|
|
367
gdb/infcmd.c
367
gdb/infcmd.c
|
@ -33,6 +33,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
#include "language.h"
|
#include "language.h"
|
||||||
#include "symfile.h"
|
#include "symfile.h"
|
||||||
#include "objfiles.h"
|
#include "objfiles.h"
|
||||||
|
#include "event-loop.h"
|
||||||
|
|
||||||
/* Functions exported for general use: */
|
/* Functions exported for general use: */
|
||||||
|
|
||||||
|
@ -46,6 +47,8 @@ void registers_info PARAMS ((char *, int));
|
||||||
|
|
||||||
void continue_command PARAMS ((char *, int));
|
void continue_command PARAMS ((char *, int));
|
||||||
|
|
||||||
|
static void finish_command_continuation PARAMS ((struct continuation_arg *));
|
||||||
|
|
||||||
static void until_next_command PARAMS ((int));
|
static void until_next_command PARAMS ((int));
|
||||||
|
|
||||||
static void until_command PARAMS ((char *, int));
|
static void until_command PARAMS ((char *, int));
|
||||||
|
@ -94,6 +97,8 @@ static void run_no_args_command PARAMS ((char *args, int from_tty));
|
||||||
|
|
||||||
static void go_command PARAMS ((char *line_no, int from_tty));
|
static void go_command PARAMS ((char *line_no, int from_tty));
|
||||||
|
|
||||||
|
static int strip_bg_char PARAMS ((char **));
|
||||||
|
|
||||||
void _initialize_infcmd PARAMS ((void));
|
void _initialize_infcmd PARAMS ((void));
|
||||||
|
|
||||||
#define GO_USAGE "Usage: go <location>\n"
|
#define GO_USAGE "Usage: go <location>\n"
|
||||||
|
@ -184,6 +189,35 @@ int step_multi;
|
||||||
struct environ *inferior_environ;
|
struct environ *inferior_environ;
|
||||||
|
|
||||||
|
|
||||||
|
/* This function detects whether or not a '&' character (indicating
|
||||||
|
background execution) has been added as *the last* of the arguments ARGS
|
||||||
|
of a command. If it has, it removes it and returns 1. Otherwise it
|
||||||
|
does nothing and returns 0. */
|
||||||
|
static int
|
||||||
|
strip_bg_char (args)
|
||||||
|
char **args;
|
||||||
|
{
|
||||||
|
char *p = NULL;
|
||||||
|
|
||||||
|
if (p = strchr (*args, '&'))
|
||||||
|
{
|
||||||
|
if (p == (*args + strlen (*args) - 1))
|
||||||
|
{
|
||||||
|
if (strlen (*args) >1)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
p--;
|
||||||
|
while (*p == ' ' || *p == '\t');
|
||||||
|
*(p + 1) = '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*args = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
void
|
void
|
||||||
tty_command (file, from_tty)
|
tty_command (file, from_tty)
|
||||||
|
@ -239,12 +273,33 @@ Start it from the beginning? "))
|
||||||
the user has to manually nuke all symbols between runs if they
|
the user has to manually nuke all symbols between runs if they
|
||||||
want them to go away (PR 2207). This is probably reasonable. */
|
want them to go away (PR 2207). This is probably reasonable. */
|
||||||
|
|
||||||
if (args)
|
if (!args)
|
||||||
|
sync_execution = 1;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
char *cmd;
|
char *cmd;
|
||||||
cmd = concat ("set args ", args, NULL);
|
int async_exec = strip_bg_char (&args);
|
||||||
make_cleanup (free, cmd);
|
|
||||||
execute_command (cmd, from_tty);
|
/* If we get a request for running in the bg but the target
|
||||||
|
doesn't support it, error out. */
|
||||||
|
if (async_p && async_exec && !target_has_async)
|
||||||
|
error ("Asynchronous execution not supported on this target.");
|
||||||
|
|
||||||
|
/* If we don't get a request of running in the bg, then we need
|
||||||
|
to simulate synchronous (fg) execution. */
|
||||||
|
if (async_p && !async_exec && target_has_async)
|
||||||
|
{
|
||||||
|
/* Simulate synchronous execution */
|
||||||
|
sync_execution = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If there were other args, beside '&', process them. */
|
||||||
|
if (args)
|
||||||
|
{
|
||||||
|
cmd = concat ("set args ", args, NULL);
|
||||||
|
make_cleanup (free, cmd);
|
||||||
|
execute_command (cmd, from_tty);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (from_tty)
|
if (from_tty)
|
||||||
|
@ -278,10 +333,28 @@ continue_command (proc_count_exp, from_tty)
|
||||||
char *proc_count_exp;
|
char *proc_count_exp;
|
||||||
int from_tty;
|
int from_tty;
|
||||||
{
|
{
|
||||||
|
int async_exec = 0;
|
||||||
ERROR_NO_INFERIOR;
|
ERROR_NO_INFERIOR;
|
||||||
|
|
||||||
/* If have argument, set proceed count of breakpoint we stopped at. */
|
/* Find out whether we must run in the background. */
|
||||||
|
if (proc_count_exp != NULL)
|
||||||
|
async_exec = strip_bg_char (&proc_count_exp);
|
||||||
|
|
||||||
|
/* If we must run in the background, but the target can't do it,
|
||||||
|
error out. */
|
||||||
|
if (async_p && async_exec && !target_has_async)
|
||||||
|
error ("Asynchronous execution not supported on this target.");
|
||||||
|
|
||||||
|
/* If we are not asked to run in the bg, then prepare to run in the
|
||||||
|
foreground, synchronously. */
|
||||||
|
if (async_p && !async_exec && target_has_async)
|
||||||
|
{
|
||||||
|
/* Simulate synchronous execution */
|
||||||
|
sync_execution = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If have argument (besides '&'), set proceed count of breakpoint
|
||||||
|
we stopped at. */
|
||||||
if (proc_count_exp != NULL)
|
if (proc_count_exp != NULL)
|
||||||
{
|
{
|
||||||
bpstat bs = stop_bpstat;
|
bpstat bs = stop_bpstat;
|
||||||
|
@ -363,8 +436,26 @@ step_1 (skip_subroutines, single_inst, count_string)
|
||||||
register int count = 1;
|
register int count = 1;
|
||||||
struct frame_info *frame;
|
struct frame_info *frame;
|
||||||
struct cleanup *cleanups = 0;
|
struct cleanup *cleanups = 0;
|
||||||
|
int async_exec = 0;
|
||||||
|
|
||||||
ERROR_NO_INFERIOR;
|
ERROR_NO_INFERIOR;
|
||||||
|
|
||||||
|
if (count_string)
|
||||||
|
async_exec = strip_bg_char (&count_string);
|
||||||
|
|
||||||
|
/* If we get a request for running in the bg but the target
|
||||||
|
doesn't support it, error out. */
|
||||||
|
if (async_p && async_exec && !target_has_async)
|
||||||
|
error ("Asynchronous execution not supported on this target.");
|
||||||
|
|
||||||
|
/* If we don't get a request of running in the bg, then we need
|
||||||
|
to simulate synchronous (fg) execution. */
|
||||||
|
if (async_p && !async_exec && target_has_async)
|
||||||
|
{
|
||||||
|
/* Simulate synchronous execution */
|
||||||
|
sync_execution = 1;
|
||||||
|
}
|
||||||
|
|
||||||
count = count_string ? parse_and_eval_address (count_string) : 1;
|
count = count_string ? parse_and_eval_address (count_string) : 1;
|
||||||
|
|
||||||
if (!single_inst || skip_subroutines) /* leave si command alone */
|
if (!single_inst || skip_subroutines) /* leave si command alone */
|
||||||
|
@ -443,9 +534,27 @@ jump_command (arg, from_tty)
|
||||||
struct symtab_and_line sal;
|
struct symtab_and_line sal;
|
||||||
struct symbol *fn;
|
struct symbol *fn;
|
||||||
struct symbol *sfn;
|
struct symbol *sfn;
|
||||||
|
int async_exec = 0;
|
||||||
|
|
||||||
ERROR_NO_INFERIOR;
|
ERROR_NO_INFERIOR;
|
||||||
|
|
||||||
|
/* Find out whether we must run in the background. */
|
||||||
|
if (arg != NULL)
|
||||||
|
async_exec = strip_bg_char (&arg);
|
||||||
|
|
||||||
|
/* If we must run in the background, but the target can't do it,
|
||||||
|
error out. */
|
||||||
|
if (async_p && async_exec && !target_has_async)
|
||||||
|
error ("Asynchronous execution not supported on this target.");
|
||||||
|
|
||||||
|
/* If we are not asked to run in the bg, then prepare to run in the
|
||||||
|
foreground, synchronously. */
|
||||||
|
if (async_p && !async_exec && target_has_async)
|
||||||
|
{
|
||||||
|
/* Simulate synchronous execution */
|
||||||
|
sync_execution = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (!arg)
|
if (!arg)
|
||||||
error_no_arg ("starting address");
|
error_no_arg ("starting address");
|
||||||
|
|
||||||
|
@ -490,7 +599,6 @@ jump_command (arg, from_tty)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
addr = sal.pc;
|
addr = sal.pc;
|
||||||
|
|
||||||
if (from_tty)
|
if (from_tty)
|
||||||
|
@ -731,14 +839,110 @@ until_command (arg, from_tty)
|
||||||
char *arg;
|
char *arg;
|
||||||
int from_tty;
|
int from_tty;
|
||||||
{
|
{
|
||||||
|
int async_exec = 0;
|
||||||
|
|
||||||
if (!target_has_execution)
|
if (!target_has_execution)
|
||||||
error ("The program is not running.");
|
error ("The program is not running.");
|
||||||
|
|
||||||
|
/* Find out whether we must run in the background. */
|
||||||
|
if (arg != NULL)
|
||||||
|
async_exec = strip_bg_char (&arg);
|
||||||
|
|
||||||
|
/* If we must run in the background, but the target can't do it,
|
||||||
|
error out. */
|
||||||
|
if (async_p && async_exec && !target_has_async)
|
||||||
|
error ("Asynchronous execution not supported on this target.");
|
||||||
|
|
||||||
|
/* If we are not asked to run in the bg, then prepare to run in the
|
||||||
|
foreground, synchronously. */
|
||||||
|
if (async_p && !async_exec && target_has_async)
|
||||||
|
{
|
||||||
|
/* Simulate synchronous execution */
|
||||||
|
sync_execution = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (arg)
|
if (arg)
|
||||||
until_break_command (arg, from_tty);
|
until_break_command (arg, from_tty);
|
||||||
else
|
else
|
||||||
until_next_command (from_tty);
|
until_next_command (from_tty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Stuff that needs to be done by the finish command after the target
|
||||||
|
has stopped. In asynchronous mode, we wait for the target to stop in
|
||||||
|
the call to poll or select in the event loop, so it is impossible to
|
||||||
|
do all the stuff as part of the finish_command function itself. The
|
||||||
|
only chance we have to complete this command is in
|
||||||
|
fetch_inferior_event, which is called by the event loop as soon as it
|
||||||
|
detects that the target has stopped. This function is called via the
|
||||||
|
cmd_continaution pointer. */
|
||||||
|
void
|
||||||
|
finish_command_continuation (arg)
|
||||||
|
struct continuation_arg *arg;
|
||||||
|
{
|
||||||
|
register struct symbol *function;
|
||||||
|
struct breakpoint *breakpoint;
|
||||||
|
|
||||||
|
breakpoint = (struct breakpoint *) arg->data;
|
||||||
|
function = (struct symbol *) (arg->next)->data;
|
||||||
|
|
||||||
|
if (bpstat_find_breakpoint(stop_bpstat, breakpoint) != NULL
|
||||||
|
&& function != 0)
|
||||||
|
{
|
||||||
|
struct type *value_type;
|
||||||
|
register value_ptr val;
|
||||||
|
CORE_ADDR funcaddr;
|
||||||
|
int struct_return;
|
||||||
|
|
||||||
|
value_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (function));
|
||||||
|
if (!value_type)
|
||||||
|
fatal ("internal: finish_command: function has no target type");
|
||||||
|
|
||||||
|
if (TYPE_CODE (value_type) == TYPE_CODE_VOID)
|
||||||
|
{
|
||||||
|
do_exec_cleanups (ALL_CLEANUPS);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
funcaddr = BLOCK_START (SYMBOL_BLOCK_VALUE (function));
|
||||||
|
|
||||||
|
struct_return = using_struct_return (value_of_variable (function, NULL),
|
||||||
|
|
||||||
|
funcaddr,
|
||||||
|
check_typedef (value_type),
|
||||||
|
BLOCK_GCC_COMPILED (SYMBOL_BLOCK_VALUE (function)));
|
||||||
|
|
||||||
|
if (!struct_return)
|
||||||
|
{
|
||||||
|
val = value_being_returned (value_type, stop_registers, struct_return);
|
||||||
|
printf_filtered ("Value returned is $%d = ", record_latest_value (val));
|
||||||
|
value_print (val, gdb_stdout, 0, Val_no_prettyprint);
|
||||||
|
printf_filtered ("\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* We cannot determine the contents of the structure because
|
||||||
|
it is on the stack, and we don't know where, since we did not
|
||||||
|
initiate the call, as opposed to the call_function_by_hand case */
|
||||||
|
#ifdef VALUE_RETURNED_FROM_STACK
|
||||||
|
val = 0;
|
||||||
|
printf_filtered ("Value returned has type: %s.",
|
||||||
|
TYPE_NAME (value_type));
|
||||||
|
printf_filtered (" Cannot determine contents\n");
|
||||||
|
#else
|
||||||
|
val = value_being_returned (value_type, stop_registers,
|
||||||
|
struct_return);
|
||||||
|
printf_filtered ("Value returned is $%d = ",
|
||||||
|
record_latest_value (val));
|
||||||
|
value_print (val, gdb_stdout, 0, Val_no_prettyprint);
|
||||||
|
printf_filtered ("\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
do_exec_cleanups (ALL_CLEANUPS);
|
||||||
|
}
|
||||||
|
|
||||||
/* "finish": Set a temporary breakpoint at the place
|
/* "finish": Set a temporary breakpoint at the place
|
||||||
the selected frame will return to, then continue. */
|
the selected frame will return to, then continue. */
|
||||||
|
|
||||||
|
@ -752,6 +956,26 @@ finish_command (arg, from_tty)
|
||||||
register struct symbol *function;
|
register struct symbol *function;
|
||||||
struct breakpoint *breakpoint;
|
struct breakpoint *breakpoint;
|
||||||
struct cleanup *old_chain;
|
struct cleanup *old_chain;
|
||||||
|
struct continuation_arg *arg1, *arg2;
|
||||||
|
|
||||||
|
int async_exec = 0;
|
||||||
|
|
||||||
|
/* Find out whether we must run in the background. */
|
||||||
|
if (arg != NULL)
|
||||||
|
async_exec = strip_bg_char (&arg);
|
||||||
|
|
||||||
|
/* If we must run in the background, but the target can't do it,
|
||||||
|
error out. */
|
||||||
|
if (async_p && async_exec && !target_has_async)
|
||||||
|
error ("Asynchronous execution not supported on this target.");
|
||||||
|
|
||||||
|
/* If we are not asked to run in the bg, then prepare to run in the
|
||||||
|
foreground, synchronously. */
|
||||||
|
if (async_p && !async_exec && target_has_async)
|
||||||
|
{
|
||||||
|
/* Simulate synchronous execution */
|
||||||
|
sync_execution = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (arg)
|
if (arg)
|
||||||
error ("The \"finish\" command does not take any arguments.");
|
error ("The \"finish\" command does not take any arguments.");
|
||||||
|
@ -771,7 +995,10 @@ finish_command (arg, from_tty)
|
||||||
|
|
||||||
breakpoint = set_momentary_breakpoint (sal, frame, bp_finish);
|
breakpoint = set_momentary_breakpoint (sal, frame, bp_finish);
|
||||||
|
|
||||||
old_chain = make_cleanup ((make_cleanup_func) delete_breakpoint, breakpoint);
|
if (!async_p || !target_has_async)
|
||||||
|
old_chain = make_cleanup ((make_cleanup_func) delete_breakpoint, breakpoint);
|
||||||
|
else
|
||||||
|
make_exec_cleanup ((make_cleanup_func) delete_breakpoint, breakpoint);
|
||||||
|
|
||||||
/* Find the function we will return from. */
|
/* Find the function we will return from. */
|
||||||
|
|
||||||
|
@ -785,62 +1012,89 @@ finish_command (arg, from_tty)
|
||||||
print_stack_frame (selected_frame, selected_frame_level, 0);
|
print_stack_frame (selected_frame, selected_frame_level, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If running asynchronously and the target support asynchronous
|
||||||
|
execution, set things up for the rest of the finish command to be
|
||||||
|
completed later on, when gdb has detected that the target has
|
||||||
|
stopped, in fetch_inferior_event. */
|
||||||
|
if (async_p && target_has_async)
|
||||||
|
{
|
||||||
|
arg1 =
|
||||||
|
(struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
|
||||||
|
arg2 =
|
||||||
|
(struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
|
||||||
|
arg1->next = arg2;
|
||||||
|
arg2->next = NULL;
|
||||||
|
arg1->data = (PTR) breakpoint;
|
||||||
|
arg2->data = (PTR) function;
|
||||||
|
add_continuation (finish_command_continuation, arg1);
|
||||||
|
}
|
||||||
|
|
||||||
proceed_to_finish = 1; /* We want stop_registers, please... */
|
proceed_to_finish = 1; /* We want stop_registers, please... */
|
||||||
proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
|
proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
|
||||||
|
|
||||||
/* Did we stop at our breakpoint? */
|
/* Do this only if not running asynchronously or if the target
|
||||||
if (bpstat_find_breakpoint(stop_bpstat, breakpoint) != NULL
|
cannot do async execution. Otherwise, complete this command when
|
||||||
&& function != 0)
|
the target actually stops, in fetch_inferior_event.*/
|
||||||
{
|
if (!async_p || !target_has_async)
|
||||||
struct type *value_type;
|
{
|
||||||
register value_ptr val;
|
|
||||||
CORE_ADDR funcaddr;
|
|
||||||
int struct_return;
|
|
||||||
|
|
||||||
value_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (function));
|
/* Did we stop at our breakpoint? */
|
||||||
if (!value_type)
|
if (bpstat_find_breakpoint(stop_bpstat, breakpoint) != NULL
|
||||||
fatal ("internal: finish_command: function has no target type");
|
&& function != 0)
|
||||||
|
{
|
||||||
|
struct type *value_type;
|
||||||
|
register value_ptr val;
|
||||||
|
CORE_ADDR funcaddr;
|
||||||
|
int struct_return;
|
||||||
|
|
||||||
if (TYPE_CODE (value_type) == TYPE_CODE_VOID)
|
value_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (function));
|
||||||
return;
|
if (!value_type)
|
||||||
|
fatal ("internal: finish_command: function has no target type");
|
||||||
|
|
||||||
funcaddr = BLOCK_START (SYMBOL_BLOCK_VALUE (function));
|
/* FIXME: Shouldn't we do the cleanups before returning? */
|
||||||
|
if (TYPE_CODE (value_type) == TYPE_CODE_VOID)
|
||||||
|
return;
|
||||||
|
|
||||||
struct_return = using_struct_return (value_of_variable (function, NULL),
|
funcaddr = BLOCK_START (SYMBOL_BLOCK_VALUE (function));
|
||||||
|
|
||||||
|
struct_return =
|
||||||
|
using_struct_return (value_of_variable (function, NULL),
|
||||||
funcaddr,
|
funcaddr,
|
||||||
check_typedef (value_type),
|
check_typedef (value_type),
|
||||||
BLOCK_GCC_COMPILED (SYMBOL_BLOCK_VALUE (function)));
|
BLOCK_GCC_COMPILED (SYMBOL_BLOCK_VALUE (function)));
|
||||||
|
|
||||||
if (!struct_return)
|
if (!struct_return)
|
||||||
{
|
{
|
||||||
val = value_being_returned (value_type, stop_registers, struct_return);
|
val =
|
||||||
printf_filtered ("Value returned is $%d = ", record_latest_value (val));
|
value_being_returned (value_type, stop_registers, struct_return);
|
||||||
value_print (val, gdb_stdout, 0, Val_no_prettyprint);
|
printf_filtered ("Value returned is $%d = ",
|
||||||
printf_filtered ("\n");
|
record_latest_value (val));
|
||||||
}
|
value_print (val, gdb_stdout, 0, Val_no_prettyprint);
|
||||||
else
|
printf_filtered ("\n");
|
||||||
{
|
}
|
||||||
/* elz: we cannot determine the contents of the structure because
|
else
|
||||||
it is on the stack, and we don't know where, since we did not
|
{
|
||||||
initiate the call, as opposed to the call_function_by_hand case */
|
/* We cannot determine the contents of the structure
|
||||||
|
because it is on the stack, and we don't know
|
||||||
|
where, since we did not initiate the call, as
|
||||||
|
opposed to the call_function_by_hand case */
|
||||||
#ifdef VALUE_RETURNED_FROM_STACK
|
#ifdef VALUE_RETURNED_FROM_STACK
|
||||||
val = 0;
|
val = 0;
|
||||||
printf_filtered ("Value returned has type: %s.",
|
printf_filtered ("Value returned has type: %s.",
|
||||||
TYPE_NAME (value_type));
|
TYPE_NAME (value_type));
|
||||||
printf_filtered (" Cannot determine contents\n");
|
printf_filtered (" Cannot determine contents\n");
|
||||||
#else
|
#else
|
||||||
val = value_being_returned (value_type, stop_registers,
|
val = value_being_returned (value_type, stop_registers,
|
||||||
struct_return);
|
struct_return);
|
||||||
printf_filtered ("Value returned is $%d = ",
|
printf_filtered ("Value returned is $%d = ",
|
||||||
record_latest_value (val));
|
record_latest_value (val));
|
||||||
value_print (val, gdb_stdout, 0, Val_no_prettyprint);
|
value_print (val, gdb_stdout, 0, Val_no_prettyprint);
|
||||||
printf_filtered ("\n");
|
printf_filtered ("\n");
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
do_cleanups(old_chain);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
do_cleanups(old_chain);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
|
@ -1355,6 +1609,20 @@ detach_command (args, from_tty)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Stop the execution of the target while running in async mode, in
|
||||||
|
the backgound. */
|
||||||
|
static void
|
||||||
|
interrupt_target_command (args, from_tty)
|
||||||
|
char *args;
|
||||||
|
int from_tty;
|
||||||
|
{
|
||||||
|
if (async_p && target_has_async)
|
||||||
|
{
|
||||||
|
dont_repeat (); /* Not for the faint of heart */
|
||||||
|
target_stop ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
static void
|
static void
|
||||||
float_info (addr_exp, from_tty)
|
float_info (addr_exp, from_tty)
|
||||||
|
@ -1530,6 +1798,9 @@ use \"set args\" without arguments.");
|
||||||
add_com ("R", class_run, run_no_args_command,
|
add_com ("R", class_run, run_no_args_command,
|
||||||
"Start debugged program with no arguments.");
|
"Start debugged program with no arguments.");
|
||||||
|
|
||||||
|
add_com ("interrupt", class_run, interrupt_target_command,
|
||||||
|
"Interrupt the execution of the debugged program.");
|
||||||
|
|
||||||
add_info ("registers", nofp_registers_info,
|
add_info ("registers", nofp_registers_info,
|
||||||
"List of integer registers and their contents, for selected stack frame.\n\
|
"List of integer registers and their contents, for selected stack frame.\n\
|
||||||
Register name as argument means describe only that register.");
|
Register name as argument means describe only that register.");
|
||||||
|
|
|
@ -71,6 +71,17 @@ extern char *inferior_io_terminal;
|
||||||
|
|
||||||
extern int inferior_pid;
|
extern int inferior_pid;
|
||||||
|
|
||||||
|
/* Is the inferior running right now, as a result of a 'run&',
|
||||||
|
'continue&' etc command? This is used in asycn gdb to determine
|
||||||
|
whether a command that the user enters while the target is running
|
||||||
|
is allowed or not. */
|
||||||
|
extern int target_executing;
|
||||||
|
|
||||||
|
/* Are we simulating synchronous execution? This is used in async gdb
|
||||||
|
to implement the 'run', 'continue' etc commands, which will not
|
||||||
|
redisplay the prompt until the execution is actually over. */
|
||||||
|
extern int sync_execution;
|
||||||
|
|
||||||
/* This is only valid when inferior_pid is non-zero.
|
/* This is only valid when inferior_pid is non-zero.
|
||||||
|
|
||||||
If this is 0, then exec events should be noticed and responded to
|
If this is 0, then exec events should be noticed and responded to
|
||||||
|
@ -148,6 +159,8 @@ extern void generic_target_write_fp PARAMS ((CORE_ADDR));
|
||||||
|
|
||||||
extern void wait_for_inferior PARAMS ((void));
|
extern void wait_for_inferior PARAMS ((void));
|
||||||
|
|
||||||
|
extern void fetch_inferior_event PARAMS ((void));
|
||||||
|
|
||||||
extern void init_wait_for_inferior PARAMS ((void));
|
extern void init_wait_for_inferior PARAMS ((void));
|
||||||
|
|
||||||
extern void close_exec_file PARAMS ((void));
|
extern void close_exec_file PARAMS ((void));
|
||||||
|
|
123
gdb/infrun.c
123
gdb/infrun.c
|
@ -32,8 +32,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
#include "annotate.h"
|
#include "annotate.h"
|
||||||
#include "symfile.h" /* for overlay functions */
|
#include "symfile.h" /* for overlay functions */
|
||||||
#include "top.h"
|
#include "top.h"
|
||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include "event-loop.h"
|
||||||
|
|
||||||
/* Prototypes for local functions */
|
/* Prototypes for local functions */
|
||||||
|
|
||||||
|
@ -53,9 +53,14 @@ static void delete_breakpoint_current_contents PARAMS ((PTR));
|
||||||
|
|
||||||
static void set_follow_fork_mode_command PARAMS ((char *arg, int from_tty, struct cmd_list_element *c));
|
static void set_follow_fork_mode_command PARAMS ((char *arg, int from_tty, struct cmd_list_element *c));
|
||||||
|
|
||||||
|
static void complete_execution PARAMS ((void));
|
||||||
|
|
||||||
int inferior_ignoring_startup_exec_events = 0;
|
int inferior_ignoring_startup_exec_events = 0;
|
||||||
int inferior_ignoring_leading_exec_events = 0;
|
int inferior_ignoring_leading_exec_events = 0;
|
||||||
|
|
||||||
|
/* In asynchronous mode, but simulating synchronous execution. */
|
||||||
|
int sync_execution = 0;
|
||||||
|
|
||||||
/* wait_for_inferior and normal_stop use this to notify the user
|
/* wait_for_inferior and normal_stop use this to notify the user
|
||||||
when the inferior stopped in a different thread than it had been
|
when the inferior stopped in a different thread than it had been
|
||||||
running in. */
|
running in. */
|
||||||
|
@ -1006,9 +1011,13 @@ The same program may be running in another process.");
|
||||||
|
|
||||||
/* Wait for it to stop (if not standalone)
|
/* Wait for it to stop (if not standalone)
|
||||||
and in any case decode why it stopped, and act accordingly. */
|
and in any case decode why it stopped, and act accordingly. */
|
||||||
|
/* Do this only if we are not using the event loop, or if the target
|
||||||
wait_for_inferior ();
|
does not support asynchronous execution. */
|
||||||
normal_stop ();
|
if (!async_p || !target_has_async)
|
||||||
|
{
|
||||||
|
wait_for_inferior ();
|
||||||
|
normal_stop ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Record the pc and sp of the program the last time it stopped.
|
/* Record the pc and sp of the program the last time it stopped.
|
||||||
|
@ -1021,7 +1030,6 @@ static char *prev_func_name;
|
||||||
|
|
||||||
|
|
||||||
/* Start remote-debugging of a machine over a serial link. */
|
/* Start remote-debugging of a machine over a serial link. */
|
||||||
|
|
||||||
void
|
void
|
||||||
start_remote ()
|
start_remote ()
|
||||||
{
|
{
|
||||||
|
@ -1029,8 +1037,24 @@ start_remote ()
|
||||||
init_wait_for_inferior ();
|
init_wait_for_inferior ();
|
||||||
stop_soon_quietly = 1;
|
stop_soon_quietly = 1;
|
||||||
trap_expected = 0;
|
trap_expected = 0;
|
||||||
wait_for_inferior ();
|
|
||||||
normal_stop ();
|
/* Go on waiting only in case gdb is not started in async mode, or
|
||||||
|
in case the target doesn't support async execution. */
|
||||||
|
if (!async_p || !target_has_async)
|
||||||
|
{
|
||||||
|
wait_for_inferior ();
|
||||||
|
normal_stop ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The 'tar rem' command should always look synchronous,
|
||||||
|
i.e. display the prompt only once it has connected and
|
||||||
|
started the target. */
|
||||||
|
sync_execution = 1;
|
||||||
|
push_prompt ("", "", "");
|
||||||
|
delete_file_handler (input_fd);
|
||||||
|
target_executing = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize static vars when a new inferior begins. */
|
/* Initialize static vars when a new inferior begins. */
|
||||||
|
@ -1179,6 +1203,72 @@ wait_for_inferior ()
|
||||||
do_cleanups (old_cleanups);
|
do_cleanups (old_cleanups);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Asynchronous version of wait_for_inferior. It is called by the
|
||||||
|
event loop whenever a change of state is detected on the file
|
||||||
|
descriptor corresponding to the target. It can be called more than
|
||||||
|
once to complete a single execution command. In such cases we need
|
||||||
|
to keep the state in a global variable ASYNC_ECSS. If it is the
|
||||||
|
last time that this function is called for a single execution
|
||||||
|
command, then report to the user that the inferior has stopped, and
|
||||||
|
do the necessary cleanups. */
|
||||||
|
|
||||||
|
struct execution_control_state async_ecss;
|
||||||
|
struct execution_control_state *async_ecs;
|
||||||
|
|
||||||
|
void
|
||||||
|
fetch_inferior_event ()
|
||||||
|
{
|
||||||
|
static struct cleanup *old_cleanups;
|
||||||
|
|
||||||
|
async_ecs = &async_ecss;
|
||||||
|
|
||||||
|
if (!async_ecs->wait_some_more)
|
||||||
|
{
|
||||||
|
old_cleanups = make_exec_cleanup (delete_breakpoint_current_contents,
|
||||||
|
&step_resume_breakpoint);
|
||||||
|
make_exec_cleanup (delete_breakpoint_current_contents,
|
||||||
|
&through_sigtramp_breakpoint);
|
||||||
|
|
||||||
|
/* Fill in with reasonable starting values. */
|
||||||
|
init_execution_control_state (async_ecs);
|
||||||
|
|
||||||
|
thread_step_needed = 0;
|
||||||
|
|
||||||
|
/* We'll update this if & when we switch to a new thread. */
|
||||||
|
if (may_switch_from_inferior_pid)
|
||||||
|
switched_from_inferior_pid = inferior_pid;
|
||||||
|
|
||||||
|
overlay_cache_invalid = 1;
|
||||||
|
|
||||||
|
/* We have to invalidate the registers BEFORE calling target_wait
|
||||||
|
because they can be loaded from the target while in target_wait.
|
||||||
|
This makes remote debugging a bit more efficient for those
|
||||||
|
targets that provide critical registers as part of their normal
|
||||||
|
status mechanism. */
|
||||||
|
|
||||||
|
registers_changed ();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target_wait_hook)
|
||||||
|
async_ecs->pid = target_wait_hook (async_ecs->waiton_pid, async_ecs->wp);
|
||||||
|
else
|
||||||
|
async_ecs->pid = target_wait (async_ecs->waiton_pid, async_ecs->wp);
|
||||||
|
|
||||||
|
/* Now figure out what to do with the result of the result. */
|
||||||
|
handle_inferior_event (async_ecs);
|
||||||
|
|
||||||
|
if (!async_ecs->wait_some_more)
|
||||||
|
{
|
||||||
|
do_exec_cleanups (old_cleanups);
|
||||||
|
normal_stop ();
|
||||||
|
/* Is there anything left to do for the command issued to
|
||||||
|
complete? */
|
||||||
|
do_all_continuations ();
|
||||||
|
/* Reset things after target has stopped for the async commands. */
|
||||||
|
complete_execution ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Prepare an execution control state for looping through a
|
/* Prepare an execution control state for looping through a
|
||||||
wait_for_inferior-type loop. */
|
wait_for_inferior-type loop. */
|
||||||
|
|
||||||
|
@ -3011,6 +3101,25 @@ stopped_for_shlib_catchpoint (bs, cp_p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Reset proper settings after an asynchronous command has finished.
|
||||||
|
If the execution command was in synchronous mode, register stdin
|
||||||
|
with the event loop, and reset the prompt. */
|
||||||
|
static void
|
||||||
|
complete_execution ()
|
||||||
|
{
|
||||||
|
extern cleanup_sigint_signal_handler PARAMS ((void));
|
||||||
|
|
||||||
|
if (sync_execution)
|
||||||
|
{
|
||||||
|
add_file_handler (input_fd, (file_handler_func *) call_readline, 0);
|
||||||
|
pop_prompt ();
|
||||||
|
sync_execution = 0;
|
||||||
|
cleanup_sigint_signal_handler ();
|
||||||
|
display_gdb_prompt (0);
|
||||||
|
}
|
||||||
|
target_executing = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Here to return control to GDB when the inferior stops for real.
|
/* Here to return control to GDB when the inferior stops for real.
|
||||||
Print appropriate messages, remove breakpoints, give terminal our modes.
|
Print appropriate messages, remove breakpoints, give terminal our modes.
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,7 @@ int dbx_commands = 0;
|
||||||
GDB_FILE *gdb_stdout;
|
GDB_FILE *gdb_stdout;
|
||||||
GDB_FILE *gdb_stderr;
|
GDB_FILE *gdb_stderr;
|
||||||
GDB_FILE *gdb_stdlog;
|
GDB_FILE *gdb_stdlog;
|
||||||
|
GDB_FILE *gdb_stdtarg;
|
||||||
|
|
||||||
/* Whether to enable writing into executable and core files */
|
/* Whether to enable writing into executable and core files */
|
||||||
extern int write_files;
|
extern int write_files;
|
||||||
|
@ -163,10 +164,12 @@ main (argc, argv)
|
||||||
gdb_stdout = stdio_fileopen (stdout);
|
gdb_stdout = stdio_fileopen (stdout);
|
||||||
gdb_stderr = stdio_fileopen (stderr);
|
gdb_stderr = stdio_fileopen (stderr);
|
||||||
gdb_stdlog = gdb_stderr; /* for moment */
|
gdb_stdlog = gdb_stderr; /* for moment */
|
||||||
|
gdb_stdtarg = gdb_stderr; /* for moment */
|
||||||
#else
|
#else
|
||||||
gdb_stdout = tui_fileopen (stdout);
|
gdb_stdout = tui_fileopen (stdout);
|
||||||
gdb_stderr = tui_fileopen (stderr);
|
gdb_stderr = tui_fileopen (stderr);
|
||||||
gdb_stdlog = gdb_stdout; /* for moment */
|
gdb_stdlog = gdb_stdout; /* for moment */
|
||||||
|
gdb_stdtarg = gdb_stderr; /* for moment */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Parse arguments and options. */
|
/* Parse arguments and options. */
|
||||||
|
|
|
@ -275,7 +275,9 @@ mn10300_analyze_prologue (fi, pc)
|
||||||
/* Do nothing if we couldn't find the start of this function or if we're
|
/* Do nothing if we couldn't find the start of this function or if we're
|
||||||
stopped at the first instruction in the prologue. */
|
stopped at the first instruction in the prologue. */
|
||||||
if (status == 0)
|
if (status == 0)
|
||||||
return pc;
|
{
|
||||||
|
return pc;
|
||||||
|
}
|
||||||
|
|
||||||
/* If we're in start, then give up. */
|
/* If we're in start, then give up. */
|
||||||
if (strcmp (name, "start") == 0)
|
if (strcmp (name, "start") == 0)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* Remote debugging interface for boot monitors, for GDB.
|
/* Remote debugging interface for boot monitors, for GDB.
|
||||||
Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
|
Copyright 1990, 1991, 1992, 1993, 1999 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is part of GDB.
|
This file is part of GDB.
|
||||||
|
|
||||||
|
@ -40,14 +40,19 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
#include "gdbcore.h"
|
#include "gdbcore.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
#include "wait.h"
|
#include "wait.h"
|
||||||
|
|
||||||
#ifdef ANSI_PROTOTYPES
|
#ifdef ANSI_PROTOTYPES
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#else
|
#else
|
||||||
#include <varargs.h>
|
#include <varargs.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_SYS_SELECT_H
|
||||||
|
#include <sys/select.h>
|
||||||
|
#endif
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include "gdb_string.h"
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "gdb_string.h"
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
#include "serial.h"
|
#include "serial.h"
|
||||||
#include "monitor.h"
|
#include "monitor.h"
|
||||||
|
|
|
@ -197,10 +197,7 @@ gdb_os_write_stdout (p, buf, len)
|
||||||
{
|
{
|
||||||
b[0] = buf[i];
|
b[0] = buf[i];
|
||||||
b[1] = 0;
|
b[1] = 0;
|
||||||
if (target_output_hook)
|
fputs_unfiltered (b, gdb_stdtarg);
|
||||||
target_output_hook (b);
|
|
||||||
else
|
|
||||||
fputs_filtered (b, gdb_stdout);
|
|
||||||
}
|
}
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
@ -229,10 +226,7 @@ gdb_os_write_stderr (p, buf, len)
|
||||||
{
|
{
|
||||||
b[0] = buf[i];
|
b[0] = buf[i];
|
||||||
b[1] = 0;
|
b[1] = 0;
|
||||||
if (target_output_hook)
|
fputs_unfiltered (b, gdb_stdtarg);
|
||||||
target_output_hook (b);
|
|
||||||
else
|
|
||||||
fputs_filtered (b, gdb_stderr);
|
|
||||||
}
|
}
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* Remote debugging interface for Tandem ST2000 phone switch, for GDB.
|
/* Remote debugging interface for Tandem ST2000 phone switch, for GDB.
|
||||||
Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
|
Copyright 1990, 1991, 1992, 1999 Free Software Foundation, Inc.
|
||||||
Contributed by Cygnus Support. Written by Jim Kingdon for Cygnus.
|
Contributed by Cygnus Support. Written by Jim Kingdon for Cygnus.
|
||||||
|
|
||||||
This file is part of GDB.
|
This file is part of GDB.
|
||||||
|
@ -38,14 +38,19 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
#include "gdbcore.h"
|
#include "gdbcore.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
#include "wait.h"
|
#include "wait.h"
|
||||||
|
|
||||||
#ifdef ANSI_PROTOTYPES
|
#ifdef ANSI_PROTOTYPES
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#else
|
#else
|
||||||
#include <varargs.h>
|
#include <varargs.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_SYS_SELECT_H
|
||||||
|
#include <sys/select.h>
|
||||||
|
#endif
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include "gdb_string.h"
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "gdb_string.h"
|
||||||
#include "serial.h"
|
#include "serial.h"
|
||||||
|
|
||||||
extern struct target_ops st2000_ops; /* Forward declaration */
|
extern struct target_ops st2000_ops; /* Forward declaration */
|
||||||
|
|
676
gdb/remote.c
676
gdb/remote.c
|
@ -1,5 +1,5 @@
|
||||||
/* Remote target communications for serial-line targets in custom GDB protocol
|
/* Remote target communications for serial-line targets in custom GDB protocol
|
||||||
Copyright 1988, 91, 92, 93, 94, 95, 96, 97, 1998
|
Copyright 1988, 91, 92, 93, 94, 95, 96, 97, 98, 1999
|
||||||
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is part of GDB.
|
This file is part of GDB.
|
||||||
|
@ -219,10 +219,23 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_SELECT_H
|
||||||
|
#include <sys/select.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "event-loop.h"
|
||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include "serial.h"
|
#include "serial.h"
|
||||||
|
|
||||||
/* Prototypes for local functions */
|
/* Prototypes for local functions */
|
||||||
|
static void initialize_sigint_signal_handler PARAMS ((void));
|
||||||
|
static void handle_remote_sigint PARAMS ((int));
|
||||||
|
static void handle_remote_sigint_twice PARAMS ((int));
|
||||||
|
static void async_remote_interrupt PARAMS ((gdb_client_data));
|
||||||
|
static void async_remote_interrupt_twice PARAMS ((gdb_client_data));
|
||||||
|
|
||||||
|
static void set_extended_protocol PARAMS ((struct continuation_arg *));
|
||||||
|
|
||||||
static void build_remote_gdbarch_data PARAMS ((void));
|
static void build_remote_gdbarch_data PARAMS ((void));
|
||||||
|
|
||||||
|
@ -244,15 +257,21 @@ static void remote_fetch_registers PARAMS ((int regno));
|
||||||
|
|
||||||
static void remote_resume PARAMS ((int pid, int step,
|
static void remote_resume PARAMS ((int pid, int step,
|
||||||
enum target_signal siggnal));
|
enum target_signal siggnal));
|
||||||
|
static void remote_async_resume PARAMS ((int pid, int step,
|
||||||
|
enum target_signal siggnal));
|
||||||
|
|
||||||
static int remote_start_remote PARAMS ((PTR));
|
static int remote_start_remote PARAMS ((PTR));
|
||||||
|
|
||||||
static void remote_open PARAMS ((char *name, int from_tty));
|
static void remote_open PARAMS ((char *name, int from_tty));
|
||||||
|
static void remote_async_open PARAMS ((char *name, int from_tty));
|
||||||
|
|
||||||
static void extended_remote_open PARAMS ((char *name, int from_tty));
|
static void extended_remote_open PARAMS ((char *name, int from_tty));
|
||||||
|
static void extended_remote_async_open PARAMS ((char *name, int from_tty));
|
||||||
|
|
||||||
static void remote_open_1 PARAMS ((char *, int, struct target_ops *,
|
static void remote_open_1 PARAMS ((char *, int, struct target_ops *,
|
||||||
int extended_p));
|
int extended_p));
|
||||||
|
static void remote_async_open_1 PARAMS ((char *, int, struct target_ops *,
|
||||||
|
int extended_p));
|
||||||
|
|
||||||
static void remote_close PARAMS ((int quitting));
|
static void remote_close PARAMS ((int quitting));
|
||||||
|
|
||||||
|
@ -265,6 +284,7 @@ static void extended_remote_restart PARAMS ((void));
|
||||||
static void extended_remote_mourn PARAMS ((void));
|
static void extended_remote_mourn PARAMS ((void));
|
||||||
|
|
||||||
static void extended_remote_create_inferior PARAMS ((char *, char *, char **));
|
static void extended_remote_create_inferior PARAMS ((char *, char *, char **));
|
||||||
|
static void extended_remote_async_create_inferior PARAMS ((char *, char *, char **));
|
||||||
|
|
||||||
static void remote_mourn_1 PARAMS ((struct target_ops *));
|
static void remote_mourn_1 PARAMS ((struct target_ops *));
|
||||||
|
|
||||||
|
@ -273,12 +293,15 @@ static void remote_send PARAMS ((char *buf));
|
||||||
static int readchar PARAMS ((int timeout));
|
static int readchar PARAMS ((int timeout));
|
||||||
|
|
||||||
static int remote_wait PARAMS ((int pid, struct target_waitstatus * status));
|
static int remote_wait PARAMS ((int pid, struct target_waitstatus * status));
|
||||||
|
static int remote_async_wait PARAMS ((int pid, struct target_waitstatus * status));
|
||||||
|
|
||||||
static void remote_kill PARAMS ((void));
|
static void remote_kill PARAMS ((void));
|
||||||
|
static void remote_async_kill PARAMS ((void));
|
||||||
|
|
||||||
static int tohex PARAMS ((int nib));
|
static int tohex PARAMS ((int nib));
|
||||||
|
|
||||||
static void remote_detach PARAMS ((char *args, int from_tty));
|
static void remote_detach PARAMS ((char *args, int from_tty));
|
||||||
|
static void remote_async_detach PARAMS ((char *args, int from_tty));
|
||||||
|
|
||||||
static void remote_interrupt PARAMS ((int signo));
|
static void remote_interrupt PARAMS ((int signo));
|
||||||
|
|
||||||
|
@ -362,6 +385,12 @@ static struct target_ops remote_ops;
|
||||||
|
|
||||||
static struct target_ops extended_remote_ops;
|
static struct target_ops extended_remote_ops;
|
||||||
|
|
||||||
|
/* Temporary target ops. Just like the remote_ops and
|
||||||
|
extended_remote_ops, but with asynchronous support. */
|
||||||
|
static struct target_ops remote_async_ops;
|
||||||
|
|
||||||
|
static struct target_ops extended_async_remote_ops;
|
||||||
|
|
||||||
/* This was 5 seconds, which is a long time to sit and wait.
|
/* This was 5 seconds, which is a long time to sit and wait.
|
||||||
Unless this is going though some terminal server or multiplexer or
|
Unless this is going though some terminal server or multiplexer or
|
||||||
other form of hairy serial connection, I would think 2 seconds would
|
other form of hairy serial connection, I would think 2 seconds would
|
||||||
|
@ -444,6 +473,10 @@ static int remote_register_buf_size = 0;
|
||||||
doesn't support 'P', the only consequence is some unnecessary traffic. */
|
doesn't support 'P', the only consequence is some unnecessary traffic. */
|
||||||
static int stub_supports_P = 1;
|
static int stub_supports_P = 1;
|
||||||
|
|
||||||
|
/* Tokens for use by the asynchronous signal handlers for SIGINT */
|
||||||
|
PTR sigint_remote_twice_token;
|
||||||
|
PTR sigint_remote_token;
|
||||||
|
|
||||||
/* These are pointers to hook functions that may be set in order to
|
/* These are pointers to hook functions that may be set in order to
|
||||||
modify resume/wait behavior for a particular architecture. */
|
modify resume/wait behavior for a particular architecture. */
|
||||||
|
|
||||||
|
@ -1604,6 +1637,15 @@ remote_open (name, from_tty)
|
||||||
remote_open_1 (name, from_tty, &remote_ops, 0);
|
remote_open_1 (name, from_tty, &remote_ops, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Just like remote_open, but with asynchronous support. */
|
||||||
|
static void
|
||||||
|
remote_async_open (name, from_tty)
|
||||||
|
char *name;
|
||||||
|
int from_tty;
|
||||||
|
{
|
||||||
|
remote_async_open_1 (name, from_tty, &remote_async_ops, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* Open a connection to a remote debugger using the extended
|
/* Open a connection to a remote debugger using the extended
|
||||||
remote gdb protocol. NAME is the filename used for communication. */
|
remote gdb protocol. NAME is the filename used for communication. */
|
||||||
|
|
||||||
|
@ -1615,6 +1657,15 @@ extended_remote_open (name, from_tty)
|
||||||
remote_open_1 (name, from_tty, &extended_remote_ops, 1/*extended_p*/);
|
remote_open_1 (name, from_tty, &extended_remote_ops, 1/*extended_p*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Just like extended_remote_open, but with asynchronous support. */
|
||||||
|
static void
|
||||||
|
extended_remote_async_open (name, from_tty)
|
||||||
|
char *name;
|
||||||
|
int from_tty;
|
||||||
|
{
|
||||||
|
remote_async_open_1 (name, from_tty, &extended_async_remote_ops, 1/*extended_p*/);
|
||||||
|
}
|
||||||
|
|
||||||
/* Generic code for opening a connection to a remote target. */
|
/* Generic code for opening a connection to a remote target. */
|
||||||
|
|
||||||
static DCACHE *remote_dcache;
|
static DCACHE *remote_dcache;
|
||||||
|
@ -1649,7 +1700,6 @@ serial device is attached to the remote system (e.g. /dev/ttya).");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SERIAL_RAW (remote_desc);
|
SERIAL_RAW (remote_desc);
|
||||||
|
|
||||||
/* If there is something sitting in the buffer we might take it as a
|
/* If there is something sitting in the buffer we might take it as a
|
||||||
|
@ -1705,6 +1755,124 @@ serial device is attached to the remote system (e.g. /dev/ttya).");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Just like remote_open but with asynchronous support. */
|
||||||
|
static void
|
||||||
|
remote_async_open_1 (name, from_tty, target, extended_p)
|
||||||
|
char *name;
|
||||||
|
int from_tty;
|
||||||
|
struct target_ops *target;
|
||||||
|
int extended_p;
|
||||||
|
{
|
||||||
|
if (name == 0)
|
||||||
|
error ("To open a remote debug connection, you need to specify what\n\
|
||||||
|
serial device is attached to the remote system (e.g. /dev/ttya).");
|
||||||
|
|
||||||
|
target_preopen (from_tty);
|
||||||
|
|
||||||
|
unpush_target (target);
|
||||||
|
|
||||||
|
remote_dcache = dcache_init (remote_read_bytes, remote_write_bytes);
|
||||||
|
|
||||||
|
remote_desc = SERIAL_OPEN (name);
|
||||||
|
if (!remote_desc)
|
||||||
|
perror_with_name (name);
|
||||||
|
|
||||||
|
if (baud_rate != -1)
|
||||||
|
{
|
||||||
|
if (SERIAL_SETBAUDRATE (remote_desc, baud_rate))
|
||||||
|
{
|
||||||
|
SERIAL_CLOSE (remote_desc);
|
||||||
|
perror_with_name (name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SERIAL_RAW (remote_desc);
|
||||||
|
|
||||||
|
/* If there is something sitting in the buffer we might take it as a
|
||||||
|
response to a command, which would be bad. */
|
||||||
|
SERIAL_FLUSH_INPUT (remote_desc);
|
||||||
|
|
||||||
|
if (from_tty)
|
||||||
|
{
|
||||||
|
puts_filtered ("Remote debugging using ");
|
||||||
|
puts_filtered (name);
|
||||||
|
puts_filtered ("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If running in asynchronous mode, register the target with the
|
||||||
|
event loop. Set things up so that when there is an event on the
|
||||||
|
file descriptor, the event loop will call fetch_inferior_event,
|
||||||
|
which will do the proper analysis to determine what happened. */
|
||||||
|
if (async_p)
|
||||||
|
add_file_handler (remote_desc->fd, (file_handler_func *) fetch_inferior_event, 0);
|
||||||
|
|
||||||
|
push_target (target); /* Switch to using remote target now */
|
||||||
|
|
||||||
|
/* Start out by trying the 'P' request to set registers. We set
|
||||||
|
this each time that we open a new target so that if the user
|
||||||
|
switches from one stub to another, we can (if the target is
|
||||||
|
closed and reopened) cope. */
|
||||||
|
stub_supports_P = 1;
|
||||||
|
|
||||||
|
general_thread = -2;
|
||||||
|
continue_thread = -2;
|
||||||
|
|
||||||
|
/* Force remote_write_bytes to check whether target supports
|
||||||
|
binary downloading. */
|
||||||
|
remote_binary_checked = 0;
|
||||||
|
|
||||||
|
/* If running asynchronously, set things up for telling the target
|
||||||
|
to use the extended protocol. This will happen only after the
|
||||||
|
target has been connected to, in fetch_inferior_event. */
|
||||||
|
if (extended_p && async_p)
|
||||||
|
add_continuation (set_extended_protocol, NULL);
|
||||||
|
|
||||||
|
/* Without this, some commands which require an active target (such
|
||||||
|
as kill) won't work. This variable serves (at least) double duty
|
||||||
|
as both the pid of the target process (if it has such), and as a
|
||||||
|
flag indicating that a target is active. These functions should
|
||||||
|
be split out into seperate variables, especially since GDB will
|
||||||
|
someday have a notion of debugging several processes. */
|
||||||
|
|
||||||
|
inferior_pid = MAGIC_NULL_PID;
|
||||||
|
/* Start the remote connection; if error (0), discard this target.
|
||||||
|
In particular, if the user quits, be sure to discard it
|
||||||
|
(we'd be in an inconsistent state otherwise). */
|
||||||
|
if (!catch_errors (remote_start_remote, NULL,
|
||||||
|
"Couldn't establish connection to remote target\n",
|
||||||
|
RETURN_MASK_ALL))
|
||||||
|
{
|
||||||
|
/* Unregister the file descriptor from the event loop. */
|
||||||
|
if (async_p)
|
||||||
|
delete_file_handler (remote_desc->fd);
|
||||||
|
pop_target ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!async_p)
|
||||||
|
{
|
||||||
|
if (extended_p)
|
||||||
|
{
|
||||||
|
/* tell the remote that we're using the extended protocol. */
|
||||||
|
char *buf = alloca (PBUFSIZ);
|
||||||
|
putpkt ("!");
|
||||||
|
getpkt (buf, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This will be called by fetch_inferior_event, via the
|
||||||
|
cmd_continuation pointer, only after the target has stopped. */
|
||||||
|
static void
|
||||||
|
set_extended_protocol (arg)
|
||||||
|
struct continuation_arg * arg;
|
||||||
|
{
|
||||||
|
/* tell the remote that we're using the extended protocol. */
|
||||||
|
char *buf = alloca (PBUFSIZ);
|
||||||
|
putpkt ("!");
|
||||||
|
getpkt (buf, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* This takes a program previously attached to and detaches it. After
|
/* This takes a program previously attached to and detaches it. After
|
||||||
this is done, GDB can be used to debug some other program. We
|
this is done, GDB can be used to debug some other program. We
|
||||||
better not have left any breakpoints in the target program or it'll
|
better not have left any breakpoints in the target program or it'll
|
||||||
|
@ -1729,6 +1897,30 @@ remote_detach (args, from_tty)
|
||||||
puts_filtered ("Ending remote debugging.\n");
|
puts_filtered ("Ending remote debugging.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Same as remote_detach, but with async support. */
|
||||||
|
static void
|
||||||
|
remote_async_detach (args, from_tty)
|
||||||
|
char *args;
|
||||||
|
int from_tty;
|
||||||
|
{
|
||||||
|
char *buf = alloca (PBUFSIZ);
|
||||||
|
|
||||||
|
if (args)
|
||||||
|
error ("Argument given to \"detach\" when remotely debugging.");
|
||||||
|
|
||||||
|
/* Tell the remote target to detach. */
|
||||||
|
strcpy (buf, "D");
|
||||||
|
remote_send (buf);
|
||||||
|
|
||||||
|
/* Unregister the file descriptor from the event loop. */
|
||||||
|
if (async_p)
|
||||||
|
delete_file_handler (remote_desc->fd);
|
||||||
|
|
||||||
|
pop_target ();
|
||||||
|
if (from_tty)
|
||||||
|
puts_filtered ("Ending remote debugging.\n");
|
||||||
|
}
|
||||||
|
|
||||||
/* Convert hex digit A to a number. */
|
/* Convert hex digit A to a number. */
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -1797,10 +1989,134 @@ remote_resume (pid, step, siggnal)
|
||||||
|
|
||||||
putpkt (buf);
|
putpkt (buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Same as remote_resume, but with async support. */
|
||||||
|
static void
|
||||||
|
remote_async_resume (pid, step, siggnal)
|
||||||
|
int pid, step;
|
||||||
|
enum target_signal siggnal;
|
||||||
|
{
|
||||||
|
char *buf = alloca (PBUFSIZ);
|
||||||
|
|
||||||
|
if (pid == -1)
|
||||||
|
set_thread (0, 0); /* run any thread */
|
||||||
|
else
|
||||||
|
set_thread (pid, 0); /* run this thread */
|
||||||
|
|
||||||
|
dcache_flush (remote_dcache);
|
||||||
|
|
||||||
|
last_sent_signal = siggnal;
|
||||||
|
last_sent_step = step;
|
||||||
|
|
||||||
|
/* A hook for when we need to do something at the last moment before
|
||||||
|
resumption. */
|
||||||
|
if (target_resume_hook)
|
||||||
|
(*target_resume_hook) ();
|
||||||
|
|
||||||
|
/* Set things up before execution starts for async commands. */
|
||||||
|
/* This function can be entered more than once for the same execution
|
||||||
|
command, because it is also called by handle_inferior_event. So
|
||||||
|
we make sure that we don't do the initialization for sync
|
||||||
|
execution more than once. */
|
||||||
|
if (async_p && !target_executing)
|
||||||
|
{
|
||||||
|
target_executing = 1;
|
||||||
|
|
||||||
|
/* If the command must look synchronous, fake it, by making gdb
|
||||||
|
display an empty prompt after the command has completed. Also
|
||||||
|
disable input. */
|
||||||
|
if (sync_execution)
|
||||||
|
{
|
||||||
|
push_prompt ("", "", "");
|
||||||
|
delete_file_handler (input_fd);
|
||||||
|
initialize_sigint_signal_handler ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (siggnal != TARGET_SIGNAL_0)
|
||||||
|
{
|
||||||
|
buf[0] = step ? 'S' : 'C';
|
||||||
|
buf[1] = tohex (((int)siggnal >> 4) & 0xf);
|
||||||
|
buf[2] = tohex ((int)siggnal & 0xf);
|
||||||
|
buf[3] = '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
strcpy (buf, step ? "s": "c");
|
||||||
|
|
||||||
|
putpkt (buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Set up the signal handler for SIGINT, while the target is
|
||||||
|
executing, ovewriting the 'regular' SIGINT signal handler. */
|
||||||
|
static void
|
||||||
|
initialize_sigint_signal_handler ()
|
||||||
|
{
|
||||||
|
sigint_remote_token =
|
||||||
|
create_async_signal_handler (async_remote_interrupt, NULL);
|
||||||
|
signal (SIGINT, handle_remote_sigint);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Signal handler for SIGINT, while the target is executing. */
|
||||||
|
static void
|
||||||
|
handle_remote_sigint (sig)
|
||||||
|
int sig;
|
||||||
|
{
|
||||||
|
signal (sig, handle_remote_sigint_twice);
|
||||||
|
sigint_remote_twice_token =
|
||||||
|
create_async_signal_handler (async_remote_interrupt_twice, NULL);
|
||||||
|
mark_async_signal_handler_wrapper (sigint_remote_token);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Signal handler for SIGINT, installed after SIGINT has already been
|
||||||
|
sent once. It will take effect the second time that the user sends
|
||||||
|
a ^C. */
|
||||||
|
static void
|
||||||
|
handle_remote_sigint_twice (sig)
|
||||||
|
int sig;
|
||||||
|
{
|
||||||
|
signal (sig, handle_sigint);
|
||||||
|
sigint_remote_twice_token =
|
||||||
|
create_async_signal_handler (async_remote_interrupt, NULL);
|
||||||
|
mark_async_signal_handler_wrapper (sigint_remote_twice_token);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Perform the real interruption of hte target execution, in response
|
||||||
|
to a ^C. */
|
||||||
|
static void
|
||||||
|
async_remote_interrupt (arg)
|
||||||
|
gdb_client_data arg;
|
||||||
|
{
|
||||||
|
if (remote_debug)
|
||||||
|
fprintf_unfiltered (gdb_stdlog, "remote_interrupt called\n");
|
||||||
|
|
||||||
|
target_stop ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Perform interrupt, if the first attempt did not succeed. Just give
|
||||||
|
up on the target alltogether. */
|
||||||
|
static void
|
||||||
|
async_remote_interrupt_twice (arg)
|
||||||
|
gdb_client_data arg;
|
||||||
|
{
|
||||||
|
interrupt_query ();
|
||||||
|
signal (SIGINT, handle_remote_sigint);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reinstall the usual SIGINT handlers, after the target has
|
||||||
|
stopped. */
|
||||||
|
void
|
||||||
|
cleanup_sigint_signal_handler ()
|
||||||
|
{
|
||||||
|
signal (SIGINT, handle_sigint);
|
||||||
|
if (sigint_remote_twice_token)
|
||||||
|
delete_async_signal_handler ((async_signal_handler**) &sigint_remote_twice_token);
|
||||||
|
if (sigint_remote_token)
|
||||||
|
delete_async_signal_handler ((async_signal_handler**) &sigint_remote_token);
|
||||||
|
}
|
||||||
|
|
||||||
/* Send ^C to target to halt it. Target will respond, and send us a
|
/* Send ^C to target to halt it. Target will respond, and send us a
|
||||||
packet. */
|
packet. */
|
||||||
|
|
||||||
static void (*ofunc) PARAMS ((int));
|
static void (*ofunc) PARAMS ((int));
|
||||||
|
|
||||||
/* The command line interface's stop routine. This function is installed
|
/* The command line interface's stop routine. This function is installed
|
||||||
|
@ -1875,16 +2191,13 @@ remote_console_output (msg)
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
for (p = msg; *p; p +=2)
|
for (p = msg; p[0] && p[1]; p +=2)
|
||||||
{
|
{
|
||||||
char tb[2];
|
char tb[2];
|
||||||
char c = fromhex (p[0]) * 16 + fromhex (p[1]);
|
char c = fromhex (p[0]) * 16 + fromhex (p[1]);
|
||||||
tb[0] = c;
|
tb[0] = c;
|
||||||
tb[1] = 0;
|
tb[1] = 0;
|
||||||
if (target_output_hook)
|
fputs_unfiltered (tb, gdb_stdtarg);
|
||||||
target_output_hook (tb);
|
|
||||||
else
|
|
||||||
fputs_filtered (tb, gdb_stdout);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2109,6 +2422,225 @@ Packet Dropped");
|
||||||
return inferior_pid;
|
return inferior_pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Async version of remote_wait. */
|
||||||
|
static int
|
||||||
|
remote_async_wait (pid, status)
|
||||||
|
int pid;
|
||||||
|
struct target_waitstatus *status;
|
||||||
|
{
|
||||||
|
unsigned char *buf = alloca (PBUFSIZ);
|
||||||
|
int thread_num = -1;
|
||||||
|
|
||||||
|
status->kind = TARGET_WAITKIND_EXITED;
|
||||||
|
status->value.integer = 0;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
unsigned char *p;
|
||||||
|
|
||||||
|
if (!async_p)
|
||||||
|
ofunc = signal (SIGINT, remote_interrupt);
|
||||||
|
getpkt ((char *) buf, 1);
|
||||||
|
if (!async_p)
|
||||||
|
signal (SIGINT, ofunc);
|
||||||
|
|
||||||
|
/* This is a hook for when we need to do something (perhaps the
|
||||||
|
collection of trace data) every time the target stops. */
|
||||||
|
if (target_wait_loop_hook)
|
||||||
|
(*target_wait_loop_hook) ();
|
||||||
|
|
||||||
|
switch (buf[0])
|
||||||
|
{
|
||||||
|
case 'E': /* Error of some sort */
|
||||||
|
warning ("Remote failure reply: %s", buf);
|
||||||
|
continue;
|
||||||
|
case 'T': /* Status with PC, SP, FP, ... */
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
long regno;
|
||||||
|
char regs[MAX_REGISTER_RAW_SIZE];
|
||||||
|
|
||||||
|
/* Expedited reply, containing Signal, {regno, reg} repeat */
|
||||||
|
/* format is: 'Tssn...:r...;n...:r...;n...:r...;#cc', where
|
||||||
|
ss = signal number
|
||||||
|
n... = register number
|
||||||
|
r... = register contents
|
||||||
|
*/
|
||||||
|
p = &buf[3]; /* after Txx */
|
||||||
|
|
||||||
|
while (*p)
|
||||||
|
{
|
||||||
|
unsigned char *p1;
|
||||||
|
char *p_temp;
|
||||||
|
|
||||||
|
/* Read the register number */
|
||||||
|
regno = strtol ((const char *) p, &p_temp, 16);
|
||||||
|
p1 = (unsigned char *)p_temp;
|
||||||
|
|
||||||
|
if (p1 == p) /* No register number present here */
|
||||||
|
{
|
||||||
|
p1 = (unsigned char *) strchr ((const char *) p, ':');
|
||||||
|
if (p1 == NULL)
|
||||||
|
warning ("Malformed packet(a) (missing colon): %s\n\
|
||||||
|
Packet: '%s'\n",
|
||||||
|
p, buf);
|
||||||
|
if (strncmp ((const char *) p, "thread", p1 - p) == 0)
|
||||||
|
{
|
||||||
|
p_temp = unpack_varlen_hex (++p1, &thread_num);
|
||||||
|
record_currthread (thread_num);
|
||||||
|
p = (unsigned char *) p_temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p = p1;
|
||||||
|
|
||||||
|
if (*p++ != ':')
|
||||||
|
warning ("Malformed packet(b) (missing colon): %s\n\
|
||||||
|
Packet: '%s'\n",
|
||||||
|
p, buf);
|
||||||
|
|
||||||
|
if (regno >= NUM_REGS)
|
||||||
|
warning ("Remote sent bad register number %ld: %s\n\
|
||||||
|
Packet: '%s'\n",
|
||||||
|
regno, p, buf);
|
||||||
|
|
||||||
|
for (i = 0; i < REGISTER_RAW_SIZE (regno); i++)
|
||||||
|
{
|
||||||
|
if (p[0] == 0 || p[1] == 0)
|
||||||
|
warning ("Remote reply is too short: %s", buf);
|
||||||
|
regs[i] = fromhex (p[0]) * 16 + fromhex (p[1]);
|
||||||
|
p += 2;
|
||||||
|
}
|
||||||
|
supply_register (regno, regs);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*p++ != ';')
|
||||||
|
{
|
||||||
|
warning ("Remote register badly formatted: %s", buf);
|
||||||
|
warning (" here: %s",p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* fall through */
|
||||||
|
case 'S': /* Old style status, just signal only */
|
||||||
|
status->kind = TARGET_WAITKIND_STOPPED;
|
||||||
|
status->value.sig = (enum target_signal)
|
||||||
|
(((fromhex (buf[1])) << 4) + (fromhex (buf[2])));
|
||||||
|
|
||||||
|
if (buf[3] == 'p')
|
||||||
|
{
|
||||||
|
/* Export Cisco kernel mode as a convenience variable
|
||||||
|
(so that it can be used in the GDB prompt if desired). */
|
||||||
|
|
||||||
|
if (cisco_kernel_mode == 1)
|
||||||
|
set_internalvar (lookup_internalvar ("cisco_kernel_mode"),
|
||||||
|
value_from_string ("PDEBUG-"));
|
||||||
|
cisco_kernel_mode = 0;
|
||||||
|
thread_num = strtol ((const char *) &buf[4], NULL, 16);
|
||||||
|
record_currthread (thread_num);
|
||||||
|
}
|
||||||
|
else if (buf[3] == 'k')
|
||||||
|
{
|
||||||
|
/* Export Cisco kernel mode as a convenience variable
|
||||||
|
(so that it can be used in the GDB prompt if desired). */
|
||||||
|
|
||||||
|
if (cisco_kernel_mode == 1)
|
||||||
|
set_internalvar (lookup_internalvar ("cisco_kernel_mode"),
|
||||||
|
value_from_string ("KDEBUG-"));
|
||||||
|
cisco_kernel_mode = 1;
|
||||||
|
}
|
||||||
|
goto got_status;
|
||||||
|
case 'N': /* Cisco special: status and offsets */
|
||||||
|
{
|
||||||
|
bfd_vma text_addr, data_addr, bss_addr;
|
||||||
|
bfd_signed_vma text_off, data_off, bss_off;
|
||||||
|
unsigned char *p1;
|
||||||
|
|
||||||
|
status->kind = TARGET_WAITKIND_STOPPED;
|
||||||
|
status->value.sig = (enum target_signal)
|
||||||
|
(((fromhex (buf[1])) << 4) + (fromhex (buf[2])));
|
||||||
|
|
||||||
|
if (symfile_objfile == NULL)
|
||||||
|
{
|
||||||
|
warning ("Relocation packet recieved with no symbol file. \
|
||||||
|
Packet Dropped");
|
||||||
|
goto got_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Relocate object file. Buffer format is NAATT;DD;BB
|
||||||
|
* where AA is the signal number, TT is the new text
|
||||||
|
* address, DD * is the new data address, and BB is the
|
||||||
|
* new bss address. */
|
||||||
|
|
||||||
|
p = &buf[3];
|
||||||
|
text_addr = strtoul (p, (char **) &p1, 16);
|
||||||
|
if (p1 == p || *p1 != ';')
|
||||||
|
warning ("Malformed relocation packet: Packet '%s'", buf);
|
||||||
|
p = p1 + 1;
|
||||||
|
data_addr = strtoul (p, (char **) &p1, 16);
|
||||||
|
if (p1 == p || *p1 != ';')
|
||||||
|
warning ("Malformed relocation packet: Packet '%s'", buf);
|
||||||
|
p = p1 + 1;
|
||||||
|
bss_addr = strtoul (p, (char **) &p1, 16);
|
||||||
|
if (p1 == p)
|
||||||
|
warning ("Malformed relocation packet: Packet '%s'", buf);
|
||||||
|
|
||||||
|
if (remote_cisco_section_offsets (text_addr, data_addr, bss_addr,
|
||||||
|
&text_off, &data_off, &bss_off)
|
||||||
|
== 0)
|
||||||
|
if (text_off != 0 || data_off != 0 || bss_off != 0)
|
||||||
|
remote_cisco_objfile_relocate (text_off, data_off, bss_off);
|
||||||
|
|
||||||
|
goto got_status;
|
||||||
|
}
|
||||||
|
case 'W': /* Target exited */
|
||||||
|
{
|
||||||
|
/* The remote process exited. */
|
||||||
|
status->kind = TARGET_WAITKIND_EXITED;
|
||||||
|
status->value.integer = (fromhex (buf[1]) << 4) + fromhex (buf[2]);
|
||||||
|
goto got_status;
|
||||||
|
}
|
||||||
|
case 'X':
|
||||||
|
status->kind = TARGET_WAITKIND_SIGNALLED;
|
||||||
|
status->value.sig = (enum target_signal)
|
||||||
|
(((fromhex (buf[1])) << 4) + (fromhex (buf[2])));
|
||||||
|
kill_kludge = 1;
|
||||||
|
|
||||||
|
goto got_status;
|
||||||
|
case 'O': /* Console output */
|
||||||
|
remote_console_output (buf + 1);
|
||||||
|
continue;
|
||||||
|
case '\0':
|
||||||
|
if (last_sent_signal != TARGET_SIGNAL_0)
|
||||||
|
{
|
||||||
|
/* Zero length reply means that we tried 'S' or 'C' and
|
||||||
|
the remote system doesn't support it. */
|
||||||
|
target_terminal_ours_for_output ();
|
||||||
|
printf_filtered
|
||||||
|
("Can't send signals to this remote system. %s not sent.\n",
|
||||||
|
target_signal_to_name (last_sent_signal));
|
||||||
|
last_sent_signal = TARGET_SIGNAL_0;
|
||||||
|
target_terminal_inferior ();
|
||||||
|
|
||||||
|
strcpy ((char *) buf, last_sent_step ? "s" : "c");
|
||||||
|
putpkt ((char *) buf);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* else fallthrough */
|
||||||
|
default:
|
||||||
|
warning ("Invalid remote reply: %s", buf);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
got_status:
|
||||||
|
if (thread_num != -1)
|
||||||
|
{
|
||||||
|
return thread_num;
|
||||||
|
}
|
||||||
|
return inferior_pid;
|
||||||
|
}
|
||||||
|
|
||||||
/* Number of bytes of registers this stub implements. */
|
/* Number of bytes of registers this stub implements. */
|
||||||
|
|
||||||
static int register_bytes_found;
|
static int register_bytes_found;
|
||||||
|
@ -2792,7 +3324,7 @@ putpkt_binary (buf, cnt)
|
||||||
/* Copy the packet into buffer BUF2, encapsulating it
|
/* Copy the packet into buffer BUF2, encapsulating it
|
||||||
and giving it a checksum. */
|
and giving it a checksum. */
|
||||||
|
|
||||||
if (cnt > (int) sizeof (buf2) - 5) /* Prosanity check */
|
if (cnt > BUFSIZ - 5) /* Prosanity check */
|
||||||
abort ();
|
abort ();
|
||||||
|
|
||||||
p = buf2;
|
p = buf2;
|
||||||
|
@ -3116,6 +3648,32 @@ remote_kill ()
|
||||||
target_mourn_inferior ();
|
target_mourn_inferior ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Async version of remote_kill. */
|
||||||
|
static void
|
||||||
|
remote_async_kill ()
|
||||||
|
{
|
||||||
|
/* Unregister the file descriptor from the event loop. */
|
||||||
|
if (async_p)
|
||||||
|
delete_file_handler (remote_desc->fd);
|
||||||
|
|
||||||
|
/* For some mysterious reason, wait_for_inferior calls kill instead of
|
||||||
|
mourn after it gets TARGET_WAITKIND_SIGNALLED. Work around it. */
|
||||||
|
if (kill_kludge)
|
||||||
|
{
|
||||||
|
kill_kludge = 0;
|
||||||
|
target_mourn_inferior ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Use catch_errors so the user can quit from gdb even when we aren't on
|
||||||
|
speaking terms with the remote system. */
|
||||||
|
catch_errors ((catch_errors_ftype*) putpkt, "k", "", RETURN_MASK_ERROR);
|
||||||
|
|
||||||
|
/* Don't wait for it to die. I'm not really sure it matters whether
|
||||||
|
we do or not. For the existing stubs, kill is a noop. */
|
||||||
|
target_mourn_inferior ();
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
remote_mourn ()
|
remote_mourn ()
|
||||||
{
|
{
|
||||||
|
@ -3175,6 +3733,36 @@ extended_remote_create_inferior (exec_file, args, env)
|
||||||
proceed (-1, TARGET_SIGNAL_0, 0);
|
proceed (-1, TARGET_SIGNAL_0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Async version of extended_remote_create_inferior. */
|
||||||
|
static void
|
||||||
|
extended_remote_async_create_inferior (exec_file, args, env)
|
||||||
|
char *exec_file;
|
||||||
|
char *args;
|
||||||
|
char **env;
|
||||||
|
{
|
||||||
|
/* Rip out the breakpoints; we'll reinsert them after restarting
|
||||||
|
the remote server. */
|
||||||
|
remove_breakpoints ();
|
||||||
|
|
||||||
|
/* If running asynchronously, register the target file descriptor
|
||||||
|
with the event loop. */
|
||||||
|
if (async_p)
|
||||||
|
add_file_handler (remote_desc->fd, (file_handler_func *) fetch_inferior_event, 0);
|
||||||
|
|
||||||
|
/* Now restart the remote server. */
|
||||||
|
extended_remote_restart ();
|
||||||
|
|
||||||
|
/* Now put the breakpoints back in. This way we're safe if the
|
||||||
|
restart function works via a unix fork on the remote side. */
|
||||||
|
insert_breakpoints ();
|
||||||
|
|
||||||
|
/* Clean up from the last time we were running. */
|
||||||
|
clear_proceed_status ();
|
||||||
|
|
||||||
|
/* Let the remote process run. */
|
||||||
|
proceed (-1, TARGET_SIGNAL_0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* On some machines, e.g. 68k, we may use a different breakpoint instruction
|
/* On some machines, e.g. 68k, we may use a different breakpoint instruction
|
||||||
than other targets; in those use REMOTE_BREAKPOINT instead of just
|
than other targets; in those use REMOTE_BREAKPOINT instead of just
|
||||||
|
@ -4103,13 +4691,75 @@ Specify the serial device it is connected to (e.g. host:2020).";
|
||||||
remote_cisco_ops.to_magic = OPS_MAGIC;
|
remote_cisco_ops.to_magic = OPS_MAGIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Target async and target extended-async.
|
||||||
|
|
||||||
|
This are temporary targets, until it is all tested. Eventually
|
||||||
|
async support will be incorporated int the usual 'remote'
|
||||||
|
target. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_remote_async_ops ()
|
||||||
|
{
|
||||||
|
remote_async_ops.to_shortname = "async";
|
||||||
|
remote_async_ops.to_longname = "Remote serial target in async version of the gdb-specific protocol";
|
||||||
|
remote_async_ops.to_doc =
|
||||||
|
"Use a remote computer via a serial line, using a gdb-specific protocol.\n\
|
||||||
|
Specify the serial device it is connected to (e.g. /dev/ttya).";
|
||||||
|
remote_async_ops.to_open = remote_async_open;
|
||||||
|
remote_async_ops.to_close = remote_close;
|
||||||
|
remote_async_ops.to_detach = remote_async_detach;
|
||||||
|
remote_async_ops.to_resume = remote_async_resume;
|
||||||
|
remote_async_ops.to_wait = remote_async_wait;
|
||||||
|
remote_async_ops.to_fetch_registers = remote_fetch_registers;
|
||||||
|
remote_async_ops.to_store_registers = remote_store_registers;
|
||||||
|
remote_async_ops.to_prepare_to_store = remote_prepare_to_store;
|
||||||
|
remote_async_ops.to_xfer_memory = remote_xfer_memory;
|
||||||
|
remote_async_ops.to_files_info = remote_files_info;
|
||||||
|
remote_async_ops.to_insert_breakpoint = remote_insert_breakpoint;
|
||||||
|
remote_async_ops.to_remove_breakpoint = remote_remove_breakpoint;
|
||||||
|
remote_async_ops.to_kill = remote_async_kill;
|
||||||
|
remote_async_ops.to_load = generic_load;
|
||||||
|
remote_async_ops.to_mourn_inferior = remote_mourn;
|
||||||
|
remote_async_ops.to_thread_alive = remote_thread_alive;
|
||||||
|
remote_async_ops.to_find_new_threads = remote_threads_info;
|
||||||
|
remote_async_ops.to_stop = remote_stop;
|
||||||
|
remote_async_ops.to_query = remote_query;
|
||||||
|
remote_async_ops.to_stratum = process_stratum;
|
||||||
|
remote_async_ops.to_has_all_memory = 1;
|
||||||
|
remote_async_ops.to_has_memory = 1;
|
||||||
|
remote_async_ops.to_has_stack = 1;
|
||||||
|
remote_async_ops.to_has_registers = 1;
|
||||||
|
remote_async_ops.to_has_execution = 1;
|
||||||
|
remote_async_ops.to_has_thread_control = tc_schedlock; /* can lock scheduler */
|
||||||
|
remote_async_ops.to_has_async_exec = 1;
|
||||||
|
remote_async_ops.to_magic = OPS_MAGIC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set up the async extended remote vector by making a copy of the standard
|
||||||
|
remote vector and adding to it. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_extended_async_remote_ops ()
|
||||||
|
{
|
||||||
|
extended_async_remote_ops = remote_async_ops;
|
||||||
|
|
||||||
|
extended_async_remote_ops.to_shortname = "extended-async";
|
||||||
|
extended_async_remote_ops.to_longname =
|
||||||
|
"Extended remote serial target in async gdb-specific protocol";
|
||||||
|
extended_async_remote_ops.to_doc =
|
||||||
|
"Use a remote computer via a serial line, using an async gdb-specific protocol.\n\
|
||||||
|
Specify the serial device it is connected to (e.g. /dev/ttya).",
|
||||||
|
extended_async_remote_ops.to_open = extended_remote_async_open;
|
||||||
|
extended_async_remote_ops.to_create_inferior = extended_remote_async_create_inferior;
|
||||||
|
extended_async_remote_ops.to_mourn_inferior = extended_remote_mourn;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
build_remote_gdbarch_data ()
|
build_remote_gdbarch_data ()
|
||||||
{
|
{
|
||||||
tty_input = xmalloc (PBUFSIZ);
|
tty_input = xmalloc (PBUFSIZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_initialize_remote ()
|
_initialize_remote ()
|
||||||
{
|
{
|
||||||
|
@ -4128,6 +4778,12 @@ _initialize_remote ()
|
||||||
init_extended_remote_ops ();
|
init_extended_remote_ops ();
|
||||||
add_target (&extended_remote_ops);
|
add_target (&extended_remote_ops);
|
||||||
|
|
||||||
|
init_remote_async_ops ();
|
||||||
|
add_target (&remote_async_ops);
|
||||||
|
|
||||||
|
init_extended_async_remote_ops ();
|
||||||
|
add_target (&extended_async_remote_ops);
|
||||||
|
|
||||||
init_remote_cisco_ops ();
|
init_remote_cisco_ops ();
|
||||||
add_target (&remote_cisco_ops);
|
add_target (&remote_cisco_ops);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* Serial interface for raw TCP connections on Un*x like systems
|
/* Serial interface for raw TCP connections on Un*x like systems
|
||||||
Copyright 1992, 1993, 1998 Free Software Foundation, Inc.
|
Copyright 1992, 1993, 1998, 1999 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is part of GDB.
|
This file is part of GDB.
|
||||||
|
|
||||||
|
@ -33,6 +33,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_SELECT_H
|
||||||
|
#include <sys/select.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "signals.h"
|
#include "signals.h"
|
||||||
#include "gdb_string.h"
|
#include "gdb_string.h"
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* Serial interface for local (hardwired) serial ports on Un*x like systems
|
/* Serial interface for local (hardwired) serial ports on Un*x like systems
|
||||||
Copyright 1992, 1993, 1994, 1998 Free Software Foundation, Inc.
|
Copyright 1992, 1993, 1994, 1998, 1999 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is part of GDB.
|
This file is part of GDB.
|
||||||
|
|
||||||
|
@ -26,6 +26,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_SELECT_H
|
||||||
|
#include <sys/select.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_TERMIOS
|
#ifdef HAVE_TERMIOS
|
||||||
|
|
||||||
struct hardwire_ttystate
|
struct hardwire_ttystate
|
||||||
|
|
|
@ -276,7 +276,7 @@ directory_command (dirname, from_tty)
|
||||||
/* FIXME, this goes to "delete dir"... */
|
/* FIXME, this goes to "delete dir"... */
|
||||||
if (dirname == 0)
|
if (dirname == 0)
|
||||||
{
|
{
|
||||||
if (query ("Reinitialize source path to empty? "))
|
if (from_tty && query ("Reinitialize source path to empty? "))
|
||||||
{
|
{
|
||||||
free (source_path);
|
free (source_path);
|
||||||
init_source_path ();
|
init_source_path ();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* Target dependent code for the Fujitsu SPARClite for GDB, the GNU debugger.
|
/* Target dependent code for the Fujitsu SPARClite for GDB, the GNU debugger.
|
||||||
Copyright 1994, 1995, 1996 Free Software Foundation, Inc.
|
Copyright 1994, 1995, 1996, 1999 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is part of GDB.
|
This file is part of GDB.
|
||||||
|
|
||||||
|
@ -24,6 +24,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
#include "serial.h"
|
#include "serial.h"
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_SELECT_H
|
||||||
|
#include <sys/select.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if (!defined(__GO32__) && !defined(_WIN32)) || defined(__CYGWIN32__)
|
#if (!defined(__GO32__) && !defined(_WIN32)) || defined(__CYGWIN32__)
|
||||||
#define HAVE_SOCKETS
|
#define HAVE_SOCKETS
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
|
@ -535,6 +535,7 @@ update_current_target ()
|
||||||
INHERIT (to_has_registers, t);
|
INHERIT (to_has_registers, t);
|
||||||
INHERIT (to_has_execution, t);
|
INHERIT (to_has_execution, t);
|
||||||
INHERIT (to_has_thread_control, t);
|
INHERIT (to_has_thread_control, t);
|
||||||
|
INHERIT (to_has_async_exec, t);
|
||||||
INHERIT (to_sections, t);
|
INHERIT (to_sections, t);
|
||||||
INHERIT (to_sections_end, t);
|
INHERIT (to_sections_end, t);
|
||||||
INHERIT (to_magic, t);
|
INHERIT (to_magic, t);
|
||||||
|
|
|
@ -381,6 +381,7 @@ struct target_ops
|
||||||
int to_has_registers;
|
int to_has_registers;
|
||||||
int to_has_execution;
|
int to_has_execution;
|
||||||
int to_has_thread_control; /* control thread execution */
|
int to_has_thread_control; /* control thread execution */
|
||||||
|
int to_has_async_exec;
|
||||||
struct section_table
|
struct section_table
|
||||||
*to_sections;
|
*to_sections;
|
||||||
struct section_table
|
struct section_table
|
||||||
|
@ -984,6 +985,10 @@ print_section_info PARAMS ((struct target_ops *, bfd *));
|
||||||
#define target_can_switch_threads \
|
#define target_can_switch_threads \
|
||||||
(current_target.to_has_thread_control & tc_switch)
|
(current_target.to_has_thread_control & tc_switch)
|
||||||
|
|
||||||
|
/* Does the target support asynchronous execution? */
|
||||||
|
#define target_has_async \
|
||||||
|
(current_target.to_has_async_exec)
|
||||||
|
|
||||||
extern void target_link PARAMS ((char *, CORE_ADDR *));
|
extern void target_link PARAMS ((char *, CORE_ADDR *));
|
||||||
|
|
||||||
/* Converts a process id to a string. Usually, the string just contains
|
/* Converts a process id to a string. Usually, the string just contains
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
Tue Jun 29 11:56:06 1999 Andrew Cagney <cagney@b1.cygnus.com>
|
||||||
|
|
||||||
|
* lib/gdb.exp (gdb_expect_list): Output one message per pattern in
|
||||||
|
a consistent format.
|
||||||
|
|
||||||
1999-06-25 Stan Shebs <shebs@andros.cygnus.com>
|
1999-06-25 Stan Shebs <shebs@andros.cygnus.com>
|
||||||
|
|
||||||
From Jimmy Guo <guo@cup.hp.com> and others at HP:
|
From Jimmy Guo <guo@cup.hp.com> and others at HP:
|
||||||
|
|
|
@ -1105,38 +1105,44 @@ proc gdb_expect { args } {
|
||||||
proc gdb_expect_list {test sentinal list} {
|
proc gdb_expect_list {test sentinal list} {
|
||||||
global gdb_prompt
|
global gdb_prompt
|
||||||
set index 0
|
set index 0
|
||||||
while { ${index} >= 0 && ${index} < [llength ${list}] } {
|
set ok 1
|
||||||
|
while { ${index} < [llength ${list}] } {
|
||||||
set pattern [lindex ${list} ${index}]
|
set pattern [lindex ${list} ${index}]
|
||||||
set index [expr ${index} + 1]
|
set index [expr ${index} + 1]
|
||||||
if { ${index} == [llength ${list}] } {
|
if { ${index} == [llength ${list}] } {
|
||||||
gdb_expect {
|
if { ${ok} } {
|
||||||
-re "${pattern}${sentinal}" {
|
gdb_expect {
|
||||||
pass "${test} (sentinal)"
|
-re "${pattern}${sentinal}" {
|
||||||
}
|
pass "${test}, pattern ${index} + sentinal"
|
||||||
timeout {
|
}
|
||||||
fail "(timeout on sentinal) ${test}"
|
timeout {
|
||||||
set index -1
|
fail "${test}, pattern ${index} + sentinal (timeout)"
|
||||||
|
set ok 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
fail "${test}, pattern ${index} + sentinal"
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
gdb_expect {
|
if { ${ok} } {
|
||||||
-re "${pattern}" {
|
gdb_expect {
|
||||||
pass "${test} (line ${index})"
|
-re "${pattern}" {
|
||||||
}
|
pass "${test}, pattern ${index}"
|
||||||
-re "${sentinal}" {
|
}
|
||||||
fail "${test} (line ${index})"
|
-re "${sentinal}" {
|
||||||
set index -1
|
fail "${test}, pattern ${index}"
|
||||||
}
|
set ok 0
|
||||||
timeout {
|
}
|
||||||
fail "(timeout on line ${index}) ${test}"
|
timeout {
|
||||||
set index -1
|
fail "${test}, pattern ${index} (timeout)"
|
||||||
|
set ok 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
fail "${test}, pattern ${index}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if { ${index} >= 0 } {
|
|
||||||
pass "${test}"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
23
gdb/top.c
23
gdb/top.c
|
@ -322,6 +322,12 @@ int remote_timeout = 20; /* Set default to 20 */
|
||||||
|
|
||||||
int remote_debug = 0;
|
int remote_debug = 0;
|
||||||
|
|
||||||
|
/* Non-zero means the target is running. Note: this is different from
|
||||||
|
saying that there is an active target and we are stopped at a
|
||||||
|
breakpoint, for instance. This is a real indicator whether the
|
||||||
|
target is off and running, which gdb is doing something else. */
|
||||||
|
int target_executing = 0;
|
||||||
|
|
||||||
/* Level of control structure. */
|
/* Level of control structure. */
|
||||||
static int control_level;
|
static int control_level;
|
||||||
|
|
||||||
|
@ -383,11 +389,6 @@ void (*command_loop_hook) PARAMS ((void));
|
||||||
|
|
||||||
void (*fputs_unfiltered_hook) PARAMS ((const char *linebuffer, GDB_FILE *stream));
|
void (*fputs_unfiltered_hook) PARAMS ((const char *linebuffer, GDB_FILE *stream));
|
||||||
|
|
||||||
/* Called when the target says something to the host, which may
|
|
||||||
want to appear in a different window. */
|
|
||||||
|
|
||||||
void (*target_output_hook) PARAMS ((char *));
|
|
||||||
|
|
||||||
/* Called from print_frame_info to list the line we stopped in. */
|
/* Called from print_frame_info to list the line we stopped in. */
|
||||||
|
|
||||||
void (*print_frame_info_listing_hook) PARAMS ((struct symtab *s, int line,
|
void (*print_frame_info_listing_hook) PARAMS ((struct symtab *s, int line,
|
||||||
|
@ -486,6 +487,8 @@ return_to_top_level (reason)
|
||||||
|
|
||||||
disable_current_display ();
|
disable_current_display ();
|
||||||
do_cleanups (ALL_CLEANUPS);
|
do_cleanups (ALL_CLEANUPS);
|
||||||
|
if (async_p && target_has_async)
|
||||||
|
do_exec_cleanups (ALL_CLEANUPS);
|
||||||
|
|
||||||
if (annotation_level > 1)
|
if (annotation_level > 1)
|
||||||
switch (reason)
|
switch (reason)
|
||||||
|
@ -1266,6 +1269,16 @@ execute_command (p, from_tty)
|
||||||
char *arg;
|
char *arg;
|
||||||
|
|
||||||
c = lookup_cmd (&p, cmdlist, "", 0, 1);
|
c = lookup_cmd (&p, cmdlist, "", 0, 1);
|
||||||
|
|
||||||
|
/* If the target is running, we allow only a limited set of
|
||||||
|
commands. */
|
||||||
|
if (async_p && target_has_async && target_executing)
|
||||||
|
if (!strcmp (c->name, "help")
|
||||||
|
&& !strcmp (c->name, "pwd")
|
||||||
|
&& !strcmp (c->name, "show")
|
||||||
|
&& !strcmp (c->name, "stop"))
|
||||||
|
error ("Cannot execute this command while the target is running.");
|
||||||
|
|
||||||
/* Pass null arg rather than an empty one. */
|
/* Pass null arg rather than an empty one. */
|
||||||
arg = *p ? p : 0;
|
arg = *p ? p : 0;
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,6 @@ extern void set_prompt PARAMS ((char *));
|
||||||
/* From random places. */
|
/* From random places. */
|
||||||
extern int mapped_symbol_files;
|
extern int mapped_symbol_files;
|
||||||
extern int readnow_symbol_files;
|
extern int readnow_symbol_files;
|
||||||
#define ALL_CLEANUPS ((struct cleanup *)0)
|
|
||||||
|
|
||||||
/* Perform _initialize initialization */
|
/* Perform _initialize initialization */
|
||||||
extern void gdb_init PARAMS ((char *));
|
extern void gdb_init PARAMS ((char *));
|
||||||
|
|
54
gdb/utils.c
54
gdb/utils.c
|
@ -92,6 +92,13 @@ set_width PARAMS ((void));
|
||||||
static struct cleanup *cleanup_chain; /* cleaned up after a failed command */
|
static struct cleanup *cleanup_chain; /* cleaned up after a failed command */
|
||||||
static struct cleanup *final_cleanup_chain; /* cleaned up when gdb exits */
|
static struct cleanup *final_cleanup_chain; /* cleaned up when gdb exits */
|
||||||
static struct cleanup *run_cleanup_chain; /* cleaned up on each 'run' */
|
static struct cleanup *run_cleanup_chain; /* cleaned up on each 'run' */
|
||||||
|
static struct cleanup *exec_cleanup_chain; /* cleaned up on each execution command */
|
||||||
|
|
||||||
|
/* Pointer to what is left to do for an execution command after the
|
||||||
|
target stops. Used only in asynchronous mode, by targets that
|
||||||
|
support async execution. The finish and until commands use it. So
|
||||||
|
does the target extended-remote command. */
|
||||||
|
struct continuation *cmd_continuation;
|
||||||
|
|
||||||
/* Nonzero if we have job control. */
|
/* Nonzero if we have job control. */
|
||||||
|
|
||||||
|
@ -175,6 +182,14 @@ make_run_cleanup (function, arg)
|
||||||
return make_my_cleanup (&run_cleanup_chain, function, arg);
|
return make_my_cleanup (&run_cleanup_chain, function, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct cleanup *
|
||||||
|
make_exec_cleanup (function, arg)
|
||||||
|
void (*function) PARAMS ((PTR));
|
||||||
|
PTR arg;
|
||||||
|
{
|
||||||
|
return make_my_cleanup (&exec_cleanup_chain, function, arg);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
do_freeargv (arg)
|
do_freeargv (arg)
|
||||||
void *arg;
|
void *arg;
|
||||||
|
@ -231,6 +246,13 @@ do_run_cleanups (old_chain)
|
||||||
do_my_cleanups (&run_cleanup_chain, old_chain);
|
do_my_cleanups (&run_cleanup_chain, old_chain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
do_exec_cleanups (old_chain)
|
||||||
|
register struct cleanup *old_chain;
|
||||||
|
{
|
||||||
|
do_my_cleanups (&exec_cleanup_chain, old_chain);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
do_my_cleanups (pmy_chain, old_chain)
|
do_my_cleanups (pmy_chain, old_chain)
|
||||||
register struct cleanup **pmy_chain;
|
register struct cleanup **pmy_chain;
|
||||||
|
@ -350,6 +372,38 @@ null_cleanup (arg)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add a continuation to the continuation list, the gloabl list
|
||||||
|
cmd_continuation. */
|
||||||
|
void
|
||||||
|
add_continuation (continuation_hook, arg_list)
|
||||||
|
void (*continuation_hook) PARAMS ((struct continuation_arg *));
|
||||||
|
struct continuation_arg *arg_list;
|
||||||
|
{
|
||||||
|
struct continuation *continuation_ptr;
|
||||||
|
|
||||||
|
continuation_ptr = (struct continuation *) xmalloc (sizeof (struct continuation));
|
||||||
|
continuation_ptr->continuation_hook = continuation_hook;
|
||||||
|
continuation_ptr->arg_list = arg_list;
|
||||||
|
continuation_ptr->next = cmd_continuation;
|
||||||
|
cmd_continuation = continuation_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Walk down the cmd_continuation list, and execute all the
|
||||||
|
continuations. */
|
||||||
|
void
|
||||||
|
do_all_continuations ()
|
||||||
|
{
|
||||||
|
struct continuation *continuation_ptr;
|
||||||
|
|
||||||
|
while (cmd_continuation)
|
||||||
|
{
|
||||||
|
(cmd_continuation->continuation_hook) (cmd_continuation->arg_list);
|
||||||
|
continuation_ptr = cmd_continuation;
|
||||||
|
cmd_continuation = continuation_ptr->next;
|
||||||
|
free (continuation_ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Print a warning message. Way to use this is to call warning_begin,
|
/* Print a warning message. Way to use this is to call warning_begin,
|
||||||
output the warning message (use unfiltered output to gdb_stderr),
|
output the warning message (use unfiltered output to gdb_stderr),
|
||||||
|
|
|
@ -1636,6 +1636,10 @@ You must use a pointer to function type variable. Command ignored.", arg_name);
|
||||||
wouldn't happen. (See store_inferior_registers in sparc-nat.c.) */
|
wouldn't happen. (See store_inferior_registers in sparc-nat.c.) */
|
||||||
write_sp (sp);
|
write_sp (sp);
|
||||||
|
|
||||||
|
#ifdef SAVE_DUMMY_FRAME_TOS
|
||||||
|
SAVE_DUMMY_FRAME_TOS (sp);
|
||||||
|
#endif
|
||||||
|
|
||||||
{
|
{
|
||||||
char retbuf[REGISTER_BYTES];
|
char retbuf[REGISTER_BYTES];
|
||||||
char *name;
|
char *name;
|
||||||
|
|
|
@ -1,3 +1,16 @@
|
||||||
|
1999-07-05 Doug Evans <devans@casey.cygnus.com>
|
||||||
|
|
||||||
|
* Make-common.in (CGEN_MAIN_CPU_DEPS): Add cgen-fpu.h.
|
||||||
|
(cgen-fpu.o,cgen-accfp.o): Add rules for.
|
||||||
|
* cgen-fpu.c: New file.
|
||||||
|
* cgen-fpu.h: New file.
|
||||||
|
* cgen-accfp.c: New file.
|
||||||
|
* cgen-cpu.h (CGEN_CPU): New member fpu.
|
||||||
|
* cgen-mem.h: Redo fp support.
|
||||||
|
* cgen-ops.h: Delete k&r support. Redo fp support.
|
||||||
|
* cgen-sim.h: Include cgen-fpu.h.
|
||||||
|
* cgen-types.h (SF,DF,XF,TF): Moved to cgen-fpu.h.
|
||||||
|
|
||||||
1999-06-23 Doug Evans <devans@casey.cygnus.com>
|
1999-06-23 Doug Evans <devans@casey.cygnus.com>
|
||||||
|
|
||||||
* cgen-engine.h (TARGET_SEM_BRANCH_FINI): Remove cruft at end of
|
* cgen-engine.h (TARGET_SEM_BRANCH_FINI): Remove cruft at end of
|
||||||
|
|
|
@ -556,7 +556,8 @@ CGEN_MAIN_CPU_DEPS = \
|
||||||
$(SIM_MAIN_DEPS) \
|
$(SIM_MAIN_DEPS) \
|
||||||
$(CGEN_INCLUDE_DEPS) \
|
$(CGEN_INCLUDE_DEPS) \
|
||||||
$(srccom)/cgen-ops.h \
|
$(srccom)/cgen-ops.h \
|
||||||
$(srccom)/cgen-mem.h
|
$(srccom)/cgen-mem.h \
|
||||||
|
$(srccom)/cgen-fpu.h
|
||||||
|
|
||||||
cgen-run.o: $(srccom)/cgen-run.c $(sim_main_headers)
|
cgen-run.o: $(srccom)/cgen-run.c $(sim_main_headers)
|
||||||
$(CC) -c $(srccom)/cgen-run.c $(ALL_CFLAGS)
|
$(CC) -c $(srccom)/cgen-run.c $(ALL_CFLAGS)
|
||||||
|
@ -567,6 +568,12 @@ cgen-scache.o: $(srccom)/cgen-scache.c $(sim_main_headers)
|
||||||
cgen-trace.o: $(srccom)/cgen-trace.c $(sim_main_headers)
|
cgen-trace.o: $(srccom)/cgen-trace.c $(sim_main_headers)
|
||||||
$(CC) -c $(srccom)/cgen-trace.c $(ALL_CFLAGS)
|
$(CC) -c $(srccom)/cgen-trace.c $(ALL_CFLAGS)
|
||||||
|
|
||||||
|
cgen-fpu.o: $(srccom)/cgen-fpu.c $(sim_main_headers) $(sim-fpu_h)
|
||||||
|
$(CC) -c $(srccom)/cgen-fpu.c $(ALL_CFLAGS)
|
||||||
|
|
||||||
|
cgen-accfp.o: $(srccom)/cgen-accfp.c $(sim_main_headers) $(sim-fpu_h)
|
||||||
|
$(CC) -c $(srccom)/cgen-accfp.c $(ALL_CFLAGS)
|
||||||
|
|
||||||
cgen-utils.o: $(srccom)/cgen-utils.c $(sim_main_headers) \
|
cgen-utils.o: $(srccom)/cgen-utils.c $(sim_main_headers) \
|
||||||
$(srccom)/cgen-mem.h $(srccom)/cgen-ops.h $(srccom)/cgen-engine.h
|
$(srccom)/cgen-mem.h $(srccom)/cgen-ops.h $(srccom)/cgen-engine.h
|
||||||
$(CC) -c $(srccom)/cgen-utils.c $(ALL_CFLAGS)
|
$(CC) -c $(srccom)/cgen-utils.c $(ALL_CFLAGS)
|
||||||
|
|
|
@ -82,6 +82,10 @@ typedef struct {
|
||||||
const CGEN_INSN * (*get_idata) (SIM_CPU *, int);
|
const CGEN_INSN * (*get_idata) (SIM_CPU *, int);
|
||||||
#define CPU_GET_IDATA(cpu) ((cpu)->cgen_cpu.get_idata)
|
#define CPU_GET_IDATA(cpu) ((cpu)->cgen_cpu.get_idata)
|
||||||
|
|
||||||
|
/* Floating point support. */
|
||||||
|
CGEN_FPU fpu;
|
||||||
|
#define CGEN_CPU_FPU(cpu) (& (cpu)->cgen_cpu.fpu)
|
||||||
|
|
||||||
/* Disassembler. */
|
/* Disassembler. */
|
||||||
CGEN_DISASSEMBLER *disassembler;
|
CGEN_DISASSEMBLER *disassembler;
|
||||||
#define CPU_DISASSEMBLER(cpu) ((cpu)->cgen_cpu.disassembler)
|
#define CPU_DISASSEMBLER(cpu) ((cpu)->cgen_cpu.disassembler)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* Memory ops header for CGEN-based simulators.
|
/* Memory ops header for CGEN-based simulators.
|
||||||
Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
|
Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
|
||||||
Contributed by Cygnus Solutions.
|
Contributed by Cygnus Solutions.
|
||||||
|
|
||||||
This file is part of the GNU Simulators.
|
This file is part of the GNU Simulators.
|
||||||
|
@ -27,7 +27,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#define MEMOPS_INLINE extern inline
|
#define MEMOPS_INLINE extern inline
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Memory read support. */
|
/* Integer memory read support.
|
||||||
|
|
||||||
|
There is no floating point support. In this context there are no
|
||||||
|
floating point modes, only floating point operations (whose arguments
|
||||||
|
and results are arrays of bits that we treat as integer modes). */
|
||||||
|
|
||||||
#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE)
|
#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE)
|
||||||
#define DECLARE_GETMEM(mode, size) \
|
#define DECLARE_GETMEM(mode, size) \
|
||||||
|
@ -52,29 +56,9 @@ DECLARE_GETMEM (USI, 4)
|
||||||
DECLARE_GETMEM (DI, 8)
|
DECLARE_GETMEM (DI, 8)
|
||||||
DECLARE_GETMEM (UDI, 8)
|
DECLARE_GETMEM (UDI, 8)
|
||||||
|
|
||||||
#undef DECLARE_GETMEM
|
|
||||||
|
|
||||||
#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE)
|
|
||||||
#define DECLARE_GETMEM(mode, size) \
|
|
||||||
MEMOPS_INLINE mode \
|
|
||||||
XCONCAT2 (GETMEM,mode) (SIM_CPU *cpu, IADDR pc, ADDR a) \
|
|
||||||
{ \
|
|
||||||
PROFILE_COUNT_READ (cpu, a, XCONCAT2 (MODE_,mode)); \
|
|
||||||
/* Don't read anything into "unaligned" here. Bad name choice. */\
|
|
||||||
return XCONCAT2 (sim_core_read_unaligned_,size) (cpu, pc, read_map, a); \
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#define DECLARE_GETMEM(mode, size) \
|
|
||||||
extern mode XCONCAT2 (GETMEM,mode) (SIM_CPU *, IADDR, ADDR);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
DECLARE_GETMEM (SF, 4)
|
|
||||||
DECLARE_GETMEM (DF, 8)
|
|
||||||
/*DECLARE_GETMEM (TF, 16)*/
|
|
||||||
|
|
||||||
#undef DECLARE_GETMEM
|
#undef DECLARE_GETMEM
|
||||||
|
|
||||||
/* Memory write support. */
|
/* Integer memory write support. */
|
||||||
|
|
||||||
#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE)
|
#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE)
|
||||||
#define DECLARE_SETMEM(mode, size) \
|
#define DECLARE_SETMEM(mode, size) \
|
||||||
|
@ -99,12 +83,6 @@ DECLARE_SETMEM (USI, 4)
|
||||||
DECLARE_SETMEM (DI, 8)
|
DECLARE_SETMEM (DI, 8)
|
||||||
DECLARE_SETMEM (UDI, 8)
|
DECLARE_SETMEM (UDI, 8)
|
||||||
|
|
||||||
/*
|
|
||||||
DECLARE_SETMEM (SF, 4)
|
|
||||||
DECLARE_SETMEM (DF, 8)
|
|
||||||
DECLARE_SETMEM (TF, 16)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#undef DECLARE_SETMEM
|
#undef DECLARE_SETMEM
|
||||||
|
|
||||||
/* Instruction read support. */
|
/* Instruction read support. */
|
||||||
|
@ -130,6 +108,54 @@ DECLARE_GETIMEM (UDI, 8)
|
||||||
|
|
||||||
#undef DECLARE_GETIMEM
|
#undef DECLARE_GETIMEM
|
||||||
|
|
||||||
|
/* Floating point support.
|
||||||
|
|
||||||
|
??? One can specify that the integer memory ops should be used instead,
|
||||||
|
and treat fp values as just a series of bits. One might even bubble
|
||||||
|
that notion up into the description language. However, that departs from
|
||||||
|
gcc. One could cross over from gcc's notion and a "series of bits" notion
|
||||||
|
between there and here, and thus still not require these routines. However,
|
||||||
|
that's a complication of its own (not that having these fns isn't).
|
||||||
|
But for now, we do things this way. */
|
||||||
|
|
||||||
|
#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE)
|
||||||
|
#define DECLARE_GETMEM(mode, size) \
|
||||||
|
MEMOPS_INLINE mode \
|
||||||
|
XCONCAT2 (GETMEM,mode) (SIM_CPU *cpu, IADDR pc, ADDR a) \
|
||||||
|
{ \
|
||||||
|
PROFILE_COUNT_READ (cpu, a, XCONCAT2 (MODE_,mode)); \
|
||||||
|
/* Don't read anything into "unaligned" here. Bad name choice. */\
|
||||||
|
return XCONCAT2 (sim_core_read_unaligned_,size) (cpu, pc, read_map, a); \
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define DECLARE_GETMEM(mode, size) \
|
||||||
|
extern mode XCONCAT2 (GETMEM,mode) (SIM_CPU *, IADDR, ADDR);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DECLARE_GETMEM (SF, 4)
|
||||||
|
DECLARE_GETMEM (DF, 8)
|
||||||
|
|
||||||
|
#undef DECLARE_GETMEM
|
||||||
|
|
||||||
|
#if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE)
|
||||||
|
#define DECLARE_SETMEM(mode, size) \
|
||||||
|
MEMOPS_INLINE void \
|
||||||
|
XCONCAT2 (SETMEM,mode) (SIM_CPU *cpu, IADDR pc, ADDR a, mode val) \
|
||||||
|
{ \
|
||||||
|
PROFILE_COUNT_WRITE (cpu, a, XCONCAT2 (MODE_,mode)); \
|
||||||
|
/* Don't read anything into "unaligned" here. Bad name choice. */ \
|
||||||
|
XCONCAT2 (sim_core_write_unaligned_,size) (cpu, pc, write_map, a, val); \
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define DECLARE_SETMEM(mode, size) \
|
||||||
|
extern void XCONCAT2 (SETMEM,mode) (SIM_CPU *, IADDR, ADDR, mode);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DECLARE_SETMEM (SF, 4)
|
||||||
|
DECLARE_SETMEM (DF, 8)
|
||||||
|
|
||||||
|
#undef DECLARE_SETMEM
|
||||||
|
|
||||||
/* GETT<mode>: translate target value at P to host value.
|
/* GETT<mode>: translate target value at P to host value.
|
||||||
This needn't be very efficient (i.e. can call memcpy) as this is
|
This needn't be very efficient (i.e. can call memcpy) as this is
|
||||||
only used when interfacing with the outside world (e.g. gdb). */
|
only used when interfacing with the outside world (e.g. gdb). */
|
||||||
|
@ -157,7 +183,7 @@ DECLARE_GETT (USI, 4)
|
||||||
DECLARE_GETT (DI, 8)
|
DECLARE_GETT (DI, 8)
|
||||||
DECLARE_GETT (UDI, 8)
|
DECLARE_GETT (UDI, 8)
|
||||||
|
|
||||||
/*
|
/* ??? defered until necessary
|
||||||
DECLARE_GETT (SF, 4)
|
DECLARE_GETT (SF, 4)
|
||||||
DECLARE_GETT (DF, 8)
|
DECLARE_GETT (DF, 8)
|
||||||
DECLARE_GETT (TF, 16)
|
DECLARE_GETT (TF, 16)
|
||||||
|
@ -192,7 +218,7 @@ DECLARE_SETT (USI, 4)
|
||||||
DECLARE_SETT (DI, 8)
|
DECLARE_SETT (DI, 8)
|
||||||
DECLARE_SETT (UDI, 8)
|
DECLARE_SETT (UDI, 8)
|
||||||
|
|
||||||
/*
|
/* ??? defered until necessary
|
||||||
DECLARE_SETT (SF, 4)
|
DECLARE_SETT (SF, 4)
|
||||||
DECLARE_SETT (DF, 8)
|
DECLARE_SETT (DF, 8)
|
||||||
DECLARE_SETT (TF, 16)
|
DECLARE_SETT (TF, 16)
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
/* Semantics ops support for CGEN-based simulators.
|
/* Semantics ops support for CGEN-based simulators.
|
||||||
Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
|
Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
|
||||||
Contributed by Cygnus Solutions.
|
Contributed by Cygnus Solutions.
|
||||||
|
@ -33,6 +34,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
/* Semantic operations.
|
/* Semantic operations.
|
||||||
At one point this file was machine generated. Maybe it will be again. */
|
At one point this file was machine generated. Maybe it will be again. */
|
||||||
|
|
||||||
|
/* TODO: Lazy encoding/decoding of fp values. */
|
||||||
|
|
||||||
/* These don't really have a mode. */
|
/* These don't really have a mode. */
|
||||||
#define ANDIF(x, y) ((x) && (y))
|
#define ANDIF(x, y) ((x) && (y))
|
||||||
#define ORIF(x, y) ((x) || (y))
|
#define ORIF(x, y) ((x) || (y))
|
||||||
|
@ -53,7 +56,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#define LEUBI(x, y) ((BI) (x) <= (BI) (y))
|
#define LEUBI(x, y) ((BI) (x) <= (BI) (y))
|
||||||
#define GTUBI(x, y) ((BI) (x) > (BI) (y))
|
#define GTUBI(x, y) ((BI) (x) > (BI) (y))
|
||||||
#define GEUBI(x, y) ((BI) (x) >= (BI) (y))
|
#define GEUBI(x, y) ((BI) (x) >= (BI) (y))
|
||||||
|
|
||||||
#define ADDQI(x, y) ((x) + (y))
|
#define ADDQI(x, y) ((x) + (y))
|
||||||
#define SUBQI(x, y) ((x) - (y))
|
#define SUBQI(x, y) ((x) - (y))
|
||||||
#define MULQI(x, y) ((x) * (y))
|
#define MULQI(x, y) ((x) * (y))
|
||||||
|
@ -64,8 +67,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#define SRAQI(x, y) ((QI) (x) >> (y))
|
#define SRAQI(x, y) ((QI) (x) >> (y))
|
||||||
#define SRLQI(x, y) ((UQI) (x) >> (y))
|
#define SRLQI(x, y) ((UQI) (x) >> (y))
|
||||||
#define SLLQI(x, y) ((UQI) (x) << (y))
|
#define SLLQI(x, y) ((UQI) (x) << (y))
|
||||||
extern QI RORQI PARAMS ((QI, int));
|
extern QI RORQI (QI, int);
|
||||||
extern QI ROLQI PARAMS ((QI, int));
|
extern QI ROLQI (QI, int);
|
||||||
#define ANDQI(x, y) ((x) & (y))
|
#define ANDQI(x, y) ((x) & (y))
|
||||||
#define ORQI(x, y) ((x) | (y))
|
#define ORQI(x, y) ((x) | (y))
|
||||||
#define XORQI(x, y) ((x) ^ (y))
|
#define XORQI(x, y) ((x) ^ (y))
|
||||||
|
@ -82,7 +85,7 @@ extern QI ROLQI PARAMS ((QI, int));
|
||||||
#define LEUQI(x, y) ((UQI) (x) <= (UQI) (y))
|
#define LEUQI(x, y) ((UQI) (x) <= (UQI) (y))
|
||||||
#define GTUQI(x, y) ((UQI) (x) > (UQI) (y))
|
#define GTUQI(x, y) ((UQI) (x) > (UQI) (y))
|
||||||
#define GEUQI(x, y) ((UQI) (x) >= (UQI) (y))
|
#define GEUQI(x, y) ((UQI) (x) >= (UQI) (y))
|
||||||
|
|
||||||
#define ADDHI(x, y) ((x) + (y))
|
#define ADDHI(x, y) ((x) + (y))
|
||||||
#define SUBHI(x, y) ((x) - (y))
|
#define SUBHI(x, y) ((x) - (y))
|
||||||
#define MULHI(x, y) ((x) * (y))
|
#define MULHI(x, y) ((x) * (y))
|
||||||
|
@ -93,8 +96,8 @@ extern QI ROLQI PARAMS ((QI, int));
|
||||||
#define SRAHI(x, y) ((HI) (x) >> (y))
|
#define SRAHI(x, y) ((HI) (x) >> (y))
|
||||||
#define SRLHI(x, y) ((UHI) (x) >> (y))
|
#define SRLHI(x, y) ((UHI) (x) >> (y))
|
||||||
#define SLLHI(x, y) ((UHI) (x) << (y))
|
#define SLLHI(x, y) ((UHI) (x) << (y))
|
||||||
extern HI RORHI PARAMS ((HI, int));
|
extern HI RORHI (HI, int);
|
||||||
extern HI ROLHI PARAMS ((HI, int));
|
extern HI ROLHI (HI, int);
|
||||||
#define ANDHI(x, y) ((x) & (y))
|
#define ANDHI(x, y) ((x) & (y))
|
||||||
#define ORHI(x, y) ((x) | (y))
|
#define ORHI(x, y) ((x) | (y))
|
||||||
#define XORHI(x, y) ((x) ^ (y))
|
#define XORHI(x, y) ((x) ^ (y))
|
||||||
|
@ -111,7 +114,7 @@ extern HI ROLHI PARAMS ((HI, int));
|
||||||
#define LEUHI(x, y) ((UHI) (x) <= (UHI) (y))
|
#define LEUHI(x, y) ((UHI) (x) <= (UHI) (y))
|
||||||
#define GTUHI(x, y) ((UHI) (x) > (UHI) (y))
|
#define GTUHI(x, y) ((UHI) (x) > (UHI) (y))
|
||||||
#define GEUHI(x, y) ((UHI) (x) >= (UHI) (y))
|
#define GEUHI(x, y) ((UHI) (x) >= (UHI) (y))
|
||||||
|
|
||||||
#define ADDSI(x, y) ((x) + (y))
|
#define ADDSI(x, y) ((x) + (y))
|
||||||
#define SUBSI(x, y) ((x) - (y))
|
#define SUBSI(x, y) ((x) - (y))
|
||||||
#define MULSI(x, y) ((x) * (y))
|
#define MULSI(x, y) ((x) * (y))
|
||||||
|
@ -122,8 +125,8 @@ extern HI ROLHI PARAMS ((HI, int));
|
||||||
#define SRASI(x, y) ((SI) (x) >> (y))
|
#define SRASI(x, y) ((SI) (x) >> (y))
|
||||||
#define SRLSI(x, y) ((USI) (x) >> (y))
|
#define SRLSI(x, y) ((USI) (x) >> (y))
|
||||||
#define SLLSI(x, y) ((USI) (x) << (y))
|
#define SLLSI(x, y) ((USI) (x) << (y))
|
||||||
extern SI RORSI PARAMS ((SI, int));
|
extern SI RORSI (SI, int);
|
||||||
extern SI ROLSI PARAMS ((SI, int));
|
extern SI ROLSI (SI, int);
|
||||||
#define ANDSI(x, y) ((x) & (y))
|
#define ANDSI(x, y) ((x) & (y))
|
||||||
#define ORSI(x, y) ((x) | (y))
|
#define ORSI(x, y) ((x) | (y))
|
||||||
#define XORSI(x, y) ((x) ^ (y))
|
#define XORSI(x, y) ((x) ^ (y))
|
||||||
|
@ -140,36 +143,36 @@ extern SI ROLSI PARAMS ((SI, int));
|
||||||
#define LEUSI(x, y) ((USI) (x) <= (USI) (y))
|
#define LEUSI(x, y) ((USI) (x) <= (USI) (y))
|
||||||
#define GTUSI(x, y) ((USI) (x) > (USI) (y))
|
#define GTUSI(x, y) ((USI) (x) > (USI) (y))
|
||||||
#define GEUSI(x, y) ((USI) (x) >= (USI) (y))
|
#define GEUSI(x, y) ((USI) (x) >= (USI) (y))
|
||||||
|
|
||||||
#ifdef DI_FN_SUPPORT
|
#ifdef DI_FN_SUPPORT
|
||||||
extern DI ADDDI PARAMS ((DI, DI));
|
extern DI ADDDI (DI, DI);
|
||||||
extern DI SUBDI PARAMS ((DI, DI));
|
extern DI SUBDI (DI, DI);
|
||||||
extern DI MULDI PARAMS ((DI, DI));
|
extern DI MULDI (DI, DI);
|
||||||
extern DI DIVDI PARAMS ((DI, DI));
|
extern DI DIVDI (DI, DI);
|
||||||
extern DI UDIVDI PARAMS ((DI, DI));
|
extern DI UDIVDI (DI, DI);
|
||||||
extern DI MODDI PARAMS ((DI, DI));
|
extern DI MODDI (DI, DI);
|
||||||
extern DI UMODDI PARAMS ((DI, DI));
|
extern DI UMODDI (DI, DI);
|
||||||
extern DI SRADI PARAMS ((DI, int));
|
extern DI SRADI (DI, int);
|
||||||
extern UDI SRLDI PARAMS ((UDI, int));
|
extern UDI SRLDI (UDI, int);
|
||||||
extern UDI SLLDI PARAMS ((UDI, int));
|
extern UDI SLLDI (UDI, int);
|
||||||
extern DI RORDI PARAMS ((DI, int));
|
extern DI RORDI (DI, int);
|
||||||
extern DI ROLDI PARAMS ((DI, int));
|
extern DI ROLDI (DI, int);
|
||||||
extern DI ANDDI PARAMS ((DI, DI));
|
extern DI ANDDI (DI, DI);
|
||||||
extern DI ORDI PARAMS ((DI, DI));
|
extern DI ORDI (DI, DI);
|
||||||
extern DI XORDI PARAMS ((DI, DI));
|
extern DI XORDI (DI, DI);
|
||||||
extern DI NEGDI PARAMS ((DI));
|
extern DI NEGDI (DI);
|
||||||
extern int NOTDI PARAMS ((DI));
|
extern int NOTDI (DI);
|
||||||
extern DI INVDI PARAMS ((DI));
|
extern DI INVDI (DI);
|
||||||
extern int EQDI PARAMS ((DI, DI));
|
extern int EQDI (DI, DI);
|
||||||
extern int NEDI PARAMS ((DI, DI));
|
extern int NEDI (DI, DI);
|
||||||
extern int LTDI PARAMS ((DI, DI));
|
extern int LTDI (DI, DI);
|
||||||
extern int LEDI PARAMS ((DI, DI));
|
extern int LEDI (DI, DI);
|
||||||
extern int GTDI PARAMS ((DI, DI));
|
extern int GTDI (DI, DI);
|
||||||
extern int GEDI PARAMS ((DI, DI));
|
extern int GEDI (DI, DI);
|
||||||
extern int LTUDI PARAMS ((UDI, UDI));
|
extern int LTUDI (UDI, UDI);
|
||||||
extern int LEUDI PARAMS ((UDI, UDI));
|
extern int LEUDI (UDI, UDI);
|
||||||
extern int GTUDI PARAMS ((UDI, UDI));
|
extern int GTUDI (UDI, UDI);
|
||||||
extern int GEUDI PARAMS ((UDI, UDI));
|
extern int GEUDI (UDI, UDI);
|
||||||
#else /* ! DI_FN_SUPPORT */
|
#else /* ! DI_FN_SUPPORT */
|
||||||
#define ADDDI(x, y) ((x) + (y))
|
#define ADDDI(x, y) ((x) + (y))
|
||||||
#define SUBDI(x, y) ((x) - (y))
|
#define SUBDI(x, y) ((x) - (y))
|
||||||
|
@ -181,8 +184,8 @@ extern int GEUDI PARAMS ((UDI, UDI));
|
||||||
#define SRADI(x, y) ((DI) (x) >> (y))
|
#define SRADI(x, y) ((DI) (x) >> (y))
|
||||||
#define SRLDI(x, y) ((UDI) (x) >> (y))
|
#define SRLDI(x, y) ((UDI) (x) >> (y))
|
||||||
#define SLLDI(x, y) ((UDI) (x) << (y))
|
#define SLLDI(x, y) ((UDI) (x) << (y))
|
||||||
extern DI RORDI PARAMS ((DI, int));
|
extern DI RORDI (DI, int);
|
||||||
extern DI ROLDI PARAMS ((DI, int));
|
extern DI ROLDI (DI, int);
|
||||||
#define ANDDI(x, y) ((x) & (y))
|
#define ANDDI(x, y) ((x) & (y))
|
||||||
#define ORDI(x, y) ((x) | (y))
|
#define ORDI(x, y) ((x) | (y))
|
||||||
#define XORDI(x, y) ((x) ^ (y))
|
#define XORDI(x, y) ((x) ^ (y))
|
||||||
|
@ -200,229 +203,61 @@ extern DI ROLDI PARAMS ((DI, int));
|
||||||
#define GTUDI(x, y) ((UDI) (x) > (UDI) (y))
|
#define GTUDI(x, y) ((UDI) (x) > (UDI) (y))
|
||||||
#define GEUDI(x, y) ((UDI) (x) >= (UDI) (y))
|
#define GEUDI(x, y) ((UDI) (x) >= (UDI) (y))
|
||||||
#endif /* DI_FN_SUPPORT */
|
#endif /* DI_FN_SUPPORT */
|
||||||
|
|
||||||
#ifdef SF_FN_SUPPORT
|
|
||||||
extern SF ADDSF PARAMS ((SF, SF));
|
|
||||||
extern SF SUBSF PARAMS ((SF, SF));
|
|
||||||
extern SF NEGSF PARAMS ((SF));
|
|
||||||
extern SF MULSF PARAMS ((SF, SF));
|
|
||||||
extern SF DIVSF PARAMS ((SF, SF));
|
|
||||||
extern int EQSF PARAMS ((SF, SF));
|
|
||||||
extern int NESF PARAMS ((SF, SF));
|
|
||||||
extern int LTSF PARAMS ((SF, SF));
|
|
||||||
extern int LESF PARAMS ((SF, SF));
|
|
||||||
extern int GTSF PARAMS ((SF, SF));
|
|
||||||
extern int GESF PARAMS ((SF, SF));
|
|
||||||
extern SF ABSSF PARAMS ((SF));
|
|
||||||
extern SF SQRTSF PARAMS ((SF));
|
|
||||||
extern SF COSSF PARAMS ((SF));
|
|
||||||
extern SF SINSF PARAMS ((SF));
|
|
||||||
#else /* ! SF_FN_SUPPORT */
|
|
||||||
#define ADDSF(x, y) ((x) + (y))
|
|
||||||
#define SUBSF(x, y) ((x) - (y))
|
|
||||||
#define NEGSF(x) (- (x))
|
|
||||||
#define MULSF(x, y) ((x) * (y))
|
|
||||||
#define DIVSF(x, y) ((x) / (y))
|
|
||||||
#define EQSF(x, y) ((SF) (x) == (SF) (y))
|
|
||||||
#define NESF(x, y) ((SF) (x) != (SF) (y))
|
|
||||||
#define LTSF(x, y) ((SF) (x) < (SF) (y))
|
|
||||||
#define LESF(x, y) ((SF) (x) <= (SF) (y))
|
|
||||||
#define GTSF(x, y) ((SF) (x) > (SF) (y))
|
|
||||||
#define GESF(x, y) ((SF) (x) >= (SF) (y))
|
|
||||||
extern SF ABSSF PARAMS ((SF));
|
|
||||||
extern SF SQRTSF PARAMS ((SF));
|
|
||||||
extern SF COSSF PARAMS ((SF));
|
|
||||||
extern SF SINSF PARAMS ((SF));
|
|
||||||
#endif /* SF_FN_SUPPORT */
|
|
||||||
|
|
||||||
#ifdef DF_FN_SUPPORT
|
|
||||||
extern DF ADDDF PARAMS ((DF, DF));
|
|
||||||
extern DF SUBDF PARAMS ((DF, DF));
|
|
||||||
extern DF NEGDF PARAMS ((DF));
|
|
||||||
extern DF MULDF PARAMS ((DF, DF));
|
|
||||||
extern DF DIVDF PARAMS ((DF, DF));
|
|
||||||
extern int EQDF PARAMS ((DF, DF));
|
|
||||||
extern int NEDF PARAMS ((DF, DF));
|
|
||||||
extern int LTDF PARAMS ((DF, DF));
|
|
||||||
extern int LEDF PARAMS ((DF, DF));
|
|
||||||
extern int GTDF PARAMS ((DF, DF));
|
|
||||||
extern int GEDF PARAMS ((DF, DF));
|
|
||||||
extern DF ABSDF PARAMS ((DF));
|
|
||||||
extern DF SQRTDF PARAMS ((DF));
|
|
||||||
extern DF COSDF PARAMS ((DF));
|
|
||||||
extern DF SINDF PARAMS ((DF));
|
|
||||||
#else /* ! DF_FN_SUPPORT */
|
|
||||||
#define ADDDF(x, y) ((x) + (y))
|
|
||||||
#define SUBDF(x, y) ((x) - (y))
|
|
||||||
#define NEGDF(x) (- (x))
|
|
||||||
#define MULDF(x, y) ((x) * (y))
|
|
||||||
#define DIVDF(x, y) ((x) / (y))
|
|
||||||
#define EQDF(x, y) ((DF) (x) == (DF) (y))
|
|
||||||
#define NEDF(x, y) ((DF) (x) != (DF) (y))
|
|
||||||
#define LTDF(x, y) ((DF) (x) < (DF) (y))
|
|
||||||
#define LEDF(x, y) ((DF) (x) <= (DF) (y))
|
|
||||||
#define GTDF(x, y) ((DF) (x) > (DF) (y))
|
|
||||||
#define GEDF(x, y) ((DF) (x) >= (DF) (y))
|
|
||||||
extern DF ABSDF PARAMS ((DF));
|
|
||||||
extern DF SQRTDF PARAMS ((DF));
|
|
||||||
extern DF COSDF PARAMS ((DF));
|
|
||||||
extern DF SINDF PARAMS ((DF));
|
|
||||||
#endif /* DF_FN_SUPPORT */
|
|
||||||
|
|
||||||
#ifdef XF_FN_SUPPORT
|
|
||||||
extern XF ADDXF PARAMS ((XF, XF));
|
|
||||||
extern XF SUBXF PARAMS ((XF, XF));
|
|
||||||
extern XF NEGXF PARAMS ((XF));
|
|
||||||
extern XF MULXF PARAMS ((XF, XF));
|
|
||||||
extern XF DIVXF PARAMS ((XF, XF));
|
|
||||||
extern int EQXF PARAMS ((XF, XF));
|
|
||||||
extern int NEXF PARAMS ((XF, XF));
|
|
||||||
extern int LTXF PARAMS ((XF, XF));
|
|
||||||
extern int LEXF PARAMS ((XF, XF));
|
|
||||||
extern int GTXF PARAMS ((XF, XF));
|
|
||||||
extern int GEXF PARAMS ((XF, XF));
|
|
||||||
extern XF ABSXF PARAMS ((XF));
|
|
||||||
extern XF SQRTXF PARAMS ((XF));
|
|
||||||
extern XF COSXF PARAMS ((XF));
|
|
||||||
extern XF SINXF PARAMS ((XF));
|
|
||||||
#else /* ! XF_FN_SUPPORT */
|
|
||||||
#define ADDXF(x, y) ((x) + (y))
|
|
||||||
#define SUBXF(x, y) ((x) - (y))
|
|
||||||
#define NEGXF(x) (- (x))
|
|
||||||
#define MULXF(x, y) ((x) * (y))
|
|
||||||
#define DIVXF(x, y) ((x) / (y))
|
|
||||||
#define EQXF(x, y) ((XF) (x) == (XF) (y))
|
|
||||||
#define NEXF(x, y) ((XF) (x) != (XF) (y))
|
|
||||||
#define LTXF(x, y) ((XF) (x) < (XF) (y))
|
|
||||||
#define LEXF(x, y) ((XF) (x) <= (XF) (y))
|
|
||||||
#define GTXF(x, y) ((XF) (x) > (XF) (y))
|
|
||||||
#define GEXF(x, y) ((XF) (x) >= (XF) (y))
|
|
||||||
extern XF ABSXF PARAMS ((XF));
|
|
||||||
extern XF SQRTXF PARAMS ((XF));
|
|
||||||
extern XF COSXF PARAMS ((XF));
|
|
||||||
extern XF SINXF PARAMS ((XF));
|
|
||||||
#endif /* XF_FN_SUPPORT */
|
|
||||||
|
|
||||||
#ifdef TF_FN_SUPPORT
|
|
||||||
extern TF ADDTF PARAMS ((TF, TF));
|
|
||||||
extern TF SUBTF PARAMS ((TF, TF));
|
|
||||||
extern TF NEGTF PARAMS ((TF));
|
|
||||||
extern TF MULTF PARAMS ((TF, TF));
|
|
||||||
extern TF DIVTF PARAMS ((TF, TF));
|
|
||||||
extern int EQTF PARAMS ((TF, TF));
|
|
||||||
extern int NETF PARAMS ((TF, TF));
|
|
||||||
extern int LTTF PARAMS ((TF, TF));
|
|
||||||
extern int LETF PARAMS ((TF, TF));
|
|
||||||
extern int GTTF PARAMS ((TF, TF));
|
|
||||||
extern int GETF PARAMS ((TF, TF));
|
|
||||||
extern TF ABSTF PARAMS ((TF));
|
|
||||||
extern TF SQRTTF PARAMS ((TF));
|
|
||||||
extern TF COSTF PARAMS ((TF));
|
|
||||||
extern TF SINTF PARAMS ((TF));
|
|
||||||
#else /* ! TF_FN_SUPPORT */
|
|
||||||
#define ADDTF(x, y) ((x) + (y))
|
|
||||||
#define SUBTF(x, y) ((x) - (y))
|
|
||||||
#define NEGTF(x) (- (x))
|
|
||||||
#define MULTF(x, y) ((x) * (y))
|
|
||||||
#define DIVTF(x, y) ((x) / (y))
|
|
||||||
#define EQTF(x, y) ((TF) (x) == (TF) (y))
|
|
||||||
#define NETF(x, y) ((TF) (x) != (TF) (y))
|
|
||||||
#define LTTF(x, y) ((TF) (x) < (TF) (y))
|
|
||||||
#define LETF(x, y) ((TF) (x) <= (TF) (y))
|
|
||||||
#define GTTF(x, y) ((TF) (x) > (TF) (y))
|
|
||||||
#define GETF(x, y) ((TF) (x) >= (TF) (y))
|
|
||||||
extern TF ABSTF PARAMS ((TF));
|
|
||||||
extern TF SQRTTF PARAMS ((TF));
|
|
||||||
extern TF COSTF PARAMS ((TF));
|
|
||||||
extern TF SINTF PARAMS ((TF));
|
|
||||||
#endif /* TF_FN_SUPPORT */
|
|
||||||
|
|
||||||
|
|
||||||
#define EXTBIQI(x) ((QI) (BI) (x))
|
#define EXTBIQI(x) ((QI) (BI) (x))
|
||||||
#define EXTBIHI(x) ((HI) (BI) (x))
|
#define EXTBIHI(x) ((HI) (BI) (x))
|
||||||
#define EXTBISI(x) ((SI) (BI) (x))
|
#define EXTBISI(x) ((SI) (BI) (x))
|
||||||
#if defined (DI_FN_SUPPORT)
|
#if defined (DI_FN_SUPPORT)
|
||||||
extern DI EXTBIDI PARAMS ((BI));
|
extern DI EXTBIDI (BI);
|
||||||
#else
|
#else
|
||||||
#define EXTBIDI(x) ((DI) (BI) (x))
|
#define EXTBIDI(x) ((DI) (BI) (x))
|
||||||
#endif
|
#endif
|
||||||
#define EXTQIHI(x) ((HI) (QI) (x))
|
#define EXTQIHI(x) ((HI) (QI) (x))
|
||||||
#define EXTQISI(x) ((SI) (QI) (x))
|
#define EXTQISI(x) ((SI) (QI) (x))
|
||||||
#if defined (DI_FN_SUPPORT)
|
#if defined (DI_FN_SUPPORT)
|
||||||
extern DI EXTQIDI PARAMS ((QI));
|
extern DI EXTQIDI (QI);
|
||||||
#else
|
#else
|
||||||
#define EXTQIDI(x) ((DI) (QI) (x))
|
#define EXTQIDI(x) ((DI) (QI) (x))
|
||||||
#endif
|
#endif
|
||||||
#define EXTHISI(x) ((SI) (HI) (x))
|
#define EXTHISI(x) ((SI) (HI) (x))
|
||||||
#if defined (DI_FN_SUPPORT)
|
#if defined (DI_FN_SUPPORT)
|
||||||
extern DI EXTHIDI PARAMS ((HI));
|
extern DI EXTHIDI (HI);
|
||||||
#else
|
#else
|
||||||
#define EXTHIDI(x) ((DI) (HI) (x))
|
#define EXTHIDI(x) ((DI) (HI) (x))
|
||||||
#endif
|
#endif
|
||||||
#if defined (DI_FN_SUPPORT)
|
#if defined (DI_FN_SUPPORT)
|
||||||
extern DI EXTSIDI PARAMS ((SI));
|
extern DI EXTSIDI (SI);
|
||||||
#else
|
#else
|
||||||
#define EXTSIDI(x) ((DI) (SI) (x))
|
#define EXTSIDI(x) ((DI) (SI) (x))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined (SF_FN_SUPPORT) || defined (DF_FN_SUPPORT)
|
|
||||||
extern DF EXTSFDF PARAMS ((SF));
|
|
||||||
#else
|
|
||||||
#define EXTSFDF(x) ((DF) (SF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (SF_FN_SUPPORT) || defined (XF_FN_SUPPORT)
|
|
||||||
extern XF EXTSFXF PARAMS ((SF));
|
|
||||||
#else
|
|
||||||
#define EXTSFXF(x) ((XF) (SF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (SF_FN_SUPPORT) || defined (TF_FN_SUPPORT)
|
|
||||||
extern TF EXTSFTF PARAMS ((SF));
|
|
||||||
#else
|
|
||||||
#define EXTSFTF(x) ((TF) (SF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (DF_FN_SUPPORT) || defined (XF_FN_SUPPORT)
|
|
||||||
extern XF EXTDFXF PARAMS ((DF));
|
|
||||||
#else
|
|
||||||
#define EXTDFXF(x) ((XF) (DF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (DF_FN_SUPPORT) || defined (TF_FN_SUPPORT)
|
|
||||||
extern TF EXTDFTF PARAMS ((DF));
|
|
||||||
#else
|
|
||||||
#define EXTDFTF(x) ((TF) (DF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (XF_FN_SUPPORT) || defined (TF_FN_SUPPORT)
|
|
||||||
extern TF EXTXFTF PARAMS ((XF));
|
|
||||||
#else
|
|
||||||
#define EXTXFTF(x) ((TF) (XF) (x))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define ZEXTBIQI(x) ((QI) (BI) (x))
|
#define ZEXTBIQI(x) ((QI) (BI) (x))
|
||||||
#define ZEXTBIHI(x) ((HI) (BI) (x))
|
#define ZEXTBIHI(x) ((HI) (BI) (x))
|
||||||
#define ZEXTBISI(x) ((SI) (BI) (x))
|
#define ZEXTBISI(x) ((SI) (BI) (x))
|
||||||
#if defined (DI_FN_SUPPORT)
|
#if defined (DI_FN_SUPPORT)
|
||||||
extern DI ZEXTBIDI PARAMS ((BI));
|
extern DI ZEXTBIDI (BI);
|
||||||
#else
|
#else
|
||||||
#define ZEXTBIDI(x) ((DI) (BI) (x))
|
#define ZEXTBIDI(x) ((DI) (BI) (x))
|
||||||
#endif
|
#endif
|
||||||
#define ZEXTQIHI(x) ((HI) (UQI) (x))
|
#define ZEXTQIHI(x) ((HI) (UQI) (x))
|
||||||
#define ZEXTQISI(x) ((SI) (UQI) (x))
|
#define ZEXTQISI(x) ((SI) (UQI) (x))
|
||||||
#if defined (DI_FN_SUPPORT)
|
#if defined (DI_FN_SUPPORT)
|
||||||
extern DI ZEXTQIDI PARAMS ((QI));
|
extern DI ZEXTQIDI (QI);
|
||||||
#else
|
#else
|
||||||
#define ZEXTQIDI(x) ((DI) (UQI) (x))
|
#define ZEXTQIDI(x) ((DI) (UQI) (x))
|
||||||
#endif
|
#endif
|
||||||
#define ZEXTHISI(x) ((SI) (UHI) (x))
|
#define ZEXTHISI(x) ((SI) (UHI) (x))
|
||||||
#if defined (DI_FN_SUPPORT)
|
#if defined (DI_FN_SUPPORT)
|
||||||
extern DI ZEXTHIDI PARAMS ((HI));
|
extern DI ZEXTHIDI (HI);
|
||||||
#else
|
#else
|
||||||
#define ZEXTHIDI(x) ((DI) (UHI) (x))
|
#define ZEXTHIDI(x) ((DI) (UHI) (x))
|
||||||
#endif
|
#endif
|
||||||
#if defined (DI_FN_SUPPORT)
|
#if defined (DI_FN_SUPPORT)
|
||||||
extern DI ZEXTSIDI PARAMS ((SI));
|
extern DI ZEXTSIDI (SI);
|
||||||
#else
|
#else
|
||||||
#define ZEXTSIDI(x) ((DI) (USI) (x))
|
#define ZEXTSIDI(x) ((DI) (USI) (x))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define TRUNCQIBI(x) ((BI) (QI) (x))
|
#define TRUNCQIBI(x) ((BI) (QI) (x))
|
||||||
#define TRUNCHIBI(x) ((BI) (HI) (x))
|
#define TRUNCHIBI(x) ((BI) (HI) (x))
|
||||||
#define TRUNCHIQI(x) ((QI) (HI) (x))
|
#define TRUNCHIQI(x) ((QI) (HI) (x))
|
||||||
|
@ -430,403 +265,31 @@ extern DI ZEXTSIDI PARAMS ((SI));
|
||||||
#define TRUNCSIQI(x) ((QI) (SI) (x))
|
#define TRUNCSIQI(x) ((QI) (SI) (x))
|
||||||
#define TRUNCSIHI(x) ((HI) (SI) (x))
|
#define TRUNCSIHI(x) ((HI) (SI) (x))
|
||||||
#if defined (DI_FN_SUPPORT)
|
#if defined (DI_FN_SUPPORT)
|
||||||
extern BI TRUNCDIBI PARAMS ((DI));
|
extern BI TRUNCDIBI (DI);
|
||||||
#else
|
#else
|
||||||
#define TRUNCDIBI(x) ((BI) (DI) (x))
|
#define TRUNCDIBI(x) ((BI) (DI) (x))
|
||||||
#endif
|
#endif
|
||||||
#if defined (DI_FN_SUPPORT)
|
#if defined (DI_FN_SUPPORT)
|
||||||
extern QI TRUNCDIQI PARAMS ((DI));
|
extern QI TRUNCDIQI (DI);
|
||||||
#else
|
#else
|
||||||
#define TRUNCDIQI(x) ((QI) (DI) (x))
|
#define TRUNCDIQI(x) ((QI) (DI) (x))
|
||||||
#endif
|
#endif
|
||||||
#if defined (DI_FN_SUPPORT)
|
#if defined (DI_FN_SUPPORT)
|
||||||
extern HI TRUNCDIHI PARAMS ((DI));
|
extern HI TRUNCDIHI (DI);
|
||||||
#else
|
#else
|
||||||
#define TRUNCDIHI(x) ((HI) (DI) (x))
|
#define TRUNCDIHI(x) ((HI) (DI) (x))
|
||||||
#endif
|
#endif
|
||||||
#if defined (DI_FN_SUPPORT)
|
#if defined (DI_FN_SUPPORT)
|
||||||
extern SI TRUNCDISI PARAMS ((DI));
|
extern SI TRUNCDISI (DI);
|
||||||
#else
|
#else
|
||||||
#define TRUNCDISI(x) ((SI) (DI) (x))
|
#define TRUNCDISI(x) ((SI) (DI) (x))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined (DF_FN_SUPPORT) || defined (SF_FN_SUPPORT)
|
|
||||||
extern SF TRUNCDFSF PARAMS ((DF));
|
|
||||||
#else
|
|
||||||
#define TRUNCDFSF(x) ((SF) (DF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (XF_FN_SUPPORT) || defined (SF_FN_SUPPORT)
|
|
||||||
extern SF TRUNCXFSF PARAMS ((XF));
|
|
||||||
#else
|
|
||||||
#define TRUNCXFSF(x) ((SF) (XF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (XF_FN_SUPPORT) || defined (DF_FN_SUPPORT)
|
|
||||||
extern DF TRUNCXFDF PARAMS ((XF));
|
|
||||||
#else
|
|
||||||
#define TRUNCXFDF(x) ((DF) (XF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (TF_FN_SUPPORT) || defined (SF_FN_SUPPORT)
|
|
||||||
extern SF TRUNCTFSF PARAMS ((TF));
|
|
||||||
#else
|
|
||||||
#define TRUNCTFSF(x) ((SF) (TF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (TF_FN_SUPPORT) || defined (DF_FN_SUPPORT)
|
|
||||||
extern DF TRUNCTFDF PARAMS ((TF));
|
|
||||||
#else
|
|
||||||
#define TRUNCTFDF(x) ((DF) (TF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (TF_FN_SUPPORT) || defined (XF_FN_SUPPORT)
|
|
||||||
extern XF TRUNCTFXF PARAMS ((TF));
|
|
||||||
#else
|
|
||||||
#define TRUNCTFXF(x) ((XF) (TF) (x))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined (SF_FN_SUPPORT)
|
|
||||||
extern SF FLOATQISF PARAMS ((QI));
|
|
||||||
#else
|
|
||||||
#define FLOATQISF(x) ((SF) (QI) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (DF_FN_SUPPORT)
|
|
||||||
extern DF FLOATQIDF PARAMS ((QI));
|
|
||||||
#else
|
|
||||||
#define FLOATQIDF(x) ((DF) (QI) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (XF_FN_SUPPORT)
|
|
||||||
extern XF FLOATQIXF PARAMS ((QI));
|
|
||||||
#else
|
|
||||||
#define FLOATQIXF(x) ((XF) (QI) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (TF_FN_SUPPORT)
|
|
||||||
extern TF FLOATQITF PARAMS ((QI));
|
|
||||||
#else
|
|
||||||
#define FLOATQITF(x) ((TF) (QI) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (SF_FN_SUPPORT)
|
|
||||||
extern SF FLOATHISF PARAMS ((HI));
|
|
||||||
#else
|
|
||||||
#define FLOATHISF(x) ((SF) (HI) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (DF_FN_SUPPORT)
|
|
||||||
extern DF FLOATHIDF PARAMS ((HI));
|
|
||||||
#else
|
|
||||||
#define FLOATHIDF(x) ((DF) (HI) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (XF_FN_SUPPORT)
|
|
||||||
extern XF FLOATHIXF PARAMS ((HI));
|
|
||||||
#else
|
|
||||||
#define FLOATHIXF(x) ((XF) (HI) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (TF_FN_SUPPORT)
|
|
||||||
extern TF FLOATHITF PARAMS ((HI));
|
|
||||||
#else
|
|
||||||
#define FLOATHITF(x) ((TF) (HI) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (SF_FN_SUPPORT)
|
|
||||||
extern SF FLOATSISF PARAMS ((SI));
|
|
||||||
#else
|
|
||||||
#define FLOATSISF(x) ((SF) (SI) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (DF_FN_SUPPORT)
|
|
||||||
extern DF FLOATSIDF PARAMS ((SI));
|
|
||||||
#else
|
|
||||||
#define FLOATSIDF(x) ((DF) (SI) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (XF_FN_SUPPORT)
|
|
||||||
extern XF FLOATSIXF PARAMS ((SI));
|
|
||||||
#else
|
|
||||||
#define FLOATSIXF(x) ((XF) (SI) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (TF_FN_SUPPORT)
|
|
||||||
extern TF FLOATSITF PARAMS ((SI));
|
|
||||||
#else
|
|
||||||
#define FLOATSITF(x) ((TF) (SI) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (DI_FN_SUPPORT) || defined (SF_FN_SUPPORT)
|
|
||||||
extern SF FLOATDISF PARAMS ((DI));
|
|
||||||
#else
|
|
||||||
#define FLOATDISF(x) ((SF) (DI) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (DI_FN_SUPPORT) || defined (DF_FN_SUPPORT)
|
|
||||||
extern DF FLOATDIDF PARAMS ((DI));
|
|
||||||
#else
|
|
||||||
#define FLOATDIDF(x) ((DF) (DI) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (DI_FN_SUPPORT) || defined (XF_FN_SUPPORT)
|
|
||||||
extern XF FLOATDIXF PARAMS ((DI));
|
|
||||||
#else
|
|
||||||
#define FLOATDIXF(x) ((XF) (DI) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (DI_FN_SUPPORT) || defined (TF_FN_SUPPORT)
|
|
||||||
extern TF FLOATDITF PARAMS ((DI));
|
|
||||||
#else
|
|
||||||
#define FLOATDITF(x) ((TF) (DI) (x))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined (SF_FN_SUPPORT)
|
|
||||||
extern SF UFLOATQISF PARAMS ((QI));
|
|
||||||
#else
|
|
||||||
#define UFLOATQISF(x) ((SF) (UQI) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (DF_FN_SUPPORT)
|
|
||||||
extern DF UFLOATQIDF PARAMS ((QI));
|
|
||||||
#else
|
|
||||||
#define UFLOATQIDF(x) ((DF) (UQI) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (XF_FN_SUPPORT)
|
|
||||||
extern XF UFLOATQIXF PARAMS ((QI));
|
|
||||||
#else
|
|
||||||
#define UFLOATQIXF(x) ((XF) (UQI) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (TF_FN_SUPPORT)
|
|
||||||
extern TF UFLOATQITF PARAMS ((QI));
|
|
||||||
#else
|
|
||||||
#define UFLOATQITF(x) ((TF) (UQI) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (SF_FN_SUPPORT)
|
|
||||||
extern SF UFLOATHISF PARAMS ((HI));
|
|
||||||
#else
|
|
||||||
#define UFLOATHISF(x) ((SF) (UHI) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (DF_FN_SUPPORT)
|
|
||||||
extern DF UFLOATHIDF PARAMS ((HI));
|
|
||||||
#else
|
|
||||||
#define UFLOATHIDF(x) ((DF) (UHI) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (XF_FN_SUPPORT)
|
|
||||||
extern XF UFLOATHIXF PARAMS ((HI));
|
|
||||||
#else
|
|
||||||
#define UFLOATHIXF(x) ((XF) (UHI) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (TF_FN_SUPPORT)
|
|
||||||
extern TF UFLOATHITF PARAMS ((HI));
|
|
||||||
#else
|
|
||||||
#define UFLOATHITF(x) ((TF) (UHI) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (SF_FN_SUPPORT)
|
|
||||||
extern SF UFLOATSISF PARAMS ((SI));
|
|
||||||
#else
|
|
||||||
#define UFLOATSISF(x) ((SF) (USI) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (DF_FN_SUPPORT)
|
|
||||||
extern DF UFLOATSIDF PARAMS ((SI));
|
|
||||||
#else
|
|
||||||
#define UFLOATSIDF(x) ((DF) (USI) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (XF_FN_SUPPORT)
|
|
||||||
extern XF UFLOATSIXF PARAMS ((SI));
|
|
||||||
#else
|
|
||||||
#define UFLOATSIXF(x) ((XF) (USI) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (TF_FN_SUPPORT)
|
|
||||||
extern TF UFLOATSITF PARAMS ((SI));
|
|
||||||
#else
|
|
||||||
#define UFLOATSITF(x) ((TF) (USI) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (DI_FN_SUPPORT) || defined (SF_FN_SUPPORT)
|
|
||||||
extern SF UFLOATDISF PARAMS ((DI));
|
|
||||||
#else
|
|
||||||
#define UFLOATDISF(x) ((SF) (UDI) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (DI_FN_SUPPORT) || defined (DF_FN_SUPPORT)
|
|
||||||
extern DF UFLOATDIDF PARAMS ((DI));
|
|
||||||
#else
|
|
||||||
#define UFLOATDIDF(x) ((DF) (UDI) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (DI_FN_SUPPORT) || defined (XF_FN_SUPPORT)
|
|
||||||
extern XF UFLOATDIXF PARAMS ((DI));
|
|
||||||
#else
|
|
||||||
#define UFLOATDIXF(x) ((XF) (UDI) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (DI_FN_SUPPORT) || defined (TF_FN_SUPPORT)
|
|
||||||
extern TF UFLOATDITF PARAMS ((DI));
|
|
||||||
#else
|
|
||||||
#define UFLOATDITF(x) ((TF) (UDI) (x))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined (SF_FN_SUPPORT)
|
|
||||||
extern BI FIXSFBI PARAMS ((SF));
|
|
||||||
#else
|
|
||||||
#define FIXSFBI(x) ((BI) (SF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (SF_FN_SUPPORT)
|
|
||||||
extern QI FIXSFQI PARAMS ((SF));
|
|
||||||
#else
|
|
||||||
#define FIXSFQI(x) ((QI) (SF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (SF_FN_SUPPORT)
|
|
||||||
extern HI FIXSFHI PARAMS ((SF));
|
|
||||||
#else
|
|
||||||
#define FIXSFHI(x) ((HI) (SF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (SF_FN_SUPPORT)
|
|
||||||
extern SI FIXSFSI PARAMS ((SF));
|
|
||||||
#else
|
|
||||||
#define FIXSFSI(x) ((SI) (SF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (SF_FN_SUPPORT) || defined (DI_FN_SUPPORT)
|
|
||||||
extern DI FIXSFDI PARAMS ((SF));
|
|
||||||
#else
|
|
||||||
#define FIXSFDI(x) ((DI) (SF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (DF_FN_SUPPORT)
|
|
||||||
extern BI FIXDFBI PARAMS ((DF));
|
|
||||||
#else
|
|
||||||
#define FIXDFBI(x) ((BI) (DF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (DF_FN_SUPPORT)
|
|
||||||
extern QI FIXDFQI PARAMS ((DF));
|
|
||||||
#else
|
|
||||||
#define FIXDFQI(x) ((QI) (DF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (DF_FN_SUPPORT)
|
|
||||||
extern HI FIXDFHI PARAMS ((DF));
|
|
||||||
#else
|
|
||||||
#define FIXDFHI(x) ((HI) (DF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (DF_FN_SUPPORT)
|
|
||||||
extern SI FIXDFSI PARAMS ((DF));
|
|
||||||
#else
|
|
||||||
#define FIXDFSI(x) ((SI) (DF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (DF_FN_SUPPORT) || defined (DI_FN_SUPPORT)
|
|
||||||
extern DI FIXDFDI PARAMS ((DF));
|
|
||||||
#else
|
|
||||||
#define FIXDFDI(x) ((DI) (DF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (XF_FN_SUPPORT)
|
|
||||||
extern BI FIXXFBI PARAMS ((XF));
|
|
||||||
#else
|
|
||||||
#define FIXXFBI(x) ((BI) (XF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (XF_FN_SUPPORT)
|
|
||||||
extern QI FIXXFQI PARAMS ((XF));
|
|
||||||
#else
|
|
||||||
#define FIXXFQI(x) ((QI) (XF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (XF_FN_SUPPORT)
|
|
||||||
extern HI FIXXFHI PARAMS ((XF));
|
|
||||||
#else
|
|
||||||
#define FIXXFHI(x) ((HI) (XF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (XF_FN_SUPPORT)
|
|
||||||
extern SI FIXXFSI PARAMS ((XF));
|
|
||||||
#else
|
|
||||||
#define FIXXFSI(x) ((SI) (XF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (XF_FN_SUPPORT) || defined (DI_FN_SUPPORT)
|
|
||||||
extern DI FIXXFDI PARAMS ((XF));
|
|
||||||
#else
|
|
||||||
#define FIXXFDI(x) ((DI) (XF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (TF_FN_SUPPORT)
|
|
||||||
extern BI FIXTFBI PARAMS ((TF));
|
|
||||||
#else
|
|
||||||
#define FIXTFBI(x) ((BI) (TF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (TF_FN_SUPPORT)
|
|
||||||
extern QI FIXTFQI PARAMS ((TF));
|
|
||||||
#else
|
|
||||||
#define FIXTFQI(x) ((QI) (TF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (TF_FN_SUPPORT)
|
|
||||||
extern HI FIXTFHI PARAMS ((TF));
|
|
||||||
#else
|
|
||||||
#define FIXTFHI(x) ((HI) (TF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (TF_FN_SUPPORT)
|
|
||||||
extern SI FIXTFSI PARAMS ((TF));
|
|
||||||
#else
|
|
||||||
#define FIXTFSI(x) ((SI) (TF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (TF_FN_SUPPORT) || defined (DI_FN_SUPPORT)
|
|
||||||
extern DI FIXTFDI PARAMS ((TF));
|
|
||||||
#else
|
|
||||||
#define FIXTFDI(x) ((DI) (TF) (x))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined (SF_FN_SUPPORT)
|
|
||||||
extern QI UFIXSFQI PARAMS ((SF));
|
|
||||||
#else
|
|
||||||
#define UFIXSFQI(x) ((UQI) (SF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (SF_FN_SUPPORT)
|
|
||||||
extern HI UFIXSFHI PARAMS ((SF));
|
|
||||||
#else
|
|
||||||
#define UFIXSFHI(x) ((UHI) (SF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (SF_FN_SUPPORT)
|
|
||||||
extern SI UFIXSFSI PARAMS ((SF));
|
|
||||||
#else
|
|
||||||
#define UFIXSFSI(x) ((USI) (SF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (SF_FN_SUPPORT) || defined (DI_FN_SUPPORT)
|
|
||||||
extern DI UFIXSFDI PARAMS ((SF));
|
|
||||||
#else
|
|
||||||
#define UFIXSFDI(x) ((UDI) (SF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (DF_FN_SUPPORT)
|
|
||||||
extern QI UFIXDFQI PARAMS ((DF));
|
|
||||||
#else
|
|
||||||
#define UFIXDFQI(x) ((UQI) (DF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (DF_FN_SUPPORT)
|
|
||||||
extern HI UFIXDFHI PARAMS ((DF));
|
|
||||||
#else
|
|
||||||
#define UFIXDFHI(x) ((UHI) (DF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (DF_FN_SUPPORT)
|
|
||||||
extern SI UFIXDFSI PARAMS ((DF));
|
|
||||||
#else
|
|
||||||
#define UFIXDFSI(x) ((USI) (DF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (DF_FN_SUPPORT) || defined (DI_FN_SUPPORT)
|
|
||||||
extern DI UFIXDFDI PARAMS ((DF));
|
|
||||||
#else
|
|
||||||
#define UFIXDFDI(x) ((UDI) (DF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (XF_FN_SUPPORT)
|
|
||||||
extern QI UFIXXFQI PARAMS ((XF));
|
|
||||||
#else
|
|
||||||
#define UFIXXFQI(x) ((UQI) (XF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (XF_FN_SUPPORT)
|
|
||||||
extern HI UFIXXFHI PARAMS ((XF));
|
|
||||||
#else
|
|
||||||
#define UFIXXFHI(x) ((UHI) (XF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (XF_FN_SUPPORT)
|
|
||||||
extern SI UFIXXFSI PARAMS ((XF));
|
|
||||||
#else
|
|
||||||
#define UFIXXFSI(x) ((USI) (XF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (XF_FN_SUPPORT) || defined (DI_FN_SUPPORT)
|
|
||||||
extern DI UFIXXFDI PARAMS ((XF));
|
|
||||||
#else
|
|
||||||
#define UFIXXFDI(x) ((UDI) (XF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (TF_FN_SUPPORT)
|
|
||||||
extern QI UFIXTFQI PARAMS ((TF));
|
|
||||||
#else
|
|
||||||
#define UFIXTFQI(x) ((UQI) (TF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (TF_FN_SUPPORT)
|
|
||||||
extern HI UFIXTFHI PARAMS ((TF));
|
|
||||||
#else
|
|
||||||
#define UFIXTFHI(x) ((UHI) (TF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (TF_FN_SUPPORT)
|
|
||||||
extern SI UFIXTFSI PARAMS ((TF));
|
|
||||||
#else
|
|
||||||
#define UFIXTFSI(x) ((USI) (TF) (x))
|
|
||||||
#endif
|
|
||||||
#if defined (TF_FN_SUPPORT) || defined (DI_FN_SUPPORT)
|
|
||||||
extern DI UFIXTFDI PARAMS ((TF));
|
|
||||||
#else
|
|
||||||
#define UFIXTFDI(x) ((UDI) (TF) (x))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Composing/decomposing the various types. */
|
/* Composing/decomposing the various types. */
|
||||||
|
|
||||||
|
/* ??? endianness issues undecided */
|
||||||
|
/* ??? CURRENT_TARGET_BYTE_ORDER usage wip */
|
||||||
|
|
||||||
#ifdef SEMOPS_DEFINE_INLINE
|
#ifdef SEMOPS_DEFINE_INLINE
|
||||||
|
|
||||||
SEMOPS_INLINE SF
|
SEMOPS_INLINE SF
|
||||||
|
@ -848,7 +311,6 @@ SUBWORDSFSI (SIM_CPU *cpu, SF in)
|
||||||
SEMOPS_INLINE SI
|
SEMOPS_INLINE SI
|
||||||
SUBWORDDISI (SIM_CPU *cpu, DI in, int word)
|
SUBWORDDISI (SIM_CPU *cpu, DI in, int word)
|
||||||
{
|
{
|
||||||
/* ??? endianness issues undecided */
|
|
||||||
if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN)
|
if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN)
|
||||||
{
|
{
|
||||||
if (word == 0)
|
if (word == 0)
|
||||||
|
@ -868,7 +330,6 @@ SUBWORDDISI (SIM_CPU *cpu, DI in, int word)
|
||||||
SEMOPS_INLINE SI
|
SEMOPS_INLINE SI
|
||||||
SUBWORDDFSI (SIM_CPU *cpu, DF in, int word)
|
SUBWORDDFSI (SIM_CPU *cpu, DF in, int word)
|
||||||
{
|
{
|
||||||
/* ??? endianness issues undecided */
|
|
||||||
union { DF in; SI out[2]; } x;
|
union { DF in; SI out[2]; } x;
|
||||||
x.in = in;
|
x.in = in;
|
||||||
if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN)
|
if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN)
|
||||||
|
@ -877,16 +338,26 @@ SUBWORDDFSI (SIM_CPU *cpu, DF in, int word)
|
||||||
return x.out[!word];
|
return x.out[!word];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SEMOPS_INLINE SI
|
||||||
|
SUBWORDXFSI (SIM_CPU *cpu, XF in, int word)
|
||||||
|
{
|
||||||
|
union { XF in; SI out[3]; } x;
|
||||||
|
x.in = in;
|
||||||
|
if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN)
|
||||||
|
return x.out[word];
|
||||||
|
else
|
||||||
|
return x.out[2 - word];
|
||||||
|
}
|
||||||
|
|
||||||
SEMOPS_INLINE SI
|
SEMOPS_INLINE SI
|
||||||
SUBWORDTFSI (SIM_CPU *cpu, TF in, int word)
|
SUBWORDTFSI (SIM_CPU *cpu, TF in, int word)
|
||||||
{
|
{
|
||||||
/* ??? endianness issues undecided */
|
|
||||||
union { TF in; SI out[4]; } x;
|
union { TF in; SI out[4]; } x;
|
||||||
x.in = in;
|
x.in = in;
|
||||||
if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN)
|
if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN)
|
||||||
return x.out[word];
|
return x.out[word];
|
||||||
else
|
else
|
||||||
return x.out[word ^ 3];
|
return x.out[3 - word];
|
||||||
}
|
}
|
||||||
|
|
||||||
SEMOPS_INLINE DI
|
SEMOPS_INLINE DI
|
||||||
|
@ -909,6 +380,17 @@ JOINSIDF (SIM_CPU *cpu, SI x0, SI x1)
|
||||||
return x.out;
|
return x.out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SEMOPS_INLINE XF
|
||||||
|
JOINSIXF (SIM_CPU *cpu, SI x0, SI x1, SI x2)
|
||||||
|
{
|
||||||
|
union { SI in[3]; XF out; } x;
|
||||||
|
if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN)
|
||||||
|
x.in[0] = x0, x.in[1] = x1, x.in[2] = x2;
|
||||||
|
else
|
||||||
|
x.in[2] = x0, x.in[1] = x1, x.in[0] = x2;
|
||||||
|
return x.out;
|
||||||
|
}
|
||||||
|
|
||||||
SEMOPS_INLINE TF
|
SEMOPS_INLINE TF
|
||||||
JOINSITF (SIM_CPU *cpu, SI x0, SI x1, SI x2, SI x3)
|
JOINSITF (SIM_CPU *cpu, SI x0, SI x1, SI x2, SI x3)
|
||||||
{
|
{
|
||||||
|
@ -926,10 +408,12 @@ SF SUBWORDSISF (SIM_CPU *, SI);
|
||||||
SI SUBWORDSFSI (SIM_CPU *, SF);
|
SI SUBWORDSFSI (SIM_CPU *, SF);
|
||||||
SI SUBWORDDISI (SIM_CPU *, DI, int);
|
SI SUBWORDDISI (SIM_CPU *, DI, int);
|
||||||
SI SUBWORDDFSI (SIM_CPU *, DF, int);
|
SI SUBWORDDFSI (SIM_CPU *, DF, int);
|
||||||
|
SI SUBWORDXFSI (SIM_CPU *, XF, int);
|
||||||
SI SUBWORDTFSI (SIM_CPU *, TF, int);
|
SI SUBWORDTFSI (SIM_CPU *, TF, int);
|
||||||
|
|
||||||
DI JOINSIDI (SIM_CPU *, SI, SI);
|
DI JOINSIDI (SIM_CPU *, SI, SI);
|
||||||
DF JOINSIDF (SIM_CPU *, SI, SI);
|
DF JOINSIDF (SIM_CPU *, SI, SI);
|
||||||
|
XF JOINSIXF (SIM_CPU *, SI, SI, SI);
|
||||||
TF JOINSITF (SIM_CPU *, SI, SI, SI, SI);
|
TF JOINSITF (SIM_CPU *, SI, SI, SI, SI);
|
||||||
|
|
||||||
#endif /* SUBWORD,JOIN */
|
#endif /* SUBWORD,JOIN */
|
||||||
|
|
|
@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
|
||||||
#include "cgen-defs.h"
|
#include "cgen-defs.h"
|
||||||
#include "cgen-scache.h"
|
#include "cgen-scache.h"
|
||||||
|
#include "cgen-fpu.h"
|
||||||
#include "cgen-cpu.h"
|
#include "cgen-cpu.h"
|
||||||
#include "cgen-trace.h"
|
#include "cgen-trace.h"
|
||||||
|
|
||||||
|
|
|
@ -98,13 +98,6 @@ extern DI make_struct_di (SI, SI);
|
||||||
#define MAKEDI(hi, lo) (make_struct_di ((hi), (lo)))
|
#define MAKEDI(hi, lo) (make_struct_di ((hi), (lo)))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* FIXME: Need to provide libraries if these aren't appropriate for target,
|
|
||||||
or user's needs. */
|
|
||||||
typedef float SF; /* FIXME: struct */
|
|
||||||
typedef double DF; /* FIXME: struct */
|
|
||||||
typedef struct { SI parts[3]; } XF; /* FIXME: configure, provide library */
|
|
||||||
typedef struct { SI parts[4]; } TF; /* FIXME: configure, provide library */
|
|
||||||
|
|
||||||
/* These are used to record extracted raw data from an instruction, among other
|
/* These are used to record extracted raw data from an instruction, among other
|
||||||
things. It must be a host data type, and not a target one. */
|
things. It must be a host data type, and not a target one. */
|
||||||
typedef int INT;
|
typedef int INT;
|
||||||
|
@ -113,4 +106,6 @@ typedef unsigned int UINT;
|
||||||
typedef unsigned_address ADDR; /* FIXME: wip*/
|
typedef unsigned_address ADDR; /* FIXME: wip*/
|
||||||
typedef unsigned_address IADDR; /* FIXME: wip*/
|
typedef unsigned_address IADDR; /* FIXME: wip*/
|
||||||
|
|
||||||
|
/* fp types are in cgen-fpu.h */
|
||||||
|
|
||||||
#endif /* CGEN_TYPES_H */
|
#endif /* CGEN_TYPES_H */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue