5 #include "tests/sys_mman.h"
15 #define MREMAP_FIXED 2
21 void mapanon_fixed ( void* start
, size_t length
)
23 void* r
= mmap(start
, length
, PROT_NONE
,
24 MAP_FIXED
|MAP_PRIVATE
|MAP_ANONYMOUS
, 0,0);
25 assert(r
!= MAP_FAILED
);
29 void unmap_and_check ( void* start
, size_t length
)
31 int r
= munmap( start
, length
);
35 char* workingarea
= NULL
;
38 // set up working area so expansion limit is 20*PAGE
40 // | 10 | 20 | 10 | 60 |
41 // | pre | src | FREE | post |
43 // A suitable attempted fixed dst is workingarea + 150*PAGE.
45 char* setup ( void* other_stuff
, int other_len
)
48 workingarea
= mmap(0, 200*PAGE
, PROT_NONE
,
49 MAP_ANONYMOUS
|MAP_PRIVATE
, 0,0);
51 try_dst
= workingarea
+ 150*PAGE
;
52 unmap_and_check(workingarea
, 200*PAGE
);
56 unmap_and_check(other_stuff
, other_len
);
59 // get rid of the old working area
60 unmap_and_check( workingarea
, 200*PAGE
);
63 mapanon_fixed( workingarea
+ 0*PAGE
, 9*PAGE
);
66 mapanon_fixed( workingarea
+ 10*PAGE
, 20*PAGE
);
69 mapanon_fixed( workingarea
+ 40*PAGE
, 60*PAGE
);
71 return workingarea
+ 10*PAGE
;
74 /* show the working area */
77 int i
,r
__attribute__((unused
));
78 for (i
= 0; i
< 200; i
++) {
79 r
= mprotect( workingarea
+ i
* PAGE
, PAGE
, PROT_NONE
);
80 // We used to print 'X' or '.' according to the mprotect result, but the
81 // results are too variable and the test was never reliable. So now we
82 // just always print '.'. At least this test gives mremap a thorough
83 // working out and so will detect egregious problems like crashes.
84 //printf("%c", r == 0 ? 'X' : '.');
86 if (i
== 49 || i
== 99 || i
== 149) printf("\n");
94 char* dst_impossible
= NULL
;
97 char* identify ( char* p
)
99 if (p
== dst
) return "dst";
100 if (p
== src
) return "src";
101 if (p
== dst_impossible
) return "dst_imp!";
102 if (p
== try_dst
) return "dst_poss";
108 int alocal
, maymove
, fixed
, nsi
, dstpossible
;
109 int newsizes
[6] = { 19, 20, 21, 29, 30, 31 };
111 char* tidythis
= NULL
;
116 dst_impossible
= (char*)(&alocal
) + 500 * 1000 * 1000;
118 PAGE
= sysconf(_SC_PAGESIZE
);
120 for (maymove
= 0; maymove
<= 1 ; maymove
++) {
121 for (fixed
= 0; fixed
<= 1; fixed
++) {
123 for (nsi
= 0; nsi
< 6; nsi
++) {
124 for (dstpossible
= 0; dstpossible
<= 1; dstpossible
++) {
127 int newsize
= newsizes
[nsi
] * PAGE
;
128 int flags
= (maymove
? MREMAP_MAYMOVE
: 0) |
129 (fixed
? MREMAP_FIXED
: 0);
130 dst
= dstpossible
? try_dst
: dst_impossible
;
131 src
= setup( tidythis
, tidylen
);
134 printf("dst_possible = %p\n", try_dst
);
135 printf("dst_impossible = %p\n", dst_impossible
);
136 printf(" src = %p\n", src
);
138 sprintf(buf
, "cat /proc/%d/maps", getpid());
143 printf("maymv %d fixed %d newsz %2d dstpo %d dst %p -> ",
144 maymove
, fixed
, newsizes
[nsi
], dstpossible
, dst
);
146 syscall(__NR_mremap
, src
, 20*PAGE
, newsize
, flags
, dst
, 0 );
147 // We used to print the address or error, but that was also unreliable.
148 //if (r == MAP_FAILED)
149 // printf("error %d\n", errno);
151 // printf("%p (== %s)\n", r, identify(r));
159 if (r
!= MAP_FAILED
) {
160 if (r
!= src
&& r
!= try_dst
&& r
!= dst_impossible
) {