xref: /aosp_15_r20/bionic/android-changes-for-ndk-developers.md (revision 8d67ca893c1523eb926b9080dbe4e2ffd2a27ba1)
1*8d67ca89SAndroid Build Coastguard Worker# Android linker changes for NDK developers
2*8d67ca89SAndroid Build Coastguard Worker
3*8d67ca89SAndroid Build Coastguard WorkerThis document details important changes related to native code
4*8d67ca89SAndroid Build Coastguard Workerloading in various Android releases.
5*8d67ca89SAndroid Build Coastguard Worker
6*8d67ca89SAndroid Build Coastguard WorkerSee also [bionic status](docs/status.md) for general libc/libm/libdl
7*8d67ca89SAndroid Build Coastguard Workerbehavior changes.
8*8d67ca89SAndroid Build Coastguard Worker
9*8d67ca89SAndroid Build Coastguard WorkerSee also the
10*8d67ca89SAndroid Build Coastguard Worker[unwinder documentation](https://android.googlesource.com/platform/system/unwinding/+/refs/heads/main/libunwindstack/AndroidVersions.md)
11*8d67ca89SAndroid Build Coastguard Workerfor details about changes in stack unwinding (crash dumps) between
12*8d67ca89SAndroid Build Coastguard Workerdifferent releases.
13*8d67ca89SAndroid Build Coastguard Worker
14*8d67ca89SAndroid Build Coastguard WorkerRequired tools: the NDK has an `llvm-readelf` binary that understands all the
15*8d67ca89SAndroid Build Coastguard Workerarchitecture-specific details of all Android's supported architectures. Recent
16*8d67ca89SAndroid Build Coastguard Workerversions of Android also have toybox readelf on the device.
17*8d67ca89SAndroid Build Coastguard Worker
18*8d67ca89SAndroid Build Coastguard Worker
19*8d67ca89SAndroid Build Coastguard Worker## How we manage incompatible changes
20*8d67ca89SAndroid Build Coastguard Worker
21*8d67ca89SAndroid Build Coastguard WorkerOur general practice with dynamic linker behavior changes is that they
22*8d67ca89SAndroid Build Coastguard Workerwill be tied to an app's target API level:
23*8d67ca89SAndroid Build Coastguard Worker
24*8d67ca89SAndroid Build Coastguard Worker* Below the affected API level we'll preserve the old behavior or issue
25*8d67ca89SAndroid Build Coastguard Workera warning, as appropriate.
26*8d67ca89SAndroid Build Coastguard Worker
27*8d67ca89SAndroid Build Coastguard Worker* At the affected API level and above, we’ll refuse to load the library.
28*8d67ca89SAndroid Build Coastguard Worker
29*8d67ca89SAndroid Build Coastguard Worker* Warnings about any behavior change that will affect a library if you
30*8d67ca89SAndroid Build Coastguard Workerincrease your target API level will appear in logcat when that library
31*8d67ca89SAndroid Build Coastguard Workeris loaded, even if you're not yet targeting that API level.
32*8d67ca89SAndroid Build Coastguard Worker
33*8d67ca89SAndroid Build Coastguard Worker* On a developer preview build, dynamic linker warnings will also show up
34*8d67ca89SAndroid Build Coastguard Workeras toasts. Experience has shown that many developers don’t habitually
35*8d67ca89SAndroid Build Coastguard Workercheck logcat for warnings until their app stops functioning, so the
36*8d67ca89SAndroid Build Coastguard Workertoasts help bring some visibility to the issues before it's too late.
37*8d67ca89SAndroid Build Coastguard Worker
38*8d67ca89SAndroid Build Coastguard Worker
39*8d67ca89SAndroid Build Coastguard Worker## Changes to library dependency resolution
40*8d67ca89SAndroid Build Coastguard Worker
41*8d67ca89SAndroid Build Coastguard WorkerUntil it was [fixed](https://issuetracker.google.com/36950617) in
42*8d67ca89SAndroid Build Coastguard WorkerAPI level 18, Android didn't include the application library directory
43*8d67ca89SAndroid Build Coastguard Workeron the dynamic linker's search path. This meant that apps
44*8d67ca89SAndroid Build Coastguard Workerhad to call `dlopen` or `System.loadLibrary` on all transitive
45*8d67ca89SAndroid Build Coastguard Workerdependencies before loading their main library. Worse, until it was
46*8d67ca89SAndroid Build Coastguard Worker[fixed](https://issuetracker.google.com/36935779) in API level 18, the
47*8d67ca89SAndroid Build Coastguard Workerdynamic linker's caching code cached failures too, so it was necessary
48*8d67ca89SAndroid Build Coastguard Workerto topologically sort your libraries and load them in reverse order.
49*8d67ca89SAndroid Build Coastguard Worker
50*8d67ca89SAndroid Build Coastguard WorkerIf you need to support Android devices running OS versions older than
51*8d67ca89SAndroid Build Coastguard WorkerAPI level 23, you might want to consider
52*8d67ca89SAndroid Build Coastguard Worker[ReLinker](https://github.com/KeepSafe/ReLinker) which claims to solve
53*8d67ca89SAndroid Build Coastguard Workerthese and other problems automatically.
54*8d67ca89SAndroid Build Coastguard Worker
55*8d67ca89SAndroid Build Coastguard WorkerAlternatively, if you don't have too many dependencies, it can be easiest to
56*8d67ca89SAndroid Build Coastguard Workersimply link all of your code into one big library and sidestep the details of
57*8d67ca89SAndroid Build Coastguard Workerlibrary and symbol lookup changes on all past (and future) Android versions.
58*8d67ca89SAndroid Build Coastguard Worker
59*8d67ca89SAndroid Build Coastguard Worker
60*8d67ca89SAndroid Build Coastguard Worker## Changes to library search order
61*8d67ca89SAndroid Build Coastguard Worker
62*8d67ca89SAndroid Build Coastguard WorkerWe have made various fixes to library search order when resolving symbols.
63*8d67ca89SAndroid Build Coastguard Worker
64*8d67ca89SAndroid Build Coastguard WorkerWith API level 22, load order switched from depth-first to breadth-first to
65*8d67ca89SAndroid Build Coastguard Workerfix dlsym(3).
66*8d67ca89SAndroid Build Coastguard Worker
67*8d67ca89SAndroid Build Coastguard WorkerBefore API level 23, the default search order was to try the main executable,
68*8d67ca89SAndroid Build Coastguard WorkerLD_PRELOAD libraries, the library itself, and its DT_NEEDED libraries
69*8d67ca89SAndroid Build Coastguard Workerin that order. For API level 23 and later, for any given library, the dynamic
70*8d67ca89SAndroid Build Coastguard Workerlinker divides other libraries into the global group and the local
71*8d67ca89SAndroid Build Coastguard Workergroup. The global group is shared by all libraries and contains the main
72*8d67ca89SAndroid Build Coastguard Workerexecutable, LD_PRELOAD libraries, and any library with the DF_1_GLOBAL
73*8d67ca89SAndroid Build Coastguard Workerflag set (by passing “-z global” to ld(1)). The local group is
74*8d67ca89SAndroid Build Coastguard Workerthe breadth-first transitive closure of the library and its DT_NEEDED
75*8d67ca89SAndroid Build Coastguard Workerlibraries. The API level 23 dynamic linker searches the global group followed by
76*8d67ca89SAndroid Build Coastguard Workerthe local group. This allows ASAN, for example, to ensure that it can
77*8d67ca89SAndroid Build Coastguard Workerintercept any symbol.
78*8d67ca89SAndroid Build Coastguard Worker
79*8d67ca89SAndroid Build Coastguard Worker
80*8d67ca89SAndroid Build Coastguard Worker## LD_PRELOAD and 32/64 bit
81*8d67ca89SAndroid Build Coastguard Worker
82*8d67ca89SAndroid Build Coastguard WorkerLD_PRELOAD applies to both 32- and 64-bit processes. This means that you
83*8d67ca89SAndroid Build Coastguard Workershould avoid saying something like `/system/lib/libfoo.so` and just say
84*8d67ca89SAndroid Build Coastguard Worker`libfoo.so` instead, letting the dynamic linker find the correct library
85*8d67ca89SAndroid Build Coastguard Workeron its search path.
86*8d67ca89SAndroid Build Coastguard Worker
87*8d67ca89SAndroid Build Coastguard Worker
88*8d67ca89SAndroid Build Coastguard Worker## RTLD_LOCAL (Available in API level >= 23)
89*8d67ca89SAndroid Build Coastguard Worker
90*8d67ca89SAndroid Build Coastguard WorkerThe dlopen(3) RTLD_LOCAL flag used to be ignored but is implemented
91*8d67ca89SAndroid Build Coastguard Workercorrectly in API level 23 and later. Note that RTLD_LOCAL is the default,
92*8d67ca89SAndroid Build Coastguard Workerso even calls to dlopen(3) that didn’t explicitly use RTLD_LOCAL will
93*8d67ca89SAndroid Build Coastguard Workerbe affected (unless they explicitly used RTLD_GLOBAL). With RTLD_LOCAL,
94*8d67ca89SAndroid Build Coastguard Workersymbols will not be made available to libraries loaded by later calls
95*8d67ca89SAndroid Build Coastguard Workerto dlopen(3) (as opposed to being referenced by DT_NEEDED entries).
96*8d67ca89SAndroid Build Coastguard Worker
97*8d67ca89SAndroid Build Coastguard Worker
98*8d67ca89SAndroid Build Coastguard Worker## GNU hashes (Availible in API level >= 23)
99*8d67ca89SAndroid Build Coastguard Worker
100*8d67ca89SAndroid Build Coastguard WorkerThe GNU hash style available with `--hash-style=gnu` allows faster
101*8d67ca89SAndroid Build Coastguard Workersymbol lookup and is supported by Android's dynamic linker in API level 23 and
102*8d67ca89SAndroid Build Coastguard Workerabove. Use `--hash-style=both` if you want to build code that uses this
103*8d67ca89SAndroid Build Coastguard Workerfeature in new enough releases but still works on older releases.
104*8d67ca89SAndroid Build Coastguard WorkerIf you're using the NDK, clang chooses the right option
105*8d67ca89SAndroid Build Coastguard Worker(automatically)[https://github.com/android/ndk/issues/2005].
106*8d67ca89SAndroid Build Coastguard Worker
107*8d67ca89SAndroid Build Coastguard Worker
108*8d67ca89SAndroid Build Coastguard Worker## Correct soname/path handling (Available in API level >= 23)
109*8d67ca89SAndroid Build Coastguard Worker
110*8d67ca89SAndroid Build Coastguard WorkerThe dynamic linker now understands the difference
111*8d67ca89SAndroid Build Coastguard Workerbetween a library’s soname and its path (public bug
112*8d67ca89SAndroid Build Coastguard Workerhttps://code.google.com/p/android/issues/detail?id=6670). API level 23
113*8d67ca89SAndroid Build Coastguard Workeris the first release where search by soname is implemented. Earlier
114*8d67ca89SAndroid Build Coastguard Workerreleases would assume that the basename of the library was the soname,
115*8d67ca89SAndroid Build Coastguard Workerand used that to search for already-loaded libraries. For example,
116*8d67ca89SAndroid Build Coastguard Worker`dlopen("/this/directory/does/not/exist/libc.so", RTLD_NOW)` would
117*8d67ca89SAndroid Build Coastguard Workerfind `/system/lib/libc.so` because it’s already loaded. This also meant
118*8d67ca89SAndroid Build Coastguard Workerthat it was impossible to have two libraries `"dir1/libx.so"` and
119*8d67ca89SAndroid Build Coastguard Worker`"dir2/libx.so"` --- the dynamic linker couldn’t tell the difference
120*8d67ca89SAndroid Build Coastguard Workerand would always use whichever was loaded first, even if you explicitly
121*8d67ca89SAndroid Build Coastguard Workertried to load both. This also applied to DT_NEEDED entries.
122*8d67ca89SAndroid Build Coastguard Worker
123*8d67ca89SAndroid Build Coastguard WorkerSome apps have bad DT_NEEDED entries (usually absolute paths on the build
124*8d67ca89SAndroid Build Coastguard Workermachine’s file system) that used to work because we ignored everything
125*8d67ca89SAndroid Build Coastguard Workerbut the basename. These apps will fail to load on API level 23 and above.
126*8d67ca89SAndroid Build Coastguard Worker
127*8d67ca89SAndroid Build Coastguard Worker
128*8d67ca89SAndroid Build Coastguard Worker## Symbol versioning (Available in API level >= 23)
129*8d67ca89SAndroid Build Coastguard Worker
130*8d67ca89SAndroid Build Coastguard WorkerSymbol versioning allows libraries to provide better backwards
131*8d67ca89SAndroid Build Coastguard Workercompatibility. For example, if a library author knowingly changes
132*8d67ca89SAndroid Build Coastguard Workerthe behavior of a function, they can provide two versions in the same
133*8d67ca89SAndroid Build Coastguard Workerlibrary so that old code gets the old version and new code gets the new
134*8d67ca89SAndroid Build Coastguard Workerversion. This is supported in API level 23 and above.
135*8d67ca89SAndroid Build Coastguard Worker
136*8d67ca89SAndroid Build Coastguard Worker
137*8d67ca89SAndroid Build Coastguard Worker## Opening shared libraries directly from an APK
138*8d67ca89SAndroid Build Coastguard Worker
139*8d67ca89SAndroid Build Coastguard WorkerIn API level 23 and above, it’s possible to open a .so file directly from
140*8d67ca89SAndroid Build Coastguard Workeryour APK. Just use `System.loadLibrary("foo")` exactly as normal but set
141*8d67ca89SAndroid Build Coastguard Worker`android:extractNativeLibs="false"` in your `AndroidManifest.xml`. In
142*8d67ca89SAndroid Build Coastguard Workerolder releases, the .so files were extracted from the APK file
143*8d67ca89SAndroid Build Coastguard Workerat install time. This meant that they took up space in your APK and
144*8d67ca89SAndroid Build Coastguard Workeragain in your installation directory (and this was counted against you
145*8d67ca89SAndroid Build Coastguard Workerand reported to the user as space taken up by your app). Any .so file
146*8d67ca89SAndroid Build Coastguard Workerthat you want to load directly from your APK must be page aligned
147*8d67ca89SAndroid Build Coastguard Worker(on a 4096-byte boundary) in the zip file and stored uncompressed.
148*8d67ca89SAndroid Build Coastguard WorkerCurrent versions of the zipalign tool take care of alignment.
149*8d67ca89SAndroid Build Coastguard Worker
150*8d67ca89SAndroid Build Coastguard WorkerNote that in API level 23 and above dlopen(3) can open a library from
151*8d67ca89SAndroid Build Coastguard Workerany zip file, not just an APK. Just give dlopen(3) a path of the form
152*8d67ca89SAndroid Build Coastguard Worker"my_zip_file.zip!/libs/libstuff.so". As with APKs, the library must be
153*8d67ca89SAndroid Build Coastguard Workerpage-aligned and stored uncompressed for this to work.
154*8d67ca89SAndroid Build Coastguard Worker
155*8d67ca89SAndroid Build Coastguard Worker
156*8d67ca89SAndroid Build Coastguard Worker## Private API (Enforced for API level >= 24)
157*8d67ca89SAndroid Build Coastguard Worker
158*8d67ca89SAndroid Build Coastguard WorkerNative libraries must use only public API, and must not link against
159*8d67ca89SAndroid Build Coastguard Workernon-NDK platform libraries. On devices running API level 24 or later,
160*8d67ca89SAndroid Build Coastguard Workerthis rule is enforced and applications are no longer able to load all
161*8d67ca89SAndroid Build Coastguard Workernon-NDK platform libraries. This was to prevent future issues similar
162*8d67ca89SAndroid Build Coastguard Workerto the disruption caused when Android switched from OpenSSL to BoringSSL
163*8d67ca89SAndroid Build Coastguard Workerat API level 23.
164*8d67ca89SAndroid Build Coastguard Worker
165*8d67ca89SAndroid Build Coastguard WorkerThe rule is enforced by the dynamic linker, so non-public libraries
166*8d67ca89SAndroid Build Coastguard Workerare not accessible regardless of the way code tries to load them:
167*8d67ca89SAndroid Build Coastguard WorkerSystem.loadLibrary(), DT_NEEDED entries, and direct calls to dlopen(3)
168*8d67ca89SAndroid Build Coastguard Workerwill all work exactly the same.
169*8d67ca89SAndroid Build Coastguard Worker
170*8d67ca89SAndroid Build Coastguard WorkerIn order to reduce the user impact of this transition, we identified
171*8d67ca89SAndroid Build Coastguard Workera set of libraries that saw significant use from Google Play's
172*8d67ca89SAndroid Build Coastguard Workermost-installed apps and were feasible for us to support in the
173*8d67ca89SAndroid Build Coastguard Workershort term (including libandroid_runtime.so, libcutils.so, libcrypto.so,
174*8d67ca89SAndroid Build Coastguard Workerand libssl.so). In order to give app developers more time to transition,
175*8d67ca89SAndroid Build Coastguard Workerwe allowed access to these libraries for apps with a target API level < 24.
176*8d67ca89SAndroid Build Coastguard WorkerOn devices running API level 26 to API level 30, this compatibility mode could be
177*8d67ca89SAndroid Build Coastguard Workerdisabled by setting a system property (`debug.ld.greylist_disabled`).
178*8d67ca89SAndroid Build Coastguard WorkerThis property is ignored on devices running API level 31 and later.
179*8d67ca89SAndroid Build Coastguard Worker
180*8d67ca89SAndroid Build Coastguard Worker```
181*8d67ca89SAndroid Build Coastguard Worker$ readelf --dynamic libBroken.so | grep NEEDED
182*8d67ca89SAndroid Build Coastguard Worker 0x00000001 (NEEDED)                     Shared library: [libnativehelper.so]
183*8d67ca89SAndroid Build Coastguard Worker 0x00000001 (NEEDED)                     Shared library: [libutils.so]
184*8d67ca89SAndroid Build Coastguard Worker 0x00000001 (NEEDED)                     Shared library: [libstagefright_foundation.so]
185*8d67ca89SAndroid Build Coastguard Worker 0x00000001 (NEEDED)                     Shared library: [libmedia_jni.so]
186*8d67ca89SAndroid Build Coastguard Worker 0x00000001 (NEEDED)                     Shared library: [liblog.so]
187*8d67ca89SAndroid Build Coastguard Worker 0x00000001 (NEEDED)                     Shared library: [libdl.so]
188*8d67ca89SAndroid Build Coastguard Worker 0x00000001 (NEEDED)                     Shared library: [libz.so]
189*8d67ca89SAndroid Build Coastguard Worker 0x00000001 (NEEDED)                     Shared library: [libstdc++.so]
190*8d67ca89SAndroid Build Coastguard Worker 0x00000001 (NEEDED)                     Shared library: [libm.so]
191*8d67ca89SAndroid Build Coastguard Worker 0x00000001 (NEEDED)                     Shared library: [libc.so]
192*8d67ca89SAndroid Build Coastguard Worker```
193*8d67ca89SAndroid Build Coastguard Worker
194*8d67ca89SAndroid Build Coastguard Worker*Potential problems*: starting from API level 24 the dynamic linker will not
195*8d67ca89SAndroid Build Coastguard Workerload private libraries, preventing the application from loading.
196*8d67ca89SAndroid Build Coastguard Worker
197*8d67ca89SAndroid Build Coastguard Worker*Resolution*: rewrite your native code to rely only on public API. As a
198*8d67ca89SAndroid Build Coastguard Workershort term workaround, platform libraries without complex dependencies
199*8d67ca89SAndroid Build Coastguard Worker(libcutils.so) can be copied to the project. As a long term solution
200*8d67ca89SAndroid Build Coastguard Workerthe relevant code must be copied to the project tree. SSL/Media/JNI
201*8d67ca89SAndroid Build Coastguard Workerinternal/binder APIs should not be accessed from the native code. When
202*8d67ca89SAndroid Build Coastguard Workernecessary, native code should call appropriate public Java API methods.
203*8d67ca89SAndroid Build Coastguard Worker
204*8d67ca89SAndroid Build Coastguard WorkerA complete list of public libraries is available within the NDK, under
205*8d67ca89SAndroid Build Coastguard Workerplatforms/android-API/usr/lib.
206*8d67ca89SAndroid Build Coastguard Worker
207*8d67ca89SAndroid Build Coastguard WorkerNote: SSL/crypto is a special case, applications must NOT use platform
208*8d67ca89SAndroid Build Coastguard Workerlibcrypto and libssl libraries directly, even on older platforms. All
209*8d67ca89SAndroid Build Coastguard Workerapplications should use GMS Security Provider to ensure they are protected
210*8d67ca89SAndroid Build Coastguard Workerfrom known vulnerabilities.
211*8d67ca89SAndroid Build Coastguard Worker
212*8d67ca89SAndroid Build Coastguard Worker
213*8d67ca89SAndroid Build Coastguard Worker## Missing Section Headers (Enforced for API level >= 24)
214*8d67ca89SAndroid Build Coastguard Worker
215*8d67ca89SAndroid Build Coastguard WorkerEach ELF file has additional information contained in the section
216*8d67ca89SAndroid Build Coastguard Workerheaders. These headers must be present now, because the dynamic linker
217*8d67ca89SAndroid Build Coastguard Workeruses them for validity checking. Some developers strip them in an
218*8d67ca89SAndroid Build Coastguard Workerattempt to obfuscate the binary and prevent reverse engineering. (This
219*8d67ca89SAndroid Build Coastguard Workerdoesn't really help because it is possible to reconstruct the stripped
220*8d67ca89SAndroid Build Coastguard Workerinformation using widely-available tools.)
221*8d67ca89SAndroid Build Coastguard Worker
222*8d67ca89SAndroid Build Coastguard Worker```
223*8d67ca89SAndroid Build Coastguard Worker$ readelf --headers libBroken.so | grep 'section headers'
224*8d67ca89SAndroid Build Coastguard Worker  Start of section headers:          0 (bytes into file)
225*8d67ca89SAndroid Build Coastguard Worker  Size of section headers:           0 (bytes)
226*8d67ca89SAndroid Build Coastguard Worker  Number of section headers:         0
227*8d67ca89SAndroid Build Coastguard Worker```
228*8d67ca89SAndroid Build Coastguard Worker
229*8d67ca89SAndroid Build Coastguard Worker*Resolution*: remove the extra steps from your build that strip section
230*8d67ca89SAndroid Build Coastguard Workerheaders.
231*8d67ca89SAndroid Build Coastguard Worker
232*8d67ca89SAndroid Build Coastguard Worker
233*8d67ca89SAndroid Build Coastguard Worker## Text Relocations (Enforced for API level >= 23)
234*8d67ca89SAndroid Build Coastguard Worker
235*8d67ca89SAndroid Build Coastguard WorkerApps with a target API level >= 23 cannot load shared objects that contain text
236*8d67ca89SAndroid Build Coastguard Workerrelocations. Such an approach reduces load time and improves security. This was
237*8d67ca89SAndroid Build Coastguard Workeronly a change for 32-bit, because 64-bit never supported text relocations.
238*8d67ca89SAndroid Build Coastguard Worker
239*8d67ca89SAndroid Build Coastguard WorkerThe usual reason for text relocations was non-position independent
240*8d67ca89SAndroid Build Coastguard Workerhand-written assembler. This is not common. You can use the scanelf tool
241*8d67ca89SAndroid Build Coastguard Workerfrom the pax-utils debian package for further diagnostics:
242*8d67ca89SAndroid Build Coastguard Worker
243*8d67ca89SAndroid Build Coastguard Worker```
244*8d67ca89SAndroid Build Coastguard Worker$ scanelf -qT libTextRel.so
245*8d67ca89SAndroid Build Coastguard Worker  libTextRel.so: (memory/data?) [0x15E0E2] in (optimized out: previous simd_broken_op1) [0x15E0E0]
246*8d67ca89SAndroid Build Coastguard Worker  libTextRel.so: (memory/data?) [0x15E3B2] in (optimized out: previous simd_broken_op2) [0x15E3B0]
247*8d67ca89SAndroid Build Coastguard Worker  ...
248*8d67ca89SAndroid Build Coastguard Worker```
249*8d67ca89SAndroid Build Coastguard Worker
250*8d67ca89SAndroid Build Coastguard WorkerIf you have no scanelf tool available, it is possible to do a basic
251*8d67ca89SAndroid Build Coastguard Workercheck with readelf instead. Look for either a TEXTREL entry or the
252*8d67ca89SAndroid Build Coastguard WorkerTEXTREL flag. Either alone is sufficient. (The value corresponding to the
253*8d67ca89SAndroid Build Coastguard WorkerTEXTREL entry is irrelevant and typically 0 --- simply the presence of
254*8d67ca89SAndroid Build Coastguard Workerthe TEXTREL entry declares that the .so contains text relocations.) This
255*8d67ca89SAndroid Build Coastguard Workerexample has both indicators present:
256*8d67ca89SAndroid Build Coastguard Worker
257*8d67ca89SAndroid Build Coastguard Worker```
258*8d67ca89SAndroid Build Coastguard Worker$ readelf --dynamic libTextRel.so | grep TEXTREL
259*8d67ca89SAndroid Build Coastguard Worker 0x00000016 (TEXTREL)                    0x0
260*8d67ca89SAndroid Build Coastguard Worker 0x0000001e (FLAGS)                      SYMBOLIC TEXTREL BIND_NOW
261*8d67ca89SAndroid Build Coastguard Worker```
262*8d67ca89SAndroid Build Coastguard Worker
263*8d67ca89SAndroid Build Coastguard WorkerNote: it is technically possible to have a shared object with the TEXTREL
264*8d67ca89SAndroid Build Coastguard Workerentry/flag but without any actual text relocations. This doesn't happen
265*8d67ca89SAndroid Build Coastguard Workerwith the NDK, but if you're generating ELF files yourself make sure
266*8d67ca89SAndroid Build Coastguard Workeryou're not generating ELF files that claim to have text relocations,
267*8d67ca89SAndroid Build Coastguard Workerbecause the Android dynamic linker trusts the entry/flag.
268*8d67ca89SAndroid Build Coastguard Worker
269*8d67ca89SAndroid Build Coastguard Worker*Potential problems*: Relocations enforce code pages being writable, and
270*8d67ca89SAndroid Build Coastguard Workerwastefully increase the number of dirty pages in memory. The dynamic
271*8d67ca89SAndroid Build Coastguard Workerlinker issued warnings about text relocations from API level 19, but on API
272*8d67ca89SAndroid Build Coastguard Workerlevel 23 and above refuses to load code with text relocations.
273*8d67ca89SAndroid Build Coastguard Worker
274*8d67ca89SAndroid Build Coastguard Worker*Resolution*: rewrite assembler to be position independent to ensure
275*8d67ca89SAndroid Build Coastguard Workerno text relocations are necessary. The
276*8d67ca89SAndroid Build Coastguard Worker[Gentoo Textrels guide](https://wiki.gentoo.org/wiki/Hardened/Textrels_Guide)
277*8d67ca89SAndroid Build Coastguard Workerhas instructions for fixing text relocations, and more detailed
278*8d67ca89SAndroid Build Coastguard Worker[scanelf documentation](https://wiki.gentoo.org/wiki/Hardened/PaX_Utilities).
279*8d67ca89SAndroid Build Coastguard Worker
280*8d67ca89SAndroid Build Coastguard Worker
281*8d67ca89SAndroid Build Coastguard Worker## Invalid DT_NEEDED Entries (Enforced for API level >= 23)
282*8d67ca89SAndroid Build Coastguard Worker
283*8d67ca89SAndroid Build Coastguard WorkerWhile library dependencies (DT_NEEDED entries in the ELF headers) can be
284*8d67ca89SAndroid Build Coastguard Workerabsolute paths, that doesn't make sense on Android because you have
285*8d67ca89SAndroid Build Coastguard Workerno control over where your library will be installed by the system. A
286*8d67ca89SAndroid Build Coastguard WorkerDT_NEEDED entry should be the same as the needed library's SONAME,
287*8d67ca89SAndroid Build Coastguard Workerleaving the business of finding the library at runtime to the dynamic
288*8d67ca89SAndroid Build Coastguard Workerlinker.
289*8d67ca89SAndroid Build Coastguard Worker
290*8d67ca89SAndroid Build Coastguard WorkerBefore API level 23, Android's dynamic linker ignored the full path, and
291*8d67ca89SAndroid Build Coastguard Workerused only the basename (the part after the last ‘/') when looking
292*8d67ca89SAndroid Build Coastguard Workerup the required libraries. Since API level 23 the runtime linker will honor
293*8d67ca89SAndroid Build Coastguard Workerthe DT_NEEDED exactly and so it won't be able to load the library if
294*8d67ca89SAndroid Build Coastguard Workerit is not present in that exact location on the device.
295*8d67ca89SAndroid Build Coastguard Worker
296*8d67ca89SAndroid Build Coastguard WorkerEven worse, some build systems have bugs that cause them to insert
297*8d67ca89SAndroid Build Coastguard WorkerDT_NEEDED entries that point to a file on the build host, something that
298*8d67ca89SAndroid Build Coastguard Workercannot be found on the device.
299*8d67ca89SAndroid Build Coastguard Worker
300*8d67ca89SAndroid Build Coastguard Worker```
301*8d67ca89SAndroid Build Coastguard Worker$ readelf --dynamic libSample.so | grep NEEDED
302*8d67ca89SAndroid Build Coastguard Worker 0x00000001 (NEEDED)                     Shared library: [libm.so]
303*8d67ca89SAndroid Build Coastguard Worker 0x00000001 (NEEDED)                     Shared library: [libc.so]
304*8d67ca89SAndroid Build Coastguard Worker 0x00000001 (NEEDED)                     Shared library: [libdl.so]
305*8d67ca89SAndroid Build Coastguard Worker 0x00000001 (NEEDED)                     Shared library:
306*8d67ca89SAndroid Build Coastguard Worker[C:\Users\build\Android\ci\jni\libBroken.so]
307*8d67ca89SAndroid Build Coastguard Worker```
308*8d67ca89SAndroid Build Coastguard Worker
309*8d67ca89SAndroid Build Coastguard Worker*Potential problems*: before API level 23 the DT_NEEDED entry's basename was
310*8d67ca89SAndroid Build Coastguard Workerused, but starting from API level 23 the Android runtime will try to load the
311*8d67ca89SAndroid Build Coastguard Workerlibrary using the path specified, and that path won't exist on the
312*8d67ca89SAndroid Build Coastguard Workerdevice. There are broken third-party toolchains/build systems that use
313*8d67ca89SAndroid Build Coastguard Workera path on a build host instead of the SONAME.
314*8d67ca89SAndroid Build Coastguard Worker
315*8d67ca89SAndroid Build Coastguard Worker*Resolution*: make sure all required libraries are referenced by SONAME
316*8d67ca89SAndroid Build Coastguard Workeronly. It is better to let the runtime linker to find and load those
317*8d67ca89SAndroid Build Coastguard Workerlibraries as the location may change from device to device.
318*8d67ca89SAndroid Build Coastguard Worker
319*8d67ca89SAndroid Build Coastguard Worker
320*8d67ca89SAndroid Build Coastguard Worker## Missing SONAME (Enforced for API level >= 23)
321*8d67ca89SAndroid Build Coastguard Worker
322*8d67ca89SAndroid Build Coastguard WorkerEach ELF shared object (“native library”) must have a SONAME
323*8d67ca89SAndroid Build Coastguard Worker(Shared Object Name) attribute. The NDK build systems add this
324*8d67ca89SAndroid Build Coastguard Workerattribute by default, so its absence (or an incorrect soname) indicates
325*8d67ca89SAndroid Build Coastguard Workera misconfiguration in your build system. A missing SONAME may lead to
326*8d67ca89SAndroid Build Coastguard Workerruntime issues such as the wrong library being loaded: the filename is
327*8d67ca89SAndroid Build Coastguard Workerused instead when this attribute is missing.
328*8d67ca89SAndroid Build Coastguard Worker
329*8d67ca89SAndroid Build Coastguard Worker```
330*8d67ca89SAndroid Build Coastguard Worker$ readelf --dynamic libWithSoName.so | grep SONAME
331*8d67ca89SAndroid Build Coastguard Worker 0x0000000e (SONAME)                     Library soname: [libWithSoName.so]
332*8d67ca89SAndroid Build Coastguard Worker```
333*8d67ca89SAndroid Build Coastguard Worker
334*8d67ca89SAndroid Build Coastguard Worker*Potential problems*: namespace conflicts may lead to the wrong library
335*8d67ca89SAndroid Build Coastguard Workerbeing loaded at runtime, which leads to crashes when required symbols
336*8d67ca89SAndroid Build Coastguard Workerare not found, or you try to use an ABI-incompatible library that isn't
337*8d67ca89SAndroid Build Coastguard Workerthe library you were expecting.
338*8d67ca89SAndroid Build Coastguard Worker
339*8d67ca89SAndroid Build Coastguard Worker*Resolution*: the current NDK generates the correct SONAME by
340*8d67ca89SAndroid Build Coastguard Workerdefault. Ensure you're using the current NDK and that you haven't
341*8d67ca89SAndroid Build Coastguard Workerconfigured your build system to generate incorrect SONAME entries (using
342*8d67ca89SAndroid Build Coastguard Workerthe `-soname` linker option).
343*8d67ca89SAndroid Build Coastguard Worker
344*8d67ca89SAndroid Build Coastguard Worker
345*8d67ca89SAndroid Build Coastguard Worker## `__register_atfork` (Available in API level >= 23)
346*8d67ca89SAndroid Build Coastguard Worker
347*8d67ca89SAndroid Build Coastguard WorkerTo allow `atfork` and `pthread_atfork` handlers to be unregistered on
348*8d67ca89SAndroid Build Coastguard Worker`dlclose`, API level 23 added a new libc function `__register_atfork`.
349*8d67ca89SAndroid Build Coastguard WorkerThis means that code using `atfork` or `pthread_atfork` functions that is
350*8d67ca89SAndroid Build Coastguard Workerbuilt with a `minSdkVersion` >= 23 will not load on earlier versions of
351*8d67ca89SAndroid Build Coastguard WorkerAndroid, with an error referencing `__register_atfork`.
352*8d67ca89SAndroid Build Coastguard Worker
353*8d67ca89SAndroid Build Coastguard Worker*Resolution*: build your code with `minSdkVersion` that matches the minimum
354*8d67ca89SAndroid Build Coastguard WorkerAPI level you actually support, or avoid using `atfork`/`pthread_atfork`.
355*8d67ca89SAndroid Build Coastguard Worker
356*8d67ca89SAndroid Build Coastguard Worker
357*8d67ca89SAndroid Build Coastguard Worker## DT_RUNPATH support (Available in API level >= 24)
358*8d67ca89SAndroid Build Coastguard Worker
359*8d67ca89SAndroid Build Coastguard WorkerIf an ELF file contains a DT_RUNPATH entry, the directories listed there
360*8d67ca89SAndroid Build Coastguard Workerwill be searched to resolve DT_NEEDED entries. The string `${ORIGIN}` will
361*8d67ca89SAndroid Build Coastguard Workerbe rewritten at runtime to the directory containing the ELF file. This
362*8d67ca89SAndroid Build Coastguard Workerallows the use of relative paths. The `${LIB}` and `${PLATFORM}`
363*8d67ca89SAndroid Build Coastguard Workersubstitutions supported on some systems are not currently implemented on
364*8d67ca89SAndroid Build Coastguard WorkerAndroid.
365*8d67ca89SAndroid Build Coastguard Worker
366*8d67ca89SAndroid Build Coastguard Worker
367*8d67ca89SAndroid Build Coastguard Worker## Writable and Executable Segments (Enforced for API level >= 26)
368*8d67ca89SAndroid Build Coastguard Worker
369*8d67ca89SAndroid Build Coastguard WorkerEach segment in an ELF file has associated flags that tell the
370*8d67ca89SAndroid Build Coastguard Workerdynamic linker what permissions to give the corresponding page in
371*8d67ca89SAndroid Build Coastguard Workermemory. For security, data shouldn't be executable and code shouldn't be
372*8d67ca89SAndroid Build Coastguard Workerwritable. This means that the W (for Writable) and E (for Executable)
373*8d67ca89SAndroid Build Coastguard Workerflags should be mutually exclusive. This wasn't historically enforced,
374*8d67ca89SAndroid Build Coastguard Workerbut is now.
375*8d67ca89SAndroid Build Coastguard Worker
376*8d67ca89SAndroid Build Coastguard Worker```
377*8d67ca89SAndroid Build Coastguard Worker$ readelf --program-headers -W libBadFlags.so | grep WE
378*8d67ca89SAndroid Build Coastguard Worker  LOAD           0x000000 0x00000000 0x00000000 0x4c01d 0x4c01d RWE 0x1000
379*8d67ca89SAndroid Build Coastguard Worker```
380*8d67ca89SAndroid Build Coastguard Worker
381*8d67ca89SAndroid Build Coastguard Worker*Resolution*: we're aware of one middleware product that introduces these
382*8d67ca89SAndroid Build Coastguard Workerinto your app. The middleware vendor is aware of the problem and has a fix
383*8d67ca89SAndroid Build Coastguard Workeravailable.
384*8d67ca89SAndroid Build Coastguard Worker
385*8d67ca89SAndroid Build Coastguard Worker
386*8d67ca89SAndroid Build Coastguard Worker## Invalid ELF header/section headers (Enforced for API level >= 26)
387*8d67ca89SAndroid Build Coastguard Worker
388*8d67ca89SAndroid Build Coastguard WorkerIn API level 26 and above the dynamic linker checks more values in
389*8d67ca89SAndroid Build Coastguard Workerthe ELF header and section headers and fails if they are invalid.
390*8d67ca89SAndroid Build Coastguard Worker
391*8d67ca89SAndroid Build Coastguard Worker*Example error*
392*8d67ca89SAndroid Build Coastguard Worker```
393*8d67ca89SAndroid Build Coastguard Workerdlopen failed: "/data/data/com.example.bad/lib.so" has unsupported e_shentsize: 0x0 (expected 0x28)
394*8d67ca89SAndroid Build Coastguard Worker```
395*8d67ca89SAndroid Build Coastguard Worker
396*8d67ca89SAndroid Build Coastguard Worker*Resolution*: don't use tools that produce invalid/malformed
397*8d67ca89SAndroid Build Coastguard WorkerELF files. Note that using them puts application under high risk of
398*8d67ca89SAndroid Build Coastguard Workerbeing incompatible with future versions of Android.
399*8d67ca89SAndroid Build Coastguard Worker
400*8d67ca89SAndroid Build Coastguard Worker
401*8d67ca89SAndroid Build Coastguard Worker## Enable logging of dlopen/dlsym and library loading errors for apps (Available for API level >= 26)
402*8d67ca89SAndroid Build Coastguard Worker
403*8d67ca89SAndroid Build Coastguard WorkerOn devices running API level 26 or later you can enable logging of dynamic
404*8d67ca89SAndroid Build Coastguard Workerlinker activity for debuggable apps by setting a property corresponding
405*8d67ca89SAndroid Build Coastguard Workerto the fully-qualified name of the specific app:
406*8d67ca89SAndroid Build Coastguard Worker```
407*8d67ca89SAndroid Build Coastguard Workeradb shell setprop debug.ld.app.com.example.myapp dlerror,dlopen,dlsym
408*8d67ca89SAndroid Build Coastguard Workeradb logcat
409*8d67ca89SAndroid Build Coastguard Worker```
410*8d67ca89SAndroid Build Coastguard Worker
411*8d67ca89SAndroid Build Coastguard WorkerAny combination of `dlerror`, `dlopen`, and `dlsym` can be used. There's
412*8d67ca89SAndroid Build Coastguard Workerno separate `dlclose` option: `dlopen` covers both loading and unloading
413*8d67ca89SAndroid Build Coastguard Workerof libraries. Note also that `dlerror` doesn't correspond to actual
414*8d67ca89SAndroid Build Coastguard Workercalls of dlerror(3) but to any time the dynamic linker writes to its
415*8d67ca89SAndroid Build Coastguard Workerinternal error buffer, so you'll see any errors the dynamic linker would
416*8d67ca89SAndroid Build Coastguard Workerhave reported, even if the code you're debugging doesn't actually call
417*8d67ca89SAndroid Build Coastguard Workerdlerror(3) itself.
418*8d67ca89SAndroid Build Coastguard Worker
419*8d67ca89SAndroid Build Coastguard WorkerOn userdebug and eng builds it is possible to enable tracing for the
420*8d67ca89SAndroid Build Coastguard Workerwhole system by using the `debug.ld.all` system property instead of
421*8d67ca89SAndroid Build Coastguard Workerapp-specific one. For example, to enable logging of all dlopen(3)
422*8d67ca89SAndroid Build Coastguard Worker(and thus dclose(3)) calls, and all failures, but not dlsym(3) calls:
423*8d67ca89SAndroid Build Coastguard Worker```
424*8d67ca89SAndroid Build Coastguard Workeradb shell setprop debug.ld.all dlerror,dlopen
425*8d67ca89SAndroid Build Coastguard Worker```
426*8d67ca89SAndroid Build Coastguard Worker
427*8d67ca89SAndroid Build Coastguard Worker
428*8d67ca89SAndroid Build Coastguard Worker## dlclose interacts badly with thread local variables with non-trivial destructors
429*8d67ca89SAndroid Build Coastguard Worker
430*8d67ca89SAndroid Build Coastguard WorkerAndroid allows `dlclose` to unload a library even if there are still
431*8d67ca89SAndroid Build Coastguard Workerthread-local variables with non-trivial destructors. This leads to
432*8d67ca89SAndroid Build Coastguard Workercrashes when a thread exits and attempts to call the destructor, the
433*8d67ca89SAndroid Build Coastguard Workercode for which has been unloaded (as in [issue 360], fixed in API level 28).
434*8d67ca89SAndroid Build Coastguard Worker
435*8d67ca89SAndroid Build Coastguard Worker[issue 360]: https://github.com/android-ndk/ndk/issues/360
436*8d67ca89SAndroid Build Coastguard Worker
437*8d67ca89SAndroid Build Coastguard WorkerNot calling `dlclose` or ensuring that your library has `RTLD_NODELETE`
438*8d67ca89SAndroid Build Coastguard Workerset (so that calls to `dlclose` don't actually unload the library)
439*8d67ca89SAndroid Build Coastguard Workerare possible workarounds.
440*8d67ca89SAndroid Build Coastguard Worker
441*8d67ca89SAndroid Build Coastguard Worker|                   | API level < 23             | >= 23   | >= 28 |
442*8d67ca89SAndroid Build Coastguard Worker| ----------------- | -------------------------- | ------- | ----- |
443*8d67ca89SAndroid Build Coastguard Worker| No workaround     | Works for static STL       | Broken  | Works |
444*8d67ca89SAndroid Build Coastguard Worker| `-Wl,-z,nodelete` | Works for static STL       | Works   | Works |
445*8d67ca89SAndroid Build Coastguard Worker| No `dlclose`      | Works                      | Works   | Works |
446*8d67ca89SAndroid Build Coastguard Worker
447*8d67ca89SAndroid Build Coastguard Worker
448*8d67ca89SAndroid Build Coastguard Worker## ELF TLS (Available for API level >= 29)
449*8d67ca89SAndroid Build Coastguard Worker
450*8d67ca89SAndroid Build Coastguard WorkerAndroid supports [ELF TLS](docs/elf-tls.md) starting at API level 29. Since
451*8d67ca89SAndroid Build Coastguard WorkerNDK r26, clang will automatically enable ELF TLS for `minSdkVersion 29` or
452*8d67ca89SAndroid Build Coastguard Workerhigher. Otherwise, the existing emutls implementation (which uses
453*8d67ca89SAndroid Build Coastguard Worker`pthread_key_create()` behind the scenes) will continue to be used. This
454*8d67ca89SAndroid Build Coastguard Workermeans that convenient C/C++ thread-local syntax is available at any API level;
455*8d67ca89SAndroid Build Coastguard Workerat worst it will perform similarly to "roll your own" thread locals using
456*8d67ca89SAndroid Build Coastguard Worker`pthread_key_create()` but at best you'll get the performance benefit of
457*8d67ca89SAndroid Build Coastguard WorkerELF TLS, and the NDK will take care of the details.
458*8d67ca89SAndroid Build Coastguard Worker
459*8d67ca89SAndroid Build Coastguard Worker
460*8d67ca89SAndroid Build Coastguard Worker## Use of IFUNC in libc (True for all API levels on devices running Android 10)
461*8d67ca89SAndroid Build Coastguard Worker
462*8d67ca89SAndroid Build Coastguard WorkerOn devices running API level 29, libc uses
463*8d67ca89SAndroid Build Coastguard Worker[IFUNC](https://sourceware.org/glibc/wiki/GNU_IFUNC)
464*8d67ca89SAndroid Build Coastguard Workerfunctionality in the dynamic linker to choose optimized assembler routines at
465*8d67ca89SAndroid Build Coastguard Workerrun time rather than at build time. This lets us use the same `libc.so` on all
466*8d67ca89SAndroid Build Coastguard Workerdevices, and is similar to what other OSes already did. Because the zygote
467*8d67ca89SAndroid Build Coastguard Workeruses the C library, this decision is made long before we know what API
468*8d67ca89SAndroid Build Coastguard Workerlevel an app targets, so all code sees the new IFUNC-using C library.
469*8d67ca89SAndroid Build Coastguard WorkerMost apps should be unaffected by this change, but apps that hook or try to
470*8d67ca89SAndroid Build Coastguard Workerdetect hooking of C library functions might need to fix their code to cope
471*8d67ca89SAndroid Build Coastguard Workerwith IFUNC relocations. The affected functions are from `<string.h>`, but
472*8d67ca89SAndroid Build Coastguard Workermay expand to include more functions (and more libraries) in future.
473*8d67ca89SAndroid Build Coastguard Worker
474*8d67ca89SAndroid Build Coastguard Worker
475*8d67ca89SAndroid Build Coastguard Worker## Relative relocations (RELR)
476*8d67ca89SAndroid Build Coastguard Worker
477*8d67ca89SAndroid Build Coastguard WorkerAndroid added experimental support for RELR relative relocations
478*8d67ca89SAndroid Build Coastguard Workerin API level 28, but using `SHT_` and `DT_` constants in the space
479*8d67ca89SAndroid Build Coastguard Workerreserved for OS private use.
480*8d67ca89SAndroid Build Coastguard Worker
481*8d67ca89SAndroid Build Coastguard WorkerAPI level 30 added support for ELF files using the official `SHT_` and
482*8d67ca89SAndroid Build Coastguard Worker`DT_` constants.
483*8d67ca89SAndroid Build Coastguard Worker
484*8d67ca89SAndroid Build Coastguard WorkerThe RELR encoding is unrelated to the earlier "packed relocations"
485*8d67ca89SAndroid Build Coastguard Workerformat available from API level 23.
486*8d67ca89SAndroid Build Coastguard Worker
487*8d67ca89SAndroid Build Coastguard WorkerThere are no plans to remove support for ELF files using the older
488*8d67ca89SAndroid Build Coastguard WorkerOS private use constants for RELR, nor for ELF files using packed
489*8d67ca89SAndroid Build Coastguard Workerrelocations.
490*8d67ca89SAndroid Build Coastguard Worker
491*8d67ca89SAndroid Build Coastguard WorkerPrior to API level 35, there was a bug that caused RELR relocations to
492*8d67ca89SAndroid Build Coastguard Workerbe applied after packed relocations. This meant that ifunc resolvers
493*8d67ca89SAndroid Build Coastguard Workerreferenced by `R_*_IRELATIVE` relocations in the packed relocation
494*8d67ca89SAndroid Build Coastguard Workersection would have been able to read globals with RELR relocations
495*8d67ca89SAndroid Build Coastguard Workerbefore they were relocated. The version of `lld` in the NDK has never
496*8d67ca89SAndroid Build Coastguard Workerproduced binaries affected by this bug, but third-party toolchains
497*8d67ca89SAndroid Build Coastguard Workershould make sure not to store `R_*_IRELATIVE` relocations in packed
498*8d67ca89SAndroid Build Coastguard Workerrelocation sections in order to maintain compatibility with API levels
499*8d67ca89SAndroid Build Coastguard Workerbelow 35.
500*8d67ca89SAndroid Build Coastguard Worker
501*8d67ca89SAndroid Build Coastguard WorkerYou can read more about relative relocations
502*8d67ca89SAndroid Build Coastguard Workerand their long and complicated history at
503*8d67ca89SAndroid Build Coastguard Workerhttps://maskray.me/blog/2021-10-31-relative-relocations-and-relr.
504*8d67ca89SAndroid Build Coastguard Worker
505*8d67ca89SAndroid Build Coastguard Worker
506*8d67ca89SAndroid Build Coastguard Worker## No more sentinels in .preinit_array/.init_array/.fini_array sections of executables (in All API levels)
507*8d67ca89SAndroid Build Coastguard Worker
508*8d67ca89SAndroid Build Coastguard WorkerIn Android <= API level 34 and NDK <= r26, Android used sentinels in the
509*8d67ca89SAndroid Build Coastguard Worker`.preinit_array`/`.init_array`/`.fini_array` sections of executables to locate
510*8d67ca89SAndroid Build Coastguard Workerthe start and end of these arrays. When building with LTO, the function pointers
511*8d67ca89SAndroid Build Coastguard Workerin the arrays can be reordered, making sentinels no longer work. This prevents
512*8d67ca89SAndroid Build Coastguard Workerconstructors for global C++ variables from being called in static executables
513*8d67ca89SAndroid Build Coastguard Workerwhen using LTO.
514*8d67ca89SAndroid Build Coastguard Worker
515*8d67ca89SAndroid Build Coastguard WorkerTo fix this, in Android >= API level 35 and NDK >= r27, we removed sentinels
516*8d67ca89SAndroid Build Coastguard Workerand switched to using symbols inserted by LLD (like `__init_array_start`,
517*8d67ca89SAndroid Build Coastguard Worker`__init_array_end`) to locate the arrays. This also avoids the need for an
518*8d67ca89SAndroid Build Coastguard Workerempty section when there are no corresponding functions.
519*8d67ca89SAndroid Build Coastguard Worker
520*8d67ca89SAndroid Build Coastguard WorkerFor dynamic executables, we kept sentinel support in `crtbegin_dynamic.o` and
521*8d67ca89SAndroid Build Coastguard Worker`libc.so`. This ensures that executables built with newer `crtbegin_dynamic.o`
522*8d67ca89SAndroid Build Coastguard Worker(in NDK >= r27) work with older `libc.so` (in Android <= API level 34), and
523*8d67ca89SAndroid Build Coastguard Workervice versa.
524