xref: /openbsd-src/regress/sys/uvm/mmap_noreplace/mmap_noreplace.c (revision 7f7d72468670c65830d0161e3ac169d5419d1887)
1*7f7d7246Smatthew /*	$OpenBSD: mmap_noreplace.c,v 1.1 2014/06/19 19:34:22 matthew Exp $	*/
2*7f7d7246Smatthew /*
3*7f7d7246Smatthew  * Copyright (c) 2014 Google Inc.
4*7f7d7246Smatthew  *
5*7f7d7246Smatthew  * Permission to use, copy, modify, and distribute this software for any
6*7f7d7246Smatthew  * purpose with or without fee is hereby granted, provided that the above
7*7f7d7246Smatthew  * copyright notice and this permission notice appear in all copies.
8*7f7d7246Smatthew  *
9*7f7d7246Smatthew  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10*7f7d7246Smatthew  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11*7f7d7246Smatthew  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12*7f7d7246Smatthew  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13*7f7d7246Smatthew  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14*7f7d7246Smatthew  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15*7f7d7246Smatthew  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16*7f7d7246Smatthew  */
17*7f7d7246Smatthew 
18*7f7d7246Smatthew #include <sys/mman.h>
19*7f7d7246Smatthew #include <assert.h>
20*7f7d7246Smatthew #include <string.h>
21*7f7d7246Smatthew #include <unistd.h>
22*7f7d7246Smatthew 
23*7f7d7246Smatthew #define CHECK(a) assert(a)
24*7f7d7246Smatthew #define CHECK_EQ(a, b) assert((a) == (b))
25*7f7d7246Smatthew #define CHECK_NE(a, b) assert((a) != (b))
26*7f7d7246Smatthew #define CHECK_GE(a, b) assert((a) >= (b))
27*7f7d7246Smatthew 
28*7f7d7246Smatthew int
ismemset(void * b,int c,size_t n)29*7f7d7246Smatthew ismemset(void *b, int c, size_t n)
30*7f7d7246Smatthew {
31*7f7d7246Smatthew 	unsigned char *p = b;
32*7f7d7246Smatthew 	size_t i;
33*7f7d7246Smatthew 	for (i = 0; i < n; i++)
34*7f7d7246Smatthew 		if (p[i] != c)
35*7f7d7246Smatthew 			return (0);
36*7f7d7246Smatthew 	return (1);
37*7f7d7246Smatthew }
38*7f7d7246Smatthew 
39*7f7d7246Smatthew int
main()40*7f7d7246Smatthew main()
41*7f7d7246Smatthew {
42*7f7d7246Smatthew 	char *p;
43*7f7d7246Smatthew 	long pagesize;
44*7f7d7246Smatthew 
45*7f7d7246Smatthew 	pagesize = sysconf(_SC_PAGESIZE);
46*7f7d7246Smatthew 	CHECK_GE(pagesize, 1);
47*7f7d7246Smatthew 
48*7f7d7246Smatthew 	/* Allocate three pages of anonymous memory. */
49*7f7d7246Smatthew 	p = mmap(NULL, 3 * pagesize, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
50*7f7d7246Smatthew 	CHECK_NE(MAP_FAILED, p);
51*7f7d7246Smatthew 
52*7f7d7246Smatthew 	/* Initialize memory to all 1 bytes. */
53*7f7d7246Smatthew 	memset(p, 1, 3 * pagesize);
54*7f7d7246Smatthew 	CHECK(ismemset(p, 1, 3 * pagesize));
55*7f7d7246Smatthew 
56*7f7d7246Smatthew 	/* Map new anonymous memory over the second page. */
57*7f7d7246Smatthew 	CHECK_EQ(p + pagesize, mmap(p + pagesize, pagesize,
58*7f7d7246Smatthew 	    PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON|MAP_FIXED, -1, 0));
59*7f7d7246Smatthew 
60*7f7d7246Smatthew 	/* Verify the second page is zero'd out, and the others are unscathed. */
61*7f7d7246Smatthew 	CHECK(ismemset(p, 1, pagesize));
62*7f7d7246Smatthew 	CHECK(ismemset(p + pagesize, 0, pagesize));
63*7f7d7246Smatthew 	CHECK(ismemset(p + 2 * pagesize, 1, pagesize));
64*7f7d7246Smatthew 
65*7f7d7246Smatthew 	/* Re-initialized memory. */
66*7f7d7246Smatthew 	memset(p, 1, 3 * pagesize);
67*7f7d7246Smatthew 	CHECK(ismemset(p, 1, 3 * pagesize));
68*7f7d7246Smatthew 
69*7f7d7246Smatthew 	/* Try to map over second page with __MAP_NOREPLACE; should fail. */
70*7f7d7246Smatthew 	CHECK_EQ(MAP_FAILED, mmap(p, pagesize, PROT_READ|PROT_WRITE,
71*7f7d7246Smatthew 	    MAP_PRIVATE|MAP_ANON|MAP_FIXED|__MAP_NOREPLACE, -1, 0));
72*7f7d7246Smatthew 
73*7f7d7246Smatthew 	/* Verify the pages are still set. */
74*7f7d7246Smatthew 	CHECK(ismemset(p, 1, 3 * pagesize));
75*7f7d7246Smatthew 
76*7f7d7246Smatthew 	return (0);
77*7f7d7246Smatthew }
78