This is an archive of the discontinued LLVM Phabricator instance.

[cfi] Emit __cfi_check stub in the frontend
ClosedPublic

Authored by eugenis on Apr 6 2017, 4:22 PM.

Details

Reviewers
pcc
Summary

Previously cfi_check was created in LTO optimization pipeline, which
means LLD has no way of knowing about the existence of this symbol
without rescanning the LTO output object. As a result, LLD fails to
export
cfi_check, even when given --export-dynamic-symbol flag.

Diff Detail

Repository
rL LLVM

Event Timeline

eugenis created this revision.Apr 6 2017, 4:22 PM
pcc added inline comments.Apr 6 2017, 4:57 PM
lib/CodeGen/CGExpr.cpp
2786

Please add a comment explaining why we are creating this function.

2788

What will happen in the CrossDSOCFI pass if it is given a module with this function definition? It looks like it will append its basic blocks to the end of the definition. Because the entry block you are creating here returns immediately, all of the blocks it adds will be unreachable.

Probably the easiest thing to do is to change CrossDSOCFI to replace any __cfi_check definition it sees with its own definition.

2790

Although this linkage may prevent inlining for now, we may in the future change the LTO implementation to promote weak functions to strong if the linker knows that a particular definition of a symbol is the final definition for the symbol. That will mean that this dummy definition may be inlined into callers.

This is a largely theoretical problem because we never create a direct call to the __cfi_check function. But if we wanted to fix this I can imagine creating an intrinsic that the CrossDSOCFI pass expands to the definition of __cfi_check.

2885

remove this line

eugenis added inline comments.Apr 6 2017, 5:46 PM
lib/CodeGen/CGExpr.cpp
2788

Yes, I've not uploaded the llvm patch yet, but it's a one liner:

F->deleteBody();

after locating or creating __cfi_check.

2790

Do you mean "expands to a call to cfi_check"?
We do need to have a definition of
cfi_check before CrossDSOCFI for the linker.

pcc added inline comments.Apr 6 2017, 5:54 PM
lib/CodeGen/CGExpr.cpp
2788

I suppose that would work for now, but what the CrossDSOCFI pass is doing seems a little hackish because it will crash if the type of the existing definition (or declaration) does not exactly match the expected type.

2790

I mean basically that Clang would create a definition like this:

define void @__cfi_check(i64 %0, i8* %1, i8* %2) {
  call void @llvm.cfi_check(i64 %0, i8* %1, i8* %2)
  ret void
}

and CrossDSOCFI would find all calls to @llvm.cfi_check and replace them with the code that the pass currently generates as the body of __cfi_check.

eugenis added inline comments.Apr 6 2017, 5:58 PM
lib/CodeGen/CGExpr.cpp
2790

Ah, that definitely makes sense. Let's mention this in a comment for now.

pcc added inline comments.Apr 6 2017, 6:01 PM
lib/CodeGen/CGExpr.cpp
2790

Works for me.

eugenis updated this revision to Diff 94467.Apr 6 2017, 6:02 PM
eugenis marked 4 inline comments as done.
pcc accepted this revision.Apr 6 2017, 6:08 PM

LGTM

lib/CodeGen/CGExpr.cpp
2798

I would terminate this definition in an llvm.trap so that the program will crash if this definition were to survive LTO for some reason.

This revision is now accepted and ready to land.Apr 6 2017, 6:08 PM
eugenis updated this revision to Diff 94567.Apr 7 2017, 2:29 PM
eugenis marked an inline comment as done.
eugenis closed this revision.Apr 7 2017, 4:13 PM

r299806
Thanks for the review!