blob: 607b5d2efa4c5e98baf820d44a49d77a88c45df3 [file] [log] [blame] [view]
Elliott Hughesa3481742017-11-28 14:47:17 -08001# 32-bit ABI bugs
Elliott Hughes0bfcbaf2017-08-28 09:18:34 -07002
Elliott Hughesa3481742017-11-28 14:47:17 -08003## 32-bit `off_t` and `_FILE_OFFSET_BITS=64`
Elliott Hughes0bfcbaf2017-08-28 09:18:34 -07004
5On 32-bit Android, `off_t` is a signed 32-bit integer. This limits functions
6that use `off_t` to working on files no larger than 2GiB.
7
8Android does not require the `_LARGEFILE_SOURCE` macro to be used to make
9`fseeko` and `ftello` available. Instead they're always available from API
10level 24 where they were introduced, and never available before then.
11
12Android also does not require the `_LARGEFILE64_SOURCE` macro to be used
13to make `off64_t` and corresponding functions such as `ftruncate64` available.
14Instead, whatever subset of those functions was available at your target API
15level will be visible.
16
17There are a couple of exceptions to note. Firstly, `off64_t` and the single
18function `lseek64` were available right from the beginning in API 3. Secondly,
19Android has always silently inserted `O_LARGEFILE` into any open call, so if
20all you need are functions like `read` that don't take/return `off_t`, large
21files have always worked.
22
23Android support for `_FILE_OFFSET_BITS=64` (which turns `off_t` into `off64_t`
24and replaces each `off_t` function with its `off64_t` counterpart, such as
25`lseek` in the source becoming `lseek64` at runtime) was added late. Even when
26it became available for the platform, it wasn't available from the NDK until
27r15. Before NDK r15, `_FILE_OFFSET_BITS=64` silently did nothing: all code
28compiled with that was actually using a 32-bit `off_t`. With a new enough NDK,
29the situation becomes complicated. If you're targeting an API before 21, almost
30all functions that take an `off_t` become unavailable. You've asked for their
3164-bit equivalents, and none of them (except `lseek`/`lseek64`) exist. As you
32increase your target API level, you'll have more and more of the functions
33available. API 12 adds some of the `<unistd.h>` functions, API 21 adds `mmap`,
34and by API 24 you have everything including `<stdio.h>`. See the
Elliott Hughesa3481742017-11-28 14:47:17 -080035[linker map](libc/libc.map.txt) for full details. Note also that in NDK r16 and
36later, we inline an mmap64 implementation in the headers when you target an API
37before 21 because it's an easy special case that's often needed. This means
38that code using `_FILE_OFFSET_BITS=64` and `mmap` will always compile.
39
40If your code stops compiling when you move to NDK r15 or later, removing any
41definition of `_FILE_OFFSET_BITS=64` will restore the behavior you used to have:
42you'll have a 32-bit `off_t` and use the 32-bit functions.
Elliott Hughes0bfcbaf2017-08-28 09:18:34 -070043
44In the 64-bit ABI, `off_t` is always 64-bit.
45
46
Elliott Hughesa3481742017-11-28 14:47:17 -080047## `sigset_t` is too small for real-time signals
Elliott Hughes0bfcbaf2017-08-28 09:18:34 -070048
49On 32-bit Android, `sigset_t` is too small for ARM and x86 (but correct for
50MIPS). This means that there is no support for real-time signals in 32-bit
51code.
52
53In the 64-bit ABI, `sigset_t` is the correct size for every architecture.
54
55
Elliott Hughesa3481742017-11-28 14:47:17 -080056## `time_t` is 32-bit
Elliott Hughes0bfcbaf2017-08-28 09:18:34 -070057
58On 32-bit Android, `time_t` is 32-bit. The header `<time64.h>` and type
59`time64_t` exist as a workaround, but the kernel interfaces exposed on 32-bit
60Android all use the 32-bit `time_t`.
61
62In the 64-bit ABI, `time_t` is 64-bit.
Elliott Hughes1d01fe82017-10-23 10:07:55 -070063
Elliott Hughesa3481742017-11-28 14:47:17 -080064## `pthread_mutex_t` is too small for large pids
Elliott Hughes1d01fe82017-10-23 10:07:55 -070065
66This doesn't generally affect Android devices, because on devices
67`/proc/sys/kernel/pid_max` is usually too small to hit the 16-bit limit,
68but 32-bit bionic's `pthread_mutex` is a total of 32 bits, leaving just
6916 bits for the owner thread id. This means bionic isn't able to support
70mutexes for tids that don't fit in 16 bits. This typically manifests as
71a hang in `pthread_mutex_lock` if the libc startup code doesn't detect
72this condition and abort.