Constify add_com
[external/binutils.git] / gdb / memattr.c
1 /* Memory attributes support, for GDB.
2
3    Copyright (C) 2001-2017 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 "command.h"
22 #include "gdbcmd.h"
23 #include "memattr.h"
24 #include "target.h"
25 #include "target-dcache.h"
26 #include "value.h"
27 #include "language.h"
28 #include "vec.h"
29 #include "breakpoint.h"
30 #include "cli/cli-utils.h"
31 #include <algorithm>
32
33 static std::vector<mem_region> user_mem_region_list, target_mem_region_list;
34 static std::vector<mem_region> *mem_region_list = &target_mem_region_list;
35 static int mem_number = 0;
36
37 /* If this flag is set, the memory region list should be automatically
38    updated from the target.  If it is clear, the list is user-controlled
39    and should be left alone.  */
40
41 static bool
42 mem_use_target ()
43 {
44   return mem_region_list == &target_mem_region_list;
45 }
46
47 /* If this flag is set, we have tried to fetch the target memory regions
48    since the last time it was invalidated.  If that list is still
49    empty, then the target can't supply memory regions.  */
50 static bool target_mem_regions_valid;
51
52 /* If this flag is set, gdb will assume that memory ranges not
53    specified by the memory map have type MEM_NONE, and will
54    emit errors on all accesses to that memory.  */
55 static int inaccessible_by_default = 1;
56
57 static void
58 show_inaccessible_by_default (struct ui_file *file, int from_tty,
59                               struct cmd_list_element *c,
60                               const char *value)
61 {
62   if (inaccessible_by_default)
63     fprintf_filtered (file, _("Unknown memory addresses will "
64                               "be treated as inaccessible.\n"));
65   else
66     fprintf_filtered (file, _("Unknown memory addresses "
67                               "will be treated as RAM.\n"));          
68 }
69
70 /* This function should be called before any command which would
71    modify the memory region list.  It will handle switching from
72    a target-provided list to a local list, if necessary.  */
73
74 static void
75 require_user_regions (int from_tty)
76 {
77   struct mem_region *m;
78   int ix, length;
79
80   /* If we're already using a user-provided list, nothing to do.  */
81   if (!mem_use_target ())
82     return;
83
84   /* Switch to a user-provided list (possibly a copy of the current
85      one).  */
86   mem_region_list = &user_mem_region_list;
87
88   /* If we don't have a target-provided region list yet, then
89      no need to warn.  */
90   if (target_mem_region_list.empty ())
91     return;
92
93   /* Otherwise, let the user know how to get back.  */
94   if (from_tty)
95     warning (_("Switching to manual control of memory regions; use "
96                "\"mem auto\" to fetch regions from the target again."));
97
98   /* And create a new list (copy of the target-supplied regions) for the user
99      to modify.  */
100   user_mem_region_list = target_mem_region_list;
101 }
102
103 /* This function should be called before any command which would
104    read the memory region list, other than those which call
105    require_user_regions.  It will handle fetching the
106    target-provided list, if necessary.  */
107
108 static void
109 require_target_regions (void)
110 {
111   if (mem_use_target () && !target_mem_regions_valid)
112     {
113       target_mem_regions_valid = true;
114       target_mem_region_list = target_memory_map ();
115     }
116 }
117
118 /* Create a new user-defined memory region.  */
119
120 static void
121 create_user_mem_region (CORE_ADDR lo, CORE_ADDR hi,
122                         const mem_attrib &attrib)
123 {
124   /* lo == hi is a useless empty region.  */
125   if (lo >= hi && hi != 0)
126     {
127       printf_unfiltered (_("invalid memory region: low >= high\n"));
128       return;
129     }
130
131   mem_region newobj (lo, hi, attrib);
132
133   auto it = std::lower_bound (user_mem_region_list.begin (),
134                               user_mem_region_list.end (),
135                               newobj);
136   int ix = std::distance (user_mem_region_list.begin (), it);
137
138   /* Check for an overlapping memory region.  We only need to check
139      in the vicinity - at most one before and one after the
140      insertion point.  */
141   for (int i = ix - 1; i < ix + 1; i++)
142     {
143       if (i < 0)
144         continue;
145       if (i >= user_mem_region_list.size ())
146         continue;
147
148       mem_region &n = user_mem_region_list[i];
149
150       if ((lo >= n.lo && (lo < n.hi || n.hi == 0))
151           || (hi > n.lo && (hi <= n.hi || n.hi == 0))
152           || (lo <= n.lo && ((hi >= n.hi && n.hi != 0) || hi == 0)))
153         {
154           printf_unfiltered (_("overlapping memory region\n"));
155           return;
156         }
157     }
158
159   newobj.number = ++mem_number;
160   user_mem_region_list.insert (it, newobj);
161 }
162
163 /* Look up the memory region corresponding to ADDR.  */
164
165 struct mem_region *
166 lookup_mem_region (CORE_ADDR addr)
167 {
168   static struct mem_region region (0, 0);
169   struct mem_region *m;
170   CORE_ADDR lo;
171   CORE_ADDR hi;
172   int ix;
173
174   require_target_regions ();
175
176   /* First we initialize LO and HI so that they describe the entire
177      memory space.  As we process the memory region chain, they are
178      redefined to describe the minimal region containing ADDR.  LO
179      and HI are used in the case where no memory region is defined
180      that contains ADDR.  If a memory region is disabled, it is
181      treated as if it does not exist.  The initial values for LO
182      and HI represent the bottom and top of memory.  */
183
184   lo = 0;
185   hi = 0;
186
187   /* Either find memory range containing ADDR, or set LO and HI
188      to the nearest boundaries of an existing memory range.
189      
190      If we ever want to support a huge list of memory regions, this
191      check should be replaced with a binary search (probably using
192      VEC_lower_bound).  */
193   for (mem_region &m : *mem_region_list)
194     {
195       if (m.enabled_p == 1)
196         {
197           /* If the address is in the memory region, return that
198              memory range.  */
199           if (addr >= m.lo && (addr < m.hi || m.hi == 0))
200             return &m;
201
202           /* This (correctly) won't match if m->hi == 0, representing
203              the top of the address space, because CORE_ADDR is unsigned;
204              no value of LO is less than zero.  */
205           if (addr >= m.hi && lo < m.hi)
206             lo = m.hi;
207
208           /* This will never set HI to zero; if we're here and ADDR
209              is at or below M, and the region starts at zero, then ADDR
210              would have been in the region.  */
211           if (addr <= m.lo && (hi == 0 || hi > m.lo))
212             hi = m.lo;
213         }
214     }
215
216   /* Because no region was found, we must cons up one based on what
217      was learned above.  */
218   region.lo = lo;
219   region.hi = hi;
220
221   /* When no memory map is defined at all, we always return 
222      'default_mem_attrib', so that we do not make all memory 
223      inaccessible for targets that don't provide a memory map.  */
224   if (inaccessible_by_default && !mem_region_list->empty ())
225     region.attrib = mem_attrib::unknown ();
226   else
227     region.attrib = mem_attrib ();
228
229   return &region;
230 }
231
232 /* Invalidate any memory regions fetched from the target.  */
233
234 void
235 invalidate_target_mem_regions (void)
236 {
237   if (!target_mem_regions_valid)
238     return;
239
240   target_mem_regions_valid = false;
241   target_mem_region_list.clear ();
242 }
243
244 /* Clear user-defined memory region list.  */
245
246 static void
247 user_mem_clear (void)
248 {
249   user_mem_region_list.clear ();
250 }
251 \f
252
253 static void
254 mem_command (const char *args, int from_tty)
255 {
256   CORE_ADDR lo, hi;
257
258   if (!args)
259     error_no_arg (_("No mem"));
260
261   /* For "mem auto", switch back to using a target provided list.  */
262   if (strcmp (args, "auto") == 0)
263     {
264       if (mem_use_target ())
265         return;
266
267       user_mem_clear ();
268       mem_region_list = &target_mem_region_list;
269
270       return;
271     }
272
273   require_user_regions (from_tty);
274
275   std::string tok = extract_arg (&args);
276   if (tok == "")
277     error (_("no lo address"));
278   lo = parse_and_eval_address (tok.c_str ());
279
280   tok = extract_arg (&args);
281   if (tok == "")
282     error (_("no hi address"));
283   hi = parse_and_eval_address (tok.c_str ());
284
285   mem_attrib attrib;
286   while ((tok = extract_arg (&args)) != "")
287     {
288       if (tok == "rw")
289         attrib.mode = MEM_RW;
290       else if (tok == "ro")
291         attrib.mode = MEM_RO;
292       else if (tok == "wo")
293         attrib.mode = MEM_WO;
294
295       else if (tok == "8")
296         attrib.width = MEM_WIDTH_8;
297       else if (tok == "16")
298         {
299           if ((lo % 2 != 0) || (hi % 2 != 0))
300             error (_("region bounds not 16 bit aligned"));
301           attrib.width = MEM_WIDTH_16;
302         }
303       else if (tok == "32")
304         {
305           if ((lo % 4 != 0) || (hi % 4 != 0))
306             error (_("region bounds not 32 bit aligned"));
307           attrib.width = MEM_WIDTH_32;
308         }
309       else if (tok == "64")
310         {
311           if ((lo % 8 != 0) || (hi % 8 != 0))
312             error (_("region bounds not 64 bit aligned"));
313           attrib.width = MEM_WIDTH_64;
314         }
315
316 #if 0
317       else if (tok == "hwbreak")
318         attrib.hwbreak = 1;
319       else if (tok == "swbreak")
320         attrib.hwbreak = 0;
321 #endif
322
323       else if (tok == "cache")
324         attrib.cache = 1;
325       else if (tok == "nocache")
326         attrib.cache = 0;
327
328 #if 0
329       else if (tok == "verify")
330         attrib.verify = 1;
331       else if (tok == "noverify")
332         attrib.verify = 0;
333 #endif
334
335       else
336         error (_("unknown attribute: %s"), tok.c_str ());
337     }
338
339   create_user_mem_region (lo, hi, attrib);
340 }
341 \f
342
343 static void
344 info_mem_command (char *args, int from_tty)
345 {
346   if (mem_use_target ())
347     printf_filtered (_("Using memory regions provided by the target.\n"));
348   else
349     printf_filtered (_("Using user-defined memory regions.\n"));
350
351   require_target_regions ();
352
353   if (mem_region_list->empty ())
354     {
355       printf_unfiltered (_("There are no memory regions defined.\n"));
356       return;
357     }
358
359   printf_filtered ("Num ");
360   printf_filtered ("Enb ");
361   printf_filtered ("Low Addr   ");
362   if (gdbarch_addr_bit (target_gdbarch ()) > 32)
363     printf_filtered ("        ");
364   printf_filtered ("High Addr  ");
365   if (gdbarch_addr_bit (target_gdbarch ()) > 32)
366     printf_filtered ("        ");
367   printf_filtered ("Attrs ");
368   printf_filtered ("\n");
369
370   for (const mem_region &m : *mem_region_list)
371     {
372       const char *tmp;
373
374       printf_filtered ("%-3d %-3c\t",
375                        m.number,
376                        m.enabled_p ? 'y' : 'n');
377       if (gdbarch_addr_bit (target_gdbarch ()) <= 32)
378         tmp = hex_string_custom (m.lo, 8);
379       else
380         tmp = hex_string_custom (m.lo, 16);
381       
382       printf_filtered ("%s ", tmp);
383
384       if (gdbarch_addr_bit (target_gdbarch ()) <= 32)
385         {
386           if (m.hi == 0)
387             tmp = "0x100000000";
388           else
389             tmp = hex_string_custom (m.hi, 8);
390         }
391       else
392         {
393           if (m.hi == 0)
394             tmp = "0x10000000000000000";
395           else
396             tmp = hex_string_custom (m.hi, 16);
397         }
398
399       printf_filtered ("%s ", tmp);
400
401       /* Print a token for each attribute.
402
403        * FIXME: Should we output a comma after each token?  It may
404        * make it easier for users to read, but we'd lose the ability
405        * to cut-and-paste the list of attributes when defining a new
406        * region.  Perhaps that is not important.
407        *
408        * FIXME: If more attributes are added to GDB, the output may
409        * become cluttered and difficult for users to read.  At that
410        * time, we may want to consider printing tokens only if they
411        * are different from the default attribute.  */
412
413       switch (m.attrib.mode)
414         {
415         case MEM_RW:
416           printf_filtered ("rw ");
417           break;
418         case MEM_RO:
419           printf_filtered ("ro ");
420           break;
421         case MEM_WO:
422           printf_filtered ("wo ");
423           break;
424         case MEM_FLASH:
425           printf_filtered ("flash blocksize 0x%x ", m.attrib.blocksize);
426           break;
427         }
428
429       switch (m.attrib.width)
430         {
431         case MEM_WIDTH_8:
432           printf_filtered ("8 ");
433           break;
434         case MEM_WIDTH_16:
435           printf_filtered ("16 ");
436           break;
437         case MEM_WIDTH_32:
438           printf_filtered ("32 ");
439           break;
440         case MEM_WIDTH_64:
441           printf_filtered ("64 ");
442           break;
443         case MEM_WIDTH_UNSPECIFIED:
444           break;
445         }
446
447 #if 0
448       if (attrib->hwbreak)
449         printf_filtered ("hwbreak");
450       else
451         printf_filtered ("swbreak");
452 #endif
453
454       if (m.attrib.cache)
455         printf_filtered ("cache ");
456       else
457         printf_filtered ("nocache ");
458
459 #if 0
460       if (attrib->verify)
461         printf_filtered ("verify ");
462       else
463         printf_filtered ("noverify ");
464 #endif
465
466       printf_filtered ("\n");
467
468       gdb_flush (gdb_stdout);
469     }
470 }
471 \f
472
473 /* Enable the memory region number NUM.  */
474
475 static void
476 mem_enable (int num)
477 {
478   for (mem_region &m : *mem_region_list)
479     if (m.number == num)
480       {
481         m.enabled_p = 1;
482         return;
483       }
484   printf_unfiltered (_("No memory region number %d.\n"), num);
485 }
486
487 static void
488 enable_mem_command (const char *args, int from_tty)
489 {
490   require_user_regions (from_tty);
491
492   target_dcache_invalidate ();
493
494   if (args == NULL || *args == '\0')
495     { /* Enable all mem regions.  */
496       for (mem_region &m : *mem_region_list)
497         m.enabled_p = 1;
498     }
499   else
500     {
501       number_or_range_parser parser (args);
502       while (!parser.finished ())
503         {
504           int num = parser.get_number ();
505           mem_enable (num);
506         }
507     }
508 }
509 \f
510
511 /* Disable the memory region number NUM.  */
512
513 static void
514 mem_disable (int num)
515 {
516   for (mem_region &m : *mem_region_list)
517     if (m.number == num)
518       {
519         m.enabled_p = 0;
520         return;
521       }
522   printf_unfiltered (_("No memory region number %d.\n"), num);
523 }
524
525 static void
526 disable_mem_command (const char *args, int from_tty)
527 {
528   require_user_regions (from_tty);
529
530   target_dcache_invalidate ();
531
532   if (args == NULL || *args == '\0')
533     {
534       struct mem_region *m;
535       int ix;
536
537       for (mem_region &m : *mem_region_list)
538         m.enabled_p = false;
539     }
540   else
541     {
542       number_or_range_parser parser (args);
543       while (!parser.finished ())
544         {
545           int num = parser.get_number ();
546           mem_disable (num);
547         }
548     }
549 }
550
551 /* Delete the memory region number NUM.  */
552
553 static void
554 mem_delete (int num)
555 {
556   struct mem_region *m;
557   int ix;
558
559   if (!mem_region_list)
560     {
561       printf_unfiltered (_("No memory region number %d.\n"), num);
562       return;
563     }
564
565   auto it = std::remove_if (mem_region_list->begin (), mem_region_list->end (),
566                             [num] (const mem_region &m)
567     {
568       return m.number == num;
569     });
570
571   if (it != mem_region_list->end ())
572     mem_region_list->erase (it);
573   else
574     printf_unfiltered (_("No memory region number %d.\n"), num);
575 }
576
577 static void
578 delete_mem_command (const char *args, int from_tty)
579 {
580   require_user_regions (from_tty);
581
582   target_dcache_invalidate ();
583
584   if (args == NULL || *args == '\0')
585     {
586       if (query (_("Delete all memory regions? ")))
587         user_mem_clear ();
588       dont_repeat ();
589       return;
590     }
591
592   number_or_range_parser parser (args);
593   while (!parser.finished ())
594     {
595       int num = parser.get_number ();
596       mem_delete (num);
597     }
598
599   dont_repeat ();
600 }
601
602 static void
603 dummy_cmd (const char *args, int from_tty)
604 {
605 }
606
607 static struct cmd_list_element *mem_set_cmdlist;
608 static struct cmd_list_element *mem_show_cmdlist;
609
610 void
611 _initialize_mem (void)
612 {
613   add_com ("mem", class_vars, mem_command, _("\
614 Define attributes for memory region or reset memory region handling to\n\
615 target-based.\n\
616 Usage: mem auto\n\
617        mem <lo addr> <hi addr> [<mode> <width> <cache>],\n\
618 where <mode>  may be rw (read/write), ro (read-only) or wo (write-only),\n\
619       <width> may be 8, 16, 32, or 64, and\n\
620       <cache> may be cache or nocache"));
621
622   add_cmd ("mem", class_vars, enable_mem_command, _("\
623 Enable memory region.\n\
624 Arguments are the code numbers of the memory regions to enable.\n\
625 Usage: enable mem <code number>...\n\
626 Do \"info mem\" to see current list of code numbers."), &enablelist);
627
628   add_cmd ("mem", class_vars, disable_mem_command, _("\
629 Disable memory region.\n\
630 Arguments are the code numbers of the memory regions to disable.\n\
631 Usage: disable mem <code number>...\n\
632 Do \"info mem\" to see current list of code numbers."), &disablelist);
633
634   add_cmd ("mem", class_vars, delete_mem_command, _("\
635 Delete memory region.\n\
636 Arguments are the code numbers of the memory regions to delete.\n\
637 Usage: delete mem <code number>...\n\
638 Do \"info mem\" to see current list of code numbers."), &deletelist);
639
640   add_info ("mem", info_mem_command,
641             _("Memory region attributes"));
642
643   add_prefix_cmd ("mem", class_vars, dummy_cmd, _("\
644 Memory regions settings"),
645                   &mem_set_cmdlist, "set mem ",
646                   0/* allow-unknown */, &setlist);
647   add_prefix_cmd ("mem", class_vars, dummy_cmd, _("\
648 Memory regions settings"),
649                   &mem_show_cmdlist, "show mem  ",
650                   0/* allow-unknown */, &showlist);
651
652   add_setshow_boolean_cmd ("inaccessible-by-default", no_class,
653                                   &inaccessible_by_default, _("\
654 Set handling of unknown memory regions."), _("\
655 Show handling of unknown memory regions."), _("\
656 If on, and some memory map is defined, debugger will emit errors on\n\
657 accesses to memory not defined in the memory map. If off, accesses to all\n\
658 memory addresses will be allowed."),
659                                 NULL,
660                                 show_inaccessible_by_default,
661                                 &mem_set_cmdlist,
662                                 &mem_show_cmdlist);
663 }