blob: 8bef8319447d320cd63b1306f50db804486379e9 [file] [log] [blame]
sewardj45f4e7c2005-09-27 19:20:21 +00001#define _GNU_SOURCE
2
3#include <stdio.h>
sewardj4bdd5052006-10-17 01:28:48 +00004
5#if defined(_AIX)
6
7int main ( void )
8{
9 printf("This test is Linux-specific.\n");
10 return 0;
11}
12
13#else
14
sewardj45f4e7c2005-09-27 19:20:21 +000015#include <sys/mman.h>
16#include <assert.h>
17#include <stdlib.h>
18#include <sys/types.h>
19#include <unistd.h>
20#include <errno.h>
21#include <syscall.h>
22
23
24#ifndef REMAP_FIXED
25#define MREMAP_FIXED 2
26#endif
27
28
29static int PAGE;
30
31void mapanon_fixed ( void* start, size_t length )
32{
33 void* r = mmap(start, length, PROT_NONE,
34 MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, 0,0);
35 assert(r != MAP_FAILED);
36 assert(r == start);
37}
38
39void unmap_and_check ( void* start, size_t length )
40{
41 int r = munmap( start, length );
42 assert(r == 0);
43}
44
45char* workingarea = NULL;
46char* try_dst = NULL;
47
48// set up working area so expansion limit is 20*PAGE
49//
50// | 10 | 20 | 10 | 60 |
51// | pre | src | FREE | post |
52//
53// A suitable attempted fixed dst is workingarea + 150*PAGE.
54
55char* setup ( void* other_stuff, int other_len )
56{
57 if (!workingarea) {
58 workingarea = mmap(0, 200*PAGE, PROT_NONE,
59 MAP_ANONYMOUS|MAP_PRIVATE, 0,0);
60 assert(workingarea);
61 try_dst = workingarea + 150*PAGE;
62 unmap_and_check(workingarea, 200*PAGE);
63 }
64
65 if (other_stuff) {
66 unmap_and_check(other_stuff, other_len);
67 }
68
69 // get rid of the old working area
70 unmap_and_check( workingarea, 200*PAGE);
71
72 // pre block
73 mapanon_fixed( workingarea + 0*PAGE, 9*PAGE);
74
75 // the area
76 mapanon_fixed( workingarea + 10*PAGE, 20*PAGE );
77
78 // upper half
79 mapanon_fixed( workingarea + 40*PAGE, 60*PAGE );
80
81 return workingarea + 10*PAGE;
82}
83
84/* show the working area */
85void show ( void )
86{
87 int i,r;
88 for (i = 0; i < 200; i++) {
89 r = mprotect( workingarea + i * PAGE, PAGE, PROT_NONE );
90 printf("%c", r == 0 ? 'X' : '.');
91 if (i == 49 || i == 99 || i == 149) printf("\n");
92 }
93 printf("\n");
94}
95
96
97char* dst = NULL;
98char* src = NULL;
99char* dst_impossible = NULL;
100
101
102char* identify ( char* p )
103{
104 if (p == dst) return "dst";
105 if (p == src) return "src";
106 if (p == dst_impossible) return "dst_imp!";
107 if (p == try_dst) return "dst_poss";
108 return "other";
109}
110
111int main ( void )
112{
113 int alocal, maymove, fixed, nsi, dstpossible;
sewardj45f4e7c2005-09-27 19:20:21 +0000114 int newsizes[6] = { 19, 20, 21, 29, 30, 31 };
115
116 char* tidythis = NULL;
117 int tidylen = 0;
118 int firsttime = 1;
119 char buf[100];
120
sewardjae986ca2005-10-12 12:53:20 +0000121 dst_impossible = (char*)(&alocal) + 500 * 1000 * 1000;
122
sewardj45f4e7c2005-09-27 19:20:21 +0000123 PAGE = sysconf(_SC_PAGESIZE);
124
125 for (maymove = 0; maymove <= 1 ; maymove++) {
126 for (fixed = 0; fixed <= 1; fixed++) {
127 printf("\n");
128 for (nsi = 0; nsi < 6; nsi++) {
129 for (dstpossible = 0; dstpossible <= 1; dstpossible++) {
130
sewardjae986ca2005-10-12 12:53:20 +0000131 char* r;
sewardj45f4e7c2005-09-27 19:20:21 +0000132 int newsize = newsizes[nsi] * PAGE;
133 int flags = (maymove ? MREMAP_MAYMOVE : 0) |
134 (fixed ? MREMAP_FIXED : 0);
135 dst = dstpossible ? try_dst : dst_impossible;
136 src = setup( tidythis, tidylen );
137
sewardj45f4e7c2005-09-27 19:20:21 +0000138 if (firsttime) {
139 printf("dst_possible = %p\n", try_dst );
140 printf("dst_impossible = %p\n", dst_impossible );
141 printf(" src = %p\n", src);
142 printf("\n");
143 sprintf(buf, "cat /proc/%d/maps", getpid());
144 if (0) system(buf);
145 firsttime = 0;
146 }
147
148 printf("maymv %d fixed %d newsz %2d dstpo %d dst %p -> ",
149 maymove, fixed, newsizes[nsi], dstpossible, dst );
150 r = (char*)
151 syscall(__NR_mremap, src, 20*PAGE, newsize, flags, dst, 0 );
152 if (r == MAP_FAILED)
153 printf("error %d\n", errno);
154 else
155 printf("%p (== %s)\n", r, identify(r));
156
157 if (1) {
158 show();
159 printf("\n");
160 }
161
162 if (r != MAP_FAILED) {
163 if (r != src && r != try_dst && r != dst_impossible) {
164 tidythis = r;
165 tidylen = newsize;
166 }
167 }
168
169 }
170 }
171 }
172 }
173 return 0;
174}
sewardj4bdd5052006-10-17 01:28:48 +0000175
176#endif /* defined(_AIX5) */