This is an archive of the discontinued LLVM Phabricator instance.

Add multiple tables support for WebAssembly and update CFI implementation
Needs ReviewPublic

Authored by ddcc on Jul 11 2016, 4:34 PM.

Details

Reviewers
pcc
sunfish
Summary

This patch adds support for multiple tables to WebAssembly, and updates the CFI implementation to place each disjoint call set into a unique WebAssembly indirect call table with homogeneous element type.

Unfortunately, the current approach is fairly hacky, and likely won't be in a state that is ready to be merged before I leave. One problem that I've encountered in general with CFI has been with pointer casts:

In C, pointer types are often casted in order to implement features such as generic callbacks and object polymorphism. But these will have different type metadata at the function definition and the call site, and fail to match up. For example, the standard library qsort() definitions a callback comparison function with type int (*compare)(const void*, const void*). But when implementing such a comparison function, it will typically have a more specific type, e.g. int compare_parse(Linkage_info* a, Linkage_info* b).

With this specific implementation in particular, there are some additional problems:

  1. There is no direct link from the call to the llvm.type.test() to the actual indirect call site. But I need to tag the indirect call so that it references the correct indirect call table in WebAssembly, so the current approach performs a restricted level-ordered search from the type test up to sibling uses of each parent node, which is mostly correct but fairly slow.
  1. Metadata is used to tag the call site with the destination indirect call table in WebAssembly. But this is very brittle, because the program should still be correct if the metadata is removed. However, this is currently not true. First, if there is no metadata present at an indirect call site, the backend assumes that the default indirect call table should be used, because indirect calls generated by the compiler for C++ vtable references have no call table tag. Additionally, if there is type metadata that is present at an indirect call site, but the program does not contain any functions with this type, then these call sites will not be tagged; this is usually caused by unreachable/dead code. Secondly, if the indirect call site is tagged but subsequently modified by a compiler optimization/transform, then it may lose the call table tag, which is incorrect.

Diff Detail

Event Timeline

ddcc updated this revision to Diff 63611.Jul 11 2016, 4:34 PM
ddcc retitled this revision from to Use multiple tables for WebAssembly CFI implementation.
ddcc updated this object.
ddcc added a subscriber: jfb.
ddcc updated this revision to Diff 64404.Jul 18 2016, 3:43 PM

Attempt to add backend wasm table operand

ddcc updated this revision to Diff 64409.Jul 18 2016, 3:51 PM

More context

ddcc updated this revision to Diff 64590.Jul 19 2016, 4:07 PM

Fix TableGen, update tests

ddcc retitled this revision from Use multiple tables for WebAssembly CFI implementation to Add multiple tables support for WebAssembly and update CFI implementation.Jul 19 2016, 4:11 PM
ddcc added reviewers: pcc, sunfish.
ddcc added a subscriber: llvm-commits.
ddcc updated this revision to Diff 64597.Jul 19 2016, 4:15 PM

Rebase

ddcc updated this revision to Diff 66399.Aug 1 2016, 4:12 PM

Rebase

is the intention that the multiple table support replaces the implementation on top of MVP features? I don't see any way to make it conditional.

ddcc added a comment.Aug 3 2016, 2:42 PM

Yes, I was thinking to add multiple support in the backend, but leave it disabled in the assembler/linker. Then, for the MVP, s2wasm would produce an error if non-default table references are encountered. But I can change the implementation if there's a better way to do this.

ddcc updated this revision to Diff 67270.Aug 8 2016, 6:17 PM

Rebase

ddcc updated this revision to Diff 67453.Aug 9 2016, 7:22 PM

Fix bug with direct call generation

ddcc updated this revision to Diff 67474.Aug 10 2016, 12:57 AM

Fix bug with multiple uses of one type check result

ddcc updated this revision to Diff 67726.Aug 11 2016, 12:11 PM

Fix bugs with C++ and invoke instructions

ddcc updated this object.Aug 11 2016, 12:11 PM
ddcc updated this revision to Diff 67956.Aug 12 2016, 10:11 PM

Replace heuristics with slow but more correct iterative search

ddcc updated this revision to Diff 68303.Aug 16 2016, 9:16 PM

Refactoring, handle more cases

ddcc updated this revision to Diff 68740.Aug 19 2016, 3:29 PM

Final prototype for testing

ddcc updated this object.Aug 19 2016, 4:10 PM