A constant complaint we get is that the typeid symbols in the CFI
jump tables causes confusing stack traces in applications. Emit the more
readable cfi_jt aliases regardless of function export (LTO vs Thin LTO).
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Unit Tests
Event Timeline
Thanks, Nick. I tested a kernel build with both ThinLTO and regular LTO + CFI, and can confirm that with this patch vmlinux has the previously missing .cfi_jt symbols again.
llvm/lib/Transforms/IPO/LowerTypeTests.cpp | ||
---|---|---|
1555 | Where and how does the new alias symbol get used in the LTO case? I only see it used when importing in the backend in the ThinLTO case. |
compiler-rt/test/cfi/cfi_jt_aliases.c | ||
---|---|---|
1 ↗ | (On Diff #365863) | This isn't an execution test so I don't think it should be together with the other execution tests. Also I think it will fail on non-ELF platforms because you're using llvm-readelf etc. It seems better to make this a test of the LTO pipeline (see e.g. llvm/test/ThinLTO/X86/cache-icall.ll). |
llvm/lib/Transforms/IPO/LowerTypeTests.cpp | ||
1555 | I think the idea is that these symbols only exist for debugging purposes. I think this could be cleaned up a bit though to ensure that the symbols aren't being exported unnecessarily. Can we set the linkage to internal for non-exported symbols and add to llvm.used to ensure that the symbols aren't dropped? |
causes confusing stack traces in applications
Peter also pointed out that jump table symbols don't actually show up in stack traces, but in the kernel's case, everywhere else where we need to print out a function name, including ftrace.
Ping; Nick, do you have a moment to rework this patch? AIUI, this is still important to getting CFI more sane for Android.
llvm/lib/Transforms/IPO/LowerTypeTests.cpp | ||
---|---|---|
1555 | I've added this; I've fixed up one of the regressions it causes, llvm/test/Transforms/LowerTypeTests/export-icall.ll, but I'm not sure about the other two:
|
llvm/lib/Transforms/IPO/LowerTypeTests.cpp | ||
---|---|---|
1555 | Specifically, it seems that the use of GlobalValue::InternalLinkage rather than GlobalValue::ExternalLinkage is what causes those two tests to regress. |
I tested the latest version with a CFI kernel build, and everything still looks good. I see the same number of .cfi_jt symbols with ThinLTO and full LTO.
llvm/lib/Transforms/IPO/LowerTypeTests.cpp | ||
---|---|---|
1565 | This should only be needed if it is internal linkage, to prevent the dropping. With external linkage it can't be dropped anyway. |
llvm/test/ThinLTO/X86/cfi_jt_aliases.ll | ||
---|---|---|
2 | I can't quite tell - is this checking both the exported and non-exported cases? Comments would be helpful, and maybe explicitly checking llvm.used contents in the IR for the non-exported case. |
- only retain used for internal linkage, add LTO test for @llvm.used
llvm/test/ThinLTO/X86/cfi_jt_aliases.ll | ||
---|---|---|
2 | The exported case should be full LTO, while the non-exported case should be thin LTO. I've copied this test to llvm/test/LTO/... as well, and added the test for @llvm.used there. PTAL. |
llvm/test/ThinLTO/X86/cfi_jt_aliases.ll | ||
---|---|---|
2 |
Did you state this backwards, since the full LTO case is checking for the llvm.used which must mean it is non-exported? Or am I misinterpreting? |
- add check next lines to check the relocations
llvm/test/LTO/X86/cfi_jt_aliases.ll | ||
---|---|---|
1 ↗ | (On Diff #382060) | Is there prior art for tests shared between llvm/test/LTO/ and llvm/test/ThinLTO/? The IR is identical between the two. The RUN lines differ slightly in the following ways:
Perhaps I could put the IR in an Inputs/ dir somewhere, then use that (not use %s) as input to opt? |
@pcc mentioned offline that I should combine test files, and double up the RUN lines.
Where and how does the new alias symbol get used in the LTO case? I only see it used when importing in the backend in the ThinLTO case.