This is an archive of the discontinued LLVM Phabricator instance.

[MSan] introduce getShadowOriginPtr(). NFC.
ClosedPublic

Authored by glider on Dec 5 2017, 6:02 AM.

Details

Reviewers
eugenis
kcc
Summary

This patch introduces getShadowOriginPtr(), a method that obtains both the shadow and origin pointers for an address as a Value pair.
The existing callers of getShadowPtr() and getOriginPtr() are updated to use getShadowOriginPtr().

The rationale for this change is to simplify KMSAN instrumentation implementation.
In KMSAN origins tracking is always enabled, and there's no direct mapping between the app memory and the shadow/origin pages.
Both the shadow and the origin pointer for a given address are obtained by calling a single runtime hook from the instrumentation, therefore it's easier to work with those pointers together.

Diff Detail

Event Timeline

glider created this revision.Dec 5 2017, 6:02 AM
glider added a subscriber: dvyukov.

dvyukov: FYI

eugenis added inline comments.Dec 5 2017, 2:49 PM
lib/Transforms/Instrumentation/MemorySanitizer.cpp
1028

Normally, we load origin (and compute OriginPtr) only when the shadow check fails. It is done in a different BB behind a cold branch, at least on the IR level. Your change moves OriginPtr computation up to the hot BB.

I really hope that the optimization pipeline is smart enough to sink it back. Please verify that this does not regress userspace codegen.

1043

You can reuse getShadowPtrOffset() result from line 1028.

1066

Why do you wrap ClCheckAccessAddress logic in this function?
Looking at the changes in visitLoadInst(), you first do the app load, and then check the address shadow. This sounds backwards.

glider marked 3 inline comments as done.Dec 8 2017, 7:07 AM
glider added inline comments.
lib/Transforms/Instrumentation/MemorySanitizer.cpp
1028

I compiled the following code with and without my patch:

void store(int *p, int x) {
  *p = x;
}

int load(int *p) {
  return *p;
}

The instructions calculating the origin address were indeed put before the shadow load and store (for store() they were even in a different BB).
However no actual origin load/store was performed before the check, and the resulting assembly was identical on O1-O3 optimization levels.

1066

On a second thought you're right, I'd better not complicate the patch with additional refactoring.
Regarding the visitLoadInst(), I just forgot to remove the extra check from that function.

glider updated this revision to Diff 126148.Dec 8 2017, 7:11 AM
glider marked 2 inline comments as done.

Addressed comments, PTAL

glider updated this revision to Diff 126150.Dec 8 2017, 7:13 AM

Removed a TODO.
In fact we do need origins at that place, but this patch has nothing to do with them.

eugenis accepted this revision.Dec 8 2017, 12:51 PM
eugenis added inline comments.
lib/Transforms/Instrumentation/MemorySanitizer.cpp
1066

Right, this can be done in a separate change.

It would be nice to refactor this code to collect all instructions to be instrumented in a vector<Instruction*>, and then run the visitor over that vector. This would let us get rid of delayed instrumentation of checks and stores (InstrumentationList and StoreList) and just insert the necessary code immediately.

That way you wound not need to wrap ClCheckAccessAddress logic in getShadowOriginPtr just because that's the only function that knows the correct code location for the address check.

This revision is now accepted and ready to land.Dec 8 2017, 12:51 PM
glider closed this revision.Dec 11 2017, 7:06 AM

Committed revision 320373.
Thank you!