xref: /aosp_15_r20/bionic/docs/32-bit-abi.md (revision 8d67ca893c1523eb926b9080dbe4e2ffd2a27ba1)
1*8d67ca89SAndroid Build Coastguard Worker# 32-bit ABI bugs
2*8d67ca89SAndroid Build Coastguard Worker
3*8d67ca89SAndroid Build Coastguard Worker## 32-bit `off_t` and `_FILE_OFFSET_BITS=64`
4*8d67ca89SAndroid Build Coastguard Worker
5*8d67ca89SAndroid Build Coastguard WorkerOn 32-bit Android, `off_t` is a signed 32-bit integer. This limits functions
6*8d67ca89SAndroid Build Coastguard Workerthat use `off_t` to working on files no larger than 2GiB.
7*8d67ca89SAndroid Build Coastguard Worker
8*8d67ca89SAndroid Build Coastguard WorkerAndroid does not require the `_LARGEFILE_SOURCE` macro to be used to make
9*8d67ca89SAndroid Build Coastguard Worker`fseeko` and `ftello` available. Instead they're always available from API
10*8d67ca89SAndroid Build Coastguard Workerlevel 24 where they were introduced, and never available before then.
11*8d67ca89SAndroid Build Coastguard Worker
12*8d67ca89SAndroid Build Coastguard WorkerAndroid also does not require the `_LARGEFILE64_SOURCE` macro to be used
13*8d67ca89SAndroid Build Coastguard Workerto make `off64_t` and corresponding functions such as `ftruncate64` available.
14*8d67ca89SAndroid Build Coastguard WorkerInstead, whatever subset of those functions was available at your target API
15*8d67ca89SAndroid Build Coastguard Workerlevel will be visible.
16*8d67ca89SAndroid Build Coastguard Worker
17*8d67ca89SAndroid Build Coastguard WorkerThere are a couple of exceptions to note. Firstly, `off64_t` and the single
18*8d67ca89SAndroid Build Coastguard Workerfunction `lseek64` were available right from the beginning in API 3. Secondly,
19*8d67ca89SAndroid Build Coastguard WorkerAndroid has always silently inserted `O_LARGEFILE` into any open call, so if
20*8d67ca89SAndroid Build Coastguard Workerall you need are functions like `read` that don't take/return `off_t`, large
21*8d67ca89SAndroid Build Coastguard Workerfiles have always worked.
22*8d67ca89SAndroid Build Coastguard Worker
23*8d67ca89SAndroid Build Coastguard WorkerAndroid support for `_FILE_OFFSET_BITS=64` (which turns `off_t` into `off64_t`
24*8d67ca89SAndroid Build Coastguard Workerand replaces each `off_t` function with its `off64_t` counterpart, such as
25*8d67ca89SAndroid Build Coastguard Worker`lseek` in the source becoming `lseek64` at runtime) was added late. Even when
26*8d67ca89SAndroid Build Coastguard Workerit became available for the platform, it wasn't available from the NDK until
27*8d67ca89SAndroid Build Coastguard Workerr15. Before NDK r15, `_FILE_OFFSET_BITS=64` silently did nothing: all code
28*8d67ca89SAndroid Build Coastguard Workercompiled with that was actually using a 32-bit `off_t`. With a new enough NDK,
29*8d67ca89SAndroid Build Coastguard Workerthe situation becomes complicated. If you're targeting an API before 21, almost
30*8d67ca89SAndroid Build Coastguard Workerall functions that take an `off_t` become unavailable. You've asked for their
31*8d67ca89SAndroid Build Coastguard Worker64-bit equivalents, and none of them (except `lseek`/`lseek64`) exist. As you
32*8d67ca89SAndroid Build Coastguard Workerincrease your target API level, you'll have more and more of the functions
33*8d67ca89SAndroid Build Coastguard Workeravailable. API 12 adds some of the `<unistd.h>` functions, API 21 adds `mmap`,
34*8d67ca89SAndroid Build Coastguard Workerand by API 24 you have everything including `<stdio.h>`. See the
35*8d67ca89SAndroid Build Coastguard Worker[linker map](libc/libc.map.txt) for full details. Note also that in NDK r16 and
36*8d67ca89SAndroid Build Coastguard Workerlater, if you're using Clang we'll inline an `mmap64` implementation in the
37*8d67ca89SAndroid Build Coastguard Workerheaders when you target an API before 21 because it's an easy special case
38*8d67ca89SAndroid Build Coastguard Workerthat's often needed. This means that code using `_FILE_OFFSET_BITS=64`
39*8d67ca89SAndroid Build Coastguard Workerand `mmap` (but no other functions that are unavailable at your target
40*8d67ca89SAndroid Build Coastguard WorkerAPI level) will always compile.
41*8d67ca89SAndroid Build Coastguard Worker
42*8d67ca89SAndroid Build Coastguard WorkerIf your code stops compiling when you move to NDK r15 or later, removing every
43*8d67ca89SAndroid Build Coastguard Workerdefinition of `_FILE_OFFSET_BITS=64` will restore the behavior you used to have:
44*8d67ca89SAndroid Build Coastguard Workeryou'll have a 32-bit `off_t` and use the 32-bit functions. Make sure you
45*8d67ca89SAndroid Build Coastguard Workergrep thoroughly in both your source and your build system: many people
46*8d67ca89SAndroid Build Coastguard Workeraren't aware that `_FILE_OFFSET_BITS` is set. You might also have to
47*8d67ca89SAndroid Build Coastguard Workerremove references to `__USE_FILE_OFFSET64` --- this is the internal
48*8d67ca89SAndroid Build Coastguard Workerflag that should never be set by user code but sometimes is (by zlib,
49*8d67ca89SAndroid Build Coastguard Workerfor example). If you think you have removed these but your code still
50*8d67ca89SAndroid Build Coastguard Workerdoesn't compile, you can insert this just before the line that's failing
51*8d67ca89SAndroid Build Coastguard Workerto double check:
52*8d67ca89SAndroid Build Coastguard Worker```
53*8d67ca89SAndroid Build Coastguard Worker#if _FILE_OFFSET_BITS == 64
54*8d67ca89SAndroid Build Coastguard Worker#error "oops, file _FILE_OFFSET_BITS == 64"
55*8d67ca89SAndroid Build Coastguard Worker#elif defined(__USE_FILE_OFFSET64)
56*8d67ca89SAndroid Build Coastguard Worker#error "oops, __USE_FILE_OFFSET64 is defined"
57*8d67ca89SAndroid Build Coastguard Worker#endif
58*8d67ca89SAndroid Build Coastguard Worker```
59*8d67ca89SAndroid Build Coastguard Worker
60*8d67ca89SAndroid Build Coastguard WorkerIn the 64-bit ABI, `off_t` is always 64-bit.
61*8d67ca89SAndroid Build Coastguard Worker
62*8d67ca89SAndroid Build Coastguard WorkerFor source compatibility, the names containing `64` are also available
63*8d67ca89SAndroid Build Coastguard Workerin the 64-bit ABI even though they're identical to the non-`64` names.
64*8d67ca89SAndroid Build Coastguard Worker
65*8d67ca89SAndroid Build Coastguard Worker
66*8d67ca89SAndroid Build Coastguard Worker## `sigset_t` is too small for real-time signals
67*8d67ca89SAndroid Build Coastguard Worker
68*8d67ca89SAndroid Build Coastguard WorkerOn 32-bit Android, `sigset_t` is too small for ARM and x86. This means that
69*8d67ca89SAndroid Build Coastguard Workerthere is no support for real-time signals in 32-bit code. Android P (API
70*8d67ca89SAndroid Build Coastguard Workerlevel 28) adds `sigset64_t` and a corresponding function for every function
71*8d67ca89SAndroid Build Coastguard Workerthat takes a `sigset_t` (so `sigprocmask64` takes a `sigset64_t` where
72*8d67ca89SAndroid Build Coastguard Worker`sigprocmask` takes a `sigset_t`).
73*8d67ca89SAndroid Build Coastguard Worker
74*8d67ca89SAndroid Build Coastguard WorkerOn 32-bit Android, `struct sigaction` is also too small because it contains
75*8d67ca89SAndroid Build Coastguard Workera `sigset_t`. We also offer a `struct sigaction64` and `sigaction64` function
76*8d67ca89SAndroid Build Coastguard Workerto work around this.
77*8d67ca89SAndroid Build Coastguard Worker
78*8d67ca89SAndroid Build Coastguard WorkerIn the 64-bit ABI, `sigset_t` is the correct size for every architecture.
79*8d67ca89SAndroid Build Coastguard Worker
80*8d67ca89SAndroid Build Coastguard WorkerFor source compatibility, the names containing `64` are also available
81*8d67ca89SAndroid Build Coastguard Workerin the 64-bit ABI even though they're identical to the non-`64` names.
82*8d67ca89SAndroid Build Coastguard Worker
83*8d67ca89SAndroid Build Coastguard Worker
84*8d67ca89SAndroid Build Coastguard Worker## `time_t` is 32-bit on LP32 (y2038)
85*8d67ca89SAndroid Build Coastguard Worker
86*8d67ca89SAndroid Build Coastguard WorkerOn 32-bit Android, `time_t` is 32-bit, which will overflow in 2038.
87*8d67ca89SAndroid Build Coastguard Worker
88*8d67ca89SAndroid Build Coastguard WorkerIn the 64-bit ABI, `time_t` is 64-bit, which will not overflow until
89*8d67ca89SAndroid Build Coastguard Workerlong after the death of the star around which we currently circle.
90*8d67ca89SAndroid Build Coastguard Worker
91*8d67ca89SAndroid Build Coastguard WorkerThe header `<time64.h>` and type `time64_t` exist as a workaround,
92*8d67ca89SAndroid Build Coastguard Workerbut the kernel interfaces exposed on 32-bit Android all use the 32-bit
93*8d67ca89SAndroid Build Coastguard Worker`time_t` and `struct timespec`/`struct timeval`. Linux 5.x kernels
94*8d67ca89SAndroid Build Coastguard Workerdo offer extra interfaces so that 32-bit processes can pass 64-bit
95*8d67ca89SAndroid Build Coastguard Workertimes to/from the kernel, but we do not plan on adding support for
96*8d67ca89SAndroid Build Coastguard Workerthese to the C library. Convenient use of the new calls would require
97*8d67ca89SAndroid Build Coastguard Workeran equivalent to `_FILE_OFFSET_BITS=64`, which we wouldn't be able
98*8d67ca89SAndroid Build Coastguard Workerto globally flip for reasons similar to `_FILE_OFFSET_BITS`, mentioned
99*8d67ca89SAndroid Build Coastguard Workerabove. All apps are already required to offer 64-bit variants, and we
100*8d67ca89SAndroid Build Coastguard Workerexpect 64-bit-only devices within the next few years.
101*8d67ca89SAndroid Build Coastguard Worker
102*8d67ca89SAndroid Build Coastguard Worker
103*8d67ca89SAndroid Build Coastguard Worker## `pthread_mutex_t` is too small for large pids
104*8d67ca89SAndroid Build Coastguard Worker
105*8d67ca89SAndroid Build Coastguard WorkerThis doesn't generally affect Android devices, because on devices
106*8d67ca89SAndroid Build Coastguard Worker`/proc/sys/kernel/pid_max` is usually too small to hit our 16-bit limit,
107*8d67ca89SAndroid Build Coastguard Workerbut 32-bit bionic's `pthread_mutex` is a total of 32 bits, leaving just
108*8d67ca89SAndroid Build Coastguard Worker16 bits for the owner thread id. This means bionic isn't able to support
109*8d67ca89SAndroid Build Coastguard Workermutexes for tids that don't fit in 16 bits. This typically manifests as
110*8d67ca89SAndroid Build Coastguard Workera hang in `pthread_mutex_lock` if the libc startup code doesn't detect
111*8d67ca89SAndroid Build Coastguard Workerthis condition and abort.
112*8d67ca89SAndroid Build Coastguard Worker
113*8d67ca89SAndroid Build Coastguard Worker
114*8d67ca89SAndroid Build Coastguard Worker## `getuid()` and friends wrongly set errno for very large results
115*8d67ca89SAndroid Build Coastguard Worker
116*8d67ca89SAndroid Build Coastguard WorkerThis doesn't generally affect Android devices, because we don't have any
117*8d67ca89SAndroid Build Coastguard Workeruids/gids/pids large enough, but 32-bit Android doesn't take into account
118*8d67ca89SAndroid Build Coastguard Workerthat functions like getuid() potentially have return values that cover the
119*8d67ca89SAndroid Build Coastguard Workerentire 32-bit, and can't fail. This means that the usual "if the result is
120*8d67ca89SAndroid Build Coastguard Workerbetween -1 and -4096, set errno and return -1" code is inappropriate for
121*8d67ca89SAndroid Build Coastguard Workerthese functions. Since LP32 is unlikely to be still supported long before
122*8d67ca89SAndroid Build Coastguard Workerthose limits could ever matter, although -- unlike the others in this
123*8d67ca89SAndroid Build Coastguard Workerdocument -- this defect is actually fixable, it doesn't seem worth fixing.
124