Automatic date update in version.in
[external/binutils.git] / gdb / guile / scm-breakpoint.c
1 /* Scheme interface to breakpoints.
2
3    Copyright (C) 2008-2019 Free Software Foundation, Inc.
4
5    This file is part of GDB.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20 /* See README file in this directory for implementation notes, coding
21    conventions, et.al.  */
22
23 #include "defs.h"
24 #include "value.h"
25 #include "breakpoint.h"
26 #include "gdbcmd.h"
27 #include "gdbthread.h"
28 #include "observable.h"
29 #include "cli/cli-script.h"
30 #include "ada-lang.h"
31 #include "arch-utils.h"
32 #include "language.h"
33 #include "guile-internal.h"
34 #include "location.h"
35
36 /* The <gdb:breakpoint> smob.
37    N.B.: The name of this struct is known to breakpoint.h.
38
39    Note: Breakpoints are added to gdb using a two step process:
40    1) Call make-breakpoint to create a <gdb:breakpoint> object.
41    2) Call register-breakpoint! to add the breakpoint to gdb.
42    It is done this way so that the constructor, make-breakpoint, doesn't have
43    any side-effects.  This means that the smob needs to store everything
44    that was passed to make-breakpoint.  */
45
46 typedef struct gdbscm_breakpoint_object
47 {
48   /* This always appears first.  */
49   gdb_smob base;
50
51   /* Non-zero if this breakpoint was created with make-breakpoint.  */
52   int is_scheme_bkpt;
53
54   /* For breakpoints created with make-breakpoint, these are the parameters
55      that were passed to make-breakpoint.  These values are not used except
56      to register the breakpoint with GDB.  */
57   struct
58   {
59     /* The string representation of the breakpoint.
60        Space for this lives in GC space.  */
61     char *location;
62
63     /* The kind of breakpoint.
64        At the moment this can only be one of bp_breakpoint, bp_watchpoint.  */
65     enum bptype type;
66
67     /* If a watchpoint, the kind of watchpoint.  */
68     enum target_hw_bp_type access_type;
69
70     /* Non-zero if the breakpoint is an "internal" breakpoint.  */
71     int is_internal;
72   } spec;
73
74   /* The breakpoint number according to gdb.
75      For breakpoints created from Scheme, this has the value -1 until the
76      breakpoint is registered with gdb.
77      This is recorded here because BP will be NULL when deleted.  */
78   int number;
79
80   /* The gdb breakpoint object, or NULL if the breakpoint has not been
81      registered yet, or has been deleted.  */
82   struct breakpoint *bp;
83
84   /* Backlink to our containing <gdb:breakpoint> smob.
85      This is needed when we are deleted, we need to unprotect the object
86      from GC.  */
87   SCM containing_scm;
88
89   /* A stop condition or #f.  */
90   SCM stop;
91 } breakpoint_smob;
92
93 static const char breakpoint_smob_name[] = "gdb:breakpoint";
94
95 /* The tag Guile knows the breakpoint smob by.  */
96 static scm_t_bits breakpoint_smob_tag;
97
98 /* Variables used to pass information between the breakpoint_smob
99    constructor and the breakpoint-created hook function.  */
100 static SCM pending_breakpoint_scm = SCM_BOOL_F;
101
102 /* Keywords used by create-breakpoint!.  */
103 static SCM type_keyword;
104 static SCM wp_class_keyword;
105 static SCM internal_keyword;
106 \f
107 /* Administrivia for breakpoint smobs.  */
108
109 /* The smob "free" function for <gdb:breakpoint>.  */
110
111 static size_t
112 bpscm_free_breakpoint_smob (SCM self)
113 {
114   breakpoint_smob *bp_smob = (breakpoint_smob *) SCM_SMOB_DATA (self);
115
116   if (bp_smob->bp)
117     bp_smob->bp->scm_bp_object = NULL;
118
119   /* Not necessary, done to catch bugs.  */
120   bp_smob->bp = NULL;
121   bp_smob->containing_scm = SCM_UNDEFINED;
122   bp_smob->stop = SCM_UNDEFINED;
123
124   return 0;
125 }
126
127 /* Return the name of TYPE.
128    This doesn't handle all types, just the ones we export.  */
129
130 static const char *
131 bpscm_type_to_string (enum bptype type)
132 {
133   switch (type)
134     {
135     case bp_none: return "BP_NONE";
136     case bp_breakpoint: return "BP_BREAKPOINT";
137     case bp_watchpoint: return "BP_WATCHPOINT";
138     case bp_hardware_watchpoint: return "BP_HARDWARE_WATCHPOINT";
139     case bp_read_watchpoint: return "BP_READ_WATCHPOINT";
140     case bp_access_watchpoint: return "BP_ACCESS_WATCHPOINT";
141     default: return "internal/other";
142     }
143 }
144
145 /* Return the name of ENABLE_STATE.  */
146
147 static const char *
148 bpscm_enable_state_to_string (enum enable_state enable_state)
149 {
150   switch (enable_state)
151     {
152     case bp_disabled: return "disabled";
153     case bp_enabled: return "enabled";
154     case bp_call_disabled: return "call_disabled";
155     default: return "unknown";
156     }
157 }
158
159 /* The smob "print" function for <gdb:breakpoint>.  */
160
161 static int
162 bpscm_print_breakpoint_smob (SCM self, SCM port, scm_print_state *pstate)
163 {
164   breakpoint_smob *bp_smob = (breakpoint_smob *) SCM_SMOB_DATA (self);
165   struct breakpoint *b = bp_smob->bp;
166
167   gdbscm_printf (port, "#<%s", breakpoint_smob_name);
168
169   /* Only print what we export to the user.
170      The rest are possibly internal implementation details.  */
171
172   gdbscm_printf (port, " #%d", bp_smob->number);
173
174   /* Careful, the breakpoint may be invalid.  */
175   if (b != NULL)
176     {
177       const char *str;
178
179       gdbscm_printf (port, " %s %s %s",
180                      bpscm_type_to_string (b->type),
181                      bpscm_enable_state_to_string (b->enable_state),
182                      b->silent ? "silent" : "noisy");
183
184       gdbscm_printf (port, " hit:%d", b->hit_count);
185       gdbscm_printf (port, " ignore:%d", b->ignore_count);
186
187       str = event_location_to_string (b->location.get ());
188       if (str != NULL)
189         gdbscm_printf (port, " @%s", str);
190     }
191
192   scm_puts (">", port);
193
194   scm_remember_upto_here_1 (self);
195
196   /* Non-zero means success.  */
197   return 1;
198 }
199
200 /* Low level routine to create a <gdb:breakpoint> object.  */
201
202 static SCM
203 bpscm_make_breakpoint_smob (void)
204 {
205   breakpoint_smob *bp_smob = (breakpoint_smob *)
206     scm_gc_malloc (sizeof (breakpoint_smob), breakpoint_smob_name);
207   SCM bp_scm;
208
209   memset (bp_smob, 0, sizeof (*bp_smob));
210   bp_smob->number = -1;
211   bp_smob->stop = SCM_BOOL_F;
212   bp_scm = scm_new_smob (breakpoint_smob_tag, (scm_t_bits) bp_smob);
213   bp_smob->containing_scm = bp_scm;
214   gdbscm_init_gsmob (&bp_smob->base);
215
216   return bp_scm;
217 }
218
219 /* Return non-zero if we want a Scheme wrapper for breakpoint B.
220    If FROM_SCHEME is non-zero,this is called for a breakpoint created
221    by the user from Scheme.  Otherwise it is zero.  */
222
223 static int
224 bpscm_want_scm_wrapper_p (struct breakpoint *bp, int from_scheme)
225 {
226   /* Don't create <gdb:breakpoint> objects for internal GDB breakpoints.  */
227   if (bp->number < 0 && !from_scheme)
228     return 0;
229
230   /* The others are not supported.  */
231   if (bp->type != bp_breakpoint
232       && bp->type != bp_watchpoint
233       && bp->type != bp_hardware_watchpoint
234       && bp->type != bp_read_watchpoint
235       && bp->type != bp_access_watchpoint)
236     return 0;
237
238   return 1;
239 }
240
241 /* Install the Scheme side of a breakpoint, CONTAINING_SCM, in
242    the gdb side BP.  */
243
244 static void
245 bpscm_attach_scm_to_breakpoint (struct breakpoint *bp, SCM containing_scm)
246 {
247   breakpoint_smob *bp_smob;
248
249   bp_smob = (breakpoint_smob *) SCM_SMOB_DATA (containing_scm);
250   bp_smob->number = bp->number;
251   bp_smob->bp = bp;
252   bp_smob->containing_scm = containing_scm;
253   bp_smob->bp->scm_bp_object = bp_smob;
254
255   /* The owner of this breakpoint is not in GC-controlled memory, so we need
256      to protect it from GC until the breakpoint is deleted.  */
257   scm_gc_protect_object (containing_scm);
258 }
259
260 /* Return non-zero if SCM is a breakpoint smob.  */
261
262 static int
263 bpscm_is_breakpoint (SCM scm)
264 {
265   return SCM_SMOB_PREDICATE (breakpoint_smob_tag, scm);
266 }
267
268 /* (breakpoint? scm) -> boolean */
269
270 static SCM
271 gdbscm_breakpoint_p (SCM scm)
272 {
273   return scm_from_bool (bpscm_is_breakpoint (scm));
274 }
275
276 /* Returns the <gdb:breakpoint> object in SELF.
277    Throws an exception if SELF is not a <gdb:breakpoint> object.  */
278
279 static SCM
280 bpscm_get_breakpoint_arg_unsafe (SCM self, int arg_pos, const char *func_name)
281 {
282   SCM_ASSERT_TYPE (bpscm_is_breakpoint (self), self, arg_pos, func_name,
283                    breakpoint_smob_name);
284
285   return self;
286 }
287
288 /* Returns a pointer to the breakpoint smob of SELF.
289    Throws an exception if SELF is not a <gdb:breakpoint> object.  */
290
291 static breakpoint_smob *
292 bpscm_get_breakpoint_smob_arg_unsafe (SCM self, int arg_pos,
293                                       const char *func_name)
294 {
295   SCM bp_scm = bpscm_get_breakpoint_arg_unsafe (self, arg_pos, func_name);
296   breakpoint_smob *bp_smob = (breakpoint_smob *) SCM_SMOB_DATA (bp_scm);
297
298   return bp_smob;
299 }
300
301 /* Return non-zero if breakpoint BP_SMOB is valid.  */
302
303 static int
304 bpscm_is_valid (breakpoint_smob *bp_smob)
305 {
306   return bp_smob->bp != NULL;
307 }
308
309 /* Returns the breakpoint smob in SELF, verifying it's valid.
310    Throws an exception if SELF is not a <gdb:breakpoint> object,
311    or is invalid.  */
312
313 static breakpoint_smob *
314 bpscm_get_valid_breakpoint_smob_arg_unsafe (SCM self, int arg_pos,
315                                             const char *func_name)
316 {
317   breakpoint_smob *bp_smob
318     = bpscm_get_breakpoint_smob_arg_unsafe (self, arg_pos, func_name);
319
320   if (!bpscm_is_valid (bp_smob))
321     {
322       gdbscm_invalid_object_error (func_name, arg_pos, self,
323                                    _("<gdb:breakpoint>"));
324     }
325
326   return bp_smob;
327 }
328 \f
329 /* Breakpoint methods.  */
330
331 /* (make-breakpoint string [#:type integer] [#:wp-class integer]
332     [#:internal boolean) -> <gdb:breakpoint>
333
334    The result is the <gdb:breakpoint> Scheme object.
335    The breakpoint is not available to be used yet, however.
336    It must still be added to gdb with register-breakpoint!.  */
337
338 static SCM
339 gdbscm_make_breakpoint (SCM location_scm, SCM rest)
340 {
341   const SCM keywords[] = {
342     type_keyword, wp_class_keyword, internal_keyword, SCM_BOOL_F
343   };
344   char *s;
345   char *location;
346   int type_arg_pos = -1, access_type_arg_pos = -1, internal_arg_pos = -1;
347   enum bptype type = bp_breakpoint;
348   enum target_hw_bp_type access_type = hw_write;
349   int internal = 0;
350   SCM result;
351   breakpoint_smob *bp_smob;
352
353   gdbscm_parse_function_args (FUNC_NAME, SCM_ARG1, keywords, "s#iit",
354                               location_scm, &location, rest,
355                               &type_arg_pos, &type,
356                               &access_type_arg_pos, &access_type,
357                               &internal_arg_pos, &internal);
358
359   result = bpscm_make_breakpoint_smob ();
360   bp_smob = (breakpoint_smob *) SCM_SMOB_DATA (result);
361
362   s = location;
363   location = gdbscm_gc_xstrdup (s);
364   xfree (s);
365
366   switch (type)
367     {
368     case bp_breakpoint:
369       if (access_type_arg_pos > 0)
370         {
371           gdbscm_misc_error (FUNC_NAME, access_type_arg_pos,
372                              scm_from_int (access_type),
373                              _("access type with breakpoint is not allowed"));
374         }
375       break;
376     case bp_watchpoint:
377       switch (access_type)
378         {
379         case hw_write:
380         case hw_access:
381         case hw_read:
382           break;
383         default:
384           gdbscm_out_of_range_error (FUNC_NAME, access_type_arg_pos,
385                                      scm_from_int (access_type),
386                                      _("invalid watchpoint class"));
387         }
388       break;
389     default:
390       gdbscm_out_of_range_error (FUNC_NAME, access_type_arg_pos,
391                                  scm_from_int (type),
392                                  _("invalid breakpoint type"));
393     }
394
395   bp_smob->is_scheme_bkpt = 1;
396   bp_smob->spec.location = location;
397   bp_smob->spec.type = type;
398   bp_smob->spec.access_type = access_type;
399   bp_smob->spec.is_internal = internal;
400
401   return result;
402 }
403
404 /* (register-breakpoint! <gdb:breakpoint>) -> unspecified
405
406    It is an error to register a breakpoint created outside of Guile,
407    or an already-registered breakpoint.  */
408
409 static SCM
410 gdbscm_register_breakpoint_x (SCM self)
411 {
412   breakpoint_smob *bp_smob
413     = bpscm_get_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
414   struct gdb_exception except = exception_none;
415   const char *location, *copy;
416
417   /* We only support registering breakpoints created with make-breakpoint.  */
418   if (!bp_smob->is_scheme_bkpt)
419     scm_misc_error (FUNC_NAME, _("not a Scheme breakpoint"), SCM_EOL);
420
421   if (bpscm_is_valid (bp_smob))
422     scm_misc_error (FUNC_NAME, _("breakpoint is already registered"), SCM_EOL);
423
424   pending_breakpoint_scm = self;
425   location = bp_smob->spec.location;
426   copy = skip_spaces (location);
427   event_location_up eloc
428     = string_to_event_location_basic (&copy,
429                                       current_language,
430                                       symbol_name_match_type::WILD);
431
432   TRY
433     {
434       int internal = bp_smob->spec.is_internal;
435
436       switch (bp_smob->spec.type)
437         {
438         case bp_breakpoint:
439           {
440             create_breakpoint (get_current_arch (),
441                                eloc.get (), NULL, -1, NULL,
442                                0,
443                                0, bp_breakpoint,
444                                0,
445                                AUTO_BOOLEAN_TRUE,
446                                &bkpt_breakpoint_ops,
447                                0, 1, internal, 0);
448             break;
449           }
450         case bp_watchpoint:
451           {
452             enum target_hw_bp_type access_type = bp_smob->spec.access_type;
453
454             if (access_type == hw_write)
455               watch_command_wrapper (location, 0, internal);
456             else if (access_type == hw_access)
457               awatch_command_wrapper (location, 0, internal);
458             else if (access_type == hw_read)
459               rwatch_command_wrapper (location, 0, internal);
460             else
461               gdb_assert_not_reached ("invalid access type");
462             break;
463           }
464         default:
465           gdb_assert_not_reached ("invalid breakpoint type");
466         }
467     }
468   CATCH (ex, RETURN_MASK_ALL)
469     {
470       except = ex;
471     }
472   END_CATCH
473
474   /* Ensure this gets reset, even if there's an error.  */
475   pending_breakpoint_scm = SCM_BOOL_F;
476   GDBSCM_HANDLE_GDB_EXCEPTION (except);
477
478   return SCM_UNSPECIFIED;
479 }
480
481 /* (delete-breakpoint! <gdb:breakpoint>) -> unspecified
482    Scheme function which deletes (removes) the underlying GDB breakpoint
483    from GDB's list of breakpoints.  This triggers the breakpoint_deleted
484    observer which will call gdbscm_breakpoint_deleted; that function cleans
485    up the Scheme bits.  */
486
487 static SCM
488 gdbscm_delete_breakpoint_x (SCM self)
489 {
490   breakpoint_smob *bp_smob
491     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
492
493   TRY
494     {
495       delete_breakpoint (bp_smob->bp);
496     }
497   CATCH (except, RETURN_MASK_ALL)
498     {
499       GDBSCM_HANDLE_GDB_EXCEPTION (except);
500     }
501   END_CATCH
502
503   return SCM_UNSPECIFIED;
504 }
505
506 /* iterate_over_breakpoints function for gdbscm_breakpoints.  */
507
508 static int
509 bpscm_build_bp_list (struct breakpoint *bp, void *arg)
510 {
511   SCM *list = (SCM *) arg;
512   breakpoint_smob *bp_smob = bp->scm_bp_object;
513
514   /* Lazily create wrappers for breakpoints created outside Scheme.  */
515
516   if (bp_smob == NULL)
517     {
518       if (bpscm_want_scm_wrapper_p (bp, 0))
519         {
520           SCM bp_scm;
521
522           bp_scm = bpscm_make_breakpoint_smob ();
523           bpscm_attach_scm_to_breakpoint (bp, bp_scm);
524           /* Refetch it.  */
525           bp_smob = bp->scm_bp_object;
526         }
527     }
528
529   /* Not all breakpoints will have a companion Scheme object.
530      Only breakpoints that trigger the created_breakpoint observer call,
531      and satisfy certain conditions (see bpscm_want_scm_wrapper_p),
532      get a companion object (this includes Scheme-created breakpoints).  */
533
534   if (bp_smob != NULL)
535     *list = scm_cons (bp_smob->containing_scm, *list);
536
537   return 0;
538 }
539
540 /* (breakpoints) -> list
541    Return a list of all breakpoints.  */
542
543 static SCM
544 gdbscm_breakpoints (void)
545 {
546   SCM list = SCM_EOL;
547
548   /* If iterate_over_breakpoints returns non-NULL it means the iteration
549      terminated early.
550      In that case abandon building the list and return #f.  */
551   if (iterate_over_breakpoints (bpscm_build_bp_list, &list) != NULL)
552     return SCM_BOOL_F;
553
554   return scm_reverse_x (list, SCM_EOL);
555 }
556
557 /* (breakpoint-valid? <gdb:breakpoint>) -> boolean
558    Returns #t if SELF is still valid.  */
559
560 static SCM
561 gdbscm_breakpoint_valid_p (SCM self)
562 {
563   breakpoint_smob *bp_smob
564     = bpscm_get_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
565
566   return scm_from_bool (bpscm_is_valid (bp_smob));
567 }
568
569 /* (breakpoint-enabled? <gdb:breakpoint>) -> boolean */
570
571 static SCM
572 gdbscm_breakpoint_enabled_p (SCM self)
573 {
574   breakpoint_smob *bp_smob
575     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
576
577   return scm_from_bool (bp_smob->bp->enable_state == bp_enabled);
578 }
579
580 /* (set-breakpoint-enabled? <gdb:breakpoint> boolean) -> unspecified */
581
582 static SCM
583 gdbscm_set_breakpoint_enabled_x (SCM self, SCM newvalue)
584 {
585   breakpoint_smob *bp_smob
586     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
587
588   SCM_ASSERT_TYPE (gdbscm_is_bool (newvalue), newvalue, SCM_ARG2, FUNC_NAME,
589                    _("boolean"));
590
591   TRY
592     {
593       if (gdbscm_is_true (newvalue))
594         enable_breakpoint (bp_smob->bp);
595       else
596         disable_breakpoint (bp_smob->bp);
597     }
598   CATCH (except, RETURN_MASK_ALL)
599     {
600       GDBSCM_HANDLE_GDB_EXCEPTION (except);
601     }
602   END_CATCH
603
604   return SCM_UNSPECIFIED;
605 }
606
607 /* (breakpoint-silent? <gdb:breakpoint>) -> boolean */
608
609 static SCM
610 gdbscm_breakpoint_silent_p (SCM self)
611 {
612   breakpoint_smob *bp_smob
613     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
614
615   return scm_from_bool (bp_smob->bp->silent);
616 }
617
618 /* (set-breakpoint-silent?! <gdb:breakpoint> boolean) -> unspecified */
619
620 static SCM
621 gdbscm_set_breakpoint_silent_x (SCM self, SCM newvalue)
622 {
623   breakpoint_smob *bp_smob
624     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
625
626   SCM_ASSERT_TYPE (gdbscm_is_bool (newvalue), newvalue, SCM_ARG2, FUNC_NAME,
627                    _("boolean"));
628
629   TRY
630     {
631       breakpoint_set_silent (bp_smob->bp, gdbscm_is_true (newvalue));
632     }
633   CATCH (except, RETURN_MASK_ALL)
634     {
635       GDBSCM_HANDLE_GDB_EXCEPTION (except);
636     }
637   END_CATCH
638
639   return SCM_UNSPECIFIED;
640 }
641
642 /* (breakpoint-ignore-count <gdb:breakpoint>) -> integer */
643
644 static SCM
645 gdbscm_breakpoint_ignore_count (SCM self)
646 {
647   breakpoint_smob *bp_smob
648     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
649
650   return scm_from_long (bp_smob->bp->ignore_count);
651 }
652
653 /* (set-breakpoint-ignore-count! <gdb:breakpoint> integer)
654      -> unspecified */
655
656 static SCM
657 gdbscm_set_breakpoint_ignore_count_x (SCM self, SCM newvalue)
658 {
659   breakpoint_smob *bp_smob
660     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
661   long value;
662
663   SCM_ASSERT_TYPE (scm_is_signed_integer (newvalue, LONG_MIN, LONG_MAX),
664                    newvalue, SCM_ARG2, FUNC_NAME, _("integer"));
665
666   value = scm_to_long (newvalue);
667   if (value < 0)
668     value = 0;
669
670   TRY
671     {
672       set_ignore_count (bp_smob->number, (int) value, 0);
673     }
674   CATCH (except, RETURN_MASK_ALL)
675     {
676       GDBSCM_HANDLE_GDB_EXCEPTION (except);
677     }
678   END_CATCH
679
680   return SCM_UNSPECIFIED;
681 }
682
683 /* (breakpoint-hit-count <gdb:breakpoint>) -> integer */
684
685 static SCM
686 gdbscm_breakpoint_hit_count (SCM self)
687 {
688   breakpoint_smob *bp_smob
689     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
690
691   return scm_from_long (bp_smob->bp->hit_count);
692 }
693
694 /* (set-breakpoint-hit-count! <gdb:breakpoint> integer) -> unspecified */
695
696 static SCM
697 gdbscm_set_breakpoint_hit_count_x (SCM self, SCM newvalue)
698 {
699   breakpoint_smob *bp_smob
700     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
701   long value;
702
703   SCM_ASSERT_TYPE (scm_is_signed_integer (newvalue, LONG_MIN, LONG_MAX),
704                    newvalue, SCM_ARG2, FUNC_NAME, _("integer"));
705
706   value = scm_to_long (newvalue);
707   if (value < 0)
708     value = 0;
709
710   if (value != 0)
711     {
712       gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG2, newvalue,
713                                  _("hit-count must be zero"));
714     }
715
716   bp_smob->bp->hit_count = 0;
717
718   return SCM_UNSPECIFIED;
719 }
720
721 /* (breakpoint-thread <gdb:breakpoint>) -> integer */
722
723 static SCM
724 gdbscm_breakpoint_thread (SCM self)
725 {
726   breakpoint_smob *bp_smob
727     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
728
729   if (bp_smob->bp->thread == -1)
730     return SCM_BOOL_F;
731
732   return scm_from_long (bp_smob->bp->thread);
733 }
734
735 /* (set-breakpoint-thread! <gdb:breakpoint> integer) -> unspecified */
736
737 static SCM
738 gdbscm_set_breakpoint_thread_x (SCM self, SCM newvalue)
739 {
740   breakpoint_smob *bp_smob
741     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
742   long id;
743
744   if (scm_is_signed_integer (newvalue, LONG_MIN, LONG_MAX))
745     {
746       id = scm_to_long (newvalue);
747       if (!valid_global_thread_id (id))
748         {
749           gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG2, newvalue,
750                                      _("invalid thread id"));
751         }
752     }
753   else if (gdbscm_is_false (newvalue))
754     id = -1;
755   else
756     SCM_ASSERT_TYPE (0, newvalue, SCM_ARG2, FUNC_NAME, _("integer or #f"));
757
758   breakpoint_set_thread (bp_smob->bp, id);
759
760   return SCM_UNSPECIFIED;
761 }
762
763 /* (breakpoint-task <gdb:breakpoint>) -> integer */
764
765 static SCM
766 gdbscm_breakpoint_task (SCM self)
767 {
768   breakpoint_smob *bp_smob
769     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
770
771   if (bp_smob->bp->task == 0)
772     return SCM_BOOL_F;
773
774   return scm_from_long (bp_smob->bp->task);
775 }
776
777 /* (set-breakpoint-task! <gdb:breakpoint> integer) -> unspecified */
778
779 static SCM
780 gdbscm_set_breakpoint_task_x (SCM self, SCM newvalue)
781 {
782   breakpoint_smob *bp_smob
783     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
784   long id;
785   int valid_id = 0;
786
787   if (scm_is_signed_integer (newvalue, LONG_MIN, LONG_MAX))
788     {
789       id = scm_to_long (newvalue);
790
791       TRY
792         {
793           valid_id = valid_task_id (id);
794         }
795       CATCH (except, RETURN_MASK_ALL)
796         {
797           GDBSCM_HANDLE_GDB_EXCEPTION (except);
798         }
799       END_CATCH
800
801       if (! valid_id)
802         {
803           gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG2, newvalue,
804                                      _("invalid task id"));
805         }
806     }
807   else if (gdbscm_is_false (newvalue))
808     id = 0;
809   else
810     SCM_ASSERT_TYPE (0, newvalue, SCM_ARG2, FUNC_NAME, _("integer or #f"));
811
812   TRY
813     {
814       breakpoint_set_task (bp_smob->bp, id);
815     }
816   CATCH (except, RETURN_MASK_ALL)
817     {
818       GDBSCM_HANDLE_GDB_EXCEPTION (except);
819     }
820   END_CATCH
821
822   return SCM_UNSPECIFIED;
823 }
824
825 /* (breakpoint-location <gdb:breakpoint>) -> string */
826
827 static SCM
828 gdbscm_breakpoint_location (SCM self)
829 {
830   breakpoint_smob *bp_smob
831     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
832   const char *str;
833
834   if (bp_smob->bp->type != bp_breakpoint)
835     return SCM_BOOL_F;
836
837   str = event_location_to_string (bp_smob->bp->location.get ());
838   if (! str)
839     str = "";
840
841   return gdbscm_scm_from_c_string (str);
842 }
843
844 /* (breakpoint-expression <gdb:breakpoint>) -> string
845    This is only valid for watchpoints.
846    Returns #f for non-watchpoints.  */
847
848 static SCM
849 gdbscm_breakpoint_expression (SCM self)
850 {
851   breakpoint_smob *bp_smob
852     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
853   struct watchpoint *wp;
854
855   if (!is_watchpoint (bp_smob->bp))
856     return SCM_BOOL_F;
857
858   wp = (struct watchpoint *) bp_smob->bp;
859
860   const char *str = wp->exp_string;
861   if (! str)
862     str = "";
863
864   return gdbscm_scm_from_c_string (str);
865 }
866
867 /* (breakpoint-condition <gdb:breakpoint>) -> string */
868
869 static SCM
870 gdbscm_breakpoint_condition (SCM self)
871 {
872   breakpoint_smob *bp_smob
873     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
874   char *str;
875
876   str = bp_smob->bp->cond_string;
877   if (! str)
878     return SCM_BOOL_F;
879
880   return gdbscm_scm_from_c_string (str);
881 }
882
883 /* (set-breakpoint-condition! <gdb:breakpoint> string|#f)
884    -> unspecified */
885
886 static SCM
887 gdbscm_set_breakpoint_condition_x (SCM self, SCM newvalue)
888 {
889   breakpoint_smob *bp_smob
890     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
891
892   SCM_ASSERT_TYPE (scm_is_string (newvalue) || gdbscm_is_false (newvalue),
893                    newvalue, SCM_ARG2, FUNC_NAME,
894                    _("string or #f"));
895
896   return gdbscm_wrap ([=]
897     {
898       gdb::unique_xmalloc_ptr<char> exp
899         = (gdbscm_is_false (newvalue)
900            ? nullptr
901            : gdbscm_scm_to_c_string (newvalue));
902
903       set_breakpoint_condition (bp_smob->bp, exp ? exp.get () : "", 0);
904
905       return SCM_UNSPECIFIED;
906     });
907 }
908
909 /* (breakpoint-stop <gdb:breakpoint>) -> procedure or #f */
910
911 static SCM
912 gdbscm_breakpoint_stop (SCM self)
913 {
914   breakpoint_smob *bp_smob
915     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
916
917   return bp_smob->stop;
918 }
919
920 /* (set-breakpoint-stop! <gdb:breakpoint> procedure|#f)
921    -> unspecified */
922
923 static SCM
924 gdbscm_set_breakpoint_stop_x (SCM self, SCM newvalue)
925 {
926   breakpoint_smob *bp_smob
927     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
928   const struct extension_language_defn *extlang = NULL;
929
930   SCM_ASSERT_TYPE (gdbscm_is_procedure (newvalue)
931                    || gdbscm_is_false (newvalue),
932                    newvalue, SCM_ARG2, FUNC_NAME,
933                    _("procedure or #f"));
934
935   if (bp_smob->bp->cond_string != NULL)
936     extlang = get_ext_lang_defn (EXT_LANG_GDB);
937   if (extlang == NULL)
938     extlang = get_breakpoint_cond_ext_lang (bp_smob->bp, EXT_LANG_GUILE);
939   if (extlang != NULL)
940     {
941       char *error_text
942         = xstrprintf (_("Only one stop condition allowed.  There is"
943                         " currently a %s stop condition defined for"
944                         " this breakpoint."),
945                       ext_lang_capitalized_name (extlang));
946
947       scm_dynwind_begin ((scm_t_dynwind_flags) 0);
948       gdbscm_dynwind_xfree (error_text);
949       gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG1, self, error_text);
950       /* The following line, while unnecessary, is present for completeness
951          sake.  */
952       scm_dynwind_end ();
953     }
954
955   bp_smob->stop = newvalue;
956
957   return SCM_UNSPECIFIED;
958 }
959
960 /* (breakpoint-commands <gdb:breakpoint>) -> string */
961
962 static SCM
963 gdbscm_breakpoint_commands (SCM self)
964 {
965   breakpoint_smob *bp_smob
966     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
967   struct breakpoint *bp;
968   SCM result;
969
970   bp = bp_smob->bp;
971
972   if (bp->commands == NULL)
973     return SCM_BOOL_F;
974
975   string_file buf;
976
977   current_uiout->redirect (&buf);
978   TRY
979     {
980       print_command_lines (current_uiout, breakpoint_commands (bp), 0);
981     }
982   CATCH (except, RETURN_MASK_ALL)
983     {
984       current_uiout->redirect (NULL);
985       gdbscm_throw_gdb_exception (except);
986     }
987   END_CATCH
988
989   current_uiout->redirect (NULL);
990   result = gdbscm_scm_from_c_string (buf.c_str ());
991
992   return result;
993 }
994
995 /* (breakpoint-type <gdb:breakpoint>) -> integer */
996
997 static SCM
998 gdbscm_breakpoint_type (SCM self)
999 {
1000   breakpoint_smob *bp_smob
1001     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
1002
1003   return scm_from_long (bp_smob->bp->type);
1004 }
1005
1006 /* (breakpoint-visible? <gdb:breakpoint>) -> boolean */
1007
1008 static SCM
1009 gdbscm_breakpoint_visible (SCM self)
1010 {
1011   breakpoint_smob *bp_smob
1012     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
1013
1014   return scm_from_bool (bp_smob->bp->number >= 0);
1015 }
1016
1017 /* (breakpoint-number <gdb:breakpoint>) -> integer */
1018
1019 static SCM
1020 gdbscm_breakpoint_number (SCM self)
1021 {
1022   breakpoint_smob *bp_smob
1023     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
1024
1025   return scm_from_long (bp_smob->number);
1026 }
1027 \f
1028 /* Return TRUE if "stop" has been set for this breakpoint.
1029
1030    This is the extension_language_ops.breakpoint_has_cond "method".  */
1031
1032 int
1033 gdbscm_breakpoint_has_cond (const struct extension_language_defn *extlang,
1034                             struct breakpoint *b)
1035 {
1036   breakpoint_smob *bp_smob = b->scm_bp_object;
1037
1038   if (bp_smob == NULL)
1039     return 0;
1040
1041   return gdbscm_is_procedure (bp_smob->stop);
1042 }
1043
1044 /* Call the "stop" method in the breakpoint class.
1045    This must only be called if gdbscm_breakpoint_has_cond returns true.
1046    If the stop method returns #t, the inferior will be stopped at the
1047    breakpoint.  Otherwise the inferior will be allowed to continue
1048    (assuming other conditions don't indicate "stop").
1049
1050    This is the extension_language_ops.breakpoint_cond_says_stop "method".  */
1051
1052 enum ext_lang_bp_stop
1053 gdbscm_breakpoint_cond_says_stop
1054   (const struct extension_language_defn *extlang, struct breakpoint *b)
1055 {
1056   breakpoint_smob *bp_smob = b->scm_bp_object;
1057   SCM predicate_result;
1058   int stop;
1059
1060   if (bp_smob == NULL)
1061     return EXT_LANG_BP_STOP_UNSET;
1062   if (!gdbscm_is_procedure (bp_smob->stop))
1063     return EXT_LANG_BP_STOP_UNSET;
1064
1065   stop = 1;
1066
1067   predicate_result
1068     = gdbscm_safe_call_1 (bp_smob->stop, bp_smob->containing_scm, NULL);
1069
1070   if (gdbscm_is_exception (predicate_result))
1071     ; /* Exception already printed.  */
1072   /* If the "stop" function returns #f that means
1073      the Scheme breakpoint wants GDB to continue.  */
1074   else if (gdbscm_is_false (predicate_result))
1075     stop = 0;
1076
1077   return stop ? EXT_LANG_BP_STOP_YES : EXT_LANG_BP_STOP_NO;
1078 }
1079 \f
1080 /* Event callback functions.  */
1081
1082 /* Callback that is used when a breakpoint is created.
1083    For breakpoints created by Scheme, i.e., gdbscm_create_breakpoint_x, finish
1084    object creation by connecting the Scheme wrapper to the gdb object.
1085    We ignore breakpoints created from gdb or python here, we create the
1086    Scheme wrapper for those when there's a need to, e.g.,
1087    gdbscm_breakpoints.  */
1088
1089 static void
1090 bpscm_breakpoint_created (struct breakpoint *bp)
1091 {
1092   SCM bp_scm;
1093
1094   if (gdbscm_is_false (pending_breakpoint_scm))
1095     return;
1096
1097   /* Verify our caller error checked the user's request.  */
1098   gdb_assert (bpscm_want_scm_wrapper_p (bp, 1));
1099
1100   bp_scm = pending_breakpoint_scm;
1101   pending_breakpoint_scm = SCM_BOOL_F;
1102
1103   bpscm_attach_scm_to_breakpoint (bp, bp_scm);
1104 }
1105
1106 /* Callback that is used when a breakpoint is deleted.  This will
1107    invalidate the corresponding Scheme object.  */
1108
1109 static void
1110 bpscm_breakpoint_deleted (struct breakpoint *b)
1111 {
1112   int num = b->number;
1113   struct breakpoint *bp;
1114
1115   /* TODO: Why the lookup?  We have B.  */
1116
1117   bp = get_breakpoint (num);
1118   if (bp)
1119     {
1120       breakpoint_smob *bp_smob = bp->scm_bp_object;
1121
1122       if (bp_smob)
1123         {
1124           bp_smob->bp = NULL;
1125           bp_smob->number = -1;
1126           bp_smob->stop = SCM_BOOL_F;
1127           scm_gc_unprotect_object (bp_smob->containing_scm);
1128         }
1129     }
1130 }
1131 \f
1132 /* Initialize the Scheme breakpoint code.  */
1133
1134 static const scheme_integer_constant breakpoint_integer_constants[] =
1135 {
1136   { "BP_NONE", bp_none },
1137   { "BP_BREAKPOINT", bp_breakpoint },
1138   { "BP_WATCHPOINT", bp_watchpoint },
1139   { "BP_HARDWARE_WATCHPOINT", bp_hardware_watchpoint },
1140   { "BP_READ_WATCHPOINT", bp_read_watchpoint },
1141   { "BP_ACCESS_WATCHPOINT", bp_access_watchpoint },
1142
1143   { "WP_READ", hw_read },
1144   { "WP_WRITE", hw_write },
1145   { "WP_ACCESS", hw_access },
1146
1147   END_INTEGER_CONSTANTS
1148 };
1149
1150 static const scheme_function breakpoint_functions[] =
1151 {
1152   { "make-breakpoint", 1, 0, 1, as_a_scm_t_subr (gdbscm_make_breakpoint),
1153     "\
1154 Create a GDB breakpoint object.\n\
1155 \n\
1156   Arguments:\n\
1157     location [#:type <type>] [#:wp-class <wp-class>] [#:internal <bool>]\n\
1158   Returns:\n\
1159     <gdb:breakpoint object" },
1160
1161   { "register-breakpoint!", 1, 0, 0,
1162     as_a_scm_t_subr (gdbscm_register_breakpoint_x),
1163     "\
1164 Register a <gdb:breakpoint> object with GDB." },
1165
1166   { "delete-breakpoint!", 1, 0, 0, as_a_scm_t_subr (gdbscm_delete_breakpoint_x),
1167     "\
1168 Delete the breakpoint from GDB." },
1169
1170   { "breakpoints", 0, 0, 0, as_a_scm_t_subr (gdbscm_breakpoints),
1171     "\
1172 Return a list of all GDB breakpoints.\n\
1173 \n\
1174   Arguments: none" },
1175
1176   { "breakpoint?", 1, 0, 0, as_a_scm_t_subr (gdbscm_breakpoint_p),
1177     "\
1178 Return #t if the object is a <gdb:breakpoint> object." },
1179
1180   { "breakpoint-valid?", 1, 0, 0, as_a_scm_t_subr (gdbscm_breakpoint_valid_p),
1181     "\
1182 Return #t if the breakpoint has not been deleted from GDB." },
1183
1184   { "breakpoint-number", 1, 0, 0, as_a_scm_t_subr (gdbscm_breakpoint_number),
1185     "\
1186 Return the breakpoint's number." },
1187
1188   { "breakpoint-type", 1, 0, 0, as_a_scm_t_subr (gdbscm_breakpoint_type),
1189     "\
1190 Return the type of the breakpoint." },
1191
1192   { "breakpoint-visible?", 1, 0, 0, as_a_scm_t_subr (gdbscm_breakpoint_visible),
1193     "\
1194 Return #t if the breakpoint is visible to the user." },
1195
1196   { "breakpoint-location", 1, 0, 0,
1197     as_a_scm_t_subr (gdbscm_breakpoint_location),
1198     "\
1199 Return the location of the breakpoint as specified by the user." },
1200
1201   { "breakpoint-expression", 1, 0, 0,
1202     as_a_scm_t_subr (gdbscm_breakpoint_expression),
1203     "\
1204 Return the expression of the breakpoint as specified by the user.\n\
1205 Valid for watchpoints only, returns #f for non-watchpoints." },
1206
1207   { "breakpoint-enabled?", 1, 0, 0,
1208     as_a_scm_t_subr (gdbscm_breakpoint_enabled_p),
1209     "\
1210 Return #t if the breakpoint is enabled." },
1211
1212   { "set-breakpoint-enabled!", 2, 0, 0,
1213     as_a_scm_t_subr (gdbscm_set_breakpoint_enabled_x),
1214     "\
1215 Set the breakpoint's enabled state.\n\
1216 \n\
1217   Arguments: <gdb:breakpoint> boolean" },
1218
1219   { "breakpoint-silent?", 1, 0, 0, as_a_scm_t_subr (gdbscm_breakpoint_silent_p),
1220     "\
1221 Return #t if the breakpoint is silent." },
1222
1223   { "set-breakpoint-silent!", 2, 0, 0,
1224     as_a_scm_t_subr (gdbscm_set_breakpoint_silent_x),
1225     "\
1226 Set the breakpoint's silent state.\n\
1227 \n\
1228   Arguments: <gdb:breakpoint> boolean" },
1229
1230   { "breakpoint-ignore-count", 1, 0, 0,
1231     as_a_scm_t_subr (gdbscm_breakpoint_ignore_count),
1232     "\
1233 Return the breakpoint's \"ignore\" count." },
1234
1235   { "set-breakpoint-ignore-count!", 2, 0, 0,
1236     as_a_scm_t_subr (gdbscm_set_breakpoint_ignore_count_x),
1237     "\
1238 Set the breakpoint's \"ignore\" count.\n\
1239 \n\
1240   Arguments: <gdb:breakpoint> count" },
1241
1242   { "breakpoint-hit-count", 1, 0, 0,
1243     as_a_scm_t_subr (gdbscm_breakpoint_hit_count),
1244     "\
1245 Return the breakpoint's \"hit\" count." },
1246
1247   { "set-breakpoint-hit-count!", 2, 0, 0,
1248     as_a_scm_t_subr (gdbscm_set_breakpoint_hit_count_x),
1249     "\
1250 Set the breakpoint's \"hit\" count.  The value must be zero.\n\
1251 \n\
1252   Arguments: <gdb:breakpoint> 0" },
1253
1254   { "breakpoint-thread", 1, 0, 0, as_a_scm_t_subr (gdbscm_breakpoint_thread),
1255     "\
1256 Return the breakpoint's global thread id or #f if there isn't one." },
1257
1258   { "set-breakpoint-thread!", 2, 0, 0,
1259     as_a_scm_t_subr (gdbscm_set_breakpoint_thread_x),
1260     "\
1261 Set the global thread id for this breakpoint.\n\
1262 \n\
1263   Arguments: <gdb:breakpoint> global-thread-id" },
1264
1265   { "breakpoint-task", 1, 0, 0, as_a_scm_t_subr (gdbscm_breakpoint_task),
1266     "\
1267 Return the breakpoint's Ada task-id or #f if there isn't one." },
1268
1269   { "set-breakpoint-task!", 2, 0, 0,
1270     as_a_scm_t_subr (gdbscm_set_breakpoint_task_x),
1271     "\
1272 Set the breakpoint's Ada task-id.\n\
1273 \n\
1274   Arguments: <gdb:breakpoint> task-id" },
1275
1276   { "breakpoint-condition", 1, 0, 0,
1277     as_a_scm_t_subr (gdbscm_breakpoint_condition),
1278     "\
1279 Return the breakpoint's condition as specified by the user.\n\
1280 Return #f if there isn't one." },
1281
1282   { "set-breakpoint-condition!", 2, 0, 0,
1283     as_a_scm_t_subr (gdbscm_set_breakpoint_condition_x),
1284     "\
1285 Set the breakpoint's condition.\n\
1286 \n\
1287   Arguments: <gdb:breakpoint> condition\n\
1288     condition: a string" },
1289
1290   { "breakpoint-stop", 1, 0, 0, as_a_scm_t_subr (gdbscm_breakpoint_stop),
1291     "\
1292 Return the breakpoint's stop predicate.\n\
1293 Return #f if there isn't one." },
1294
1295   { "set-breakpoint-stop!", 2, 0, 0,
1296     as_a_scm_t_subr (gdbscm_set_breakpoint_stop_x),
1297     "\
1298 Set the breakpoint's stop predicate.\n\
1299 \n\
1300   Arguments: <gdb:breakpoint> procedure\n\
1301     procedure: A procedure of one argument, the breakpoint.\n\
1302       Its result is true if program execution should stop." },
1303
1304   { "breakpoint-commands", 1, 0, 0,
1305     as_a_scm_t_subr (gdbscm_breakpoint_commands),
1306     "\
1307 Return the breakpoint's commands." },
1308
1309   END_FUNCTIONS
1310 };
1311
1312 void
1313 gdbscm_initialize_breakpoints (void)
1314 {
1315   breakpoint_smob_tag
1316     = gdbscm_make_smob_type (breakpoint_smob_name, sizeof (breakpoint_smob));
1317   scm_set_smob_free (breakpoint_smob_tag, bpscm_free_breakpoint_smob);
1318   scm_set_smob_print (breakpoint_smob_tag, bpscm_print_breakpoint_smob);
1319
1320   gdb::observers::breakpoint_created.attach (bpscm_breakpoint_created);
1321   gdb::observers::breakpoint_deleted.attach (bpscm_breakpoint_deleted);
1322
1323   gdbscm_define_integer_constants (breakpoint_integer_constants, 1);
1324   gdbscm_define_functions (breakpoint_functions, 1);
1325
1326   type_keyword = scm_from_latin1_keyword ("type");
1327   wp_class_keyword = scm_from_latin1_keyword ("wp-class");
1328   internal_keyword = scm_from_latin1_keyword ("internal");
1329 }