/* This testcase is part of GDB, the GNU debugger.
Copyright 2012-2020 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 . */
#include
#include
#include
#include
#include
#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;
}