* gas/config/tc-avr.c: Change ISA for devices with USB support to
[external/binutils.git] / gdb / testsuite / gdb.base / find-unmapped.c
1 /* This testcase is part of GDB, the GNU debugger.
2
3    Copyright 2012-2013 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 <stdlib.h>
19 #include <stdio.h>
20 #include <sys/mman.h>
21 #include <unistd.h>
22 #include <string.h>
23
24 #define CHUNK_SIZE 16000 /* same as findcmd.c's */
25
26 void *global_var_0;
27 void *global_var_1;
28 void *global_var_2;
29
30 void
31 breakpt ()
32 {
33   /* Nothing. */
34 }
35
36 int
37 main (void)
38 {
39   void *p;
40   size_t pg_size;
41   int pg_count;
42   void *unmapped_page, *last_mapped_page, *first_mapped_page;
43
44   /*
45     Map enough pages to cover at least CHUNK_SIZE, and one extra page.  We
46     then unmap the last page.
47
48     From gdb we can then perform find commands into unmapped region, gdb
49     should give an error.
50
51     .-- global_var_0  .-- global_var_1
52     |                 |   .-- global_var_2
53     |                 |   |
54     .----.----.----.----.----.
55     |    |    |    |    |    |
56     '----'----'----'----'----'
57     |<- CHUNK_SIZE ->|
58
59     If CHUNK_SIZE equals page size then we'll get 3 pages, and if
60     CHUNK_SIZE is less than page size we'll get 2 pages.  The test will
61     still work in these cases.
62
63     (1) We do a find from global_var_0 to global_var_2, this will fail when
64     loading the second chunk, as we know at least CHUNK_SIZE bytes are in
65     mapped space.
66
67     (2) We do a find from global_var_1 to global_var_2, this will fail when
68     loading the first chunk, assuming the CHUNK_SIZE is at least 16 bytes.
69
70     (3) We do a find from global_var_2 to (global_var_2 + 16), this too
71     will fail when loading the first chunk regardless of the chunk size.
72   */
73
74   pg_size = getpagesize ();
75   /* The +2 ensures the extra page.  */
76   pg_count = CHUNK_SIZE / pg_size + 2;
77
78   p = mmap (0, pg_count * pg_size, PROT_READ|PROT_WRITE,
79             MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
80   if (p == MAP_FAILED)
81     {
82       perror ("mmap");
83       return EXIT_FAILURE;
84     }
85
86   memset (p, 0, pg_count * pg_size);
87
88   if (munmap (p + (pg_count - 1) * pg_size, pg_size) == -1)
89     {
90       perror ("munmap");
91       return EXIT_FAILURE;
92     }
93
94   first_mapped_page = p;
95   last_mapped_page = p + (pg_count - 2) * pg_size;
96   unmapped_page = last_mapped_page + pg_size;
97
98   /* Setup global variables we reference from gdb.  */
99   global_var_0 = first_mapped_page;
100   global_var_1 = unmapped_page - 16;
101   global_var_2 = unmapped_page + 16;
102
103   breakpt ();
104
105   return EXIT_SUCCESS;
106 }