Move the ILP32 mmap() hackery into legacy_32_bit_support.cpp.
Every time I look at mmap.cpp, I fail to realize it's only built for ILP32.
Also improve some of the commentary in SYSCALLS.TXT and legacy_32_bit_support.cpp.
Change-Id: Ieedfe800b437e30c060c3e8663b6d96d517dbf6f
diff --git a/libc/Android.bp b/libc/Android.bp
index 2efca68..d8467a8 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -1224,9 +1224,6 @@
// off64_t/time64_t support on LP32.
"bionic/legacy_32_bit_support.cpp",
"bionic/time64.c",
-
- // TODO: move to libc/bionic/legacy_32_bit_support.cpp or #if __LP64__ instead.
- "bionic/mmap.cpp",
],
},
},
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index 0db5d79..ce14e49 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -174,20 +174,21 @@
off_t lseek(int, off_t, int) lp32
int __llseek:_llseek(int, unsigned long, unsigned long, off64_t*, int) lp32
off_t lseek|lseek64(int, off_t, int) lp64
-int ftruncate64(int, off64_t) lp32
-int ftruncate|ftruncate64(int, off_t) lp64
ssize_t sendfile(int out_fd, int in_fd, off_t* offset, size_t count) lp32
ssize_t sendfile64(int out_fd, int in_fd, off64_t* offset, size_t count) lp32
ssize_t sendfile|sendfile64(int out_fd, int in_fd, off_t* offset, size_t count) lp64
int truncate(const char*, off_t) lp32
int truncate64(const char*, off64_t) lp32
int truncate|truncate64(const char*, off_t) lp64
-# (mmap only gets two lines because we only used the 64-bit variant on 32-bit systems.)
-void* __mmap2:mmap2(void*, size_t, int, int, int, long) lp32
-void* mmap|mmap64(void*, size_t, int, int, int, off_t) lp64
# (fallocate only gets two lines because there is no 32-bit variant.)
int fallocate64:fallocate(int, int, off64_t, off64_t) lp32
int fallocate|fallocate64(int, int, off_t, off_t) lp64
+# (ftruncate only gets two lines because 32-bit bionic only uses the 64-bit call.)
+int ftruncate64(int, off64_t) lp32
+int ftruncate|ftruncate64(int, off_t) lp64
+# (mmap only gets two lines because 32-bit bionic only uses the 64-bit call.)
+void* __mmap2:mmap2(void*, size_t, int, int, int, long) lp32
+void* mmap|mmap64(void*, size_t, int, int, int, off_t) lp64
# posix_fadvise64 is awkward: arm has shuffled arguments,
# the POSIX functions don't set errno, and no architecture has posix_fadvise.
diff --git a/libc/bionic/legacy_32_bit_support.cpp b/libc/bionic/legacy_32_bit_support.cpp
index 41108e6..314fe9b 100644
--- a/libc/bionic/legacy_32_bit_support.cpp
+++ b/libc/bionic/legacy_32_bit_support.cpp
@@ -30,24 +30,28 @@
#include <errno.h>
#include <fcntl.h>
-#include <stdarg.h>
+#include <stdint.h>
+#include <sys/mman.h>
#include <sys/resource.h>
#include <sys/types.h>
-#include <sys/uio.h>
-#include <sys/vfs.h>
#include <unistd.h>
+#include "platform/bionic/macros.h"
+#include "platform/bionic/page.h"
+#include "private/ErrnoRestorer.h"
#include "private/bionic_fdtrack.h"
#if defined(__LP64__)
#error This code is only needed on 32-bit systems!
#endif
-// System calls we need.
+// To implement lseek64() on ILP32, we need to use the _llseek() system call
+// which splits the off64_t into two 32-bit arguments and returns the off64_t
+// result via a pointer because 32-bit kernels can't accept 64-bit arguments
+// or return 64-bit results. (Our symbol is __llseek with two underscores for
+// historical reasons, but it's exposed as ABI so we can't fix it.)
extern "C" int __llseek(int, unsigned long, unsigned long, off64_t*, int);
-// For lseek64 we need to use the llseek system call which splits the off64_t in two and
-// returns the off64_t result via a pointer because 32-bit kernels can't return 64-bit results.
off64_t lseek64(int fd, off64_t off, int whence) {
off64_t result;
unsigned long off_hi = static_cast<unsigned long>(off >> 32);
@@ -101,3 +105,33 @@
}
return result;
}
+
+// mmap2(2) is like mmap(2), but the offset is in 4096-byte blocks (regardless
+// of page size), not bytes, to enable mapping parts of large files past the
+// 4GiB limit but without the inconvenience of dealing with 64-bit values, with
+// no down side since mappings need to be page aligned anyway, and the 32-bit
+// architectures that support this system call all have 4KiB pages.
+extern "C" void* __mmap2(void*, size_t, int, int, int, size_t);
+
+void* mmap64(void* addr, size_t size, int prot, int flags, int fd, off64_t offset) {
+ static constexpr size_t MMAP2_SHIFT = 12;
+
+ if (offset < 0 || (offset & ((1UL << MMAP2_SHIFT) - 1)) != 0) {
+ errno = EINVAL;
+ return MAP_FAILED;
+ }
+
+ // Prevent allocations large enough for `end - start` to overflow,
+ // to avoid security bugs.
+ size_t rounded = __BIONIC_ALIGN(size, page_size());
+ if (rounded < size || rounded > PTRDIFF_MAX) {
+ errno = ENOMEM;
+ return MAP_FAILED;
+ }
+
+ return __mmap2(addr, size, prot, flags, fd, offset >> MMAP2_SHIFT);
+}
+
+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));
+}
diff --git a/libc/bionic/mmap.cpp b/libc/bionic/mmap.cpp
deleted file mode 100644
index f05dcb8..0000000
--- a/libc/bionic/mmap.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <errno.h>
-#include <stdint.h>
-#include <sys/mman.h>
-#include <unistd.h>
-
-#include "platform/bionic/macros.h"
-#include "platform/bionic/page.h"
-#include "private/ErrnoRestorer.h"
-
-// mmap2(2) is like mmap(2), but the offset is in 4096-byte blocks, not bytes.
-extern "C" void* __mmap2(void*, size_t, int, int, int, size_t);
-
-#define MMAP2_SHIFT 12 // 2**12 == 4096
-
-void* mmap64(void* addr, size_t size, int prot, int flags, int fd, off64_t offset) {
- if (offset < 0 || (offset & ((1UL << MMAP2_SHIFT)-1)) != 0) {
- errno = EINVAL;
- return MAP_FAILED;
- }
-
- // Prevent allocations large enough for `end - start` to overflow.
- size_t rounded = __BIONIC_ALIGN(size, page_size());
- if (rounded < size || rounded > PTRDIFF_MAX) {
- errno = ENOMEM;
- return MAP_FAILED;
- }
-
- return __mmap2(addr, size, prot, flags, fd, offset >> MMAP2_SHIFT);
-}
-
-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));
-}