From owner-freebsd-emulation@FreeBSD.ORG Sat Jan 20 00:25:52 2007 Return-Path: X-Original-To: freebsd-emulation@FreeBSD.org Delivered-To: freebsd-emulation@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 8C69316A402 for ; Sat, 20 Jan 2007 00:25:52 +0000 (UTC) (envelope-from jkim@FreeBSD.org) Received: from anuket.mj.niksun.com (gwnew.niksun.com [65.115.46.162]) by mx1.freebsd.org (Postfix) with ESMTP id 3E52113C45B for ; Sat, 20 Jan 2007 00:25:52 +0000 (UTC) (envelope-from jkim@FreeBSD.org) Received: from niksun.com (anuket [10.70.0.5]) by anuket.mj.niksun.com (8.13.6/8.13.6) with ESMTP id l0JNpBdU069079 for ; Fri, 19 Jan 2007 18:51:11 -0500 (EST) (envelope-from jkim@FreeBSD.org) From: Jung-uk Kim To: freebsd-emulation@FreeBSD.org Date: Fri, 19 Jan 2007 18:51:03 -0500 User-Agent: KMail/1.6.2 MIME-Version: 1.0 Content-Disposition: inline Content-Type: Multipart/Mixed; boundary="Boundary-00=_slVsFRjAyW28ZgI" Message-Id: <200701191851.08685.jkim@FreeBSD.org> X-Virus-Scanned: ClamAV 0.88.6/2466/Thu Jan 18 18:49:11 2007 on anuket.mj.niksun.com X-Virus-Status: Clean Cc: Subject: A new mmap finger printer X-BeenThere: freebsd-emulation@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Development of Emulators of other operating systems List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 20 Jan 2007 00:25:52 -0000 --Boundary-00=_slVsFRjAyW28ZgI Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-Disposition: inline I added PROT_EXEC test and cleaned up Marcin Cieslak's mmap finger printer. Can any one try this on a real Linux/i386 box and send me the output? Thanks, Jung-uk Kim --Boundary-00=_slVsFRjAyW28ZgI Content-Type: text/plain; charset="iso-8859-1"; name="mmap_test.c" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="mmap_test.c" #include #include #include #include #include #include #include #include struct intdesc { const int val; const char *desc; }; static sigjmp_buf env; static char nofile[] = "anonymous"; static char testfile[] = "/tmp/test.XXXXXX"; #if defined(__amd64__) || defined(__x86_64__) static char testfunc[] = { 0x55, /* push %rbp */ 0x48, 0x89, 0xe5, /* mov %rsp,%rbp */ 0xc7, 0x45, 0xfc, 0x42, 0x00, 0x00, 0x00, /* movl $0x42,-4(%rbp) */ 0xc9, /* leaveq */ 0xc3 /* retq */ }; #define TOFFSET 7 #elif defined(__i386__) static char testfunc[] = { 0x55, /* push %ebp */ 0x89, 0xe5, /* mov %esp,%ebp */ 0x83, 0xec, 0x04, /* sub $0x4,%esp */ 0xc7, 0x45, 0xfc, 0x42, 0x00, 0x00, 0x00, /* movl $0x42,-4(%ebp) */ 0xc9, /* leave */ 0xc3 /* ret */ }; #define TOFFSET 9 #else #warn "Sorry, this platform is not supported." #endif static char * mmap_test(int map_prot, int map_mode, int fd) { char *qp; qp = mmap(0, 1024, map_prot, map_mode, fd, 0); if (qp != MAP_FAILED) { printf("mmap OK "); return (qp); } else { printf("mmap error (%d)", errno); return (NULL); } } static void unmap_test(void *ptr) { if (ptr != NULL) munmap(ptr, 1024); } static int sigsegv = 0; static int buserr = 0; static int othersig = 0; static void handle_sig(int sig) { switch(sig) { case SIGSEGV: sigsegv ++; break; case SIGBUS: buserr ++; break; default: othersig = sig; } siglongjmp(env, 1); } #define PRINT_SIGNAL() \ do { \ if (sigsegv) \ printf("sigsegv"); \ if (buserr) \ printf("buserr"); \ if (othersig) \ printf("sig%02d", othersig); \ } while(0) static void access_test(void *ptr) { struct sigaction newsig = { .sa_handler = &handle_sig, .sa_flags = 0, .sa_mask = 0, }; struct sigaction oldsegv; struct sigaction oldbus; char *qp = (char *)ptr; /* read test */ sigsegv = buserr = othersig = 0; sigaction(SIGSEGV, &newsig, &oldsegv); sigaction(SIGBUS, &newsig, &oldbus); printf("read: "); if (sigsetjmp(env, 1) == 0) printf("0x%02x", qp[TOFFSET]); else PRINT_SIGNAL(); /* write test */ sigsegv = buserr = othersig = 0; printf(" write: "); if (sigsetjmp(env, 1) == 0) { memcpy(qp, testfunc, sizeof(testfunc)); qp[TOFFSET] = 0x41; printf("OK"); } else PRINT_SIGNAL(); /* exec test */ sigsegv = buserr = othersig = 0; printf(" exec: "); if (sigsetjmp(env, 1) == 0) { ((void (*)())qp)(); printf("OK"); } else PRINT_SIGNAL(); sigaction(SIGSEGV, &oldsegv, NULL); sigaction(SIGBUS, &oldbus, NULL); } #undef PRINT_SIGNAL static void run_cases(struct intdesc filemodes[], struct intdesc mapmodes[], struct intdesc mapprots[], char *(*mapfunc)(int, int, int), void (*accessfunc)(void *), void (*unmapfunc)(void *)) { struct intdesc *filemode, *map_mode, *map_prot; int fd, caseid, anon; void *region; caseid = 1; for (filemode = filemodes; filemode->desc != NULL; filemode++) { for (map_mode = mapmodes; map_mode->desc != NULL; map_mode++) { for (map_prot = mapprots; map_prot->desc != NULL; map_prot++) { if (filemode->desc != nofile) { anon = 0; if ((fd = open(testfile, filemode->val, 0644)) < 0 ) { perror("open testfile"); return; } } else { fd = -1; anon = MAP_ANON; } printf("%04d: mmap(0, 1024, %s, %s%s, ...)\n" " for filemode %s: ", caseid, map_prot->desc, anon ? "MAP_ANON|" : "", map_mode->desc, filemode->desc); region = (*mapfunc)(map_prot->val, anon | map_mode->val, fd); if (region) { (*accessfunc)(region); (*unmapfunc)(region); } caseid++; if (fd >= 0) close(fd); printf("\n"); } } } } int main(void) { struct intdesc filemodes[] = { {O_RDONLY, "O_RDONLY"}, {O_WRONLY, "O_WRONLY"}, {O_RDWR, "O_RDWR"}, {-1, nofile}, {-1, NULL}, }; struct intdesc mapmodes[] = { #if 0 {0, "none"}, #endif {MAP_SHARED, "MAP_SHARED"}, {MAP_PRIVATE, "MAP_PRIVATE"}, {-1, NULL}, }; struct intdesc mapprots[] = { {PROT_NONE, "PROT_NONE"}, {PROT_READ, "PROT_READ"}, {PROT_WRITE, "PROT_WRITE"}, {PROT_EXEC, "PROT_EXEC"}, {PROT_READ|PROT_WRITE, "PROT_READ|PROT_WRITE"}, {PROT_READ|PROT_EXEC, "PROT_READ|PROT_EXEC"}, {PROT_WRITE|PROT_EXEC, "PROT_WRITE|PROT_EXEC"}, {PROT_READ|PROT_WRITE|PROT_EXEC, "PROT_READ|PROT_WRITE|PROT_EXEC"}, {-1, NULL}, }; int fd; fd = mkstemp(testfile); if (fd < 0) { perror("open testfile"); return (-1); } if (write(fd, testfunc, sizeof(testfunc)) != sizeof(testfunc)) { perror("write testfile"); return (-1); } close(fd); run_cases(filemodes, mapmodes, mapprots, &mmap_test, &access_test, &unmap_test); unlink(testfile); return (0); } --Boundary-00=_slVsFRjAyW28ZgI--