1 /* Memory attributes support, for GDB.
2 Copyright 2001 Free Software Foundation, Inc.
4 This file is part of GDB.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
28 #include "gdb_string.h"
30 /* FIXME: While this conflicts with the enum defined in breakpoint.h,
31 I used them to be consistant with how breakpoints, tracepoints, and
32 displays are implemented. It doesn't lose now because breakpoint.h
40 const struct mem_attrib default_mem_attrib
=
43 MEM_WIDTH_UNSPECIFIED
,
49 static struct mem_region
*mem_region_chain
= NULL
;
50 static int mem_number
= 0;
52 static struct mem_region
*
53 create_mem_region (CORE_ADDR lo
, CORE_ADDR hi
,
54 const struct mem_attrib
*attrib
)
56 struct mem_region
*n
, *new;
60 printf_unfiltered ("invalid memory region\n");
67 /* overlapping node */
68 if ((lo
>= n
->lo
&& lo
<= n
->hi
) ||
69 (hi
>= n
->lo
&& hi
<= n
->hi
))
71 printf_unfiltered ("overlapping memory region\n");
76 new = xmalloc (sizeof (struct mem_region
));
79 new->number
= ++mem_number
;
80 new->status
= enabled
;
81 new->attrib
= *attrib
;
83 /* link in new node */
84 new->next
= mem_region_chain
;
85 mem_region_chain
= new;
91 delete_mem_region (struct mem_region
*m
)
97 * Look up the memory region cooresponding to ADDR.
100 lookup_mem_region (CORE_ADDR addr
)
102 static struct mem_region region
;
103 struct mem_region
*m
;
107 /* First we initialize LO and HI so that they describe the entire
108 memory space. As we process the memory region chain, they are
109 redefined to describe the minimal region containing ADDR. LO
110 and HI are used in the case where no memory region is defined
111 that contains ADDR. If a memory region is disabled, it is
112 treated as if it does not exist. */
115 hi
= (CORE_ADDR
) ~ 0;
117 for (m
= mem_region_chain
; m
; m
= m
->next
)
119 if (m
->status
== enabled
)
121 if (addr
>= m
->lo
&& addr
< m
->hi
)
124 if (addr
>= m
->hi
&& lo
< m
->hi
)
127 if (addr
<= m
->lo
&& hi
> m
->lo
)
132 /* Because no region was found, we must cons up one based on what
133 was learned above. */
136 region
.attrib
= default_mem_attrib
;
142 mem_command (char *args
, int from_tty
)
146 struct mem_attrib attrib
;
149 error_no_arg ("No mem");
151 tok
= strtok (args
, " \t");
153 error ("no lo address");
154 lo
= parse_and_eval_address (tok
);
156 tok
= strtok (NULL
, " \t");
158 error ("no hi address");
159 hi
= parse_and_eval_address (tok
);
161 attrib
= default_mem_attrib
;
162 while ((tok
= strtok (NULL
, " \t")) != NULL
)
164 if (strcmp (tok
, "rw") == 0)
165 attrib
.mode
= MEM_RW
;
166 else if (strcmp (tok
, "ro") == 0)
167 attrib
.mode
= MEM_RO
;
168 else if (strcmp (tok
, "wo") == 0)
169 attrib
.mode
= MEM_WO
;
171 else if (strcmp (tok
, "8") == 0)
172 attrib
.width
= MEM_WIDTH_8
;
173 else if (strcmp (tok
, "16") == 0)
175 if ((lo
% 2 != 0) || (hi
% 2 != 0))
176 error ("region bounds not 16 bit aligned");
177 attrib
.width
= MEM_WIDTH_16
;
179 else if (strcmp (tok
, "32") == 0)
181 if ((lo
% 4 != 0) || (hi
% 4 != 0))
182 error ("region bounds not 32 bit aligned");
183 attrib
.width
= MEM_WIDTH_32
;
185 else if (strcmp (tok
, "64") == 0)
187 if ((lo
% 8 != 0) || (hi
% 8 != 0))
188 error ("region bounds not 64 bit aligned");
189 attrib
.width
= MEM_WIDTH_64
;
193 else if (strcmp (tok
, "hwbreak") == 0)
194 attrib
.hwbreak
= true;
195 else if (strcmp (tok
, "swbreak") == 0)
196 attrib
.hwbreak
= false;
199 else if (strcmp (tok
, "cache") == 0)
201 else if (strcmp (tok
, "nocache") == 0)
202 attrib
.cache
= false;
205 else if (strcmp (tok
, "verify") == 0)
206 attrib
.verify
= true;
207 else if (strcmp (tok
, "noverify") == 0)
208 attrib
.verify
= false;
212 error ("unknown attribute: %s", tok
);
215 create_mem_region (lo
, hi
, &attrib
);
220 mem_info_command (char *args
, int from_tty
)
222 struct mem_region
*m
;
223 struct mem_attrib
*attrib
;
225 if (!mem_region_chain
)
227 printf_unfiltered ("There are no memory regions defined.\n");
231 printf_filtered ("Memory regions now in effect:\n");
232 for (m
= mem_region_chain
; m
; m
= m
->next
)
234 printf_filtered ("%d: %c\t",
236 m
->status
? 'y' : 'n');
237 printf_filtered ("%s - ",
238 local_hex_string_custom ((unsigned long) m
->lo
, "08l"));
239 printf_filtered ("%s\t",
240 local_hex_string_custom ((unsigned long) m
->hi
, "08l"));
242 /* Print a token for each attribute.
244 * FIXME: Should we output a comma after each token? It may
245 * make it easier for users to read, but we'd lose the ability
246 * to cut-and-paste the list of attributes when defining a new
247 * region. Perhaps that is not important.
249 * FIXME: If more attributes are added to GDB, the output may
250 * become cluttered and difficult for users to read. At that
251 * time, we may want to consider printing tokens only if they
252 * are different from the default attribute. */
255 switch (attrib
->mode
)
258 printf_filtered ("rw ");
261 printf_filtered ("ro ");
264 printf_filtered ("wo ");
268 switch (attrib
->width
)
271 printf_filtered ("8 ");
274 printf_filtered ("16 ");
277 printf_filtered ("32 ");
280 printf_filtered ("64 ");
282 case MEM_WIDTH_UNSPECIFIED
:
288 printf_filtered ("hwbreak");
290 printf_filtered ("swbreak");
294 printf_filtered ("cache ");
296 printf_filtered ("nocache ");
300 printf_filtered ("verify ");
302 printf_filtered ("noverify ");
305 printf_filtered ("\n");
307 gdb_flush (gdb_stdout
);
312 /* Enable the memory region number NUM. */
317 struct mem_region
*m
;
319 for (m
= mem_region_chain
; m
; m
= m
->next
)
320 if (m
->number
== num
)
325 printf_unfiltered ("No memory region number %d.\n", num
);
329 mem_enable_command (char *args
, int from_tty
)
334 struct mem_region
*m
;
336 dcache_invalidate (target_dcache
);
340 for (m
= mem_region_chain
; m
; m
= m
->next
)
347 while (*p1
>= '0' && *p1
<= '9')
349 if (*p1
&& *p1
!= ' ' && *p1
!= '\t')
350 error ("Arguments must be memory region numbers.");
356 while (*p
== ' ' || *p
== '\t')
362 /* Disable the memory region number NUM. */
365 mem_disable (int num
)
367 struct mem_region
*m
;
369 for (m
= mem_region_chain
; m
; m
= m
->next
)
370 if (m
->number
== num
)
372 m
->status
= disabled
;
375 printf_unfiltered ("No memory region number %d.\n", num
);
379 mem_disable_command (char *args
, int from_tty
)
384 struct mem_region
*m
;
386 dcache_invalidate (target_dcache
);
390 for (m
= mem_region_chain
; m
; m
= m
->next
)
391 m
->status
= disabled
;
397 while (*p1
>= '0' && *p1
<= '9')
399 if (*p1
&& *p1
!= ' ' && *p1
!= '\t')
400 error ("Arguments must be memory region numbers.");
406 while (*p
== ' ' || *p
== '\t')
411 /* Clear memory region list */
416 struct mem_region
*m
;
418 while ((m
= mem_region_chain
) != 0)
420 mem_region_chain
= m
->next
;
421 delete_mem_region (m
);
425 /* Delete the memory region number NUM. */
430 struct mem_region
*m1
, *m
;
432 if (!mem_region_chain
)
434 printf_unfiltered ("No memory region number %d.\n", num
);
438 if (mem_region_chain
->number
== num
)
440 m1
= mem_region_chain
;
441 mem_region_chain
= m1
->next
;
442 delete_mem_region (m1
);
445 for (m
= mem_region_chain
; m
->next
; m
= m
->next
)
447 if (m
->next
->number
== num
)
451 delete_mem_region (m1
);
458 mem_delete_command (char *args
, int from_tty
)
464 dcache_invalidate (target_dcache
);
468 if (query ("Delete all memory regions? "))
477 while (*p1
>= '0' && *p1
<= '9')
479 if (*p1
&& *p1
!= ' ' && *p1
!= '\t')
480 error ("Arguments must be memory region numbers.");
486 while (*p
== ' ' || *p
== '\t')
496 add_com ("mem", class_vars
, mem_command
,
497 "Define attributes for memory region.");
499 add_cmd ("mem", class_vars
, mem_enable_command
,
500 "Enable memory region.\n\
501 Arguments are the code numbers of the memory regions to enable.\n\
502 Do \"info mem\" to see current list of code numbers.", &enablelist
);
504 add_cmd ("mem", class_vars
, mem_disable_command
,
505 "Disable memory region.\n\
506 Arguments are the code numbers of the memory regions to disable.\n\
507 Do \"info mem\" to see current list of code numbers.", &disablelist
);
509 add_cmd ("mem", class_vars
, mem_delete_command
,
510 "Delete memory region.\n\
511 Arguments are the code numbers of the memory regions to delete.\n\
512 Do \"info mem\" to see current list of code numbers.", &deletelist
);
514 add_info ("mem", mem_info_command
,
515 "Memory region attributes");