This is an archive of the discontinued LLVM Phabricator instance.

hwasan: Untag unwound stack frames by wrapping personality functions.
ClosedPublic

Authored by pcc on Aug 16 2019, 6:18 PM.

Details

Summary

One problem with untagging memory in landing pads is that it only works
correctly if the function that catches the exception is instrumented.
If the function is uninstrumented, we have no opportunity to untag the
memory.

To address this, replace landing pad instrumentation with personality function
wrapping. Each function with an instrumented stack has its personality function
replaced with a wrapper provided by the runtime. Functions that did not have
a personality function to begin with also get wrappers if they may be unwound
past. As the unwinder calls personality functions during stack unwinding,
the original personality function is called and the function's stack frame is
untagged by the wrapper if the personality function instructs the unwinder
to keep unwinding. If unwinding stops at a landing pad, the function is
still responsible for untagging its stack frame if it resumes unwinding.

The old landing pad mechanism is preserved for compatibility with old runtimes.

Diff Detail

Repository
rL LLVM

Event Timeline

pcc created this revision.Aug 16 2019, 6:18 PM
Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptAug 16 2019, 6:18 PM
Herald added subscribers: Restricted Project, hiraditya, mgorny, srhines. · View Herald Transcript

What's the binary size overhead? I assume most of it comes from adding personality functions to noexcept but !nounwind functions?

llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
1434 ↗(On Diff #215729)

What if the personality function is an alias or an expression that does not strip down to a function? We could still wrap it.

pcc updated this revision to Diff 216746.Aug 22 2019, 5:42 PM
pcc marked an inline comment as done.
  • Support aliases and other constants
pcc added a comment.Aug 22 2019, 5:42 PM

What's the binary size overhead? I assume most of it comes from adding personality functions to noexcept but !nounwind functions?

It seems to be negative overhead, at least for Android libc++.so, presumably because we're no longer instrumenting landing pads. The size of libc++.so is 1116808 bytes without this change and 1101704 bytes with the change.

llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
1434 ↗(On Diff #215729)

Yes we could, done.

eugenis accepted this revision.Aug 22 2019, 5:50 PM

LGTM

This revision is now accepted and ready to land.Aug 22 2019, 5:50 PM
This revision was automatically updated to reflect the committed changes.