-Wwrite-strings: Fix Solaris "set procfs-file"
[deliverable/binutils-gdb.git] / gdb / break-catch-syscall.c
index 1718f496113f9666737dc10895ff0077346d5330..322f680ad820aa025fe845edd2fee7db6f60549f 100644 (file)
@@ -1,6 +1,6 @@
 /* Everything about syscall catchpoints, for GDB.
 
-   Copyright (C) 2009-2015 Free Software Foundation, Inc.
+   Copyright (C) 2009-2017 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -85,7 +85,8 @@ get_catch_syscall_inferior_data (struct inferior *inf)
 {
   struct catch_syscall_inferior_data *inf_data;
 
-  inf_data = inferior_data (inf, catch_syscall_inferior_data);
+  inf_data = ((struct catch_syscall_inferior_data *)
+             inferior_data (inf, catch_syscall_inferior_data));
   if (inf_data == NULL)
     {
       inf_data = XCNEW (struct catch_syscall_inferior_data);
@@ -157,7 +158,7 @@ insert_catch_syscall (struct bp_location *bl)
    catchpoints.  */
 
 static int
-remove_catch_syscall (struct bp_location *bl)
+remove_catch_syscall (struct bp_location *bl, enum remove_bp_reason reason)
 {
   struct syscall_catchpoint *c = (struct syscall_catchpoint *) bl->owner;
   struct inferior *inf = current_inferior ();
@@ -253,32 +254,33 @@ print_it_catch_syscall (bpstat bs)
   get_syscall_by_number (gdbarch, last.value.syscall_number, &s);
 
   annotate_catchpoint (b->number);
+  maybe_print_thread_hit_breakpoint (uiout);
 
   if (b->disposition == disp_del)
-    ui_out_text (uiout, "\nTemporary catchpoint ");
+    uiout->text ("Temporary catchpoint ");
   else
-    ui_out_text (uiout, "\nCatchpoint ");
-  if (ui_out_is_mi_like_p (uiout))
+    uiout->text ("Catchpoint ");
+  if (uiout->is_mi_like_p ())
     {
-      ui_out_field_string (uiout, "reason",
+      uiout->field_string ("reason",
                           async_reason_lookup (last.kind == TARGET_WAITKIND_SYSCALL_ENTRY
                                                ? EXEC_ASYNC_SYSCALL_ENTRY
                                                : EXEC_ASYNC_SYSCALL_RETURN));
-      ui_out_field_string (uiout, "disp", bpdisp_text (b->disposition));
+      uiout->field_string ("disp", bpdisp_text (b->disposition));
     }
-  ui_out_field_int (uiout, "bkptno", b->number);
+  uiout->field_int ("bkptno", b->number);
 
   if (last.kind == TARGET_WAITKIND_SYSCALL_ENTRY)
-    ui_out_text (uiout, " (call to syscall ");
+    uiout->text (" (call to syscall ");
   else
-    ui_out_text (uiout, " (returned from syscall ");
+    uiout->text (" (returned from syscall ");
 
-  if (s.name == NULL || ui_out_is_mi_like_p (uiout))
-    ui_out_field_int (uiout, "syscall-number", last.value.syscall_number);
+  if (s.name == NULL || uiout->is_mi_like_p ())
+    uiout->field_int ("syscall-number", last.value.syscall_number);
   if (s.name != NULL)
-    ui_out_field_string (uiout, "syscall-name", s.name);
+    uiout->field_string ("syscall-name", s.name);
 
-  ui_out_text (uiout, "), ");
+  uiout->text ("), ");
 
   return PRINT_SRC_AND_LOC;
 }
@@ -300,14 +302,14 @@ print_one_catch_syscall (struct breakpoint *b,
      line up too nicely with the headers, but the effect is relatively
      readable).  */
   if (opts.addressprint)
-    ui_out_field_skip (uiout, "addr");
+    uiout->field_skip ("addr");
   annotate_field (5);
 
   if (c->syscalls_to_be_caught
       && VEC_length (int, c->syscalls_to_be_caught) > 1)
-    ui_out_text (uiout, "syscalls \"");
+    uiout->text ("syscalls \"");
   else
-    ui_out_text (uiout, "syscall \"");
+    uiout->text ("syscall \"");
 
   if (c->syscalls_to_be_caught)
     {
@@ -334,14 +336,14 @@ print_one_catch_syscall (struct breakpoint *b,
         }
       /* Remove the last comma.  */
       text[strlen (text) - 2] = '\0';
-      ui_out_field_string (uiout, "what", text);
+      uiout->field_string ("what", text);
     }
   else
-    ui_out_field_string (uiout, "what", "<any syscall>");
-  ui_out_text (uiout, "\" ");
+    uiout->field_string ("what", "<any syscall>");
+  uiout->text ("\" ");
 
-  if (ui_out_is_mi_like_p (uiout))
-    ui_out_field_string (uiout, "catch-type", "syscall");
+  if (uiout->is_mi_like_p ())
+    uiout->field_string ("catch-type", "syscall");
 }
 
 /* Implement the "print_mention" breakpoint_ops method for syscall
@@ -431,7 +433,7 @@ create_syscall_event_catchpoint (int tempflag, VEC(int) *filter,
   struct syscall_catchpoint *c;
   struct gdbarch *gdbarch = get_current_arch ();
 
-  c = XNEW (struct syscall_catchpoint);
+  c = new syscall_catchpoint ();
   init_catchpoint (&c->base, gdbarch, tempflag, NULL, ops);
   c->syscalls_to_be_caught = filter;
 
@@ -462,10 +464,38 @@ catch_syscall_split_args (char *arg)
       cur_name[i] = '\0';
       arg += i;
 
-      /* Check if the user provided a syscall name or a number.  */
+      /* Check if the user provided a syscall name, group, or a number.  */
       syscall_number = (int) strtol (cur_name, &endptr, 0);
       if (*endptr == '\0')
-       get_syscall_by_number (gdbarch, syscall_number, &s);
+       {
+         get_syscall_by_number (gdbarch, syscall_number, &s);
+         VEC_safe_push (int, result, s.number);
+       }
+      else if (startswith (cur_name, "g:")
+              || startswith (cur_name, "group:"))
+       {
+         /* We have a syscall group.  Let's expand it into a syscall
+            list before inserting.  */
+         struct syscall *syscall_list;
+         const char *group_name;
+
+         /* Skip over "g:" and "group:" prefix strings.  */
+         group_name = strchr (cur_name, ':') + 1;
+
+         syscall_list = get_syscalls_by_group (gdbarch, group_name);
+
+         if (syscall_list == NULL)
+           error (_("Unknown syscall group '%s'."), group_name);
+
+         for (i = 0; syscall_list[i].name != NULL; i++)
+           {
+             /* Insert each syscall that are part of the group.  No
+                need to check if it is valid.  */
+             VEC_safe_push (int, result, syscall_list[i].number);
+           }
+
+         xfree (syscall_list);
+       }
       else
        {
          /* We have a name.  Let's check if it's valid and convert it
@@ -477,10 +507,10 @@ catch_syscall_split_args (char *arg)
               because GDB cannot do anything useful if there's no
               syscall number to be caught.  */
            error (_("Unknown syscall name '%s'."), cur_name);
-       }
 
-      /* Ok, it's valid.  */
-      VEC_safe_push (int, result, s.number);
+         /* Ok, it's valid.  */
+         VEC_safe_push (int, result, s.number);
+       }
     }
 
   discard_cleanups (cleanup);
@@ -595,11 +625,58 @@ static VEC (char_ptr) *
 catch_syscall_completer (struct cmd_list_element *cmd,
                          const char *text, const char *word)
 {
-  const char **list = get_syscall_names (get_current_arch ());
-  VEC (char_ptr) *retlist
-    = (list == NULL) ? NULL : complete_on_enum (list, word, word);
+  struct gdbarch *gdbarch = get_current_arch ();
+  struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
+  VEC (char_ptr) *group_retlist = NULL;
+  VEC (char_ptr) *syscall_retlist = NULL;
+  VEC (char_ptr) *retlist = NULL;
+  const char **group_list = NULL;
+  const char **syscall_list = NULL;
+  const char *prefix;
+  int i;
+
+  /* Completion considers ':' to be a word separator, so we use this to
+     verify whether the previous word was a group prefix.  If so, we
+     build the completion list using group names only.  */
+  for (prefix = word; prefix != text && prefix[-1] != ' '; prefix--)
+    ;
+
+  if (startswith (prefix, "g:") || startswith (prefix, "group:"))
+    {
+      /* Perform completion inside 'group:' namespace only.  */
+      group_list = get_syscall_group_names (gdbarch);
+      retlist = (group_list == NULL
+                ? NULL : complete_on_enum (group_list, word, word));
+    }
+  else
+    {
+      /* Complete with both, syscall names and groups.  */
+      syscall_list = get_syscall_names (gdbarch);
+      group_list = get_syscall_group_names (gdbarch);
+
+      /* Append "group:" prefix to syscall groups.  */
+      for (i = 0; group_list[i] != NULL; i++)
+       {
+         char *prefixed_group = xstrprintf ("group:%s", group_list[i]);
+
+         group_list[i] = prefixed_group;
+         make_cleanup (xfree, prefixed_group);
+       }
+
+      syscall_retlist = ((syscall_list == NULL)
+                        ? NULL : complete_on_enum (syscall_list, word, word));
+      group_retlist = ((group_list == NULL)
+                      ? NULL : complete_on_enum (group_list, word, word));
+
+      retlist = VEC_merge (char_ptr, syscall_retlist, group_retlist);
+    }
+
+  VEC_free (char_ptr, syscall_retlist);
+  VEC_free (char_ptr, group_retlist);
+  xfree (syscall_list);
+  xfree (group_list);
+  do_cleanups (cleanups);
 
-  xfree (list);
   return retlist;
 }
 
@@ -647,11 +724,11 @@ _initialize_break_catch_syscall (void)
                                           catch_syscall_inferior_data_cleanup);
 
   add_catch_command ("syscall", _("\
-Catch system calls by their names and/or numbers.\n\
-Arguments say which system calls to catch.  If no arguments\n\
-are given, every system call will be caught.\n\
-Arguments, if given, should be one or more system call names\n\
-(if your system supports that), or system call numbers."),
+Catch system calls by their names, groups and/or numbers.\n\
+Arguments say which system calls to catch.  If no arguments are given,\n\
+every system call will be caught.  Arguments, if given, should be one\n\
+or more system call names (if your system supports that), system call\n\
+groups or system call numbers."),
                     catch_syscall_command_1,
                     catch_syscall_completer,
                     CATCH_PERMANENT,
This page took 0.043176 seconds and 4 git commands to generate.