Closed cyxcw1 closed 1 year ago
We can Reproduce it by the description in this issue: https://github.com/android/ndk/issues/1865
although it's "only" a warning, i think
W/linker: Warning: "/data/app/com.test.csdk.sample_app-ZWeY82cnmYLTHIVMDD5iuQ==/lib/arm64/libbz2.so" unused DT entry: unknown (type 0x5858585858585858 arg 0x0) (ignoring)
is your real problem. 0x5858585858585858 doesn't look remotely like a a DT_* constant, so i suspect you've corrupted your ELF file... (you did mention that you were doing some post-processing. i suggest trying to load the ELF file "fresh" from the linker, to confirm that it's the post-processing that's corrupting it.)
https://github.com/NixOS/patchelf/issues/480
It's most likely a bug that patchelf introduced. I will write a C/C++ compiler driver wrapper to inject -Wl,-soname,libxx.so
option when building a shared library rather than using patchelf
to chang DT_SONAME
@enh-google @leleliu008 , thanks.
With @leleliu008 's help, I solve this problem. This problem was cause after I using patchelf
to change DT_SONAME
@enh-google
Why the .so file is corrupted, readelf
can still read the info?
@enh-google Why the .so file is corrupted, readelf can still read the info?
because it's different code? having written toybox's readelf for the device myself, and having been somewhat involved in bionic's dynamic linker too, i can say they're very different.
(i'd be curious to know what adb shell readelf
and llvm-readelf say about your corrupt file. let me know if either of them crashes :-) i wonder if gnu readelf [which you seem to have used] just stops trying to read the dynamic section if it hits an obviously nonsense entry? certainly gnu ld does some weird stuff in there, and i had to add a special case to toybox readelf to not dump all the terminating null entries, since gnu ld can leave a lot lying around, rather than the obvious single one!)
re.txt @enh-google This is the result I used llvm-readelf to the corrupt file. The command:
./toolchains/llvm/prebuilt/darwin-x86_64/bin/llvm-readelf -a /Users/cyxcw1/.ndk-pkg/install.d/android/21/bzip2-tmp/arm64-v8a/lib-no-versioning/libbz2.so > ~/Downloads/re.txt
I could not use adb shell readelf
:
/system/bin/sh: readelf: inaccessible or not found
Here is the file: https://drive.google.com/file/d/1TfoppEfw9-tqG5sKP1w1VmV2uXlJR6Iq/view?usp=sharing
/system/bin/sh: readelf: inaccessible or not found
if you're on an old version of Android, you won't have it; it was added in Android R: https://android.googlesource.com/platform/system/core/+/master/shell_and_utilities/README.md
here's Android U:
~/aosp-master-with-phones/bionic$ adb shell readelf -aW /data/local/tmp/libbz2.so
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: DYN (Shared object file)
Machine: arm64
Version: 0x1
Entry point address: 0x2e54
Start of program headers: 64 (bytes into file)
Start of section headers: 57272 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 11
Size of section headers: 64 (bytes)
Number of section headers: 23
Section header string table index: 19
Section Headers:
[Nr] Name Type Address Off Size ES Flg Lk Inf Al
[ 0] NULL 0000000000000000 000000 000000 00 0 0 0
[ 1] .dynsym DYNSYM 0000000000000308 000308 000540 18 A 21 1 8
[ 2] .gnu.version VERSYM 0000000000000848 000848 000070 02 A 1 0 2
[ 3] .gnu.version_r VERNEED 00000000000008b8 0008b8 000020 00 A 21 1 4
[ 4] .gnu.hash GNU_HASH 00000000000008d8 0008d8 0000fc 00 A 1 0 8
[ 5] .hash HASH 00000000000009d4 0009d4 0001c8 04 A 1 0 4
[ 6] .rela.dyn RELA 0000000000000e80 000e80 000210 18 A 1 0 8
[ 7] .rela.plt RELA 0000000000001090 001090 0003a8 18 AI 1 16 8
[ 8] .rodata PROGBITS 0000000000001440 001440 000a02 00 AMS 0 0 16
[ 9] .eh_frame_hdr PROGBITS 0000000000001e44 001e44 00000c 00 A 0 0 4
[10] .eh_frame PROGBITS 0000000000001e50 001e50 000004 00 A 0 0 4
[11] .text PROGBITS 0000000000002e54 001e54 00ad70 00 AX 0 0 4
[12] .plt PROGBITS 000000000000dbd0 00cbd0 000290 00 AX 0 0 16
[13] .data.rel.ro PROGBITS 000000000000ee60 00ce60 000088 00 WA 0 0 8
[14] .fini_array FINI_ARRAY 000000000000eee8 00cee8 000010 08 WA 0 0 8
[15] .got PROGBITS 000000000000f068 00d068 000018 00 WA 0 0 8
[16] .got.plt PROGBITS 000000000000f080 00d080 000150 00 WA 0 0 8
[17] .data PROGBITS 00000000000101d0 00d1d0 000c00 00 WA 0 0 4
[18] .comment PROGBITS 0000000000000000 00ddd0 000115 01 MS 0 0 1
[19] .shstrtab STRTAB 0000000000000000 00dee5 0000ce 00 0 0 1
[20] .dynamic DYNAMIC 0000000000020000 010000 000180 10 WA 21 0 8
[21] .dynstr STRTAB 0000000000020180 010180 0002ea 00 A 0 0 8
[22] .note.android.ident NOTE 0000000000020470 010470 000098 00 A 0 0 4
Key:
(W)rite, (A)lloc, e(X)ecute, (M)erge, (S)trings, (I)nfo
(L)ink order, (O)S, (G)roup, (T)LS, (C)ompressed, x=unknown
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000040 0x0000000000000040 0x0000000000000040 0x00268 0x00268 R 0x8
LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x01e54 0x01e54 R 0x1000
GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x00000 0x00000 RW 0
GNU_EH_FRAME 0x001e44 0x0000000000001e44 0x0000000000001e44 0x0000c 0x0000c R 0x4
LOAD 0x001e54 0x0000000000002e54 0x0000000000002e54 0x0b00c 0x0b00c R E 0x1000
LOAD 0x00ce60 0x000000000000ee60 0x000000000000ee60 0x00370 0x00370 RW 0x1000
GNU_RELRO 0x00ce60 0x000000000000ee60 0x000000000000ee60 0x00370 0x011a0 R 0x1
LOAD 0x00d1d0 0x00000000000101d0 0x00000000000101d0 0x00c00 0x00c00 RW 0x1000
DYNAMIC 0x010000 0x0000000000020000 0x0000000000020000 0x00180 0x00180 RW 0x8
phdr 9 has bad offset/size 65536/1288phdr 10 has bad offset/size 66672/152
Section to Segment mapping:
Segment Sections...
00
01 .dynsym .gnu.version .gnu.version_r .gnu.hash .hash .rela.dyn .rela.plt .rodata .eh_frame_hdr .eh_frame
02
03 .eh_frame_hdr
04 .text .plt
05 .data.rel.ro .fini_array .got .got.plt
06 .data.rel.ro .fini_array .got .got.plt
07 .data
08 .dynamic
phdr 9 has bad offset/size 65536/1288phdr 10 has bad offset/size 66672/152
Dynamic section at offset 0x10000 contains 24 entries:
Tag Type Name/Value
0x000000000000000e (SONAME) Library soname: [libbz2.so]
0x0000000000000001 (NEEDED) Shared library: [libc.so]
0x000000000000001e (FLAGS) BIND_NOW
0x000000006ffffffb (FLAGS_1) Flags: NOW
0x0000000000000007 (RELA) 0xe80
0x0000000000000008 (RELASZ) 528 (bytes)
0x0000000000000009 (RELAENT) 24 (bytes)
0x000000006ffffff9 (RELACOUNT) 19
0x0000000000000017 (JMPREL) 0x1090
0x0000000000000002 (PLTRELSZ) 936 (bytes)
0x0000000000000003 (PLTGOT) 0xf080
0x0000000000000014 (PLTREL) RELA
0x0000000000000006 (SYMTAB) 0x308
0x000000000000000b (SYMENT) 24 (bytes)
0x0000000000000005 (STRTAB) 0x20180
0x000000000000000a (STRSZ) 746 (bytes)
0x000000006ffffef5 (GNU_HASH) 0x8d8
0x0000000000000004 (HASH) 0x9d4
0x000000000000001a (FINI_ARRAY) 0xeee8
0x000000000000001c (FINI_ARRAYSZ) 16 (bytes)
0x000000006ffffff0 (VERSYM) 0x848
0x000000006ffffffe (VERNEED) 0x8b8
0x000000006fffffff (VERNEEDNUM) 1
0x0000000000000000 (NULL) 0x0
Symbol table '.dynsym' contains 56 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __cxa_finalize
2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __cxa_atexit
3: 0000000000000000 0 OBJECT GLOBAL DEFAULT UND __sF
4: 0000000000000000 0 FUNC GLOBAL DEFAULT UND fprintf
5: 0000000000000000 0 FUNC GLOBAL DEFAULT UND fwrite
6: 0000000000000000 0 FUNC GLOBAL DEFAULT UND memcpy
7: 0000000000000000 0 FUNC GLOBAL DEFAULT UND memset
8: 0000000000000000 0 FUNC GLOBAL DEFAULT UND fputc
9: 0000000000000000 0 FUNC GLOBAL DEFAULT UND exit
10: 0000000000000000 0 FUNC GLOBAL DEFAULT UND fclose
11: 0000000000000000 0 FUNC GLOBAL DEFAULT UND fdopen
12: 0000000000000000 0 FUNC GLOBAL DEFAULT UND ferror
13: 0000000000000000 0 FUNC GLOBAL DEFAULT UND fflush
14: 0000000000000000 0 FUNC GLOBAL DEFAULT UND fgetc
15: 0000000000000000 0 FUNC GLOBAL DEFAULT UND fopen
16: 0000000000000000 0 FUNC GLOBAL DEFAULT UND fread
17: 0000000000000000 0 FUNC GLOBAL DEFAULT UND free
18: 0000000000000000 0 FUNC GLOBAL DEFAULT UND malloc
19: 0000000000000000 0 FUNC GLOBAL DEFAULT UND strlen
20: 0000000000000000 0 FUNC GLOBAL DEFAULT UND ungetc
21: 000000000000b48c 96 FUNC GLOBAL DEFAULT 11 BZ2_bz__AssertH__fail
22: 000000000000d220 156 FUNC GLOBAL DEFAULT 11 BZ2_bzReadClose
23: 000000000000da50 32 FUNC GLOBAL DEFAULT 11 BZ2_bzerror
24: 000000000000d998 8 FUNC GLOBAL DEFAULT 11 BZ2_bzflush
25: 000000000000d73c 16 FUNC GLOBAL DEFAULT 11 BZ2_bzopen
26: 0000000000004d54 15188 FUNC GLOBAL DEFAULT 11 BZ2_compressBlock
27: 000000000000bc5c 128 FUNC GLOBAL DEFAULT 11 BZ2_bzCompressEnd
28: 000000000000cd5c 324 FUNC GLOBAL DEFAULT 11 BZ2_bzWrite
29: 000000000000ceb0 504 FUNC GLOBAL DEFAULT 11 BZ2_bzWriteClose64
30: 000000000000d95c 60 FUNC GLOBAL DEFAULT 11 BZ2_bzwrite
31: 00000000000047d0 964 FUNC GLOBAL DEFAULT 11 BZ2_hbMakeCodeLengths
32: 000000000000bda4 52 FUNC GLOBAL DEFAULT 11 BZ2_indexIntoF
33: 000000000000b6d8 396 FUNC GLOBAL DEFAULT 11 BZ2_bzCompress
34: 000000000000cba8 128 FUNC GLOBAL DEFAULT 11 BZ2_bzDecompressEnd
35: 000000000000d2bc 456 FUNC GLOBAL DEFAULT 11 BZ2_bzRead
36: 000000000000d90c 80 FUNC GLOBAL DEFAULT 11 BZ2_bzread
37: 000000000000d534 268 FUNC GLOBAL DEFAULT 11 BZ2_bzBuffToBuffCompress
38: 000000000000bdd8 3536 FUNC GLOBAL DEFAULT 11 BZ2_bzDecompress
39: 000000000000cc28 308 FUNC GLOBAL DEFAULT 11 BZ2_bzWriteOpen
40: 000000000000b4ec 12 FUNC GLOBAL DEFAULT 11 BZ2_bzlibVersion
41: 000000000000d640 252 FUNC GLOBAL DEFAULT 11 BZ2_bzBuffToBuffDecompress
42: 000000000000d0a8 376 FUNC GLOBAL DEFAULT 11 BZ2_bzReadOpen
43: 000000000000d9a0 176 FUNC GLOBAL DEFAULT 11 BZ2_bzclose
44: 000000000000d8f8 20 FUNC GLOBAL DEFAULT 11 BZ2_bzdopen
45: 0000000000002e90 3664 FUNC GLOBAL DEFAULT 11 BZ2_blockSort
46: 0000000000004d48 12 FUNC GLOBAL DEFAULT 11 BZ2_bsInitWrite
47: 000000000000b4f8 452 FUNC GLOBAL DEFAULT 11 BZ2_bzCompressInit
48: 000000000000d4c0 116 FUNC GLOBAL DEFAULT 11 BZ2_bzReadGetUnused
49: 0000000000004b94 100 FUNC GLOBAL DEFAULT 11 BZ2_hbAssignCodes
50: 0000000000004bf8 336 FUNC GLOBAL DEFAULT 11 BZ2_hbCreateDecodeTables
51: 00000000000101d0 1024 OBJECT GLOBAL DEFAULT 17 BZ2_crc32Table
52: 00000000000105d0 2048 OBJECT GLOBAL DEFAULT 17 BZ2_rNums
53: 0000000000008a38 10836 FUNC GLOBAL DEFAULT 11 BZ2_decompress
54: 000000000000bcdc 200 FUNC GLOBAL DEFAULT 11 BZ2_bzDecompressInit
55: 000000000000cea0 16 FUNC GLOBAL DEFAULT 11 BZ2_bzWriteClose
Displaying notes found in: .note.android.ident
Owner Data size Description
Android 0x00000084 NT_VERSION API level 21, NDK r22b (7171670)
where the only complaints are:
phdr 9 has bad offset/size 65536/1288
and
phdr 10 has bad offset/size 66672/152
which llvm-readelf shows as
LOAD 0x010000 0x0000000000020000 0x0000000000020000 0x000508 0x000508 RW 0x10000
NOTE 0x010470 0x0000000000020470 0x0000000000020470 0x000098 0x000098 R 0x4
the file is 66824 bytes long, so there's an off-by-one there, and i think it's in our readelf, so i'll fix that.
anyway... your .so file's dynamic section looks fine:
00010000 0e 00 00 00 00 00 00 00 e0 02 00 00 00 00 00 00 N@@@@@@@?B@@@@@@
00010010 01 00 00 00 00 00 00 00 d3 02 00 00 00 00 00 00 A@@@@@@@?B@@@@@@
00010020 1e 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00 ^@@@@@@@H@@@@@@@
00010030 fb ff ff 6f 00 00 00 00 01 00 00 00 00 00 00 00 ???o@@@@A@@@@@@@
00010040 07 00 00 00 00 00 00 00 80 0e 00 00 00 00 00 00 G@@@@@@@?N@@@@@@
00010050 08 00 00 00 00 00 00 00 10 02 00 00 00 00 00 00 H@@@@@@@PB@@@@@@
00010060 09 00 00 00 00 00 00 00 18 00 00 00 00 00 00 00 I@@@@@@@X@@@@@@@
00010070 f9 ff ff 6f 00 00 00 00 13 00 00 00 00 00 00 00 ???o@@@@S@@@@@@@
00010080 17 00 00 00 00 00 00 00 90 10 00 00 00 00 00 00 W@@@@@@@?P@@@@@@
00010090 02 00 00 00 00 00 00 00 a8 03 00 00 00 00 00 00 B@@@@@@@?C@@@@@@
000100a0 03 00 00 00 00 00 00 00 80 f0 00 00 00 00 00 00 C@@@@@@@??@@@@@@
000100b0 14 00 00 00 00 00 00 00 07 00 00 00 00 00 00 00 T@@@@@@@G@@@@@@@
000100c0 06 00 00 00 00 00 00 00 08 03 00 00 00 00 00 00 F@@@@@@@HC@@@@@@
000100d0 0b 00 00 00 00 00 00 00 18 00 00 00 00 00 00 00 K@@@@@@@X@@@@@@@
000100e0 05 00 00 00 00 00 00 00 80 01 02 00 00 00 00 00 E@@@@@@@?AB@@@@@
000100f0 0a 00 00 00 00 00 00 00 ea 02 00 00 00 00 00 00 J@@@@@@@?B@@@@@@
00010100 f5 fe ff 6f 00 00 00 00 d8 08 00 00 00 00 00 00 ???o@@@@?H@@@@@@
00010110 04 00 00 00 00 00 00 00 d4 09 00 00 00 00 00 00 D@@@@@@@?I@@@@@@
00010120 1a 00 00 00 00 00 00 00 e8 ee 00 00 00 00 00 00 Z@@@@@@@??@@@@@@
00010130 1c 00 00 00 00 00 00 00 10 00 00 00 00 00 00 00 \@@@@@@@P@@@@@@@
00010140 f0 ff ff 6f 00 00 00 00 48 08 00 00 00 00 00 00 ???o@@@@HH@@@@@@
00010150 fe ff ff 6f 00 00 00 00 b8 08 00 00 00 00 00 00 ???o@@@@?H@@@@@@
00010160 ff ff ff 6f 00 00 00 00 01 00 00 00 00 00 00 00 ???o@@@@A@@@@@@@
00010170 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 @@@@@@@@@@@@@@@@
those seem like the right entries, in the right order, with a single DT_NULL at the end. the string table follows, and although there are large sections of 'X'es in the ELF file (corresponding to the 0x58585858'58585858 that the dynamic linker complained about), there's nothing down here near the end of the file.
okay, time to actually try this on an arm64 device!
(there will now be a short intermission while i find a suitable device, build for it, flash it, and test it...)
hmm... your libbz2.so with sha256 ac03f5e33e6c90edeed67646588c2d068f4d868f058cb6f432161589528b3b05 dlopen()s fine for me on AOSP master.
what version of Android were you having trouble on?
I saw a similar crash with an unrelated cause. I was able to fix it by following the Android NDK guide, Support 16 KB page sizes.
Really? Did you end up on a 16k configured device somehow? That should be a very rare configuration (as in zero devices rare).
"similar crash" in just the "dlopen failed", or actually the "empty/missing DT_HASH/DT_GNU_HASH"?
@DanAlbert I was using an emulator at SDK level 35 on a aarch64 MacBook Pro.
@enh-google the exact error is
java.lang.UnsatisfiedLinkError: dlopen failed: empty/missing DT_HASH/DT_GNU_HASH in "/data/app/~~ZxUFcGuDQcv9ij_KMRXCVQ==/app.cash.zipline.test-K-VxaF1awxuos15EVjM0lQ==/lib/arm64/libquickjs.so" (new hash type from the future?)
You might repro by cloning zipline a running this:
./gradlew zipline:connectedAndroidTest
You’ll need a running Android API 35 emulator for the test to connect to.
(i'm hoping the URL-escaping in the error message was you rather than something that actually came out of the linker/libcore :-) )
so funnily enough -- implausible though this seemed to me and danalbert yesterday -- we have actually seen this specific error message from 4KiB/16KiB confusion before: that's what https://android-review.googlesource.com/c/platform/bionic/+/3101667 was about. as rprichard said there: "I'm guessing the reason for the missing DT_HASH/DT_GNU_HASH error is that it just happens to be the first thing diagnosed in soinfo::prelink_image. Maybe we're loading a dynamic section of all zeros because the mmap ranges overlap (once the 4KiB addresses are adjusted to 16KiB)."
it's possible that surenb's [otherwise unrelated] optimization to just do one big mmap() rather than lots of little read()s and mmap()s in https://android-review.googlesource.com/c/platform/bionic/+/3164056 might make this just go away...
Fixed the URL-escaping. Firefox bug?
Yeah, I agree that DT_HASH/DT_GNU_HASH is the wrong error message. I can see both when I inspect the .so
file with readelf
.
Following Google’s Support 16 KB page sizes guide fixed the bug for me.
Does the API level 35 emulator require 16 KB page sizes? Or did my fix work by accident?
Here’s a Realm bug report that’s got the same symptoms as my bug. https://github.com/realm/realm-java/issues/7894
Does the API level 35 emulator require 16 KB page sizes?
i don't think it's supposed to unless you explicitly choose the "Google APIs Experimental 16k Page Size ARM 64 v8a System Image" or "Google APIs Experimental 16k Page Size Intel x86_64 Atom System Image" option. @smore-lore
Which version of Android Studio is this? If it is very old, there was an issue where it was not able to distinguish between the VM type.
API level 35 emulator does not require 16 KB page sizes, and production devices are still 4 KB.
That being said, you could also follow the steps here, and then the app will run on 4 KB and 16 KB devices moving forward. https://developer.android.com/guide/practices/page-sizes
@smore-lore ooh that’s it. I chose the first ‘Android 35’ emulator in the list, and didn’t pay attention to the fine print!
Several years old Android Studio installations will not even it show it here, but that's it! If it's a wider menu box, you should be able to see it there as well. I've forwarded this clarity issue to the Android Studio team (Google ref: 334196072). Thank you.
@smore-lore ooh that’s it. I chose the first ‘Android 35’ emulator in the list, and didn’t pay attention to the fine print!
Emulator: system-images/android-35/google_apis_playstore_ps16k/arm64-v8a/ Android Studio: Koala | 2024.1.1.
Ohh I did the same mistake. It's so weird! Now it works!
I had to add these lines to for Realm as well:
val appInitializer = AppInitializer.getInstance(this)
appInitializer.initializeComponent(RealmInitializer::class.java)
Thanks man.
Description
It is related to this issue: https://github.com/android/ndk/issues/1865, after I solve the
soname
problem. Also with the libbz2.so, my app crash when starting up:But I checked the
libbz2.so
and found:Below is part of the elf info:
Affected versions
r23
I’ve used the latest NDK version: 25.2.9519653, and the problem still exists.
Canary version
No response
Host OS
Mac
Host OS version
macOS 13.2.1
Affected ABIs
arm64-v8a
Build system
CMake
Other build system
No response
minSdkVersion
21
Device API level
29