//#define MAP_PRIVATE //#define MAP_SHARED LPVOID FILE_dommap( int unix_handle, LPVOID start, DWORD size_high, DWORD size_low, DWORD offset_high, DWORD offset_low, int prot, int flags ) { int fd = -1; int pos; LPVOID ret; if (size_high || offset_high) printf("offsets larger than 4Gb not supported\n"); if (unix_handle == -1) { ret = mmap_anon( start, size_low, prot, flags, offset_low ); } else { fd = unix_handle; ret = mmap( start, size_low, prot, flags, fd, offset_low ); } if (ret != (LPVOID)-1) { // printf("address %08x\n", *(int*)ret); // printf("%x\n", ret); return ret; } // printf("mmap %d\n", errno); /* mmap() failed; if this is because the file offset is not */ /* page-aligned (EINVAL), or because the underlying filesystem */ /* does not support mmap() (ENOEXEC), we do it by hand. */ if (unix_handle == -1) return ret; if ((errno != ENOEXEC) && (errno != EINVAL)) return ret; if (prot & PROT_WRITE) { /* We cannot fake shared write mappings */ #ifdef MAP_SHARED if (flags & MAP_SHARED) return ret; #endif #ifdef MAP_PRIVATE if (!(flags & MAP_PRIVATE)) return ret; #endif } /* printf( "FILE_mmap: mmap failed (%d), faking it\n", errno );*/ /* Reserve the memory with an anonymous mmap */ ret = FILE_dommap( -1, start, size_high, size_low, 0, 0, PROT_READ | PROT_WRITE, flags ); if (ret == (LPVOID)-1) // { // perror( return ret; /* Now read in the file */ if ((pos = lseek( fd, offset_low, SEEK_SET )) == -1) { FILE_munmap( ret, size_high, size_low ); // printf("lseek\n"); return (LPVOID)-1; } read( fd, ret, size_low ); lseek( fd, pos, SEEK_SET ); /* Restore the file pointer */ mprotect( ret, size_low, prot ); /* Set the right protection */ // printf("address %08x\n", *(int*)ret); return ret; }
LPVOID FILE_dommap (int unix_handle, LPVOID start, DWORD size_high, DWORD size_low, DWORD offset_high, DWORD offset_low, int prot, int flags) { int fd = -1; int pos; LPVOID ret; ssize_t read_ret; if (size_high || offset_high) printf ("offsets larger than 4Gb not supported\n"); if (unix_handle == -1) { #ifdef MAP_ANON // printf("Anonymous\n"); flags |= MAP_ANON; #else static int fdzero = -1; if (fdzero == -1) { if ((fdzero = open ("/dev/zero", O_RDONLY)) == -1) { perror ("Cannot open /dev/zero for READ. Check permissions! error: "); abort (); } } fd = fdzero; #endif /* MAP_ANON */ /* Linux EINVAL's on us if we don't pass MAP_PRIVATE to an anon mmap */ #ifdef MAP_SHARED flags &= ~MAP_SHARED; #endif #ifdef MAP_PRIVATE flags |= MAP_PRIVATE; #endif } else fd = unix_handle; // printf("fd %x, start %x, size %x, pos %x, prot %x\n",fd,start,size_low, offset_low, prot); // if ((ret = mmap( start, size_low, prot, // flags, fd, offset_low )) != (LPVOID)-1) if ((ret = mmap (start, size_low, prot, MAP_PRIVATE | MAP_FIXED, fd, offset_low)) != (LPVOID) - 1) { // printf("address %08x\n", *(int*)ret); // printf("%x\n", ret); return ret; } // printf("mmap %d\n", errno); /* mmap() failed; if this is because the file offset is not */ /* page-aligned (EINVAL), or because the underlying filesystem */ /* does not support mmap() (ENOEXEC), we do it by hand. */ if (unix_handle == -1) return ret; if ((errno != ENOEXEC) && (errno != EINVAL)) return ret; if (prot & PROT_WRITE) { /* We cannot fake shared write mappings */ #ifdef MAP_SHARED if (flags & MAP_SHARED) return ret; #endif #ifdef MAP_PRIVATE if (!(flags & MAP_PRIVATE)) return ret; #endif } /* printf( "FILE_mmap: mmap failed (%d), faking it\n", errno );*/ /* Reserve the memory with an anonymous mmap */ ret = FILE_dommap (-1, start, size_high, size_low, 0, 0, PROT_READ | PROT_WRITE, flags); if (ret == (LPVOID) - 1) // { // perror( return ret; /* Now read in the file */ if ((pos = lseek (fd, offset_low, SEEK_SET)) == -1) { FILE_munmap (ret, size_high, size_low); // printf("lseek\n"); return (LPVOID) - 1; } if ((read_ret = read (fd, ret, size_low)) != size_low) { FILE_munmap (ret, size_high, size_low); // printf("read\n"); return (LPVOID) - 1; } /* Restore the file pointer */ if (lseek (fd, pos, SEEK_SET) == -1) { FILE_munmap (ret, size_high, size_low); // printf("lseek back\n"); return (LPVOID) - 1; } /* Set the right protection */ if (mprotect (ret, size_low, prot) == -1) { FILE_munmap (ret, size_high, size_low); // printf("mprotect\n"); return (LPVOID) - 1; } // printf("address %08x\n", *(int*)ret); return ret; }