+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.
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
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
$(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
# 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)
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)
$(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) \
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
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
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
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 \
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) \
/* Prototypes for local functions. */
+static void until_break_command_continuation (struct continuation_arg *arg);
+
static void
catch_command_1 PARAMS ((char *, int, int));
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));
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
{
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);
&& 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);
}
}
-/* 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. */
static char *bpdisps[] =
{"del", "dstp", "dis", "keep"};
- static char bpenables[] = "nyn";
+ static char bpenables[] = "nynny";
char wrap_indent[80];
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 ");
/* 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)
{
register struct breakpoint *b;
register int count = 0;
+ struct breakpoint *perm_bp = 0;
if (address == 0) /* Watchpoints are uninteresting */
return;
&& 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.
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
delete_breakpoint (b);
}
-void
+struct breakpoint *
create_solib_event_breakpoint (address)
CORE_ADDR 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
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
{
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
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);
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 ();
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. */
};
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
+ };
\f
/* Prototypes for breakpoint-related functions. */
/* 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));
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));
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) */
# 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
/* 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
#define CALL_DUMMY_LENGTH (INSTRUCTION_SIZE * 28)
#define REG_PARM_STACK_SPACE 16
-#define ARGS_GROW_DOWNWARD
#else /* defined PA_LEVEL_0 */
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);
#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
}
}
+/* 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,
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
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). */
+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.
@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}.
@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.
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);
#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
#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.
/* 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;
/* 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
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);
\f
/* Insert an event object into the gdb event queue at
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)
{
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;
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;
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;
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,
/* 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
}
\f
-
/* 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
}
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;
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));
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;
#ifdef HAVE_POLL
- gdb_notifier.num_fds++;
if (gdb_notifier.poll_fds)
gdb_notifier.poll_fds =
(struct pollfd *) realloc (gdb_notifier.poll_fds,
/* 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;
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. */
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 */
/* 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;
}
}
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;
#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,
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. */
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;
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;
/* Call all the handlers that are ready. */
static void
-invoke_async_signal_handler ()
+invoke_async_signal_handler (void)
{
async_signal_handler *async_handler_ptr;
/* 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;
/* 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;
+}
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
#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;
#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"
/* 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
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. */
readline_input_state;
\f
+/* 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;
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
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
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 ();
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;
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));
/* 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. */
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);
+}
+
\f
/* Handles a gdb command. This function is called by
command_line_handler, which has processed one or more input lines
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);
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;
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;
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;
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 =
}
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);
/* 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
/* 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);
/* 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. */
}
/* 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",
#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
/* 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);
/* 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. */
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);
/* 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 ();
}
/* 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 ();
}
/* 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));
}
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
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
--- /dev/null
+/* 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;
/* 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];
};
#include <stdlib.h>
#include <string.h>
#include <errno.h>
+#include <unistd.h>
#include <io.h>
#include <dpmi.h>
#include <debug/v2load.h>
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) \
#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)
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. */
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);
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;
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);
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)
/* %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
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
}
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]
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)
/* Iterate over each argument provided by the user. */
for (i = 0; i < nargs; i++)
{
- lengths[i] = TYPE_LENGTH (VALUE_TYPE (args[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;
-#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
+ /* 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));
- /* If the argument is a double word argument, then it needs to be
- double word aligned.
+ /* Note the space we've wasted, if any. */
+ bytes_reserved += new_offset - offset[i];
+ offset[i] = new_offset;
+ }
- ?!? I do not think this code is correct when !ARGS_GROW_DOWNWAR. */
+ 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++)
+ {
+ lengths[i] = TYPE_LENGTH (VALUE_TYPE (args[i]));
+
+ /* 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 + lengths[i];
+
+ /* If the argument is a double word argument, then it needs to be
+ 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
}
- /* 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
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
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;
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)
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)
{
/* 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;
}
#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 ()
{
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);
}
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 */
}
}
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 ()
{
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)
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));
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);
}
\f
/* NEW_TTY_PREFORK is called before forking a new child process,
#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 */
#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. */
}
+
+
/* 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
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 */
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);
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;
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. */
}
}
+/* 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
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 ();
#include "defs.h"
#include "gdb_string.h"
+#include "kod.h"
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
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;
#include "gdbcmd.h"
#include "target.h"
#include "gdb_string.h"
+#include "kod.h"
/* Prototypes for exported functions. */
void _initialize_kod (void);
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) ();
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
--- /dev/null
+/* 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
#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;
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,
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 */
#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));
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);
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));
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);
}
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;
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;
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
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
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
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");
}
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;
}
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");
}
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");
}
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;)
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");
}
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);
}
}
- if (FD_ISSET (monitor_desc, &readfds))
+ if (FD_ISSET (DEPRECATED_SERIAL_FD (monitor_desc), &readfds))
{
while (1)
{
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);
}
}
- if (FD_ISSET (st2000_desc, &readfds))
+ if (FD_ISSET (DEPRECATED_SERIAL_FD (st2000_desc), &readfds))
{
while (1)
{
#include "objfiles.h"
#include "gdb-stabs.h"
#include "gdbthread.h"
+#include "remote.h"
#include "dcache.h"
#endif
#include "event-loop.h"
+#include "event-top.h"
#include <signal.h>
#include "serial.h"
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;
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 */
/* 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
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)
{
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)
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;
{
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
{
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
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. */
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)
{
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. */
+
+ c = readchar (remote_timeout);
+ csum += c;
+ repeat = fromhex (c) << 4;
+ c = readchar (remote_timeout);
+ csum += c;
+ repeat += fromhex (c);
+ }
- *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 */
+ 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)
{
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. */
/* 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 ();
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))
--- /dev/null
+/* 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
}
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;
}
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;
}
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;
/* 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.
#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. */
/* 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];
}
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;
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 */
#include "defs.h"
#include "serial.h"
+#include "ser-unix.h"
+
#include <sys/types.h>
#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#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
{
/* 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;
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);
}
#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)
}
}
-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);
}
/* 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.
#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
#include "signals.h"
#include "gdb_string.h"
-extern int (*ui_loop_hook) PARAMS ((int));
-
-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));
+static int tcp_open (serial_t scb, const char *name);
+static void tcp_close (serial_t scb);
+
+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;
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;
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);
}
/* 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.
#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
#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;
};
#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));
-
-void _initialize_ser_hardwire PARAMS ((void));
-
-extern int (*ui_loop_hook) PARAMS ((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 (void);
+
+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)
}
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)
}
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)
}
static serial_ttystate
-hardwire_get_tty_state (scb)
- serial_t scb;
+hardwire_get_tty_state (serial_t scb)
{
struct hardwire_ttystate *state;
}
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;
}
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
}
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);
}
static int
-hardwire_flush_output (scb)
- serial_t scb;
+hardwire_flush_output (serial_t scb)
{
#ifdef HAVE_TERMIOS
return tcflush (scb->fd, TCOFLUSH);
}
static int
-hardwire_flush_input (scb)
- serial_t scb;
+hardwire_flush_input (serial_t scb)
{
scb->bufcnt = 0;
scb->bufp = scb->buf;
}
static int
-hardwire_send_break (scb)
- serial_t scb;
+hardwire_send_break (serial_t scb)
{
#ifdef HAVE_TERMIOS
return tcsendbreak (scb->fd, 0);
}
static void
-hardwire_raw (scb)
- serial_t scb;
+hardwire_raw (serial_t scb)
{
struct hardwire_ttystate state;
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
{
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;
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)
{
};
static int
-rate_to_code (rate)
- int rate;
+rate_to_code (int rate)
{
int i;
}
static int
-hardwire_setbaudrate (scb, rate)
- serial_t scb;
- int rate;
+hardwire_setbaudrate (serial_t scb, int rate)
{
struct hardwire_ttystate state;
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;
cc = write (scb->fd, str, len);
if (cc < 0)
- return 1;
+ return 1;
len -= cc;
str += cc;
}
return 0;
}
+
static void
-hardwire_close (scb)
- serial_t scb;
+hardwire_close (serial_t scb)
{
if (scb->fd < 0)
return;
scb->fd = -1;
}
-static struct serial_ops hardwire_ops =
-{
- "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 */
-};
+\f
+/* 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;
+
+ while (len > 0)
+ {
+ cc = write (scb->fd, str, len);
+
+ if (cc < 0)
+ return 1;
+ len -= cc;
+ str += cc;
+ }
+ return 0;
+}
+
+int
+ser_unix_nop_flush_output (serial_t scb)
+{
+ return 0;
+}
+
+int
+ser_unix_nop_flush_input (serial_t scb)
+{
+ 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
+ser_unix_async (serial_t scb,
+ int async_p)
+{
+ if (async_p)
+ {
+ add_file_handler (scb->fd, ser_unix_event, scb);
+ }
+ else
+ {
+ delete_file_handler (scb->fd);
+ }
+}
void
-_initialize_ser_hardwire ()
+_initialize_ser_hardwire (void)
{
- serial_add_interface (&hardwire_ops);
+ 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);
}
--- /dev/null
+/* 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
/* 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.
#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 */
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";
static char *serial_logbase = logbase_ascii;
\f
+
static int serial_current_type = 0;
/* Log char CH of type CHTYPE, with TIMEOUT */
#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)
{
}
void
-serial_log_command (cmd)
- const char *cmd;
+serial_log_command (const char *cmd)
{
if (!serial_logfp)
return;
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));
-}
-
+\f
static struct serial_ops *
-serial_interface_lookup (name)
- char *name;
+serial_interface_lookup (char *name)
{
struct serial_ops *ops;
}
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;
/* 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)
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");
scb->bufcnt = 0;
scb->bufp = scb->buf;
- if (scb->ops->open (scb, name))
+ if (scb->ops->open (scb, open_name))
{
free (scb);
return NULL;
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;
}
serial_t
-serial_fdopen (fd)
- const int fd;
+serial_fdopen (const int fd)
{
serial_t scb;
struct serial_ops *ops;
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;
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;
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);
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
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);
}
static void
-connect_command (args, fromtty)
- char *args;
- int fromtty;
+connect_command (char *args, int fromtty)
{
int c;
char cur_esc = 0;
#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,
/* 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.
#ifndef SERIAL_H
#define SERIAL_H
-/* Terminal state pointer. This is specific to each type of interface. */
-
-typedef PTR serial_ttystate;
+/* For most routines, if a failure is indicated, then errno should be
+ examined. */
-struct _serial_t
- {
- int fd; /* File descriptor */
- struct serial_ops *ops; /* Function vector */
- void *state; /* Local context info for open FD */
- serial_ttystate ttystate; /* Not used (yet) */
- int bufcnt; /* Amount of data in receive buffer */
- unsigned char *bufp; /* Current byte */
- unsigned char buf[BUFSIZ]; /* Da buffer itself */
- int current_timeout; /* (termio{s} only), last value of VTIME */
- /* ser-unix.c termio{,s} only, we still need to wait for this many more
- seconds. */
- int timeout_remaining;
- 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 */
- };
+/* Terminal state pointer. This is specific to each type of
+ interface. */
+typedef void *serial_ttystate;
+struct _serial_t;
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));
- /* Discard pending output */
- int (*flush_output) PARAMS ((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));
- /* Wait for output to drain */
- int (*drain_output) PARAMS ((serial_t));
- };
+/* Try to open NAME. Returns a new serial_t on success, NULL on
+ failure. */
-/* Add a new serial interface to the interface list */
+extern serial_t serial_open (const char *name);
+#define SERIAL_OPEN(NAME) serial_open(NAME)
-void serial_add_interface PARAMS ((struct serial_ops * optable));
+/* Open a new serial stream using a file handle. */
-serial_t serial_open PARAMS ((const char *name));
+extern serial_t serial_fdopen (const int fd);
+#define SERIAL_FDOPEN(FD) serial_fdopen(FD)
-serial_t serial_fdopen PARAMS ((const int fd));
+/* Push out all buffers, close the device and destroy SERIAL_T. */
-/* For most routines, if a failure is indicated, then errno should be
- examined. */
+extern void serial_close (serial_t);
+#define SERIAL_CLOSE(SERIAL_T) serial_close ((SERIAL_T))
-/* Try to open NAME. Returns a new serial_t on success, NULL on failure.
- */
+/* Push out all buffers and destroy SERIAL_T without closing the
+ device. */
-#define SERIAL_OPEN(NAME) serial_open(NAME)
+extern void serial_un_fdopen (serial_t scb);
+#define SERIAL_UN_FDOPEN(SERIAL_T) serial_un_fdopen ((SERIAL_T))
-/* Open a new serial stream using a file handle. */
+/* 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_FDOPEN(FD) serial_fdopen(FD)
+#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. */
-#define SERIAL_DRAIN_OUTPUT(SERIAL_T) \
- ((SERIAL_T)->ops->drain_output((SERIAL_T)))
+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). */
+/* 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)))
+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). */
+/* 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)))
+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 PARAMS ((serial_t scb));
-
+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. */
-#define SERIAL_RAW(SERIAL_T) (SERIAL_T)->ops->go_raw((SERIAL_T))
+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. */
-#define SERIAL_GET_TTY_STATE(SERIAL_T) (SERIAL_T)->ops->get_tty_state((SERIAL_T))
+
+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). */
-#define SERIAL_SET_TTY_STATE(SERIAL_T, TTYSTATE) (SERIAL_T)->ops->set_tty_state((SERIAL_T), (TTYSTATE))
+ 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. */
-#define SERIAL_PRINT_TTY_STATE(SERIAL_T, TTYSTATE) \
- ((*((SERIAL_T)->ops->print_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. */
+ 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_T)->ops->noflush_set_tty_state)) \
- ((SERIAL_T), (NEW_TTYSTATE), (OLD_TTYSTATE)))
+serial_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. */
+/* Set the baudrate to the decimal value supplied. Returns 0 for
+ success, -1 for failure. */
-#define SERIAL_ERROR -1 /* General error, see errno for details */
-#define SERIAL_TIMEOUT -2
-#define SERIAL_EOF -3
+extern int serial_setbaudrate (serial_t scb, int rate);
+#define SERIAL_SETBAUDRATE(SERIAL_T, RATE) serial_setbaudrate ((SERIAL_T), (RATE))
-extern int serial_readchar PARAMS ((serial_t scb, int timeout));
+/* Set the number of stop bits to the value specified. Returns 0 for
+ success, -1 for failure. */
-#define SERIAL_READCHAR(SERIAL_T, TIMEOUT) serial_readchar (SERIAL_T, TIMEOUT)
+#define SERIAL_1_STOPBITS 1
+#define SERIAL_1_AND_A_HALF_STOPBITS 2 /* 1.5 bits, snicker... */
+#define SERIAL_2_STOPBITS 3
-/* Set the baudrate to the decimal value supplied. Returns 0 for success,
- -1 for failure. */
+extern int serial_setstopbits (serial_t scb, int num);
+#define SERIAL_SETSTOPBITS(SERIAL_T, NUM) serial_setstopbits ((SERIAL_T), (NUM))
-#define SERIAL_SETBAUDRATE(SERIAL_T, RATE) ((SERIAL_T)->ops->setbaudrate((SERIAL_T), RATE))
+/* Asynchronous serial interface: */
-/* Set the number of stop bits to the value specified. Returns 0 for success,
- -1 for failure. */
+/* Can the serial device support asynchronous mode? */
-#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_can_async_p (serial_t scb);
+#define SERIAL_CAN_ASYNC_P(SERIAL_T) serial_can_async_p ((SERIAL_T))
-#define SERIAL_SETSTOPBITS(SERIAL_T, NUM) ((SERIAL_T)->ops->setstopbits((SERIAL_T), NUM))
+/* Has the serial device been put in asynchronous mode? */
-/* Write LEN chars from STRING to the port SERIAL_T. Returns 0 for
- success, non-zero for failure. */
+extern int serial_is_async_p (serial_t scb);
+#define SERIAL_IS_ASYNC_P(SERIAL_T) serial_is_async_p ((SERIAL_T))
-extern int serial_write PARAMS ((serial_t scb, const char *str, int len));
+/* For ASYNC enabled devices, register a callback and enable
+ asynchronous mode. To disable asynchronous mode, register a NULL
+ callback. */
-#define SERIAL_WRITE(SERIAL_T, STRING,LEN) serial_write (SERIAL_T, STRING, LEN)
+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))
-/* Push out all buffers, close the device and destroy SERIAL_T. */
+/* 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 void serial_close PARAMS ((serial_t, int));
+extern int deprecated_serial_fd (serial_t scb);
+#define DEPRECATED_SERIAL_FD(SERIAL_T) deprecated_serial_fd ((SERIAL_T))
-#define SERIAL_CLOSE(SERIAL_T) serial_close(SERIAL_T, 1)
-/* Push out all buffers and destroy SERIAL_T without closing the device. */
+/* Details of an instance of a serial object */
-#define SERIAL_UN_FDOPEN(SERIAL_T) serial_close(SERIAL_T, 0)
+struct _serial_t
+ {
+ int fd; /* File descriptor */
+ struct serial_ops *ops; /* Function vector */
+ void *state; /* Local context info for open FD */
+ serial_ttystate ttystate; /* Not used (yet) */
+ int bufcnt; /* Amount of data in receive buffer */
+ unsigned char *bufp; /* Current byte */
+ unsigned char buf[BUFSIZ]; /* Da buffer itself */
+ int current_timeout; /* (termio{s} only), last value of VTIME */
+ /* ser-unix.c termio{,s} only, we still need to wait for this many more
+ seconds. */
+ int timeout_remaining;
+ 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 */
+ };
+
+struct serial_ops
+ {
+ char *name;
+ struct serial_ops *next;
+ 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) (serial_t);
+ /* Discard pending input */
+ 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) (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 */
-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 */
#include "expression.h"
#include "language.h"
#include "command.h"
+#include "source.h"
#include "gdbcmd.h"
#include "frame.h"
#include "value.h"
#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));
--- /dev/null
+/* 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
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;
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;
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))
{
&& 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
#ifdef SOFUN_ADDRESS_MAYBE_MISSING
extern CORE_ADDR find_stab_function_addr PARAMS ((char *,
- struct partial_symtab *,
+ char *,
struct objfile *));
#endif
+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
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] {
# 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 $"\
-# 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
# Purpose is to test conditional breakpoints.
# Modeled after "break.exp".
-
-
if $tracelevel then {
strace $tracelevel
}
set prms_id 0
set bug_id 0
-set testfile "condbreak"
+set testfile "break"
set srcfile ${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}
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);
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. */
-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"
#include <sys/types.h>
#include "event-loop.h"
+#include "event-top.h"
#include "gdb_string.h"
#include "gdb_stat.h"
#include <ctype.h>
#include "gdb_string.h"
#include "inferior.h"
#include "tracepoint.h"
+#include "remote.h"
#include "ax.h"
#include "ax-gdb.h"
}
}
-/* 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)
+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
#include "symtab.h"
#include "frame.h"
#include "breakpoint.h"
+#include "source.h"
#include "tui.h"
#include "tuiData.h"
#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 **
******************************************/
#include <ctype.h>
#include "gdb_string.h"
#include "event-loop.h"
+#include "event-top.h"
#ifdef HAVE_CURSES_H
#include <curses.h>
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);
+ }
+}
+
\f
/* Print a warning message. Way to use this is to call warning_begin,
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 *));
{
struct type *base_type;
value_ptr arg2;
- value_ptr real_val;
COERCE_ARRAY (arg1);
int *boffset;
{
struct type *t;
- value_ptr v;
t = check_typedef (VALUE_TYPE (*argp));
/* 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]));
+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.
$(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)
/* 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);
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;
/* 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,
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;
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);
#include "hw-main.h"
#include "hw-base.h"
+#include "sim-io.h"
#include "sim-assert.h"
struct hw_instance_data {
#include "hw-main.h"
#include "hw-base.h"
+#include "sim-io.h"
#include "sim-assert.h"
#ifdef HAVE_STRING_H
#include "hw-base.h"
#include "hw-tree.h"
+#include "sim-io.h"
#include "sim-assert.h"
#ifdef HAVE_STDLIB_H
#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;
{
do
{
- f->fraction >>= 1;
+ f->fraction = (f->fraction >> 1) | (f->fraction & 1);
f->normal_exp += 1;
}
while (f->fraction >= IMPLICIT_2);
# 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
# 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
# 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
# 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
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.
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
{ 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
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
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
# 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
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
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
# 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
# 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
# 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
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
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
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
# 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
# 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
# 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
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.
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
{ 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
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
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
# 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
esac
-
-
# Is there a testsuite directory for the target?
testdir=`echo ${target} | sed -e 's/-.*-/-/'`
if test -r ${srcdir}/testsuite/${testdir}/configure ; then
esac
-
-
# Is there a testsuite directory for the target?
testdir=`echo ${target} | sed -e 's/-.*-/-/'`
if test -r ${srcdir}/testsuite/${testdir}/configure ; then
+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.
PSW_MASK = (PSW_SM_BIT
| PSW_EA_BIT
| PSW_DB_BIT
- | PSW_DM_BIT
| PSW_IE_BIT
| PSW_RP_BIT
| PSW_MD_BIT
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 ();
}
trace_output_void ();
}
-
/* sac */
void OP_5209 ()
{
trace_output_40 (tmp);
}
-
/* sachi */
void
OP_4209 ()
trace_output_16 (OP[0]);
}
-
/* sadd */
void
OP_1223 ()
trace_output_40(tmp);
}
-
/* sleep */
void
OP_5FC0 ()
SET_GPR (OP[0], tmp);
trace_output_16 (tmp);
}
-
+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.