diff options
| author | Elliott Hughes <enh@google.com> | 2017-11-28 14:47:17 -0800 |
|---|---|---|
| committer | Elliott Hughes <enh@google.com> | 2017-11-28 15:47:01 -0800 |
| commit | a34817457feee026e8702a1d2dffe9e92b51d7d1 (patch) | |
| tree | a1ff7c6193a54bd11121fc34f0fe25a7b00b9ace | |
| parent | 7d5777ef15136e4e12a27c85d7b06d6806b98e70 (diff) | |
Improve the _FILE_OFFSET_BITS docs and link to them.
We're still seeing lots of confusion. People do seem to look as far as
the headers, but stop there. So let's try a bit harder to point them in
the right direction.
Also explicitly state that removing _FILE_OFFSET_BITS=64 is the
behavior-preserving fix for compilation problems when upgrading to NDK
r15 or later.
Bug: N/A
Test: N/A
Change-Id: I2d5c65b2fb5cccb9977901e51fea1ad2ccc0fd95
| -rw-r--r-- | docs/32-bit-abi.md | 24 | ||||
| -rw-r--r-- | libc/include/stdio.h | 1 | ||||
| -rw-r--r-- | libc/include/sys/cdefs.h | 17 | ||||
| -rw-r--r-- | libc/include/sys/mman.h | 18 | ||||
| -rw-r--r-- | libc/include/sys/sendfile.h | 1 | ||||
| -rw-r--r-- | libc/include/sys/types.h | 3 | ||||
| -rw-r--r-- | libc/include/unistd.h | 12 |
7 files changed, 41 insertions, 35 deletions
diff --git a/docs/32-bit-abi.md b/docs/32-bit-abi.md index 5e3ae4590..607b5d2ef 100644 --- a/docs/32-bit-abi.md +++ b/docs/32-bit-abi.md @@ -1,8 +1,6 @@ -32-bit ABI bugs -=============== +# 32-bit ABI bugs -`off_t` is 32-bit ------------------ +## 32-bit `off_t` and `_FILE_OFFSET_BITS=64` On 32-bit Android, `off_t` is a signed 32-bit integer. This limits functions that use `off_t` to working on files no larger than 2GiB. @@ -34,13 +32,19 @@ all functions that take an `off_t` become unavailable. You've asked for their increase your target API level, you'll have more and more of the functions available. API 12 adds some of the `<unistd.h>` functions, API 21 adds `mmap`, and by API 24 you have everything including `<stdio.h>`. See the -[linker map](libc/libc.map.txt) for full details. +[linker map](libc/libc.map.txt) for full details. Note also that in NDK r16 and +later, we inline an mmap64 implementation in the headers when you target an API +before 21 because it's an easy special case that's often needed. This means +that code using `_FILE_OFFSET_BITS=64` and `mmap` will always compile. + +If your code stops compiling when you move to NDK r15 or later, removing any +definition of `_FILE_OFFSET_BITS=64` will restore the behavior you used to have: +you'll have a 32-bit `off_t` and use the 32-bit functions. In the 64-bit ABI, `off_t` is always 64-bit. -`sigset_t` is too small for real-time signals ---------------------------------------------- +## `sigset_t` is too small for real-time signals On 32-bit Android, `sigset_t` is too small for ARM and x86 (but correct for MIPS). This means that there is no support for real-time signals in 32-bit @@ -49,8 +53,7 @@ code. In the 64-bit ABI, `sigset_t` is the correct size for every architecture. -`time_t` is 32-bit ------------------- +## `time_t` is 32-bit On 32-bit Android, `time_t` is 32-bit. The header `<time64.h>` and type `time64_t` exist as a workaround, but the kernel interfaces exposed on 32-bit @@ -58,8 +61,7 @@ Android all use the 32-bit `time_t`. In the 64-bit ABI, `time_t` is 64-bit. -`pthread_mutex_t` is too small for large pids ---------------------------------------------- +## `pthread_mutex_t` is too small for large pids This doesn't generally affect Android devices, because on devices `/proc/sys/kernel/pid_max` is usually too small to hit the 16-bit limit, diff --git a/libc/include/stdio.h b/libc/include/stdio.h index 2d45fc5ea..e02a37113 100644 --- a/libc/include/stdio.h +++ b/libc/include/stdio.h @@ -173,6 +173,7 @@ int renameat(int __old_dir_fd, const char* __old_path, int __new_dir_fd, const c int fseek(FILE* __fp, long __offset, int __whence); long ftell(FILE* __fp); +/* See https://android.googlesource.com/platform/bionic/+/master/docs/32-bit-abi.md */ #if defined(__USE_FILE_OFFSET64) int fgetpos(FILE* __fp, fpos_t* __pos) __RENAME(fgetpos64) __INTRODUCED_IN(24); int fsetpos(FILE* __fp, const fpos_t* __pos) __RENAME(fsetpos64) __INTRODUCED_IN(24); diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h index 833ced07f..3cf6723be 100644 --- a/libc/include/sys/cdefs.h +++ b/libc/include/sys/cdefs.h @@ -205,25 +205,28 @@ * In our header files we test against __USE_BSD and __USE_GNU. */ #if defined(_GNU_SOURCE) -# define __USE_BSD 1 -# define __USE_GNU 1 +# define __USE_BSD 1 +# define __USE_GNU 1 #endif #if defined(_BSD_SOURCE) -# define __USE_BSD 1 +# define __USE_BSD 1 #endif -/* _FILE_OFFSET_BITS 64 support. */ +/* + * _FILE_OFFSET_BITS 64 support. + * See https://android.googlesource.com/platform/bionic/+/master/docs/32-bit-abi.md + */ #if !defined(__LP64__) && defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64 -#define __USE_FILE_OFFSET64 1 +# define __USE_FILE_OFFSET64 1 /* * Note that __RENAME_IF_FILE_OFFSET64 is only valid if the off_t and off64_t * functions were both added at the same API level because if you use this, * you only have one declaration to attach __INTRODUCED_IN to. */ -#define __RENAME_IF_FILE_OFFSET64(func) __RENAME(func) +# define __RENAME_IF_FILE_OFFSET64(func) __RENAME(func) #else -#define __RENAME_IF_FILE_OFFSET64(func) +# define __RENAME_IF_FILE_OFFSET64(func) #endif /* diff --git a/libc/include/sys/mman.h b/libc/include/sys/mman.h index 028b0245b..5a7e3c03b 100644 --- a/libc/include/sys/mman.h +++ b/libc/include/sys/mman.h @@ -44,8 +44,9 @@ __BEGIN_DECLS #define MREMAP_MAYMOVE 1 #define MREMAP_FIXED 2 -#if defined(__USE_FILE_OFFSET64) /* + * See https://android.googlesource.com/platform/bionic/+/master/docs/32-bit-abi.md + * * 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. * @@ -54,17 +55,18 @@ __BEGIN_DECLS * mmap64 to every translation unit that includes this header. Instead, just * preserve the old behavior for GCC and emit a useful diagnostic. */ +#if defined(__USE_FILE_OFFSET64) void* mmap(void* __addr, size_t __size, int __prot, int __flags, int __fd, off_t __offset) -#if !defined(__clang__) && __ANDROID_API__ < __ANDROID_API_L__ - __attribute__((error("mmap is not available with _FILE_OFFSET_BITS=64 when using GCC until " - "android-21. Either raise your minSdkVersion, disable " - "_FILE_OFFSET_BITS=64, or switch to Clang."))); -#else +# if !defined(__clang__) && __ANDROID_API__ < __ANDROID_API_L__ + __attribute__((error("mmap is not available with _FILE_OFFSET_BITS=64 when using GCC until " + "android-21. Either raise your minSdkVersion, disable " + "_FILE_OFFSET_BITS=64, or switch to Clang."))); +# else __RENAME(mmap64); -#endif /* defined(__clang__) */ +# endif #else void* mmap(void* __addr, size_t __size, int __prot, int __flags, int __fd, off_t __offset); -#endif /* defined(__USE_FILE_OFFSET64) */ +#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); diff --git a/libc/include/sys/sendfile.h b/libc/include/sys/sendfile.h index ecdb76c63..97432c04a 100644 --- a/libc/include/sys/sendfile.h +++ b/libc/include/sys/sendfile.h @@ -34,6 +34,7 @@ __BEGIN_DECLS +/* See https://android.googlesource.com/platform/bionic/+/master/docs/32-bit-abi.md */ #if defined(__USE_FILE_OFFSET64) ssize_t sendfile(int __out_fd, int __in_fd, off_t* __offset, size_t __count) __RENAME(sendfile64) __INTRODUCED_IN(21); #else diff --git a/libc/include/sys/types.h b/libc/include/sys/types.h index 26ad6a5af..f07c8fdef 100644 --- a/libc/include/sys/types.h +++ b/libc/include/sys/types.h @@ -95,12 +95,13 @@ typedef uint64_t dev_t; typedef __kernel_time_t __time_t; typedef __time_t time_t; +/* This historical accident means that we had a 32-bit off_t on 32-bit architectures. */ +/* See https://android.googlesource.com/platform/bionic/+/master/docs/32-bit-abi.md */ #if defined(__USE_FILE_OFFSET64) || defined(__LP64__) typedef int64_t off_t; typedef off_t loff_t; typedef loff_t off64_t; #else -/* This historical accident means that we had a 32-bit off_t on 32-bit architectures. */ typedef __kernel_off_t off_t; typedef __kernel_loff_t loff_t; typedef loff_t off64_t; diff --git a/libc/include/unistd.h b/libc/include/unistd.h index c60cf80c9..ef75c8430 100644 --- a/libc/include/unistd.h +++ b/libc/include/unistd.h @@ -168,16 +168,10 @@ int dup3(int __old_fd, int __new_fd, int __flags) __INTRODUCED_IN(21); int fsync(int __fd); int fdatasync(int __fd) __INTRODUCED_IN(9); -#if defined(__USE_FILE_OFFSET64) -off_t lseek(int __fd, off_t __offset, int __whence) __RENAME(lseek64); -#else -off_t lseek(int __fd, off_t __offset, int __whence); -#endif - -off64_t lseek64(int __fd, off64_t __offset, int __whence); - +/* See https://android.googlesource.com/platform/bionic/+/master/docs/32-bit-abi.md */ #if defined(__USE_FILE_OFFSET64) int truncate(const char* __path, off_t __length) __RENAME(truncate64) __INTRODUCED_IN(21); +off_t lseek(int __fd, off_t __offset, int __whence) __RENAME(lseek64); ssize_t pread(int __fd, void* __buf, size_t __count, off_t __offset) __overloadable __RENAME(pread64) __INTRODUCED_IN(12); ssize_t pwrite(int __fd, const void* __buf, size_t __count, off_t __offset) @@ -185,6 +179,7 @@ ssize_t pwrite(int __fd, const void* __buf, size_t __count, off_t __offset) int ftruncate(int __fd, off_t __length) __RENAME(ftruncate64) __INTRODUCED_IN(12); #else int truncate(const char* __path, off_t __length); +off_t lseek(int __fd, off_t __offset, int __whence); ssize_t pread(int __fd, void* __buf, size_t __count, off_t __offset) __overloadable __RENAME_CLANG(pread); ssize_t pwrite(int __fd, const void* __buf, size_t __count, off_t __offset) @@ -193,6 +188,7 @@ int ftruncate(int __fd, off_t __length); #endif int truncate64(const char* __path, off64_t __length) __INTRODUCED_IN(21); +off64_t lseek64(int __fd, off64_t __offset, int __whence); ssize_t pread64(int __fd, void* __buf, size_t __count, off64_t __offset) __INTRODUCED_IN(12) __overloadable __RENAME_CLANG(pread64); ssize_t pwrite64(int __fd, const void* __buf, size_t __count, off64_t __offset) |
