This is an archive of the discontinued LLVM Phabricator instance.

[LowerTypeTests] Emit cfi_jt aliases regardless of function export
ClosedPublic

Authored by nickdesaulniers on Aug 11 2021, 3:34 PM.

Details

Summary

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).

Diff Detail

Event Timeline

nickdesaulniers requested review of this revision.Aug 11 2021, 3:34 PM
Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptAug 11 2021, 3:34 PM
Herald added subscribers: llvm-commits, Restricted Project. · View Herald Transcript

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.

tejohnson added inline comments.Aug 16 2021, 8:45 PM
llvm/lib/Transforms/IPO/LowerTypeTests.cpp
1566

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.

pcc added inline comments.Sep 9 2021, 1:57 PM
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
1566

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.

kees added a subscriber: kees.Oct 13 2021, 1:11 PM

Ping; Nick, do you have a moment to rework this patch? AIUI, this is still important to getting CFI more sane for Android.

nickdesaulniers marked an inline comment as done.
  • rebase, convert compiler-rt test to ThinLTO test. TODO: llvm.used and linkage
nickdesaulniers planned changes to this revision.Oct 13 2021, 2:43 PM
  • emit cfi_jt symbols as InternalLinkage and add them to llvm.used
nickdesaulniers marked 2 inline comments as done.Oct 13 2021, 3:24 PM
nickdesaulniers added inline comments.
llvm/lib/Transforms/IPO/LowerTypeTests.cpp
1566

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:

  1. compiler-rt/test/cfi/icall/external-call.c
  2. compiler-rt/test/cfi/icall/weak.c
nickdesaulniers marked an inline comment as done.Oct 13 2021, 4:47 PM
nickdesaulniers added inline comments.
llvm/lib/Transforms/IPO/LowerTypeTests.cpp
1566

Specifically, it seems that the use of GlobalValue::InternalLinkage rather than GlobalValue::ExternalLinkage is what causes those two tests to regress.

nickdesaulniers planned changes to this revision.Oct 13 2021, 5:42 PM
  • change linkage to internal only if !exported, as @pcc said
  • use M rather than *F->getParent(), store Functions[I]->isExported() in local var

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.

tejohnson added inline comments.Oct 25 2021, 10:42 AM
llvm/lib/Transforms/IPO/LowerTypeTests.cpp
1575

This should only be needed if it is internal linkage, to prevent the dropping. With external linkage it can't be dropped anyway.

tejohnson added inline comments.Oct 25 2021, 10:45 AM
llvm/test/ThinLTO/X86/cfi_jt_aliases.ll
1 ↗(On Diff #379572)

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.

nickdesaulniers marked 2 inline comments as done.
  • only retain used for internal linkage, add LTO test for @llvm.used
llvm/test/ThinLTO/X86/cfi_jt_aliases.ll
1 ↗(On Diff #379572)

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.

tejohnson added inline comments.Oct 25 2021, 11:17 AM
llvm/test/ThinLTO/X86/cfi_jt_aliases.ll
1 ↗(On Diff #379572)

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.

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?

llvm/test/ThinLTO/X86/cfi_jt_aliases.ll
1 ↗(On Diff #379572)

*egg on face*

Yes; you're right.

1 ↗(On Diff #379572)

ie.

The exported case should be thin LTO, while the non-exported case should be full LTO. I've copied this test to llvm/test/LTO/... as well, and added the test for @llvm.used there. PTAL.

This revision is now accepted and ready to land.Oct 25 2021, 11:24 AM
pcc added inline comments.Oct 26 2021, 12:53 PM
llvm/test/LTO/X86/cfi_jt_aliases.ll
2

Can this file and the ThinLTO one be combined into a single file?

17

Shouldn't it be checking for a relocation pointing to a? (Same below.)

nickdesaulniers marked an inline comment as done.
  • add check next lines to check the relocations
llvm/test/LTO/X86/cfi_jt_aliases.ll
2

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:

  • additional opt flags for thin LTO
  • -save-temps for full LTO's invocation of llvm-lto2
  • additional llvm-dis invocation for full LTO checking one of those saved temporaries.

Perhaps I could put the IR in an Inputs/ dir somewhere, then use that (not use %s) as input to opt?

nickdesaulniers planned changes to this revision.Oct 27 2021, 10:52 AM

@pcc mentioned offline that I should combine test files, and double up the RUN lines.

  • combine test files into one source
This revision is now accepted and ready to land.Oct 27 2021, 11:02 AM
nickdesaulniers marked an inline comment as done.Oct 27 2021, 11:02 AM
pcc accepted this revision.Oct 27 2021, 11:33 AM

LGTM

This revision was landed with ongoing or failed builds.Oct 27 2021, 11:45 AM
This revision was automatically updated to reflect the committed changes.