import gdb-1999-09-28 snapshot
This commit is contained in:
parent
f4bda9848f
commit
6426a772a2
37 changed files with 925 additions and 603 deletions
242
gdb/ChangeLog
242
gdb/ChangeLog
|
@ -1,3 +1,245 @@
|
|||
Tue Sep 28 11:08:34 1999 Jeffrey A Law (law@cygnus.com)
|
||||
|
||||
* hppa-tdep.c (hppa_fix_call_dummy): Ignore IMPORT_SHLIB stubs
|
||||
except for hpux11 native. Break out of the loop to find a
|
||||
stub as soon as we find an IMPORT stub.
|
||||
(skip_prologue_hard_way): Also recognize copy %ret1,target and
|
||||
all PA64 argument stores as prologue instructions.
|
||||
|
||||
1999-09-28 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
|
||||
|
||||
* breakpoint.c, defs.h, event-top.c, infcmd.c, infrun.c, main.c,
|
||||
remote.c, top.c, tracepoint.c, utils.c (async_p): Change var name
|
||||
to event_loop_p.
|
||||
|
||||
1999-09-28 Jim Blandy <jimb@cris.red-bean.com>
|
||||
|
||||
* hppa-tdep.c (skip_prologue_hard_way): Recognize ldo insns
|
||||
which generate pointers into the argument list.
|
||||
|
||||
Tue Sep 28 13:56:49 1999 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* remote.h (cleanup_sigint_signal_handler,
|
||||
initialize_sigint_signal_handler): Delete extern declarations.
|
||||
* event-top.c, infrun.c: No longer need to include "remote.h".
|
||||
* remote.c (cleanup_sigint_signal_handler,
|
||||
initialize_sigint_signal_handler): Make static.
|
||||
* Makefile.in (event-top.o): Delete dependency on "remote.h".
|
||||
|
||||
* remote.c (remote_async_terminal_ours_p): New static global. Keep
|
||||
track of who currently owns the terminal.
|
||||
(remote_async_open_1): Initialize.
|
||||
(remote_async_terminal_inferior): Test
|
||||
remote_async_terminal_ours_p. Claim CNTRL-C handler as part of
|
||||
transfering the terminal to the target.
|
||||
(remote_async_terminal_ours): Similar.
|
||||
|
||||
Mon Sep 27 12:33:45 1999 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* remote.c (async_interrupt_query): Delete function. Merged into
|
||||
interrupt_query. Async cases handled by target_terminal_ours,
|
||||
target_terminal_inferior and SERIAL_CLOSE.
|
||||
(async_remote_interrupt_twice): Update.
|
||||
(remote_async_terminal_ours, remote_async_terminal_inferior): New
|
||||
functions. Steal STDIN from GDB's CLI.
|
||||
(init_remote_async_ops): Initialize to_terminal_ours and
|
||||
to_terminal_inferior.
|
||||
|
||||
* event-top.c (async_disable_stdin, async_disable_stdin): Use
|
||||
target_terminal_ours / target_terminal_inferior to transfer
|
||||
ownership of the terminal between GDB and the target.
|
||||
|
||||
1999-09-27 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
|
||||
|
||||
* infcmd.c (run_command): Call async_disable_stdin() only if
|
||||
dealing with an asynchronous target.
|
||||
|
||||
Mon Sep 27 11:48:38 1999 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* target.h (struct target_ops): Add to_can_async_p, to_is_async_p,
|
||||
to_async. Delete to_has_async. These correspond well with
|
||||
SERIAL* async methods.
|
||||
(target_can_async_p, target_is_async_p, target_async): Define.
|
||||
* target.c (update_current_target, cleanup_target): Update.
|
||||
|
||||
* remote.c (remote_async_open_1): Change target to async using
|
||||
target_async.
|
||||
(remote_can_async_p, remote_is_async_p, remote_async): New
|
||||
functions.
|
||||
(remote_async_wait, remote_async_open_1): Add FIXME about how
|
||||
wait_forever_enabled_p can almost be deleted once the client can
|
||||
enable/disable target_async.
|
||||
|
||||
* breakpoint.c (until_break_command), infrun.c (proceed), infcmd.c
|
||||
(run_command, continue_command, step_1, jump_command,
|
||||
until_command, finish_command, interrupt_target_command), top.c
|
||||
(return_to_top_level, execute_command), event-top.c
|
||||
(command_handler): Replace target_has_async with
|
||||
target_can_async_p.
|
||||
|
||||
Sun Sep 26 02:10:47 1999 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* remote.c (remote_async_open_1): If we go into async mode, never
|
||||
wait for ever.
|
||||
|
||||
* infcmd.c: Include "event-top.h".
|
||||
(run_command, continue_command, jump_command, until_command,
|
||||
finish_command): Use async_disable_stdin to disable the console
|
||||
for synchronous commands.
|
||||
|
||||
* remote.c (async_interrupt_query): Only disconnect the console
|
||||
from the terminal when sync_execution.
|
||||
|
||||
* remote.c (initialize_sigint_signal_handler): Move declaration
|
||||
from here.
|
||||
* remote.h: To here. Make non-static.
|
||||
|
||||
* remote.c (remote_async_resume, async_interrupt_query): Move
|
||||
prompt code from here.
|
||||
* event-top.c (async_disable_stdin, async_enable_stdin): To
|
||||
here. New function.
|
||||
|
||||
* infrun.c (start_remote): Delete commented out code.
|
||||
|
||||
Fri Sep 24 12:38:31 1999 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* remote.c (remote_async_open_1): Perform the initial async_open
|
||||
using only synchronous calls. Only after the target is fully
|
||||
connected, switch to async mode. Include FIXME about now it
|
||||
currently works VS how it should be working.
|
||||
(remote_async_open_1, set_extended_protocol): Delete function
|
||||
set_extended_protocol. All open communication is now done
|
||||
synchronously.
|
||||
(forever_enabled_p): New variable. Determine if remote_async_wait
|
||||
should block FOREVER when fetching target information.
|
||||
(remote_cisco_open, remote_open_1): Set forever_enabled_p.
|
||||
|
||||
* infrun.c (start_remote): During the initial connect, always use
|
||||
a synchronous wait.
|
||||
|
||||
Sat Sep 25 18:13:38 1999 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* Makefile.in (event-top.o): Add dependency.
|
||||
* event-top.c: Include "remote.h".
|
||||
* remote.c (async_interrupt_query), event-top.c:
|
||||
(async_enable_stdin): Pass dummy parameter to
|
||||
cleanup_sigint_signal_handler.
|
||||
* remote.c (cleanup_sigint_signal_handler), remote.h
|
||||
(cleanup_sigint_signal_handler), event-top.c (async_enable_stdin),
|
||||
event-top.h (async_enable_stdin): Change signature to match
|
||||
make_exec_error_cleanup handler pararameter.
|
||||
|
||||
Thu Sep 23 20:48:22 1999 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* defs.h (enum command_class): Move from here.
|
||||
* command.h (command_class): To here.
|
||||
|
||||
1999-09-24 Kevin Buettner <kevinb@cygnus.com>
|
||||
* breakpoint.c (bpstat_stop_status): Use not_a_breakpoint to
|
||||
help properly set bp_addr.
|
||||
* infrun.c (handle_inferior_event): Simplify calls to
|
||||
bp_stop_status.
|
||||
|
||||
1999-09-24 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
|
||||
|
||||
* top.c (return_to_top_level): Do exec_error cleanups if are
|
||||
interrupting a simulated synchronous execution command.
|
||||
|
||||
* infrun.c (start_remote): Create a cleanup to enable stdin in
|
||||
case of error from this command.
|
||||
(complete_execution): Do the enabling of stdin via the exec_error
|
||||
cleanups, when needed.
|
||||
|
||||
* remote.c (remote_async_resume): Make sure we re-enable stdin in
|
||||
case of error from the target.
|
||||
(handle_remote_sigint_twice): The handler to be set is
|
||||
async_remote_interrupt_twice, not async_remote_interrupt.
|
||||
(async_remote_interrupt_twice): Don't do anything if the target
|
||||
has been killed already. Call async_interrupt_query, instead of
|
||||
interrupt_query.
|
||||
(async_interrupt_query): New function. Async case of
|
||||
interrupt_query().
|
||||
|
||||
* event-top.c (async_enable_stdin): New function. Reinstate stdin
|
||||
with the event loop.
|
||||
* event-top.h (async_enable_stdin): Export.
|
||||
|
||||
* utils.c (exec_error_cleanup_chain): New cleanup chain.
|
||||
(make_exec_error_cleanup, do_exec_error_cleanups,
|
||||
discard_exec_error_cleanups): New functions.
|
||||
* defs.h (make_exec_error_cleanup, do_exec_error_cleanups,
|
||||
discard_exec_error_cleanups): Export.
|
||||
|
||||
1999-09-24 Jim Blandy <jimb@zwingli.cygnus.com>
|
||||
|
||||
* ax-gdb.c (expr_to_agent): Don't forget to pass argument to
|
||||
new_agent_expr.
|
||||
|
||||
1999-09-24 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
|
||||
|
||||
* event-loop.c (fetch_inferior_event_wrapper): New
|
||||
function. Wrapper to pass to catch_errors.
|
||||
(inferior_event_handler): Pop the target if things go bad with it.
|
||||
Call fetch_inferior_event() from within catch_errors().
|
||||
|
||||
1999-09-24 Jim Blandy <jimb@zwingli.cygnus.com>
|
||||
|
||||
* ax-gdb.c: Use internal_error instead of error, where
|
||||
appropriate.
|
||||
|
||||
1999-09-23 James Ingham <jingham@leda.cygnus.com>
|
||||
|
||||
* target.c (target_resize_to_sections): New function. Gather the
|
||||
resizing code for the to_sections field into one place, and make
|
||||
sure you update the other targets that are sharing the to_sections
|
||||
structure.
|
||||
* target.h: Declare the target_resize_to_sections function.
|
||||
* solib.c (solib_add): use target_resize_to_sections.
|
||||
* somsolib.c (som_solib_load_symbols): ditto
|
||||
* rs6000-nat.c (xcoff_relocate_core): ditto
|
||||
* pa64solib.c (pa64_solib_load_symbols): ditto
|
||||
* irix5-nat.c (solib_add):ditto
|
||||
|
||||
* top.c: Define the attach & detach hooks
|
||||
* defs.h: Declare the attach & detach hooks.
|
||||
* infcmd.c (attach_command): call the attach hook if it exists.
|
||||
(detach_command): call the detach hook if it exists.
|
||||
|
||||
* complaints.c (complain): Send the complaints to stderr rather
|
||||
than stdout, so they don't get mixed into the result stream from
|
||||
commands.
|
||||
|
||||
1999-09-23 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
|
||||
|
||||
* event-loop.c (poll_timers): Use correct timeval field names,
|
||||
when setting the notifier timeouts, in case of select() used.
|
||||
(gdb_wait_for_event): Pass a pointer to the timeout structure to
|
||||
select(), not the structure.
|
||||
|
||||
Wed Sep 22 10:35:32 1999 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* Makefile.in (init.c): Change generated file to include "defs.h"
|
||||
and "call-cmds.h". Use initialize_file_ftype when declaring
|
||||
each initialize functions.
|
||||
(call_cmds_h): Add definition.
|
||||
(init.o): Add target and dependencies.
|
||||
(init.c): Don't grep for _initialize* in init.c.
|
||||
|
||||
* defs.h (initialize_file_ftype): Add function typedef.
|
||||
|
||||
1999-09-22 Michael Snyder <msnyder@cleaver.cygnus.com>
|
||||
|
||||
* procfs.c (init_procinfo): move fltset initialization to caller.
|
||||
(do_attach, create_procinfo): initialize fltset.
|
||||
|
||||
1999-09-22 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
|
||||
|
||||
* event-loop.c, event-top.c, event-loop.h: Rerun indent.
|
||||
|
||||
1999-09-21 Doug Evans <devans@casey.cygnus.com>
|
||||
|
||||
* m32r-stub.c (handle_exception): Fix typo in patch of 1999-08-26.
|
||||
|
||||
Tue Sep 21 14:55:29 1999 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
From 1999-08-20 J.T. Conklin <jtc@redback.com>:
|
||||
|
|
|
@ -229,7 +229,7 @@ CDEPS = $(XM_CDEPS) $(TM_CDEPS) $(NAT_CDEPS) $(SIM) $(BFD) $(READLINE) \
|
|||
ADD_FILES = $(REGEX) $(XM_ADD_FILES) $(TM_ADD_FILES) $(NAT_ADD_FILES)
|
||||
ADD_DEPS = $(REGEX1) $(XM_ADD_FILES) $(TM_ADD_FILES) $(NAT_ADD_FILES)
|
||||
|
||||
VERSION = 19990921
|
||||
VERSION = 19990928
|
||||
DIST=gdb
|
||||
|
||||
LINT=/usr/5bin/lint
|
||||
|
@ -448,6 +448,7 @@ breakpoint_h = breakpoint.h $(frame_h) $(value_h)
|
|||
command_h = command.h
|
||||
gdbcmd_h = gdbcmd.h $(command_h)
|
||||
|
||||
call_cmds_h = call-cmds.h
|
||||
defs_h = defs.h xm.h tm.h nm.h config.status config.h gdbarch.h
|
||||
|
||||
top_h = top.h
|
||||
|
@ -622,15 +623,11 @@ uninstall: force
|
|||
|
||||
init.c: $(OBS) $(TSOBS)
|
||||
@echo Making init.c
|
||||
@rm -f init.c-tmp
|
||||
@echo '/* Do not modify this file. */' >init.c-tmp
|
||||
@echo '/* It is created automatically by the Makefile. */'>>init.c-tmp
|
||||
@echo '#include "ansidecl.h"' >>init.c-tmp
|
||||
@echo 'extern void initialize_all_files PARAMS ((void));' >>init.c-tmp
|
||||
@echo 'void initialize_all_files PARAMS ((void)) {' >>init.c-tmp
|
||||
@rm -f init.c-tmp init.l-tmp
|
||||
@-echo $(OBS) $(TSOBS) | \
|
||||
tr ' ' '\012' | \
|
||||
sed -e '/^Onindy.o/d' \
|
||||
-e '/^init.o/d' \
|
||||
-e '/^nindy.o/d' \
|
||||
-e '/ttyflush.o/d' \
|
||||
-e '/xdr_ld.o/d' \
|
||||
|
@ -645,12 +642,24 @@ init.c: $(OBS) $(TSOBS)
|
|||
-e 's/\.o/.c/' \
|
||||
-e 's|\([^ ][^ ]*\)|$(srcdir)/\1|g' | \
|
||||
while read f; do grep '^_initialize_[a-z_0-9A-Z]* *(' $$f 2>/dev/null; done | \
|
||||
sed -e 's/^.*://' -e 's/^\([a-z_0-9A-Z]*\).*/ {extern void \1 PARAMS ((void)); \1 ();}/' >>init.c-tmp
|
||||
sed -e 's/^.*://' -e 's/^\([a-z_0-9A-Z]*\).*/\1/' > init.l-tmp
|
||||
@echo '/* Do not modify this file. */' >>init.c-tmp
|
||||
@echo '/* It is created automatically by the Makefile. */'>>init.c-tmp
|
||||
@echo '#include "defs.h"' >>init.c-tmp
|
||||
@echo '#include "call-cmds.h"' >>init.c-tmp
|
||||
@sed -e 's/\(.*\)/extern initialize_file_ftype \1;/' <init.l-tmp >>init.c-tmp
|
||||
@echo 'void' >>init.c-tmp
|
||||
@echo 'initialize_all_files (void)' >>init.c-tmp
|
||||
@echo '{' >>init.c-tmp
|
||||
@sed -e 's/\(.*\)/ \1 ();/' <init.l-tmp >>init.c-tmp
|
||||
@echo '}' >>init.c-tmp
|
||||
@rm init.l-tmp
|
||||
@mv init.c-tmp init.c
|
||||
|
||||
.PRECIOUS: init.c
|
||||
|
||||
init.o: init.c $(defs_h) $(call_cmds_h)
|
||||
|
||||
# Removing the old gdb first works better if it is running, at least on SunOS.
|
||||
gdb$(EXEEXT): main.o libgdb.a $(ADD_DEPS) $(CDEPS) $(TDEPLIBS)
|
||||
rm -f gdb$(EXEEXT)
|
||||
|
@ -755,7 +764,7 @@ tags: TAGS
|
|||
|
||||
clean mostlyclean:
|
||||
@$(MAKE) $(FLAGS_TO_PASS) DO=clean "DODIRS=$(SUBDIRS)" subdir_do
|
||||
rm -f *.o *.a $(ADD_FILES) *~ init.c-tmp
|
||||
rm -f *.o *.a $(ADD_FILES) *~ init.c-tmp init.l-tmp
|
||||
rm -f init.c version.c
|
||||
rm -f gdb$(EXEEXT) core make.log
|
||||
rm -f gdb[0-9]$(EXEEXT)
|
||||
|
@ -1127,7 +1136,8 @@ eval.o: eval.c $(bfd_h) $(defs_h) $(expression_h) $(frame_h) \
|
|||
event-loop.o: event-loop.c $(defs_h) $(top_h) $(event_loop_h) $(event_top_h)
|
||||
|
||||
event-top.o: event-top.c top.h $(readline_headers) \
|
||||
$(defs_h) $(inferior_h) $(event_loop_h) $(event_top_h) terminal.h $(gdbcmd_h)
|
||||
$(defs_h) $(inferior_h) $(event_loop_h) $(event_top_h) terminal.h \
|
||||
$(gdbcmd_h)
|
||||
|
||||
exec.o: exec.c $(defs_h) $(gdbcmd_h) $(gdbcore_h) $(inferior_h) \
|
||||
target.h language.h gdb_string.h
|
||||
|
@ -1699,5 +1709,4 @@ m2-exp.tab.o: m2-exp.tab.c $(defs_h) $(expression_h) $(gdbtypes_h) \
|
|||
|
||||
gdb-events.o: gdb-events.c gdb-events.h $(defs_h) $(gdbcmd_h)
|
||||
|
||||
|
||||
### end of the gdb Makefile.in.
|
||||
|
|
37
gdb/ax-gdb.c
37
gdb/ax-gdb.c
|
@ -31,10 +31,11 @@
|
|||
#include "ax.h"
|
||||
#include "ax-gdb.h"
|
||||
|
||||
/* Probably the best way to read this file is to start with the types
|
||||
and enums in ax-gdb.h, and then look at gen_expr, towards the
|
||||
bottom; that's the main function that looks at the GDB expressions
|
||||
and calls everything else to generate code.
|
||||
/* To make sense of this file, you should read doc/agentexpr.texi.
|
||||
Then look at the types and enums in ax-gdb.h. For the code itself,
|
||||
look at gen_expr, towards the bottom; that's the main function that
|
||||
looks at the GDB expressions and calls everything else to generate
|
||||
code.
|
||||
|
||||
I'm beginning to wonder whether it wouldn't be nicer to internally
|
||||
generate trees, with types, and then spit out the bytecode in
|
||||
|
@ -439,7 +440,7 @@ gen_fetch (ax, type)
|
|||
implementing something we should be (this code's fault).
|
||||
In any case, it's a bug the user shouldn't see. */
|
||||
default:
|
||||
error ("GDB bug: ax-gdb.c (gen_fetch): strange size");
|
||||
internal_error ("ax-gdb.c (gen_fetch): strange size");
|
||||
}
|
||||
|
||||
gen_sign_extend (ax, type);
|
||||
|
@ -450,7 +451,7 @@ gen_fetch (ax, type)
|
|||
pointer (other code's fault), or we're not implementing
|
||||
something we should be (this code's fault). In any case,
|
||||
it's a bug the user shouldn't see. */
|
||||
error ("GDB bug: ax-gdb.c (gen_fetch): bad type code");
|
||||
internal_error ("ax-gdb.c (gen_fetch): bad type code");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -571,7 +572,7 @@ gen_var_ref (ax, value, var)
|
|||
break;
|
||||
|
||||
case LOC_CONST_BYTES:
|
||||
error ("GDB bug: ax-gdb.c (gen_var_ref): LOC_CONST_BYTES symbols are not supported");
|
||||
internal_error ("ax-gdb.c (gen_var_ref): LOC_CONST_BYTES symbols are not supported");
|
||||
|
||||
/* Variable at a fixed location in memory. Easy. */
|
||||
case LOC_STATIC:
|
||||
|
@ -1162,7 +1163,7 @@ gen_deref (ax, value)
|
|||
/* The caller should check the type, because several operators use
|
||||
this, and we don't know what error message to generate. */
|
||||
if (value->type->code != TYPE_CODE_PTR)
|
||||
error ("GDB bug: ax-gdb.c (gen_deref): expected a pointer");
|
||||
internal_error ("ax-gdb.c (gen_deref): expected a pointer");
|
||||
|
||||
/* We've got an rvalue now, which is a pointer. We want to yield an
|
||||
lvalue, whose address is exactly that pointer. So we don't
|
||||
|
@ -1221,7 +1222,7 @@ find_field (type, name)
|
|||
|
||||
/* Make sure this isn't C++. */
|
||||
if (TYPE_N_BASECLASSES (type) != 0)
|
||||
error ("GDB bug: ax-gdb.c (find_field): derived classes supported");
|
||||
internal_error ("ax-gdb.c (find_field): derived classes supported");
|
||||
|
||||
for (i = 0; i < TYPE_NFIELDS (type); i++)
|
||||
{
|
||||
|
@ -1231,7 +1232,7 @@ find_field (type, name)
|
|||
return i;
|
||||
|
||||
if (this_name[0] == '\0')
|
||||
error ("GDB bug: ax-gdb.c (find_field): anonymous unions not supported");
|
||||
internal_error ("ax-gdb.c (find_field): anonymous unions not supported");
|
||||
}
|
||||
|
||||
error ("Couldn't find member named `%s' in struct/union `%s'",
|
||||
|
@ -1306,7 +1307,7 @@ gen_bitfield_ref (ax, value, type, start, end)
|
|||
|
||||
/* Can we fetch the number of bits requested at all? */
|
||||
if ((end - start) > ((1 << num_ops) * 8))
|
||||
error ("GDB bug: ax-gdb.c (gen_bitfield_ref): bitfield too wide");
|
||||
internal_error ("ax-gdb.c (gen_bitfield_ref): bitfield too wide");
|
||||
|
||||
/* Note that we know here that we only need to try each opcode once.
|
||||
That may not be true on machines with weird byte sizes. */
|
||||
|
@ -1626,7 +1627,7 @@ gen_expr (pc, ax, value)
|
|||
default:
|
||||
/* We should only list operators in the outer case statement
|
||||
that we actually handle in the inner case statement. */
|
||||
error ("GDB bug: ax-gdb.c (gen_expr): op case sets don't match");
|
||||
internal_error ("ax-gdb.c (gen_expr): op case sets don't match");
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1701,7 +1702,7 @@ gen_expr (pc, ax, value)
|
|||
the given type, and dereference it. */
|
||||
if (value->kind != axs_rvalue)
|
||||
/* This would be weird. */
|
||||
error ("GDB bug: ax-gdb.c (gen_expr): OP_MEMVAL operand isn't an rvalue???");
|
||||
internal_error ("ax-gdb.c (gen_expr): OP_MEMVAL operand isn't an rvalue???");
|
||||
value->type = type;
|
||||
value->kind = axs_lvalue_memory;
|
||||
}
|
||||
|
@ -1769,7 +1770,7 @@ gen_expr (pc, ax, value)
|
|||
else
|
||||
/* If this `if' chain doesn't handle it, then the case list
|
||||
shouldn't mention it, and we shouldn't be here. */
|
||||
error ("GDB bug: ax-gdb.c (gen_expr): unhandled struct case");
|
||||
internal_error ("ax-gdb.c (gen_expr): unhandled struct case");
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1783,7 +1784,6 @@ gen_expr (pc, ax, value)
|
|||
|
||||
|
||||
|
||||
#if 0 /* not used */
|
||||
/* Generating bytecode from GDB expressions: driver */
|
||||
|
||||
/* Given a GDB expression EXPR, produce a string of agent bytecode
|
||||
|
@ -1795,7 +1795,7 @@ expr_to_agent (expr, value)
|
|||
struct axs_value *value;
|
||||
{
|
||||
struct cleanup *old_chain = 0;
|
||||
struct agent_expr *ax = new_agent_expr ();
|
||||
struct agent_expr *ax = new_agent_expr (0);
|
||||
union exp_element *pc;
|
||||
|
||||
old_chain = make_cleanup ((make_cleanup_func) free_agent_expr, ax);
|
||||
|
@ -1812,6 +1812,7 @@ expr_to_agent (expr, value)
|
|||
}
|
||||
|
||||
|
||||
#if 0 /* not used */
|
||||
/* Given a GDB expression EXPR denoting an lvalue in memory, produce a
|
||||
string of agent bytecode which will leave its address and size on
|
||||
the top of stack. Return the agent expression.
|
||||
|
@ -1836,7 +1837,7 @@ expr_to_address_and_size (expr)
|
|||
|
||||
return ax;
|
||||
}
|
||||
#endif /* 0 */
|
||||
#endif
|
||||
|
||||
/* Given a GDB expression EXPR, return bytecode to trace its value.
|
||||
The result will use the `trace' and `trace_quick' bytecodes to
|
||||
|
@ -1909,7 +1910,7 @@ agent_command (exp, from_tty)
|
|||
struct cleanup *old_chain = 0;
|
||||
struct expression *expr;
|
||||
struct agent_expr *agent;
|
||||
struct frame_info *fi = get_current_frame (); /* need current scope */
|
||||
struct frame_info *fi = get_current_frame (); /* need current scope */
|
||||
|
||||
/* We don't deal with overlay debugging at the moment. We need to
|
||||
think more carefully about this. If you copy this code into
|
||||
|
|
|
@ -2155,7 +2155,8 @@ bpstat_stop_status (pc, not_a_breakpoint)
|
|||
char message[sizeof (message1) + 30 /* slop */ ];
|
||||
|
||||
/* Get the address where the breakpoint would have been. */
|
||||
bp_addr = *pc - DECR_PC_AFTER_BREAK;
|
||||
bp_addr = *pc - (not_a_breakpoint && !SOFTWARE_SINGLE_STEP_P ?
|
||||
0 : DECR_PC_AFTER_BREAK);
|
||||
|
||||
ALL_BREAKPOINTS_SAFE (b, temp)
|
||||
{
|
||||
|
@ -2184,13 +2185,6 @@ bpstat_stop_status (pc, not_a_breakpoint)
|
|||
&& b->address != (*pc - DECR_PC_AFTER_HW_BREAK))
|
||||
continue;
|
||||
|
||||
if (b->type != bp_watchpoint
|
||||
&& b->type != bp_hardware_watchpoint
|
||||
&& b->type != bp_read_watchpoint
|
||||
&& b->type != bp_access_watchpoint
|
||||
&& not_a_breakpoint)
|
||||
continue;
|
||||
|
||||
/* Is this a catchpoint of a load or unload? If so, did we
|
||||
get a load or unload of the specified library? If not,
|
||||
ignore it. */
|
||||
|
@ -4757,7 +4751,7 @@ until_break_command (arg, from_tty)
|
|||
|
||||
breakpoint = set_momentary_breakpoint (sal, selected_frame, bp_until);
|
||||
|
||||
if (!async_p || !target_has_async)
|
||||
if (!event_loop_p || !target_can_async_p ())
|
||||
old_chain = make_cleanup ((make_cleanup_func) delete_breakpoint,
|
||||
breakpoint);
|
||||
else
|
||||
|
@ -4770,7 +4764,7 @@ until_break_command (arg, from_tty)
|
|||
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)
|
||||
if (event_loop_p && target_can_async_p ())
|
||||
{
|
||||
/* In this case we don't need args for the continuation, because
|
||||
all it needs to do is do the cleanups in the
|
||||
|
@ -4786,7 +4780,7 @@ until_break_command (arg, from_tty)
|
|||
sal = find_pc_line (prev_frame->pc, 0);
|
||||
sal.pc = prev_frame->pc;
|
||||
breakpoint = set_momentary_breakpoint (sal, prev_frame, bp_until);
|
||||
if (!async_p || !target_has_async)
|
||||
if (!event_loop_p || !target_can_async_p ())
|
||||
make_cleanup ((make_cleanup_func) delete_breakpoint, breakpoint);
|
||||
else
|
||||
make_exec_cleanup ((make_cleanup_func) delete_breakpoint, breakpoint);
|
||||
|
@ -4795,7 +4789,7 @@ until_break_command (arg, from_tty)
|
|||
proceed (-1, TARGET_SIGNAL_DEFAULT, 0);
|
||||
/* 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)
|
||||
if (!event_loop_p || !target_can_async_p ())
|
||||
do_cleanups (old_chain);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,23 @@
|
|||
#if !defined (COMMAND_H)
|
||||
#define COMMAND_H 1
|
||||
|
||||
/* Command classes are top-level categories into which commands are broken
|
||||
down for "help" purposes.
|
||||
Notes on classes: class_alias is for alias commands which are not
|
||||
abbreviations of the original command. class-pseudo is for
|
||||
commands which are not really commands nor help topics ("stop"). */
|
||||
|
||||
enum command_class
|
||||
{
|
||||
/* Special args to help_list */
|
||||
class_deprecated, all_classes = -2, all_commands = -1,
|
||||
/* Classes of commands */
|
||||
no_class = -1, class_run = 0, class_vars, class_stack,
|
||||
class_files, class_support, class_info, class_breakpoint, class_trace,
|
||||
class_alias, class_obscure, class_user, class_maintenance,
|
||||
class_pseudo, class_tui, class_xdb,
|
||||
};
|
||||
|
||||
/* Not a set/show command. Note that some commands which begin with
|
||||
"set" or "show" might be in this category, if their syntax does
|
||||
not fall into one of the following categories. */
|
||||
|
|
|
@ -84,18 +84,18 @@ complain (struct complaint *complaint,...)
|
|||
/* Isolated messages, must be self-explanatory. */
|
||||
case 0:
|
||||
begin_line ();
|
||||
puts_filtered ("During symbol reading, ");
|
||||
fputs_filtered ("During symbol reading, ", gdb_stderr);
|
||||
wrap_here ("");
|
||||
vprintf_filtered (complaint->message, args);
|
||||
puts_filtered (".\n");
|
||||
vfprintf_filtered (gdb_stderr, complaint->message, args);
|
||||
fputs_filtered (".\n", gdb_stderr);
|
||||
break;
|
||||
|
||||
/* First of a series, without `set verbose'. */
|
||||
case 1:
|
||||
begin_line ();
|
||||
puts_filtered ("During symbol reading...");
|
||||
vprintf_filtered (complaint->message, args);
|
||||
puts_filtered ("...");
|
||||
fputs_filtered ("During symbol reading...", gdb_stderr);
|
||||
vfprintf_filtered (gdb_stderr, complaint->message, args);
|
||||
fputs_filtered ("...", gdb_stderr);
|
||||
wrap_here ("");
|
||||
complaint_series++;
|
||||
break;
|
||||
|
@ -104,14 +104,14 @@ complain (struct complaint *complaint,...)
|
|||
(We'll already have produced a "Reading in symbols for XXX..."
|
||||
message and will clean up at the end with a newline.) */
|
||||
default:
|
||||
vprintf_filtered (complaint->message, args);
|
||||
puts_filtered ("...");
|
||||
vfprintf_filtered (gdb_stderr, complaint->message, args);
|
||||
fputs_filtered ("...", gdb_stderr);
|
||||
wrap_here ("");
|
||||
}
|
||||
/* If GDB dumps core, we'd like to see the complaints first. Presumably
|
||||
GDB will not be sending so many complaints that this becomes a
|
||||
performance hog. */
|
||||
gdb_flush (gdb_stdout);
|
||||
gdb_flush (gdb_stderr);
|
||||
va_end (args);
|
||||
}
|
||||
|
||||
|
|
26
gdb/defs.h
26
gdb/defs.h
|
@ -165,23 +165,6 @@ extern void quit PARAMS ((void));
|
|||
}
|
||||
#endif
|
||||
|
||||
/* Command classes are top-level categories into which commands are broken
|
||||
down for "help" purposes.
|
||||
Notes on classes: class_alias is for alias commands which are not
|
||||
abbreviations of the original command. class-pseudo is for commands
|
||||
which are not really commands nor help topics ("stop"). */
|
||||
|
||||
enum command_class
|
||||
{
|
||||
/* Special args to help_list */
|
||||
all_classes = -2, all_commands = -1,
|
||||
/* Classes of commands */
|
||||
no_class = -1, class_run = 0, class_vars, class_stack,
|
||||
class_files, class_support, class_info, class_breakpoint, class_trace,
|
||||
class_alias, class_obscure, class_user, class_maintenance,
|
||||
class_pseudo, class_tui, class_xdb
|
||||
};
|
||||
|
||||
/* Languages represented in the symbol table and elsewhere.
|
||||
This should probably be in language.h, but since enum's can't
|
||||
be forward declared to satisfy opaque references before their
|
||||
|
@ -303,9 +286,11 @@ extern void do_final_cleanups PARAMS ((struct cleanup *));
|
|||
extern void do_my_cleanups PARAMS ((struct cleanup **, struct cleanup *));
|
||||
extern void do_run_cleanups PARAMS ((struct cleanup *));
|
||||
extern void do_exec_cleanups PARAMS ((struct cleanup *));
|
||||
extern void do_exec_error_cleanups PARAMS ((struct cleanup *));
|
||||
|
||||
extern void discard_cleanups PARAMS ((struct cleanup *));
|
||||
extern void discard_final_cleanups PARAMS ((struct cleanup *));
|
||||
extern void discard_exec_error_cleanups PARAMS ((struct cleanup *));
|
||||
extern void discard_my_cleanups PARAMS ((struct cleanup **, struct cleanup *));
|
||||
|
||||
typedef void (*make_cleanup_func) PARAMS ((void *));
|
||||
|
@ -322,6 +307,7 @@ extern struct cleanup *make_my_cleanup PARAMS ((struct cleanup **,
|
|||
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 *make_exec_error_cleanup PARAMS ((make_cleanup_func, void *));
|
||||
|
||||
extern struct cleanup *save_cleanups PARAMS ((void));
|
||||
extern struct cleanup *save_final_cleanups PARAMS ((void));
|
||||
|
@ -552,6 +538,8 @@ extern void symbol_file_command PARAMS ((char *, int));
|
|||
|
||||
/* From top.c */
|
||||
|
||||
typedef void initialize_file_ftype (void);
|
||||
|
||||
extern char *skip_quoted PARAMS ((char *));
|
||||
|
||||
extern char *gdb_readline PARAMS ((char *));
|
||||
|
@ -1146,7 +1134,7 @@ struct cmd_list_element;
|
|||
|
||||
/* Should the asynchronous variant of the interpreter (using the
|
||||
event-loop) be enabled? */
|
||||
extern int async_p;
|
||||
extern int event_loop_p;
|
||||
|
||||
extern void (*init_ui_hook) PARAMS ((char *argv0));
|
||||
extern void (*command_loop_hook) PARAMS ((void));
|
||||
|
@ -1173,6 +1161,8 @@ extern void (*context_hook) PARAMS ((int));
|
|||
extern int (*target_wait_hook) PARAMS ((int pid,
|
||||
struct target_waitstatus *status));
|
||||
|
||||
extern void (*attach_hook) PARAMS ((void));
|
||||
extern void (*detach_hook) PARAMS ((void));
|
||||
extern void (*call_command_hook) PARAMS ((struct cmd_list_element *c,
|
||||
char *cmd, int from_tty));
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
extern void _initialize_elfread PARAMS ((void));
|
||||
|
||||
/* The struct elfinfo is available only during ELF symbol table and
|
||||
psymtab reading. It is destroyed at the complation of psymtab-reading.
|
||||
psymtab reading. It is destroyed at the completion of psymtab-reading.
|
||||
It's local to elf_symfile_read. */
|
||||
|
||||
struct elfinfo
|
||||
|
|
139
gdb/event-loop.c
139
gdb/event-loop.c
|
@ -23,7 +23,7 @@
|
|||
#include "top.h"
|
||||
#include "event-loop.h"
|
||||
#include "event-top.h"
|
||||
#include "inferior.h" /* For fetch_inferior_event. */
|
||||
#include "inferior.h" /* For fetch_inferior_event. */
|
||||
#ifdef HAVE_POLL
|
||||
#include <poll.h>
|
||||
#else
|
||||
|
@ -103,9 +103,9 @@ typedef struct file_handler
|
|||
int mask; /* Events we want to monitor: POLLIN, etc. */
|
||||
int ready_mask; /* Events that have been seen since
|
||||
the last time. */
|
||||
handler_func *proc; /* Procedure to call when fd is ready. */
|
||||
handler_func *proc; /* Procedure to call when fd is ready. */
|
||||
gdb_client_data client_data; /* Argument to pass to proc. */
|
||||
int error; /* Was an error detected on this fd? */
|
||||
int error; /* Was an error detected on this fd? */
|
||||
struct file_handler *next_file; /* Next registered file descriptor. */
|
||||
}
|
||||
file_handler;
|
||||
|
@ -123,7 +123,7 @@ typedef struct async_signal_handler
|
|||
int ready; /* If ready, call this handler from the main event loop,
|
||||
using invoke_async_handler. */
|
||||
struct async_signal_handler *next_handler; /* Ptr to next handler */
|
||||
sig_handler_func *proc; /* Function to call to do the work */
|
||||
sig_handler_func *proc; /* Function to call to do the work */
|
||||
gdb_client_data client_data; /* Argument to async_handler_func */
|
||||
}
|
||||
async_signal_handler;
|
||||
|
@ -206,7 +206,7 @@ static struct
|
|||
|
||||
/* Flag to tell whether the timeout struct should be used. */
|
||||
int timeout_valid;
|
||||
}
|
||||
}
|
||||
gdb_notifier;
|
||||
|
||||
#endif /* HAVE_POLL */
|
||||
|
@ -218,13 +218,13 @@ struct gdb_timer
|
|||
struct timeval when;
|
||||
int timer_id;
|
||||
struct gdb_timer *next;
|
||||
timer_handler_func *proc; /* Function to call to do the work */
|
||||
gdb_client_data client_data; /* Argument to async_handler_func */
|
||||
timer_handler_func *proc; /* Function to call to do the work */
|
||||
gdb_client_data client_data; /* Argument to async_handler_func */
|
||||
}
|
||||
gdb_timer;
|
||||
|
||||
/* List of currently active timers. It is sorted in order of
|
||||
increasing timers.*/
|
||||
increasing timers. */
|
||||
static struct
|
||||
{
|
||||
/* Pointer to first in timer list. */
|
||||
|
@ -253,17 +253,18 @@ sighandler_list;
|
|||
function. */
|
||||
static int async_handler_ready = 0;
|
||||
|
||||
static void create_file_handler (int fd, int mask, handler_func *proc, gdb_client_data client_data);
|
||||
static void create_file_handler (int fd, int mask, handler_func * proc, gdb_client_data client_data);
|
||||
static void invoke_async_signal_handler (void);
|
||||
static void handle_file_event (int event_file_desc);
|
||||
static int gdb_wait_for_event (void);
|
||||
static int gdb_do_one_event (void);
|
||||
static int check_async_ready (void);
|
||||
static void async_queue_event (gdb_event *event_ptr, queue_position position);
|
||||
static gdb_event * create_file_event (int fd);
|
||||
static void async_queue_event (gdb_event * event_ptr, queue_position position);
|
||||
static gdb_event *create_file_event (int fd);
|
||||
static int process_event (void);
|
||||
static void handle_timer_event (int dummy);
|
||||
static void poll_timers (void);
|
||||
static int fetch_inferior_event_wrapper (gdb_client_data client_data);
|
||||
|
||||
|
||||
/* Insert an event object into the gdb event queue at
|
||||
|
@ -277,7 +278,7 @@ static void poll_timers (void);
|
|||
as last in first out. Event appended at the tail of the queue
|
||||
will be processed first in first out. */
|
||||
static void
|
||||
async_queue_event (gdb_event *event_ptr, queue_position position)
|
||||
async_queue_event (gdb_event * event_ptr, queue_position position)
|
||||
{
|
||||
if (position == TAIL)
|
||||
{
|
||||
|
@ -407,7 +408,7 @@ gdb_do_one_event (void)
|
|||
break;
|
||||
}
|
||||
|
||||
/* Are any timers that are ready? If so, put an event on the queue.*/
|
||||
/* Are any timers that are ready? If so, put an event on the queue. */
|
||||
poll_timers ();
|
||||
|
||||
/* Wait for a new event. If gdb_wait_for_event returns -1,
|
||||
|
@ -470,7 +471,7 @@ start_event_loop (void)
|
|||
doesn't have to know implementation details about the use of poll
|
||||
vs. select. */
|
||||
void
|
||||
add_file_handler (int fd, handler_func *proc, gdb_client_data client_data)
|
||||
add_file_handler (int fd, handler_func * proc, gdb_client_data client_data)
|
||||
{
|
||||
#ifdef HAVE_POLL
|
||||
create_file_handler (fd, POLLIN, proc, client_data);
|
||||
|
@ -490,7 +491,7 @@ add_file_handler (int fd, handler_func *proc, gdb_client_data client_data)
|
|||
PROC is the procedure that will be called when an event occurs for
|
||||
FD. CLIENT_DATA is the argument to pass to PROC. */
|
||||
static void
|
||||
create_file_handler (int fd, int mask, handler_func *proc, gdb_client_data client_data)
|
||||
create_file_handler (int fd, int mask, handler_func * proc, gdb_client_data client_data)
|
||||
{
|
||||
file_handler *file_ptr;
|
||||
|
||||
|
@ -508,7 +509,7 @@ create_file_handler (int fd, int mask, handler_func *proc, gdb_client_data clien
|
|||
}
|
||||
|
||||
/* It is a new file descriptor. Add it to the list. Otherwise, just
|
||||
change the data associated with it.*/
|
||||
change the data associated with it. */
|
||||
if (file_ptr == NULL)
|
||||
{
|
||||
file_ptr = (file_handler *) xmalloc (sizeof (file_handler));
|
||||
|
@ -703,16 +704,16 @@ handle_file_event (int event_file_desc)
|
|||
if (error_mask_returned != 0)
|
||||
{
|
||||
/* Work in progress. We may need to tell somebody what
|
||||
kind of error we had. */
|
||||
kind of error we had. */
|
||||
/*if (error_mask_returned & POLLHUP)
|
||||
printf_unfiltered ("Hangup detected on fd %d\n", file_ptr->fd);
|
||||
if (error_mask_returned & POLLERR)
|
||||
printf_unfiltered ("Error detected on fd %d\n", file_ptr->fd);
|
||||
if (error_mask_returned & POLLNVAL)
|
||||
printf_unfiltered ("Invalid fd %d\n", file_ptr->fd);*/
|
||||
printf_unfiltered ("Hangup detected on fd %d\n", file_ptr->fd);
|
||||
if (error_mask_returned & POLLERR)
|
||||
printf_unfiltered ("Error detected on fd %d\n", file_ptr->fd);
|
||||
if (error_mask_returned & POLLNVAL)
|
||||
printf_unfiltered ("Invalid fd %d\n", file_ptr->fd); */
|
||||
file_ptr->error = 1;
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
file_ptr->error = 0;
|
||||
#else /* ! HAVE_POLL */
|
||||
if (file_ptr->ready_mask & GDB_EXCEPTION)
|
||||
|
@ -764,12 +765,12 @@ gdb_wait_for_event (void)
|
|||
|
||||
#ifdef HAVE_POLL
|
||||
num_found =
|
||||
poll (gdb_notifier.poll_fds,
|
||||
(unsigned long) gdb_notifier.num_fds,
|
||||
poll (gdb_notifier.poll_fds,
|
||||
(unsigned long) gdb_notifier.num_fds,
|
||||
gdb_notifier.timeout_valid ? gdb_notifier.timeout : -1);
|
||||
|
||||
/* Don't print anything if we get out of poll because of a
|
||||
signal.*/
|
||||
signal. */
|
||||
if (num_found == -1 && errno != EINTR)
|
||||
perror_with_name ("Poll");
|
||||
|
||||
|
@ -780,8 +781,8 @@ gdb_wait_for_event (void)
|
|||
num_found = select (gdb_notifier.num_fds,
|
||||
(SELECT_MASK *) & gdb_notifier.ready_masks[0],
|
||||
(SELECT_MASK *) & gdb_notifier.ready_masks[MASK_SIZE],
|
||||
(SELECT_MASK *) & gdb_notifier.ready_masks[2 * MASK_SIZE],
|
||||
gdb_notifier.timeout_valid ? gdb_notifier.timeout : NULL);
|
||||
(SELECT_MASK *) & gdb_notifier.ready_masks[2 * MASK_SIZE],
|
||||
gdb_notifier.timeout_valid ? &gdb_notifier.timeout : NULL);
|
||||
|
||||
/* Clear the masks after an error from select. */
|
||||
if (num_found == -1)
|
||||
|
@ -871,7 +872,7 @@ gdb_wait_for_event (void)
|
|||
PROC is the function to call with CLIENT_DATA argument
|
||||
whenever the handler is invoked. */
|
||||
async_signal_handler *
|
||||
create_async_signal_handler (sig_handler_func *proc, gdb_client_data client_data)
|
||||
create_async_signal_handler (sig_handler_func * proc, gdb_client_data client_data)
|
||||
{
|
||||
async_signal_handler *async_handler_ptr;
|
||||
|
||||
|
@ -894,7 +895,7 @@ create_async_signal_handler (sig_handler_func *proc, gdb_client_data client_data
|
|||
some event. The caller of this function is the interrupt handler
|
||||
associated with a signal. */
|
||||
void
|
||||
mark_async_signal_handler (async_signal_handler *async_handler_ptr)
|
||||
mark_async_signal_handler (async_signal_handler * async_handler_ptr)
|
||||
{
|
||||
((async_signal_handler *) async_handler_ptr)->ready = 1;
|
||||
async_handler_ready = 1;
|
||||
|
@ -933,7 +934,7 @@ invoke_async_signal_handler (void)
|
|||
/* Delete an asynchronous handler (ASYNC_HANDLER_PTR).
|
||||
Free the space allocated for it. */
|
||||
void
|
||||
delete_async_signal_handler (async_signal_handler **async_handler_ptr)
|
||||
delete_async_signal_handler (async_signal_handler ** async_handler_ptr)
|
||||
{
|
||||
async_signal_handler *prev_ptr;
|
||||
|
||||
|
@ -975,18 +976,36 @@ inferior_event_handler (int error, gdb_client_data client_data, int fd)
|
|||
{
|
||||
printf_unfiltered ("error detected on fd %d\n", fd);
|
||||
delete_file_handler (fd);
|
||||
pop_target ();
|
||||
discard_all_continuations ();
|
||||
}
|
||||
else
|
||||
fetch_inferior_event (client_data);
|
||||
/* Use catch errors for now, until the inner layers of
|
||||
fetch_inferior_event (i.e. readchar) can return meaningful
|
||||
error status. If an error occurs while getting an event from
|
||||
the target, just get rid of the target. */
|
||||
if (!catch_errors (fetch_inferior_event_wrapper, client_data, "", RETURN_MASK_ALL))
|
||||
{
|
||||
delete_file_handler (fd);
|
||||
discard_all_continuations ();
|
||||
pop_target ();
|
||||
display_gdb_prompt (0);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
fetch_inferior_event_wrapper (gdb_client_data client_data)
|
||||
{
|
||||
fetch_inferior_event (client_data);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Create a timer that will expire in MILLISECONDS from now. When the
|
||||
timer is ready, PROC will be executed. At creation, the timer is
|
||||
aded to the timers queue. This queue is kept sorted in order of
|
||||
increasing timers. Return a handle to the timer struct.*/
|
||||
increasing timers. Return a handle to the timer struct. */
|
||||
int
|
||||
create_timer (int milliseconds, timer_handler_func *proc, gdb_client_data client_data)
|
||||
create_timer (int milliseconds, timer_handler_func * proc, gdb_client_data client_data)
|
||||
{
|
||||
struct gdb_timer *timer_ptr, *timer_index, *prev_timer;
|
||||
struct timeval time_now, delta;
|
||||
|
@ -994,39 +1013,39 @@ create_timer (int milliseconds, timer_handler_func *proc, gdb_client_data client
|
|||
/* compute seconds */
|
||||
delta.tv_sec = milliseconds / 1000;
|
||||
/* compute microseconds */
|
||||
delta.tv_usec = (milliseconds % 1000) * 1000;
|
||||
|
||||
delta.tv_usec = (milliseconds % 1000) * 1000;
|
||||
|
||||
gettimeofday (&time_now, NULL);
|
||||
|
||||
timer_ptr = (struct gdb_timer *) xmalloc (sizeof (gdb_timer));
|
||||
timer_ptr->when.tv_sec = time_now.tv_sec + delta.tv_sec;
|
||||
timer_ptr->when.tv_usec = time_now.tv_usec + delta.tv_usec;
|
||||
/* carry? */
|
||||
if (timer_ptr->when.tv_usec >= 1000000 )
|
||||
if (timer_ptr->when.tv_usec >= 1000000)
|
||||
{
|
||||
timer_ptr->when.tv_sec += 1;
|
||||
timer_ptr->when.tv_usec -= 1000000;
|
||||
}
|
||||
timer_ptr->proc = proc;
|
||||
timer_ptr->client_data = client_data;
|
||||
timer_list.num_timers ++;
|
||||
timer_list.num_timers++;
|
||||
timer_ptr->timer_id = timer_list.num_timers;
|
||||
|
||||
/* Now add the timer to the timer queue, making sure it is sorted in
|
||||
increasing order of expiration. */
|
||||
|
||||
for (timer_index = timer_list.first_timer;
|
||||
timer_index != NULL;
|
||||
for (timer_index = timer_list.first_timer;
|
||||
timer_index != NULL;
|
||||
timer_index = timer_index->next)
|
||||
{
|
||||
/* If the seconds field is greater or if it is the same, but the
|
||||
microsecond field is greater. */
|
||||
if ((timer_index->when.tv_sec > timer_ptr->when.tv_sec) ||
|
||||
if ((timer_index->when.tv_sec > timer_ptr->when.tv_sec) ||
|
||||
((timer_index->when.tv_sec == timer_ptr->when.tv_sec)
|
||||
&& (timer_index->when.tv_usec > timer_ptr->when.tv_usec)))
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (timer_index == timer_list.first_timer)
|
||||
{
|
||||
timer_ptr->next = timer_list.first_timer;
|
||||
|
@ -1035,11 +1054,11 @@ create_timer (int milliseconds, timer_handler_func *proc, gdb_client_data client
|
|||
}
|
||||
else
|
||||
{
|
||||
for (prev_timer = timer_list.first_timer;
|
||||
prev_timer->next != timer_index;
|
||||
for (prev_timer = timer_list.first_timer;
|
||||
prev_timer->next != timer_index;
|
||||
prev_timer = prev_timer->next)
|
||||
;
|
||||
|
||||
|
||||
prev_timer->next = timer_ptr;
|
||||
timer_ptr->next = timer_index;
|
||||
}
|
||||
|
@ -1085,20 +1104,20 @@ delete_timer (int id)
|
|||
/* When a timer event is put on the event queue, it will be handled by
|
||||
this function. Just call the assiciated procedure and delete the
|
||||
timer event from the event queue. Repeat this for each timer that
|
||||
has expired.*/
|
||||
has expired. */
|
||||
static void
|
||||
handle_timer_event (int dummy)
|
||||
{
|
||||
struct timeval time_now;
|
||||
struct gdb_timer *timer_ptr, *saved_timer;
|
||||
|
||||
|
||||
gettimeofday (&time_now, NULL);
|
||||
timer_ptr = timer_list.first_timer;
|
||||
|
||||
while (timer_ptr != NULL)
|
||||
{
|
||||
if ((timer_ptr->when.tv_sec > time_now.tv_sec) ||
|
||||
((timer_ptr->when.tv_sec == time_now.tv_sec) &&
|
||||
if ((timer_ptr->when.tv_sec > time_now.tv_sec) ||
|
||||
((timer_ptr->when.tv_sec == time_now.tv_sec) &&
|
||||
(timer_ptr->when.tv_usec > time_now.tv_usec)))
|
||||
break;
|
||||
|
||||
|
@ -1113,19 +1132,19 @@ handle_timer_event (int dummy)
|
|||
|
||||
gdb_notifier.timeout_valid = 0;
|
||||
}
|
||||
|
||||
|
||||
/* Check whether any timers in the timers queue are ready. If at least
|
||||
one timer is ready, stick an event onto the event queue. Even in
|
||||
case more than one timer is ready, one event is enough, because the
|
||||
handle_timer_event() will go through the timers list and call the
|
||||
procedures associated with all that have expired. Update the
|
||||
timeout for the select() or poll() as well.*/
|
||||
timeout for the select() or poll() as well. */
|
||||
static void
|
||||
poll_timers (void)
|
||||
{
|
||||
struct timeval time_now, delta;
|
||||
gdb_event *event_ptr;
|
||||
|
||||
|
||||
if (timer_list.num_timers)
|
||||
{
|
||||
gettimeofday (&time_now, NULL);
|
||||
|
@ -1137,9 +1156,9 @@ poll_timers (void)
|
|||
delta.tv_sec -= 1;
|
||||
delta.tv_usec += 1000000;
|
||||
}
|
||||
|
||||
|
||||
/* Oops it expired already. Tell select / poll to return
|
||||
immediately. */
|
||||
immediately. */
|
||||
if (delta.tv_sec < 0)
|
||||
{
|
||||
delta.tv_sec = 0;
|
||||
|
@ -1155,15 +1174,15 @@ poll_timers (void)
|
|||
}
|
||||
|
||||
/* Now we need to update the timeout for select/ poll, because we
|
||||
don't want to sit there while this timer is expiring. */
|
||||
don't want to sit there while this timer is expiring. */
|
||||
#ifdef HAVE_POLL
|
||||
gdb_notifier.timeout = delta.tv_sec * 1000;
|
||||
gdb_notifier.timeout = delta.tv_sec * 1000;
|
||||
#else
|
||||
gdb_notifier.timeout.sec = delta.tv_sec;
|
||||
gdb_notifier.timeout.usec = delta.tv_usec;
|
||||
gdb_notifier.timeout.tv_sec = delta.tv_sec;
|
||||
gdb_notifier.timeout.tv_usec = delta.tv_usec;
|
||||
#endif
|
||||
gdb_notifier.timeout_valid = 1;
|
||||
}
|
||||
else
|
||||
else
|
||||
gdb_notifier.timeout_valid = 0;
|
||||
}
|
||||
|
|
|
@ -86,15 +86,11 @@ queue_position;
|
|||
|
||||
extern void start_event_loop (void);
|
||||
extern void delete_file_handler (int fd);
|
||||
extern void add_file_handler (int fd, handler_func *proc, gdb_client_data client_data);
|
||||
extern void add_file_handler (int fd, handler_func * proc, gdb_client_data client_data);
|
||||
extern void mark_async_signal_handler (struct async_signal_handler *async_handler_ptr);
|
||||
extern struct async_signal_handler *
|
||||
create_async_signal_handler (sig_handler_func *proc, gdb_client_data client_data);
|
||||
extern void delete_async_signal_handler (struct async_signal_handler ** async_handler_ptr);
|
||||
extern struct async_signal_handler *
|
||||
create_async_signal_handler (sig_handler_func * proc, gdb_client_data client_data);
|
||||
extern void delete_async_signal_handler (struct async_signal_handler **async_handler_ptr);
|
||||
extern void inferior_event_handler (int error, gdb_client_data client_data, int fd);
|
||||
extern int create_timer (int milliseconds, timer_handler_func *proc, gdb_client_data client_data);
|
||||
extern int create_timer (int milliseconds, timer_handler_func * proc, gdb_client_data client_data);
|
||||
extern void delete_timer (int id);
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -244,22 +244,22 @@ display_gdb_prompt (char *new_prompt)
|
|||
char *gdb_prompt = get_prompt ();
|
||||
|
||||
|
||||
if (target_executing && sync_execution)
|
||||
if (target_executing && sync_execution)
|
||||
{
|
||||
/* This is to trick readline into not trying to display the
|
||||
prompt. Even though we display the prompt using this
|
||||
function, readline still tries to do its own display if we
|
||||
don't call rl_callback_handler_install and
|
||||
rl_callback_handler_remove (which readline detects because a
|
||||
global variable is not set). If readline did that, it could
|
||||
mess up gdb signal handlers for SIGINT. Readline assumes
|
||||
that between calls to rl_set_signals and rl_clear_signals gdb
|
||||
doesn't do anything with the signal handlers. Well, that's
|
||||
not the case, because when the target executes we change the
|
||||
SIGINT signal handler. If we allowed readline to display the
|
||||
prompt, the signal handler change would happen exactly
|
||||
between the calls to the above two functions.
|
||||
Calling rl_callback_handler_remove(), does the job. */
|
||||
prompt. Even though we display the prompt using this
|
||||
function, readline still tries to do its own display if we
|
||||
don't call rl_callback_handler_install and
|
||||
rl_callback_handler_remove (which readline detects because a
|
||||
global variable is not set). If readline did that, it could
|
||||
mess up gdb signal handlers for SIGINT. Readline assumes
|
||||
that between calls to rl_set_signals and rl_clear_signals gdb
|
||||
doesn't do anything with the signal handlers. Well, that's
|
||||
not the case, because when the target executes we change the
|
||||
SIGINT signal handler. If we allowed readline to display the
|
||||
prompt, the signal handler change would happen exactly
|
||||
between the calls to the above two functions.
|
||||
Calling rl_callback_handler_remove(), does the job. */
|
||||
|
||||
rl_callback_handler_remove ();
|
||||
return;
|
||||
|
@ -410,10 +410,44 @@ stdin_event_handler (int error, int fd, gdb_client_data client_data)
|
|||
exit (1);
|
||||
}
|
||||
else
|
||||
(*call_readline) (client_data);
|
||||
(*call_readline) (client_data);
|
||||
}
|
||||
|
||||
/* Re-enable stdin after the end of an execution command in
|
||||
synchronous mode, or after an error from the target, and we aborted
|
||||
the exec operation. */
|
||||
|
||||
void
|
||||
async_enable_stdin (void *dummy)
|
||||
{
|
||||
/* See NOTE in async_disable_stdin() */
|
||||
/* FIXME: cagney/1999-09-27: Call this before clearing
|
||||
sync_execution. Current target_terminal_ours() implementations
|
||||
check for sync_execution before switching the terminal. */
|
||||
target_terminal_ours ();
|
||||
pop_prompt ();
|
||||
sync_execution = 0;
|
||||
}
|
||||
|
||||
/* Disable reads from stdin (the console) marking the command as
|
||||
synchronous. */
|
||||
|
||||
void
|
||||
async_disable_stdin (void)
|
||||
{
|
||||
sync_execution = 1;
|
||||
push_prompt ("", "", "");
|
||||
/* FIXME: cagney/1999-09-27: At present this call is technically
|
||||
redundant since infcmd.c and infrun.c both already call
|
||||
target_terminal_inferior(). As the terminal handling (in
|
||||
sync/async mode) is refined, the duplicate calls can be
|
||||
eliminated (Here or in infcmd.c/infrun.c). */
|
||||
target_terminal_inferior ();
|
||||
make_exec_cleanup (async_enable_stdin, NULL);
|
||||
make_exec_error_cleanup (async_enable_stdin, NULL);
|
||||
}
|
||||
|
||||
|
||||
/* Handles a gdb command. This function is called by
|
||||
command_line_handler, which has processed one or more input lines
|
||||
into COMMAND. */
|
||||
|
@ -471,7 +505,7 @@ command_handler (char *command)
|
|||
/* 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)
|
||||
if (target_can_async_p () && target_executing)
|
||||
{
|
||||
arg1 =
|
||||
(struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
|
||||
|
@ -487,7 +521,7 @@ command_handler (char *command)
|
|||
/* 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)
|
||||
if (!target_can_async_p () || !target_executing)
|
||||
{
|
||||
bpstat_do_actions (&stop_bpstat);
|
||||
do_cleanups (old_chain);
|
||||
|
@ -1077,7 +1111,7 @@ set_async_prompt (char *args, int from_tty, struct cmd_list_element *c)
|
|||
void
|
||||
_initialize_event_loop (void)
|
||||
{
|
||||
if (async_p)
|
||||
if (event_loop_p)
|
||||
{
|
||||
/* When a character is detected on instream by select or poll,
|
||||
readline will be invoked via this callback function. */
|
||||
|
|
|
@ -90,6 +90,8 @@ extern void gdb_readline2 (gdb_client_data client_data);
|
|||
extern void mark_async_signal_handler_wrapper (PTR token);
|
||||
extern void async_request_quit (gdb_client_data arg);
|
||||
extern void stdin_event_handler (int error, int fd, gdb_client_data client_data);
|
||||
extern void async_disable_stdin (void);
|
||||
extern void async_enable_stdin (void *dummy);
|
||||
|
||||
/* Exported variables from event-top.c.
|
||||
FIXME: these should really go into top.h. */
|
||||
|
|
|
@ -2254,14 +2254,34 @@ hppa_fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p)
|
|||
|
||||
/* It must also be an import stub. */
|
||||
u = find_unwind_entry (SYMBOL_VALUE (stub_symbol));
|
||||
if (!u
|
||||
|| (u->stub_unwind.stub_type != IMPORT)
|
||||
&& u->stub_unwind.stub_type != IMPORT_SHLIB)
|
||||
if (u == NULL
|
||||
|| (u->stub_unwind.stub_type != IMPORT
|
||||
#ifdef GDB_NATIVE_HPUX_11
|
||||
/* Sigh. The hpux 10.20 dynamic linker will blow
|
||||
chunks if we perform a call to an unbound function
|
||||
via the IMPORT_SHLIB stub. The hpux 11.00 dynamic
|
||||
linker will blow chunks if we do not call the
|
||||
unbound function via the IMPORT_SHLIB stub.
|
||||
|
||||
We currently have no way to select bevahior on just
|
||||
the target. However, we only support HPUX/SOM in
|
||||
native mode. So we conditinalize on a native
|
||||
#ifdef. Ugly. Ugly. Ugly */
|
||||
&& u->stub_unwind.stub_type != IMPORT_SHLIB
|
||||
#endif
|
||||
))
|
||||
continue;
|
||||
|
||||
/* OK. Looks like the correct import stub. */
|
||||
newfun = SYMBOL_VALUE (stub_symbol);
|
||||
fun = newfun;
|
||||
|
||||
/* If we found an IMPORT stub, then we want to stop
|
||||
searching now. If we found an IMPORT_SHLIB, we want
|
||||
to continue the search in the hopes that we will find
|
||||
an IMPORT stub. */
|
||||
if (u->stub_unwind.stub_type == IMPORT)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3671,6 +3691,15 @@ restart:
|
|||
|| (inst & 0xffffc00c) == 0x73c10008)
|
||||
save_sp = 0;
|
||||
|
||||
/* Are we loading some register with an offset from the argument
|
||||
pointer? */
|
||||
if ((inst & 0xffe00000) == 0x37a00000
|
||||
|| (inst & 0xffffffe0) == 0x081d0240)
|
||||
{
|
||||
pc += 4;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Account for general and floating-point register saves. */
|
||||
reg_num = inst_saves_gr (inst);
|
||||
save_gr &= ~(1 << reg_num);
|
||||
|
@ -3685,9 +3714,9 @@ restart:
|
|||
|
||||
FIXME. Can still die if we have a mix of GR and FR argument
|
||||
stores! */
|
||||
if (reg_num >= 23 && reg_num <= 26)
|
||||
if (reg_num >= (TARGET_PTR_BIT == 64 ? 19 : 23) && reg_num <= 26)
|
||||
{
|
||||
while (reg_num >= 23 && reg_num <= 26)
|
||||
while (reg_num >= (TARGET_PTR_BIT == 64 ? 19 : 23) && reg_num <= 26)
|
||||
{
|
||||
pc += 4;
|
||||
status = target_read_memory (pc, buf, 4);
|
||||
|
@ -3714,7 +3743,7 @@ restart:
|
|||
save. */
|
||||
if ((inst & 0xfc000000) == 0x34000000
|
||||
&& inst_saves_fr (next_inst) >= 4
|
||||
&& inst_saves_fr (next_inst) <= 7)
|
||||
&& inst_saves_fr (next_inst) <= (TARGET_PTR_BIT == 64 ? 11 : 7))
|
||||
{
|
||||
/* So we drop into the code below in a reasonable state. */
|
||||
reg_num = inst_saves_fr (next_inst);
|
||||
|
@ -3725,9 +3754,9 @@ restart:
|
|||
This is a kludge as on the HP compiler sets this bit and it
|
||||
never does prologue scheduling. So once we see one, skip past
|
||||
all of them. */
|
||||
if (reg_num >= 4 && reg_num <= 7)
|
||||
if (reg_num >= 4 && reg_num <= (TARGET_PTR_BIT == 64 ? 11 : 7))
|
||||
{
|
||||
while (reg_num >= 4 && reg_num <= 7)
|
||||
while (reg_num >= 4 && reg_num <= (TARGET_PTR_BIT == 64 ? 11 : 7))
|
||||
{
|
||||
pc += 8;
|
||||
status = target_read_memory (pc, buf, 4);
|
||||
|
|
55
gdb/infcmd.c
55
gdb/infcmd.c
|
@ -35,6 +35,7 @@
|
|||
#include "symfile.h"
|
||||
#include "objfiles.h"
|
||||
#include "event-loop.h"
|
||||
#include "event-top.h"
|
||||
#include "parser-defs.h"
|
||||
|
||||
/* Functions exported for general use: */
|
||||
|
@ -280,7 +281,10 @@ Start it from the beginning? "))
|
|||
want them to go away (PR 2207). This is probably reasonable. */
|
||||
|
||||
if (!args)
|
||||
sync_execution = 1;
|
||||
{
|
||||
if (event_loop_p && target_can_async_p ())
|
||||
async_disable_stdin ();
|
||||
}
|
||||
else
|
||||
{
|
||||
char *cmd;
|
||||
|
@ -288,15 +292,15 @@ Start it from the beginning? "))
|
|||
|
||||
/* 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)
|
||||
if (event_loop_p && async_exec && !target_can_async_p ())
|
||||
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)
|
||||
if (event_loop_p && !async_exec && target_can_async_p ())
|
||||
{
|
||||
/* Simulate synchronous execution */
|
||||
sync_execution = 1;
|
||||
async_disable_stdin ();
|
||||
}
|
||||
|
||||
/* If there were other args, beside '&', process them. */
|
||||
|
@ -348,15 +352,15 @@ continue_command (proc_count_exp, from_tty)
|
|||
|
||||
/* If we must run in the background, but the target can't do it,
|
||||
error out. */
|
||||
if (async_p && async_exec && !target_has_async)
|
||||
if (event_loop_p && async_exec && !target_can_async_p ())
|
||||
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)
|
||||
if (event_loop_p && !async_exec && target_can_async_p ())
|
||||
{
|
||||
/* Simulate synchronous execution */
|
||||
sync_execution = 1;
|
||||
async_disable_stdin ();
|
||||
}
|
||||
|
||||
/* If have argument (besides '&'), set proceed count of breakpoint
|
||||
|
@ -451,15 +455,15 @@ step_1 (skip_subroutines, single_inst, 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)
|
||||
if (event_loop_p && async_exec && !target_can_async_p ())
|
||||
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)
|
||||
if (event_loop_p && !async_exec && target_can_async_p ())
|
||||
{
|
||||
/* Simulate synchronous execution */
|
||||
sync_execution = 1;
|
||||
async_disable_stdin ();
|
||||
}
|
||||
|
||||
count = count_string ? parse_and_eval_address (count_string) : 1;
|
||||
|
@ -550,15 +554,15 @@ jump_command (arg, from_tty)
|
|||
|
||||
/* If we must run in the background, but the target can't do it,
|
||||
error out. */
|
||||
if (async_p && async_exec && !target_has_async)
|
||||
if (event_loop_p && async_exec && !target_can_async_p ())
|
||||
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)
|
||||
if (event_loop_p && !async_exec && target_can_async_p ())
|
||||
{
|
||||
/* Simulate synchronous execution */
|
||||
sync_execution = 1;
|
||||
async_disable_stdin ();
|
||||
}
|
||||
|
||||
if (!arg)
|
||||
|
@ -848,15 +852,15 @@ until_command (arg, from_tty)
|
|||
|
||||
/* If we must run in the background, but the target can't do it,
|
||||
error out. */
|
||||
if (async_p && async_exec && !target_has_async)
|
||||
if (event_loop_p && async_exec && !target_can_async_p ())
|
||||
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)
|
||||
if (event_loop_p && !async_exec && target_can_async_p ())
|
||||
{
|
||||
/* Simulate synchronous execution */
|
||||
sync_execution = 1;
|
||||
async_disable_stdin ();
|
||||
}
|
||||
|
||||
if (arg)
|
||||
|
@ -964,15 +968,15 @@ finish_command (arg, from_tty)
|
|||
|
||||
/* If we must run in the background, but the target can't do it,
|
||||
error out. */
|
||||
if (async_p && async_exec && !target_has_async)
|
||||
if (event_loop_p && async_exec && !target_can_async_p ())
|
||||
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)
|
||||
if (event_loop_p && !async_exec && target_can_async_p ())
|
||||
{
|
||||
/* Simulate synchronous execution */
|
||||
sync_execution = 1;
|
||||
async_disable_stdin ();
|
||||
}
|
||||
|
||||
if (arg)
|
||||
|
@ -993,7 +997,7 @@ finish_command (arg, from_tty)
|
|||
|
||||
breakpoint = set_momentary_breakpoint (sal, frame, bp_finish);
|
||||
|
||||
if (!async_p || !target_has_async)
|
||||
if (!event_loop_p || !target_can_async_p ())
|
||||
old_chain = make_cleanup ((make_cleanup_func) delete_breakpoint, breakpoint);
|
||||
else
|
||||
make_exec_cleanup ((make_cleanup_func) delete_breakpoint, breakpoint);
|
||||
|
@ -1014,7 +1018,7 @@ finish_command (arg, from_tty)
|
|||
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)
|
||||
if (event_loop_p && target_can_async_p ())
|
||||
{
|
||||
arg1 =
|
||||
(struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
|
||||
|
@ -1033,7 +1037,7 @@ finish_command (arg, from_tty)
|
|||
/* Do this only if not running asynchronously or if the target
|
||||
cannot do async execution. Otherwise, complete this command when
|
||||
the target actually stops, in fetch_inferior_event. */
|
||||
if (!async_p || !target_has_async)
|
||||
if (!event_loop_p || !target_can_async_p ())
|
||||
{
|
||||
|
||||
/* Did we stop at our breakpoint? */
|
||||
|
@ -1589,6 +1593,9 @@ attach_command (args, from_tty)
|
|||
target_post_attach (inferior_pid);
|
||||
|
||||
normal_stop ();
|
||||
|
||||
if (attach_hook)
|
||||
attach_hook ();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1612,6 +1619,8 @@ detach_command (args, from_tty)
|
|||
#if defined(SOLIB_RESTART)
|
||||
SOLIB_RESTART ();
|
||||
#endif
|
||||
if (detach_hook)
|
||||
detach_hook ();
|
||||
}
|
||||
|
||||
/* Stop the execution of the target while running in async mode, in
|
||||
|
@ -1621,7 +1630,7 @@ interrupt_target_command (args, from_tty)
|
|||
char *args;
|
||||
int from_tty;
|
||||
{
|
||||
if (async_p && target_has_async)
|
||||
if (event_loop_p && target_can_async_p ())
|
||||
{
|
||||
dont_repeat (); /* Not for the faint of heart */
|
||||
target_stop ();
|
||||
|
|
87
gdb/infrun.c
87
gdb/infrun.c
|
@ -36,7 +36,6 @@
|
|||
#include <signal.h>
|
||||
#include "event-loop.h"
|
||||
#include "event-top.h"
|
||||
#include "remote.h" /* For cleanup_sigint_signal_handler. */
|
||||
|
||||
/* Prototypes for local functions */
|
||||
|
||||
|
@ -1070,7 +1069,7 @@ The same program may be running in another process.");
|
|||
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
|
||||
does not support asynchronous execution. */
|
||||
if (!async_p || !target_has_async)
|
||||
if (!event_loop_p || !target_can_async_p ())
|
||||
{
|
||||
wait_for_inferior ();
|
||||
normal_stop ();
|
||||
|
@ -1096,23 +1095,22 @@ start_remote (void)
|
|||
stop_soon_quietly = 1;
|
||||
trap_expected = 0;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
/* Always go on waiting for the target, regardless of the mode. */
|
||||
/* FIXME: cagney/1999-09-23: At present it isn't possible to
|
||||
indicate th wait_for_inferior that a target should timeout if
|
||||
nothing is returned (instead of just blocking). Because of this,
|
||||
targets expecting an immediate response need to, internally, set
|
||||
things up so that the target_wait() is forced to eventually
|
||||
timeout. */
|
||||
/* FIXME: cagney/1999-09-24: It isn't possible for target_open() to
|
||||
differentiate to its caller what the state of the target is after
|
||||
the initial open has been performed. Here we're assuming that
|
||||
the target has stopped. It should be possible to eventually have
|
||||
target_open() return to the caller an indication that the target
|
||||
is currently running and GDB state should be set to the same as
|
||||
for an async run. */
|
||||
wait_for_inferior ();
|
||||
normal_stop ();
|
||||
}
|
||||
|
||||
/* Initialize static vars when a new inferior begins. */
|
||||
|
@ -1588,13 +1586,7 @@ handle_inferior_event (struct execution_control_state *ecs)
|
|||
stop_pc = read_pc_pid (ecs->pid);
|
||||
ecs->saved_inferior_pid = inferior_pid;
|
||||
inferior_pid = ecs->pid;
|
||||
stop_bpstat = bpstat_stop_status
|
||||
(&stop_pc,
|
||||
(DECR_PC_AFTER_BREAK ?
|
||||
(prev_pc != stop_pc - DECR_PC_AFTER_BREAK
|
||||
&& currently_stepping (ecs))
|
||||
: 0)
|
||||
);
|
||||
stop_bpstat = bpstat_stop_status (&stop_pc, currently_stepping (ecs));
|
||||
ecs->random_signal = !bpstat_explains_signal (stop_bpstat);
|
||||
inferior_pid = ecs->saved_inferior_pid;
|
||||
goto process_event_stop_test;
|
||||
|
@ -1642,13 +1634,7 @@ handle_inferior_event (struct execution_control_state *ecs)
|
|||
}
|
||||
|
||||
stop_pc = read_pc ();
|
||||
stop_bpstat = bpstat_stop_status
|
||||
(&stop_pc,
|
||||
(DECR_PC_AFTER_BREAK ?
|
||||
(prev_pc != stop_pc - DECR_PC_AFTER_BREAK
|
||||
&& currently_stepping (ecs))
|
||||
: 0)
|
||||
);
|
||||
stop_bpstat = bpstat_stop_status (&stop_pc, currently_stepping (ecs));
|
||||
ecs->random_signal = !bpstat_explains_signal (stop_bpstat);
|
||||
goto process_event_stop_test;
|
||||
|
||||
|
@ -1713,13 +1699,7 @@ handle_inferior_event (struct execution_control_state *ecs)
|
|||
stop_pc = read_pc_pid (ecs->pid);
|
||||
ecs->saved_inferior_pid = inferior_pid;
|
||||
inferior_pid = ecs->pid;
|
||||
stop_bpstat = bpstat_stop_status
|
||||
(&stop_pc,
|
||||
(DECR_PC_AFTER_BREAK ?
|
||||
(prev_pc != stop_pc - DECR_PC_AFTER_BREAK
|
||||
&& currently_stepping (ecs))
|
||||
: 0)
|
||||
);
|
||||
stop_bpstat = bpstat_stop_status (&stop_pc, currently_stepping (ecs));
|
||||
ecs->random_signal = !bpstat_explains_signal (stop_bpstat);
|
||||
inferior_pid = ecs->saved_inferior_pid;
|
||||
goto process_event_stop_test;
|
||||
|
@ -2105,22 +2085,15 @@ handle_inferior_event (struct execution_control_state *ecs)
|
|||
/* See if there is a breakpoint at the current PC. */
|
||||
stop_bpstat = bpstat_stop_status
|
||||
(&stop_pc,
|
||||
(DECR_PC_AFTER_BREAK ?
|
||||
/* Notice the case of stepping through a jump
|
||||
that lands just after a breakpoint.
|
||||
Don't confuse that with hitting the breakpoint.
|
||||
What we check for is that 1) stepping is going on
|
||||
and 2) the pc before the last insn does not match
|
||||
the address of the breakpoint before the current pc
|
||||
and 3) we didn't hit a breakpoint in a signal handler
|
||||
without an intervening stop in sigtramp, which is
|
||||
detected by a new stack pointer value below
|
||||
any usual function calling stack adjustments. */
|
||||
/* Pass TRUE if our reason for stopping is something other
|
||||
than hitting a breakpoint. We do this by checking that
|
||||
1) stepping is going on and 2) we didn't hit a breakpoint
|
||||
in a signal handler without an intervening stop in
|
||||
sigtramp, which is detected by a new stack pointer value
|
||||
below any usual function calling stack adjustments. */
|
||||
(currently_stepping (ecs)
|
||||
&& prev_pc != stop_pc - DECR_PC_AFTER_BREAK
|
||||
&& !(step_range_end
|
||||
&& INNER_THAN (read_sp (), (step_sp - 16)))) :
|
||||
0)
|
||||
&& INNER_THAN (read_sp (), (step_sp - 16))))
|
||||
);
|
||||
/* Following in case break condition called a
|
||||
function. */
|
||||
|
@ -3274,12 +3247,10 @@ static void
|
|||
complete_execution (void)
|
||||
{
|
||||
target_executing = 0;
|
||||
|
||||
if (sync_execution)
|
||||
{
|
||||
add_file_handler (input_fd, stdin_event_handler, 0);
|
||||
pop_prompt ();
|
||||
sync_execution = 0;
|
||||
cleanup_sigint_signal_handler ();
|
||||
do_exec_error_cleanups (ALL_CLEANUPS);
|
||||
display_gdb_prompt (0);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -908,37 +908,8 @@ solib_add (arg_string, from_tty, target)
|
|||
|
||||
if (count)
|
||||
{
|
||||
int update_coreops;
|
||||
|
||||
/* We must update the to_sections field in the core_ops structure
|
||||
here, otherwise we dereference a potential dangling pointer
|
||||
for each call to target_read/write_memory within this routine. */
|
||||
update_coreops = core_ops.to_sections == target->to_sections;
|
||||
|
||||
/* Reallocate the target's section table including the new size. */
|
||||
if (target->to_sections)
|
||||
{
|
||||
old = target->to_sections_end - target->to_sections;
|
||||
target->to_sections = (struct section_table *)
|
||||
xrealloc ((char *) target->to_sections,
|
||||
(sizeof (struct section_table)) * (count + old));
|
||||
}
|
||||
else
|
||||
{
|
||||
old = 0;
|
||||
target->to_sections = (struct section_table *)
|
||||
xmalloc ((sizeof (struct section_table)) * count);
|
||||
}
|
||||
target->to_sections_end = target->to_sections + (count + old);
|
||||
|
||||
/* Update the to_sections field in the core_ops structure
|
||||
if needed. */
|
||||
if (update_coreops)
|
||||
{
|
||||
core_ops.to_sections = target->to_sections;
|
||||
core_ops.to_sections_end = target->to_sections_end;
|
||||
}
|
||||
|
||||
old = target_resize_to_sections (target, count);
|
||||
|
||||
/* Add these section table entries to the target's table. */
|
||||
while ((so = find_solib (so)) != NULL)
|
||||
{
|
||||
|
|
|
@ -429,7 +429,7 @@ handle_exception(int exceptionVector)
|
|||
break;
|
||||
}
|
||||
case 'G': /* set the value of the CPU registers - return OK */
|
||||
hex2mem(&ptr, (unsigned char*) registers, NUMREGBYTES, 0);
|
||||
hex2mem(ptr, (unsigned char*) registers, NUMREGBYTES, 0);
|
||||
strcpy(remcomOutBuffer,"OK");
|
||||
break;
|
||||
case 's': /* sAA..AA Step one instruction from AA..AA(optional) */
|
||||
|
|
|
@ -46,7 +46,7 @@ int display_space;
|
|||
invoked on the command line with the -nw --async options. In this
|
||||
version, the usual command_loop is substituted by and event loop which
|
||||
processes UI events asynchronously. */
|
||||
int async_p = 1;
|
||||
int event_loop_p = 1;
|
||||
|
||||
/* Whether this is the command line version or not */
|
||||
int tui_version = 0;
|
||||
|
@ -177,8 +177,8 @@ main (argc, argv)
|
|||
with no equivalent). */
|
||||
static struct option long_options[] =
|
||||
{
|
||||
{"async", no_argument, &async_p, 1},
|
||||
{"noasync", no_argument, &async_p, 0},
|
||||
{"async", no_argument, &event_loop_p, 1},
|
||||
{"noasync", no_argument, &event_loop_p, 0},
|
||||
#if defined(TUI)
|
||||
{"tui", no_argument, &tui_version, 1},
|
||||
#endif
|
||||
|
|
|
@ -655,38 +655,10 @@ solib_add (arg_string, from_tty, target)
|
|||
|
||||
if (count)
|
||||
{
|
||||
int update_coreops;
|
||||
|
||||
/* We must update the to_sections field in the core_ops structure
|
||||
here, otherwise we dereference a potential dangling pointer
|
||||
for each call to target_read/write_memory within this routine. */
|
||||
update_coreops = core_ops.to_sections == target->to_sections;
|
||||
|
||||
/* Reallocate the target's section table including the new size. */
|
||||
if (target->to_sections)
|
||||
{
|
||||
old = target->to_sections_end - target->to_sections;
|
||||
target->to_sections = (struct section_table *)
|
||||
xrealloc ((char *) target->to_sections,
|
||||
(sizeof (struct section_table)) * (count + old));
|
||||
}
|
||||
else
|
||||
{
|
||||
old = 0;
|
||||
target->to_sections = (struct section_table *)
|
||||
xmalloc ((sizeof (struct section_table)) * count);
|
||||
}
|
||||
target->to_sections_end = target->to_sections + (count + old);
|
||||
|
||||
/* Update the to_sections field in the core_ops structure
|
||||
if needed. */
|
||||
if (update_coreops)
|
||||
{
|
||||
core_ops.to_sections = target->to_sections;
|
||||
core_ops.to_sections_end = target->to_sections_end;
|
||||
}
|
||||
|
||||
/* Add these section table entries to the target's table. */
|
||||
|
||||
old = target_resize_to_sections (target, count);
|
||||
|
||||
while ((so = find_solib (so)) != NULL)
|
||||
{
|
||||
if (so->so_name[0])
|
||||
|
|
|
@ -357,49 +357,12 @@ pa64_solib_load_symbols (so, name, from_tty, text_addr, target)
|
|||
status = target_read_memory (text_addr, buf, 4);
|
||||
if (status != 0)
|
||||
{
|
||||
int old, new;
|
||||
int update_coreops;
|
||||
int update_execops;
|
||||
|
||||
/* We must update the to_sections field in the core_ops structure
|
||||
here, otherwise we dereference a potential dangling pointer
|
||||
for each call to target_read/write_memory within this routine. */
|
||||
update_coreops = core_ops.to_sections == target->to_sections;
|
||||
|
||||
/* Ditto exec_ops (this was a bug). */
|
||||
update_execops = exec_ops.to_sections == target->to_sections;
|
||||
|
||||
int new, old;
|
||||
|
||||
new = so->sections_end - so->sections;
|
||||
/* Add sections from the shared library to the core target. */
|
||||
if (target->to_sections)
|
||||
{
|
||||
old = target->to_sections_end - target->to_sections;
|
||||
target->to_sections = (struct section_table *)
|
||||
xrealloc ((char *) target->to_sections,
|
||||
((sizeof (struct section_table)) * (old + new)));
|
||||
}
|
||||
else
|
||||
{
|
||||
old = 0;
|
||||
target->to_sections = (struct section_table *)
|
||||
xmalloc ((sizeof (struct section_table)) * new);
|
||||
}
|
||||
target->to_sections_end = (target->to_sections + old + new);
|
||||
|
||||
/* Update the to_sections field in the core_ops structure
|
||||
if needed, ditto exec_ops. */
|
||||
if (update_coreops)
|
||||
{
|
||||
core_ops.to_sections = target->to_sections;
|
||||
core_ops.to_sections_end = target->to_sections_end;
|
||||
}
|
||||
|
||||
if (update_execops)
|
||||
{
|
||||
exec_ops.to_sections = target->to_sections;
|
||||
exec_ops.to_sections_end = target->to_sections_end;
|
||||
}
|
||||
|
||||
old = target_resize_to_sections (target, new);
|
||||
|
||||
/* Copy over the old data before it gets clobbered. */
|
||||
memcpy ((char *) (target->to_sections + old),
|
||||
so->sections,
|
||||
|
|
24
gdb/procfs.c
24
gdb/procfs.c
|
@ -2265,9 +2265,6 @@ init_procinfo (pid, kill)
|
|||
|
||||
prfillset (&sctl.sigset);
|
||||
notice_signals (pi, &sctl);
|
||||
prfillset (&fctl.fltset);
|
||||
prdelset (&fctl.fltset, FLTPAGE);
|
||||
|
||||
#else /* ! UNIXWARE */
|
||||
ioctl (pi->ctl_fd, PIOCGTRACE, &pi->saved_trace.sigset);
|
||||
ioctl (pi->ctl_fd, PIOCGHOLD, &pi->saved_sighold.sigset);
|
||||
|
@ -2280,11 +2277,6 @@ init_procinfo (pid, kill)
|
|||
memset ((char *) &pi->prrun, 0, sizeof (pi->prrun));
|
||||
prfillset (&pi->prrun.pr_trace);
|
||||
procfs_notice_signals (pid);
|
||||
prfillset (&pi->prrun.pr_fault);
|
||||
prdelset (&pi->prrun.pr_fault, FLTPAGE);
|
||||
#ifdef PROCFS_DONT_TRACE_FAULTS
|
||||
premptyset (&pi->prrun.pr_fault);
|
||||
#endif
|
||||
#endif /* UNIXWARE */
|
||||
|
||||
if (!procfs_read_status (pi))
|
||||
|
@ -2340,9 +2332,17 @@ create_procinfo (pid)
|
|||
|
||||
#ifdef PROCFS_USE_READ_WRITE
|
||||
fctl.cmd = PCSFAULT;
|
||||
prfillset (&fctl.fltset);
|
||||
prdelset (&fctl.fltset, FLTPAGE);
|
||||
|
||||
if (write (pi->ctl_fd, (char *) &fctl, sizeof (struct flt_ctl)) < 0)
|
||||
proc_init_failed (pi, "PCSFAULT failed", 1);
|
||||
#else
|
||||
prfillset (&pi->prrun.pr_fault);
|
||||
prdelset (&pi->prrun.pr_fault, FLTPAGE);
|
||||
#ifdef PROCFS_DONT_TRACE_FAULTS
|
||||
premptyset (&pi->prrun.pr_fault);
|
||||
#endif
|
||||
if (ioctl (pi->ctl_fd, PIOCSFAULT, &pi->prrun.pr_fault) < 0)
|
||||
proc_init_failed (pi, "PIOCSFAULT failed", 1);
|
||||
#endif
|
||||
|
@ -3318,9 +3318,17 @@ do_attach (pid)
|
|||
|
||||
#ifdef PROCFS_USE_READ_WRITE
|
||||
fctl.cmd = PCSFAULT;
|
||||
prfillset (&fctl.fltset);
|
||||
prdelset (&fctl.fltset, FLTPAGE);
|
||||
|
||||
if (write (pi->ctl_fd, (char *) &fctl, sizeof (struct flt_ctl)) < 0)
|
||||
print_sys_errmsg ("PCSFAULT failed", errno);
|
||||
#else /* PROCFS_USE_READ_WRITE */
|
||||
prfillset (&pi->prrun.pr_fault);
|
||||
prdelset (&pi->prrun.pr_fault, FLTPAGE);
|
||||
#ifdef PROCFS_DONT_TRACE_FAULTS
|
||||
premptyset (&pi->prrun.pr_fault);
|
||||
#endif
|
||||
if (ioctl (pi->ctl_fd, PIOCSFAULT, &pi->prrun.pr_fault))
|
||||
{
|
||||
print_sys_errmsg ("PIOCSFAULT failed", errno);
|
||||
|
|
222
gdb/remote.c
222
gdb/remote.c
|
@ -53,7 +53,9 @@
|
|||
#include "serial.h"
|
||||
|
||||
/* Prototypes for local functions */
|
||||
static void initialize_sigint_signal_handler PARAMS ((void));
|
||||
static void cleanup_sigint_signal_handler (void *dummy);
|
||||
static void initialize_sigint_signal_handler (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));
|
||||
|
@ -83,7 +85,6 @@ static void remote_resume PARAMS ((int pid, int step,
|
|||
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 void remote_open PARAMS ((char *name, int from_tty));
|
||||
|
@ -253,6 +254,16 @@ static struct target_ops extended_async_remote_ops;
|
|||
was static int remote_timeout = 2; */
|
||||
extern int remote_timeout;
|
||||
|
||||
/* FIXME: cagney/1999-09-23: Even though getpkt was called with
|
||||
``forever'' still use the normal timeout mechanism. This is
|
||||
currently used by the ASYNC code to guarentee that target reads
|
||||
during the initial connect always time-out. Once getpkt has been
|
||||
modified to return a timeout indication and, in turn
|
||||
remote_wait()/wait_for_inferior() have gained a timeout parameter
|
||||
this can go away. */
|
||||
static int wait_forever_enabled_p = 1;
|
||||
|
||||
|
||||
/* This variable chooses whether to send a ^C or a break when the user
|
||||
requests program interruption. Although ^C is usually what remote
|
||||
systems expect, and that is the default here, sometimes a break is
|
||||
|
@ -311,6 +322,11 @@ static int remote_address_size;
|
|||
|
||||
static int remote_register_buf_size = 0;
|
||||
|
||||
/* Tempoary to track who currently owns the terminal. See
|
||||
target_async_terminal_* for more details. */
|
||||
|
||||
static int remote_async_terminal_ours_p;
|
||||
|
||||
/* Generic configuration support for packets the stub optionally
|
||||
supports. Allows the user to specify the use of the packet as well
|
||||
as allowing GDB to auto-detect support in the remote stub. */
|
||||
|
@ -1717,6 +1733,9 @@ remote_open_1 (name, from_tty, target, extended_p)
|
|||
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).");
|
||||
|
||||
/* See FIXME above */
|
||||
wait_forever_enabled_p = 1;
|
||||
|
||||
target_preopen (from_tty);
|
||||
|
||||
unpush_target (target);
|
||||
|
@ -1832,15 +1851,6 @@ serial device is attached to the remote system (e.g. /dev/ttya).");
|
|||
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 && SERIAL_CAN_ASYNC_P (remote_desc))
|
||||
SERIAL_ASYNC (remote_desc, inferior_event_handler, 0);
|
||||
if (remote_debug && SERIAL_IS_ASYNC_P (remote_desc))
|
||||
fputs_unfiltered ("Async mode.\n", gdb_stdlog);
|
||||
|
||||
push_target (target); /* Switch to using remote target now */
|
||||
|
||||
init_packet_config (&remote_protocol_P);
|
||||
|
@ -1853,20 +1863,26 @@ serial device is attached to the remote system (e.g. /dev/ttya).");
|
|||
binary downloading. */
|
||||
init_packet_config (&remote_protocol_binary_download);
|
||||
|
||||
/* 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 && SERIAL_IS_ASYNC_P (remote_desc))
|
||||
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;
|
||||
|
||||
/* With this target we start out by owning the terminal. */
|
||||
remote_async_terminal_ours_p = 1;
|
||||
|
||||
/* FIXME: cagney/1999-09-23: During the initial connection it is
|
||||
assumed that the target is already ready and able to respond to
|
||||
requests. Unfortunatly remote_start_remote() eventually calls
|
||||
wait_for_inferior() with no timeout. wait_forever_enabled_p gets
|
||||
around this. Eventually a mechanism that allows
|
||||
wait_for_inferior() to expect/get timeouts will be
|
||||
implemented. */
|
||||
wait_forever_enabled_p = 0;
|
||||
|
||||
/* 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). */
|
||||
|
@ -1874,35 +1890,32 @@ serial device is attached to the remote system (e.g. /dev/ttya).");
|
|||
"Couldn't establish connection to remote target\n",
|
||||
RETURN_MASK_ALL))
|
||||
{
|
||||
/* Unregister the file descriptor from the event loop. */
|
||||
if (SERIAL_IS_ASYNC_P (remote_desc))
|
||||
SERIAL_ASYNC (remote_desc, NULL, 0);
|
||||
pop_target ();
|
||||
wait_forever_enabled_p = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!SERIAL_IS_ASYNC_P (remote_desc))
|
||||
{
|
||||
if (extended_p)
|
||||
{
|
||||
/* tell the remote that we're using the extended protocol. */
|
||||
char *buf = alloca (PBUFSIZ);
|
||||
putpkt ("!");
|
||||
getpkt (buf, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
wait_forever_enabled_p = 1;
|
||||
|
||||
/* 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);
|
||||
if (extended_p)
|
||||
{
|
||||
/* tell the remote that we're using the extended protocol. */
|
||||
char *buf = alloca (PBUFSIZ);
|
||||
putpkt ("!");
|
||||
getpkt (buf, 0);
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
/* FIXME: cagney/1999-09-26: We shouldn't just put the target into
|
||||
async mode. Instead we should leave the target synchronous and
|
||||
then leave it to the client to flip modes. */
|
||||
if (event_loop_p && target_can_async_p ())
|
||||
target_async (inferior_event_handler, 0);
|
||||
if (remote_debug && SERIAL_IS_ASYNC_P (remote_desc))
|
||||
fputs_unfiltered ("Serial put into async mode.\n", gdb_stdlog);
|
||||
}
|
||||
|
||||
/* This takes a program previously attached to and detaches it. After
|
||||
|
@ -2046,25 +2059,13 @@ remote_async_resume (pid, step, siggnal)
|
|||
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 (SERIAL_IS_ASYNC_P (remote_desc) && !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 ();
|
||||
}
|
||||
}
|
||||
/* Tell the world that the target is now executing. */
|
||||
/* FIXME: cagney/1999-09-23: Is it the targets responsibility to set
|
||||
this? Instead, should the client of target just assume (for
|
||||
async targets) that the target is going to start executing? Is
|
||||
this information already found in the continuation block? */
|
||||
if (SERIAL_IS_ASYNC_P (remote_desc))
|
||||
target_executing = 1;
|
||||
|
||||
if (siggnal != TARGET_SIGNAL_0)
|
||||
{
|
||||
|
@ -2110,11 +2111,11 @@ handle_remote_sigint_twice (sig)
|
|||
{
|
||||
signal (sig, handle_sigint);
|
||||
sigint_remote_twice_token =
|
||||
create_async_signal_handler (async_remote_interrupt, NULL);
|
||||
create_async_signal_handler (async_remote_interrupt_twice, NULL);
|
||||
mark_async_signal_handler_wrapper (sigint_remote_twice_token);
|
||||
}
|
||||
|
||||
/* Perform the real interruption of hte target execution, in response
|
||||
/* Perform the real interruption of the target execution, in response
|
||||
to a ^C. */
|
||||
static void
|
||||
async_remote_interrupt (arg)
|
||||
|
@ -2132,14 +2133,19 @@ static void
|
|||
async_remote_interrupt_twice (arg)
|
||||
gdb_client_data arg;
|
||||
{
|
||||
interrupt_query ();
|
||||
signal (SIGINT, handle_remote_sigint);
|
||||
/* Do something only if the target was not killed by the previous
|
||||
cntl-C. */
|
||||
if (target_executing)
|
||||
{
|
||||
interrupt_query ();
|
||||
signal (SIGINT, handle_remote_sigint);
|
||||
}
|
||||
}
|
||||
|
||||
/* Reinstall the usual SIGINT handlers, after the target has
|
||||
stopped. */
|
||||
void
|
||||
cleanup_sigint_signal_handler ()
|
||||
static void
|
||||
cleanup_sigint_signal_handler (void *dummy)
|
||||
{
|
||||
signal (SIGINT, handle_sigint);
|
||||
if (sigint_remote_twice_token)
|
||||
|
@ -2214,6 +2220,51 @@ Give up (and stop debugging it)? "))
|
|||
target_terminal_inferior ();
|
||||
}
|
||||
|
||||
/* Enable/disable target terminal ownership. Most targets can use
|
||||
terminal groups to control terminal ownership. Remote targets are
|
||||
different in that explicit transfer of ownership to/from GDB/target
|
||||
is required. */
|
||||
|
||||
static void
|
||||
remote_async_terminal_inferior (void)
|
||||
{
|
||||
/* FIXME: cagney/1999-09-27: Shouldn't need to test for
|
||||
sync_execution here. This function should only be called when
|
||||
GDB is resuming the inferior in the forground. A background
|
||||
resume (``run&'') should leave GDB in control of the terminal and
|
||||
consequently should not call this code. */
|
||||
if (!sync_execution)
|
||||
return;
|
||||
/* FIXME: cagney/1999-09-27: Closely related to the above. Make
|
||||
calls target_terminal_*() idenpotent. The event-loop GDB talking
|
||||
to an asynchronous target with a synchronous command calls this
|
||||
function from both event-top.c and infrun.c/infcmd.c. Once GDB
|
||||
stops trying to transfer the terminal to the target when it
|
||||
shouldn't this guard can go away. */
|
||||
if (!remote_async_terminal_ours_p)
|
||||
return;
|
||||
delete_file_handler (input_fd);
|
||||
remote_async_terminal_ours_p = 0;
|
||||
initialize_sigint_signal_handler ();
|
||||
/* NOTE: At this point we could also register our selves as the
|
||||
recipient of all input. Any characters typed could then be
|
||||
passed on down to the target. */
|
||||
}
|
||||
|
||||
static void
|
||||
remote_async_terminal_ours (void)
|
||||
{
|
||||
/* See FIXME in remote_async_terminal_inferior. */
|
||||
if (!sync_execution)
|
||||
return;
|
||||
/* See FIXME in remote_async_terminal_inferior. */
|
||||
if (remote_async_terminal_ours_p)
|
||||
return;
|
||||
cleanup_sigint_signal_handler (NULL);
|
||||
add_file_handler (input_fd, stdin_event_handler, 0);
|
||||
remote_async_terminal_ours_p = 1;
|
||||
}
|
||||
|
||||
/* If nonzero, ignore the next kill. */
|
||||
|
||||
int kill_kludge;
|
||||
|
@ -2473,7 +2524,11 @@ remote_async_wait (pid, status)
|
|||
|
||||
if (!SERIAL_IS_ASYNC_P (remote_desc))
|
||||
ofunc = signal (SIGINT, remote_interrupt);
|
||||
getpkt ((char *) buf, 1);
|
||||
/* FIXME: cagney/1999-09-27: If we're in async mode we should
|
||||
_never_ wait for ever -> test on target_is_async_p().
|
||||
However, before we do that we need to ensure that the caller
|
||||
knows how to take the target into/out of async mode. */
|
||||
getpkt ((char *) buf, wait_forever_enabled_p);
|
||||
if (!SERIAL_IS_ASYNC_P (remote_desc))
|
||||
signal (SIGINT, ofunc);
|
||||
|
||||
|
@ -3832,7 +3887,7 @@ extended_remote_async_create_inferior (exec_file, args, env)
|
|||
|
||||
/* If running asynchronously, register the target file descriptor
|
||||
with the event loop. */
|
||||
if (async_p && SERIAL_CAN_ASYNC_P (remote_desc))
|
||||
if (event_loop_p && SERIAL_CAN_ASYNC_P (remote_desc))
|
||||
SERIAL_ASYNC (remote_desc, inferior_event_handler, 0);
|
||||
|
||||
/* Now restart the remote server. */
|
||||
|
@ -4673,6 +4728,9 @@ remote_cisco_open (name, from_tty)
|
|||
"To open a remote debug connection, you need to specify what \n\
|
||||
device is attached to the remote system (e.g. host:port).");
|
||||
|
||||
/* See FIXME above */
|
||||
wait_forever_enabled_p = 1;
|
||||
|
||||
target_preopen (from_tty);
|
||||
|
||||
unpush_target (&remote_cisco_ops);
|
||||
|
@ -5010,6 +5068,26 @@ Specify the serial device it is connected to (e.g. host:2020).";
|
|||
remote_cisco_ops.to_magic = OPS_MAGIC;
|
||||
}
|
||||
|
||||
static int
|
||||
remote_can_async_p (void)
|
||||
{
|
||||
/* We're async whenever the serial device is. */
|
||||
return SERIAL_CAN_ASYNC_P (remote_desc);
|
||||
}
|
||||
|
||||
static int
|
||||
remote_is_async_p (void)
|
||||
{
|
||||
/* We're async whenever the serial device is. */
|
||||
return SERIAL_IS_ASYNC_P (remote_desc);
|
||||
}
|
||||
|
||||
static void
|
||||
remote_async (void (*callback) (int error, void *context, int fd), void *context)
|
||||
{
|
||||
SERIAL_ASYNC (remote_desc, callback, context);
|
||||
}
|
||||
|
||||
/* Target async and target extended-async.
|
||||
|
||||
This are temporary targets, until it is all tested. Eventually
|
||||
|
@ -5036,6 +5114,8 @@ Specify the serial device it is connected to (e.g. /dev/ttya).";
|
|||
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_terminal_inferior = remote_async_terminal_inferior;
|
||||
remote_async_ops.to_terminal_ours = remote_async_terminal_ours;
|
||||
remote_async_ops.to_kill = remote_async_kill;
|
||||
remote_async_ops.to_load = generic_load;
|
||||
remote_async_ops.to_mourn_inferior = remote_async_mourn;
|
||||
|
@ -5051,7 +5131,9 @@ Specify the serial device it is connected to (e.g. /dev/ttya).";
|
|||
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_can_async_p = remote_can_async_p;
|
||||
remote_async_ops.to_is_async_p = remote_is_async_p;
|
||||
remote_async_ops.to_async = remote_async;
|
||||
remote_async_ops.to_magic = OPS_MAGIC;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,11 +43,6 @@ extern int putpkt (char *buf);
|
|||
extern void remote_console_output PARAMS ((char *));
|
||||
|
||||
|
||||
/* FIXME: cagney/1999-09-20: This function is going to be replaced
|
||||
with a more generic (non remote specific) mechanism. */
|
||||
|
||||
extern void cleanup_sigint_signal_handler (void);
|
||||
|
||||
/* FIXME: cagney/1999-09-20: The remote cisco stuff in remote.c needs
|
||||
to be broken out into a separate file (remote-cisco.[hc]?). Before
|
||||
that can happen, a remote protocol stack framework needs to be
|
||||
|
|
|
@ -755,28 +755,9 @@ xcoff_relocate_core (target)
|
|||
add our sections to the section table for the core target. */
|
||||
if (vp != vmap)
|
||||
{
|
||||
int count;
|
||||
struct section_table *stp;
|
||||
int update_coreops;
|
||||
|
||||
/* We must update the to_sections field in the core_ops structure
|
||||
now to avoid dangling pointer dereferences. */
|
||||
update_coreops = core_ops.to_sections == target->to_sections;
|
||||
|
||||
count = target->to_sections_end - target->to_sections;
|
||||
count += 2;
|
||||
target->to_sections = (struct section_table *)
|
||||
xrealloc (target->to_sections,
|
||||
sizeof (struct section_table) * count);
|
||||
target->to_sections_end = target->to_sections + count;
|
||||
|
||||
/* Update the to_sections field in the core_ops structure
|
||||
if needed. */
|
||||
if (update_coreops)
|
||||
{
|
||||
core_ops.to_sections = target->to_sections;
|
||||
core_ops.to_sections_end = target->to_sections_end;
|
||||
}
|
||||
target_resize_to_sections (target, 2);
|
||||
stp = target->to_sections_end - 2;
|
||||
|
||||
stp->bfd = vp->bfd;
|
||||
|
|
35
gdb/solib.c
35
gdb/solib.c
|
@ -1174,7 +1174,7 @@ solib_add (arg_string, from_tty, target)
|
|||
|
||||
#endif SVR4_SHARED_LIBS
|
||||
|
||||
if ((re_err = re_comp (arg_string ? arg_string : ".")) != NULL)
|
||||
if ((re_err = re_comp (arg_string? arg_string : ".")) != NULL)
|
||||
{
|
||||
error ("Invalid regexp: %s", re_err);
|
||||
}
|
||||
|
@ -1196,38 +1196,9 @@ solib_add (arg_string, from_tty, target)
|
|||
|
||||
if (count)
|
||||
{
|
||||
int update_coreops;
|
||||
|
||||
/* We must update the to_sections field in the core_ops structure
|
||||
here, otherwise we dereference a potential dangling pointer
|
||||
for each call to target_read/write_memory within this routine. */
|
||||
update_coreops = core_ops.to_sections == target->to_sections;
|
||||
|
||||
/* Reallocate the target's section table including the new size. */
|
||||
if (target->to_sections)
|
||||
{
|
||||
old = target->to_sections_end - target->to_sections;
|
||||
target->to_sections = (struct section_table *)
|
||||
xrealloc ((char *) target->to_sections,
|
||||
(sizeof (struct section_table)) * (count + old));
|
||||
}
|
||||
else
|
||||
{
|
||||
old = 0;
|
||||
target->to_sections = (struct section_table *)
|
||||
xmalloc ((sizeof (struct section_table)) * count);
|
||||
}
|
||||
target->to_sections_end = target->to_sections + (count + old);
|
||||
|
||||
/* Update the to_sections field in the core_ops structure
|
||||
if needed. */
|
||||
if (update_coreops)
|
||||
{
|
||||
core_ops.to_sections = target->to_sections;
|
||||
core_ops.to_sections_end = target->to_sections_end;
|
||||
}
|
||||
|
||||
|
||||
/* Add these section table entries to the target's table. */
|
||||
old = target_resize_to_sections (target, count);
|
||||
while ((so = find_solib (so)) != NULL)
|
||||
{
|
||||
if (so->so_name[0])
|
||||
|
|
|
@ -375,49 +375,11 @@ som_solib_load_symbols (so, name, from_tty, text_addr, target)
|
|||
if (status != 0)
|
||||
{
|
||||
int old, new;
|
||||
int update_coreops;
|
||||
int update_execops;
|
||||
|
||||
/* We must update the to_sections field in the core_ops structure
|
||||
here, otherwise we dereference a potential dangling pointer
|
||||
for each call to target_read/write_memory within this routine. */
|
||||
update_coreops = core_ops.to_sections == target->to_sections;
|
||||
|
||||
/* Ditto exec_ops (this was a bug).
|
||||
*/
|
||||
update_execops = exec_ops.to_sections == target->to_sections;
|
||||
|
||||
new = so->sections_end - so->sections;
|
||||
/* Add sections from the shared library to the core target. */
|
||||
if (target->to_sections)
|
||||
{
|
||||
old = target->to_sections_end - target->to_sections;
|
||||
target->to_sections = (struct section_table *)
|
||||
xrealloc ((char *) target->to_sections,
|
||||
((sizeof (struct section_table)) * (old + new)));
|
||||
}
|
||||
else
|
||||
{
|
||||
old = 0;
|
||||
target->to_sections = (struct section_table *)
|
||||
xmalloc ((sizeof (struct section_table)) * new);
|
||||
}
|
||||
target->to_sections_end = (target->to_sections + old + new);
|
||||
|
||||
/* Update the to_sections field in the core_ops structure
|
||||
if needed, ditto exec_ops. */
|
||||
if (update_coreops)
|
||||
{
|
||||
core_ops.to_sections = target->to_sections;
|
||||
core_ops.to_sections_end = target->to_sections_end;
|
||||
}
|
||||
|
||||
if (update_execops)
|
||||
{
|
||||
exec_ops.to_sections = target->to_sections;
|
||||
exec_ops.to_sections_end = target->to_sections_end;
|
||||
}
|
||||
|
||||
|
||||
old = target_resize_to_sections (target, new);
|
||||
|
||||
/* Copy over the old data before it gets clobbered. */
|
||||
memcpy ((char *) (target->to_sections + old),
|
||||
so->sections,
|
||||
|
|
57
gdb/target.c
57
gdb/target.c
|
@ -450,6 +450,9 @@ cleanup_target (t)
|
|||
|
||||
de_fault (to_pid_to_exec_file, (char *(*)PARAMS ((int))) return_zero);
|
||||
de_fault (to_core_file_to_sym_file, (char *(*)PARAMS ((char *))) return_zero);
|
||||
de_fault (to_can_async_p, (int (*) (void)) return_zero);
|
||||
de_fault (to_is_async_p, (int (*) (void)) return_zero);
|
||||
de_fault (to_async, (void (*) (void (*) (int, void*, int), void*)) tcomplain);
|
||||
#undef de_fault
|
||||
}
|
||||
|
||||
|
@ -541,9 +544,11 @@ update_current_target ()
|
|||
INHERIT (to_has_registers, t);
|
||||
INHERIT (to_has_execution, t);
|
||||
INHERIT (to_has_thread_control, t);
|
||||
INHERIT (to_has_async_exec, t);
|
||||
INHERIT (to_sections, t);
|
||||
INHERIT (to_sections_end, t);
|
||||
INHERIT (to_can_async_p, t);
|
||||
INHERIT (to_is_async_p, t);
|
||||
INHERIT (to_async, t);
|
||||
INHERIT (to_magic, t);
|
||||
|
||||
#undef INHERIT
|
||||
|
@ -1113,6 +1118,56 @@ return_one ()
|
|||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Resize the to_sections pointer. Also make sure that anyone that
|
||||
* was holding on to an old value of it gets updated.
|
||||
* Returns the old size.
|
||||
*/
|
||||
|
||||
int
|
||||
target_resize_to_sections (struct target_ops *target, int num_added)
|
||||
{
|
||||
struct target_ops **t;
|
||||
struct section_table *old_value;
|
||||
int old_count;
|
||||
|
||||
old_value = target->to_sections;
|
||||
|
||||
if (target->to_sections)
|
||||
{
|
||||
old_count = target->to_sections_end - target->to_sections;
|
||||
target->to_sections = (struct section_table *)
|
||||
xrealloc ((char *) target->to_sections,
|
||||
(sizeof (struct section_table)) * (num_added + old_count));
|
||||
}
|
||||
else
|
||||
{
|
||||
old_count = 0;
|
||||
target->to_sections = (struct section_table *)
|
||||
xmalloc ((sizeof (struct section_table)) * num_added);
|
||||
}
|
||||
target->to_sections_end = target->to_sections + (num_added + old_count);
|
||||
|
||||
/* Check to see if anyone else was pointing to this structure.
|
||||
If old_value was null, then no one was. */
|
||||
|
||||
if (old_value)
|
||||
{
|
||||
for (t = target_structs; t < target_structs + target_struct_size;
|
||||
++t)
|
||||
{
|
||||
if ((*t)->to_sections == old_value)
|
||||
{
|
||||
(*t)->to_sections = target->to_sections;
|
||||
(*t)->to_sections_end = target->to_sections_end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return old_count;
|
||||
|
||||
}
|
||||
|
||||
/* Find a single runnable target in the stack and return it. If for
|
||||
some reason there is more than one, return NULL. */
|
||||
|
||||
|
|
19
gdb/target.h
19
gdb/target.h
|
@ -397,11 +397,14 @@ struct target_ops
|
|||
int to_has_registers;
|
||||
int to_has_execution;
|
||||
int to_has_thread_control; /* control thread execution */
|
||||
int to_has_async_exec;
|
||||
struct section_table
|
||||
*to_sections;
|
||||
struct section_table
|
||||
*to_sections_end;
|
||||
/* ASYNC target controls */
|
||||
int (*to_can_async_p) (void);
|
||||
int (*to_is_async_p) (void);
|
||||
void (*to_async) (void (*cb) (int error, void *context, int fd), void *context);
|
||||
int to_magic;
|
||||
/* Need sub-structure for target machine related rather than comm related? */
|
||||
};
|
||||
|
@ -1009,9 +1012,14 @@ print_section_info PARAMS ((struct target_ops *, bfd *));
|
|||
#define target_can_switch_threads \
|
||||
(current_target.to_has_thread_control & tc_switch)
|
||||
|
||||
/* Does the target support asynchronous execution? */
|
||||
#define target_has_async \
|
||||
(current_target.to_has_async_exec)
|
||||
/* Can the target support asynchronous execution? */
|
||||
#define target_can_async_p() (current_target.to_can_async_p ())
|
||||
|
||||
/* Is the target in asynchronous execution mode? */
|
||||
#define target_is_async_p() (current_target.to_is_async_p())
|
||||
|
||||
/* Put the target in async mode with the specified callback function. */
|
||||
#define target_async(CALLBACK,CONTEXT) (current_target.to_async((CALLBACK), (CONTEXT)))
|
||||
|
||||
extern void target_link PARAMS ((char *, CORE_ADDR *));
|
||||
|
||||
|
@ -1266,6 +1274,9 @@ extern struct target_ops *find_run_target PARAMS ((void));
|
|||
|
||||
extern struct target_ops *
|
||||
find_core_target PARAMS ((void));
|
||||
|
||||
int
|
||||
target_resize_to_sections PARAMS ((struct target_ops *target, int num_added));
|
||||
|
||||
/* Stuff that should be shared among the various remote targets. */
|
||||
|
||||
|
|
34
gdb/top.c
34
gdb/top.c
|
@ -417,6 +417,12 @@ void (*create_breakpoint_hook) PARAMS ((struct breakpoint * bpt));
|
|||
void (*delete_breakpoint_hook) PARAMS ((struct breakpoint * bpt));
|
||||
void (*modify_breakpoint_hook) PARAMS ((struct breakpoint * bpt));
|
||||
|
||||
/* Called as appropriate to notify the interface that we have attached
|
||||
to or detached from an already running process. */
|
||||
|
||||
void (*attach_hook) PARAMS ((void));
|
||||
void (*detach_hook) PARAMS ((void));
|
||||
|
||||
/* Called during long calculations to allow GUI to repair window damage, and to
|
||||
check for stop buttons, etc... */
|
||||
|
||||
|
@ -471,7 +477,7 @@ PARAMS ((void)) ATTR_NORETURN;
|
|||
loop, but can be caught via catch_errors. */
|
||||
|
||||
NORETURN void
|
||||
return_to_top_level (reason)
|
||||
return_to_top_level (reason)
|
||||
enum return_reason reason;
|
||||
{
|
||||
quit_flag = 0;
|
||||
|
@ -483,8 +489,10 @@ PARAMS ((void)) ATTR_NORETURN;
|
|||
|
||||
disable_current_display ();
|
||||
do_cleanups (ALL_CLEANUPS);
|
||||
if (async_p && target_has_async)
|
||||
if (event_loop_p && target_can_async_p ())
|
||||
do_exec_cleanups (ALL_CLEANUPS);
|
||||
if (event_loop_p && sync_execution)
|
||||
do_exec_error_cleanups (ALL_CLEANUPS);
|
||||
|
||||
if (annotation_level > 1)
|
||||
switch (reason)
|
||||
|
@ -688,7 +696,7 @@ gdb_init (argv0)
|
|||
not the async version is run. NOTE: in the future we plan to make
|
||||
the event loop be the default engine of gdb, and this difference
|
||||
will disappear. */
|
||||
if (async_p)
|
||||
if (event_loop_p)
|
||||
async_init_signals ();
|
||||
else
|
||||
init_signals ();
|
||||
|
@ -1275,7 +1283,7 @@ execute_command (p, from_tty)
|
|||
|
||||
/* If the target is running, we allow only a limited set of
|
||||
commands. */
|
||||
if (async_p && target_has_async && target_executing)
|
||||
if (event_loop_p && target_can_async_p () && target_executing)
|
||||
if (!strcmp (c->name, "help")
|
||||
&& !strcmp (c->name, "pwd")
|
||||
&& !strcmp (c->name, "show")
|
||||
|
@ -2100,7 +2108,7 @@ command_line_input (prompt_arg, repeat, annotation_suffix)
|
|||
#ifdef STOP_SIGNAL
|
||||
if (job_control)
|
||||
{
|
||||
if (async_p)
|
||||
if (event_loop_p)
|
||||
signal (STOP_SIGNAL, handle_stop_sig);
|
||||
else
|
||||
signal (STOP_SIGNAL, stop_sig);
|
||||
|
@ -2965,7 +2973,7 @@ get_prompt_1 (formatted_prompt)
|
|||
{
|
||||
char *local_prompt;
|
||||
|
||||
if (async_p)
|
||||
if (event_loop_p)
|
||||
local_prompt = PROMPT (0);
|
||||
else
|
||||
local_prompt = gdb_prompt_string;
|
||||
|
@ -3201,7 +3209,7 @@ get_prompt ()
|
|||
else
|
||||
{
|
||||
/* Prompt could not be formatted. */
|
||||
if (async_p)
|
||||
if (event_loop_p)
|
||||
return PROMPT (0);
|
||||
else
|
||||
return gdb_prompt_string;
|
||||
|
@ -3217,7 +3225,7 @@ set_prompt (s)
|
|||
if (prompt != NULL)
|
||||
free (prompt);
|
||||
*/
|
||||
if (async_p)
|
||||
if (event_loop_p)
|
||||
PROMPT (0) = savestring (s, strlen (s));
|
||||
else
|
||||
gdb_prompt_string = savestring (s, strlen (s));
|
||||
|
@ -3789,7 +3797,7 @@ init_main ()
|
|||
|
||||
/* If we are running the asynchronous version,
|
||||
we initialize the prompts differently. */
|
||||
if (!async_p)
|
||||
if (!event_loop_p)
|
||||
{
|
||||
gdb_prompt_string = savestring (DEFAULT_PROMPT, strlen (DEFAULT_PROMPT));
|
||||
}
|
||||
|
@ -3862,7 +3870,7 @@ until the next time it is started.", &cmdlist);
|
|||
async version is run. NOTE: this difference is going to
|
||||
disappear as we make the event loop be the default engine of
|
||||
gdb. */
|
||||
if (!async_p)
|
||||
if (!event_loop_p)
|
||||
{
|
||||
add_show_from_set
|
||||
(add_set_cmd ("prompt", class_support, var_string,
|
||||
|
@ -3938,7 +3946,7 @@ hitting return.");
|
|||
/* The set editing command is different depending whether or not the
|
||||
async version is run. NOTE: this difference is going to disappear
|
||||
as we make the event loop be the default engine of gdb. */
|
||||
if (!async_p)
|
||||
if (!event_loop_p)
|
||||
{
|
||||
add_show_from_set
|
||||
(add_set_cmd ("editing", class_support, var_boolean, (char *) &command_editing_p,
|
||||
|
@ -4062,7 +4070,7 @@ from the target.", &setlist),
|
|||
the async version is run. NOTE: this difference is going to
|
||||
disappear as we make the event loop be the default engine of
|
||||
gdb. */
|
||||
if (!async_p)
|
||||
if (!event_loop_p)
|
||||
{
|
||||
c = add_set_cmd ("annotate", class_obscure, var_zinteger,
|
||||
(char *) &annotation_level, "Set annotation_level.\n\
|
||||
|
@ -4081,7 +4089,7 @@ from the target.", &setlist),
|
|||
add_show_from_set (c, &showlist);
|
||||
c->function.sfunc = set_async_annotation_level;
|
||||
}
|
||||
if (async_p)
|
||||
if (event_loop_p)
|
||||
{
|
||||
add_show_from_set
|
||||
(add_set_cmd ("exec-done-display", class_support, var_boolean, (char *) &exec_done_display_p,
|
||||
|
|
|
@ -842,7 +842,7 @@ read_actions (t)
|
|||
#ifdef STOP_SIGNAL
|
||||
if (job_control)
|
||||
{
|
||||
if (async_p)
|
||||
if (event_loop_p)
|
||||
signal (STOP_SIGNAL, handle_stop_sig);
|
||||
else
|
||||
signal (STOP_SIGNAL, stop_sig);
|
||||
|
|
26
gdb/utils.c
26
gdb/utils.c
|
@ -84,6 +84,8 @@ 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 *run_cleanup_chain; /* cleaned up on each 'run' */
|
||||
static struct cleanup *exec_cleanup_chain; /* cleaned up on each execution command */
|
||||
/* cleaned up on each error from within an execution command */
|
||||
static struct cleanup *exec_error_cleanup_chain;
|
||||
|
||||
/* Pointer to what is left to do for an execution command after the
|
||||
target stops. Used only in asynchronous mode, by targets that
|
||||
|
@ -181,6 +183,14 @@ make_exec_cleanup (function, arg)
|
|||
return make_my_cleanup (&exec_cleanup_chain, function, arg);
|
||||
}
|
||||
|
||||
struct cleanup *
|
||||
make_exec_error_cleanup (function, arg)
|
||||
void (*function) PARAMS ((PTR));
|
||||
PTR arg;
|
||||
{
|
||||
return make_my_cleanup (&exec_error_cleanup_chain, function, arg);
|
||||
}
|
||||
|
||||
static void
|
||||
do_freeargv (arg)
|
||||
void *arg;
|
||||
|
@ -244,6 +254,13 @@ do_exec_cleanups (old_chain)
|
|||
do_my_cleanups (&exec_cleanup_chain, old_chain);
|
||||
}
|
||||
|
||||
void
|
||||
do_exec_error_cleanups (old_chain)
|
||||
register struct cleanup *old_chain;
|
||||
{
|
||||
do_my_cleanups (&exec_error_cleanup_chain, old_chain);
|
||||
}
|
||||
|
||||
void
|
||||
do_my_cleanups (pmy_chain, old_chain)
|
||||
register struct cleanup **pmy_chain;
|
||||
|
@ -275,6 +292,13 @@ discard_final_cleanups (old_chain)
|
|||
discard_my_cleanups (&final_cleanup_chain, old_chain);
|
||||
}
|
||||
|
||||
void
|
||||
discard_exec_error_cleanups (old_chain)
|
||||
register struct cleanup *old_chain;
|
||||
{
|
||||
discard_my_cleanups (&exec_error_cleanup_chain, old_chain);
|
||||
}
|
||||
|
||||
void
|
||||
discard_my_cleanups (pmy_chain, old_chain)
|
||||
register struct cleanup **pmy_chain;
|
||||
|
@ -1487,7 +1511,7 @@ prompt_for_continue ()
|
|||
++p;
|
||||
if (p[0] == 'q')
|
||||
{
|
||||
if (!async_p)
|
||||
if (!event_loop_p)
|
||||
request_quit (SIGINT);
|
||||
else
|
||||
async_request_quit (0);
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
1999-07-16 Ben Elliston <bje@cygnus.com>
|
||||
|
||||
* configure.in: Configure the testsuite directory for arm.
|
||||
* configure: Regenerate.
|
||||
|
||||
1999-04-08 Nick Clifton <nickc@cygnus.com>
|
||||
|
||||
* configure.in: Add support for MCore target.
|
||||
|
|
|
@ -1,3 +1,14 @@
|
|||
1999-09-25 Doug Evans <devans@casey.cygnus.com>
|
||||
|
||||
* cgen-ops.h (SUBWORD*): Delete cpu arg.
|
||||
(JOIN*): Delete cpu arg.
|
||||
|
||||
Tue Sep 21 17:14:16 1999 Dave Brolley <brolley@cygnus.com>
|
||||
|
||||
* genmloop.sh (@cpu@_scache_lookup): No longer takes last_insn_p
|
||||
parameter.
|
||||
(SET_LAST_INSN_P): Set last_insn_p flag in the scache element.
|
||||
|
||||
Mon Sep 20 21:44:06 1999 Geoffrey Keating <geoffk@cygnus.com>
|
||||
|
||||
* sim-fpu.c (i2fpu): Keep the guard bits sticky when converting
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/* Semantics ops support for CGEN-based simulators.
|
||||
Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
|
||||
Contributed by Cygnus Solutions.
|
||||
|
@ -285,15 +284,15 @@ extern SI TRUNCDISI (DI);
|
|||
#define TRUNCDISI(x) ((SI) (DI) (x))
|
||||
#endif
|
||||
|
||||
/* Composing/decomposing the various types. */
|
||||
|
||||
/* ??? endianness issues undecided */
|
||||
/* ??? CURRENT_TARGET_BYTE_ORDER usage wip */
|
||||
/* Composing/decomposing the various types.
|
||||
Word ordering is endian-independent. Words are specified most to least
|
||||
significant and word number 0 is the most significant word.
|
||||
??? May also wish an endian-dependent version. Later. */
|
||||
|
||||
#ifdef SEMOPS_DEFINE_INLINE
|
||||
|
||||
SEMOPS_INLINE SF
|
||||
SUBWORDSISF (SIM_CPU *cpu, SI in)
|
||||
SUBWORDSISF (SI in)
|
||||
{
|
||||
union { SI in; SF out; } x;
|
||||
x.in = in;
|
||||
|
@ -301,7 +300,7 @@ SUBWORDSISF (SIM_CPU *cpu, SI in)
|
|||
}
|
||||
|
||||
SEMOPS_INLINE SI
|
||||
SUBWORDSFSI (SIM_CPU *cpu, SF in)
|
||||
SUBWORDSFSI (SF in)
|
||||
{
|
||||
union { SF in; SI out; } x;
|
||||
x.in = in;
|
||||
|
@ -309,59 +308,44 @@ SUBWORDSFSI (SIM_CPU *cpu, SF in)
|
|||
}
|
||||
|
||||
SEMOPS_INLINE SI
|
||||
SUBWORDDISI (SIM_CPU *cpu, DI in, int word)
|
||||
SUBWORDDISI (DI in, int word)
|
||||
{
|
||||
if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN)
|
||||
{
|
||||
if (word == 0)
|
||||
return (UDI) in >> 32;
|
||||
else
|
||||
return in;
|
||||
}
|
||||
if (word == 0)
|
||||
return (UDI) in >> 32;
|
||||
else
|
||||
{
|
||||
if (word == 1)
|
||||
return (UDI) in >> 32;
|
||||
else
|
||||
return in;
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
||||
SEMOPS_INLINE SI
|
||||
SUBWORDDFSI (SIM_CPU *cpu, DF in, int word)
|
||||
SUBWORDDFSI (DF in, int word)
|
||||
{
|
||||
union { DF in; SI out[2]; } x;
|
||||
x.in = in;
|
||||
if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN)
|
||||
return x.out[word];
|
||||
/* Note: typedef UDI DF; */
|
||||
if (word == 0)
|
||||
return (UDI) in >> 32;
|
||||
else
|
||||
return x.out[!word];
|
||||
return in;
|
||||
}
|
||||
|
||||
SEMOPS_INLINE SI
|
||||
SUBWORDXFSI (SIM_CPU *cpu, XF in, int word)
|
||||
SUBWORDXFSI (XF in, int word)
|
||||
{
|
||||
/* Note: typedef struct { SI parts[3]; } XF; */
|
||||
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];
|
||||
return x.out[word];
|
||||
}
|
||||
|
||||
SEMOPS_INLINE SI
|
||||
SUBWORDTFSI (SIM_CPU *cpu, TF in, int word)
|
||||
SUBWORDTFSI (TF in, int word)
|
||||
{
|
||||
/* Note: typedef struct { SI parts[4]; } TF; */
|
||||
union { TF in; SI out[4]; } x;
|
||||
x.in = in;
|
||||
if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN)
|
||||
return x.out[word];
|
||||
else
|
||||
return x.out[3 - word];
|
||||
return x.out[word];
|
||||
}
|
||||
|
||||
SEMOPS_INLINE DI
|
||||
JOINSIDI (SIM_CPU *cpu, SI x0, SI x1)
|
||||
JOINSIDI (SI x0, SI x1)
|
||||
{
|
||||
if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN)
|
||||
return MAKEDI (x0, x1);
|
||||
|
@ -370,7 +354,7 @@ JOINSIDI (SIM_CPU *cpu, SI x0, SI x1)
|
|||
}
|
||||
|
||||
SEMOPS_INLINE DF
|
||||
JOINSIDF (SIM_CPU *cpu, SI x0, SI x1)
|
||||
JOINSIDF (SI x0, SI x1)
|
||||
{
|
||||
union { SI in[2]; DF out; } x;
|
||||
if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN)
|
||||
|
@ -381,7 +365,7 @@ JOINSIDF (SIM_CPU *cpu, SI x0, SI x1)
|
|||
}
|
||||
|
||||
SEMOPS_INLINE XF
|
||||
JOINSIXF (SIM_CPU *cpu, SI x0, SI x1, SI x2)
|
||||
JOINSIXF (SI x0, SI x1, SI x2)
|
||||
{
|
||||
union { SI in[3]; XF out; } x;
|
||||
if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN)
|
||||
|
@ -392,7 +376,7 @@ JOINSIXF (SIM_CPU *cpu, SI x0, SI x1, SI x2)
|
|||
}
|
||||
|
||||
SEMOPS_INLINE TF
|
||||
JOINSITF (SIM_CPU *cpu, SI x0, SI x1, SI x2, SI x3)
|
||||
JOINSITF (SI x0, SI x1, SI x2, SI x3)
|
||||
{
|
||||
union { SI in[4]; TF out; } x;
|
||||
if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN)
|
||||
|
@ -404,17 +388,17 @@ JOINSITF (SIM_CPU *cpu, SI x0, SI x1, SI x2, SI x3)
|
|||
|
||||
#else
|
||||
|
||||
SF SUBWORDSISF (SIM_CPU *, SI);
|
||||
SI SUBWORDSFSI (SIM_CPU *, SF);
|
||||
SI SUBWORDDISI (SIM_CPU *, DI, int);
|
||||
SI SUBWORDDFSI (SIM_CPU *, DF, int);
|
||||
SI SUBWORDXFSI (SIM_CPU *, XF, int);
|
||||
SI SUBWORDTFSI (SIM_CPU *, TF, int);
|
||||
SF SUBWORDSISF (SI);
|
||||
SI SUBWORDSFSI (SF);
|
||||
SI SUBWORDDISI (DI, int);
|
||||
SI SUBWORDDFSI (DF, int);
|
||||
SI SUBWORDXFSI (XF, int);
|
||||
SI SUBWORDTFSI (TF, int);
|
||||
|
||||
DI JOINSIDI (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);
|
||||
DI JOINSIDI (SI, SI);
|
||||
DF JOINSIDF (SI, SI);
|
||||
XF JOINSIXF (SI, SI, SI);
|
||||
TF JOINSITF (SI, SI, SI, SI);
|
||||
|
||||
#endif /* SUBWORD,JOIN */
|
||||
|
||||
|
|
|
@ -651,7 +651,7 @@ if [ x$scache = xyes -a x$parallel != xno ] ; then
|
|||
|
||||
static INLINE SCACHE *
|
||||
@cpu@_scache_lookup (SIM_CPU *current_cpu, PCADDR vpc, SCACHE *scache,
|
||||
unsigned int hash_mask, int *last_insn_p, int FAST_P)
|
||||
unsigned int hash_mask, int FAST_P)
|
||||
{
|
||||
/* First step: look up current insn in hash table. */
|
||||
SCACHE *sc = scache + SCACHE_HASH_PC (vpc, hash_mask);
|
||||
|
@ -663,7 +663,7 @@ static INLINE SCACHE *
|
|||
if (! FAST_P)
|
||||
PROFILE_COUNT_SCACHE_MISS (current_cpu);
|
||||
|
||||
#define SET_LAST_INSN_P(last_p) do { *last_insn_p = (last_p); } while (0)
|
||||
#define SET_LAST_INSN_P(last_p) do { sc->last_insn_p = (last_p); } while (0)
|
||||
/* begin extract-scache */
|
||||
EOF
|
||||
|
||||
|
|
5
sim/configure
vendored
5
sim/configure
vendored
|
@ -1397,7 +1397,10 @@ extra_subdirs=common
|
|||
# convention, else the table becomes a real mess to understand and maintain.
|
||||
|
||||
case "${target}" in
|
||||
arm*-*-*) sim_target=arm ;;
|
||||
arm*-*-*)
|
||||
sim_target=arm
|
||||
extra_subdirs="${extra_subdirs} testsuite"
|
||||
;;
|
||||
strongarm*-*-*) sim_target=arm ;;
|
||||
thumb*-*-*) sim_target=arm ;;
|
||||
d10v-*-*) sim_target=d10v ;;
|
||||
|
|
|
@ -47,7 +47,10 @@ extra_subdirs=common
|
|||
# convention, else the table becomes a real mess to understand and maintain.
|
||||
|
||||
case "${target}" in
|
||||
arm*-*-*) sim_target=arm ;;
|
||||
arm*-*-*)
|
||||
sim_target=arm
|
||||
extra_subdirs="${extra_subdirs} testsuite"
|
||||
;;
|
||||
strongarm*-*-*) sim_target=arm ;;
|
||||
thumb*-*-*) sim_target=arm ;;
|
||||
d10v-*-*) sim_target=d10v ;;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue