Add a legacy inline for mmap64.

While this was never an inline, this function alone has caused most of
the bug reports related to _FILE_OFFSET_BITS=64. Providing an inline
for it should allow a lot more code to build with _FILE_OFFSET_BITS=64
when targeting pre-L.

Test: make checkbuild
Test: built trivial cc_binary for LP32 against API 14 with
      _FILE_OFFSET_BITS=64 set
Bug: lots
Change-Id: I8479d34af4da358c11423bee43d45b59e9d4143e
diff --git a/libc/bionic/grp_pwd.cpp b/libc/bionic/grp_pwd.cpp
index 2823662..50fcbce 100644
--- a/libc/bionic/grp_pwd.cpp
+++ b/libc/bionic/grp_pwd.cpp
@@ -580,7 +580,7 @@
   ErrnoRestorer errno_restorer;
   *result = NULL;
   char* p = reinterpret_cast<char*>(
-      BIONIC_ALIGN(reinterpret_cast<uintptr_t>(buf), sizeof(uintptr_t)));
+      __BIONIC_ALIGN(reinterpret_cast<uintptr_t>(buf), sizeof(uintptr_t)));
   if (p + sizeof(group_state_t) > buf + buflen) {
     return ERANGE;
   }
diff --git a/libc/bionic/jemalloc_wrapper.cpp b/libc/bionic/jemalloc_wrapper.cpp
index 266b966..19081a4 100644
--- a/libc/bionic/jemalloc_wrapper.cpp
+++ b/libc/bionic/jemalloc_wrapper.cpp
@@ -23,7 +23,7 @@
 
 void* je_pvalloc(size_t bytes) {
   size_t pagesize = getpagesize();
-  size_t size = BIONIC_ALIGN(bytes, pagesize);
+  size_t size = __BIONIC_ALIGN(bytes, pagesize);
   if (size < bytes) {
     return NULL;
   }
diff --git a/libc/bionic/mmap.cpp b/libc/bionic/mmap.cpp
index 57a8cdf..3503319 100644
--- a/libc/bionic/mmap.cpp
+++ b/libc/bionic/mmap.cpp
@@ -48,7 +48,7 @@
   }
 
   // prevent allocations large enough for `end - start` to overflow
-  size_t rounded = BIONIC_ALIGN(size, PAGE_SIZE);
+  size_t rounded = __BIONIC_ALIGN(size, PAGE_SIZE);
   if (rounded < size || rounded > PTRDIFF_MAX) {
     errno = ENOMEM;
     return MAP_FAILED;
diff --git a/libc/bionic/mremap.cpp b/libc/bionic/mremap.cpp
index 6653d43..896ccef 100644
--- a/libc/bionic/mremap.cpp
+++ b/libc/bionic/mremap.cpp
@@ -38,7 +38,7 @@
 
 void* mremap(void* old_address, size_t old_size, size_t new_size, int flags, ...) {
   // prevent allocations large enough for `end - start` to overflow
-  size_t rounded = BIONIC_ALIGN(new_size, PAGE_SIZE);
+  size_t rounded = __BIONIC_ALIGN(new_size, PAGE_SIZE);
   if (rounded < new_size || rounded > PTRDIFF_MAX) {
     errno = ENOMEM;
     return MAP_FAILED;
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp
index 65ab92c..be0fd1b 100644
--- a/libc/bionic/pthread_create.cpp
+++ b/libc/bionic/pthread_create.cpp
@@ -172,8 +172,8 @@
     // Make sure the stack size and guard size are multiples of PAGE_SIZE.
     if (__builtin_add_overflow(attr->stack_size, attr->guard_size, &mmap_size)) return EAGAIN;
     if (__builtin_add_overflow(mmap_size, sizeof(pthread_internal_t), &mmap_size)) return EAGAIN;
-    mmap_size = BIONIC_ALIGN(mmap_size, PAGE_SIZE);
-    attr->guard_size = BIONIC_ALIGN(attr->guard_size, PAGE_SIZE);
+    mmap_size = __BIONIC_ALIGN(mmap_size, PAGE_SIZE);
+    attr->guard_size = __BIONIC_ALIGN(attr->guard_size, PAGE_SIZE);
     attr->stack_base = __create_thread_mapped_space(mmap_size, attr->guard_size);
     if (attr->stack_base == NULL) {
       return EAGAIN;
diff --git a/libc/bionic/system_properties.cpp b/libc/bionic/system_properties.cpp
index c57cd9c..b781ea3 100644
--- a/libc/bionic/system_properties.cpp
+++ b/libc/bionic/system_properties.cpp
@@ -304,7 +304,7 @@
 }
 
 void* prop_area::allocate_obj(const size_t size, uint_least32_t* const off) {
-  const size_t aligned = BIONIC_ALIGN(size, sizeof(uint_least32_t));
+  const size_t aligned = __BIONIC_ALIGN(size, sizeof(uint_least32_t));
   if (bytes_used_ + aligned > pa_data_size) {
     return nullptr;
   }
diff --git a/libc/include/android/legacy_sys_mman_inlines.h b/libc/include/android/legacy_sys_mman_inlines.h
new file mode 100644
index 0000000..7171896
--- /dev/null
+++ b/libc/include/android/legacy_sys_mman_inlines.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#pragma once
+
+#include <sys/cdefs.h>
+#include <sys/mman.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+#if __ANDROID_API__ < __ANDROID_API_L__
+
+__BEGIN_DECLS
+
+/*
+ * While this was never an inline, this function alone has caused most of the
+ * bug reports related to _FILE_OFFSET_BITS=64. Providing an inline for it
+ * should allow a lot more code to build with _FILE_OFFSET_BITS=64 when
+ * targeting pre-L.
+ */
+static __inline void* mmap64(void* __addr, size_t __size, int __prot, int __flags, int __fd,
+                             off64_t __offset) {
+  const int __mmap2_shift = 12; // 2**12 == 4096
+  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;
+  }
+
+  extern void* __mmap2(void* __addr, size_t __size, int __prot, int __flags, int __fd,
+                       size_t __offset);
+  return __mmap2(__addr, __size, __prot, __flags, __fd, __offset >> __mmap2_shift);
+}
+
+__END_DECLS
+
+#endif  /* __ANDROID_API__ < __ANDROID_API_L__ */
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index 063b51d..3656733 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -79,6 +79,8 @@
 #define __BIONIC_CAST(_k,_t,_v) ((_t) (_v))
 #endif
 
+#define __BIONIC_ALIGN(__value, __alignment) (((__value) + (__alignment)-1) & ~((__alignment)-1))
+
 /*
  * The __CONCAT macro is used to concatenate parts of symbol names, e.g.
  * with "#define OLD(foo) __CONCAT(old,foo)", OLD(foo) produces oldfoo.
diff --git a/libc/include/sys/mman.h b/libc/include/sys/mman.h
index 1e752c4..83b5e6f 100644
--- a/libc/include/sys/mman.h
+++ b/libc/include/sys/mman.h
@@ -45,12 +45,19 @@
 #define MREMAP_FIXED    2
 
 #if defined(__USE_FILE_OFFSET64)
-void* mmap(void* __addr, size_t __size, int __prot, int __flags, int __fd, off_t __offset) __RENAME(mmap64) __INTRODUCED_IN(21);
+/*
+ * mmap64 wasn't really around until L, but we added an inline for it since it
+ * allows a lot more code to compile with _FILE_OFFSET_BITS=64.
+ */
+void* mmap(void* __addr, size_t __size, int __prot, int __flags, int __fd, off_t __offset)
+    __RENAME(mmap64);
 #else
 void* mmap(void* __addr, size_t __size, int __prot, int __flags, int __fd, off_t __offset);
 #endif
 
+#if __ANDROID_API__ >= __ANDROID_API_L__
 void* mmap64(void* __addr, size_t __size, int __prot, int __flags, int __fd, off64_t __offset) __INTRODUCED_IN(21);
+#endif
 
 int munmap(void* __addr, size_t __size);
 int msync(void* __addr, size_t __size, int __flags);
@@ -86,4 +93,6 @@
 
 __END_DECLS
 
+#include <android/legacy_sys_mman_inlines.h>
+
 #endif
diff --git a/libc/malloc_debug/BacktraceData.cpp b/libc/malloc_debug/BacktraceData.cpp
index 65ae6fa..d597280 100644
--- a/libc/malloc_debug/BacktraceData.cpp
+++ b/libc/malloc_debug/BacktraceData.cpp
@@ -53,7 +53,7 @@
     : OptionData(debug_data) {
   size_t hdr_len = sizeof(BacktraceHeader) + sizeof(uintptr_t) * config.backtrace_frames();
   alloc_offset_ = *offset;
-  *offset += BIONIC_ALIGN(hdr_len, MINIMUM_ALIGNMENT_BYTES);
+  *offset += __BIONIC_ALIGN(hdr_len, MINIMUM_ALIGNMENT_BYTES);
 }
 
 bool BacktraceData::Initialize(const Config& config) {
diff --git a/libc/malloc_debug/Config.cpp b/libc/malloc_debug/Config.cpp
index e3798ab..3cecf9b 100644
--- a/libc/malloc_debug/Config.cpp
+++ b/libc/malloc_debug/Config.cpp
@@ -191,7 +191,7 @@
 
   // It's necessary to align the front guard to MINIMUM_ALIGNMENT_BYTES to
   // make sure that the header is aligned properly.
-  front_guard_bytes_ = BIONIC_ALIGN(rear_guard_bytes_, MINIMUM_ALIGNMENT_BYTES);
+  front_guard_bytes_ = __BIONIC_ALIGN(rear_guard_bytes_, MINIMUM_ALIGNMENT_BYTES);
   return true;
 }
 
@@ -201,7 +201,7 @@
   }
   // It's necessary to align the front guard to MINIMUM_ALIGNMENT_BYTES to
   // make sure that the header is aligned properly.
-  front_guard_bytes_ = BIONIC_ALIGN(front_guard_bytes_, MINIMUM_ALIGNMENT_BYTES);
+  front_guard_bytes_ = __BIONIC_ALIGN(front_guard_bytes_, MINIMUM_ALIGNMENT_BYTES);
   return true;
 }
 
diff --git a/libc/malloc_debug/DebugData.cpp b/libc/malloc_debug/DebugData.cpp
index e9974d7..d6ca998 100644
--- a/libc/malloc_debug/DebugData.cpp
+++ b/libc/malloc_debug/DebugData.cpp
@@ -47,7 +47,7 @@
     need_header_ = true;
 
     // Initialize all of the static header offsets.
-    pointer_offset_ = BIONIC_ALIGN(sizeof(Header), MINIMUM_ALIGNMENT_BYTES);
+    pointer_offset_ = __BIONIC_ALIGN(sizeof(Header), MINIMUM_ALIGNMENT_BYTES);
 
     if (config_.options() & BACKTRACE) {
       backtrace.reset(new BacktraceData(this, config_, &pointer_offset_));
diff --git a/libc/malloc_debug/malloc_debug.cpp b/libc/malloc_debug/malloc_debug.cpp
index d890a1c..a2ada2f 100644
--- a/libc/malloc_debug/malloc_debug.cpp
+++ b/libc/malloc_debug/malloc_debug.cpp
@@ -767,7 +767,7 @@
   }
 
   size_t pagesize = getpagesize();
-  size_t size = BIONIC_ALIGN(bytes, pagesize);
+  size_t size = __BIONIC_ALIGN(bytes, pagesize);
   if (size < bytes) {
     // Overflow
     errno = ENOMEM;
diff --git a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
index 37d8057..d7ba379 100644
--- a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
@@ -74,9 +74,10 @@
 constexpr uint32_t BACKTRACE_HEADER = 0x1;
 
 static size_t get_tag_offset(uint32_t flags = 0, size_t backtrace_frames = 0) {
-  size_t offset = BIONIC_ALIGN(sizeof(Header), MINIMUM_ALIGNMENT_BYTES);
+  size_t offset = __BIONIC_ALIGN(sizeof(Header), MINIMUM_ALIGNMENT_BYTES);
   if (flags & BACKTRACE_HEADER) {
-    offset += BIONIC_ALIGN(sizeof(BacktraceHeader) + sizeof(uintptr_t) * backtrace_frames, MINIMUM_ALIGNMENT_BYTES);
+    offset += __BIONIC_ALIGN(sizeof(BacktraceHeader) + sizeof(uintptr_t) * backtrace_frames,
+                             MINIMUM_ALIGNMENT_BYTES);
   }
   return offset;
 }
diff --git a/libc/private/bionic_macros.h b/libc/private/bionic_macros.h
index 303218e..ea19bca 100644
--- a/libc/private/bionic_macros.h
+++ b/libc/private/bionic_macros.h
@@ -40,9 +40,6 @@
   TypeName() = delete;                           \
   DISALLOW_COPY_AND_ASSIGN(TypeName)
 
-#define BIONIC_ALIGN(value, alignment) \
-  (((value) + (alignment) - 1) & ~((alignment) - 1))
-
 #define BIONIC_ROUND_UP_POWER_OF_2(value) \
   ((sizeof(value) == 8) \
     ? (1UL << (64 - __builtin_clzl(static_cast<unsigned long>(value)))) \
diff --git a/libc/private/bionic_tls.h b/libc/private/bionic_tls.h
index 852b9ae..de086f2 100644
--- a/libc/private/bionic_tls.h
+++ b/libc/private/bionic_tls.h
@@ -102,7 +102,7 @@
   passwd_state_t passwd;
 };
 
-#define BIONIC_TLS_SIZE (BIONIC_ALIGN(sizeof(bionic_tls), PAGE_SIZE))
+#define BIONIC_TLS_SIZE (__BIONIC_ALIGN(sizeof(bionic_tls), PAGE_SIZE))
 
 /*
  * Bionic uses some pthread keys internally. All pthread keys used internally