1 /* Maps several pages with or without MAP_NORESEVE. 2 Mappings with MAP_NORESEVE do not show in /proc/self/xmap 3 (only in /proc/self/rmap) until they actually materialize. 4 Very nice from Solaris kernel :-( 5 */ 6 7 #include <dlfcn.h> 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <unistd.h> 11 #include <wait.h> 12 #include <sys/mman.h> 13 #include <sys/param.h> 14 15 static void *do_map(int flags) 16 { 17 flags |= MAP_PRIVATE | MAP_ANON; 18 void *addr = mmap(0, PAGESIZE, PROT_READ | PROT_WRITE, flags, -1, 0); 19 if (addr == NULL) { 20 perror("mmap"); 21 exit(1); 22 } else { 23 return addr; 24 } 25 } 26 27 static void *do_dlopen(const char *pathname) 28 { 29 int mode = RTLD_LAZY | RTLD_LOCAL; 30 void *handle = dlopen(pathname, mode); 31 if (handle == NULL) { 32 fprintf(stderr, "dlopen failed for %s: %s", 33 pathname, dlerror()); 34 exit(1); 35 } else { 36 return handle; 37 } 38 } 39 40 int main(int argc, const char *argv[]) 41 { 42 do_map(MAP_NORESERVE); 43 do_dlopen("libm.so"); 44 do_map(0); 45 do_map(0); 46 do_map(MAP_NORESERVE); 47 do_dlopen("liby.so"); 48 do_map(MAP_NORESERVE); 49 do_map(0); 50 do_map(0); 51 do_map(MAP_NORESERVE); 52 do_map(MAP_NORESERVE); 53 do_dlopen("libz.so"); 54 do_map(MAP_NORESERVE); 55 do_map(MAP_NORESERVE); 56 do_map(0); 57 58 pid_t pid = fork(); 59 if (pid == -1) { 60 perror("fork"); 61 exit(1); 62 } 63 64 if (pid == 0) { 65 do_map(MAP_NORESERVE); 66 do_map(0); 67 do_map(0); 68 do_dlopen("libw.so"); 69 do_map(0); 70 do_map(MAP_NORESERVE); 71 do_map(MAP_NORESERVE); 72 do_map(0); 73 printf("CHILD: PASSED\n"); 74 fflush(stdout); 75 return 0; 76 } 77 78 int status; 79 if (waitpid(pid, &status, 0) != pid) { 80 perror("waitpid"); 81 } else if ((WIFEXITED(status) != 0) && (WEXITSTATUS(status) == 0)) { 82 printf("PASSED\n"); 83 } else { 84 fprintf(stderr, "FAILED: child exited with unexpected status %s %d\n", 85 WIFEXITED(status) ? "exit" : "signal", 86 WIFEXITED(status) ? WEXITSTATUS(status) : WTERMSIG(status)); 87 } 88 89 return 0; 90 } 91