mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 03:54:41 +08:00
import gdb-1999-09-21
This commit is contained in:
parent
54af6ff675
commit
c2c6d25f0d
524
gdb/ChangeLog
524
gdb/ChangeLog
@ -1,3 +1,527 @@
|
||||
Tue Sep 21 14:55:29 1999 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
From 1999-08-20 J.T. Conklin <jtc@redback.com>:
|
||||
* remote.c (read_frame): expand cisco run-length encoding variant
|
||||
inline as is done for the standard encoding.
|
||||
(remote_cisco_expand): Removed.
|
||||
|
||||
1999-09-20 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
|
||||
|
||||
* event-loop.c: Include <sys/time.h>.
|
||||
|
||||
1999-09-20 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
|
||||
|
||||
* ser-ocd.c: (ser_ocd_open, ser_ocd_raw, ser_ocd_readchar,
|
||||
ser_ocd_setbaudrate, ser_ocd_write, ser_ocd_close,
|
||||
ser_ocd_get_tty_state, ser_ocd_set_tty_state): Remove unused
|
||||
prototypes.
|
||||
(ocd_readremote): Remove.
|
||||
(ocd_write): Remove unused var 'c'.
|
||||
|
||||
1999-09-20 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
|
||||
|
||||
* event-top.c (change_line_handler): Cleanup dead code. Add comments.
|
||||
* event-loop.c: Cleanup #if 0 code.
|
||||
|
||||
* event-loop.h (timer_handler_func): New function type.
|
||||
(create_timer): Export function.
|
||||
(delete_timer): Export function.
|
||||
|
||||
* event-loop.c: Add timeout and timeout_valid fields to
|
||||
gdb_notifier. New structures gdb_timer and timer_list.
|
||||
(gdb_do_one_event): Check whether there are any timers tht are
|
||||
ready, before going to wait.
|
||||
(gdb_wait_for_event): If the timeout structure is meaningful, pass
|
||||
that to select()/poll().
|
||||
(create_timer): New function. Creates a timer.
|
||||
(delete_timer): New function. Deletes a timer.
|
||||
(handle_timer_event): New function. Deals with timers that are ready.
|
||||
(poll_timers): New Function. Chack whether timers have expired.
|
||||
|
||||
Mon Sep 20 17:00:06 1999 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* remote.c (getpkt, putpkt, remote_console_output): Move
|
||||
declaration from here.
|
||||
* remote.h: To here. New file.
|
||||
* tracepoint.c(putpkt, getpkt, remote_console_output): Delete
|
||||
declarations. Moved to "remote.h".
|
||||
* Makefile.in (remote_h): Define.
|
||||
* remote.c, tracepoint.c: Include "remote.h".
|
||||
* Makefile.in (tracepoint.o, remote.o): Add dependency on
|
||||
"remote.h".
|
||||
|
||||
* remote.h (remote_cisco_objfile_relocate,
|
||||
cleanup_sigint_signal_handler): Add declaration. Include FIXME.
|
||||
* infrun.c: Include "remote.h".
|
||||
(complete_execution): Delete local extern declaration
|
||||
of ``cleanup_sigint_signal_handler''.
|
||||
* Makefile.in (infrun.o): Add dependency on remote.h.
|
||||
|
||||
Mon Sep 20 13:41:04 1999 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* kod.c (ecos_kod_open, ecos_kod_request, ecos_kod_close,
|
||||
cisco_kod_open, cisco_kod_request, cisco_kod_close): Move
|
||||
declarations from here.
|
||||
* kod.h: To here. New file.
|
||||
* kod-cisco.c, kod.c: Include "kod.h".
|
||||
* Makefile.in (kod-cisco.o, kod.o): Add dependency on "kod.h".
|
||||
|
||||
* kod.h (kod_display_callback_ftype, kod_query_callback_ftype):
|
||||
New function types.
|
||||
* kod.h (kod_cisco_open): Use in declaration.
|
||||
* kod.c (gdb_kod_open): Update definition.
|
||||
* kod-cisco.c (cisco_kod_open): Update definition.
|
||||
|
||||
Mon Sep 20 12:13:27 1999 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* mn10300-tdep.c (_initialize_mn10300_tdep): Add declaration.
|
||||
|
||||
* breakpoint.c (until_break_command_continuation): Add
|
||||
declaration. Make static.
|
||||
* event-top.c (rl_callback_read_char_wrapper): Ditto.
|
||||
|
||||
Fri Sep 17 19:28:17 1999 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* source.c: Include "source.h".
|
||||
(open_source_file, find_source_lines): Move declaration from here.
|
||||
* source.h: New file. To here.
|
||||
* Makefile.in (source.o): Add dependency on source.h.
|
||||
|
||||
* breakpoints.c (delete_command): Move declaration from here.
|
||||
* breakpoints.h (delete_command): To here.
|
||||
|
||||
1999-09-18 Jim Blandy <jimb@cris.red-bean.com>
|
||||
|
||||
* hppa-tdep.c (in_solib_call_trampoline): If we can't recognize
|
||||
the instruction we're at, we're not in a stub.
|
||||
|
||||
Sat Sep 18 07:13:03 1999 Jeffrey A Law (law@cygnus.com)
|
||||
|
||||
* dwarf2read.c (dwarf_decode_lines): Correctly handle
|
||||
DW_LNS_const_add_pc.
|
||||
|
||||
1999-09-18 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
|
||||
|
||||
* remote.c (remote_async_open_1): Use inferior_event_handler to
|
||||
handle inferior events.
|
||||
(extended_remote_async_create_inferior): Ditto.
|
||||
|
||||
* serial.h (serial_event_ftype): Add two pars.
|
||||
|
||||
* ser-unix.c (ser_unix_event): Add two parameters, error and fd.
|
||||
Pass those into the call to the actual inferior event handler.
|
||||
|
||||
* infrun.c (complete_execution): Stdin handler is stdin_event_handler.
|
||||
|
||||
* event-top.h (stdin_event_handler): Export new function.
|
||||
|
||||
* event-top.c (stdin_event_handler): New function. Smarter handler
|
||||
for events on stdin.
|
||||
(change_line_handler): Don't need to update the handler for stdin
|
||||
here anymore.
|
||||
(_initialize_event_loop): Stdin handler is now stdin_event_handler.
|
||||
|
||||
* event-loop.h: (handler_func): Change signature, adding two new
|
||||
args.
|
||||
(sig_handler_func): New function type. It is the old handler_func.
|
||||
(create_async_signal_handler): Update to use sig_handler_func.
|
||||
(delete_async_signal_handler): Prototype for new function.
|
||||
|
||||
* event-loop.c: Include "inferior.h".
|
||||
(struct file_handler): Add field error, to indicate error
|
||||
condition on fd.
|
||||
(struct async_signal_handler): Rename type of proc field.
|
||||
(add_file_handler): Add exception condition as something select()
|
||||
should report.
|
||||
(handle_file_event): In case of error on the fd, record this in
|
||||
the file_handler structure. Update call to (*proc)() to match new
|
||||
signature.
|
||||
(gdb_wait_for_event): If select() or poll() return error, report
|
||||
this to user.
|
||||
(create_async_signal_handler): Change first param type to
|
||||
sig_handler_func*.
|
||||
(inferior_event_handler): New function. Smarter inferior event
|
||||
handling.
|
||||
|
||||
1999-09-18 Jim Blandy <jimb@cris.red-bean.com>
|
||||
|
||||
* pa64solib.c (pa64_solib_create_inferior_hook): Remove code which
|
||||
tries to set __d_pid; it's not relevant to PA64 shared libraries.
|
||||
|
||||
A psymtab's texthigh element, and a block's endaddr element, are
|
||||
the address past the end of the address range, never the address
|
||||
of the last byte. These data structures mean the same thing on
|
||||
forty different architectures; there's no reason they should be
|
||||
different on HP/UX.
|
||||
* symtab.c (find_pc_sect_psymtab): Remove special case for HP/UX.
|
||||
(find_pc_sect_symtab): Same.
|
||||
* objfiles.c (find_pc_sect_section): Same.
|
||||
|
||||
Sat Sep 18 07:13:03 1999 Jeffrey A Law (law@cygnus.com)
|
||||
|
||||
* hppa-tdep.c (internalize_unwinds): Handle PA64 shared libraries
|
||||
correctly
|
||||
|
||||
* hppa-tdep.c (in_solib_call_trampoline): Handle PA64 shared library
|
||||
trampolines.
|
||||
|
||||
1999-09-17 Jim Blandy <jimb@zwingli.cygnus.com>
|
||||
|
||||
* breakpoint.c (permanent_breakpoint_here_p): Delete.
|
||||
Accidentally left over from previous changes.
|
||||
|
||||
1999-09-17 Jim Blandy <jimb@cris.red-bean.com>
|
||||
|
||||
* config/pa/tm-hppa64.h (ARGS_GROW_DOWNWARD): Deleted. There are
|
||||
many more differences between the 32- and 64-bit ABI's than the
|
||||
direction the arguments grow, so this name is misleading.
|
||||
(PA20W_CALLING_CONVENTIONS): Define this instead.
|
||||
* config/pa/tm-hppa.h (ARGS_GROW_DOWNWARD): Delete.
|
||||
* hppa-tdep.c (hppa_push_arguments): Split into two separate
|
||||
functions, depending on whether PA20W_CALLING_CONVENTIONS is
|
||||
#defined. These implement completely separate specifications,
|
||||
they don't really share that much code anyway, and this is much
|
||||
more readable. Specifically: leave a 16-byte, not 32-byte, frame
|
||||
marker; correctly align objects larger than eight bytes; promote
|
||||
all integral scalar arguments smaller than eight bytes to a full
|
||||
register width; pad aggregates smaller than eight bytes on the
|
||||
right.
|
||||
|
||||
Thu Sep 16 17:33:35 1999 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* remote.c (remote_async_open_1): Use SERIAL_ASYNC to
|
||||
enable/disable async event callback on serial port. Use
|
||||
SERIAL_CAN_ASYNC_P / SERIAL_IS_ASYNC_P to determine if / when
|
||||
async mode.
|
||||
(remote_async_resume, remote_async_detach, remote_async_kill,
|
||||
extended_remote_async_create_inferior, remote_async_wait): Ditto.
|
||||
|
||||
* ser-unix.c (hardwire_readchar): When ASYNC, only read a single
|
||||
character.
|
||||
(ser_unix_readchar): Ditto. Problems occure with back-to-back
|
||||
data from a target. The ASYNC code can loose the second data
|
||||
chunk.
|
||||
|
||||
* serial.c (serial_fdopen): Initialize async_handler and
|
||||
async_context.
|
||||
|
||||
1999-09-16 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
|
||||
|
||||
* utils.c (discard_all_continuations): New function.
|
||||
* defs.h: (discard_all_continuations): Add prototype.
|
||||
|
||||
1999-09-16 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
|
||||
|
||||
* valops.c: Remove prototype for search_struct_field_aux(). THe
|
||||
function was nowhere in the file.
|
||||
(value_ind): Remove unused var real_val.
|
||||
(value_find_oload_method_list): Remove unused var v.
|
||||
(find_overload_match): Remove extra declaration of var jj.
|
||||
|
||||
* Makefile.in (event_top_h): Define. Add dependency on this for
|
||||
every file that includes event-top.h.
|
||||
|
||||
Thu Sep 16 17:33:35 1999 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* serial.c (serial_open): Delete ``&'' device.
|
||||
* ser-unix.c (_initialize_ser_hardwire): Make the "hardwire"
|
||||
device async. Delete temporary "async-hardwire" device.
|
||||
|
||||
Thu Sep 16 16:27:13 1999 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* serial.h (SERIAL_IS_ASYNC_P): Define. Non-zero when serial
|
||||
device is in async mode.
|
||||
(SERIAL_CAN_ASYNC_P): Rename SERIAL_ASYNC_P.
|
||||
* serial.c (serial_is_async_p): Implement.
|
||||
(serial_can_async_p): Rename serial_async_p.
|
||||
(serial_open): Initialize ASYNC_HANDLER and ASYNC_CONTEXT. Save
|
||||
the original name in SCB instead of the stripped name.
|
||||
|
||||
Thu Sep 16 12:20:11 1999 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* serial.h (struct serial_ops): Add field ASYNC.
|
||||
(SERIAL_ASYNC, SERIAL_ASYNC_P): New macros.
|
||||
(struct _serial_t): Add fields async_context and async_handler.
|
||||
* serial.c (serial_async, serial_async_p): Implement.
|
||||
|
||||
* ser-unix.c: Include "event-loop.h".
|
||||
(ser_unix_async), ser-unix.c: New function. Implement async mode.
|
||||
(async_event): Handle async events.
|
||||
* ser-unix.c (_initialize_ser_hardwire), ser-tcp.c
|
||||
(_initialize_ser_tcp), ser-pipe.c (_initialize_ser_pipe): Enable
|
||||
ASYNC.
|
||||
|
||||
* serial.c (serial_open): Discard leading ``|'' before opening a
|
||||
pipe device.
|
||||
* ser-pipe.c (pipe_open): Adjust.
|
||||
* serial.c (serial_open): Add ``&'' prefix so that
|
||||
"async-hardwire" device can be explicitly selected. Work in
|
||||
progress.
|
||||
* ser-unix.c: Register "async-hardwire" device.
|
||||
|
||||
Thu Sep 16 09:04:53 1999 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* ser-unix.h: New file. Declare generic ser_unix functions.
|
||||
* ser-unix.c (ser_unix_nop_get_tty_state,
|
||||
ser_unix_nop_set_tty_state, ser_unix_nop_raw, ser_unix_wait_for,
|
||||
ser_unix_readchar, ser_unix_nop_noflush_set_tty_state,
|
||||
ser_unix_nop_print_tty_state, ser_unix_nop_setbaudrate,
|
||||
ser_unix_nop_setstopbits, ser_unix_write,
|
||||
ser_unix_nop_flush_output, ser_unix_nop_flush_input,
|
||||
ser_unix_nop_send_break, ser_unix_nop_drain_output): New
|
||||
functions.
|
||||
* ser-unix.c: Include <sys/wait.h>, <sys/socket.h>,
|
||||
"gdb_string.h".
|
||||
|
||||
* ser-tcp.c (_initialize_ser_tcp), ser-unix.c
|
||||
(_initialize_ser_hardwire), ser-pipe.c (_initialize_ser_tcp):
|
||||
Initialize ops vector using assignment.
|
||||
|
||||
* ser-pipe.c, ser-tcp.c, ser-unix.c: Include ser-unix.h.
|
||||
|
||||
* ser-pipe.c (pipe_get_tty_state, pipe_set_tty_state,
|
||||
pipe_return_0, pipe_raw, wait_for, pipe_readchar,
|
||||
pipe_noflush_set_tty_state, pipe_print_tty_state,
|
||||
pipe_setbaudrate, pipe_setstopbits, pipe_write), ser-tcp.c
|
||||
(tcp_get_tty_state, tcp_set_tty_state, tcp_return_0, tcp_raw,
|
||||
wait_for, tcp_readchar, tcp_noflush_set_tty_state,
|
||||
tcp_print_tty_state, tcp_setbaudrate, tcp_setstopbits, tcp_write):
|
||||
Delete functions.
|
||||
|
||||
1999-09-15 Stan Shebs <shebs@andros.cygnus.com>
|
||||
|
||||
* d10v-tdep.c (remote_d10v_translate_xfer_address): Move to here
|
||||
from remote-d10v.c, also change the memory translation to its
|
||||
previous version.
|
||||
* remote-d10v.c: Remove.
|
||||
* config/d10v/d10v.mt (TDEPFILES): Remove remote-d10v.o.
|
||||
|
||||
1999-09-15 Jim Blandy <jimb@cris.red-bean.com>
|
||||
|
||||
* breakpoint.c (remove_breakpoint): Return zero, not nothing.
|
||||
|
||||
1999-09-14 Jim Blandy <jimb@cris.red-bean.com>
|
||||
|
||||
* hppa-tdep.c (frame_chain): If the unwind info says we've saved
|
||||
r3, don't trust it. Call get_frame_saved_regs and see if we can
|
||||
actually find an address for r3 there.
|
||||
|
||||
* pa64solib.c (pa64_sharedlibrary_info_command): Text fix.
|
||||
|
||||
Tue Sep 14 14:34:28 1999 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* serial.h (DEPRECATED_SERIAL_FD): Define.
|
||||
* serial.c (deprecated_serial_fd): New function.
|
||||
|
||||
* remote.c (remote_async_open_1, remote_async_open_1,
|
||||
remote_async_detach, remote_async_kill,
|
||||
extended_remote_async_create_inferior, minitelnet): Update.
|
||||
* remote-es.c (es1800_open, es1800_close, es1800_transparent): Update.
|
||||
|
||||
* remote-st.c (connect_command), remote-os9k.c (connect_command):
|
||||
Fix. Call FD_SET et.al. with FD instead of serial_t.
|
||||
|
||||
1999-09-14 Jim Blandy <jimb@cris.red-bean.com>
|
||||
|
||||
* hppa-tdep.c (hppa_frame_find_saved_regs): The two possible
|
||||
instructions for saving the return pointer (32- and 64-bit) save
|
||||
it at different offsets.
|
||||
|
||||
* config/pa/tm-hppa64.h: Doc fix.
|
||||
|
||||
* defs.h (continuation): Make this a typedef.
|
||||
|
||||
* Makefile.in (gdbtk.o, gdbtk-cmds.o): Depend on $(top_h).
|
||||
|
||||
* Makefile.in (i386-linux-nat.o): Depend on symfile.h, not
|
||||
$(symfile_h); the latter has no definition.
|
||||
|
||||
* breakpoint.c (breakpoint_here_p): Remove meaningless code,
|
||||
testing b->enable against shlib_disabled and call_disabled after
|
||||
we know it is enabled.
|
||||
|
||||
Implement "permanent breakpoints" --- breakpoints that are
|
||||
hardwired into the inferior's code. GDB knows they're there, but
|
||||
doesn't try to insert or remove them, etc.
|
||||
* breakpoint.h (enum enable): Add `permanent' enablement state.
|
||||
* breakpoint.c (make_breakpoint_permanent): New function.
|
||||
* breakpoint.h (make_breakpoint_permanent): Add declaration.
|
||||
* breakpoint.c (insert_breakpoints): Don't bother to insert
|
||||
permanent breakpoints...
|
||||
(remove_breakpoint): ... or remove them.
|
||||
(breakpoint_here_p): Handle `permanent' like `enabled'. Change
|
||||
return value to indicate whether it's a permanent breakpoint here,
|
||||
or an ordinary breakpoint.
|
||||
* breakpoint.h (enum breakpoint_here): New enum.
|
||||
(breakpoint_here_p): Change declaration.
|
||||
* breakpoint.h (breakpoint_1): Extend bpenables to cover all the
|
||||
enablement states.
|
||||
(describe_other_breakpoints): Describe permanent breakpoints.
|
||||
(check_duplicates): If one of the breakpoints at ADDRESS is a
|
||||
permanent breakpoint, treat all the others as the duplicates, so
|
||||
we don't try to insert or remove any of them. Verify that only
|
||||
the permanent breakpoint is actually inserted.
|
||||
(delete_breakpoint): Complain if we discover that another
|
||||
breakpoint was inserted at the same place as a permanent
|
||||
breakpoint.
|
||||
(disable_breakpoint): Fail silently if asked to disable a
|
||||
permanent breakpoint.
|
||||
(do_enable_breakpoint): Don't change a permanent breakpoint's
|
||||
enablement to ordinary `enabled'. Leave it alone.
|
||||
(create_solib_event_breakpoint): Return the
|
||||
breakpoint object created.
|
||||
* breakpoint.h (create_solib_event_breakpoint): Fix declaration.
|
||||
* pa64solib.c (pa64_solib_create_inferior_hook): Do turn on the
|
||||
DT_HP_DEBUG_CALLBACK flag in the dynamic linker, so it will call
|
||||
__dld_break, which contains the permanent breakpoint, when interesting
|
||||
things happen. Tell GDB that the breakpoint in __dld_break is
|
||||
permanent.
|
||||
* gdbtk-cmds.c (gdb_get_breakpoint_info): Report a permanent
|
||||
breakpoint as enabled.
|
||||
* infrun.c (SKIP_PERMANENT_BREAKPOINT): Provide default definition.
|
||||
(default_skip_permanent_breakpoint): New function.
|
||||
(resume): If we're trying to resume at a permanent breakpoint, use
|
||||
SKIP_PERMANENT_BREAKPOINT to step over it.
|
||||
* hppa-tdep.c (hppa_skip_permanent_breakpoint): New function.
|
||||
* config/pa/tm-hppa.h (hppa_skip_permanent_breakpoint): Declare.
|
||||
(SKIP_PERMANENT_BREAKPOINT): Define.
|
||||
|
||||
1999-09-14 Kevin Buettner <kevinb@cygnus.com>
|
||||
|
||||
* symtab.h, minsyms.c (find_stab_function_addr): Changed
|
||||
type of second parameter from partial_symtab * to char *.
|
||||
Fixed all callers.
|
||||
* minsyms.c (find_stab_function_addr): Look for minimal
|
||||
symbol without filename if filename based search fails.
|
||||
* dbxread.c (process_one_symbol): Call find_stab_function_addr()
|
||||
in place of inline code with identical functionality.
|
||||
* partial-stab.h (case N_FUN, descriptors 'F' and 'f'): Look
|
||||
up symbol's address from minimal symbol table when N_FUN
|
||||
address is missing. Also, make sure this value is used for
|
||||
calculating the value of the texthigh field.
|
||||
|
||||
1999-09-14 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
|
||||
|
||||
* event-loop.c (create_file_handler): Increment the total number
|
||||
of file descriptors for the poll case, only if this is a new file
|
||||
desc.
|
||||
|
||||
1999-09-14 Eli Zaretskii <eliz@is.elta.co.il>
|
||||
|
||||
* go32-nat.c: misc minor cleanups and fixes missed in last patch.
|
||||
|
||||
Tue Sep 14 12:37:33 1999 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* serial.h (SERIAL_PRINT_TTY_STATE): Add STREAM parameter.
|
||||
(union serial_ops): Update.
|
||||
|
||||
* ser-unix.c (hardwire_print_tty_state, ser-tcp.c
|
||||
(tcp_print_tty_state), ser-pipe.c (pipe_print_tty_state,
|
||||
ser-go32.c (dos_print_tty_state, ser-mac.c (mac_print_tty_state,
|
||||
ser-ocd.c (ocd_print_tty_state, ser-e7kpc.c
|
||||
(e7000pc_print_tty_state): Update.
|
||||
* inflow.c (child_terminal_info): Update.
|
||||
* serial.c (serial_print_tty_state): Update.
|
||||
|
||||
Tue Sep 14 11:41:37 1999 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* serial.c, serial.h, ser-tcp.c, ser-unix.c, ser-pipe.c: Convert
|
||||
all functions to ISO-C.
|
||||
* serial.h, serial.c: Move all indirect macro function calls from
|
||||
serial.h into serial.c.
|
||||
(serial_drain_output, serial_flush_output, serial_flush_input,
|
||||
serial_raw, serial_get_tty_state, serial_set_tty_state,
|
||||
serial_print_tty_state, serial_noflush_set_tty_state,
|
||||
serial_setbaudrate, serial_setstopbits): New functions.
|
||||
(do_serial_close): Rename serial_close.
|
||||
(serial_close, serial_un_fdopen): New functions. Call
|
||||
do_serial_close.
|
||||
|
||||
1999-09-13 James Ingham <jingham@leda.cygnus.com>
|
||||
|
||||
* symtab.c (decode_line_1): Find the rightmost parenthesis in the
|
||||
expression, not the leftmost. This allows us to parse function
|
||||
declarations with embedded function prototypes.
|
||||
|
||||
Mon Sep 13 18:39:31 1999 Jeffrey A Law (law@cygnus.com)
|
||||
|
||||
* pa64solib.c (pa64_sharedlibrary_info_command): Fix typos.
|
||||
|
||||
1999-09-13 Kevin Buettner <kevinb@cygnus.com>
|
||||
|
||||
* i386-tdep.c (i386_extract_return_value): ifdef'd so that
|
||||
non-linux targets will work again.
|
||||
(i386_do_registers_info, i386_print_register): Revert changes
|
||||
of 1999-09-03; these functions have been removed because they
|
||||
are Linux specific and break non-Linux builds. This functionality
|
||||
will be restored after FP support unification has been achieved.
|
||||
* i387-tdep.c (i387_print_register, void i387_float_info):
|
||||
Likewise.
|
||||
* config/i386/tm-linux.h (i387_float_info, FLOAT_INFO,
|
||||
DO_REGISTERS_INFO, i386_do_registers_info,
|
||||
i387_print_register): Likewise.
|
||||
|
||||
1999-09-13 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
|
||||
|
||||
* event-top.c (call_readline): Change to accept gdb_client_data as
|
||||
param.
|
||||
(rl_callback_read_char_wrapper): New function to match what the
|
||||
event loop expects and what readline expects.
|
||||
(change_line_handler): Make call_readline point to
|
||||
rl_callback_read_char_wrapper, instead of rl_callback_read_char.
|
||||
(_initialize_event_loop): Ditto.
|
||||
(gdb_readline2): Change parameter to gdb_client_data.
|
||||
* event-top.h (call_readline, gdb_readline2): Change accordingly.
|
||||
|
||||
* event-loop.c (add_file_handler): Change 2nd par to
|
||||
handler_func*. No more need for casting.
|
||||
* event-loop.h (create_async_signal_handler): Change accordingly.
|
||||
|
||||
* inferior.h (fetch_inferior_event): Change parameter to void*.
|
||||
* infrun.c (fetch_inferior_event): Ditto.
|
||||
|
||||
1999-09-13 Stan Shebs <shebs@andros.cygnus.com>
|
||||
|
||||
* infrun.c (step_into_function): New function, broken out from the
|
||||
step_into_function label in handle_inferior_event.
|
||||
(handle_inferior_event): Change a goto into a function call.
|
||||
|
||||
1999-09-13 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
|
||||
|
||||
* event-top.h: New file. All the exported vars and functions from
|
||||
event-top.c.
|
||||
|
||||
* event-loop.h (struct gdb_event, event_handler_func,
|
||||
file_handler, async_signal_handler, SELECT_MASK, fd_mask, NBBY,
|
||||
FD_SETSIZE, howmany, NFDBITS, MASK_SIZE): Move to event-loop.c.
|
||||
(struct prompts, PROMPT, PREFIX, SUFFIX, display_gdb_prompt,
|
||||
async_init_signals, set_async_editing_command,
|
||||
set_async_annotation_level, set_async_prompt, handle_stop_sig,
|
||||
handle_sigint, pop_prompt, push_prompt, gdb_readline2,
|
||||
mark_async_signal_handler_wrapper, async_request_quit,
|
||||
async_command_editing_p, exec_done_display_p,
|
||||
async_annotation_suffix, new_async_prompt, the_prompts,
|
||||
call_readline, input_handler, input_fd): Move to event-top.h.
|
||||
(All function prototypes): Don't use PARAMS anymore.
|
||||
|
||||
* event-loop.c: (struct gdb_event, event_handler_func,
|
||||
file_handler, async_signal_handler, SELECT_MASK, fd_mask, NBBY,
|
||||
FD_SETSIZE, howmany, NFDBITS, MASK_SIZE): Move to here from
|
||||
event-loop.h.
|
||||
Include event-top.h. Remove use of PARAMS. ANSIfy functions headers.
|
||||
|
||||
* event-top.c: Include event-top.h. Include "signals.h", not
|
||||
<signals.h>.
|
||||
Remove use of PARAMS. ANSIfy functions headers.
|
||||
(handle_stop_sig): move prototype to event-top.h.
|
||||
|
||||
* remote.c: Include event-top.h. Make it understand
|
||||
async_signal_handler type.
|
||||
* infrun.c: Include event-top.h.
|
||||
* mi-main.c: Ditto.
|
||||
* top.c Ditto.
|
||||
* utils.c: Ditto.
|
||||
|
||||
Mon Sep 13 18:54:05 1999 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* gdbarch.sh: Describe each of the fields.
|
||||
|
@ -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 = 19990913
|
||||
VERSION = 19990921
|
||||
DIST=gdb
|
||||
|
||||
LINT=/usr/5bin/lint
|
||||
@ -454,8 +454,10 @@ top_h = top.h
|
||||
inferior_h = inferior.h $(breakpoint_h)
|
||||
tracepoint_h = tracepoint.h
|
||||
ax_h = ax.h
|
||||
event_loop_h = event-loop.h
|
||||
version_h = version.h
|
||||
event_loop_h = event-loop.h
|
||||
event_top_h = event-top.h
|
||||
remote_h = remote.h
|
||||
version_h = version.h
|
||||
|
||||
# Header files that need to have srcdir added. Note that in the cases
|
||||
# where we use a macro like $(gdbcmd_h), things are carefully arranged
|
||||
@ -1122,10 +1124,10 @@ eval.o: eval.c $(bfd_h) $(defs_h) $(expression_h) $(frame_h) \
|
||||
$(gdbtypes_h) language.h $(symtab_h) target.h $(value_h) \
|
||||
gdb_string.h
|
||||
|
||||
event-loop.o: event-loop.c $(defs_h) $(top_h) $(event_loop_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) 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
|
||||
@ -1143,7 +1145,7 @@ fork-child.o: fork-child.c $(wait_h) $(defs_h) $(gdbcore_h) \
|
||||
# to fix breakpoint.c's compiler warnings.
|
||||
tracepoint.o: tracepoint.c $(defs_h) $(symtab_h) $(frame_h) $(tracepoint_h) \
|
||||
$(gdbtypes_h) $(expression_h) $(gdbcmd_h) $(value_h) target.h \
|
||||
language.h gdb_string.h $(readline_headers)
|
||||
language.h gdb_string.h $(readline_headers) $(remote_h)
|
||||
$(CC) -c $(INTERNAL_WARN_CFLAGS) $(NO_WERROR_CFLAGS) $<
|
||||
|
||||
gdbarch.o: gdbarch.c $(defs_h) $(bfd_h) $(gdbcmd_h)
|
||||
@ -1217,7 +1219,8 @@ infptrace.o: infptrace.c $(defs_h) $(gdbcore_h) $(inferior_h) target.h \
|
||||
gdb_string.h $(wait_h) $(command_h)
|
||||
|
||||
infrun.o: infrun.c $(wait_h) $(defs_h) $(gdbcmd_h) $(gdbcore_h) \
|
||||
$(inferior_h) target.h gdbthread.h gdb_string.h $(event_loop_h)
|
||||
$(inferior_h) target.h gdbthread.h gdb_string.h $(event_loop_h) \
|
||||
$(event_top_h) target.h
|
||||
|
||||
inftarg.o: inftarg.c $(wait_h) $(defs_h) $(gdbcore_h) $(inferior_h) \
|
||||
target.h terminal.h $(command_h)
|
||||
@ -1241,9 +1244,9 @@ jv-valprint.o: jv-valprint.c $(bfd_h) $(defs_h) $(symtab_h) $(gdbtypes_h) \
|
||||
$(expression_h) $(value_h) $(INCLUDE_DIR)/demangle.h valprint.h \
|
||||
language.h jv-lang.h c-lang.h gdbcore.h annotate.h
|
||||
|
||||
kod.o: kod.c $(defs_h) $(command_h) $(gdbcmd_h) target.h gdb_string.h
|
||||
kod.o: kod.c $(defs_h) $(command_h) $(gdbcmd_h) target.h gdb_string.h kod.h
|
||||
|
||||
kod-cisco.o: kod-cisco.c $(defs_h) gdb_string.h
|
||||
kod-cisco.o: kod-cisco.c $(defs_h) gdb_string.h kod.h
|
||||
|
||||
language.o: language.c $(bfd_h) $(defs_h) $(expression_h) $(frame_h) \
|
||||
$(gdbcmd_h) $(gdbtypes_h) language.h parser-defs.h $(symtab_h) \
|
||||
@ -1504,7 +1507,7 @@ remote-utils.o: remote-utils.c $(defs_h) $(gdbcmd_h) $(gdbcore_h) \
|
||||
|
||||
remote.o: remote.c $(bfd_h) $(wait_h) $(defs_h) $(gdbcmd_h) \
|
||||
$(inferior_h) $(remote_utils_h) symfile.h terminal.h gdb_string.h \
|
||||
$(event_loop_h)
|
||||
$(event_loop_h) $(event_top_h) $(remote_h)
|
||||
|
||||
remote-nrom.o: remote-nrom.c $(bfd_h) $(wait_h) $(defs_h) $(gdbcmd_h) \
|
||||
$(inferior_h) $(remote_utils_h) symfile.h terminal.h
|
||||
@ -1533,11 +1536,11 @@ ser-mac.o: ser-mac.c $(defs_h) serial.h signals.h
|
||||
|
||||
ser-ocd.o: ser-ocd.c $(defs_h) serial.h signals.h gdb_string.h
|
||||
|
||||
ser-pipe.o: ser-pipe.c $(defs_h) serial.h signals.h gdb_string.h
|
||||
ser-pipe.o: ser-pipe.c $(defs_h) serial.h signals.h gdb_string.h ser-unix.h
|
||||
|
||||
ser-tcp.o: ser-tcp.c $(defs_h) serial.h signals.h gdb_string.h
|
||||
ser-tcp.o: ser-tcp.c $(defs_h) serial.h signals.h gdb_string.h ser-unix.h
|
||||
|
||||
ser-unix.o: ser-unix.c $(defs_h) serial.h
|
||||
ser-unix.o: ser-unix.c $(defs_h) serial.h ser-unix.h
|
||||
|
||||
serial.o: serial.c $(defs_h) serial.h gdb_string.h
|
||||
|
||||
@ -1556,7 +1559,7 @@ solib.o: solib.c $(command_h) $(defs_h) $(gdbcore_h) $(inferior_h) \
|
||||
|
||||
source.o: source.c $(defs_h) $(expression_h) $(frame_h) $(gdbcmd_h) \
|
||||
$(gdbcore_h) language.h objfiles.h gnu-regex.h symfile.h $(symtab_h) \
|
||||
gdb_string.h
|
||||
gdb_string.h source.h
|
||||
|
||||
sparc-nat.o: sparc-nat.c $(bfd_h) $(defs_h) $(inferior_h) $(gdbcore_h) \
|
||||
target.h
|
||||
@ -1614,7 +1617,7 @@ thread.o: thread.c $(defs_h) gdbthread.h $(gdbcmd_h) target.h
|
||||
|
||||
top.o: top.c top.h $(bfd_h) $(getopt_h) $(readline_headers) call-cmds.h \
|
||||
$(defs_h) $(gdbcmd_h) $(inferior_h) language.h signals.h \
|
||||
$(remote_utils_h) gdb_string.h $(event_loop_h) $(version_h)
|
||||
$(remote_utils_h) gdb_string.h $(event_loop_h) $(event_top_h) $(version_h)
|
||||
|
||||
typeprint.o: typeprint.c $(defs_h) $(expression_h) $(gdbcmd_h) \
|
||||
$(gdbcore_h) $(gdbtypes_h) language.h $(symtab_h) target.h \
|
||||
@ -1628,7 +1631,7 @@ umax-xdep.o: umax-xdep.c $(defs_h) $(gdbcore_h) $(inferior_h)
|
||||
|
||||
utils.o: utils.c $(bfd_h) $(defs_h) $(expression_h) $(gdbcmd_h) \
|
||||
language.h signals.h target.h terminal.h $(readline_headers) \
|
||||
gdb_string.h $(event_loop_h)
|
||||
gdb_string.h $(event_loop_h) $(event_top_h)
|
||||
|
||||
valarith.o: valarith.c $(bfd_h) $(defs_h) $(expression_h) \
|
||||
$(gdbtypes_h) language.h $(symtab_h) target.h $(value_h) \
|
||||
|
138
gdb/breakpoint.c
138
gdb/breakpoint.c
@ -44,6 +44,8 @@
|
||||
|
||||
/* Prototypes for local functions. */
|
||||
|
||||
static void until_break_command_continuation (struct continuation_arg *arg);
|
||||
|
||||
static void
|
||||
catch_command_1 PARAMS ((char *, int, int));
|
||||
|
||||
@ -252,8 +254,6 @@ do_enable_breakpoint PARAMS ((struct breakpoint *, enum bpdisp));
|
||||
if such is available. */
|
||||
static int can_use_hw_watchpoints;
|
||||
|
||||
void delete_command PARAMS ((char *, int));
|
||||
|
||||
void _initialize_breakpoint PARAMS ((void));
|
||||
|
||||
void set_breakpoint_count PARAMS ((int));
|
||||
@ -671,7 +671,10 @@ insert_breakpoints ()
|
||||
|
||||
ALL_BREAKPOINTS_SAFE (b, temp)
|
||||
{
|
||||
if (b->type != bp_watchpoint
|
||||
if (b->enable == permanent)
|
||||
/* Permanent breakpoints cannot be inserted or removed. */
|
||||
continue;
|
||||
else if (b->type != bp_watchpoint
|
||||
&& b->type != bp_hardware_watchpoint
|
||||
&& b->type != bp_read_watchpoint
|
||||
&& b->type != bp_access_watchpoint
|
||||
@ -1131,6 +1134,10 @@ remove_breakpoint (b, is)
|
||||
{
|
||||
int val;
|
||||
|
||||
if (b->enable == permanent)
|
||||
/* Permanent breakpoints cannot be inserted or removed. */
|
||||
return 0;
|
||||
|
||||
if (b->type == bp_none)
|
||||
warning ("attempted to remove apparently deleted breakpoint #%d?",
|
||||
b->number);
|
||||
@ -1144,7 +1151,6 @@ remove_breakpoint (b, is)
|
||||
&& b->type != bp_catch_exec
|
||||
&& b->type != bp_catch_catch
|
||||
&& b->type != bp_catch_throw)
|
||||
|
||||
{
|
||||
if (b->type == bp_hardware_breakpoint)
|
||||
val = target_remove_hw_breakpoint (b->address, b->shadow_contents);
|
||||
@ -1357,33 +1363,42 @@ breakpoint_init_inferior (context)
|
||||
}
|
||||
}
|
||||
|
||||
/* breakpoint_here_p (PC) returns 1 if an enabled breakpoint exists at
|
||||
PC. When continuing from a location with a breakpoint, we actually
|
||||
single step once before calling insert_breakpoints. */
|
||||
/* breakpoint_here_p (PC) returns non-zero if an enabled breakpoint
|
||||
exists at PC. It returns ordinary_breakpoint_here if it's an
|
||||
ordinary breakpoint, or permanent_breakpoint_here if it's a
|
||||
permanent breakpoint.
|
||||
- When continuing from a location with an ordinary breakpoint, we
|
||||
actually single step once before calling insert_breakpoints.
|
||||
- When continuing from a localion with a permanent breakpoint, we
|
||||
need to use the `SKIP_PERMANENT_BREAKPOINT' macro, provided by
|
||||
the target, to advance the PC past the breakpoint. */
|
||||
|
||||
int
|
||||
enum breakpoint_here
|
||||
breakpoint_here_p (pc)
|
||||
CORE_ADDR pc;
|
||||
{
|
||||
register struct breakpoint *b;
|
||||
int any_breakpoint_here = 0;
|
||||
|
||||
ALL_BREAKPOINTS (b)
|
||||
if (b->enable == enabled
|
||||
&& b->enable != shlib_disabled
|
||||
&& b->enable != call_disabled
|
||||
if ((b->enable == enabled
|
||||
|| b->enable == permanent)
|
||||
&& b->address == pc) /* bp is enabled and matches pc */
|
||||
{
|
||||
if (overlay_debugging &&
|
||||
section_is_overlay (b->section) &&
|
||||
!section_is_mapped (b->section))
|
||||
continue; /* unmapped overlay -- can't be a match */
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
{
|
||||
if (overlay_debugging &&
|
||||
section_is_overlay (b->section) &&
|
||||
!section_is_mapped (b->section))
|
||||
continue; /* unmapped overlay -- can't be a match */
|
||||
else if (b->enable == permanent)
|
||||
return permanent_breakpoint_here;
|
||||
else
|
||||
any_breakpoint_here = 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return any_breakpoint_here ? ordinary_breakpoint_here : 0;
|
||||
}
|
||||
|
||||
|
||||
/* breakpoint_inserted_here_p (PC) is just like breakpoint_here_p(),
|
||||
but it only returns true if there is actually a breakpoint inserted
|
||||
at PC. */
|
||||
@ -2842,7 +2857,7 @@ breakpoint_1 (bnum, allflag)
|
||||
|
||||
static char *bpdisps[] =
|
||||
{"del", "dstp", "dis", "keep"};
|
||||
static char bpenables[] = "nyn";
|
||||
static char bpenables[] = "nynny";
|
||||
char wrap_indent[80];
|
||||
|
||||
|
||||
@ -3141,8 +3156,9 @@ describe_other_breakpoints (pc, section)
|
||||
b->number,
|
||||
((b->enable == disabled ||
|
||||
b->enable == shlib_disabled ||
|
||||
b->enable == call_disabled)
|
||||
? " (disabled)" : ""),
|
||||
b->enable == call_disabled) ? " (disabled)"
|
||||
: b->enable == permanent ? " (permanent)"
|
||||
: ""),
|
||||
(others > 1) ? "," : ((others == 1) ? " and" : ""));
|
||||
}
|
||||
printf_filtered ("also set at pc ");
|
||||
@ -3169,7 +3185,9 @@ set_default_breakpoint (valid, addr, symtab, line)
|
||||
|
||||
/* Rescan breakpoints at address ADDRESS,
|
||||
marking the first one as "first" and any others as "duplicates".
|
||||
This is so that the bpt instruction is only inserted once. */
|
||||
This is so that the bpt instruction is only inserted once.
|
||||
If we have a permanent breakpoint at ADDRESS, make that one
|
||||
the official one, and the rest as duplicates. */
|
||||
|
||||
static void
|
||||
check_duplicates (address, section)
|
||||
@ -3178,6 +3196,7 @@ check_duplicates (address, section)
|
||||
{
|
||||
register struct breakpoint *b;
|
||||
register int count = 0;
|
||||
struct breakpoint *perm_bp = 0;
|
||||
|
||||
if (address == 0) /* Watchpoints are uninteresting */
|
||||
return;
|
||||
@ -3189,9 +3208,44 @@ check_duplicates (address, section)
|
||||
&& b->address == address
|
||||
&& (overlay_debugging == 0 || b->section == section))
|
||||
{
|
||||
/* Have we found a permanent breakpoint? */
|
||||
if (b->enable == permanent)
|
||||
{
|
||||
perm_bp = b;
|
||||
break;
|
||||
}
|
||||
|
||||
count++;
|
||||
b->duplicate = count > 1;
|
||||
}
|
||||
|
||||
/* If we found a permanent breakpoint at this address, go over the
|
||||
list again and declare all the other breakpoints there to be the
|
||||
duplicates. */
|
||||
if (perm_bp)
|
||||
{
|
||||
perm_bp->duplicate = 0;
|
||||
|
||||
/* Permanent breakpoint should always be inserted. */
|
||||
if (! perm_bp->inserted)
|
||||
internal_error ("allegedly permanent breakpoint is not "
|
||||
"actually inserted");
|
||||
|
||||
ALL_BREAKPOINTS (b)
|
||||
if (b != perm_bp)
|
||||
{
|
||||
if (b->inserted)
|
||||
internal_error ("another breakpoint was inserted on top of "
|
||||
"a permanent breakpoint");
|
||||
|
||||
if (b->enable != disabled
|
||||
&& b->enable != shlib_disabled
|
||||
&& b->enable != call_disabled
|
||||
&& b->address == address
|
||||
&& (overlay_debugging == 0 || b->section == section))
|
||||
b->duplicate = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Low level routine to set a breakpoint.
|
||||
@ -3254,6 +3308,18 @@ set_raw_breakpoint (sal)
|
||||
return b;
|
||||
}
|
||||
|
||||
|
||||
/* Note that the breakpoint object B describes a permanent breakpoint
|
||||
instruction, hard-wired into the inferior's code. */
|
||||
void
|
||||
make_breakpoint_permanent (struct breakpoint *b)
|
||||
{
|
||||
b->enable = permanent;
|
||||
|
||||
/* By definition, permanent breakpoints are already present in the code. */
|
||||
b->inserted = 1;
|
||||
}
|
||||
|
||||
#ifdef GET_LONGJMP_TARGET
|
||||
|
||||
static void
|
||||
@ -3333,7 +3399,7 @@ remove_solib_event_breakpoints ()
|
||||
delete_breakpoint (b);
|
||||
}
|
||||
|
||||
void
|
||||
struct breakpoint *
|
||||
create_solib_event_breakpoint (address)
|
||||
CORE_ADDR address;
|
||||
{
|
||||
@ -3347,6 +3413,8 @@ create_solib_event_breakpoint (address)
|
||||
b->number = internal_breakpoint_number--;
|
||||
b->disposition = donttouch;
|
||||
b->type = bp_shlib_event;
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
/* Disable any breakpoints that are on code in shared libraries. Only
|
||||
@ -4643,9 +4711,8 @@ awatch_command (arg, from_tty)
|
||||
cmd_continuation pointer, to complete the until command. It takes
|
||||
care of cleaning up the temporary breakpoints set up by the until
|
||||
command. */
|
||||
void
|
||||
until_break_command_continuation (arg)
|
||||
struct continuation_arg *arg;
|
||||
static void
|
||||
until_break_command_continuation (struct continuation_arg *arg)
|
||||
{
|
||||
/* Do all the exec cleanups, which at this point should only be the
|
||||
one set up in the first part of the until_break_command
|
||||
@ -5929,6 +5996,14 @@ delete_breakpoint (bpt)
|
||||
{
|
||||
int val;
|
||||
|
||||
/* We should never reach this point if there is a permanent
|
||||
breakpoint at the same address as the one being deleted.
|
||||
If there is a permanent breakpoint somewhere, it should
|
||||
always be the only one inserted. */
|
||||
if (b->enable == permanent)
|
||||
internal_error ("another breakpoint was inserted on top of "
|
||||
"a permanent breakpoint");
|
||||
|
||||
if (b->type == bp_hardware_breakpoint)
|
||||
val = target_insert_hw_breakpoint (b->address, b->shadow_contents);
|
||||
else
|
||||
@ -6377,6 +6452,10 @@ disable_breakpoint (bpt)
|
||||
if (bpt->type == bp_watchpoint_scope)
|
||||
return;
|
||||
|
||||
/* You can't disable permanent breakpoints. */
|
||||
if (bpt->enable == permanent)
|
||||
return;
|
||||
|
||||
bpt->enable = disabled;
|
||||
|
||||
check_duplicates (bpt->address, bpt->section);
|
||||
@ -6445,7 +6524,8 @@ do_enable_breakpoint (bpt, disposition)
|
||||
error ("Hardware breakpoints used exceeds limit.");
|
||||
}
|
||||
|
||||
bpt->enable = enabled;
|
||||
if (bpt->enable != permanent)
|
||||
bpt->enable = enabled;
|
||||
bpt->disposition = disposition;
|
||||
check_duplicates (bpt->address, bpt->section);
|
||||
breakpoints_changed ();
|
||||
|
@ -129,13 +129,18 @@ enum enable
|
||||
shlib_disabled, /* The eventpoint's address is in an unloaded solib.
|
||||
The eventpoint will be automatically enabled
|
||||
and reset when that solib is loaded. */
|
||||
call_disabled /* The eventpoint has been disabled while a call
|
||||
call_disabled, /* The eventpoint has been disabled while a call
|
||||
into the inferior is "in flight", because some
|
||||
eventpoints interfere with the implementation of
|
||||
a call on some targets. The eventpoint will be
|
||||
automatically enabled and reset when the call
|
||||
"lands" (either completes, or stops at another
|
||||
eventpoint). */
|
||||
permanent /* There is a breakpoint instruction hard-wired into
|
||||
the target's code. Don't try to write another
|
||||
breakpoint instruction on top of it, or restore
|
||||
its value. Step over it using the architecture's
|
||||
SKIP_INSN macro. */
|
||||
};
|
||||
|
||||
|
||||
@ -459,6 +464,15 @@ enum inf_context
|
||||
inf_running,
|
||||
inf_exited
|
||||
};
|
||||
|
||||
/* The possible return values for breakpoint_here_p.
|
||||
We guarantee that zero always means "no breakpoint here". */
|
||||
enum breakpoint_here
|
||||
{
|
||||
no_breakpoint_here = 0,
|
||||
ordinary_breakpoint_here,
|
||||
permanent_breakpoint_here
|
||||
};
|
||||
|
||||
|
||||
/* Prototypes for breakpoint-related functions. */
|
||||
@ -466,7 +480,7 @@ enum inf_context
|
||||
/* Forward declarations for prototypes */
|
||||
struct frame_info;
|
||||
|
||||
extern int breakpoint_here_p PARAMS ((CORE_ADDR));
|
||||
extern enum breakpoint_here breakpoint_here_p PARAMS ((CORE_ADDR));
|
||||
|
||||
extern int breakpoint_inserted_here_p PARAMS ((CORE_ADDR));
|
||||
|
||||
@ -594,7 +608,9 @@ extern void disable_breakpoint PARAMS ((struct breakpoint *));
|
||||
|
||||
extern void enable_breakpoint PARAMS ((struct breakpoint *));
|
||||
|
||||
extern void create_solib_event_breakpoint PARAMS ((CORE_ADDR));
|
||||
extern void make_breakpoint_permanent PARAMS ((struct breakpoint *));
|
||||
|
||||
extern struct breakpoint *create_solib_event_breakpoint PARAMS ((CORE_ADDR));
|
||||
|
||||
extern void remove_solib_event_breakpoints PARAMS ((void));
|
||||
|
||||
@ -624,4 +640,8 @@ extern int ep_is_shlib_catchpoint PARAMS ((struct breakpoint *));
|
||||
|
||||
extern struct breakpoint *set_breakpoint_sal PARAMS ((struct symtab_and_line));
|
||||
|
||||
/* Enable breakpoints and delete when hit. Called with ARG == NULL
|
||||
deletes all breakpoints. */
|
||||
extern void delete_command (char *arg, int from_tty);
|
||||
|
||||
#endif /* !defined (BREAKPOINT_H) */
|
||||
|
@ -1,5 +1,6 @@
|
||||
# Target: Mitsubishi D10V processor
|
||||
TDEPFILES= d10v-tdep.o remote-d10v.o
|
||||
TDEPFILES= d10v-tdep.o
|
||||
TM_FILE= tm-d10v.h
|
||||
|
||||
SIM_OBS= remote-sim.o
|
||||
SIM= ../sim/d10v/libsim.a
|
||||
|
@ -214,20 +214,9 @@ double_to_i387 PARAMS ((char *, char *));
|
||||
|
||||
/* end of copy */
|
||||
|
||||
extern void i387_float_info(void);
|
||||
#define FLOAT_INFO { i387_float_info (); }
|
||||
|
||||
/* The following works around a problem with /usr/include/sys/procfs.h */
|
||||
#define sys_quotactl 1
|
||||
|
||||
/* Define DO_REGISTERS_INFO() to do machine-specific formatting
|
||||
of register dumps. */
|
||||
|
||||
#define DO_REGISTERS_INFO(_regnum, fp) i386_do_registers_info(_regnum, fp)
|
||||
extern void i386_do_registers_info PARAMS ((int, int));
|
||||
|
||||
extern void i387_print_register PARAMS ((char *, int));
|
||||
|
||||
/* When the i386 Linux kernel calls a signal handler, the return
|
||||
address points to a bit of code on the stack. These definitions
|
||||
are used to identify this bit of code as a signal trampoline in
|
||||
|
@ -563,7 +563,6 @@ extern void hppa_pop_frame PARAMS ((void));
|
||||
|
||||
#define CALL_DUMMY_LENGTH (INSTRUCTION_SIZE * 28)
|
||||
#define REG_PARM_STACK_SPACE 16
|
||||
#define ARGS_GROW_DOWNWARD
|
||||
|
||||
#else /* defined PA_LEVEL_0 */
|
||||
|
||||
@ -796,3 +795,7 @@ PARAMS ((CORE_ADDR, int))
|
||||
probably much more common. (FIXME). */
|
||||
|
||||
#define COERCE_FLOAT_TO_DOUBLE (current_language -> la_language == language_c)
|
||||
|
||||
/* Here's how to step off a permanent breakpoint. */
|
||||
#define SKIP_PERMANENT_BREAKPOINT (hppa_skip_permanent_breakpoint)
|
||||
extern void hppa_skip_permanent_breakpoint (void);
|
||||
|
@ -210,8 +210,8 @@ call_dummy
|
||||
#undef REG_PARM_STACK_SPACE
|
||||
#define REG_PARM_STACK_SPACE 64
|
||||
|
||||
/* Arguments grow in the normal direction for the PA64 port. */
|
||||
#undef ARGS_GROW_DOWNWARD
|
||||
/* Use the 64-bit calling conventions designed for the PA2.0 in wide mode. */
|
||||
#define PA20W_CALLING_CONVENTIONS
|
||||
|
||||
#undef FUNC_LDIL_OFFSET
|
||||
#undef FUNC_LDO_OFFSET
|
||||
|
159
gdb/d10v-tdep.c
159
gdb/d10v-tdep.c
@ -1030,6 +1030,165 @@ d10v_extract_return_value (type, regbuf, valbuf)
|
||||
}
|
||||
}
|
||||
|
||||
/* Translate a GDB virtual ADDR/LEN into a format the remote target
|
||||
understands. Returns number of bytes that can be transfered
|
||||
starting at taddr, ZERO if no bytes can be transfered. */
|
||||
|
||||
void
|
||||
remote_d10v_translate_xfer_address (CORE_ADDR memaddr, int nr_bytes,
|
||||
CORE_ADDR *targ_addr, int *targ_len)
|
||||
{
|
||||
CORE_ADDR phys;
|
||||
CORE_ADDR seg;
|
||||
CORE_ADDR off;
|
||||
char *from = "unknown";
|
||||
char *to = "unknown";
|
||||
|
||||
/* GDB interprets addresses as:
|
||||
|
||||
0x00xxxxxx: Physical unified memory segment (Unified memory)
|
||||
0x01xxxxxx: Physical instruction memory segment (On-chip insn memory)
|
||||
0x02xxxxxx: Physical data memory segment (On-chip data memory)
|
||||
0x10xxxxxx: Logical data address segment (DMAP translated memory)
|
||||
0x11xxxxxx: Logical instruction address segment (IMAP translated memory)
|
||||
|
||||
The remote d10v board interprets addresses as:
|
||||
|
||||
0x00xxxxxx: Physical unified memory segment (Unified memory)
|
||||
0x01xxxxxx: Physical instruction memory segment (On-chip insn memory)
|
||||
0x02xxxxxx: Physical data memory segment (On-chip data memory)
|
||||
|
||||
Translate according to current IMAP/dmap registers */
|
||||
|
||||
enum
|
||||
{
|
||||
targ_unified = 0x00000000,
|
||||
targ_insn = 0x01000000,
|
||||
targ_data = 0x02000000,
|
||||
};
|
||||
|
||||
seg = (memaddr >> 24);
|
||||
off = (memaddr & 0xffffffL);
|
||||
|
||||
switch (seg)
|
||||
{
|
||||
case 0x00: /* Physical unified memory */
|
||||
from = "phys-unified";
|
||||
phys = targ_unified | off;
|
||||
to = "unified";
|
||||
break;
|
||||
|
||||
case 0x01: /* Physical instruction memory */
|
||||
from = "phys-insn";
|
||||
phys = targ_insn | off;
|
||||
to = "chip-insn";
|
||||
break;
|
||||
|
||||
case 0x02: /* Physical data memory segment */
|
||||
from = "phys-data";
|
||||
phys = targ_data | off;
|
||||
to = "chip-data";
|
||||
break;
|
||||
|
||||
case 0x10: /* in logical data address segment */
|
||||
{
|
||||
from = "logical-data";
|
||||
if (off <= 0x7fffL)
|
||||
{
|
||||
/* On chip data */
|
||||
phys = targ_data + off;
|
||||
if (off + nr_bytes > 0x7fffL)
|
||||
/* don't cross VM boundary */
|
||||
nr_bytes = 0x7fffL - off + 1;
|
||||
to = "chip-data";
|
||||
}
|
||||
else if (off <= 0xbfffL)
|
||||
{
|
||||
unsigned short dmap = read_register (DMAP_REGNUM);
|
||||
short map = dmap;
|
||||
|
||||
if (map & 0x1000)
|
||||
{
|
||||
/* Instruction memory */
|
||||
phys = targ_insn | ((map & 0xf) << 14) | (off & 0x3fff);
|
||||
to = "chip-insn";
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Unified memory */
|
||||
phys = targ_unified | ((map & 0x3ff) << 14) | (off & 0x3fff);
|
||||
to = "unified";
|
||||
}
|
||||
if (off + nr_bytes > 0xbfffL)
|
||||
/* don't cross VM boundary */
|
||||
nr_bytes = (0xbfffL - off + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Logical address out side of data segments, not supported */
|
||||
*targ_len = 0;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x11: /* in logical instruction address segment */
|
||||
{
|
||||
short map;
|
||||
unsigned short imap0 = read_register (IMAP0_REGNUM);
|
||||
unsigned short imap1 = read_register (IMAP1_REGNUM);
|
||||
|
||||
from = "logical-insn";
|
||||
if (off <= 0x1ffffL)
|
||||
{
|
||||
map = imap0;
|
||||
}
|
||||
else if (off <= 0x3ffffL)
|
||||
{
|
||||
map = imap1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Logical address outside of IMAP[01] segment, not
|
||||
supported */
|
||||
*targ_len = 0;
|
||||
return;
|
||||
}
|
||||
if ((off & 0x1ffff) + nr_bytes > 0x1ffffL)
|
||||
{
|
||||
/* don't cross VM boundary */
|
||||
nr_bytes = 0x1ffffL - (off & 0x1ffffL) + 1;
|
||||
}
|
||||
if (map & 0x1000)
|
||||
/* Instruction memory */
|
||||
{
|
||||
phys = targ_insn | off;
|
||||
to = "chip-insn";
|
||||
}
|
||||
else
|
||||
{
|
||||
phys = ((map & 0x7fL) << 17) + (off & 0x1ffffL);
|
||||
if (phys > 0xffffffL)
|
||||
{
|
||||
/* Address outside of unified address segment */
|
||||
*targ_len = 0;
|
||||
return;
|
||||
}
|
||||
phys |= targ_unified;
|
||||
to = "unified";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
*targ_len = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
*targ_addr = phys;
|
||||
*targ_len = nr_bytes;
|
||||
}
|
||||
|
||||
/* The following code implements access to, and display of, the D10V's
|
||||
instruction trace buffer. The buffer consists of 64K or more
|
||||
4-byte words of data, of which each words includes an 8-bit count,
|
||||
|
@ -2314,34 +2314,8 @@ process_one_symbol (type, desc, valu, name, section_offsets, objfile)
|
||||
from N_FUN symbols. */
|
||||
if (type == N_FUN
|
||||
&& valu == ANOFFSET (section_offsets, SECT_OFF_TEXT))
|
||||
{
|
||||
struct minimal_symbol *msym;
|
||||
char *p;
|
||||
int n;
|
||||
|
||||
p = strchr (name, ':');
|
||||
if (p == NULL)
|
||||
p = name;
|
||||
n = p - name;
|
||||
p = alloca (n + 2);
|
||||
strncpy (p, name, n);
|
||||
p[n] = 0;
|
||||
|
||||
msym = lookup_minimal_symbol (p, last_source_file,
|
||||
objfile);
|
||||
if (msym == NULL)
|
||||
{
|
||||
/* Sun Fortran appends an underscore to the minimal
|
||||
symbol name, try again with an appended underscore
|
||||
if the minimal symbol was not found. */
|
||||
p[n] = '_';
|
||||
p[n + 1] = 0;
|
||||
msym = lookup_minimal_symbol (p, last_source_file,
|
||||
objfile);
|
||||
}
|
||||
if (msym)
|
||||
valu = SYMBOL_VALUE_ADDRESS (msym);
|
||||
}
|
||||
valu =
|
||||
find_stab_function_addr (name, last_source_file, objfile);
|
||||
#endif
|
||||
|
||||
#ifdef SUN_FIXED_LBRAC_BUG
|
||||
|
@ -691,9 +691,10 @@ continuation;
|
||||
extern struct continuation *cmd_continuation;
|
||||
|
||||
/* From utils.c */
|
||||
void add_continuation PARAMS ((void (*) PARAMS ((struct continuation_arg *)),
|
||||
extern void add_continuation PARAMS ((void (*) PARAMS ((struct continuation_arg *)),
|
||||
struct continuation_arg *));
|
||||
void do_all_continuations PARAMS ((void));
|
||||
extern void do_all_continuations PARAMS ((void));
|
||||
extern void discard_all_continuations PARAMS ((void));
|
||||
|
||||
/* String containing the current directory (what getwd would return). */
|
||||
|
||||
|
@ -1,3 +1,12 @@
|
||||
1999-09-14 Michael Snyder <msnyder@cleaver.cygnus.com>
|
||||
|
||||
* gdbint.texinfo: Fix typo, add the word "have".
|
||||
|
||||
1999-09-14 Jim Blandy <jimb@cris.red-bean.com>
|
||||
|
||||
* gdbint.texinfo (Target Architecture Definition): Document the
|
||||
SKIP_PERMANENT_BREAKPOINT macro.
|
||||
|
||||
1999-09-07 Stan Shebs <shebs@andros.cygnus.com>
|
||||
|
||||
* gdb.texinfo: Fiks speling errers.
|
||||
|
@ -1596,6 +1596,16 @@ defined, no conversion will be done.
|
||||
@item SHIFT_INST_REGS
|
||||
(Only used for m88k targets.)
|
||||
|
||||
@item SKIP_PERMANENT_BREAKPOINT
|
||||
Advance the inferior's PC past a permanent breakpoint. GDB normally
|
||||
steps over a breakpoint by removing it, stepping one instruction, and
|
||||
re-inserting the breakpoint. However, permanent breakpoints are
|
||||
hardwired into the inferior, and can't be removed, so this strategy
|
||||
doesn't work. Calling SKIP_PERMANENT_BREAKPOINT adjusts the processor's
|
||||
state so that execution will resume just after the breakpoint. This
|
||||
macro does the right thing even when the breakpoint is in the delay slot
|
||||
of a branch or jump.
|
||||
|
||||
@item SKIP_PROLOGUE (pc)
|
||||
A C expression that returns the address of the ``real'' code beyond the
|
||||
function entry prologue found at @var{pc}.
|
||||
@ -2759,7 +2769,7 @@ also documents all the available macros.
|
||||
@c Conditionals}, @pxref{Native Conditionals}, and @pxref{Obsolete
|
||||
@c Conditionals})
|
||||
|
||||
Start with the header files. Once you some idea of how GDB's internal
|
||||
Start with the header files. Once you have some idea of how GDB's internal
|
||||
symbol tables are stored (see @file{symtab.h}, @file{gdbtypes.h}), you
|
||||
will find it much easier to understand the code which uses and creates
|
||||
those symbol tables.
|
||||
|
@ -4016,8 +4016,14 @@ dwarf_decode_lines (offset, comp_dir, abfd)
|
||||
case DW_LNS_set_basic_block:
|
||||
basic_block = 1;
|
||||
break;
|
||||
/* Add to the address register of the state machine the
|
||||
address increment value corresponding to special opcode
|
||||
255. Ie, this value is scaled by the minimum instruction
|
||||
length since special opcode 255 would have scaled the
|
||||
the increment. */
|
||||
case DW_LNS_const_add_pc:
|
||||
address += (255 - lh.opcode_base) / lh.line_range;
|
||||
address += (lh.minimum_instruction_length
|
||||
* ((255 - lh.opcode_base) / lh.line_range));
|
||||
break;
|
||||
case DW_LNS_fixed_advance_pc:
|
||||
address += read_2_bytes (abfd, line_ptr);
|
||||
|
473
gdb/event-loop.c
473
gdb/event-loop.c
@ -22,6 +22,8 @@
|
||||
#include "defs.h"
|
||||
#include "top.h"
|
||||
#include "event-loop.h"
|
||||
#include "event-top.h"
|
||||
#include "inferior.h" /* For fetch_inferior_event. */
|
||||
#ifdef HAVE_POLL
|
||||
#include <poll.h>
|
||||
#else
|
||||
@ -29,6 +31,103 @@
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <setjmp.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
/* Type of the mask arguments to select. */
|
||||
|
||||
#ifndef NO_FD_SET
|
||||
#define SELECT_MASK fd_set
|
||||
#else
|
||||
#ifndef _AIX
|
||||
typedef long fd_mask;
|
||||
#endif
|
||||
#if defined(_IBMR2)
|
||||
#define SELECT_MASK void
|
||||
#else
|
||||
#define SELECT_MASK int
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Define "NBBY" (number of bits per byte) if it's not already defined. */
|
||||
|
||||
#ifndef NBBY
|
||||
#define NBBY 8
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the number of fd_masks in an fd_set */
|
||||
|
||||
#ifndef FD_SETSIZE
|
||||
#ifdef OPEN_MAX
|
||||
#define FD_SETSIZE OPEN_MAX
|
||||
#else
|
||||
#define FD_SETSIZE 256
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(howmany)
|
||||
#define howmany(x, y) (((x)+((y)-1))/(y))
|
||||
#endif
|
||||
#ifndef NFDBITS
|
||||
#define NFDBITS NBBY*sizeof(fd_mask)
|
||||
#endif
|
||||
#define MASK_SIZE howmany(FD_SETSIZE, NFDBITS)
|
||||
|
||||
|
||||
typedef struct gdb_event gdb_event;
|
||||
typedef void (event_handler_func) (int);
|
||||
|
||||
/* Event for the GDB event system. Events are queued by calling
|
||||
async_queue_event and serviced later on by gdb_do_one_event. An
|
||||
event can be, for instance, a file descriptor becoming ready to be
|
||||
read. Servicing an event simply means that the procedure PROC will
|
||||
be called. We have 2 queues, one for file handlers that we listen
|
||||
to in the event loop, and one for the file handlers+events that are
|
||||
ready. The procedure PROC associated with each event is always the
|
||||
same (handle_file_event). Its duty is to invoke the handler
|
||||
associated with the file descriptor whose state change generated
|
||||
the event, plus doing other cleanups adn such. */
|
||||
|
||||
struct gdb_event
|
||||
{
|
||||
event_handler_func *proc; /* Procedure to call to service this event. */
|
||||
int fd; /* File descriptor that is ready. */
|
||||
struct gdb_event *next_event; /* Next in list of events or NULL. */
|
||||
};
|
||||
|
||||
/* Information about each file descriptor we register with the event
|
||||
loop. */
|
||||
|
||||
typedef struct file_handler
|
||||
{
|
||||
int fd; /* File descriptor. */
|
||||
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. */
|
||||
gdb_client_data client_data; /* Argument to pass to proc. */
|
||||
int error; /* Was an error detected on this fd? */
|
||||
struct file_handler *next_file; /* Next registered file descriptor. */
|
||||
}
|
||||
file_handler;
|
||||
|
||||
/* PROC is a function to be invoked when the READY flag is set. This
|
||||
happens when there has been a signal and the corresponding signal
|
||||
handler has 'triggered' this async_signal_handler for
|
||||
execution. The actual work to be done in response to a signal will
|
||||
be carried out by PROC at a later time, within process_event. This
|
||||
provides a deferred execution of signal handlers.
|
||||
Async_init_signals takes care of setting up such an
|
||||
asyn_signal_handler for each interesting signal. */
|
||||
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 */
|
||||
gdb_client_data client_data; /* Argument to async_handler_func */
|
||||
}
|
||||
async_signal_handler;
|
||||
|
||||
|
||||
/* Event queue:
|
||||
- the first event in the queue is the head of the queue.
|
||||
@ -75,6 +174,11 @@ static struct
|
||||
/* Number of file descriptors to monitor. */
|
||||
int num_fds;
|
||||
|
||||
/* Timeout in milliseconds for calls to poll(). */
|
||||
int timeout;
|
||||
|
||||
/* Flag to tell whether the timeout value shuld be used. */
|
||||
int timeout_valid;
|
||||
}
|
||||
gdb_notifier;
|
||||
|
||||
@ -97,11 +201,40 @@ static struct
|
||||
/* Number of valid bits (highest fd value + 1). */
|
||||
int num_fds;
|
||||
|
||||
}
|
||||
/* Time structure for calls to select(). */
|
||||
struct timeval timeout;
|
||||
|
||||
/* Flag to tell whether the timeout struct should be used. */
|
||||
int timeout_valid;
|
||||
}
|
||||
gdb_notifier;
|
||||
|
||||
#endif /* HAVE_POLL */
|
||||
|
||||
/* Structure associated with a timer. PROC will be executed at the
|
||||
first occasion after WHEN. */
|
||||
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 */
|
||||
}
|
||||
gdb_timer;
|
||||
|
||||
/* List of currently active timers. It is sorted in order of
|
||||
increasing timers.*/
|
||||
static struct
|
||||
{
|
||||
/* Pointer to first in timer list. */
|
||||
struct gdb_timer *first_timer;
|
||||
|
||||
/* Length of timer list. */
|
||||
int num_timers;
|
||||
}
|
||||
timer_list;
|
||||
|
||||
/* All the async_signal_handlers gdb is interested in are kept onto
|
||||
this list. */
|
||||
static struct
|
||||
@ -120,12 +253,17 @@ sighandler_list;
|
||||
function. */
|
||||
static int async_handler_ready = 0;
|
||||
|
||||
static void create_file_handler PARAMS ((int, int, handler_func *, gdb_client_data));
|
||||
static void invoke_async_signal_handler PARAMS ((void));
|
||||
static void handle_file_event PARAMS ((int));
|
||||
static int gdb_wait_for_event PARAMS ((void));
|
||||
static int gdb_do_one_event PARAMS ((void));
|
||||
static int check_async_ready PARAMS ((void));
|
||||
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 int process_event (void);
|
||||
static void handle_timer_event (int dummy);
|
||||
static void poll_timers (void);
|
||||
|
||||
|
||||
/* Insert an event object into the gdb event queue at
|
||||
@ -139,9 +277,7 @@ static int check_async_ready PARAMS ((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 (event_ptr, position)
|
||||
gdb_event *event_ptr;
|
||||
queue_position position;
|
||||
async_queue_event (gdb_event *event_ptr, queue_position position)
|
||||
{
|
||||
if (position == TAIL)
|
||||
{
|
||||
@ -169,9 +305,8 @@ async_queue_event (event_ptr, position)
|
||||
processing. The procedure associated to this event is always
|
||||
handle_file_event, which will in turn invoke the one that was
|
||||
associated to FD when it was registered with the event loop. */
|
||||
gdb_event *
|
||||
create_file_event (fd)
|
||||
int fd;
|
||||
static gdb_event *
|
||||
create_file_event (int fd)
|
||||
{
|
||||
gdb_event *file_event_ptr;
|
||||
|
||||
@ -191,7 +326,7 @@ create_file_event (fd)
|
||||
priority events first, by invoking the associated event handler
|
||||
procedure. */
|
||||
static int
|
||||
process_event ()
|
||||
process_event (void)
|
||||
{
|
||||
gdb_event *event_ptr, *prev_ptr;
|
||||
event_handler_func *proc;
|
||||
@ -257,7 +392,7 @@ process_event ()
|
||||
it. Returns 1 if something was done otherwise returns 0 (this can
|
||||
happen if there are no event sources to wait for). */
|
||||
static int
|
||||
gdb_do_one_event ()
|
||||
gdb_do_one_event (void)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
@ -272,6 +407,9 @@ gdb_do_one_event ()
|
||||
break;
|
||||
}
|
||||
|
||||
/* 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,
|
||||
we should get out because this means that there are no
|
||||
event sources left. This will make the event loop stop,
|
||||
@ -313,7 +451,7 @@ gdb_do_one_event ()
|
||||
/* Start up the event loop. This is the entry point to the event loop
|
||||
from the command loop. */
|
||||
void
|
||||
start_event_loop ()
|
||||
start_event_loop (void)
|
||||
{
|
||||
/* Loop until there is something to do. This is the entry point to
|
||||
the event loop engine. gdb_do_one_event will process one event
|
||||
@ -328,20 +466,16 @@ start_event_loop ()
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Wrapper function for create_file_handler, so that the caller
|
||||
doesn't have to know implementation details about the use of poll
|
||||
vs. select. */
|
||||
void
|
||||
add_file_handler (fd, proc, client_data)
|
||||
int fd;
|
||||
void (*proc) (void);
|
||||
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, (handler_func *) proc, client_data);
|
||||
create_file_handler (fd, POLLIN, proc, client_data);
|
||||
#else
|
||||
create_file_handler (fd, GDB_READABLE, (handler_func *) proc, client_data);
|
||||
create_file_handler (fd, GDB_READABLE | GDB_EXCEPTION, proc, client_data);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -356,11 +490,7 @@ add_file_handler (fd, proc, 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 (fd, mask, proc, client_data)
|
||||
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;
|
||||
|
||||
@ -377,7 +507,8 @@ create_file_handler (fd, mask, proc, client_data)
|
||||
break;
|
||||
}
|
||||
|
||||
/* It is a new file descriptor. */
|
||||
/* It is a new file descriptor. Add it to the list. Otherwise, just
|
||||
change the data associated with it.*/
|
||||
if (file_ptr == NULL)
|
||||
{
|
||||
file_ptr = (file_handler *) xmalloc (sizeof (file_handler));
|
||||
@ -385,6 +516,9 @@ create_file_handler (fd, mask, proc, client_data)
|
||||
file_ptr->ready_mask = 0;
|
||||
file_ptr->next_file = gdb_notifier.first_file_handler;
|
||||
gdb_notifier.first_file_handler = file_ptr;
|
||||
#ifdef HAVE_POLL
|
||||
gdb_notifier.num_fds++;
|
||||
#endif
|
||||
}
|
||||
file_ptr->proc = proc;
|
||||
file_ptr->client_data = client_data;
|
||||
@ -392,7 +526,6 @@ create_file_handler (fd, mask, proc, client_data)
|
||||
|
||||
#ifdef HAVE_POLL
|
||||
|
||||
gdb_notifier.num_fds++;
|
||||
if (gdb_notifier.poll_fds)
|
||||
gdb_notifier.poll_fds =
|
||||
(struct pollfd *) realloc (gdb_notifier.poll_fds,
|
||||
@ -433,8 +566,7 @@ create_file_handler (fd, mask, proc, client_data)
|
||||
/* Remove the file descriptor FD from the list of monitored fd's:
|
||||
i.e. we don't care anymore about events on the FD. */
|
||||
void
|
||||
delete_file_handler (fd)
|
||||
int fd;
|
||||
delete_file_handler (int fd)
|
||||
{
|
||||
file_handler *file_ptr, *prev_ptr = NULL;
|
||||
int i, j;
|
||||
@ -536,11 +668,14 @@ delete_file_handler (fd)
|
||||
through event_ptr->proc. EVENT_FILE_DESC is file descriptor of the
|
||||
event in the front of the event queue. */
|
||||
static void
|
||||
handle_file_event (event_file_desc)
|
||||
int event_file_desc;
|
||||
handle_file_event (int event_file_desc)
|
||||
{
|
||||
file_handler *file_ptr;
|
||||
int mask, error_mask;
|
||||
int mask;
|
||||
#ifdef HAVE_POLL
|
||||
int error_mask;
|
||||
int error_mask_returned;
|
||||
#endif
|
||||
|
||||
/* Search the file handler list to find one that matches the fd in
|
||||
the event. */
|
||||
@ -563,8 +698,30 @@ handle_file_event (event_file_desc)
|
||||
error_mask = POLLHUP | POLLERR | POLLNVAL;
|
||||
mask = (file_ptr->ready_mask & file_ptr->mask) |
|
||||
(file_ptr->ready_mask & error_mask);
|
||||
error_mask_returned = mask & error_mask;
|
||||
|
||||
if (error_mask_returned != 0)
|
||||
{
|
||||
/* Work in progress. We may need to tell somebody what
|
||||
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);*/
|
||||
file_ptr->error = 1;
|
||||
}
|
||||
else
|
||||
file_ptr->error = 0;
|
||||
#else /* ! HAVE_POLL */
|
||||
if (file_ptr->ready_mask & GDB_EXCEPTION)
|
||||
{
|
||||
printf_unfiltered ("Exception condition detected on fd %d\n", file_ptr->fd);
|
||||
file_ptr->error = 1;
|
||||
}
|
||||
else
|
||||
file_ptr->error = 0;
|
||||
mask = file_ptr->ready_mask & file_ptr->mask;
|
||||
#endif /* HAVE_POLL */
|
||||
|
||||
@ -573,7 +730,7 @@ handle_file_event (event_file_desc)
|
||||
|
||||
/* If there was a match, then call the handler. */
|
||||
if (mask != 0)
|
||||
(*file_ptr->proc) (file_ptr->client_data);
|
||||
(*file_ptr->proc) (file_ptr->error, file_ptr->fd, file_ptr->client_data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -587,7 +744,7 @@ handle_file_event (event_file_desc)
|
||||
Return -1 if there are no files descriptors to monitor,
|
||||
otherwise return 0. */
|
||||
static int
|
||||
gdb_wait_for_event ()
|
||||
gdb_wait_for_event (void)
|
||||
{
|
||||
file_handler *file_ptr;
|
||||
gdb_event *file_event_ptr;
|
||||
@ -607,7 +764,14 @@ gdb_wait_for_event ()
|
||||
|
||||
#ifdef HAVE_POLL
|
||||
num_found =
|
||||
poll (gdb_notifier.poll_fds, (unsigned long) gdb_notifier.num_fds, -1);
|
||||
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.*/
|
||||
if (num_found == -1 && errno != EINTR)
|
||||
perror_with_name ("Poll");
|
||||
|
||||
#else /* ! HAVE_POLL */
|
||||
memcpy (gdb_notifier.ready_masks,
|
||||
@ -616,14 +780,18 @@ gdb_wait_for_event ()
|
||||
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],
|
||||
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)
|
||||
memset (gdb_notifier.ready_masks,
|
||||
0, 3 * MASK_SIZE * sizeof (fd_mask));
|
||||
|
||||
{
|
||||
memset (gdb_notifier.ready_masks,
|
||||
0, 3 * MASK_SIZE * sizeof (fd_mask));
|
||||
/* Dont print anything is we got a signal, let gdb handle it. */
|
||||
if (errno != EINTR)
|
||||
perror_with_name ("Select");
|
||||
}
|
||||
#endif /* HAVE_POLL */
|
||||
|
||||
/* Enqueue all detected file events. */
|
||||
@ -703,9 +871,7 @@ gdb_wait_for_event ()
|
||||
PROC is the function to call with CLIENT_DATA argument
|
||||
whenever the handler is invoked. */
|
||||
async_signal_handler *
|
||||
create_async_signal_handler (proc, client_data)
|
||||
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;
|
||||
|
||||
@ -728,8 +894,7 @@ create_async_signal_handler (proc, client_data)
|
||||
some event. The caller of this function is the interrupt handler
|
||||
associated with a signal. */
|
||||
void
|
||||
mark_async_signal_handler (async_handler_ptr)
|
||||
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;
|
||||
@ -737,7 +902,7 @@ mark_async_signal_handler (async_handler_ptr)
|
||||
|
||||
/* Call all the handlers that are ready. */
|
||||
static void
|
||||
invoke_async_signal_handler ()
|
||||
invoke_async_signal_handler (void)
|
||||
{
|
||||
async_signal_handler *async_handler_ptr;
|
||||
|
||||
@ -768,8 +933,7 @@ invoke_async_signal_handler ()
|
||||
/* Delete an asynchronous handler (ASYNC_HANDLER_PTR).
|
||||
Free the space allocated for it. */
|
||||
void
|
||||
delete_async_signal_handler (async_handler_ptr)
|
||||
async_signal_handler **async_handler_ptr;
|
||||
delete_async_signal_handler (async_signal_handler **async_handler_ptr)
|
||||
{
|
||||
async_signal_handler *prev_ptr;
|
||||
|
||||
@ -794,7 +958,212 @@ delete_async_signal_handler (async_handler_ptr)
|
||||
|
||||
/* Is it necessary to call invoke_async_signal_handler? */
|
||||
static int
|
||||
check_async_ready ()
|
||||
check_async_ready (void)
|
||||
{
|
||||
return async_handler_ready;
|
||||
}
|
||||
|
||||
/* FIXME: where does this function belong? */
|
||||
/* General function to handle events in the inferior. So far it just
|
||||
takes care of detecting errors reported by select() or poll(),
|
||||
otherwise it assumes that all is OK, and goes on reading data from
|
||||
the fd. This however may not always be what we want to do. */
|
||||
void
|
||||
inferior_event_handler (int error, gdb_client_data client_data, int fd)
|
||||
{
|
||||
if (error == 1)
|
||||
{
|
||||
printf_unfiltered ("error detected on fd %d\n", fd);
|
||||
delete_file_handler (fd);
|
||||
discard_all_continuations ();
|
||||
}
|
||||
else
|
||||
fetch_inferior_event (client_data);
|
||||
}
|
||||
|
||||
/* 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.*/
|
||||
int
|
||||
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;
|
||||
|
||||
/* compute seconds */
|
||||
delta.tv_sec = milliseconds / 1000;
|
||||
/* compute microseconds */
|
||||
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 )
|
||||
{
|
||||
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_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;
|
||||
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) ||
|
||||
((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;
|
||||
timer_list.first_timer = timer_ptr;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
gdb_notifier.timeout_valid = 0;
|
||||
return timer_ptr->timer_id;
|
||||
}
|
||||
|
||||
/* There is a chance that the creator of the timer wants to get rid of
|
||||
it before it expires. */
|
||||
void
|
||||
delete_timer (int id)
|
||||
{
|
||||
struct gdb_timer *timer_ptr, *prev_timer = NULL;
|
||||
|
||||
/* Find the entry for the given timer. */
|
||||
|
||||
for (timer_ptr = timer_list.first_timer; timer_ptr != NULL;
|
||||
timer_ptr = timer_ptr->next)
|
||||
{
|
||||
if (timer_ptr->timer_id == id)
|
||||
break;
|
||||
}
|
||||
|
||||
if (timer_ptr == NULL)
|
||||
return;
|
||||
/* Get rid of the timer in the timer list. */
|
||||
if (timer_ptr == timer_list.first_timer)
|
||||
timer_list.first_timer = timer_ptr->next;
|
||||
else
|
||||
{
|
||||
for (prev_timer = timer_list.first_timer;
|
||||
prev_timer->next != timer_ptr;
|
||||
prev_timer = prev_timer->next)
|
||||
;
|
||||
prev_timer->next = timer_ptr->next;
|
||||
}
|
||||
free ((char *) timer_ptr);
|
||||
|
||||
gdb_notifier.timeout_valid = 0;
|
||||
}
|
||||
|
||||
/* 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.*/
|
||||
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) &&
|
||||
(timer_ptr->when.tv_usec > time_now.tv_usec)))
|
||||
break;
|
||||
|
||||
/* Get rid of the timer from the beginning of the list. */
|
||||
timer_list.first_timer = timer_ptr->next;
|
||||
saved_timer = timer_ptr;
|
||||
timer_ptr = timer_ptr->next;
|
||||
/* Call the procedure associated with that timer. */
|
||||
(*saved_timer->proc) (timer_ptr->client_data);
|
||||
free (saved_timer);
|
||||
}
|
||||
|
||||
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.*/
|
||||
static void
|
||||
poll_timers (void)
|
||||
{
|
||||
struct timeval time_now, delta;
|
||||
gdb_event *event_ptr;
|
||||
|
||||
if (timer_list.num_timers)
|
||||
{
|
||||
gettimeofday (&time_now, NULL);
|
||||
delta.tv_sec = timer_list.first_timer->when.tv_sec - time_now.tv_sec;
|
||||
delta.tv_usec = timer_list.first_timer->when.tv_usec - time_now.tv_usec;
|
||||
/* borrow? */
|
||||
if (delta.tv_usec < 0)
|
||||
{
|
||||
delta.tv_sec -= 1;
|
||||
delta.tv_usec += 1000000;
|
||||
}
|
||||
|
||||
/* Oops it expired already. Tell select / poll to return
|
||||
immediately. */
|
||||
if (delta.tv_sec < 0)
|
||||
{
|
||||
delta.tv_sec = 0;
|
||||
delta.tv_usec = 0;
|
||||
}
|
||||
|
||||
if (delta.tv_sec == 0 && delta.tv_usec == 0)
|
||||
{
|
||||
event_ptr = (gdb_event *) xmalloc (sizeof (gdb_event));
|
||||
event_ptr->proc = handle_timer_event;
|
||||
event_ptr->fd = timer_list.first_timer->timer_id;
|
||||
async_queue_event (event_ptr, TAIL);
|
||||
}
|
||||
|
||||
/* Now we need to update the timeout for select/ poll, because we
|
||||
don't want to sit there while this timer is expiring. */
|
||||
#ifdef HAVE_POLL
|
||||
gdb_notifier.timeout = delta.tv_sec * 1000;
|
||||
#else
|
||||
gdb_notifier.timeout.sec = delta.tv_sec;
|
||||
gdb_notifier.timeout.usec = delta.tv_usec;
|
||||
#endif
|
||||
gdb_notifier.timeout_valid = 1;
|
||||
}
|
||||
else
|
||||
gdb_notifier.timeout_valid = 0;
|
||||
}
|
||||
|
190
gdb/event-loop.h
190
gdb/event-loop.h
@ -58,62 +58,10 @@
|
||||
Corollary tasks are the creation and deletion of event sources. */
|
||||
|
||||
typedef PTR gdb_client_data;
|
||||
typedef struct gdb_event gdb_event;
|
||||
|
||||
typedef void (handler_func) PARAMS ((gdb_client_data));
|
||||
typedef void (event_handler_func) PARAMS ((int));
|
||||
|
||||
/* Event for the GDB event system. Events are queued by calling
|
||||
async_queue_event and serviced later on by gdb_do_one_event. An
|
||||
event can be, for instance, a file descriptor becoming ready to be
|
||||
read. Servicing an event simply means that the procedure PROC will
|
||||
be called. We have 2 queues, one for file handlers that we listen
|
||||
to in the event loop, and one for the file handlers+events that are
|
||||
ready. The procedure PROC associated with each event is always the
|
||||
same (handle_file_event). Its duty is to invoke the handler
|
||||
associated with the file descriptor whose state change generated
|
||||
the event, plus doing other cleanups adn such. */
|
||||
|
||||
struct gdb_event
|
||||
{
|
||||
event_handler_func *proc; /* Procedure to call to service this event. */
|
||||
int fd; /* File descriptor that is ready. */
|
||||
struct gdb_event *next_event; /* Next in list of events or NULL. */
|
||||
};
|
||||
|
||||
/* Information about each file descriptor we register with the event
|
||||
loop. */
|
||||
|
||||
typedef struct file_handler
|
||||
{
|
||||
int fd; /* File descriptor. */
|
||||
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. */
|
||||
gdb_client_data client_data; /* Argument to pass to proc. */
|
||||
struct file_handler *next_file; /* Next registered file descriptor. */
|
||||
}
|
||||
file_handler;
|
||||
|
||||
/* PROC is a function to be invoked when the READY flag is set. This
|
||||
happens when there has been a signal and the corresponding signal
|
||||
handler has 'triggered' this async_signal_handler for
|
||||
execution. The actual work to be done in response to a signal will
|
||||
be carried out by PROC at a later time, within process_event. This
|
||||
provides a deferred execution of signal handlers.
|
||||
Async_init_signals takes care of setting up such an
|
||||
asyn_signal_handler for each interesting signal. */
|
||||
|
||||
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 */
|
||||
handler_func *proc; /* Function to call to do the work */
|
||||
gdb_client_data client_data; /* Argument to async_handler_func */
|
||||
}
|
||||
async_signal_handler;
|
||||
struct async_signal_handler;
|
||||
typedef void (handler_func) (int, int, gdb_client_data);
|
||||
typedef void (sig_handler_func) (gdb_client_data);
|
||||
typedef void (timer_handler_func) (gdb_client_data);
|
||||
|
||||
/* Where to add an event onto the event queue, by queue_event. */
|
||||
typedef enum
|
||||
@ -134,129 +82,19 @@ queue_position;
|
||||
#define GDB_WRITABLE (1<<2)
|
||||
#define GDB_EXCEPTION (1<<3)
|
||||
|
||||
/* Type of the mask arguments to select. */
|
||||
|
||||
#ifndef NO_FD_SET
|
||||
#define SELECT_MASK fd_set
|
||||
#else
|
||||
#ifndef _AIX
|
||||
typedef long fd_mask;
|
||||
#endif
|
||||
#if defined(_IBMR2)
|
||||
#define SELECT_MASK void
|
||||
#else
|
||||
#define SELECT_MASK int
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Define "NBBY" (number of bits per byte) if it's not already defined. */
|
||||
|
||||
#ifndef NBBY
|
||||
#define NBBY 8
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the number of fd_masks in an fd_set */
|
||||
|
||||
#ifndef FD_SETSIZE
|
||||
#ifdef OPEN_MAX
|
||||
#define FD_SETSIZE OPEN_MAX
|
||||
#else
|
||||
#define FD_SETSIZE 256
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(howmany)
|
||||
#define howmany(x, y) (((x)+((y)-1))/(y))
|
||||
#endif
|
||||
#ifndef NFDBITS
|
||||
#define NFDBITS NBBY*sizeof(fd_mask)
|
||||
#endif
|
||||
#define MASK_SIZE howmany(FD_SETSIZE, NFDBITS)
|
||||
|
||||
|
||||
/* Stack for prompts. Each prompt is composed as a prefix, a prompt
|
||||
and a suffix. The prompt to be displayed at any given time is the
|
||||
one on top of the stack. A stack is necessary because of cases in
|
||||
which the execution of a gdb command requires further input from
|
||||
the user, like for instance 'commands' for breakpoints and
|
||||
'actions' for tracepoints. In these cases, the prompt is '>' and
|
||||
gdb should process input using the asynchronous readline interface
|
||||
and the event loop. In order to achieve this, we need to save
|
||||
somewhere the state of GDB, i.e. that it is processing user input
|
||||
as part of a command and not as part of the top level command loop.
|
||||
The prompt stack represents part of the saved state. Another part
|
||||
would be the function that readline would invoke after a whole line
|
||||
of input has ben entered. This second piece would be something
|
||||
like, for instance, where to return within the code for the actions
|
||||
commands after a line has been read. This latter portion has not
|
||||
beeen implemented yet. The need for a 3-part prompt arises from
|
||||
the annotation level. When this is set to 2, the prompt is actually
|
||||
composed of a prefix, the prompt itself and a suffix. */
|
||||
|
||||
/* At any particular time there will be always at least one prompt on
|
||||
the stack, the one being currently displayed by gdb. If gdb is
|
||||
using annotation level equal 2, there will be 2 prompts on the
|
||||
stack: the usual one, w/o prefix and suffix (at top - 1), and the
|
||||
'composite' one with prefix and suffix added (at top). At this
|
||||
time, this is the only use of the prompt stack. Resetting annotate
|
||||
to 0 or 1, pops the top of the stack, resetting its size to one
|
||||
element. The MAXPROMPTS limit is safe, for now. Once other cases
|
||||
are dealt with (like the different prompts used for 'commands' or
|
||||
'actions') this array implementation of the prompt stack may have
|
||||
to change. */
|
||||
|
||||
#define MAXPROMPTS 10
|
||||
struct prompts
|
||||
{
|
||||
struct
|
||||
{
|
||||
char *prefix;
|
||||
char *prompt;
|
||||
char *suffix;
|
||||
}
|
||||
prompt_stack[MAXPROMPTS];
|
||||
int top;
|
||||
};
|
||||
|
||||
#define PROMPT(X) the_prompts.prompt_stack[the_prompts.top + X].prompt
|
||||
#define PREFIX(X) the_prompts.prompt_stack[the_prompts.top + X].prefix
|
||||
#define SUFFIX(X) the_prompts.prompt_stack[the_prompts.top + X].suffix
|
||||
|
||||
/* Exported functions from event-loop.c */
|
||||
|
||||
extern void start_event_loop PARAMS ((void));
|
||||
extern void delete_file_handler PARAMS ((int));
|
||||
extern void add_file_handler PARAMS ((int, void (*) (void), gdb_client_data));
|
||||
extern void mark_async_signal_handler PARAMS ((async_signal_handler *));
|
||||
extern async_signal_handler *
|
||||
create_async_signal_handler PARAMS ((handler_func *, gdb_client_data));
|
||||
extern void delete_async_signal_handler PARAMS ((async_signal_handler ** async_handler_ptr));
|
||||
extern gdb_event *create_file_event PARAMS ((int));
|
||||
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 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 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 void delete_timer (int id);
|
||||
|
||||
/* Exported functions from event-top.c.
|
||||
FIXME: these should really go into top.h. */
|
||||
|
||||
extern void display_gdb_prompt PARAMS ((char *));
|
||||
extern void async_init_signals PARAMS ((void));
|
||||
extern void set_async_editing_command PARAMS ((char *, int, struct cmd_list_element *));
|
||||
extern void set_async_annotation_level PARAMS ((char *, int, struct cmd_list_element *));
|
||||
extern void set_async_prompt PARAMS ((char *, int, struct cmd_list_element *));
|
||||
extern void handle_stop_sig PARAMS ((int));
|
||||
extern void handle_sigint PARAMS ((int));
|
||||
extern void pop_prompt PARAMS ((void));
|
||||
extern void push_prompt PARAMS ((char *, char *, char *));
|
||||
extern void gdb_readline2 PARAMS ((void));
|
||||
extern void mark_async_signal_handler_wrapper (void *);
|
||||
extern void async_request_quit (gdb_client_data);
|
||||
|
||||
/* Exported variables from event-top.c.
|
||||
FIXME: these should really go into top.h. */
|
||||
|
||||
extern int async_command_editing_p;
|
||||
extern int exec_done_display_p;
|
||||
extern char *async_annotation_suffix;
|
||||
extern char *new_async_prompt;
|
||||
extern struct prompts the_prompts;
|
||||
extern void (*call_readline) PARAMS ((void));
|
||||
extern void (*input_handler) PARAMS ((char *));
|
||||
extern int input_fd;
|
||||
|
186
gdb/event-top.c
186
gdb/event-top.c
@ -23,8 +23,9 @@
|
||||
#include "top.h"
|
||||
#include "inferior.h"
|
||||
#include "terminal.h" /* for job_control */
|
||||
#include <signal.h>
|
||||
#include "signals.h"
|
||||
#include "event-loop.h"
|
||||
#include "event-top.h"
|
||||
|
||||
/* For dont_repeat() */
|
||||
#include "gdbcmd.h"
|
||||
@ -36,39 +37,34 @@
|
||||
/* readline defines this. */
|
||||
#undef savestring
|
||||
|
||||
extern void _initialize_event_loop PARAMS ((void));
|
||||
extern void _initialize_event_loop (void);
|
||||
|
||||
static void command_line_handler PARAMS ((char *));
|
||||
static void command_line_handler_continuation PARAMS ((struct continuation_arg *));
|
||||
void gdb_readline2 PARAMS ((void));
|
||||
void pop_prompt PARAMS ((void));
|
||||
void push_prompt PARAMS ((char *, char *, char *));
|
||||
static void change_line_handler PARAMS ((void));
|
||||
static void change_annotation_level PARAMS ((void));
|
||||
static void command_handler PARAMS ((char *));
|
||||
static void rl_callback_read_char_wrapper (gdb_client_data client_data);
|
||||
static void command_line_handler (char *rl);
|
||||
static void command_line_handler_continuation (struct continuation_arg *arg);
|
||||
static void change_line_handler (void);
|
||||
static void change_annotation_level (void);
|
||||
static void command_handler (char *command);
|
||||
void cli_command_loop (void);
|
||||
static void async_do_nothing (gdb_client_data arg);
|
||||
static void async_disconnect (gdb_client_data arg);
|
||||
static void async_stop_sig (gdb_client_data arg);
|
||||
static void async_float_handler (gdb_client_data arg);
|
||||
|
||||
/* Signal handlers. */
|
||||
void handle_sigint PARAMS ((int));
|
||||
static void handle_sigquit PARAMS ((int));
|
||||
static void handle_sighup PARAMS ((int));
|
||||
static void handle_sigfpe PARAMS ((int));
|
||||
static void handle_sigquit (int sig);
|
||||
static void handle_sighup (int sig);
|
||||
static void handle_sigfpe (int sig);
|
||||
#if defined(SIGWINCH) && defined(SIGWINCH_HANDLER)
|
||||
static void handle_sigwinch PARAMS ((int));
|
||||
#endif
|
||||
/* Signal to catch ^Z typed while reading a command: SIGTSTP or SIGCONT. */
|
||||
#ifndef STOP_SIGNAL
|
||||
#ifdef SIGTSTP
|
||||
#define STOP_SIGNAL SIGTSTP
|
||||
void handle_stop_sig PARAMS ((int));
|
||||
#endif
|
||||
static void handle_sigwinch (int sig);
|
||||
#endif
|
||||
|
||||
/* Functions to be invoked by the event loop in response to
|
||||
signals. */
|
||||
static void async_do_nothing PARAMS ((gdb_client_data));
|
||||
static void async_disconnect PARAMS ((gdb_client_data));
|
||||
static void async_float_handler PARAMS ((gdb_client_data));
|
||||
static void async_stop_sig PARAMS ((gdb_client_data));
|
||||
static void async_do_nothing (gdb_client_data);
|
||||
static void async_disconnect (gdb_client_data);
|
||||
static void async_float_handler (gdb_client_data);
|
||||
static void async_stop_sig (gdb_client_data);
|
||||
|
||||
/* Readline offers an alternate interface, via callback
|
||||
functions. These are all included in the file callback.c in the
|
||||
@ -90,8 +86,8 @@ static void async_stop_sig PARAMS ((gdb_client_data));
|
||||
line of input is ready. CALL_READLINE is to be set to the function
|
||||
that readline offers as callback to the event_loop. */
|
||||
|
||||
void (*input_handler) PARAMS ((char *));
|
||||
void (*call_readline) PARAMS ((void));
|
||||
void (*input_handler) (char *);
|
||||
void (*call_readline) (gdb_client_data);
|
||||
|
||||
/* Important variables for the event loop. */
|
||||
|
||||
@ -158,10 +154,19 @@ struct readline_input_state
|
||||
readline_input_state;
|
||||
|
||||
|
||||
/* Wrapper function foe calling into the readline library. The event
|
||||
loop expects the callback function to have a paramter, while readline
|
||||
expects none. */
|
||||
static void
|
||||
rl_callback_read_char_wrapper (gdb_client_data client_data)
|
||||
{
|
||||
rl_callback_read_char ();
|
||||
}
|
||||
|
||||
/* Initialize all the necessary variables, start the event loop,
|
||||
register readline, and stdin, start the loop. */
|
||||
void
|
||||
cli_command_loop ()
|
||||
cli_command_loop (void)
|
||||
{
|
||||
int length;
|
||||
char *a_prompt;
|
||||
@ -195,12 +200,18 @@ cli_command_loop ()
|
||||
which the user sets editing on again, by restoring readline
|
||||
handling of the input. */
|
||||
static void
|
||||
change_line_handler ()
|
||||
change_line_handler (void)
|
||||
{
|
||||
/* NOTE: this operates on input_fd, not instream. If we are reading
|
||||
commands from a file, instream will point to the file. However in
|
||||
async mode, we always read commands from a file with editing
|
||||
off. This means that the 'set editing on/off' will have effect
|
||||
only on the interactive session. */
|
||||
|
||||
if (async_command_editing_p)
|
||||
{
|
||||
/* Turn on editing by using readline. */
|
||||
call_readline = rl_callback_read_char;
|
||||
call_readline = rl_callback_read_char_wrapper;
|
||||
input_handler = command_line_handler;
|
||||
}
|
||||
else
|
||||
@ -213,18 +224,6 @@ change_line_handler ()
|
||||
first thing from .gdbinit. */
|
||||
input_handler = command_line_handler;
|
||||
}
|
||||
|
||||
/* To tell the event loop to change the handler associated with the
|
||||
input file descriptor, we need to create a new event source,
|
||||
corresponding to the same fd, but with a new event handler
|
||||
function. */
|
||||
/* NOTE: this operates on input_fd, not instream. If we are reading
|
||||
commands from a file, instream will point to the file. However in
|
||||
async mode, we always read commands from a file with editing
|
||||
off. This means that the 'set editing on/off' will have effect
|
||||
only on the interactive session. */
|
||||
delete_file_handler (input_fd);
|
||||
add_file_handler (input_fd, call_readline, 0);
|
||||
}
|
||||
|
||||
/* Displays the prompt. The prompt that is displayed is the current
|
||||
@ -239,8 +238,7 @@ change_line_handler ()
|
||||
3. Other????
|
||||
FIXME: 2. & 3. not implemented yet for async. */
|
||||
void
|
||||
display_gdb_prompt (new_prompt)
|
||||
char *new_prompt;
|
||||
display_gdb_prompt (char *new_prompt)
|
||||
{
|
||||
int prompt_length = 0;
|
||||
char *gdb_prompt = get_prompt ();
|
||||
@ -312,7 +310,7 @@ display_gdb_prompt (new_prompt)
|
||||
it pops the top of the prompt stack when we want the annotation level
|
||||
to be the normal ones (1 or 0). */
|
||||
static void
|
||||
change_annotation_level ()
|
||||
change_annotation_level (void)
|
||||
{
|
||||
char *prefix, *suffix;
|
||||
|
||||
@ -357,10 +355,7 @@ change_annotation_level ()
|
||||
strings, except when the annotation level is 2. Memory is allocated
|
||||
within savestring for the new prompt. */
|
||||
void
|
||||
push_prompt (prefix, prompt, suffix)
|
||||
char *prefix;
|
||||
char *prompt;
|
||||
char *suffix;
|
||||
push_prompt (char *prefix, char *prompt, char *suffix)
|
||||
{
|
||||
the_prompts.top++;
|
||||
PREFIX (0) = savestring (prefix, strlen (prefix));
|
||||
@ -378,7 +373,7 @@ push_prompt (prefix, prompt, suffix)
|
||||
|
||||
/* Pops the top of the prompt stack, and frees the memory allocated for it. */
|
||||
void
|
||||
pop_prompt ()
|
||||
pop_prompt (void)
|
||||
{
|
||||
/* If we are not during a 'synchronous' execution command, in which
|
||||
case, the top prompt would be empty. */
|
||||
@ -398,6 +393,26 @@ pop_prompt ()
|
||||
free (SUFFIX (0));
|
||||
the_prompts.top--;
|
||||
}
|
||||
|
||||
/* When there is an event ready on the stdin file desriptor, instead
|
||||
of calling readline directly throught the callback function, or
|
||||
instead of calling gdb_readline2, give gdb a chance to detect
|
||||
errors and do something. */
|
||||
void
|
||||
stdin_event_handler (int error, int fd, gdb_client_data client_data)
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
printf_unfiltered ("error detected on stdin, fd %d\n", fd);
|
||||
delete_file_handler (fd);
|
||||
discard_all_continuations ();
|
||||
/* If stdin died, we may as well kill gdb. */
|
||||
exit (1);
|
||||
}
|
||||
else
|
||||
(*call_readline) (client_data);
|
||||
}
|
||||
|
||||
|
||||
/* Handles a gdb command. This function is called by
|
||||
command_line_handler, which has processed one or more input lines
|
||||
@ -406,8 +421,7 @@ pop_prompt ()
|
||||
function. The command_loop function will be obsolete when we
|
||||
switch to use the event loop at every execution of gdb. */
|
||||
static void
|
||||
command_handler (command)
|
||||
char *command;
|
||||
command_handler (char *command)
|
||||
{
|
||||
struct cleanup *old_chain;
|
||||
int stdin_is_tty = ISATTY (stdin);
|
||||
@ -507,8 +521,7 @@ command_handler (command)
|
||||
are always running synchronously. Or if we have just executed a
|
||||
command that doesn't start the target. */
|
||||
void
|
||||
command_line_handler_continuation (arg)
|
||||
struct continuation_arg *arg;
|
||||
command_line_handler_continuation (struct continuation_arg *arg)
|
||||
{
|
||||
extern int display_time;
|
||||
extern int display_space;
|
||||
@ -551,8 +564,7 @@ command_line_handler_continuation (arg)
|
||||
obsolete once we use the event loop as the default mechanism in
|
||||
GDB. */
|
||||
static void
|
||||
command_line_handler (rl)
|
||||
char *rl;
|
||||
command_line_handler (char *rl)
|
||||
{
|
||||
static char *linebuffer = 0;
|
||||
static unsigned linelength = 0;
|
||||
@ -768,7 +780,7 @@ command_line_handler (rl)
|
||||
will become obsolete when the event loop is made the default
|
||||
execution for gdb. */
|
||||
void
|
||||
gdb_readline2 ()
|
||||
gdb_readline2 (gdb_client_data client_data)
|
||||
{
|
||||
int c;
|
||||
char *result;
|
||||
@ -851,7 +863,7 @@ gdb_readline2 ()
|
||||
init_signals will become obsolete as we move to have to event loop
|
||||
as the default for gdb. */
|
||||
void
|
||||
async_init_signals ()
|
||||
async_init_signals (void)
|
||||
{
|
||||
signal (SIGINT, handle_sigint);
|
||||
sigint_token =
|
||||
@ -899,17 +911,15 @@ async_init_signals ()
|
||||
}
|
||||
|
||||
void
|
||||
mark_async_signal_handler_wrapper (token)
|
||||
void *token;
|
||||
mark_async_signal_handler_wrapper (PTR token)
|
||||
{
|
||||
mark_async_signal_handler ((async_signal_handler *) token);
|
||||
mark_async_signal_handler ((struct async_signal_handler *) token);
|
||||
}
|
||||
|
||||
/* Tell the event loop what to do if SIGINT is received.
|
||||
See event-signal.c. */
|
||||
void
|
||||
handle_sigint (sig)
|
||||
int sig;
|
||||
handle_sigint (int sig)
|
||||
{
|
||||
signal (sig, handle_sigint);
|
||||
|
||||
@ -930,8 +940,7 @@ handle_sigint (sig)
|
||||
|
||||
/* Do the quit. All the checks have been done by the caller. */
|
||||
void
|
||||
async_request_quit (arg)
|
||||
gdb_client_data arg;
|
||||
async_request_quit (gdb_client_data arg)
|
||||
{
|
||||
quit_flag = 1;
|
||||
#ifdef REQUEST_QUIT
|
||||
@ -944,8 +953,7 @@ async_request_quit (arg)
|
||||
/* Tell the event loop what to do if SIGQUIT is received.
|
||||
See event-signal.c. */
|
||||
static void
|
||||
handle_sigquit (sig)
|
||||
int sig;
|
||||
handle_sigquit (int sig)
|
||||
{
|
||||
mark_async_signal_handler_wrapper (sigquit_token);
|
||||
signal (sig, handle_sigquit);
|
||||
@ -953,8 +961,7 @@ handle_sigquit (sig)
|
||||
|
||||
/* Called by the event loop in response to a SIGQUIT. */
|
||||
static void
|
||||
async_do_nothing (arg)
|
||||
gdb_client_data arg;
|
||||
async_do_nothing (gdb_client_data arg)
|
||||
{
|
||||
/* Empty function body. */
|
||||
}
|
||||
@ -972,8 +979,7 @@ handle_sighup (sig)
|
||||
|
||||
/* Called by the event loop to process a SIGHUP */
|
||||
static void
|
||||
async_disconnect (arg)
|
||||
gdb_client_data arg;
|
||||
async_disconnect (gdb_client_data arg)
|
||||
{
|
||||
catch_errors (quit_cover, NULL,
|
||||
"Could not kill the program being debugged",
|
||||
@ -985,16 +991,14 @@ async_disconnect (arg)
|
||||
|
||||
#ifdef STOP_SIGNAL
|
||||
void
|
||||
handle_stop_sig (sig)
|
||||
int sig;
|
||||
handle_stop_sig (int sig)
|
||||
{
|
||||
mark_async_signal_handler_wrapper (sigtstp_token);
|
||||
signal (sig, handle_stop_sig);
|
||||
}
|
||||
|
||||
static void
|
||||
async_stop_sig (arg)
|
||||
gdb_client_data arg;
|
||||
async_stop_sig (gdb_client_data arg)
|
||||
{
|
||||
char *prompt = get_prompt ();
|
||||
#if STOP_SIGNAL == SIGTSTP
|
||||
@ -1016,8 +1020,7 @@ async_stop_sig (arg)
|
||||
/* Tell the event loop what to do if SIGFPE is received.
|
||||
See event-signal.c. */
|
||||
static void
|
||||
handle_sigfpe (sig)
|
||||
int sig;
|
||||
handle_sigfpe (int sig)
|
||||
{
|
||||
mark_async_signal_handler_wrapper (sigfpe_token);
|
||||
signal (sig, handle_sigfpe);
|
||||
@ -1025,8 +1028,7 @@ handle_sigfpe (sig)
|
||||
|
||||
/* Event loop will call this functin to process a SIGFPE. */
|
||||
static void
|
||||
async_float_handler (arg)
|
||||
gdb_client_data arg;
|
||||
async_float_handler (gdb_client_data arg)
|
||||
{
|
||||
/* This message is based on ANSI C, section 4.7. Note that integer
|
||||
divide by zero causes this, so "float" is a misnomer. */
|
||||
@ -1037,8 +1039,7 @@ async_float_handler (arg)
|
||||
See event-signal.c. */
|
||||
#if defined(SIGWINCH) && defined(SIGWINCH_HANDLER)
|
||||
static void
|
||||
handle_sigwinch (sig)
|
||||
int sig;
|
||||
handle_sigwinch (int sig)
|
||||
{
|
||||
mark_async_signal_handler_wrapper (sigwinch_token);
|
||||
signal (sig, handle_sigwinch);
|
||||
@ -1049,10 +1050,7 @@ handle_sigwinch (sig)
|
||||
/* Called by do_setshow_command. */
|
||||
/* ARGSUSED */
|
||||
void
|
||||
set_async_editing_command (args, from_tty, c)
|
||||
char *args;
|
||||
int from_tty;
|
||||
struct cmd_list_element *c;
|
||||
set_async_editing_command (char *args, int from_tty, struct cmd_list_element *c)
|
||||
{
|
||||
change_line_handler ();
|
||||
}
|
||||
@ -1060,10 +1058,7 @@ set_async_editing_command (args, from_tty, c)
|
||||
/* Called by do_setshow_command. */
|
||||
/* ARGSUSED */
|
||||
void
|
||||
set_async_annotation_level (args, from_tty, c)
|
||||
char *args;
|
||||
int from_tty;
|
||||
struct cmd_list_element *c;
|
||||
set_async_annotation_level (char *args, int from_tty, struct cmd_list_element *c)
|
||||
{
|
||||
change_annotation_level ();
|
||||
}
|
||||
@ -1071,10 +1066,7 @@ set_async_annotation_level (args, from_tty, c)
|
||||
/* Called by do_setshow_command. */
|
||||
/* ARGSUSED */
|
||||
void
|
||||
set_async_prompt (args, from_tty, c)
|
||||
char *args;
|
||||
int from_tty;
|
||||
struct cmd_list_element *c;
|
||||
set_async_prompt (char *args, int from_tty, struct cmd_list_element *c)
|
||||
{
|
||||
PROMPT (0) = savestring (new_async_prompt, strlen (new_async_prompt));
|
||||
}
|
||||
@ -1083,13 +1075,13 @@ set_async_prompt (args, from_tty, c)
|
||||
interface, i.e. via a callback function (rl_callback_read_char),
|
||||
and hook up instream to the event loop. */
|
||||
void
|
||||
_initialize_event_loop ()
|
||||
_initialize_event_loop (void)
|
||||
{
|
||||
if (async_p)
|
||||
{
|
||||
/* When a character is detected on instream by select or poll,
|
||||
readline will be invoked via this callback function. */
|
||||
call_readline = rl_callback_read_char;
|
||||
call_readline = rl_callback_read_char_wrapper;
|
||||
|
||||
/* When readline has read an end-of-line character, it passes
|
||||
the complete line to gdb for processing. command_line_handler
|
||||
@ -1113,7 +1105,7 @@ _initialize_event_loop ()
|
||||
the target program (inferior), but that must be registered
|
||||
only when it actually exists (I.e. after we say 'run' or
|
||||
after we connect to a remote target. */
|
||||
add_file_handler (input_fd, call_readline, 0);
|
||||
add_file_handler (input_fd, stdin_event_handler, 0);
|
||||
|
||||
/* Tell gdb that we will be using the readline library. This
|
||||
could be overwritten by a command in .gdbinit like 'set
|
||||
|
104
gdb/event-top.h
Normal file
104
gdb/event-top.h
Normal file
@ -0,0 +1,104 @@
|
||||
/* Definitions used by GDB event-top.c.
|
||||
Copyright 1999 Free Software Foundation, Inc.
|
||||
Written by Elena Zannoni <ezannoni@cygnus.com> of Cygnus Solutions.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Stack for prompts. Each prompt is composed as a prefix, a prompt
|
||||
and a suffix. The prompt to be displayed at any given time is the
|
||||
one on top of the stack. A stack is necessary because of cases in
|
||||
which the execution of a gdb command requires further input from
|
||||
the user, like for instance 'commands' for breakpoints and
|
||||
'actions' for tracepoints. In these cases, the prompt is '>' and
|
||||
gdb should process input using the asynchronous readline interface
|
||||
and the event loop. In order to achieve this, we need to save
|
||||
somewhere the state of GDB, i.e. that it is processing user input
|
||||
as part of a command and not as part of the top level command loop.
|
||||
The prompt stack represents part of the saved state. Another part
|
||||
would be the function that readline would invoke after a whole line
|
||||
of input has ben entered. This second piece would be something
|
||||
like, for instance, where to return within the code for the actions
|
||||
commands after a line has been read. This latter portion has not
|
||||
beeen implemented yet. The need for a 3-part prompt arises from
|
||||
the annotation level. When this is set to 2, the prompt is actually
|
||||
composed of a prefix, the prompt itself and a suffix. */
|
||||
|
||||
/* At any particular time there will be always at least one prompt on
|
||||
the stack, the one being currently displayed by gdb. If gdb is
|
||||
using annotation level equal 2, there will be 2 prompts on the
|
||||
stack: the usual one, w/o prefix and suffix (at top - 1), and the
|
||||
'composite' one with prefix and suffix added (at top). At this
|
||||
time, this is the only use of the prompt stack. Resetting annotate
|
||||
to 0 or 1, pops the top of the stack, resetting its size to one
|
||||
element. The MAXPROMPTS limit is safe, for now. Once other cases
|
||||
are dealt with (like the different prompts used for 'commands' or
|
||||
'actions') this array implementation of the prompt stack may have
|
||||
to change. */
|
||||
|
||||
#define MAXPROMPTS 10
|
||||
struct prompts
|
||||
{
|
||||
struct
|
||||
{
|
||||
char *prefix;
|
||||
char *prompt;
|
||||
char *suffix;
|
||||
}
|
||||
prompt_stack[MAXPROMPTS];
|
||||
int top;
|
||||
};
|
||||
|
||||
#define PROMPT(X) the_prompts.prompt_stack[the_prompts.top + X].prompt
|
||||
#define PREFIX(X) the_prompts.prompt_stack[the_prompts.top + X].prefix
|
||||
#define SUFFIX(X) the_prompts.prompt_stack[the_prompts.top + X].suffix
|
||||
|
||||
/* Exported functions from event-top.c.
|
||||
FIXME: these should really go into top.h. */
|
||||
|
||||
extern void display_gdb_prompt (char *new_prompt);
|
||||
extern void async_init_signals (void);
|
||||
extern void set_async_editing_command (char *args, int from_tty, struct cmd_list_element *c);
|
||||
extern void set_async_annotation_level (char *args, int from_tty, struct cmd_list_element *c);
|
||||
extern void set_async_prompt (char *args, int from_tty, struct cmd_list_element *c);
|
||||
|
||||
/* Signal to catch ^Z typed while reading a command: SIGTSTP or SIGCONT. */
|
||||
#ifndef STOP_SIGNAL
|
||||
#ifdef SIGTSTP
|
||||
#define STOP_SIGNAL SIGTSTP
|
||||
extern void handle_stop_sig (int sig);
|
||||
#endif
|
||||
#endif
|
||||
extern void handle_sigint (int sig);
|
||||
extern void pop_prompt (void);
|
||||
extern void push_prompt (char *prefix, char *prompt, char *suffix);
|
||||
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);
|
||||
|
||||
/* Exported variables from event-top.c.
|
||||
FIXME: these should really go into top.h. */
|
||||
|
||||
extern int async_command_editing_p;
|
||||
extern int exec_done_display_p;
|
||||
extern char *async_annotation_suffix;
|
||||
extern char *new_async_prompt;
|
||||
extern struct prompts the_prompts;
|
||||
extern void (*call_readline) (gdb_client_data);
|
||||
extern void (*input_handler) (char *);
|
||||
extern int input_fd;
|
12
gdb/frame.h
12
gdb/frame.h
@ -27,13 +27,13 @@
|
||||
/* XXXX - deprecated */
|
||||
struct frame_saved_regs
|
||||
{
|
||||
/* For each register R (except the SP), regs[R] is the address at
|
||||
which it was saved on entry to the frame, or zero if it was not
|
||||
saved on entry to this frame. This includes special registers
|
||||
such as pc and fp saved in special ways in the stack frame.
|
||||
|
||||
/* For each register, address of where it was saved on entry to
|
||||
the frame, or zero if it was not saved on entry to this frame.
|
||||
This includes special registers such as pc and fp saved in
|
||||
special ways in the stack frame. The SP_REGNUM is even more
|
||||
special, the address here is the sp for the next frame, not the
|
||||
address where the sp was saved. */
|
||||
regs[SP_REGNUM] is different. It holds the actual SP, not the
|
||||
address at which it was saved. */
|
||||
|
||||
CORE_ADDR regs[NUM_REGS];
|
||||
};
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <io.h>
|
||||
#include <dpmi.h>
|
||||
#include <debug/v2load.h>
|
||||
@ -797,6 +798,7 @@ ignore (void)
|
||||
do {\
|
||||
CONTROL &= ~(DR_CONTROL_MASK << (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * (index)));\
|
||||
D_REGS[index] = address;\
|
||||
dr_ref_count[index]++;\
|
||||
} while(0)
|
||||
|
||||
#define SET_WATCH(index,address,rw,len) \
|
||||
@ -808,11 +810,7 @@ ignore (void)
|
||||
#define IS_WATCH(index) \
|
||||
(CONTROL & (DR_CONTROL_MASK << (DR_CONTROL_SHIFT + DR_CONTROL_SIZE*(index))))
|
||||
|
||||
#define WATCH_HIT(index) \
|
||||
(\
|
||||
(STATUS & (1 << index)) && \
|
||||
(CONTROL & (DR_CONTROL_MASK << (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * index)))\
|
||||
)
|
||||
#define WATCH_HIT(index) ((STATUS & (1 << (index))) && IS_WATCH(index))
|
||||
|
||||
#define DR_DEF(index) \
|
||||
((CONTROL >> (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * (index))) & 0x0f)
|
||||
@ -1142,10 +1140,6 @@ go32_insert_hw_breakpoint (CORE_ADDR addr, CORE_ADDR shadow)
|
||||
return i < 4 ? 0 : -1;
|
||||
}
|
||||
|
||||
static int inf_flags_valid = 0;
|
||||
static int inf_in_flag;
|
||||
static int inf_out_flag;
|
||||
|
||||
/* Put the device open on handle FD into either raw or cooked
|
||||
mode, return 1 if it was in raw mode, zero otherwise. */
|
||||
|
||||
|
344
gdb/hppa-tdep.c
344
gdb/hppa-tdep.c
@ -341,8 +341,12 @@ internalize_unwinds (objfile, table, section, entries, size, text_offset)
|
||||
low_text_segment_address = -1;
|
||||
|
||||
/* If addresses are 64 bits wide, then unwinds are supposed to
|
||||
be segment relative offsets instead of absolute addresses. */
|
||||
if (TARGET_PTR_BIT == 64)
|
||||
be segment relative offsets instead of absolute addresses.
|
||||
|
||||
Note that when loading a shared library (text_offset != 0) the
|
||||
unwinds are already relative to the text_offset that will be
|
||||
passed in. */
|
||||
if (TARGET_PTR_BIT == 64 && text_offset == 0)
|
||||
{
|
||||
bfd_map_over_sections (objfile->obfd,
|
||||
record_text_segment_lowaddr, (PTR) NULL);
|
||||
@ -1102,6 +1106,12 @@ frame_chain (frame)
|
||||
CORE_ADDR frame_base;
|
||||
struct frame_info *tmp_frame;
|
||||
|
||||
/* A frame in the current frame list, or zero. */
|
||||
struct frame_info *saved_regs_frame = 0;
|
||||
/* Where the registers were saved in saved_regs_frame.
|
||||
If saved_regs_frame is zero, this is garbage. */
|
||||
struct frame_saved_regs saved_regs;
|
||||
|
||||
CORE_ADDR caller_pc;
|
||||
|
||||
struct minimal_symbol *min_frame_symbol;
|
||||
@ -1195,8 +1205,7 @@ frame_chain (frame)
|
||||
We use information from unwind descriptors to determine if %r3
|
||||
is saved into the stack (Entry_GR field has this information). */
|
||||
|
||||
tmp_frame = frame;
|
||||
while (tmp_frame)
|
||||
for (tmp_frame = frame; tmp_frame; tmp_frame = tmp_frame->next)
|
||||
{
|
||||
u = find_unwind_entry (tmp_frame->pc);
|
||||
|
||||
@ -1216,14 +1225,25 @@ frame_chain (frame)
|
||||
return (CORE_ADDR) 0;
|
||||
}
|
||||
|
||||
/* Entry_GR specifies the number of callee-saved general registers
|
||||
saved in the stack. It starts at %r3, so %r3 would be 1. */
|
||||
if (u->Entry_GR >= 1 || u->Save_SP
|
||||
if (u->Save_SP
|
||||
|| tmp_frame->signal_handler_caller
|
||||
|| pc_in_interrupt_handler (tmp_frame->pc))
|
||||
break;
|
||||
else
|
||||
tmp_frame = tmp_frame->next;
|
||||
|
||||
/* Entry_GR specifies the number of callee-saved general registers
|
||||
saved in the stack. It starts at %r3, so %r3 would be 1. */
|
||||
if (u->Entry_GR >= 1)
|
||||
{
|
||||
/* The unwind entry claims that r3 is saved here. However,
|
||||
in optimized code, GCC often doesn't actually save r3.
|
||||
We'll discover this if we look at the prologue. */
|
||||
get_frame_saved_regs (tmp_frame, &saved_regs);
|
||||
saved_regs_frame = tmp_frame;
|
||||
|
||||
/* If we have an address for r3, that's good. */
|
||||
if (saved_regs.regs[FP_REGNUM])
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (tmp_frame)
|
||||
@ -1239,8 +1259,6 @@ frame_chain (frame)
|
||||
/* %r3 was saved somewhere in the stack. Dig it out. */
|
||||
else
|
||||
{
|
||||
struct frame_saved_regs saved_regs;
|
||||
|
||||
/* Sick.
|
||||
|
||||
For optimization purposes many kernels don't have the
|
||||
@ -1267,7 +1285,8 @@ frame_chain (frame)
|
||||
fail miserably if the function which performs the
|
||||
system call has a variable sized stack frame. */
|
||||
|
||||
get_frame_saved_regs (tmp_frame, &saved_regs);
|
||||
if (tmp_frame != saved_regs_frame)
|
||||
get_frame_saved_regs (tmp_frame, &saved_regs);
|
||||
|
||||
/* Abominable hack. */
|
||||
if (current_target.to_has_execution == 0
|
||||
@ -1296,14 +1315,14 @@ frame_chain (frame)
|
||||
}
|
||||
else
|
||||
{
|
||||
struct frame_saved_regs saved_regs;
|
||||
|
||||
/* Get the innermost frame. */
|
||||
tmp_frame = frame;
|
||||
while (tmp_frame->next != NULL)
|
||||
tmp_frame = tmp_frame->next;
|
||||
|
||||
get_frame_saved_regs (tmp_frame, &saved_regs);
|
||||
if (tmp_frame != saved_regs_frame)
|
||||
get_frame_saved_regs (tmp_frame, &saved_regs);
|
||||
|
||||
/* Abominable hack. See above. */
|
||||
if (current_target.to_has_execution == 0
|
||||
&& ((saved_regs.regs[FLAGS_REGNUM]
|
||||
@ -1670,19 +1689,22 @@ restore_pc_queue (fsr)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
#ifdef PA20W_CALLING_CONVENTIONS
|
||||
|
||||
/* This function pushes a stack frame with arguments as part of the
|
||||
inferior function calling mechanism.
|
||||
|
||||
For PAs the stack always grows to higher addresses. However the arguments
|
||||
may grow to either higher or lower addresses depending on which ABI is
|
||||
currently in use.
|
||||
This is the version for the PA64, in which later arguments appear
|
||||
at higher addresses. (The stack always grows towards higher
|
||||
addresses.)
|
||||
|
||||
We simply allocate the appropriate amount of stack space and put
|
||||
arguments into their proper slots. The call dummy code will copy
|
||||
arguments into registers as needed by the ABI.
|
||||
|
||||
Note for the PA64 ABI we load up the argument pointer since the caller
|
||||
must provide the argument pointer to the callee. */
|
||||
This ABI also requires that the caller provide an argument pointer
|
||||
to the callee, so we do that too. */
|
||||
|
||||
CORE_ADDR
|
||||
hppa_push_arguments (nargs, args, sp, struct_return, struct_addr)
|
||||
@ -1713,6 +1735,125 @@ hppa_push_arguments (nargs, args, sp, struct_return, struct_addr)
|
||||
int cum_bytes_aligned = 0;
|
||||
int i;
|
||||
|
||||
/* Iterate over each argument provided by the user. */
|
||||
for (i = 0; i < nargs; i++)
|
||||
{
|
||||
struct type *arg_type = VALUE_TYPE (args[i]);
|
||||
|
||||
/* Integral scalar values smaller than a register are padded on
|
||||
the left. We do this by promoting them to full-width,
|
||||
although the ABI says to pad them with garbage. */
|
||||
if (is_integral_type (arg_type)
|
||||
&& TYPE_LENGTH (arg_type) < REGISTER_SIZE)
|
||||
{
|
||||
args[i] = value_cast ((TYPE_UNSIGNED (arg_type)
|
||||
? builtin_type_unsigned_long
|
||||
: builtin_type_long),
|
||||
args[i]);
|
||||
arg_type = VALUE_TYPE (args[i]);
|
||||
}
|
||||
|
||||
lengths[i] = TYPE_LENGTH (arg_type);
|
||||
|
||||
/* Align the size of the argument to the word size for this
|
||||
target. */
|
||||
bytes_reserved = (lengths[i] + REGISTER_SIZE - 1) & -REGISTER_SIZE;
|
||||
|
||||
offset[i] = cum_bytes_reserved;
|
||||
|
||||
/* Aggregates larger than eight bytes (the only types larger
|
||||
than eight bytes we have) are aligned on a 16-byte boundary,
|
||||
possibly padded on the right with garbage. This may leave an
|
||||
empty word on the stack, and thus an unused register, as per
|
||||
the ABI. */
|
||||
if (bytes_reserved > 8)
|
||||
{
|
||||
/* Round up the offset to a multiple of two slots. */
|
||||
int new_offset = ((offset[i] + 2*REGISTER_SIZE-1)
|
||||
& -(2*REGISTER_SIZE));
|
||||
|
||||
/* Note the space we've wasted, if any. */
|
||||
bytes_reserved += new_offset - offset[i];
|
||||
offset[i] = new_offset;
|
||||
}
|
||||
|
||||
cum_bytes_reserved += bytes_reserved;
|
||||
}
|
||||
|
||||
/* CUM_BYTES_RESERVED already accounts for all the arguments
|
||||
passed by the user. However, the ABIs mandate minimum stack space
|
||||
allocations for outgoing arguments.
|
||||
|
||||
The ABIs also mandate minimum stack alignments which we must
|
||||
preserve. */
|
||||
cum_bytes_aligned = STACK_ALIGN (cum_bytes_reserved);
|
||||
sp += max (cum_bytes_aligned, REG_PARM_STACK_SPACE);
|
||||
|
||||
/* Now write each of the args at the proper offset down the stack. */
|
||||
for (i = 0; i < nargs; i++)
|
||||
write_memory (orig_sp + offset[i], VALUE_CONTENTS (args[i]), lengths[i]);
|
||||
|
||||
/* If a structure has to be returned, set up register 28 to hold its
|
||||
address */
|
||||
if (struct_return)
|
||||
write_register (28, struct_addr);
|
||||
|
||||
/* For the PA64 we must pass a pointer to the outgoing argument list.
|
||||
The ABI mandates that the pointer should point to the first byte of
|
||||
storage beyond the register flushback area.
|
||||
|
||||
However, the call dummy expects the outgoing argument pointer to
|
||||
be passed in register %r4. */
|
||||
write_register (4, orig_sp + REG_PARM_STACK_SPACE);
|
||||
|
||||
/* ?!? This needs further work. We need to set up the global data
|
||||
pointer for this procedure. This assumes the same global pointer
|
||||
for every procedure. The call dummy expects the dp value to
|
||||
be passed in register %r6. */
|
||||
write_register (6, read_register (27));
|
||||
|
||||
/* The stack will have 64 bytes of additional space for a frame marker. */
|
||||
return sp + 64;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* This function pushes a stack frame with arguments as part of the
|
||||
inferior function calling mechanism.
|
||||
|
||||
This is the version of the function for the 32-bit PA machines, in
|
||||
which later arguments appear at lower addresses. (The stack always
|
||||
grows towards higher addresses.)
|
||||
|
||||
We simply allocate the appropriate amount of stack space and put
|
||||
arguments into their proper slots. The call dummy code will copy
|
||||
arguments into registers as needed by the ABI. */
|
||||
|
||||
CORE_ADDR
|
||||
hppa_push_arguments (nargs, args, sp, struct_return, struct_addr)
|
||||
int nargs;
|
||||
value_ptr *args;
|
||||
CORE_ADDR sp;
|
||||
int struct_return;
|
||||
CORE_ADDR struct_addr;
|
||||
{
|
||||
/* array of arguments' offsets */
|
||||
int *offset = (int *) alloca (nargs * sizeof (int));
|
||||
|
||||
/* array of arguments' lengths: real lengths in bytes, not aligned to
|
||||
word size */
|
||||
int *lengths = (int *) alloca (nargs * sizeof (int));
|
||||
|
||||
/* The number of stack bytes occupied by the current argument. */
|
||||
int bytes_reserved;
|
||||
|
||||
/* The total number of bytes reserved for the arguments. */
|
||||
int cum_bytes_reserved = 0;
|
||||
|
||||
/* Similarly, but aligned. */
|
||||
int cum_bytes_aligned = 0;
|
||||
int i;
|
||||
|
||||
/* Iterate over each argument provided by the user. */
|
||||
for (i = 0; i < nargs; i++)
|
||||
{
|
||||
@ -1722,24 +1863,12 @@ hppa_push_arguments (nargs, args, sp, struct_return, struct_addr)
|
||||
target. */
|
||||
bytes_reserved = (lengths[i] + REGISTER_SIZE - 1) & -REGISTER_SIZE;
|
||||
|
||||
#ifdef ARGS_GROW_DOWNWARD
|
||||
offset[i] = cum_bytes_reserved + lengths[i];
|
||||
#else
|
||||
/* If the arguments grow towards lower addresses, then we want
|
||||
offset[i] to point to the start of the argument rather than
|
||||
the end of the argument. */
|
||||
offset[i] = cum_bytes_reserved;
|
||||
|
||||
offset[i] += (lengths[i] < REGISTER_SIZE
|
||||
? REGISTER_SIZE - lengths[i] : 0);
|
||||
#endif
|
||||
|
||||
/* If the argument is a double word argument, then it needs to be
|
||||
double word aligned.
|
||||
|
||||
?!? I do not think this code is correct when !ARGS_GROW_DOWNWAR. */
|
||||
double word aligned. */
|
||||
if ((bytes_reserved == 2 * REGISTER_SIZE)
|
||||
&& (offset[i] % 2 * REGISTER_SIZE))
|
||||
&& (offset[i] % 2 * REGISTER_SIZE))
|
||||
{
|
||||
int new_offset = 0;
|
||||
/* BYTES_RESERVED is already aligned to the word, so we put
|
||||
@ -1761,55 +1890,31 @@ hppa_push_arguments (nargs, args, sp, struct_return, struct_addr)
|
||||
|
||||
}
|
||||
|
||||
/* CUM_BYTES_RESERVED already accounts for all the arguments
|
||||
passed by the user. However, the ABIs mandate minimum stack space
|
||||
/* CUM_BYTES_RESERVED already accounts for all the arguments passed
|
||||
by the user. However, the ABI mandates minimum stack space
|
||||
allocations for outgoing arguments.
|
||||
|
||||
The ABIs also mandate minimum stack alignments which we must
|
||||
The ABI also mandates minimum stack alignments which we must
|
||||
preserve. */
|
||||
cum_bytes_aligned = STACK_ALIGN (cum_bytes_reserved);
|
||||
sp += max (cum_bytes_aligned, REG_PARM_STACK_SPACE);
|
||||
|
||||
/* Now write each of the args at the proper offset down the stack.
|
||||
|
||||
The two ABIs write arguments in different directions using different
|
||||
starting points. What fun.
|
||||
|
||||
?!? We need to promote values to a full register instead of skipping
|
||||
words in the stack. */
|
||||
#ifndef ARGS_GROW_DOWNWARD
|
||||
for (i = 0; i < nargs; i++)
|
||||
write_memory (orig_sp + offset[i], VALUE_CONTENTS (args[i]), lengths[i]);
|
||||
#else
|
||||
for (i = 0; i < nargs; i++)
|
||||
write_memory (sp - offset[i], VALUE_CONTENTS (args[i]), lengths[i]);
|
||||
#endif
|
||||
|
||||
/* If a structure has to be returned, set up register 28 to hold its
|
||||
address */
|
||||
if (struct_return)
|
||||
write_register (28, struct_addr);
|
||||
|
||||
#ifndef ARGS_GROW_DOWNWARD
|
||||
/* For the PA64 we must pass a pointer to the outgoing argument list.
|
||||
The ABI mandates that the pointer should point to the first byte of
|
||||
storage beyond the register flushback area.
|
||||
|
||||
However, the call dummy expects the outgoing argument pointer to
|
||||
be passed in register %r4. */
|
||||
write_register (4, orig_sp + REG_PARM_STACK_SPACE);
|
||||
|
||||
/* ?!? This needs further work. We need to set up the global data
|
||||
pointer for this procedure. This assumes the same global pointer
|
||||
for every procedure. The call dummy expects the dp value to
|
||||
be passed in register %r6. */
|
||||
write_register (6, read_register (27));
|
||||
#endif
|
||||
|
||||
/* The stack will have 32 bytes of additional space for a frame marker. */
|
||||
return sp + 32;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* elz: this function returns a value which is built looking at the given address.
|
||||
It is called from call_function_by_hand, in case we need to return a
|
||||
@ -1973,8 +2078,8 @@ hppa_fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p)
|
||||
CORE_ADDR solib_handle = 0;
|
||||
|
||||
/* Nonzero if we will use GCC's PLT call routine. This routine must be
|
||||
passed an import stub, not a PLABEL. It is also necessary to set %r19
|
||||
(the PIC register) before performing the call.
|
||||
passed an import stub, not a PLABEL. It is also necessary to set %r19
|
||||
(the PIC register) before performing the call.
|
||||
|
||||
If zero, then we are using __d_plt_call (HP's PLT call routine) or we
|
||||
are calling the target directly. When using __d_plt_call we want to
|
||||
@ -2045,7 +2150,7 @@ hppa_fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p)
|
||||
write_register (5, fun);
|
||||
|
||||
/* We need to see if this objfile has a different DP value than our
|
||||
own (it could be a shared library for example. */
|
||||
own (it could be a shared library for example). */
|
||||
ALL_OBJFILES (objfile)
|
||||
{
|
||||
struct obj_section *s;
|
||||
@ -2822,8 +2927,73 @@ in_solib_call_trampoline (pc, name)
|
||||
static CORE_ADDR dyncall = 0;
|
||||
static CORE_ADDR sr4export = 0;
|
||||
|
||||
/* FIXME XXX - dyncall and sr4export must be initialized whenever we get a
|
||||
new exec file */
|
||||
#ifdef GDB_TARGET_IS_HPPA_20W
|
||||
/* PA64 has a completely different stub/trampoline scheme. Is it
|
||||
better? Maybe. It's certainly harder to determine with any
|
||||
certainty that we are in a stub because we can not refer to the
|
||||
unwinders to help.
|
||||
|
||||
The heuristic is simple. Try to lookup the current PC value in th
|
||||
minimal symbol table. If that fails, then assume we are not in a
|
||||
stub and return.
|
||||
|
||||
Then see if the PC value falls within the section bounds for the
|
||||
section containing the minimal symbol we found in the first
|
||||
step. If it does, then assume we are not in a stub and return.
|
||||
|
||||
Finally peek at the instructions to see if they look like a stub. */
|
||||
{
|
||||
struct minimal_symbol *minsym;
|
||||
asection *sec;
|
||||
CORE_ADDR addr;
|
||||
int insn, i;
|
||||
|
||||
minsym = lookup_minimal_symbol_by_pc (pc);
|
||||
if (! minsym)
|
||||
return 0;
|
||||
|
||||
sec = SYMBOL_BFD_SECTION (minsym);
|
||||
|
||||
if (sec->vma <= pc
|
||||
&& sec->vma + sec->_cooked_size < pc)
|
||||
return 0;
|
||||
|
||||
/* We might be in a stub. Peek at the instructions. Stubs are 3
|
||||
instructions long. */
|
||||
insn = read_memory_integer (pc, 4);
|
||||
|
||||
/* Find out where we we think we are within the stub. */
|
||||
if ((insn & 0xffffc00e) == 0x53610000)
|
||||
addr = pc;
|
||||
else if ((insn & 0xffffffff) == 0xe820d000)
|
||||
addr = pc - 4;
|
||||
else if ((insn & 0xffffc00e) == 0x537b0000)
|
||||
addr = pc - 8;
|
||||
else
|
||||
return 0;
|
||||
|
||||
/* Now verify each insn in the range looks like a stub instruction. */
|
||||
insn = read_memory_integer (addr, 4);
|
||||
if ((insn & 0xffffc00e) != 0x53610000)
|
||||
return 0;
|
||||
|
||||
/* Now verify each insn in the range looks like a stub instruction. */
|
||||
insn = read_memory_integer (addr + 4, 4);
|
||||
if ((insn & 0xffffffff) != 0xe820d000)
|
||||
return 0;
|
||||
|
||||
/* Now verify each insn in the range looks like a stub instruction. */
|
||||
insn = read_memory_integer (addr + 8, 4);
|
||||
if ((insn & 0xffffc00e) != 0x537b0000)
|
||||
return 0;
|
||||
|
||||
/* Looks like a stub. */
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* FIXME XXX - dyncall and sr4export must be initialized whenever we get a
|
||||
new exec file */
|
||||
|
||||
/* First see if PC is in one of the two C-library trampolines. */
|
||||
if (!dyncall)
|
||||
@ -2997,9 +3167,8 @@ skip_trampoline_code (pc, name)
|
||||
struct minimal_symbol *msym;
|
||||
struct unwind_table_entry *u;
|
||||
|
||||
|
||||
/* FIXME XXX - dyncall and sr4export must be initialized whenever we get a
|
||||
new exec file */
|
||||
/* FIXME XXX - dyncall and sr4export must be initialized whenever we get a
|
||||
new exec file */
|
||||
|
||||
if (!dyncall)
|
||||
{
|
||||
@ -3829,16 +3998,21 @@ hppa_frame_find_saved_regs (frame_info, frame_saved_regs)
|
||||
|
||||
/* There are limited ways to store the return pointer into the
|
||||
stack. */
|
||||
if (inst == 0x6bc23fd9 || inst == 0x0fc212c1)
|
||||
if (inst == 0x6bc23fd9) /* stw rp,-0x14(sr0,sp) */
|
||||
{
|
||||
save_rp = 0;
|
||||
frame_saved_regs->regs[RP_REGNUM] = frame_info->frame - 20;
|
||||
}
|
||||
else if (inst == 0x0fc212c1) /* std rp,-0x10(sr0,sp) */
|
||||
{
|
||||
save_rp = 0;
|
||||
frame_saved_regs->regs[RP_REGNUM] = frame_info->frame - 16;
|
||||
}
|
||||
|
||||
/* Note if we saved SP into the stack. This also happens to indicate
|
||||
the location of the saved frame pointer. */
|
||||
if ((inst & 0xffffc000) == 0x6fc10000
|
||||
|| (inst & 0xffffc00c) == 0x73c10008)
|
||||
if ( (inst & 0xffffc000) == 0x6fc10000 /* stw,ma r1,N(sr0,sp) */
|
||||
|| (inst & 0xffffc00c) == 0x73c10008) /* std,ma r1,N(sr0,sp) */
|
||||
{
|
||||
frame_saved_regs->regs[FP_REGNUM] = frame_info->frame;
|
||||
save_sp = 0;
|
||||
@ -4541,6 +4715,30 @@ hppa_prepare_to_proceed ()
|
||||
}
|
||||
#endif /* PREPARE_TO_PROCEED */
|
||||
|
||||
void
|
||||
hppa_skip_permanent_breakpoint ()
|
||||
{
|
||||
/* To step over a breakpoint instruction on the PA takes some
|
||||
fiddling with the instruction address queue.
|
||||
|
||||
When we stop at a breakpoint, the IA queue front (the instruction
|
||||
we're executing now) points at the breakpoint instruction, and
|
||||
the IA queue back (the next instruction to execute) points to
|
||||
whatever instruction we would execute after the breakpoint, if it
|
||||
were an ordinary instruction. This is the case even if the
|
||||
breakpoint is in the delay slot of a branch instruction.
|
||||
|
||||
Clearly, to step past the breakpoint, we need to set the queue
|
||||
front to the back. But what do we put in the back? What
|
||||
instruction comes after that one? Because of the branch delay
|
||||
slot, the next insn is always at the back + 4. */
|
||||
write_register (PCOQ_HEAD_REGNUM, read_register (PCOQ_TAIL_REGNUM));
|
||||
write_register (PCSQ_HEAD_REGNUM, read_register (PCSQ_TAIL_REGNUM));
|
||||
|
||||
write_register (PCOQ_TAIL_REGNUM, read_register (PCOQ_TAIL_REGNUM) + 4);
|
||||
/* We can leave the tail's space the same, since there's no jump. */
|
||||
}
|
||||
|
||||
void
|
||||
_initialize_hppa_tdep ()
|
||||
{
|
||||
|
@ -684,13 +684,19 @@ i386_extract_return_value (type, regbuf, valbuf)
|
||||
double d;
|
||||
/* 387 %st(0), gcc uses this */
|
||||
floatformat_to_double (&floatformat_i387_ext,
|
||||
®buf[REGISTER_BYTE(FPDATA_REGNUM)],
|
||||
#if defined(FPDATA_REGNUM)
|
||||
®buf[REGISTER_BYTE (FPDATA_REGNUM)],
|
||||
#else /* !FPDATA_REGNUM */
|
||||
®buf[REGISTER_BYTE (FP0_REGNUM)],
|
||||
#endif /* FPDATA_REGNUM */
|
||||
|
||||
&d);
|
||||
store_floating (valbuf, TYPE_LENGTH (type), d);
|
||||
}
|
||||
else
|
||||
#endif /* I386_AIX_TARGET || I386_GNULINUX_TARGET*/
|
||||
{
|
||||
#if defined(LOW_RETURN_REGNUM)
|
||||
int len = TYPE_LENGTH (type);
|
||||
int low_size = REGISTER_RAW_SIZE (LOW_RETURN_REGNUM);
|
||||
int high_size = REGISTER_RAW_SIZE (HIGH_RETURN_REGNUM);
|
||||
@ -708,6 +714,9 @@ i386_extract_return_value (type, regbuf, valbuf)
|
||||
}
|
||||
else
|
||||
error ("GDB bug: i386-tdep.c (i386_extract_return_value): Don't know how to find a return value %d bytes long", len);
|
||||
#else /* !LOW_RETURN_REGNUM */
|
||||
memcpy (valbuf, regbuf, TYPE_LENGTH (type));
|
||||
#endif /* LOW_RETURN_REGNUM */
|
||||
}
|
||||
}
|
||||
|
||||
@ -961,51 +970,6 @@ set_disassembly_flavor ()
|
||||
set_architecture_from_arch_mach (bfd_arch_i386, bfd_mach_i386_i386_intel_syntax);
|
||||
}
|
||||
|
||||
/* Print the register regnum, or all registers if regnum is -1 */
|
||||
|
||||
void
|
||||
i386_do_registers_info (regnum, fpregs)
|
||||
int regnum;
|
||||
int fpregs;
|
||||
{
|
||||
char raw_regs [REGISTER_BYTES];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_REGS; i++)
|
||||
read_relative_register_raw_bytes (i, raw_regs + REGISTER_BYTE (i));
|
||||
|
||||
if (regnum < FPSTART_REGNUM)
|
||||
i386_print_register (raw_regs, regnum, fpregs);
|
||||
else
|
||||
i387_print_register (raw_regs, regnum);
|
||||
}
|
||||
|
||||
static void
|
||||
i386_print_register (raw_regs, regnum, fpregs)
|
||||
char *raw_regs;
|
||||
int regnum;
|
||||
int fpregs;
|
||||
{
|
||||
int i;
|
||||
long val;
|
||||
char string[12];
|
||||
|
||||
for (i = 0; i < FPSTART_REGNUM; i++)
|
||||
{
|
||||
if ((regnum != -1) && (i != regnum))
|
||||
continue;
|
||||
|
||||
val = extract_signed_integer (raw_regs + REGISTER_BYTE (i), 4);
|
||||
|
||||
sprintf(string, "0x%x", val);
|
||||
printf_filtered ("%8.8s: %10.10s %11d\n", REGISTER_NAME(i), string, val);
|
||||
}
|
||||
|
||||
if ((regnum == -1) && fpregs)
|
||||
for (i = FPSTART_REGNUM; i < FPEND_REGNUM; i++)
|
||||
i387_print_register (raw_regs, i);
|
||||
}
|
||||
|
||||
void
|
||||
_initialize_i386_tdep ()
|
||||
{
|
||||
|
139
gdb/i387-tdep.c
139
gdb/i387-tdep.c
@ -149,145 +149,6 @@ print_387_status_word (status)
|
||||
puts_unfiltered ("\n");
|
||||
}
|
||||
|
||||
void
|
||||
i387_print_register (raw_regs, regnum)
|
||||
char *raw_regs;
|
||||
int regnum;
|
||||
{
|
||||
unsigned char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE];
|
||||
unsigned long val;
|
||||
int j, sign, special;
|
||||
unsigned swd, tags, expon, top, norm, ls, ms;
|
||||
char string[12];
|
||||
|
||||
#if (FPREG_RAW_SIZE != 10)
|
||||
#error "Bad FPREG_RAW_SIZE"
|
||||
#endif
|
||||
|
||||
printf_filtered ("%8.8s: ", REGISTER_NAME (regnum));
|
||||
if (regnum < FPDATA_REGNUM)
|
||||
{
|
||||
val = extract_unsigned_integer (raw_regs + REGISTER_BYTE (regnum), 4);
|
||||
if ( (regnum < FPSTART_REGNUM + 3) ||
|
||||
(regnum == FPSTART_REGNUM + 6) )
|
||||
/* Don't print the un-modifiable bytes. */
|
||||
sprintf(string, "0x%04x", val & 0xffff);
|
||||
else
|
||||
sprintf(string, "0x%08x", val);
|
||||
|
||||
printf_unfiltered ("%10.10s", string);
|
||||
|
||||
if (regnum == FPCONTROL_REGNUM)
|
||||
print_387_control_bits (val);
|
||||
else if (regnum == FPSTATUS_REGNUM)
|
||||
print_387_status_bits (val);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* An FPU stack register. */
|
||||
if ( REGISTER_RAW_SIZE (regnum) != FPREG_RAW_SIZE )
|
||||
error ("GDB bug: i387-tdep.c (i387_print_register): wrong size for FPU stack register");
|
||||
|
||||
/* Put the data in the buffer. No conversions are ever necessary. */
|
||||
memcpy (virtual_buffer, raw_regs + REGISTER_BYTE (regnum),
|
||||
FPREG_RAW_SIZE);
|
||||
|
||||
swd = extract_signed_integer (raw_regs + REGISTER_BYTE (FPSTATUS_REGNUM),
|
||||
4);
|
||||
top = (swd >> 11) & 7;
|
||||
tags = extract_signed_integer (raw_regs + REGISTER_BYTE (FPTAG_REGNUM),
|
||||
4);
|
||||
|
||||
puts_unfiltered ("0x");
|
||||
for (j = 0; j < FPREG_RAW_SIZE; j++)
|
||||
printf_unfiltered ("%02x",
|
||||
(unsigned char)raw_regs[REGISTER_BYTE (regnum)
|
||||
+ FPREG_RAW_SIZE - 1 - j]);
|
||||
|
||||
puts_unfiltered (" ");
|
||||
special = 0;
|
||||
switch ((tags >> (((regnum - FPDATA_REGNUM + top) & 7) * 2)) & 3)
|
||||
{
|
||||
case 0: puts_unfiltered ("Valid "); break;
|
||||
case 1: puts_unfiltered ("Zero "); break;
|
||||
case 2: puts_unfiltered ("Spec ");
|
||||
special = 1;
|
||||
break;
|
||||
case 3: puts_unfiltered ("Empty "); break;
|
||||
}
|
||||
|
||||
expon = extract_unsigned_integer (raw_regs + REGISTER_BYTE (regnum)
|
||||
+ FPREG_RAW_SIZE - 2, 2);
|
||||
sign = expon & 0x8000;
|
||||
expon &= 0x7fff;
|
||||
ms = extract_unsigned_integer (raw_regs + REGISTER_BYTE (regnum) + 4, 4);
|
||||
ls = extract_signed_integer (raw_regs + REGISTER_BYTE (regnum), 4);
|
||||
norm = ms & 0x80000000;
|
||||
|
||||
if ( expon == 0 )
|
||||
{
|
||||
if ( ms | ls )
|
||||
{
|
||||
/* Denormal or Pseudodenormal. */
|
||||
if ( norm )
|
||||
puts_unfiltered ("Pseudo ");
|
||||
else
|
||||
puts_unfiltered ("Denorm ");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Zero. */
|
||||
puts_unfiltered ("Zero ");
|
||||
}
|
||||
}
|
||||
else if ( expon == 0x7fff )
|
||||
{
|
||||
/* Infinity, NaN or unsupported. */
|
||||
if ( (ms == 0x80000000) &&
|
||||
(ls == 0) )
|
||||
{
|
||||
puts_unfiltered ("Infty ");
|
||||
}
|
||||
else if ( norm )
|
||||
{
|
||||
if ( ms & 0x40000000 )
|
||||
puts_unfiltered ("QNaN ");
|
||||
else
|
||||
puts_unfiltered ("SNaN ");
|
||||
}
|
||||
else
|
||||
{
|
||||
puts_unfiltered ("Unsupp ");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Normal or unsupported. */
|
||||
if ( norm )
|
||||
puts_unfiltered ("Normal ");
|
||||
else
|
||||
puts_unfiltered ("Unsupp ");
|
||||
}
|
||||
|
||||
val_print (REGISTER_VIRTUAL_TYPE (regnum), virtual_buffer, 0, 0,
|
||||
gdb_stdout, 0,
|
||||
1, 0, Val_pretty_default);
|
||||
}
|
||||
puts_filtered ("\n");
|
||||
}
|
||||
|
||||
void i387_float_info(void)
|
||||
{
|
||||
char raw_regs [REGISTER_BYTES];
|
||||
int i;
|
||||
|
||||
for (i = FPSTART_REGNUM; i <= FPEND_REGNUM; i++)
|
||||
read_relative_register_raw_bytes (i, raw_regs + REGISTER_BYTE (i));
|
||||
|
||||
for (i = FPSTART_REGNUM; i <= FPEND_REGNUM; i++)
|
||||
i387_print_register (raw_regs, i);
|
||||
}
|
||||
|
||||
#ifdef LD_I387
|
||||
int
|
||||
i387_extract_floating (PTR addr, int len, DOUBLEST *dretptr)
|
||||
|
@ -158,7 +158,7 @@ extern void generic_target_write_fp PARAMS ((CORE_ADDR));
|
||||
|
||||
extern void wait_for_inferior PARAMS ((void));
|
||||
|
||||
extern void fetch_inferior_event PARAMS ((void));
|
||||
extern void fetch_inferior_event PARAMS ((void *));
|
||||
|
||||
extern void init_wait_for_inferior PARAMS ((void));
|
||||
|
||||
|
@ -492,7 +492,7 @@ child_terminal_info (args, from_tty)
|
||||
printf_filtered ("Process group = %d\n", inferior_process_group);
|
||||
#endif
|
||||
|
||||
SERIAL_PRINT_TTY_STATE (stdin_serial, inferior_ttystate);
|
||||
SERIAL_PRINT_TTY_STATE (stdin_serial, inferior_ttystate, gdb_stdout);
|
||||
}
|
||||
|
||||
/* NEW_TTY_PREFORK is called before forking a new child process,
|
||||
|
155
gdb/infrun.c
155
gdb/infrun.c
@ -35,6 +35,8 @@
|
||||
#include "top.h"
|
||||
#include <signal.h>
|
||||
#include "event-loop.h"
|
||||
#include "event-top.h"
|
||||
#include "remote.h" /* For cleanup_sigint_signal_handler. */
|
||||
|
||||
/* Prototypes for local functions */
|
||||
|
||||
@ -268,6 +270,26 @@ static int use_thread_step_needed = USE_THREAD_STEP_NEEDED;
|
||||
#define INSTRUCTION_NULLIFIED 0
|
||||
#endif
|
||||
|
||||
/* We can't step off a permanent breakpoint in the ordinary way, because we
|
||||
can't remove it. Instead, we have to advance the PC to the next
|
||||
instruction. This macro should expand to a pointer to a function that
|
||||
does that, or zero if we have no such function. If we don't have a
|
||||
definition for it, we have to report an error. */
|
||||
#ifndef SKIP_PERMANENT_BREAKPOINT
|
||||
#define SKIP_PERMANENT_BREAKPOINT (default_skip_permanent_breakpoint)
|
||||
static void
|
||||
default_skip_permanent_breakpoint ()
|
||||
{
|
||||
error_begin ();
|
||||
fprintf_filtered (gdb_stderr, "\
|
||||
The program is stopped at a permanent breakpoint, but GDB does not know\n\
|
||||
how to step past a permanent breakpoint on this architecture. Try using\n\
|
||||
a command like `return' or `jump' to continue execution.\n");
|
||||
return_to_top_level (RETURN_ERROR);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Convert the #defines into values. This is temporary until wfi control
|
||||
flow is completely sorted out. */
|
||||
|
||||
@ -766,6 +788,8 @@ set_schedlock_func (char *args, int from_tty, struct cmd_list_element *c)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Resume the inferior, but allow a QUIT. This is useful if the user
|
||||
wants to interrupt some lengthy single-stepping operation
|
||||
(for child processes, the SIGINT goes to the inferior, and so
|
||||
@ -790,6 +814,13 @@ resume (int step, enum target_signal sig)
|
||||
step = 0;
|
||||
#endif
|
||||
|
||||
/* Normally, by the time we reach `resume', the breakpoints are either
|
||||
removed or inserted, as appropriate. The exception is if we're sitting
|
||||
at a permanent breakpoint; we need to step over it, but permanent
|
||||
breakpoints can't be removed. So we have to test for it here. */
|
||||
if (breakpoint_here_p (read_pc ()) == permanent_breakpoint_here)
|
||||
SKIP_PERMANENT_BREAKPOINT ();
|
||||
|
||||
if (SOFTWARE_SINGLE_STEP_P && step)
|
||||
{
|
||||
/* Do it the hard way, w/temp breakpoints */
|
||||
@ -1175,6 +1206,7 @@ void init_execution_control_state (struct execution_control_state * ecs);
|
||||
void handle_inferior_event (struct execution_control_state * ecs);
|
||||
|
||||
static void check_sigtramp2 (struct execution_control_state *ecs);
|
||||
static void step_into_function (struct execution_control_state *ecs);
|
||||
static void step_over_function (struct execution_control_state *ecs);
|
||||
static void stop_stepping (struct execution_control_state *ecs);
|
||||
static void prepare_to_wait (struct execution_control_state *ecs);
|
||||
@ -1250,7 +1282,8 @@ struct execution_control_state async_ecss;
|
||||
struct execution_control_state *async_ecs;
|
||||
|
||||
void
|
||||
fetch_inferior_event (void)
|
||||
fetch_inferior_event (client_data)
|
||||
gdb_client_data client_data;
|
||||
{
|
||||
static struct cleanup *old_cleanups;
|
||||
|
||||
@ -2761,66 +2794,15 @@ handle_inferior_event (struct execution_control_state *ecs)
|
||||
|
||||
tmp_sal = find_pc_line (ecs->stop_func_start, 0);
|
||||
if (tmp_sal.line != 0)
|
||||
goto step_into_function;
|
||||
{
|
||||
step_into_function (ecs);
|
||||
return;
|
||||
}
|
||||
}
|
||||
step_over_function (ecs);
|
||||
keep_going (ecs);
|
||||
return;
|
||||
|
||||
step_into_function:
|
||||
/* Subroutine call with source code we should not step over.
|
||||
Do step to the first line of code in it. */
|
||||
{
|
||||
struct symtab *s;
|
||||
|
||||
s = find_pc_symtab (stop_pc);
|
||||
if (s && s->language != language_asm)
|
||||
ecs->stop_func_start = SKIP_PROLOGUE (ecs->stop_func_start);
|
||||
}
|
||||
ecs->sal = find_pc_line (ecs->stop_func_start, 0);
|
||||
/* Use the step_resume_break to step until
|
||||
the end of the prologue, even if that involves jumps
|
||||
(as it seems to on the vax under 4.2). */
|
||||
/* If the prologue ends in the middle of a source line,
|
||||
continue to the end of that source line (if it is still
|
||||
within the function). Otherwise, just go to end of prologue. */
|
||||
#ifdef PROLOGUE_FIRSTLINE_OVERLAP
|
||||
/* no, don't either. It skips any code that's
|
||||
legitimately on the first line. */
|
||||
#else
|
||||
if (ecs->sal.end && ecs->sal.pc != ecs->stop_func_start && ecs->sal.end < ecs->stop_func_end)
|
||||
ecs->stop_func_start = ecs->sal.end;
|
||||
#endif
|
||||
|
||||
if (ecs->stop_func_start == stop_pc)
|
||||
{
|
||||
/* We are already there: stop now. */
|
||||
stop_step = 1;
|
||||
stop_stepping (ecs);
|
||||
return;
|
||||
}
|
||||
else
|
||||
/* Put the step-breakpoint there and go until there. */
|
||||
{
|
||||
struct symtab_and_line sr_sal;
|
||||
|
||||
INIT_SAL (&sr_sal); /* initialize to zeroes */
|
||||
sr_sal.pc = ecs->stop_func_start;
|
||||
sr_sal.section = find_pc_overlay (ecs->stop_func_start);
|
||||
/* Do not specify what the fp should be when we stop
|
||||
since on some machines the prologue
|
||||
is where the new fp value is established. */
|
||||
check_for_old_step_resume_breakpoint ();
|
||||
step_resume_breakpoint =
|
||||
set_momentary_breakpoint (sr_sal, NULL, bp_step_resume);
|
||||
if (breakpoints_inserted)
|
||||
insert_breakpoints ();
|
||||
|
||||
/* And make sure stepping stops right away then. */
|
||||
step_range_end = step_range_start;
|
||||
}
|
||||
keep_going (ecs);
|
||||
return;
|
||||
}
|
||||
|
||||
/* We've wandered out of the step range. */
|
||||
@ -2980,6 +2962,63 @@ check_sigtramp2 (struct execution_control_state *ecs)
|
||||
}
|
||||
}
|
||||
|
||||
/* Subroutine call with source code we should not step over. Do step
|
||||
to the first line of code in it. */
|
||||
|
||||
static void
|
||||
step_into_function (struct execution_control_state *ecs)
|
||||
{
|
||||
struct symtab *s;
|
||||
struct symtab_and_line sr_sal;
|
||||
|
||||
s = find_pc_symtab (stop_pc);
|
||||
if (s && s->language != language_asm)
|
||||
ecs->stop_func_start = SKIP_PROLOGUE (ecs->stop_func_start);
|
||||
|
||||
ecs->sal = find_pc_line (ecs->stop_func_start, 0);
|
||||
/* Use the step_resume_break to step until the end of the prologue,
|
||||
even if that involves jumps (as it seems to on the vax under
|
||||
4.2). */
|
||||
/* If the prologue ends in the middle of a source line, continue to
|
||||
the end of that source line (if it is still within the function).
|
||||
Otherwise, just go to end of prologue. */
|
||||
#ifdef PROLOGUE_FIRSTLINE_OVERLAP
|
||||
/* no, don't either. It skips any code that's legitimately on the
|
||||
first line. */
|
||||
#else
|
||||
if (ecs->sal.end
|
||||
&& ecs->sal.pc != ecs->stop_func_start
|
||||
&& ecs->sal.end < ecs->stop_func_end)
|
||||
ecs->stop_func_start = ecs->sal.end;
|
||||
#endif
|
||||
|
||||
if (ecs->stop_func_start == stop_pc)
|
||||
{
|
||||
/* We are already there: stop now. */
|
||||
stop_step = 1;
|
||||
stop_stepping (ecs);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Put the step-breakpoint there and go until there. */
|
||||
INIT_SAL (&sr_sal); /* initialize to zeroes */
|
||||
sr_sal.pc = ecs->stop_func_start;
|
||||
sr_sal.section = find_pc_overlay (ecs->stop_func_start);
|
||||
/* Do not specify what the fp should be when we stop since on
|
||||
some machines the prologue is where the new fp value is
|
||||
established. */
|
||||
check_for_old_step_resume_breakpoint ();
|
||||
step_resume_breakpoint =
|
||||
set_momentary_breakpoint (sr_sal, NULL, bp_step_resume);
|
||||
if (breakpoints_inserted)
|
||||
insert_breakpoints ();
|
||||
|
||||
/* And make sure stepping stops right away then. */
|
||||
step_range_end = step_range_start;
|
||||
}
|
||||
keep_going (ecs);
|
||||
}
|
||||
|
||||
/* We've just entered a callee, and we wish to resume until it returns
|
||||
to the caller. Setting a step_resume breakpoint on the return
|
||||
@ -3234,12 +3273,10 @@ stopped_for_internal_shlib_event (bpstat bs)
|
||||
static void
|
||||
complete_execution (void)
|
||||
{
|
||||
extern int cleanup_sigint_signal_handler (void);
|
||||
|
||||
target_executing = 0;
|
||||
if (sync_execution)
|
||||
{
|
||||
add_file_handler (input_fd, call_readline, 0);
|
||||
add_file_handler (input_fd, stdin_event_handler, 0);
|
||||
pop_prompt ();
|
||||
sync_execution = 0;
|
||||
cleanup_sigint_signal_handler ();
|
||||
|
@ -21,6 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "defs.h"
|
||||
#include "gdb_string.h"
|
||||
#include "kod.h"
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
@ -43,8 +44,8 @@ static void (*gdb_kod_query) (char *, char *, int *);
|
||||
displaying output (presumably to the user) and the other for
|
||||
querying the target. */
|
||||
char *
|
||||
cisco_kod_open (void (*display_func) (char *),
|
||||
void (*query_func) (char *, char *, int *))
|
||||
cisco_kod_open (kod_display_callback_ftype *display_func,
|
||||
kod_query_callback_ftype *query_func)
|
||||
{
|
||||
char buffer[PBUFSIZ];
|
||||
int bufsiz = PBUFSIZ;
|
||||
|
15
gdb/kod.c
15
gdb/kod.c
@ -25,6 +25,7 @@
|
||||
#include "gdbcmd.h"
|
||||
#include "target.h"
|
||||
#include "gdb_string.h"
|
||||
#include "kod.h"
|
||||
|
||||
/* Prototypes for exported functions. */
|
||||
void _initialize_kod (void);
|
||||
@ -61,7 +62,8 @@ static void gdb_kod_query (char *, char *, int *);
|
||||
gdb_kod_close - This is called when the KOD connection to the
|
||||
remote should be terminated. */
|
||||
|
||||
static char *(*gdb_kod_open) (void *, void *);
|
||||
static char *(*gdb_kod_open) (kod_display_callback_ftype *display,
|
||||
kod_query_callback_ftype *query);
|
||||
static void (*gdb_kod_request) (char *, int);
|
||||
static void (*gdb_kod_close) ();
|
||||
|
||||
@ -73,17 +75,6 @@ char *operating_system;
|
||||
switching OS's. */
|
||||
static char *old_operating_system;
|
||||
|
||||
/* Functions imported from the library for all supported OSes.
|
||||
FIXME: we really should do something better, such as dynamically
|
||||
loading the KOD modules. */
|
||||
extern char *ecos_kod_open (void *, void *);
|
||||
extern void ecos_kod_request (char *, int);
|
||||
extern void ecos_kod_close ();
|
||||
extern char *cisco_kod_open (void *, void *);
|
||||
extern void cisco_kod_request (char *, int);
|
||||
extern void cisco_kod_close ();
|
||||
|
||||
|
||||
/* Print a line of data generated by the module. */
|
||||
|
||||
static void
|
||||
|
61
gdb/kod.h
Normal file
61
gdb/kod.h
Normal file
@ -0,0 +1,61 @@
|
||||
/* Kernel Object Display facility for Cisco
|
||||
Copyright 1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef KOD_H
|
||||
#define KOD_H
|
||||
|
||||
typedef void kod_display_callback_ftype (char *);
|
||||
typedef void kod_query_callback_ftype (char *, char *, int *);
|
||||
|
||||
/* ???/???: Functions imported from the library for all supported
|
||||
OSes. FIXME: we really should do something better, such as
|
||||
dynamically loading the KOD modules. */
|
||||
|
||||
/* FIXME: cagney/1999-09-20: The kod-cisco.c et.al. kernel modules
|
||||
should register themselve with kod.c during the _initialization*()
|
||||
phase. With that implemented the extern declarations below would
|
||||
be replaced with the KOD register function that the various kernel
|
||||
modules should call. An example of this mechanism can be seen in
|
||||
gdbarch.c:register_gdbarch_init(). */
|
||||
|
||||
#if 0
|
||||
/* Don't have ecos code yet. */
|
||||
extern char *ecos_kod_open (kod_display_callback_ftype *display_func,
|
||||
kod_query_callback_ftype *query_func);
|
||||
extern void ecos_kod_request (char *, int);
|
||||
extern void ecos_kod_close (void);
|
||||
#endif
|
||||
|
||||
/* Initialize and return library name and version. The gdb side of
|
||||
KOD, kod.c, passes us two functions: one for displaying output
|
||||
(presumably to the user) and the other for querying the target. */
|
||||
|
||||
extern char *cisco_kod_open (kod_display_callback_ftype *display_func,
|
||||
kod_query_callback_ftype *query_func);
|
||||
|
||||
/* Print information about currently known kernel objects. We
|
||||
currently ignore the argument. There is only one mode of querying
|
||||
the Cisco kernel: we ask for a dump of everything, and it returns
|
||||
it. */
|
||||
|
||||
extern void cisco_kod_request (char *arg, int from_tty);
|
||||
|
||||
extern void cisco_kod_close (void);
|
||||
|
||||
#endif
|
@ -440,9 +440,9 @@ lookup_minimal_symbol_by_pc (pc)
|
||||
|
||||
#ifdef SOFUN_ADDRESS_MAYBE_MISSING
|
||||
CORE_ADDR
|
||||
find_stab_function_addr (namestring, pst, objfile)
|
||||
find_stab_function_addr (namestring, filename, objfile)
|
||||
char *namestring;
|
||||
struct partial_symtab *pst;
|
||||
char *filename;
|
||||
struct objfile *objfile;
|
||||
{
|
||||
struct minimal_symbol *msym;
|
||||
@ -457,7 +457,7 @@ find_stab_function_addr (namestring, pst, objfile)
|
||||
strncpy (p, namestring, n);
|
||||
p[n] = 0;
|
||||
|
||||
msym = lookup_minimal_symbol (p, pst->filename, objfile);
|
||||
msym = lookup_minimal_symbol (p, filename, objfile);
|
||||
if (msym == NULL)
|
||||
{
|
||||
/* Sun Fortran appends an underscore to the minimal symbol name,
|
||||
@ -465,8 +465,23 @@ find_stab_function_addr (namestring, pst, objfile)
|
||||
was not found. */
|
||||
p[n] = '_';
|
||||
p[n + 1] = 0;
|
||||
msym = lookup_minimal_symbol (p, pst->filename, objfile);
|
||||
msym = lookup_minimal_symbol (p, filename, objfile);
|
||||
}
|
||||
|
||||
if (msym == NULL && filename != NULL)
|
||||
{
|
||||
/* Try again without the filename. */
|
||||
p[n] = 0;
|
||||
msym = lookup_minimal_symbol (p, 0, objfile);
|
||||
}
|
||||
if (msym == NULL && filename != NULL)
|
||||
{
|
||||
/* And try again for Sun Fortran, but without the filename. */
|
||||
p[n] = '_';
|
||||
p[n + 1] = 0;
|
||||
msym = lookup_minimal_symbol (p, 0, objfile);
|
||||
}
|
||||
|
||||
return msym == NULL ? 0 : SYMBOL_VALUE_ADDRESS (msym);
|
||||
}
|
||||
#endif /* SOFUN_ADDRESS_MAYBE_MISSING */
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "gdbcore.h"
|
||||
#include "symfile.h"
|
||||
|
||||
extern void _initialize_mn10300_tdep (void);
|
||||
static CORE_ADDR mn10300_analyze_prologue PARAMS ((struct frame_info * fi,
|
||||
CORE_ADDR pc));
|
||||
|
||||
|
@ -960,13 +960,8 @@ find_pc_sect_section (pc, section)
|
||||
struct objfile *objfile;
|
||||
|
||||
ALL_OBJSECTIONS (objfile, s)
|
||||
#if defined(HPUXHPPA)
|
||||
if ((section == 0 || section == s->the_bfd_section) &&
|
||||
s->addr <= pc && pc <= s->endaddr)
|
||||
#else
|
||||
if ((section == 0 || section == s->the_bfd_section) &&
|
||||
s->addr <= pc && pc < s->endaddr)
|
||||
#endif
|
||||
return (s);
|
||||
|
||||
return (NULL);
|
||||
|
@ -530,40 +530,13 @@ pa64_solib_create_inferior_hook ()
|
||||
if (bfd_section_size (symfile_objfile->obfd, shlib_info) == 0)
|
||||
return;
|
||||
|
||||
/* Slam the pid of the process into __d_pid; failing is only a warning! */
|
||||
msymbol = lookup_minimal_symbol ("__d_pid", NULL, symfile_objfile);
|
||||
if (msymbol == NULL)
|
||||
{
|
||||
warning ("Unable to find __d_pid symbol in object file.");
|
||||
warning ("Suggest linking with /opt/langtools/lib/end.o.");
|
||||
warning ("GDB will be unable to track explicit library load/unload calls");
|
||||
goto keep_going;
|
||||
}
|
||||
|
||||
anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
|
||||
store_unsigned_integer (buf, 4, inferior_pid);
|
||||
status = target_write_memory (anaddr, buf, 4);
|
||||
if (status != 0)
|
||||
{
|
||||
warning ("Unable to write __d_pid");
|
||||
warning ("Suggest linking with /opt/langtools/lib/end.o.");
|
||||
warning ("GDB will be unable to track explicit library load/unload calls");
|
||||
goto keep_going;
|
||||
}
|
||||
|
||||
keep_going:
|
||||
|
||||
/* Read in the .dynamic section. */
|
||||
if (! read_dynamic_info (shlib_info, &dld_cache))
|
||||
error ("Unable to read the .dynamic section.");
|
||||
|
||||
/* Turn on the flags we care about. */
|
||||
dld_cache.dld_flags |= DT_HP_DEBUG_PRIVATE;
|
||||
/* ?!? Right now GDB is not recognizing hitting the callback breakpoint
|
||||
as a shared library event. Fix that and remove the #if0 code. */
|
||||
#if 0
|
||||
dld_cache.dld_flags |= DT_HP_DEBUG_CALLBACK;
|
||||
#endif
|
||||
status = target_write_memory (dld_cache.dld_flags_addr,
|
||||
(char *) &dld_cache.dld_flags,
|
||||
sizeof (dld_cache.dld_flags));
|
||||
@ -621,7 +594,17 @@ keep_going:
|
||||
sym_addr = load_addr + sym_addr + 4;
|
||||
|
||||
/* Create the shared library breakpoint. */
|
||||
create_solib_event_breakpoint (sym_addr);
|
||||
{
|
||||
struct breakpoint *b
|
||||
= create_solib_event_breakpoint (sym_addr);
|
||||
|
||||
/* The breakpoint is actually hard-coded into the dynamic linker,
|
||||
so we don't need to actually insert a breakpoint instruction
|
||||
there. In fact, the dynamic linker's code is immutable, even to
|
||||
ttrace, so we shouldn't even try to do that. For cases like
|
||||
this, we have "permanent" breakpoints. */
|
||||
make_breakpoint_permanent (b);
|
||||
}
|
||||
|
||||
/* We're done with the temporary bfd. */
|
||||
bfd_close (tmp_bfd);
|
||||
@ -856,9 +839,9 @@ pa64_sharedlibrary_info_command (ignore, from_tty)
|
||||
}
|
||||
|
||||
printf_unfiltered ("Shared Object Libraries\n");
|
||||
printf_unfiltered (" %-19s%-19s%-19s%-19s\n",
|
||||
" tstart", " tend",
|
||||
" dstart", " dend");
|
||||
printf_unfiltered (" %-19s%-19s%-19s%-19s\n",
|
||||
" text start", " text end",
|
||||
" data start", " data end");
|
||||
while (so_list)
|
||||
{
|
||||
unsigned int flags;
|
||||
@ -876,14 +859,14 @@ pa64_sharedlibrary_info_command (ignore, from_tty)
|
||||
local_hex_string_custom (so_list->pa64_solib_desc.text_base,
|
||||
"016l"));
|
||||
printf_unfiltered (" %-18s",
|
||||
local_hex_string_custom ((so_list->pa64_solib_desc.text_base,
|
||||
local_hex_string_custom ((so_list->pa64_solib_desc.text_base
|
||||
+ so_list->pa64_solib_desc.text_size),
|
||||
"016l"));
|
||||
printf_unfiltered (" %-18s",
|
||||
local_hex_string_custom (so_list->pa64_solib_desc.data_base,
|
||||
"016l"));
|
||||
printf_unfiltered (" %-18s\n",
|
||||
local_hex_string_custom ((so_list->pa64_solib_desc.data_base,
|
||||
local_hex_string_custom ((so_list->pa64_solib_desc.data_base
|
||||
+ so_list->pa64_solib_desc.data_size),
|
||||
"016l"));
|
||||
so_list = so_list->next;
|
||||
|
@ -577,9 +577,6 @@ switch (CUR_SYMBOL_TYPE)
|
||||
case 'f':
|
||||
CUR_SYMBOL_VALUE += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT);
|
||||
#ifdef DBXREAD_ONLY
|
||||
/* Keep track of the start of the last function so we
|
||||
can handle end of function symbols. */
|
||||
last_function_start = CUR_SYMBOL_VALUE;
|
||||
/* Kludges for ELF/STABS with Sun ACC */
|
||||
last_function_name = namestring;
|
||||
#ifdef SOFUN_ADDRESS_MAYBE_MISSING
|
||||
@ -588,12 +585,16 @@ switch (CUR_SYMBOL_TYPE)
|
||||
if (pst && textlow_not_set)
|
||||
{
|
||||
pst->textlow =
|
||||
find_stab_function_addr (namestring, pst, objfile);
|
||||
find_stab_function_addr (namestring, pst->filename, objfile);
|
||||
textlow_not_set = 0;
|
||||
}
|
||||
#endif
|
||||
/* End kludge. */
|
||||
|
||||
/* Keep track of the start of the last function so we
|
||||
can handle end of function symbols. */
|
||||
last_function_start = CUR_SYMBOL_VALUE;
|
||||
|
||||
/* In reordered executables this function may lie outside
|
||||
the bounds created by N_SO symbols. If that's the case
|
||||
use the address of this function as the low bound for
|
||||
@ -620,22 +621,27 @@ switch (CUR_SYMBOL_TYPE)
|
||||
case 'F':
|
||||
CUR_SYMBOL_VALUE += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT);
|
||||
#ifdef DBXREAD_ONLY
|
||||
/* Keep track of the start of the last function so we
|
||||
can handle end of function symbols. */
|
||||
last_function_start = CUR_SYMBOL_VALUE;
|
||||
/* Kludges for ELF/STABS with Sun ACC */
|
||||
last_function_name = namestring;
|
||||
#ifdef SOFUN_ADDRESS_MAYBE_MISSING
|
||||
/* Do not fix textlow==0 for .o or NLM files, as 0 is a legit
|
||||
value for the bottom of the text seg in those cases. */
|
||||
if (CUR_SYMBOL_VALUE == ANOFFSET (objfile->section_offsets,
|
||||
SECT_OFF_TEXT))
|
||||
CUR_SYMBOL_VALUE =
|
||||
find_stab_function_addr (namestring, pst->filename, objfile);
|
||||
if (pst && textlow_not_set)
|
||||
{
|
||||
pst->textlow =
|
||||
find_stab_function_addr (namestring, pst, objfile);
|
||||
pst->textlow = CUR_SYMBOL_VALUE;
|
||||
textlow_not_set = 0;
|
||||
}
|
||||
#endif
|
||||
/* End kludge. */
|
||||
|
||||
/* Keep track of the start of the last function so we
|
||||
can handle end of function symbols. */
|
||||
last_function_start = CUR_SYMBOL_VALUE;
|
||||
|
||||
/* In reordered executables this function may lie outside
|
||||
the bounds created by N_SO symbols. If that's the case
|
||||
use the address of this function as the low bound for
|
||||
|
@ -360,14 +360,14 @@ es1800_open (name, from_tty)
|
||||
|
||||
es1800_saved_ttystate = SERIAL_GET_TTY_STATE (es1800_desc);
|
||||
|
||||
if ((fcflag = fcntl (es1800_desc->fd, F_GETFL, 0)) == -1)
|
||||
if ((fcflag = fcntl (DEPRECATED_SERIAL_FD (es1800_desc), F_GETFL, 0)) == -1)
|
||||
{
|
||||
perror_with_name ("fcntl serial");
|
||||
}
|
||||
es1800_fc_save = fcflag;
|
||||
|
||||
fcflag = (fcflag & (FREAD | FWRITE)); /* mask out any funny stuff */
|
||||
if (fcntl (es1800_desc->fd, F_SETFL, fcflag) == -1)
|
||||
if (fcntl (DEPRECATED_SERIAL_FD (es1800_desc), F_SETFL, fcflag) == -1)
|
||||
{
|
||||
perror_with_name ("fcntl serial");
|
||||
}
|
||||
@ -470,7 +470,7 @@ es1800_close (quitting)
|
||||
printf ("\nClosing connection to emulator...\n");
|
||||
if (SERIAL_SET_TTY_STATE (es1800_desc, es1800_saved_ttystate) < 0)
|
||||
print_sys_errmsg ("warning: unable to restore tty state", errno);
|
||||
fcntl (es1800_desc->fd, F_SETFL, es1800_fc_save);
|
||||
fcntl (DEPRECATED_SERIAL_FD (es1800_desc), F_SETFL, es1800_fc_save);
|
||||
SERIAL_CLOSE (es1800_desc);
|
||||
es1800_desc = NULL;
|
||||
}
|
||||
@ -1876,7 +1876,7 @@ es1800_transparent (args, from_tty)
|
||||
perror_with_name ("ioctl console");
|
||||
}
|
||||
|
||||
if ((fcflag = fcntl (es1800_desc->fd, F_GETFL, 0)) == -1)
|
||||
if ((fcflag = fcntl (DEPRECATED_SERIAL_FD (es1800_desc), F_GETFL, 0)) == -1)
|
||||
{
|
||||
perror_with_name ("fcntl serial");
|
||||
}
|
||||
@ -1884,7 +1884,7 @@ es1800_transparent (args, from_tty)
|
||||
es1800_fc_save = fcflag;
|
||||
fcflag = fcflag | FNDELAY;
|
||||
|
||||
if (fcntl (es1800_desc->fd, F_SETFL, fcflag) == -1)
|
||||
if (fcntl (DEPRECATED_SERIAL_FD (es1800_desc), F_SETFL, fcflag) == -1)
|
||||
{
|
||||
perror_with_name ("fcntl serial");
|
||||
}
|
||||
@ -1920,7 +1920,7 @@ es1800_transparent (args, from_tty)
|
||||
perror_with_name ("FEL! read:");
|
||||
}
|
||||
|
||||
cc = read (es1800_desc->fd, inputbuf, inputcnt);
|
||||
cc = read (DEPRECATED_SERIAL_FD (es1800_desc), inputbuf, inputcnt);
|
||||
if (cc != -1)
|
||||
{
|
||||
for (i = 0; i < cc;)
|
||||
@ -1959,7 +1959,7 @@ es1800_transparent (args, from_tty)
|
||||
|
||||
close (console);
|
||||
|
||||
if (fcntl (es1800_desc->fd, F_SETFL, es1800_fc_save) == -1)
|
||||
if (fcntl (DEPRECATED_SERIAL_FD (es1800_desc), F_SETFL, es1800_fc_save) == -1)
|
||||
{
|
||||
perror_with_name ("FEL! fcntl");
|
||||
}
|
||||
|
@ -1074,7 +1074,7 @@ connect_command (args, fromtty)
|
||||
do
|
||||
{
|
||||
FD_SET (0, &readfds);
|
||||
FD_SET (monitor_desc, &readfds);
|
||||
FD_SET (DEPRECATED_SERIAL_FD (monitor_desc), &readfds);
|
||||
numfds = select (sizeof (readfds) * 8, &readfds, 0, 0, 0);
|
||||
}
|
||||
while (numfds == 0);
|
||||
@ -1109,7 +1109,7 @@ connect_command (args, fromtty)
|
||||
}
|
||||
}
|
||||
|
||||
if (FD_ISSET (monitor_desc, &readfds))
|
||||
if (FD_ISSET (DEPRECATED_SERIAL_FD (monitor_desc), &readfds))
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
|
@ -729,7 +729,7 @@ connect_command (args, fromtty)
|
||||
do
|
||||
{
|
||||
FD_SET (0, &readfds);
|
||||
FD_SET (st2000_desc, &readfds);
|
||||
FD_SET (DEPRECATED_SERIAL_FD (st2000_desc), &readfds);
|
||||
numfds = select (sizeof (readfds) * 8, &readfds, 0, 0, 0);
|
||||
}
|
||||
while (numfds == 0);
|
||||
@ -764,7 +764,7 @@ connect_command (args, fromtty)
|
||||
}
|
||||
}
|
||||
|
||||
if (FD_ISSET (st2000_desc, &readfds))
|
||||
if (FD_ISSET (DEPRECATED_SERIAL_FD (st2000_desc), &readfds))
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
|
138
gdb/remote.c
138
gdb/remote.c
@ -36,6 +36,7 @@
|
||||
#include "objfiles.h"
|
||||
#include "gdb-stabs.h"
|
||||
#include "gdbthread.h"
|
||||
#include "remote.h"
|
||||
|
||||
#include "dcache.h"
|
||||
|
||||
@ -46,6 +47,7 @@
|
||||
#endif
|
||||
|
||||
#include "event-loop.h"
|
||||
#include "event-top.h"
|
||||
|
||||
#include <signal.h>
|
||||
#include "serial.h"
|
||||
@ -186,14 +188,8 @@ static void record_currthread PARAMS ((int currthread));
|
||||
|
||||
extern int fromhex PARAMS ((int a));
|
||||
|
||||
extern void getpkt PARAMS ((char *buf, int forever));
|
||||
|
||||
extern int putpkt PARAMS ((char *buf));
|
||||
|
||||
static int putpkt_binary PARAMS ((char *buf, int cnt));
|
||||
|
||||
void remote_console_output PARAMS ((char *));
|
||||
|
||||
static void check_binary_download PARAMS ((CORE_ADDR addr));
|
||||
|
||||
struct packet_config;
|
||||
@ -1840,8 +1836,10 @@ serial device is attached to the remote system (e.g. /dev/ttya).");
|
||||
event loop. Set things up so that when there is an event on the
|
||||
file descriptor, the event loop will call fetch_inferior_event,
|
||||
which will do the proper analysis to determine what happened. */
|
||||
if (async_p)
|
||||
add_file_handler (remote_desc->fd, fetch_inferior_event, 0);
|
||||
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 */
|
||||
|
||||
@ -1858,7 +1856,7 @@ serial device is attached to the remote system (e.g. /dev/ttya).");
|
||||
/* If running asynchronously, set things up for telling the target
|
||||
to use the extended protocol. This will happen only after the
|
||||
target has been connected to, in fetch_inferior_event. */
|
||||
if (extended_p && async_p)
|
||||
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
|
||||
@ -1877,13 +1875,13 @@ serial device is attached to the remote system (e.g. /dev/ttya).");
|
||||
RETURN_MASK_ALL))
|
||||
{
|
||||
/* Unregister the file descriptor from the event loop. */
|
||||
if (async_p)
|
||||
delete_file_handler (remote_desc->fd);
|
||||
if (SERIAL_IS_ASYNC_P (remote_desc))
|
||||
SERIAL_ASYNC (remote_desc, NULL, 0);
|
||||
pop_target ();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!async_p)
|
||||
if (!SERIAL_IS_ASYNC_P (remote_desc))
|
||||
{
|
||||
if (extended_p)
|
||||
{
|
||||
@ -1948,8 +1946,8 @@ remote_async_detach (args, from_tty)
|
||||
remote_send (buf);
|
||||
|
||||
/* Unregister the file descriptor from the event loop. */
|
||||
if (async_p)
|
||||
delete_file_handler (remote_desc->fd);
|
||||
if (SERIAL_IS_ASYNC_P (remote_desc))
|
||||
SERIAL_ASYNC (remote_desc, NULL, 0);
|
||||
|
||||
pop_target ();
|
||||
if (from_tty)
|
||||
@ -2053,7 +2051,7 @@ remote_async_resume (pid, step, siggnal)
|
||||
command, because it is also called by handle_inferior_event. So
|
||||
we make sure that we don't do the initialization for sync
|
||||
execution more than once. */
|
||||
if (async_p && !target_executing)
|
||||
if (SERIAL_IS_ASYNC_P (remote_desc) && !target_executing)
|
||||
{
|
||||
target_executing = 1;
|
||||
|
||||
@ -2145,9 +2143,9 @@ cleanup_sigint_signal_handler ()
|
||||
{
|
||||
signal (SIGINT, handle_sigint);
|
||||
if (sigint_remote_twice_token)
|
||||
delete_async_signal_handler ((async_signal_handler **) & sigint_remote_twice_token);
|
||||
delete_async_signal_handler ((struct async_signal_handler **) & sigint_remote_twice_token);
|
||||
if (sigint_remote_token)
|
||||
delete_async_signal_handler ((async_signal_handler **) & sigint_remote_token);
|
||||
delete_async_signal_handler ((struct async_signal_handler **) & sigint_remote_token);
|
||||
}
|
||||
|
||||
/* Send ^C to target to halt it. Target will respond, and send us a
|
||||
@ -2473,10 +2471,10 @@ remote_async_wait (pid, status)
|
||||
{
|
||||
unsigned char *p;
|
||||
|
||||
if (!async_p)
|
||||
if (!SERIAL_IS_ASYNC_P (remote_desc))
|
||||
ofunc = signal (SIGINT, remote_interrupt);
|
||||
getpkt ((char *) buf, 1);
|
||||
if (!async_p)
|
||||
if (!SERIAL_IS_ASYNC_P (remote_desc))
|
||||
signal (SIGINT, ofunc);
|
||||
|
||||
/* This is a hook for when we need to do something (perhaps the
|
||||
@ -3519,33 +3517,6 @@ putpkt_binary (buf, cnt)
|
||||
|
||||
static int remote_cisco_mode;
|
||||
|
||||
static void
|
||||
remote_cisco_expand (src, dest)
|
||||
char *src;
|
||||
char *dest;
|
||||
{
|
||||
int i;
|
||||
int repeat;
|
||||
|
||||
do
|
||||
{
|
||||
if (*src == '*')
|
||||
{
|
||||
repeat = (fromhex (src[1]) << 4) + fromhex (src[2]);
|
||||
for (i = 0; i < repeat; i++)
|
||||
{
|
||||
*dest++ = *(src - 1);
|
||||
}
|
||||
src += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
*dest++ = *src;
|
||||
}
|
||||
}
|
||||
while (*src++);
|
||||
}
|
||||
|
||||
/* Come here after finding the start of the frame. Collect the rest
|
||||
into BUF, verifying the checksum, length, and handling run-length
|
||||
compression. Returns 0 on any error, 1 on success. */
|
||||
@ -3586,16 +3557,7 @@ read_frame (buf)
|
||||
pktcsum |= fromhex (readchar (remote_timeout));
|
||||
|
||||
if (csum == pktcsum)
|
||||
{
|
||||
if (remote_cisco_mode) /* variant run-length-encoding */
|
||||
{
|
||||
char *tmp_buf = alloca (PBUFSIZ);
|
||||
|
||||
remote_cisco_expand (buf, tmp_buf);
|
||||
strcpy (buf, tmp_buf);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
|
||||
if (remote_debug)
|
||||
{
|
||||
@ -3608,27 +3570,43 @@ read_frame (buf)
|
||||
return 0;
|
||||
}
|
||||
case '*': /* Run length encoding */
|
||||
if (remote_cisco_mode == 0) /* variant run-length-encoding */
|
||||
{
|
||||
csum += c;
|
||||
c = readchar (remote_timeout);
|
||||
csum += c;
|
||||
c = c - ' ' + 3; /* Compute repeat count */
|
||||
{
|
||||
int repeat;
|
||||
csum += c;
|
||||
|
||||
if (c > 0 && c < 255 && bp + c - 1 < buf + PBUFSIZ - 1)
|
||||
{
|
||||
memset (bp, *(bp - 1), c);
|
||||
bp += c;
|
||||
continue;
|
||||
}
|
||||
if (remote_cisco_mode == 0)
|
||||
{
|
||||
c = readchar (remote_timeout);
|
||||
csum += c;
|
||||
repeat = c - ' ' + 3; /* Compute repeat count */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Cisco's run-length encoding variant uses two
|
||||
hex chars to represent the repeat count. */
|
||||
|
||||
*bp = '\0';
|
||||
printf_filtered ("Repeat count %d too large for buffer: ", c);
|
||||
puts_filtered (buf);
|
||||
puts_filtered ("\n");
|
||||
return 0;
|
||||
}
|
||||
/* else fall thru to treat like default */
|
||||
c = readchar (remote_timeout);
|
||||
csum += c;
|
||||
repeat = fromhex (c) << 4;
|
||||
c = readchar (remote_timeout);
|
||||
csum += c;
|
||||
repeat += fromhex (c);
|
||||
}
|
||||
|
||||
if (repeat > 0 && repeat <= 255
|
||||
&& bp + repeat - 1 < buf + PBUFSIZ - 1)
|
||||
{
|
||||
memset (bp, *(bp - 1), repeat);
|
||||
bp += c;
|
||||
continue;
|
||||
}
|
||||
|
||||
*bp = '\0';
|
||||
printf_filtered ("Repeat count %d too large for buffer: ", repeat);
|
||||
puts_filtered (buf);
|
||||
puts_filtered ("\n");
|
||||
return 0;
|
||||
}
|
||||
default:
|
||||
if (bp < buf + PBUFSIZ - 1)
|
||||
{
|
||||
@ -3755,8 +3733,8 @@ static void
|
||||
remote_async_kill ()
|
||||
{
|
||||
/* Unregister the file descriptor from the event loop. */
|
||||
if (async_p)
|
||||
delete_file_handler (remote_desc->fd);
|
||||
if (SERIAL_IS_ASYNC_P (remote_desc))
|
||||
SERIAL_ASYNC (remote_desc, NULL, 0);
|
||||
|
||||
/* For some mysterious reason, wait_for_inferior calls kill instead of
|
||||
mourn after it gets TARGET_WAITKIND_SIGNALLED. Work around it. */
|
||||
@ -3854,8 +3832,8 @@ extended_remote_async_create_inferior (exec_file, args, env)
|
||||
|
||||
/* If running asynchronously, register the target file descriptor
|
||||
with the event loop. */
|
||||
if (async_p)
|
||||
add_file_handler (remote_desc->fd, fetch_inferior_event, 0);
|
||||
if (async_p && SERIAL_CAN_ASYNC_P (remote_desc))
|
||||
SERIAL_ASYNC (remote_desc, inferior_event_handler, 0);
|
||||
|
||||
/* Now restart the remote server. */
|
||||
extended_remote_restart ();
|
||||
@ -4939,7 +4917,7 @@ minitelnet ()
|
||||
|
||||
FD_ZERO (&input);
|
||||
FD_SET (fileno (stdin), &input);
|
||||
FD_SET (remote_desc->fd, &input);
|
||||
FD_SET (DEPRECATED_SERIAL_FD (remote_desc), &input);
|
||||
|
||||
status = select (tablesize, &input, 0, 0, 0);
|
||||
if ((status == -1) && (errno != EINTR))
|
||||
|
60
gdb/remote.h
Normal file
60
gdb/remote.h
Normal file
@ -0,0 +1,60 @@
|
||||
/* Remote target communications for serial-line targets in custom GDB protocol
|
||||
Copyright 1999, Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef REMOTE_H
|
||||
#define REMOTE_H
|
||||
|
||||
/* FIXME?: move this interface down to tgt vector) */
|
||||
|
||||
/* Read a packet from the remote machine, with error checking, and
|
||||
store it in BUF. BUF is expected to be of size PBUFSIZ. If
|
||||
FOREVER, wait forever rather than timing out; this is used while
|
||||
the target is executing user code. */
|
||||
|
||||
extern void getpkt (char *buf, int forever);
|
||||
|
||||
/* Send a packet to the remote machine, with error checking. The data
|
||||
of the packet is in BUF. The string in BUF can be at most PBUFSIZ
|
||||
- 5 to account for the $, # and checksum, and for a possible /0 if
|
||||
we are debugging (remote_debug) and want to print the sent packet
|
||||
as a string */
|
||||
|
||||
extern int putpkt (char *buf);
|
||||
|
||||
/* Send HEX encoded string to the target console. (gdb_stdtarg) */
|
||||
|
||||
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
|
||||
implemented. */
|
||||
|
||||
extern void remote_cisco_objfile_relocate (bfd_signed_vma text_off,
|
||||
bfd_signed_vma data_off,
|
||||
bfd_signed_vma bss_off);
|
||||
|
||||
#endif
|
@ -420,9 +420,9 @@ e7000pc_noflush_set_tty_state (scb, new_ttystate, old_ttystate)
|
||||
}
|
||||
|
||||
static void
|
||||
e7000pc_print_tty_state (scb, ttystate)
|
||||
serial_t scb;
|
||||
serial_ttystate ttystate;
|
||||
e7000pc_print_tty_state (serial_t scb,
|
||||
serial_ttystate ttystate,
|
||||
struct gdb_file *stream)
|
||||
{
|
||||
/* Nothing to print. */
|
||||
return;
|
||||
|
@ -696,9 +696,9 @@ dos_flush_input (scb)
|
||||
}
|
||||
|
||||
static void
|
||||
dos_print_tty_state (scb, ttystate)
|
||||
serial_t scb;
|
||||
serial_ttystate ttystate;
|
||||
dos_print_tty_state (serial_t scb,
|
||||
serial_ttystate ttystate,
|
||||
struct gdb_file *stream)
|
||||
{
|
||||
/* Nothing to print */
|
||||
return;
|
||||
|
@ -232,9 +232,9 @@ mac_noflush_set_tty_state (scb, new_ttystate, old_ttystate)
|
||||
}
|
||||
|
||||
static void
|
||||
mac_print_tty_state (scb, ttystate)
|
||||
serial_t scb;
|
||||
serial_ttystate ttystate;
|
||||
mac_print_tty_state (serial_t scb,
|
||||
serial_ttystate ttystate,
|
||||
struct gdb_file *stream)
|
||||
{
|
||||
/* Nothing to print. */
|
||||
return;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* Remote serial interface for Macraigor Systems implementation of
|
||||
On-Chip Debugging using serial target box or serial wiggler
|
||||
|
||||
Copyright 1994, 1997 Free Software Foundation, Inc.
|
||||
Copyright 1994, 1997, 1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
@ -27,15 +27,6 @@
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
static int ser_ocd_open PARAMS ((serial_t scb, const char *name));
|
||||
static void ser_ocd_raw PARAMS ((serial_t scb));
|
||||
static int ser_ocd_readchar PARAMS ((serial_t scb, int timeout));
|
||||
static int ser_ocd_setbaudrate PARAMS ((serial_t scb, int rate));
|
||||
static int ser_ocd_write PARAMS ((serial_t scb, const char *str, int len));
|
||||
static void ser_ocd_close PARAMS ((serial_t scb));
|
||||
static serial_ttystate ser_ocd_get_tty_state PARAMS ((serial_t scb));
|
||||
static int ser_ocd_set_tty_state PARAMS ((serial_t scb, serial_ttystate state));
|
||||
|
||||
#ifdef _WIN32
|
||||
/* On Windows, this function pointer is initialized to a function in
|
||||
the wiggler DLL. */
|
||||
@ -84,11 +75,6 @@ ocd_raw (scb)
|
||||
/* Always in raw mode */
|
||||
}
|
||||
|
||||
static void
|
||||
ocd_readremote ()
|
||||
{
|
||||
}
|
||||
|
||||
/* We need a buffer to store responses from the Wigglers.dll */
|
||||
#define WIGGLER_BUFF_SIZE 512
|
||||
unsigned char from_wiggler_buffer[WIGGLER_BUFF_SIZE];
|
||||
@ -144,9 +130,9 @@ ocd_noflush_set_tty_state (scb, new_ttystate, old_ttystate)
|
||||
}
|
||||
|
||||
static void
|
||||
ocd_print_tty_state (scb, ttystate)
|
||||
serial_t scb;
|
||||
serial_ttystate ttystate;
|
||||
ocd_print_tty_state (serial_t scb,
|
||||
serial_ttystate ttystate,
|
||||
struct gdb_file *stream)
|
||||
{
|
||||
/* Nothing to print. */
|
||||
return;
|
||||
@ -166,8 +152,6 @@ ocd_write (scb, str, len)
|
||||
const char *str;
|
||||
int len;
|
||||
{
|
||||
char c;
|
||||
|
||||
#ifdef _WIN32
|
||||
/* send packet to Wigglers.dll and store response so we can give it to
|
||||
remote-wiggler.c when get_packet is run */
|
||||
|
297
gdb/ser-pipe.c
297
gdb/ser-pipe.c
@ -22,6 +22,8 @@
|
||||
|
||||
#include "defs.h"
|
||||
#include "serial.h"
|
||||
#include "ser-unix.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_SYS_WAIT_H
|
||||
#include <sys/wait.h>
|
||||
@ -31,31 +33,11 @@
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "signals.h"
|
||||
#include "gdb_string.h"
|
||||
|
||||
extern int (*ui_loop_hook) PARAMS ((int));
|
||||
|
||||
static int pipe_open PARAMS ((serial_t scb, const char *name));
|
||||
static void pipe_raw PARAMS ((serial_t scb));
|
||||
static int wait_for PARAMS ((serial_t scb, int timeout));
|
||||
static int pipe_readchar PARAMS ((serial_t scb, int timeout));
|
||||
static int pipe_setbaudrate PARAMS ((serial_t scb, int rate));
|
||||
static int pipe_setstopbits PARAMS ((serial_t scb, int num));
|
||||
static int pipe_write PARAMS ((serial_t scb, const char *str, int len));
|
||||
/* FIXME: static void pipe_restore PARAMS ((serial_t scb)); */
|
||||
static void pipe_close PARAMS ((serial_t scb));
|
||||
static serial_ttystate pipe_get_tty_state PARAMS ((serial_t scb));
|
||||
static int pipe_set_tty_state PARAMS ((serial_t scb, serial_ttystate state));
|
||||
static int pipe_return_0 PARAMS ((serial_t));
|
||||
static int pipe_noflush_set_tty_state PARAMS ((serial_t, serial_ttystate,
|
||||
serial_ttystate));
|
||||
static void pipe_print_tty_state PARAMS ((serial_t, serial_ttystate));
|
||||
|
||||
extern void _initialize_ser_pipe PARAMS ((void));
|
||||
|
||||
#undef XMALLOC
|
||||
#define XMALLOC(T) ((T*) xmalloc (sizeof (T)))
|
||||
static int pipe_open (serial_t scb, const char *name);
|
||||
static void pipe_close (serial_t scb);
|
||||
|
||||
extern void _initialize_ser_pipe (void);
|
||||
|
||||
struct pipe_state
|
||||
{
|
||||
@ -65,9 +47,7 @@ struct pipe_state
|
||||
/* Open up a raw pipe */
|
||||
|
||||
static int
|
||||
pipe_open (scb, name)
|
||||
serial_t scb;
|
||||
const char *name;
|
||||
pipe_open (serial_t scb, const char *name)
|
||||
{
|
||||
#if !defined(O_NONBLOCK) || !defined(F_GETFL) || !defined(F_SETFL) || !HAVE_SOCKETPAIR
|
||||
return -1;
|
||||
@ -114,7 +94,7 @@ pipe_open (scb, name)
|
||||
for (old = pidlist; old; old = old->next)
|
||||
close (fileno (old->fp)); /* don't allow a flush */
|
||||
#endif
|
||||
execl ("/bin/sh", "sh", "-c", name + 1, NULL);
|
||||
execl ("/bin/sh", "sh", "-c", name, NULL);
|
||||
_exit (127);
|
||||
}
|
||||
|
||||
@ -143,224 +123,8 @@ pipe_open (scb, name)
|
||||
#endif
|
||||
}
|
||||
|
||||
static serial_ttystate
|
||||
pipe_get_tty_state (scb)
|
||||
serial_t scb;
|
||||
{
|
||||
/* return garbage */
|
||||
return xmalloc (sizeof (int));
|
||||
}
|
||||
|
||||
static int
|
||||
pipe_set_tty_state (scb, ttystate)
|
||||
serial_t scb;
|
||||
serial_ttystate ttystate;
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pipe_return_0 (scb)
|
||||
serial_t scb;
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
pipe_raw (scb)
|
||||
serial_t scb;
|
||||
{
|
||||
return; /* Always in raw mode */
|
||||
}
|
||||
|
||||
/* Wait for input on scb, with timeout seconds. Returns 0 on success,
|
||||
otherwise SERIAL_TIMEOUT or SERIAL_ERROR.
|
||||
|
||||
For termio{s}, we actually just setup VTIME if necessary, and let the
|
||||
timeout occur in the read() in pipe_read().
|
||||
*/
|
||||
|
||||
static int
|
||||
wait_for (scb, timeout)
|
||||
serial_t scb;
|
||||
int timeout;
|
||||
{
|
||||
int numfds;
|
||||
struct timeval tv;
|
||||
fd_set readfds, exceptfds;
|
||||
|
||||
FD_ZERO (&readfds);
|
||||
FD_ZERO (&exceptfds);
|
||||
|
||||
tv.tv_sec = timeout;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
FD_SET (scb->fd, &readfds);
|
||||
FD_SET (scb->fd, &exceptfds);
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (timeout >= 0)
|
||||
numfds = select (scb->fd + 1, &readfds, 0, &exceptfds, &tv);
|
||||
else
|
||||
numfds = select (scb->fd + 1, &readfds, 0, &exceptfds, 0);
|
||||
|
||||
if (numfds <= 0)
|
||||
{
|
||||
if (numfds == 0)
|
||||
return SERIAL_TIMEOUT;
|
||||
else if (errno == EINTR)
|
||||
continue;
|
||||
else
|
||||
return SERIAL_ERROR; /* Got an error from select or poll */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read a character with user-specified timeout. TIMEOUT is number of seconds
|
||||
to wait, or -1 to wait forever. Use timeout of 0 to effect a poll. Returns
|
||||
char if successful. Returns -2 if timeout expired, EOF if line dropped
|
||||
dead, or -3 for any other error (see errno in that case). */
|
||||
|
||||
static int
|
||||
pipe_readchar (scb, timeout)
|
||||
serial_t scb;
|
||||
int timeout;
|
||||
{
|
||||
int status;
|
||||
int delta;
|
||||
|
||||
if (scb->bufcnt-- > 0)
|
||||
return *scb->bufp++;
|
||||
|
||||
/* We have to be able to keep the GUI alive here, so we break the original
|
||||
timeout into steps of 1 second, running the "keep the GUI alive" hook
|
||||
each time through the loop.
|
||||
|
||||
Also, timeout = 0 means to poll, so we just set the delta to 0, so we
|
||||
will only go through the loop once. */
|
||||
|
||||
delta = (timeout == 0 ? 0 : 1);
|
||||
while (1)
|
||||
{
|
||||
|
||||
/* N.B. The UI may destroy our world (for instance by calling
|
||||
remote_stop,) in which case we want to get out of here as
|
||||
quickly as possible. It is not safe to touch scb, since
|
||||
someone else might have freed it. The ui_loop_hook signals that
|
||||
we should exit by returning 1. */
|
||||
|
||||
if (ui_loop_hook)
|
||||
{
|
||||
if (ui_loop_hook (0))
|
||||
return SERIAL_TIMEOUT;
|
||||
}
|
||||
|
||||
status = wait_for (scb, delta);
|
||||
timeout -= delta;
|
||||
|
||||
/* If we got a character or an error back from wait_for, then we can
|
||||
break from the loop before the timeout is completed. */
|
||||
|
||||
if (status != SERIAL_TIMEOUT)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
/* If we have exhausted the original timeout, then generate
|
||||
a SERIAL_TIMEOUT, and pass it out of the loop. */
|
||||
|
||||
else if (timeout == 0)
|
||||
{
|
||||
status = SERIAL_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
while (1)
|
||||
{
|
||||
scb->bufcnt = read (scb->fd, scb->buf, BUFSIZ);
|
||||
if (scb->bufcnt != -1 || errno != EINTR)
|
||||
break;
|
||||
}
|
||||
|
||||
if (scb->bufcnt <= 0)
|
||||
{
|
||||
if (scb->bufcnt == 0)
|
||||
return SERIAL_TIMEOUT; /* 0 chars means timeout [may need to
|
||||
distinguish between EOF & timeouts
|
||||
someday] */
|
||||
else
|
||||
return SERIAL_ERROR; /* Got an error from read */
|
||||
}
|
||||
|
||||
scb->bufcnt--;
|
||||
scb->bufp = scb->buf;
|
||||
return *scb->bufp++;
|
||||
}
|
||||
|
||||
static int
|
||||
pipe_noflush_set_tty_state (scb, new_ttystate, old_ttystate)
|
||||
serial_t scb;
|
||||
serial_ttystate new_ttystate;
|
||||
serial_ttystate old_ttystate;
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
pipe_print_tty_state (scb, ttystate)
|
||||
serial_t scb;
|
||||
serial_ttystate ttystate;
|
||||
{
|
||||
/* Nothing to print. */
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
pipe_setbaudrate (scb, rate)
|
||||
serial_t scb;
|
||||
int rate;
|
||||
{
|
||||
return 0; /* Never fails! */
|
||||
}
|
||||
|
||||
static int
|
||||
pipe_setstopbits (scb, num)
|
||||
serial_t scb;
|
||||
int num;
|
||||
{
|
||||
return 0; /* Never fails! */
|
||||
}
|
||||
|
||||
static int
|
||||
pipe_write (scb, str, len)
|
||||
serial_t scb;
|
||||
const char *str;
|
||||
int len;
|
||||
{
|
||||
int cc;
|
||||
|
||||
while (len > 0)
|
||||
{
|
||||
cc = write (scb->fd, str, len);
|
||||
|
||||
if (cc < 0)
|
||||
return 1;
|
||||
len -= cc;
|
||||
str += cc;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
pipe_close (scb)
|
||||
serial_t scb;
|
||||
pipe_close (serial_t scb)
|
||||
{
|
||||
struct pipe_state *state = scb->state;
|
||||
if (state != NULL)
|
||||
@ -375,29 +139,30 @@ pipe_close (scb)
|
||||
}
|
||||
}
|
||||
|
||||
static struct serial_ops pipe_ops =
|
||||
{
|
||||
"pipe",
|
||||
0,
|
||||
pipe_open,
|
||||
pipe_close,
|
||||
pipe_readchar,
|
||||
pipe_write,
|
||||
pipe_return_0, /* flush output */
|
||||
pipe_return_0, /* flush input */
|
||||
pipe_return_0, /* send break */
|
||||
pipe_raw,
|
||||
pipe_get_tty_state,
|
||||
pipe_set_tty_state,
|
||||
pipe_print_tty_state,
|
||||
pipe_noflush_set_tty_state,
|
||||
pipe_setbaudrate,
|
||||
pipe_setstopbits,
|
||||
pipe_return_0, /* wait for output to drain */
|
||||
};
|
||||
static struct serial_ops pipe_ops;
|
||||
|
||||
void
|
||||
_initialize_ser_pipe ()
|
||||
_initialize_ser_pipe (void)
|
||||
{
|
||||
serial_add_interface (&pipe_ops);
|
||||
struct serial_ops *ops = XMALLOC (struct serial_ops);
|
||||
memset (ops, sizeof (struct serial_ops), 0);
|
||||
ops->name = "pipe";
|
||||
ops->next = 0;
|
||||
ops->open = pipe_open;
|
||||
ops->close = pipe_close;
|
||||
ops->readchar = ser_unix_readchar;
|
||||
ops->write = ser_unix_write;
|
||||
ops->flush_output = ser_unix_nop_flush_output;
|
||||
ops->flush_input = ser_unix_nop_flush_input;
|
||||
ops->send_break = ser_unix_nop_send_break;
|
||||
ops->go_raw = ser_unix_nop_raw;
|
||||
ops->get_tty_state = ser_unix_nop_get_tty_state;
|
||||
ops->set_tty_state = ser_unix_nop_set_tty_state;
|
||||
ops->print_tty_state = ser_unix_nop_print_tty_state;
|
||||
ops->noflush_set_tty_state = ser_unix_nop_noflush_set_tty_state;
|
||||
ops->setbaudrate = ser_unix_nop_setbaudrate;
|
||||
ops->setstopbits = ser_unix_nop_setstopbits;
|
||||
ops->drain_output = ser_unix_nop_drain_output;
|
||||
ops->async = ser_unix_async;
|
||||
serial_add_interface (ops);
|
||||
}
|
||||
|
305
gdb/ser-tcp.c
305
gdb/ser-tcp.c
@ -1,5 +1,5 @@
|
||||
/* Serial interface for raw TCP connections on Un*x like systems
|
||||
Copyright 1992, 1993, 1998 Free Software Foundation, Inc.
|
||||
Copyright 1992, 1993, 1998-1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
@ -20,13 +20,14 @@
|
||||
|
||||
#include "defs.h"
|
||||
#include "serial.h"
|
||||
#include "ser-unix.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#ifndef __CYGWIN32__
|
||||
#include <netinet/tcp.h>
|
||||
#endif
|
||||
@ -34,37 +35,15 @@
|
||||
#include "signals.h"
|
||||
#include "gdb_string.h"
|
||||
|
||||
extern int (*ui_loop_hook) PARAMS ((int));
|
||||
static int tcp_open (serial_t scb, const char *name);
|
||||
static void tcp_close (serial_t scb);
|
||||
|
||||
struct tcp_ttystate
|
||||
{
|
||||
int bogus;
|
||||
};
|
||||
|
||||
static int tcp_open PARAMS ((serial_t scb, const char *name));
|
||||
static void tcp_raw PARAMS ((serial_t scb));
|
||||
static int wait_for PARAMS ((serial_t scb, int timeout));
|
||||
static int tcp_readchar PARAMS ((serial_t scb, int timeout));
|
||||
static int tcp_setbaudrate PARAMS ((serial_t scb, int rate));
|
||||
static int tcp_setstopbits PARAMS ((serial_t scb, int num));
|
||||
static int tcp_write PARAMS ((serial_t scb, const char *str, int len));
|
||||
/* FIXME: static void tcp_restore PARAMS ((serial_t scb)); */
|
||||
static void tcp_close PARAMS ((serial_t scb));
|
||||
static serial_ttystate tcp_get_tty_state PARAMS ((serial_t scb));
|
||||
static int tcp_set_tty_state PARAMS ((serial_t scb, serial_ttystate state));
|
||||
static int tcp_return_0 PARAMS ((serial_t));
|
||||
static int tcp_noflush_set_tty_state PARAMS ((serial_t, serial_ttystate,
|
||||
serial_ttystate));
|
||||
static void tcp_print_tty_state PARAMS ((serial_t, serial_ttystate));
|
||||
|
||||
void _initialize_ser_tcp PARAMS ((void));
|
||||
void _initialize_ser_tcp (void);
|
||||
|
||||
/* Open up a raw tcp socket */
|
||||
|
||||
static int
|
||||
tcp_open (scb, name)
|
||||
serial_t scb;
|
||||
const char *name;
|
||||
tcp_open (serial_t scb, const char *name)
|
||||
{
|
||||
char *port_str;
|
||||
int port;
|
||||
@ -143,231 +122,8 @@ tcp_open (scb, name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static serial_ttystate
|
||||
tcp_get_tty_state (scb)
|
||||
serial_t scb;
|
||||
{
|
||||
struct tcp_ttystate *state;
|
||||
|
||||
state = (struct tcp_ttystate *) xmalloc (sizeof *state);
|
||||
|
||||
return (serial_ttystate) state;
|
||||
}
|
||||
|
||||
static int
|
||||
tcp_set_tty_state (scb, ttystate)
|
||||
serial_t scb;
|
||||
serial_ttystate ttystate;
|
||||
{
|
||||
struct tcp_ttystate *state;
|
||||
|
||||
state = (struct tcp_ttystate *) ttystate;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
tcp_return_0 (scb)
|
||||
serial_t scb;
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
tcp_raw (scb)
|
||||
serial_t scb;
|
||||
{
|
||||
return; /* Always in raw mode */
|
||||
}
|
||||
|
||||
/* Wait for input on scb, with timeout seconds. Returns 0 on success,
|
||||
otherwise SERIAL_TIMEOUT or SERIAL_ERROR.
|
||||
|
||||
For termio{s}, we actually just setup VTIME if necessary, and let the
|
||||
timeout occur in the read() in tcp_read().
|
||||
*/
|
||||
|
||||
static int
|
||||
wait_for (scb, timeout)
|
||||
serial_t scb;
|
||||
int timeout;
|
||||
{
|
||||
int numfds;
|
||||
struct timeval tv;
|
||||
fd_set readfds, exceptfds;
|
||||
|
||||
FD_ZERO (&readfds);
|
||||
FD_ZERO (&exceptfds);
|
||||
|
||||
tv.tv_sec = timeout;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
FD_SET (scb->fd, &readfds);
|
||||
FD_SET (scb->fd, &exceptfds);
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (timeout >= 0)
|
||||
numfds = select (scb->fd + 1, &readfds, 0, &exceptfds, &tv);
|
||||
else
|
||||
numfds = select (scb->fd + 1, &readfds, 0, &exceptfds, 0);
|
||||
|
||||
if (numfds <= 0)
|
||||
{
|
||||
if (numfds == 0)
|
||||
return SERIAL_TIMEOUT;
|
||||
else if (errno == EINTR)
|
||||
continue;
|
||||
else
|
||||
return SERIAL_ERROR; /* Got an error from select or poll */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read a character with user-specified timeout. TIMEOUT is number of seconds
|
||||
to wait, or -1 to wait forever. Use timeout of 0 to effect a poll. Returns
|
||||
char if successful. Returns -2 if timeout expired, EOF if line dropped
|
||||
dead, or -3 for any other error (see errno in that case). */
|
||||
|
||||
static int
|
||||
tcp_readchar (scb, timeout)
|
||||
serial_t scb;
|
||||
int timeout;
|
||||
{
|
||||
int status;
|
||||
int delta;
|
||||
|
||||
if (scb->bufcnt-- > 0)
|
||||
return *scb->bufp++;
|
||||
|
||||
/* We have to be able to keep the GUI alive here, so we break the original
|
||||
timeout into steps of 1 second, running the "keep the GUI alive" hook
|
||||
each time through the loop.
|
||||
|
||||
Also, timeout = 0 means to poll, so we just set the delta to 0, so we
|
||||
will only go through the loop once. */
|
||||
|
||||
delta = (timeout == 0 ? 0 : 1);
|
||||
while (1)
|
||||
{
|
||||
|
||||
/* N.B. The UI may destroy our world (for instance by calling
|
||||
remote_stop,) in which case we want to get out of here as
|
||||
quickly as possible. It is not safe to touch scb, since
|
||||
someone else might have freed it. The ui_loop_hook signals that
|
||||
we should exit by returning 1. */
|
||||
|
||||
if (ui_loop_hook)
|
||||
{
|
||||
if (ui_loop_hook (0))
|
||||
return SERIAL_TIMEOUT;
|
||||
}
|
||||
|
||||
status = wait_for (scb, delta);
|
||||
timeout -= delta;
|
||||
|
||||
/* If we got a character or an error back from wait_for, then we can
|
||||
break from the loop before the timeout is completed. */
|
||||
|
||||
if (status != SERIAL_TIMEOUT)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
/* If we have exhausted the original timeout, then generate
|
||||
a SERIAL_TIMEOUT, and pass it out of the loop. */
|
||||
|
||||
else if (timeout == 0)
|
||||
{
|
||||
status = SERIAL_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
while (1)
|
||||
{
|
||||
scb->bufcnt = read (scb->fd, scb->buf, BUFSIZ);
|
||||
if (scb->bufcnt != -1 || errno != EINTR)
|
||||
break;
|
||||
}
|
||||
|
||||
if (scb->bufcnt <= 0)
|
||||
{
|
||||
if (scb->bufcnt == 0)
|
||||
return SERIAL_TIMEOUT; /* 0 chars means timeout [may need to
|
||||
distinguish between EOF & timeouts
|
||||
someday] */
|
||||
else
|
||||
return SERIAL_ERROR; /* Got an error from read */
|
||||
}
|
||||
|
||||
scb->bufcnt--;
|
||||
scb->bufp = scb->buf;
|
||||
return *scb->bufp++;
|
||||
}
|
||||
|
||||
static int
|
||||
tcp_noflush_set_tty_state (scb, new_ttystate, old_ttystate)
|
||||
serial_t scb;
|
||||
serial_ttystate new_ttystate;
|
||||
serial_ttystate old_ttystate;
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
tcp_print_tty_state (scb, ttystate)
|
||||
serial_t scb;
|
||||
serial_ttystate ttystate;
|
||||
{
|
||||
/* Nothing to print. */
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
tcp_setbaudrate (scb, rate)
|
||||
serial_t scb;
|
||||
int rate;
|
||||
{
|
||||
return 0; /* Never fails! */
|
||||
}
|
||||
|
||||
static int
|
||||
tcp_setstopbits (scb, num)
|
||||
serial_t scb;
|
||||
int num;
|
||||
{
|
||||
return 0; /* Never fails! */
|
||||
}
|
||||
|
||||
static int
|
||||
tcp_write (scb, str, len)
|
||||
serial_t scb;
|
||||
const char *str;
|
||||
int len;
|
||||
{
|
||||
int cc;
|
||||
|
||||
while (len > 0)
|
||||
{
|
||||
cc = write (scb->fd, str, len);
|
||||
|
||||
if (cc < 0)
|
||||
return 1;
|
||||
len -= cc;
|
||||
str += cc;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
tcp_close (scb)
|
||||
serial_t scb;
|
||||
tcp_close (serial_t scb)
|
||||
{
|
||||
if (scb->fd < 0)
|
||||
return;
|
||||
@ -376,29 +132,28 @@ tcp_close (scb)
|
||||
scb->fd = -1;
|
||||
}
|
||||
|
||||
static struct serial_ops tcp_ops =
|
||||
{
|
||||
"tcp",
|
||||
0,
|
||||
tcp_open,
|
||||
tcp_close,
|
||||
tcp_readchar,
|
||||
tcp_write,
|
||||
tcp_return_0, /* flush output */
|
||||
tcp_return_0, /* flush input */
|
||||
tcp_return_0, /* send break */
|
||||
tcp_raw,
|
||||
tcp_get_tty_state,
|
||||
tcp_set_tty_state,
|
||||
tcp_print_tty_state,
|
||||
tcp_noflush_set_tty_state,
|
||||
tcp_setbaudrate,
|
||||
tcp_setstopbits,
|
||||
tcp_return_0, /* wait for output to drain */
|
||||
};
|
||||
|
||||
void
|
||||
_initialize_ser_tcp ()
|
||||
_initialize_ser_tcp (void)
|
||||
{
|
||||
serial_add_interface (&tcp_ops);
|
||||
struct serial_ops *ops = XMALLOC (struct serial_ops);
|
||||
memset (ops, sizeof (struct serial_ops), 0);
|
||||
ops->name = "tcp";
|
||||
ops->next = 0;
|
||||
ops->open = tcp_open;
|
||||
ops->close = tcp_close;
|
||||
ops->readchar = ser_unix_readchar;
|
||||
ops->write = ser_unix_write;
|
||||
ops->flush_output = ser_unix_nop_flush_output;
|
||||
ops->flush_input = ser_unix_nop_flush_input;
|
||||
ops->send_break = ser_unix_nop_send_break;
|
||||
ops->go_raw = ser_unix_nop_raw;
|
||||
ops->get_tty_state = ser_unix_nop_get_tty_state;
|
||||
ops->set_tty_state = ser_unix_nop_set_tty_state;
|
||||
ops->print_tty_state = ser_unix_nop_print_tty_state;
|
||||
ops->noflush_set_tty_state = ser_unix_nop_noflush_set_tty_state;
|
||||
ops->setbaudrate = ser_unix_nop_setbaudrate;
|
||||
ops->setstopbits = ser_unix_nop_setstopbits;
|
||||
ops->drain_output = ser_unix_nop_drain_output;
|
||||
ops->async = ser_unix_async;
|
||||
serial_add_interface (ops);
|
||||
}
|
||||
|
507
gdb/ser-unix.c
507
gdb/ser-unix.c
@ -1,5 +1,5 @@
|
||||
/* Serial interface for local (hardwired) serial ports on Un*x like systems
|
||||
Copyright 1992, 1993, 1994, 1998 Free Software Foundation, Inc.
|
||||
Copyright 1992, 1993, 1994, 1998-1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
@ -20,9 +20,20 @@
|
||||
|
||||
#include "defs.h"
|
||||
#include "serial.h"
|
||||
#include "ser-unix.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include "terminal.h"
|
||||
#ifdef HAVE_SYS_WAIT_H
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "gdb_string.h"
|
||||
#include "event-loop.h"
|
||||
|
||||
|
||||
#ifdef HAVE_TERMIOS
|
||||
|
||||
@ -46,10 +57,6 @@ struct hardwire_ttystate
|
||||
#endif /* termio */
|
||||
|
||||
#ifdef HAVE_SGTTY
|
||||
/* Needed for the code which uses select(). We would include <sys/select.h>
|
||||
too if it existed on all systems. */
|
||||
#include <sys/time.h>
|
||||
|
||||
struct hardwire_ttystate
|
||||
{
|
||||
struct sgttyb sgttyb;
|
||||
@ -60,37 +67,35 @@ struct hardwire_ttystate
|
||||
};
|
||||
#endif /* sgtty */
|
||||
|
||||
static int hardwire_open PARAMS ((serial_t scb, const char *name));
|
||||
static void hardwire_raw PARAMS ((serial_t scb));
|
||||
static int wait_for PARAMS ((serial_t scb, int timeout));
|
||||
static int hardwire_readchar PARAMS ((serial_t scb, int timeout));
|
||||
static int rate_to_code PARAMS ((int rate));
|
||||
static int hardwire_setbaudrate PARAMS ((serial_t scb, int rate));
|
||||
static int hardwire_write PARAMS ((serial_t scb, const char *str, int len));
|
||||
static void hardwire_close PARAMS ((serial_t scb));
|
||||
static int get_tty_state PARAMS ((serial_t scb, struct hardwire_ttystate * state));
|
||||
static int set_tty_state PARAMS ((serial_t scb, struct hardwire_ttystate * state));
|
||||
static serial_ttystate hardwire_get_tty_state PARAMS ((serial_t scb));
|
||||
static int hardwire_set_tty_state PARAMS ((serial_t scb, serial_ttystate state));
|
||||
static int hardwire_noflush_set_tty_state PARAMS ((serial_t, serial_ttystate,
|
||||
serial_ttystate));
|
||||
static void hardwire_print_tty_state PARAMS ((serial_t, serial_ttystate));
|
||||
static int hardwire_drain_output PARAMS ((serial_t));
|
||||
static int hardwire_flush_output PARAMS ((serial_t));
|
||||
static int hardwire_flush_input PARAMS ((serial_t));
|
||||
static int hardwire_send_break PARAMS ((serial_t));
|
||||
static int hardwire_setstopbits PARAMS ((serial_t, int));
|
||||
static int hardwire_open (serial_t scb, const char *name);
|
||||
static void hardwire_raw (serial_t scb);
|
||||
static int wait_for (serial_t scb, int timeout);
|
||||
static int hardwire_readchar (serial_t scb, int timeout);
|
||||
static int rate_to_code (int rate);
|
||||
static int hardwire_setbaudrate (serial_t scb, int rate);
|
||||
static int hardwire_write (serial_t scb, const char *str, int len);
|
||||
static void hardwire_close (serial_t scb);
|
||||
static int get_tty_state (serial_t scb, struct hardwire_ttystate * state);
|
||||
static int set_tty_state (serial_t scb, struct hardwire_ttystate * state);
|
||||
static serial_ttystate hardwire_get_tty_state (serial_t scb);
|
||||
static int hardwire_set_tty_state (serial_t scb, serial_ttystate state);
|
||||
static int hardwire_noflush_set_tty_state (serial_t, serial_ttystate,
|
||||
serial_ttystate);
|
||||
static void hardwire_print_tty_state (serial_t, serial_ttystate, struct gdb_file *);
|
||||
static int hardwire_drain_output (serial_t);
|
||||
static int hardwire_flush_output (serial_t);
|
||||
static int hardwire_flush_input (serial_t);
|
||||
static int hardwire_send_break (serial_t);
|
||||
static int hardwire_setstopbits (serial_t, int);
|
||||
|
||||
void _initialize_ser_hardwire PARAMS ((void));
|
||||
void _initialize_ser_hardwire (void);
|
||||
|
||||
extern int (*ui_loop_hook) PARAMS ((int));
|
||||
extern int (*ui_loop_hook) (int);
|
||||
|
||||
/* Open up a real live device for serial I/O */
|
||||
|
||||
static int
|
||||
hardwire_open (scb, name)
|
||||
serial_t scb;
|
||||
const char *name;
|
||||
hardwire_open (serial_t scb, const char *name)
|
||||
{
|
||||
scb->fd = open (name, O_RDWR);
|
||||
if (scb->fd < 0)
|
||||
@ -100,9 +105,7 @@ hardwire_open (scb, name)
|
||||
}
|
||||
|
||||
static int
|
||||
get_tty_state (scb, state)
|
||||
serial_t scb;
|
||||
struct hardwire_ttystate *state;
|
||||
get_tty_state (serial_t scb, struct hardwire_ttystate *state)
|
||||
{
|
||||
#ifdef HAVE_TERMIOS
|
||||
if (tcgetattr (scb->fd, &state->termios) < 0)
|
||||
@ -132,9 +135,7 @@ get_tty_state (scb, state)
|
||||
}
|
||||
|
||||
static int
|
||||
set_tty_state (scb, state)
|
||||
serial_t scb;
|
||||
struct hardwire_ttystate *state;
|
||||
set_tty_state (serial_t scb, struct hardwire_ttystate *state)
|
||||
{
|
||||
#ifdef HAVE_TERMIOS
|
||||
if (tcsetattr (scb->fd, TCSANOW, &state->termios) < 0)
|
||||
@ -164,8 +165,7 @@ set_tty_state (scb, state)
|
||||
}
|
||||
|
||||
static serial_ttystate
|
||||
hardwire_get_tty_state (scb)
|
||||
serial_t scb;
|
||||
hardwire_get_tty_state (serial_t scb)
|
||||
{
|
||||
struct hardwire_ttystate *state;
|
||||
|
||||
@ -178,9 +178,7 @@ hardwire_get_tty_state (scb)
|
||||
}
|
||||
|
||||
static int
|
||||
hardwire_set_tty_state (scb, ttystate)
|
||||
serial_t scb;
|
||||
serial_ttystate ttystate;
|
||||
hardwire_set_tty_state (serial_t scb, serial_ttystate ttystate)
|
||||
{
|
||||
struct hardwire_ttystate *state;
|
||||
|
||||
@ -190,10 +188,9 @@ hardwire_set_tty_state (scb, ttystate)
|
||||
}
|
||||
|
||||
static int
|
||||
hardwire_noflush_set_tty_state (scb, new_ttystate, old_ttystate)
|
||||
serial_t scb;
|
||||
serial_ttystate new_ttystate;
|
||||
serial_ttystate old_ttystate;
|
||||
hardwire_noflush_set_tty_state (serial_t scb,
|
||||
serial_ttystate new_ttystate,
|
||||
serial_ttystate old_ttystate)
|
||||
{
|
||||
struct hardwire_ttystate new_state;
|
||||
#ifdef HAVE_SGTTY
|
||||
@ -224,63 +221,63 @@ hardwire_noflush_set_tty_state (scb, new_ttystate, old_ttystate)
|
||||
}
|
||||
|
||||
static void
|
||||
hardwire_print_tty_state (scb, ttystate)
|
||||
serial_t scb;
|
||||
serial_ttystate ttystate;
|
||||
hardwire_print_tty_state (serial_t scb,
|
||||
serial_ttystate ttystate,
|
||||
struct gdb_file *stream)
|
||||
{
|
||||
struct hardwire_ttystate *state = (struct hardwire_ttystate *) ttystate;
|
||||
int i;
|
||||
|
||||
#ifdef HAVE_TERMIOS
|
||||
printf_filtered ("c_iflag = 0x%x, c_oflag = 0x%x,\n",
|
||||
state->termios.c_iflag, state->termios.c_oflag);
|
||||
printf_filtered ("c_cflag = 0x%x, c_lflag = 0x%x\n",
|
||||
state->termios.c_cflag, state->termios.c_lflag);
|
||||
fprintf_filtered (stream, "c_iflag = 0x%x, c_oflag = 0x%x,\n",
|
||||
state->termios.c_iflag, state->termios.c_oflag);
|
||||
fprintf_filtered (stream, "c_cflag = 0x%x, c_lflag = 0x%x\n",
|
||||
state->termios.c_cflag, state->termios.c_lflag);
|
||||
#if 0
|
||||
/* This not in POSIX, and is not really documented by those systems
|
||||
which have it (at least not Sun). */
|
||||
printf_filtered ("c_line = 0x%x.\n", state->termios.c_line);
|
||||
fprintf_filtered (stream, "c_line = 0x%x.\n", state->termios.c_line);
|
||||
#endif
|
||||
printf_filtered ("c_cc: ");
|
||||
fprintf_filtered (stream, "c_cc: ");
|
||||
for (i = 0; i < NCCS; i += 1)
|
||||
printf_filtered ("0x%x ", state->termios.c_cc[i]);
|
||||
printf_filtered ("\n");
|
||||
fprintf_filtered (stream, "0x%x ", state->termios.c_cc[i]);
|
||||
fprintf_filtered (stream, "\n");
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TERMIO
|
||||
printf_filtered ("c_iflag = 0x%x, c_oflag = 0x%x,\n",
|
||||
state->termio.c_iflag, state->termio.c_oflag);
|
||||
printf_filtered ("c_cflag = 0x%x, c_lflag = 0x%x, c_line = 0x%x.\n",
|
||||
state->termio.c_cflag, state->termio.c_lflag,
|
||||
state->termio.c_line);
|
||||
printf_filtered ("c_cc: ");
|
||||
fprintf_filtered (stream, "c_iflag = 0x%x, c_oflag = 0x%x,\n",
|
||||
state->termio.c_iflag, state->termio.c_oflag);
|
||||
fprintf_filtered (stream, "c_cflag = 0x%x, c_lflag = 0x%x, c_line = 0x%x.\n",
|
||||
state->termio.c_cflag, state->termio.c_lflag,
|
||||
state->termio.c_line);
|
||||
fprintf_filtered (stream, "c_cc: ");
|
||||
for (i = 0; i < NCC; i += 1)
|
||||
printf_filtered ("0x%x ", state->termio.c_cc[i]);
|
||||
printf_filtered ("\n");
|
||||
fprintf_filtered (stream, "0x%x ", state->termio.c_cc[i]);
|
||||
fprintf_filtered (stream, "\n");
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SGTTY
|
||||
printf_filtered ("sgttyb.sg_flags = 0x%x.\n", state->sgttyb.sg_flags);
|
||||
fprintf_filtered (stream, "sgttyb.sg_flags = 0x%x.\n",
|
||||
state->sgttyb.sg_flags);
|
||||
|
||||
printf_filtered ("tchars: ");
|
||||
fprintf_filtered (stream, "tchars: ");
|
||||
for (i = 0; i < (int) sizeof (struct tchars); i++)
|
||||
printf_filtered ("0x%x ", ((unsigned char *) &state->tc)[i]);
|
||||
printf_filtered ("\n");
|
||||
fprintf_filtered (stream, "0x%x ", ((unsigned char *) &state->tc)[i]);
|
||||
fprintf_filtered ("\n");
|
||||
|
||||
printf_filtered ("ltchars: ");
|
||||
fprintf_filtered (stream, "ltchars: ");
|
||||
for (i = 0; i < (int) sizeof (struct ltchars); i++)
|
||||
printf_filtered ("0x%x ", ((unsigned char *) &state->ltc)[i]);
|
||||
printf_filtered ("\n");
|
||||
fprintf_filtered (stream, "0x%x ", ((unsigned char *) &state->ltc)[i]);
|
||||
fprintf_filtered (stream, "\n");
|
||||
|
||||
printf_filtered ("lmode: 0x%x\n", state->lmode);
|
||||
fprintf_filtered (stream, "lmode: 0x%x\n", state->lmode);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Wait for the output to drain away, as opposed to flushing (discarding) it */
|
||||
|
||||
static int
|
||||
hardwire_drain_output (scb)
|
||||
serial_t scb;
|
||||
hardwire_drain_output (serial_t scb)
|
||||
{
|
||||
#ifdef HAVE_TERMIOS
|
||||
return tcdrain (scb->fd);
|
||||
@ -309,8 +306,7 @@ hardwire_drain_output (scb)
|
||||
}
|
||||
|
||||
static int
|
||||
hardwire_flush_output (scb)
|
||||
serial_t scb;
|
||||
hardwire_flush_output (serial_t scb)
|
||||
{
|
||||
#ifdef HAVE_TERMIOS
|
||||
return tcflush (scb->fd, TCOFLUSH);
|
||||
@ -327,8 +323,7 @@ hardwire_flush_output (scb)
|
||||
}
|
||||
|
||||
static int
|
||||
hardwire_flush_input (scb)
|
||||
serial_t scb;
|
||||
hardwire_flush_input (serial_t scb)
|
||||
{
|
||||
scb->bufcnt = 0;
|
||||
scb->bufp = scb->buf;
|
||||
@ -348,8 +343,7 @@ hardwire_flush_input (scb)
|
||||
}
|
||||
|
||||
static int
|
||||
hardwire_send_break (scb)
|
||||
serial_t scb;
|
||||
hardwire_send_break (serial_t scb)
|
||||
{
|
||||
#ifdef HAVE_TERMIOS
|
||||
return tcsendbreak (scb->fd, 0);
|
||||
@ -379,8 +373,7 @@ hardwire_send_break (scb)
|
||||
}
|
||||
|
||||
static void
|
||||
hardwire_raw (scb)
|
||||
serial_t scb;
|
||||
hardwire_raw (serial_t scb)
|
||||
{
|
||||
struct hardwire_ttystate state;
|
||||
|
||||
@ -425,10 +418,12 @@ hardwire_raw (scb)
|
||||
timeout occur in the read() in hardwire_read().
|
||||
*/
|
||||
|
||||
/* FIXME: Don't replace this with the equivalent ser_unix*() until the
|
||||
old TERMIOS/SGTTY/... timer code has been flushed. cagney
|
||||
1999-09-16. */
|
||||
|
||||
static int
|
||||
wait_for (scb, timeout)
|
||||
serial_t scb;
|
||||
int timeout;
|
||||
wait_for (serial_t scb, int timeout)
|
||||
{
|
||||
#ifdef HAVE_SGTTY
|
||||
{
|
||||
@ -537,10 +532,19 @@ wait_for (scb, timeout)
|
||||
to wait, or -1 to wait forever. Use timeout of 0 to effect a poll. Returns
|
||||
char if successful. Returns SERIAL_TIMEOUT if timeout expired, EOF if line
|
||||
dropped dead, or SERIAL_ERROR for any other error (see errno in that case). */
|
||||
|
||||
/* FIXME: cagney/1999-09-16: Don't replace this with the equivalent
|
||||
ser_unix*() until the old TERMIOS/SGTTY/... timer code has been
|
||||
flushed. */
|
||||
|
||||
/* NOTE: cagney/1999-09-16: This function is not identical to
|
||||
ser_unix_readchar() as part of replacing it with ser_unix*()
|
||||
merging will be required - this code handles the case where read()
|
||||
times out due to no data while ser_unix_readchar() doesn't expect
|
||||
that. */
|
||||
|
||||
static int
|
||||
hardwire_readchar (scb, timeout)
|
||||
serial_t scb;
|
||||
int timeout;
|
||||
hardwire_readchar (serial_t scb, int timeout)
|
||||
{
|
||||
int status, delta;
|
||||
int detach = 0;
|
||||
@ -579,7 +583,11 @@ hardwire_readchar (scb, timeout)
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
scb->bufcnt = read (scb->fd, scb->buf, BUFSIZ);
|
||||
/* NOTE: cagney/1999-09-17: See ser_unix_readchar() for reason
|
||||
why ASYNC reads are character by character. */
|
||||
|
||||
scb->bufcnt = read (scb->fd, scb->buf,
|
||||
(SERIAL_IS_ASYNC_P (scb) ? 1 : BUFSIZ));
|
||||
|
||||
if (scb->bufcnt <= 0)
|
||||
{
|
||||
@ -718,8 +726,7 @@ baudtab[] =
|
||||
};
|
||||
|
||||
static int
|
||||
rate_to_code (rate)
|
||||
int rate;
|
||||
rate_to_code (int rate)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -731,9 +738,7 @@ rate_to_code (rate)
|
||||
}
|
||||
|
||||
static int
|
||||
hardwire_setbaudrate (scb, rate)
|
||||
serial_t scb;
|
||||
int rate;
|
||||
hardwire_setbaudrate (serial_t scb, int rate)
|
||||
{
|
||||
struct hardwire_ttystate state;
|
||||
|
||||
@ -807,11 +812,220 @@ hardwire_setstopbits (scb, num)
|
||||
return set_tty_state (scb, &state);
|
||||
}
|
||||
|
||||
/* FIXME: Don't replace this with the equivalent ser_unix*() until the
|
||||
old TERMIOS/SGTTY/... timer code has been flushed. cagney
|
||||
1999-09-16. */
|
||||
|
||||
static int
|
||||
hardwire_write (scb, str, len)
|
||||
serial_t scb;
|
||||
const char *str;
|
||||
int len;
|
||||
hardwire_write (serial_t scb, const char *str, int len)
|
||||
{
|
||||
int cc;
|
||||
|
||||
while (len > 0)
|
||||
{
|
||||
cc = write (scb->fd, str, len);
|
||||
|
||||
if (cc < 0)
|
||||
return 1;
|
||||
len -= cc;
|
||||
str += cc;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
hardwire_close (serial_t scb)
|
||||
{
|
||||
if (scb->fd < 0)
|
||||
return;
|
||||
|
||||
close (scb->fd);
|
||||
scb->fd = -1;
|
||||
}
|
||||
|
||||
|
||||
/* Generic operations used by all UNIX/FD based serial interfaces. */
|
||||
|
||||
serial_ttystate
|
||||
ser_unix_nop_get_tty_state (serial_t scb)
|
||||
{
|
||||
/* allocate a dummy */
|
||||
return (serial_ttystate) XMALLOC (int);
|
||||
}
|
||||
|
||||
int
|
||||
ser_unix_nop_set_tty_state (serial_t scb, serial_ttystate ttystate)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
ser_unix_nop_raw (serial_t scb)
|
||||
{
|
||||
return; /* Always in raw mode */
|
||||
}
|
||||
|
||||
/* Wait for input on scb, with timeout seconds. Returns 0 on success,
|
||||
otherwise SERIAL_TIMEOUT or SERIAL_ERROR. */
|
||||
|
||||
int
|
||||
ser_unix_wait_for (serial_t scb, int timeout)
|
||||
{
|
||||
int numfds;
|
||||
struct timeval tv;
|
||||
fd_set readfds, exceptfds;
|
||||
|
||||
FD_ZERO (&readfds);
|
||||
FD_ZERO (&exceptfds);
|
||||
|
||||
tv.tv_sec = timeout;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
FD_SET (scb->fd, &readfds);
|
||||
FD_SET (scb->fd, &exceptfds);
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (timeout >= 0)
|
||||
numfds = select (scb->fd + 1, &readfds, 0, &exceptfds, &tv);
|
||||
else
|
||||
numfds = select (scb->fd + 1, &readfds, 0, &exceptfds, 0);
|
||||
|
||||
if (numfds <= 0)
|
||||
{
|
||||
if (numfds == 0)
|
||||
return SERIAL_TIMEOUT;
|
||||
else if (errno == EINTR)
|
||||
continue;
|
||||
else
|
||||
return SERIAL_ERROR; /* Got an error from select or poll */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read a character with user-specified timeout. TIMEOUT is number of seconds
|
||||
to wait, or -1 to wait forever. Use timeout of 0 to effect a poll. Returns
|
||||
char if successful. Returns -2 if timeout expired, EOF if line dropped
|
||||
dead, or -3 for any other error (see errno in that case). */
|
||||
|
||||
int
|
||||
ser_unix_readchar (serial_t scb, int timeout)
|
||||
{
|
||||
int status;
|
||||
int delta;
|
||||
|
||||
if (scb->bufcnt-- > 0)
|
||||
return *scb->bufp++;
|
||||
|
||||
/* We have to be able to keep the GUI alive here, so we break the original
|
||||
timeout into steps of 1 second, running the "keep the GUI alive" hook
|
||||
each time through the loop.
|
||||
|
||||
Also, timeout = 0 means to poll, so we just set the delta to 0, so we
|
||||
will only go through the loop once. */
|
||||
|
||||
delta = (timeout == 0 ? 0 : 1);
|
||||
while (1)
|
||||
{
|
||||
|
||||
/* N.B. The UI may destroy our world (for instance by calling
|
||||
remote_stop,) in which case we want to get out of here as
|
||||
quickly as possible. It is not safe to touch scb, since
|
||||
someone else might have freed it. The ui_loop_hook signals that
|
||||
we should exit by returning 1. */
|
||||
|
||||
if (ui_loop_hook)
|
||||
{
|
||||
if (ui_loop_hook (0))
|
||||
return SERIAL_TIMEOUT;
|
||||
}
|
||||
|
||||
status = ser_unix_wait_for (scb, delta);
|
||||
timeout -= delta;
|
||||
|
||||
/* If we got a character or an error back from wait_for, then we can
|
||||
break from the loop before the timeout is completed. */
|
||||
|
||||
if (status != SERIAL_TIMEOUT)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
/* If we have exhausted the original timeout, then generate
|
||||
a SERIAL_TIMEOUT, and pass it out of the loop. */
|
||||
|
||||
else if (timeout == 0)
|
||||
{
|
||||
status = SERIAL_TIMEOUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
while (1)
|
||||
{
|
||||
/* FIXME: cagney/1999-09-17: ASYNC: The ASYNC serial code needs
|
||||
to be modified so that it agressivly tries to drain its local
|
||||
input buffer. Until this is done, the read() below can only
|
||||
take in single characters. This is to ensure that
|
||||
unprocessed data doesn't end up sitting in the input fifo. */
|
||||
scb->bufcnt = read (scb->fd, scb->buf,
|
||||
(SERIAL_IS_ASYNC_P (scb) ? 1 : BUFSIZ));
|
||||
if (scb->bufcnt != -1 || errno != EINTR)
|
||||
break;
|
||||
}
|
||||
|
||||
if (scb->bufcnt <= 0)
|
||||
{
|
||||
if (scb->bufcnt == 0)
|
||||
return SERIAL_TIMEOUT; /* 0 chars means timeout [may need to
|
||||
distinguish between EOF & timeouts
|
||||
someday] */
|
||||
else
|
||||
return SERIAL_ERROR; /* Got an error from read */
|
||||
}
|
||||
|
||||
scb->bufcnt--;
|
||||
scb->bufp = scb->buf;
|
||||
return *scb->bufp++;
|
||||
}
|
||||
|
||||
int
|
||||
ser_unix_nop_noflush_set_tty_state (serial_t scb,
|
||||
serial_ttystate new_ttystate,
|
||||
serial_ttystate old_ttystate)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
ser_unix_nop_print_tty_state (serial_t scb,
|
||||
serial_ttystate ttystate,
|
||||
struct gdb_file *stream)
|
||||
{
|
||||
/* Nothing to print. */
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
ser_unix_nop_setbaudrate (serial_t scb, int rate)
|
||||
{
|
||||
return 0; /* Never fails! */
|
||||
}
|
||||
|
||||
int
|
||||
ser_unix_nop_setstopbits (serial_t scb, int num)
|
||||
{
|
||||
return 0; /* Never fails! */
|
||||
}
|
||||
|
||||
int
|
||||
ser_unix_write (serial_t scb, const char *str, int len)
|
||||
{
|
||||
int cc;
|
||||
|
||||
@ -827,40 +1041,79 @@ hardwire_write (scb, str, len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
hardwire_close (scb)
|
||||
serial_t scb;
|
||||
int
|
||||
ser_unix_nop_flush_output (serial_t scb)
|
||||
{
|
||||
if (scb->fd < 0)
|
||||
return;
|
||||
|
||||
close (scb->fd);
|
||||
scb->fd = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct serial_ops hardwire_ops =
|
||||
int
|
||||
ser_unix_nop_flush_input (serial_t scb)
|
||||
{
|
||||
"hardwire",
|
||||
0,
|
||||
hardwire_open,
|
||||
hardwire_close,
|
||||
hardwire_readchar,
|
||||
hardwire_write,
|
||||
hardwire_flush_output,
|
||||
hardwire_flush_input,
|
||||
hardwire_send_break,
|
||||
hardwire_raw,
|
||||
hardwire_get_tty_state,
|
||||
hardwire_set_tty_state,
|
||||
hardwire_print_tty_state,
|
||||
hardwire_noflush_set_tty_state,
|
||||
hardwire_setbaudrate,
|
||||
hardwire_setstopbits,
|
||||
hardwire_drain_output, /* wait for output to drain */
|
||||
};
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ser_unix_nop_send_break (serial_t scb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ser_unix_nop_drain_output (serial_t scb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ser_unix_event (int error, int fd, gdb_client_data context)
|
||||
{
|
||||
serial_t scb = context;
|
||||
scb->async_handler (error, scb->async_context, fd);
|
||||
}
|
||||
|
||||
void
|
||||
_initialize_ser_hardwire ()
|
||||
ser_unix_async (serial_t scb,
|
||||
int async_p)
|
||||
{
|
||||
serial_add_interface (&hardwire_ops);
|
||||
if (async_p)
|
||||
{
|
||||
add_file_handler (scb->fd, ser_unix_event, scb);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete_file_handler (scb->fd);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_initialize_ser_hardwire (void)
|
||||
{
|
||||
struct serial_ops *ops = XMALLOC (struct serial_ops);
|
||||
memset (ops, sizeof (struct serial_ops), 0);
|
||||
ops->name = "hardwire";
|
||||
ops->next = 0;
|
||||
ops->open = hardwire_open;
|
||||
ops->close = hardwire_close;
|
||||
/* FIXME: Don't replace this with the equivalent ser_unix*() until
|
||||
the old TERMIOS/SGTTY/... timer code has been flushed. cagney
|
||||
1999-09-16. */
|
||||
ops->readchar = hardwire_readchar;
|
||||
/* FIXME: Don't replace this with the equivalent ser_unix*() until
|
||||
the old TERMIOS/SGTTY/... timer code has been flushed. cagney
|
||||
1999-09-16. */
|
||||
ops->write = hardwire_write;
|
||||
ops->flush_output = hardwire_flush_output;
|
||||
ops->flush_input = hardwire_flush_input;
|
||||
ops->send_break = hardwire_send_break;
|
||||
ops->go_raw = hardwire_raw;
|
||||
ops->get_tty_state = hardwire_get_tty_state;
|
||||
ops->set_tty_state = hardwire_set_tty_state;
|
||||
ops->print_tty_state = hardwire_print_tty_state;
|
||||
ops->noflush_set_tty_state = hardwire_noflush_set_tty_state;
|
||||
ops->setbaudrate = hardwire_setbaudrate;
|
||||
ops->setstopbits = hardwire_setstopbits;
|
||||
ops->drain_output = hardwire_drain_output;
|
||||
ops->async = ser_unix_async;
|
||||
serial_add_interface (ops);
|
||||
}
|
||||
|
48
gdb/ser-unix.h
Normal file
48
gdb/ser-unix.h
Normal file
@ -0,0 +1,48 @@
|
||||
/* Serial interface for UN*X file-descriptor based connection.
|
||||
Copyright 1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef SER_UNIX_H
|
||||
#define SER_UNIX_H
|
||||
|
||||
#undef XMALLOC
|
||||
#define XMALLOC(TYPE) (TYPE*) xmalloc (sizeof (TYPE))
|
||||
|
||||
/* Generic UNIX/FD functions */
|
||||
|
||||
extern int ser_unix_nop_flush_output (serial_t scb);
|
||||
extern int ser_unix_nop_flush_input (serial_t scb);
|
||||
extern int ser_unix_nop_send_break (serial_t scb);
|
||||
extern void ser_unix_nop_raw (serial_t scb);
|
||||
extern serial_ttystate ser_unix_nop_get_tty_state (serial_t scb);
|
||||
extern int ser_unix_nop_set_tty_state (serial_t scb, serial_ttystate ttystate);
|
||||
extern void ser_unix_nop_print_tty_state (serial_t scb, serial_ttystate ttystate, struct gdb_file *stream);
|
||||
extern int ser_unix_nop_noflush_set_tty_state (serial_t scb, serial_ttystate new_ttystate, serial_ttystate old_ttystate);
|
||||
extern int ser_unix_nop_setbaudrate (serial_t scb, int rate);
|
||||
extern int ser_unix_nop_setstopbits (serial_t scb, int rate);
|
||||
extern int ser_unix_nop_drain_output (serial_t scb);
|
||||
|
||||
extern int ser_unix_wait_for (serial_t scb, int timeout);
|
||||
extern int ser_unix_readchar (serial_t scb, int timeout);
|
||||
|
||||
extern int ser_unix_write (serial_t scb, const char *str, int len);
|
||||
|
||||
extern void ser_unix_async (serial_t scb, int async_p);
|
||||
|
||||
#endif
|
298
gdb/serial.c
298
gdb/serial.c
@ -1,5 +1,5 @@
|
||||
/* Generic serial interface routines
|
||||
Copyright 1992, 1993, 1996, 1997 Free Software Foundation, Inc.
|
||||
Copyright 1992, 1993, 1996, 1997, 1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
#include "gdb_string.h"
|
||||
#include "gdbcmd.h"
|
||||
|
||||
extern void _initialize_serial PARAMS ((void));
|
||||
extern void _initialize_serial (void);
|
||||
|
||||
/* Linked list of serial I/O handlers */
|
||||
|
||||
@ -44,8 +44,8 @@ static serial_t scb_base;
|
||||
static char *serial_logfile = NULL;
|
||||
static GDB_FILE *serial_logfp = NULL;
|
||||
|
||||
static struct serial_ops *serial_interface_lookup PARAMS ((char *));
|
||||
static void serial_logchar PARAMS ((int, int, int));
|
||||
static struct serial_ops *serial_interface_lookup (char *);
|
||||
static void serial_logchar (int, int, int);
|
||||
static char logbase_hex[] = "hex";
|
||||
static char logbase_octal[] = "octal";
|
||||
static char logbase_ascii[] = "ascii";
|
||||
@ -54,6 +54,7 @@ static char *logbase_enums[] =
|
||||
static char *serial_logbase = logbase_ascii;
|
||||
|
||||
|
||||
|
||||
static int serial_current_type = 0;
|
||||
|
||||
/* Log char CH of type CHTYPE, with TIMEOUT */
|
||||
@ -63,10 +64,7 @@ static int serial_current_type = 0;
|
||||
#define SERIAL_BREAK 1235
|
||||
|
||||
static void
|
||||
serial_logchar (ch_type, ch, timeout)
|
||||
int ch_type;
|
||||
int ch;
|
||||
int timeout;
|
||||
serial_logchar (int ch_type, int ch, int timeout)
|
||||
{
|
||||
if (ch_type != serial_current_type)
|
||||
{
|
||||
@ -128,8 +126,7 @@ serial_logchar (ch_type, ch, timeout)
|
||||
}
|
||||
|
||||
void
|
||||
serial_log_command (cmd)
|
||||
const char *cmd;
|
||||
serial_log_command (const char *cmd)
|
||||
{
|
||||
if (!serial_logfp)
|
||||
return;
|
||||
@ -144,60 +141,9 @@ serial_log_command (cmd)
|
||||
gdb_flush (serial_logfp);
|
||||
}
|
||||
|
||||
int
|
||||
serial_write (scb, str, len)
|
||||
serial_t scb;
|
||||
const char *str;
|
||||
int len;
|
||||
{
|
||||
if (serial_logfp != NULL)
|
||||
{
|
||||
int count;
|
||||
|
||||
for (count = 0; count < len; count++)
|
||||
serial_logchar ('w', str[count] & 0xff, 0);
|
||||
|
||||
/* Make sure that the log file is as up-to-date as possible,
|
||||
in case we are getting ready to dump core or something. */
|
||||
gdb_flush (serial_logfp);
|
||||
}
|
||||
|
||||
return (scb->ops->write (scb, str, len));
|
||||
}
|
||||
|
||||
int
|
||||
serial_readchar (scb, timeout)
|
||||
serial_t scb;
|
||||
int timeout;
|
||||
{
|
||||
int ch;
|
||||
|
||||
ch = scb->ops->readchar (scb, timeout);
|
||||
if (serial_logfp != NULL)
|
||||
{
|
||||
serial_logchar ('r', ch, timeout);
|
||||
|
||||
/* Make sure that the log file is as up-to-date as possible,
|
||||
in case we are getting ready to dump core or something. */
|
||||
gdb_flush (serial_logfp);
|
||||
}
|
||||
|
||||
return (ch);
|
||||
}
|
||||
|
||||
int
|
||||
serial_send_break (scb)
|
||||
serial_t scb;
|
||||
{
|
||||
if (serial_logfp != NULL)
|
||||
serial_logchar ('w', SERIAL_BREAK, 0);
|
||||
|
||||
return (scb->ops->send_break (scb));
|
||||
}
|
||||
|
||||
|
||||
static struct serial_ops *
|
||||
serial_interface_lookup (name)
|
||||
char *name;
|
||||
serial_interface_lookup (char *name)
|
||||
{
|
||||
struct serial_ops *ops;
|
||||
|
||||
@ -209,8 +155,7 @@ serial_interface_lookup (name)
|
||||
}
|
||||
|
||||
void
|
||||
serial_add_interface (optable)
|
||||
struct serial_ops *optable;
|
||||
serial_add_interface (struct serial_ops *optable)
|
||||
{
|
||||
optable->next = serial_ops_list;
|
||||
serial_ops_list = optable;
|
||||
@ -219,11 +164,11 @@ serial_add_interface (optable)
|
||||
/* Open up a device or a network socket, depending upon the syntax of NAME. */
|
||||
|
||||
serial_t
|
||||
serial_open (name)
|
||||
const char *name;
|
||||
serial_open (const char *name)
|
||||
{
|
||||
serial_t scb;
|
||||
struct serial_ops *ops;
|
||||
const char *open_name = name;
|
||||
|
||||
for (scb = scb_base; scb; scb = scb->next)
|
||||
if (scb->name && strcmp (scb->name, name) == 0)
|
||||
@ -241,7 +186,10 @@ serial_open (name)
|
||||
else if (strncmp (name, "lpt", 3) == 0)
|
||||
ops = serial_interface_lookup ("parallel");
|
||||
else if (strncmp (name, "|", 1) == 0)
|
||||
ops = serial_interface_lookup ("pipe");
|
||||
{
|
||||
ops = serial_interface_lookup ("pipe");
|
||||
open_name = name + 1; /* discard ``|'' */
|
||||
}
|
||||
else
|
||||
ops = serial_interface_lookup ("hardwire");
|
||||
|
||||
@ -255,7 +203,7 @@ serial_open (name)
|
||||
scb->bufcnt = 0;
|
||||
scb->bufp = scb->buf;
|
||||
|
||||
if (scb->ops->open (scb, name))
|
||||
if (scb->ops->open (scb, open_name))
|
||||
{
|
||||
free (scb);
|
||||
return NULL;
|
||||
@ -264,6 +212,8 @@ serial_open (name)
|
||||
scb->name = strsave (name);
|
||||
scb->next = scb_base;
|
||||
scb->refcnt = 1;
|
||||
scb->async_handler = NULL;
|
||||
scb->async_context = NULL;
|
||||
scb_base = scb;
|
||||
|
||||
last_serial_opened = scb;
|
||||
@ -279,8 +229,7 @@ serial_open (name)
|
||||
}
|
||||
|
||||
serial_t
|
||||
serial_fdopen (fd)
|
||||
const int fd;
|
||||
serial_fdopen (const int fd)
|
||||
{
|
||||
serial_t scb;
|
||||
struct serial_ops *ops;
|
||||
@ -309,6 +258,8 @@ serial_fdopen (fd)
|
||||
scb->name = NULL;
|
||||
scb->next = scb_base;
|
||||
scb->refcnt = 1;
|
||||
scb->async_handler = NULL;
|
||||
scb->async_context = NULL;
|
||||
scb_base = scb;
|
||||
|
||||
last_serial_opened = scb;
|
||||
@ -316,10 +267,8 @@ serial_fdopen (fd)
|
||||
return scb;
|
||||
}
|
||||
|
||||
void
|
||||
serial_close (scb, really_close)
|
||||
serial_t scb;
|
||||
int really_close;
|
||||
static void
|
||||
do_serial_close (serial_t scb, int really_close)
|
||||
{
|
||||
serial_t tmp_scb;
|
||||
|
||||
@ -345,6 +294,10 @@ serial_close (scb, really_close)
|
||||
if (scb->refcnt > 0)
|
||||
return;
|
||||
|
||||
/* ensure that the FD has been taken out of async mode */
|
||||
if (scb->async_handler != NULL)
|
||||
serial_async (scb, NULL, NULL);
|
||||
|
||||
if (really_close)
|
||||
scb->ops->close (scb);
|
||||
|
||||
@ -366,6 +319,178 @@ serial_close (scb, really_close)
|
||||
free (scb);
|
||||
}
|
||||
|
||||
void
|
||||
serial_close (serial_t scb)
|
||||
{
|
||||
do_serial_close (scb, 1);
|
||||
}
|
||||
|
||||
void
|
||||
serial_un_fdopen (serial_t scb)
|
||||
{
|
||||
do_serial_close (scb, 0);
|
||||
}
|
||||
|
||||
int
|
||||
serial_readchar (serial_t scb, int timeout)
|
||||
{
|
||||
int ch;
|
||||
|
||||
ch = scb->ops->readchar (scb, timeout);
|
||||
if (serial_logfp != NULL)
|
||||
{
|
||||
serial_logchar ('r', ch, timeout);
|
||||
|
||||
/* Make sure that the log file is as up-to-date as possible,
|
||||
in case we are getting ready to dump core or something. */
|
||||
gdb_flush (serial_logfp);
|
||||
}
|
||||
|
||||
return (ch);
|
||||
}
|
||||
|
||||
int
|
||||
serial_write (serial_t scb, const char *str, int len)
|
||||
{
|
||||
if (serial_logfp != NULL)
|
||||
{
|
||||
int count;
|
||||
|
||||
for (count = 0; count < len; count++)
|
||||
serial_logchar ('w', str[count] & 0xff, 0);
|
||||
|
||||
/* Make sure that the log file is as up-to-date as possible,
|
||||
in case we are getting ready to dump core or something. */
|
||||
gdb_flush (serial_logfp);
|
||||
}
|
||||
|
||||
return (scb->ops->write (scb, str, len));
|
||||
}
|
||||
|
||||
void
|
||||
serial_printf (serial_t desc, const char *format,...)
|
||||
{
|
||||
va_list args;
|
||||
char *buf;
|
||||
va_start (args, format);
|
||||
|
||||
vasprintf (&buf, format, args);
|
||||
SERIAL_WRITE (desc, buf, strlen (buf));
|
||||
|
||||
free (buf);
|
||||
va_end (args);
|
||||
}
|
||||
|
||||
int
|
||||
serial_drain_output (serial_t scb)
|
||||
{
|
||||
return scb->ops->drain_output (scb);
|
||||
}
|
||||
|
||||
int
|
||||
serial_flush_output (serial_t scb)
|
||||
{
|
||||
return scb->ops->flush_output (scb);
|
||||
}
|
||||
|
||||
int
|
||||
serial_flush_input (serial_t scb)
|
||||
{
|
||||
return scb->ops->flush_input (scb);
|
||||
}
|
||||
|
||||
int
|
||||
serial_send_break (serial_t scb)
|
||||
{
|
||||
if (serial_logfp != NULL)
|
||||
serial_logchar ('w', SERIAL_BREAK, 0);
|
||||
|
||||
return (scb->ops->send_break (scb));
|
||||
}
|
||||
|
||||
void
|
||||
serial_raw (serial_t scb)
|
||||
{
|
||||
scb->ops->go_raw (scb);
|
||||
}
|
||||
|
||||
serial_ttystate
|
||||
serial_get_tty_state (serial_t scb)
|
||||
{
|
||||
return scb->ops->get_tty_state (scb);
|
||||
}
|
||||
|
||||
int
|
||||
serial_set_tty_state (serial_t scb, serial_ttystate ttystate)
|
||||
{
|
||||
return scb->ops->set_tty_state (scb, ttystate);
|
||||
}
|
||||
|
||||
void
|
||||
serial_print_tty_state (serial_t scb,
|
||||
serial_ttystate ttystate,
|
||||
struct gdb_file *stream)
|
||||
{
|
||||
scb->ops->print_tty_state (scb, ttystate, stream);
|
||||
}
|
||||
|
||||
int
|
||||
serial_noflush_set_tty_state (serial_t scb,
|
||||
serial_ttystate new_ttystate,
|
||||
serial_ttystate old_ttystate)
|
||||
{
|
||||
return scb->ops->noflush_set_tty_state (scb, new_ttystate, old_ttystate);
|
||||
}
|
||||
|
||||
int
|
||||
serial_setbaudrate (serial_t scb, int rate)
|
||||
{
|
||||
return scb->ops->setbaudrate (scb, rate);
|
||||
}
|
||||
|
||||
int
|
||||
serial_setstopbits (serial_t scb, int num)
|
||||
{
|
||||
return scb->ops->setstopbits (scb, num);
|
||||
}
|
||||
|
||||
int
|
||||
serial_can_async_p (serial_t scb)
|
||||
{
|
||||
return (scb->ops->async != NULL);
|
||||
}
|
||||
|
||||
int
|
||||
serial_is_async_p (serial_t scb)
|
||||
{
|
||||
return (scb->ops->async != NULL) && (scb->async_handler != NULL);
|
||||
}
|
||||
|
||||
void
|
||||
serial_async (serial_t scb,
|
||||
serial_event_ftype *handler,
|
||||
void *context)
|
||||
{
|
||||
/* Only change mode if there is a need. */
|
||||
if ((scb->async_handler == NULL)
|
||||
!= (handler == NULL))
|
||||
scb->ops->async (scb, handler != NULL);
|
||||
scb->async_handler = handler;
|
||||
scb->async_context = context;
|
||||
}
|
||||
|
||||
int
|
||||
deprecated_serial_fd (serial_t scb)
|
||||
{
|
||||
/* FIXME: should this output a warning that deprecated code is being
|
||||
called? */
|
||||
if (scb->fd < 0)
|
||||
{
|
||||
internal_error ("serial: FD not valid");
|
||||
}
|
||||
return scb->fd; /* sigh */
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
The connect command is #if 0 because I hadn't thought of an elegant
|
||||
@ -389,8 +514,7 @@ serial_close (scb, really_close)
|
||||
static serial_t tty_desc; /* Controlling terminal */
|
||||
|
||||
static void
|
||||
cleanup_tty (ttystate)
|
||||
serial_ttystate ttystate;
|
||||
cleanup_tty (serial_ttystate ttystate)
|
||||
{
|
||||
printf_unfiltered ("\r\n[Exiting connect mode]\r\n");
|
||||
SERIAL_SET_TTY_STATE (tty_desc, ttystate);
|
||||
@ -399,9 +523,7 @@ cleanup_tty (ttystate)
|
||||
}
|
||||
|
||||
static void
|
||||
connect_command (args, fromtty)
|
||||
char *args;
|
||||
int fromtty;
|
||||
connect_command (char *args, int fromtty)
|
||||
{
|
||||
int c;
|
||||
char cur_esc = 0;
|
||||
@ -493,21 +615,7 @@ connect_command (args, fromtty)
|
||||
#endif /* 0 */
|
||||
|
||||
void
|
||||
serial_printf (serial_t desc, const char *format,...)
|
||||
{
|
||||
va_list args;
|
||||
char *buf;
|
||||
va_start (args, format);
|
||||
|
||||
vasprintf (&buf, format, args);
|
||||
SERIAL_WRITE (desc, buf, strlen (buf));
|
||||
|
||||
free (buf);
|
||||
va_end (args);
|
||||
}
|
||||
|
||||
void
|
||||
_initialize_serial ()
|
||||
_initialize_serial (void)
|
||||
{
|
||||
#if 0
|
||||
add_com ("connect", class_obscure, connect_command,
|
||||
|
318
gdb/serial.h
318
gdb/serial.h
@ -1,5 +1,5 @@
|
||||
/* Remote serial support interface definitions for GDB, the GNU Debugger.
|
||||
Copyright 1992, 1993 Free Software Foundation, Inc.
|
||||
Copyright 1992, 1993, 1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
@ -21,9 +21,164 @@
|
||||
#ifndef SERIAL_H
|
||||
#define SERIAL_H
|
||||
|
||||
/* Terminal state pointer. This is specific to each type of interface. */
|
||||
/* For most routines, if a failure is indicated, then errno should be
|
||||
examined. */
|
||||
|
||||
typedef PTR serial_ttystate;
|
||||
/* Terminal state pointer. This is specific to each type of
|
||||
interface. */
|
||||
|
||||
typedef void *serial_ttystate;
|
||||
struct _serial_t;
|
||||
typedef struct _serial_t *serial_t;
|
||||
|
||||
/* Try to open NAME. Returns a new serial_t on success, NULL on
|
||||
failure. */
|
||||
|
||||
extern serial_t serial_open (const char *name);
|
||||
#define SERIAL_OPEN(NAME) serial_open(NAME)
|
||||
|
||||
/* Open a new serial stream using a file handle. */
|
||||
|
||||
extern serial_t serial_fdopen (const int fd);
|
||||
#define SERIAL_FDOPEN(FD) serial_fdopen(FD)
|
||||
|
||||
/* Push out all buffers, close the device and destroy SERIAL_T. */
|
||||
|
||||
extern void serial_close (serial_t);
|
||||
#define SERIAL_CLOSE(SERIAL_T) serial_close ((SERIAL_T))
|
||||
|
||||
/* Push out all buffers and destroy SERIAL_T without closing the
|
||||
device. */
|
||||
|
||||
extern void serial_un_fdopen (serial_t scb);
|
||||
#define SERIAL_UN_FDOPEN(SERIAL_T) serial_un_fdopen ((SERIAL_T))
|
||||
|
||||
/* Read one char from the serial device with TIMEOUT seconds to wait
|
||||
or -1 to wait forever. Use timeout of 0 to effect a poll. Returns
|
||||
char if ok, else one of the following codes. Note that all error
|
||||
codes are guaranteed to be < 0. */
|
||||
|
||||
#define SERIAL_ERROR -1 /* General error, see errno for details */
|
||||
#define SERIAL_TIMEOUT -2
|
||||
#define SERIAL_EOF -3
|
||||
|
||||
extern int serial_readchar (serial_t scb, int timeout);
|
||||
#define SERIAL_READCHAR(SERIAL_T, TIMEOUT) serial_readchar ((SERIAL_T), (TIMEOUT))
|
||||
|
||||
/* Write LEN chars from STRING to the port SERIAL_T. Returns 0 for
|
||||
success, non-zero for failure. */
|
||||
|
||||
extern int serial_write (serial_t scb, const char *str, int len);
|
||||
#define SERIAL_WRITE(SERIAL_T, STRING,LEN) serial_write (SERIAL_T, STRING, LEN)
|
||||
|
||||
/* Write a printf style string onto the serial port. */
|
||||
|
||||
extern void serial_printf (serial_t desc, const char *,...) ATTR_FORMAT (printf, 2, 3);
|
||||
|
||||
/* Allow pending output to drain. */
|
||||
|
||||
extern int serial_drain_output (serial_t);
|
||||
#define SERIAL_DRAIN_OUTPUT(SERIAL_T) serial_drain_output ((SERIAL_T))
|
||||
|
||||
/* Flush (discard) pending output. Might also flush input (if this
|
||||
system can't flush only output). */
|
||||
|
||||
extern int serial_flush_output (serial_t);
|
||||
#define SERIAL_FLUSH_OUTPUT(SERIAL_T) serial_flush_output ((SERIAL_T))
|
||||
|
||||
/* Flush pending input. Might also flush output (if this system can't
|
||||
flush only input). */
|
||||
|
||||
extern int serial_flush_input (serial_t);
|
||||
#define SERIAL_FLUSH_INPUT(SERIAL_T) serial_flush_input ((SERIAL_T))
|
||||
|
||||
/* Send a break between 0.25 and 0.5 seconds long. */
|
||||
|
||||
extern int serial_send_break (serial_t scb);
|
||||
#define SERIAL_SEND_BREAK(SERIAL_T) serial_send_break (SERIAL_T)
|
||||
|
||||
/* Turn the port into raw mode. */
|
||||
|
||||
extern void serial_raw (serial_t scb);
|
||||
#define SERIAL_RAW(SERIAL_T) serial_raw ((SERIAL_T))
|
||||
|
||||
/* Return a pointer to a newly malloc'd ttystate containing the state
|
||||
of the tty. */
|
||||
|
||||
extern serial_ttystate serial_get_tty_state (serial_t scb);
|
||||
#define SERIAL_GET_TTY_STATE(SERIAL_T) serial_get_tty_state ((SERIAL_T))
|
||||
|
||||
/* Set the state of the tty to TTYSTATE. The change is immediate.
|
||||
When changing to or from raw mode, input might be discarded.
|
||||
Returns 0 for success, negative value for error (in which case
|
||||
errno contains the error). */
|
||||
|
||||
extern int serial_set_tty_state (serial_t scb, serial_ttystate ttystate);
|
||||
#define SERIAL_SET_TTY_STATE(SERIAL_T, TTYSTATE) serial_set_tty_state ((SERIAL_T), (TTYSTATE))
|
||||
|
||||
/* printf_filtered a user-comprehensible description of ttystate on
|
||||
the specified STREAM. FIXME: At present this sends output to the
|
||||
default stream - GDB_STDOUT. */
|
||||
|
||||
extern void serial_print_tty_state (serial_t scb, serial_ttystate ttystate, struct gdb_file *);
|
||||
#define SERIAL_PRINT_TTY_STATE(SERIAL_T, TTYSTATE, STREAM) serial_print_tty_state ((SERIAL_T), (TTYSTATE), (STREAM))
|
||||
|
||||
/* Set the tty state to NEW_TTYSTATE, where OLD_TTYSTATE is the
|
||||
current state (generally obtained from a recent call to
|
||||
SERIAL_GET_TTY_STATE), but be careful not to discard any input.
|
||||
This means that we never switch in or out of raw mode, even if
|
||||
NEW_TTYSTATE specifies a switch. */
|
||||
|
||||
extern int serial_noflush_set_tty_state (serial_t scb, serial_ttystate new_ttystate, serial_ttystate old_ttystate);
|
||||
#define SERIAL_NOFLUSH_SET_TTY_STATE(SERIAL_T, NEW_TTYSTATE, OLD_TTYSTATE) \
|
||||
serial_noflush_set_tty_state ((SERIAL_T), (NEW_TTYSTATE), (OLD_TTYSTATE))
|
||||
|
||||
/* Set the baudrate to the decimal value supplied. Returns 0 for
|
||||
success, -1 for failure. */
|
||||
|
||||
extern int serial_setbaudrate (serial_t scb, int rate);
|
||||
#define SERIAL_SETBAUDRATE(SERIAL_T, RATE) serial_setbaudrate ((SERIAL_T), (RATE))
|
||||
|
||||
/* Set the number of stop bits to the value specified. Returns 0 for
|
||||
success, -1 for failure. */
|
||||
|
||||
#define SERIAL_1_STOPBITS 1
|
||||
#define SERIAL_1_AND_A_HALF_STOPBITS 2 /* 1.5 bits, snicker... */
|
||||
#define SERIAL_2_STOPBITS 3
|
||||
|
||||
extern int serial_setstopbits (serial_t scb, int num);
|
||||
#define SERIAL_SETSTOPBITS(SERIAL_T, NUM) serial_setstopbits ((SERIAL_T), (NUM))
|
||||
|
||||
/* Asynchronous serial interface: */
|
||||
|
||||
/* Can the serial device support asynchronous mode? */
|
||||
|
||||
extern int serial_can_async_p (serial_t scb);
|
||||
#define SERIAL_CAN_ASYNC_P(SERIAL_T) serial_can_async_p ((SERIAL_T))
|
||||
|
||||
/* Has the serial device been put in asynchronous mode? */
|
||||
|
||||
extern int serial_is_async_p (serial_t scb);
|
||||
#define SERIAL_IS_ASYNC_P(SERIAL_T) serial_is_async_p ((SERIAL_T))
|
||||
|
||||
/* For ASYNC enabled devices, register a callback and enable
|
||||
asynchronous mode. To disable asynchronous mode, register a NULL
|
||||
callback. */
|
||||
|
||||
typedef void (serial_event_ftype) (int error, void *context, int fd);
|
||||
extern void serial_async (serial_t scb, serial_event_ftype *handler, void *context);
|
||||
#define SERIAL_ASYNC(SERIAL_T, HANDLER, CONTEXT) serial_async ((SERIAL_T), (HANDLER), (CONTEXT))
|
||||
|
||||
/* Provide direct access to the underlying FD (if any) used to
|
||||
implement the serial device. This interface is clearly
|
||||
deprecated. Will call internal_error() if the operation isn't
|
||||
applicable to the current serial device. */
|
||||
|
||||
extern int deprecated_serial_fd (serial_t scb);
|
||||
#define DEPRECATED_SERIAL_FD(SERIAL_T) deprecated_serial_fd ((SERIAL_T))
|
||||
|
||||
|
||||
/* Details of an instance of a serial object */
|
||||
|
||||
struct _serial_t
|
||||
{
|
||||
@ -41,155 +196,44 @@ struct _serial_t
|
||||
char *name; /* The name of the device or host */
|
||||
struct _serial_t *next; /* Pointer to the next serial_t */
|
||||
int refcnt; /* Number of pointers to this block */
|
||||
void *async_context; /* Async event thread's context */
|
||||
serial_event_ftype *async_handler;/* Async event handler */
|
||||
};
|
||||
|
||||
typedef struct _serial_t *serial_t;
|
||||
|
||||
struct serial_ops
|
||||
{
|
||||
char *name;
|
||||
struct serial_ops *next;
|
||||
int (*open) PARAMS ((serial_t, const char *name));
|
||||
void (*close) PARAMS ((serial_t));
|
||||
int (*readchar) PARAMS ((serial_t, int timeout));
|
||||
int (*write) PARAMS ((serial_t, const char *str, int len));
|
||||
int (*open) (serial_t, const char *name);
|
||||
void (*close) (serial_t);
|
||||
int (*readchar) (serial_t, int timeout);
|
||||
int (*write) (serial_t, const char *str, int len);
|
||||
/* Discard pending output */
|
||||
int (*flush_output) PARAMS ((serial_t));
|
||||
int (*flush_output) (serial_t);
|
||||
/* Discard pending input */
|
||||
int (*flush_input) PARAMS ((serial_t));
|
||||
int (*send_break) PARAMS ((serial_t));
|
||||
void (*go_raw) PARAMS ((serial_t));
|
||||
serial_ttystate (*get_tty_state) PARAMS ((serial_t));
|
||||
int (*set_tty_state) PARAMS ((serial_t, serial_ttystate));
|
||||
void (*print_tty_state) PARAMS ((serial_t, serial_ttystate));
|
||||
int (*noflush_set_tty_state)
|
||||
PARAMS ((serial_t, serial_ttystate, serial_ttystate));
|
||||
int (*setbaudrate) PARAMS ((serial_t, int rate));
|
||||
int (*setstopbits) PARAMS ((serial_t, int num));
|
||||
int (*flush_input) (serial_t);
|
||||
int (*send_break) (serial_t);
|
||||
void (*go_raw) (serial_t);
|
||||
serial_ttystate (*get_tty_state) (serial_t);
|
||||
int (*set_tty_state) (serial_t, serial_ttystate);
|
||||
void (*print_tty_state) (serial_t, serial_ttystate, struct gdb_file *);
|
||||
int (*noflush_set_tty_state) (serial_t, serial_ttystate, serial_ttystate);
|
||||
int (*setbaudrate) (serial_t, int rate);
|
||||
int (*setstopbits) (serial_t, int num);
|
||||
/* Wait for output to drain */
|
||||
int (*drain_output) PARAMS ((serial_t));
|
||||
int (*drain_output) (serial_t);
|
||||
/* Change the serial device into/out of asynchronous mode, call
|
||||
the specified function when ever there is something
|
||||
interesting. */
|
||||
void (*async) (serial_t scb, int async_p);
|
||||
};
|
||||
|
||||
/* Add a new serial interface to the interface list */
|
||||
|
||||
void serial_add_interface PARAMS ((struct serial_ops * optable));
|
||||
|
||||
serial_t serial_open PARAMS ((const char *name));
|
||||
|
||||
serial_t serial_fdopen PARAMS ((const int fd));
|
||||
|
||||
/* For most routines, if a failure is indicated, then errno should be
|
||||
examined. */
|
||||
|
||||
/* Try to open NAME. Returns a new serial_t on success, NULL on failure.
|
||||
*/
|
||||
|
||||
#define SERIAL_OPEN(NAME) serial_open(NAME)
|
||||
|
||||
/* Open a new serial stream using a file handle. */
|
||||
|
||||
#define SERIAL_FDOPEN(FD) serial_fdopen(FD)
|
||||
|
||||
/* Allow pending output to drain. */
|
||||
|
||||
#define SERIAL_DRAIN_OUTPUT(SERIAL_T) \
|
||||
((SERIAL_T)->ops->drain_output((SERIAL_T)))
|
||||
|
||||
/* Flush (discard) pending output. Might also flush input (if this system can't flush
|
||||
only output). */
|
||||
|
||||
#define SERIAL_FLUSH_OUTPUT(SERIAL_T) \
|
||||
((SERIAL_T)->ops->flush_output((SERIAL_T)))
|
||||
|
||||
/* Flush pending input. Might also flush output (if this system can't flush
|
||||
only input). */
|
||||
|
||||
#define SERIAL_FLUSH_INPUT(SERIAL_T)\
|
||||
((*(SERIAL_T)->ops->flush_input) ((SERIAL_T)))
|
||||
|
||||
/* Send a break between 0.25 and 0.5 seconds long. */
|
||||
|
||||
extern int serial_send_break PARAMS ((serial_t scb));
|
||||
|
||||
#define SERIAL_SEND_BREAK(SERIAL_T) serial_send_break (SERIAL_T)
|
||||
|
||||
/* Turn the port into raw mode. */
|
||||
|
||||
#define SERIAL_RAW(SERIAL_T) (SERIAL_T)->ops->go_raw((SERIAL_T))
|
||||
|
||||
/* Return a pointer to a newly malloc'd ttystate containing the state
|
||||
of the tty. */
|
||||
#define SERIAL_GET_TTY_STATE(SERIAL_T) (SERIAL_T)->ops->get_tty_state((SERIAL_T))
|
||||
|
||||
/* Set the state of the tty to TTYSTATE. The change is immediate.
|
||||
When changing to or from raw mode, input might be discarded.
|
||||
Returns 0 for success, negative value for error (in which case errno
|
||||
contains the error). */
|
||||
#define SERIAL_SET_TTY_STATE(SERIAL_T, TTYSTATE) (SERIAL_T)->ops->set_tty_state((SERIAL_T), (TTYSTATE))
|
||||
|
||||
/* printf_filtered a user-comprehensible description of ttystate. */
|
||||
#define SERIAL_PRINT_TTY_STATE(SERIAL_T, TTYSTATE) \
|
||||
((*((SERIAL_T)->ops->print_tty_state)) ((SERIAL_T), (TTYSTATE)))
|
||||
|
||||
/* Set the tty state to NEW_TTYSTATE, where OLD_TTYSTATE is the
|
||||
current state (generally obtained from a recent call to
|
||||
SERIAL_GET_TTY_STATE), but be careful not to discard any input.
|
||||
This means that we never switch in or out of raw mode, even
|
||||
if NEW_TTYSTATE specifies a switch. */
|
||||
#define SERIAL_NOFLUSH_SET_TTY_STATE(SERIAL_T, NEW_TTYSTATE, OLD_TTYSTATE) \
|
||||
((*((SERIAL_T)->ops->noflush_set_tty_state)) \
|
||||
((SERIAL_T), (NEW_TTYSTATE), (OLD_TTYSTATE)))
|
||||
|
||||
/* Read one char from the serial device with TIMEOUT seconds to wait
|
||||
or -1 to wait forever. Use timeout of 0 to effect a poll. Returns
|
||||
char if ok, else one of the following codes. Note that all error
|
||||
codes are guaranteed to be < 0. */
|
||||
|
||||
#define SERIAL_ERROR -1 /* General error, see errno for details */
|
||||
#define SERIAL_TIMEOUT -2
|
||||
#define SERIAL_EOF -3
|
||||
|
||||
extern int serial_readchar PARAMS ((serial_t scb, int timeout));
|
||||
|
||||
#define SERIAL_READCHAR(SERIAL_T, TIMEOUT) serial_readchar (SERIAL_T, TIMEOUT)
|
||||
|
||||
/* Set the baudrate to the decimal value supplied. Returns 0 for success,
|
||||
-1 for failure. */
|
||||
|
||||
#define SERIAL_SETBAUDRATE(SERIAL_T, RATE) ((SERIAL_T)->ops->setbaudrate((SERIAL_T), RATE))
|
||||
|
||||
/* Set the number of stop bits to the value specified. Returns 0 for success,
|
||||
-1 for failure. */
|
||||
|
||||
#define SERIAL_1_STOPBITS 1
|
||||
#define SERIAL_1_AND_A_HALF_STOPBITS 2 /* 1.5 bits, snicker... */
|
||||
#define SERIAL_2_STOPBITS 3
|
||||
|
||||
#define SERIAL_SETSTOPBITS(SERIAL_T, NUM) ((SERIAL_T)->ops->setstopbits((SERIAL_T), NUM))
|
||||
|
||||
/* Write LEN chars from STRING to the port SERIAL_T. Returns 0 for
|
||||
success, non-zero for failure. */
|
||||
|
||||
extern int serial_write PARAMS ((serial_t scb, const char *str, int len));
|
||||
|
||||
#define SERIAL_WRITE(SERIAL_T, STRING,LEN) serial_write (SERIAL_T, STRING, LEN)
|
||||
|
||||
/* Push out all buffers, close the device and destroy SERIAL_T. */
|
||||
|
||||
extern void serial_close PARAMS ((serial_t, int));
|
||||
|
||||
#define SERIAL_CLOSE(SERIAL_T) serial_close(SERIAL_T, 1)
|
||||
|
||||
/* Push out all buffers and destroy SERIAL_T without closing the device. */
|
||||
|
||||
#define SERIAL_UN_FDOPEN(SERIAL_T) serial_close(SERIAL_T, 0)
|
||||
|
||||
extern void serial_printf
|
||||
PARAMS ((serial_t desc, const char *,...))
|
||||
ATTR_FORMAT (printf, 2, 3);
|
||||
extern void serial_add_interface (struct serial_ops * optable);
|
||||
|
||||
/* File in which to record the remote debugging session */
|
||||
|
||||
extern void serial_log_command PARAMS ((const char *));
|
||||
extern void serial_log_command (const char *);
|
||||
|
||||
#endif /* SERIAL_H */
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "expression.h"
|
||||
#include "language.h"
|
||||
#include "command.h"
|
||||
#include "source.h"
|
||||
#include "gdbcmd.h"
|
||||
#include "frame.h"
|
||||
#include "value.h"
|
||||
@ -58,12 +59,6 @@
|
||||
|
||||
#endif /* ! defined (CRLF_SOURCE_FILES) */
|
||||
|
||||
/* Forward declarations */
|
||||
|
||||
int open_source_file PARAMS ((struct symtab *));
|
||||
|
||||
void find_source_lines PARAMS ((struct symtab *, int));
|
||||
|
||||
/* Prototypes for exported functions. */
|
||||
|
||||
void _initialize_source PARAMS ((void));
|
||||
|
34
gdb/source.h
Normal file
34
gdb/source.h
Normal file
@ -0,0 +1,34 @@
|
||||
/* List lines of source files for GDB, the GNU debugger.
|
||||
Copyright 1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef SOURCE_H
|
||||
#define SOURCE_H
|
||||
|
||||
/* Open a source file given a symtab S. Returns a file descriptor or
|
||||
negative number for error. */
|
||||
extern int open_source_file (struct symtab *s);
|
||||
|
||||
/* Create and initialize the table S->line_charpos that records the
|
||||
positions of the lines in the source file, which is assumed to be
|
||||
open on descriptor DESC. All set S->nlines to the number of such
|
||||
lines. */
|
||||
extern void find_source_lines (struct symtab *s, int desc);
|
||||
|
||||
#endif
|
14
gdb/symtab.c
14
gdb/symtab.c
@ -396,11 +396,7 @@ find_pc_sect_psymtab (pc, section)
|
||||
|
||||
ALL_PSYMTABS (objfile, pst)
|
||||
{
|
||||
#if defined(HPUXHPPA)
|
||||
if (pc >= pst->textlow && pc <= pst->texthigh)
|
||||
#else
|
||||
if (pc >= pst->textlow && pc < pst->texthigh)
|
||||
#endif
|
||||
{
|
||||
struct minimal_symbol *msymbol;
|
||||
struct partial_symtab *tpst;
|
||||
@ -419,11 +415,7 @@ find_pc_sect_psymtab (pc, section)
|
||||
|
||||
for (tpst = pst; tpst != NULL; tpst = tpst->next)
|
||||
{
|
||||
#if defined(HPUXHPPA)
|
||||
if (pc >= tpst->textlow && pc <= tpst->texthigh)
|
||||
#else
|
||||
if (pc >= tpst->textlow && pc < tpst->texthigh)
|
||||
#endif
|
||||
{
|
||||
struct partial_symbol *p;
|
||||
|
||||
@ -1437,11 +1429,7 @@ find_pc_sect_symtab (pc, section)
|
||||
b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
|
||||
|
||||
if (BLOCK_START (b) <= pc
|
||||
#if defined(HPUXHPPA)
|
||||
&& BLOCK_END (b) >= pc
|
||||
#else
|
||||
&& BLOCK_END (b) > pc
|
||||
#endif
|
||||
&& (distance == 0
|
||||
|| BLOCK_END (b) - BLOCK_START (b) < distance))
|
||||
{
|
||||
@ -2578,7 +2566,7 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
|
||||
&& strchr (gdb_completer_quote_characters, **argptr) != NULL);
|
||||
|
||||
has_parens = ((pp = strchr (*argptr, '(')) != NULL
|
||||
&& (pp = strchr (pp, ')')) != NULL);
|
||||
&& (pp = strrchr (pp, ')')) != NULL);
|
||||
|
||||
/* Now that we're safely past the has_parens check,
|
||||
* put back " if (condition)" so outer layers can see it
|
||||
|
@ -1219,7 +1219,7 @@ extern struct minimal_symbol *prim_record_minimal_symbol_and_info
|
||||
|
||||
#ifdef SOFUN_ADDRESS_MAYBE_MISSING
|
||||
extern CORE_ADDR find_stab_function_addr PARAMS ((char *,
|
||||
struct partial_symtab *,
|
||||
char *,
|
||||
struct objfile *));
|
||||
#endif
|
||||
|
||||
|
@ -1,3 +1,24 @@
|
||||
1999-09-18 Jim Blandy <jimb@cris.red-bean.com>
|
||||
|
||||
* gdb.base/break.exp: Code locations are in hex, don't forget!
|
||||
(For HP-UX.)
|
||||
|
||||
1999-09-17 Stan Shebs <shebs@andros.cygnus.com>
|
||||
|
||||
* condbreak.exp: Use break.c as test program.
|
||||
* condbreak.c: Remove, redundant with break.c.
|
||||
|
||||
1999-09-15 Stan Shebs <shebs@andros.cygnus.com>
|
||||
|
||||
* config/monitor.exp (gdb_target_monitor): Disable X- and
|
||||
Z-packets if the target needs it.
|
||||
|
||||
1999-09-13 James Ingham <jingham@leda.cygnus.com>
|
||||
|
||||
* gdb.c++/overload.exp: Added tests for listing overloaded
|
||||
functions with function pointers in the arg, explicitly calling
|
||||
out the version you want.
|
||||
|
||||
1999-09-09 Stan Shebs <shebs@andros.cygnus.com>
|
||||
|
||||
* long_long.exp: Add variations of test cases that work for
|
||||
|
@ -38,6 +38,12 @@ proc gdb_target_monitor { exec_file } {
|
||||
if [target_info exists binarydownload] {
|
||||
gdb_test "set remotebinarydownload [target_info binarydownload]" "" ""
|
||||
}
|
||||
if { [ target_info exists disable_x_packet ] } {
|
||||
gdb_test "set remote X-packet disable" ""
|
||||
}
|
||||
if { [ target_info exists disable_z_packet ] } {
|
||||
gdb_test "set remote Z-packet disable" ""
|
||||
}
|
||||
if [target_info exists gdb_serial] {
|
||||
set serialport "[target_info gdb_serial]";
|
||||
} elseif [target_info exists netport] {
|
||||
|
@ -556,12 +556,13 @@ gdb_expect {
|
||||
# As long as we're stopped (breakpointed) in a called function,
|
||||
# verify that we can successfully backtrace & such from here.
|
||||
#
|
||||
|
||||
if [istarget "hppa*-*-hpux*"] then {
|
||||
send_gdb "bt\n"
|
||||
gdb_expect {
|
||||
-re "#0\[ \t\]*0x\[0-9\]* in marker2.*:4\[49\]\r\n#1.*_sr4export.*$gdb_prompt $"\
|
||||
-re "#0\[ \t\]*$hex in marker2.*:4\[49\]\r\n#1.*_sr4export.*$gdb_prompt $"\
|
||||
{pass "backtrace while in called function"}
|
||||
-re "#0\[ \t\]*0x\[0-9\]* in marker2.*:4\[49\]\r\n#1.*function called from gdb.*$gdb_prompt $"\
|
||||
-re "#0\[ \t\]*$hex in marker2.*:4\[49\]\r\n#1.*function called from gdb.*$gdb_prompt $"\
|
||||
|
||||
{pass "backtrace while in called function"}
|
||||
-re "$gdb_prompt $"\
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright (C) 1997, 1998 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@ -21,8 +21,6 @@
|
||||
# Purpose is to test conditional breakpoints.
|
||||
# Modeled after "break.exp".
|
||||
|
||||
|
||||
|
||||
if $tracelevel then {
|
||||
strace $tracelevel
|
||||
}
|
||||
@ -35,7 +33,7 @@ global usestubs
|
||||
set prms_id 0
|
||||
set bug_id 0
|
||||
|
||||
set testfile "condbreak"
|
||||
set testfile "break"
|
||||
set srcfile ${testfile}.c
|
||||
set binfile ${objdir}/${subdir}/${testfile}
|
||||
|
||||
|
@ -24,6 +24,10 @@ int overload1arg (unsigned long);
|
||||
int overload1arg (float);
|
||||
int overload1arg (double);
|
||||
|
||||
int overloadfnarg (void);
|
||||
int overloadfnarg (int);
|
||||
int overloadfnarg (int, int (*) (int));
|
||||
|
||||
int overloadargs (int a1);
|
||||
int overloadargs (int a1, int a2);
|
||||
int overloadargs (int a1, int a2, int a3);
|
||||
@ -94,6 +98,12 @@ int foo::overload1arg (unsigned long arg) { arg = 0; return 10;}
|
||||
int foo::overload1arg (float arg) { arg = 0; return 11;}
|
||||
int foo::overload1arg (double arg) { arg = 0; return 12;}
|
||||
|
||||
/* Test to see that we can explicitly request overloaded functions
|
||||
with function pointers in the prototype. */
|
||||
|
||||
int foo::overloadfnarg (void) { return ifoo * 20; }
|
||||
int foo::overloadfnarg (int arg) { arg = 0; return 13;}
|
||||
int foo::overloadfnarg (int arg, int (*foo) (int)) { return foo(arg); }
|
||||
|
||||
/* Some functions to test overloading by varying argument count. */
|
||||
|
||||
|
@ -397,3 +397,25 @@ gdb_expect {
|
||||
-re ".*$gdb_prompt $" { fail "print call overloaded func double arg" }
|
||||
timeout { fail "(timeout) print call overloaded func double arg" }
|
||||
}
|
||||
|
||||
# Now some tests to see if we can list overloaded functions properly:
|
||||
|
||||
send_gdb "set listsize 1\n"
|
||||
gdb_expect -re ".*$gdb_prompt $"
|
||||
|
||||
gdb_test "list foo::overloadfnarg(void)"\
|
||||
".*int foo::overloadfnarg.*\\(void\\).*" \
|
||||
"print overloaded function with no args"
|
||||
|
||||
gdb_test "list foo::overloadfnarg(int)"\
|
||||
"int foo::overloadfnarg.*\\(int arg\\).*" \
|
||||
"print overloaded function with int arg"
|
||||
|
||||
gdb_test "list foo::overloadfnarg(int, int (*)(int))" \
|
||||
"int foo::overloadfnarg.*\\(int arg, int \\(\\*foo\\) \\(int\\)\\).*" \
|
||||
"print overloaded function with function ptr args"
|
||||
|
||||
# This one crashes GDB. Don't know why yet.
|
||||
gdb_test "list \"foo::overloadfnarg(int, int (*)(int))\"" \
|
||||
"int foo::overloadfnarg.*\\(int arg, int \\(\\*foo\\) \\(int\\)\\).*" \
|
||||
"print overloaded function with function ptr args - quotes around argument"
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "event-loop.h"
|
||||
#include "event-top.h"
|
||||
#include "gdb_string.h"
|
||||
#include "gdb_stat.h"
|
||||
#include <ctype.h>
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "gdb_string.h"
|
||||
#include "inferior.h"
|
||||
#include "tracepoint.h"
|
||||
#include "remote.h"
|
||||
|
||||
#include "ax.h"
|
||||
#include "ax-gdb.h"
|
||||
@ -193,13 +194,6 @@ trace_error (buf)
|
||||
}
|
||||
}
|
||||
|
||||
/* Entry points into remote.c (FIXME: move this interface down to tgt vector)
|
||||
*/
|
||||
|
||||
extern int putpkt PARAMS ((char *));
|
||||
extern void getpkt PARAMS ((char *, int));
|
||||
extern void remote_console_output PARAMS ((char *));
|
||||
|
||||
/* Utility: wait for reply from stub, while accepting "O" packets */
|
||||
static char *
|
||||
remote_get_noisy_reply (buf)
|
||||
|
@ -1,3 +1,8 @@
|
||||
Fri Sep 17 19:34:38 1999 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* tuiSource.c: Include "source.h".
|
||||
(open_source_file, find_source_lines): Delete declarations.
|
||||
|
||||
1999-01-26 Jason Molenda (jsm@bugshack.cygnus.com)
|
||||
|
||||
* tui.h: Include stdarg.h instead of varargs.h if we're on an ISO Cish
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "symtab.h"
|
||||
#include "frame.h"
|
||||
#include "breakpoint.h"
|
||||
#include "source.h"
|
||||
|
||||
#include "tui.h"
|
||||
#include "tuiData.h"
|
||||
@ -16,13 +17,6 @@
|
||||
#include "tuiSource.h"
|
||||
|
||||
|
||||
/*****************************************
|
||||
** EXTERNAL FUNCTION DECLS **
|
||||
******************************************/
|
||||
|
||||
extern int open_source_file PARAMS ((struct symtab *));
|
||||
extern void find_source_lines PARAMS ((struct symtab *, int));
|
||||
|
||||
/*****************************************
|
||||
** EXTERNAL DATA DECLS **
|
||||
******************************************/
|
||||
|
17
gdb/utils.c
17
gdb/utils.c
@ -22,6 +22,7 @@
|
||||
#include <ctype.h>
|
||||
#include "gdb_string.h"
|
||||
#include "event-loop.h"
|
||||
#include "event-top.h"
|
||||
|
||||
#ifdef HAVE_CURSES_H
|
||||
#include <curses.h>
|
||||
@ -393,6 +394,22 @@ do_all_continuations ()
|
||||
free (continuation_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
/* Walk down the cmd_continuation list, and get rid of all the
|
||||
continuations. */
|
||||
void
|
||||
discard_all_continuations ()
|
||||
{
|
||||
struct continuation *continuation_ptr;
|
||||
|
||||
while (cmd_continuation)
|
||||
{
|
||||
continuation_ptr = cmd_continuation;
|
||||
cmd_continuation = continuation_ptr->next;
|
||||
free (continuation_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Print a warning message. Way to use this is to call warning_begin,
|
||||
|
@ -61,10 +61,6 @@ static CORE_ADDR value_push PARAMS ((CORE_ADDR, value_ptr));
|
||||
static value_ptr search_struct_field PARAMS ((char *, value_ptr, int,
|
||||
struct type *, int));
|
||||
|
||||
static value_ptr search_struct_field_aux PARAMS ((char *, value_ptr, int,
|
||||
struct type *, int, int *, char *,
|
||||
struct type **));
|
||||
|
||||
static value_ptr search_struct_method PARAMS ((char *, value_ptr *,
|
||||
value_ptr *,
|
||||
int, int *, struct type *));
|
||||
@ -970,7 +966,6 @@ value_ind (arg1)
|
||||
{
|
||||
struct type *base_type;
|
||||
value_ptr arg2;
|
||||
value_ptr real_val;
|
||||
|
||||
COERCE_ARRAY (arg1);
|
||||
|
||||
@ -2544,7 +2539,6 @@ value_find_oload_method_list (argp, method, offset, static_memfuncp, num_fns, ba
|
||||
int *boffset;
|
||||
{
|
||||
struct type *t;
|
||||
value_ptr v;
|
||||
|
||||
t = check_typedef (VALUE_TYPE (*argp));
|
||||
|
||||
@ -2677,8 +2671,6 @@ find_overload_match (arg_types, nargs, name, method, lax, obj, fsym, valp, symp,
|
||||
/* Consider each candidate in turn */
|
||||
for (ix = 0; ix < num_fns; ix++)
|
||||
{
|
||||
int jj;
|
||||
|
||||
/* Number of parameters for current candidate */
|
||||
nparms = method ? TYPE_NFIELDS (fns_ptr[ix].type)
|
||||
: TYPE_NFIELDS (SYMBOL_TYPE (oload_syms[ix]));
|
||||
|
@ -1,3 +1,20 @@
|
||||
Mon Sep 20 21:44:06 1999 Geoffrey Keating <geoffk@cygnus.com>
|
||||
|
||||
* sim-fpu.c (i2fpu): Keep the guard bits sticky when converting
|
||||
large values.
|
||||
|
||||
Wed Sep 15 14:12:37 1999 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* hw-tree.c, hw-properties.c, hw-instances.c: Include "sim-io.h".
|
||||
|
||||
Tue Sep 14 14:15:47 1999 Dave Brolley <brolley@cygnus.com>
|
||||
|
||||
* cgen-par.h (CGEN_BI_WRITE): New enumerator.
|
||||
(bi_write): New union element.
|
||||
(sim_queue_bi_write): New function.
|
||||
* cgen-par.c (sim_queue_bi_write): New function.
|
||||
(cgen_write_queue_element_execute): Handle CGEN_BI_WRITE.
|
||||
|
||||
Thu Sep 2 18:15:53 1999 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* configure: Regenerated to track ../common/aclocal.m4 changes.
|
||||
|
@ -399,7 +399,6 @@ sim-fpu.o: $(srccom)/sim-fpu.c $(sim-fpu_h) \
|
||||
$(SIM_EXTRA_DEPS)
|
||||
$(CC) -c $(srccom)/sim-fpu.c $(ALL_CFLAGS)
|
||||
|
||||
|
||||
sim-hload.o: $(srccom)/sim-hload.c $(sim-assert_h) \
|
||||
$(srcroot)/include/remote-sim.h \
|
||||
$(SIM_EXTRA_DEPS)
|
||||
|
@ -24,6 +24,15 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
|
||||
/* Functions required by the cgen interface. These functions add various
|
||||
kinds of writes to the write queue. */
|
||||
void sim_queue_bi_write (SIM_CPU *cpu, BI *target, BI value)
|
||||
{
|
||||
CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
|
||||
CGEN_WRITE_QUEUE_ELEMENT *element = CGEN_WRITE_QUEUE_NEXT (q);
|
||||
element->kind = CGEN_BI_WRITE;
|
||||
element->kinds.bi_write.target = target;
|
||||
element->kinds.bi_write.value = value;
|
||||
}
|
||||
|
||||
void sim_queue_qi_write (SIM_CPU *cpu, UQI *target, UQI value)
|
||||
{
|
||||
CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (cpu);
|
||||
@ -138,6 +147,9 @@ cgen_write_queue_element_execute (SIM_CPU *cpu, CGEN_WRITE_QUEUE_ELEMENT *item)
|
||||
IADDR pc;
|
||||
switch (CGEN_WRITE_QUEUE_ELEMENT_KIND (item))
|
||||
{
|
||||
case CGEN_BI_WRITE:
|
||||
*item->kinds.bi_write.target = item->kinds.bi_write.value;
|
||||
break;
|
||||
case CGEN_QI_WRITE:
|
||||
*item->kinds.qi_write.target = item->kinds.qi_write.value;
|
||||
break;
|
||||
|
@ -23,7 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
|
||||
/* Kinds of writes stored on the write queue. */
|
||||
enum cgen_write_queue_kind {
|
||||
CGEN_QI_WRITE, CGEN_SI_WRITE, CGEN_SF_WRITE,
|
||||
CGEN_BI_WRITE, CGEN_QI_WRITE, CGEN_SI_WRITE, CGEN_SF_WRITE,
|
||||
CGEN_PC_WRITE,
|
||||
CGEN_FN_SI_WRITE, CGEN_FN_DI_WRITE, CGEN_FN_DF_WRITE,
|
||||
CGEN_MEM_QI_WRITE, CGEN_MEM_HI_WRITE, CGEN_MEM_SI_WRITE,
|
||||
@ -34,6 +34,10 @@ enum cgen_write_queue_kind {
|
||||
typedef struct {
|
||||
enum cgen_write_queue_kind kind; /* Used to select union member below. */
|
||||
union {
|
||||
struct {
|
||||
BI *target;
|
||||
BI value;
|
||||
} bi_write;
|
||||
struct {
|
||||
UQI *target;
|
||||
QI value;
|
||||
@ -107,6 +111,7 @@ typedef struct {
|
||||
extern CGEN_WRITE_QUEUE_ELEMENT *cgen_write_queue_overflow (CGEN_WRITE_QUEUE *);
|
||||
|
||||
/* Functions for queuing writes. Used by semantic code. */
|
||||
extern void sim_queue_bi_write (SIM_CPU *, BI *, BI);
|
||||
extern void sim_queue_qi_write (SIM_CPU *, UQI *, UQI);
|
||||
extern void sim_queue_si_write (SIM_CPU *, SI *, SI);
|
||||
extern void sim_queue_sf_write (SIM_CPU *, SI *, SF);
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "hw-main.h"
|
||||
#include "hw-base.h"
|
||||
|
||||
#include "sim-io.h"
|
||||
#include "sim-assert.h"
|
||||
|
||||
struct hw_instance_data {
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "hw-main.h"
|
||||
#include "hw-base.h"
|
||||
|
||||
#include "sim-io.h"
|
||||
#include "sim-assert.h"
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "hw-base.h"
|
||||
#include "hw-tree.h"
|
||||
|
||||
#include "sim-io.h"
|
||||
#include "sim-assert.h"
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
|
@ -236,7 +236,6 @@ typedef struct {
|
||||
#define STATE_HW(sd) ((sd)->base.hw)
|
||||
#endif
|
||||
|
||||
|
||||
/* Should image loads be performed using the LMA or VMA? Older
|
||||
simulators use the VMA while newer simulators prefer the LMA. */
|
||||
int load_at_lma_p;
|
||||
|
@ -541,7 +541,7 @@ i2fpu (sim_fpu *f, signed64 i, int is_64bit)
|
||||
{
|
||||
do
|
||||
{
|
||||
f->fraction >>= 1;
|
||||
f->fraction = (f->fraction >> 1) | (f->fraction & 1);
|
||||
f->normal_exp += 1;
|
||||
}
|
||||
while (f->fraction >= IMPLICIT_2);
|
||||
|
64
sim/configure
vendored
64
sim/configure
vendored
@ -13,8 +13,6 @@ ac_default_prefix=/usr/local
|
||||
# Any additions from configure.in:
|
||||
ac_help="$ac_help
|
||||
--enable-sim "
|
||||
ac_help="$ac_help
|
||||
"
|
||||
|
||||
# Initialize some variables set by options.
|
||||
# The variables have the same names as the options, with
|
||||
@ -529,7 +527,7 @@ fi
|
||||
# Extract the first word of "gcc", so it can be a program name with args.
|
||||
set dummy gcc; ac_word=$2
|
||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||
echo "configure:533: checking for $ac_word" >&5
|
||||
echo "configure:531: checking for $ac_word" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -559,7 +557,7 @@ if test -z "$CC"; then
|
||||
# Extract the first word of "cc", so it can be a program name with args.
|
||||
set dummy cc; ac_word=$2
|
||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||
echo "configure:563: checking for $ac_word" >&5
|
||||
echo "configure:561: checking for $ac_word" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -610,7 +608,7 @@ fi
|
||||
# Extract the first word of "cl", so it can be a program name with args.
|
||||
set dummy cl; ac_word=$2
|
||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||
echo "configure:614: checking for $ac_word" >&5
|
||||
echo "configure:612: checking for $ac_word" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -642,7 +640,7 @@ fi
|
||||
fi
|
||||
|
||||
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
|
||||
echo "configure:646: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
|
||||
echo "configure:644: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
|
||||
|
||||
ac_ext=c
|
||||
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
|
||||
@ -653,12 +651,12 @@ cross_compiling=$ac_cv_prog_cc_cross
|
||||
|
||||
cat > conftest.$ac_ext << EOF
|
||||
|
||||
#line 657 "configure"
|
||||
#line 655 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
main(){return(0);}
|
||||
EOF
|
||||
if { (eval echo configure:662: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
|
||||
if { (eval echo configure:660: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
|
||||
ac_cv_prog_cc_works=yes
|
||||
# If we can't run a trivial program, we are probably using a cross compiler.
|
||||
if (./conftest; exit) 2>/dev/null; then
|
||||
@ -684,12 +682,12 @@ if test $ac_cv_prog_cc_works = no; then
|
||||
{ echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
|
||||
fi
|
||||
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
|
||||
echo "configure:688: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
|
||||
echo "configure:686: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
|
||||
echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
|
||||
cross_compiling=$ac_cv_prog_cc_cross
|
||||
|
||||
echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
|
||||
echo "configure:693: checking whether we are using GNU C" >&5
|
||||
echo "configure:691: checking whether we are using GNU C" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -698,7 +696,7 @@ else
|
||||
yes;
|
||||
#endif
|
||||
EOF
|
||||
if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:702: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
|
||||
if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:700: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
|
||||
ac_cv_prog_gcc=yes
|
||||
else
|
||||
ac_cv_prog_gcc=no
|
||||
@ -717,7 +715,7 @@ ac_test_CFLAGS="${CFLAGS+set}"
|
||||
ac_save_CFLAGS="$CFLAGS"
|
||||
CFLAGS=
|
||||
echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
|
||||
echo "configure:721: checking whether ${CC-cc} accepts -g" >&5
|
||||
echo "configure:719: checking whether ${CC-cc} accepts -g" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -779,7 +777,7 @@ ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
|
||||
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
|
||||
# ./install, which can be erroneously created by make from ./install.sh.
|
||||
echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
|
||||
echo "configure:783: checking for a BSD compatible install" >&5
|
||||
echo "configure:781: checking for a BSD compatible install" >&5
|
||||
if test -z "$INSTALL"; then
|
||||
if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
@ -838,7 +836,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
|
||||
fi
|
||||
|
||||
echo $ac_n "checking host system type""... $ac_c" 1>&6
|
||||
echo "configure:842: checking host system type" >&5
|
||||
echo "configure:840: checking host system type" >&5
|
||||
|
||||
host_alias=$host
|
||||
case "$host_alias" in
|
||||
@ -859,7 +857,7 @@ host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
|
||||
echo "$ac_t""$host" 1>&6
|
||||
|
||||
echo $ac_n "checking build system type""... $ac_c" 1>&6
|
||||
echo "configure:863: checking build system type" >&5
|
||||
echo "configure:861: checking build system type" >&5
|
||||
|
||||
build_alias=$build
|
||||
case "$build_alias" in
|
||||
@ -885,7 +883,7 @@ fi
|
||||
# Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
|
||||
set dummy ${ac_tool_prefix}ar; ac_word=$2
|
||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||
echo "configure:889: checking for $ac_word" >&5
|
||||
echo "configure:887: checking for $ac_word" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -917,7 +915,7 @@ fi
|
||||
# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
|
||||
set dummy ${ac_tool_prefix}ranlib; ac_word=$2
|
||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||
echo "configure:921: checking for $ac_word" >&5
|
||||
echo "configure:919: checking for $ac_word" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -949,7 +947,7 @@ if test -n "$ac_tool_prefix"; then
|
||||
# Extract the first word of "ranlib", so it can be a program name with args.
|
||||
set dummy ranlib; ac_word=$2
|
||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||
echo "configure:953: checking for $ac_word" >&5
|
||||
echo "configure:951: checking for $ac_word" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -1029,7 +1027,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
|
||||
fi
|
||||
|
||||
echo $ac_n "checking host system type""... $ac_c" 1>&6
|
||||
echo "configure:1033: checking host system type" >&5
|
||||
echo "configure:1031: checking host system type" >&5
|
||||
|
||||
host_alias=$host
|
||||
case "$host_alias" in
|
||||
@ -1050,7 +1048,7 @@ host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
|
||||
echo "$ac_t""$host" 1>&6
|
||||
|
||||
echo $ac_n "checking target system type""... $ac_c" 1>&6
|
||||
echo "configure:1054: checking target system type" >&5
|
||||
echo "configure:1052: checking target system type" >&5
|
||||
|
||||
target_alias=$target
|
||||
case "$target_alias" in
|
||||
@ -1068,7 +1066,7 @@ target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
|
||||
echo "$ac_t""$target" 1>&6
|
||||
|
||||
echo $ac_n "checking build system type""... $ac_c" 1>&6
|
||||
echo "configure:1072: checking build system type" >&5
|
||||
echo "configure:1070: checking build system type" >&5
|
||||
|
||||
build_alias=$build
|
||||
case "$build_alias" in
|
||||
@ -1112,7 +1110,7 @@ test "$program_transform_name" = "" && program_transform_name="s,x,x,"
|
||||
# Extract the first word of "gcc", so it can be a program name with args.
|
||||
set dummy gcc; ac_word=$2
|
||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||
echo "configure:1116: checking for $ac_word" >&5
|
||||
echo "configure:1114: checking for $ac_word" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -1142,7 +1140,7 @@ if test -z "$CC"; then
|
||||
# Extract the first word of "cc", so it can be a program name with args.
|
||||
set dummy cc; ac_word=$2
|
||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||
echo "configure:1146: checking for $ac_word" >&5
|
||||
echo "configure:1144: checking for $ac_word" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -1193,7 +1191,7 @@ fi
|
||||
# Extract the first word of "cl", so it can be a program name with args.
|
||||
set dummy cl; ac_word=$2
|
||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||
echo "configure:1197: checking for $ac_word" >&5
|
||||
echo "configure:1195: checking for $ac_word" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -1225,7 +1223,7 @@ fi
|
||||
fi
|
||||
|
||||
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
|
||||
echo "configure:1229: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
|
||||
echo "configure:1227: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
|
||||
|
||||
ac_ext=c
|
||||
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
|
||||
@ -1236,12 +1234,12 @@ cross_compiling=$ac_cv_prog_cc_cross
|
||||
|
||||
cat > conftest.$ac_ext << EOF
|
||||
|
||||
#line 1240 "configure"
|
||||
#line 1238 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
main(){return(0);}
|
||||
EOF
|
||||
if { (eval echo configure:1245: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
|
||||
if { (eval echo configure:1243: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
|
||||
ac_cv_prog_cc_works=yes
|
||||
# If we can't run a trivial program, we are probably using a cross compiler.
|
||||
if (./conftest; exit) 2>/dev/null; then
|
||||
@ -1267,12 +1265,12 @@ if test $ac_cv_prog_cc_works = no; then
|
||||
{ echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
|
||||
fi
|
||||
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
|
||||
echo "configure:1271: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
|
||||
echo "configure:1269: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
|
||||
echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
|
||||
cross_compiling=$ac_cv_prog_cc_cross
|
||||
|
||||
echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
|
||||
echo "configure:1276: checking whether we are using GNU C" >&5
|
||||
echo "configure:1274: checking whether we are using GNU C" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -1281,7 +1279,7 @@ else
|
||||
yes;
|
||||
#endif
|
||||
EOF
|
||||
if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1285: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
|
||||
if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1283: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
|
||||
ac_cv_prog_gcc=yes
|
||||
else
|
||||
ac_cv_prog_gcc=no
|
||||
@ -1300,7 +1298,7 @@ ac_test_CFLAGS="${CFLAGS+set}"
|
||||
ac_save_CFLAGS="$CFLAGS"
|
||||
CFLAGS=
|
||||
echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
|
||||
echo "configure:1304: checking whether ${CC-cc} accepts -g" >&5
|
||||
echo "configure:1302: checking whether ${CC-cc} accepts -g" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -1338,7 +1336,7 @@ AR=${AR-ar}
|
||||
# Extract the first word of "ranlib", so it can be a program name with args.
|
||||
set dummy ranlib; ac_word=$2
|
||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||
echo "configure:1342: checking for $ac_word" >&5
|
||||
echo "configure:1340: checking for $ac_word" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -1483,8 +1481,6 @@ case "${target}" in
|
||||
esac
|
||||
|
||||
|
||||
|
||||
|
||||
# Is there a testsuite directory for the target?
|
||||
testdir=`echo ${target} | sed -e 's/-.*-/-/'`
|
||||
if test -r ${srcdir}/testsuite/${testdir}/configure ; then
|
||||
|
@ -131,8 +131,6 @@ case "${target}" in
|
||||
esac
|
||||
|
||||
|
||||
|
||||
|
||||
# Is there a testsuite directory for the target?
|
||||
testdir=`echo ${target} | sed -e 's/-.*-/-/'`
|
||||
if test -r ${srcdir}/testsuite/${testdir}/configure ; then
|
||||
|
@ -1,3 +1,7 @@
|
||||
1999-09-14 Nick Clifton <nickc@cygnus.com>
|
||||
|
||||
* simops.c: Disable setting of DM bit in PSW.
|
||||
|
||||
Wed Sep 8 19:34:55 MDT 1999 Diego Novillo <dnovillo@cygnus.com>
|
||||
|
||||
* simops.c (op_types): Added new memory indirect type OP_MEMREF3.
|
||||
|
@ -48,7 +48,6 @@ enum {
|
||||
PSW_MASK = (PSW_SM_BIT
|
||||
| PSW_EA_BIT
|
||||
| PSW_DB_BIT
|
||||
| PSW_DM_BIT
|
||||
| PSW_IE_BIT
|
||||
| PSW_RP_BIT
|
||||
| PSW_MD_BIT
|
||||
@ -1097,7 +1096,7 @@ OP_5F20 ()
|
||||
trace_input ("dbt", OP_VOID, OP_VOID, OP_VOID);
|
||||
SET_DPC (PC + 1);
|
||||
SET_DPSW (PSW);
|
||||
SET_PSW (PSW_DM_BIT | (PSW & (PSW_F0_BIT | PSW_F1_BIT | PSW_C_BIT)));
|
||||
SET_PSW (PSW & (PSW_F0_BIT | PSW_F1_BIT | PSW_C_BIT));
|
||||
JMP (DBT_VECTOR_START);
|
||||
trace_output_void ();
|
||||
}
|
||||
@ -2242,7 +2241,6 @@ OP_5F40 ()
|
||||
trace_output_void ();
|
||||
}
|
||||
|
||||
|
||||
/* sac */
|
||||
void OP_5209 ()
|
||||
{
|
||||
@ -2275,7 +2273,6 @@ void OP_5209 ()
|
||||
trace_output_40 (tmp);
|
||||
}
|
||||
|
||||
|
||||
/* sachi */
|
||||
void
|
||||
OP_4209 ()
|
||||
@ -2309,7 +2306,6 @@ OP_4209 ()
|
||||
trace_output_16 (OP[0]);
|
||||
}
|
||||
|
||||
|
||||
/* sadd */
|
||||
void
|
||||
OP_1223 ()
|
||||
@ -2407,7 +2403,6 @@ OP_3220 ()
|
||||
trace_output_40(tmp);
|
||||
}
|
||||
|
||||
|
||||
/* sleep */
|
||||
void
|
||||
OP_5FC0 ()
|
||||
@ -3428,4 +3423,3 @@ OP_5000000 ()
|
||||
SET_GPR (OP[0], tmp);
|
||||
trace_output_16 (tmp);
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,9 @@
|
||||
1999-09-15 Doug Evans <devans@casey.cygnus.com>
|
||||
|
||||
* sim/arm/b.cgs: New testcase.
|
||||
* sim/arm/bic.cgs: New testcase.
|
||||
* sim/arm/bl.cgs: New testcase.
|
||||
|
||||
Thu Sep 2 18:15:53 1999 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* configure: Regenerated to track ../common/aclocal.m4 changes.
|
||||
|
Loading…
Reference in New Issue
Block a user