This is an archive of the discontinued LLVM Phabricator instance.

[cfi] CFI-ICall for ThinLTO.
ClosedPublic

Authored by eugenis on Jun 13 2017, 1:38 PM.

Details

Summary

Implement ControlFlowIntegrity for indirect function calls in ThinLTO.
Design follows the RFC in llvm-dev, see
https://groups.google.com/d/msg/llvm-dev/MgUlaphu4Qc/kywu0AqjAQAJ

Diff Detail

Repository
rL LLVM

Event Timeline

eugenis created this revision.Jun 13 2017, 1:38 PM
eugenis added inline comments.Jun 13 2017, 1:41 PM
include/llvm/IR/ModuleSummaryIndexYAML.h
245

An alternative to this is rewriting SequenceTraits in terms of begin/end iterators.
The current interface does not work for std::set at all because it is index-based.

pcc added inline comments.Jun 13 2017, 4:57 PM
include/llvm/IR/ModuleSummaryIndex.h
39

Sort by name.

include/llvm/IR/ModuleSummaryIndexYAML.h
245

Yes, that's one possibility. But for now I'd suggest performing the vector/set conversions directly here, then relying on the built-in handling of std::vector which would avoid the need for the StringSetYaml class.

if (io.outputting()) {
  std::vector<std::string> CfiFunctionDefs(index.CfiFunctionDefs.begin(), index.CfiFunctionDefs.end());
  io.mapOptional("CfiFunctionDefs", CfiFunctionDefs);

  // same for CfiFunctionDecls
} else {
  std::vector<std::string> CfiFunctionDefs;
  io.mapOptional("CfiFunctionDefs", CfiFunctionDefs);
  index.CfiFunctionDefs = {CfiFunctionDefs.begin(), CfiFunctionDefs.end()};

  // same for CfiFunctionDecls
}
include/llvm/Support/YAMLTraits.h
662 ↗(On Diff #102396)

This is only necessary because of StringSetYaml, right?

lib/Bitcode/Reader/BitcodeReader.cpp
5255

I'd do this with two record types, one for defs and the other for decls, but up to you.

lib/Bitcode/Writer/BitcodeWriter.cpp
3855

clang-format

lib/Transforms/IPO/LowerTypeTests.cpp
1447

Will this do the right thing if a (non-address-taken) function with local linkage has the same name as an unrelated function in another module with external linkage? I think you need to check that the function has external linkage before testing for set membership.

1475

I would declare a struct inline here instead of using a pair, to make this a little more self-documenting.

1492

I think this would be clearer as if (!V.first).

Could V.first be uninitialized at this point?

1498

Remove line.

lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
35–36

Rebuilding the metadata in here doesn't seem very elegant. Maybe instead you could:

  1. compute a SetVector<GlobalValue *> of which functions require jump table entries
  2. pass that set into this function and use it to control whether to promote
  3. once it returns, produce the metadata in the merged module by enumerating the set.
315

Can we declare an enum somewhere instead of using these magic numbers?

I would also rewrite with if/else.

eugenis updated this revision to Diff 102617.Jun 14 2017, 3:57 PM
eugenis marked 9 inline comments as done.
eugenis added inline comments.
include/llvm/Support/YAMLTraits.h
662 ↗(On Diff #102396)

Right. Still seems like the right thing to do. I've uploaded it as a separate NFC revision in D34116.

lib/Transforms/IPO/LowerTypeTests.cpp
1492

It's initialized to zero, which is what we want.

eugenis updated this revision to Diff 102625.Jun 14 2017, 5:09 PM
eugenis added inline comments.
lib/Transforms/IPO/LowerTypeTests.cpp
1492

I've rewrote this code in a more explicit way.

pcc accepted this revision.Jun 14 2017, 5:23 PM

LGTM

lib/Transforms/IPO/CrossDSOCFI.cpp
98

Please add test coverage for this code.

lib/Transforms/IPO/LowerTypeTests.cpp
40

This should be the first include.

This revision is now accepted and ready to land.Jun 14 2017, 5:23 PM
eugenis updated this revision to Diff 102630.Jun 14 2017, 5:33 PM
eugenis marked 2 inline comments as done.
pcc added inline comments.Jun 15 2017, 10:30 AM
lib/Transforms/IPO/LowerTypeTests.cpp
1415

You could remove this function and use ModuleSummaryIndex::isGUIDLive now.

eugenis added inline comments.Jun 15 2017, 2:51 PM
lib/Transforms/IPO/LowerTypeTests.cpp
1415

I did not notice this before, but isGUIDLive thinks that all external functions are dead, because only definitions have value summaries.

eugenis updated this revision to Diff 102727.Jun 15 2017, 2:54 PM
eugenis added inline comments.
lib/Transforms/IPO/LowerTypeTests.cpp
1415

Fixed, PTAL

eugenis updated this revision to Diff 102733.Jun 15 2017, 3:34 PM

One more fix: ignore !types in thinlto-exported declarations when the regular lto module has a definition.

pcc added a comment.Jun 15 2017, 5:05 PM

Still LGTM

test/Transforms/LowerTypeTests/Inputs/use-typeid1-typeid2.yaml
4 ↗(On Diff #102733)

Why did you change this to false?

Presumably the test still passes because WithGlobalValueDeadStripping is false?

eugenis added inline comments.Jun 15 2017, 5:06 PM
test/Transforms/LowerTypeTests/Inputs/use-typeid1-typeid2.yaml
4 ↗(On Diff #102733)

Right. I'll change it back.

eugenis updated this revision to Diff 102762.Jun 15 2017, 5:09 PM
eugenis closed this revision.Jun 15 2017, 5:19 PM

r305533