* elflink.h (elf_bfd_final_link): Check if dynobj is not NULL
[binutils-gdb.git] / gdb / breakpoint.c
index 879a31eb218c0d3689b929b15e97f1429d999bfd..cf2b6c0582378fab9bc099c4e3800b6559ab28bb 100644 (file)
@@ -41,6 +41,7 @@
 #include "objfiles.h"
 #include "linespec.h"
 #include "completer.h"
+#include "gdb.h"
 #ifdef UI_OUT
 #include "ui-out.h"
 #endif
@@ -136,7 +137,7 @@ static enum print_stop_action print_bp_stop_message (bpstat bs);
 typedef struct
   {
     enum exception_event_kind kind;
-    int enable;
+    int enable_p;
   }
 args_for_catchpoint_enable;
 
@@ -376,7 +377,7 @@ get_number_trailer (char **pp, int trailer)
          to pass to lookup_internalvar().  */
       char *varname;
       char *start = ++p;
-      value_ptr val;
+      struct value *val;
 
       while (isalnum (*p) || *p == '_')
        p++;
@@ -722,7 +723,7 @@ insert_breakpoints (void)
 
   ALL_BREAKPOINTS_SAFE (b, temp)
   {
-    if (b->enable == permanent)
+    if (b->enable_state == bp_permanent)
       /* Permanent breakpoints cannot be inserted or removed.  */
       continue;
     else if (b->type != bp_watchpoint
@@ -734,9 +735,9 @@ insert_breakpoints (void)
        && b->type != bp_catch_exec
        && b->type != bp_catch_throw
        && b->type != bp_catch_catch
-       && b->enable != disabled
-       && b->enable != shlib_disabled
-       && b->enable != call_disabled
+       && b->enable_state != bp_disabled
+       && b->enable_state != bp_shlib_disabled
+       && b->enable_state != bp_call_disabled
        && !b->inserted
        && !b->duplicate)
       {
@@ -775,7 +776,7 @@ insert_breakpoints (void)
              {
                /* See also: disable_breakpoints_in_shlibs. */
                val = 0;
-               b->enable = shlib_disabled;
+               b->enable_state = bp_shlib_disabled;
                if (!disabled_breaks)
                  {
                    target_terminal_ours_for_output ();
@@ -803,9 +804,9 @@ insert_breakpoints (void)
          return_val = val;     /* remember failure */
       }
     else if (ep_is_exception_catchpoint (b)
-            && b->enable != disabled
-            && b->enable != shlib_disabled
-            && b->enable != call_disabled
+            && b->enable_state != bp_disabled
+            && b->enable_state != bp_shlib_disabled
+            && b->enable_state != bp_call_disabled
             && !b->inserted
             && !b->duplicate)
 
@@ -823,7 +824,7 @@ insert_breakpoints (void)
            target_terminal_ours_for_output ();
            warning ("Cannot insert catchpoint %d; disabling it.",
                     b->number);
-           b->enable = disabled;
+           b->enable_state = bp_disabled;
          }
        else
          {
@@ -832,7 +833,7 @@ insert_breakpoints (void)
            args_for_catchpoint_enable args;
            args.kind = b->type == bp_catch_catch ? 
              EX_EVENT_CATCH : EX_EVENT_THROW;
-           args.enable = 1;
+           args.enable_p = 1;
            val = catch_errors (cover_target_enable_exception_callback,
                                &args,
                                message, RETURN_MASK_ALL);
@@ -847,7 +848,7 @@ insert_breakpoints (void)
                target_terminal_ours_for_output ();
                warning ("Cannot insert catchpoint %d; disabling it.",
                         b->number);
-               b->enable = disabled;
+               b->enable_state = bp_disabled;
              }
          }
 
@@ -858,15 +859,15 @@ insert_breakpoints (void)
     else if ((b->type == bp_hardware_watchpoint ||
              b->type == bp_read_watchpoint ||
              b->type == bp_access_watchpoint)
-            && b->enable == enabled
-            && b->disposition != del_at_next_stop
+            && b->enable_state == bp_enabled
+            && b->disposition != disp_del_at_next_stop
             && !b->inserted
             && !b->duplicate)
       {
        struct frame_info *saved_frame;
        int saved_level, within_current_scope;
-       value_ptr mark = value_mark ();
-       value_ptr v;
+       struct value *mark = value_mark ();
+       struct value *v;
 
        /* Save the current frame and level so we can restore it after
           evaluating the watchpoint expression on its own frame.  */
@@ -966,8 +967,8 @@ insert_breakpoints (void)
            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;
+             b->related_breakpoint->disposition = disp_del_at_next_stop;
+           b->disposition = disp_del_at_next_stop;
          }
 
        /* Restore the frame and level.  */
@@ -981,7 +982,7 @@ insert_breakpoints (void)
     else if ((b->type == bp_catch_fork
              || b->type == bp_catch_vfork
              || b->type == bp_catch_exec)
-            && b->enable == enabled
+            && b->enable_state == bp_enabled
             && !b->inserted
             && !b->duplicate)
       {
@@ -1250,7 +1251,7 @@ remove_breakpoint (struct breakpoint *b, insertion_state_t is)
 {
   int val;
 
-  if (b->enable == permanent)
+  if (b->enable_state == bp_permanent)
     /* Permanent breakpoints cannot be inserted or removed.  */
     return 0;
 
@@ -1302,10 +1303,11 @@ remove_breakpoint (struct breakpoint *b, insertion_state_t is)
   else if ((b->type == bp_hardware_watchpoint ||
            b->type == bp_read_watchpoint ||
            b->type == bp_access_watchpoint)
-          && b->enable == enabled
+          && b->enable_state == bp_enabled
           && !b->duplicate)
     {
-      value_ptr v, n;
+      struct value *v;
+      struct value *n;
 
       b->inserted = (is == mark_inserted);
       /* Walk down the saved value chain.  */
@@ -1357,7 +1359,7 @@ remove_breakpoint (struct breakpoint *b, insertion_state_t is)
   else if ((b->type == bp_catch_fork ||
            b->type == bp_catch_vfork ||
            b->type == bp_catch_exec)
-          && b->enable == enabled
+          && b->enable_state == bp_enabled
           && !b->duplicate)
     {
       val = -1;
@@ -1382,7 +1384,7 @@ remove_breakpoint (struct breakpoint *b, insertion_state_t is)
     }
   else if ((b->type == bp_catch_catch ||
            b->type == bp_catch_throw)
-          && b->enable == enabled
+          && b->enable_state == bp_enabled
           && !b->duplicate)
     {
 
@@ -1393,7 +1395,7 @@ remove_breakpoint (struct breakpoint *b, insertion_state_t is)
     }
   else if (ep_is_exception_catchpoint (b)
           && b->inserted       /* sometimes previous insert doesn't happen */
-          && b->enable == enabled
+          && b->enable_state == bp_enabled
           && !b->duplicate)
     {
 
@@ -1504,15 +1506,15 @@ breakpoint_here_p (CORE_ADDR pc)
   int any_breakpoint_here = 0;
 
   ALL_BREAKPOINTS (b)
-    if ((b->enable == enabled
-        || b->enable == permanent)
+    if ((b->enable_state == bp_enabled
+        || b->enable_state == bp_permanent)
        && b->address == pc)    /* bp is enabled and matches pc */
       {
        if (overlay_debugging &&
            section_is_overlay (b->section) &&
            !section_is_mapped (b->section))
          continue;             /* unmapped overlay -- can't be a match */
-       else if (b->enable == permanent)
+       else if (b->enable_state == bp_permanent)
          return permanent_breakpoint_here;
        else
          any_breakpoint_here = 1;
@@ -1590,9 +1592,9 @@ breakpoint_thread_match (CORE_ADDR pc, ptid_t ptid)
   thread = pid_to_thread_id (ptid);
 
   ALL_BREAKPOINTS (b)
-    if (b->enable != disabled
-       && b->enable != shlib_disabled
-       && b->enable != call_disabled
+    if (b->enable_state != bp_disabled
+       && b->enable_state != bp_shlib_disabled
+       && b->enable_state != bp_call_disabled
        && b->address == pc
        && (b->thread == -1 || b->thread == thread))
     {
@@ -1889,7 +1891,7 @@ print_it_typical (bpstat bs)
 #ifdef UI_OUT
       annotate_breakpoint (bs->breakpoint_at->number);
       ui_out_text (uiout, "\nBreakpoint ");
-      if (interpreter_p && strncmp (interpreter_p, "mi", 2) == 0)
+      if (ui_out_is_mi_like_p (uiout))
        ui_out_field_string (uiout, "reason", "breakpoint-hit");
       ui_out_field_int (uiout, "bkptno", bs->breakpoint_at->number);
       ui_out_text (uiout, ", ");
@@ -2034,7 +2036,7 @@ print_it_typical (bpstat bs)
        {
          annotate_watchpoint (bs->breakpoint_at->number);
 #ifdef UI_OUT
-         if (interpreter_p && strncmp (interpreter_p, "mi", 2) == 0)
+         if (ui_out_is_mi_like_p (uiout))
            ui_out_field_string (uiout, "reason", "watchpoint-trigger");
          mention (bs->breakpoint_at);
          ui_out_tuple_begin (uiout, "value");
@@ -2064,7 +2066,7 @@ print_it_typical (bpstat bs)
 
     case bp_read_watchpoint:
 #ifdef UI_OUT
-      if (interpreter_p && strncmp (interpreter_p, "mi", 2) == 0)
+      if (ui_out_is_mi_like_p (uiout))
        ui_out_field_string (uiout, "reason", "read-watchpoint-trigger");
       mention (bs->breakpoint_at);
       ui_out_tuple_begin (uiout, "value");
@@ -2088,7 +2090,7 @@ print_it_typical (bpstat bs)
       if (bs->old_val != NULL)     
        {
          annotate_watchpoint (bs->breakpoint_at->number);
-         if (interpreter_p && strncmp (interpreter_p, "mi", 2) == 0)
+         if (ui_out_is_mi_like_p (uiout))
            ui_out_field_string (uiout, "reason", "access-watchpoint-trigger");
          mention (bs->breakpoint_at);
          ui_out_tuple_begin (uiout, "value");
@@ -2102,7 +2104,7 @@ print_it_typical (bpstat bs)
       else 
        {
          mention (bs->breakpoint_at);
-         if (interpreter_p && strncmp (interpreter_p, "mi", 2) == 0)
+         if (ui_out_is_mi_like_p (uiout))
            ui_out_field_string (uiout, "reason", "access-watchpoint-trigger");
          ui_out_tuple_begin (uiout, "value");
          ui_out_text (uiout, "\nValue = ");
@@ -2139,7 +2141,7 @@ print_it_typical (bpstat bs)
 
     case bp_finish:
 #ifdef UI_OUT
-      if (interpreter_p && strncmp (interpreter_p, "mi", 2) == 0)
+      if (ui_out_is_mi_like_p (uiout))
        ui_out_field_string (uiout, "reason", "function-finished");
 #endif
       return PRINT_UNKNOWN;
@@ -2147,7 +2149,7 @@ print_it_typical (bpstat bs)
 
     case bp_until:
 #ifdef UI_OUT
-      if (interpreter_p && strncmp (interpreter_p, "mi", 2) == 0)
+      if (ui_out_is_mi_like_p (uiout))
        ui_out_field_string (uiout, "reason", "location-reached");
 #endif
       return PRINT_UNKNOWN;
@@ -2249,7 +2251,7 @@ bpstat_print (bpstat bs)
 static int
 breakpoint_cond_eval (PTR exp)
 {
-  value_ptr mark = value_mark ();
+  struct value *mark = value_mark ();
   int i = !value_true (evaluate_expression ((struct expression *) exp));
   value_free_to_mark (mark);
   return i;
@@ -2306,6 +2308,14 @@ watchpoint_check (PTR p)
       reinit_frame_cache ();
       fr = find_frame_addr_in_frame_chain (b->watchpoint_frame);
       within_current_scope = (fr != NULL);
+      /* in_function_epilogue_p() returns a non-zero value if we're still
+        in the function but the stack frame has already been invalidated.
+        Since we can't rely on the values of local variables after the
+        stack has been destroyed, we are treating the watchpoint in that
+        state as `not changed' without further checking. */
+      if (within_current_scope && fr == get_current_frame ()
+          && gdbarch_in_function_epilogue_p (current_gdbarch, read_pc ()))
+       return WP_VALUE_NOT_CHANGED;
       if (within_current_scope)
        /* If we end up stopping, the current frame will get selected
           in normal_stop.  So this call to select_frame won't affect
@@ -2320,8 +2330,8 @@ watchpoint_check (PTR p)
          call free_all_values.  We can't call free_all_values because
          we might be in the middle of evaluating a function call.  */
 
-      value_ptr mark = value_mark ();
-      value_ptr new_val = evaluate_expression (bs->breakpoint_at->exp);
+      struct value *mark = value_mark ();
+      struct value *new_val = evaluate_expression (bs->breakpoint_at->exp);
       if (!value_equal (b->val, new_val))
        {
          release_value (new_val);
@@ -2354,7 +2364,7 @@ watchpoint_check (PTR p)
         will be deleted already. So we have no choice but print the
         information here. */
 #ifdef UI_OUT
-      if (interpreter_p && strncmp (interpreter_p, "mi", 2) == 0)
+      if (ui_out_is_mi_like_p (uiout))
        ui_out_field_string (uiout, "reason", "watchpoint-scope");
       ui_out_text (uiout, "\nWatchpoint ");
       ui_out_field_int (uiout, "wpnum", bs->breakpoint_at->number);
@@ -2367,8 +2377,8 @@ which its expression is valid.\n", bs->breakpoint_at->number);
 #endif 
 
       if (b->related_breakpoint)
-       b->related_breakpoint->disposition = del_at_next_stop;
-      b->disposition = del_at_next_stop;
+       b->related_breakpoint->disposition = disp_del_at_next_stop;
+      b->disposition = disp_del_at_next_stop;
 
       return WP_DELETED;
     }
@@ -2409,15 +2419,20 @@ bpstat_stop_status (CORE_ADDR *pc, int not_a_breakpoint)
   "Error evaluating expression for watchpoint %d\n";
   char message[sizeof (message1) + 30 /* slop */ ];
 
-  /* Get the address where the breakpoint would have been.  */
+  /* Get the address where the breakpoint would have been.  
+     The "not_a_breakpoint" argument is meant to distinguish 
+     between a breakpoint trap event and a trace/singlestep
+     trap event.  For a trace/singlestep trap event, we would
+     not want to subtract DECR_PC_AFTER_BREAK from the PC. */
+
   bp_addr = *pc - (not_a_breakpoint && !SOFTWARE_SINGLE_STEP_P () ? 
                    0 : DECR_PC_AFTER_BREAK);
 
   ALL_BREAKPOINTS_SAFE (b, temp)
   {
-    if (b->enable == disabled
-       || b->enable == shlib_disabled
-       || b->enable == call_disabled)
+    if (b->enable_state == bp_disabled
+       || b->enable_state == bp_shlib_disabled
+       || b->enable_state == bp_call_disabled)
       continue;
 
     if (b->type != bp_watchpoint
@@ -2524,8 +2539,8 @@ bpstat_stop_status (CORE_ADDR *pc, int not_a_breakpoint)
            /* Error from catch_errors.  */
            printf_filtered ("Watchpoint %d deleted.\n", b->number);
            if (b->related_breakpoint)
-             b->related_breakpoint->disposition = del_at_next_stop;
-           b->disposition = del_at_next_stop;
+             b->related_breakpoint->disposition = disp_del_at_next_stop;
+           b->disposition = disp_del_at_next_stop;
            /* We've already printed what needs to be printed.  */
            bs->print_it = print_it_done;
 
@@ -2537,7 +2552,7 @@ bpstat_stop_status (CORE_ADDR *pc, int not_a_breakpoint)
             b->type == bp_access_watchpoint)
       {
        CORE_ADDR addr;
-       value_ptr v;
+       struct value *v;
        int found = 0;
 
        addr = target_stopped_data_address ();
@@ -2596,8 +2611,8 @@ bpstat_stop_status (CORE_ADDR *pc, int not_a_breakpoint)
              /* Error from catch_errors.  */
              printf_filtered ("Watchpoint %d deleted.\n", b->number);
              if (b->related_breakpoint)
-               b->related_breakpoint->disposition = del_at_next_stop;
-             b->disposition = del_at_next_stop;
+               b->related_breakpoint->disposition = disp_del_at_next_stop;
+             b->disposition = disp_del_at_next_stop;
              /* We've already printed what needs to be printed.  */
              bs->print_it = print_it_done;
              break;
@@ -2656,8 +2671,8 @@ bpstat_stop_status (CORE_ADDR *pc, int not_a_breakpoint)
        else
          {
            /* We will stop here */
-           if (b->disposition == disable)
-             b->enable = disabled;
+           if (b->disposition == disp_disable)
+             b->enable_state = bp_disabled;
            bs->commands = b->commands;
            if (b->silent)
              bs->print = 0;
@@ -2998,7 +3013,7 @@ bpstat_should_step (void)
 {
   struct breakpoint *b;
   ALL_BREAKPOINTS (b)
-    if (b->enable == enabled && b->type == bp_watchpoint)
+    if (b->enable_state == bp_enabled && b->type == bp_watchpoint)
       return 1;
   return 0;
 }
@@ -3009,7 +3024,7 @@ bpstat_have_active_hw_watchpoints (void)
 {
   struct breakpoint *b;
   ALL_BREAKPOINTS (b)
-    if ((b->enable == enabled) &&
+    if ((b->enable_state == bp_enabled) &&
        (b->inserted) &&
        ((b->type == bp_hardware_watchpoint) ||
         (b->type == bp_read_watchpoint) ||
@@ -3168,10 +3183,10 @@ print_one_breakpoint (struct breakpoint *b,
   /* 4 */
   annotate_field (3);
 #ifdef UI_OUT
-  ui_out_field_fmt (uiout, "enabled", "%c", bpenables[(int) b->enable]);
+  ui_out_field_fmt (uiout, "enabled", "%c", bpenables[(int) b->enable_state]);
   ui_out_spaces (uiout, 2);
 #else
-  printf_filtered ("%-3c ", bpenables[(int) b->enable]);
+  printf_filtered ("%-3c ", bpenables[(int) b->enable_state]);
 #endif
   
   /* 5 and 6 */
@@ -3476,7 +3491,7 @@ print_one_breakpoint (struct breakpoint *b,
 #ifdef UI_OUT
   /* Output the count also if it is zero, but only if this is
      mi. FIXME: Should have a better test for this. */
-  if (interpreter_p && strncmp (interpreter_p, "mi", 2) == 0)
+  if (ui_out_is_mi_like_p (uiout))
     if (show_breakpoint_hit_counts && b->hit_count == 0)
       ui_out_field_int (uiout, "times", b->hit_count);
 #endif
@@ -3520,7 +3535,7 @@ struct captured_breakpoint_query_args
   };
 
 static int
-do_captured_breakpoint_query (void *data)
+do_captured_breakpoint_query (struct ui_out *uiout, void *data)
 {
   struct captured_breakpoint_query_args *args = data;
   register struct breakpoint *b;
@@ -3537,14 +3552,14 @@ do_captured_breakpoint_query (void *data)
 }
 
 enum gdb_rc
-gdb_breakpoint_query (/* output object, */ int bnum)
+gdb_breakpoint_query (struct ui_out *uiout, int bnum)
 {
   struct captured_breakpoint_query_args args;
   args.bnum = bnum;
   /* For the moment we don't trust print_one_breakpoint() to not throw
      an error. */
-  return catch_errors (do_captured_breakpoint_query, &args,
-                      NULL, RETURN_MASK_ALL);
+  return catch_exceptions (uiout, do_captured_breakpoint_query, &args,
+                          NULL, RETURN_MASK_ALL);
 }
 
 /* Return non-zero if B is user settable (breakpoints, watchpoints,
@@ -3598,29 +3613,34 @@ breakpoint_1 (int bnum, int allflag)
 
 #ifdef UI_OUT
   if (nr_printable_breakpoints > 0)
-    {
-      annotate_breakpoints_headers ();
-      annotate_field (0);
-      ui_out_table_header (uiout, 3, ui_left, "number", "Num");                /* 1 */
-      annotate_field (1);
-      ui_out_table_header (uiout, 14, ui_left, "type", "Type");                /* 2 */
-      annotate_field (2);
-      ui_out_table_header (uiout, 4, ui_left, "disp", "Disp");         /* 3 */
-      annotate_field (3);
-      ui_out_table_header (uiout, 3, ui_left, "enabled", "Enb");       /* 4 */
-      if (addressprint)
+    annotate_breakpoints_headers ();
+  if (nr_printable_breakpoints > 0)
+    annotate_field (0);
+  ui_out_table_header (uiout, 3, ui_left, "number", "Num");            /* 1 */
+  if (nr_printable_breakpoints > 0)
+    annotate_field (1);
+  ui_out_table_header (uiout, 14, ui_left, "type", "Type");            /* 2 */
+  if (nr_printable_breakpoints > 0)
+    annotate_field (2);
+  ui_out_table_header (uiout, 4, ui_left, "disp", "Disp");             /* 3 */
+  if (nr_printable_breakpoints > 0)
+    annotate_field (3);
+  ui_out_table_header (uiout, 3, ui_left, "enabled", "Enb");   /* 4 */
+  if (addressprint)
        {
-         annotate_field (4);
+         if (nr_printable_breakpoints > 0)
+           annotate_field (4);
          if (TARGET_ADDR_BIT <= 32)
            ui_out_table_header (uiout, 10, ui_left, "addr", "Address");/* 5 */
          else
            ui_out_table_header (uiout, 18, ui_left, "addr", "Address");/* 5 */
        }
-      annotate_field (5);
-      ui_out_table_header (uiout, 40, ui_noalign, "what", "What");     /* 6 */
-      ui_out_table_body (uiout);
-      annotate_breakpoints_table ();
-    }
+  if (nr_printable_breakpoints > 0)
+    annotate_field (5);
+  ui_out_table_header (uiout, 40, ui_noalign, "what", "What"); /* 6 */
+  ui_out_table_body (uiout);
+  if (nr_printable_breakpoints > 0)
+    annotate_breakpoints_table ();
 #else
   if (nr_printable_breakpoints > 0)
     {
@@ -3738,10 +3758,10 @@ describe_other_breakpoints (CORE_ADDR pc, asection *section)
            others--;
            printf_filtered ("%d%s%s ",
                             b->number,
-                            ((b->enable == disabled || 
-                              b->enable == shlib_disabled || 
-                              b->enable == call_disabled) ? " (disabled)" 
-                             : b->enable == permanent ? " (permanent)"
+                            ((b->enable_state == bp_disabled || 
+                              b->enable_state == bp_shlib_disabled || 
+                              b->enable_state == bp_call_disabled) ? " (disabled)" 
+                             : b->enable_state == bp_permanent ? " (permanent)"
                              : ""),
                             (others > 1) ? "," 
                             : ((others == 1) ? " and" : ""));
@@ -3818,15 +3838,15 @@ check_duplicates (struct breakpoint *bpt)
     return;
 
   ALL_BREAKPOINTS (b)
-    if (b->enable != disabled
-       && b->enable != shlib_disabled
-       && b->enable != call_disabled
+    if (b->enable_state != bp_disabled
+       && b->enable_state != bp_shlib_disabled
+       && b->enable_state != bp_call_disabled
        && b->address == address
        && (overlay_debugging == 0 || b->section == section)
        && breakpoint_address_is_meaningful (b))
     {
       /* Have we found a permanent breakpoint?  */
-      if (b->enable == permanent)
+      if (b->enable_state == bp_permanent)
        {
          perm_bp = b;
          break;
@@ -3857,9 +3877,9 @@ check_duplicates (struct breakpoint *bpt)
                              "another breakpoint was inserted on top of "
                              "a permanent breakpoint");
 
-           if (b->enable != disabled
-               && b->enable != shlib_disabled
-               && b->enable != call_disabled
+           if (b->enable_state != bp_disabled
+               && b->enable_state != bp_shlib_disabled
+               && b->enable_state != bp_call_disabled
                && b->address == address
                && (overlay_debugging == 0 || b->section == section)
                && breakpoint_address_is_meaningful (b))
@@ -3902,7 +3922,7 @@ set_raw_breakpoint (struct symtab_and_line sal, enum bptype bptype)
   b->input_radix = input_radix;
   b->thread = -1;
   b->line_number = sal.line;
-  b->enable = enabled;
+  b->enable_state = bp_enabled;
   b->next = 0;
   b->silent = 0;
   b->ignore_count = 0;
@@ -3939,7 +3959,7 @@ set_raw_breakpoint (struct symtab_and_line sal, enum bptype bptype)
 void
 make_breakpoint_permanent (struct breakpoint *b)
 {
-  b->enable = permanent;
+  b->enable_state = bp_permanent;
 
   /* By definition, permanent breakpoints are already present in the code.  */
   b->inserted = 1;
@@ -3969,8 +3989,8 @@ create_longjmp_breakpoint (char *func_name)
   b = set_raw_breakpoint (sal,
                           func_name != NULL ? bp_longjmp : bp_longjmp_resume);
 
-  b->disposition = donttouch;
-  b->enable = disabled;
+  b->disposition = disp_donttouch;
+  b->enable_state = bp_disabled;
   b->silent = 1;
   if (func_name)
     b->addr_string = xstrdup (func_name);
@@ -3991,7 +4011,7 @@ enable_longjmp_breakpoint (void)
   ALL_BREAKPOINTS (b)
     if (b->type == bp_longjmp)
     {
-      b->enable = enabled;
+      b->enable_state = bp_enabled;
       check_duplicates (b);
     }
 }
@@ -4005,7 +4025,7 @@ disable_longjmp_breakpoint (void)
     if (b->type == bp_longjmp
        || b->type == bp_longjmp_resume)
     {
-      b->enable = disabled;
+      b->enable_state = bp_disabled;
       check_duplicates (b);
     }
 }
@@ -4023,8 +4043,8 @@ create_thread_event_breakpoint (CORE_ADDR address)
   b = set_raw_breakpoint (sal, bp_thread_event);
   
   b->number = internal_breakpoint_number--;
-  b->disposition = donttouch;
-  b->enable = enabled;
+  b->disposition = disp_donttouch;
+  b->enable_state = bp_enabled;
   /* addr_string has to be used or breakpoint_re_set will delete me.  */
   sprintf (addr_string, "*0x%s", paddr (b->address));
   b->addr_string = xstrdup (addr_string);
@@ -4064,7 +4084,7 @@ create_solib_event_breakpoint (CORE_ADDR address)
   sal.section = find_pc_overlay (sal.pc);
   b = set_raw_breakpoint (sal, bp_shlib_event);
   b->number = internal_breakpoint_number--;
-  b->disposition = donttouch;
+  b->disposition = disp_donttouch;
 
   return b;
 }
@@ -4084,11 +4104,11 @@ disable_breakpoints_in_shlibs (int silent)
 #if defined (PC_SOLIB)
     if (((b->type == bp_breakpoint) ||
         (b->type == bp_hardware_breakpoint)) &&
-       b->enable == enabled &&
+       b->enable_state == bp_enabled &&
        !b->duplicate &&
        PC_SOLIB (b->address))
       {
-       b->enable = shlib_disabled;
+       b->enable_state = bp_shlib_disabled;
        if (!silent)
          {
            if (!disabled_shlib_breaks)
@@ -4111,14 +4131,14 @@ re_enable_breakpoints_in_shlibs (void)
   struct breakpoint *b;
 
   ALL_BREAKPOINTS (b)
-    if (b->enable == shlib_disabled)
+    if (b->enable_state == bp_shlib_disabled)
     {
       char buf[1];
 
       /* Do not reenable the breakpoint if the shared library
          is still not mapped in.  */
       if (target_read_memory (b->address, buf, 1) == 0)
-       b->enable = enabled;
+       b->enable_state = bp_enabled;
     }
 }
 
@@ -4185,8 +4205,8 @@ solib_load_unload_1 (char *hookname, int tempflag, char *dll_pathname,
   else if (addr_start)
     b->addr_string = savestring (addr_start, addr_end - addr_start);
 
-  b->enable = enabled;
-  b->disposition = tempflag ? del : donttouch;
+  b->enable_state = bp_enabled;
+  b->disposition = tempflag ? disp_del : disp_donttouch;
 
   if (dll_pathname == NULL)
     b->dll_pathname = NULL;
@@ -4237,8 +4257,8 @@ create_fork_vfork_event_catchpoint (int tempflag, char *cond_string,
     NULL : savestring (cond_string, strlen (cond_string));
   b->thread = thread;
   b->addr_string = NULL;
-  b->enable = enabled;
-  b->disposition = tempflag ? del : donttouch;
+  b->enable_state = bp_enabled;
+  b->disposition = tempflag ? disp_del : disp_donttouch;
   b->forked_inferior_pid = 0;
 
   mention (b);
@@ -4276,8 +4296,8 @@ create_exec_event_catchpoint (int tempflag, char *cond_string)
     NULL : savestring (cond_string, strlen (cond_string));
   b->thread = thread;
   b->addr_string = NULL;
-  b->enable = enabled;
-  b->disposition = tempflag ? del : donttouch;
+  b->enable_state = bp_enabled;
+  b->disposition = tempflag ? disp_del : disp_donttouch;
 
   mention (b);
 }
@@ -4290,7 +4310,7 @@ hw_breakpoint_used_count (void)
 
   ALL_BREAKPOINTS (b)
   {
-    if (b->type == bp_hardware_breakpoint && b->enable == enabled)
+    if (b->type == bp_hardware_breakpoint && b->enable_state == bp_enabled)
       i++;
   }
 
@@ -4306,14 +4326,14 @@ hw_watchpoint_used_count (enum bptype type, int *other_type_used)
   *other_type_used = 0;
   ALL_BREAKPOINTS (b)
   {
-    if (b->enable == enabled)
+    if (b->enable_state == bp_enabled)
       {
        if (b->type == type)
          i++;
        else if ((b->type == bp_hardware_watchpoint ||
                  b->type == bp_read_watchpoint ||
                  b->type == bp_access_watchpoint)
-                && b->enable == enabled)
+                && b->enable_state == bp_enabled)
          *other_type_used = 1;
       }
   }
@@ -4335,7 +4355,7 @@ set_longjmp_resume_breakpoint (CORE_ADDR pc, struct frame_info *frame)
     if (b->type == bp_longjmp_resume)
     {
       b->address = pc;
-      b->enable = enabled;
+      b->enable_state = bp_enabled;
       if (frame != NULL)
        b->frame = frame->frame;
       else
@@ -4357,9 +4377,9 @@ disable_watchpoints_before_interactive_call_start (void)
         || (b->type == bp_read_watchpoint)
         || (b->type == bp_access_watchpoint)
         || ep_is_exception_catchpoint (b))
-       && (b->enable == enabled))
+       && (b->enable_state == bp_enabled))
       {
-       b->enable = call_disabled;
+       b->enable_state = bp_call_disabled;
        check_duplicates (b);
       }
   }
@@ -4377,9 +4397,9 @@ enable_watchpoints_after_interactive_call_stop (void)
         || (b->type == bp_read_watchpoint)
         || (b->type == bp_access_watchpoint)
         || ep_is_exception_catchpoint (b))
-       && (b->enable == call_disabled))
+       && (b->enable_state == bp_call_disabled))
       {
-       b->enable = enabled;
+       b->enable_state = bp_enabled;
        check_duplicates (b);
       }
   }
@@ -4396,8 +4416,8 @@ set_momentary_breakpoint (struct symtab_and_line sal, struct frame_info *frame,
 {
   register struct breakpoint *b;
   b = set_raw_breakpoint (sal, type);
-  b->enable = enabled;
-  b->disposition = donttouch;
+  b->enable_state = bp_enabled;
+  b->disposition = disp_donttouch;
   b->frame = (frame ? frame->frame : 0);
 
   /* If we're debugging a multi-threaded program, then we
@@ -4499,7 +4519,7 @@ mention (struct breakpoint *b)
 #endif
     case bp_breakpoint:
 #ifdef UI_OUT
-      if (interpreter_p && strncmp (interpreter_p, "mi", 2) == 0)
+      if (ui_out_is_mi_like_p (uiout))
        {
          say_where = 0;
          break;
@@ -4510,7 +4530,7 @@ mention (struct breakpoint *b)
       break;
     case bp_hardware_breakpoint:
 #ifdef UI_OUT
-      if (interpreter_p && strncmp (interpreter_p, "mi", 2) == 0)
+      if (ui_out_is_mi_like_p (uiout))
        {
          say_where = 0;
          break;
@@ -4566,14 +4586,12 @@ mention (struct breakpoint *b)
       if (b->source_file)
        printf_filtered (": file %s, line %d.",
                         b->source_file, b->line_number);
-      TUIDO (((TuiOpaqueFuncPtr) tui_vAllSetHasBreakAt, b, 1));
-      TUIDO (((TuiOpaqueFuncPtr) tuiUpdateAllExecInfos));
     }
 #ifdef UI_OUT
   do_cleanups (old_chain);
 #endif
 #ifdef UI_OUT
-  if (interpreter_p && strncmp (interpreter_p, "mi", 2) == 0)
+  if (ui_out_is_mi_like_p (uiout))
     return;
 #endif
   printf_filtered ("\n");
@@ -4627,7 +4645,7 @@ create_breakpoints (struct symtabs_and_lines sals, char **addr_string,
        b->addr_string = addr_string[i];
        b->cond_string = cond_string[i];
        b->ignore_count = ignore_count;
-       b->enable = enabled;
+       b->enable_state = bp_enabled;
        b->disposition = disposition;
        mention (b);
       }
@@ -4852,7 +4870,7 @@ break_command_1 (char *arg, int flag, int from_tty)
 
   create_breakpoints (sals, addr_string, cond, cond_string,
                      hardwareflag ? bp_hardware_breakpoint : bp_breakpoint,
-                     tempflag ? del : donttouch,
+                     tempflag ? disp_del : disp_donttouch,
                      thread, ignore_count, from_tty);
 
   if (sals.nelts > 1)
@@ -4964,7 +4982,7 @@ do_captured_breakpoint (void *data)
 
   create_breakpoints (sals, addr_string, cond, cond_string,
                      args->hardwareflag ? bp_hardware_breakpoint : bp_breakpoint,
-                     args->tempflag ? del : donttouch,
+                     args->tempflag ? disp_del : disp_donttouch,
                      args->thread, args->ignore_count, 0/*from-tty*/);
 
   /* That's it. Discard the cleanups for data inserted into the
@@ -5430,7 +5448,7 @@ watch_command_1 (char *arg, int accessflag, int from_tty)
   b = set_raw_breakpoint (sal, bp_type);
   set_breakpoint_count (breakpoint_count + 1);
   b->number = breakpoint_count;
-  b->disposition = donttouch;
+  b->disposition = disp_donttouch;
   b->exp = exp;
   b->exp_valid_block = exp_valid_block;
   b->exp_string = savestring (exp_start, exp_end - exp_start);
@@ -5469,10 +5487,10 @@ watch_command_1 (char *arg, int accessflag, int from_tty)
          set_breakpoint_count (breakpoint_count + 1);
          scope_breakpoint->number = breakpoint_count;
 
-         scope_breakpoint->enable = enabled;
+         scope_breakpoint->enable_state = bp_enabled;
 
          /* Automatically delete the breakpoint when it hits.  */
-         scope_breakpoint->disposition = del;
+         scope_breakpoint->disposition = disp_del;
 
          /* Only break in the proper frame (help with recursion).  */
          scope_breakpoint->frame = prev_frame->frame;
@@ -5862,15 +5880,11 @@ get_catch_sals (int this_level_only)
          if (blocks_searched[index] == 0)
            {
              struct block *b = BLOCKVECTOR_BLOCK (bl, index);
-             int nsyms;
              register int i;
              register struct symbol *sym;
 
-             nsyms = BLOCK_NSYMS (b);
-
-             for (i = 0; i < nsyms; i++)
+             ALL_BLOCK_SYMBOLS (b, i, sym)
                {
-                 sym = BLOCK_SYM (b, i);
                  if (STREQ (SYMBOL_NAME (sym), "default"))
                    {
                      if (have_default)
@@ -6223,8 +6237,8 @@ create_exception_catchpoint (int tempflag, char *cond_string,
     NULL : savestring (cond_string, strlen (cond_string));
   b->thread = thread;
   b->addr_string = NULL;
-  b->enable = enabled;
-  b->disposition = tempflag ? del : donttouch;
+  b->enable_state = bp_enabled;
+  b->disposition = tempflag ? disp_del : disp_donttouch;
   mention (b);
 }
 
@@ -6287,7 +6301,7 @@ cover_target_enable_exception_callback (PTR arg)
 {
   args_for_catchpoint_enable *args = arg;
   struct symtab_and_line *sal;
-  sal = target_enable_exception_callback (args->kind, args->enable);
+  sal = target_enable_exception_callback (args->kind, args->enable_p);
   if (sal == NULL)
     return 0;
   else if (sal == (struct symtab_and_line *) -1)
@@ -6387,8 +6401,8 @@ handle_gnu_4_16_catch_command (char *arg, int tempflag, int from_tty)
       b->number = breakpoint_count;
 
       b->cond = cond;
-      b->enable = enabled;
-      b->disposition = tempflag ? del : donttouch;
+      b->enable_state = bp_enabled;
+      b->disposition = tempflag ? disp_del : disp_donttouch;
 
       mention (b);
     }
@@ -6417,8 +6431,8 @@ create_temp_exception_breakpoint (CORE_ADDR pc)
 
   b = set_raw_breakpoint (sal, bp_breakpoint);
 
-  b->disposition = del;
-  b->enable = enabled;
+  b->disposition = disp_del;
+  b->enable_state = bp_enabled;
   b->silent = 1;
   b->number = internal_breakpoint_number--;
   return b;
@@ -6742,13 +6756,13 @@ breakpoint_auto_delete (bpstat bs)
   struct breakpoint *b, *temp;
 
   for (; bs; bs = bs->next)
-    if (bs->breakpoint_at && bs->breakpoint_at->disposition == del
+    if (bs->breakpoint_at && bs->breakpoint_at->disposition == disp_del
        && bs->stop)
       delete_breakpoint (bs->breakpoint_at);
 
   ALL_BREAKPOINTS_SAFE (b, temp)
   {
-    if (b->disposition == del_at_next_stop)
+    if (b->disposition == disp_del_at_next_stop)
       delete_breakpoint (b);
   }
 }
@@ -6808,7 +6822,7 @@ delete_breakpoint (struct breakpoint *bpt)
       sprintf (message, message1, bpt->number);
       args.kind = bpt->type == bp_catch_catch ? 
        EX_EVENT_CATCH : EX_EVENT_THROW;
-      args.enable = 0;
+      args.enable_p = 0;
       catch_errors (cover_target_enable_exception_callback, &args,
                    message, RETURN_MASK_ALL);
     }
@@ -6821,26 +6835,6 @@ delete_breakpoint (struct breakpoint *bpt)
       break;
     }
 
-  /* Before turning off the visuals for the bp, check to see that
-     there are no other bps at the same address. */
-  if (tui_version)
-    {
-      int clearIt;
-
-      ALL_BREAKPOINTS (b)
-      {
-       clearIt = (b->address != bpt->address);
-       if (!clearIt)
-         break;
-      }
-
-      if (clearIt)
-       {
-         TUIDO (((TuiOpaqueFuncPtr) tui_vAllSetHasBreakAt, bpt, 0));
-         TUIDO (((TuiOpaqueFuncPtr) tuiUpdateAllExecInfos));
-       }
-    }
-
   check_duplicates (bpt);
   /* If this breakpoint was inserted, and there is another breakpoint
      at the same address, we need to insert the other breakpoint.  */
@@ -6856,9 +6850,9 @@ delete_breakpoint (struct breakpoint *bpt)
        if (b->address == bpt->address
            && b->section == bpt->section
            && !b->duplicate
-           && b->enable != disabled
-           && b->enable != shlib_disabled
-           && b->enable != call_disabled)
+           && b->enable_state != bp_disabled
+           && b->enable_state != bp_shlib_disabled
+           && b->enable_state != bp_call_disabled)
        {
          int val;
 
@@ -6866,7 +6860,7 @@ delete_breakpoint (struct breakpoint *bpt)
             breakpoint at the same address as the one being deleted.
             If there is a permanent breakpoint somewhere, it should
             always be the only one inserted.  */
-         if (b->enable == permanent)
+         if (b->enable_state == bp_permanent)
            internal_error (__FILE__, __LINE__,
                            "another breakpoint was inserted on top of "
                            "a permanent breakpoint");
@@ -7002,7 +6996,7 @@ breakpoint_re_set_one (PTR bint)
   int i;
   struct symtabs_and_lines sals;
   char *s;
-  enum enable save_enable;
+  enum enable_state save_enable;
 
   switch (b->type)
     {
@@ -7020,10 +7014,32 @@ breakpoint_re_set_one (PTR bint)
          delete_breakpoint (b);
          return 0;
        }
-      /* In case we have a problem, disable this breakpoint.  We'll restore
-         its status if we succeed.  */
-      save_enable = b->enable;
-      b->enable = disabled;
+      /* HACK: cagney/2001-11-11: kettenis/2001-11-11: MarkK wrote:
+
+        ``And a hack it is, although Apple's Darwin version of GDB
+        contains an almost identical hack to implement a "future
+        break" command.  It seems to work in many real world cases,
+        but it is easy to come up with a test case where the patch
+        doesn't help at all.''
+
+        ``It seems that the way GDB implements breakpoints - in -
+        shared - libraries was designed for a.out shared library
+        systems (SunOS 4) where shared libraries were loaded at a
+        fixed address in memory.  Since ELF shared libraries can (and
+        will) be loaded at any address in memory, things break.
+        Fixing this is not trivial.  Therefore, I'm not sure whether
+        we should add this hack to the branch only.  I cannot
+        guarantee that things will be fixed on the trunk in the near
+        future.''
+
+         In case we have a problem, disable this breakpoint.  We'll
+         restore its status if we succeed.  Don't disable a
+         shlib_disabled breakpoint though.  There's a fair chance we
+         can't re-set it if the shared library it's in hasn't been
+         loaded yet.  */
+      save_enable = b->enable_state;
+      if (b->enable_state != bp_shlib_disabled)
+        b->enable_state = bp_disabled;
 
       set_language (b->language);
       input_radix = b->input_radix;
@@ -7079,7 +7095,7 @@ breakpoint_re_set_one (PTR bint)
              breakpoints_changed ();
            }
          b->section = sals.sals[i].section;
-         b->enable = save_enable;      /* Restore it, this worked. */
+         b->enable_state = save_enable;        /* Restore it, this worked. */
 
 
          /* Now that this is re-enabled, check_duplicates
@@ -7123,7 +7139,7 @@ breakpoint_re_set_one (PTR bint)
            xfree (b->cond);
          b->cond = parse_exp_1 (&s, (struct block *) 0, 0);
        }
-      if (b->enable == enabled)
+      if (b->enable_state == bp_enabled)
        mention (b);
       value_free_to_mark (mark);
       break;
@@ -7344,10 +7360,10 @@ disable_breakpoint (struct breakpoint *bpt)
     return;
 
   /* You can't disable permanent breakpoints.  */
-  if (bpt->enable == permanent)
+  if (bpt->enable_state == bp_permanent)
     return;
 
-  bpt->enable = disabled;
+  bpt->enable_state = bp_disabled;
 
   check_duplicates (bpt);
 
@@ -7411,8 +7427,8 @@ do_enable_breakpoint (struct breakpoint *bpt, enum bpdisp disposition)
        error ("Hardware breakpoints used exceeds limit.");
     }
 
-  if (bpt->enable != permanent)
-    bpt->enable = enabled;
+  if (bpt->enable_state != bp_permanent)
+    bpt->enable_state = bp_enabled;
   bpt->disposition = disposition;
   check_duplicates (bpt);
   breakpoints_changed ();
@@ -7436,7 +7452,7 @@ do_enable_breakpoint (struct breakpoint *bpt, enum bpdisp disposition)
              printf_filtered ("\
 Cannot enable watchpoint %d because the block in which its expression\n\
 is valid is not currently in scope.\n", bpt->number);
-             bpt->enable = disabled;
+             bpt->enable_state = bp_disabled;
              return;
            }
 
@@ -7470,7 +7486,7 @@ is valid is not currently in scope.\n", bpt->number);
              printf_filtered ("\
 Cannot enable watchpoint %d because target watch resources\n\
 have been allocated for other watchpoints.\n", bpt->number);
-             bpt->enable = disabled;
+             bpt->enable_state = bp_disabled;
              value_free_to_mark (mark);
              return;
            }
@@ -7532,7 +7548,7 @@ enable_command (char *args, int from_tty)
 static void
 enable_once_breakpoint (struct breakpoint *bpt)
 {
-  do_enable_breakpoint (bpt, disable);
+  do_enable_breakpoint (bpt, disp_disable);
 }
 
 /* ARGSUSED */
@@ -7545,7 +7561,7 @@ enable_once_command (char *args, int from_tty)
 static void
 enable_delete_breakpoint (struct breakpoint *bpt)
 {
-  do_enable_breakpoint (bpt, del);
+  do_enable_breakpoint (bpt, disp_del);
 }
 
 /* ARGSUSED */