Home | History | Annotate | Download | only in solaris
      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