2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-08-31 14:25:49 +00:00

zdtm/grow_map: fix test failure for clang

When this code is compiled by clang, it optimizes two byte writes into
one word write, like this:

>        fake_grow_down[0] = 'c';
>        *(fake_grow_down - 1) = 'b';
> 401b60:       66 41 c7 46 ff 62 63    movw   $0x6362,-0x1(%r14)

This is incorrect, as the stack is supposed to grow page by page,
so we need to touch one page then another, i.e. the order is important.

To fix, let's use volatile pointer. After this change, the following
(correct) code is generated:

>        *p-- = 'c';
>   401b60:       41 c6 06 63             movb   $0x63,(%r14)
>        *p = 'b';
>   401b64:       41 c6 46 ff 62          movb   $0x62,-0x1(%r14)

[v2: same fix for another similar place]

Cc: Andrei Vagin <avagin@virtuozzo.com>
Signed-off-by: Kir Kolyshkin <kir@openvz.org>
Acked-by: Andrei Vagin <avagin@virtuozzo.com>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
This commit is contained in:
Kir Kolyshkin
2016-10-11 18:47:00 -07:00
committed by Pavel Emelyanov
parent 5465179f96
commit 391bdbe44f

View File

@@ -11,6 +11,7 @@ const char *test_author = "Andrew Vagin <avagin@openvz.org>";
int main(int argc, char **argv)
{
char *start_addr, *fake_grow_down, *test_addr, *grow_down;
volatile char *p;
test_init(argc, argv);
start_addr = mmap(NULL, PAGE_SIZE * 10, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
@@ -28,8 +29,9 @@ int main(int argc, char **argv)
return 1;
}
fake_grow_down[0] = 'c';
*(fake_grow_down - 1) = 'b';
p = fake_grow_down;
*p-- = 'c';
*p = 'b';
/* overlap the guard page of fake_grow_down */
test_addr = mmap(start_addr + PAGE_SIZE * 3, PAGE_SIZE,
@@ -57,8 +59,9 @@ int main(int argc, char **argv)
return 1;
}
grow_down[0] = 'z';
*(grow_down - 1) = 'x';
p = grow_down;
*p-- = 'z';
*p = 'x';
pass();