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