Add mmap64()

This adds mmap64() to bionic so that it is possible to have
large offset passed to kernel. However, the syscall mechanism
only passes 32-bit number to kernel. So effectively, the
largest offset that can be passed is about 43 bits (since
offset is signed, and the number passed to kernel is number
of pages (page size == 4K => 12 bits)).

Change-Id: Ib54f4e9b54acb6ef8b0324f3b89c9bc810b07281
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
Daniel Leung 2013-09-18 14:41:18 -07:00 committed by Elliott Hughes
parent d5ddf40ecf
commit afcc0cccda
2 changed files with 7 additions and 2 deletions

View File

@ -37,13 +37,13 @@ extern "C" void* __mmap2(void*, size_t, int, int, int, size_t);
#define MMAP2_SHIFT 12 // 2**12 == 4096
void* mmap(void* addr, size_t size, int prot, int flags, int fd, off_t offset) {
void* mmap64(void* addr, size_t size, int prot, int flags, int fd, off64_t offset) {
if (offset & ((1UL << MMAP2_SHIFT)-1)) {
errno = EINVAL;
return MAP_FAILED;
}
size_t unsigned_offset = static_cast<size_t>(offset); // To avoid sign extension.
uint64_t unsigned_offset = static_cast<uint64_t>(offset); // To avoid sign extension.
void* result = __mmap2(addr, size, prot, flags, fd, unsigned_offset >> MMAP2_SHIFT);
if (result != MAP_FAILED && (flags & (MAP_PRIVATE | MAP_ANONYMOUS)) != 0) {
@ -53,3 +53,7 @@ void* mmap(void* addr, size_t size, int prot, int flags, int fd, off_t offset) {
return result;
}
void* mmap(void* addr, size_t size, int prot, int flags, int fd, off_t offset) {
return mmap64(addr, size, prot, flags, fd, static_cast<off64_t>(offset));
}

View File

@ -45,6 +45,7 @@ __BEGIN_DECLS
#define MREMAP_FIXED 2
extern void* mmap(void *, size_t, int, int, int, off_t);
extern void* mmap64(void *, size_t, int, int, int, off64_t);
extern int munmap(void *, size_t);
extern int msync(const void *, size_t, int);
extern int mprotect(const void *, size_t, int);