8 #include "map-unshare.h"
12 #define STRING(x) STRING2(x)
15 void map_unshare(void) {
17 FILE *maps = fopen("/proc/self/maps", "r");
19 while (fgets(lbuf,sizeof(lbuf),maps)) {
20 uintptr_t mstart,mend;
22 char flagstr[MAXFLAGS+1];
25 int ll = strlen(lbuf);
27 assert(lbuf[ll-1]=='\n');
31 sscanf(lbuf,"%"SCNxPTR"-%"SCNxPTR" %"STRING(MAXFLAGS)"s"
32 " %*"SCNxPTR" %*x:%*x %lu %n",
33 &mstart,&mend, flagstr, &inum, &pathoffset);
34 assert(pathoffset>=0 && pathoffset<=ll);
35 const char *orgpath = lbuf+pathoffset;
36 fprintf(stderr,"%"PRIxPTR"-%"PRIxPTR" %s %lu %s: ",
37 mstart,mend,flagstr,inum,orgpath);
39 (!!strchr(flagstr,'x') * PROT_EXEC) |
40 (!!strchr(flagstr,'r') * PROT_READ) |
41 (!!strchr(flagstr,'w') * PROT_WRITE);
43 (!!strchr(flagstr,'p') * MAP_PRIVATE) |
44 (!!strchr(flagstr,'s') * MAP_SHARED);
46 #define SKIP(why) { fprintf(stderr,"skip, %s\n",(why)); continue; }
48 if (mstart==mend) SKIP("zero length");
49 if (!(prot & PROT_READ)) SKIP("unreadable");
50 if ((prot & PROT_WRITE) && (flags & MAP_SHARED)) SKIP("shared write");
51 if (orgpath[0] != '/') SKIP("no path");
53 FILE *copyf = tmpfile();
56 size_t length = mend-mstart;
57 void *startp = (void*)mstart;
59 fputs("copy ",stderr);
60 size_t done = fwrite(startp, 1, length, copyf);
61 assert(done == length);
62 int r = fflush(copyf);
65 fputs("mmap ",stderr);
67 mapped = mmap(startp, length, prot, MAP_SHARED|MAP_FIXED, fileno(copyf), 0);
68 assert(mapped == startp);
71 fputs("done.\n",stderr);
73 assert(!ferror(maps));