Open llvmbot opened 4 years ago
Hmm, yes I assume the thunks must be generated by the linker. I observed the issue with gold. I don't have easy access to cross-linking builds of the other linkers to test with, unfortunately.
The suitable DWARF for these thunks would be same thing that gets produced by the compiler for e.g. virtual and non-virtual thunks, a CIE and (empty) FDE like this:
0000af08 0000000c ffffffff CIE Version: 3 Augmentation: "" Code alignment factor: 1 Data alignment factor: -4 Return address column: 14
DW_CFA_def_cfa: reg13 +0
0000afbc 0000000c 0000af08 FDE cie=0000af08 pc=011fa240...011fa246
Given that the linker is synthesizing code, it seems like it should support synthesizing unwind info too. :)
I tried to make a simple test case with assembly & nops but wasn't able to get the linker to generate a thunk in the case where functions were too far apart. I'm not sure the code it output was even valid for that matter. I'm guessing either the assembly-generated code is too different from what's produced by the compiler, or I'm not supplying the right linker flags, or both.
These thunks are created by the linker, by the looks of it?
Generally the linker doesn't dabble in DWARF - doesn't create it/parse it/etc.
What do the various different linkers do with these? (bfd, gold, lld, ld64)
(but, all that said, I don't really know much about debug_frame - what would be suitable DWARF to produce for these thunks, etc)
You can probably make a simpler test case with assembly & nops to pad out the gaps to force thunks.
@llvm/issue-subscribers-backend-arm
Author: None (llvmbot)
@llvm/issue-subscribers-debuginfo
Author: None (llvmbot)
Extended Description
The .debug_frame section of a .so for Android arm32 contains no FDEs covering ThumbV7PILongThunks. This is particularly problematic for Chromium where the .text section of libchrome.so is 80MB and contains 42k thunks, and a non-trivial amount of execution time is spent in the thunks.
This was observed in Chromium's clang built from 1bd7046e4ce0102adef6096a12a289d7f94b8c73.
It's not clear that a reduced repro is possible since thunks are only needed on arm32 when the text section is >32MB. To reproduce with Chromium:
target_os = "android" target_cpu = "arm" is_component_build = false
After building chrome_public_apk the relevant .so is in out/Default/lib.unstripped/libchrome.so.
Find the address of an example thunk: third_party/android_ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/arm-linux-androideabi/bin/objdump -j .text -dC out/Default/lib.unstripped/libchrome.so | perl -lne 'print if /^.{8} <__ARMV7PILongThunk___cxa_finalize>/../^$/'
Observe that no FDEs cover the address of the example thunk in the output of llvm-dwarfdump --debug-frame out/Debug/lib.unstripped/libchrome.so