diff options
Diffstat (limited to 'gdb')
47 files changed, 3581 insertions, 1420 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 3a63a2b..fe8c1357 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,292 @@ +Mon Aug 23 10:16:32 1999 Jeffrey A Law (law@cygnus.com) + + * pa64solib.c: Fix some minor whitespace problems. + (bfd_lookup_symbol): New function. + (pa64_solib_create_inferior_hook): Find the address __dld_break + in the dynamic linker. Try to set a shlib event breakpoint in + that function. + (add_to_solist): Do not add the same shared library to the shlib + list more than once. + +Sun Aug 22 14:49:40 1999 Andrew Cagney <cagney@b1.cygnus.com> + + * value.h (enum lval_type): Move declaration from here. + * defs.h (enum lval_type): To here. + * frame.h, gdbarch.h: Delete incomplete declaration of ``enum + lval_type''. + +1999-08-20 Michael Snyder <msnyder@cleaver.cygnus.com> + + * breakpoint.c (can_use_hardware_watchpoint): reject expressions + that refer to registers or register variables. + +Fri Aug 20 10:53:38 1999 Jeffrey A Law (law@cygnus.com) + + * hppa-tdep.c (hppa_fix_call_dummy): Provide PA2.0W aware code. + + * pa64solib.c pa64solib.h: New files. + + * config/pa/hppa64.mt: Delete commented out code that is and + never will be appropriate for this target. + * config/pa/hpux11w.mt (TDEPFILES): Remove SOM references. Also + remove pa64solib.o. + * config/pa/hpux11w.mh (NATDEPFILES): Remove SOM references. + + * configure.host; Use "hpux11w" and "hpux11" instead of + "hpux1100w" and "hpux1100" respectively + * config/pa/hpux11w.mh: Renamed from hpux1100w.mh. + * config/pa/hpux11w.mt, config/pa/hpux11.mh: Likewise. + * config/pa/hpux11.mt: Likewise. + +1999-08-19 Michael Snyder <msnyder@cleaver.cygnus.com> + + * breakpoint.h (target_hw_bp_type): new enum. + * breakpoint.c (insert_breakpoints): use enum instead of consts. + (remove_breakpoint): use enum instead of consts. + [Also clean up a bunch of excessively long lines.] + +1999-08-19 J.T. Conklin <jtc@redback.com> + + * i386-stub.c (waitabit): Removed. + (breakpoint): Update. + + * i386-stub.c, m32r-stub.c, sparc-stub.c, sparcl-stub.c, + sparclet-stub.c (set_debug_traps): Don't send gratuitous ACK. + + * m68k-stub.c (putpacket): Restore code so that packets are sent + until an ACK is received. + +1999-08-19 Eli Zaretskii <eliz@is.elta.co.il> + + * breakpoint.c (bpstat_stop_status): Accept triggered addresses + anywhere inside the region occupied by a watched variable as a + sign that the watchpoint fired. Don't stop if some watchpoint + was triggered, but its address doesn't match the address of this + watchpoint. + (TARGET_REGION_OK_FOR_HW_WATCHPOINT): New macro. + Default definition is to call TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT. + (can_use_hardware_watchpoint): Call TARGET_REGION_OK_FOR_HW_WATCHPOINT; + if it returns zero, return zero immediately. + (insert_breakpoints): Try to insert watchpoints for all the values + on the value chain, even if some of them fail to insert. Remove + the breakpoint if parts of its value chain couldn't be inserted. + +1999-08-19 Eli Zaretskii <eliz@is.elta.co.il> + + * go32-nat.c (go32_stopped_by_watchpoint): Remove unused code. + +1999-08-19 Eli Zaretskii <eliz@is.elta.co.il> + + * go32-nat.c (tcgetpgrp, tcsetpgrp): New functions. + +1999-08-19 Eli Zaretskii <eliz@is.elta.co.il> + + * go32-nat.c (go32_wait): If we are in a single-step mode, and the + next instruction is INT nn or INTO, use a temporary breakpoint to + simulate single-step mode, and reset the trace flag. + +1999-08-19 Eli Zaretskii <eliz@is.elta.co.il> + + * go32-nat.c (wp_op): New typedef. + (SHOW_DR): Print the length of watched region as well. + (go32_insert_aligned_watchpoint): Remove unused argument PID. All + callers and the prototype changed. + (go32_handle_nonaligned_watchpoint): Renamed from + go32_insert_nonaligned_watchpoint. Now handles all operations on + non-aligned watchpoints: insertion, deletion, and counting. If + called with wp_count as the first argument, return the count of + debug registers needed to watch the region. Don't break out of + the loop before all the addresses in the region are processed. + (go32_remove_watchpoint): Call go32_remove_aligned_watchpoint to + do the actual work. + (go32_remove_aligned_watchpoint): New function, modeled after + go32_insert_aligned_watchpoint. Removes watchpoints that watch + regions of arbitrary length by calling + go32_handle_nonaligned_watchpoint as needed. + (go32_region_ok_for_watchpoint): New function, called from + can_use_hardware_watchpoint via the new macro + TARGET_REGION_OK_FOR_HW_WATCHPOINT. + + * config/i386/nm-go32.h (TARGET_REGION_OK_FOR_HW_WATCHPOINT): + Define to call go32_region_ok_for_watchpoint. + (DECR_PC_AFTER_HW_BREAK): Define back to zero (previous redefinition + to 1 was due to a bug in go32-nat.c). + +1999-08-19 Eli Zaretskii <eliz@is.elta.co.il> + + * go32-nat.c (cleanup_dregs): New function. + (go32_mourn_inferior): Call it. + (IS_REG_FREE, LOCAL_ENABLE_REG, GLOBAL_ENABLE_REG, DISABLE_REG, + SET_BREAK, SET_WATCH, IS_WATCH, WATCH_HIT): Protect arguments with + parentheses. + (SET_BREAK): Increment the debug register's reference count. + (DR_DEF): New macro, returns the access and length bits of the + breakpoint. + (SHOW_DR): Print the reference count of each register. Disable or + enable print-out depending on an environment variable GDB_SHOW_DR. + (go32_insert_aligned_watchpoint): Look for an occupied debug + register with the same address and access/length bits, and reuse + it by incrementing reference the count, before occupying another + register. Return zero upon success. + (go32_insert_nonaligned_watchpoint): Pass the read/write bits to + go32_remove_watchpoint. + (go32_remove_watchpoint): Accept an additional parameter: the + read/write bits of the watchpoint to remove, and only remove a + watchpoint if it's occupied and its address and read/write bits + match. Only disable the register if its reference count is zero; + otherwise just decrease the reference count. + (go32_remove_hw_breakpoint): Only decrease reference count and + disable the debug register if it is occupied and its access bits + match those of an instruction breakpoint. + (go32_insert_hw_breakpoint): Before occupying another debug + register, look for an already occupied register that defines an + instruction breakpoint with the same address. If found, increment + its reference count. Call SHOW_DR even if failed to insert a + breakpoint. + + * config/i386/nm-go32.h (target_remove_watchpoint): Accept the + TYPE argument as well. + +Wed Aug 18 17:47:25 1999 Andrew Cagney <cagney@b1.cygnus.com> + + * mips-tdep.c: Add more comments. + +1999-08-17 Stan Shebs <shebs@andros.cygnus.com> + + * blockframe.c: Don't use PARAMS anymore, remove obsolete comment + about frameless functions. + +1999-08-16 Michael Snyder <msnyder@cleaver.cygnus.com> + + * thread.c (delete_thread): delete any step_resume breakpoint + held by the thread. (prune_threads): call delete_thread. + * breakpoint.c (breakpoint_init_inferior): if startup, then + delete any remaining step_resume breakpoints. + * infrun.c (handle_inferior_event): add cautionary comment. + +1999-08-16 Fernando Nasser <fnasser@totem.to.cygnus.com> + + * remote.c (remote_async_mourn): New function. Async version of + remote_mourn(). + +1999-08-16 Eli Zaretskii <eliz@is.elta.co.il> + + * terminal.h [__GO32__]: Remove conditional; DJGPP now supports + termios. + +1999-08-16 Eli Zaretskii <eliz@is.elta.co.il> + + * command.c (CANT_FORK) [__MSDOS__]: Define. + (shell_escape) [CANT_FORK]: If ARG is NULL, pass an empty string + to `system'. + [__DJGPP__]: Return to the original directory after the shell + exits. + +1999-08-16 Eli Zaretskii <eliz@is.elta.co.il> + + * config/i386/xm-go32.h (ROOTED_P): Don't reference X[1] if X[0] + is a null character. + + * config/i386/nm-go32.h (DECR_PC_AFTER_HW_BREAK): Define to 1. + +1999-08-16 Eli Zaretskii <eliz@is.elta.co.il> + + * go32-nat.c (redir_cmdline_parse, redir_cmdline_delete, + redir_to_child, redir_to_debugger, redir_debug_init) + [__DJGPP_MINOR__ < 3]: Dummy stubs for redirecting debuggee's + standard handles. + (print_387_status): Print "last FP instruction", not "last + exception". Restore the upper 5 bits of the opcode that aren't + stored in the FPU state. Print the FPU stack in its physical + order, not relative to ST(0). Print "special", not "trap" for + unnormals and infinities. Print all 10 bytes of each FP register, + and print them with 19 significant digits. + (regno_mapping): Make the mapping consistent with tm-go32.h. + (sig_map): Add mappings for SIGQUIT, SIGFPE, SIGALRM. Map NMI to + SIGBUS. + (excep_map): New variable, maps GDB signals to DJGPP exceptions. + (go32_attach): Signal an error: we cannot attach to other + processes. + (go32_resume): Record the signal with which the inferior should be + resumed, mapped to the DJGPP exception number. + (go32_wait): Pass the signal recorded in go32_resume to the + debuggee. Save and restore debugger's and debuggee's current + working directory. + [__DJGPP_MINOR__ < 3]: Save and restore inferior's FPU state. + (store_register): FPU regsiters have numbers less than 31. + (go32_kill_inferior): Delete the parsed command-line storage. + (go32_create_inferior): Initialize the parsed command-line + storage. Parse the command line and create the redirections for + inferior's standard handles. + [__DJGPP_MINOR__ < 3]: Init the inferior's FPU state. + (ignore2): Function deleted. + (device_mode): New function, switches a character device between + raw and cooked mode. + (go32_terminal_init): Invalidate the raw/cooked mode information. + (go32_terminal_info): Print whether the inferior's terminal is in + raw or cooked mode. + [__DJGPP_MINOR__ > 2]: Say if standard handles are redirected or + closed by the inferior. + (go32_terminal_inferior): Switch standard handles to the + inferior's files/devices. Put the inferior's input device to + raw/cooked mode, exactly like we found it last time. + (go32_terminal_ours): Restore debugger's standard handles and put + the terminal into cooked mode. Save the mode of inferior's input + device. + (init_go32_ops): Assign go32_ops.to_attach, + go32_ops.to_terminal_info, go32_ops.to_terminal_ours_for_output. + Initialize inferior's cwd and the command-line storage. + +Mon Aug 16 14:29:30 1999 Jeffrey A Law (law@cygnus.com) + + * config/pa/tm-hppa.h (ARGS_GROW_DOWNWARD): Define. + * config/pa/tm-hppa64.h (ARGS_GROW_DOWNWARD): Undefine. + * hppa-tdep.c (hppa_push_arguments): Handle arguments growing in + both directions depending ARGS_GROW_DOWNWARD. + (hppa_find_saved_regs): Update for 64bit wide registers & pointers + and PA64 ABI. + + * hppa-tdep.c (hppa_pop_frame): Various fixes for 64bit wide + registers and pointers. + (hppa_fix_call_dummy, skip_trampoline_code): Likewise. + (restore_pc_queue): Update tests for width of memory loads. + (hppa_push_arguments): Delete version that was #if 0'd out. + + * hppa-tdep.c (push_dummy_frame): Handle the new 64it ABI. + (find_dummy_frame_regs): Corresponding changes. + + * hppa-tdep.c (read_unwind_info): Initialize obj_private->dp. + (internalize_unwinds): Improve test for when to use segment + relative code for unwinder bounds. + (rp_saved): Fix offset of saved return pointer for the 64bit ABI. + (hppa_frame_saved_pc): Various updates to handle 64bit registers + and pointers. + (frame_chain, restore_pc_queue): Likewise. + + * hppa-tdep.c (rp_saved): RP is saved at frame-16 when + pointers are 64bits wide. + + * hppa-tdep.c (record_text_segment_lowaddr): New function. + (internalize_unwinds): Use it if addressess are 8 bytes wide. + + * symfile.c (syms_from_objfile): No longer warn if the lowest + section does not have SEC_CODE set. + + * Makefile.in (pa64solib.o): Add dependencies. + + * hppah-nat.c (store_inferior_registers): Do not try to write a + nonzero value to the high part of IPSW. Fix typo in unable to store + warning. + + * config/pa/tm-hppa.h (opd_data structure): Delete. Not actually + needed. + (struct obj_private_struct): Add new entry for the objfile's DP + value. + * config/pa/tm-hppa64.h (CALL_DUMMY): Add a nop to make it an even + number of instructions. Pack the dummy into word sized hunks. + (CALL_DUMMY_LENGTH): Update appropriately. + (PC_IN_CALL_DUMMY, CALL_DUMMY_LOCATION_AFTER_TEXT_END): Delete. + Mon Aug 16 19:08:19 1999 Andrew Cagney <cagney@b1.cygnus.com> * configure.in: Try -lsocket when looking for socketpair. diff --git a/gdb/Makefile.in b/gdb/Makefile.in index e669a18..df4caad 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -224,7 +224,7 @@ CDEPS = $(XM_CDEPS) $(TM_CDEPS) $(NAT_CDEPS) $(SIM) $(BFD) $(READLINE) \ ADD_FILES = $(REGEX) $(XM_ADD_FILES) $(TM_ADD_FILES) $(NAT_ADD_FILES) ADD_DEPS = $(REGEX1) $(XM_ADD_FILES) $(TM_ADD_FILES) $(NAT_ADD_FILES) -VERSION = 19990816 +VERSION = 19990823 DIST=gdb LINT=/usr/5bin/lint @@ -1346,6 +1346,9 @@ somread.o: somread.c $(bfd_h) buildsym.h complaints.h $(defs_h) \ somsolib.o: somsolib.c $(defs_h) +pa64solib.o: pa64solib.c $(defs_h) + +hpux-thread.o: hpux-thread.c $(defs_h) gdbthread.h target.h inferior.h hpux-thread.o: hpux-thread.c $(defs_h) gdbthread.h target.h inferior.h $(CC) -c $(INTERNAL_CFLAGS) -I$(srcdir)/osf-share \ -I$(srcdir)/osf-share/HP800 -I/usr/include/dce $(srcdir)/hpux-thread.c diff --git a/gdb/blockframe.c b/gdb/blockframe.c index 6b8e83b..b4f42d2 100644 --- a/gdb/blockframe.c +++ b/gdb/blockframe.c @@ -34,7 +34,7 @@ /* Prototypes for exported functions. */ -void _initialize_blockframe PARAMS ((void)); +void _initialize_blockframe (void); /* A default FRAME_CHAIN_VALID, in the form that is suitable for most targets. If FRAME_CHAIN_VALID returns zero it means that the given @@ -286,11 +286,6 @@ reinit_frame_cache () } } -/* If a machine allows frameless functions, it should define a macro - FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS) in param.h. FI is the struct - frame_info for the frame, and FRAMELESS should be set to nonzero - if it represents a frameless function invocation. */ - /* Return nonzero if the function for this frame lacks a prologue. Many machines can define FRAMELESS_FUNCTION_INVOCATION to just call this function. */ @@ -300,14 +295,15 @@ frameless_look_for_prologue (frame) struct frame_info *frame; { CORE_ADDR func_start, after_prologue; + func_start = get_pc_function_start (frame->pc); if (func_start) { func_start += FUNCTION_START_OFFSET; after_prologue = func_start; #ifdef SKIP_PROLOGUE_FRAMELESS_P - /* This is faster, since only care whether there *is* a prologue, - not how long it is. */ + /* This is faster, since only care whether there *is* a + prologue, not how long it is. */ after_prologue = SKIP_PROLOGUE_FRAMELESS_P (after_prologue); #else after_prologue = SKIP_PROLOGUE (after_prologue); @@ -315,10 +311,10 @@ frameless_look_for_prologue (frame) return after_prologue == func_start; } else if (frame->pc == 0) - /* A frame with a zero PC is usually created by dereferencing a NULL - function pointer, normally causing an immediate core dump of the - inferior. Mark function as frameless, as the inferior has no chance - of setting up a stack frame. */ + /* A frame with a zero PC is usually created by dereferencing a + NULL function pointer, normally causing an immediate core dump + of the inferior. Mark function as frameless, as the inferior + has no chance of setting up a stack frame. */ return 1; else /* If we can't find the start of the function, we don't really @@ -1239,7 +1235,7 @@ generic_save_dummy_frame_tos (sp) void generic_pop_current_frame (pop) - void (*pop) PARAMS ((struct frame_info * frame)); + void (*pop) (struct frame_info * frame); { struct frame_info *frame = get_current_frame (); if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame)) @@ -1401,7 +1397,7 @@ generic_get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval) } void -_initialize_blockframe () +_initialize_blockframe (void) { obstack_init (&frame_cache_obstack); } diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index ef9dfb8..c4987b3 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -192,13 +192,23 @@ static void awatch_command PARAMS ((char *, int)); static void do_enable_breakpoint PARAMS ((struct breakpoint *, enum bpdisp)); -static void create_solib_load_unload_event_breakpoint PARAMS ((char *hookname, int tempflag, char *dll_pathname, char *cond_string, enum bptype bp_kind)); +static void solib_load_unload_1 PARAMS ((char *hookname, + int tempflag, + char *dll_pathname, + char *cond_string, + enum bptype bp_kind)); -static void create_fork_vfork_event_catchpoint PARAMS ((int tempflag, char *cond_string, enum bptype bp_kind)); +static void create_fork_vfork_event_catchpoint PARAMS ((int tempflag, + char *cond_string, + enum bptype bp_kind)); -static void break_at_finish_at_depth_command_1 PARAMS ((char *arg, int flag, int from_tty)); +static void break_at_finish_at_depth_command_1 PARAMS ((char *arg, + int flag, + int from_tty)); -static void break_at_finish_command_1 PARAMS ((char *arg, int flag, int from_tty)); +static void break_at_finish_command_1 PARAMS ((char *arg, + int flag, + int from_tty)); static void stop_command PARAMS ((char *arg, int from_tty)); @@ -212,11 +222,17 @@ static char *ep_parse_optional_if_clause PARAMS ((char **arg)); static char *ep_parse_optional_filename PARAMS ((char **arg)); -static void catch_exec_command_1 PARAMS ((char *arg, int tempflag, int from_tty)); +static void catch_exec_command_1 PARAMS ((char *arg, int tempflag, + int from_tty)); -static void create_exception_catchpoint PARAMS ((int tempflag, char *cond_string, enum exception_event_kind ex_event, struct symtab_and_line * sal)); +static void create_exception_catchpoint + PARAMS ((int tempflag, char *cond_string, + enum exception_event_kind ex_event, + struct symtab_and_line * sal)); -static void catch_exception_command_1 PARAMS ((enum exception_event_kind ex_event, char *arg, int tempflag, int from_tty)); +static void catch_exception_command_1 + PARAMS ((enum exception_event_kind ex_event, + char *arg, int tempflag, int from_tty)); static void tcatch_command PARAMS ((char *arg, int from_tty)); @@ -412,7 +428,7 @@ get_number (pp) val = value_of_internalvar (lookup_internalvar (varname)); if (TYPE_CODE (VALUE_TYPE (val)) != TYPE_CODE_INT) error ( - "Convenience variables used to specify breakpoints must have integer values." + "Convenience variables used to specify breakpoints must have integer values." ); retval = (int) value_as_long (val); } @@ -514,7 +530,9 @@ commands_command (arg, from_tty) if (b->number == bnum) { char tmpbuf[128]; - sprintf (tmpbuf, "Type commands for when breakpoint %d is hit, one per line.", bnum); + sprintf (tmpbuf, + "Type commands for when breakpoint %d is hit, one per line.", + bnum); l = read_command_lines (tmpbuf, from_tty); free_command_lines (&b->commands); b->commands = l; @@ -550,7 +568,8 @@ read_memory_nobpt (memaddr, myaddr, len) ALL_BREAKPOINTS (b) { if (b->type == bp_none) - warning ("attempted to read through apparently deleted breakpoint #%d?\n", b->number); + warning ("reading through apparently deleted breakpoint #%d?", + b->number); /* memory breakpoint? */ if (b->type == bp_watchpoint @@ -640,6 +659,7 @@ int insert_breakpoints () { register struct breakpoint *b, *temp; + int return_val = 0; /* return success code. */ int val = 0; int disabled_breaks = 0; @@ -703,27 +723,28 @@ insert_breakpoints () if (!disabled_breaks) { target_terminal_ours_for_output (); - fprintf_unfiltered (gdb_stderr, - "Cannot insert breakpoint %d:\n", b->number); - printf_filtered ("Temporarily disabling shared library breakpoints:\n"); + warning ("Cannot insert breakpoint %d:", b->number); + warning ("Temporarily disabling shared library breakpoints:"); } disabled_breaks = 1; - printf_filtered ("%d ", b->number); + warning ("breakpoint #%d ", b->number); } else #endif { target_terminal_ours_for_output (); - fprintf_unfiltered (gdb_stderr, "Cannot insert breakpoint %d:\n", b->number); + warning ("Cannot insert breakpoint %d:", b->number); #ifdef ONE_PROCESS_WRITETEXT - fprintf_unfiltered (gdb_stderr, - "The same program may be running in another process.\n"); + warning ("The same program may be running in another process."); #endif - memory_error (val, b->address); /* which bombs us out */ + memory_error (val, b->address); /* which bombs us out */ } } else b->inserted = 1; + + if (val) + return_val = val; /* remember failure */ } else if (ep_is_exception_catchpoint (b) && b->enable != disabled @@ -736,15 +757,16 @@ insert_breakpoints () /* If we get here, we must have a callback mechanism for exception events -- with g++ style embedded label support, we insert ordinary breakpoints and not catchpoints. */ - sprintf (message, message1, b->number); /* Format possible error message */ + /* Format possible error message */ + sprintf (message, message1, b->number); val = target_insert_breakpoint (b->address, b->shadow_contents); if (val) { /* Couldn't set breakpoint for some reason */ target_terminal_ours_for_output (); - fprintf_unfiltered (gdb_stderr, - "Cannot insert catchpoint %d; disabling it\n", b->number); + warning ("Cannot insert catchpoint %d; disabling it.", + b->number); b->enable = disabled; } else @@ -752,7 +774,8 @@ insert_breakpoints () /* Bp set, now make sure callbacks are enabled */ int val; args_for_catchpoint_enable args; - args.kind = b->type == bp_catch_catch ? EX_EVENT_CATCH : EX_EVENT_THROW; + args.kind = b->type == bp_catch_catch ? + EX_EVENT_CATCH : EX_EVENT_THROW; args.enable = 1; val = catch_errors (cover_target_enable_exception_callback, &args, @@ -766,10 +789,14 @@ insert_breakpoints () { /* something went wrong */ target_terminal_ours_for_output (); - fprintf_unfiltered (gdb_stderr, "Cannot insert catchpoint %d; disabling it\n", b->number); + warning ("Cannot insert catchpoint %d; disabling it.", + b->number); b->enable = disabled; } } + + if (val) + return_val = val; /* remember failure */ } else if ((b->type == bp_hardware_watchpoint || @@ -827,11 +854,11 @@ insert_breakpoints () addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v); len = TYPE_LENGTH (VALUE_TYPE (v)); - type = 0; + type = hw_write; if (b->type == bp_read_watchpoint) - type = 1; + type = hw_read; else if (b->type == bp_access_watchpoint) - type = 2; + type = hw_access; val = target_insert_watchpoint (addr, len, type); if (val == -1) @@ -845,14 +872,18 @@ insert_breakpoints () /* Failure to insert a watchpoint on any memory value in the value chain brings us here. */ if (!b->inserted) - warning ("Hardware watchpoint %d: Could not insert watchpoint\n", - b->number); + { + remove_breakpoint (b, mark_uninserted); + warning ("Could not insert hardware watchpoint %d.", + b->number); + val = -1; + } } else { - printf_filtered ("\ -Hardware watchpoint %d deleted because the program has left the block in\n\ -which its expression is valid.\n", b->number); + printf_filtered ("Hardware watchpoint %d deleted", b->number); + printf_filtered ("because the program has left the block \n"); + printf_filtered ("in which its expression is valid.\n"); if (b->related_breakpoint) b->related_breakpoint->disposition = del_at_next_stop; b->disposition = del_at_next_stop; @@ -862,6 +893,9 @@ which its expression is valid.\n", b->number); if ((saved_frame != selected_frame) || (saved_level != selected_frame_level)) select_and_print_frame (saved_frame, saved_level); + + if (val) + return_val = val; /* remember failure */ } else if ((b->type == bp_catch_fork || b->type == bp_catch_vfork @@ -883,22 +917,23 @@ which its expression is valid.\n", b->number); val = target_insert_exec_catchpoint (inferior_pid); break; default: - warning ("GDB bug: breakpoint.c (insert_breakpoints): enclosing `if' does not protect `switch'"); + warning ("Internal error, %s line %d.", __FILE__, __LINE__); break; } if (val < 0) { target_terminal_ours_for_output (); - fprintf_unfiltered (gdb_stderr, "Cannot insert catchpoint %d:\n", b->number); + warning ("Cannot insert catchpoint %d.", b->number); } else b->inserted = 1; + + if (val) + return_val = val; /* remember failure */ } } - if (disabled_breaks) - printf_filtered ("\n"); - return val; + return return_val; } @@ -928,7 +963,8 @@ reattach_breakpoints (pid) int val; int saved_inferior_pid = inferior_pid; - inferior_pid = pid; /* Because remove_breakpoint will use this global. */ + /* FIXME: use a cleanup, to insure that inferior_pid gets replaced! */ + inferior_pid = pid; /* Because remove_breakpoint will use this global. */ ALL_BREAKPOINTS (b) { if (b->inserted) @@ -994,10 +1030,10 @@ update_breakpoints_after_exec () won't stop when it ought! Similarly, we probably ought to keep vfork catchpoints, 'cause - on this target, we may not be able to stop when the vfork is seen, - but only when the subsequent exec is seen. (And because deleting - fork catchpoints here but not vfork catchpoints will seem mysterious - to users, keep those too.) + on this target, we may not be able to stop when the vfork is + seen, but only when the subsequent exec is seen. (And because + deleting fork catchpoints here but not vfork catchpoints will + seem mysterious to users, keep those too.) ??rehrauer: Let's hope that merely clearing out this catchpoint's target address field, if any, is sufficient to have it be reset @@ -1025,15 +1061,17 @@ update_breakpoints_after_exec () gets 'round to deleting the "use to be a bp_finish" breakpoint. We really must allow finish_command to delete a bp_finish. - In the absense of a general solution for the "how do we know it's - safe to delete something others may have handles to?" problem, what - we'll do here is just uninsert the bp_finish, and let finish_command - delete it. + In the absense of a general solution for the "how do we know + it's safe to delete something others may have handles to?" + problem, what we'll do here is just uninsert the bp_finish, and + let finish_command delete it. + + (We know the bp_finish is "doomed" in the sense that it's + momentary, and will be deleted as soon as finish_command sees + the inferior stopped. So it doesn't matter that the bp's + address is probably bogus in the new a.out, unlike e.g., the + solib breakpoints.) */ - (We know the bp_finish is "doomed" in the sense that it's momentary, - and will be deleted as soon as finish_command sees the inferior stopped. - So it doesn't matter that the bp's address is probably bogus in the - new a.out, unlike e.g., the solib breakpoints.) */ if (b->type == bp_finish) { continue; @@ -1066,7 +1104,8 @@ detach_breakpoints (pid) if (pid == inferior_pid) error ("Cannot detach breakpoints of inferior_pid"); - inferior_pid = pid; /* Because remove_breakpoint will use this global. */ + /* FIXME: use a cleanup, to insure that inferior_pid gets replaced! */ + inferior_pid = pid; /* Because remove_breakpoint will use this global. */ ALL_BREAKPOINTS (b) { if (b->inserted) @@ -1091,7 +1130,8 @@ remove_breakpoint (b, is) int val; if (b->type == bp_none) - warning ("attempted to remove apparently deleted breakpoint #%d?\n", b->number); + warning ("attempted to remove apparently deleted breakpoint #%d?", + b->number); if (b->type != bp_watchpoint && b->type != bp_hardware_watchpoint @@ -1155,11 +1195,11 @@ remove_breakpoint (b, is) addr = VALUE_ADDRESS (v) + VALUE_OFFSET (v); len = TYPE_LENGTH (VALUE_TYPE (v)); - type = 0; + type = hw_write; if (b->type == bp_read_watchpoint) - type = 1; + type = hw_read; else if (b->type == bp_access_watchpoint) - type = 2; + type = hw_access; val = target_remove_watchpoint (addr, len, type); if (val == -1) @@ -1169,7 +1209,7 @@ remove_breakpoint (b, is) } /* Failure to remove any of the hardware watchpoints comes here. */ if ((is == mark_uninserted) && (b->inserted)) - warning ("Hardware watchpoint %d: Could not remove watchpoint\n", + warning ("Could not remove hardware watchpoint %d.", b->number); /* Free the saved value chain. We will construct a new one @@ -1200,7 +1240,7 @@ remove_breakpoint (b, is) val = target_remove_exec_catchpoint (inferior_pid); break; default: - warning ("GDB bug: breakpoint.c (remove_breakpoint): enclosing `if' does not protect `switch'"); + warning ("Internal error, %s line %d.", __FILE__, __LINE__); break; } if (val) @@ -1245,14 +1285,15 @@ mark_breakpoints_out () b->inserted = 0; } -/* Clear the "inserted" flag in all breakpoints and delete any breakpoints - which should go away between runs of the program. +/* Clear the "inserted" flag in all breakpoints and delete any + breakpoints which should go away between runs of the program. Plus other such housekeeping that has to be done for breakpoints between runs. - Note: this function gets called at the end of a run (by generic_mourn_inferior) - and when a run begins (by init_wait_for_inferior). */ + Note: this function gets called at the end of a run (by + generic_mourn_inferior) and when a run begins (by + init_wait_for_inferior). */ @@ -1308,14 +1349,15 @@ breakpoint_init_inferior (context) /* Don't issue the warning unless it's really needed... */ if (warning_needed && (context != inf_exited)) { - warning ("Exception catchpoints from last run were deleted, you must reinsert them explicitly"); + warning ("Exception catchpoints from last run were deleted."); + warning ("You must reinsert them explicitly."); warning_needed = 0; } } -/* 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 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. */ int breakpoint_here_p (pc) @@ -1340,8 +1382,9 @@ breakpoint_here_p (pc) return 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. */ +/* 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. */ int breakpoint_inserted_here_p (pc) @@ -1364,10 +1407,11 @@ breakpoint_inserted_here_p (pc) return 0; } -/* Return nonzero if FRAME is a dummy frame. We can't use PC_IN_CALL_DUMMY - because figuring out the saved SP would take too much time, at least using - get_saved_register on the 68k. This means that for this function to - work right a port must use the bp_call_dummy breakpoint. */ +/* Return nonzero if FRAME is a dummy frame. We can't use + PC_IN_CALL_DUMMY because figuring out the saved SP would take too + much time, at least using get_saved_register on the 68k. This + means that for this function to work right a port must use the + bp_call_dummy breakpoint. */ int frame_in_dummy (frame) @@ -1737,7 +1781,8 @@ print_it_normal (bs) printf_filtered ("forked"); else if (bs->breakpoint_at->type == bp_catch_vfork) printf_filtered ("vforked"); - printf_filtered (" process %d), ", bs->breakpoint_at->forked_inferior_pid); + printf_filtered (" process %d), ", + bs->breakpoint_at->forked_inferior_pid); return 0; } else if (bs->breakpoint_at->type == bp_catch_exec) @@ -1750,10 +1795,12 @@ print_it_normal (bs) } else if (bs->breakpoint_at->type == bp_catch_catch) { - if (current_exception_event && (CURRENT_EXCEPTION_KIND == EX_EVENT_CATCH)) + if (current_exception_event && + (CURRENT_EXCEPTION_KIND == EX_EVENT_CATCH)) { annotate_catchpoint (bs->breakpoint_at->number); - printf_filtered ("\nCatchpoint %d (exception caught), ", bs->breakpoint_at->number); + printf_filtered ("\nCatchpoint %d (exception caught), ", + bs->breakpoint_at->number); printf_filtered ("throw location "); if (CURRENT_EXCEPTION_THROW_PC && CURRENT_EXCEPTION_THROW_LINE) printf_filtered ("%s:%d", @@ -1771,19 +1818,21 @@ print_it_normal (bs) printf_filtered ("unknown"); printf_filtered ("\n"); - return 1; /* don't bother to print location frame info */ + return 1; /* don't bother to print location frame info */ } else { - return -1; /* really throw, some other bpstat will handle it */ + return -1; /* really throw, some other bpstat will handle it */ } } else if (bs->breakpoint_at->type == bp_catch_throw) { - if (current_exception_event && (CURRENT_EXCEPTION_KIND == EX_EVENT_THROW)) + if (current_exception_event && + (CURRENT_EXCEPTION_KIND == EX_EVENT_THROW)) { annotate_catchpoint (bs->breakpoint_at->number); - printf_filtered ("\nCatchpoint %d (exception thrown), ", bs->breakpoint_at->number); + printf_filtered ("\nCatchpoint %d (exception thrown), ", + bs->breakpoint_at->number); printf_filtered ("throw location "); if (CURRENT_EXCEPTION_THROW_PC && CURRENT_EXCEPTION_THROW_LINE) printf_filtered ("%s:%d", @@ -1801,11 +1850,11 @@ print_it_normal (bs) printf_filtered ("unknown"); printf_filtered ("\n"); - return 1; /* don't bother to print location frame info */ + return 1; /* don't bother to print location frame info */ } else { - return -1; /* really catch, some other bpstat willhandle it */ + return -1; /* really catch, some other bpstat willhandle it */ } } @@ -1846,7 +1895,8 @@ print_it_normal (bs) printf_filtered ("\n"); return -1; } - /* We can't deal with it. Maybe another member of the bpstat chain can. */ + /* We can't deal with it. + Maybe another member of the bpstat chain can. */ return -1; } @@ -1883,8 +1933,8 @@ bpstat_print (bs) return val; /* Maybe another breakpoint in the chain caused us to stop. - (Currently all watchpoints go on the bpstat whether hit or - not. That probably could (should) be changed, provided care is taken + (Currently all watchpoints go on the bpstat whether hit or not. + That probably could (should) be changed, provided care is taken with respect to bpstat_explains_signal). */ if (bs->next) return bpstat_print (bs->next); @@ -2131,7 +2181,9 @@ bpstat_stop_status (pc, not_a_breakpoint) #if defined(SOLIB_HAVE_LOAD_EVENT) && (!SOLIB_HAVE_LOAD_EVENT (inferior_pid) || ((b->dll_pathname != NULL) - && (strcmp (b->dll_pathname, SOLIB_LOADED_LIBRARY_PATHNAME (inferior_pid)) != 0))) + && (strcmp (b->dll_pathname, + SOLIB_LOADED_LIBRARY_PATHNAME (inferior_pid)) + != 0))) #endif ) continue; @@ -2140,7 +2192,9 @@ bpstat_stop_status (pc, not_a_breakpoint) #if defined(SOLIB_HAVE_UNLOAD_EVENT) && (!SOLIB_HAVE_UNLOAD_EVENT (inferior_pid) || ((b->dll_pathname != NULL) - && (strcmp (b->dll_pathname, SOLIB_UNLOADED_LIBRARY_PATHNAME (inferior_pid)) != 0))) + && (strcmp (b->dll_pathname, + SOLIB_UNLOADED_LIBRARY_PATHNAME (inferior_pid)) + != 0))) #endif ) continue; @@ -2170,9 +2224,11 @@ bpstat_stop_status (pc, not_a_breakpoint) bs->print = 1; sprintf (message, message1, b->number); - if (b->type == bp_watchpoint || b->type == bp_hardware_watchpoint) + if (b->type == bp_watchpoint || + b->type == bp_hardware_watchpoint) { - switch (catch_errors (watchpoint_check, bs, message, RETURN_MASK_ALL)) + switch (catch_errors (watchpoint_check, bs, message, + RETURN_MASK_ALL)) { case WP_DELETED: /* We've already printed what needs to be printed. */ @@ -2206,7 +2262,8 @@ bpstat_stop_status (pc, not_a_breakpoint) break; } } - else if (b->type == bp_read_watchpoint || b->type == bp_access_watchpoint) + else if (b->type == bp_read_watchpoint || + b->type == bp_access_watchpoint) { CORE_ADDR addr; value_ptr v; @@ -2222,12 +2279,16 @@ bpstat_stop_status (pc, not_a_breakpoint) CORE_ADDR vaddr; vaddr = VALUE_ADDRESS (v) + VALUE_OFFSET (v); - if (addr == vaddr) + /* Exact match not required. Within range is sufficient. + */ + if (addr >= vaddr && + addr < vaddr + TYPE_LENGTH (VALUE_TYPE (v))) found = 1; } } if (found) - switch (catch_errors (watchpoint_check, bs, message, RETURN_MASK_ALL)) + switch (catch_errors (watchpoint_check, bs, message, + RETURN_MASK_ALL)) { case WP_DELETED: /* We've already printed what needs to be printed. */ @@ -2251,6 +2312,16 @@ bpstat_stop_status (pc, not_a_breakpoint) bs->print_it = print_it_done; break; } + else /* found == 0 */ + { + /* This is a case where some watchpoint(s) triggered, + but not at the address of this watchpoint (FOUND + was left zero). So don't print anything for this + watchpoint. */ + bs->print_it = print_it_noop; + bs->stop = 0; + continue; + } } else { @@ -2427,8 +2498,8 @@ bpstat_what (bs) as bp_silent and wp_noisy is the same as bp_noisy. That is because after stopping, the check for whether to step over a breakpoint (BPSTAT_WHAT_SINGLE type stuff) is handled in proceed() without - reference to how we stopped. We retain separate wp_silent and bp_silent - codes in case we want to change that someday. + reference to how we stopped. We retain separate wp_silent and + bp_silent codes in case we want to change that someday. Another possibly interesting property of this table is that there's a partial ordering, priority-like, of the actions. Once @@ -2548,8 +2619,8 @@ bpstat_what (bs) bs_class = wp_silent; } else - /* There was a watchpoint, but we're not stopping. This requires - no further action. */ + /* There was a watchpoint, but we're not stopping. + This requires no further action. */ bs_class = no_effect; break; case bp_longjmp: @@ -2597,8 +2668,8 @@ bpstat_what (bs) bs_class = bp_silent; } else - /* There was a catchpoint, but we're not stopping. This requires - no further action. */ + /* There was a catchpoint, but we're not stopping. + This requires no further action. */ bs_class = no_effect; break; case bp_catch_catch: @@ -2614,8 +2685,8 @@ bpstat_what (bs) bs_class = bs->print ? bp_noisy : bp_silent; break; case bp_call_dummy: - /* Make sure the action is stop (silent or noisy), so infrun.c - pops the dummy frame. */ + /* Make sure the action is stop (silent or noisy), + so infrun.c pops the dummy frame. */ bs_class = bp_silent; retval.call_dummy = 1; break; @@ -2681,7 +2752,8 @@ bpstat_get_triggered_catchpoints (ep_list, cp_list) if ((ep->type != bp_catch_load) && (ep->type != bp_catch_unload) && (ep->type != bp_catch_catch) && - (ep->type != bp_catch_throw)) /* pai: (temp) ADD fork/vfork here!! */ + (ep->type != bp_catch_throw)) + /* pai: (temp) ADD fork/vfork here!! */ continue; /* Yes; add it to the list. */ @@ -2707,7 +2779,8 @@ bpstat_get_triggered_catchpoints (ep_list, cp_list) #endif if (dll_pathname) { - ep->triggered_dll_pathname = (char *) xmalloc (strlen (dll_pathname) + 1); + ep->triggered_dll_pathname = (char *) + xmalloc (strlen (dll_pathname) + 1); strcpy (ep->triggered_dll_pathname, dll_pathname); } else @@ -2771,6 +2844,7 @@ breakpoint_1 (bnum, allflag) char wrap_indent[80]; + ALL_BREAKPOINTS (b) if (bnum == -1 || bnum == b->number) @@ -3063,7 +3137,9 @@ describe_other_breakpoints (pc, section) printf_filtered ("%d%s%s ", b->number, - ((b->enable == disabled || b->enable == shlib_disabled || b->enable == call_disabled) + ((b->enable == disabled || + b->enable == shlib_disabled || + b->enable == call_disabled) ? " (disabled)" : ""), (others > 1) ? "," : ((others == 1) ? " and" : "")); } @@ -3190,7 +3266,8 @@ create_longjmp_breakpoint (func_name) { struct minimal_symbol *m; - m = lookup_minimal_symbol_text (func_name, NULL, (struct objfile *) NULL); + m = lookup_minimal_symbol_text (func_name, NULL, + (struct objfile *) NULL); if (m) sal.pc = SYMBOL_VALUE_ADDRESS (m); else @@ -3212,8 +3289,8 @@ create_longjmp_breakpoint (func_name) #endif /* #ifdef GET_LONGJMP_TARGET */ -/* Call this routine when stepping and nexting to enable a breakpoint if we do - a longjmp(). When we hit that breakpoint, call +/* Call this routine when stepping and nexting to enable a breakpoint + if we do a longjmp(). When we hit that breakpoint, call set_longjmp_resume_breakpoint() to figure out where we are going. */ void @@ -3294,16 +3371,14 @@ disable_breakpoints_in_shlibs (silent) if (!disabled_shlib_breaks) { target_terminal_ours_for_output (); - printf_filtered ("Temporarily disabling shared library breakpoints:\n"); + warning ("Temporarily disabling shared library breakpoints:"); } disabled_shlib_breaks = 1; - printf_filtered ("%d ", b->number); + warning ("breakpoint #%d ", b->number); } } #endif } - if (disabled_shlib_breaks && !silent) - printf_filtered ("\n"); } /* Try to reenable any breakpoints in shared libraries. */ @@ -3327,7 +3402,7 @@ re_enable_breakpoints_in_shlibs () #endif static void -create_solib_load_unload_event_breakpoint (hookname, tempflag, dll_pathname, cond_string, bp_kind) +solib_load_unload_1 (hookname, tempflag, dll_pathname, cond_string, bp_kind) char *hookname; int tempflag; char *dll_pathname; @@ -3358,13 +3433,13 @@ create_solib_load_unload_event_breakpoint (hookname, tempflag, dll_pathname, con } if (sals.nelts != 1) { - warning ("Unable to set a unique breakpoint on dynamic linker callback."); + warning ("Unable to set unique breakpoint on dynamic linker callback."); warning ("GDB will be unable to track shl_load/shl_unload calls"); return; } - /* Make sure that all storage allocated in decode_line_1 gets freed in case - the following errors out. */ + /* Make sure that all storage allocated in decode_line_1 gets freed + in case the following errors out. */ old_chain = make_cleanup (free, sals.sals); if (canonical != (char **) NULL) { @@ -3384,7 +3459,8 @@ create_solib_load_unload_event_breakpoint (hookname, tempflag, dll_pathname, con set_breakpoint_count (breakpoint_count + 1); b->number = breakpoint_count; b->cond = NULL; - b->cond_string = (cond_string == NULL) ? NULL : savestring (cond_string, strlen (cond_string)); + b->cond_string = (cond_string == NULL) ? + NULL : savestring (cond_string, strlen (cond_string)); b->thread = thread; if (canonical != (char **) NULL && canonical[0] != NULL) @@ -3409,31 +3485,27 @@ create_solib_load_unload_event_breakpoint (hookname, tempflag, dll_pathname, con } void -create_solib_load_event_breakpoint (hookname, tempflag, dll_pathname, cond_string) +create_solib_load_event_breakpoint (hookname, tempflag, + dll_pathname, cond_string) char *hookname; int tempflag; char *dll_pathname; char *cond_string; { - create_solib_load_unload_event_breakpoint (hookname, - tempflag, - dll_pathname, - cond_string, - bp_catch_load); + solib_load_unload_1 (hookname, tempflag, dll_pathname, + cond_string, bp_catch_load); } void -create_solib_unload_event_breakpoint (hookname, tempflag, dll_pathname, cond_string) +create_solib_unload_event_breakpoint (hookname, tempflag, + dll_pathname, cond_string) char *hookname; int tempflag; char *dll_pathname; char *cond_string; { - create_solib_load_unload_event_breakpoint (hookname, - tempflag, - dll_pathname, - cond_string, - bp_catch_unload); + solib_load_unload_1 (hookname,tempflag, dll_pathname, + cond_string, bp_catch_unload); } static void @@ -3455,7 +3527,8 @@ create_fork_vfork_event_catchpoint (tempflag, cond_string, bp_kind) set_breakpoint_count (breakpoint_count + 1); b->number = breakpoint_count; b->cond = NULL; - b->cond_string = (cond_string == NULL) ? NULL : savestring (cond_string, strlen (cond_string)); + b->cond_string = (cond_string == NULL) ? + NULL : savestring (cond_string, strlen (cond_string)); b->thread = thread; b->addr_string = NULL; b->enable = enabled; @@ -3501,7 +3574,8 @@ create_exec_event_catchpoint (tempflag, cond_string) set_breakpoint_count (breakpoint_count + 1); b->number = breakpoint_count; b->cond = NULL; - b->cond_string = (cond_string == NULL) ? NULL : savestring (cond_string, strlen (cond_string)); + b->cond_string = (cond_string == NULL) ? + NULL : savestring (cond_string, strlen (cond_string)); b->thread = thread; b->addr_string = NULL; b->enable = enabled; @@ -3552,11 +3626,11 @@ hw_watchpoint_used_count (type, other_type_used) return i; } -/* Call this after hitting the longjmp() breakpoint. Use this to set a new - breakpoint at the target of the jmp_buf. +/* Call this after hitting the longjmp() breakpoint. Use this to set + a new breakpoint at the target of the jmp_buf. - FIXME - This ought to be done by setting a temporary breakpoint that gets - deleted automatically... */ + FIXME - This ought to be done by setting a temporary breakpoint + that gets deleted automatically... */ void set_longjmp_resume_breakpoint (pc, frame) @@ -3681,7 +3755,8 @@ mention (b) print_expression (b->exp, gdb_stdout); break; case bp_access_watchpoint: - printf_filtered ("Hardware access (read/write) watchpoint %d: ", b->number); + printf_filtered ("Hardware access (read/write) watchpoint %d: ", + b->number); print_expression (b->exp, gdb_stdout); break; case bp_breakpoint: @@ -3697,7 +3772,8 @@ mention (b) printf_filtered ("Catchpoint %d (%s %s)", b->number, (b->type == bp_catch_load) ? "load" : "unload", - (b->dll_pathname != NULL) ? b->dll_pathname : "<any library>"); + (b->dll_pathname != NULL) ? + b->dll_pathname : "<any library>"); break; case bp_catch_fork: case bp_catch_vfork: @@ -3821,8 +3897,8 @@ break_command_1 (arg, flag, from_tty) if (!sals.nelts) return; - /* Make sure that all storage allocated in decode_line_1 gets freed in case - the following `for' loop errors out. */ + /* Make sure that all storage allocated in decode_line_1 gets freed + in case the following `for' loop errors out. */ old_chain = make_cleanup (free, sals.sals); if (canonical != (char **) NULL) { @@ -3861,7 +3937,8 @@ break_command_1 (arg, flag, from_tty) try to make a breakpoint for it. */ if (PC_REQUIRES_RUN_BEFORE_USE (sals.sals[i].pc)) { - error ("Cannot break on %s without a running program.", addr_start); + error ("Cannot break on %s without a running program.", + addr_start); } tok = arg; @@ -3905,8 +3982,9 @@ break_command_1 (arg, flag, from_tty) int i, target_resources_ok; i = hw_breakpoint_used_count (); - target_resources_ok = TARGET_CAN_USE_HARDWARE_WATCHPOINT ( - bp_hardware_breakpoint, i + sals.nelts, 0); + target_resources_ok = + TARGET_CAN_USE_HARDWARE_WATCHPOINT (bp_hardware_breakpoint, + i + sals.nelts, 0); if (target_resources_ok == 0) error ("No hardware breakpoint support in the target."); else if (target_resources_ok < 0) @@ -3948,8 +4026,8 @@ break_command_1 (arg, flag, from_tty) if (sals.nelts > 1) { - printf_filtered ("Multiple breakpoints were set.\n"); - printf_filtered ("Use the \"delete\" command to delete unwanted breakpoints.\n"); + warning ("Multiple breakpoints were set."); + warning ("Use the \"delete\" command to delete unwanted breakpoints."); } do_cleanups (old_chain); } @@ -4114,8 +4192,8 @@ break_at_finish_command_1 (arg, flag, from_tty) } if (sals.nelts > 1) { - printf_filtered ("Multiple breakpoints were set.\n"); - printf_filtered ("Use the \"delete\" command to delete unwanted breakpoints.\n"); + warning ("Multiple breakpoints were set.\n"); + warning ("Use the \"delete\" command to delete unwanted breakpoints."); } do_cleanups (old_chain); } @@ -4251,9 +4329,9 @@ stopin_command (arg, from_tty) char *argptr = arg; int hasColon = 0; - /* look for a ':'. If this is a line number specification, then say - it is bad, otherwise, it should be an address or function/method - name */ + /* look for a ':'. If this is a line number specification, then + say it is bad, otherwise, it should be an address or + function/method name */ while (*argptr && !hasColon) { hasColon = (*argptr == ':'); @@ -4307,7 +4385,9 @@ stopat_command (arg, from_tty) } /* ARGSUSED */ -/* accessflag: 0: watch write, 1: watch read, 2: watch access(read or write) */ +/* accessflag: hw_write: watch write, + hw_read: watch read, + hw_access: watch access (read or write) */ static void watch_command_1 (arg, accessflag, from_tty) char *arg; @@ -4364,9 +4444,9 @@ watch_command_1 (arg, accessflag, from_tty) if (*tok) error ("Junk at end of command."); - if (accessflag == 1) + if (accessflag == hw_read) bp_type = bp_read_watchpoint; - else if (accessflag == 2) + else if (accessflag == hw_access) bp_type = bp_access_watchpoint; else bp_type = bp_hardware_watchpoint; @@ -4377,12 +4457,14 @@ watch_command_1 (arg, accessflag, from_tty) if (mem_cnt != 0) { i = hw_watchpoint_used_count (bp_type, &other_type_used); - target_resources_ok = TARGET_CAN_USE_HARDWARE_WATCHPOINT ( - bp_type, i + mem_cnt, other_type_used); + target_resources_ok = + TARGET_CAN_USE_HARDWARE_WATCHPOINT (bp_type, i + mem_cnt, + other_type_used); if (target_resources_ok == 0 && bp_type != bp_hardware_watchpoint) - error ("Target does not have this type of hardware watchpoint support."); + error ("Target does not support this type of hardware watchpoint."); + if (target_resources_ok < 0 && bp_type != bp_hardware_watchpoint) - error ("Target resources have been allocated for other types of watchpoints."); + error ("Target can only support one kind of HW watchpoint at a time."); } #if defined(HPUXHPPA) @@ -4480,8 +4562,13 @@ watch_command_1 (arg, accessflag, from_tty) in hardware return zero. */ #if !defined(TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT) -#define TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT(byte_size) \ - ((byte_size) <= (REGISTER_SIZE)) +#define TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT(BYTE_SIZE) \ + ((BYTE_SIZE) <= (REGISTER_SIZE)) +#endif + +#if !defined(TARGET_REGION_OK_FOR_HW_WATCHPOINT) +#define TARGET_REGION_OK_FOR_HW_WATCHPOINT(ADDR,LEN) \ + TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT(LEN) #endif static int @@ -4502,11 +4589,18 @@ can_use_hardware_watchpoint (v) { if (v->lval == lval_memory) { - if (TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT (TYPE_LENGTH (VALUE_TYPE (v)))) + CORE_ADDR vaddr = VALUE_ADDRESS (v) + VALUE_OFFSET (v); + int len = TYPE_LENGTH (VALUE_TYPE (v)); + + if (!TARGET_REGION_OK_FOR_HW_WATCHPOINT (vaddr, len)) + return 0; + else found_memory_cnt++; } else if (v->lval != not_lval && v->modifiable == 0) - return 0; + return 0; /* ??? What does this represent? */ + else if (v->lval == lval_register) + return 0; /* cannot watch a register with a HW watchpoint */ } /* The expression itself looks suitable for using a hardware @@ -4519,7 +4613,7 @@ watch_command (arg, from_tty) char *arg; int from_tty; { - watch_command_1 (arg, 0, from_tty); + watch_command_1 (arg, hw_write, from_tty); } static void @@ -4527,7 +4621,7 @@ rwatch_command (arg, from_tty) char *arg; int from_tty; { - watch_command_1 (arg, 1, from_tty); + watch_command_1 (arg, hw_read, from_tty); } static void @@ -4535,7 +4629,7 @@ awatch_command (arg, from_tty) char *arg; int from_tty; { - watch_command_1 (arg, 2, from_tty); + watch_command_1 (arg, hw_access, from_tty); } @@ -4578,7 +4672,8 @@ until_break_command (arg, from_tty) sals = decode_line_1 (&arg, 1, default_breakpoint_symtab, default_breakpoint_line, (char ***) NULL); else - sals = decode_line_1 (&arg, 1, (struct symtab *) NULL, 0, (char ***) NULL); + sals = decode_line_1 (&arg, 1, (struct symtab *) NULL, + 0, (char ***) NULL); if (sals.nelts != 1) error ("Couldn't get information on specified line."); @@ -4594,7 +4689,8 @@ until_break_command (arg, from_tty) breakpoint = set_momentary_breakpoint (sal, selected_frame, bp_until); if (!async_p || !target_has_async) - old_chain = make_cleanup ((make_cleanup_func) delete_breakpoint, breakpoint); + old_chain = make_cleanup ((make_cleanup_func) delete_breakpoint, + breakpoint); else make_exec_cleanup ((make_cleanup_func) delete_breakpoint, breakpoint); @@ -4806,7 +4902,8 @@ get_catch_sals (this_level_only) struct sal_chain *next = (struct sal_chain *) alloca (sizeof (struct sal_chain)); next->next = sal_chain; - next->sal = find_pc_line (SYMBOL_VALUE_ADDRESS (sym), 0); + next->sal = find_pc_line (SYMBOL_VALUE_ADDRESS (sym), + 0); sal_chain = next; } } @@ -4860,6 +4957,7 @@ ep_skip_leading_whitespace (s) that might be an event name in the leading characters. If a possible match is found, a pointer to the last character of the token is returned. Else, NULL is returned. */ + static char * ep_find_event_name_end (arg) char *arg; @@ -4893,6 +4991,7 @@ ep_find_event_name_end (arg) attempt to evaluate the string against a particular block.) And, it updates arg to point to the first character following the parsed if clause in the arg string. */ + static char * ep_parse_optional_if_clause (arg) char **arg; @@ -4962,7 +5061,10 @@ typedef enum } catch_fork_kind; -static void catch_fork_command_1 PARAMS ((catch_fork_kind fork_kind, char *arg, int tempflag, int from_tty)); +static void catch_fork_command_1 PARAMS ((catch_fork_kind fork_kind, + char *arg, + int tempflag, + int from_tty)); static void catch_fork_command_1 (fork_kind, arg, tempflag, from_tty) @@ -5068,7 +5170,8 @@ catch_load_command_1 (arg, tempflag, from_tty) /* Create a load breakpoint that only triggers when a load of the specified dll (or any dll, if no pathname was specified) occurs. */ - SOLIB_CREATE_CATCH_LOAD_HOOK (inferior_pid, tempflag, dll_pathname, cond_string); + SOLIB_CREATE_CATCH_LOAD_HOOK (inferior_pid, tempflag, + dll_pathname, cond_string); } static void @@ -5112,7 +5215,8 @@ catch_unload_command_1 (arg, tempflag, from_tty) /* Create an unload breakpoint that only triggers when an unload of the specified dll (or any dll, if no pathname was specified) occurs. */ - SOLIB_CREATE_CATCH_UNLOAD_HOOK (inferior_pid, tempflag, dll_pathname, cond_string); + SOLIB_CREATE_CATCH_UNLOAD_HOOK (inferior_pid, tempflag, + dll_pathname, cond_string); } #endif /* SOLIB_ADD */ @@ -5139,7 +5243,8 @@ create_exception_catchpoint (tempflag, cond_string, ex_event, sal) set_breakpoint_count (breakpoint_count + 1); b->number = breakpoint_count; b->cond = NULL; - b->cond_string = (cond_string == NULL) ? NULL : savestring (cond_string, strlen (cond_string)); + b->cond_string = (cond_string == NULL) ? + NULL : savestring (cond_string, strlen (cond_string)); b->thread = thread; b->addr_string = NULL; b->enable = enabled; @@ -5193,7 +5298,7 @@ catch_exception_command_1 (ex_event, arg, tempflag, from_tty) if (sal != (struct symtab_and_line *) -1) create_exception_catchpoint (tempflag, cond_string, ex_event, sal); else - return; /* something went wrong with setting up callbacks */ + return; /* something went wrong with setting up callbacks */ } else { @@ -5207,9 +5312,9 @@ catch_exception_command_1 (ex_event, arg, tempflag, from_tty) { /* Set a breakpoint on __raise_exception () */ - fprintf_filtered (gdb_stderr, "Unsupported with this platform/compiler combination.\n"); - fprintf_filtered (gdb_stderr, "Perhaps you can achieve the effect you want by setting\n"); - fprintf_filtered (gdb_stderr, "a breakpoint on __raise_exception().\n"); + warning ("Unsupported with this platform/compiler combination."); + warning ("Perhaps you can achieve the effect you want by setting"); + warning ("a breakpoint on __raise_exception()."); } } } @@ -5319,12 +5424,13 @@ handle_gnu_4_16_catch_command (arg, tempflag, from_tty) b = set_raw_breakpoint (sal); set_breakpoint_count (breakpoint_count + 1); b->number = breakpoint_count; - b->type = bp_breakpoint; /* Important -- this is an ordinary breakpoint. - For platforms with callback support for exceptions, - create_exception_catchpoint() will create special - bp types (bp_catch_catch and bp_catch_throw), and - there is code in insert_breakpoints() and elsewhere - that depends on that. */ + + /* Important -- this is an ordinary breakpoint. For platforms + with callback support for exceptions, + create_exception_catchpoint() will create special bp types + (bp_catch_catch and bp_catch_throw), and there is code in + insert_breakpoints() and elsewhere that depends on that. */ + b->type = bp_breakpoint; b->cond = cond; b->enable = enabled; @@ -5335,8 +5441,8 @@ handle_gnu_4_16_catch_command (arg, tempflag, from_tty) if (sals.nelts > 1) { - printf_unfiltered ("Multiple breakpoints were set.\n"); - printf_unfiltered ("Use the \"delete\" command to delete unwanted breakpoints.\n"); + warning ("Multiple breakpoints were set."); + warning ("Use the \"delete\" command to delete unwanted breakpoints."); } free ((PTR) sals.sals); } @@ -5407,11 +5513,13 @@ catch_command_1 (arg, tempflag, from_tty) } else if (strncmp (arg1_start, "catch", arg1_length) == 0) { - catch_exception_command_1 (EX_EVENT_CATCH, arg1_end + 1, tempflag, from_tty); + catch_exception_command_1 (EX_EVENT_CATCH, arg1_end + 1, + tempflag, from_tty); } else if (strncmp (arg1_start, "throw", arg1_length) == 0) { - catch_exception_command_1 (EX_EVENT_THROW, arg1_end + 1, tempflag, from_tty); + catch_exception_command_1 (EX_EVENT_THROW, arg1_end + 1, + tempflag, from_tty); } else if (strncmp (arg1_start, "thread_start", arg1_length) == 0) { @@ -5710,7 +5818,8 @@ breakpoint_auto_delete (bs) } } -/* Delete a breakpoint and clean up all traces of it in the data structures. */ +/* Delete a breakpoint and clean up all traces of it in the data + structures. */ void delete_breakpoint (bpt) @@ -5760,8 +5869,10 @@ delete_breakpoint (bpt) static char message[sizeof (message1) + 30]; args_for_catchpoint_enable args; - sprintf (message, message1, bpt->number); /* Format possible error msg */ - args.kind = bpt->type == bp_catch_catch ? EX_EVENT_CATCH : EX_EVENT_THROW; + /* Format possible error msg */ + sprintf (message, message1, bpt->number); + args.kind = bpt->type == bp_catch_catch ? + EX_EVENT_CATCH : EX_EVENT_THROW; args.enable = 0; catch_errors (cover_target_enable_exception_callback, &args, message, RETURN_MASK_ALL); @@ -5815,11 +5926,16 @@ delete_breakpoint (bpt) && b->enable != call_disabled) { int val; - val = target_insert_breakpoint (b->address, b->shadow_contents); + + if (b->type == bp_hardware_breakpoint) + val = target_insert_hw_breakpoint (b->address, b->shadow_contents); + else + val = target_insert_breakpoint (b->address, b->shadow_contents); + if (val != 0) { target_terminal_ours_for_output (); - fprintf_unfiltered (gdb_stderr, "Cannot insert breakpoint %d:\n", b->number); + warning ("Cannot insert breakpoint %d:", b->number); memory_error (val, b->address); /* which bombs us out */ } else @@ -5919,7 +6035,8 @@ static int breakpoint_re_set_one (bint) PTR bint; { - struct breakpoint *b = (struct breakpoint *) bint; /* get past catch_errs */ + /* get past catch_errs */ + struct breakpoint *b = (struct breakpoint *) bint; struct value *mark; int i; struct symtabs_and_lines sals; @@ -5929,7 +6046,8 @@ breakpoint_re_set_one (bint) switch (b->type) { case bp_none: - warning ("attempted to reset apparently deleted breakpoint #%d?\n", b->number); + warning ("attempted to reset apparently deleted breakpoint #%d?", + b->number); return 0; case bp_breakpoint: case bp_hardware_breakpoint: @@ -6016,13 +6134,14 @@ breakpoint_re_set_one (bint) case bp_read_watchpoint: case bp_access_watchpoint: innermost_block = NULL; - /* The issue arises of what context to evaluate this in. The same - one as when it was set, but what does that mean when symbols have - been re-read? We could save the filename and functionname, but - if the context is more local than that, the best we could do would - be something like how many levels deep and which index at that - particular level, but that's going to be less stable than filenames - or functionnames. */ + /* The issue arises of what context to evaluate this in. The + same one as when it was set, but what does that mean when + symbols have been re-read? We could save the filename and + functionname, but if the context is more local than that, the + best we could do would be something like how many levels deep + and which index at that particular level, but that's going to + be less stable than filenames or function names. */ + /* So for now, just use a global context. */ if (b->exp) free ((PTR) b->exp); @@ -6101,7 +6220,8 @@ breakpoint_re_set () save_input_radix = input_radix; ALL_BREAKPOINTS_SAFE (b, temp) { - sprintf (message, message1, b->number); /* Format possible error msg */ + /* Format possible error msg */ + sprintf (message, message1, b->number); catch_errors (breakpoint_re_set_one, b, message, RETURN_MASK_ALL); } set_language (save_language); @@ -6275,7 +6395,8 @@ disable_command (args, from_tty) switch (bpt->type) { case bp_none: - warning ("attempted to disable apparently deleted breakpoint #%d?\n", bpt->number); + warning ("attempted to disable apparently deleted breakpoint #%d?", + bpt->number); continue; case bp_breakpoint: case bp_catch_load: @@ -6312,8 +6433,9 @@ do_enable_breakpoint (bpt, disposition) { int i; i = hw_breakpoint_used_count (); - target_resources_ok = TARGET_CAN_USE_HARDWARE_WATCHPOINT ( - bp_hardware_breakpoint, i + 1, 0); + target_resources_ok = + TARGET_CAN_USE_HARDWARE_WATCHPOINT (bp_hardware_breakpoint, + i + 1, 0); if (target_resources_ok == 0) error ("No hardware breakpoint support in the target."); else if (target_resources_ok < 0) @@ -6325,8 +6447,10 @@ do_enable_breakpoint (bpt, disposition) check_duplicates (bpt->address, bpt->section); breakpoints_changed (); - if (bpt->type == bp_watchpoint || bpt->type == bp_hardware_watchpoint || - bpt->type == bp_read_watchpoint || bpt->type == bp_access_watchpoint) + if (bpt->type == bp_watchpoint || + bpt->type == bp_hardware_watchpoint || + bpt->type == bp_read_watchpoint || + bpt->type == bp_access_watchpoint) { if (bpt->exp_valid_block != NULL) { @@ -6383,7 +6507,8 @@ have been allocated for other watchpoints.\n", bpt->number); } if (save_selected_frame_level >= 0) - select_and_print_frame (save_selected_frame, save_selected_frame_level); + select_and_print_frame (save_selected_frame, + save_selected_frame_level); value_free_to_mark (mark); } if (modify_breakpoint_hook) @@ -6413,7 +6538,8 @@ enable_command (args, from_tty) switch (bpt->type) { case bp_none: - warning ("attempted to enable apparently deleted breakpoint #%d?\n", bpt->number); + warning ("attempted to enable apparently deleted breakpoint #%d?", + bpt->number); continue; case bp_breakpoint: case bp_catch_load: @@ -6480,7 +6606,8 @@ decode_line_spec_1 (string, funfirstline) error ("Empty line specification."); if (default_breakpoint_valid) sals = decode_line_1 (&string, funfirstline, - default_breakpoint_symtab, default_breakpoint_line, + default_breakpoint_symtab, + default_breakpoint_line, (char ***) NULL); else sals = decode_line_1 (&string, funfirstline, @@ -6797,7 +6924,6 @@ so it will be deleted when hit. Equivalent to \"catch\" followed\n\ by using \"enable delete\" on the catchpoint number."); add_com ("watch", class_breakpoint, watch_command, - "Set a watchpoint for an expression.\n\ A watchpoint stops execution of your program whenever the value of\n\ an expression changes."); diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h index 8061e86..3f710aa 100644 --- a/gdb/breakpoint.h +++ b/gdb/breakpoint.h @@ -122,17 +122,18 @@ enum bptype enum enable { - disabled, /* The eventpoint is inactive, and cannot trigger. */ - enabled, /* The eventpoint is active, and can trigger. */ - shlib_disabled, /* The eventpoint's address is within an unloaded solib. - The eventpoint will be automatically enabled & reset - when that solib is loaded. */ - 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 - & reset when the call "lands" (either completes, or - stops at another eventpoint). */ + disabled, /* The eventpoint is inactive, and cannot trigger. */ + enabled, /* The eventpoint is active, and can trigger. */ + 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 + 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). */ }; @@ -146,6 +147,14 @@ enum bpdisp donttouch /* Leave it alone */ }; +enum target_hw_bp_type + { + hw_write = 0, /* Common HW watchpoint */ + hw_read = 1, /* Read HW watchpoint */ + hw_access = 2, /* Access HW watchpoint */ + hw_execute = 3 /* Execute HW breakpoint */ + }; + /* Note that the ->silent field is not currently used by any commands (though the code is in there if it was to be, and set_raw_breakpoint does set it to 0). I implemented it because I thought it would be @@ -248,8 +257,9 @@ struct breakpoint aborting, so you can back up to just before the abort. */ int hit_count; - /* Filename of a dynamically-linked library (dll), used for bp_catch_load - and bp_catch_unload (malloc'd), or NULL if any library is significant. */ + /* Filename of a dynamically-linked library (dll), used for + bp_catch_load and bp_catch_unload (malloc'd), or NULL if any + library is significant. */ char *dll_pathname; /* Filename of a dll whose state change (e.g., load or unload) @@ -257,20 +267,22 @@ struct breakpoint after this catchpoint has triggered. */ char *triggered_dll_pathname; - /* Process id of a child process whose forking triggered this catchpoint. - This field is only vaid immediately after this catchpoint has triggered. */ + /* Process id of a child process whose forking triggered this + catchpoint. This field is only vaid immediately after this + catchpoint has triggered. */ int forked_inferior_pid; - /* Filename of a program whose exec triggered this catchpoint. This - field is only vaid immediately after this catchpoint has triggered. */ + /* Filename of a program whose exec triggered this catchpoint. + This field is only vaid immediately after this catchpoint has + triggered. */ char *exec_pathname; asection *section; }; -/* The following stuff is an abstract data type "bpstat" ("breakpoint status"). - This provides the ability to determine whether we have stopped at a - breakpoint, and what we should do about it. */ +/* The following stuff is an abstract data type "bpstat" ("breakpoint + status"). This provides the ability to determine whether we have + stopped at a breakpoint, and what we should do about it. */ typedef struct bpstats *bpstat; @@ -417,8 +429,8 @@ extern void bpstat_get_triggered_catchpoints PARAMS ((bpstat, bpstat *)); /* Implementation: */ struct bpstats { - /* Linked list because there can be two breakpoints at the - same place, and a bpstat reflects the fact that both have been hit. */ + /* Linked list because there can be two breakpoints at the same + place, and a bpstat reflects the fact that both have been hit. */ bpstat next; /* Breakpoint that we are at. */ struct breakpoint *breakpoint_at; @@ -474,7 +486,8 @@ extern struct breakpoint *set_momentary_breakpoint extern void set_ignore_count PARAMS ((int, int, int)); -extern void set_default_breakpoint PARAMS ((int, CORE_ADDR, struct symtab *, int)); +extern void set_default_breakpoint PARAMS ((int, CORE_ADDR, + struct symtab *, int)); extern void mark_breakpoints_out PARAMS ((void)); @@ -588,9 +601,11 @@ extern void disable_breakpoints_in_shlibs PARAMS ((int silent)); extern void re_enable_breakpoints_in_shlibs PARAMS ((void)); -extern void create_solib_load_event_breakpoint PARAMS ((char *, int, char *, char *)); +extern void create_solib_load_event_breakpoint PARAMS ((char *, int, + char *, char *)); -extern void create_solib_unload_event_breakpoint PARAMS ((char *, int, char *, char *)); +extern void create_solib_unload_event_breakpoint PARAMS ((char *, int, + char *, char *)); extern void create_fork_event_catchpoint PARAMS ((int, char *)); diff --git a/gdb/command.c b/gdb/command.c index dc39265..277d7e5 100644 --- a/gdb/command.c +++ b/gdb/command.c @@ -36,6 +36,11 @@ #include "wait.h" +/* FIXME: this should be auto-configured! */ +#ifdef __MSDOS__ +# define CANT_FORK +#endif + /* Prototypes for local functions */ static void undef_cmd_error PARAMS ((char *, char *)); @@ -1453,9 +1458,29 @@ shell_escape (arg, from_tty) int from_tty; { #ifdef CANT_FORK - /* FIXME: what about errors (I don't know how GO32 system() handles - them)? */ - system (arg); + /* If ARG is NULL, they want an inferior shell, but `system' just + reports if the shell is available when passed a NULL arg. */ + int rc = system (arg ? arg : ""); + + if (!arg) + arg = "inferior shell"; + + if (rc == -1) + { + fprintf_unfiltered (gdb_stderr, "Cannot execute %s: %s\n", arg, + safe_strerror (errno)); + gdb_flush (gdb_stderr); + } + else if (rc) + { + fprintf_unfiltered (gdb_stderr, "%s exited with status %d\n", arg, rc); + gdb_flush (gdb_stderr); + } +#ifdef __DJGPP__ + /* Make sure to return to the directory GDB thinks it is, in case the + shell command we just ran changed it. */ + chdir (current_directory); +#endif #else /* Can fork. */ int rc, status, pid; char *p, *user_shell; diff --git a/gdb/config/i386/nm-go32.h b/gdb/config/i386/nm-go32.h index ba79c1b..3a9d224 100644 --- a/gdb/config/i386/nm-go32.h +++ b/gdb/config/i386/nm-go32.h @@ -24,8 +24,31 @@ #define TARGET_HAS_HARDWARE_WATCHPOINTS +/* Returns the number of hardware watchpoints of type TYPE that we can + set. Value is positive if we can set CNT watchpoints, zero if + setting watchpoints of type TYPE is not supported, and negative if + CNT is more than the maximum number of watchpoints of type TYPE + that we can support. TYPE is one of bp_hardware_watchpoint, + bp_read_watchpoint, bp_write_watchpoint, or bp_hardware_breakpoint. + CNT is the number of such watchpoints used so far (including this + one). OTHERTYPE is non-zero if other types of watchpoints are + currently enabled. + + We always return 1 here because we don't have enough information + about possible overlap of addresses that they want to watch. As + an extreme example, consider the case where all the watchpoints + watch the same address and the same region length: then we can + handle a virtually unlimited number of watchpoints, due to debug + register sharing implemented via reference counts in go32-nat.c. */ + #define TARGET_CAN_USE_HARDWARE_WATCHPOINT(type, cnt, ot) 1 +/* Returns non-zero if we can use hardware watchpoints to watch a region + whose address is ADDR and whose length is LEN. */ + +#define TARGET_REGION_OK_FOR_HW_WATCHPOINT(addr,len) \ + go32_region_ok_for_watchpoint(addr,len) + /* After a watchpoint trap, the PC points to the instruction after the one that caused the trap. Therefore we don't need to step over it. But we do need to reset the status register to avoid another trap. */ @@ -33,15 +56,18 @@ #define HAVE_CONTINUABLE_WATCHPOINT #define STOPPED_BY_WATCHPOINT(W) \ - go32_stopped_by_watchpoint (inferior_pid) + go32_stopped_by_watchpoint (inferior_pid, 0) + +#define target_stopped_data_address() \ + go32_stopped_by_watchpoint (inferior_pid, 1) /* Use these macros for watchpoint insertion/removal. */ #define target_insert_watchpoint(addr, len, type) \ - go32_insert_watchpoint (inferior_pid, addr, len, 2) + go32_insert_watchpoint (inferior_pid, addr, len, type) #define target_remove_watchpoint(addr, len, type) \ - go32_remove_watchpoint (inferior_pid, addr, len) + go32_remove_watchpoint (inferior_pid, addr, len, type) #define target_insert_hw_breakpoint(addr, shadow) \ go32_insert_hw_breakpoint(addr, shadow) diff --git a/gdb/config/i386/xm-go32.h b/gdb/config/i386/xm-go32.h index cb8fc78..868074d 100644 --- a/gdb/config/i386/xm-go32.h +++ b/gdb/config/i386/xm-go32.h @@ -26,7 +26,7 @@ #define SLASH_P(X) ((X)=='\\' || (X) == '/') -#define ROOTED_P(X) ((SLASH_P((X)[0]))|| ((X)[1] ==':')) +#define ROOTED_P(X) ((SLASH_P((X)[0])) || ((X)[0] && (X)[1] ==':')) #define SLASH_CHAR '/' #define SLASH_STRING "/" diff --git a/gdb/config/pa/hppa64.mt b/gdb/config/pa/hppa64.mt index ea7559f..d55da77 100644 --- a/gdb/config/pa/hppa64.mt +++ b/gdb/config/pa/hppa64.mt @@ -1,4 +1,4 @@ # Target: HP PA-RISC 2.0 running HPUX 11.00 in wide mode -TDEPFILES= hppa-tdep.o # pa64-solib.o +TDEPFILES= hppa-tdep.o TM_FILE= tm-hppa64.h -TM_CLIBS= # $(srcdir)/libxpdl.a +TM_CLIBS= diff --git a/gdb/config/pa/hpux11.mh b/gdb/config/pa/hpux11.mh new file mode 100644 index 0000000..10fbd7e --- /dev/null +++ b/gdb/config/pa/hpux11.mh @@ -0,0 +1,11 @@ +# Host: Hewlett-Packard PA-RISC machine, running HPUX 11.00 + +MH_CFLAGS = -D__HP_CURSES + +XM_FILE= xm-hppah.h +XDEPFILES= ser-tcp.o + +NAT_FILE= nm-hppah11.h +NATDEPFILES= hppah-nat.o corelow.o core-aout.o inftarg.o fork-child.o infttrace.o somread.o hp-psymtab-read.o hp-symtab-read.o somsolib.o + +HOST_IPC=-DBSD_IPC -DPOSIX_WAIT diff --git a/gdb/config/pa/hpux11.mt b/gdb/config/pa/hpux11.mt new file mode 100644 index 0000000..405f73a --- /dev/null +++ b/gdb/config/pa/hpux11.mt @@ -0,0 +1,3 @@ +# Target: HP PA-RISC running HPUX 11.00 +TDEPFILES= hppa-tdep.o remote-pa.o somsolib.o +TM_FILE= tm-hppah.h diff --git a/gdb/config/pa/hpux11w.mh b/gdb/config/pa/hpux11w.mh new file mode 100644 index 0000000..248bb6e --- /dev/null +++ b/gdb/config/pa/hpux11w.mh @@ -0,0 +1,11 @@ +# Host: Hewlett-Packard PA-RISC machine, running HPUX 11.00 + +MH_CFLAGS = -D__HP_CURSES + +XM_FILE= xm-hppah.h +XDEPFILES= ser-tcp.o + +NAT_FILE= nm-hppah11.h +NATDEPFILES= hppah-nat.o corelow.o core-aout.o inftarg.o fork-child.o infttrace.o hp-psymtab-read.o hp-symtab-read.o pa64solib.o + +HOST_IPC=-DBSD_IPC -DPOSIX_WAIT diff --git a/gdb/config/pa/hpux11w.mt b/gdb/config/pa/hpux11w.mt new file mode 100644 index 0000000..4064d20 --- /dev/null +++ b/gdb/config/pa/hpux11w.mt @@ -0,0 +1,3 @@ +# Target: HP PA-RISC running HPUX 11.00 +TDEPFILES= hppa-tdep.o remote-pa.o +TM_FILE= tm-hppah.h diff --git a/gdb/config/pa/tm-hppa.h b/gdb/config/pa/tm-hppa.h index a35a098..907978f 100644 --- a/gdb/config/pa/tm-hppa.h +++ b/gdb/config/pa/tm-hppa.h @@ -565,6 +565,7 @@ extern void hppa_pop_frame PARAMS ((void)); #define CALL_DUMMY_LENGTH (INSTRUCTION_SIZE * 28) #define REG_PARM_STACK_SPACE 16 +#define ARGS_GROW_DOWNWARD #else /* defined PA_LEVEL_0 */ @@ -754,18 +755,11 @@ struct obj_unwind_info int last; /* Index of last entry */ }; -typedef struct data { - CORE_ADDR dummy[2]; - CORE_ADDR func_addr; - CORE_ADDR dp; -} opd_data; - typedef struct obj_private_struct { struct obj_unwind_info *unwind_info; /* a pointer */ struct so_list *so_info; /* a pointer */ - opd_data *opd; - int n_opd_entries; + CORE_ADDR dp; } obj_private_data_t; diff --git a/gdb/config/pa/tm-hppa64.h b/gdb/config/pa/tm-hppa64.h index ea9090f..11cfd3b 100644 --- a/gdb/config/pa/tm-hppa64.h +++ b/gdb/config/pa/tm-hppa64.h @@ -152,6 +152,7 @@ extern int hpread_adjust_stack_address PARAMS ((CORE_ADDR)); ; the right place, we load the first 8 word of arguments into both the general ; and fp registers. call_dummy + nop copy %r4,%r29 copy %r5,%r22 copy %r6,%r27 @@ -179,17 +180,23 @@ call_dummy nop */ +/* Call dummys are sized and written out in word sized hunks. So we have + to pack the instructions into words. Ugh. */ #undef CALL_DUMMY -#define CALL_DUMMY {0x349d0000, 0x34b60000, 0x34db0000, \ - 0x53a43f83, 0x53a53f93, 0x53a63fa3, 0x53a73fb3,\ - 0x53a83fc3, 0x53a93fd3, 0x2fa1100a, 0x2fb1100b,\ - 0x36c10000, 0x53ba3f81, 0x53b93f91, 0x53b83fa1,\ - 0x53b73fb1, 0x53b63fc1, 0x53b53fd1, 0x0fa110d4,\ - 0xe820f000, 0x0fb110d3, 0x00010004, 0x00151820,\ - 0xe6c00000, 0x08000240} - +#define CALL_DUMMY {0x08000240349d0000LL, 0x34b6000034db0000LL, \ + 0x53a43f8353a53f93LL, 0x53a63fa353a73fb3LL,\ + 0x53a83fc353a93fd3LL, 0x2fa1100a2fb1100bLL,\ + 0x36c1000053ba3f81LL, 0x53b93f9153b83fa1LL,\ + 0x53b73fb153b63fc1LL, 0x53b53fd10fa110d4LL,\ + 0xe820f0000fb110d3LL, 0x0001000400151820LL,\ + 0xe6c0000008000240LL} + +/* CALL_DUMMY_LENGTH is computed based on the size of a word on the target + machine, not the size of an instruction. Since a word on this target + holds two instructions we have to divide the instruction size by two to + get the word size of the dummy. */ #undef CALL_DUMMY_LENGTH -#define CALL_DUMMY_LENGTH (INSTRUCTION_SIZE * 25) +#define CALL_DUMMY_LENGTH (INSTRUCTION_SIZE * 26 / 2) /* The PA64 ABI mandates a 16 byte stack alignment. */ #undef STACK_ALIGN @@ -200,23 +207,15 @@ call_dummy #undef REG_PARM_STACK_SPACE #define REG_PARM_STACK_SPACE 64 +/* Arguments grow in the normal direction for the PA64 port. */ +#undef ARGS_GROW_DOWNWARD + #undef FUNC_LDIL_OFFSET #undef FUNC_LDO_OFFSET #undef SR4EXPORT_LDIL_OFFSET #undef SR4EXPORT_LDO_OFFSET #undef CALL_DUMMY_LOCATION -#define PC_IN_CALL_DUMMY(pc, sp, frame_address) hppa64_pc_in_call_dummy (pc) -/* jimb: need to find out what AT_WDB_CALL_DUMMY is about */ -#if 0 -#define CALL_DUMMY_LOCATION AFTER_TEXT_END -extern CORE_ADDR wdb_call_dummy_addr; -#undef PC_IN_CALL_DUMMY -#define PC_IN_CALL_DUMMY(pc, sp, frame_address) \ - ((pc) >= wdb_call_dummy_addr && \ - (pc) <= wdb_call_dummy_addr + CALL_DUMMY_LENGTH) -#endif - #undef REG_STRUCT_HAS_ADDR #undef EXTRACT_RETURN_VALUE diff --git a/gdb/configure.host b/gdb/configure.host index 7ee60ef..dae1801a 100644 --- a/gdb/configure.host +++ b/gdb/configure.host @@ -42,8 +42,8 @@ arm-*-*) gdb_host=arm ;; hppa*-*-bsd*) gdb_host=hppabsd ;; hppa*-*-hiux*) gdb_host=hppahpux ;; hppa*-*-hpux10.20) gdb_host=hpux1020 ;; -hppa2.0w-*-hpux11*) gdb_host=hpux1100w ;; -hppa*-*-hpux11*) gdb_host=hpux1100 ;; +hppa2.0w-*-hpux11*) gdb_host=hpux11w ;; +hppa*-*-hpux11*) gdb_host=hpux11 ;; hppa*-*-hpux*) gdb_host=hppahpux ;; hppa*-*-osf*) gdb_host=hppaosf ;; @@ -574,10 +574,29 @@ extern char *symtab_to_filename PARAMS ((struct symtab *)); extern int read_relative_register_raw_bytes PARAMS ((int, char *)); -#if __STDC__ -enum lval_type; +/* Possible lvalue types. Like enum language, this should be in + value.h, but needs to be here for the same reason. */ + +enum lval_type + { + /* Not an lval. */ + not_lval, + /* In memory. Could be a saved register. */ + lval_memory, + /* In a register. */ + lval_register, + /* In a gdb internal variable. */ + lval_internalvar, + /* Part of a gdb internal variable (structure field). */ + lval_internalvar_component, + /* In a register series in a frame not the current one, which may have been + partially saved or saved in different places (otherwise would be + lval_register or lval_memory). */ + lval_reg_frame_relative + }; + struct frame_info; -#endif + void default_get_saved_register PARAMS ((char *raw_buffer, int *optimized, CORE_ADDR *addrp, struct frame_info *frame, int regnum, diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index 46bb910..98e37cf 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,21 @@ +1999-08-20 Stan Shebs <shebs@andros.cygnus.com> + + * gdb.texinfo: Remove remaining "HPPA" conditionals, rewrite + surrounding text to fit HP-UX bits into general info. + (HPPA-cfg.texi): Remove, no longer useful. + + * gdb.texinfo: Remove explicit links from @node lines, remove + HP-added "Detailed Node Listing" from main menu which confuses + things. + + From Dmitry Sivachenko <dima@Chg.RU>: + * gdb.texinfo: Use @value{GDBN} instead of plain GDB, fix grouping + in description of `set environment'. + +1999-08-17 Stan Shebs <shebs@andros.cygnus.com> + + * gdbint.texinfo: Update coding standard to allow pure ANSI/ISO C. + 1999-08-12 Ben Elliston <bje@cygnus.com> * gdbint.texinfo (Breakpoint Handling): Add missing words. diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index d150881..7d77765 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -77,45 +77,28 @@ into another language, under the above conditions for modified versions. @title Debugging with @value{GDBN} @subtitle The @sc{gnu} Source-Level Debugger @sp 1 -@ifclear HPPA @subtitle @value{EDITION} Edition, for @value{GDBN} version @value{GDBVN} @subtitle @value{DATE} @author Richard M. Stallman and Roland H. Pesch -@end ifclear -@ifset HPPA -@subtitle Edition @value{EDITION}, for @value{HPVER} (based on @value{GDBN} @value{GDBVN}) -@subtitle @value{DATE} -@author Richard M. Stallman and Roland H. Pesch (modified by HP) -@end ifset @page -@ifclear HPPA @tex {\parskip=0pt -\hfill (Send bugs and comments on @value{GDBN} to bug-gdb\@prep.ai.mit.edu.)\par +\hfill (Send bugs and comments on @value{GDBN} to bug-gdb\@gnu.org.)\par \hfill {\it Debugging with @value{GDBN}}\par \hfill \TeX{}info \texinfoversion\par } @end tex -@end ifclear -@ifset HPPA -@tex -{\parskip=0pt -\hfill {\it Debugging with @value{GDBN}}\par -\hfill \TeX{}info \texinfoversion\par -} -@end tex -@end ifset + +@c ISBN seems to be wrong... @vskip 0pt plus 1filll Copyright @copyright{} 1988-1999 Free Software Foundation, Inc. @sp 2 -@ifclear HPPA Published by the Free Software Foundation @* 59 Temple Place - Suite 330, @* Boston, MA 02111-1307 USA @* Printed copies are available for $20 each. @* ISBN 1-882114-11-6 @* -@end ifclear Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice @@ -132,7 +115,7 @@ into another language, under the above conditions for modified versions. @page @ifinfo -@node Top, Summary, (dir), (dir) +@node Top @top Debugging with @value{GDBN} This file describes @value{GDBN}, the @sc{gnu} symbolic debugger. @@ -154,7 +137,6 @@ Copyright (C) 1988-1999 Free Software Foundation, Inc. * Data:: Examining data * Languages:: Using @value{GDBN} with different languages -* C:: C language support * Symbols:: Examining the symbol table * Altering:: Altering execution @@ -165,221 +147,17 @@ Copyright (C) 1988-1999 Free Software Foundation, Inc. * Emacs:: Using @value{GDBN} under @sc{gnu} Emacs * GDB Bugs:: Reporting bugs in @value{GDBN} - -@ifclear PRECONFIGURED -@ifclear HPPA * Formatting Documentation:: How to format and print @value{GDBN} documentation -@end ifclear - -@end ifclear * Command Line Editing:: Command Line Editing * Using History Interactively:: Using History Interactively * Installing GDB:: Installing GDB * Index:: Index - - --- The Detailed Node Listing --- - -Summary of @value{GDBN} - -* Free Software:: Freely redistributable software -* Contributors:: Contributors to GDB - -Getting In and Out of @value{GDBN} - -* Invoking GDB:: How to start @value{GDBN} -* Quitting GDB:: How to quit @value{GDBN} -* Shell Commands:: How to use shell commands inside @value{GDBN} - -Invoking @value{GDBN} - -* File Options:: Choosing files -* Mode Options:: Choosing modes - -@value{GDBN} Commands - -* Command Syntax:: How to give commands to @value{GDBN} -* Completion:: Command completion -* Help:: How to ask @value{GDBN} for help - -Running Programs Under @value{GDBN} - -* Compilation:: Compiling for debugging -* Starting:: Starting your program -* Arguments:: Your program's arguments -* Environment:: Your program's environment -* Working Directory:: Your program's working directory -* Input/Output:: Your program's input and output -* Attach:: Debugging an already-running process -* Kill Process:: Killing the child process -* Process Information:: Additional process information - -* Threads:: Debugging programs with multiple threads -* Processes:: Debugging programs with multiple processes - -Stopping and Continuing - -* Breakpoints:: Breakpoints, watchpoints, and catchpoints -* Continuing and Stepping:: Resuming execution -* Signals:: Signals -* Thread Stops:: Stopping and starting multi-thread programs - -Breakpoints and watchpoints - -* Set Breaks:: Setting breakpoints -* Set Watchpoints:: Setting watchpoints -* Set Catchpoints:: Setting catchpoints -* Delete Breaks:: Deleting breakpoints -* Disabling:: Disabling breakpoints -* Conditions:: Break conditions -* Break Commands:: Breakpoint command lists -* Breakpoint Menus:: Breakpoint menus - -Examining the Stack - -* Frames:: Stack frames -* Backtrace:: Backtraces -* Selection:: Selecting a frame -* Frame Info:: Information on a frame -* Alpha/MIPS Stack:: Alpha and MIPS machines and the function stack - -Examining Source Files - -* List:: Printing source lines -* Search:: Searching source files -* Source Path:: Specifying source directories -* Machine Code:: Source and machine code - -Examining Data - -* Expressions:: Expressions -* Variables:: Program variables -* Arrays:: Artificial arrays -* Output Formats:: Output formats -* Memory:: Examining memory -* Auto Display:: Automatic display -* Print Settings:: Print settings -* Value History:: Value history -* Convenience Vars:: Convenience variables -* Registers:: Registers -* Floating Point Hardware:: Floating point hardware - -Using @value{GDBN} with Different Languages - -* Setting:: Switching between source languages -* Show:: Displaying the language -* Checks:: Type and range checks -* Support:: Supported languages - -Switching between source languages - -* Filenames:: Filename extensions and languages. -* Manually:: Setting the working language manually -* Automatically:: Having @value{GDBN} infer the source language - -Type and range checking - -* Type Checking:: An overview of type checking -* Range Checking:: An overview of range checking - -Supported languages - -C Language Support - -* C:: C and C++ -* C Operators:: C and C++ operators -* C Constants:: C and C++ constants -* C plus plus expressions:: C++ expressions -* C Defaults:: Default settings for C and C++ -* C Checks:: C and C++ type and range checks -* Debugging C:: @value{GDBN} and C -* Debugging C plus plus:: @value{GDBN} features for C++ - -Modula-2 - -* M2 Operators:: Built-in operators -* Built-In Func/Proc:: Built-in functions and procedures -* M2 Constants:: Modula-2 constants -* M2 Defaults:: Default settings for Modula-2 -* Deviations:: Deviations from standard Modula-2 -* M2 Checks:: Modula-2 type and range checks -* M2 Scope:: The scope operators @code{::} and @code{.} -* GDB/M2:: @value{GDBN} and Modula-2 - -Altering Execution - -* Assignment:: Assignment to variables -* Jumping:: Continuing at a different address -* Signaling:: Giving your program a signal -* Returning:: Returning from a function -* Calling:: Calling your program's functions -* Patching:: Patching your program - -@value{GDBN} Files - -* Files:: Commands to specify files -* Symbol Errors:: Errors reading symbol files - -Specifying a Debugging Target - -* Active Targets:: Active targets -* Target Commands:: Commands for managing targets -@ifclear HPPA -* Byte Order:: Choosing target byte order -* Remote:: Remote debugging - -Remote debugging -@end ifclear - -* Remote Serial:: @value{GDBN} remote serial protocol - -* i960-Nindy Remote:: @value{GDBN} with a remote i960 (Nindy) - -* UDI29K Remote:: The UDI protocol for AMD29K - -* EB29K Remote:: The EBMON protocol for AMD29K - -* VxWorks Remote:: @value{GDBN} and VxWorks - -* ST2000 Remote:: @value{GDBN} with a Tandem ST2000 - -* Hitachi Remote:: @value{GDBN} and Hitachi Microprocessors - -* MIPS Remote:: @value{GDBN} and MIPS boards - -* Simulator:: Simulated CPU target - -Controlling @value{GDBN} - -* Prompt:: Prompt -* Editing:: Command editing -* History:: Command history -* Screen Size:: Screen size -* Numbers:: Numbers -* Messages/Warnings:: Optional warnings and messages - -Canned Sequences of Commands - -* Define:: User-defined commands -* Hooks:: User-defined command hooks -* Command Files:: Command files -* Output:: Commands for controlled output - -Reporting Bugs in @value{GDBN} - -* Bug Criteria:: Have you found a bug? -* Bug Reporting:: How to report bugs - -Installing @value{GDBN} - -* Separate Objdir:: Compiling @value{GDBN} in another directory -* Config Names:: Specifying names for hosts and targets -* Configure Options:: Summary of options for configure @end menu @end ifinfo -@node Summary, Sample Session, Top, Top +@node Summary @unnumbered Summary of @value{GDBN} The purpose of a debugger such as @value{GDBN} is to allow you to see what is @@ -421,24 +199,15 @@ syntax. @cindex Fortran @value{GDBN} can be used to debug programs written in Fortran, although -It may be necessary to refer to some variables with a trailing +it may be necessary to refer to some variables with a trailing underscore. -@ifset HPPA -This version of the manual documents HP Wildebeest (WDB) Version 0.75, -implemented on HP 9000 systems running Release 10.20, 10.30, or 11.0 of -the HP-UX operating system. HP WDB 0.75 can be used to debug code -generated by the HP ANSI C and HP ANSI C++ compilers as well as the -@sc{gnu} C and C++ compilers. It does not support the debugging of -Fortran, Modula-2, or Chill programs. -@end ifset - @menu * Free Software:: Freely redistributable software * Contributors:: Contributors to GDB @end menu -@node Free Software, Contributors, Summary, Summary +@node Free Software @unnumberedsec Free software @value{GDBN} is @dfn{free software}, protected by the @sc{gnu} @@ -454,7 +223,7 @@ Fundamentally, the General Public License is a license which says that you have these freedoms and that you cannot take these freedoms away from anyone else. -@node Contributors, , Free Software, Summary +@node Contributors @unnumberedsec Contributors to GDB Richard Stallman was the original author of GDB, and of many other @@ -592,7 +361,7 @@ Unrau, Jim Wilson, and David Zuhn have made contributions both large and small. -@node Sample Session, Invocation, Summary, Top +@node Sample Session @chapter A Sample @value{GDBN} Session You can use this manual at your leisure to read all about @value{GDBN}. @@ -639,7 +408,6 @@ m4: End of input: 0: fatal error: EOF in string @noindent Let us use @value{GDBN} to try to see what is going on. -@ifclear HPPA @smallexample $ @b{@value{GDBP} m4} @c FIXME: this falsifies the exact text played out, to permit smallbook @@ -653,21 +421,6 @@ There is absolutely no warranty for @value{GDBN}; type "show warranty" @value{GDBN} @value{GDBVN}, Copyright 1999 Free Software Foundation, Inc... (@value{GDBP}) @end smallexample -@end ifclear -@ifset HPPA -@smallexample -$ @b{@value{GDBP} m4} -Wildebeest is free software and you are welcome to distribute copies of -it under certain conditions; type "show copying" to see the conditions. -There is absolutely no warranty for Wildebeest; type "show warranty" -for details. - -Hewlett-Packard Wildebeest 0.75 (based on GDB 4.16) -(built for PA-RISC 1.1 or 2.0, HP-UX 10.20) -Copyright 1996, 1997 Free Software Foundation, Inc. -(@value{GDBP}) -@end smallexample -@end ifset @noindent @value{GDBN} reads only enough symbol data to know where to find the @@ -878,14 +631,14 @@ session with the @value{GDBN} @code{quit} command. (@value{GDBP}) @b{quit} @end smallexample -@node Invocation, Commands, Sample Session, Top +@node Invocation @chapter Getting In and Out of @value{GDBN} This chapter discusses how to start @value{GDBN}, and how to get out of it. The essentials are: @itemize @bullet @item -type @samp{@value{GDBP}} to start GDB. +type @samp{@value{GDBP}} to start @value{GDBN}. @item type @kbd{quit} or @kbd{C-d} to exit. @end itemize @@ -896,7 +649,7 @@ type @kbd{quit} or @kbd{C-d} to exit. * Shell Commands:: How to use shell commands inside @value{GDBN} @end menu -@node Invoking GDB, Quitting GDB, Invocation, Invocation +@node Invoking GDB @section Invoking @value{GDBN} Invoke @value{GDBN} by running the program @code{@value{GDBP}}. Once started, @@ -935,12 +688,10 @@ to debug a running process: would attach @value{GDBN} to process @code{1234} (unless you also have a file named @file{1234}; @value{GDBN} does check for a core file first). -@ifclear HPPA Taking advantage of the second command-line argument requires a fairly complete operating system; when you use @value{GDBN} as a remote debugger attached to a bare board, there may not be any notion of ``process'', and there is often no way to get a core dump. -@end ifclear You can run @code{gdb} without printing the front material, which describes @value{GDBN}'s non-warranty, by specifying @code{-silent}: @@ -977,7 +728,7 @@ in sequential order. The order makes a difference when the @node File Options @subsection Choosing files -When @value{GDBN} starts, it reads any arguments other than options as +When @value{GDBN} starts specifying an executable file and core file (or process ID). This is the same as if the arguments were specified by the @samp{-se} and @samp{-c} options respectively. (@value{GDBN} reads the first argument @@ -1028,7 +779,6 @@ Files,, Command files}. @itemx -d @var{directory} Add @var{directory} to the path to search for source files. -@ifclear HPPA @item -m @itemx -mapped @emph{Warning: this option depends on operating system facilities that are not @@ -1045,30 +795,26 @@ the symbol table from the executable program. The @file{.syms} file is specific to the host machine where @value{GDBN} is run. It holds an exact image of the internal @value{GDBN} symbol table. It cannot be shared across multiple host platforms. -@end ifclear -@ifclear HPPA @item -r @itemx -readnow Read each symbol file's entire symbol table immediately, rather than the default, which is to read it incrementally as it is needed. This makes startup slower, but makes future operations faster. -@end ifclear + @end table -@ifclear HPPA The @code{-mapped} and @code{-readnow} options are typically combined in order to build a @file{.syms} file that contains complete symbol information. (@xref{Files,,Commands to specify files}, for -information on @file{.syms} files.) A simple GDB invocation to do +information on @file{.syms} files.) A simple @value{GDBN} invocation to do nothing but build a @file{.syms} file for future use is: @example gdb -batch -nx -mapped -readnow programname @end example -@end ifclear -@node Mode Options, , File Options, Invoking GDB +@node Mode Options @subsection Choosing modes You can run @value{GDBN} in various alternative modes---for example, in @@ -1122,33 +868,31 @@ and a newline. The Emacs-to-@value{GDBN} interface program uses the two @samp{\032} characters as a signal to display the source code for the frame. -@ifclear HPPA @item -b @var{bps} Set the line speed (baud rate or bits per second) of any serial interface used by @value{GDBN} for remote debugging. -@end ifclear @item -tty @var{device} Run using @var{device} for your program's standard input and output. @c FIXME: kingdon thinks there is more to -tty. Investigate. -@ifset HPPA -@item -tui -Use a Terminal User Interface. For information, use your Web browser to -read the file @file{TUI.html}, which is usually installed in the -directory @code{/opt/langtools/wdb/doc} on HP-UX systems. Do not use -this option if you run @value{GDBN} from Emacs (see @pxref{Emacs, ,Using -@value{GDBN} under @sc{gnu} Emacs}). - -@item -xdb -Run in XDB compatibility mode, allowing the use of certain XDB commands. -For information, see the file @file{xdb_trans.html}, which is usually -installed in the directory @code{/opt/langtools/wdb/doc} on HP-UX -systems. -@end ifset +@c resolve the situation of these eventually +@c @item -tui +@c Use a Terminal User Interface. For information, use your Web browser to +@c read the file @file{TUI.html}, which is usually installed in the +@c directory @code{/opt/langtools/wdb/doc} on HP-UX systems. Do not use +@c this option if you run @value{GDBN} from Emacs (see @pxref{Emacs, ,Using +@c @value{GDBN} under @sc{gnu} Emacs}). + +@c @item -xdb +@c Run in XDB compatibility mode, allowing the use of certain XDB commands. +@c For information, see the file @file{xdb_trans.html}, which is usually +@c installed in the directory @code{/opt/langtools/wdb/doc} on HP-UX +@c systems. + @end table -@node Quitting GDB, Shell Commands, Invoking GDB, Invocation +@node Quitting GDB @section Quitting @value{GDBN} @cindex exiting @value{GDBN} @cindex leaving @value{GDBN} @@ -1174,7 +918,7 @@ If you have been using @value{GDBN} to control an attached process or device, you can release it with the @code{detach} command (@pxref{Attach, ,Debugging an already-running process}). -@node Shell Commands, , Quitting GDB, Invocation +@node Shell Commands @section Shell commands If you need to execute occasional shell commands during your @@ -1202,7 +946,7 @@ Execute the @code{make} program with the specified arguments. This is equivalent to @samp{shell make @var{make-args}}. @end table -@node Commands, Running, Invocation, Top +@node Commands @chapter @value{GDBN} Commands You can abbreviate a @value{GDBN} command to the first few letters of the command @@ -1217,7 +961,7 @@ show you the alternatives available, if there is more than one possibility). * Help:: How to ask @value{GDBN} for help @end menu -@node Command Syntax, Completion, Commands, Commands +@node Command Syntax @section Command syntax A @value{GDBN} command is a single line of input. There is no limit on @@ -1260,7 +1004,7 @@ Any text from a @kbd{#} to the end of the line is a comment; it does nothing. This is useful mainly in command files (@pxref{Command Files,,Command files}). -@node Completion, Help, Command Syntax, Commands +@node Completion @section Command completion @cindex completion @@ -1379,7 +1123,7 @@ overload-resolution off} to disable overload resolution; @pxref{Debugging C plus plus, ,@value{GDBN} features for C++}. -@node Help, , Completion, Commands +@node Help @section Getting help @cindex online documentation @kindex help @@ -1534,7 +1278,7 @@ Display information about permission for copying @value{GDBN}. Display the @sc{gnu} ``NO WARRANTY'' statement. @end table -@node Running, Stopping, Commands, Top +@node Running @chapter Running Programs Under @value{GDBN} When you run a program under @value{GDBN}, you must first generate @@ -1561,7 +1305,7 @@ kill a child process. * Processes:: Debugging programs with multiple processes @end menu -@node Compilation, Starting, Running, Running +@node Compilation @section Compiling for debugging In order to debug a program effectively, you need to generate @@ -1577,17 +1321,11 @@ Many C compilers are unable to handle the @samp{-g} and @samp{-O} options together. Using those compilers, you cannot generate optimized executables containing debugging information. -@ifclear HPPA -@value{NGCC}, the @sc{gnu} C compiler, supports @samp{-g} with or without -@end ifclear -@ifset HPPA -The HP ANSI C and C++ compilers, as well as @value{NGCC}, the @sc{gnu} C -compiler, support @samp{-g} with or without -@end ifset -@samp{-O}, making it possible to debug optimized code. We recommend -that you @emph{always} use @samp{-g} whenever you compile a program. -You may think your program is correct, but there is no sense in pushing -your luck. +@value{NGCC}, the @sc{gnu} C compiler, supports @samp{-g} with or +without @samp{-O}, making it possible to debug optimized code. We +recommend that you @emph{always} use @samp{-g} whenever you compile a +program. You may think your program is correct, but there is no sense +in pushing your luck. @cindex optimized code, debugging @cindex debugging optimized code @@ -1608,7 +1346,7 @@ Older versions of the @sc{gnu} C compiler permitted a variant option format; if your @sc{gnu} C compiler has this option, do not use it. @need 2000 -@node Starting, Arguments, Compilation, Running +@node Starting @section Starting your program @cindex starting @cindex running @@ -1684,7 +1422,7 @@ time @value{GDBN} read its symbols, @value{GDBN} discards its symbol table, and reads it again. When it does this, @value{GDBN} tries to retain your current breakpoints. -@node Arguments, Environment, Starting, Running +@node Arguments @section Your program's arguments @cindex arguments (to your program) @@ -1713,7 +1451,7 @@ it again without arguments. Show the arguments to give your program when it is started. @end table -@node Environment, Working Directory, Arguments, Running +@node Environment @section Your program's environment @cindex environment (of your program) @@ -1756,7 +1494,7 @@ print the names and values of all environment variables to be given to your program. You can abbreviate @code{environment} as @code{env}. @kindex set environment -@item set environment @var{varname} @r{[}=@r{]} @var{value} +@item set environment @var{varname} @r{[}=@var{value}@r{]} Set environment variable @var{varname} to @var{value}. The value changes for your program only, not for @value{GDBN} itself. @var{value} may be any string; the values of environment variables are just strings, and @@ -1794,7 +1532,7 @@ your program. You may wish to move setting of environment variables to files that are only run when you sign on, such as @file{.login} or @file{.profile}. -@node Working Directory, Input/Output, Environment, Running +@node Working Directory @section Your program's working directory @cindex working directory (of your program) @@ -1818,7 +1556,7 @@ Set the @value{GDBN} working directory to @var{directory}. Print the @value{GDBN} working directory. @end table -@node Input/Output, Attach, Working Directory, Running +@node Input/Output @section Your program's input and output @cindex redirection @@ -1872,7 +1610,7 @@ When you use the @code{tty} command or redirect input in the @code{run} command, only the input @emph{for your program} is affected. The input for @value{GDBN} still comes from your terminal. -@node Attach, Kill Process, Input/Output, Running +@node Attach @section Debugging an already-running process @kindex attach @cindex attach @@ -1903,16 +1641,10 @@ Specify Files}. The first thing @value{GDBN} does after arranging to debug the specified process is to stop it. You can examine and modify an attached process -with all the @value{GDBN} commands that are ordinarily available when you start -@ifclear HPPA -processes with @code{run}. You can insert breakpoints; you can step and -@end ifclear -@ifset HPPA -processes with @code{run}. You can insert breakpoints (except in shared -libraries); you can step and -@end ifset -continue; you can modify storage. If you would rather the process -continue running, you may use the @code{continue} command after +with all the @value{GDBN} commands that are ordinarily available when +you start processes with @code{run}. You can insert breakpoints; you +can step and continue; you can modify storage. If you would rather the +process continue running, you may use the @code{continue} command after attaching @value{GDBN} to the process. @table @code @@ -1934,7 +1666,7 @@ control whether or not you need to confirm by using the @code{set confirm} command (@pxref{Messages/Warnings, ,Optional warnings and messages}). -@node Kill Process, Process Information, Attach, Running +@node Kill Process @section Killing the child process @table @code @@ -1959,7 +1691,7 @@ next type @code{run}, @value{GDBN} notices that the file has changed, and reads the symbol table again (while trying to preserve your current breakpoint settings). -@node Process Information, Threads, Kill Process, Running +@node Process Information @section Additional process information @kindex /proc @@ -2004,7 +1736,7 @@ received. Show all the above information about the process. @end table -@node Threads, Processes, Process Information, Running +@node Threads @section Debugging programs with multiple threads @cindex threads of execution @@ -2030,7 +1762,6 @@ a command to apply a command to a list of threads @item thread-specific breakpoints @end itemize -@ifclear HPPA @quotation @emph{Warning:} These facilities are not yet available on every @value{GDBN} configuration where the operating system supports threads. @@ -2048,7 +1779,6 @@ see the IDs of currently known threads. @c FIXME to implementors: how hard would it be to say "sorry, this GDB @c doesn't support threads"? @end quotation -@end ifclear @cindex focus of debugging @cindex current thread @@ -2058,7 +1788,6 @@ control, one thread in particular is always the focus of debugging. This thread is called the @dfn{current thread}. Debugging commands show program information from the perspective of the current thread. -@ifclear HPPA @kindex New @var{systag} @cindex thread identifier (system) @c FIXME-implementors!! It would be more helpful if the [New...] message @@ -2121,8 +1850,8 @@ For example, * 1 process 35 thread 13 main (argc=1, argv=0x7ffffff8) at threadtest.c:68 @end smallexample -@end ifclear -@ifset HPPA + +On HP-UX systems: @cindex thread number @cindex thread identifier (GDB) @@ -2176,7 +1905,6 @@ For example, 2 system thread 26606 0x7b0030d8 in __ksleep () from /usr/lib/libc.2 1 system thread 27905 0x7b003498 in _brk () from /usr/lib/libc.2 @end example -@end ifset @table @code @kindex thread @var{threadno} @@ -2190,12 +1918,7 @@ you selected, and its current stack frame summary: @smallexample @c FIXME!! This example made up; find a @value{GDBN} w/threads and get real one (@value{GDBP}) thread 2 -@ifclear HPPA [Switching to process 35 thread 23] -@end ifclear -@ifset HPPA -[Switching to thread 2 (system thread 26594)] -@end ifset 0x34e5 in sigpause () @end smallexample @@ -2230,19 +1953,19 @@ programs with multiple threads. @xref{Set Watchpoints,,Setting watchpoints}, for information about watchpoints in programs with multiple threads. -@ifclear HPPA -@node Processes, , Threads, Running +@node Processes @section Debugging programs with multiple processes @cindex fork, debugging programs which call @cindex multiple processes @cindex processes, multiple -@value{GDBN} has no special support for debugging programs which create -additional processes using the @code{fork} function. When a program -forks, @value{GDBN} will continue to debug the parent process and the -child process will run unimpeded. If you have set a breakpoint in any -code which the child then executes, the child will get a @code{SIGTRAP} -signal which (unless it catches the signal) will cause it to terminate. +On most systems, @value{GDBN} has no special support for debugging +programs which create additional processes using the @code{fork} +function. When a program forks, @value{GDBN} will continue to debug the +parent process and the child process will run unimpeded. If you have +set a breakpoint in any code which the child then executes, the child +will get a @code{SIGTRAP} signal which (unless it catches the signal) +will cause it to terminate. However, if you want to debug the child process there is a workaround which isn't too painful. Put a call to @code{sleep} in the code which @@ -2254,17 +1977,10 @@ get its process ID. Then tell @value{GDBN} (a new invocation of @value{GDBN} if you are also debugging the parent process) to attach to the child process (see @ref{Attach}). From that point on you can debug the child process just like any other process which you attached to. -@end ifclear -@ifset HPPA -@node Processes, , Threads, Running -@section Debugging programs with multiple processes - -@cindex fork, debugging programs which call -@cindex multiple processes -@cindex processes, multiple -@value{GDBN} provides support for debugging programs that create -additional processes using the @code{fork} or @code{vfork} function. +On HP-UX (11.x and later only?), @value{GDBN} provides support for +debugging programs that create additional processes using the +@code{fork} or @code{vfork} function. By default, when a program forks, @value{GDBN} will continue to debug the parent process and the child process will run unimpeded. @@ -2313,9 +2029,8 @@ argument. You can use the @code{catch} command to make @value{GDBN} stop whenever a @code{fork}, @code{vfork}, or @code{exec} call is made. @xref{Set Catchpoints, ,Setting catchpoints}. -@end ifset -@node Stopping, Stack, Running, Top +@node Stopping @chapter Stopping and Continuing The principal purposes of using a debugger are so that you can stop your @@ -2344,7 +2059,7 @@ running or not, what process it is, and why it stopped. * Thread Stops:: Stopping and starting multi-thread programs @end menu -@node Breakpoints, Continuing and Stepping, Stopping, Stopping +@node Breakpoints @section Breakpoints, watchpoints, and catchpoints @cindex breakpoints @@ -2411,7 +2126,7 @@ enable it again. @c * Error in Breakpoints:: ``Cannot insert breakpoints'' @end menu -@node Set Breaks, Set Watchpoints, Breakpoints, Breakpoints +@node Set Breaks @subsection Setting breakpoints @c FIXME LMB what does GDB do if no code on line of breakpt? @@ -2496,7 +2211,6 @@ same as for the @code{break} command, and the breakpoint is set in the same way, but the breakpoint is automatically deleted after the first time your program stops there. @xref{Disabling, ,Disabling breakpoints}. -@ifclear HPPA @kindex hbreak @item hbreak @var{args} Set a hardware-assisted breakpoint. @var{args} are the same as for the @@ -2522,7 +2236,6 @@ first time your program stops there. Also, like the @code{hbreak} command, the breakpoint requires hardware support and some target hardware may not have this support. @xref{Disabling, ,Disabling breakpoints}. Also @xref{Conditions, ,Break conditions}. -@end ifclear @kindex rbreak @cindex regular expression @@ -2629,15 +2342,15 @@ Temporary internal breakpoint used by the @value{GDBN} @code{until} command. @item finish Temporary internal breakpoint used by the @value{GDBN} @code{finish} command. -@ifset HPPA @item shlib events Shared library events. -@end ifset + @end table + @end table -@node Set Watchpoints, Set Catchpoints, Set Breaks, Breakpoints +@node Set Watchpoints @subsection Setting watchpoints @cindex setting watchpoints @@ -2758,7 +2471,6 @@ way of doing that would be to set a code breakpoint at the entry to the @quotation @cindex watchpoints and threads @cindex threads and watchpoints -@ifclear HPPA @emph{Warning:} In multi-thread programs, watchpoints have only limited usefulness. With the current watchpoint implementation, @value{GDBN} can only watch the value of an expression @emph{in a single thread}. If @@ -2767,21 +2479,19 @@ thread's activity (and if you are also confident that no other thread can become current), then you can use watchpoints as usual. However, @value{GDBN} may not notice when a non-current thread's activity changes the expression. -@end ifclear -@ifset HPPA -@emph{Warning:} In multi-thread programs, software watchpoints have only -limited usefulness. If @value{GDBN} creates a software watchpoint, it -can only watch the value of an expression @emph{in a single thread}. If -you are confident that the expression can only change due to the current -thread's activity (and if you are also confident that no other thread -can become current), then you can use software watchpoints as usual. -However, @value{GDBN} may not notice when a non-current thread's -activity changes the expression. (Hardware watchpoints, in contrast, -watch an expression in all threads.) -@end ifset + +@emph{HP-UX Warning:} In multi-thread programs, software watchpoints +have only limited usefulness. If @value{GDBN} creates a software +watchpoint, it can only watch the value of an expression @emph{in a +single thread}. If you are confident that the expression can only +change due to the current thread's activity (and if you are also +confident that no other thread can become current), then you can use +software watchpoints as usual. However, @value{GDBN} may not notice +when a non-current thread's activity changes the expression. (Hardware +watchpoints, in contrast, watch an expression in all threads.) @end quotation -@node Set Catchpoints, Delete Breaks, Set Watchpoints, Breakpoints +@node Set Catchpoints @subsection Setting catchpoints @cindex catchpoints @cindex exception handlers @@ -2889,7 +2599,7 @@ breakpoints to stop your program when any of a number of exceptions are raised. -@node Delete Breaks, Disabling, Set Catchpoints, Breakpoints +@node Delete Breaks @subsection Deleting breakpoints @cindex clearing breakpoints, watchpoints, catchpoints @@ -2934,7 +2644,7 @@ breakpoints (@value{GDBN} asks confirmation, unless you have @code{set confirm off}). You can abbreviate this command as @code{d}. @end table -@node Disabling, Conditions, Delete Breaks, Breakpoints +@node Disabling @subsection Disabling breakpoints @kindex disable breakpoints @@ -3005,7 +2715,7 @@ breakpoint of its own, but it does not change the state of your other breakpoints; see @ref{Continuing and Stepping, ,Continuing and stepping}.) -@node Conditions, Break Commands, Disabling, Breakpoints +@node Conditions @subsection Break conditions @cindex conditional breakpoints @cindex breakpoint conditions @@ -3046,19 +2756,11 @@ Break conditions can be specified when a breakpoint is set, by using @samp{if} in the arguments to the @code{break} command. @xref{Set Breaks, ,Setting breakpoints}. They can also be changed at any time with the @code{condition} command. -@ifclear HPPA -@c The watch command now seems to recognize the if keyword. -@c catch doesn't, though. -The @code{watch} command does not recognize the @code{if} keyword; -@code{condition} is the only way to impose a further condition on a -watchpoint. -@end ifclear -@ifset HPPA + You can also use the @code{if} keyword with the @code{watch} command. The @code{catch} command does not recognize the @code{if} keyword; @code{condition} is the only way to impose a further condition on a catchpoint. -@end ifset @table @code @kindex condition @@ -3122,7 +2824,7 @@ variables}. Ignore counts apply to breakpoints, watchpoints, and catchpoints. -@node Break Commands, Breakpoint Menus, Conditions, Breakpoints +@node Break Commands @subsection Breakpoint command lists @cindex breakpoint commands @@ -3203,7 +2905,7 @@ cont end @end example -@node Breakpoint Menus, , Break Commands, Breakpoints +@node Breakpoint Menus @subsection Breakpoint menus @cindex overloading @cindex symbol overloading @@ -3255,7 +2957,7 @@ Use the "delete" command to delete unwanted @c @c FIXME!! 14/6/95 Is there a real example of this? Let's use it. @c -@c Under some operating systems, breakpoints cannot be used in a program if +@c Under some operating systems @c any other process is running that program. In this situation, @c attempting to run or continue a program with a breakpoint causes @c @value{GDBN} to stop the other process. @@ -3279,7 +2981,7 @@ Use the "delete" command to delete unwanted @c @end enumerate @c @end ifclear -@node Continuing and Stepping, Signals, Breakpoints, Stopping +@node Continuing and Stepping @section Continuing and stepping @cindex stepping @@ -3475,7 +3177,7 @@ proceed until the function returns. An argument is a repeat count, as in @code{next}. @end table -@node Signals, Thread Stops, Continuing and Stepping, Stopping +@node Signals @section Signals @cindex signals @@ -3569,7 +3271,7 @@ a result of the fatal signal once it saw the signal. To prevent this, you can continue with @samp{signal 0}. @xref{Signaling, ,Giving your program a signal}. -@node Thread Stops, , Signals, Stopping +@node Thread Stops @section Stopping and starting multi-thread programs When your program has multiple threads (@pxref{Threads,, Debugging @@ -3654,7 +3356,7 @@ Display the current scheduler locking mode. @end table -@node Stack, Source, Stopping, Top +@node Stack @chapter Examining the Stack When your program has stopped, the first thing you need to know is where it @@ -3694,7 +3396,7 @@ currently executing frame and describes it briefly, similar to the @end menu -@node Frames, Backtrace, Stack, Stack +@node Frames @section Stack frames @cindex frame @@ -3760,7 +3462,7 @@ to another without printing the frame. This is the silent version of @code{frame}. @end table -@node Backtrace, Selection, Frames, Stack +@node Backtrace @section Backtraces @cindex backtraces @@ -3823,7 +3525,7 @@ The display for frame zero does not begin with a program counter value, indicating that your program has stopped at the beginning of the code for line @code{993} of @code{builtin.c}. -@node Selection, Frame Info, Backtrace, Stack +@node Selection @section Selecting a frame Most commands for examining the stack and other data in your program work on @@ -3849,7 +3551,6 @@ impossible for @value{GDBN} to assign numbers properly to all frames. In addition, this can be useful when your program has multiple stacks and switches between them. -@ifclear HPPA On the SPARC architecture, @code{frame} needs two addresses to select an arbitrary frame: a frame pointer and a stack pointer. @@ -3861,7 +3562,6 @@ pointer, a program counter, and a memory stack pointer. @c note to future updaters: this is conditioned on a flag @c SETUP_ARBITRARY_FRAME in the tm-*.h files. The above is up to date @c as of 27 Jan 1994. -@end ifclear @kindex up @item up @var{n} @@ -3911,7 +3611,7 @@ in @value{GDBN} command scripts, where the output might be unnecessary and distracting. @end table -@node Frame Info, Alpha/MIPS Stack, Selection, Stack +@node Frame Info @section Information about a frame There are several other commands to print information about the selected @@ -3972,7 +3672,6 @@ Print the local variables of the selected frame, each on a separate line. These are all variables (declared either static or automatic) accessible at the point of execution of the selected frame. -@ifclear HPPA @kindex info catch @cindex catch exceptions @cindex exception handlers @@ -3982,10 +3681,10 @@ current stack frame at the current point of execution. To see other exception handlers, visit the associated frame (using the @code{up}, @code{down}, or @code{frame} commands); then type @code{info catch}. @xref{Set Catchpoints, , Setting catchpoints}. -@end ifclear + @end table -@node Alpha/MIPS Stack, , Frame Info, Stack +@node Alpha/MIPS Stack @section MIPS/Alpha machines and the function stack @cindex stack on Alpha @@ -4020,7 +3719,7 @@ These commands are available @emph{only} when @value{GDBN} is configured for debugging programs on Alpha or MIPS processors. -@node Source, Data, Stack, Top +@node Source @chapter Examining Source Files @value{GDBN} can print parts of your program's source, since the debugging @@ -4042,7 +3741,7 @@ prefer to use Emacs facilities to view source; @pxref{Emacs, ,Using * Machine Code:: Source and machine code @end menu -@node List, Search, Source, Source +@node List @section Printing source lines @kindex list @@ -4159,7 +3858,7 @@ Specifies the line containing the program address @var{address}. @var{address} may be any expression. @end table -@node Search, Source Path, List, Source +@node Search @section Searching source files @cindex searching @kindex reverse-search @@ -4185,7 +3884,7 @@ for @var{regexp}. It lists the line that is found. You can abbreviate this command as @code{rev}. @end table -@node Source Path, Machine Code, Search, Source +@node Source Path @section Specifying source directories @cindex source path @@ -4265,7 +3964,7 @@ directories you want in the source path. You can add all the directories in one command. @end enumerate -@node Machine Code, , Source Path, Source +@node Machine Code @section Source and machine code You can use the command @code{info line} to map source lines to program @@ -4360,7 +4059,7 @@ The default is @code{i386}. @end table -@node Data, Languages, Source, Top +@node Data @chapter Examining Data @cindex printing data @@ -4415,7 +4114,7 @@ Table}. * Floating Point Hardware:: Floating point hardware @end menu -@node Expressions, Variables, Data, Data +@node Expressions @section Expressions @cindex expressions @@ -4468,7 +4167,7 @@ a cast). This construct is allowed regardless of what kind of data is normally supposed to reside at @var{addr}. @end table -@node Variables, Arrays, Expressions, Data +@node Variables @section Program variables The most common kind of expression to use is the name of a variable @@ -4566,7 +4265,7 @@ This may also happen when the compiler does significant optimizations. To be sure of always seeing accurate values, turn off all optimization when compiling. -@node Arrays, Output Formats, Variables, Data +@node Arrays @section Artificial arrays @cindex artificial array @@ -4638,7 +4337,7 @@ p dtab[$i++]->fv @dots{} @end example -@node Output Formats, Memory, Arrays, Data +@node Output Formats @section Output formats @cindex formatted output @@ -4707,7 +4406,7 @@ To reprint the last value in the value history with a different format, you can use the @code{print} command with just a format and no expression. For example, @samp{p/x} reprints the last value in hex. -@node Memory, Auto Display, Output Formats, Data +@node Memory @section Examining memory You can use the command @code{x} (for ``examine'') to examine memory in @@ -4812,7 +4511,7 @@ If the @code{x} command has a repeat count, the address and contents saved are from the last memory unit printed; this is not the same as the last address printed if several units were printed on the last line of output. -@node Auto Display, Print Settings, Memory, Data +@node Auto Display @section Automatic display @cindex automatic display @cindex display of expressions @@ -4908,7 +4607,7 @@ there is no variable @code{last_char}---the display is disabled automatically. The next time your program stops where @code{last_char} is meaningful, you can enable the display expression once again. -@node Print Settings, Value History, Auto Display, Data +@node Print Settings @section Print settings @cindex format options @@ -5203,9 +4902,7 @@ Allow @value{GDBN} to choose a decoding style by inspecting your program. @item gnu Decode based on the @sc{gnu} C++ compiler (@code{g++}) encoding algorithm. -@ifclear HPPA This is the default. -@end ifclear @item hp Decode based on the HP ANSI C++ (@code{aCC}) encoding algorithm. @@ -5258,10 +4955,8 @@ Show whether C++ static members are printed, or not. @item set print vtbl @itemx set print vtbl on Pretty print C++ virtual function tables. The default is off. -@ifset HPPA (The @code{vtbl} commands do not work on programs compiled with the HP ANSI C++ compiler (@code{aCC}).) -@end ifset @item set print vtbl off Do not pretty print C++ virtual function tables. @@ -5271,7 +4966,7 @@ Do not pretty print C++ virtual function tables. Show whether C++ virtual function tables are pretty printed, or not. @end table -@node Value History, Convenience Vars, Print Settings, Data +@node Value History @section Value history @cindex value history @@ -5348,7 +5043,7 @@ values are available, @code{show values +} produces no display. Pressing @key{RET} to repeat @code{show values @var{n}} has exactly the same effect as @samp{show values +}. -@node Convenience Vars, Registers, Value History, Data +@node Convenience Vars @section Convenience variables @cindex convenience variables @@ -5429,13 +5124,11 @@ The variable @code{$_exitcode} is automatically set to the exit code when the program being debugged terminates. @end table -@ifset HPPA -If you refer to a function or variable name that begins with a dollar -sign, @value{GDBN} searches for a user or system name first, before it -searches for a convenience variable. -@end ifset +On HP-UX systems, if you refer to a function or variable name that +begins with a dollar sign, @value{GDBN} searches for a user or system +name first, before it searches for a convenience variable. -@node Registers, Floating Point Hardware, Convenience Vars, Data +@node Registers @section Registers @cindex registers @@ -5554,7 +5247,7 @@ Display the current limit of the register stack, on AMD 29000 family processors. @end table -@node Floating Point Hardware, , Registers, Data +@node Floating Point Hardware @section Floating point hardware @cindex floating point @@ -5570,7 +5263,7 @@ floating point chip. Currently, @samp{info float} is supported on the ARM and x86 machines. @end table -@node Languages, Symbols, Data, Top +@node Languages @chapter Using @value{GDBN} with Different Languages @cindex languages @@ -5596,7 +5289,7 @@ language}. * Support:: Supported languages @end menu -@node Setting, Show, Languages, Languages +@node Setting @section Switching between source languages There are two ways to control the working language---either have @value{GDBN} @@ -5628,7 +5321,7 @@ program, and will display that source code, not the generated C code. * Automatically:: Having @value{GDBN} infer the source language @end menu -@node Filenames, Manually, Setting, Setting +@node Filenames @subsection List of filename extensions and languages If a source file name ends in one of the following extensions, then @@ -5651,12 +5344,10 @@ C++ source file @itemx .F Fortran source file -@ifclear HPPA @item .ch @itemx .c186 @itemx .c286 CHILL source file. -@end ifclear @item .mod Modula-2 source file @@ -5670,7 +5361,7 @@ Assembler source file. This actually behaves almost like C, but In addition, you may set the language associated with a filename extension. @xref{Show, , Displaying the language}. -@node Manually, Automatically, Filenames, Setting +@node Manually @subsection Setting the working language If you allow @value{GDBN} to set the language automatically, @@ -5702,7 +5393,7 @@ might not have the effect you intended. In C, this means to add printed would be the value of @code{a}. In Modula-2, this means to compare @code{a} to the result of @code{b+c}, yielding a @code{BOOLEAN} value. -@node Automatically, , Manually, Setting +@node Automatically @subsection Having @value{GDBN} infer the source language To have @value{GDBN} set the working language automatically, use @@ -5721,7 +5412,7 @@ written in one source language can be used by a main program written in a different source language. Using @samp{set language auto} in this case frees you from having to set the working language manually. -@node Show, Checks, Setting, Languages +@node Show @section Displaying the language The following commands help you find out which language is the @@ -5763,7 +5454,7 @@ the source language @var{language}. List all the filename extensions and the associated languages. @end table -@node Checks, Support, Show, Languages +@node Checks @section Type and range checking @quotation @@ -5796,7 +5487,7 @@ for the default settings of supported languages. @cindex type checking @cindex checks, type -@node Type Checking, Range Checking, Checks, Checks +@node Type Checking @subsection An overview of type checking Some languages, such as Modula-2, are strongly typed, meaning that the @@ -5867,7 +5558,7 @@ is setting it automatically. @cindex range checking @cindex checks, range -@node Range Checking, , Type Checking, Checks +@node Range Checking @subsection An overview of range checking In some languages (such as Modula-2), it is an error to exceed the @@ -5926,7 +5617,7 @@ Show the current setting of the range checker, and whether or not it is being set automatically by @value{GDBN}. @end table -@node Support, , Checks, Languages +@node Support @section Supported languages @value{GDBN} supports C, C++, Fortran, Java, Chill, assembly, and Modula-2. @@ -5951,7 +5642,7 @@ language reference or tutorial. * Chill:: Chill @end menu -@node C, Modula-2, , Support +@node C @subsection C and C++ @cindex C and C++ @@ -5961,7 +5652,6 @@ Since C and C++ are so closely related, many features of @value{GDBN} apply to both languages. Whenever this is the case, we discuss those languages together. -@ifclear HPPA @cindex C++ @kindex g++ @cindex @sc{gnu} C++ @@ -5976,23 +5666,6 @@ format. You can select that format explicitly with the @code{g++} command-line options @samp{-gstabs} or @samp{-gstabs+}. See @ref{Debugging Options,,Options for Debugging Your Program or @sc{gnu} CC, gcc.info, Using @sc{gnu} CC}, for more information. -@end ifclear -@ifset HPPA -@cindex C++ -@kindex g++ -@cindex @sc{gnu} C++ -You can use @value{GDBN} to debug C programs compiled with either the HP -C compiler (@code{cc}) or the GNU C compiler (@code{gcc}), and to debug -programs compiled with either the HP ANSI C++ compiler (@code{aCC}) or -the @sc{gnu} C++ compiler (@code{g++}). - -If you compile with the @sc{gnu} C++ compiler, use the stabs debugging -format for best results when debugging. You can select that format -explicitly with the @code{g++} command-line options @samp{-gstabs} or -@samp{-gstabs+}. See @ref{Debugging Options,,Options for Debugging Your -Program or @sc{gnu} CC, gcc.info, Using @sc{gnu} CC}, for more -information. -@end ifset @menu * C Operators:: C and C++ operators @@ -6004,7 +5677,7 @@ information. * Debugging C plus plus:: @value{GDBN} features for C++ @end menu -@node C Operators, C Constants, , C +@node C Operators @subsubsection C and C++ operators @cindex C and C++ operators @@ -6016,25 +5689,20 @@ often defined on groups of types. For the purposes of C and C++, the following definitions hold: @itemize @bullet + @item -@ifclear HPPA -@emph{Integral types} include @code{int} with any of its storage-class -specifiers; @code{char}; and @code{enum}. -@end ifclear -@ifset HPPA @emph{Integral types} include @code{int} with any of its storage-class specifiers; @code{char}; @code{enum}; and, for C++, @code{bool}. -@end ifset @item @emph{Floating-point types} include @code{float} and @code{double}. @item -@emph{Pointer types} include all types defined as @code{(@var{type} -*)}. +@emph{Pointer types} include all types defined as @code{(@var{type} *)}. @item @emph{Scalar types} include all of the above. + @end itemize @noindent @@ -6140,10 +5808,8 @@ Structure member, and pointer-to-structure member. For convenience, pointer based on the stored type information. Defined on @code{struct} and @code{union} data. -@ifset HPPA @item .*@r{, }->* Dereferences of pointers to members. -@end ifset @item [] Array indexing. @code{@var{a}[@var{i}]} is defined as @@ -6162,17 +5828,15 @@ Doubled colons also represent the @value{GDBN} scope operator above. @end table -@ifset HPPA If an operator is redefined in the user code, @value{GDBN} usually attempts to invoke the redefined version instead of using the operator's predefined meaning. -@end ifset @menu * C Constants:: @end menu -@node C Constants, C plus plus expressions, C Operators, C +@node C Constants @subsubsection C and C++ constants @cindex C and C++ constants @@ -6232,13 +5896,12 @@ and @samp{@{&"hi", &"there", &"fred"@}} is a three-element array of pointers. * Debugging C:: @end menu -@node C plus plus expressions, C Defaults, C Constants, C +@node C plus plus expressions @subsubsection C++ expressions @cindex expressions in C++ @value{GDBN} expression handling can interpret most C++ expressions. -@ifclear HPPA @cindex C++ support, not in @sc{coff} @cindex @sc{coff} versus C++ @cindex C++ and object formats @@ -6262,7 +5925,6 @@ extensions explicitly.) Where the object code format is standard @sc{coff} or @sc{dwarf} in @sc{elf}, on the other hand, most of the C++ support in @value{GDBN} does @emph{not} work. @end quotation -@end ifclear @enumerate @@ -6282,17 +5944,6 @@ expressions have the same namespace available as the member function; that is, @value{GDBN} allows implicit references to the class instance pointer @code{this} following the same rules as C++. -@ifclear HPPA -@cindex call overloaded functions -@cindex type conversions in C++ -@item -You can call overloaded functions; @value{GDBN} resolves the function -call to the right definition, with one restriction---you must use -arguments of the type required by the function that you want to call. -@value{GDBN} does not perform conversions requiring constructors or -user-defined type operators. -@end ifclear -@ifset HPPA @cindex call overloaded functions @cindex overloaded functions @cindex type conversions in C++ @@ -6322,8 +5973,6 @@ p 'foo(char,int)'('x', 13) The @value{GDBN} command-completion facility can simplify this; @pxref{Completion, ,Command completion}. -@end ifset - @cindex reference declarations @item @value{GDBN} understands variables declared as C++ references; you can use @@ -6346,23 +5995,20 @@ resolving name scope by reference to source files, in both C and C++ debugging (@pxref{Variables, ,Program variables}). @end enumerate -@ifset HPPA -In addition, @value{GDBN} supports calling virtual functions correctly, -printing out virtual bases of objects, calling functions in a base -subobject, casting objects, and invoking user-defined operators. -@end ifset +In addition, when used with HP's C++ compiler, @value{GDBN} supports +calling virtual functions correctly, printing out virtual bases of +objects, calling functions in a base subobject, casting objects, and +invoking user-defined operators. -@node C Defaults, C Checks, C plus plus expressions, C +@node C Defaults @subsubsection C and C++ defaults @cindex C and C++ defaults -@ifclear HPPA If you allow @value{GDBN} to set type and range checking automatically, they both default to @code{off} whenever the working language changes to C or C++. This happens regardless of whether you or @value{GDBN} selects the working language. -@end ifclear If you allow @value{GDBN} to set the language automatically, it recognizes source files whose names end with @file{.c}, @file{.C}, or @@ -6375,7 +6021,7 @@ for further details. @c unimplemented. If (b) changes, it might make sense to let this node @c appear even if Mod-2 does not, but meanwhile ignore it. roland 16jul93. -@node C Checks, Debugging C, C Defaults, C Constants +@node C Checks @subsubsection C and C++ type and range checks @cindex C and C++ checks @@ -6407,7 +6053,7 @@ Range checking, if turned on, is done on mathematical operations. Array indices are not checked, since they are often used to index a pointer that is not itself an array. -@node Debugging C, Debugging C plus plus, C Checks, C +@node Debugging C @subsubsection @value{GDBN} and C The @code{set print union} and @code{show print union} commands apply to @@ -6423,7 +6069,7 @@ with pointers and a memory allocation function. @xref{Expressions, * Debugging C plus plus:: @end menu -@node Debugging C plus plus, , Debugging C, C +@node Debugging C plus plus @subsubsection @value{GDBN} features for C++ @cindex commands for C++ @@ -6475,7 +6121,6 @@ Choose whether to print derived (actual) or declared types of objects. @itemx show print vtbl Control the format for printing virtual function tables. @xref{Print Settings, ,Print settings}. -@ifset HPPA (The @code{vtbl} commands do not work on programs compiled with the HP ANSI C++ compiler (@code{aCC}).) @@ -6497,7 +6142,6 @@ symbol table, whether or not its arguments are of the correct type. For overloaded functions that are class member functions, @value{GDBN} searches for a function whose signature @emph{exactly} matches the argument types. -@end ifset @item @r{Overloaded symbol names} You can specify a particular definition of an overloaded symbol, using @@ -6508,7 +6152,7 @@ available choices, or to finish the type list for you. @xref{Completion,, Command completion}, for details on how to do this. @end table -@node Modula-2, Chill, C, Support +@node Modula-2 @subsection Modula-2 @cindex Modula-2 @@ -6532,7 +6176,7 @@ table. * GDB/M2:: @value{GDBN} and Modula-2 @end menu -@node M2 Operators, Built-In Func/Proc, Modula-2, Modula-2 +@node M2 Operators @subsubsection Operators @cindex Modula-2 operators @@ -6656,7 +6300,7 @@ treats the use of the operator @code{IN}, or the use of operators @end quotation @cindex Modula-2 built-ins -@node Built-In Func/Proc, M2 Constants, M2 Operators, Modula-2 +@node Built-In Func/Proc @subsubsection Built-in functions and procedures Modula-2 also makes available several built-in procedures and functions. @@ -6768,7 +6412,7 @@ an error. @end quotation @cindex Modula-2 constants -@node M2 Constants, M2 Defaults, Built-In Func/Proc, Modula-2 +@node M2 Constants @subsubsection Constants @value{GDBN} allows you to express the constants of Modula-2 in the following @@ -6817,7 +6461,7 @@ Pointer constants consist of integral values only. Set constants are not yet supported. @end itemize -@node M2 Defaults, Deviations, M2 Constants, Modula-2 +@node M2 Defaults @subsubsection Modula-2 defaults @cindex Modula-2 defaults @@ -6831,7 +6475,7 @@ code compiled from a file whose name ends with @file{.mod} sets the working language to Modula-2. @xref{Automatically, ,Having @value{GDBN} set the language automatically}, for further details. -@node Deviations, M2 Checks, M2 Defaults, Modula-2 +@node Deviations @subsubsection Deviations from standard Modula-2 @cindex Modula-2, deviations from @@ -6861,7 +6505,7 @@ argument. All built-in procedures both modify @emph{and} return their argument. @end itemize -@node M2 Checks, M2 Scope, Deviations, Modula-2 +@node M2 Checks @subsubsection Modula-2 type and range checks @cindex Modula-2 checks @@ -6889,7 +6533,7 @@ whose types are not equivalent is an error. Range checking is done on all mathematical operations, assignment, array index bounds, and all built-in functions and procedures. -@node M2 Scope, GDB/M2, M2 Checks, Modula-2 +@node M2 Scope @subsubsection The scope operators @code{::} and @code{.} @cindex scope @kindex . @@ -6929,7 +6573,7 @@ an error if the identifier @var{id} was not imported from definition module @var{module}, or if @var{id} is not an identifier in @var{module}. -@node GDB/M2, , M2 Scope, Modula-2 +@node GDB/M2 @subsubsection @value{GDBN} and Modula-2 Some @value{GDBN} commands have little use when debugging Modula-2 programs. @@ -6950,7 +6594,7 @@ address can be specified by an integral constant, the construct In @value{GDBN} scripts, the Modula-2 inequality operator @code{#} is interpreted as the beginning of a comment. Use @code{<>} instead. -@node Chill, , Modula-2, Support +@node Chill @subsection Chill The extensions made to @value{GDBN} to support Chill only support output @@ -6966,6 +6610,8 @@ of @value{GDBN} which support these topics. * How modes are displayed:: How modes are displayed * Locations:: Locations and their accesses * Values and their Operations:: Values and their Operations +* Chill type and range checks:: +* Chill defaults:: @end menu @node How modes are displayed @@ -7101,7 +6747,7 @@ A location in Chill is an object which can contain values. A value of a location is generally accessed by the (declared) name of the location. The output conforms to the specification of values in -Chill programs. How values are specified, and which operations are valid +Chill programs. How values are specified is the topic of the next section. The pseudo-location @code{RESULT} (or @code{result}) can be used to @@ -7358,6 +7004,7 @@ Membership operator. @end table @end table +@node Chill type and range checks @subsubsection Chill type and range checks @value{GDBN} considers two Chill variables mode equivalent if the sizes @@ -7380,10 +7027,11 @@ All checks can be disabled by the @value{GDBN} command @code{set check off}. @ignore -@subsubsection Deviations from the Chill Standard Z200/88 +@c Deviations from the Chill Standard Z200/88 see last paragraph ? @end ignore +@node Chill defaults @subsubsection Chill defaults If type and range checking are set automatically by @value{GDBN}, they @@ -7396,7 +7044,7 @@ code compiled from a file whose name ends with @file{.ch} sets the working language to Chill. @xref{Automatically, ,Having @value{GDBN} set the language automatically}, for further details. -@node Symbols, Altering, Languages, Top +@node Symbols @chapter Examining the Symbol Table The commands described in this section allow you to inquire about the @@ -7547,7 +7195,6 @@ from the @code{ptype} command can be overwhelming and hard to use. The which match the regular-expression @var{regexp}. @end ignore -@ifclear HPPA @cindex reloading symbols Some systems allow individual object files that make up your program to be replaced without stopping and restarting your program. For example, @@ -7573,9 +7220,7 @@ different directories or libraries) with the same name. @item show symbol-reloading Show the current @code{on} or @code{off} setting. @end table -@end ifclear -@ifset HPPA @kindex set opaque-type-resolution @item set opaque-type-resolution on Tell @value{GDBN} to resolve opaque types. An opaque type is a type @@ -7597,7 +7242,6 @@ is printed as follows: @kindex show opaque-type-resolution @item show opaque-type-resolution Show whether opaque types are resolved or not. -@end ifset @kindex maint print symbols @cindex symbol dump @@ -7622,7 +7266,7 @@ required for each object file from which @value{GDBN} has read some symbols. @value{GDBN} reads symbols (in the description of @code{symbol-file}). @end table -@node Altering, GDB Files, Symbols, Top +@node Altering @chapter Altering Execution Once you think you have found an error in your program, you might want to @@ -7644,7 +7288,7 @@ address, or even return prematurely from a function. * Patching:: Patching your program @end menu -@node Assignment, Jumping, Altering, Altering +@node Assignment @section Assignment to variables @cindex assignment @@ -7670,7 +7314,6 @@ really the same as @code{print} except that the expression's value is not printed and is not put in the value history (@pxref{Value History, ,Value history}). The expression is evaluated only for its effects. -@ifclear HPPA If the beginning of the argument string of the @code{set} command appears identical to a @code{set} subcommand, use the @code{set variable} command instead of just @code{set}. This command is identical @@ -7695,8 +7338,7 @@ order to actually set the program's variable @code{width}, use @example (@value{GDBP}) set var width=47 @end example -@end ifclear -@ifset HPPA + Because the @code{set} command has many subcommands that can conflict with the names of program variables, it is a good idea to use the @code{set variable} command instead of just @code{set}. For example, if @@ -7731,7 +7373,6 @@ The program variable @code{g} did not change, and you silently set the @example (@value{GDBP}) set var g=4 @end example -@end ifset @value{GDBN} allows more implicit conversions in assignments than C; you can freely store an integer value into a pointer variable or vice versa, @@ -7753,7 +7394,7 @@ set @{int@}0x83040 = 4 @noindent stores the value 4 into that memory location. -@node Jumping, Signaling, Assignment, Altering +@node Jumping @section Continuing at a different address Ordinarily, when you continue your program, you do so at the place where @@ -7784,12 +7425,12 @@ well acquainted with the machine-language code of your program. Resume execution at the instruction at address @var{address}. @end table -@ifclear HPPA @c Doesn't work on HP-UX; have to set $pcoqh and $pcoqt. -You can get much the same effect as the @code{jump} command by storing a -new value into the register @code{$pc}. The difference is that this -does not start your program running; it only changes the address of where it -@emph{will} run when you continue. For example, +On many systems, you can get much the same effect as the @code{jump} +command by storing a new value into the register @code{$pc}. The +difference is that this does not start your program running; it only +changes the address of where it @emph{will} run when you continue. For +example, @example set $pc = 0x485 @@ -7799,7 +7440,6 @@ set $pc = 0x485 makes the next @code{continue} command or stepping command execute at address @code{0x485}, rather than at the address where your program stopped. @xref{Continuing and Stepping, ,Continuing and stepping}. -@end ifclear The most common occasion to use the @code{jump} command is to back up---perhaps with more breakpoints set---over a portion of a program @@ -7807,7 +7447,7 @@ that has already executed, in order to examine its execution in more detail. @c @group -@node Signaling, Returning, Jumping, Altering +@node Signaling @section Giving your program a signal @table @code @@ -7836,7 +7476,7 @@ the signal handling tables (@pxref{Signals}). The @code{signal} command passes the signal directly to your program. -@node Returning, Calling, Signaling, Altering +@node Returning @section Returning from a function @table @code @@ -7867,7 +7507,7 @@ returned. In contrast, the @code{finish} command (@pxref{Continuing and Stepping, ,Continuing and stepping}) resumes execution until the selected stack frame returns naturally. -@node Calling, Patching, Returning, Altering +@node Calling @section Calling program functions @cindex calling functions @@ -7883,15 +7523,13 @@ execute a function from your program, but without cluttering the output with @code{void} returned values. If the result is not void, it is printed and saved in the value history. -@ifclear HPPA For the A29K, a user-controlled variable @code{call_scratch_address}, specifies the location of a scratch area to be used when @value{GDBN} calls a function in the target. This is necessary because the usual method of putting the scratch area on the stack does not work in systems that have separate instruction and data spaces. -@end ifclear -@node Patching, , Calling, Altering +@node Patching @section Patching programs @cindex patching binaries @@ -7926,7 +7564,7 @@ Display whether executable files and core files are opened for writing as well as reading. @end table -@node GDB Files, Targets, Altering, Top +@node GDB Files @chapter @value{GDBN} Files @value{GDBN} needs to know the file name of the program to be debugged, @@ -7939,7 +7577,7 @@ program. To debug a core dump of a previous run, you must also tell * Symbol Errors:: Errors reading symbol files @end menu -@node Files, Symbol Errors, GDB Files, GDB Files +@node Files @section Commands to specify files @cindex symbol table @@ -7968,7 +7606,6 @@ directories to search, just as the shell does when looking for a program to run. You can change the value of this variable, for both @value{GDBN} and your program, using the @code{path} command. -@ifclear HPPA On systems with memory-mapped files, an auxiliary file @file{@var{filename}.syms} may hold symbol table information for @var{filename}. If so, @value{GDBN} maps in the symbol table from @@ -7977,7 +7614,6 @@ descriptions of the file options @samp{-mapped} and @samp{-readnow} (available on the command line, and with the commands @code{file}, @code{symbol-file}, or @code{add-symbol-file}, described below), for more information. -@end ifclear @item file @code{file} with no argument makes @value{GDBN} discard any information it @@ -8012,11 +7648,9 @@ When @value{GDBN} is configured for a particular environment, it understands debugging information in whatever format is the standard generated for that environment; you may use either a @sc{gnu} compiler, or other compilers that adhere to the local conventions. -@ifclear HPPA Best results are usually obtained from @sc{gnu} compilers; for example, using @code{@value{GCC}} you can generate debugging information for optimized code. -@end ifclear For most kinds of object files, with the exception of old SVR3 systems using COFF, the @code{symbol-file} command does not normally read the @@ -8031,7 +7665,6 @@ file are being read. (The @code{set verbose} command can turn these pauses into messages if desired. @xref{Messages/Warnings, ,Optional warnings and messages}.) -@ifclear HPPA We have not implemented the two-stage strategy for COFF yet. When the symbol table is stored in COFF format, @code{symbol-file} reads the symbol table data in full right away. Note that ``stabs-in-COFF'' @@ -8050,9 +7683,7 @@ You can override the @value{GDBN} two-stage strategy for reading symbol tables by using the @samp{-readnow} option with any of the commands that load symbol table information, if you want to be sure @value{GDBN} has the entire symbol table available. -@end ifclear -@ifclear HPPA If memory-mapped files are available on your system through the @code{mmap} system call, you can use another option, @samp{-mapped}, to cause @value{GDBN} to write the symbols for your program into a reusable @@ -8099,9 +7730,7 @@ under @value{GDBN}. So, if you have been running your program and you wish to debug a core file instead, you must kill the subprocess in which the program is running. To do this, use the @code{kill} command (@pxref{Kill Process, ,Killing the child process}). -@end ifclear -@ifclear HPPA @kindex add-symbol-file @cindex dynamic linking @item add-symbol-file @var{filename} @var{address} @@ -8131,9 +7760,7 @@ The @code{add-shared-symbol-file} command can be used only under Harris' CXUX operating system for the Motorola 88k. @value{GDBN} automatically looks for shared libraries, however if @value{GDBN} does not find yours, you can run @code{add-shared-symbol-file}. It takes no arguments. -@end ifclear -@ifclear HPPA @kindex section @item section The @code{section} command changes the base address of section SECTION of @@ -8142,7 +7769,6 @@ section addresses, (such as in the a.out format), or when the addresses specified in the file itself are wrong. Each section must be changed separately. The ``info files'' command lists all the sections and their addresses. -@end ifclear @kindex info files @kindex info target @@ -8162,23 +7788,18 @@ as arguments. @value{GDBN} always converts the file name to an absolute file name and remembers it that way. @cindex shared libraries -@ifclear HPPA -@c added HP-UX -- Kim (HP writer) @value{GDBN} supports HP-UX, SunOS, SVr4, Irix 5, and IBM RS/6000 shared libraries. -@end ifclear -@ifset HPPA -@value{GDBN} supports HP-UX shared libraries. -@end ifset + @value{GDBN} automatically loads symbol definitions from shared libraries when you use the @code{run} command, or when you examine a core file. (Before you issue the @code{run} command, @value{GDBN} does not understand references to a function in a shared library, however---unless you are debugging a core file). -@ifset HPPA -If the program loads a library explicitly, @value{GDBN} automatically -loads the symbols at the time of the @code{shl_load} call. -@end ifset + +On HP-UX, if the program loads a library explicitly, @value{GDBN} +automatically loads the symbols at the time of the @code{shl_load} call. + @c FIXME: some @value{GDBN} release may permit some refs to undef @c FIXME...symbols---eg in a break cmd---assuming they are from a shared @c FIXME...lib; check this from time to time when updating manual @@ -8203,10 +7824,9 @@ required by your program for a core file or after typing @code{run}. If loaded. @end table -@ifset HPPA -@value{GDBN} detects the loading of a shared library and automatically -reads in symbols from the newly loaded library, up to a threshold that -is initially set but that you can modify if you wish. +On HP-UX systems, @value{GDBN} detects the loading of a shared library +and automatically reads in symbols from the newly loaded library, up to +a threshold that is initially set but that you can modify if you wish. Beyond that threshold, symbols from shared libraries must be explicitly loaded. To load these symbols, use the command @code{sharedlibrary} @@ -8230,9 +7850,8 @@ Otherwise, symbols must be loaded manually, using the @item show auto-solib-add Display the current autoloading size threshold, in megabytes. @end table -@end ifset -@node Symbol Errors, , Files, GDB Files +@node Symbol Errors @section Errors reading symbol files While reading a symbol file, @value{GDBN} occasionally encounters problems, @@ -8321,46 +7940,22 @@ it. @end table -@node Targets, Controlling GDB, GDB Files, Top +@node Targets @chapter Specifying a Debugging Target @cindex debugging target @kindex target A @dfn{target} is the execution environment occupied by your program. -@ifclear HPPA -Often, @value{GDBN} runs in the same host environment as your program; in -that case, the debugging target is specified as a side effect when you -use the @code{file} or @code{core} commands. When you need more + +Often, @value{GDBN} runs in the same host environment as your program; +in that case, the debugging target is specified as a side effect when +you use the @code{file} or @code{core} commands. When you need more flexibility---for example, running @value{GDBN} on a physically separate host, or controlling a standalone system over a serial port or a -realtime system over a TCP/IP connection---you -@end ifclear -@ifset HPPA -On HP-UX systems, @value{GDBN} has been configured to support debugging -of processes running on the PA-RISC architecture. This means that the -only possible targets are: - -@itemize @bullet -@item -An executable that has been compiled and linked to run on HP-UX - -@item -A live HP-UX process, either started by @value{GDBN} (with the -@code{run} command) or started outside of @value{GDBN} and attached to -(with the @code{attach} command) - -@item -A core file generated by an HP-UX process that previously aborted -execution -@end itemize - -@value{GDBN} on HP-UX has not been configured to support remote -debugging, or to support programs running on other platforms. You -can use the @code{target} command to specify one of the target types -configured for @value{GDBN} (@pxref{Target Commands, ,Commands for managing -targets}). -@end ifset +realtime system over a TCP/IP connection---you can use the @code{target} +command to specify one of the target types configured for @value{GDBN} +(@pxref{Target Commands, ,Commands for managing targets}). @menu * Active Targets:: Active targets @@ -8371,7 +7966,7 @@ targets}). @end menu -@node Active Targets, Target Commands, Targets, Targets +@node Active Targets @section Active targets @cindex stacking targets @@ -8406,7 +8001,7 @@ files}). To specify as a target a process that is already running, use the @code{attach} command (@pxref{Attach, ,Debugging an already-running process}). -@node Target Commands, Byte Order, Active Targets, Targets +@node Target Commands @section Commands for managing targets @table @code @@ -8454,13 +8049,8 @@ Use the @code{show gnutarget} command to display what file format and @code{show gnutarget} displays @samp{The current BDF target is "auto"}. @end table -@ifclear HPPA Here are some common targets (available, or not, depending on the GDB configuration): -@end ifclear -@ifset HPPA -These are the valid targets on HP-UX systems: -@end ifset @table @code @kindex target exec @@ -8482,11 +8072,9 @@ now supports the @code{load} command. This is only useful if you have some other way of getting the stub to the target system, and you can put it somewhere in memory where it won't get clobbered by the download. -@ifclear HPPA @kindex target sim @item target sim CPU simulator. @xref{Simulator,,Simulated CPU Target}. -@end ifclear @end table The following targets are all CPU-specific, and only available for @@ -8706,7 +8294,7 @@ opens it as the current executable target for @value{GDBN} on your host @code{load} does not repeat if you press @key{RET} again after using it. @end table -@node Byte Order, Remote, Target Commands, Targets +@node Byte Order @section Choosing target byte order @cindex choosing target byte order @@ -8746,7 +8334,7 @@ Note that these commands merely adjust interpretation of symbolic data on the host, and that they have absolutely no effect on the target system. -@node Remote, KOD, Byte Order, Targets +@node Remote @section Remote debugging @cindex remote debugging @@ -8785,7 +8373,7 @@ configuration of @value{GDBN}; use @code{help target} to list them. @include remote.texi -@node KOD, , Remote, Targets +@node KOD @section Kernel Object Display @cindex kernel object display @cindex kernel object @@ -8826,10 +8414,10 @@ is supported other than to try it. @node Controlling GDB @chapter Controlling @value{GDBN} -You can alter the way @value{GDBN} interacts with you by using -the @code{set} command. For commands controlling how @value{GDBN} displays -data, @pxref{Print Settings, ,Print settings}; other settings are described -here. +You can alter the way @value{GDBN} interacts with you by using the +@code{set} command. For commands controlling how @value{GDBN} displays +data, @pxref{Print Settings, ,Print settings}; other settings are +described here. @menu * Prompt:: Prompt @@ -8840,7 +8428,7 @@ here. * Messages/Warnings:: Optional warnings and messages @end menu -@node Prompt, Editing, Controlling GDB, Controlling GDB +@node Prompt @section Prompt @cindex prompt @@ -8866,7 +8454,7 @@ Directs @value{GDBN} to use @var{newprompt} as its prompt string henceforth. Prints a line of the form: @samp{Gdb's prompt is: @var{your-prompt}} @end table -@node Editing, History, Prompt, Controlling GDB +@node Editing @section Command editing @cindex readline @cindex command line editing @@ -8896,7 +8484,7 @@ Disable command line editing. Show whether command line editing is enabled. @end table -@node History, Screen Size, Editing, Controlling GDB +@node History @section Command history @value{GDBN} can keep track of the commands you type during your @@ -8992,7 +8580,7 @@ Print ten commands centered on command number @var{n}. Print ten commands just after the commands last printed. @end table -@node Screen Size, Numbers, History, Controlling GDB +@node Screen Size @section Screen size @cindex size of screen @cindex pauses in output @@ -9033,7 +8621,7 @@ Likewise, you can specify @samp{set width 0} to prevent @value{GDBN} from wrapping its output. @end table -@node Numbers, Messages/Warnings, Screen Size, Controlling GDB +@node Numbers @section Numbers @cindex number representation @cindex entering numbers @@ -9079,7 +8667,7 @@ Display the current default base for numeric input. Display the current default base for numeric display. @end table -@node Messages/Warnings, , Numbers, Controlling GDB +@node Messages/Warnings @section Optional warnings and messages By default, @value{GDBN} is silent about its inner workings. If you are running @@ -9150,7 +8738,7 @@ Enables confirmation requests (the default). Displays state of confirmation requests. @end table -@node Sequences, Emacs, Controlling GDB, Top +@node Sequences @chapter Canned Sequences of Commands Aside from breakpoint commands (@pxref{Break Commands, ,Breakpoint @@ -9164,7 +8752,7 @@ for execution as a unit: user-defined commands and command files. * Output:: Commands for controlled output @end menu -@node Define, Hooks, Sequences, Sequences +@node Define @section User-defined commands @cindex user-defined command @@ -9253,7 +8841,7 @@ without asking when used inside a user-defined command. Many @value{GDBN} commands that normally print messages to say what they are doing omit the messages when used in a user-defined command. -@node Hooks, Command Files, Define, Sequences +@node Hooks @section User-defined command hooks @cindex command files @@ -9297,7 +8885,7 @@ If an error occurs during the execution of your hook, execution of If you try to define a hook which does not match any known command, you get a warning from the @code{define} command. -@node Command Files, Output, Hooks, Sequences +@node Command Files @section Command files @cindex command files @@ -9357,7 +8945,7 @@ without asking when used in a command file. Many @value{GDBN} commands that normally print messages to say what they are doing omit the messages when called from command files. -@node Output, , Command Files, Sequences +@node Output @section Commands for controlled output During the execution of a command file or a user-defined command, normal @@ -9433,7 +9021,7 @@ string are the simple ones that consist of backslash followed by a letter. @end table -@node Emacs, GDB Bugs, Sequences, Top +@node Emacs @chapter Using @value{GDBN} under @sc{gnu} Emacs @cindex Emacs @@ -9446,9 +9034,7 @@ To use this interface, use the command @kbd{M-x gdb} in Emacs. Give the executable file you want to debug as an argument. This command starts @value{GDBN} as a subprocess of Emacs, with input and output through a newly created Emacs buffer. -@ifset HPPA -(Do not use the @code{-tui} option to run @value{GDBN} from Emacs.) -@end ifset +@c (Do not use the @code{-tui} option to run @value{GDBN} from Emacs.) Using @value{GDBN} under Emacs is just like using @value{GDBN} normally except for two things: @@ -9610,8 +9196,6 @@ each value is printed in its own window. @end ignore @node GDB Bugs -@c links whacked to pacify makeinfo -@c , Command Line Editing, Emacs, Top @chapter Reporting Bugs in @value{GDBN} @cindex bugs in @value{GDBN} @cindex reporting bugs in @value{GDBN} @@ -9631,7 +9215,7 @@ information that enables us to fix the bug. * Bug Reporting:: How to report bugs @end menu -@node Bug Criteria, Bug Reporting, GDB Bugs, GDB Bugs +@node Bug Criteria @section Have you found a bug? @cindex bug criteria @@ -9663,12 +9247,11 @@ If you are an experienced user of debugging tools, your suggestions for improvement of @value{GDBN} are welcome in any case. @end itemize -@node Bug Reporting, , Bug Criteria, GDB Bugs +@node Bug Reporting @section How to report bugs @cindex bug reports @cindex @value{GDBN} bugs, reporting -@ifclear HPPA A number of companies and individuals offer support for @sc{gnu} products. If you obtained @value{GDBN} from a support organization, we recommend you contact that organization first. @@ -9708,15 +9291,6 @@ Free Software Foundation Inc. Boston, MA 02111-1307 USA @end example -@end ifclear - -@ifset HPPA -If you obtained HP GDB as part of your HP ANSI C or HP ANSI C++ compiler -kit, report problems to your HP Support Representative. - -If you obtained HP GDB from the Hewlett-Packard Web site, report -problems by electronic mail to @code{wdb-www@@ch.hp.com}. -@end ifset The fundamental principle of reporting bugs usefully is this: @strong{report all the facts}. If you are not sure whether to state a @@ -9757,11 +9331,9 @@ the bug in the current version of @value{GDBN}. The type of machine you are using, and the operating system name and version number. -@ifclear HPPA @item What compiler (and its version) was used to compile @value{GDBN}---e.g. ``@value{GCC}--2.8.1''. -@end ifclear @item What compiler (and its version) was used to compile the program you are @@ -9801,7 +9373,6 @@ ours fails to crash, we would know that the bug was not happening for us. If you had not told us to expect a crash, then we would not be able to draw any conclusion from our observations. -@ifclear HPPA @item If you wish to suggest changes to the @value{GDBN} source, send us context diffs. If you even discuss something in the @value{GDBN} source, refer to @@ -9809,7 +9380,7 @@ it by context, not by line number. The line numbers in our development sources will not match those in your sources. Your line numbers would convey no useful information to us. -@end ifclear + @end itemize Here are some things that are not necessary: @@ -9869,11 +9440,7 @@ things without first using the debugger to find the facts. @include inc-hist.texinfo -@ifclear PRECONFIGURED -@ifclear HPPA @node Formatting Documentation -@c links whacked to pacify makeinfo -@c , Installing GDB, Renamed Commands, Top @appendix Formatting Documentation @cindex @value{GDBN} reference card @@ -9958,43 +9525,12 @@ make gdb.dvi @end example Then give @file{gdb.dvi} to your @sc{dvi} printing program. -@end ifclear -@node Installing GDB, Index, Using History Interactively, Top +@node Installing GDB @appendix Installing @value{GDBN} @cindex configuring @value{GDBN} @cindex installation -@ifset HPPA -If you obtain @value{GDBN} (HP WDB 0.75) as part of your HP ANSI C or -HP ANSI C++ Developer's Kit at HP-UX Release 11.0, you do not have to -take any special action to build or install @value{GDBN}. - -If you obtain @value{GDBN} (HP WDB 0.75) from an HP web site, you may -download either a @code{swinstall}-able package or a source tree, or -both. - -Most customers will want to install the @value{GDBN} binary that is part -of the @code{swinstall}-able package. To do so, use a command of the -form - -@smallexample -/usr/sbin/swinstall -s @var{package-name} WDB -@end smallexample - -Alternatively, it is possible to build @value{GDBN} from the source -distribution. Sophisticated customers who want to modify the debugger -sources to tailor @value{GDBN} to their their needs may wish to do this. -The source distribution consists of a @code{tar}'ed source tree rooted -at @file{gdb-4.16/...}. The instructions that follow describe how to -build a @file{gdb} executable from this source tree. HP believes that -these instructions apply to the WDB source tree that it distributes. -However, HP does not explicitly support building a @file{gdb} for any -non-HP platform from the WDB source tree. It may work, but HP has not -tested it for any platforms other than those described in the WDB 0.75 -Release Notes. -@end ifset - @value{GDBN} comes with a @code{configure} script that automates the process of preparing @value{GDBN} for installation; you can then use @code{make} to build the @code{gdb} program. @@ -10110,7 +9646,7 @@ let @value{GDBN} debug child processes whose programs are not readable. * Configure Options:: Summary of options for configure @end menu -@node Separate Objdir, Config Names, Installing GDB, Installing GDB +@node Separate Objdir @section Compiling @value{GDBN} in another directory If you want to run @value{GDBN} versions for several host or target machines, @@ -10171,7 +9707,7 @@ directories, you can run @code{make} on them in parallel (for example, if they are NFS-mounted on each of the hosts); they will not interfere with each other. -@node Config Names, Configure Options, Separate Objdir, Installing GDB +@node Config Names @section Specifying names for hosts and targets The specifications used for hosts and targets in the @code{configure} @@ -10213,7 +9749,7 @@ Invalid configuration `i986v': machine `i986v' not recognized @code{config.sub} is also distributed in the @value{GDBN} source directory (@file{gdb-@value{GDBVN}}, for version @value{GDBVN}). -@node Configure Options, , Config Names, Installing GDB +@node Configure Options @section @code{configure} options Here is a summary of the @code{configure} options and arguments that @@ -10281,10 +9817,8 @@ There is no convenient way to generate a list of all available hosts. There are many other options available as well, but they are generally needed for special purposes only. -@end ifclear - -@node Index, , Installing GDB, Top +@node Index @unnumbered Index @printindex cp diff --git a/gdb/doc/gdbint.texinfo b/gdb/doc/gdbint.texinfo index 8787112..d7df1e5 100644 --- a/gdb/doc/gdbint.texinfo +++ b/gdb/doc/gdbint.texinfo @@ -2365,35 +2365,15 @@ are just as hard to understand as a single thousand-line function. @subsection Function Prototypes -Prototypes must be used to @emph{declare} functions but never to +Prototypes must be used to @emph{declare} functions, and may be used to @emph{define} them. Prototypes for GDB functions must include both the argument type and name, with the name matching that used in the actual function definition. -For the sake of compatibility with pre-ANSI compilers, define prototypes -with the @code{PARAMS} macro: - -@example @code -extern int memory_remove_breakpoint PARAMS ((CORE_ADDR addr, - char *contents_cache)); -@end example - -Note the double parentheses around the parameter types. This allows an -arbitrary number of parameters to be described, without freaking out the -C preprocessor. When the function has no parameters, it should be -described like: - -@example @code -extern void noprocess PARAMS ((void)); -@end example - -The @code{PARAMS} macro expands to its argument in ANSI C, or to a -simple @code{()} in traditional C. - -All external functions should have a @code{PARAMS} declaration in a -header file that callers include, except for @code{_initialize_*} -functions, which must be external so that @file{init.c} construction -works, but shouldn't be visible to random source files. +All external functions should have a declaration in a header file that +callers include, except for @code{_initialize_*} functions, which must +be external so that @file{init.c} construction works, but shouldn't be +visible to random source files. All static functions must be declared in a block near the top of the source file. diff --git a/gdb/frame.h b/gdb/frame.h index 39e41ef..d154b94 100644 --- a/gdb/frame.h +++ b/gdb/frame.h @@ -247,11 +247,6 @@ extern void generic_fix_call_dummy PARAMS ((char *dummy, CORE_ADDR pc, CORE_ADDR int nargs, struct value ** args, struct type * type, int gcc_p)); -#ifdef __STDC__ -/* Some native compilers, even ones that are supposed to be ANSI and for which __STDC__ - is true, complain about forward decls of enums. */ -enum lval_type; extern void generic_get_saved_register PARAMS ((char *, int *, CORE_ADDR *, struct frame_info *, int, enum lval_type *)); -#endif #endif /* !defined (FRAME_H) */ diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h index 3d57097..d7583fd 100644 --- a/gdb/gdbarch.h +++ b/gdb/gdbarch.h @@ -26,7 +26,6 @@ #ifdef __STDC__ struct frame_info; struct value; -enum lval_type; #endif diff --git a/gdb/go32-nat.c b/gdb/go32-nat.c index b77f3f0..0c133bc 100644 --- a/gdb/go32-nat.c +++ b/gdb/go32-nat.c @@ -33,9 +33,15 @@ #include <stdio.h> /* required for __DJGPP_MINOR__ */ #include <stdlib.h> #include <string.h> +#include <errno.h> #include <unistd.h> +#include <io.h> +#include <dpmi.h> #include <debug/v2load.h> #include <debug/dbgcom.h> +#if __DJGPP_MINOR__ > 2 +#include <debug/redir.h> +#endif #if __DJGPP_MINOR__ < 3 /* This code will be provided from DJGPP 2.03 on. Until then I code it @@ -106,6 +112,27 @@ load_npx (void) { asm ("frstor %0":"=m" (npx)); } +/* ------------------------------------------------------------------------- */ +/* Stubs for the missing redirection functions. */ +typedef struct { + char *command; + int redirected; +} cmdline_t; + +void redir_cmdline_delete (cmdline_t *ptr) {ptr->redirected = 0;} +int redir_cmdline_parse (const char *args, cmdline_t *ptr) +{ + return -1; +} +int redir_to_child (cmdline_t *ptr) +{ + return 1; +} +int redir_to_debugger (cmdline_t *ptr) +{ + return 1; +} +int redir_debug_init (cmdline_t *ptr) { return 0; } #endif /* __DJGPP_MINOR < 3 */ extern void _initialize_go32_nat (void); @@ -127,6 +154,11 @@ struct env387 unsigned char regs[8][10]; }; +typedef enum { wp_insert, wp_remove, wp_count } wp_op; + +/* This holds the current reference counts for each debug register. */ +static int dr_ref_count[4]; + extern char **environ; #define SOME_PID 42 @@ -149,14 +181,17 @@ static void go32_files_info (struct target_ops *target); static void go32_stop (void); static void go32_kill_inferior (void); static void go32_create_inferior (char *exec_file, char *args, char **env); +static void cleanup_dregs (void); static void go32_mourn_inferior (void); static int go32_can_run (void); static void ignore (void); static void ignore2 (char *a, int b); -static int go32_insert_aligned_watchpoint (int pid, CORE_ADDR waddr, - CORE_ADDR addr, int len, int rw); -static int go32_insert_nonaligned_watchpoint (int pid, CORE_ADDR waddr, - CORE_ADDR addr, int len, int rw); +static int go32_insert_aligned_watchpoint (CORE_ADDR waddr, CORE_ADDR addr, + int len, int rw); +static int go32_remove_aligned_watchpoint (CORE_ADDR waddr, CORE_ADDR addr, + int len, int rw); +static int go32_handle_nonaligned_watchpoint (wp_op what, CORE_ADDR waddr, + CORE_ADDR addr, int len, int rw); static struct target_ops go32_ops; static void go32_terminal_init (void); @@ -187,8 +222,14 @@ print_387_status (unsigned short status, struct env387 *ep) } print_387_control_word (ep->control & 0xffff); - printf_unfiltered ("last exception: "); - printf_unfiltered ("opcode %s; ", local_hex_string (ep->opcode)); + /* Other platforms say "last exception", but that's not true: the + FPU stores the last non-control instruction there. */ + printf_unfiltered ("last FP instruction: "); + /* The ORing with D800h restores the upper 5 bits of the opcode that + are not stored by the FPU (since these bits are the same for all + floating-point instructions). */ + printf_unfiltered ("opcode %s; ", + local_hex_string (ep->opcode ? (ep->opcode|0xd800) : 0)); printf_unfiltered ("pc %s:", local_hex_string (ep->code_seg)); printf_unfiltered ("%s; ", local_hex_string (ep->eip)); printf_unfiltered ("operand %s", local_hex_string (ep->operand_seg)); @@ -196,35 +237,44 @@ print_387_status (unsigned short status, struct env387 *ep) top = (ep->status >> 11) & 7; - printf_unfiltered ("regno tag msb lsb value\n"); - for (fpreg = 0; fpreg < 8; fpreg++) + printf_unfiltered ("regno tag msb lsb value\n"); + for (fpreg = 7; fpreg >= 0; fpreg--) { + /* FNSAVE saves the FP registers in their logical TOP-relative + order, beginning with ST(0). Since we need to print them in + their physical order, we have to remap them. */ + int regno = fpreg - top; long double val; + if (regno < 0) + regno += 8; + printf_unfiltered ("%s %d: ", fpreg == top ? "=>" : " ", fpreg); switch ((ep->tag >> (fpreg * 2)) & 3) { case 0: - printf_unfiltered ("valid "); + printf_unfiltered ("valid "); break; case 1: - printf_unfiltered ("zero "); + printf_unfiltered ("zero "); break; case 2: - printf_unfiltered ("trap "); + /* All other versions of print_387_status use TRAP here, but I + think this is misleading, since Intel manuals say SPECIAL. */ + printf_unfiltered ("special "); break; case 3: - printf_unfiltered ("empty "); + printf_unfiltered ("empty "); break; } - for (i = 0; i < 8; i++) - printf_unfiltered ("%02x", ep->regs[fpreg][i]); + for (i = 9; i >= 0; i--) + printf_unfiltered ("%02x", ep->regs[regno][i]); - REGISTER_CONVERT_TO_VIRTUAL (FP0_REGNUM + fpreg, builtin_type_long_double, - &ep->regs[fpreg], &val); + REGISTER_CONVERT_TO_VIRTUAL (FP0_REGNUM+regno, builtin_type_long_double, + &ep->regs[regno], &val); - printf_unfiltered (" %LG\n", val); + printf_unfiltered (" %.19LG\n", val); } } @@ -234,16 +284,16 @@ i386_go32_float_info (void) print_387_status (0, (struct env387 *) &npx); } -#define r_ofs(x) ((int)(&(((TSS *)0)->x))) +#define r_ofs(x) (offsetof(TSS,x)) static struct { - int tss_ofs; - int size; + size_t tss_ofs; + size_t size; } regno_mapping[] = { - r_ofs (tss_eax), 4, + r_ofs (tss_eax), 4, /* normal registers, from a_tss */ r_ofs (tss_ecx), 4, r_ofs (tss_edx), 4, r_ofs (tss_ebx), 4, @@ -259,7 +309,7 @@ regno_mapping[] = r_ofs (tss_es), 2, r_ofs (tss_fs), 2, r_ofs (tss_gs), 2, - 0, 10, + 0, 10, /* 8 FP registers, from npx.reg[] */ 1, 10, 2, 10, 3, 10, @@ -267,13 +317,15 @@ regno_mapping[] = 5, 10, 6, 10, 7, 10, - 0, 2, - 4, 2, - 8, 2, - 12, 4, - 16, 2, - 20, 4, - 24, 2 + /* The order of the next 7 registers must be consistent + with their numbering in config/i386/tm-go32.h, which see. */ + 0, 2, /* control word, from npx */ + 4, 2, /* status word, from npx */ + 8, 2, /* tag word, from npx */ + 16, 2, /* last FP exception CS from npx */ + 24, 2, /* last FP exception operand selector from npx */ + 12, 4, /* last FP exception EIP from npx */ + 20, 4 /* last FP exception operand offset from npx */ }; static struct @@ -285,7 +337,10 @@ sig_map[] = { 0, TARGET_SIGNAL_FPE, 1, TARGET_SIGNAL_TRAP, - 2, TARGET_SIGNAL_UNKNOWN, + /* Exception 2 is triggered by the NMI. DJGPP handles it as SIGILL, + but I think SIGBUS is better, since the NMI is usually activated + as a result of a memory parity check failure. */ + 2, TARGET_SIGNAL_BUS, 3, TARGET_SIGNAL_TRAP, 4, TARGET_SIGNAL_FPE, 5, TARGET_SIGNAL_SEGV, @@ -296,20 +351,43 @@ sig_map[] = 10, TARGET_SIGNAL_BUS, 11, TARGET_SIGNAL_SEGV, 12, TARGET_SIGNAL_SEGV, - 13, TARGET_SIGNAL_ABRT, + 13, TARGET_SIGNAL_SEGV, 14, TARGET_SIGNAL_SEGV, 16, TARGET_SIGNAL_FPE, + 17, TARGET_SIGNAL_BUS, 31, TARGET_SIGNAL_ILL, + 0x1b, TARGET_SIGNAL_INT, 0x75, TARGET_SIGNAL_FPE, + 0x78, TARGET_SIGNAL_ALRM, 0x79, TARGET_SIGNAL_INT, - 0x1b, TARGET_SIGNAL_INT, + 0x7a, TARGET_SIGNAL_QUIT, -1, -1 }; +static struct { + enum target_signal gdb_sig; + int djgpp_excepno; +} excepn_map[] = { + TARGET_SIGNAL_0, -1, + TARGET_SIGNAL_ILL, 6, /* Invalid Opcode */ + TARGET_SIGNAL_EMT, 7, /* triggers SIGNOFP */ + TARGET_SIGNAL_SEGV, 13, /* GPF */ + TARGET_SIGNAL_BUS, 17, /* Alignment Check */ + /* The rest are fake exceptions, see dpmiexcp.c in djlsr*.zip for + details. */ + TARGET_SIGNAL_TERM, 0x1b, /* triggers Ctrl-Break type of SIGINT */ + TARGET_SIGNAL_FPE, 0x75, + TARGET_SIGNAL_INT, 0x79, + TARGET_SIGNAL_QUIT, 0x7a, + TARGET_SIGNAL_ALRM, 0x78, /* triggers SIGTIMR */ + TARGET_SIGNAL_PROF, 0x78, + -1, -1 +}; + static void go32_open (char *name, int from_tty) { - printf_unfiltered ("Use the `run' command to run go32 programs\n"); + printf_unfiltered ("Done. Use the \"run\" command to run the program.\n"); } static void @@ -320,7 +398,9 @@ go32_close (int quitting) static void go32_attach (char *args, int from_tty) { - printf_unfiltered ("Use the `run' command to run go32 programs\n"); + error ("\ +You cannot attach to a running program on this platform.\n\ +Use the `run' command to run DJGPP programs."); } static void @@ -329,31 +409,115 @@ go32_detach (char *args, int from_tty) } static int resume_is_step; +static int resume_signal = -1; static void go32_resume (int pid, int step, enum target_signal siggnal) { + int i; + resume_is_step = step; + + if (siggnal != TARGET_SIGNAL_0 && siggnal != TARGET_SIGNAL_TRAP) + { + for (i = 0, resume_signal = -1; excepn_map[i].gdb_sig != -1; i++) + if (excepn_map[i].gdb_sig == siggnal) + { + resume_signal = excepn_map[i].djgpp_excepno; + break; + } + if (resume_signal == -1) + printf_unfiltered ("Cannot deliver signal %s on this platform.\n", + target_signal_to_name (siggnal)); + } } +static char child_cwd[FILENAME_MAX]; + static int go32_wait (int pid, struct target_waitstatus *status) { int i; + unsigned char saved_opcode; + unsigned long INT3_addr; + int stepping_over_INT = 0; + a_tss.tss_eflags &= 0xfeff; /* reset the single-step flag (TF) */ if (resume_is_step) - a_tss.tss_eflags |= 0x0100; + { + /* If the next instruction is INT xx or INTO, we need to handle + them specially. Intel manuals say that these instructions + reset the single-step flag (a.k.a. TF). However, it seems + that, at least in the DPMI environment, and at least when + stepping over the DPMI interrupt 31h, the problem is having + TF set at all when INT 31h is executed: the debuggee either + crashes (and takes the system with it) or is killed by a + SIGTRAP. + + So we need to emulate single-step mode: we put an INT3 opcode + right after the INT xx instruction, let the debuggee run + until it hits INT3 and stops, then restore the original + instruction which we overwrote with the INT3 opcode, and back + up the debuggee's EIP to that instruction. */ + read_child (a_tss.tss_eip, &saved_opcode, 1); + if (saved_opcode == 0xCD || saved_opcode == 0xCE) + { + unsigned char INT3_opcode = 0xCC; + + INT3_addr + = saved_opcode == 0xCD ? a_tss.tss_eip + 2 : a_tss.tss_eip + 1; + stepping_over_INT = 1; + read_child (INT3_addr, &saved_opcode, 1); + write_child (INT3_addr, &INT3_opcode, 1); + } + else + a_tss.tss_eflags |= 0x0100; /* normal instruction: set TF */ + } + + /* The special value FFFFh in tss_trap indicates to run_child that + tss_irqn holds a signal to be delivered to the debuggee. */ + if (resume_signal <= -1) + { + a_tss.tss_trap = 0; + a_tss.tss_irqn = 0xff; + } else - a_tss.tss_eflags &= 0xfeff; + { + a_tss.tss_trap = 0xffff; /* run_child looks for this */ + a_tss.tss_irqn = resume_signal; + } + + /* The child might change working directory behind our back. The + GDB users won't like the side effects of that when they work with + relative file names, and GDB might be confused by its current + directory not being in sync with the truth. So we always make a + point of changing back to where GDB thinks is its cwd, when we + return control to the debugger, but restore child's cwd before we + run it. */ + chdir (child_cwd); #if __DJGPP_MINOR__ < 3 - save_npx (); + load_npx (); #endif run_child (); #if __DJGPP_MINOR__ < 3 - load_npx (); + save_npx (); #endif + /* Did we step over an INT xx instruction? */ + if (stepping_over_INT && a_tss.tss_eip == INT3_addr + 1) + { + /* Restore the original opcode. */ + a_tss.tss_eip--; /* EIP points *after* the INT3 instruction */ + write_child (a_tss.tss_eip, &saved_opcode, 1); + /* Simulate a TRAP exception. */ + a_tss.tss_irqn = 1; + a_tss.tss_eflags |= 0x0100; + } + + getcwd (child_cwd, sizeof (child_cwd)); /* in case it has changed */ + chdir (current_directory); + if (a_tss.tss_irqn == 0x21) { status->kind = TARGET_WAITKIND_EXITED; @@ -367,9 +531,13 @@ go32_wait (int pid, struct target_waitstatus *status) { if (a_tss.tss_irqn == sig_map[i].go32_sig) { +#if __DJGPP_MINOR__ < 3 if ((status->value.sig = sig_map[i].gdb_sig) != TARGET_SIGNAL_TRAP) status->kind = TARGET_WAITKIND_SIGNALLED; +#else + status->value.sig = sig_map[i].gdb_sig; +#endif break; } } @@ -400,13 +568,9 @@ go32_fetch_registers (int regno) (char *) &npx.reg[regno_mapping[regno].tss_ofs]); else if (regno < 31) supply_register (regno, - (char *) &npx.reg + regno_mapping[regno].tss_ofs); + (char *) &npx + regno_mapping[regno].tss_ofs); else - { - printf_unfiltered ("Invalid register in go32_fetch_register(%d)", - regno); - exit (1); - } + fatal ("Invalid register no. %d in go32_fetch_register.", regno); } } @@ -420,13 +584,10 @@ store_register (int regno) rp = (char *) &a_tss + regno_mapping[regno].tss_ofs; else if (regno < 24) rp = (char *) &npx.reg[regno_mapping[regno].tss_ofs]; - else if (regno > 31) + else if (regno < 31) rp = (char *) &npx + regno_mapping[regno].tss_ofs; else - { - printf_unfiltered ("Invalid register in store_register(%d)", regno); - exit (1); - } + fatal ("Invalid register no. %d in store_register.", regno); memcpy (rp, v, regno_mapping[regno].size); } @@ -477,10 +638,12 @@ go32_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, } } +static cmdline_t child_cmd; /* parsed child's command line kept here */ + static void go32_files_info (struct target_ops *target) { - printf_unfiltered ("You are running a DJGPP V2 program\n"); + printf_unfiltered ("You are running a DJGPP V2 program.\n"); } static void @@ -495,6 +658,9 @@ go32_stop (void) static void go32_kill_inferior (void) { + redir_cmdline_delete (&child_cmd); + resume_signal = -1; + resume_is_step = 0; unpush_target (&go32_ops); } @@ -510,6 +676,22 @@ go32_create_inferior (char *exec_file, char *args, char **env) go32_stop (); go32_kill_inferior (); } + resume_signal = -1; + resume_is_step = 0; + /* Init command line storage. */ + if (redir_debug_init (&child_cmd) == -1) + fatal ("Cannot allocate redirection storage: not enough memory.\n"); + + /* Parse the command line and create redirections. */ + if (strpbrk (args, "<>")) + { + if (redir_cmdline_parse (args, &child_cmd) == 0) + args = child_cmd.command; + else + error ("Syntax error in command line."); + } + else + child_cmd.command = strdup (args); cmdline = (char *) alloca (strlen (args) + 4); cmdline[0] = strlen (args); @@ -527,6 +709,9 @@ go32_create_inferior (char *exec_file, char *args, char **env) environ = env_save; edi_init (start_state); +#if __DJGPP_MINOR__ < 3 + save_npx (); +#endif inferior_pid = SOME_PID; push_target (&go32_ops); @@ -539,6 +724,14 @@ go32_create_inferior (char *exec_file, char *args, char **env) static void go32_mourn_inferior (void) { + /* We need to make sure all the breakpoint enable bits in the DR7 + register are reset when the inferior exits. Otherwise, if they + rerun the inferior, the uncleared bits may cause random SIGTRAPs, + failure to set more watchpoints, and other calamities. It would + be nice if GDB itself would take care to remove all breakpoints + at all times, but it doesn't, probably under an assumption that + the OS cleans up when the debuggee exits. */ + cleanup_dregs (); go32_kill_inferior (); generic_mourn_inferior (); } @@ -554,11 +747,6 @@ ignore (void) { } -static void -ignore2 (char *a, int b) -{ -} - /* Hardware watchpoint support. */ #define DR_STATUS 6 @@ -570,7 +758,7 @@ ignore2 (char *a, int b) #define DR_GLOBAL_SLOWDOWN 0x200 #define DR_CONTROL_SHIFT 16 #define DR_CONTROL_SIZE 4 -#define DR_RW_READ 0x3 +#define DR_RW_READWRITE 0x3 #define DR_RW_WRITE 0x1 #define DR_CONTROL_MASK 0xf #define DR_ENABLE_MASK 0x3 @@ -583,16 +771,16 @@ ignore2 (char *a, int b) #define STATUS D_REGS[DR_STATUS] #define IS_REG_FREE(index) \ - (!(CONTROL & (3 << (DR_ENABLE_SIZE * index)))) + (!(CONTROL & (3 << (DR_ENABLE_SIZE * (index))))) #define LOCAL_ENABLE_REG(index) \ - (CONTROL |= (1 << (DR_LOCAL_ENABLE_SHIFT + DR_ENABLE_SIZE * index))) + (CONTROL |= (1 << (DR_LOCAL_ENABLE_SHIFT + DR_ENABLE_SIZE * (index)))) #define GLOBAL_ENABLE_REG(index) \ - (CONTROL |= (1 << (DR_GLOBAL_ENABLE_SHIFT + DR_ENABLE_SIZE * index))) + (CONTROL |= (1 << (DR_GLOBAL_ENABLE_SHIFT + DR_ENABLE_SIZE * (index)))) #define DISABLE_REG(index) \ - (CONTROL &= ~(3 << (DR_ENABLE_SIZE * index))) + (CONTROL &= ~(3 << (DR_ENABLE_SIZE * (index)))) #define SET_LOCAL_EXACT() \ (CONTROL |= DR_LOCAL_SLOWDOWN) @@ -600,96 +788,158 @@ ignore2 (char *a, int b) #define SET_GLOBAL_EXACT() \ (CONTROL |= DR_GLOBAL_SLOWDOWN) +#define RESET_LOCAL_EXACT() \ + (CONTROL &= ~(DR_LOCAL_SLOWDOWN)) + +#define RESET_GLOBAL_EXACT() \ + (CONTROL &= ~(DR_GLOBAL_SLOWDOWN)) + #define SET_BREAK(index,address) \ do {\ - CONTROL &= ~(DR_CONTROL_MASK << (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * index));\ + CONTROL &= ~(DR_CONTROL_MASK << (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * (index)));\ D_REGS[index] = address;\ } while(0) #define SET_WATCH(index,address,rw,len) \ do {\ SET_BREAK(index,address);\ - CONTROL |= (len | rw) << (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * index);\ + CONTROL |= ((len)|(rw)) << (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * (index));\ } while (0) +#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)))\ ) -#if 0 /* use debugging macro */ -#define SHOW_DR(text) \ +#define DR_DEF(index) \ + ((CONTROL >> (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * (index))) & 0x0f) + + +#if 0 /* use debugging macro */ +#define SHOW_DR(text,len) \ do { \ + if (!getenv ("GDB_SHOW_DR")) break; \ fprintf(stderr,"%08x %08x ",edi.dr[7],edi.dr[6]); \ - fprintf(stderr,"%08x %08x ",edi.dr[0],edi.dr[1]); \ - fprintf(stderr,"%08x %08x ",edi.dr[2],edi.dr[3]); \ - fprintf(stderr,"(%s)\n",#text); \ + fprintf(stderr,"%08x %d %08x %d ", \ + edi.dr[0],dr_ref_count[0],edi.dr[1],dr_ref_count[1]); \ + fprintf(stderr,"%08x %d %08x %d ", \ + edi.dr[2],dr_ref_count[2],edi.dr[3],dr_ref_count[3]); \ + fprintf(stderr,(len)?"(%s:%d)\n":"(%s)\n",#text,len); \ } while (0) #else -#define SHOW_DR(text) do {} while (0) +#define SHOW_DR(text,len) do {} while (0) #endif +static void +cleanup_dregs (void) +{ + int i; + + CONTROL = 0; + STATUS = 0; + for (i = 0; i < 4; i++) + { + D_REGS[i] = 0; + dr_ref_count[i] = 0; + } +} + /* Insert a watchpoint. */ int go32_insert_watchpoint (int pid, CORE_ADDR addr, int len, int rw) { - int ret = go32_insert_aligned_watchpoint (pid, addr, addr, len, rw); + int ret = go32_insert_aligned_watchpoint (addr, addr, len, rw); - SHOW_DR (insert_watch); + SHOW_DR (insert_watch, len); return ret; } static int -go32_insert_aligned_watchpoint (int pid, CORE_ADDR waddr, CORE_ADDR addr, +go32_insert_aligned_watchpoint (CORE_ADDR waddr, CORE_ADDR addr, int len, int rw) { int i; int read_write_bits, len_bits; - /* Look for a free debug register. */ - for (i = 0; i <= 3; i++) + /* Values of rw: 0 - write, 1 - read, 2 - access (read and write). + However, x86 doesn't support read-only data breakpoints. */ + read_write_bits = rw ? DR_RW_READWRITE : DR_RW_WRITE; + + switch (len) + { + case 4: + len_bits = DR_LEN_4; + break; + case 2: + len_bits = DR_LEN_2; + break; + case 1: + len_bits = DR_LEN_1; + break; + default: + /* The debug registers only have 2 bits for the length, so + so this value will always fail the loop below. */ + len_bits = 0x10; + } + + /* Look for an occupied debug register with the same address and the + same RW and LEN definitions. If we find one, we can use it for + this watchpoint as well (and save a register). */ + for (i = 0; i < 4; i++) + { + if (!IS_REG_FREE (i) && D_REGS[i] == addr + && DR_DEF (i) == (len_bits | read_write_bits)) { - if (IS_REG_FREE (i)) - break; + dr_ref_count[i]++; + return 0; } + } + + /* Look for a free debug register. */ + for (i = 0; i <= 3; i++) + { + if (IS_REG_FREE (i)) + break; + } /* No more debug registers! */ if (i > 3) return -1; - read_write_bits = ((rw & 1) ? DR_RW_READ : 0) | ((rw & 2) ? DR_RW_WRITE : 0); - - if (len == 1) - len_bits = DR_LEN_1; - else if (len == 2) - { - if (addr % 2) - return go32_insert_nonaligned_watchpoint (pid, waddr, addr, len, rw); - len_bits = DR_LEN_2; - } + if (len == 2) + { + if (addr % 2) + return go32_handle_nonaligned_watchpoint (wp_insert, waddr, addr, + len, rw); + } else if (len == 4) - { - if (addr % 4) - return go32_insert_nonaligned_watchpoint (pid, waddr, addr, len, rw); - len_bits = DR_LEN_4; - } - else - return go32_insert_nonaligned_watchpoint (pid, waddr, addr, len, rw); + { + if (addr % 4) + return go32_handle_nonaligned_watchpoint (wp_insert, waddr, addr, + len, rw); + } + else if (len != 1) + return go32_handle_nonaligned_watchpoint (wp_insert, waddr, addr, len, rw); SET_WATCH (i, addr, read_write_bits, len_bits); LOCAL_ENABLE_REG (i); SET_LOCAL_EXACT (); + SET_GLOBAL_EXACT (); + return 0; } static int -go32_insert_nonaligned_watchpoint (int pid, CORE_ADDR waddr, CORE_ADDR addr, +go32_handle_nonaligned_watchpoint (wp_op what, CORE_ADDR waddr, CORE_ADDR addr, int len, int rw) { int align; int size; - int rv = 0; + int rv = 0, status = 0; static int size_try_array[16] = { @@ -705,12 +955,24 @@ go32_insert_nonaligned_watchpoint (int pid, CORE_ADDR waddr, CORE_ADDR addr, /* Four is the maximum length for 386. */ size = (len > 4) ? 3 : len - 1; size = size_try_array[size * 4 + align]; - rv = go32_insert_aligned_watchpoint (pid, waddr, addr, size, rw); - if (rv) - { - go32_remove_watchpoint (pid, waddr, size); - return rv; - } + if (what == wp_insert) + status = go32_insert_aligned_watchpoint (waddr, addr, size, rw); + else if (what == wp_remove) + status = go32_remove_aligned_watchpoint (waddr, addr, size, rw); + else if (what == wp_count) + rv++; + else + status = -1; + /* We keep the loop going even after a failure, because some of + the other aligned watchpoints might still succeed, e.g. if + they watch addresses that are already watched, and thus just + increment the reference counts of occupied debug registers. + If we break out of the loop too early, we could cause those + addresses watched by other watchpoints to be disabled when + GDB reacts to our failure to insert this watchpoint and tries + to remove it. */ + if (status) + rv = status; addr += size; len -= size; } @@ -720,47 +982,105 @@ go32_insert_nonaligned_watchpoint (int pid, CORE_ADDR waddr, CORE_ADDR addr, /* Remove a watchpoint. */ int -go32_remove_watchpoint (int pid, CORE_ADDR addr, int len) +go32_remove_watchpoint (int pid, CORE_ADDR addr, int len, int rw) +{ + int ret = go32_remove_aligned_watchpoint (addr, addr, len, rw); + + SHOW_DR (remove_watch, len); + return ret; +} + +static int +go32_remove_aligned_watchpoint (CORE_ADDR waddr, CORE_ADDR addr, + int len, int rw) { int i; + int read_write_bits, len_bits; + + /* Values of rw: 0 - write, 1 - read, 2 - access (read and write). + However, x86 doesn't support read-only data breakpoints. */ + read_write_bits = rw ? DR_RW_READWRITE : DR_RW_WRITE; + + switch (len) + { + case 4: + len_bits = DR_LEN_4; + break; + case 2: + len_bits = DR_LEN_2; + break; + case 1: + len_bits = DR_LEN_1; + break; + default: + /* The debug registers only have 2 bits for the length, so + so this value will always fail the loop below. */ + len_bits = 0x10; + } + + if (len == 2) + { + if (addr % 2) + return go32_handle_nonaligned_watchpoint (wp_remove, waddr, addr, + len, rw); + } + else if (len == 4) + { + if (addr % 4) + return go32_handle_nonaligned_watchpoint (wp_remove, waddr, addr, + len, rw); + } + else if (len != 1) + return go32_handle_nonaligned_watchpoint (wp_remove, waddr, addr, len, rw); for (i = 0; i <= 3; i++) { - if (D_REGS[i] == addr) + if (!IS_REG_FREE (i) && D_REGS[i] == addr + && DR_DEF (i) == (len_bits | read_write_bits)) { - DISABLE_REG (i); + dr_ref_count[i]--; + if (dr_ref_count[i] == 0) + DISABLE_REG (i); } } - SHOW_DR (remove_watch); + RESET_LOCAL_EXACT (); + RESET_GLOBAL_EXACT (); return 0; } -/* Check if stopped by a watchpoint. */ +/* Can we use debug registers to watch a region whose address is ADDR + and whose length is LEN bytes? */ + +int +go32_region_ok_for_watchpoint (CORE_ADDR addr, int len) +{ + /* Compute how many aligned watchpoints we would need to cover this + region. */ + int nregs = go32_handle_nonaligned_watchpoint (wp_count, addr, addr, len, 0); + + return nregs <= 4 ? 1 : 0; +} + +/* Check if stopped by a data watchpoint. If so, return the address + whose access triggered the watchpoint. */ CORE_ADDR -go32_stopped_by_watchpoint (int pid) +go32_stopped_by_watchpoint (int pid, int data_watchpoint) { int i, ret = 0; int status; status = edi.dr[DR_STATUS]; - SHOW_DR (stopped_by); + SHOW_DR (stopped_by, 0); for (i = 0; i <= 3; i++) { - if (WATCH_HIT (i)) + if (WATCH_HIT (i) && data_watchpoint) { - SHOW_DR (HIT); + SHOW_DR (WP_HIT, 0); ret = D_REGS[i]; } } - /* this is a hack to GDB. If we stopped at a hardware breakpoint, - the stop_pc must incremented by DECR_PC_AFTER_BREAK. I tried everything - with the DECR_PC_AFTER_HW_BREAK, but nothing works. */ - /* This is probably fixed by jtc's recent patch -sts 2/19/99 */ - if (STATUS && !ret) - stop_pc += DECR_PC_AFTER_BREAK; - STATUS = 0; return ret; } @@ -773,12 +1093,14 @@ go32_remove_hw_breakpoint (CORE_ADDR addr, CORE_ADDR shadow) int i; for (i = 0; i <= 3; i++) { - if (D_REGS[i] == addr) + if (!IS_REG_FREE (i) && D_REGS[i] == addr && DR_DEF (i) == 0) { - DISABLE_REG (i); + dr_ref_count[i]--; + if (dr_ref_count[i] == 0) + DISABLE_REG (i); } } - SHOW_DR (remove_hw); + SHOW_DR (remove_hw, 0); return 0; } @@ -790,6 +1112,19 @@ go32_insert_hw_breakpoint (CORE_ADDR addr, CORE_ADDR shadow) int free_debug_register; int register_number; + /* Look for an occupied debug register with the same address and the + same RW and LEN definitions. If we find one, we can use it for + this breakpoint as well (and save a register). */ + for (i = 0; i < 4; i++) + { + if (!IS_REG_FREE (i) && D_REGS[i] == addr && DR_DEF (i) == 0) + { + dr_ref_count[i]++; + SHOW_DR (insert_hw, 0); + return 0; + } + } + /* Look for a free debug register. */ for (i = 0; i <= 3; i++) { @@ -797,50 +1132,147 @@ go32_insert_hw_breakpoint (CORE_ADDR addr, CORE_ADDR shadow) break; } - /* No more debug registers! */ - if (i > 3) - return -1; - - SET_BREAK (i, addr); - LOCAL_ENABLE_REG (i); - SHOW_DR (insert_hw); + /* No more debug registers? */ + if (i < 4) + { + SET_BREAK (i, addr); + LOCAL_ENABLE_REG (i); + } + SHOW_DR (insert_hw, 0); - return 0; + 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. */ + +static int +device_mode (int fd, int raw_p) +{ + int oldmode, newmode; + __dpmi_regs regs; + + regs.x.ax = 0x4400; + regs.x.bx = fd; + __dpmi_int (0x21, ®s); + if (regs.x.flags & 1) + return -1; + newmode = oldmode = regs.x.dx; + + if (raw_p) + newmode |= 0x20; + else + newmode &= ~0x20; + + if (oldmode & 0x80) /* Only for character dev */ + { + regs.x.ax = 0x4401; + regs.x.bx = fd; + regs.x.dx = newmode & 0xff; /* Force upper byte zero, else it fails */ + __dpmi_int (0x21, ®s); + if (regs.x.flags & 1) + return -1; + } + return (oldmode & 0x20) == 0x20; +} + + +static int inf_mode_valid = 0; +static int inf_terminal_mode; + +/* This semaphore is needed because, amazingly enough, GDB calls + target.to_terminal_ours more than once after the inferior stops. + But we need the information from the first call only, since the + second call will always see GDB's own cooked terminal. */ +static int terminal_is_ours = 1; + static void go32_terminal_init (void) { - /* Save the filemodes for stdin/stout */ - inf_in_flag = setmode (0, 0); - setmode (0, inf_in_flag); - inf_out_flag = setmode (1, 0); - setmode (1, inf_out_flag); - inf_flags_valid = 1; + inf_mode_valid = 0; /* reinitialize, in case they are restarting child */ + terminal_is_ours = 1; } static void -go32_terminal_inferior (void) +go32_terminal_info (char *args, int from_tty) { - /* set the filemodes for stdin/stdout of the inferior */ - if (inf_flags_valid) + printf_unfiltered ("Inferior's terminal is in %s mode.\n", + !inf_mode_valid + ? "default" : inf_terminal_mode ? "raw" : "cooked"); + +#if __DJGPP_MINOR__ > 2 + if (child_cmd.redirection) + { + int i; + + for (i = 0; i < DBG_HANDLES; i++) { - setmode (0, inf_in_flag); - setmode (1, inf_out_flag); + if (child_cmd.redirection[i]->file_name) + printf_unfiltered ("\tFile handle %d is redirected to `%s'.\n", + i, child_cmd.redirection[i]->file_name); + else if (_get_dev_info (child_cmd.redirection[i]->inf_handle) == -1) + printf_unfiltered + ("\tFile handle %d appears to be closed by inferior.\n", i); + /* Mask off the raw/cooked bit when comparing device info words. */ + else if ((_get_dev_info (child_cmd.redirection[i]->inf_handle) & 0xdf) + != (_get_dev_info (i) & 0xdf)) + printf_unfiltered + ("\tFile handle %d appears to be redirected by inferior.\n", i); } + } +#endif +} + +static void +go32_terminal_inferior (void) +{ + /* Redirect standard handles as child wants them. */ + errno = 0; + if (redir_to_child (&child_cmd) == -1) + { + redir_to_debugger (&child_cmd); + error ("Cannot redirect standard handles for program: %s.", + strerror (errno)); + } + /* set the console device of the inferior to whatever mode + (raw or cooked) we found it last time */ + if (terminal_is_ours) + { + if (inf_mode_valid) + device_mode (0, inf_terminal_mode); + terminal_is_ours = 0; + } } static void go32_terminal_ours (void) { - /* Switch to text mode on stdin/stdout always on the gdb terminal and - save the inferior modes to be restored later */ - inf_in_flag = setmode (0, O_TEXT); - inf_out_flag = setmode (1, O_TEXT); + /* Switch to cooked mode on the gdb terminal and save the inferior + terminal mode to be restored when it is resumed */ + if (!terminal_is_ours) + { + inf_terminal_mode = device_mode (0, 0); + if (inf_terminal_mode != -1) + inf_mode_valid = 1; + else + /* If device_mode returned -1, we don't know what happens with + handle 0 anymore, so make the info invalid. */ + inf_mode_valid = 0; + terminal_is_ours = 1; + + /* Restore debugger's standard handles. */ + errno = 0; + if (redir_to_debugger (&child_cmd) == -1) + { + redir_to_child (&child_cmd); + error ("Cannot redirect standard handles for debugger: %s.", + strerror (errno)); + } + } } static void @@ -852,6 +1284,7 @@ init_go32_ops (void) "Program loaded by djgpp, when gdb is used as an external debugger"; go32_ops.to_open = go32_open; go32_ops.to_close = go32_close; + go32_ops.to_attach = go32_attach; go32_ops.to_detach = go32_detach; go32_ops.to_resume = go32_resume; go32_ops.to_wait = go32_wait; @@ -864,9 +1297,9 @@ init_go32_ops (void) go32_ops.to_remove_breakpoint = memory_remove_breakpoint; go32_ops.to_terminal_init = go32_terminal_init; go32_ops.to_terminal_inferior = go32_terminal_inferior; - go32_ops.to_terminal_ours_for_output = ignore; + go32_ops.to_terminal_ours_for_output = go32_terminal_ours; go32_ops.to_terminal_ours = go32_terminal_ours; - go32_ops.to_terminal_info = ignore2; + go32_ops.to_terminal_info = go32_terminal_info; go32_ops.to_kill = go32_kill_inferior; go32_ops.to_create_inferior = go32_create_inferior; go32_ops.to_mourn_inferior = go32_mourn_inferior; @@ -879,6 +1312,13 @@ init_go32_ops (void) go32_ops.to_has_registers = 1; go32_ops.to_has_execution = 1; go32_ops.to_magic = OPS_MAGIC; + + /* Initialize child's cwd with the current one. */ + getcwd (child_cwd, sizeof (child_cwd)); + + /* Initialize child's command line storage. */ + if (redir_debug_init (&child_cmd) == -1) + fatal ("Cannot allocate redirection storage: not enough memory.\n"); } void @@ -887,3 +1327,21 @@ _initialize_go32_nat (void) init_go32_ops (); add_target (&go32_ops); } + +pid_t +tcgetpgrp (int fd) +{ + if (isatty (fd)) + return SOME_PID; + errno = ENOTTY; + return -1; +} + +int +tcsetpgrp (int fd, pid_t pgid) +{ + if (isatty (fd) && pgid == SOME_PID) + return 0; + errno = pgid == SOME_PID ? ENOTTY : ENOSYS; + return -1; +} diff --git a/gdb/hppa-tdep.c b/gdb/hppa-tdep.c index 25dbcfb..54fbf99 100644 --- a/gdb/hppa-tdep.c +++ b/gdb/hppa-tdep.c @@ -129,6 +129,7 @@ static void pa_strcat_registers PARAMS ((char *, int, int, GDB_FILE *)); static void pa_register_look_aside PARAMS ((char *, int, long *)); static void pa_print_fp_reg PARAMS ((int)); static void pa_strcat_fp_reg PARAMS ((int, GDB_FILE *, enum precision_type)); +static void record_text_segment_lowaddr PARAMS ((bfd *, asection *, void *)); typedef struct { @@ -310,6 +311,20 @@ compare_unwind_entries (arg1, arg2) return 0; } +static CORE_ADDR low_text_segment_address; + +static void +record_text_segment_lowaddr (abfd, section, ignored) + bfd *abfd ATTRIBUTE_UNUSED; + asection *section; + PTR ignored ATTRIBUTE_UNUSED; +{ + if ((section->flags & (SEC_ALLOC | SEC_LOAD | SEC_READONLY) + == (SEC_ALLOC | SEC_LOAD | SEC_READONLY)) + && section->vma < low_text_segment_address) + low_text_segment_address = section->vma; +} + static void internalize_unwinds (objfile, table, section, entries, size, text_offset) struct objfile *objfile; @@ -326,6 +341,22 @@ internalize_unwinds (objfile, table, section, entries, size, text_offset) unsigned i; char *buf = alloca (size); + 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) + { + bfd_map_over_sections (objfile->obfd, + record_text_segment_lowaddr, (PTR) NULL); + + /* ?!? Mask off some low bits. Should this instead subtract + out the lowest section's filepos or something like that? + This looks very hokey to me. */ + low_text_segment_address &= ~0xfff; + text_offset += low_text_segment_address; + } + bfd_get_section_contents (objfile->obfd, section, buf, 0, size); /* Now internalize the information being careful to handle host/target @@ -510,6 +541,7 @@ read_unwind_info (objfile) sizeof (obj_private_data_t)); obj_private->unwind_info = NULL; obj_private->so_info = NULL; + obj_private->dp = 0; objfile->obj_private = (PTR) obj_private; } @@ -764,7 +796,7 @@ rp_saved (pc) } if (u->Save_RP) - return -20; + return (TARGET_PTR_BIT == 64 ? -16 : -20); else if (u->stub_unwind.stub_type != 0) { switch (u->stub_unwind.stub_type) @@ -831,7 +863,8 @@ hppa_frame_saved_pc (frame) are saved in the exact same order as GDB numbers registers. How convienent. */ if (pc_in_interrupt_handler (pc)) - return read_memory_integer (frame->frame + PC_REGNUM * 4, 4) & ~0x3; + return read_memory_integer (frame->frame + PC_REGNUM * 4, + TARGET_PTR_BIT / 8) & ~0x3; #ifdef FRAME_SAVED_PC_IN_SIGTRAMP /* Deal with signal handler caller frames too. */ @@ -860,19 +893,23 @@ hppa_frame_saved_pc (frame) struct frame_saved_regs saved_regs; get_frame_saved_regs (frame->next, &saved_regs); - if (read_memory_integer (saved_regs.regs[FLAGS_REGNUM], 4) & 0x2) + if (read_memory_integer (saved_regs.regs[FLAGS_REGNUM], + TARGET_PTR_BIT / 8) & 0x2) { - pc = read_memory_integer (saved_regs.regs[31], 4) & ~0x3; + pc = read_memory_integer (saved_regs.regs[31], + TARGET_PTR_BIT / 8) & ~0x3; /* Syscalls are really two frames. The syscall stub itself with a return pointer in %rp and the kernel call with a return pointer in %r31. We return the %rp variant if %r31 is the same as frame->pc. */ if (pc == frame->pc) - pc = read_memory_integer (saved_regs.regs[RP_REGNUM], 4) & ~0x3; + pc = read_memory_integer (saved_regs.regs[RP_REGNUM], + TARGET_PTR_BIT / 8) & ~0x3; } else - pc = read_memory_integer (saved_regs.regs[RP_REGNUM], 4) & ~0x3; + pc = read_memory_integer (saved_regs.regs[RP_REGNUM], + TARGET_PTR_BIT / 8) & ~0x3; } else pc = read_register (ret_regnum) & ~0x3; @@ -896,19 +933,23 @@ hppa_frame_saved_pc (frame) struct frame_saved_regs saved_regs; get_frame_saved_regs (frame->next, &saved_regs); - if (read_memory_integer (saved_regs.regs[FLAGS_REGNUM], 4) & 0x2) + if (read_memory_integer (saved_regs.regs[FLAGS_REGNUM], + TARGET_PTR_BIT / 8) & 0x2) { - pc = read_memory_integer (saved_regs.regs[31], 4) & ~0x3; + pc = read_memory_integer (saved_regs.regs[31], + TARGET_PTR_BIT / 8) & ~0x3; /* Syscalls are really two frames. The syscall stub itself with a return pointer in %rp and the kernel call with a return pointer in %r31. We return the %rp variant if %r31 is the same as frame->pc. */ if (pc == frame->pc) - pc = read_memory_integer (saved_regs.regs[RP_REGNUM], 4) & ~0x3; + pc = read_memory_integer (saved_regs.regs[RP_REGNUM], + TARGET_PTR_BIT / 8) & ~0x3; } else - pc = read_memory_integer (saved_regs.regs[RP_REGNUM], 4) & ~0x3; + pc = read_memory_integer (saved_regs.regs[RP_REGNUM], + TARGET_PTR_BIT / 8) & ~0x3; } else if (rp_offset == 0) { @@ -918,7 +959,8 @@ hppa_frame_saved_pc (frame) else { old_pc = pc; - pc = read_memory_integer (frame->frame + rp_offset, 4) & ~0x3; + pc = read_memory_integer (frame->frame + rp_offset, + TARGET_PTR_BIT / 8) & ~0x3; } } @@ -1073,7 +1115,8 @@ frame_chain (frame) pull the old stack pointer from. Also see frame_saved_pc for code to dig a saved PC out of the save state structure. */ if (pc_in_interrupt_handler (frame->pc)) - frame_base = read_memory_integer (frame->frame + SP_REGNUM * 4, 4); + frame_base = read_memory_integer (frame->frame + SP_REGNUM * 4, + TARGET_PTR_BIT / 8); #ifdef FRAME_BASE_BEFORE_SIGTRAMP else if (frame->signal_handler_caller) { @@ -1107,7 +1150,7 @@ frame_chain (frame) The previous frame pointer is found at the top of the current frame. */ if (caller_framesize == -1 && my_framesize == -1) { - return read_memory_integer (frame_base, 4); + return read_memory_integer (frame_base, TARGET_PTR_BIT / 8); } /* Caller has a frame pointer, but callee does not. This is a little more difficult as GCC and HP C lay out locals and callee register save @@ -1164,7 +1207,7 @@ frame_chain (frame) && !tmp_frame->signal_handler_caller && !pc_in_interrupt_handler (tmp_frame->pc)) { - return read_memory_integer (tmp_frame->frame, 4); + return read_memory_integer (tmp_frame->frame, TARGET_PTR_BIT / 8); } /* %r3 was saved somewhere in the stack. Dig it out. */ else @@ -1202,7 +1245,8 @@ frame_chain (frame) /* Abominable hack. */ if (current_target.to_has_execution == 0 && ((saved_regs.regs[FLAGS_REGNUM] - && (read_memory_integer (saved_regs.regs[FLAGS_REGNUM], 4) + && (read_memory_integer (saved_regs.regs[FLAGS_REGNUM], + TARGET_PTR_BIT / 8) & 0x2)) || (saved_regs.regs[FLAGS_REGNUM] == 0 && read_register (FLAGS_REGNUM) & 0x2))) @@ -1210,7 +1254,8 @@ frame_chain (frame) u = find_unwind_entry (FRAME_SAVED_PC (frame)); if (!u) { - return read_memory_integer (saved_regs.regs[FP_REGNUM], 4); + return read_memory_integer (saved_regs.regs[FP_REGNUM], + TARGET_PTR_BIT / 8); } else { @@ -1218,7 +1263,8 @@ frame_chain (frame) } } - return read_memory_integer (saved_regs.regs[FP_REGNUM], 4); + return read_memory_integer (saved_regs.regs[FP_REGNUM], + TARGET_PTR_BIT / 8); } } else @@ -1234,7 +1280,8 @@ frame_chain (frame) /* Abominable hack. See above. */ if (current_target.to_has_execution == 0 && ((saved_regs.regs[FLAGS_REGNUM] - && (read_memory_integer (saved_regs.regs[FLAGS_REGNUM], 4) + && (read_memory_integer (saved_regs.regs[FLAGS_REGNUM], + TARGET_PTR_BIT / 8) & 0x2)) || (saved_regs.regs[FLAGS_REGNUM] == 0 && read_register (FLAGS_REGNUM) & 0x2))) @@ -1242,7 +1289,8 @@ frame_chain (frame) u = find_unwind_entry (FRAME_SAVED_PC (frame)); if (!u) { - return read_memory_integer (saved_regs.regs[FP_REGNUM], 4); + return read_memory_integer (saved_regs.regs[FP_REGNUM], + TARGET_PTR_BIT / 8); } else { @@ -1329,7 +1377,7 @@ push_dummy_frame (inf_status) { CORE_ADDR sp, pc, pcspace; register int regnum; - int int_buffer; + CORE_ADDR int_buffer; double freg_buffer; /* Oh, what a hack. If we're trying to perform an inferior call @@ -1364,20 +1412,28 @@ push_dummy_frame (inf_status) /* Space for "arguments"; the RP goes in here. */ sp = read_register (SP_REGNUM) + 48; int_buffer = read_register (RP_REGNUM) | 0x3; - write_memory (sp - 20, (char *) &int_buffer, 4); + + /* The 32bit and 64bit ABIs save the return pointer into different + stack slots. */ + if (REGISTER_SIZE == 8) + write_memory (sp - 16, (char *) &int_buffer, REGISTER_SIZE); + else + write_memory (sp - 20, (char *) &int_buffer, REGISTER_SIZE); int_buffer = TARGET_READ_FP (); - write_memory (sp, (char *) &int_buffer, 4); + write_memory (sp, (char *) &int_buffer, REGISTER_SIZE); write_register (FP_REGNUM, sp); - sp += 8; + sp += 2 * REGISTER_SIZE; for (regnum = 1; regnum < 32; regnum++) if (regnum != RP_REGNUM && regnum != FP_REGNUM) sp = push_word (sp, read_register (regnum)); - sp += 4; + /* This is not necessary for the 64bit ABI. In fact it is dangerous. */ + if (REGISTER_SIZE != 8) + sp += 4; for (regnum = FP0_REGNUM; regnum < NUM_REGS; regnum++) { @@ -1401,29 +1457,38 @@ find_dummy_frame_regs (frame, frame_saved_regs) CORE_ADDR fp = frame->frame; int i; - frame_saved_regs->regs[RP_REGNUM] = (fp - 20) & ~0x3; + /* The 32bit and 64bit ABIs save RP into different locations. */ + if (REGISTER_SIZE == 8) + frame_saved_regs->regs[RP_REGNUM] = (fp - 16) & ~0x3; + else + frame_saved_regs->regs[RP_REGNUM] = (fp - 20) & ~0x3; + frame_saved_regs->regs[FP_REGNUM] = fp; - frame_saved_regs->regs[1] = fp + 8; - for (fp += 12, i = 3; i < 32; i++) + frame_saved_regs->regs[1] = fp + (2 * REGISTER_SIZE); + + for (fp += 3 * REGISTER_SIZE, i = 3; i < 32; i++) { if (i != FP_REGNUM) { frame_saved_regs->regs[i] = fp; - fp += 4; + fp += REGISTER_SIZE; } } - fp += 4; + /* This is not necessary or desirable for the 64bit ABI. */ + if (REGISTER_SIZE != 8) + fp += 4; + for (i = FP0_REGNUM; i < NUM_REGS; i++, fp += 8) frame_saved_regs->regs[i] = fp; frame_saved_regs->regs[IPSW_REGNUM] = fp; - frame_saved_regs->regs[SAR_REGNUM] = fp + 4; - frame_saved_regs->regs[PCOQ_HEAD_REGNUM] = fp + 8; - frame_saved_regs->regs[PCSQ_HEAD_REGNUM] = fp + 12; - frame_saved_regs->regs[PCOQ_TAIL_REGNUM] = fp + 16; - frame_saved_regs->regs[PCSQ_TAIL_REGNUM] = fp + 20; + frame_saved_regs->regs[SAR_REGNUM] = fp + REGISTER_SIZE; + frame_saved_regs->regs[PCOQ_HEAD_REGNUM] = fp + 2 * REGISTER_SIZE; + frame_saved_regs->regs[PCSQ_HEAD_REGNUM] = fp + 3 * REGISTER_SIZE; + frame_saved_regs->regs[PCOQ_TAIL_REGNUM] = fp + 4 * REGISTER_SIZE; + frame_saved_regs->regs[PCSQ_TAIL_REGNUM] = fp + 5 * REGISTER_SIZE; } void @@ -1445,7 +1510,8 @@ hppa_pop_frame () for (regnum = 31; regnum > 0; regnum--) if (fsr.regs[regnum]) - write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); + write_register (regnum, read_memory_integer (fsr.regs[regnum], + REGISTER_SIZE)); for (regnum = NUM_REGS - 1; regnum >= FP0_REGNUM; regnum--) if (fsr.regs[regnum]) @@ -1456,16 +1522,19 @@ hppa_pop_frame () if (fsr.regs[IPSW_REGNUM]) write_register (IPSW_REGNUM, - read_memory_integer (fsr.regs[IPSW_REGNUM], 4)); + read_memory_integer (fsr.regs[IPSW_REGNUM], + REGISTER_SIZE)); if (fsr.regs[SAR_REGNUM]) write_register (SAR_REGNUM, - read_memory_integer (fsr.regs[SAR_REGNUM], 4)); + read_memory_integer (fsr.regs[SAR_REGNUM], + REGISTER_SIZE)); /* If the PC was explicitly saved, then just restore it. */ if (fsr.regs[PCOQ_TAIL_REGNUM]) { - npc = read_memory_integer (fsr.regs[PCOQ_TAIL_REGNUM], 4); + npc = read_memory_integer (fsr.regs[PCOQ_TAIL_REGNUM], + REGISTER_SIZE); write_register (PCOQ_TAIL_REGNUM, npc); } /* Else use the value in %rp to set the new PC. */ @@ -1475,7 +1544,7 @@ hppa_pop_frame () write_pc (npc); } - write_register (FP_REGNUM, read_memory_integer (fp, 4)); + write_register (FP_REGNUM, read_memory_integer (fp, REGISTER_SIZE)); if (fsr.regs[IPSW_REGNUM]) /* call dummy */ write_register (SP_REGNUM, fp - 48); @@ -1525,7 +1594,8 @@ restore_pc_queue (fsr) struct frame_saved_regs *fsr; { CORE_ADDR pc = read_pc (); - CORE_ADDR new_pc = read_memory_integer (fsr->regs[PCOQ_HEAD_REGNUM], 4); + CORE_ADDR new_pc = read_memory_integer (fsr->regs[PCOQ_HEAD_REGNUM], + TARGET_PTR_BIT / 8); struct target_waitstatus w; int insn_count; @@ -1543,7 +1613,8 @@ restore_pc_queue (fsr) So, load up the registers and single step until we are in the right place. */ - write_register (21, read_memory_integer (fsr->regs[PCSQ_HEAD_REGNUM], 4)); + write_register (21, read_memory_integer (fsr->regs[PCSQ_HEAD_REGNUM], + REGISTER_SIZE)); write_register (22, new_pc); for (insn_count = 0; insn_count < 3; insn_count++) @@ -1572,65 +1643,20 @@ restore_pc_queue (fsr) return 1; } -#if 0 -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)); - int cum = 0; - int i, alignment; - - for (i = 0; i < nargs; i++) - { - int x = 0; - /* cum is the sum of the lengths in bytes of - the arguments seen so far */ - cum += TYPE_LENGTH (VALUE_TYPE (args[i])); +/* This function pushes a stack frame with arguments as part of the + inferior function calling mechanism. - /* value must go at proper alignment. Assume alignment is a - power of two. */ - alignment = hppa_alignof (VALUE_TYPE (args[i])); + 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. - if (cum % alignment) - cum = (cum + alignment) & -alignment; - offset[i] = -cum; - - } - sp += max ((cum + 7) & -8, 16); - - for (i = 0; i < nargs; i++) - write_memory (sp + offset[i], VALUE_CONTENTS (args[i]), - TYPE_LENGTH (VALUE_TYPE (args[i]))); - - if (struct_return) - write_register (28, struct_addr); - return sp + 32; -} -#endif - -/* elz: I am rewriting this function, because the one above is a very - obscure piece of code. - This function pushes the arguments on the stack. The stack grows up - on the PA. - Each argument goes in one (or more) word (4 bytes) on the stack. - The first four words for the args must be allocated, even if they - are not used. - The 'topmost' arg is arg0, the 'bottom-most' is arg3. (if you think of - them as 1 word long). - Below these there can be any number of arguments, as needed by the function. - If an arg is bigger than one word, it will be written on the stack - occupying as many words as needed. Args that are bigger than 64bits - are not copied on the stack, a pointer is passed instead. - - On top of the arg0 word there are other 8 words (32bytes) which are used - for other purposes */ + 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. */ + CORE_ADDR hppa_push_arguments (nargs, args, sp, struct_return, struct_addr) int nargs; @@ -1641,57 +1667,66 @@ hppa_push_arguments (nargs, args, sp, struct_return, 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 */ + + /* array of arguments' lengths: real lengths in bytes, not aligned to + word size */ int *lengths = (int *) alloca (nargs * sizeof (int)); - int bytes_reserved; /* this is the number of bytes on the stack occupied by an - argument. This will be always a multiple of 4 */ + /* The value of SP as it was passed into this function after + aligning. */ + CORE_ADDR orig_sp = STACK_ALIGN (sp); - int cum_bytes_reserved = 0; /* this is the total number of bytes reserved by the args - seen so far. It is a multiple of 4 always */ - int cum_bytes_aligned = 0; /* same as above, but aligned on 8 bytes */ - int i; + /* 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; - /* When an arg does not occupy a whole word, for instance in bitfields: - if the arg is x bits (0<x<32), it must be written - starting from the (x-1)-th position down until the 0-th position. - It is enough to align it to the word. */ - /* if an arg occupies 8 bytes, it must be aligned on the 64-bits - high order word in odd arg word. */ - /* if an arg is larger than 64 bits, we need to pass a pointer to it, and - copy the actual value on the stack, so that the callee can play with it. - This is taken care of in valops.c in the call_function_by_hand function. - The argument that is received in this function here has already be converted - to a pointer to whatever is needed, so that it just can be pushed - as a word argument */ + /* 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])); - if (lengths[i] % 4) - bytes_reserved = (lengths[i] / 4) * 4 + 4; - else - bytes_reserved = lengths[i]; + /* 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 - if ((bytes_reserved == 8) && (offset[i] % 8)) /* if 64-bit arg is not 64 bit aligned */ + /* If the argument is a double word argument, then it needs to be + double word aligned. + + ?!? I do not think this code is correct when !ARGS_GROW_DOWNWAR. */ + if ((bytes_reserved == 2 * REGISTER_SIZE) + && (offset[i] % 2 * REGISTER_SIZE)) { int new_offset = 0; - /* bytes_reserved is already aligned to the word, so we put it at one word - more down the stack. This will leave one empty word on the - stack, and one unused register. This is OK, see the calling - convention doc */ - /* the offset may have to be moved to the corresponding position - one word down the stack, to maintain - alignment. */ - new_offset = (offset[i] / 8) * 8 + 8; - if ((new_offset - offset[i]) >= 4) + /* BYTES_RESERVED is already aligned to the word, so we put + the argument at one word more down the stack. + + This will leave one empty word on the stack, and one unused + register as mandated by the ABI. */ + new_offset = ((offset[i] + 2 * REGISTER_SIZE - 1) + & -(2 * REGISTER_SIZE)); + + if ((new_offset - offset[i]) >= 2 * REGISTER_SIZE) { - bytes_reserved += 4; - offset[i] += 4; + bytes_reserved += REGISTER_SIZE; + offset[i] += REGISTER_SIZE; } } @@ -1699,22 +1734,52 @@ hppa_push_arguments (nargs, args, sp, struct_return, struct_addr) } - /* now move up the sp to reserve at least 4 words required for the args, - or more than this if needed */ - /* wee also need to keep the sp aligned to 8 bytes */ + /* 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, 16); + 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. - /* now write each of the args at the proper offset down the stack */ + ?!? 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 a structure has to be returned, set up register 28 to hold its + address */ if (struct_return) write_register (28, struct_addr); - /* the stack will have other 8 words on top of the args */ +#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; } @@ -1889,6 +1954,103 @@ hppa_fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p) use a PLABEL instead of an import stub. */ int using_gcc_plt_call = 1; +#ifdef GDB_TARGET_IS_HPPA_20W + /* We currently use completely different code for the PA2.0W inferior + function call sequences. This needs to be cleaned up. */ + { + CORE_ADDR pcsqh, pcsqt, pcoqh, pcoqt, sr5; + struct target_waitstatus w; + int inst1, inst2; + char buf[4]; + int status; + struct objfile *objfile; + + /* We can not modify the PC space queues directly, so we start + up the inferior and execute a couple instructions to set the + space queues so that they point to the call dummy in the stack. */ + pcsqh = read_register (PCSQ_HEAD_REGNUM); + sr5 = read_register (SR5_REGNUM); + if (1) + { + pcoqh = read_register (PCOQ_HEAD_REGNUM); + pcoqt = read_register (PCOQ_TAIL_REGNUM); + if (target_read_memory (pcoqh, buf, 4) != 0) + error ("Couldn't modify space queue\n"); + inst1 = extract_unsigned_integer (buf, 4); + + if (target_read_memory (pcoqt, buf, 4) != 0) + error ("Couldn't modify space queue\n"); + inst2 = extract_unsigned_integer (buf, 4); + + /* BVE (r1) */ + *((int *) buf) = 0xe820d000; + if (target_write_memory (pcoqh, buf, 4) != 0) + error ("Couldn't modify space queue\n"); + + /* NOP */ + *((int *) buf) = 0x08000240; + if (target_write_memory (pcoqt, buf, 4) != 0) + { + *((int *) buf) = inst1; + target_write_memory (pcoqh, buf, 4); + error ("Couldn't modify space queue\n"); + } + + write_register (1, pc); + + /* Single step twice, the BVE instruction will set the space queue + such that it points to the PC value written immediately above + (ie the call dummy). */ + resume (1, 0); + target_wait (inferior_pid, &w); + resume (1, 0); + target_wait (inferior_pid, &w); + + /* Restore the two instructions at the old PC locations. */ + *((int *) buf) = inst1; + target_write_memory (pcoqh, buf, 4); + *((int *) buf) = inst2; + target_write_memory (pcoqt, buf, 4); + } + + /* The call dummy wants the ultimate destination address initially + in register %r5. */ + 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. */ + ALL_OBJFILES (objfile) + { + struct obj_section *s; + obj_private_data_t *obj_private; + + /* See if FUN is in any section within this shared library. */ + for (s = objfile->sections; s < objfile->sections_end; s++) + if (s->addr <= fun && fun < s->endaddr) + break; + + if (s >= objfile->sections_end) + continue; + + obj_private = (obj_private_data_t *) objfile->obj_private; + + /* The DP value may be different for each objfile. But within an + objfile each function uses the same dp value. Thus we do not need + to grope around the opd section looking for dp values. + + ?!? This is not strictly correct since we may be in a shared library + and want to call back into the main program. To make that case + work correctly we need to set obj_private->dp for the main program's + objfile, then remove this conditional. */ + if (obj_private->dp) + write_register (27, obj_private->dp); + break; + } + return pc; + } +#endif + +#ifndef GDB_TARGET_IS_HPPA_20W /* Prefer __gcc_plt_call over the HP supplied routine because __gcc_plt_call works for any number of arguments. */ trampoline = NULL; @@ -1909,11 +2071,13 @@ hppa_fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p) /* Get the GOT/DP value for the target function. It's at *(fun+4). Note the call dummy is *NOT* allowed to trash %r19 before calling the target function. */ - write_register (19, read_memory_integer ((fun & ~0x3) + 4, 4)); + write_register (19, read_memory_integer ((fun & ~0x3) + 4, + REGISTER_SIZE)); /* Now get the real address for the function we are calling, it's at *fun. */ - fun = (CORE_ADDR) read_memory_integer (fun & ~0x3, 4); + fun = (CORE_ADDR) read_memory_integer (fun & ~0x3, + TARGET_PTR_BIT / 8); } else { @@ -2044,7 +2208,6 @@ hppa_fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p) } } -#ifndef GDB_TARGET_IS_HPPA_20W /* Store upper 21 bits of function address into ldil. fun will either be the final target (most cases) or __d_plt_call when calling into a shared library and __gcc_plt_call is not available. */ @@ -2062,7 +2225,6 @@ hppa_fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p) deposit_14 (fun & MASK_11, extract_unsigned_integer (&dummy[FUNC_LDO_OFFSET], INSTRUCTION_SIZE))); -#endif /* GDB_TARGET_IS_HPPA_20W */ #ifdef SR4EXPORT_LDIL_OFFSET { @@ -2119,6 +2281,7 @@ hppa_fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p) #endif else return dyncall_addr; +#endif } @@ -2790,17 +2953,6 @@ in_solib_return_trampoline (pc, name) calling an argument relocation stub. It even handles some stubs used in dynamic executables. */ -#if 0 -CORE_ADDR -skip_trampoline_code (pc, name) - CORE_ADDR pc; - char *name; -{ - return find_solib_trampoline_target (pc); -} - -#endif - CORE_ADDR skip_trampoline_code (pc, name) CORE_ADDR pc; @@ -2855,12 +3007,12 @@ skip_trampoline_code (pc, name) the PLT entry for this function, not the address of the function itself. Bit 31 has meaning too, but only for MPE. */ if (pc & 0x2) - pc = (CORE_ADDR) read_memory_integer (pc & ~0x3, 4); + pc = (CORE_ADDR) read_memory_integer (pc & ~0x3, TARGET_PTR_BIT / 8); } if (pc == dyncall_external) { pc = (CORE_ADDR) read_register (22); - pc = (CORE_ADDR) read_memory_integer (pc & ~0x3, 4); + pc = (CORE_ADDR) read_memory_integer (pc & ~0x3, TARGET_PTR_BIT / 8); } else if (pc == sr4export) pc = (CORE_ADDR) (read_register (22)); @@ -3052,7 +3204,7 @@ skip_trampoline_code (pc, name) else if ((curr_inst & 0xffe0f000) == 0xe840d000) { return (read_memory_integer - (read_register (SP_REGNUM) - 24, 4)) & ~0x3; + (read_register (SP_REGNUM) - 24, TARGET_PTR_BIT / 8)) & ~0x3; } /* What about be,n 0(sr0,%rp)? It's just another way we return to @@ -3064,7 +3216,7 @@ skip_trampoline_code (pc, name) I guess we could check for the previous instruction being mtsp %r1,%sr0 if we want to do sanity checking. */ return (read_memory_integer - (read_register (SP_REGNUM) - 24, 4)) & ~0x3; + (read_register (SP_REGNUM) - 24, TARGET_PTR_BIT / 8)) & ~0x3; } /* Haven't found the branch yet, but we're still in the stub. @@ -3531,9 +3683,20 @@ hppa_frame_find_saved_regs (frame_info, frame_saved_regs) instead, let find_dummy_frame_regs fill in the correct offsets for the saved registers. */ if ((frame_info->pc >= frame_info->frame - && frame_info->pc <= (frame_info->frame + CALL_DUMMY_LENGTH - + 32 * 4 + (NUM_REGS - FP0_REGNUM) * 8 - + 6 * 4))) + && frame_info->pc <= (frame_info->frame + /* A call dummy is sized in words, but it is + actually a series of instructions. Account + for that scaling factor. */ + + ((REGISTER_SIZE / INSTRUCTION_SIZE) + * CALL_DUMMY_LENGTH) + /* Similarly we have to account for 64bit + wide register saves. */ + + (32 * REGISTER_SIZE) + /* We always consider FP regs 8 bytes long. */ + + (NUM_REGS - FP0_REGNUM) * 8 + /* Similarly we have to account for 64bit + wide register saves. */ + + (6 * REGISTER_SIZE)))) find_dummy_frame_regs (frame_info, frame_saved_regs); /* Interrupt handlers are special too. They lay out the register @@ -3545,7 +3708,8 @@ hppa_frame_find_saved_regs (frame_info, frame_saved_regs) /* SP is a little special. */ if (i == SP_REGNUM) frame_saved_regs->regs[SP_REGNUM] - = read_memory_integer (frame_info->frame + SP_REGNUM * 4, 4); + = read_memory_integer (frame_info->frame + SP_REGNUM * 4, + TARGET_PTR_BIT / 8); else frame_saved_regs->regs[i] = frame_info->frame + i * 4; } @@ -3882,6 +4046,7 @@ initialize_hp_cxx_exception_support () return 0; } +#ifndef GDB_TARGET_IS_HPPA_20W /* Check whether the executable is dynamically linked or archive bound */ /* With an archive-bound executable we can use the raw addresses we find for the callback function, etc. without modification. For an executable @@ -3925,6 +4090,7 @@ initialize_hp_cxx_exception_support () } else exception_catchpoints_are_fragile = 0; +#endif /* Now, look for the breakpointable routine in end.o */ /* This should also be available in the SOM symbol dict. if end.o linked in */ diff --git a/gdb/hppah-nat.c b/gdb/hppah-nat.c index 11e9d02..03157ed 100644 --- a/gdb/hppah-nat.c +++ b/gdb/hppah-nat.c @@ -139,6 +139,12 @@ store_inferior_registers (regno) } return; } + + /* Another crock. HPUX complains if you write a nonzero value to + the high part of IPSW. What will it take for HP to catch a + clue about building sensible interfaces? */ + if (regno == IPSW_REGNUM && len == 8) + *(int *)®isters[REGISTER_BYTE (regno)] = 0; #endif for (i = 0; i < len; i += sizeof (int)) @@ -152,7 +158,7 @@ store_inferior_registers (regno) the kernel doesn't let us at the registers. */ char *err = safe_strerror (errno); char *msg = alloca (strlen (err) + 128); - sprintf (msg, "reading `%s' register: %s", + sprintf (msg, "writing `%s' register: %s", REGISTER_NAME (regno), err); /* If we fail to write the PC, give a true error instead of just a warning. */ diff --git a/gdb/i386-stub.c b/gdb/i386-stub.c index 768f00c..b05170b 100644 --- a/gdb/i386-stub.c +++ b/gdb/i386-stub.c @@ -116,8 +116,6 @@ static char initialized; /* boolean flag. != 0 means we've been initialized */ int remote_debug; /* debug > 0 prints ill-formed commands in valid packets & checksum errors */ -void waitabit(); - static const char hexchars[]="0123456789abcdef"; /* Number of registers. */ @@ -893,12 +891,7 @@ int exception; exceptionHook = remcomHandler; } - /* In case GDB is started before us, ack any packets (presumably - "$?#xx") sitting there. */ - putDebugChar ('+'); - initialized = 1; - } /* This function will generate a breakpoint exception. It is used at the @@ -909,19 +902,5 @@ int exception; void breakpoint() { if (initialized) -#if 0 - handle_exception(3); -#else BREAKPOINT(); -#endif - waitabit(); -} - -int waitlimit = 1000000; - -void -waitabit() -{ - int i; - for (i = 0; i < waitlimit; i++) ; } diff --git a/gdb/infrun.c b/gdb/infrun.c index 0ddb8f2..a227c7a 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -1285,8 +1285,9 @@ init_execution_control_state (struct execution_control_state *ecs) } /* Call this function before setting step_resume_breakpoint, as a - sanity check. We should never be setting a new - step_resume_breakpoint when we have an old one active. */ + sanity check. There should never be more than one step-resume + breakpoint per thread, so we should never be setting a new + step_resume_breakpoint when one is already active. */ static void check_for_old_step_resume_breakpoint (void) { @@ -2289,7 +2290,12 @@ handle_inferior_event (struct execution_control_state *ecs) If we reach here and step_resume_breakpoint is already NULL, then apparently we have multiple active step-resume bp's. We'll just delete the breakpoint we - stopped at, and carry on. */ + stopped at, and carry on. + + Correction: what the code currently does is delete a + step-resume bp, but it makes no effort to ensure that + the one deleted is the one currently stopped at. MVS */ + if (step_resume_breakpoint == NULL) { step_resume_breakpoint = diff --git a/gdb/m32r-stub.c b/gdb/m32r-stub.c index 7055fe0..d4d8842 100644 --- a/gdb/m32r-stub.c +++ b/gdb/m32r-stub.c @@ -1576,10 +1576,6 @@ set_debug_traps() exceptionHandler (16, _catchException16); /* exceptionHandler (17, _catchException17); */ - /* In case GDB is started before us, ack any packets (presumably - "$?#xx") sitting there. */ - putDebugChar ('+'); - initialized = 1; } diff --git a/gdb/m68k-stub.c b/gdb/m68k-stub.c index c2f1d3f..a7187eb 100644 --- a/gdb/m68k-stub.c +++ b/gdb/m68k-stub.c @@ -576,8 +576,7 @@ char * buffer; } -/* send the packet in buffer. The host get's one chance to read it. - This routine does not wait for a positive acknowledge. */ +/* send the packet in buffer. */ void putpacket(buffer) @@ -603,7 +602,7 @@ char * buffer; putDebugChar(hexchars[checksum >> 4]); putDebugChar(hexchars[checksum % 16]); - } while (1 == 0); /* (getDebugChar() != '+'); */ + } while (getDebugChar() != '+'); } diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index 73429dc..786508e 100644 --- a/gdb/mips-tdep.c +++ b/gdb/mips-tdep.c @@ -1,6 +1,5 @@ /* Target-dependent code for the MIPS architecture, for GDB, the GNU Debugger. - Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998 - Free Software Foundation, Inc. + Copyright 1988-1999, Free Software Foundation, Inc. Contributed by Alessandro Forin(af@cs.cmu.edu) at CMU and by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin. @@ -2032,10 +2031,16 @@ mips_push_arguments (nargs, args, sp, struct_return, struct_addr) { /* This is a floating point value that fits entirely in a single register. */ + /* On 32 bit ABI's the float_argreg is further adjusted + above to ensure that it is even register aligned. */ CORE_ADDR regval = extract_address (val, len); write_register (float_argreg++, regval); if (!MIPS_EABI) { + /* CAGNEY: 32 bit MIPS ABI's always reserve two FP + registers for each argument. The below is (my + guess) to ensure that the corresponding integer + register has reserved the same space. */ write_register (argreg, regval); argreg += FP_REGISTER_DOUBLE ? 1 : 2; } diff --git a/gdb/pa64solib.c b/gdb/pa64solib.c new file mode 100644 index 0000000..aa11f24 --- /dev/null +++ b/gdb/pa64solib.c @@ -0,0 +1,1327 @@ +/* Handle HP ELF shared libraries 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. + + HP in their infinite stupidity choose not to use standard ELF dynamic + linker interfaces. They also choose not to make their ELF dymamic + linker interfaces compatible with the SOM dynamic linker. The + net result is we can not use either of the existing somsolib.c or + solib.c. What a crock. + + Even more disgusting. This file depends on functions provided only + in certain PA64 libraries. Thus this file is supposed to only be + used native. When will HP ever learn that they need to provide the + same functionality in all their libraries! */ + +#include <dlfcn.h> +#include <elf.h> +#include <elf_hp.h> + +#include "defs.h" + +#include "frame.h" +#include "bfd.h" +#include "libhppa.h" +#include "gdbcore.h" +#include "symtab.h" +#include "breakpoint.h" +#include "symfile.h" +#include "objfiles.h" +#include "inferior.h" +#include "gdb-stabs.h" +#include "gdb_stat.h" +#include "gdbcmd.h" +#include "assert.h" +#include "language.h" + +#include <fcntl.h> + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +/* Defined in exec.c; used to prevent dangling pointer bug. */ +extern struct target_ops exec_ops; + +static CORE_ADDR + bfd_lookup_symbol PARAMS ((bfd *, char *)); +/* This lives in hppa-tdep.c. */ +extern struct unwind_table_entry *find_unwind_entry PARAMS ((CORE_ADDR pc)); + +/* These ought to be defined in some public interface, but aren't. They + identify dynamic linker events. */ +#define DLD_CB_LOAD 1 +#define DLD_CB_UNLOAD 0 + +/* A structure to keep track of all the known shared objects. */ +struct so_list + { + bfd *abfd; + char *name; + struct so_list *next; + struct objfile *objfile; + CORE_ADDR pa64_solib_desc_addr; + struct load_module_desc pa64_solib_desc; + struct section_table *sections; + struct section_table *sections_end; + boolean loaded; + }; + +static struct so_list *so_list_head; + +/* This is the cumulative size in bytes of the symbol tables of all + shared objects on the so_list_head list. (When we say size, here + we mean of the information before it is brought into memory and + potentially expanded by GDB.) When adding a new shlib, this value + is compared against the threshold size, held by auto_solib_add + (in megabytes). If adding symbols for the new shlib would cause + the total size to exceed the threshold, then the new shlib's symbols + are not loaded. */ +static LONGEST pa64_solib_total_st_size; + +/* When the threshold is reached for any shlib, we refuse to add + symbols for subsequent shlibs, even if those shlibs' symbols would + be small enough to fit under the threshold. (Although this may + result in one, early large shlib preventing the loading of later, + smalller shlibs' symbols, it allows us to issue one informational + message. The alternative, to issue a message for each shlib whose + symbols aren't loaded, could be a big annoyance where the threshold + is exceeded due to a very large number of shlibs.) */ +static int pa64_solib_st_size_threshold_exceeded; + +/* When adding fields, be sure to clear them in _initialize_pa64_solib. */ +typedef struct + { + CORE_ADDR dld_flags_addr; + long long dld_flags; + sec_ptr dyninfo_sect; + boolean have_read_dld_descriptor; + boolean is_valid; + CORE_ADDR load_map; + CORE_ADDR load_map_addr; + struct load_module_desc dld_desc; + } +dld_cache_t; + +static dld_cache_t dld_cache; + +static void pa64_sharedlibrary_info_command PARAMS ((char *, int)); + +static void pa64_solib_sharedlibrary_command PARAMS ((char *, int)); + +static void * pa64_target_read_memory PARAMS ((void *, CORE_ADDR, size_t, int)); + +static boolean read_dld_descriptor PARAMS ((struct target_ops *)); + +static boolean read_dynamic_info PARAMS ((asection *, dld_cache_t *)); + +static void add_to_solist PARAMS ((boolean, char *, struct load_module_desc *, + CORE_ADDR, struct target_ops *)); + +/* When examining the shared library for debugging information we have to + look for HP debug symbols, stabs and dwarf2 debug symbols. */ +static char *pa64_debug_section_names[] = { + ".debug_header", ".debug_gntt", ".debug_lntt", ".debug_slt", ".debug_vt", + ".stabs", ".stabstr", ".debug_info", ".debug_abbrev", ".debug_aranges", + ".debug_macinfo", ".debug_line", ".debug_loc", ".debug_pubnames", + ".debug_str", NULL +}; + +/* Return a ballbark figure for the amount of memory GDB will need to + allocate to read in the debug symbols from FILENAME. */ +static LONGEST +pa64_solib_sizeof_symbol_table (filename) + char *filename; +{ + bfd *abfd; + int i; + int desc; + char *absolute_name; + LONGEST st_size = (LONGEST) 0; + asection *sect; + + /* We believe that filename was handed to us by the dynamic linker, and + is therefore always an absolute path. */ + desc = openp (getenv ("PATH"), 1, filename, O_RDONLY | O_BINARY, + 0, &absolute_name); + if (desc < 0) + { + perror_with_name (filename); + } + filename = absolute_name; + + abfd = bfd_fdopenr (filename, gnutarget, desc); + if (!abfd) + { + close (desc); + make_cleanup (free, filename); + error ("\"%s\": can't open to read symbols: %s.", filename, + bfd_errmsg (bfd_get_error ())); + } + + if (!bfd_check_format (abfd, bfd_object)) + { + bfd_close (abfd); + make_cleanup (free, filename); + error ("\"%s\": can't read symbols: %s.", filename, + bfd_errmsg (bfd_get_error ())); + } + + /* Sum the sizes of the various sections that compose debug info. */ + for (i = 0; pa64_debug_section_names[i] != NULL; i++) + { + asection *sect; + + sect = bfd_get_section_by_name (abfd, pa64_debug_section_names[i]); + if (sect) + st_size += (LONGEST)bfd_section_size (abfd, sect); + } + + bfd_close (abfd); + free (filename); + + /* Unfortunately, just summing the sizes of various debug info + sections isn't a very accurate measurement of how much heap + space the debugger will need to hold them. It also doesn't + account for space needed by linker (aka "minimal") symbols. + + Anecdotal evidence suggests that just summing the sizes of + debug-info-related sections understates the heap space needed + to represent it internally by about an order of magnitude. + + Since it's not exactly brain surgery we're doing here, rather + than attempt to more accurately measure the size of a shlib's + symbol table in GDB's heap, we'll just apply a 10x fudge- + factor to the debug info sections' size-sum. No, this doesn't + account for minimal symbols in non-debuggable shlibs. But it + all roughly washes out in the end. */ + return st_size * (LONGEST) 10; +} + +/* Add a shared library to the objfile list and load its symbols into + GDB's symbol table. */ +static void +pa64_solib_add_solib_objfile (so, name, from_tty, text_addr) + struct so_list *so; + char *name; + int from_tty; + CORE_ADDR text_addr; +{ + bfd *tmp_bfd; + asection *sec; + obj_private_data_t *obj_private; + + /* We need the BFD so that we can look at its sections. We open up the + file temporarily, then close it when we are done. */ + tmp_bfd = bfd_openr (name, gnutarget); + if (tmp_bfd == NULL) + { + perror_with_name (name); + return; + } + + if (!bfd_check_format (tmp_bfd, bfd_object)) + { + bfd_close (tmp_bfd); + error ("\"%s\" is not an object file: %s", name, + bfd_errmsg (bfd_get_error ())); + } + + + /* Undo some braindamage from symfile.c. + + First, symfile.c will subtract the VMA of the first .text section + in the shared library that it finds. Undo that. */ + sec = bfd_get_section_by_name (tmp_bfd, ".text"); + text_addr += bfd_section_vma (tmp_bfd, sec); + + /* Now find the true lowest section in the shared library. */ + sec = NULL; + bfd_map_over_sections (tmp_bfd, find_lowest_section, (PTR) &sec); + + if (sec) + { + /* Subtract out the VMA of the lowest section. */ + text_addr -= bfd_section_vma (tmp_bfd, sec); + + /* ??? Add back in the filepos of that lowest section. */ + text_addr += sec->filepos; + } + + /* We are done with the temporary bfd. Get rid of it and make sure + nobody else can us it. */ + bfd_close (tmp_bfd); + tmp_bfd = NULL; + + /* Now let the generic code load up symbols for this library. */ + so->objfile = symbol_file_add (name, from_tty, text_addr, 0, 0, 0, 0, 1); + so->abfd = so->objfile->obfd; + + /* Mark this as a shared library and save private data. */ + so->objfile->flags |= OBJF_SHARED; + + if (so->objfile->obj_private == NULL) + { + obj_private = (obj_private_data_t *) + obstack_alloc (&so->objfile->psymbol_obstack, + sizeof (obj_private_data_t)); + obj_private->unwind_info = NULL; + obj_private->so_info = NULL; + so->objfile->obj_private = (PTR) obj_private; + } + + obj_private = (obj_private_data_t *) so->objfile->obj_private; + obj_private->so_info = so; + obj_private->dp = so->pa64_solib_desc.linkage_ptr; +} + +/* Load debugging information for a shared library. TARGET may be + NULL if we are not attaching to a process or reading a core file. */ + +static void +pa64_solib_load_symbols (so, name, from_tty, text_addr, target) + struct so_list *so; + char *name; + int from_tty; + CORE_ADDR text_addr; + struct target_ops *target; +{ + struct section_table *p; + asection *sec; + int status; + char buf[4]; + CORE_ADDR presumed_data_start; + + if (text_addr == 0) + text_addr = so->pa64_solib_desc.text_base; + + pa64_solib_add_solib_objfile (so, name, from_tty, text_addr); + + /* Now we need to build a section table for this library since + we might be debugging a core file from a dynamically linked + executable in which the libraries were not privately mapped. */ + if (build_section_table (so->abfd, + &so->sections, + &so->sections_end)) + { + error ("Unable to build section table for shared library\n."); + return; + } + + ANOFFSET (so->objfile->section_offsets, SECT_OFF_TEXT) + = so->pa64_solib_desc.text_base; + ANOFFSET (so->objfile->section_offsets, SECT_OFF_DATA) + = so->pa64_solib_desc.data_base; + + /* Relocate all the sections based on where they got loaded. */ + for (p = so->sections; p < so->sections_end; p++) + { + if (p->the_bfd_section->flags & SEC_CODE) + { + p->addr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_TEXT); + p->endaddr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_TEXT); + } + else if (p->the_bfd_section->flags & SEC_DATA) + { + p->addr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_DATA); + p->endaddr += ANOFFSET (so->objfile->section_offsets, SECT_OFF_DATA); + } + } + + /* Now see if we need to map in the text and data for this shared + library (for example debugging a core file which does not use + private shared libraries.). + + Carefully peek at the first text address in the library. If the + read succeeds, then the libraries were privately mapped and were + included in the core dump file. + + If the peek failed, then the libraries were not privately mapped + and are not in the core file, we'll have to read them in ourselves. */ + status = target_read_memory (text_addr, buf, 4); + if (status != 0) + { + int old, new; + int update_coreops; + int update_execops; + + /* We must update the to_sections field in the core_ops structure + here, otherwise we dereference a potential dangling pointer + for each call to target_read/write_memory within this routine. */ + update_coreops = core_ops.to_sections == target->to_sections; + + /* Ditto exec_ops (this was a bug). */ + update_execops = exec_ops.to_sections == target->to_sections; + + new = so->sections_end - so->sections; + /* Add sections from the shared library to the core target. */ + if (target->to_sections) + { + old = target->to_sections_end - target->to_sections; + target->to_sections = (struct section_table *) + xrealloc ((char *) target->to_sections, + ((sizeof (struct section_table)) * (old + new))); + } + else + { + old = 0; + target->to_sections = (struct section_table *) + xmalloc ((sizeof (struct section_table)) * new); + } + target->to_sections_end = (target->to_sections + old + new); + + /* Update the to_sections field in the core_ops structure + if needed, ditto exec_ops. */ + if (update_coreops) + { + core_ops.to_sections = target->to_sections; + core_ops.to_sections_end = target->to_sections_end; + } + + if (update_execops) + { + exec_ops.to_sections = target->to_sections; + exec_ops.to_sections_end = target->to_sections_end; + } + + /* Copy over the old data before it gets clobbered. */ + memcpy ((char *) (target->to_sections + old), + so->sections, + ((sizeof (struct section_table)) * new)); + } +} + + +/* Add symbols from shared libraries into the symtab list, unless the + size threshold (specified by auto_solib_add, in megabytes) would + be exceeded. */ + +void +pa64_solib_add (arg_string, from_tty, target) + char *arg_string; + int from_tty; + struct target_ops *target; +{ + struct minimal_symbol *msymbol; + CORE_ADDR addr; + asection *shlib_info; + int status; + unsigned int dld_flags; + char buf[4], *re_err; + int threshold_warning_given = 0; + int dll_index; + struct load_module_desc dll_desc; + char *dll_path; + + /* First validate our arguments. */ + if ((re_err = re_comp (arg_string ? arg_string : ".")) != NULL) + { + error ("Invalid regexp: %s", re_err); + } + + /* If we're debugging a core file, or have attached to a running + process, then pa64_solib_create_inferior_hook will not have been + called. + + We need to first determine if we're dealing with a dynamically + linked executable. If not, then return without an error or warning. + + We also need to examine __dld_flags to determine if the shared library + list is valid and to determine if the libraries have been privately + mapped. */ + if (symfile_objfile == NULL) + return; + + /* First see if the objfile was dynamically linked. */ + shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, ".dynamic"); + if (!shlib_info) + return; + + /* It's got a .dynamic section, make sure it's not empty. */ + if (bfd_section_size (symfile_objfile->obfd, shlib_info) == 0) + return; + + /* Read in the load map pointer if we have not done so already. */ + if (! dld_cache.have_read_dld_descriptor) + if (! read_dld_descriptor (target)) + return; + + /* If the libraries were not mapped private, warn the user. */ + if ((dld_cache.dld_flags & DT_HP_DEBUG_PRIVATE) == 0) + warning ("The shared libraries were not privately mapped; setting a\nbreakpoint in a shared library will not work until you rerun the program.\n"); + + /* For each shaerd library, add it to the shared library list. */ + for (dll_index = 1; ; dll_index++) + { + /* Read in the load module descriptor. */ + if (dlgetmodinfo (dll_index, &dll_desc, sizeof (dll_desc), + pa64_target_read_memory, 0, dld_cache.load_map) + == 0) + return; + + /* Get the name of the shared library. */ + dll_path = (char *)dlgetname (&dll_desc, sizeof (dll_desc), + pa64_target_read_memory, + 0, dld_cache.load_map); + + if (!dll_path) + error ("pa64_solib_add, unable to read shared library path."); + + add_to_solist (from_tty, dll_path, &dll_desc, 0, target); + } +} + + +/* This hook gets called just before the first instruction in the + inferior process is executed. + + This is our opportunity to set magic flags in the inferior so + that GDB can be notified when a shared library is mapped in and + to tell the dynamic linker that a private copy of the library is + needed (so GDB can set breakpoints in the library). + + We need to set two flag bits in this routine. + + DT_HP_DEBUG_PRIVATE to indicate that shared libraries should be + mapped private. + + DT_HP_DEBUG_CALLBACK to indicate that we want the dynamic linker to + call the breakpoint routine for significant events. */ + +void +pa64_solib_create_inferior_hook () +{ + struct minimal_symbol *msymbol; + unsigned int dld_flags, status; + asection *shlib_info, *interp_sect; + char buf[4]; + struct objfile *objfile; + CORE_ADDR anaddr; + + /* First, remove all the solib event breakpoints. Their addresses + may have changed since the last time we ran the program. */ + remove_solib_event_breakpoints (); + + if (symfile_objfile == NULL) + return; + + /* First see if the objfile was dynamically linked. */ + shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, ".dynamic"); + if (!shlib_info) + return; + + /* It's got a .dynamic section, make sure it's not empty. */ + 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)); + if (status != 0) + error ("Unable to modify dynamic linker flags."); + + /* Now we have to create a shared library breakpoint in the dynamic + linker. This can be somewhat tricky since the symbol is inside + the dynamic linker (for which we do not have symbols or a base + load address! Luckily I wrote this code for solib.c years ago. */ + interp_sect = bfd_get_section_by_name (exec_bfd, ".interp"); + if (interp_sect) + { + unsigned int interp_sect_size; + char *buf; + CORE_ADDR load_addr; + bfd *tmp_bfd; + CORE_ADDR sym_addr = 0; + + /* Read the contents of the .interp section into a local buffer; + the contents specify the dynamic linker this program uses. */ + interp_sect_size = bfd_section_size (exec_bfd, interp_sect); + buf = alloca (interp_sect_size); + bfd_get_section_contents (exec_bfd, interp_sect, + buf, 0, interp_sect_size); + + /* Now we need to figure out where the dynamic linker was + loaded so that we can load its symbols and place a breakpoint + in the dynamic linker itself. + + This address is stored on the stack. However, I've been unable + to find any magic formula to find it for Solaris (appears to + be trivial on GNU/Linux). Therefore, we have to try an alternate + mechanism to find the dynamic linker's base address. */ + tmp_bfd = bfd_openr (buf, gnutarget); + if (tmp_bfd == NULL) + goto get_out; + + /* Make sure the dynamic linker's really a useful object. */ + if (!bfd_check_format (tmp_bfd, bfd_object)) + { + warning ("Unable to grok dynamic linker %s as an object file", buf); + bfd_close (tmp_bfd); + goto get_out; + } + + /* We find the dynamic linker's base address by examining the + current pc (which point at the entry point for the dynamic + linker) and subtracting the offset of the entry point. + + Also note the breakpoint is the second instruction in the + routine. */ + load_addr = read_pc () - tmp_bfd->start_address; + sym_addr = bfd_lookup_symbol (tmp_bfd, "__dld_break"); + sym_addr = load_addr + sym_addr + 4; + + /* Create the shared library breakpoint. */ + create_solib_event_breakpoint (sym_addr); + + /* We're done with the temporary bfd. */ + bfd_close (tmp_bfd); + } + +get_out: + /* Wipe out all knowledge of old shared libraries since their + mapping can change from one exec to another! */ + while (so_list_head) + { + struct so_list *temp; + + temp = so_list_head; + free (so_list_head); + so_list_head = temp->next; + } + clear_symtab_users (); +} + +/* This operation removes the "hook" between GDB and the dynamic linker, + which causes the dld to notify GDB of shared library events. + + After this operation completes, the dld will no longer notify GDB of + shared library events. To resume notifications, GDB must call + pa64_solib_create_inferior_hook. + + This operation does not remove any knowledge of shared libraries which + GDB may already have been notified of. */ + +void +pa64_solib_remove_inferior_hook (pid) + int pid; +{ + /* Turn off the DT_HP_DEBUG_CALLBACK bit in the dynamic linker flags. */ + dld_cache.dld_flags &= ~DT_HP_DEBUG_CALLBACK; + target_write_memory (dld_cache.dld_flags_addr, + (char *)&dld_cache.dld_flags, + sizeof (dld_cache.dld_flags)); +} + +/* This function creates a breakpoint on the dynamic linker hook, which + is called when e.g., a shl_load or shl_unload call is made. This + breakpoint will only trigger when a shl_load call is made. + + If filename is NULL, then loads of any dll will be caught. Else, + only loads of the file whose pathname is the string contained by + filename will be caught. + + Undefined behaviour is guaranteed if this function is called before + pa64_solib_create_inferior_hook. */ + +void +pa64_solib_create_catch_load_hook (pid, tempflag, filename, cond_string) + int pid; + int tempflag; + char *filename; + char *cond_string; +{ + create_solib_load_event_breakpoint ("", tempflag, filename, cond_string); +} + +/* This function creates a breakpoint on the dynamic linker hook, which + is called when e.g., a shl_load or shl_unload call is made. This + breakpoint will only trigger when a shl_unload call is made. + + If filename is NULL, then unloads of any dll will be caught. Else, + only unloads of the file whose pathname is the string contained by + filename will be caught. + + Undefined behaviour is guaranteed if this function is called before + pa64_solib_create_inferior_hook. */ + +void +pa64_solib_create_catch_unload_hook (pid, tempflag, filename, cond_string) + int pid; + int tempflag; + char *filename; + char *cond_string; +{ + create_solib_unload_event_breakpoint ("", tempflag, filename, cond_string); +} + +/* Return nonzero if the dynamic linker has reproted that a library + has been loaded. */ + +int +pa64_solib_have_load_event (pid) + int pid; +{ + CORE_ADDR event_kind; + + event_kind = read_register (ARG0_REGNUM); + return (event_kind == DLD_CB_LOAD); +} + +/* Return nonzero if the dynamic linker has reproted that a library + has been unloaded. */ +int +pa64_solib_have_unload_event (pid) + int pid; +{ + CORE_ADDR event_kind; + + event_kind = read_register (ARG0_REGNUM); + return (event_kind == DLD_CB_UNLOAD); +} + +/* Return a pointer to a string indicating the pathname of the most + recently loaded library. + + The caller is reposible for copying the string before the inferior is + restarted. */ + +char * +pa64_solib_loaded_library_pathname (pid) + int pid; +{ + static char dll_path[MAXPATHLEN]; + CORE_ADDR dll_path_addr = read_register (ARG3_REGNUM); + read_memory_string (dll_path_addr, dll_path, MAXPATHLEN); + return dll_path; +} + +/* Return a pointer to a string indicating the pathname of the most + recently unloaded library. + + The caller is reposible for copying the string before the inferior is + restarted. */ + +char * +pa64_solib_unloaded_library_pathname (pid) + int pid; +{ + static char dll_path[MAXPATHLEN]; + CORE_ADDR dll_path_addr = read_register (ARG3_REGNUM); + read_memory_string (dll_path_addr, dll_path, MAXPATHLEN); + return dll_path; +} + +/* Return nonzero if PC is an address inside the dynamic linker. */ + +int +pa64_solib_in_dynamic_linker (pid, pc) + int pid; + CORE_ADDR pc; +{ + asection *shlib_info; + + if (symfile_objfile == NULL) + return 0; + + if (!dld_cache.have_read_dld_descriptor) + if (!read_dld_descriptor (¤t_target)) + return 0; + + return (pc >= dld_cache.dld_desc.text_base + && pc < dld_cache.dld_desc.text_base + dld_cache.dld_desc.text_size); +} + + +/* Return the GOT value for the shared library in which ADDR belongs. If + ADDR isn't in any known shared library, return zero. */ + +CORE_ADDR +pa64_solib_get_got_by_pc (addr) + CORE_ADDR addr; +{ + struct so_list *so_list = so_list_head; + CORE_ADDR got_value = 0; + + while (so_list) + { + if (so_list->pa64_solib_desc.text_base <= addr + && ((so_list->pa64_solib_desc.text_base + + so_list->pa64_solib_desc.text_size) + > addr)) + { + got_value = so_list->pa64_solib_desc.linkage_ptr; + break; + } + so_list = so_list->next; + } + return got_value; +} + +/* Return the address of the handle of the shared library in which ADDR + belongs. If ADDR isn't in any known shared library, return zero. + + This function is used in hppa_fix_call_dummy in hppa-tdep.c. */ + +CORE_ADDR +pa64_solib_get_solib_by_pc (addr) + CORE_ADDR addr; +{ + struct so_list *so_list = so_list_head; + CORE_ADDR retval = 0; + + while (so_list) + { + if (so_list->pa64_solib_desc.text_base <= addr + && ((so_list->pa64_solib_desc.text_base + + so_list->pa64_solib_desc.text_size) + > addr)) + { + retval = so_list->pa64_solib_desc_addr; + break; + } + so_list = so_list->next; + } + return retval; +} + +/* Dump information about all the currently loaded shared libraries. */ + +static void +pa64_sharedlibrary_info_command (ignore, from_tty) + char *ignore; + int from_tty; +{ + struct so_list *so_list = so_list_head; + + if (exec_bfd == NULL) + { + printf_unfiltered ("no exec file.\n"); + return; + } + + if (so_list == NULL) + { + printf_unfiltered ("No shared libraries loaded at this time.\n"); + return; + } + + printf_unfiltered ("Shared Object Libraries\n"); + printf_unfiltered (" %-19s%-19s%-19s%-19s\n", + " tstart", " tend", + " dstart", " dend"); + while (so_list) + { + unsigned int flags; + + printf_unfiltered ("%s", so_list->name); + if (so_list->objfile == NULL) + printf_unfiltered (" (symbols not loaded)"); + if (so_list->loaded == 0) + printf_unfiltered (" (shared library unloaded)"); + printf_unfiltered (" %-18s", + local_hex_string_custom (so_list->pa64_solib_desc.linkage_ptr, + "016l")); + printf_unfiltered ("\n"); + printf_unfiltered ("%-18s", + 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, + + 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, + + so_list->pa64_solib_desc.data_size), + "016l")); + so_list = so_list->next; + } +} + +/* Load up one or more shared libraries as directed by the user. */ + +static void +pa64_solib_sharedlibrary_command (args, from_tty) + char *args; + int from_tty; +{ + dont_repeat (); + pa64_solib_add (args, from_tty, (struct target_ops *) 0); +} + +/* Return the name of the shared library containing ADDR or NULL if ADDR + is not contained in any known shared library. */ + +char * +pa64_solib_address (addr) + CORE_ADDR addr; +{ + struct so_list *so = so_list_head; + + while (so) + { + /* Is this address within this shlib's text range? If so, + return the shlib's name. */ + if (addr >= so->pa64_solib_desc.text_base + && addr < (so->pa64_solib_desc.text_base + | so->pa64_solib_desc.text_size)) + return so->name; + + /* Nope, keep looking... */ + so = so->next; + } + + /* No, we couldn't prove that the address is within a shlib. */ + return NULL; +} + +/* We are killing the inferior and restarting the program. */ + +void +pa64_solib_restart () +{ + struct so_list *sl = so_list_head; + + /* Before the shlib info vanishes, use it to disable any breakpoints + that may still be active in those shlibs. */ + disable_breakpoints_in_shlibs (0); + + /* Discard all the shlib descriptors. */ + while (sl) + { + struct so_list *next_sl = sl->next; + free (sl); + sl = next_sl; + } + so_list_head = NULL; + + pa64_solib_total_st_size = (LONGEST) 0; + pa64_solib_st_size_threshold_exceeded = 0; + + dld_cache.is_valid = 0; + dld_cache.have_read_dld_descriptor = 0; + dld_cache.dld_flags_addr = 0; + dld_cache.load_map = 0; + dld_cache.load_map_addr = 0; + dld_cache.dld_desc.data_base = 0; + dld_cache.dld_flags = 0; + dld_cache.dyninfo_sect = 0; +} + +void +_initialize_pa64_solib () +{ + add_com ("sharedlibrary", class_files, pa64_solib_sharedlibrary_command, + "Load shared object library symbols for files matching REGEXP."); + add_info ("sharedlibrary", pa64_sharedlibrary_info_command, + "Status of loaded shared object libraries."); + add_show_from_set + (add_set_cmd ("auto-solib-add", class_support, var_zinteger, + (char *) &auto_solib_add, + "Set autoloading size threshold (in megabytes) of shared library symbols.\n\ +If nonzero, symbols from all shared object libraries will be loaded\n\ +automatically when the inferior begins execution or when the dynamic linker\n\ +informs gdb that a new library has been loaded, until the symbol table\n\ +of the program and libraries exceeds this threshold.\n\ +Otherwise, symbols must be loaded manually, using `sharedlibrary'.", + &setlist), + &showlist); + + /* ??rehrauer: On HP-UX, the kernel parameter MAXDSIZ limits how much + data space a process can use. We ought to be reading MAXDSIZ and + setting auto_solib_add to some large fraction of that value. If + not that, we maybe ought to be setting it smaller than the default + for MAXDSIZ (that being 64Mb, I believe). However, [1] this threshold + is only crudely approximated rather than actually measured, and [2] + 50 Mbytes is too small for debugging gdb itself. Thus, the arbitrary + 100 figure. + */ + auto_solib_add = 100; /* Megabytes */ + + pa64_solib_restart (); +} + +/* Get some HPUX-specific data from a shared lib. */ +CORE_ADDR +so_lib_thread_start_addr (so) + struct so_list *so; +{ + return so->pa64_solib_desc.tls_start_addr; +} + +/* Read the dynamic linker's internal shared library descriptor. + + This must happen after dld starts running, so we can't do it in + read_dynamic_info. Record the fact that we have loaded the + descriptor. If the library is archive bound, then return zero, else + return nonzero. */ + +static boolean +read_dld_descriptor (target) + struct target_ops *target; +{ + char *dll_path; + asection *dyninfo_sect; + + /* If necessary call read_dynamic_info to extract the contents of the + .dynamic section from the shared library. */ + if (!dld_cache.is_valid) + { + if (symfile_objfile == NULL) + error ("No object file symbols."); + + dyninfo_sect = bfd_get_section_by_name (symfile_objfile->obfd, + ".dynamic"); + if (!dyninfo_sect) + { + return 0; + } + + if (!read_dynamic_info (dyninfo_sect, &dld_cache)) + error ("Unable to read in .dynamic section information."); + } + + /* Read the load map pointer. */ + if (target_read_memory (dld_cache.load_map_addr, + (char*) &dld_cache.load_map, + sizeof(dld_cache.load_map)) + != 0) + { + error ("Error while reading in load map pointer."); + } + + /* Read in the dld load module descriptor */ + if (dlgetmodinfo (-1, + &dld_cache.dld_desc, + sizeof(dld_cache.dld_desc), + pa64_target_read_memory, + 0, + dld_cache.load_map) + == 0) + { + error ("Error trying to get information about dynamic linker."); + } + + /* Indicate that we have loaded the dld descriptor. */ + dld_cache.have_read_dld_descriptor = 1; + + /* Add dld.sl to the list of known shared libraries so that we can + do unwind, etc. + + ?!? This may not be correct. Consider of dld.sl contains symbols + which are also referenced/defined by the user program or some user + shared library. We need to make absolutely sure that we do not + pollute the namespace from GDB's point of view. */ + dll_path = dlgetname (&dld_cache.dld_desc, + sizeof(dld_cache.dld_desc), + pa64_target_read_memory, + 0, + dld_cache.load_map); + add_to_solist(0, dll_path, &dld_cache.dld_desc, 0, target); + + return 1; +} + +/* Read the .dynamic section and extract the information of interest, + which is stored in dld_cache. The routine elf_locate_base in solib.c + was used as a model for this. */ + +static boolean +read_dynamic_info (dyninfo_sect, dld_cache_p) + asection *dyninfo_sect; + dld_cache_t *dld_cache_p; +{ + char *buf; + char *bufend; + CORE_ADDR dyninfo_addr; + int dyninfo_sect_size; + CORE_ADDR entry_addr; + + /* Read in .dynamic section, silently ignore errors. */ + dyninfo_addr = bfd_section_vma (symfile_objfile->obfd, dyninfo_sect); + dyninfo_sect_size = bfd_section_size (exec_bfd, dyninfo_sect); + buf = alloca (dyninfo_sect_size); + if (target_read_memory (dyninfo_addr, buf, dyninfo_sect_size)) + return 0; + + /* Scan the .dynamic section and record the items of interest. + In particular, DT_HP_DLD_FLAGS */ + for (bufend = buf + dyninfo_sect_size, entry_addr = dyninfo_addr; + buf < bufend; + buf += sizeof (Elf64_Dyn), entry_addr += sizeof (Elf64_Dyn)) + { + Elf64_Dyn *x_dynp = (Elf64_Dyn*)buf; + Elf64_Sxword dyn_tag; + CORE_ADDR dyn_ptr; + char pbuf[TARGET_PTR_BIT / HOST_CHAR_BIT]; + + dyn_tag = bfd_h_get_64 (symfile_objfile->obfd, + (bfd_byte*) &x_dynp->d_tag); + + /* We can't use a switch here because dyn_tag is 64 bits and HP's + lame comiler does not handle 64bit items in switch statements. */ + if (dyn_tag == DT_NULL) + break; + else if (dyn_tag == DT_HP_DLD_FLAGS) + { + /* Set dld_flags_addr and dld_flags in *dld_cache_p */ + dld_cache_p->dld_flags_addr = entry_addr + offsetof(Elf64_Dyn, d_un); + if (target_read_memory (dld_cache_p->dld_flags_addr, + (char*) &dld_cache_p->dld_flags, + sizeof(dld_cache_p->dld_flags)) + != 0) + { + error ("Error while reading in .dynamic section of the program."); + } + } + else if (dyn_tag == DT_HP_LOAD_MAP) + { + /* Dld will place the address of the load map at load_map_addr + after it starts running. */ + if (target_read_memory (entry_addr + offsetof(Elf64_Dyn, + d_un.d_ptr), + (char*) &dld_cache_p->load_map_addr, + sizeof(dld_cache_p->load_map_addr)) + != 0) + { + error ("Error while reading in .dynamic section of the program."); + } + } + else + { + /* tag is not of interest */ + } + } + + /* Record other information and set is_valid to 1. */ + dld_cache_p->dyninfo_sect = dyninfo_sect; + + /* Verify that we read in required info. These fields are re-set to zero + in pa64_solib_restart. */ + + if (dld_cache_p->dld_flags_addr != 0 && dld_cache_p->load_map_addr != 0) + dld_cache_p->is_valid = 1; + else + return 0; + + return 1; +} + +/* Wrapper for target_read_memory to make dlgetmodinfo happy. */ + +static void * +pa64_target_read_memory (buffer, ptr, bufsiz, ident) + void *buffer; + CORE_ADDR ptr; + size_t bufsiz; + int ident; +{ + if (target_read_memory (ptr, buffer, bufsiz) != 0) + return 0; + return buffer; +} + +/* Called from handle_dynlink_load_event and pa64_solib_add to add + a shared library to so_list_head list and possibly to read in the + debug information for the library. + + If load_module_desc_p is NULL, then the load module descriptor must + be read from the inferior process at the address load_module_desc_addr. */ + +static void +add_to_solist (from_tty, dll_path, load_module_desc_p, + load_module_desc_addr, target) + boolean from_tty; + char *dll_path; + struct load_module_desc *load_module_desc_p; + CORE_ADDR load_module_desc_addr; + struct target_ops *target; +{ + struct so_list *new_so, *so_list_tail; + int pa64_solib_st_size_threshhold_exceeded; + LONGEST st_size; + + if (symfile_objfile == NULL) + return; + + so_list_tail = so_list_head; + /* Find the end of the list of shared objects. */ + while (so_list_tail && so_list_tail->next) + { + if (strcmp (so_list_tail->name, dll_path) == 0) + return; + so_list_tail = so_list_tail->next; + } + + if (so_list_tail && strcmp (so_list_tail->name, dll_path) == 0) + return; + + /* Add the shared library to the so_list_head list */ + new_so = (struct so_list *) xmalloc (sizeof (struct so_list)); + memset ((char *)new_so, 0, sizeof (struct so_list)); + if (so_list_head == NULL) + { + so_list_head = new_so; + so_list_tail = new_so; + } + else + { + so_list_tail->next = new_so; + so_list_tail = new_so; + } + + /* Initialize the new_so */ + if (load_module_desc_p) + { + new_so->pa64_solib_desc = *load_module_desc_p; + } + else + { + if (target_read_memory (load_module_desc_addr, + (char*) &new_so->pa64_solib_desc, + sizeof(struct load_module_desc)) + != 0) + { + error ("Error while reading in dynamic library %s", dll_path); + } + } + + new_so->pa64_solib_desc_addr = load_module_desc_addr; + new_so->loaded = 1; + new_so->name = obsavestring (dll_path, strlen(dll_path), + &symfile_objfile->symbol_obstack); + + /* If we are not going to load the library, tell the user if we + haven't already and return. */ + + st_size = pa64_solib_sizeof_symbol_table (dll_path); + pa64_solib_st_size_threshhold_exceeded = + !from_tty + && ( (st_size + pa64_solib_total_st_size) + > (auto_solib_add * (LONGEST)1000000)); + if (pa64_solib_st_size_threshhold_exceeded) + { + pa64_solib_add_solib_objfile (new_so, dll_path, from_tty, 1); + return; + } + + /* Now read in debug info. */ + pa64_solib_total_st_size += st_size; + + /* This fills in new_so->objfile, among others. */ + pa64_solib_load_symbols (new_so, + dll_path, + from_tty, + 0); + return; +} + + +/* + LOCAL FUNCTION + + bfd_lookup_symbol -- lookup the value for a specific symbol + + SYNOPSIS + + CORE_ADDR bfd_lookup_symbol (bfd *abfd, char *symname) + + DESCRIPTION + + An expensive way to lookup the value of a single symbol for + bfd's that are only temporary anyway. This is used by the + shared library support to find the address of the debugger + interface structures in the shared library. + + Note that 0 is specifically allowed as an error return (no + such symbol). + */ + +static CORE_ADDR +bfd_lookup_symbol (abfd, symname) + bfd *abfd; + char *symname; +{ + unsigned int storage_needed; + asymbol *sym; + asymbol **symbol_table; + unsigned int number_of_symbols; + unsigned int i; + struct cleanup *back_to; + CORE_ADDR symaddr = 0; + + storage_needed = bfd_get_symtab_upper_bound (abfd); + + if (storage_needed > 0) + { + symbol_table = (asymbol **) xmalloc (storage_needed); + back_to = make_cleanup (free, (PTR) symbol_table); + number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table); + + for (i = 0; i < number_of_symbols; i++) + { + sym = *symbol_table++; + if (STREQ (sym->name, symname)) + { + /* Bfd symbols are section relative. */ + symaddr = sym->value + sym->section->vma; + break; + } + } + do_cleanups (back_to); + } + return (symaddr); +} + diff --git a/gdb/pa64solib.h b/gdb/pa64solib.h new file mode 100644 index 0000000..5dbc5a5 --- /dev/null +++ b/gdb/pa64solib.h @@ -0,0 +1,164 @@ +/* HP PA64 ELF Shared library declarations for GDB, the GNU Debugger. + Copyright (C) 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. */ + +/* Forward decl's for prototypes */ +#ifdef __STDC__ +struct target_ops; +struct objfile; +struct section_offsets; +#endif + +/* Called to add symbols from a shared library to gdb's symbol table. */ + +#define SOLIB_ADD(filename, from_tty, targ) \ + pa64_solib_add (filename, from_tty, targ) + +extern void + pa64_solib_add PARAMS ((char *, int, struct target_ops *)); + +extern CORE_ADDR + pa64_solib_get_got_by_pc PARAMS ((CORE_ADDR)); + +/* Function to be called when the inferior starts up, to discover the names + of shared libraries that are dynamically linked, the base addresses to + which they are linked, and sufficient information to read in their symbols + at a later time. */ + +#define SOLIB_CREATE_INFERIOR_HOOK(PID) pa64_solib_create_inferior_hook() + +extern void + pa64_solib_create_inferior_hook PARAMS ((void)); + +/* Function to be called to remove the connection between debugger and + dynamic linker that was established by SOLIB_CREATE_INFERIOR_HOOK. + (This operation does not remove shared library information from + the debugger, as CLEAR_SOLIB does.) */ +#define SOLIB_REMOVE_INFERIOR_HOOK(PID) pa64_solib_remove_inferior_hook(PID) + +extern void + pa64_solib_remove_inferior_hook PARAMS ((int)); + +/* This function is called by the "catch load" command. It allows + the debugger to be notified by the dynamic linker when a specified + library file (or any library file, if filename is NULL) is loaded. */ +#define SOLIB_CREATE_CATCH_LOAD_HOOK(pid,tempflag, filename,cond_string) \ + pa64_solib_create_catch_load_hook (pid, tempflag, filename, cond_string) + +extern void + pa64_solib_create_catch_load_hook PARAMS ((int, int, char *, char *)); + +/* This function is called by the "catch unload" command. It allows + the debugger to be notified by the dynamic linker when a specified + library file (or any library file, if filename is NULL) is unloaded. */ +#define SOLIB_CREATE_CATCH_UNLOAD_HOOK(pid,tempflag,filename, cond_string) \ + pa64_solib_create_catch_unload_hook (pid, tempflag, filename, cond_string) + +extern void + pa64_solib_create_catch_unload_hook PARAMS ((int, int, char *, char *)); + +/* This function returns TRUE if the dynamic linker has just reported + a load of a library. + + This function must be used only when the inferior has stopped in + the dynamic linker hook, or undefined results are guaranteed. */ +#define SOLIB_HAVE_LOAD_EVENT(pid) \ + pa64_solib_have_load_event (pid) + +extern int + pa64_solib_have_load_event PARAMS ((int)); + +/* This function returns a pointer to the string representation of the + pathname of the dynamically-linked library that has just been loaded. + + This function must be used only when SOLIB_HAVE_LOAD_EVENT is TRUE, + or undefined results are guaranteed. + + This string's contents are only valid immediately after the inferior + has stopped in the dynamic linker hook, and becomes invalid as soon + as the inferior is continued. Clients should make a copy of this + string if they wish to continue the inferior and then access the string. */ +#define SOLIB_LOADED_LIBRARY_PATHNAME(pid) \ + pa64_solib_loaded_library_pathname (pid) + +extern char * + pa64_solib_loaded_library_pathname PARAMS ((int)); + +/* This function returns TRUE if the dynamic linker has just reported + an unload of a library. + + This function must be used only when the inferior has stopped in + the dynamic linker hook, or undefined results are guaranteed. */ +#define SOLIB_HAVE_UNLOAD_EVENT(pid) \ + pa64_solib_have_unload_event (pid) + +extern int + pa64_solib_have_unload_event PARAMS ((int)); + +/* This function returns a pointer to the string representation of the + pathname of the dynamically-linked library that has just been unloaded. + + This function must be used only when SOLIB_HAVE_UNLOAD_EVENT is TRUE, + or undefined results are guaranteed. + + This string's contents are only valid immediately after the inferior + has stopped in the dynamic linker hook, and becomes invalid as soon + as the inferior is continued. Clients should make a copy of this + string if they wish to continue the inferior and then access the string. */ +#define SOLIB_UNLOADED_LIBRARY_PATHNAME(pid) \ + pa64_solib_unloaded_library_pathname (pid) + +extern char * + pa64_solib_unloaded_library_pathname PARAMS ((int)); + +/* This function returns TRUE if pc is the address of an instruction that + lies within the dynamic linker (such as the event hook, or the dld + itself). + + This function must be used only when a dynamic linker event has been + caught, and the inferior is being stepped out of the hook, or undefined + results are guaranteed. */ +#define SOLIB_IN_DYNAMIC_LINKER(pid,pc) \ + pa64_solib_in_dynamic_linker (pid, pc) + +extern int + pa64_solib_in_dynamic_linker PARAMS ((int, CORE_ADDR)); + +/* This function must be called when the inferior is killed, and the program + restarted. This is not the same as CLEAR_SOLIB, in that it doesn't discard + any symbol tables. + + Presently, this functionality is not implemented. */ +#define SOLIB_RESTART() \ + pa64_solib_restart () + +extern void + pa64_solib_restart PARAMS ((void)); + +/* If we can't set a breakpoint, and it's in a shared library, just + disable it. */ + +#define DISABLE_UNSETTABLE_BREAK(addr) (pa64_solib_address(addr) != NULL) + +extern char * + pa64_solib_address PARAMS ((CORE_ADDR)); /* somsolib.c */ + +/* If ADDR lies in a shared library, return its name. */ + +#define PC_SOLIB(addr) pa64_solib_address (addr) diff --git a/gdb/remote.c b/gdb/remote.c index 263e20b..5c8ca61 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -100,6 +100,7 @@ static void remote_close PARAMS ((int quitting)); static void remote_store_registers PARAMS ((int regno)); static void remote_mourn PARAMS ((void)); +static void remote_async_mourn PARAMS ((void)); static void extended_remote_restart PARAMS ((void)); @@ -3794,6 +3795,12 @@ remote_mourn () } static void +remote_async_mourn () +{ + remote_mourn_1 (&remote_async_ops); +} + +static void extended_remote_mourn () { /* We do _not_ want to mourn the target like this; this will @@ -5068,7 +5075,7 @@ Specify the serial device it is connected to (e.g. /dev/ttya)."; remote_async_ops.to_remove_breakpoint = remote_remove_breakpoint; remote_async_ops.to_kill = remote_async_kill; remote_async_ops.to_load = generic_load; - remote_async_ops.to_mourn_inferior = remote_mourn; + remote_async_ops.to_mourn_inferior = remote_async_mourn; remote_async_ops.to_thread_alive = remote_thread_alive; remote_async_ops.to_find_new_threads = remote_threads_info; remote_async_ops.to_stop = remote_stop; diff --git a/gdb/sh-stub.c b/gdb/sh-stub.c index 56f8915..d2b0e18 100644 --- a/gdb/sh-stub.c +++ b/gdb/sh-stub.c @@ -439,8 +439,7 @@ getpacket (char *buffer) } -/* send the packet in buffer. The host get's one chance to read it. - This routine does not wait for a positive acknowledge. */ +/* send the packet in buffer. */ static void putpacket (register char *buffer) diff --git a/gdb/sparc-stub.c b/gdb/sparc-stub.c index 7da65c2..5769b25 100644 --- a/gdb/sparc-stub.c +++ b/gdb/sparc-stub.c @@ -485,11 +485,6 @@ set_debug_traps() for (ht = hard_trap_info; ht->tt && ht->signo; ht++) exceptionHandler(ht->tt, trap_low); - /* In case GDB is started before us, ack any packets (presumably - "$?#xx") sitting there. */ - - putDebugChar ('+'); - initialized = 1; } diff --git a/gdb/sparcl-stub.c b/gdb/sparcl-stub.c index c7994fe..bc508b3 100644 --- a/gdb/sparcl-stub.c +++ b/gdb/sparcl-stub.c @@ -602,11 +602,6 @@ set_debug_traps() if (ht->tt != 4 || ! (read_psr () & 0x1000)) exceptionHandler(ht->tt, trap_low); - /* In case GDB is started before us, ack any packets (presumably - "$?#xx") sitting there. */ - - putDebugChar ('+'); - initialized = 1; } diff --git a/gdb/sparclet-stub.c b/gdb/sparclet-stub.c index ecf670b..effc67f 100644 --- a/gdb/sparclet-stub.c +++ b/gdb/sparclet-stub.c @@ -649,10 +649,6 @@ set_debug_traps() for (ht = hard_trap_info; ht->tt && ht->signo; ht++) exceptionHandler(ht->tt, trap_low); - /* In case GDB is started before us, ack any packets (presumably - "$?#xx") sitting there. */ - putDebugChar ('+'); - initialized = 1; } diff --git a/gdb/stabsread.c b/gdb/stabsread.c index 98f377a..464fce1 100644 --- a/gdb/stabsread.c +++ b/gdb/stabsread.c @@ -3724,7 +3724,8 @@ read_baseclasses (fip, pp, type, objfile) { static struct complaint msg = { - "Unknown visibility `%c' for baseclass", 0, 0}; + "Unknown visibility `%c' for baseclass", 0, 0 + }; complain (&msg, new->visibility); new->visibility = VISIBILITY_PUBLIC; } diff --git a/gdb/symfile.c b/gdb/symfile.c index c951866..b5d2821 100644 --- a/gdb/symfile.c +++ b/gdb/symfile.c @@ -536,9 +536,10 @@ syms_from_objfile (objfile, addr, mainline, verbo) /* Convert addr into an offset rather than an absolute address. We find the lowest address of a loaded segment in the objfile, - and assume that <addr> is where that got loaded. Due to historical - precedent, we warn if that doesn't happen to be a text segment. */ + and assume that <addr> is where that got loaded. + We no longer warn if the lowest section is not a text segment (as + happens for the PA64 port. */ if (mainline) { addr = 0; /* No offset from objfile addresses. */ @@ -553,13 +554,6 @@ syms_from_objfile (objfile, addr, mainline, verbo) if (lowest_sect == NULL) warning ("no loadable sections found in added symbol-file %s", objfile->name); - else if ((bfd_get_section_flags (objfile->obfd, lowest_sect) & SEC_CODE) - == 0) - /* FIXME-32x64--assumes bfd_vma fits in long. */ - warning ("Lowest section in %s is %s at 0x%lx", - objfile->name, - bfd_section_name (objfile->obfd, lowest_sect), - (unsigned long) bfd_section_vma (objfile->obfd, lowest_sect)); if (lowest_sect) addr -= bfd_section_vma (objfile->obfd, lowest_sect); diff --git a/gdb/terminal.h b/gdb/terminal.h index 72d38f7..b764437 100644 --- a/gdb/terminal.h +++ b/gdb/terminal.h @@ -30,8 +30,6 @@ nothing has already defined the one of the names, and do the right thing. */ -/* nothing works with go32, and the headers aren't complete */ -#if !defined (__GO32__) #if !defined (HAVE_TERMIOS) && !defined(HAVE_TERMIO) && !defined(HAVE_SGTTY) #if defined(HAVE_TERMIOS_H) #define HAVE_TERMIOS @@ -45,13 +43,12 @@ #endif /* ! defined (HAVE_TERMIO_H) */ #endif /* ! defined (HAVE_TERMIOS_H) */ #endif /* !defined (HAVE_TERMIOS) && !defined(HAVE_TERMIO) && !defined(HAVE_SGTTY) */ -#endif /* ! defined (__GO32__) */ #if defined(HAVE_TERMIOS) #include <termios.h> #endif -#if !defined(__GO32__) && !defined(_WIN32) && !defined (HAVE_TERMIOS) +#if !defined(_WIN32) && !defined (HAVE_TERMIOS) /* Define a common set of macros -- BSD based -- and redefine whatever the system offers to make it look like that. FIXME: serial.h and diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 4b0a6238..61f62aa 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,24 @@ +Mon Aug 23 10:25:20 1999 Jeffrey A Law (law@cygnus.com) + + * gdb.base/dollar.exp: Do not run for PA processors in wide mode + on hpux11. + + * gdb.base/attach.exp: Handle another hpux11 error message variant + when attaching to a process that does not exist. + +1999-08-19 J.T. Conklin <jtc@redback.com> + + * gdb.base/call-ar-exp.exp: Fix pattern matching whitespace + characters in 'continue to 1241' test. + +1999-08-17 Stan Shebs <shebs@andros.cygnus.com> + + * gdb.base/call-ar-st.exp: Add a shorter match case for the + stop in print_long_arg_list, define and use a whitespace + variable in print_small_structs test, add an XFAIL for Solaris. + * gdb.base/dbx.exp: XFAIL func commands until somebody is + interested enough to fix. + 1999-08-13 Keith Seitz <keiths@cygnus.com> * gdb.base/dbx.exp (dbx_gdb_file_cmd): Rename to gdb_file_cmd. diff --git a/gdb/testsuite/gdb.base/attach.exp b/gdb/testsuite/gdb.base/attach.exp index 09a0877..3b93efe 100644 --- a/gdb/testsuite/gdb.base/attach.exp +++ b/gdb/testsuite/gdb.base/attach.exp @@ -131,6 +131,8 @@ proc do_attach_tests {} { # This response is expected on HP-UX 11.0 (i.e., ttrace-based). -re "Attaching to.*, process 0 failed.*Hint.*$gdb_prompt $"\ {pass "attach to nonexistent process is prohibited"} + -re "Attaching to.*, process 0.*denied.*$gdb_prompt $"\ + {pass "attach to nonexistent process is prohibited"} -re "$gdb_prompt $" {fail "attach to nonexistent process is prohibited"} timeout {fail "(timeout) attach to nonexistent process is prohibited"} } diff --git a/gdb/testsuite/gdb.base/call-ar-st.exp b/gdb/testsuite/gdb.base/call-ar-st.exp index 15ebe1d..e534157 100644 --- a/gdb/testsuite/gdb.base/call-ar-st.exp +++ b/gdb/testsuite/gdb.base/call-ar-st.exp @@ -311,7 +311,7 @@ gdb_test "tbreak 1241" \ send_gdb "continue\n" gdb_expect { - -re ".*main \\(\\) at .*call-ar-st.c:1241\r\n1241\t\[ \]+sum_array_print\\(10, \\*list1, \\*list2, \\*list3, \\*list4\\);.*$gdb_prompt $" { + -re ".*main \\(\\) at .*call-ar-st.c:1241\r\n1241\[\t \]+sum_array_print\\(10, \\*list1, \\*list2, \\*list3, \\*list4\\);.*$gdb_prompt $" { pass "continue to 1241"} -re ".*$gdb_prompt $" { fail "continue to 1241"} timeout { fail "(timeout) continue to 1241"} @@ -424,18 +424,24 @@ if { [istarget "hppa*-*-hpux*"] } { } } else { - # We can't just assume that a "step" will get us into print_long_arg_list here,either. + # We can't just assume that a "step" will get us into + # print_long_arg_list here,either. gdb_test "tbreak print_long_arg_list" \ "Breakpoint .* file .*call-ar-st.c, line .*" \ "tbreak in print_long_arg_list after stepping into memcpy" + # The short match case below handles cases where a buffer + # overflows or something, and expect can't deal with the full + # line. Perhaps a more elegant solution exists... -sts 1999-08-17 send_gdb "continue\n" if {![target_info exists gdb,skip_float_tests]} { gdb_expect { - -re ".*print_long_arg_list \\(a=22.219999999999999, b=33.332999999999998, c=0, d=-25, e=100, f=2345, struct1=\{value = 6, head = 0\}, struct2=\{value = 10, head = 0\}, struct3=\{value = 12, head = 0\}, struct4=\{value = 14, head = 0\}, flags=\{alpha = 1, beta = 0, gamma = 1, delta = 0, epsilon = 1, omega = 0\}, flags_combo=\{alpha = 1, beta = 0, ch1 = 121 \'y\', gamma = 1, delta = 0, ch2 = 110 \'n\', epsilon = 1, omega = 0\}, three_char=\{ch1 = 97 \'a\', ch2 = 98 \'b\', ch3 = 99 \'c\'\}, five_char=\{ch1 = 108 \'l\', ch2 = 109 \'m\', ch3 = 110 \'n\', ch4 = 111 \'o\', ch5 = 112 \'p\'\}, int_char_combo=\{int1 = 123, ch1 = 122 \'z\'\}, d1=\{double1 = 10.5\}, d2=\{double1 = -3.3399999999999999\}, d3=\{double1 = 675.09123\}, f1=\{float1 = 45.2340012, float2 = 43.5999985\}, f2=\{float1 = 78.0100021, float2 = 122.099998\}, f3=\{float1 = -1232.34497, float2 = -199.210007\}\\) at ${srcdir}/${subdir}/${srcfile}:992\[\r\n\]+992\[ \t\]+printf\\(\"double :.*\", a\\);.*$gdb_prompt $" {pass "step into print_long_arg_list"} + -re ".*print_long_arg_list \\(a=22.219999999999999, b=33.332999999999998, c=0, d=-25, e=100, f=2345, struct1=\{value = 6, head = 0\}, struct2=\{value = 10, head = 0\}, struct3=\{value = 12, head = 0\}, struct4=\{value = 14, head = 0\}, flags=\{alpha = 1, beta = 0, gamma = 1, delta = 0, epsilon = 1, omega = 0\}, flags_combo=\{alpha = 1, beta = 0, ch1 = 121 \'y\', gamma = 1, delta = 0, ch2 = 110 \'n\', epsilon = 1, omega = 0\}, three_char=\{ch1 = 97 \'a\', ch2 = 98 \'b\', ch3 = 99 \'c\'\}, five_char=\{ch1 = 108 \'l\', ch2 = 109 \'m\', ch3 = 110 \'n\', ch4 = 111 \'o\', ch5 = 112 \'p\'\}, int_char_combo=\{int1 = 123, ch1 = 122 \'z\'\}, d1=\{double1 = 10.5\}, d2=\{double1 = -3.3399999999999999\}, d3=\{double1 = 675.09123\}, f1=\{float1 = 45.2340012, float2 = 43.5999985\}, f2=\{float1 = 78.0100021, float2 = 122.099998\}, f3=\{float1 = -1232.34497, float2 = -199.210007\}\\) at ${srcdir}/${subdir}/${srcfile}:992\[\r\n\]+992\[ \t\]+printf\\(\"double :.*\", a\\);.*$gdb_prompt $" { pass "step into print_long_arg_list" } + -re ".*print_long_arg_list.*\\(a=22.219999999999999, b=33.332999999999998, c=0, d=-25, e=100, f=2345, struct1=\{value = 6, head = 0\}, struct2=\{value = 10, head = 0\}, struct3=\{value = 12, head = 0\}, struct4=\{value = 14, head = 0\}, flags=\{alpha = 1, beta = 0, gamma = 1, delta = 0, epsilon = 1, omega = 0\}, flags_combo=\{alpha = 1, beta = 0, ch1 = 121 \'y\', gamma = 1, delta = 0, ch2 = 110 \'n\', epsilon = 1, omega = 0\}, three_char=\{ch1 = 97 \'a\', ch2 = 98 \'b\', ch3 = 99 \'c\'\}.*\\) at ${srcdir}/${subdir}/${srcfile}:992\[\r\n\]+992\[ \t\]+printf\\(\"double :.*\", a\\);.*$gdb_prompt $" {pass "step into print_long_arg_list (short match)"} -re ".*$gdb_prompt $" { fail "step into print_long_arg_list" } timeout { fail "step into print_long_arg_list (timeout)" } } } else { + # If skipping float tests, don't expect anything in arg list. gdb_expect { -re ".*print_long_arg_list \\(.*\\).*$gdb_prompt $" { pass "step into print_long_arg_list" } -re ".*$gdb_prompt $" { fail "step into print_long_arg_list" } @@ -444,16 +450,23 @@ if { [istarget "hppa*-*-hpux*"] } { } } +set ws "\[\n\r\t \]+" + #call print_small_structs(struct1, struct2, struct3, struct4, flags, flags_combo, three_char, five_char, int_char_combo, d1, d2, d3, f1, f2, f3) if {![target_info exists gdb,skip_float_tests]} { - send_gdb "print print_small_structs(struct1, struct2, struct3, struct4, flags, flags_combo, three_char, five_char, int_char_combo, d1, d2, d3, f1, f2, f3)\n" - gdb_expect { - -re ".*alpha\[\t\r\n \]+gamma\[\t\r\n \]+epsilon\[\t\r\n \]+alpha\[\t\r\n \]+gamma\[\t\r\n \]+epsilon\[\t\r\n \]+ch1: y\tch2: n\[\t\r\n \]+Contents of three_char_t:\[\t\r\n \]+a\tb\tc\[\t\r\n \]+Contents of five_char_t:\[\t\r\n \]+l\tm\tn\to\tp\[\t\r\n \]+Contents of int_char_combo_t:\[\t\r\n \]+123.*z\[\t\r\n \]+Sum of the 4 struct values and seed :\[\t\r\n \]+52\[\t\r\n \]+Contents of struct1:\[\t\r\n \]+6.*0\[\t\r\n \]+Contents of struct2:\[\t\r\n \]+10.*0\[\t\r\n \]+Contents of struct3:\[\t\r\n \]+12.*0\[\t\r\n \]+Contents of one_double_t:\[\t\r\n \]+10.500000\[\t\r\n \]+Contents of one_double_t:\[\t\r\n \]+-3.340000\[\t\r\n \]+Contents of one_double_t:\[\t\r\n \]+675.091230\[\t\r\n \]+Contents of two_floats_t:\[\t\r\n \]+45.234001.*43.599998\[\t\r\n \]+Contents of two_floats_t:\[\t\r\n \]+78.010002.*122.099998\[\t\r\n \]+Contents of two_floats_t:\[\t\r\n \]+-1232.344971.*-199.210007\[\t\r\n \]+.*$gdb_prompt $" { - pass "print print_small_structs from print_long_arg_list " + # On Solaris, some of the args are passed by ref, others by value, + # and GDB gets confused and says "Invalid cast" because it thinks + # it has to cast the structure into a pointer to structure. A real + # GDB bug, probably for all Sparc configs, but obscure. -sts 1999-08-17. + setup_xfail "sparc*-*-solaris*" + send_gdb "print print_small_structs(struct1, struct2, struct3, struct4, flags, flags_combo, three_char, five_char, int_char_combo, d1, d2, d3, f1, f2, f3)\n" + gdb_expect { + -re ".*alpha${ws}gamma${ws}epsilon${ws}alpha${ws}gamma${ws}epsilon${ws}ch1: y\tch2: n${ws}Contents of three_char_t:${ws}a\tb\tc${ws}Contents of five_char_t:${ws}l\tm\tn\to\tp${ws}Contents of int_char_combo_t:${ws}123.*z${ws}Sum of the 4 struct values and seed :${ws}52${ws}Contents of struct1:${ws}6.*0${ws}Contents of struct2:${ws}10.*0${ws}Contents of struct3:${ws}12.*0${ws}Contents of one_double_t:${ws}10.500000${ws}Contents of one_double_t:${ws}-3.340000${ws}Contents of one_double_t:${ws}675.091230${ws}Contents of two_floats_t:${ws}45.234001.*43.599998${ws}Contents of two_floats_t:${ws}78.010002.*122.099998${ws}Contents of two_floats_t:${ws}-1232.344971.*-199.210007${ws}.*$gdb_prompt $" { + pass "print print_small_structs from print_long_arg_list" + } + -re ".*$gdb_prompt $" { fail "print print_small_structs from print_long_arg_list" } + timeout { fail "(timeout) print_small_structs from print_long_arg_list" } } - -re ".*$gdb_prompt $" { fail "print print_small_structs from print_long_arg_list" } - timeout { fail "(timeout) print_small_structs from print_long_arg_list" } - } } diff --git a/gdb/testsuite/gdb.base/dbx.exp b/gdb/testsuite/gdb.base/dbx.exp index 092b31a..2c0ad65 100644 --- a/gdb/testsuite/gdb.base/dbx.exp +++ b/gdb/testsuite/gdb.base/dbx.exp @@ -308,9 +308,13 @@ proc test_whereis { } { proc test_func { } { gdb_test "cont" "" gdb_test "step" "" + # This always fails, but it's not clear why. -sts 1999-08-17 + setup_xfail "*-*-*" gdb_test "func sum" "'sum' not within current stack frame\." gdb_test "stop in sum" "Breakpoint.*at.*: file.*sum\.c, line 11\." gdb_test "cont" + # This always fails, but it's not clear why. -sts 1999-08-17 + setup_xfail "*-*-*" gdb_test "func print_average" ".*in print_average.*\\(list=.*, low=0, high=6\\).*at.*average\.c:24\r\n24\[ \t\]+total = sum\\(list, low, high\\);" } diff --git a/gdb/testsuite/gdb.base/dollar.exp b/gdb/testsuite/gdb.base/dollar.exp index 50fac6a..1efb9c9 100644 --- a/gdb/testsuite/gdb.base/dollar.exp +++ b/gdb/testsuite/gdb.base/dollar.exp @@ -32,6 +32,12 @@ if ![ istarget "*-*-hpux*" ] then { return } +# When we are in "wide" mode we do not necessary have $$dyncall as a symbol +# name, which makes all these tests useless +if ![ istarget "hppa*w-*-hpux11*" ] then { + return +} + if $tracelevel then { strace $tracelevel } diff --git a/gdb/thread.c b/gdb/thread.c index 4be1a74..4a2070b 100644 --- a/gdb/thread.c +++ b/gdb/thread.c @@ -160,6 +160,11 @@ delete_thread (pid) else thread_list = tp->next; + /* NOTE: this will take care of any left-over step_resume breakpoints, + but not any user-specified thread-specific breakpoints. */ + if (tp->step_resume_breakpoint) + delete_breakpoint (tp->step_resume_breakpoint); + free (tp); return; @@ -350,20 +355,11 @@ prune_threads () { struct thread_info *tp, *tpprev, *next; - tpprev = 0; for (tp = thread_list; tp; tp = next) { next = tp->next; if (!thread_alive (tp)) - { - if (tpprev) - tpprev->next = next; - else - thread_list = next; - free (tp); - } - else - tpprev = tp; + delete_thread (tp->pid); } } diff --git a/gdb/value.h b/gdb/value.h index c4a33f5..453e934 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -27,23 +27,6 @@ * be possible for a program lval value to survive over a call to the inferior * (ie to be put into the history list or an internal variable). */ -enum lval_type - { - /* Not an lval. */ - not_lval, - /* In memory. Could be a saved register. */ - lval_memory, - /* In a register. */ - lval_register, - /* In a gdb internal variable. */ - lval_internalvar, - /* Part of a gdb internal variable (structure field). */ - lval_internalvar_component, - /* In a register series in a frame not the current one, which may have been - partially saved or saved in different places (otherwise would be - lval_register or lval_memory). */ - lval_reg_frame_relative - }; struct value { |