Merge "Move the ILP32 mmap() hackery into legacy_32_bit_support.cpp." into main am: cbc07d4d31
Original change: https://android-review.googlesource.com/c/platform/bionic/+/3118911 Change-Id: I9a5922f1dd6fb6dd84352568799d8aec9d2e4837 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
commit
0031c5a935
4 changed files with 46 additions and 75 deletions
|
@ -1224,9 +1224,6 @@ cc_library_static {
|
|||
// 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",
|
||||
],
|
||||
},
|
||||
},
|
||||
|
|
|
@ -174,20 +174,21 @@ int utimensat(int, const char*, const struct timespec times[2], int) all
|
|||
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.
|
||||
|
|
|
@ -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 @@ int prlimit(pid_t pid, int resource, const rlimit* n32, rlimit* o32) {
|
|||
}
|
||||
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));
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
Loading…
Reference in a new issue