/* * This tests the Mac OS X Superpage API introduced in 10.7 * * Note that most of these calls go through the mach_vm_allocate() interface, * but the actually supported and documented interface is the mmap() one * (see mmap(2)). */ #include #include #include #include #include #include #include #include #include #include #define SUPERPAGE_SIZE (2*1024*1024) #define SUPERPAGE_MASK (-SUPERPAGE_SIZE) #ifdef __LP64__ #define FIXED_ADDRESS1 (0x100000000ULL+500*1024*1024) /* at 4 GB + 500 MB virtual */ #define FIXED_ADDRESS2 (0x100000000ULL+502*1024*1024 + 4*1024) /* at 4 GB + 502 MB + 4 KB virtual */ #else #define FIXED_ADDRESS1 (500*1024*1024) /* at 500 MB virtual */ #define FIXED_ADDRESS2 (502*1024*1024 + 4*1024) /* at 502 MB + 4 KB virtual */ #endif char error[100]; jmp_buf resume; void test_signal_handler(int signo) { longjmp(resume, signo); } char *signame[32] = { [SIGBUS] "SIGBUS", [SIGSEGV] "SIGSEGV" }; typedef struct { char *description; boolean_t (*fn)(); } test_t; boolean_t check_kr(int kr, char *fn) { if (kr) { sprintf(error, "%s() returned %d", fn, kr); return FALSE; } return TRUE; } boolean_t check_addr0(mach_vm_address_t addr, char *fn) { if (!addr) { sprintf(error, "%s() returned address 0", fn); return FALSE; } return TRUE; } boolean_t check_addr(mach_vm_address_t addr1, mach_vm_address_t addr2, char *fn) { if (addr1 != addr2) { sprintf(error, "%s() returned address %llx instead of %llx", fn, addr1, addr2); return FALSE; } return TRUE; } boolean_t check_align(mach_vm_address_t addr) { if (addr & !SUPERPAGE_MASK) { sprintf(error, "address not aligned properly: 0x%llx", addr); return FALSE; } return TRUE; } boolean_t check_r(mach_vm_address_t addr, mach_vm_size_t size, int *res) { volatile char *data = (char*)(uintptr_t)addr; int i, sig, test; if ((sig = setjmp(resume)) != 0) { sprintf(error, "%s when reading", signame[sig]); return FALSE; } test = 0; for (i=0; i1) { if (!strcmp(argv[1], "-h")) { printf("Usage: %s \n", argv[0]); printf("\tmode = 0: test all cases\n"); printf("\tmode = -1: allocate/deallocate until failure\n"); printf("\tmode > 0: run test \n"); exit(0); } mode=atoi(argv[1]); } /* install SIGBUS handler */ struct sigaction my_sigaction; my_sigaction.sa_handler = test_signal_handler; my_sigaction.sa_flags = SA_RESTART; my_sigaction.sa_mask = 0; sigaction( SIGBUS, &my_sigaction, NULL ); sigaction( SIGSEGV, &my_sigaction, NULL ); if (mode>0) /* one specific test */ testit(mode-1); if (mode==0) { /* test all cases */ printf("Running %d tests:\n", TESTS); for (i=0; i