1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
/* This testcase is part of GDB, the GNU debugger.
Copyright 2012 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include <stdlib.h>
#include <stdio.h>
#include <sys/mman.h>
#include <unistd.h>
#include <string.h>
#define CHUNK_SIZE 16000 /* same as findcmd.c's */
void *global_var_0;
void *global_var_1;
void *global_var_2;
void
breakpt ()
{
/* Nothing. */
}
int
main (void)
{
void *p;
size_t pg_size;
int pg_count;
void *unmapped_page, *last_mapped_page, *first_mapped_page;
/*
Map enough pages to cover at least CHUNK_SIZE, and one extra page. We
then unmap the last page.
From gdb we can then perform find commands into unmapped region, gdb
should give an error.
.-- global_var_0 .-- global_var_1
| | .-- global_var_2
| | |
.----.----.----.----.----.
| | | | | |
'----'----'----'----'----'
|<- CHUNK_SIZE ->|
If CHUNK_SIZE equals page size then we'll get 3 pages, and if
CHUNK_SIZE is less than page size we'll get 2 pages. The test will
still work in these cases.
(1) We do a find from global_var_0 to global_var_2, this will fail when
loading the second chunk, as we know at least CHUNK_SIZE bytes are in
mapped space.
(2) We do a find from global_var_1 to global_var_2, this will fail when
loading the first chunk, assuming the CHUNK_SIZE is at least 16 bytes.
(3) We do a find from global_var_2 to (global_var_2 + 16), this too
will fail when loading the first chunk regardless of the chunk size.
*/
pg_size = getpagesize ();
/* The +2 ensures the extra page. */
pg_count = CHUNK_SIZE / pg_size + 2;
p = mmap (0, pg_count * pg_size, PROT_READ|PROT_WRITE,
MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
if (p == MAP_FAILED)
{
perror ("mmap");
return EXIT_FAILURE;
}
memset (p, 0, pg_count * pg_size);
if (munmap (p + (pg_count - 1) * pg_size, pg_size) == -1)
{
perror ("munmap");
return EXIT_FAILURE;
}
first_mapped_page = p;
last_mapped_page = p + (pg_count - 2) * pg_size;
unmapped_page = last_mapped_page + pg_size;
/* Setup global variables we reference from gdb. */
global_var_0 = first_mapped_page;
global_var_1 = unmapped_page - 16;
global_var_2 = unmapped_page + 16;
breakpt ();
return EXIT_SUCCESS;
}
|