Add test programs for lage page
Tests arm64 specific, contiguous bit based large pages as well. Change-Id: I09edad8cfde6c23a259f1f32cfc97974d9cb63c3
This commit is contained in:
committed by
Dominique Martinet
parent
100754f556
commit
9f7425c152
88
test/large_page/README
Normal file
88
test/large_page/README
Normal file
@ -0,0 +1,88 @@
|
||||
==========
|
||||
How to run
|
||||
==========
|
||||
|
||||
(1) cd <mckernel> && patch -p0 < <mckernel>/test/large_page/large_page.patch
|
||||
(2) Build McKernel
|
||||
(3) cd <mckernel>/test/large_page/<arch> && make test
|
||||
|
||||
============
|
||||
What to test
|
||||
============
|
||||
|
||||
Check the large page allocation with the following settings.
|
||||
|
||||
------
|
||||
x86_64
|
||||
------
|
||||
|
||||
ID Program sections Size
|
||||
---------------------------------------
|
||||
001 mmap + THP 2M, 1G
|
||||
101 mmap + flag 2M, 1G
|
||||
201 shmget + THP 2M, 1G
|
||||
301 shmget + flag 2M, 1G
|
||||
401 heap 2M
|
||||
402 heap 1G
|
||||
501 .data, .bss, stack 2M
|
||||
601 mmap + hugetlbfs 2M, 1G
|
||||
--------------------------------------
|
||||
|
||||
* 1 GiB for .data, .bss, stack is not tested because it's impossible to
|
||||
align symbol to 1 GiB due to relocation restrictions.
|
||||
|
||||
-----
|
||||
arm64
|
||||
-----
|
||||
|
||||
(1) Granule size: 64 KiB
|
||||
|
||||
ID Program sections Size
|
||||
---------------------------------------
|
||||
001 mmap + THP 2M, 512M
|
||||
101 mmap + flag 2M, 512M
|
||||
201 shmget + THP 2M, 512M
|
||||
301 shmget + flag 2M, 512M
|
||||
401 heap 2M
|
||||
402 heap 512M
|
||||
501 .data, .bss, stack 2M
|
||||
502 .data, .bss 512M
|
||||
601 mmap + hugetlbfs 2M, 512M
|
||||
|
||||
* 512 MiB for stack is not tested because it's impossible to
|
||||
align symbol to 512 MiB due to relocation restrictions.
|
||||
|
||||
(2) Granule size: 4 KiB
|
||||
|
||||
ID Program sections Size
|
||||
---------------------------------------
|
||||
001 mmap + THP 64K, 2M, 32M, 1G
|
||||
101 mmap + flag 64K, 2M, 32M, 1G
|
||||
201 shmget + THP 64K, 2M, 32M, 1G
|
||||
301 shmget + flag 64K, 2M, 32M, 1G
|
||||
401 heap 64K
|
||||
402 heap 2M
|
||||
403 heap 32M
|
||||
404 heap 1G
|
||||
501 .data, .bss, stack 64K
|
||||
502 .data, .bss, stack 2M
|
||||
503 .data, .bss, stack 32M
|
||||
504 .data, .bss 1G
|
||||
601 mmap + hugetlbfs 64K, 2M, 32M, 1G
|
||||
|
||||
* 1 GiB for stack is not tested because it's impossible to
|
||||
align symbol to 1 GiB due to relocation restrictions.
|
||||
|
||||
======
|
||||
Detail
|
||||
======
|
||||
|
||||
With the patch, McKernel does the followings for the test:
|
||||
(1) Align heap with the value passed via mcexec -h option
|
||||
(2) Map stack and .data with the page with the size of the value
|
||||
passed via mcexec -s option
|
||||
(3) Enable THP via shmget
|
||||
(5) Report large page allocations
|
||||
|
||||
Alignment of symbols in .data, .bss is done by using the modified
|
||||
linker scripts.
|
||||
72
test/large_page/arm64/001_4K.c
Normal file
72
test/large_page/arm64/001_4K.c
Normal file
@ -0,0 +1,72 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/mman.h>
|
||||
#include "../util.h"
|
||||
|
||||
#define PAGE_SHIFT_64K 16
|
||||
#define PAGE_SIZE_64K (1UL << PAGE_SHIFT_64K)
|
||||
|
||||
#define PAGE_SHIFT_2M 21
|
||||
#define PAGE_SIZE_2M (1UL << PAGE_SHIFT_2M)
|
||||
|
||||
#define PAGE_SHIFT_32M 25
|
||||
#define PAGE_SIZE_32M (1UL << PAGE_SHIFT_32M)
|
||||
|
||||
#define PAGE_SHIFT_1G 30
|
||||
#define PAGE_SIZE_1G (1UL << PAGE_SHIFT_1G)
|
||||
|
||||
int trial_num;
|
||||
|
||||
int mmap_thp(size_t page_size)
|
||||
{
|
||||
char *addr_mmap;
|
||||
|
||||
addr_mmap = mmap(0, page_size,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_ANONYMOUS | MAP_PRIVATE,
|
||||
-1, 0);
|
||||
NG(addr_mmap != (void *)-1, "mmap failed\n");
|
||||
|
||||
addr_mmap[0] = 'z';
|
||||
NG(__atomic_load_n(addr_mmap, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_mmap, page_size);
|
||||
|
||||
munmap(addr_mmap, page_size);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = mmap_thp(PAGE_SIZE_64K);
|
||||
NG(ret == 0, "mmap_thp failed, size: %ld\n",
|
||||
PAGE_SIZE_64K);
|
||||
|
||||
ret = mmap_thp(PAGE_SIZE_2M);
|
||||
NG(ret == 0, "mmap_thp failed, size: %ld\n",
|
||||
PAGE_SIZE_2M);
|
||||
|
||||
ret = mmap_thp(PAGE_SIZE_32M);
|
||||
NG(ret == 0, "mmap_thp failed, size: %ld\n",
|
||||
PAGE_SIZE_32M);
|
||||
|
||||
ret = mmap_thp(PAGE_SIZE_1G);
|
||||
NG(ret == 0, "mmap_thp failed, size: %ld\n",
|
||||
PAGE_SIZE_1G);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
56
test/large_page/arm64/001_64K.c
Normal file
56
test/large_page/arm64/001_64K.c
Normal file
@ -0,0 +1,56 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/mman.h>
|
||||
#include "../util.h"
|
||||
|
||||
#define PAGE_SHIFT_2M 21
|
||||
#define PAGE_SIZE_2M (1UL << PAGE_SHIFT_2M)
|
||||
|
||||
#define PAGE_SHIFT_512M 29
|
||||
#define PAGE_SIZE_512M (1UL << PAGE_SHIFT_512M)
|
||||
|
||||
int trial_num;
|
||||
|
||||
int mmap_thp(size_t page_size)
|
||||
{
|
||||
char *addr_mmap;
|
||||
|
||||
addr_mmap = mmap(0, page_size,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_ANONYMOUS | MAP_PRIVATE,
|
||||
-1, 0);
|
||||
NG(addr_mmap != (void *)-1, "mmap failed\n");
|
||||
addr_mmap[0] = 'z';
|
||||
NG(__atomic_load_n(addr_mmap, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_mmap, page_size);
|
||||
|
||||
munmap(addr_mmap, page_size);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = mmap_thp(PAGE_SIZE_2M);
|
||||
NG(ret == 0, "mmap_thp failed, size: %ld\n",
|
||||
PAGE_SIZE_2M);
|
||||
|
||||
ret = mmap_thp(PAGE_SIZE_512M);
|
||||
NG(ret == 0, "mmap_thp failed, size: %ld\n",
|
||||
PAGE_SIZE_512M);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
75
test/large_page/arm64/101_4K.c
Normal file
75
test/large_page/arm64/101_4K.c
Normal file
@ -0,0 +1,75 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/mman.h>
|
||||
#include "../util.h"
|
||||
|
||||
#define PAGE_SHIFT_64K 16
|
||||
#define PAGE_SIZE_64K (1UL << PAGE_SHIFT_64K)
|
||||
|
||||
#define PAGE_SHIFT_2M 21
|
||||
#define PAGE_SIZE_2M (1UL << PAGE_SHIFT_2M)
|
||||
|
||||
#define PAGE_SHIFT_32M 25
|
||||
#define PAGE_SIZE_32M (1UL << PAGE_SHIFT_32M)
|
||||
|
||||
#define PAGE_SHIFT_1G 30
|
||||
#define PAGE_SIZE_1G (1UL << PAGE_SHIFT_1G)
|
||||
|
||||
#define MAP_HUGE_SHIFT 26
|
||||
|
||||
int trial_num;
|
||||
|
||||
int mmap_flag(size_t page_size, unsigned long page_shift)
|
||||
{
|
||||
char *addr_mmap;
|
||||
|
||||
addr_mmap = mmap(0, page_size,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_ANONYMOUS | MAP_PRIVATE |
|
||||
MAP_HUGETLB | (page_shift << MAP_HUGE_SHIFT),
|
||||
-1, 0);
|
||||
NG(addr_mmap != (void *)-1, "mmap failed\n");
|
||||
|
||||
addr_mmap[0] = 'z';
|
||||
NG(__atomic_load_n(addr_mmap, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_mmap, page_size);
|
||||
|
||||
munmap(addr_mmap, page_size);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = mmap_flag(PAGE_SIZE_64K, PAGE_SHIFT_64K);
|
||||
NG(ret == 0, "mmap_flag failed, size: %ld\n",
|
||||
PAGE_SIZE_64K);
|
||||
|
||||
ret = mmap_flag(PAGE_SIZE_2M, PAGE_SHIFT_2M);
|
||||
NG(ret == 0, "mmap_flag failed, size: %ld\n",
|
||||
PAGE_SIZE_2M);
|
||||
|
||||
ret = mmap_flag(PAGE_SIZE_32M, PAGE_SHIFT_32M);
|
||||
NG(ret == 0, "mmap_flag failed, size: %ld\n",
|
||||
PAGE_SIZE_32M);
|
||||
|
||||
ret = mmap_flag(PAGE_SIZE_1G, PAGE_SHIFT_1G);
|
||||
NG(ret == 0, "mmap_flag failed, size: %ld\n",
|
||||
PAGE_SIZE_1G);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
59
test/large_page/arm64/101_64K.c
Normal file
59
test/large_page/arm64/101_64K.c
Normal file
@ -0,0 +1,59 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/mman.h>
|
||||
#include "../util.h"
|
||||
|
||||
#define PAGE_SHIFT_2M 21
|
||||
#define PAGE_SIZE_2M (1UL << PAGE_SHIFT_2M)
|
||||
|
||||
#define PAGE_SHIFT_512M 29
|
||||
#define PAGE_SIZE_512M (1UL << PAGE_SHIFT_512M)
|
||||
|
||||
#define MAP_HUGE_SHIFT 26
|
||||
|
||||
int trial_num;
|
||||
|
||||
int mmap_flag(size_t page_size, unsigned long page_shift)
|
||||
{
|
||||
char *addr_mmap;
|
||||
|
||||
addr_mmap = mmap(0, page_size,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_ANONYMOUS | MAP_PRIVATE |
|
||||
MAP_HUGETLB | (page_shift << MAP_HUGE_SHIFT),
|
||||
-1, 0);
|
||||
NG(addr_mmap != (void *)-1, "mmap failed\n");
|
||||
addr_mmap[0] = 'z';
|
||||
NG(__atomic_load_n(addr_mmap, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_mmap, page_size);
|
||||
|
||||
munmap(addr_mmap, page_size);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = mmap_flag(PAGE_SIZE_2M, PAGE_SHIFT_2M);
|
||||
NG(ret == 0, "mmap_flag failed, size: %ld\n",
|
||||
PAGE_SIZE_2M);
|
||||
|
||||
ret = mmap_flag(PAGE_SIZE_512M, PAGE_SHIFT_512M);
|
||||
NG(ret == 0, "mmap_flag failed, size: %ld\n",
|
||||
PAGE_SIZE_512M);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
81
test/large_page/arm64/201_4K.c
Normal file
81
test/large_page/arm64/201_4K.c
Normal file
@ -0,0 +1,81 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include "../util.h"
|
||||
|
||||
#define PAGE_SHIFT_64K 16
|
||||
#define PAGE_SIZE_64K (1UL << PAGE_SHIFT_64K)
|
||||
|
||||
#define PAGE_SHIFT_2M 21
|
||||
#define PAGE_SIZE_2M (1UL << PAGE_SHIFT_2M)
|
||||
|
||||
#define PAGE_SHIFT_32M 25
|
||||
#define PAGE_SIZE_32M (1UL << PAGE_SHIFT_32M)
|
||||
|
||||
#define PAGE_SHIFT_1G 30
|
||||
#define PAGE_SIZE_1G (1UL << PAGE_SHIFT_1G)
|
||||
|
||||
int trial_num;
|
||||
|
||||
int shmat_thp(char **argv, size_t page_size)
|
||||
{
|
||||
int ret;
|
||||
key_t key;
|
||||
int shmid;
|
||||
struct shmid_ds shmid_ds;
|
||||
char *addr_shmget;
|
||||
|
||||
key = ftok(argv[0], 0);
|
||||
|
||||
shmid = shmget(key, page_size, IPC_CREAT | 0660);
|
||||
NG(shmid != -1, "shmget failed\n");
|
||||
|
||||
addr_shmget = shmat(shmid, NULL, 0);
|
||||
NG(addr_shmget != (void *)-1, "shmat failed\n");
|
||||
|
||||
addr_shmget[0] = 'z';
|
||||
NG(__atomic_load_n(addr_shmget, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_shmget, page_size);
|
||||
|
||||
ret = shmdt(addr_shmget);
|
||||
NG(ret != -1, "shmdt failed\n");
|
||||
|
||||
ret = shmctl(shmid, IPC_RMID, &shmid_ds);
|
||||
NG(ret != -1, "shmctl failed\n");
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = shmat_thp(argv, PAGE_SIZE_64K);
|
||||
NG(ret == 0, "shmat_thp failed, size: %ld\n",
|
||||
PAGE_SIZE_64K);
|
||||
|
||||
ret = shmat_thp(argv, PAGE_SIZE_2M);
|
||||
NG(ret == 0, "shmat_thp failed, size: %ld\n",
|
||||
PAGE_SIZE_2M);
|
||||
|
||||
ret = shmat_thp(argv, PAGE_SIZE_32M);
|
||||
NG(ret == 0, "shmat_thp failed, size: %ld\n",
|
||||
PAGE_SIZE_32M);
|
||||
|
||||
ret = shmat_thp(argv, PAGE_SIZE_1G);
|
||||
NG(ret == 0, "shmat_thp failed, size: %ld\n",
|
||||
PAGE_SIZE_1G);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
66
test/large_page/arm64/201_64K.c
Normal file
66
test/large_page/arm64/201_64K.c
Normal file
@ -0,0 +1,66 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include "../util.h"
|
||||
|
||||
#define PAGE_SHIFT_2M 21
|
||||
#define PAGE_SIZE_2M (1UL << PAGE_SHIFT_2M)
|
||||
|
||||
#define PAGE_SHIFT_512M 29
|
||||
#define PAGE_SIZE_512M (1UL << PAGE_SHIFT_512M)
|
||||
|
||||
int trial_num;
|
||||
|
||||
int shmat_thp(char **argv, size_t page_size)
|
||||
{
|
||||
int ret;
|
||||
key_t key;
|
||||
int shmid;
|
||||
struct shmid_ds shmid_ds;
|
||||
char *addr_shmget;
|
||||
|
||||
key = ftok(argv[0], 0);
|
||||
|
||||
shmid = shmget(key, page_size, IPC_CREAT | 0660);
|
||||
NG(shmid != -1, "shmget failed\n");
|
||||
|
||||
addr_shmget = shmat(shmid, NULL, 0);
|
||||
NG(addr_shmget != (void *)-1, "shmat failed\n");
|
||||
|
||||
addr_shmget[0] = 'z';
|
||||
NG(__atomic_load_n(addr_shmget, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_shmget, page_size);
|
||||
|
||||
ret = shmctl(shmid, IPC_RMID, &shmid_ds);
|
||||
NG(ret != -1, "shmctl failed\n");
|
||||
|
||||
ret = shmdt(addr_shmget);
|
||||
NG(ret != -1, "shmdt failed\n");
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = shmat_thp(argv, PAGE_SIZE_2M);
|
||||
NG(ret == 0, "shmat_thp failed, size: %ld\n",
|
||||
PAGE_SIZE_2M);
|
||||
|
||||
ret = shmat_thp(argv, PAGE_SIZE_512M);
|
||||
NG(ret == 0, "shmat_thp failed, size: %ld\n",
|
||||
PAGE_SIZE_512M);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
84
test/large_page/arm64/301_4K.c
Normal file
84
test/large_page/arm64/301_4K.c
Normal file
@ -0,0 +1,84 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include "../util.h"
|
||||
|
||||
#define PAGE_SHIFT_64K 16
|
||||
#define PAGE_SIZE_64K (1UL << PAGE_SHIFT_64K)
|
||||
|
||||
#define PAGE_SHIFT_2M 21
|
||||
#define PAGE_SIZE_2M (1UL << PAGE_SHIFT_2M)
|
||||
|
||||
#define PAGE_SHIFT_32M 25
|
||||
#define PAGE_SIZE_32M (1UL << PAGE_SHIFT_32M)
|
||||
|
||||
#define PAGE_SHIFT_1G 30
|
||||
#define PAGE_SIZE_1G (1UL << PAGE_SHIFT_1G)
|
||||
|
||||
#define SHM_HUGE_SHIFT 26
|
||||
|
||||
int trial_num;
|
||||
|
||||
int shmat_thp(char **argv, size_t page_size, unsigned long page_shift)
|
||||
{
|
||||
int ret;
|
||||
key_t key;
|
||||
int shmid;
|
||||
struct shmid_ds shmid_ds;
|
||||
char *addr_shmget;
|
||||
|
||||
key = ftok(argv[0], 0);
|
||||
|
||||
shmid = shmget(key, page_size, IPC_CREAT | 0660 |
|
||||
SHM_HUGETLB | (page_shift << SHM_HUGE_SHIFT));
|
||||
NG(shmid != -1, "shmget failed\n");
|
||||
|
||||
addr_shmget = shmat(shmid, NULL, 0);
|
||||
NG(addr_shmget != (void *)-1, "shmat failed\n");
|
||||
|
||||
addr_shmget[0] = 'z';
|
||||
NG(__atomic_load_n(addr_shmget, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_shmget, page_size);
|
||||
|
||||
ret = shmctl(shmid, IPC_RMID, &shmid_ds);
|
||||
NG(ret != -1, "shmctl failed\n");
|
||||
|
||||
ret = shmdt(addr_shmget);
|
||||
NG(ret != -1, "shmdt failed\n");
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = shmat_thp(argv, PAGE_SIZE_64K, PAGE_SHIFT_64K);
|
||||
NG(ret == 0, "shmat_thp failed, size: %ld\n",
|
||||
PAGE_SIZE_64K);
|
||||
|
||||
ret = shmat_thp(argv, PAGE_SIZE_2M, PAGE_SHIFT_2M);
|
||||
NG(ret == 0, "shmat_thp failed, size: %ld\n",
|
||||
PAGE_SIZE_2M);
|
||||
|
||||
ret = shmat_thp(argv, PAGE_SIZE_32M, PAGE_SHIFT_32M);
|
||||
NG(ret == 0, "shmat_thp failed, size: %ld\n",
|
||||
PAGE_SIZE_32M);
|
||||
|
||||
ret = shmat_thp(argv, PAGE_SIZE_1G, PAGE_SHIFT_1G);
|
||||
NG(ret == 0, "shmat_thp failed, size: %ld\n",
|
||||
PAGE_SIZE_1G);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
69
test/large_page/arm64/301_64K.c
Normal file
69
test/large_page/arm64/301_64K.c
Normal file
@ -0,0 +1,69 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include "../util.h"
|
||||
|
||||
#define PAGE_SHIFT_2M 21
|
||||
#define PAGE_SIZE_2M (1UL << PAGE_SHIFT_2M)
|
||||
|
||||
#define PAGE_SHIFT_512M 29
|
||||
#define PAGE_SIZE_512M (1UL << PAGE_SHIFT_512M)
|
||||
|
||||
#define SHM_HUGE_SHIFT 26
|
||||
|
||||
int trial_num;
|
||||
|
||||
int shmat_thp(char **argv, size_t page_size, unsigned long page_shift)
|
||||
{
|
||||
int ret;
|
||||
key_t key;
|
||||
int shmid;
|
||||
struct shmid_ds shmid_ds;
|
||||
char *addr_shmget;
|
||||
|
||||
key = ftok(argv[0], 0);
|
||||
|
||||
shmid = shmget(key, page_size, IPC_CREAT | 0660 |
|
||||
SHM_HUGETLB | (page_shift << SHM_HUGE_SHIFT));
|
||||
NG(shmid != -1, "shmget failed\n");
|
||||
|
||||
addr_shmget = shmat(shmid, NULL, 0);
|
||||
NG(addr_shmget != (void *)-1, "shmat failed\n");
|
||||
|
||||
addr_shmget[0] = 'z';
|
||||
NG(__atomic_load_n(addr_shmget, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_shmget, page_size);
|
||||
|
||||
ret = shmctl(shmid, IPC_RMID, &shmid_ds);
|
||||
NG(ret != -1, "shmctl failed\n");
|
||||
|
||||
ret = shmdt(addr_shmget);
|
||||
NG(ret != -1, "shmdt failed\n");
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = shmat_thp(argv, PAGE_SIZE_2M, PAGE_SHIFT_2M);
|
||||
NG(ret == 0, "shmat_thp failed, size: %ld\n",
|
||||
PAGE_SIZE_2M);
|
||||
|
||||
ret = shmat_thp(argv, PAGE_SIZE_512M, PAGE_SHIFT_512M);
|
||||
NG(ret == 0, "shmat_thp failed, size: %ld\n",
|
||||
PAGE_SIZE_512M);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
35
test/large_page/arm64/401_4K.c
Normal file
35
test/large_page/arm64/401_4K.c
Normal file
@ -0,0 +1,35 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/shm.h>
|
||||
#include "../util.h"
|
||||
|
||||
#define TARGET_PAGE_SHIFT 16
|
||||
#define TARGET_PAGE_SIZE (1UL << TARGET_PAGE_SHIFT)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *addr_brk;
|
||||
int trial_num = 0;
|
||||
|
||||
/* Assuming heap size starts from zero and
|
||||
* incremented by the amount specified with mcexec -h
|
||||
*/
|
||||
addr_brk = sbrk(TARGET_PAGE_SIZE);
|
||||
NG(addr_brk != (void *)-1, "sbrk failed");
|
||||
|
||||
addr_brk[0] = 'z';
|
||||
NG(__atomic_load_n(addr_brk, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_brk, TARGET_PAGE_SIZE);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
35
test/large_page/arm64/401_64K.c
Normal file
35
test/large_page/arm64/401_64K.c
Normal file
@ -0,0 +1,35 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/shm.h>
|
||||
#include "../util.h"
|
||||
|
||||
#define TARGET_PAGE_SHIFT 21
|
||||
#define TARGET_PAGE_SIZE (1UL << TARGET_PAGE_SHIFT)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *addr_brk;
|
||||
int trial_num = 0;
|
||||
|
||||
/* Assuming heap size starts from zero and
|
||||
* incremented by the amount specified with mcexec -h
|
||||
*/
|
||||
addr_brk = sbrk(TARGET_PAGE_SIZE);
|
||||
NG(addr_brk != (void *)-1, "sbrk failed\n");
|
||||
|
||||
addr_brk[0] = 'z';
|
||||
NG(__atomic_load_n(addr_brk, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_brk, TARGET_PAGE_SIZE);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
35
test/large_page/arm64/402_4K.c
Normal file
35
test/large_page/arm64/402_4K.c
Normal file
@ -0,0 +1,35 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/shm.h>
|
||||
#include "../util.h"
|
||||
|
||||
#define TARGET_PAGE_SHIFT 21
|
||||
#define TARGET_PAGE_SIZE (1UL << TARGET_PAGE_SHIFT)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *addr_brk;
|
||||
int trial_num = 0;
|
||||
|
||||
/* Assuming heap size starts from zero and
|
||||
* incremented by the amount specified with mcexec -h
|
||||
*/
|
||||
addr_brk = sbrk(TARGET_PAGE_SIZE);
|
||||
NG(addr_brk != (void *)-1, "sbrk failed");
|
||||
|
||||
addr_brk[0] = 'z';
|
||||
NG(__atomic_load_n(addr_brk, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_brk, TARGET_PAGE_SIZE);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
35
test/large_page/arm64/402_64K.c
Normal file
35
test/large_page/arm64/402_64K.c
Normal file
@ -0,0 +1,35 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/shm.h>
|
||||
#include "../util.h"
|
||||
|
||||
#define TARGET_PAGE_SHIFT 29
|
||||
#define TARGET_PAGE_SIZE (1UL << TARGET_PAGE_SHIFT)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *addr_brk;
|
||||
int trial_num = 0;
|
||||
|
||||
/* Assuming heap size starts from zero and
|
||||
* incremented by the amount specified with mcexec -h
|
||||
*/
|
||||
addr_brk = sbrk(TARGET_PAGE_SIZE);
|
||||
NG(addr_brk != (void *)-1, "sbrk failed\n");
|
||||
|
||||
addr_brk[0] = 'z';
|
||||
NG(__atomic_load_n(addr_brk, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_brk, TARGET_PAGE_SIZE);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
35
test/large_page/arm64/403_4K.c
Normal file
35
test/large_page/arm64/403_4K.c
Normal file
@ -0,0 +1,35 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/shm.h>
|
||||
#include "../util.h"
|
||||
|
||||
#define TARGET_PAGE_SHIFT 25
|
||||
#define TARGET_PAGE_SIZE (1UL << TARGET_PAGE_SHIFT)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *addr_brk;
|
||||
int trial_num = 0;
|
||||
|
||||
/* Assuming heap size starts from zero and
|
||||
* incremented by the amount specified with mcexec -h
|
||||
*/
|
||||
addr_brk = sbrk(TARGET_PAGE_SIZE);
|
||||
NG(addr_brk != (void *)-1, "sbrk failed");
|
||||
|
||||
addr_brk[0] = 'z';
|
||||
NG(__atomic_load_n(addr_brk, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_brk, TARGET_PAGE_SIZE);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
35
test/large_page/arm64/404_4K.c
Normal file
35
test/large_page/arm64/404_4K.c
Normal file
@ -0,0 +1,35 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/shm.h>
|
||||
#include "../util.h"
|
||||
|
||||
#define TARGET_PAGE_SHIFT 30
|
||||
#define TARGET_PAGE_SIZE (1UL << TARGET_PAGE_SHIFT)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *addr_brk;
|
||||
int trial_num = 0;
|
||||
|
||||
/* Assuming heap size starts from zero and
|
||||
* incremented by the amount specified with mcexec -h
|
||||
*/
|
||||
addr_brk = sbrk(TARGET_PAGE_SIZE);
|
||||
NG(addr_brk != (void *)-1, "sbrk failed");
|
||||
|
||||
addr_brk[0] = 'z';
|
||||
NG(__atomic_load_n(addr_brk, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_brk, TARGET_PAGE_SIZE);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
50
test/large_page/arm64/501_4K.c
Normal file
50
test/large_page/arm64/501_4K.c
Normal file
@ -0,0 +1,50 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/shm.h>
|
||||
#include "../util.h"
|
||||
|
||||
#define TARGET_PAGE_SHIFT 16
|
||||
#define TARGET_PAGE_SIZE (1UL << TARGET_PAGE_SHIFT)
|
||||
|
||||
/* .data */
|
||||
char addr_data[TARGET_PAGE_SIZE] = { 1 };
|
||||
|
||||
/* .bss */
|
||||
char addr_bss[TARGET_PAGE_SIZE];
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int trial_num = 0;
|
||||
char addr_stack[TARGET_PAGE_SIZE]
|
||||
__attribute__((aligned(TARGET_PAGE_SIZE)));
|
||||
|
||||
/* .data */
|
||||
addr_data[0] = 'z';
|
||||
NG(__atomic_load_n(addr_data, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_data, TARGET_PAGE_SIZE);
|
||||
|
||||
/* .bss */
|
||||
addr_bss[0] = 'z';
|
||||
NG(__atomic_load_n(addr_bss, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_bss, TARGET_PAGE_SIZE);
|
||||
|
||||
/* stack */
|
||||
addr_stack[0] = 'z';
|
||||
NG(__atomic_load_n(addr_stack, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_stack, TARGET_PAGE_SIZE);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
224
test/large_page/arm64/501_4K.lds
Normal file
224
test/large_page/arm64/501_4K.lds
Normal file
@ -0,0 +1,224 @@
|
||||
/* Script for -z combreloc: combine and sort reloc sections */
|
||||
/* Copyright (C) 2014-2016 Free Software Foundation, Inc.
|
||||
Copying and distribution of this script, with or without modification,
|
||||
are permitted in any medium without royalty provided the copyright
|
||||
notice and this notice are preserved. */
|
||||
OUTPUT_FORMAT("elf64-littleaarch64", "elf64-bigaarch64",
|
||||
"elf64-littleaarch64")
|
||||
OUTPUT_ARCH(aarch64)
|
||||
ENTRY(_start)
|
||||
SEARCH_DIR("=/usr/aarch64-redhat-linux/lib64"); SEARCH_DIR("=/usr/lib64"); SEARCH_DIR("=/usr/local/lib64"); SEARCH_DIR("=/lib64"); SEARCH_DIR("=/usr/aarch64-redhat-linux/lib"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib");
|
||||
SECTIONS
|
||||
{
|
||||
/* Read-only sections, merged into text segment: */
|
||||
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS;
|
||||
.interp : { *(.interp) }
|
||||
.note.gnu.build-id : { *(.note.gnu.build-id) }
|
||||
.hash : { *(.hash) }
|
||||
.gnu.hash : { *(.gnu.hash) }
|
||||
.dynsym : { *(.dynsym) }
|
||||
.dynstr : { *(.dynstr) }
|
||||
.gnu.version : { *(.gnu.version) }
|
||||
.gnu.version_d : { *(.gnu.version_d) }
|
||||
.gnu.version_r : { *(.gnu.version_r) }
|
||||
.rela.dyn :
|
||||
{
|
||||
*(.rela.init)
|
||||
*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
|
||||
*(.rela.fini)
|
||||
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
|
||||
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
|
||||
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
|
||||
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
|
||||
*(.rela.ctors)
|
||||
*(.rela.dtors)
|
||||
*(.rela.got)
|
||||
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
|
||||
*(.rela.ifunc)
|
||||
}
|
||||
.rela.plt :
|
||||
{
|
||||
*(.rela.plt)
|
||||
PROVIDE_HIDDEN (__rela_iplt_start = .);
|
||||
*(.rela.iplt)
|
||||
PROVIDE_HIDDEN (__rela_iplt_end = .);
|
||||
}
|
||||
.init :
|
||||
{
|
||||
KEEP (*(SORT_NONE(.init)))
|
||||
} =0
|
||||
.plt : ALIGN(16) { *(.plt) *(.iplt) }
|
||||
.text :
|
||||
{
|
||||
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
|
||||
*(.text.exit .text.exit.*)
|
||||
*(.text.startup .text.startup.*)
|
||||
*(.text.hot .text.hot.*)
|
||||
*(.text .stub .text.* .gnu.linkonce.t.*)
|
||||
/* .gnu.warning sections are handled specially by elf32.em. */
|
||||
*(.gnu.warning)
|
||||
} =0
|
||||
.fini :
|
||||
{
|
||||
KEEP (*(SORT_NONE(.fini)))
|
||||
} =0
|
||||
PROVIDE (__etext = .);
|
||||
PROVIDE (_etext = .);
|
||||
PROVIDE (etext = .);
|
||||
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
|
||||
.rodata1 : { *(.rodata1) }
|
||||
.eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }
|
||||
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }
|
||||
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table
|
||||
.gcc_except_table.*) }
|
||||
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) }
|
||||
/* These sections are generated by the Sun/Oracle C++ compiler. */
|
||||
.exception_ranges : ONLY_IF_RO { *(.exception_ranges
|
||||
.exception_ranges*) }
|
||||
/* Adjust the address for the data segment. We want to adjust up to
|
||||
the same address within the page on the next page up. */
|
||||
. = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
|
||||
/* Exception handling */
|
||||
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) }
|
||||
.gnu_extab : ONLY_IF_RW { *(.gnu_extab) }
|
||||
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
|
||||
.exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) }
|
||||
/* Thread Local Storage sections */
|
||||
.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
|
||||
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
|
||||
.preinit_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
}
|
||||
. = ALIGN(0x10000);
|
||||
.init_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
|
||||
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
}
|
||||
.fini_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
|
||||
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
}
|
||||
.ctors :
|
||||
{
|
||||
/* gcc uses crtbegin.o to find the start of
|
||||
the constructors, so we make sure it is
|
||||
first. Because this is a wildcard, it
|
||||
doesn't matter if the user does not
|
||||
actually link against crtbegin.o; the
|
||||
linker won't look for a file to match a
|
||||
wildcard. The wildcard also means that it
|
||||
doesn't matter which directory crtbegin.o
|
||||
is in. */
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*crtbegin?.o(.ctors))
|
||||
/* We don't want to include the .ctor section from
|
||||
the crtend.o file until after the sorted ctors.
|
||||
The .ctor section from the crtend file contains the
|
||||
end of ctors marker and it must be last */
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
}
|
||||
.dtors :
|
||||
{
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*crtbegin?.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
}
|
||||
.jcr : { KEEP (*(.jcr)) }
|
||||
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }
|
||||
.dynamic : { *(.dynamic) }
|
||||
.got : { *(.got) *(.igot) }
|
||||
. = DATA_SEGMENT_RELRO_END (24, .);
|
||||
.got.plt : { *(.got.plt) *(.igot.plt) }
|
||||
. = ALIGN(0x10000);
|
||||
.data :
|
||||
{
|
||||
addr_data = .;
|
||||
PROVIDE (__data_start = .);
|
||||
*(.data .data.* .gnu.linkonce.d.*)
|
||||
SORT(CONSTRUCTORS)
|
||||
. = ALIGN(0x10000);
|
||||
}
|
||||
.data1 : { *(.data1) }
|
||||
_edata = .; PROVIDE (edata = .);
|
||||
. = .;
|
||||
. = ALIGN(0x10000);
|
||||
__bss_start = .;
|
||||
__bss_start__ = .;
|
||||
.bss :
|
||||
{
|
||||
addr_bss = .;
|
||||
*(.dynbss)
|
||||
*(.bss .bss.* .gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
/* Align here to ensure that the .bss section occupies space up to
|
||||
_end. Align after .bss to ensure correct alignment even if the
|
||||
.bss section disappears because there are no input sections.
|
||||
FIXME: Why do we need it? When there is no .bss section, we don't
|
||||
pad the .data section. */
|
||||
. = ALIGN(. != 0 ? 64 / 8 : 1);
|
||||
. = ALIGN(0x10000);
|
||||
}
|
||||
_bss_end__ = . ; __bss_end__ = . ;
|
||||
. = ALIGN(64 / 8);
|
||||
. = SEGMENT_START("ldata-segment", .);
|
||||
. = ALIGN(64 / 8);
|
||||
__end__ = . ;
|
||||
_end = .; PROVIDE (end = .);
|
||||
. = DATA_SEGMENT_END (.);
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
/* DWARF 3 */
|
||||
.debug_pubtypes 0 : { *(.debug_pubtypes) }
|
||||
.debug_ranges 0 : { *(.debug_ranges) }
|
||||
/* DWARF Extension. */
|
||||
.debug_macro 0 : { *(.debug_macro) }
|
||||
.ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) }
|
||||
.note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
|
||||
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
|
||||
}
|
||||
|
||||
|
||||
50
test/large_page/arm64/501_64K.c
Normal file
50
test/large_page/arm64/501_64K.c
Normal file
@ -0,0 +1,50 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/shm.h>
|
||||
#include "../util.h"
|
||||
|
||||
#define TARGET_PAGE_SHIFT 21
|
||||
#define TARGET_PAGE_SIZE (1UL << TARGET_PAGE_SHIFT)
|
||||
|
||||
/* .data */
|
||||
char addr_data[TARGET_PAGE_SIZE] = { 1 };
|
||||
|
||||
/* .bss */
|
||||
char addr_bss[TARGET_PAGE_SIZE];
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int trial_num = 0;
|
||||
char addr_stack[TARGET_PAGE_SIZE]
|
||||
__attribute__((aligned(TARGET_PAGE_SIZE)));
|
||||
|
||||
/* .data */
|
||||
addr_data[0] = 'z';
|
||||
NG(__atomic_load_n(addr_data, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_data, TARGET_PAGE_SIZE);
|
||||
|
||||
/* .bss */
|
||||
addr_bss[0] = 'z';
|
||||
NG(__atomic_load_n(addr_bss, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_bss, TARGET_PAGE_SIZE);
|
||||
|
||||
/* stack */
|
||||
addr_stack[0] = 'z';
|
||||
NG(__atomic_load_n(addr_stack, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_stack, TARGET_PAGE_SIZE);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
224
test/large_page/arm64/501_64K.lds
Normal file
224
test/large_page/arm64/501_64K.lds
Normal file
@ -0,0 +1,224 @@
|
||||
/* Script for -z combreloc: combine and sort reloc sections */
|
||||
/* Copyright (C) 2014-2016 Free Software Foundation, Inc.
|
||||
Copying and distribution of this script, with or without modification,
|
||||
are permitted in any medium without royalty provided the copyright
|
||||
notice and this notice are preserved. */
|
||||
OUTPUT_FORMAT("elf64-littleaarch64", "elf64-bigaarch64",
|
||||
"elf64-littleaarch64")
|
||||
OUTPUT_ARCH(aarch64)
|
||||
ENTRY(_start)
|
||||
SEARCH_DIR("=/usr/aarch64-redhat-linux/lib64"); SEARCH_DIR("=/usr/lib64"); SEARCH_DIR("=/usr/local/lib64"); SEARCH_DIR("=/lib64"); SEARCH_DIR("=/usr/aarch64-redhat-linux/lib"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib");
|
||||
SECTIONS
|
||||
{
|
||||
/* Read-only sections, merged into text segment: */
|
||||
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS;
|
||||
.interp : { *(.interp) }
|
||||
.note.gnu.build-id : { *(.note.gnu.build-id) }
|
||||
.hash : { *(.hash) }
|
||||
.gnu.hash : { *(.gnu.hash) }
|
||||
.dynsym : { *(.dynsym) }
|
||||
.dynstr : { *(.dynstr) }
|
||||
.gnu.version : { *(.gnu.version) }
|
||||
.gnu.version_d : { *(.gnu.version_d) }
|
||||
.gnu.version_r : { *(.gnu.version_r) }
|
||||
.rela.dyn :
|
||||
{
|
||||
*(.rela.init)
|
||||
*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
|
||||
*(.rela.fini)
|
||||
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
|
||||
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
|
||||
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
|
||||
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
|
||||
*(.rela.ctors)
|
||||
*(.rela.dtors)
|
||||
*(.rela.got)
|
||||
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
|
||||
*(.rela.ifunc)
|
||||
}
|
||||
.rela.plt :
|
||||
{
|
||||
*(.rela.plt)
|
||||
PROVIDE_HIDDEN (__rela_iplt_start = .);
|
||||
*(.rela.iplt)
|
||||
PROVIDE_HIDDEN (__rela_iplt_end = .);
|
||||
}
|
||||
.init :
|
||||
{
|
||||
KEEP (*(SORT_NONE(.init)))
|
||||
} =0
|
||||
.plt : ALIGN(16) { *(.plt) *(.iplt) }
|
||||
.text :
|
||||
{
|
||||
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
|
||||
*(.text.exit .text.exit.*)
|
||||
*(.text.startup .text.startup.*)
|
||||
*(.text.hot .text.hot.*)
|
||||
*(.text .stub .text.* .gnu.linkonce.t.*)
|
||||
/* .gnu.warning sections are handled specially by elf32.em. */
|
||||
*(.gnu.warning)
|
||||
} =0
|
||||
.fini :
|
||||
{
|
||||
KEEP (*(SORT_NONE(.fini)))
|
||||
} =0
|
||||
PROVIDE (__etext = .);
|
||||
PROVIDE (_etext = .);
|
||||
PROVIDE (etext = .);
|
||||
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
|
||||
.rodata1 : { *(.rodata1) }
|
||||
.eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }
|
||||
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }
|
||||
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table
|
||||
.gcc_except_table.*) }
|
||||
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) }
|
||||
/* These sections are generated by the Sun/Oracle C++ compiler. */
|
||||
.exception_ranges : ONLY_IF_RO { *(.exception_ranges
|
||||
.exception_ranges*) }
|
||||
/* Adjust the address for the data segment. We want to adjust up to
|
||||
the same address within the page on the next page up. */
|
||||
. = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
|
||||
/* Exception handling */
|
||||
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) }
|
||||
.gnu_extab : ONLY_IF_RW { *(.gnu_extab) }
|
||||
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
|
||||
.exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) }
|
||||
/* Thread Local Storage sections */
|
||||
.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
|
||||
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
|
||||
.preinit_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
}
|
||||
. = ALIGN(0x200000);
|
||||
.init_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
|
||||
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
}
|
||||
.fini_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
|
||||
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
}
|
||||
.ctors :
|
||||
{
|
||||
/* gcc uses crtbegin.o to find the start of
|
||||
the constructors, so we make sure it is
|
||||
first. Because this is a wildcard, it
|
||||
doesn't matter if the user does not
|
||||
actually link against crtbegin.o; the
|
||||
linker won't look for a file to match a
|
||||
wildcard. The wildcard also means that it
|
||||
doesn't matter which directory crtbegin.o
|
||||
is in. */
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*crtbegin?.o(.ctors))
|
||||
/* We don't want to include the .ctor section from
|
||||
the crtend.o file until after the sorted ctors.
|
||||
The .ctor section from the crtend file contains the
|
||||
end of ctors marker and it must be last */
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
}
|
||||
.dtors :
|
||||
{
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*crtbegin?.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
}
|
||||
.jcr : { KEEP (*(.jcr)) }
|
||||
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }
|
||||
.dynamic : { *(.dynamic) }
|
||||
.got : { *(.got) *(.igot) }
|
||||
. = DATA_SEGMENT_RELRO_END (24, .);
|
||||
.got.plt : { *(.got.plt) *(.igot.plt) }
|
||||
. = ALIGN(0x200000);
|
||||
.data :
|
||||
{
|
||||
addr_data = .;
|
||||
PROVIDE (__data_start = .);
|
||||
*(.data .data.* .gnu.linkonce.d.*)
|
||||
SORT(CONSTRUCTORS)
|
||||
. = ALIGN(0x200000);
|
||||
}
|
||||
.data1 : { *(.data1) }
|
||||
_edata = .; PROVIDE (edata = .);
|
||||
. = .;
|
||||
. = ALIGN(0x200000);
|
||||
__bss_start = .;
|
||||
__bss_start__ = .;
|
||||
.bss :
|
||||
{
|
||||
addr_bss = .;
|
||||
*(.dynbss)
|
||||
*(.bss .bss.* .gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
/* Align here to ensure that the .bss section occupies space up to
|
||||
_end. Align after .bss to ensure correct alignment even if the
|
||||
.bss section disappears because there are no input sections.
|
||||
FIXME: Why do we need it? When there is no .bss section, we don't
|
||||
pad the .data section. */
|
||||
. = ALIGN(. != 0 ? 64 / 8 : 1);
|
||||
. = ALIGN(0x200000);
|
||||
}
|
||||
_bss_end__ = . ; __bss_end__ = . ;
|
||||
. = ALIGN(64 / 8);
|
||||
. = SEGMENT_START("ldata-segment", .);
|
||||
. = ALIGN(64 / 8);
|
||||
__end__ = . ;
|
||||
_end = .; PROVIDE (end = .);
|
||||
. = DATA_SEGMENT_END (.);
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
/* DWARF 3 */
|
||||
.debug_pubtypes 0 : { *(.debug_pubtypes) }
|
||||
.debug_ranges 0 : { *(.debug_ranges) }
|
||||
/* DWARF Extension. */
|
||||
.debug_macro 0 : { *(.debug_macro) }
|
||||
.ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) }
|
||||
.note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
|
||||
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
|
||||
}
|
||||
|
||||
|
||||
268
test/large_page/arm64/501_64K.org.lds
Normal file
268
test/large_page/arm64/501_64K.org.lds
Normal file
@ -0,0 +1,268 @@
|
||||
GNU ld version 2.27-27.base.el7
|
||||
Supported emulations:
|
||||
aarch64linux
|
||||
aarch64elf
|
||||
aarch64elf32
|
||||
aarch64elf32b
|
||||
aarch64elfb
|
||||
armelf
|
||||
armelfb
|
||||
aarch64linuxb
|
||||
aarch64linux32
|
||||
aarch64linux32b
|
||||
armelfb_linux_eabi
|
||||
armelf_linux_eabi
|
||||
using internal linker script:
|
||||
==================================================
|
||||
/* Script for -z combreloc: combine and sort reloc sections */
|
||||
/* Copyright (C) 2014-2016 Free Software Foundation, Inc.
|
||||
Copying and distribution of this script, with or without modification,
|
||||
are permitted in any medium without royalty provided the copyright
|
||||
notice and this notice are preserved. */
|
||||
OUTPUT_FORMAT("elf64-littleaarch64", "elf64-bigaarch64",
|
||||
"elf64-littleaarch64")
|
||||
OUTPUT_ARCH(aarch64)
|
||||
ENTRY(_start)
|
||||
SEARCH_DIR("=/usr/aarch64-redhat-linux/lib64"); SEARCH_DIR("=/usr/lib64"); SEARCH_DIR("=/usr/local/lib64"); SEARCH_DIR("=/lib64"); SEARCH_DIR("=/usr/aarch64-redhat-linux/lib"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib");
|
||||
SECTIONS
|
||||
{
|
||||
/* Read-only sections, merged into text segment: */
|
||||
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS;
|
||||
.interp : { *(.interp) }
|
||||
.note.gnu.build-id : { *(.note.gnu.build-id) }
|
||||
.hash : { *(.hash) }
|
||||
.gnu.hash : { *(.gnu.hash) }
|
||||
.dynsym : { *(.dynsym) }
|
||||
.dynstr : { *(.dynstr) }
|
||||
.gnu.version : { *(.gnu.version) }
|
||||
.gnu.version_d : { *(.gnu.version_d) }
|
||||
.gnu.version_r : { *(.gnu.version_r) }
|
||||
.rela.dyn :
|
||||
{
|
||||
*(.rela.init)
|
||||
*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
|
||||
*(.rela.fini)
|
||||
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
|
||||
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
|
||||
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
|
||||
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
|
||||
*(.rela.ctors)
|
||||
*(.rela.dtors)
|
||||
*(.rela.got)
|
||||
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
|
||||
*(.rela.ifunc)
|
||||
}
|
||||
.rela.plt :
|
||||
{
|
||||
*(.rela.plt)
|
||||
PROVIDE_HIDDEN (__rela_iplt_start = .);
|
||||
*(.rela.iplt)
|
||||
PROVIDE_HIDDEN (__rela_iplt_end = .);
|
||||
}
|
||||
.init :
|
||||
{
|
||||
KEEP (*(SORT_NONE(.init)))
|
||||
} =0
|
||||
.plt : ALIGN(16) { *(.plt) *(.iplt) }
|
||||
.text :
|
||||
{
|
||||
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
|
||||
*(.text.exit .text.exit.*)
|
||||
*(.text.startup .text.startup.*)
|
||||
*(.text.hot .text.hot.*)
|
||||
*(.text .stub .text.* .gnu.linkonce.t.*)
|
||||
/* .gnu.warning sections are handled specially by elf32.em. */
|
||||
*(.gnu.warning)
|
||||
} =0
|
||||
.fini :
|
||||
{
|
||||
KEEP (*(SORT_NONE(.fini)))
|
||||
} =0
|
||||
PROVIDE (__etext = .);
|
||||
PROVIDE (_etext = .);
|
||||
PROVIDE (etext = .);
|
||||
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
|
||||
.rodata1 : { *(.rodata1) }
|
||||
.eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }
|
||||
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }
|
||||
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table
|
||||
.gcc_except_table.*) }
|
||||
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) }
|
||||
/* These sections are generated by the Sun/Oracle C++ compiler. */
|
||||
.exception_ranges : ONLY_IF_RO { *(.exception_ranges
|
||||
.exception_ranges*) }
|
||||
/* Adjust the address for the data segment. We want to adjust up to
|
||||
the same address within the page on the next page up. */
|
||||
. = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
|
||||
/* Exception handling */
|
||||
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) }
|
||||
.gnu_extab : ONLY_IF_RW { *(.gnu_extab) }
|
||||
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
|
||||
.exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) }
|
||||
/* Thread Local Storage sections */
|
||||
.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
|
||||
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
|
||||
.preinit_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
}
|
||||
.init_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
|
||||
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
}
|
||||
.fini_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
|
||||
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
}
|
||||
.ctors :
|
||||
{
|
||||
/* gcc uses crtbegin.o to find the start of
|
||||
the constructors, so we make sure it is
|
||||
first. Because this is a wildcard, it
|
||||
doesn't matter if the user does not
|
||||
actually link against crtbegin.o; the
|
||||
linker won't look for a file to match a
|
||||
wildcard. The wildcard also means that it
|
||||
doesn't matter which directory crtbegin.o
|
||||
is in. */
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*crtbegin?.o(.ctors))
|
||||
/* We don't want to include the .ctor section from
|
||||
the crtend.o file until after the sorted ctors.
|
||||
The .ctor section from the crtend file contains the
|
||||
end of ctors marker and it must be last */
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
}
|
||||
.dtors :
|
||||
{
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*crtbegin?.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
}
|
||||
.jcr : { KEEP (*(.jcr)) }
|
||||
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }
|
||||
.dynamic : { *(.dynamic) }
|
||||
.got : { *(.got) *(.igot) }
|
||||
. = DATA_SEGMENT_RELRO_END (24, .);
|
||||
.got.plt : { *(.got.plt) *(.igot.plt) }
|
||||
.data :
|
||||
{
|
||||
PROVIDE (__data_start = .);
|
||||
*(.data .data.* .gnu.linkonce.d.*)
|
||||
SORT(CONSTRUCTORS)
|
||||
}
|
||||
.data1 : { *(.data1) }
|
||||
_edata = .; PROVIDE (edata = .);
|
||||
. = .;
|
||||
__bss_start = .;
|
||||
__bss_start__ = .;
|
||||
.bss :
|
||||
{
|
||||
*(.dynbss)
|
||||
*(.bss .bss.* .gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
/* Align here to ensure that the .bss section occupies space up to
|
||||
_end. Align after .bss to ensure correct alignment even if the
|
||||
.bss section disappears because there are no input sections.
|
||||
FIXME: Why do we need it? When there is no .bss section, we don't
|
||||
pad the .data section. */
|
||||
. = ALIGN(. != 0 ? 64 / 8 : 1);
|
||||
}
|
||||
_bss_end__ = . ; __bss_end__ = . ;
|
||||
. = ALIGN(64 / 8);
|
||||
. = SEGMENT_START("ldata-segment", .);
|
||||
. = ALIGN(64 / 8);
|
||||
__end__ = . ;
|
||||
_end = .; PROVIDE (end = .);
|
||||
. = DATA_SEGMENT_END (.);
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
/* DWARF 3 */
|
||||
.debug_pubtypes 0 : { *(.debug_pubtypes) }
|
||||
.debug_ranges 0 : { *(.debug_ranges) }
|
||||
/* DWARF Extension. */
|
||||
.debug_macro 0 : { *(.debug_macro) }
|
||||
.ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) }
|
||||
.note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
|
||||
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
|
||||
}
|
||||
|
||||
|
||||
==================================================
|
||||
attempt to open /usr/lib/gcc/aarch64-redhat-linux/4.8.5/../../../../lib64/crt1.o succeeded
|
||||
/usr/lib/gcc/aarch64-redhat-linux/4.8.5/../../../../lib64/crt1.o
|
||||
attempt to open /usr/lib/gcc/aarch64-redhat-linux/4.8.5/../../../../lib64/crti.o succeeded
|
||||
/usr/lib/gcc/aarch64-redhat-linux/4.8.5/../../../../lib64/crti.o
|
||||
attempt to open /usr/lib/gcc/aarch64-redhat-linux/4.8.5/crtbegin.o succeeded
|
||||
/usr/lib/gcc/aarch64-redhat-linux/4.8.5/crtbegin.o
|
||||
attempt to open 501_64K.o succeeded
|
||||
501_64K.o
|
||||
attempt to open /usr/lib/gcc/aarch64-redhat-linux/4.8.5/libgcc.so failed
|
||||
attempt to open /usr/lib/gcc/aarch64-redhat-linux/4.8.5/libgcc.a succeeded
|
||||
attempt to open /usr/lib/gcc/aarch64-redhat-linux/4.8.5/libgcc_s.so succeeded
|
||||
-lgcc_s (/usr/lib/gcc/aarch64-redhat-linux/4.8.5/libgcc_s.so)
|
||||
attempt to open /usr/lib/gcc/aarch64-redhat-linux/4.8.5/libc.so failed
|
||||
attempt to open /usr/lib/gcc/aarch64-redhat-linux/4.8.5/libc.a failed
|
||||
attempt to open /usr/lib/gcc/aarch64-redhat-linux/4.8.5/../../../../lib64/libc.so succeeded
|
||||
opened script file /usr/lib/gcc/aarch64-redhat-linux/4.8.5/../../../../lib64/libc.so
|
||||
opened script file /usr/lib/gcc/aarch64-redhat-linux/4.8.5/../../../../lib64/libc.so
|
||||
attempt to open /lib64/libc.so.6 succeeded
|
||||
/lib64/libc.so.6
|
||||
attempt to open /usr/lib64/libc_nonshared.a succeeded
|
||||
(/usr/lib64/libc_nonshared.a)elf-init.oS
|
||||
attempt to open /lib/ld-linux-aarch64.so.1 succeeded
|
||||
/lib/ld-linux-aarch64.so.1
|
||||
/lib/ld-linux-aarch64.so.1
|
||||
attempt to open /usr/lib/gcc/aarch64-redhat-linux/4.8.5/libgcc.so failed
|
||||
attempt to open /usr/lib/gcc/aarch64-redhat-linux/4.8.5/libgcc.a succeeded
|
||||
attempt to open /usr/lib/gcc/aarch64-redhat-linux/4.8.5/libgcc_s.so succeeded
|
||||
-lgcc_s (/usr/lib/gcc/aarch64-redhat-linux/4.8.5/libgcc_s.so)
|
||||
attempt to open /usr/lib/gcc/aarch64-redhat-linux/4.8.5/crtend.o succeeded
|
||||
/usr/lib/gcc/aarch64-redhat-linux/4.8.5/crtend.o
|
||||
attempt to open /usr/lib/gcc/aarch64-redhat-linux/4.8.5/../../../../lib64/crtn.o succeeded
|
||||
/usr/lib/gcc/aarch64-redhat-linux/4.8.5/../../../../lib64/crtn.o
|
||||
ld-linux-aarch64.so.1 needed by /lib64/libc.so.6
|
||||
found ld-linux-aarch64.so.1 at /lib/ld-linux-aarch64.so.1
|
||||
50
test/large_page/arm64/502_4K.c
Normal file
50
test/large_page/arm64/502_4K.c
Normal file
@ -0,0 +1,50 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/shm.h>
|
||||
#include "../util.h"
|
||||
|
||||
#define TARGET_PAGE_SHIFT 21
|
||||
#define TARGET_PAGE_SIZE (1UL << TARGET_PAGE_SHIFT)
|
||||
|
||||
/* .data */
|
||||
char addr_data[TARGET_PAGE_SIZE] = { 1 };
|
||||
|
||||
/* .bss */
|
||||
char addr_bss[TARGET_PAGE_SIZE];
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int trial_num = 0;
|
||||
char addr_stack[TARGET_PAGE_SIZE]
|
||||
__attribute__((aligned(TARGET_PAGE_SIZE)));
|
||||
|
||||
/* .data */
|
||||
addr_data[0] = 'z';
|
||||
NG(__atomic_load_n(addr_data, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_data, TARGET_PAGE_SIZE);
|
||||
|
||||
/* .bss */
|
||||
addr_bss[0] = 'z';
|
||||
NG(__atomic_load_n(addr_bss, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_bss, TARGET_PAGE_SIZE);
|
||||
|
||||
/* stack */
|
||||
addr_stack[0] = 'z';
|
||||
NG(__atomic_load_n(addr_stack, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_stack, TARGET_PAGE_SIZE);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
224
test/large_page/arm64/502_4K.lds
Normal file
224
test/large_page/arm64/502_4K.lds
Normal file
@ -0,0 +1,224 @@
|
||||
/* Script for -z combreloc: combine and sort reloc sections */
|
||||
/* Copyright (C) 2014-2016 Free Software Foundation, Inc.
|
||||
Copying and distribution of this script, with or without modification,
|
||||
are permitted in any medium without royalty provided the copyright
|
||||
notice and this notice are preserved. */
|
||||
OUTPUT_FORMAT("elf64-littleaarch64", "elf64-bigaarch64",
|
||||
"elf64-littleaarch64")
|
||||
OUTPUT_ARCH(aarch64)
|
||||
ENTRY(_start)
|
||||
SEARCH_DIR("=/usr/aarch64-redhat-linux/lib64"); SEARCH_DIR("=/usr/lib64"); SEARCH_DIR("=/usr/local/lib64"); SEARCH_DIR("=/lib64"); SEARCH_DIR("=/usr/aarch64-redhat-linux/lib"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib");
|
||||
SECTIONS
|
||||
{
|
||||
/* Read-only sections, merged into text segment: */
|
||||
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS;
|
||||
.interp : { *(.interp) }
|
||||
.note.gnu.build-id : { *(.note.gnu.build-id) }
|
||||
.hash : { *(.hash) }
|
||||
.gnu.hash : { *(.gnu.hash) }
|
||||
.dynsym : { *(.dynsym) }
|
||||
.dynstr : { *(.dynstr) }
|
||||
.gnu.version : { *(.gnu.version) }
|
||||
.gnu.version_d : { *(.gnu.version_d) }
|
||||
.gnu.version_r : { *(.gnu.version_r) }
|
||||
.rela.dyn :
|
||||
{
|
||||
*(.rela.init)
|
||||
*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
|
||||
*(.rela.fini)
|
||||
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
|
||||
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
|
||||
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
|
||||
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
|
||||
*(.rela.ctors)
|
||||
*(.rela.dtors)
|
||||
*(.rela.got)
|
||||
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
|
||||
*(.rela.ifunc)
|
||||
}
|
||||
.rela.plt :
|
||||
{
|
||||
*(.rela.plt)
|
||||
PROVIDE_HIDDEN (__rela_iplt_start = .);
|
||||
*(.rela.iplt)
|
||||
PROVIDE_HIDDEN (__rela_iplt_end = .);
|
||||
}
|
||||
.init :
|
||||
{
|
||||
KEEP (*(SORT_NONE(.init)))
|
||||
} =0
|
||||
.plt : ALIGN(16) { *(.plt) *(.iplt) }
|
||||
.text :
|
||||
{
|
||||
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
|
||||
*(.text.exit .text.exit.*)
|
||||
*(.text.startup .text.startup.*)
|
||||
*(.text.hot .text.hot.*)
|
||||
*(.text .stub .text.* .gnu.linkonce.t.*)
|
||||
/* .gnu.warning sections are handled specially by elf32.em. */
|
||||
*(.gnu.warning)
|
||||
} =0
|
||||
.fini :
|
||||
{
|
||||
KEEP (*(SORT_NONE(.fini)))
|
||||
} =0
|
||||
PROVIDE (__etext = .);
|
||||
PROVIDE (_etext = .);
|
||||
PROVIDE (etext = .);
|
||||
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
|
||||
.rodata1 : { *(.rodata1) }
|
||||
.eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }
|
||||
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }
|
||||
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table
|
||||
.gcc_except_table.*) }
|
||||
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) }
|
||||
/* These sections are generated by the Sun/Oracle C++ compiler. */
|
||||
.exception_ranges : ONLY_IF_RO { *(.exception_ranges
|
||||
.exception_ranges*) }
|
||||
/* Adjust the address for the data segment. We want to adjust up to
|
||||
the same address within the page on the next page up. */
|
||||
. = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
|
||||
/* Exception handling */
|
||||
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) }
|
||||
.gnu_extab : ONLY_IF_RW { *(.gnu_extab) }
|
||||
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
|
||||
.exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) }
|
||||
/* Thread Local Storage sections */
|
||||
.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
|
||||
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
|
||||
.preinit_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
}
|
||||
. = ALIGN(0x200000);
|
||||
.init_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
|
||||
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
}
|
||||
.fini_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
|
||||
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
}
|
||||
.ctors :
|
||||
{
|
||||
/* gcc uses crtbegin.o to find the start of
|
||||
the constructors, so we make sure it is
|
||||
first. Because this is a wildcard, it
|
||||
doesn't matter if the user does not
|
||||
actually link against crtbegin.o; the
|
||||
linker won't look for a file to match a
|
||||
wildcard. The wildcard also means that it
|
||||
doesn't matter which directory crtbegin.o
|
||||
is in. */
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*crtbegin?.o(.ctors))
|
||||
/* We don't want to include the .ctor section from
|
||||
the crtend.o file until after the sorted ctors.
|
||||
The .ctor section from the crtend file contains the
|
||||
end of ctors marker and it must be last */
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
}
|
||||
.dtors :
|
||||
{
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*crtbegin?.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
}
|
||||
.jcr : { KEEP (*(.jcr)) }
|
||||
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }
|
||||
.dynamic : { *(.dynamic) }
|
||||
.got : { *(.got) *(.igot) }
|
||||
. = DATA_SEGMENT_RELRO_END (24, .);
|
||||
.got.plt : { *(.got.plt) *(.igot.plt) }
|
||||
. = ALIGN(0x200000);
|
||||
.data :
|
||||
{
|
||||
addr_data = .;
|
||||
PROVIDE (__data_start = .);
|
||||
*(.data .data.* .gnu.linkonce.d.*)
|
||||
SORT(CONSTRUCTORS)
|
||||
. = ALIGN(0x200000);
|
||||
}
|
||||
.data1 : { *(.data1) }
|
||||
_edata = .; PROVIDE (edata = .);
|
||||
. = .;
|
||||
. = ALIGN(0x200000);
|
||||
__bss_start = .;
|
||||
__bss_start__ = .;
|
||||
.bss :
|
||||
{
|
||||
addr_bss = .;
|
||||
*(.dynbss)
|
||||
*(.bss .bss.* .gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
/* Align here to ensure that the .bss section occupies space up to
|
||||
_end. Align after .bss to ensure correct alignment even if the
|
||||
.bss section disappears because there are no input sections.
|
||||
FIXME: Why do we need it? When there is no .bss section, we don't
|
||||
pad the .data section. */
|
||||
. = ALIGN(. != 0 ? 64 / 8 : 1);
|
||||
. = ALIGN(0x200000);
|
||||
}
|
||||
_bss_end__ = . ; __bss_end__ = . ;
|
||||
. = ALIGN(64 / 8);
|
||||
. = SEGMENT_START("ldata-segment", .);
|
||||
. = ALIGN(64 / 8);
|
||||
__end__ = . ;
|
||||
_end = .; PROVIDE (end = .);
|
||||
. = DATA_SEGMENT_END (.);
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
/* DWARF 3 */
|
||||
.debug_pubtypes 0 : { *(.debug_pubtypes) }
|
||||
.debug_ranges 0 : { *(.debug_ranges) }
|
||||
/* DWARF Extension. */
|
||||
.debug_macro 0 : { *(.debug_macro) }
|
||||
.ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) }
|
||||
.note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
|
||||
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
|
||||
}
|
||||
|
||||
|
||||
41
test/large_page/arm64/502_64K.c
Normal file
41
test/large_page/arm64/502_64K.c
Normal file
@ -0,0 +1,41 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/shm.h>
|
||||
#include "../util.h"
|
||||
|
||||
#define TARGET_PAGE_SHIFT 29
|
||||
#define TARGET_PAGE_SIZE (1UL << TARGET_PAGE_SHIFT)
|
||||
|
||||
/* .data */
|
||||
char addr_data[TARGET_PAGE_SIZE] = { 1 };
|
||||
|
||||
/* .bss */
|
||||
char addr_bss[TARGET_PAGE_SIZE];
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int trial_num = 0;
|
||||
|
||||
/* .data */
|
||||
addr_data[0] = 'z';
|
||||
NG(__atomic_load_n(addr_data, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_data, TARGET_PAGE_SIZE);
|
||||
|
||||
/* .bss */
|
||||
addr_bss[0] = 'z';
|
||||
NG(__atomic_load_n(addr_bss, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_bss, TARGET_PAGE_SIZE);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
224
test/large_page/arm64/502_64K.lds
Normal file
224
test/large_page/arm64/502_64K.lds
Normal file
@ -0,0 +1,224 @@
|
||||
/* Script for -z combreloc: combine and sort reloc sections */
|
||||
/* Copyright (C) 2014-2016 Free Software Foundation, Inc.
|
||||
Copying and distribution of this script, with or without modification,
|
||||
are permitted in any medium without royalty provided the copyright
|
||||
notice and this notice are preserved. */
|
||||
OUTPUT_FORMAT("elf64-littleaarch64", "elf64-bigaarch64",
|
||||
"elf64-littleaarch64")
|
||||
OUTPUT_ARCH(aarch64)
|
||||
ENTRY(_start)
|
||||
SEARCH_DIR("=/usr/aarch64-redhat-linux/lib64"); SEARCH_DIR("=/usr/lib64"); SEARCH_DIR("=/usr/local/lib64"); SEARCH_DIR("=/lib64"); SEARCH_DIR("=/usr/aarch64-redhat-linux/lib"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib");
|
||||
SECTIONS
|
||||
{
|
||||
/* Read-only sections, merged into text segment: */
|
||||
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS;
|
||||
.interp : { *(.interp) }
|
||||
.note.gnu.build-id : { *(.note.gnu.build-id) }
|
||||
.hash : { *(.hash) }
|
||||
.gnu.hash : { *(.gnu.hash) }
|
||||
.dynsym : { *(.dynsym) }
|
||||
.dynstr : { *(.dynstr) }
|
||||
.gnu.version : { *(.gnu.version) }
|
||||
.gnu.version_d : { *(.gnu.version_d) }
|
||||
.gnu.version_r : { *(.gnu.version_r) }
|
||||
.rela.dyn :
|
||||
{
|
||||
*(.rela.init)
|
||||
*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
|
||||
*(.rela.fini)
|
||||
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
|
||||
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
|
||||
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
|
||||
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
|
||||
*(.rela.ctors)
|
||||
*(.rela.dtors)
|
||||
*(.rela.got)
|
||||
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
|
||||
*(.rela.ifunc)
|
||||
}
|
||||
.rela.plt :
|
||||
{
|
||||
*(.rela.plt)
|
||||
PROVIDE_HIDDEN (__rela_iplt_start = .);
|
||||
*(.rela.iplt)
|
||||
PROVIDE_HIDDEN (__rela_iplt_end = .);
|
||||
}
|
||||
.init :
|
||||
{
|
||||
KEEP (*(SORT_NONE(.init)))
|
||||
} =0
|
||||
.plt : ALIGN(16) { *(.plt) *(.iplt) }
|
||||
.text :
|
||||
{
|
||||
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
|
||||
*(.text.exit .text.exit.*)
|
||||
*(.text.startup .text.startup.*)
|
||||
*(.text.hot .text.hot.*)
|
||||
*(.text .stub .text.* .gnu.linkonce.t.*)
|
||||
/* .gnu.warning sections are handled specially by elf32.em. */
|
||||
*(.gnu.warning)
|
||||
} =0
|
||||
.fini :
|
||||
{
|
||||
KEEP (*(SORT_NONE(.fini)))
|
||||
} =0
|
||||
PROVIDE (__etext = .);
|
||||
PROVIDE (_etext = .);
|
||||
PROVIDE (etext = .);
|
||||
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
|
||||
.rodata1 : { *(.rodata1) }
|
||||
.eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }
|
||||
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }
|
||||
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table
|
||||
.gcc_except_table.*) }
|
||||
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) }
|
||||
/* These sections are generated by the Sun/Oracle C++ compiler. */
|
||||
.exception_ranges : ONLY_IF_RO { *(.exception_ranges
|
||||
.exception_ranges*) }
|
||||
/* Adjust the address for the data segment. We want to adjust up to
|
||||
the same address within the page on the next page up. */
|
||||
. = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
|
||||
/* Exception handling */
|
||||
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) }
|
||||
.gnu_extab : ONLY_IF_RW { *(.gnu_extab) }
|
||||
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
|
||||
.exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) }
|
||||
/* Thread Local Storage sections */
|
||||
.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
|
||||
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
|
||||
.preinit_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
}
|
||||
. = ALIGN(0x20000000);
|
||||
.init_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
|
||||
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
}
|
||||
.fini_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
|
||||
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
}
|
||||
.ctors :
|
||||
{
|
||||
/* gcc uses crtbegin.o to find the start of
|
||||
the constructors, so we make sure it is
|
||||
first. Because this is a wildcard, it
|
||||
doesn't matter if the user does not
|
||||
actually link against crtbegin.o; the
|
||||
linker won't look for a file to match a
|
||||
wildcard. The wildcard also means that it
|
||||
doesn't matter which directory crtbegin.o
|
||||
is in. */
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*crtbegin?.o(.ctors))
|
||||
/* We don't want to include the .ctor section from
|
||||
the crtend.o file until after the sorted ctors.
|
||||
The .ctor section from the crtend file contains the
|
||||
end of ctors marker and it must be last */
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
}
|
||||
.dtors :
|
||||
{
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*crtbegin?.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
}
|
||||
.jcr : { KEEP (*(.jcr)) }
|
||||
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }
|
||||
.dynamic : { *(.dynamic) }
|
||||
.got : { *(.got) *(.igot) }
|
||||
. = DATA_SEGMENT_RELRO_END (24, .);
|
||||
.got.plt : { *(.got.plt) *(.igot.plt) }
|
||||
. = ALIGN(0x20000000);
|
||||
.data :
|
||||
{
|
||||
addr_data = .;
|
||||
PROVIDE (__data_start = .);
|
||||
*(.data .data.* .gnu.linkonce.d.*)
|
||||
SORT(CONSTRUCTORS)
|
||||
. = ALIGN(0x20000000);
|
||||
}
|
||||
.data1 : { *(.data1) }
|
||||
_edata = .; PROVIDE (edata = .);
|
||||
. = .;
|
||||
. = ALIGN(0x20000000);
|
||||
__bss_start = .;
|
||||
__bss_start__ = .;
|
||||
.bss :
|
||||
{
|
||||
addr_bss = .;
|
||||
*(.dynbss)
|
||||
*(.bss .bss.* .gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
/* Align here to ensure that the .bss section occupies space up to
|
||||
_end. Align after .bss to ensure correct alignment even if the
|
||||
.bss section disappears because there are no input sections.
|
||||
FIXME: Why do we need it? When there is no .bss section, we don't
|
||||
pad the .data section. */
|
||||
. = ALIGN(. != 0 ? 64 / 8 : 1);
|
||||
. = ALIGN(0x20000000);
|
||||
}
|
||||
_bss_end__ = . ; __bss_end__ = . ;
|
||||
. = ALIGN(64 / 8);
|
||||
. = SEGMENT_START("ldata-segment", .);
|
||||
. = ALIGN(64 / 8);
|
||||
__end__ = . ;
|
||||
_end = .; PROVIDE (end = .);
|
||||
. = DATA_SEGMENT_END (.);
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
/* DWARF 3 */
|
||||
.debug_pubtypes 0 : { *(.debug_pubtypes) }
|
||||
.debug_ranges 0 : { *(.debug_ranges) }
|
||||
/* DWARF Extension. */
|
||||
.debug_macro 0 : { *(.debug_macro) }
|
||||
.ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) }
|
||||
.note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
|
||||
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
|
||||
}
|
||||
|
||||
|
||||
50
test/large_page/arm64/503_4K.c
Normal file
50
test/large_page/arm64/503_4K.c
Normal file
@ -0,0 +1,50 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/shm.h>
|
||||
#include "../util.h"
|
||||
|
||||
#define TARGET_PAGE_SHIFT 25
|
||||
#define TARGET_PAGE_SIZE (1UL << TARGET_PAGE_SHIFT)
|
||||
|
||||
/* .data */
|
||||
char addr_data[TARGET_PAGE_SIZE] = { 1 };
|
||||
|
||||
/* .bss */
|
||||
char addr_bss[TARGET_PAGE_SIZE];
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int trial_num = 0;
|
||||
char addr_stack[TARGET_PAGE_SIZE]
|
||||
__attribute__((aligned(TARGET_PAGE_SIZE)));
|
||||
|
||||
/* .data */
|
||||
addr_data[0] = 'z';
|
||||
NG(__atomic_load_n(addr_data, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_data, TARGET_PAGE_SIZE);
|
||||
|
||||
/* .bss */
|
||||
addr_bss[0] = 'z';
|
||||
NG(__atomic_load_n(addr_bss, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_bss, TARGET_PAGE_SIZE);
|
||||
|
||||
/* stack */
|
||||
addr_stack[0] = 'z';
|
||||
NG(__atomic_load_n(addr_stack, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_stack, TARGET_PAGE_SIZE);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
224
test/large_page/arm64/503_4K.lds
Normal file
224
test/large_page/arm64/503_4K.lds
Normal file
@ -0,0 +1,224 @@
|
||||
/* Script for -z combreloc: combine and sort reloc sections */
|
||||
/* Copyright (C) 2014-2016 Free Software Foundation, Inc.
|
||||
Copying and distribution of this script, with or without modification,
|
||||
are permitted in any medium without royalty provided the copyright
|
||||
notice and this notice are preserved. */
|
||||
OUTPUT_FORMAT("elf64-littleaarch64", "elf64-bigaarch64",
|
||||
"elf64-littleaarch64")
|
||||
OUTPUT_ARCH(aarch64)
|
||||
ENTRY(_start)
|
||||
SEARCH_DIR("=/usr/aarch64-redhat-linux/lib64"); SEARCH_DIR("=/usr/lib64"); SEARCH_DIR("=/usr/local/lib64"); SEARCH_DIR("=/lib64"); SEARCH_DIR("=/usr/aarch64-redhat-linux/lib"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib");
|
||||
SECTIONS
|
||||
{
|
||||
/* Read-only sections, merged into text segment: */
|
||||
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS;
|
||||
.interp : { *(.interp) }
|
||||
.note.gnu.build-id : { *(.note.gnu.build-id) }
|
||||
.hash : { *(.hash) }
|
||||
.gnu.hash : { *(.gnu.hash) }
|
||||
.dynsym : { *(.dynsym) }
|
||||
.dynstr : { *(.dynstr) }
|
||||
.gnu.version : { *(.gnu.version) }
|
||||
.gnu.version_d : { *(.gnu.version_d) }
|
||||
.gnu.version_r : { *(.gnu.version_r) }
|
||||
.rela.dyn :
|
||||
{
|
||||
*(.rela.init)
|
||||
*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
|
||||
*(.rela.fini)
|
||||
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
|
||||
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
|
||||
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
|
||||
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
|
||||
*(.rela.ctors)
|
||||
*(.rela.dtors)
|
||||
*(.rela.got)
|
||||
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
|
||||
*(.rela.ifunc)
|
||||
}
|
||||
.rela.plt :
|
||||
{
|
||||
*(.rela.plt)
|
||||
PROVIDE_HIDDEN (__rela_iplt_start = .);
|
||||
*(.rela.iplt)
|
||||
PROVIDE_HIDDEN (__rela_iplt_end = .);
|
||||
}
|
||||
.init :
|
||||
{
|
||||
KEEP (*(SORT_NONE(.init)))
|
||||
} =0
|
||||
.plt : ALIGN(16) { *(.plt) *(.iplt) }
|
||||
.text :
|
||||
{
|
||||
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
|
||||
*(.text.exit .text.exit.*)
|
||||
*(.text.startup .text.startup.*)
|
||||
*(.text.hot .text.hot.*)
|
||||
*(.text .stub .text.* .gnu.linkonce.t.*)
|
||||
/* .gnu.warning sections are handled specially by elf32.em. */
|
||||
*(.gnu.warning)
|
||||
} =0
|
||||
.fini :
|
||||
{
|
||||
KEEP (*(SORT_NONE(.fini)))
|
||||
} =0
|
||||
PROVIDE (__etext = .);
|
||||
PROVIDE (_etext = .);
|
||||
PROVIDE (etext = .);
|
||||
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
|
||||
.rodata1 : { *(.rodata1) }
|
||||
.eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }
|
||||
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }
|
||||
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table
|
||||
.gcc_except_table.*) }
|
||||
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) }
|
||||
/* These sections are generated by the Sun/Oracle C++ compiler. */
|
||||
.exception_ranges : ONLY_IF_RO { *(.exception_ranges
|
||||
.exception_ranges*) }
|
||||
/* Adjust the address for the data segment. We want to adjust up to
|
||||
the same address within the page on the next page up. */
|
||||
. = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
|
||||
/* Exception handling */
|
||||
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) }
|
||||
.gnu_extab : ONLY_IF_RW { *(.gnu_extab) }
|
||||
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
|
||||
.exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) }
|
||||
/* Thread Local Storage sections */
|
||||
.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
|
||||
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
|
||||
.preinit_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
}
|
||||
. = ALIGN(0x2000000);
|
||||
.init_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
|
||||
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
}
|
||||
.fini_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
|
||||
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
}
|
||||
.ctors :
|
||||
{
|
||||
/* gcc uses crtbegin.o to find the start of
|
||||
the constructors, so we make sure it is
|
||||
first. Because this is a wildcard, it
|
||||
doesn't matter if the user does not
|
||||
actually link against crtbegin.o; the
|
||||
linker won't look for a file to match a
|
||||
wildcard. The wildcard also means that it
|
||||
doesn't matter which directory crtbegin.o
|
||||
is in. */
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*crtbegin?.o(.ctors))
|
||||
/* We don't want to include the .ctor section from
|
||||
the crtend.o file until after the sorted ctors.
|
||||
The .ctor section from the crtend file contains the
|
||||
end of ctors marker and it must be last */
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
}
|
||||
.dtors :
|
||||
{
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*crtbegin?.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
}
|
||||
.jcr : { KEEP (*(.jcr)) }
|
||||
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }
|
||||
.dynamic : { *(.dynamic) }
|
||||
.got : { *(.got) *(.igot) }
|
||||
. = DATA_SEGMENT_RELRO_END (24, .);
|
||||
.got.plt : { *(.got.plt) *(.igot.plt) }
|
||||
. = ALIGN(0x2000000);
|
||||
.data :
|
||||
{
|
||||
addr_data = .;
|
||||
PROVIDE (__data_start = .);
|
||||
*(.data .data.* .gnu.linkonce.d.*)
|
||||
SORT(CONSTRUCTORS)
|
||||
. = ALIGN(0x2000000);
|
||||
}
|
||||
.data1 : { *(.data1) }
|
||||
_edata = .; PROVIDE (edata = .);
|
||||
. = .;
|
||||
. = ALIGN(0x2000000);
|
||||
__bss_start = .;
|
||||
__bss_start__ = .;
|
||||
.bss :
|
||||
{
|
||||
addr_bss = .;
|
||||
*(.dynbss)
|
||||
*(.bss .bss.* .gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
/* Align here to ensure that the .bss section occupies space up to
|
||||
_end. Align after .bss to ensure correct alignment even if the
|
||||
.bss section disappears because there are no input sections.
|
||||
FIXME: Why do we need it? When there is no .bss section, we don't
|
||||
pad the .data section. */
|
||||
. = ALIGN(. != 0 ? 64 / 8 : 1);
|
||||
. = ALIGN(0x2000000);
|
||||
}
|
||||
_bss_end__ = . ; __bss_end__ = . ;
|
||||
. = ALIGN(64 / 8);
|
||||
. = SEGMENT_START("ldata-segment", .);
|
||||
. = ALIGN(64 / 8);
|
||||
__end__ = . ;
|
||||
_end = .; PROVIDE (end = .);
|
||||
. = DATA_SEGMENT_END (.);
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
/* DWARF 3 */
|
||||
.debug_pubtypes 0 : { *(.debug_pubtypes) }
|
||||
.debug_ranges 0 : { *(.debug_ranges) }
|
||||
/* DWARF Extension. */
|
||||
.debug_macro 0 : { *(.debug_macro) }
|
||||
.ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) }
|
||||
.note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
|
||||
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
|
||||
}
|
||||
|
||||
|
||||
41
test/large_page/arm64/504_4K.c
Normal file
41
test/large_page/arm64/504_4K.c
Normal file
@ -0,0 +1,41 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/shm.h>
|
||||
#include "../util.h"
|
||||
|
||||
#define TARGET_PAGE_SHIFT 30
|
||||
#define TARGET_PAGE_SIZE (1UL << TARGET_PAGE_SHIFT)
|
||||
|
||||
/* .data */
|
||||
char addr_data[TARGET_PAGE_SIZE] = { 1 };
|
||||
|
||||
/* .bss */
|
||||
char addr_bss[TARGET_PAGE_SIZE];
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int trial_num = 0;
|
||||
|
||||
/* .data */
|
||||
addr_data[0] = 'z';
|
||||
NG(__atomic_load_n(addr_data, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_data, TARGET_PAGE_SIZE);
|
||||
|
||||
/* .bss */
|
||||
addr_bss[0] = 'z';
|
||||
NG(__atomic_load_n(addr_bss, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_bss, TARGET_PAGE_SIZE);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
224
test/large_page/arm64/504_4K.lds
Normal file
224
test/large_page/arm64/504_4K.lds
Normal file
@ -0,0 +1,224 @@
|
||||
/* Script for -z combreloc: combine and sort reloc sections */
|
||||
/* Copyright (C) 2014-2016 Free Software Foundation, Inc.
|
||||
Copying and distribution of this script, with or without modification,
|
||||
are permitted in any medium without royalty provided the copyright
|
||||
notice and this notice are preserved. */
|
||||
OUTPUT_FORMAT("elf64-littleaarch64", "elf64-bigaarch64",
|
||||
"elf64-littleaarch64")
|
||||
OUTPUT_ARCH(aarch64)
|
||||
ENTRY(_start)
|
||||
SEARCH_DIR("=/usr/aarch64-redhat-linux/lib64"); SEARCH_DIR("=/usr/lib64"); SEARCH_DIR("=/usr/local/lib64"); SEARCH_DIR("=/lib64"); SEARCH_DIR("=/usr/aarch64-redhat-linux/lib"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib");
|
||||
SECTIONS
|
||||
{
|
||||
/* Read-only sections, merged into text segment: */
|
||||
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS;
|
||||
.interp : { *(.interp) }
|
||||
.note.gnu.build-id : { *(.note.gnu.build-id) }
|
||||
.hash : { *(.hash) }
|
||||
.gnu.hash : { *(.gnu.hash) }
|
||||
.dynsym : { *(.dynsym) }
|
||||
.dynstr : { *(.dynstr) }
|
||||
.gnu.version : { *(.gnu.version) }
|
||||
.gnu.version_d : { *(.gnu.version_d) }
|
||||
.gnu.version_r : { *(.gnu.version_r) }
|
||||
.rela.dyn :
|
||||
{
|
||||
*(.rela.init)
|
||||
*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
|
||||
*(.rela.fini)
|
||||
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
|
||||
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
|
||||
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
|
||||
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
|
||||
*(.rela.ctors)
|
||||
*(.rela.dtors)
|
||||
*(.rela.got)
|
||||
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
|
||||
*(.rela.ifunc)
|
||||
}
|
||||
.rela.plt :
|
||||
{
|
||||
*(.rela.plt)
|
||||
PROVIDE_HIDDEN (__rela_iplt_start = .);
|
||||
*(.rela.iplt)
|
||||
PROVIDE_HIDDEN (__rela_iplt_end = .);
|
||||
}
|
||||
.init :
|
||||
{
|
||||
KEEP (*(SORT_NONE(.init)))
|
||||
} =0
|
||||
.plt : ALIGN(16) { *(.plt) *(.iplt) }
|
||||
.text :
|
||||
{
|
||||
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
|
||||
*(.text.exit .text.exit.*)
|
||||
*(.text.startup .text.startup.*)
|
||||
*(.text.hot .text.hot.*)
|
||||
*(.text .stub .text.* .gnu.linkonce.t.*)
|
||||
/* .gnu.warning sections are handled specially by elf32.em. */
|
||||
*(.gnu.warning)
|
||||
} =0
|
||||
.fini :
|
||||
{
|
||||
KEEP (*(SORT_NONE(.fini)))
|
||||
} =0
|
||||
PROVIDE (__etext = .);
|
||||
PROVIDE (_etext = .);
|
||||
PROVIDE (etext = .);
|
||||
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
|
||||
.rodata1 : { *(.rodata1) }
|
||||
.eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }
|
||||
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }
|
||||
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table
|
||||
.gcc_except_table.*) }
|
||||
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) }
|
||||
/* These sections are generated by the Sun/Oracle C++ compiler. */
|
||||
.exception_ranges : ONLY_IF_RO { *(.exception_ranges
|
||||
.exception_ranges*) }
|
||||
/* Adjust the address for the data segment. We want to adjust up to
|
||||
the same address within the page on the next page up. */
|
||||
. = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
|
||||
/* Exception handling */
|
||||
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) }
|
||||
.gnu_extab : ONLY_IF_RW { *(.gnu_extab) }
|
||||
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
|
||||
.exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) }
|
||||
/* Thread Local Storage sections */
|
||||
.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
|
||||
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
|
||||
.preinit_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
}
|
||||
. = ALIGN(0x40000000);
|
||||
.init_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
|
||||
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
}
|
||||
.fini_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
|
||||
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
}
|
||||
.ctors :
|
||||
{
|
||||
/* gcc uses crtbegin.o to find the start of
|
||||
the constructors, so we make sure it is
|
||||
first. Because this is a wildcard, it
|
||||
doesn't matter if the user does not
|
||||
actually link against crtbegin.o; the
|
||||
linker won't look for a file to match a
|
||||
wildcard. The wildcard also means that it
|
||||
doesn't matter which directory crtbegin.o
|
||||
is in. */
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*crtbegin?.o(.ctors))
|
||||
/* We don't want to include the .ctor section from
|
||||
the crtend.o file until after the sorted ctors.
|
||||
The .ctor section from the crtend file contains the
|
||||
end of ctors marker and it must be last */
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
}
|
||||
.dtors :
|
||||
{
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*crtbegin?.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
}
|
||||
.jcr : { KEEP (*(.jcr)) }
|
||||
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }
|
||||
.dynamic : { *(.dynamic) }
|
||||
.got : { *(.got) *(.igot) }
|
||||
. = DATA_SEGMENT_RELRO_END (24, .);
|
||||
.got.plt : { *(.got.plt) *(.igot.plt) }
|
||||
. = ALIGN(0x40000000);
|
||||
.data :
|
||||
{
|
||||
addr_data = .;
|
||||
PROVIDE (__data_start = .);
|
||||
*(.data .data.* .gnu.linkonce.d.*)
|
||||
SORT(CONSTRUCTORS)
|
||||
. = ALIGN(0x40000000);
|
||||
}
|
||||
.data1 : { *(.data1) }
|
||||
_edata = .; PROVIDE (edata = .);
|
||||
. = .;
|
||||
. = ALIGN(0x40000000);
|
||||
__bss_start = .;
|
||||
__bss_start__ = .;
|
||||
.bss :
|
||||
{
|
||||
addr_bss = .;
|
||||
*(.dynbss)
|
||||
*(.bss .bss.* .gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
/* Align here to ensure that the .bss section occupies space up to
|
||||
_end. Align after .bss to ensure correct alignment even if the
|
||||
.bss section disappears because there are no input sections.
|
||||
FIXME: Why do we need it? When there is no .bss section, we don't
|
||||
pad the .data section. */
|
||||
. = ALIGN(. != 0 ? 64 / 8 : 1);
|
||||
. = ALIGN(0x40000000);
|
||||
}
|
||||
_bss_end__ = . ; __bss_end__ = . ;
|
||||
. = ALIGN(64 / 8);
|
||||
. = SEGMENT_START("ldata-segment", .);
|
||||
. = ALIGN(64 / 8);
|
||||
__end__ = . ;
|
||||
_end = .; PROVIDE (end = .);
|
||||
. = DATA_SEGMENT_END (.);
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
/* DWARF 3 */
|
||||
.debug_pubtypes 0 : { *(.debug_pubtypes) }
|
||||
.debug_ranges 0 : { *(.debug_ranges) }
|
||||
/* DWARF Extension. */
|
||||
.debug_macro 0 : { *(.debug_macro) }
|
||||
.ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) }
|
||||
.note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
|
||||
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
|
||||
}
|
||||
|
||||
|
||||
77
test/large_page/arm64/601_4K.c
Normal file
77
test/large_page/arm64/601_4K.c
Normal file
@ -0,0 +1,77 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/mman.h>
|
||||
#include "../util.h"
|
||||
|
||||
#define PAGE_SHIFT_64K 16
|
||||
#define PAGE_SIZE_64K (1UL << PAGE_SHIFT_64K)
|
||||
char fn_64K[] = "/mnt/hugetlbfs-64K/tmp";
|
||||
|
||||
#define PAGE_SHIFT_2M 21
|
||||
#define PAGE_SIZE_2M (1UL << PAGE_SHIFT_2M)
|
||||
char fn_2M[] = "/mnt/hugetlbfs-2M/tmp";
|
||||
|
||||
#define PAGE_SHIFT_32M 25
|
||||
#define PAGE_SIZE_32M (1UL << PAGE_SHIFT_32M)
|
||||
char fn_32M[] = "/mnt/hugetlbfs-32M/tmp";
|
||||
|
||||
#define PAGE_SHIFT_1G 30
|
||||
#define PAGE_SIZE_1G (1UL << PAGE_SHIFT_1G)
|
||||
char fn_1G[] = "/mnt/hugetlbfs-1G/tmp";
|
||||
|
||||
int trial_num;
|
||||
|
||||
int mmap_hugetlbfs(char *fn, size_t page_size)
|
||||
{
|
||||
int fd;
|
||||
char *addr_mmap;
|
||||
|
||||
fd = open(fn, O_CREAT | O_RDWR, 0755);
|
||||
NG(fd != -1, "open failed, fn: %s\n", fn);
|
||||
|
||||
addr_mmap = mmap(0, page_size,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED,
|
||||
fd, 0);
|
||||
NG(addr_mmap != (void *)-1, "mmap failed\n");
|
||||
addr_mmap[0] = 'z';
|
||||
NG(__atomic_load_n(addr_mmap, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_mmap, page_size);
|
||||
|
||||
munmap(addr_mmap, page_size);
|
||||
close(fd);
|
||||
unlink(fn);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = mmap_hugetlbfs(fn_64K, PAGE_SIZE_64K);
|
||||
NG(ret == 0, "mmap_hugetlbfs failed, fn: %s", fn_64K);
|
||||
|
||||
ret = mmap_hugetlbfs(fn_2M, PAGE_SIZE_2M);
|
||||
NG(ret == 0, "mmap_hugetlbfs failed, fn: %s", fn_2M);
|
||||
|
||||
ret = mmap_hugetlbfs(fn_32M, PAGE_SIZE_32M);
|
||||
NG(ret == 0, "mmap_hugetlbfs failed, fn: %s", fn_32M);
|
||||
|
||||
ret = mmap_hugetlbfs(fn_1G, PAGE_SIZE_1G);
|
||||
NG(ret == 0, "mmap_hugetlbfs failed, fn: %s", fn_1G);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
63
test/large_page/arm64/601_64K.c
Normal file
63
test/large_page/arm64/601_64K.c
Normal file
@ -0,0 +1,63 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/mman.h>
|
||||
#include "../util.h"
|
||||
|
||||
#define PAGE_SHIFT_2M 21
|
||||
#define PAGE_SIZE_2M (1UL << PAGE_SHIFT_2M)
|
||||
char fn_2M[] = "/mnt/hugetlbfs-2M/tmp";
|
||||
|
||||
#define PAGE_SHIFT_512M 29
|
||||
#define PAGE_SIZE_512M (1UL << PAGE_SHIFT_512M)
|
||||
char fn_512M[] = "/mnt/hugetlbfs-512M/tmp";
|
||||
|
||||
int trial_num;
|
||||
|
||||
int mmap_hugetlbfs(char *fn, size_t page_size)
|
||||
{
|
||||
int fd;
|
||||
char *addr_mmap;
|
||||
|
||||
fd = open(fn, O_CREAT | O_RDWR, 0755);
|
||||
NG(fd != -1, "open failed, fn: %s\n", fn);
|
||||
|
||||
addr_mmap = mmap(0, page_size,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED,
|
||||
fd, 0);
|
||||
NG(addr_mmap != (void *)-1, "mmap failed\n");
|
||||
addr_mmap[0] = 'z';
|
||||
NG(__atomic_load_n(addr_mmap, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_mmap, page_size);
|
||||
|
||||
munmap(addr_mmap, page_size);
|
||||
close(fd);
|
||||
unlink(fn);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = mmap_hugetlbfs(fn_2M, PAGE_SIZE_2M);
|
||||
NG(ret == 0, "mmap_hugetlbfs failed, fn: %s", fn_2M);
|
||||
|
||||
ret = mmap_hugetlbfs(fn_512M, PAGE_SIZE_512M);
|
||||
NG(ret == 0, "mmap_hugetlbfs failed, fn: %s", fn_512M);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
46
test/large_page/arm64/Makefile
Normal file
46
test/large_page/arm64/Makefile
Normal file
@ -0,0 +1,46 @@
|
||||
include $(HOME)/.mck_test_config.mk
|
||||
|
||||
CC = gcc
|
||||
|
||||
CPPFLAGS =
|
||||
CFLAGS = -Wall -Werror -g
|
||||
LDFLAGS =
|
||||
|
||||
PAGESIZE = $(shell getconf PAGESIZE)
|
||||
ifeq ($(PAGESIZE),65536)
|
||||
SRCS = $(shell ls *_64K.c)
|
||||
endif
|
||||
|
||||
ifeq ($(PAGESIZE),4096)
|
||||
SRCS = $(shell ls *_4K.c)
|
||||
endif
|
||||
|
||||
EXES = $(SRCS:.c=)
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
|
||||
all: $(EXES)
|
||||
|
||||
test:: $(EXES)
|
||||
../driver.sh $(TESTSET)
|
||||
|
||||
501_64K: 501_64K.o 501_64K.lds
|
||||
$(CC) -o $@ $< $(LDFLAGS) -T 501_64K.lds
|
||||
|
||||
502_64K: 502_64K.o 502_64K.lds
|
||||
$(CC) -o $@ $< $(LDFLAGS) -T 502_64K.lds
|
||||
|
||||
501_4K: 501_4K.o 501_4K.lds
|
||||
$(CC) -o $@ $< $(LDFLAGS) -T 501_4K.lds
|
||||
|
||||
502_4K: 502_4K.o 502_4K.lds
|
||||
$(CC) -o $@ $< $(LDFLAGS) -T 502_4K.lds
|
||||
|
||||
503_4K: 503_4K.o 503_4K.lds
|
||||
$(CC) -o $@ $< $(LDFLAGS) -T 503_4K.lds
|
||||
|
||||
504_4K: 504_4K.o 504_4K.lds
|
||||
$(CC) -o $@ $< $(LDFLAGS) -T 504_4K.lds
|
||||
|
||||
clean:
|
||||
rm -f core $(EXES) $(OBJS)
|
||||
|
||||
4
test/large_page/arm64/fini/601_4K.fini
Normal file
4
test/large_page/arm64/fini/601_4K.fini
Normal file
@ -0,0 +1,4 @@
|
||||
sudo umount /mnt/hugetlbfs-64K
|
||||
sudo umount /mnt/hugetlbfs-2M
|
||||
sudo umount /mnt/hugetlbfs-32M
|
||||
sudo umount /mnt/hugetlbfs-1G
|
||||
2
test/large_page/arm64/fini/601_64K.fini
Normal file
2
test/large_page/arm64/fini/601_64K.fini
Normal file
@ -0,0 +1,2 @@
|
||||
sudo umount /mnt/hugetlbfs-2M
|
||||
sudo umount /mnt/hugetlbfs-512M
|
||||
2
test/large_page/arm64/init/001_4K.init
Normal file
2
test/large_page/arm64/init/001_4K.init
Normal file
@ -0,0 +1,2 @@
|
||||
BOOTPARAM="-c 1-7 -m 16G -r 1-7:0"
|
||||
MCEXECOPT="-s 4K,16G"
|
||||
1
test/large_page/arm64/init/001_64K.init
Normal file
1
test/large_page/arm64/init/001_64K.init
Normal file
@ -0,0 +1 @@
|
||||
BOOTPARAM="-c 1-7 -m 16G -r 1-7:0"
|
||||
2
test/large_page/arm64/init/101_4K.init
Normal file
2
test/large_page/arm64/init/101_4K.init
Normal file
@ -0,0 +1,2 @@
|
||||
BOOTPARAM="-c 1-7 -m 16G -r 1-7:0"
|
||||
MCEXECOPT="-s 4K,16G"
|
||||
1
test/large_page/arm64/init/101_64K.init
Normal file
1
test/large_page/arm64/init/101_64K.init
Normal file
@ -0,0 +1 @@
|
||||
BOOTPARAM="-c 1-7 -m 16G -r 1-7:0"
|
||||
2
test/large_page/arm64/init/201_4K.init
Normal file
2
test/large_page/arm64/init/201_4K.init
Normal file
@ -0,0 +1,2 @@
|
||||
BOOTPARAM="-c 1-7 -m 16G -r 1-7:0"
|
||||
MCEXECOPT="-s 4K,16G"
|
||||
1
test/large_page/arm64/init/201_64K.init
Normal file
1
test/large_page/arm64/init/201_64K.init
Normal file
@ -0,0 +1 @@
|
||||
BOOTPARAM="-c 1-7 -m 16G -r 1-7:0"
|
||||
2
test/large_page/arm64/init/301_4K.init
Normal file
2
test/large_page/arm64/init/301_4K.init
Normal file
@ -0,0 +1,2 @@
|
||||
BOOTPARAM="-c 1-7 -m 16G -r 1-7:0"
|
||||
MCEXECOPT="-s 4K,16G"
|
||||
1
test/large_page/arm64/init/301_64K.init
Normal file
1
test/large_page/arm64/init/301_64K.init
Normal file
@ -0,0 +1 @@
|
||||
BOOTPARAM="-c 1-7 -m 16G -r 1-7:0"
|
||||
2
test/large_page/arm64/init/401_4K.init
Normal file
2
test/large_page/arm64/init/401_4K.init
Normal file
@ -0,0 +1,2 @@
|
||||
BOOTPARAM="-c 1-7 -m 16G -r 1-7:0"
|
||||
MCEXECOPT="-s 4K,16G -h 64K"
|
||||
2
test/large_page/arm64/init/401_64K.init
Normal file
2
test/large_page/arm64/init/401_64K.init
Normal file
@ -0,0 +1,2 @@
|
||||
BOOTPARAM="-c 1-7 -m 16G -r 1-7:0"
|
||||
MCEXECOPT="-h 2M"
|
||||
2
test/large_page/arm64/init/402_4K.init
Normal file
2
test/large_page/arm64/init/402_4K.init
Normal file
@ -0,0 +1,2 @@
|
||||
BOOTPARAM="-c 1-7 -m 16G -r 1-7:0"
|
||||
MCEXECOPT="-s 4K,16G -h 2M"
|
||||
2
test/large_page/arm64/init/402_64K.init
Normal file
2
test/large_page/arm64/init/402_64K.init
Normal file
@ -0,0 +1,2 @@
|
||||
BOOTPARAM="-c 1-7 -m 16G -r 1-7:0"
|
||||
MCEXECOPT="-h 512M"
|
||||
2
test/large_page/arm64/init/403_4K.init
Normal file
2
test/large_page/arm64/init/403_4K.init
Normal file
@ -0,0 +1,2 @@
|
||||
BOOTPARAM="-c 1-7 -m 16G -r 1-7:0"
|
||||
MCEXECOPT="-s 4K,16G -h 32M"
|
||||
2
test/large_page/arm64/init/404_4K.init
Normal file
2
test/large_page/arm64/init/404_4K.init
Normal file
@ -0,0 +1,2 @@
|
||||
BOOTPARAM="-c 1-7 -m 16G -r 1-7:0"
|
||||
MCEXECOPT="-s 4K,16G -h 1G"
|
||||
2
test/large_page/arm64/init/501_4K.init
Normal file
2
test/large_page/arm64/init/501_4K.init
Normal file
@ -0,0 +1,2 @@
|
||||
BOOTPARAM="-c 1-7 -m 16G -r 1-7:0"
|
||||
MCEXECOPT="-s 64K,16G"
|
||||
2
test/large_page/arm64/init/501_64K.init
Normal file
2
test/large_page/arm64/init/501_64K.init
Normal file
@ -0,0 +1,2 @@
|
||||
BOOTPARAM="-c 1-7 -m 16G -r 1-7:0"
|
||||
MCEXECOPT="-s 2M,16G"
|
||||
2
test/large_page/arm64/init/502_4K.init
Normal file
2
test/large_page/arm64/init/502_4K.init
Normal file
@ -0,0 +1,2 @@
|
||||
BOOTPARAM="-c 1-7 -m 16G -r 1-7:0"
|
||||
MCEXECOPT="-s 2M,16G"
|
||||
2
test/large_page/arm64/init/502_64K.init
Normal file
2
test/large_page/arm64/init/502_64K.init
Normal file
@ -0,0 +1,2 @@
|
||||
BOOTPARAM="-c 1-7 -m 16G -r 1-7:0"
|
||||
MCEXECOPT="-s 512M,16G"
|
||||
2
test/large_page/arm64/init/503_4K.init
Normal file
2
test/large_page/arm64/init/503_4K.init
Normal file
@ -0,0 +1,2 @@
|
||||
BOOTPARAM="-c 1-7 -m 16G -r 1-7:0"
|
||||
MCEXECOPT="-s 32M,16G"
|
||||
2
test/large_page/arm64/init/504_4K.init
Normal file
2
test/large_page/arm64/init/504_4K.init
Normal file
@ -0,0 +1,2 @@
|
||||
BOOTPARAM="-c 1-7 -m 16G -r 1-7:0"
|
||||
MCEXECOPT="-s 1G,16G"
|
||||
14
test/large_page/arm64/init/601_4K.init
Normal file
14
test/large_page/arm64/init/601_4K.init
Normal file
@ -0,0 +1,14 @@
|
||||
BOOTPARAM="-c 1-7 -m 16G -r 1-7:0"
|
||||
MCEXECOPT="-s 4K,16G"
|
||||
|
||||
sudo mkdir -p /mnt/hugetlbfs-64K
|
||||
sudo mount -t hugetlbfs -o mode=777,pagesize=64k none /mnt/hugetlbfs-64K
|
||||
|
||||
sudo mkdir -p /mnt/hugetlbfs-2M
|
||||
sudo mount -t hugetlbfs -o mode=777,pagesize=2m none /mnt/hugetlbfs-2M
|
||||
|
||||
sudo mkdir -p /mnt/hugetlbfs-32M
|
||||
sudo mount -t hugetlbfs -o mode=777,pagesize=32m none /mnt/hugetlbfs-32M
|
||||
|
||||
sudo mkdir -p /mnt/hugetlbfs-1G
|
||||
sudo mount -t hugetlbfs -o mode=777,pagesize=1g none /mnt/hugetlbfs-1G
|
||||
7
test/large_page/arm64/init/601_64K.init
Normal file
7
test/large_page/arm64/init/601_64K.init
Normal file
@ -0,0 +1,7 @@
|
||||
BOOTPARAM="-c 1-7 -m 16G -r 1-7:0"
|
||||
|
||||
sudo mkdir -p /mnt/hugetlbfs-2M
|
||||
sudo mount -t hugetlbfs -o mode=777,pagesize=2m none /mnt/hugetlbfs-2M
|
||||
|
||||
sudo mkdir -p /mnt/hugetlbfs-512M
|
||||
sudo mount -t hugetlbfs -o mode=777,pagesize=512m none /mnt/hugetlbfs-512M
|
||||
57
test/large_page/arm64/test_set.conf
Normal file
57
test/large_page/arm64/test_set.conf
Normal file
@ -0,0 +1,57 @@
|
||||
pagesize=$(getconf PAGESIZE)
|
||||
|
||||
case $pagesize in
|
||||
65536)
|
||||
# mmap + THP: 2MB, 512MB
|
||||
test_set="${test_set} 001"
|
||||
|
||||
# shget + THP: 2MB, 512MB
|
||||
test_set="${test_set} 101"
|
||||
|
||||
# mmap + flag: 2MB, 512MB
|
||||
test_set="${test_set} 201"
|
||||
|
||||
# shmget + flag: 2MB, 512MB
|
||||
test_set="${test_set} 301"
|
||||
|
||||
# brk: 2MB, 512MB
|
||||
test_set="${test_set} 401 402"
|
||||
|
||||
# .data, .bss, .stack: 2MB
|
||||
test_set="${test_set} 501"
|
||||
|
||||
# .data, .bss: 512M
|
||||
test_set="${test_set} 502"
|
||||
|
||||
# hugetlbfs: 2MB, 512MB
|
||||
test_set="${test_set} 601"
|
||||
;;
|
||||
4096)
|
||||
# mmap + THP: 64KB, 2MB, 32MB, 1GB
|
||||
test_set="${test_set} 001"
|
||||
|
||||
# shget + THP: 64KB, 2MB, 32MB, 1GB
|
||||
test_set="${test_set} 101"
|
||||
|
||||
# mmap + flag: 64KB, 2MB, 32MB, 1GB
|
||||
test_set="${test_set} 201"
|
||||
|
||||
# shmget + flag: 64KB, 2MB, 32MB, 1GB
|
||||
test_set="${test_set} 301"
|
||||
|
||||
# brk: 64KB, 2MB, 32MB. 1GB
|
||||
test_set="${test_set} 401 402 403 404"
|
||||
|
||||
# .data, .bss, .stack: 64KB, 2MB, 32MB
|
||||
test_set="${test_set} 501 502 503"
|
||||
|
||||
# .data, .bss: 1GB
|
||||
test_set="${test_set} 504"
|
||||
|
||||
# hugetlbfs: 64KB, 2MB, 32MB, 1GB
|
||||
test_set="${test_set} 601"
|
||||
;;
|
||||
*) echo "Error: Unknown page size: $pagesize"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
28
test/large_page/check.sh
Executable file
28
test/large_page/check.sh
Executable file
@ -0,0 +1,28 @@
|
||||
#!/bin/sh
|
||||
|
||||
test_id=$1
|
||||
log_file="./log/${test_id}.log"
|
||||
|
||||
num_addrs=`grep -c1 "large page request" $log_file`
|
||||
|
||||
for i in `seq 0 $((num_addrs - 1))`
|
||||
do
|
||||
|
||||
addr=`grep "large page request" $log_file | grep -e "trial#: $(printf "%03d" $i)" | tail -1 | grep -oE 'addr: \w{16}' | sed 's/addr: //'`
|
||||
pgsize_requested=`grep "large page request" $log_file | grep -e "trial#: $(printf "%03d" $i)" | tail -1 | grep -oE 'size: \w*' | sed 's/size: //'`
|
||||
pgsize_allocated=`grep "large page allocation" $log_file | grep -e $addr | tail -1 | grep -oE 'size: \w*' | sed 's/size: //'`
|
||||
|
||||
if [ "$pgsize_requested" != "$pgsize_allocated" ]; then
|
||||
printf "\t[ NG ] "
|
||||
else
|
||||
printf "\t[ OK ] "
|
||||
fi
|
||||
|
||||
printf "trial #: $(printf "%03d" $i), addr: $addr, requested size: $pgsize_requested, allocated size: $pgsize_allocated\n"
|
||||
|
||||
if [ "$pgsize_requested" != "$pgsize_allocated" ]; then
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
exit 0
|
||||
41
test/large_page/driver.sh
Executable file
41
test/large_page/driver.sh
Executable file
@ -0,0 +1,41 @@
|
||||
#!/bin/sh
|
||||
|
||||
# driver.sh [<test_set>]
|
||||
|
||||
test_set=$1
|
||||
|
||||
if [ "`git diff | grep -c 'large page allocation'`" == "0" ]; then
|
||||
echo "Perform \"patch -p0 < large_page.patch\""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$test_set" == "" ]; then
|
||||
source ./test_set.conf
|
||||
fi
|
||||
|
||||
if [ ! -d ./log ]; then
|
||||
mkdir log
|
||||
fi
|
||||
|
||||
for i in $test_set
|
||||
do
|
||||
test_id=$(printf "%03d" $i)
|
||||
|
||||
echo "[INFO] ${test_id} started"
|
||||
|
||||
../run.sh ${test_id} &> ./log/${test_id}.log
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "[ NG ] ${test_id} run failed"
|
||||
continue
|
||||
fi
|
||||
|
||||
../check.sh ${test_id}
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "[ NG ] ${test_id} result check failed"
|
||||
continue
|
||||
fi
|
||||
|
||||
echo "[ OK ] ${test_id} passed"
|
||||
done
|
||||
374
test/large_page/large_page.patch
Normal file
374
test/large_page/large_page.patch
Normal file
@ -0,0 +1,374 @@
|
||||
diff --git arch/arm64/kernel/memory.c arch/arm64/kernel/memory.c
|
||||
index ceca343..5e6c137 100644
|
||||
--- arch/arm64/kernel/memory.c
|
||||
+++ arch/arm64/kernel/memory.c
|
||||
@@ -2701,6 +2701,13 @@ int set_range_l1(void *args0, pte_t *ptep, uintptr_t base, uintptr_t start,
|
||||
ptl1_set(ptep, pte);
|
||||
|
||||
error = 0;
|
||||
+
|
||||
+ if (args->attr[0] & PTE_CONT &&
|
||||
+ __page_offset(base, PTL1_CONT_SIZE) == 0) {
|
||||
+ kprintf("%s: large page allocation, addr: %016lx, size: %d, phys: %lx\n",
|
||||
+ __func__, base, PTL1_CONT_SIZE, phys);
|
||||
+ }
|
||||
+
|
||||
// call memory_stat_rss_add() here because pgshift is resolved here
|
||||
if (rusage_memory_stat_add(args->range, phys, PTL1_SIZE, PTL1_SIZE)) {
|
||||
dkprintf("%lx+,%s: calling memory_stat_rss_add(),base=%lx,phys=%lx,size=%ld,pgsize=%ld\n", phys, __FUNCTION__, base, phys, PTL1_SIZE, PTL1_SIZE);
|
||||
@@ -2791,6 +2798,17 @@ retry:
|
||||
|
||||
ptl_set(ptep, phys | args->attr[level-1], level);
|
||||
error = 0;
|
||||
+
|
||||
+ if (args->attr[level-1] & PTE_CONT) {
|
||||
+ if (__page_offset(base, tbl.cont_pgsize) == 0) {
|
||||
+ kprintf("%s: large page allocation, addr: %016lx, size: %d, phys: %lx\n",
|
||||
+ __func__, base, tbl.cont_pgsize, phys);
|
||||
+ }
|
||||
+ } else {
|
||||
+ kprintf("%s: large page allocation, addr: %016lx, size: %d, phys: %lx\n",
|
||||
+ __func__, base, tbl.pgsize, phys);
|
||||
+ }
|
||||
+
|
||||
dkprintf("set_range_middle(%lx,%lx,%lx,%d):"
|
||||
"large page. %d %lx\n",
|
||||
base, start, end, level, error, *ptep);
|
||||
diff --git arch/x86_64/kernel/memory.c arch/x86_64/kernel/memory.c
|
||||
index 980d935..4fea4b0 100644
|
||||
--- arch/x86_64/kernel/memory.c
|
||||
+++ arch/x86_64/kernel/memory.c
|
||||
@@ -2030,6 +2030,10 @@ retry:
|
||||
dkprintf("set_range_l2(%lx,%lx,%lx):"
|
||||
"2MiB page. %d %lx\n",
|
||||
base, start, end, error, *ptep);
|
||||
+
|
||||
+ kprintf("%s: large page allocation, addr: %016lx, size: %d\n",
|
||||
+ __func__, base, PTL2_SIZE);
|
||||
+
|
||||
// Call memory_stat_rss_add() here because pgshift is resolved here
|
||||
if (rusage_memory_stat_add(args->range, phys, PTL2_SIZE, PTL2_SIZE)) {
|
||||
dkprintf("%lx+,%s: calling memory_stat_rss_add(),base=%lx,phys=%lx,size=%ld,pgsize=%ld\n", phys, __FUNCTION__, base, phys, PTL2_SIZE, PTL2_SIZE);
|
||||
@@ -2119,6 +2123,9 @@ retry:
|
||||
"1GiB page. %d %lx\n",
|
||||
base, start, end, error, *ptep);
|
||||
|
||||
+ kprintf("%s: large page allocation, addr: %016lx, size: %d\n",
|
||||
+ __func__, base, PTL3_SIZE);
|
||||
+
|
||||
// Call memory_stat_rss_add() here because pgshift is resolved here
|
||||
if (rusage_memory_stat_add(args->range, phys, PTL3_SIZE, PTL3_SIZE)) {
|
||||
dkprintf("%lx+,%s: calling memory_stat_rss_add(),base=%lx,phys=%lx,size=%ld,pgsize=%ld\n", phys, __FUNCTION__, base, phys, PTL3_SIZE, PTL3_SIZE);
|
||||
diff --git kernel/host.c kernel/host.c
|
||||
index 0de0a08..6fb906e 100644
|
||||
--- kernel/host.c
|
||||
+++ kernel/host.c
|
||||
@@ -96,10 +96,34 @@ int prepare_process_ranges_args_envs(struct thread *thread,
|
||||
unsigned long ap_flags;
|
||||
enum ihk_mc_pt_attribute ptattr;
|
||||
|
||||
+ unsigned long stack_page_size = pn->stack_premap;
|
||||
+ unsigned long stack_page_mask = ~(stack_page_size - 1);
|
||||
+ unsigned long stack_page_shift = 63 - __builtin_clzl(stack_page_size);
|
||||
+ unsigned long stack_page_p2align = stack_page_shift - PAGE_SHIFT;
|
||||
+
|
||||
+ unsigned long section_page_size;
|
||||
+ unsigned long section_page_mask;
|
||||
+ unsigned long section_page_shift;
|
||||
+ int section_page_p2align;
|
||||
+
|
||||
n = p->num_sections;
|
||||
|
||||
aout_base = (pn->reloc)? vm->region.map_end: 0;
|
||||
for (i = 0; i < n; i++) {
|
||||
+ if (stack_page_size > PAGE_SIZE &&
|
||||
+ pn->sections[i].len >= stack_page_size &&
|
||||
+ !(pn->sections[i].len & ~stack_page_mask)) {
|
||||
+ section_page_size = stack_page_size;
|
||||
+ section_page_mask = stack_page_mask;
|
||||
+ section_page_shift = stack_page_shift;
|
||||
+ section_page_p2align = stack_page_p2align;
|
||||
+ } else {
|
||||
+ section_page_size = PAGE_SIZE;
|
||||
+ section_page_mask = PAGE_MASK;
|
||||
+ section_page_shift = PAGE_SHIFT;
|
||||
+ section_page_p2align = PAGE_P2ALIGN;
|
||||
+ }
|
||||
+
|
||||
ap_flags = 0;
|
||||
if (pn->sections[i].interp && (interp_nbase == (uintptr_t)-1)) {
|
||||
interp_obase = pn->sections[i].vaddr;
|
||||
@@ -118,11 +142,22 @@ int prepare_process_ranges_args_envs(struct thread *thread,
|
||||
pn->sections[i].vaddr += aout_base;
|
||||
p->sections[i].vaddr = pn->sections[i].vaddr;
|
||||
}
|
||||
- s = (pn->sections[i].vaddr) & PAGE_MASK;
|
||||
+ s = (pn->sections[i].vaddr & section_page_mask);
|
||||
e = (pn->sections[i].vaddr + pn->sections[i].len
|
||||
- + PAGE_SIZE - 1) & PAGE_MASK;
|
||||
- range_npages = ((pn->sections[i].vaddr - s) +
|
||||
- pn->sections[i].filesz + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
||||
+ + section_page_size - 1) & section_page_mask;
|
||||
+
|
||||
+ if (section_page_size > PAGE_SIZE) {
|
||||
+ /* Pre-map .bss as well */
|
||||
+ range_npages = (((pn->sections[i].vaddr - s) +
|
||||
+ pn->sections[i].len + section_page_size - 1) >>
|
||||
+ section_page_shift) <<
|
||||
+ section_page_p2align;
|
||||
+ } else {
|
||||
+ range_npages = ((pn->sections[i].vaddr - s) +
|
||||
+ pn->sections[i].filesz + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
||||
+
|
||||
+ }
|
||||
+
|
||||
flags = VR_NONE;
|
||||
flags |= PROT_TO_VR_FLAG(pn->sections[i].prot);
|
||||
flags |= VRFLAG_PROT_TO_MAXPROT(flags);
|
||||
@@ -138,18 +173,37 @@ int prepare_process_ranges_args_envs(struct thread *thread,
|
||||
flags |= VR_AP_USER;
|
||||
}
|
||||
|
||||
- if (add_process_memory_range(vm, s, e, NOPHYS, flags, NULL, 0,
|
||||
- pn->sections[i].len > LARGE_PAGE_SIZE ?
|
||||
- LARGE_PAGE_SHIFT : PAGE_SHIFT,
|
||||
- &range) != 0) {
|
||||
- kprintf("ERROR: adding memory range for ELF section %i\n", i);
|
||||
- goto err;
|
||||
+ if (section_page_size > PAGE_SIZE) {
|
||||
+ if (add_process_memory_range(vm, s, e, NOPHYS, flags, NULL, 0,
|
||||
+ section_page_shift,
|
||||
+ &range) != 0) {
|
||||
+ kprintf("ERROR: adding memory range for ELF section %i\n", i);
|
||||
+ goto err;
|
||||
+ }
|
||||
+ } else {
|
||||
+ if (add_process_memory_range(vm, s, e, NOPHYS, flags, NULL, 0,
|
||||
+ pn->sections[i].len > LARGE_PAGE_SIZE ?
|
||||
+ LARGE_PAGE_SHIFT : PAGE_SHIFT,
|
||||
+ &range) != 0) {
|
||||
+ kprintf("ERROR: adding memory range for ELF section %i\n", i);
|
||||
+ goto err;
|
||||
+ }
|
||||
}
|
||||
|
||||
- if ((up_v = ihk_mc_alloc_pages_user(range_npages,
|
||||
- IHK_MC_AP_NOWAIT | ap_flags, s)) == NULL) {
|
||||
- kprintf("ERROR: alloc pages for ELF section %i\n", i);
|
||||
- goto err;
|
||||
+
|
||||
+ if (section_page_size > PAGE_SIZE) {
|
||||
+ if ((up_v = ihk_mc_alloc_aligned_pages_user(range_npages,
|
||||
+ section_page_p2align,
|
||||
+ IHK_MC_AP_NOWAIT | ap_flags, s)) == NULL) {
|
||||
+ kprintf("ERROR: alloc pages for ELF section %i\n", i);
|
||||
+ goto err;
|
||||
+ }
|
||||
+ } else {
|
||||
+ if ((up_v = ihk_mc_alloc_pages_user(range_npages,
|
||||
+ IHK_MC_AP_NOWAIT | ap_flags, s)) == NULL) {
|
||||
+ kprintf("ERROR: alloc pages for ELF section %i\n", i);
|
||||
+ goto err;
|
||||
+ }
|
||||
}
|
||||
|
||||
up = virt_to_phys(up_v);
|
||||
@@ -212,8 +266,19 @@ int prepare_process_ranges_args_envs(struct thread *thread,
|
||||
pn->at_entry += aout_base;
|
||||
}
|
||||
|
||||
+ unsigned long heap_page_size;
|
||||
+ unsigned long heap_page_mask;
|
||||
+
|
||||
+ if (proc->heap_extension > PAGE_SIZE) {
|
||||
+ heap_page_size = proc->heap_extension;
|
||||
+ heap_page_mask = ~(heap_page_size - 1);
|
||||
+ } else {
|
||||
+ heap_page_size = PAGE_SIZE;
|
||||
+ heap_page_mask = PAGE_MASK;
|
||||
+ }
|
||||
+
|
||||
vm->region.brk_start = vm->region.brk_end =
|
||||
- (vm->region.data_end + LARGE_PAGE_SIZE - 1) & LARGE_PAGE_MASK;
|
||||
+ (vm->region.data_end + heap_page_size - 1) & heap_page_mask;
|
||||
|
||||
#if 0
|
||||
{
|
||||
diff --git kernel/include/rusage_private.h kernel/include/rusage_private.h
|
||||
index 7da7728..14253b2 100644
|
||||
--- kernel/include/rusage_private.h
|
||||
+++ kernel/include/rusage_private.h
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <arch_rusage.h>
|
||||
#include <debug.h>
|
||||
|
||||
-#ifdef ENABLE_RUSAGE
|
||||
+#if 0 /* def ENABLE_RUSAGE */
|
||||
|
||||
#define RUSAGE_OOM_MARGIN (2 * 1024 * 1024) // 2MB
|
||||
|
||||
diff --git kernel/process.c kernel/process.c
|
||||
index 32a8ef6..24f262a 100644
|
||||
--- kernel/process.c
|
||||
+++ kernel/process.c
|
||||
@@ -2030,6 +2030,12 @@ retry:
|
||||
#endif /* POSTK_DEBUG_TEMP_FIX_86 */
|
||||
|
||||
dkprintf("%s: attr=%x\n", __FUNCTION__, attr);
|
||||
+
|
||||
+ if (pgsize > PAGE_SIZE) {
|
||||
+ kprintf("large page allocation, addr: %016lx, size: %d, phys: %lx\n",
|
||||
+ pgaddr, pgsize, phys);
|
||||
+ }
|
||||
+
|
||||
error = ihk_mc_pt_set_pte(vm->address_space->page_table, ptep,
|
||||
pgsize, phys, attr);
|
||||
if (error) {
|
||||
@@ -2256,15 +2262,20 @@ int init_process_stack(struct thread *thread, struct program_load_desc *pn,
|
||||
int stack_populated_size = 0;
|
||||
int stack_align_padding = 0;
|
||||
|
||||
+
|
||||
+ unsigned long stack_page_size = pn->stack_premap;
|
||||
+ unsigned long stack_page_mask = ~(stack_page_size - 1);
|
||||
+ unsigned long stack_page_shift = 63 - __builtin_clzl(stack_page_size);
|
||||
+ unsigned long stack_page_p2align = stack_page_shift - PAGE_SHIFT;
|
||||
+
|
||||
/* Create stack range */
|
||||
#ifdef POSTK_DEBUG_ARCH_DEP_104 /* user stack prepage size fix */
|
||||
- end = STACK_TOP(&thread->vm->region) & USER_STACK_PAGE_MASK;
|
||||
- minsz = (pn->stack_premap + USER_STACK_PREPAGE_SIZE - 1) &
|
||||
- USER_STACK_PAGE_MASK;
|
||||
+ end = STACK_TOP(&thread->vm->region) & stack_page_mask;
|
||||
+ minsz = stack_page_size;
|
||||
#else /* POSTK_DEBUG_ARCH_DEP_104 */
|
||||
- end = STACK_TOP(&thread->vm->region) & LARGE_PAGE_MASK;
|
||||
+ end = STACK_TOP(&thread->vm->region) & stack_page_mask;
|
||||
minsz = (pn->stack_premap
|
||||
- + LARGE_PAGE_SIZE - 1) & LARGE_PAGE_MASK;
|
||||
+ + stack_page_size - 1) & stack_page_mask;
|
||||
#endif /* POSTK_DEBUG_ARCH_DEP_104 */
|
||||
maxsz = (end - thread->vm->region.map_start) / 2;
|
||||
size = proc->rlimit[MCK_RLIMIT_STACK].rlim_cur;
|
||||
@@ -2275,9 +2286,9 @@ int init_process_stack(struct thread *thread, struct program_load_desc *pn,
|
||||
size = minsz;
|
||||
}
|
||||
#ifdef POSTK_DEBUG_ARCH_DEP_104 /* user stack prepage size fix */
|
||||
- size = (size + USER_STACK_PREPAGE_SIZE - 1) & USER_STACK_PAGE_MASK;
|
||||
+ size = (size + stack_page_size - 1) & stack_page_mask;
|
||||
#else /* POSTK_DEBUG_ARCH_DEP_104 */
|
||||
- size = (size + LARGE_PAGE_SIZE - 1) & LARGE_PAGE_MASK;
|
||||
+ size = (size + stack_page_size - 1) & stack_page_mask;
|
||||
#endif /* POSTK_DEBUG_ARCH_DEP_104 */
|
||||
dkprintf("%s: stack_premap: %lu, rlim_cur: %lu, minsz: %lu, size: %lu\n",
|
||||
__FUNCTION__,
|
||||
@@ -2285,9 +2296,9 @@ int init_process_stack(struct thread *thread, struct program_load_desc *pn,
|
||||
proc->rlimit[MCK_RLIMIT_STACK].rlim_cur,
|
||||
minsz, size);
|
||||
#ifdef POSTK_DEBUG_ARCH_DEP_104 /* user stack prepage size fix */
|
||||
- start = (end - size) & USER_STACK_PAGE_MASK;
|
||||
+ start = (end - size) & stack_page_mask;
|
||||
#else /* POSTK_DEBUG_ARCH_DEP_104 */
|
||||
- start = (end - size) & LARGE_PAGE_MASK;
|
||||
+ start = (end - size) & stack_page_mask;
|
||||
#endif /* POSTK_DEBUG_ARCH_DEP_104 */
|
||||
|
||||
/* Apply user allocation policy to stacks */
|
||||
@@ -2300,10 +2311,10 @@ int init_process_stack(struct thread *thread, struct program_load_desc *pn,
|
||||
|
||||
#ifdef POSTK_DEBUG_ARCH_DEP_104 /* user stack prepage size fix */
|
||||
stack = ihk_mc_alloc_aligned_pages_user(minsz >> PAGE_SHIFT,
|
||||
- USER_STACK_PAGE_P2ALIGN, IHK_MC_AP_NOWAIT | ap_flag, start);
|
||||
+ stack_page_p2align, IHK_MC_AP_NOWAIT | ap_flag, start);
|
||||
#else /* POSTK_DEBUG_ARCH_DEP_104 */
|
||||
stack = ihk_mc_alloc_aligned_pages_user(minsz >> PAGE_SHIFT,
|
||||
- LARGE_PAGE_P2ALIGN, IHK_MC_AP_NOWAIT | ap_flag, start);
|
||||
+ stack_page_p2align, IHK_MC_AP_NOWAIT | ap_flag, start);
|
||||
#endif /* POSTK_DEBUG_ARCH_DEP_104 */
|
||||
|
||||
if (!stack) {
|
||||
@@ -2321,13 +2332,13 @@ int init_process_stack(struct thread *thread, struct program_load_desc *pn,
|
||||
#define NOPHYS ((uintptr_t)-1)
|
||||
#ifdef POSTK_DEBUG_ARCH_DEP_104 /* user stack prepage size fix */
|
||||
if ((rc = add_process_memory_range(thread->vm, start, end, NOPHYS,
|
||||
- vrflag, NULL, 0, USER_STACK_PAGE_SHIFT, &range)) != 0) {
|
||||
+ vrflag, NULL, 0, stack_page_shift, &range)) != 0) {
|
||||
ihk_mc_free_pages_user(stack, minsz >> PAGE_SHIFT);
|
||||
return rc;
|
||||
}
|
||||
#else /* POSTK_DEBUG_ARCH_DEP_104 */
|
||||
if ((rc = add_process_memory_range(thread->vm, start, end, NOPHYS,
|
||||
- vrflag, NULL, 0, LARGE_PAGE_SHIFT, &range)) != 0) {
|
||||
+ vrflag, NULL, 0, stack_page_shift, &range)) != 0) {
|
||||
ihk_mc_free_pages_user(stack, minsz >> PAGE_SHIFT);
|
||||
kprintf("%s: error addding process memory range: %d\n", rc);
|
||||
return rc;
|
||||
@@ -2340,14 +2351,14 @@ int init_process_stack(struct thread *thread, struct program_load_desc *pn,
|
||||
thread->vm, (void *)(end - minsz),
|
||||
(void *)end, virt_to_phys(stack),
|
||||
arch_vrflag_to_ptattr(vrflag, PF_POPULATE, NULL),
|
||||
- USER_STACK_PAGE_SHIFT, range, 0
|
||||
+ stack_page_shift, range, 0
|
||||
);
|
||||
#else /* POSTK_DEBUG_ARCH_DEP_104 */
|
||||
error = ihk_mc_pt_set_range(thread->vm->address_space->page_table,
|
||||
thread->vm, (void *)(end - minsz),
|
||||
(void *)end, virt_to_phys(stack),
|
||||
arch_vrflag_to_ptattr(vrflag, PF_POPULATE, NULL),
|
||||
- LARGE_PAGE_SHIFT, range, 0
|
||||
+ stack_page_shift, range, 0
|
||||
);
|
||||
#endif /* POSTK_DEBUG_ARCH_DEP_104 */
|
||||
|
||||
@@ -2464,14 +2475,15 @@ unsigned long extend_process_region(struct process_vm *vm,
|
||||
void *p;
|
||||
int rc;
|
||||
|
||||
- size_t align_size = vm->proc->heap_extension > PAGE_SIZE ?
|
||||
- LARGE_PAGE_SIZE : PAGE_SIZE;
|
||||
- unsigned long align_mask = vm->proc->heap_extension > PAGE_SIZE ?
|
||||
- LARGE_PAGE_MASK : PAGE_MASK;
|
||||
- unsigned long align_p2align = vm->proc->heap_extension > PAGE_SIZE ?
|
||||
- LARGE_PAGE_P2ALIGN : PAGE_P2ALIGN;
|
||||
- int align_shift = vm->proc->heap_extension > PAGE_SIZE ?
|
||||
- LARGE_PAGE_SHIFT : PAGE_SHIFT;
|
||||
+ unsigned long heap_page_size = vm->proc->heap_extension;
|
||||
+ unsigned long heap_page_mask = ~(heap_page_size - 1);
|
||||
+ unsigned long heap_page_shift = 63 - __builtin_clzl(heap_page_size);
|
||||
+ unsigned long heap_page_p2align = heap_page_shift - PAGE_SHIFT;
|
||||
+
|
||||
+ size_t align_size = heap_page_size;
|
||||
+ unsigned long align_mask = heap_page_mask;
|
||||
+ unsigned long align_p2align = heap_page_p2align;
|
||||
+ int align_shift = heap_page_shift;
|
||||
|
||||
new_end_allocated = (address + (PAGE_SIZE - 1)) & PAGE_MASK;
|
||||
if ((new_end_allocated - end_allocated) < vm->proc->heap_extension) {
|
||||
diff --git kernel/syscall.c kernel/syscall.c
|
||||
index 449c931..10a9039 100644
|
||||
--- kernel/syscall.c
|
||||
+++ kernel/syscall.c
|
||||
@@ -5228,9 +5228,22 @@ int do_shmget(const key_t key, const size_t size, const int shmflg)
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
- pgshift = PAGE_SHIFT;
|
||||
if (shmflg & SHM_HUGETLB) {
|
||||
pgshift = (shmflg >> SHM_HUGE_SHIFT) & 0x3F;
|
||||
+ } else {
|
||||
+ size_t pgsize;
|
||||
+
|
||||
+ if (size > PAGE_SIZE) {
|
||||
+ error = arch_get_smaller_page_size(NULL, size + 1, &pgsize, NULL);
|
||||
+ if (error) {
|
||||
+ ekprintf("%s: arch_get_smaller_page_size failed. %d\n", error);
|
||||
+ return error;
|
||||
+ }
|
||||
+
|
||||
+ pgshift = 63 - __builtin_clzl(pgsize);;
|
||||
+ } else {
|
||||
+ pgshift = PAGE_SHIFT;
|
||||
+ }
|
||||
}
|
||||
|
||||
memset(&ads, 0, sizeof(ads));
|
||||
69
test/large_page/run.sh
Executable file
69
test/large_page/run.sh
Executable file
@ -0,0 +1,69 @@
|
||||
#!/bin/sh
|
||||
|
||||
source ${HOME}/.mck_test_config
|
||||
|
||||
if [ $# -lt 1 ]; then
|
||||
echo "Error: too few arguments."
|
||||
echo "usage: `basename $0` <test_id>"
|
||||
fi
|
||||
|
||||
test_id=$1
|
||||
|
||||
pagesize=$(getconf PAGESIZE)
|
||||
case $pagesize in
|
||||
4096) base_name="${test_id}_4K"
|
||||
;;
|
||||
65536) base_name="${test_id}_64K"
|
||||
;;
|
||||
*) echo "Error: Unknown page size"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
init="init/${base_name}.init"
|
||||
|
||||
if [ ! -e $init ]; then
|
||||
echo "$init not found"
|
||||
exit 1
|
||||
fi
|
||||
source $init
|
||||
|
||||
# kill mcexec
|
||||
pidof 'mcexec ' | xargs -r kill -9
|
||||
|
||||
# stop mckernel
|
||||
echo "sudo ${MCK_DIR}/sbin/mcstop+release.sh"
|
||||
sudo ${MCK_DIR}/sbin/mcstop+release.sh
|
||||
|
||||
# boot mckernel
|
||||
echo "sudo ${MCK_DIR}/sbin/mcreboot.sh ${BOOTPARAM}"
|
||||
sudo ${MCK_DIR}/sbin/mcreboot.sh ${BOOTPARAM}
|
||||
|
||||
if [ ! -e "/dev/mcos0" ]; then
|
||||
echo "Error: failed to mcreboot"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# run test program
|
||||
echo "${MCK_DIR}/bin/mcexec ${MCEXECOPT} ./$base_name"
|
||||
${MCK_DIR}/bin/mcexec ${MCEXECOPT} ./$base_name
|
||||
|
||||
ret=$?
|
||||
if [ $ret == 0 ]; then
|
||||
echo "${MCK_DIR}/sbin/ihkosctl 0 kmsg"
|
||||
sudo ${MCK_DIR}/sbin/ihkosctl 0 kmsg
|
||||
else
|
||||
echo "Error: mcexec returned $ret"
|
||||
fi
|
||||
|
||||
fini="fini/${base_name}.fini"
|
||||
if [ -e $fini ]; then
|
||||
source $fini
|
||||
fi
|
||||
|
||||
if [ $ret == 0 ]; then
|
||||
exit 0
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
|
||||
56
test/large_page/util.h
Normal file
56
test/large_page/util.h
Normal file
@ -0,0 +1,56 @@
|
||||
#ifndef __UTIL_H_INCLUDED__
|
||||
#define __UTIL_H_INCLUDED__
|
||||
|
||||
#define DEBUG
|
||||
|
||||
#ifdef DEBUG
|
||||
#define dprintf(...) do { \
|
||||
char msg[1024]; \
|
||||
sprintf(msg, __VA_ARGS__); \
|
||||
fprintf(stderr, "%s: %s", __func__, msg); \
|
||||
} while (0)
|
||||
#else
|
||||
#define dprintf(...) do { } while (0)
|
||||
#endif
|
||||
|
||||
#define eprintf(...) do { \
|
||||
char msg[1024]; \
|
||||
sprintf(msg, __VA_ARGS__); \
|
||||
fprintf(stderr, "%s: ERROR: %s", __func__, msg); \
|
||||
} while (0)
|
||||
|
||||
#define CHKANDJUMP(cond, err, ...) do { \
|
||||
if (cond) { \
|
||||
eprintf(__VA_ARGS__); \
|
||||
ret = err; \
|
||||
goto fn_fail; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define _OKNG(verb, jump, cond, fmt, args...) do { \
|
||||
if (cond) { \
|
||||
if (verb) \
|
||||
printf("\t[ OK ] " fmt, ##args); \
|
||||
} else { \
|
||||
printf("\t[ NG ] " fmt, ##args); \
|
||||
if (jump) \
|
||||
goto fn_fail; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define OKNG(args...) _OKNG(1, 1, ##args)
|
||||
#define NG(args...) _OKNG(0, 1, ##args)
|
||||
#define OKNGNOJUMP(args...) _OKNG(1, 0, ##args)
|
||||
|
||||
#define Q(x) #x
|
||||
#define QUOTE(x) Q(x)
|
||||
|
||||
extern char *mck_dir;
|
||||
extern char *arch;
|
||||
extern char *target;
|
||||
|
||||
int get_config(void);
|
||||
void destroy_config(void);
|
||||
|
||||
#endif
|
||||
|
||||
58
test/large_page/x86_64/001_4K.c
Normal file
58
test/large_page/x86_64/001_4K.c
Normal file
@ -0,0 +1,58 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/mman.h>
|
||||
#include "../util.h"
|
||||
|
||||
#define PAGE_SHIFT_2M 21
|
||||
#define PAGE_SIZE_2M (1UL << PAGE_SHIFT_2M)
|
||||
|
||||
#define PAGE_SHIFT_1G 30
|
||||
#define PAGE_SIZE_1G (1UL << PAGE_SHIFT_1G)
|
||||
|
||||
int trial_num;
|
||||
|
||||
int mmap_thp(size_t page_size)
|
||||
{
|
||||
char *addr_mmap;
|
||||
|
||||
addr_mmap = mmap(0, page_size,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_ANONYMOUS | MAP_PRIVATE,
|
||||
-1, 0);
|
||||
NG(addr_mmap != (void *)-1, "mmap failed\n");
|
||||
|
||||
addr_mmap[0] = 'z';
|
||||
NG(__atomic_load_n(addr_mmap, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_mmap, page_size);
|
||||
|
||||
munmap(addr_mmap, page_size);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = mmap_thp(PAGE_SIZE_2M);
|
||||
NG(ret == 0, "mmap_thp failed, size: %ld\n",
|
||||
PAGE_SIZE_2M);
|
||||
|
||||
ret = mmap_thp(PAGE_SIZE_1G);
|
||||
NG(ret == 0, "mmap_thp failed, size: %ld\n",
|
||||
PAGE_SIZE_1G);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
61
test/large_page/x86_64/101_4K.c
Normal file
61
test/large_page/x86_64/101_4K.c
Normal file
@ -0,0 +1,61 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/mman.h>
|
||||
#include "../util.h"
|
||||
|
||||
#define PAGE_SHIFT_2M 21
|
||||
#define PAGE_SIZE_2M (1UL << PAGE_SHIFT_2M)
|
||||
|
||||
#define PAGE_SHIFT_1G 30
|
||||
#define PAGE_SIZE_1G (1UL << PAGE_SHIFT_1G)
|
||||
|
||||
#define MAP_HUGE_SHIFT 26
|
||||
|
||||
int trial_num;
|
||||
|
||||
int mmap_flag(size_t page_size, unsigned long page_shift)
|
||||
{
|
||||
char *addr_mmap;
|
||||
|
||||
addr_mmap = mmap(0, page_size,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_ANONYMOUS | MAP_PRIVATE |
|
||||
MAP_HUGETLB | (page_shift << MAP_HUGE_SHIFT),
|
||||
-1, 0);
|
||||
NG(addr_mmap != (void *)-1, "mmap failed\n");
|
||||
|
||||
addr_mmap[0] = 'z';
|
||||
NG(__atomic_load_n(addr_mmap, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_mmap, page_size);
|
||||
|
||||
munmap(addr_mmap, page_size);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = mmap_flag(PAGE_SIZE_2M, PAGE_SHIFT_2M);
|
||||
NG(ret == 0, "mmap_flag failed, size: %ld\n",
|
||||
PAGE_SIZE_2M);
|
||||
|
||||
ret = mmap_flag(PAGE_SIZE_1G, PAGE_SHIFT_1G);
|
||||
NG(ret == 0, "mmap_flag failed, size: %ld\n",
|
||||
PAGE_SIZE_1G);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
67
test/large_page/x86_64/201_4K.c
Normal file
67
test/large_page/x86_64/201_4K.c
Normal file
@ -0,0 +1,67 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include "../util.h"
|
||||
|
||||
#define PAGE_SHIFT_2M 21
|
||||
#define PAGE_SIZE_2M (1UL << PAGE_SHIFT_2M)
|
||||
|
||||
#define PAGE_SHIFT_1G 30
|
||||
#define PAGE_SIZE_1G (1UL << PAGE_SHIFT_1G)
|
||||
|
||||
int trial_num;
|
||||
|
||||
int shmat_thp(char **argv, size_t page_size)
|
||||
{
|
||||
int ret;
|
||||
key_t key;
|
||||
int shmid;
|
||||
struct shmid_ds shmid_ds;
|
||||
char *addr_shmget;
|
||||
|
||||
key = ftok(argv[0], 0);
|
||||
|
||||
shmid = shmget(key, page_size, IPC_CREAT | 0660);
|
||||
NG(shmid != -1, "shmget failed\n");
|
||||
|
||||
addr_shmget = shmat(shmid, NULL, 0);
|
||||
NG(addr_shmget != (void *)-1, "shmat failed\n");
|
||||
|
||||
addr_shmget[0] = 'z';
|
||||
NG(__atomic_load_n(addr_shmget, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_shmget, page_size);
|
||||
|
||||
ret = shmctl(shmid, IPC_RMID, &shmid_ds);
|
||||
NG(ret != -1, "shmctl failed\n");
|
||||
|
||||
ret = shmdt(addr_shmget);
|
||||
NG(ret != -1, "shmdt failed\n");
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = shmat_thp(argv, PAGE_SIZE_2M);
|
||||
NG(ret == 0, "shmat_thp failed, size: %ld\n",
|
||||
PAGE_SIZE_2M);
|
||||
|
||||
ret = shmat_thp(argv, PAGE_SIZE_1G);
|
||||
NG(ret == 0, "shmat_thp failed, size: %ld\n",
|
||||
PAGE_SIZE_1G);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
70
test/large_page/x86_64/301_4K.c
Normal file
70
test/large_page/x86_64/301_4K.c
Normal file
@ -0,0 +1,70 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include "../util.h"
|
||||
|
||||
#define PAGE_SHIFT_2M 21
|
||||
#define PAGE_SIZE_2M (1UL << PAGE_SHIFT_2M)
|
||||
|
||||
#define PAGE_SHIFT_1G 30
|
||||
#define PAGE_SIZE_1G (1UL << PAGE_SHIFT_1G)
|
||||
|
||||
#define SHM_HUGE_SHIFT 26
|
||||
|
||||
int trial_num;
|
||||
|
||||
int shmat_thp(char **argv, size_t page_size, unsigned long page_shift)
|
||||
{
|
||||
int ret;
|
||||
key_t key;
|
||||
int shmid;
|
||||
struct shmid_ds shmid_ds;
|
||||
char *addr_shmget;
|
||||
|
||||
key = ftok(argv[0], 0);
|
||||
|
||||
shmid = shmget(key, page_size, IPC_CREAT | 0660 |
|
||||
SHM_HUGETLB | (page_shift << SHM_HUGE_SHIFT));
|
||||
NG(shmid != -1, "shmget failed\n");
|
||||
|
||||
addr_shmget = shmat(shmid, NULL, 0);
|
||||
NG(addr_shmget != (void *)-1, "shmat failed\n");
|
||||
|
||||
addr_shmget[0] = 'z';
|
||||
NG(__atomic_load_n(addr_shmget, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_shmget, page_size);
|
||||
|
||||
ret = shmctl(shmid, IPC_RMID, &shmid_ds);
|
||||
NG(ret != -1, "shmctl failed\n");
|
||||
|
||||
ret = shmdt(addr_shmget);
|
||||
NG(ret != -1, "shmdt failed\n");
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = shmat_thp(argv, PAGE_SIZE_2M, PAGE_SHIFT_2M);
|
||||
NG(ret == 0, "shmat_thp failed, size: %ld\n",
|
||||
PAGE_SIZE_2M);
|
||||
|
||||
ret = shmat_thp(argv, PAGE_SIZE_1G, PAGE_SHIFT_1G);
|
||||
NG(ret == 0, "shmat_thp failed, size: %ld\n",
|
||||
PAGE_SIZE_1G);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
35
test/large_page/x86_64/401_4K.c
Normal file
35
test/large_page/x86_64/401_4K.c
Normal file
@ -0,0 +1,35 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/shm.h>
|
||||
#include "../util.h"
|
||||
|
||||
#define TARGET_PAGE_SHIFT 21
|
||||
#define TARGET_PAGE_SIZE (1UL << TARGET_PAGE_SHIFT)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *addr_brk;
|
||||
int trial_num = 0;
|
||||
|
||||
/* Assuming heap size starts from zero and
|
||||
* incremented by the amount specified with mcexec -h
|
||||
*/
|
||||
addr_brk = sbrk(TARGET_PAGE_SIZE);
|
||||
NG(addr_brk != (void *)-1, "sbrk failed\n");
|
||||
|
||||
addr_brk[0] = 'z';
|
||||
NG(__atomic_load_n(addr_brk, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_brk, TARGET_PAGE_SIZE);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
35
test/large_page/x86_64/402_4K.c
Normal file
35
test/large_page/x86_64/402_4K.c
Normal file
@ -0,0 +1,35 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/shm.h>
|
||||
#include "../util.h"
|
||||
|
||||
#define TARGET_PAGE_SHIFT 30
|
||||
#define TARGET_PAGE_SIZE (1UL << TARGET_PAGE_SHIFT)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *addr_brk;
|
||||
int trial_num = 0;
|
||||
|
||||
/* Assuming heap size starts from zero and
|
||||
* incremented by the amount specified with mcexec -h
|
||||
*/
|
||||
addr_brk = sbrk(TARGET_PAGE_SIZE);
|
||||
NG(addr_brk != (void *)-1, "sbrk failed\n");
|
||||
|
||||
addr_brk[0] = 'z';
|
||||
NG(__atomic_load_n(addr_brk, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_brk, TARGET_PAGE_SIZE);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
50
test/large_page/x86_64/501_4K.c
Normal file
50
test/large_page/x86_64/501_4K.c
Normal file
@ -0,0 +1,50 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/shm.h>
|
||||
#include "../util.h"
|
||||
|
||||
#define TARGET_PAGE_SHIFT 21
|
||||
#define TARGET_PAGE_SIZE (1UL << TARGET_PAGE_SHIFT)
|
||||
|
||||
/* .data */
|
||||
char addr_data[TARGET_PAGE_SIZE] = { 1 };
|
||||
|
||||
/* .bss */
|
||||
char addr_bss[TARGET_PAGE_SIZE];
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int trial_num = 0;
|
||||
char addr_stack[TARGET_PAGE_SIZE]
|
||||
__attribute__((aligned(TARGET_PAGE_SIZE)));
|
||||
|
||||
/* .data */
|
||||
addr_data[0] = 'z';
|
||||
NG(__atomic_load_n(addr_data, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_data, TARGET_PAGE_SIZE);
|
||||
|
||||
/* .bss */
|
||||
addr_bss[0] = 'z';
|
||||
NG(__atomic_load_n(addr_bss, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_bss, TARGET_PAGE_SIZE);
|
||||
|
||||
/* stack */
|
||||
addr_stack[0] = 'z';
|
||||
NG(__atomic_load_n(addr_stack, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_stack, TARGET_PAGE_SIZE);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
255
test/large_page/x86_64/501_4K.lds
Normal file
255
test/large_page/x86_64/501_4K.lds
Normal file
@ -0,0 +1,255 @@
|
||||
/* Script for -z combreloc: combine and sort reloc sections */
|
||||
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64",
|
||||
"elf64-x86-64")
|
||||
OUTPUT_ARCH(i386:x86-64)
|
||||
ENTRY(_start)
|
||||
SEARCH_DIR("/usr/x86_64-redhat-linux/lib64"); SEARCH_DIR("/usr/local/lib64"); SEARCH_DIR("/lib64"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/x86_64-redhat-linux/lib"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib");
|
||||
SECTIONS
|
||||
{
|
||||
/* Read-only sections, merged into text segment: */
|
||||
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS;
|
||||
.interp : { *(.interp) }
|
||||
.note.gnu.build-id : { *(.note.gnu.build-id) }
|
||||
.hash : { *(.hash) }
|
||||
.gnu.hash : { *(.gnu.hash) }
|
||||
.dynsym : { *(.dynsym) }
|
||||
.dynstr : { *(.dynstr) }
|
||||
.gnu.version : { *(.gnu.version) }
|
||||
.gnu.version_d : { *(.gnu.version_d) }
|
||||
.gnu.version_r : { *(.gnu.version_r) }
|
||||
.rela.dyn :
|
||||
{
|
||||
*(.rela.init)
|
||||
*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
|
||||
*(.rela.fini)
|
||||
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
|
||||
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
|
||||
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
|
||||
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
|
||||
*(.rela.ctors)
|
||||
*(.rela.dtors)
|
||||
*(.rela.got)
|
||||
*(.rela.sharable_data .rela.sharable_data.* .rela.gnu.linkonce.shrd.*)
|
||||
*(.rela.sharable_bss .rela.sharable_bss.* .rela.gnu.linkonce.shrb.*)
|
||||
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
|
||||
*(.rela.ldata .rela.ldata.* .rela.gnu.linkonce.l.*)
|
||||
*(.rela.lbss .rela.lbss.* .rela.gnu.linkonce.lb.*)
|
||||
*(.rela.lrodata .rela.lrodata.* .rela.gnu.linkonce.lr.*)
|
||||
*(.rela.ifunc)
|
||||
}
|
||||
.rela.plt :
|
||||
{
|
||||
*(.rela.plt)
|
||||
PROVIDE_HIDDEN (__rela_iplt_start = .);
|
||||
*(.rela.iplt)
|
||||
PROVIDE_HIDDEN (__rela_iplt_end = .);
|
||||
}
|
||||
.init :
|
||||
{
|
||||
KEEP (*(SORT_NONE(.init)))
|
||||
}
|
||||
.plt : { *(.plt) *(.iplt) }
|
||||
.text :
|
||||
{
|
||||
*(.text.unlikely .text.*_unlikely)
|
||||
*(.text.exit .text.exit.*)
|
||||
*(.text.startup .text.startup.*)
|
||||
*(.text.hot .text.hot.*)
|
||||
*(.text .stub .text.* .gnu.linkonce.t.*)
|
||||
/* .gnu.warning sections are handled specially by elf32.em. */
|
||||
*(.gnu.warning)
|
||||
}
|
||||
.fini :
|
||||
{
|
||||
KEEP (*(SORT_NONE(.fini)))
|
||||
}
|
||||
PROVIDE (__etext = .);
|
||||
PROVIDE (_etext = .);
|
||||
PROVIDE (etext = .);
|
||||
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
|
||||
.rodata1 : { *(.rodata1) }
|
||||
.eh_frame_hdr : { *(.eh_frame_hdr) }
|
||||
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
|
||||
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table
|
||||
.gcc_except_table.*) }
|
||||
/* These sections are generated by the Sun/Oracle C++ compiler. */
|
||||
.exception_ranges : ONLY_IF_RO { *(.exception_ranges
|
||||
.exception_ranges*) }
|
||||
/* Adjust the address for the data segment. We want to adjust up to
|
||||
the same address within the page on the next page up. */
|
||||
. = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
|
||||
/* Exception handling */
|
||||
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
|
||||
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
|
||||
.exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) }
|
||||
/* Thread Local Storage sections */
|
||||
.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
|
||||
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
|
||||
.preinit_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
}
|
||||
. = ALIGN(0x200000);
|
||||
.init_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
|
||||
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
}
|
||||
.fini_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
|
||||
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
}
|
||||
.ctors :
|
||||
{
|
||||
/* gcc uses crtbegin.o to find the start of
|
||||
the constructors, so we make sure it is
|
||||
first. Because this is a wildcard, it
|
||||
doesn't matter if the user does not
|
||||
actually link against crtbegin.o; the
|
||||
linker won't look for a file to match a
|
||||
wildcard. The wildcard also means that it
|
||||
doesn't matter which directory crtbegin.o
|
||||
is in. */
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*crtbegin?.o(.ctors))
|
||||
/* We don't want to include the .ctor section from
|
||||
the crtend.o file until after the sorted ctors.
|
||||
The .ctor section from the crtend file contains the
|
||||
end of ctors marker and it must be last */
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
}
|
||||
.dtors :
|
||||
{
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*crtbegin?.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
}
|
||||
.jcr : { KEEP (*(.jcr)) }
|
||||
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }
|
||||
.dynamic : { *(.dynamic) }
|
||||
.got : { *(.got) *(.igot) }
|
||||
. = DATA_SEGMENT_RELRO_END (SIZEOF (.got.plt) >= 24 ? 24 : 0, .);
|
||||
.got.plt : { *(.got.plt) *(.igot.plt) }
|
||||
. = ALIGN(0x200000);
|
||||
.data :
|
||||
{
|
||||
addr_data = .;
|
||||
*(.data .data.* .gnu.linkonce.d.*)
|
||||
SORT(CONSTRUCTORS)
|
||||
. = ALIGN(0x200000);
|
||||
}
|
||||
.data1 : { *(.data1) }
|
||||
/* Sharable data sections. */
|
||||
.sharable_data : ALIGN(CONSTANT (MAXPAGESIZE))
|
||||
{
|
||||
PROVIDE_HIDDEN (__sharable_data_start = .);
|
||||
*(.sharable_data .sharable_data.* .gnu.linkonce.shrd.*)
|
||||
/* Align here to ensure that the sharable data section ends at the
|
||||
page boundary. */
|
||||
. = ALIGN(. != 0 ? CONSTANT (MAXPAGESIZE) : 1);
|
||||
PROVIDE_HIDDEN (__sharable_data_end = .);
|
||||
}
|
||||
_edata = .; PROVIDE (edata = .);
|
||||
. = .;
|
||||
. = ALIGN(0x200000);
|
||||
__bss_start = .;
|
||||
.bss :
|
||||
{
|
||||
addr_bss = .;
|
||||
*(.dynbss)
|
||||
*(.bss .bss.* .gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
/* Align here to ensure that the .bss section occupies space up to
|
||||
_end. Align after .bss to ensure correct alignment even if the
|
||||
.bss section disappears because there are no input sections.
|
||||
FIXME: Why do we need it? When there is no .bss section, we don't
|
||||
pad the .data section. */
|
||||
. = ALIGN(. != 0 ? 64 / 8 : 1);
|
||||
. = ALIGN(0x200000);
|
||||
}
|
||||
/* Sharable bss sections */
|
||||
.sharable_bss : ALIGN(CONSTANT (MAXPAGESIZE))
|
||||
{
|
||||
PROVIDE_HIDDEN (__sharable_bss_start = .);
|
||||
*(.dynsharablebss)
|
||||
*(.sharable_bss .sharable_bss.* .gnu.linkonce.shrb.*)
|
||||
*(SHARABLE_COMMON)
|
||||
/* Align here to ensure that the sharable bss section ends at the
|
||||
page boundary. */
|
||||
. = ALIGN(. != 0 ? CONSTANT (MAXPAGESIZE) : 1);
|
||||
PROVIDE_HIDDEN (__sharable_bss_end = .);
|
||||
}
|
||||
.lbss :
|
||||
{
|
||||
*(.dynlbss)
|
||||
*(.lbss .lbss.* .gnu.linkonce.lb.*)
|
||||
*(LARGE_COMMON)
|
||||
}
|
||||
. = ALIGN(64 / 8);
|
||||
. = SEGMENT_START("ldata-segment", .);
|
||||
.lrodata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
|
||||
{
|
||||
*(.lrodata .lrodata.* .gnu.linkonce.lr.*)
|
||||
}
|
||||
.ldata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
|
||||
{
|
||||
*(.ldata .ldata.* .gnu.linkonce.l.*)
|
||||
. = ALIGN(. != 0 ? 64 / 8 : 1);
|
||||
}
|
||||
. = ALIGN(64 / 8);
|
||||
_end = .; PROVIDE (end = .);
|
||||
. = DATA_SEGMENT_END (.);
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
/* DWARF 3 */
|
||||
.debug_pubtypes 0 : { *(.debug_pubtypes) }
|
||||
.debug_ranges 0 : { *(.debug_ranges) }
|
||||
/* DWARF Extension. */
|
||||
.debug_macro 0 : { *(.debug_macro) }
|
||||
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
|
||||
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) *(.gnu_object_only) }
|
||||
}
|
||||
|
||||
|
||||
292
test/large_page/x86_64/501_4K.org.lds
Normal file
292
test/large_page/x86_64/501_4K.org.lds
Normal file
@ -0,0 +1,292 @@
|
||||
GNU ld version 2.23.52.0.1-55.el7 20130226
|
||||
Supported emulations:
|
||||
elf_x86_64
|
||||
elf32_x86_64
|
||||
elf_i386
|
||||
i386linux
|
||||
elf_l1om
|
||||
elf_k1om
|
||||
using internal linker script:
|
||||
==================================================
|
||||
/* Script for -z combreloc: combine and sort reloc sections */
|
||||
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64",
|
||||
"elf64-x86-64")
|
||||
OUTPUT_ARCH(i386:x86-64)
|
||||
ENTRY(_start)
|
||||
SEARCH_DIR("/usr/x86_64-redhat-linux/lib64"); SEARCH_DIR("/usr/local/lib64"); SEARCH_DIR("/lib64"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/x86_64-redhat-linux/lib"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib");
|
||||
SECTIONS
|
||||
{
|
||||
/* Read-only sections, merged into text segment: */
|
||||
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS;
|
||||
.interp : { *(.interp) }
|
||||
.note.gnu.build-id : { *(.note.gnu.build-id) }
|
||||
.hash : { *(.hash) }
|
||||
.gnu.hash : { *(.gnu.hash) }
|
||||
.dynsym : { *(.dynsym) }
|
||||
.dynstr : { *(.dynstr) }
|
||||
.gnu.version : { *(.gnu.version) }
|
||||
.gnu.version_d : { *(.gnu.version_d) }
|
||||
.gnu.version_r : { *(.gnu.version_r) }
|
||||
.rela.dyn :
|
||||
{
|
||||
*(.rela.init)
|
||||
*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
|
||||
*(.rela.fini)
|
||||
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
|
||||
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
|
||||
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
|
||||
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
|
||||
*(.rela.ctors)
|
||||
*(.rela.dtors)
|
||||
*(.rela.got)
|
||||
*(.rela.sharable_data .rela.sharable_data.* .rela.gnu.linkonce.shrd.*)
|
||||
*(.rela.sharable_bss .rela.sharable_bss.* .rela.gnu.linkonce.shrb.*)
|
||||
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
|
||||
*(.rela.ldata .rela.ldata.* .rela.gnu.linkonce.l.*)
|
||||
*(.rela.lbss .rela.lbss.* .rela.gnu.linkonce.lb.*)
|
||||
*(.rela.lrodata .rela.lrodata.* .rela.gnu.linkonce.lr.*)
|
||||
*(.rela.ifunc)
|
||||
}
|
||||
.rela.plt :
|
||||
{
|
||||
*(.rela.plt)
|
||||
PROVIDE_HIDDEN (__rela_iplt_start = .);
|
||||
*(.rela.iplt)
|
||||
PROVIDE_HIDDEN (__rela_iplt_end = .);
|
||||
}
|
||||
.init :
|
||||
{
|
||||
KEEP (*(SORT_NONE(.init)))
|
||||
}
|
||||
.plt : { *(.plt) *(.iplt) }
|
||||
.text :
|
||||
{
|
||||
*(.text.unlikely .text.*_unlikely)
|
||||
*(.text.exit .text.exit.*)
|
||||
*(.text.startup .text.startup.*)
|
||||
*(.text.hot .text.hot.*)
|
||||
*(.text .stub .text.* .gnu.linkonce.t.*)
|
||||
/* .gnu.warning sections are handled specially by elf32.em. */
|
||||
*(.gnu.warning)
|
||||
}
|
||||
.fini :
|
||||
{
|
||||
KEEP (*(SORT_NONE(.fini)))
|
||||
}
|
||||
PROVIDE (__etext = .);
|
||||
PROVIDE (_etext = .);
|
||||
PROVIDE (etext = .);
|
||||
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
|
||||
.rodata1 : { *(.rodata1) }
|
||||
.eh_frame_hdr : { *(.eh_frame_hdr) }
|
||||
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
|
||||
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table
|
||||
.gcc_except_table.*) }
|
||||
/* These sections are generated by the Sun/Oracle C++ compiler. */
|
||||
.exception_ranges : ONLY_IF_RO { *(.exception_ranges
|
||||
.exception_ranges*) }
|
||||
/* Adjust the address for the data segment. We want to adjust up to
|
||||
the same address within the page on the next page up. */
|
||||
. = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
|
||||
/* Exception handling */
|
||||
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
|
||||
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
|
||||
.exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) }
|
||||
/* Thread Local Storage sections */
|
||||
.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
|
||||
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
|
||||
.preinit_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
}
|
||||
.init_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
|
||||
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
}
|
||||
.fini_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
|
||||
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
}
|
||||
.ctors :
|
||||
{
|
||||
/* gcc uses crtbegin.o to find the start of
|
||||
the constructors, so we make sure it is
|
||||
first. Because this is a wildcard, it
|
||||
doesn't matter if the user does not
|
||||
actually link against crtbegin.o; the
|
||||
linker won't look for a file to match a
|
||||
wildcard. The wildcard also means that it
|
||||
doesn't matter which directory crtbegin.o
|
||||
is in. */
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*crtbegin?.o(.ctors))
|
||||
/* We don't want to include the .ctor section from
|
||||
the crtend.o file until after the sorted ctors.
|
||||
The .ctor section from the crtend file contains the
|
||||
end of ctors marker and it must be last */
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
}
|
||||
.dtors :
|
||||
{
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*crtbegin?.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
}
|
||||
.jcr : { KEEP (*(.jcr)) }
|
||||
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }
|
||||
.dynamic : { *(.dynamic) }
|
||||
.got : { *(.got) *(.igot) }
|
||||
. = DATA_SEGMENT_RELRO_END (SIZEOF (.got.plt) >= 24 ? 24 : 0, .);
|
||||
.got.plt : { *(.got.plt) *(.igot.plt) }
|
||||
.data :
|
||||
{
|
||||
*(.data .data.* .gnu.linkonce.d.*)
|
||||
SORT(CONSTRUCTORS)
|
||||
}
|
||||
.data1 : { *(.data1) }
|
||||
/* Sharable data sections. */
|
||||
.sharable_data : ALIGN(CONSTANT (MAXPAGESIZE))
|
||||
{
|
||||
PROVIDE_HIDDEN (__sharable_data_start = .);
|
||||
*(.sharable_data .sharable_data.* .gnu.linkonce.shrd.*)
|
||||
/* Align here to ensure that the sharable data section ends at the
|
||||
page boundary. */
|
||||
. = ALIGN(. != 0 ? CONSTANT (MAXPAGESIZE) : 1);
|
||||
PROVIDE_HIDDEN (__sharable_data_end = .);
|
||||
}
|
||||
_edata = .; PROVIDE (edata = .);
|
||||
. = .;
|
||||
__bss_start = .;
|
||||
.bss :
|
||||
{
|
||||
*(.dynbss)
|
||||
*(.bss .bss.* .gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
/* Align here to ensure that the .bss section occupies space up to
|
||||
_end. Align after .bss to ensure correct alignment even if the
|
||||
.bss section disappears because there are no input sections.
|
||||
FIXME: Why do we need it? When there is no .bss section, we don't
|
||||
pad the .data section. */
|
||||
. = ALIGN(. != 0 ? 64 / 8 : 1);
|
||||
}
|
||||
/* Sharable bss sections */
|
||||
.sharable_bss : ALIGN(CONSTANT (MAXPAGESIZE))
|
||||
{
|
||||
PROVIDE_HIDDEN (__sharable_bss_start = .);
|
||||
*(.dynsharablebss)
|
||||
*(.sharable_bss .sharable_bss.* .gnu.linkonce.shrb.*)
|
||||
*(SHARABLE_COMMON)
|
||||
/* Align here to ensure that the sharable bss section ends at the
|
||||
page boundary. */
|
||||
. = ALIGN(. != 0 ? CONSTANT (MAXPAGESIZE) : 1);
|
||||
PROVIDE_HIDDEN (__sharable_bss_end = .);
|
||||
}
|
||||
.lbss :
|
||||
{
|
||||
*(.dynlbss)
|
||||
*(.lbss .lbss.* .gnu.linkonce.lb.*)
|
||||
*(LARGE_COMMON)
|
||||
}
|
||||
. = ALIGN(64 / 8);
|
||||
. = SEGMENT_START("ldata-segment", .);
|
||||
.lrodata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
|
||||
{
|
||||
*(.lrodata .lrodata.* .gnu.linkonce.lr.*)
|
||||
}
|
||||
.ldata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
|
||||
{
|
||||
*(.ldata .ldata.* .gnu.linkonce.l.*)
|
||||
. = ALIGN(. != 0 ? 64 / 8 : 1);
|
||||
}
|
||||
. = ALIGN(64 / 8);
|
||||
_end = .; PROVIDE (end = .);
|
||||
. = DATA_SEGMENT_END (.);
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
/* DWARF 3 */
|
||||
.debug_pubtypes 0 : { *(.debug_pubtypes) }
|
||||
.debug_ranges 0 : { *(.debug_ranges) }
|
||||
/* DWARF Extension. */
|
||||
.debug_macro 0 : { *(.debug_macro) }
|
||||
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
|
||||
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) *(.gnu_object_only) }
|
||||
}
|
||||
|
||||
|
||||
==================================================
|
||||
attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crt1.o succeeded
|
||||
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crt1.o
|
||||
attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crti.o succeeded
|
||||
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crti.o
|
||||
attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtbegin.o succeeded
|
||||
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtbegin.o
|
||||
attempt to open 501_4K.o succeeded
|
||||
501_4K.o
|
||||
attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/libgcc.so failed
|
||||
attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/libgcc.a succeeded
|
||||
attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/libgcc_s.so succeeded
|
||||
-lgcc_s (/usr/lib/gcc/x86_64-redhat-linux/4.8.5/libgcc_s.so)
|
||||
attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/libc.so failed
|
||||
attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/libc.a failed
|
||||
attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/libc.so succeeded
|
||||
opened script file /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/libc.so
|
||||
opened script file /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/libc.so
|
||||
attempt to open /lib64/libc.so.6 succeeded
|
||||
/lib64/libc.so.6
|
||||
attempt to open /usr/lib64/libc_nonshared.a succeeded
|
||||
(/usr/lib64/libc_nonshared.a)elf-init.oS
|
||||
attempt to open /lib64/ld-linux-x86-64.so.2 succeeded
|
||||
/lib64/ld-linux-x86-64.so.2
|
||||
attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/libgcc.so failed
|
||||
attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/libgcc.a succeeded
|
||||
attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/libgcc_s.so succeeded
|
||||
-lgcc_s (/usr/lib/gcc/x86_64-redhat-linux/4.8.5/libgcc_s.so)
|
||||
attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtend.o succeeded
|
||||
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtend.o
|
||||
attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crtn.o succeeded
|
||||
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crtn.o
|
||||
ld-linux-x86-64.so.2 needed by /lib64/libc.so.6
|
||||
found ld-linux-x86-64.so.2 at /lib64/ld-linux-x86-64.so.2
|
||||
49
test/large_page/x86_64/502_4K.c
Normal file
49
test/large_page/x86_64/502_4K.c
Normal file
@ -0,0 +1,49 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/shm.h>
|
||||
#include "../util.h"
|
||||
|
||||
#define TARGET_PAGE_SHIFT 30
|
||||
#define TARGET_PAGE_SIZE (1UL << TARGET_PAGE_SHIFT)
|
||||
|
||||
/* .data */
|
||||
char addr_data[TARGET_PAGE_SIZE] = { 1 };
|
||||
|
||||
/* .bss */
|
||||
char addr_bss[TARGET_PAGE_SIZE];
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int trial_num = 0;
|
||||
char addr_stack[TARGET_PAGE_SIZE];
|
||||
|
||||
/* .data */
|
||||
addr_data[0] = 'z';
|
||||
NG(__atomic_load_n(addr_data, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_data, TARGET_PAGE_SIZE);
|
||||
|
||||
/* .bss */
|
||||
addr_bss[0] = 'z';
|
||||
NG(__atomic_load_n(addr_bss, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_bss, TARGET_PAGE_SIZE);
|
||||
|
||||
/* stack */
|
||||
addr_stack[0] = 'z';
|
||||
NG(__atomic_load_n(addr_stack, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_stack, TARGET_PAGE_SIZE);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
252
test/large_page/x86_64/502_4K.lds
Normal file
252
test/large_page/x86_64/502_4K.lds
Normal file
@ -0,0 +1,252 @@
|
||||
/* Script for -z combreloc: combine and sort reloc sections */
|
||||
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64",
|
||||
"elf64-x86-64")
|
||||
OUTPUT_ARCH(i386:x86-64)
|
||||
ENTRY(_start)
|
||||
SEARCH_DIR("/usr/x86_64-redhat-linux/lib64"); SEARCH_DIR("/usr/local/lib64"); SEARCH_DIR("/lib64"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/x86_64-redhat-linux/lib"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib");
|
||||
SECTIONS
|
||||
{
|
||||
/* Read-only sections, merged into text segment: */
|
||||
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS;
|
||||
.interp : { *(.interp) }
|
||||
.note.gnu.build-id : { *(.note.gnu.build-id) }
|
||||
.hash : { *(.hash) }
|
||||
.gnu.hash : { *(.gnu.hash) }
|
||||
.dynsym : { *(.dynsym) }
|
||||
.dynstr : { *(.dynstr) }
|
||||
.gnu.version : { *(.gnu.version) }
|
||||
.gnu.version_d : { *(.gnu.version_d) }
|
||||
.gnu.version_r : { *(.gnu.version_r) }
|
||||
.rela.dyn :
|
||||
{
|
||||
*(.rela.init)
|
||||
*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
|
||||
*(.rela.fini)
|
||||
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
|
||||
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
|
||||
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
|
||||
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
|
||||
*(.rela.ctors)
|
||||
*(.rela.dtors)
|
||||
*(.rela.got)
|
||||
*(.rela.sharable_data .rela.sharable_data.* .rela.gnu.linkonce.shrd.*)
|
||||
*(.rela.sharable_bss .rela.sharable_bss.* .rela.gnu.linkonce.shrb.*)
|
||||
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
|
||||
*(.rela.ldata .rela.ldata.* .rela.gnu.linkonce.l.*)
|
||||
*(.rela.lbss .rela.lbss.* .rela.gnu.linkonce.lb.*)
|
||||
*(.rela.lrodata .rela.lrodata.* .rela.gnu.linkonce.lr.*)
|
||||
*(.rela.ifunc)
|
||||
}
|
||||
.rela.plt :
|
||||
{
|
||||
*(.rela.plt)
|
||||
PROVIDE_HIDDEN (__rela_iplt_start = .);
|
||||
*(.rela.iplt)
|
||||
PROVIDE_HIDDEN (__rela_iplt_end = .);
|
||||
}
|
||||
.init :
|
||||
{
|
||||
KEEP (*(SORT_NONE(.init)))
|
||||
}
|
||||
.plt : { *(.plt) *(.iplt) }
|
||||
.text :
|
||||
{
|
||||
*(.text.unlikely .text.*_unlikely)
|
||||
*(.text.exit .text.exit.*)
|
||||
*(.text.startup .text.startup.*)
|
||||
*(.text.hot .text.hot.*)
|
||||
*(.text .stub .text.* .gnu.linkonce.t.*)
|
||||
/* .gnu.warning sections are handled specially by elf32.em. */
|
||||
*(.gnu.warning)
|
||||
}
|
||||
.fini :
|
||||
{
|
||||
KEEP (*(SORT_NONE(.fini)))
|
||||
}
|
||||
PROVIDE (__etext = .);
|
||||
PROVIDE (_etext = .);
|
||||
PROVIDE (etext = .);
|
||||
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
|
||||
.rodata1 : { *(.rodata1) }
|
||||
.eh_frame_hdr : { *(.eh_frame_hdr) }
|
||||
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
|
||||
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table
|
||||
.gcc_except_table.*) }
|
||||
/* These sections are generated by the Sun/Oracle C++ compiler. */
|
||||
.exception_ranges : ONLY_IF_RO { *(.exception_ranges
|
||||
.exception_ranges*) }
|
||||
/* Adjust the address for the data segment. We want to adjust up to
|
||||
the same address within the page on the next page up. */
|
||||
. = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
|
||||
/* Exception handling */
|
||||
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
|
||||
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
|
||||
.exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) }
|
||||
/* Thread Local Storage sections */
|
||||
.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
|
||||
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
|
||||
.preinit_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
}
|
||||
.init_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
|
||||
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
}
|
||||
.fini_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
|
||||
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
}
|
||||
.ctors :
|
||||
{
|
||||
/* gcc uses crtbegin.o to find the start of
|
||||
the constructors, so we make sure it is
|
||||
first. Because this is a wildcard, it
|
||||
doesn't matter if the user does not
|
||||
actually link against crtbegin.o; the
|
||||
linker won't look for a file to match a
|
||||
wildcard. The wildcard also means that it
|
||||
doesn't matter which directory crtbegin.o
|
||||
is in. */
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*crtbegin?.o(.ctors))
|
||||
/* We don't want to include the .ctor section from
|
||||
the crtend.o file until after the sorted ctors.
|
||||
The .ctor section from the crtend file contains the
|
||||
end of ctors marker and it must be last */
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
}
|
||||
.dtors :
|
||||
{
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*crtbegin?.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
}
|
||||
.jcr : { KEEP (*(.jcr)) }
|
||||
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }
|
||||
.dynamic : { *(.dynamic) }
|
||||
.got : { *(.got) *(.igot) }
|
||||
. = DATA_SEGMENT_RELRO_END (SIZEOF (.got.plt) >= 24 ? 24 : 0, .);
|
||||
.got.plt : { *(.got.plt) *(.igot.plt) }
|
||||
. = ALIGN(0x40000000);
|
||||
.data :
|
||||
{
|
||||
addr_data = .;
|
||||
*(.data .data.* .gnu.linkonce.d.*)
|
||||
SORT(CONSTRUCTORS)
|
||||
}
|
||||
.data1 : { *(.data1) }
|
||||
/* Sharable data sections. */
|
||||
.sharable_data : ALIGN(CONSTANT (MAXPAGESIZE))
|
||||
{
|
||||
PROVIDE_HIDDEN (__sharable_data_start = .);
|
||||
*(.sharable_data .sharable_data.* .gnu.linkonce.shrd.*)
|
||||
/* Align here to ensure that the sharable data section ends at the
|
||||
page boundary. */
|
||||
. = ALIGN(. != 0 ? CONSTANT (MAXPAGESIZE) : 1);
|
||||
PROVIDE_HIDDEN (__sharable_data_end = .);
|
||||
}
|
||||
_edata = .; PROVIDE (edata = .);
|
||||
. = .;
|
||||
. = ALIGN(0x40000000);
|
||||
__bss_start = .;
|
||||
.bss :
|
||||
{
|
||||
addr_bss = .;
|
||||
*(.dynbss)
|
||||
*(.bss .bss.* .gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
/* Align here to ensure that the .bss section occupies space up to
|
||||
_end. Align after .bss to ensure correct alignment even if the
|
||||
.bss section disappears because there are no input sections.
|
||||
FIXME: Why do we need it? When there is no .bss section, we don't
|
||||
pad the .data section. */
|
||||
. = ALIGN(. != 0 ? 64 / 8 : 1);
|
||||
}
|
||||
/* Sharable bss sections */
|
||||
.sharable_bss : ALIGN(CONSTANT (MAXPAGESIZE))
|
||||
{
|
||||
PROVIDE_HIDDEN (__sharable_bss_start = .);
|
||||
*(.dynsharablebss)
|
||||
*(.sharable_bss .sharable_bss.* .gnu.linkonce.shrb.*)
|
||||
*(SHARABLE_COMMON)
|
||||
/* Align here to ensure that the sharable bss section ends at the
|
||||
page boundary. */
|
||||
. = ALIGN(. != 0 ? CONSTANT (MAXPAGESIZE) : 1);
|
||||
PROVIDE_HIDDEN (__sharable_bss_end = .);
|
||||
}
|
||||
.lbss :
|
||||
{
|
||||
*(.dynlbss)
|
||||
*(.lbss .lbss.* .gnu.linkonce.lb.*)
|
||||
*(LARGE_COMMON)
|
||||
}
|
||||
. = ALIGN(64 / 8);
|
||||
. = SEGMENT_START("ldata-segment", .);
|
||||
.lrodata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
|
||||
{
|
||||
*(.lrodata .lrodata.* .gnu.linkonce.lr.*)
|
||||
}
|
||||
.ldata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
|
||||
{
|
||||
*(.ldata .ldata.* .gnu.linkonce.l.*)
|
||||
. = ALIGN(. != 0 ? 64 / 8 : 1);
|
||||
}
|
||||
. = ALIGN(64 / 8);
|
||||
_end = .; PROVIDE (end = .);
|
||||
. = DATA_SEGMENT_END (.);
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
/* DWARF 3 */
|
||||
.debug_pubtypes 0 : { *(.debug_pubtypes) }
|
||||
.debug_ranges 0 : { *(.debug_ranges) }
|
||||
/* DWARF Extension. */
|
||||
.debug_macro 0 : { *(.debug_macro) }
|
||||
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
|
||||
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) *(.gnu_object_only) }
|
||||
}
|
||||
|
||||
|
||||
63
test/large_page/x86_64/601_4K.c
Normal file
63
test/large_page/x86_64/601_4K.c
Normal file
@ -0,0 +1,63 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/mman.h>
|
||||
#include "../util.h"
|
||||
|
||||
#define PAGE_SHIFT_2M 21
|
||||
#define PAGE_SIZE_2M (1UL << PAGE_SHIFT_2M)
|
||||
char fn_2M[] = "/mnt/hugetlbfs-2M/tmp";
|
||||
|
||||
#define PAGE_SHIFT_1G 30
|
||||
#define PAGE_SIZE_1G (1UL << PAGE_SHIFT_1G)
|
||||
char fn_1G[] = "/mnt/hugetlbfs-1G/tmp";
|
||||
|
||||
int trial_num;
|
||||
|
||||
int mmap_hugetlbfs(char *fn, size_t page_size)
|
||||
{
|
||||
int fd;
|
||||
char *addr_mmap;
|
||||
|
||||
fd = open(fn, O_CREAT | O_RDWR, 0755);
|
||||
NG(fd != -1, "open failed, fn: %s\n", fn);
|
||||
|
||||
addr_mmap = mmap(0, page_size,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED,
|
||||
fd, 0);
|
||||
NG(addr_mmap != (void *)-1, "mmap failed\n");
|
||||
addr_mmap[0] = 'z';
|
||||
NG(__atomic_load_n(addr_mmap, __ATOMIC_SEQ_CST) == 'z',
|
||||
"memory access failed\n");
|
||||
|
||||
printf("large page request, trial#: %03d, addr: %016lx, size: %ld\n",
|
||||
trial_num++, (unsigned long)addr_mmap, page_size);
|
||||
|
||||
munmap(addr_mmap, page_size);
|
||||
close(fd);
|
||||
unlink(fn);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = mmap_hugetlbfs(fn_2M, PAGE_SIZE_2M);
|
||||
NG(ret == 0, "mmap_hugetlbfs failed, fn: %s", fn_2M);
|
||||
|
||||
ret = mmap_hugetlbfs(fn_1G, PAGE_SIZE_1G);
|
||||
NG(ret == 0, "mmap_hugetlbfs failed, fn: %s", fn_1G);
|
||||
|
||||
return 0;
|
||||
fn_fail:
|
||||
return 1;
|
||||
}
|
||||
30
test/large_page/x86_64/Makefile
Normal file
30
test/large_page/x86_64/Makefile
Normal file
@ -0,0 +1,30 @@
|
||||
include $(HOME)/.mck_test_config.mk
|
||||
|
||||
CC = gcc
|
||||
|
||||
CPPFLAGS =
|
||||
CFLAGS = -Wall -Werror -g
|
||||
LDFLAGS =
|
||||
|
||||
PAGESIZE = $(shell getconf PAGESIZE)
|
||||
ifeq ($(PAGESIZE),4096)
|
||||
SRCS = $(shell ls *_4K.c | grep -v 502)
|
||||
endif
|
||||
|
||||
EXES = $(SRCS:.c=)
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
|
||||
all: $(EXES)
|
||||
|
||||
test:: $(EXES)
|
||||
../driver.sh $(TESTSET)
|
||||
|
||||
501_4K: 501_4K.o 501_4K.lds
|
||||
$(CC) -o $@ $< $(LDFLAGS) -T 501_4K.lds
|
||||
|
||||
502_4K: 502_4K.o 502_4K.lds
|
||||
$(CC) -o $@ $< $(LDFLAGS) -T 502_4K.lds
|
||||
|
||||
clean:
|
||||
rm -f core $(EXES) $(OBJS)
|
||||
|
||||
2
test/large_page/x86_64/fini/601_4K.fini
Normal file
2
test/large_page/x86_64/fini/601_4K.fini
Normal file
@ -0,0 +1,2 @@
|
||||
sudo umount /mnt/hugetlbfs-2M
|
||||
sudo umount /mnt/hugetlbfs-1G
|
||||
1
test/large_page/x86_64/init/001_4K.init
Normal file
1
test/large_page/x86_64/init/001_4K.init
Normal file
@ -0,0 +1 @@
|
||||
BOOTPARAM="-c 1-7,9-15,17-23,25-31 -m 28G@0,28G@1 -r 1-7:0+9-15:8+17-23:16+25-31:24"
|
||||
1
test/large_page/x86_64/init/101_4K.init
Normal file
1
test/large_page/x86_64/init/101_4K.init
Normal file
@ -0,0 +1 @@
|
||||
BOOTPARAM="-c 1-7,9-15,17-23,25-31 -m 28G@0,28G@1 -r 1-7:0+9-15:8+17-23:16+25-31:24"
|
||||
1
test/large_page/x86_64/init/201_4K.init
Normal file
1
test/large_page/x86_64/init/201_4K.init
Normal file
@ -0,0 +1 @@
|
||||
BOOTPARAM="-c 1-7,9-15,17-23,25-31 -m 28G@0,28G@1 -r 1-7:0+9-15:8+17-23:16+25-31:24"
|
||||
1
test/large_page/x86_64/init/301_4K.init
Normal file
1
test/large_page/x86_64/init/301_4K.init
Normal file
@ -0,0 +1 @@
|
||||
BOOTPARAM="-c 1-7,9-15,17-23,25-31 -m 28G@0,28G@1 -r 1-7:0+9-15:8+17-23:16+25-31:24"
|
||||
2
test/large_page/x86_64/init/401_4K.init
Normal file
2
test/large_page/x86_64/init/401_4K.init
Normal file
@ -0,0 +1,2 @@
|
||||
BOOTPARAM="-c 1-7,9-15,17-23,25-31 -m 28G@0,28G@1 -r 1-7:0+9-15:8+17-23:16+25-31:24"
|
||||
MCEXECOPT="-h 2M"
|
||||
2
test/large_page/x86_64/init/402_4K.init
Normal file
2
test/large_page/x86_64/init/402_4K.init
Normal file
@ -0,0 +1,2 @@
|
||||
BOOTPARAM="-c 1-7,9-15,17-23,25-31 -m 28G@0,28G@1 -r 1-7:0+9-15:8+17-23:16+25-31:24"
|
||||
MCEXECOPT="-h 1G"
|
||||
2
test/large_page/x86_64/init/501_4K.init
Normal file
2
test/large_page/x86_64/init/501_4K.init
Normal file
@ -0,0 +1,2 @@
|
||||
BOOTPARAM="-c 1-7,9-15,17-23,25-31 -m 28G@0,28G@1 -r 1-7:0+9-15:8+17-23:16+25-31:24"
|
||||
MCEXECOPT="-s 2M,16G"
|
||||
2
test/large_page/x86_64/init/502_4K.init
Normal file
2
test/large_page/x86_64/init/502_4K.init
Normal file
@ -0,0 +1,2 @@
|
||||
BOOTPARAM="-c 1-7,9-15,17-23,25-31 -m 28G@0,28G@1 -r 1-7:0+9-15:8+17-23:16+25-31:24"
|
||||
MCEXECOPT="-s 1G,16G"
|
||||
5
test/large_page/x86_64/init/601_4K.init
Normal file
5
test/large_page/x86_64/init/601_4K.init
Normal file
@ -0,0 +1,5 @@
|
||||
sudo mkdir -p /mnt/hugetlbfs-2M
|
||||
sudo mount -t hugetlbfs -o mode=777,pagesize=2m none /mnt/hugetlbfs-2M
|
||||
|
||||
sudo mkdir -p /mnt/hugetlbfs-1G
|
||||
sudo mount -t hugetlbfs -o mode=777,pagesize=1g none /mnt/hugetlbfs-1G
|
||||
38
test/large_page/x86_64/result.log
Normal file
38
test/large_page/x86_64/result.log
Normal file
@ -0,0 +1,38 @@
|
||||
Script started on Sun Dec 9 14:59:15 2018
|
||||
]0;m-takagi@wallaby14:~/project/os/mckernel/test/large_page/x86_64[?1034h[m-takagi@wallaby14 x86_64]$ makt e test
|
||||
../driver.sh
|
||||
[INFO] 001 started
|
||||
[ OK ] trial #: 000, addr: 00002aaaab200000, requested size: 2097152, allocated size: 2097152
|
||||
[ OK ] trial #: 001, addr: 00002aaac0000000, requested size: 1073741824, allocated size: 1073741824
|
||||
[ OK ] 001 passed
|
||||
[INFO] 101 started
|
||||
[ OK ] trial #: 000, addr: 00002aaaab200000, requested size: 2097152, allocated size: 2097152
|
||||
[ OK ] trial #: 001, addr: 00002aaac0000000, requested size: 1073741824, allocated size: 1073741824
|
||||
[ OK ] 101 passed
|
||||
[INFO] 201 started
|
||||
[ OK ] trial #: 000, addr: 00002aaaab200000, requested size: 2097152, allocated size: 2097152
|
||||
[ OK ] trial #: 001, addr: 00002aaac0000000, requested size: 1073741824, allocated size: 1073741824
|
||||
[ OK ] 201 passed
|
||||
[INFO] 301 started
|
||||
[ OK ] trial #: 000, addr: 00002aaaab200000, requested size: 2097152, allocated size: 2097152
|
||||
[ OK ] trial #: 001, addr: 00002aaac0000000, requested size: 1073741824, allocated size: 1073741824
|
||||
[ OK ] 301 passed
|
||||
[INFO] 401 started
|
||||
[ OK ] trial #: 000, addr: 0000000000800000, requested size: 2097152, allocated size: 2097152
|
||||
[ OK ] 401 passed
|
||||
[INFO] 402 started
|
||||
[ OK ] trial #: 000, addr: 0000000040000000, requested size: 1073741824, allocated size: 1073741824
|
||||
[ OK ] 402 passed
|
||||
[INFO] 501 started
|
||||
[ OK ] trial #: 000, addr: 0000000000a00000, requested size: 2097152, allocated size: 2097152
|
||||
[ OK ] trial #: 001, addr: 0000000000e00000, requested size: 2097152, allocated size: 2097152
|
||||
[ OK ] trial #: 002, addr: 0000547fffa00000, requested size: 2097152, allocated size: 2097152
|
||||
[ OK ] 501 passed
|
||||
[INFO] 601 started
|
||||
[ OK ] trial #: 000, addr: 00002aaaab200000, requested size: 2097152, allocated size: 2097152
|
||||
[ OK ] trial #: 001, addr: 00002aaac0000000, requested size: 1073741824, allocated size: 1073741824
|
||||
[ OK ] 601 passed
|
||||
]0;m-takagi@wallaby14:~/project/os/mckernel/test/large_page/x86_64[m-takagi@wallaby14 x86_64]$ exu it
|
||||
exit
|
||||
|
||||
Script done on Sun Dec 9 15:00:22 2018
|
||||
22
test/large_page/x86_64/test_set.conf
Normal file
22
test/large_page/x86_64/test_set.conf
Normal file
@ -0,0 +1,22 @@
|
||||
|
||||
# mmap + THP: 2MB, 1GB
|
||||
test_set="001"
|
||||
|
||||
# mmap + flag: 2MB, 1GB
|
||||
test_set="${test_set} 101"
|
||||
|
||||
# shget + THP: 2MB, 1GB
|
||||
test_set="${test_set} 201"
|
||||
|
||||
# shmget + flag: 2MB, 1GB
|
||||
test_set="${test_set} 301"
|
||||
|
||||
# heap: 2MB, 1GB
|
||||
test_set="${test_set} 401 402"
|
||||
|
||||
# .data, .bss, .stack: 2MB
|
||||
test_set="${test_set} 501"
|
||||
|
||||
# hugetlbfs: 2MB, 1GB
|
||||
test_set="${test_set} 601"
|
||||
|
||||
Reference in New Issue
Block a user