Remove a cleanup from gdbserver
[external/binutils.git] / gdb / break-catch-syscall.c
1 /* Everything about syscall catchpoints, for GDB.
2
3    Copyright (C) 2009-2018 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 #include "defs.h"
21 #include <ctype.h>
22 #include "breakpoint.h"
23 #include "gdbcmd.h"
24 #include "inferior.h"
25 #include "cli/cli-utils.h"
26 #include "annotate.h"
27 #include "mi/mi-common.h"
28 #include "valprint.h"
29 #include "arch-utils.h"
30 #include "observer.h"
31 #include "xml-syscall.h"
32
33 /* An instance of this type is used to represent a syscall catchpoint.
34    A breakpoint is really of this type iff its ops pointer points to
35    CATCH_SYSCALL_BREAKPOINT_OPS.  */
36
37 struct syscall_catchpoint : public breakpoint
38 {
39   /* Syscall numbers used for the 'catch syscall' feature.  If no
40      syscall has been specified for filtering, it is empty.
41      Otherwise, it holds a list of all syscalls to be caught.  */
42   std::vector<int> syscalls_to_be_caught;
43 };
44
45 static const struct inferior_data *catch_syscall_inferior_data = NULL;
46
47 struct catch_syscall_inferior_data
48 {
49   /* We keep a count of the number of times the user has requested a
50      particular syscall to be tracked, and pass this information to the
51      target.  This lets capable targets implement filtering directly.  */
52
53   /* Number of times that "any" syscall is requested.  */
54   int any_syscall_count;
55
56   /* Count of each system call.  */
57   std::vector<int> syscalls_counts;
58
59   /* This counts all syscall catch requests, so we can readily determine
60      if any catching is necessary.  */
61   int total_syscalls_count;
62 };
63
64 static struct catch_syscall_inferior_data *
65 get_catch_syscall_inferior_data (struct inferior *inf)
66 {
67   struct catch_syscall_inferior_data *inf_data;
68
69   inf_data = ((struct catch_syscall_inferior_data *)
70               inferior_data (inf, catch_syscall_inferior_data));
71   if (inf_data == NULL)
72     {
73       inf_data = new struct catch_syscall_inferior_data ();
74       set_inferior_data (inf, catch_syscall_inferior_data, inf_data);
75     }
76
77   return inf_data;
78 }
79
80 static void
81 catch_syscall_inferior_data_cleanup (struct inferior *inf, void *arg)
82 {
83   struct catch_syscall_inferior_data *inf_data
84     = (struct catch_syscall_inferior_data *) arg;
85   delete inf_data;
86 }
87
88
89 /* Implement the "insert" breakpoint_ops method for syscall
90    catchpoints.  */
91
92 static int
93 insert_catch_syscall (struct bp_location *bl)
94 {
95   struct syscall_catchpoint *c = (struct syscall_catchpoint *) bl->owner;
96   struct inferior *inf = current_inferior ();
97   struct catch_syscall_inferior_data *inf_data
98     = get_catch_syscall_inferior_data (inf);
99
100   ++inf_data->total_syscalls_count;
101   if (c->syscalls_to_be_caught.empty ())
102     ++inf_data->any_syscall_count;
103   else
104     {
105       for (int iter : c->syscalls_to_be_caught)
106         {
107           if (iter >= inf_data->syscalls_counts.size ())
108             inf_data->syscalls_counts.resize (iter + 1);
109           ++inf_data->syscalls_counts[iter];
110         }
111     }
112
113   return target_set_syscall_catchpoint (ptid_get_pid (inferior_ptid),
114                                         inf_data->total_syscalls_count != 0,
115                                         inf_data->any_syscall_count,
116                                         inf_data->syscalls_counts);
117 }
118
119 /* Implement the "remove" breakpoint_ops method for syscall
120    catchpoints.  */
121
122 static int
123 remove_catch_syscall (struct bp_location *bl, enum remove_bp_reason reason)
124 {
125   struct syscall_catchpoint *c = (struct syscall_catchpoint *) bl->owner;
126   struct inferior *inf = current_inferior ();
127   struct catch_syscall_inferior_data *inf_data
128     = get_catch_syscall_inferior_data (inf);
129
130   --inf_data->total_syscalls_count;
131   if (c->syscalls_to_be_caught.empty ())
132     --inf_data->any_syscall_count;
133   else
134     {
135       for (int iter : c->syscalls_to_be_caught)
136         {
137           if (iter >= inf_data->syscalls_counts.size ())
138             /* Shouldn't happen.  */
139             continue;
140           --inf_data->syscalls_counts[iter];
141         }
142     }
143
144   return target_set_syscall_catchpoint (ptid_get_pid (inferior_ptid),
145                                         inf_data->total_syscalls_count != 0,
146                                         inf_data->any_syscall_count,
147                                         inf_data->syscalls_counts);
148 }
149
150 /* Implement the "breakpoint_hit" breakpoint_ops method for syscall
151    catchpoints.  */
152
153 static int
154 breakpoint_hit_catch_syscall (const struct bp_location *bl,
155                               const address_space *aspace, CORE_ADDR bp_addr,
156                               const struct target_waitstatus *ws)
157 {
158   /* We must check if we are catching specific syscalls in this
159      breakpoint.  If we are, then we must guarantee that the called
160      syscall is the same syscall we are catching.  */
161   int syscall_number = 0;
162   const struct syscall_catchpoint *c
163     = (const struct syscall_catchpoint *) bl->owner;
164
165   if (ws->kind != TARGET_WAITKIND_SYSCALL_ENTRY
166       && ws->kind != TARGET_WAITKIND_SYSCALL_RETURN)
167     return 0;
168
169   syscall_number = ws->value.syscall_number;
170
171   /* Now, checking if the syscall is the same.  */
172   if (!c->syscalls_to_be_caught.empty ())
173     {
174       for (int iter : c->syscalls_to_be_caught)
175         if (syscall_number == iter)
176           return 1;
177
178       return 0;
179     }
180
181   return 1;
182 }
183
184 /* Implement the "print_it" breakpoint_ops method for syscall
185    catchpoints.  */
186
187 static enum print_stop_action
188 print_it_catch_syscall (bpstat bs)
189 {
190   struct ui_out *uiout = current_uiout;
191   struct breakpoint *b = bs->breakpoint_at;
192   /* These are needed because we want to know in which state a
193      syscall is.  It can be in the TARGET_WAITKIND_SYSCALL_ENTRY
194      or TARGET_WAITKIND_SYSCALL_RETURN, and depending on it we
195      must print "called syscall" or "returned from syscall".  */
196   ptid_t ptid;
197   struct target_waitstatus last;
198   struct syscall s;
199   struct gdbarch *gdbarch = bs->bp_location_at->gdbarch;
200
201   get_last_target_status (&ptid, &last);
202
203   get_syscall_by_number (gdbarch, last.value.syscall_number, &s);
204
205   annotate_catchpoint (b->number);
206   maybe_print_thread_hit_breakpoint (uiout);
207
208   if (b->disposition == disp_del)
209     uiout->text ("Temporary catchpoint ");
210   else
211     uiout->text ("Catchpoint ");
212   if (uiout->is_mi_like_p ())
213     {
214       uiout->field_string ("reason",
215                            async_reason_lookup (last.kind == TARGET_WAITKIND_SYSCALL_ENTRY
216                                                 ? EXEC_ASYNC_SYSCALL_ENTRY
217                                                 : EXEC_ASYNC_SYSCALL_RETURN));
218       uiout->field_string ("disp", bpdisp_text (b->disposition));
219     }
220   uiout->field_int ("bkptno", b->number);
221
222   if (last.kind == TARGET_WAITKIND_SYSCALL_ENTRY)
223     uiout->text (" (call to syscall ");
224   else
225     uiout->text (" (returned from syscall ");
226
227   if (s.name == NULL || uiout->is_mi_like_p ())
228     uiout->field_int ("syscall-number", last.value.syscall_number);
229   if (s.name != NULL)
230     uiout->field_string ("syscall-name", s.name);
231
232   uiout->text ("), ");
233
234   return PRINT_SRC_AND_LOC;
235 }
236
237 /* Implement the "print_one" breakpoint_ops method for syscall
238    catchpoints.  */
239
240 static void
241 print_one_catch_syscall (struct breakpoint *b,
242                          struct bp_location **last_loc)
243 {
244   struct syscall_catchpoint *c = (struct syscall_catchpoint *) b;
245   struct value_print_options opts;
246   struct ui_out *uiout = current_uiout;
247   struct gdbarch *gdbarch = b->loc->gdbarch;
248
249   get_user_print_options (&opts);
250   /* Field 4, the address, is omitted (which makes the columns not
251      line up too nicely with the headers, but the effect is relatively
252      readable).  */
253   if (opts.addressprint)
254     uiout->field_skip ("addr");
255   annotate_field (5);
256
257   if (c->syscalls_to_be_caught.size () > 1)
258     uiout->text ("syscalls \"");
259   else
260     uiout->text ("syscall \"");
261
262   if (!c->syscalls_to_be_caught.empty ())
263     {
264       char *text = xstrprintf ("%s", "");
265
266       for (int iter : c->syscalls_to_be_caught)
267         {
268           char *x = text;
269           struct syscall s;
270           get_syscall_by_number (gdbarch, iter, &s);
271
272           if (s.name != NULL)
273             text = xstrprintf ("%s%s, ", text, s.name);
274           else
275             text = xstrprintf ("%s%d, ", text, iter);
276
277           /* We have to xfree the last 'text' (now stored at 'x')
278              because xstrprintf dynamically allocates new space for it
279              on every call.  */
280           xfree (x);
281         }
282       /* Remove the last comma.  */
283       text[strlen (text) - 2] = '\0';
284       uiout->field_string ("what", text);
285     }
286   else
287     uiout->field_string ("what", "<any syscall>");
288   uiout->text ("\" ");
289
290   if (uiout->is_mi_like_p ())
291     uiout->field_string ("catch-type", "syscall");
292 }
293
294 /* Implement the "print_mention" breakpoint_ops method for syscall
295    catchpoints.  */
296
297 static void
298 print_mention_catch_syscall (struct breakpoint *b)
299 {
300   struct syscall_catchpoint *c = (struct syscall_catchpoint *) b;
301   struct gdbarch *gdbarch = b->loc->gdbarch;
302
303   if (!c->syscalls_to_be_caught.empty ())
304     {
305       if (c->syscalls_to_be_caught.size () > 1)
306         printf_filtered (_("Catchpoint %d (syscalls"), b->number);
307       else
308         printf_filtered (_("Catchpoint %d (syscall"), b->number);
309
310       for (int iter : c->syscalls_to_be_caught)
311         {
312           struct syscall s;
313           get_syscall_by_number (gdbarch, iter, &s);
314
315           if (s.name != NULL)
316             printf_filtered (" '%s' [%d]", s.name, s.number);
317           else
318             printf_filtered (" %d", s.number);
319         }
320       printf_filtered (")");
321     }
322   else
323     printf_filtered (_("Catchpoint %d (any syscall)"),
324                      b->number);
325 }
326
327 /* Implement the "print_recreate" breakpoint_ops method for syscall
328    catchpoints.  */
329
330 static void
331 print_recreate_catch_syscall (struct breakpoint *b, struct ui_file *fp)
332 {
333   struct syscall_catchpoint *c = (struct syscall_catchpoint *) b;
334   struct gdbarch *gdbarch = b->loc->gdbarch;
335
336   fprintf_unfiltered (fp, "catch syscall");
337
338   for (int iter : c->syscalls_to_be_caught)
339     {
340       struct syscall s;
341
342       get_syscall_by_number (gdbarch, iter, &s);
343       if (s.name != NULL)
344         fprintf_unfiltered (fp, " %s", s.name);
345       else
346         fprintf_unfiltered (fp, " %d", s.number);
347     }
348
349   print_recreate_thread (b, fp);
350 }
351
352 /* The breakpoint_ops structure to be used in syscall catchpoints.  */
353
354 static struct breakpoint_ops catch_syscall_breakpoint_ops;
355
356 /* Returns non-zero if 'b' is a syscall catchpoint.  */
357
358 static int
359 syscall_catchpoint_p (struct breakpoint *b)
360 {
361   return (b->ops == &catch_syscall_breakpoint_ops);
362 }
363
364 static void
365 create_syscall_event_catchpoint (int tempflag, std::vector<int> &&filter,
366                                  const struct breakpoint_ops *ops)
367 {
368   struct gdbarch *gdbarch = get_current_arch ();
369
370   std::unique_ptr<syscall_catchpoint> c (new syscall_catchpoint ());
371   init_catchpoint (c.get (), gdbarch, tempflag, NULL, ops);
372   c->syscalls_to_be_caught = std::move (filter);
373
374   install_breakpoint (0, std::move (c), 1);
375 }
376
377 /* Splits the argument using space as delimiter.  */
378
379 static std::vector<int>
380 catch_syscall_split_args (const char *arg)
381 {
382   std::vector<int> result;
383   struct gdbarch *gdbarch = target_gdbarch ();
384
385   while (*arg != '\0')
386     {
387       int i, syscall_number;
388       char *endptr;
389       char cur_name[128];
390       struct syscall s;
391
392       /* Skip whitespace.  */
393       arg = skip_spaces (arg);
394
395       for (i = 0; i < 127 && arg[i] && !isspace (arg[i]); ++i)
396         cur_name[i] = arg[i];
397       cur_name[i] = '\0';
398       arg += i;
399
400       /* Check if the user provided a syscall name, group, or a number.  */
401       syscall_number = (int) strtol (cur_name, &endptr, 0);
402       if (*endptr == '\0')
403         {
404           get_syscall_by_number (gdbarch, syscall_number, &s);
405           result.push_back (s.number);
406         }
407       else if (startswith (cur_name, "g:")
408                || startswith (cur_name, "group:"))
409         {
410           /* We have a syscall group.  Let's expand it into a syscall
411              list before inserting.  */
412           struct syscall *syscall_list;
413           const char *group_name;
414
415           /* Skip over "g:" and "group:" prefix strings.  */
416           group_name = strchr (cur_name, ':') + 1;
417
418           syscall_list = get_syscalls_by_group (gdbarch, group_name);
419
420           if (syscall_list == NULL)
421             error (_("Unknown syscall group '%s'."), group_name);
422
423           for (i = 0; syscall_list[i].name != NULL; i++)
424             {
425               /* Insert each syscall that are part of the group.  No
426                  need to check if it is valid.  */
427               result.push_back (syscall_list[i].number);
428             }
429
430           xfree (syscall_list);
431         }
432       else
433         {
434           /* We have a name.  Let's check if it's valid and convert it
435              to a number.  */
436           get_syscall_by_name (gdbarch, cur_name, &s);
437
438           if (s.number == UNKNOWN_SYSCALL)
439             /* Here we have to issue an error instead of a warning,
440                because GDB cannot do anything useful if there's no
441                syscall number to be caught.  */
442             error (_("Unknown syscall name '%s'."), cur_name);
443
444           /* Ok, it's valid.  */
445           result.push_back (s.number);
446         }
447     }
448
449   return result;
450 }
451
452 /* Implement the "catch syscall" command.  */
453
454 static void
455 catch_syscall_command_1 (const char *arg, int from_tty, 
456                          struct cmd_list_element *command)
457 {
458   int tempflag;
459   std::vector<int> filter;
460   struct syscall s;
461   struct gdbarch *gdbarch = get_current_arch ();
462
463   /* Checking if the feature if supported.  */
464   if (gdbarch_get_syscall_number_p (gdbarch) == 0)
465     error (_("The feature 'catch syscall' is not supported on \
466 this architecture yet."));
467
468   tempflag = get_cmd_context (command) == CATCH_TEMPORARY;
469
470   arg = skip_spaces (arg);
471
472   /* We need to do this first "dummy" translation in order
473      to get the syscall XML file loaded or, most important,
474      to display a warning to the user if there's no XML file
475      for his/her architecture.  */
476   get_syscall_by_number (gdbarch, 0, &s);
477
478   /* The allowed syntax is:
479      catch syscall
480      catch syscall <name | number> [<name | number> ... <name | number>]
481
482      Let's check if there's a syscall name.  */
483
484   if (arg != NULL)
485     filter = catch_syscall_split_args (arg);
486
487   create_syscall_event_catchpoint (tempflag, std::move (filter),
488                                    &catch_syscall_breakpoint_ops);
489 }
490
491
492 /* Returns 0 if 'bp' is NOT a syscall catchpoint,
493    non-zero otherwise.  */
494 static int
495 is_syscall_catchpoint_enabled (struct breakpoint *bp)
496 {
497   if (syscall_catchpoint_p (bp)
498       && bp->enable_state != bp_disabled
499       && bp->enable_state != bp_call_disabled)
500     return 1;
501   else
502     return 0;
503 }
504
505 int
506 catch_syscall_enabled (void)
507 {
508   struct catch_syscall_inferior_data *inf_data
509     = get_catch_syscall_inferior_data (current_inferior ());
510
511   return inf_data->total_syscalls_count != 0;
512 }
513
514 /* Helper function for catching_syscall_number.  If B is a syscall
515    catchpoint for SYSCALL_NUMBER, return 1 (which will make
516    'breakpoint_find_if' return).  Otherwise, return 0.  */
517
518 static int
519 catching_syscall_number_1 (struct breakpoint *b,
520                            void *data)
521 {
522   int syscall_number = (int) (uintptr_t) data;
523
524   if (is_syscall_catchpoint_enabled (b))
525     {
526       struct syscall_catchpoint *c = (struct syscall_catchpoint *) b;
527
528       if (!c->syscalls_to_be_caught.empty ())
529         {
530           for (int iter : c->syscalls_to_be_caught)
531             if (syscall_number == iter)
532               return 1;
533         }
534       else
535         return 1;
536     }
537
538   return 0;
539 }
540
541 int
542 catching_syscall_number (int syscall_number)
543 {
544   struct breakpoint *b = breakpoint_find_if (catching_syscall_number_1,
545                                          (void *) (uintptr_t) syscall_number);
546
547   return b != NULL;
548 }
549
550 /* Complete syscall names.  Used by "catch syscall".  */
551
552 static void
553 catch_syscall_completer (struct cmd_list_element *cmd,
554                          completion_tracker &tracker,
555                          const char *text, const char *word)
556 {
557   struct gdbarch *gdbarch = get_current_arch ();
558   gdb::unique_xmalloc_ptr<const char *> group_list;
559   const char *prefix;
560
561   /* Completion considers ':' to be a word separator, so we use this to
562      verify whether the previous word was a group prefix.  If so, we
563      build the completion list using group names only.  */
564   for (prefix = word; prefix != text && prefix[-1] != ' '; prefix--)
565     ;
566
567   if (startswith (prefix, "g:") || startswith (prefix, "group:"))
568     {
569       /* Perform completion inside 'group:' namespace only.  */
570       group_list.reset (get_syscall_group_names (gdbarch));
571       if (group_list != NULL)
572         complete_on_enum (tracker, group_list.get (), word, word);
573     }
574   else
575     {
576       /* Complete with both, syscall names and groups.  */
577       gdb::unique_xmalloc_ptr<const char *> syscall_list
578         (get_syscall_names (gdbarch));
579       group_list.reset (get_syscall_group_names (gdbarch));
580
581       const char **group_ptr = group_list.get ();
582
583       /* Hold on to strings while we're using them.  */
584       std::vector<std::string> holders;
585
586       /* Append "group:" prefix to syscall groups.  */
587       for (int i = 0; group_ptr[i] != NULL; i++)
588         holders.push_back (string_printf ("group:%s", group_ptr[i]));
589
590       for (int i = 0; group_ptr[i] != NULL; i++)
591         group_ptr[i] = holders[i].c_str ();
592
593       if (syscall_list != NULL)
594         complete_on_enum (tracker, syscall_list.get (), word, word);
595       if (group_list != NULL)
596         complete_on_enum (tracker, group_ptr, word, word);
597     }
598 }
599
600 static void
601 clear_syscall_counts (struct inferior *inf)
602 {
603   struct catch_syscall_inferior_data *inf_data
604     = get_catch_syscall_inferior_data (inf);
605
606   inf_data->total_syscalls_count = 0;
607   inf_data->any_syscall_count = 0;
608   inf_data->syscalls_counts.clear ();
609 }
610
611 static void
612 initialize_syscall_catchpoint_ops (void)
613 {
614   struct breakpoint_ops *ops;
615
616   initialize_breakpoint_ops ();
617
618   /* Syscall catchpoints.  */
619   ops = &catch_syscall_breakpoint_ops;
620   *ops = base_breakpoint_ops;
621   ops->insert_location = insert_catch_syscall;
622   ops->remove_location = remove_catch_syscall;
623   ops->breakpoint_hit = breakpoint_hit_catch_syscall;
624   ops->print_it = print_it_catch_syscall;
625   ops->print_one = print_one_catch_syscall;
626   ops->print_mention = print_mention_catch_syscall;
627   ops->print_recreate = print_recreate_catch_syscall;
628 }
629
630 void
631 _initialize_break_catch_syscall (void)
632 {
633   initialize_syscall_catchpoint_ops ();
634
635   observer_attach_inferior_exit (clear_syscall_counts);
636   catch_syscall_inferior_data
637     = register_inferior_data_with_cleanup (NULL,
638                                            catch_syscall_inferior_data_cleanup);
639
640   add_catch_command ("syscall", _("\
641 Catch system calls by their names, groups and/or numbers.\n\
642 Arguments say which system calls to catch.  If no arguments are given,\n\
643 every system call will be caught.  Arguments, if given, should be one\n\
644 or more system call names (if your system supports that), system call\n\
645 groups or system call numbers."),
646                      catch_syscall_command_1,
647                      catch_syscall_completer,
648                      CATCH_PERMANENT,
649                      CATCH_TEMPORARY);
650 }