Class-ify ui_out
[external/binutils.git] / gdb / skip.c
1 /* Skipping uninteresting files and functions while stepping.
2
3    Copyright (C) 2011-2016 Free Software Foundation, Inc.
4
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 3 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
17
18 #include "defs.h"
19 #include "skip.h"
20 #include "value.h"
21 #include "valprint.h"
22 #include "ui-out.h"
23 #include "symtab.h"
24 #include "gdbcmd.h"
25 #include "command.h"
26 #include "completer.h"
27 #include "stack.h"
28 #include "cli/cli-utils.h"
29 #include "arch-utils.h"
30 #include "linespec.h"
31 #include "objfiles.h"
32 #include "breakpoint.h" /* for get_sal_arch () */
33 #include "source.h"
34 #include "filenames.h"
35 #include "fnmatch.h"
36 #include "gdb_regex.h"
37
38 struct skiplist_entry
39 {
40   int number;
41
42   /* Non-zero if FILE is a glob-style pattern.
43      Otherewise it is the plain file name (possibly with directories).  */
44   int file_is_glob;
45
46   /* The name of the file or NULL.
47      The skiplist entry owns this pointer.  */
48   char *file;
49
50   /* Non-zero if FUNCTION is a regexp.
51      Otherwise it is a plain function name (possibly with arguments,
52      for C++).  */
53   int function_is_regexp;
54
55   /* The name of the function or NULL.
56      The skiplist entry owns this pointer.  */
57   char *function;
58
59   /* If this is a function regexp, the compiled form.  */
60   regex_t compiled_function_regexp;
61
62   /* Non-zero if the function regexp has been compiled.  */
63   int compiled_function_regexp_is_valid;
64
65   int enabled;
66
67   struct skiplist_entry *next;
68 };
69
70 static void add_skiplist_entry (struct skiplist_entry *e);
71
72 static struct skiplist_entry *skiplist_entry_chain;
73 static int skiplist_entry_count;
74
75 #define ALL_SKIPLIST_ENTRIES(E) \
76   for (E = skiplist_entry_chain; E; E = E->next)
77
78 #define ALL_SKIPLIST_ENTRIES_SAFE(E,TMP) \
79   for (E = skiplist_entry_chain;         \
80        E ? (TMP = E->next, 1) : 0;       \
81        E = TMP)
82
83 /* Create a skip object.  */
84
85 static struct skiplist_entry *
86 make_skip_entry (int file_is_glob, const char *file,
87                  int function_is_regexp, const char *function)
88 {
89   struct skiplist_entry *e = XCNEW (struct skiplist_entry);
90
91   gdb_assert (file != NULL || function != NULL);
92   if (file_is_glob)
93     gdb_assert (file != NULL);
94   if (function_is_regexp)
95     gdb_assert (function != NULL);
96
97   if (file != NULL)
98     e->file = xstrdup (file);
99   if (function != NULL)
100     e->function = xstrdup (function);
101   e->file_is_glob = file_is_glob;
102   e->function_is_regexp = function_is_regexp;
103   e->enabled = 1;
104
105   return e;
106 }
107
108 /* Free a skiplist entry.  */
109
110 static void
111 free_skiplist_entry (struct skiplist_entry *e)
112 {
113   xfree (e->file);
114   xfree (e->function);
115   if (e->function_is_regexp && e->compiled_function_regexp_is_valid)
116     regfree (&e->compiled_function_regexp);
117   xfree (e);
118 }
119
120 /* Wrapper to free_skiplist_entry for use as a cleanup.  */
121
122 static void
123 free_skiplist_entry_cleanup (void *e)
124 {
125   free_skiplist_entry ((struct skiplist_entry *) e);
126 }
127
128 /* Create a cleanup to free skiplist entry E.  */
129
130 static struct cleanup *
131 make_free_skiplist_entry_cleanup (struct skiplist_entry *e)
132 {
133   return make_cleanup (free_skiplist_entry_cleanup, e);
134 }
135
136 static void
137 skip_file_command (char *arg, int from_tty)
138 {
139   struct symtab *symtab;
140   const char *filename = NULL;
141
142   /* If no argument was given, try to default to the last
143      displayed codepoint.  */
144   if (arg == NULL)
145     {
146       symtab = get_last_displayed_symtab ();
147       if (symtab == NULL)
148         error (_("No default file now."));
149
150       /* It is not a typo, symtab_to_filename_for_display woule be needlessly
151          ambiguous.  */
152       filename = symtab_to_fullname (symtab);
153     }
154   else
155     filename = arg;
156
157   add_skiplist_entry (make_skip_entry (0, filename, 0, NULL));
158
159   printf_filtered (_("File %s will be skipped when stepping.\n"), filename);
160 }
161
162 /* Create a skiplist entry for the given function NAME and add it to the
163    list.  */
164
165 static void
166 skip_function (const char *name)
167 {
168   add_skiplist_entry (make_skip_entry (0, NULL, 0, name));
169
170   printf_filtered (_("Function %s will be skipped when stepping.\n"), name);
171 }
172
173 static void
174 skip_function_command (char *arg, int from_tty)
175 {
176   /* Default to the current function if no argument is given.  */
177   if (arg == NULL)
178     {
179       const char *name = NULL;
180       CORE_ADDR pc;
181
182       if (!last_displayed_sal_is_valid ())
183         error (_("No default function now."));
184
185       pc = get_last_displayed_addr ();
186       if (!find_pc_partial_function (pc, &name, NULL, NULL))
187         {
188           error (_("No function found containing current program point %s."),
189                   paddress (get_current_arch (), pc));
190         }
191       skip_function (name);
192       return;
193     }
194
195   skip_function (arg);
196 }
197
198 /* Compile the regexp in E.
199    An error is thrown if there's an error.
200    MESSAGE is used as a prefix of the error message.  */
201
202 static void
203 compile_skip_regexp (struct skiplist_entry *e, const char *message)
204 {
205   int code;
206   int flags = REG_NOSUB;
207
208 #ifdef REG_EXTENDED
209   flags |= REG_EXTENDED;
210 #endif
211
212   gdb_assert (e->function_is_regexp && e->function != NULL);
213
214   code = regcomp (&e->compiled_function_regexp, e->function, flags);
215   if (code != 0)
216     {
217       char *err = get_regcomp_error (code, &e->compiled_function_regexp);
218
219       make_cleanup (xfree, err);
220       error (_("%s: %s"), message, err);
221     }
222   e->compiled_function_regexp_is_valid = 1;
223 }
224
225 /* Process "skip ..." that does not match "skip file" or "skip function".  */
226
227 static void
228 skip_command (char *arg, int from_tty)
229 {
230   const char *file = NULL;
231   const char *gfile = NULL;
232   const char *function = NULL;
233   const char *rfunction = NULL;
234   char **argv;
235   struct cleanup *cleanups;
236   struct skiplist_entry *e;
237   int i;
238
239   if (arg == NULL)
240     {
241       skip_function_command (arg, from_tty);
242       return;
243     }
244
245   argv = buildargv (arg);
246   cleanups = make_cleanup_freeargv (argv);
247
248   for (i = 0; argv[i] != NULL; ++i)
249     {
250       const char *p = argv[i];
251       const char *value = argv[i + 1];
252
253       if (strcmp (p, "-fi") == 0
254           || strcmp (p, "-file") == 0)
255         {
256           if (value == NULL)
257             error (_("Missing value for %s option."), p);
258           file = value;
259           ++i;
260         }
261       else if (strcmp (p, "-gfi") == 0
262                || strcmp (p, "-gfile") == 0)
263         {
264           if (value == NULL)
265             error (_("Missing value for %s option."), p);
266           gfile = value;
267           ++i;
268         }
269       else if (strcmp (p, "-fu") == 0
270                || strcmp (p, "-function") == 0)
271         {
272           if (value == NULL)
273             error (_("Missing value for %s option."), p);
274           function = value;
275           ++i;
276         }
277       else if (strcmp (p, "-rfu") == 0
278                || strcmp (p, "-rfunction") == 0)
279         {
280           if (value == NULL)
281             error (_("Missing value for %s option."), p);
282           rfunction = value;
283           ++i;
284         }
285       else if (*p == '-')
286         error (_("Invalid skip option: %s"), p);
287       else if (i == 0)
288         {
289           /* Assume the user entered "skip FUNCTION-NAME".
290              FUNCTION-NAME may be `foo (int)', and therefore we pass the
291              complete original arg to skip_function command as if the user
292              typed "skip function arg".  */
293           do_cleanups (cleanups);
294           skip_function_command (arg, from_tty);
295           return;
296         }
297       else
298         error (_("Invalid argument: %s"), p);
299     }
300
301   if (file != NULL && gfile != NULL)
302     error (_("Cannot specify both -file and -gfile."));
303
304   if (function != NULL && rfunction != NULL)
305     error (_("Cannot specify both -function and -rfunction."));
306
307   /* This shouldn't happen as "skip" by itself gets punted to
308      skip_function_command.  */
309   gdb_assert (file != NULL || gfile != NULL
310               || function != NULL || rfunction != NULL);
311
312   e = make_skip_entry (gfile != NULL, file ? file : gfile,
313                        rfunction != NULL, function ? function : rfunction);
314   if (rfunction != NULL)
315     {
316       struct cleanup *rf_cleanups = make_free_skiplist_entry_cleanup (e);
317
318       compile_skip_regexp (e, _("regexp"));
319       discard_cleanups (rf_cleanups);
320     }
321   add_skiplist_entry (e);
322
323   /* I18N concerns drive some of the choices here (we can't piece together
324      the output too much).  OTOH we want to keep this simple.  Therefore the
325      only polish we add to the output is to append "(s)" to "File" or
326      "Function" if they're a glob/regexp.  */
327   {
328     const char *file_to_print = file != NULL ? file : gfile;
329     const char *function_to_print = function != NULL ? function : rfunction;
330     const char *file_text = gfile != NULL ? _("File(s)") : _("File");
331     const char *lower_file_text = gfile != NULL ? _("file(s)") : _("file");
332     const char *function_text
333       = rfunction != NULL ? _("Function(s)") : _("Function");
334
335     if (function_to_print == NULL)
336       {
337         printf_filtered (_("%s %s will be skipped when stepping.\n"),
338                          file_text, file_to_print);
339       }
340     else if (file_to_print == NULL)
341       {
342         printf_filtered (_("%s %s will be skipped when stepping.\n"),
343                          function_text, function_to_print);
344       }
345     else
346       {
347         printf_filtered (_("%s %s in %s %s will be skipped"
348                            " when stepping.\n"),
349                          function_text, function_to_print,
350                          lower_file_text, file_to_print);
351       }
352   }
353
354   do_cleanups (cleanups);
355 }
356
357 static void
358 skip_info (char *arg, int from_tty)
359 {
360   struct skiplist_entry *e;
361   int num_printable_entries = 0;
362   struct value_print_options opts;
363   struct cleanup *tbl_chain;
364
365   get_user_print_options (&opts);
366
367   /* Count the number of rows in the table and see if we need space for a
368      64-bit address anywhere.  */
369   ALL_SKIPLIST_ENTRIES (e)
370     if (arg == NULL || number_is_in_list (arg, e->number))
371       num_printable_entries++;
372
373   if (num_printable_entries == 0)
374     {
375       if (arg == NULL)
376         current_uiout->message (_("Not skipping any files or functions.\n"));
377       else
378         current_uiout->message (
379           _("No skiplist entries found with number %s.\n"), arg);
380
381       return;
382     }
383
384   tbl_chain = make_cleanup_ui_out_table_begin_end (current_uiout, 6,
385                                                    num_printable_entries,
386                                                    "SkiplistTable");
387
388   current_uiout->table_header (5, ui_left, "number", "Num");   /* 1 */
389   current_uiout->table_header (3, ui_left, "enabled", "Enb");  /* 2 */
390   current_uiout->table_header (4, ui_right, "regexp", "Glob"); /* 3 */
391   current_uiout->table_header (20, ui_left, "file", "File");   /* 4 */
392   current_uiout->table_header (2, ui_right, "regexp", "RE");   /* 5 */
393   current_uiout->table_header (40, ui_noalign, "function", "Function"); /* 6 */
394   current_uiout->table_body ();
395
396   ALL_SKIPLIST_ENTRIES (e)
397     {
398       struct cleanup *entry_chain;
399
400       QUIT;
401       if (arg != NULL && !number_is_in_list (arg, e->number))
402         continue;
403
404       entry_chain = make_cleanup_ui_out_tuple_begin_end (current_uiout,
405                                                          "blklst-entry");
406       current_uiout->field_int ("number", e->number); /* 1 */
407
408       if (e->enabled)
409         current_uiout->field_string ("enabled", "y"); /* 2 */
410       else
411         current_uiout->field_string ("enabled", "n"); /* 2 */
412
413       if (e->file_is_glob)
414         current_uiout->field_string ("regexp", "y"); /* 3 */
415       else
416         current_uiout->field_string ("regexp", "n"); /* 3 */
417
418       current_uiout->field_string ("file",
419                            e->file ? e->file : "<none>"); /* 4 */
420       if (e->function_is_regexp)
421         current_uiout->field_string ("regexp", "y"); /* 5 */
422       else
423         current_uiout->field_string ("regexp", "n"); /* 5 */
424
425       current_uiout->field_string (
426         "function", e->function ? e->function : "<none>"); /* 6 */
427
428       current_uiout->text ("\n");
429       do_cleanups (entry_chain);
430     }
431
432   do_cleanups (tbl_chain);
433 }
434
435 static void
436 skip_enable_command (char *arg, int from_tty)
437 {
438   struct skiplist_entry *e;
439   int found = 0;
440
441   ALL_SKIPLIST_ENTRIES (e)
442     if (arg == NULL || number_is_in_list (arg, e->number))
443       {
444         e->enabled = 1;
445         found = 1;
446       }
447
448   if (!found)
449     error (_("No skiplist entries found with number %s."), arg);
450 }
451
452 static void
453 skip_disable_command (char *arg, int from_tty)
454 {
455   struct skiplist_entry *e;
456   int found = 0;
457
458   ALL_SKIPLIST_ENTRIES (e)
459     if (arg == NULL || number_is_in_list (arg, e->number))
460       {
461         e->enabled = 0;
462         found = 1;
463       }
464
465   if (!found)
466     error (_("No skiplist entries found with number %s."), arg);
467 }
468
469 static void
470 skip_delete_command (char *arg, int from_tty)
471 {
472   struct skiplist_entry *e, *temp, *b_prev;
473   int found = 0;
474
475   b_prev = 0;
476   ALL_SKIPLIST_ENTRIES_SAFE (e, temp)
477     if (arg == NULL || number_is_in_list (arg, e->number))
478       {
479         if (b_prev != NULL)
480           b_prev->next = e->next;
481         else
482           skiplist_entry_chain = e->next;
483
484         free_skiplist_entry (e);
485         found = 1;
486       }
487     else
488       {
489         b_prev = e;
490       }
491
492   if (!found)
493     error (_("No skiplist entries found with number %s."), arg);
494 }
495
496 /* Add the given skiplist entry to our list, and set the entry's number.  */
497
498 static void
499 add_skiplist_entry (struct skiplist_entry *e)
500 {
501   struct skiplist_entry *e1;
502
503   e->number = ++skiplist_entry_count;
504
505   /* Add to the end of the chain so that the list of
506      skiplist entries will be in numerical order.  */
507
508   e1 = skiplist_entry_chain;
509   if (e1 == NULL)
510     skiplist_entry_chain = e;
511   else
512     {
513       while (e1->next)
514         e1 = e1->next;
515       e1->next = e;
516     }
517 }
518
519 /* Return non-zero if we're stopped at a file to be skipped.  */
520
521 static int
522 skip_file_p (struct skiplist_entry *e,
523              const struct symtab_and_line *function_sal)
524 {
525   gdb_assert (e->file != NULL && !e->file_is_glob);
526
527   if (function_sal->symtab == NULL)
528     return 0;
529
530   /* Check first sole SYMTAB->FILENAME.  It may not be a substring of
531      symtab_to_fullname as it may contain "./" etc.  */
532   if (compare_filenames_for_search (function_sal->symtab->filename, e->file))
533     return 1;
534
535   /* Before we invoke realpath, which can get expensive when many
536      files are involved, do a quick comparison of the basenames.  */
537   if (!basenames_may_differ
538       && filename_cmp (lbasename (function_sal->symtab->filename),
539                        lbasename (e->file)) != 0)
540     return 0;
541
542   /* Note: symtab_to_fullname caches its result, thus we don't have to.  */
543   {
544     const char *fullname = symtab_to_fullname (function_sal->symtab);
545
546     if (compare_filenames_for_search (fullname, e->file))
547       return 1;
548   }
549
550   return 0;
551 }
552
553 /* Return non-zero if we're stopped at a globbed file to be skipped.  */
554
555 static int
556 skip_gfile_p (struct skiplist_entry *e,
557               const struct symtab_and_line *function_sal)
558 {
559   gdb_assert (e->file != NULL && e->file_is_glob);
560
561   if (function_sal->symtab == NULL)
562     return 0;
563
564   /* Check first sole SYMTAB->FILENAME.  It may not be a substring of
565      symtab_to_fullname as it may contain "./" etc.  */
566   if (gdb_filename_fnmatch (e->file, function_sal->symtab->filename,
567                             FNM_FILE_NAME | FNM_NOESCAPE) == 0)
568     return 1;
569
570   /* Before we invoke symtab_to_fullname, which is expensive, do a quick
571      comparison of the basenames.
572      Note that we assume that lbasename works with glob-style patterns.
573      If the basename of the glob pattern is something like "*.c" then this
574      isn't much of a win.  Oh well.  */
575   if (!basenames_may_differ
576       && gdb_filename_fnmatch (lbasename (e->file),
577                                lbasename (function_sal->symtab->filename),
578                                FNM_FILE_NAME | FNM_NOESCAPE) != 0)
579     return 0;
580
581   /* Note: symtab_to_fullname caches its result, thus we don't have to.  */
582   {
583     const char *fullname = symtab_to_fullname (function_sal->symtab);
584
585     if (compare_glob_filenames_for_search (fullname, e->file))
586       return 1;
587   }
588
589   return 0;
590 }
591
592 /* Return non-zero if we're stopped at a function to be skipped.  */
593
594 static int
595 skip_function_p (struct skiplist_entry *e, const char *function_name)
596 {
597   gdb_assert (e->function != NULL && !e->function_is_regexp);
598   return strcmp_iw (function_name, e->function) == 0;
599 }
600
601 /* Return non-zero if we're stopped at a function regexp to be skipped.  */
602
603 static int
604 skip_rfunction_p (struct skiplist_entry *e, const char *function_name)
605 {
606   gdb_assert (e->function != NULL && e->function_is_regexp
607               && e->compiled_function_regexp_is_valid);
608   return (regexec (&e->compiled_function_regexp, function_name, 0, NULL, 0)
609           == 0);
610 }
611
612 /* See skip.h.  */
613
614 int
615 function_name_is_marked_for_skip (const char *function_name,
616                                   const struct symtab_and_line *function_sal)
617 {
618   struct skiplist_entry *e;
619
620   if (function_name == NULL)
621     return 0;
622
623   ALL_SKIPLIST_ENTRIES (e)
624     {
625       int skip_by_file = 0;
626       int skip_by_function = 0;
627
628       if (!e->enabled)
629         continue;
630
631       if (e->file != NULL)
632         {
633           if (e->file_is_glob)
634             {
635               if (skip_gfile_p (e, function_sal))
636                 skip_by_file = 1;
637             }
638           else
639             {
640               if (skip_file_p (e, function_sal))
641                 skip_by_file = 1;
642             }
643         }
644       if (e->function != NULL)
645         {
646           if (e->function_is_regexp)
647             {
648               if (skip_rfunction_p (e, function_name))
649                 skip_by_function = 1;
650             }
651           else
652             {
653               if (skip_function_p (e, function_name))
654                 skip_by_function = 1;
655             }
656         }
657
658       /* If both file and function must match, make sure we don't errantly
659          exit if only one of them match.  */
660       if (e->file != NULL && e->function != NULL)
661         {
662           if (skip_by_file && skip_by_function)
663             return 1;
664         }
665       /* Only one of file/function is specified.  */
666       else if (skip_by_file || skip_by_function)
667         return 1;
668     }
669
670   return 0;
671 }
672
673 /* Provide a prototype to silence -Wmissing-prototypes.  */
674 extern initialize_file_ftype _initialize_step_skip;
675
676 void
677 _initialize_step_skip (void)
678 {
679   static struct cmd_list_element *skiplist = NULL;
680   struct cmd_list_element *c;
681
682   skiplist_entry_chain = 0;
683   skiplist_entry_count = 0;
684
685   add_prefix_cmd ("skip", class_breakpoint, skip_command, _("\
686 Ignore a function while stepping.\n\
687 \n\
688 Usage: skip [FUNCTION-NAME]\n\
689        skip [<file-spec>] [<function-spec>]\n\
690 If no arguments are given, ignore the current function.\n\
691 \n\
692 <file-spec> is one of:\n\
693        -fi|-file FILE-NAME\n\
694        -gfi|-gfile GLOB-FILE-PATTERN\n\
695 <function-spec> is one of:\n\
696        -fu|-function FUNCTION-NAME\n\
697        -rfu|-rfunction FUNCTION-NAME-REGULAR-EXPRESSION"),
698                   &skiplist, "skip ", 1, &cmdlist);
699
700   c = add_cmd ("file", class_breakpoint, skip_file_command, _("\
701 Ignore a file while stepping.\n\
702 Usage: skip file [FILE-NAME]\n\
703 If no filename is given, ignore the current file."),
704                &skiplist);
705   set_cmd_completer (c, filename_completer);
706
707   c = add_cmd ("function", class_breakpoint, skip_function_command, _("\
708 Ignore a function while stepping.\n\
709 Usage: skip function [FUNCTION-NAME]\n\
710 If no function name is given, skip the current function."),
711                &skiplist);
712   set_cmd_completer (c, location_completer);
713
714   add_cmd ("enable", class_breakpoint, skip_enable_command, _("\
715 Enable skip entries.  You can specify numbers (e.g. \"skip enable 1 3\"), \
716 ranges (e.g. \"skip enable 4-8\"), or both (e.g. \"skip enable 1 3 4-8\").\n\n\
717 If you don't specify any numbers or ranges, we'll enable all skip entries.\n\n\
718 Usage: skip enable [NUMBERS AND/OR RANGES]"),
719            &skiplist);
720
721   add_cmd ("disable", class_breakpoint, skip_disable_command, _("\
722 Disable skip entries.  You can specify numbers (e.g. \"skip disable 1 3\"), \
723 ranges (e.g. \"skip disable 4-8\"), or both (e.g. \"skip disable 1 3 4-8\").\n\n\
724 If you don't specify any numbers or ranges, we'll disable all skip entries.\n\n\
725 Usage: skip disable [NUMBERS AND/OR RANGES]"),
726            &skiplist);
727
728   add_cmd ("delete", class_breakpoint, skip_delete_command, _("\
729 Delete skip entries.  You can specify numbers (e.g. \"skip delete 1 3\"), \
730 ranges (e.g. \"skip delete 4-8\"), or both (e.g. \"skip delete 1 3 4-8\").\n\n\
731 If you don't specify any numbers or ranges, we'll delete all skip entries.\n\n\
732 Usage: skip delete [NUMBERS AND/OR RANGES]"),
733            &skiplist);
734
735   add_info ("skip", skip_info, _("\
736 Display the status of skips.  You can specify numbers (e.g. \"skip info 1 3\"), \
737 ranges (e.g. \"skip info 4-8\"), or both (e.g. \"skip info 1 3 4-8\").\n\n\
738 If you don't specify any numbers or ranges, we'll show all skips.\n\n\
739 Usage: skip info [NUMBERS AND/OR RANGES]\n\
740 The \"Type\" column indicates one of:\n\
741 \tfile        - ignored file\n\
742 \tfunction    - ignored function"));
743 }