This is an archive of the discontinued LLVM Phabricator instance.

hwasan: Add a tag_offset DWARF attribute to instrumented stack variables.
ClosedPublic

Authored by pcc on Jun 10 2019, 8:40 PM.

Details

Summary

The goal is to improve hwasan's error reporting for stack use-after-return by
recording enough information to allow the specific variable that was accessed
to be identified based on the pointer's tag. Currently we record the PC and
lower bits of SP for each stack frame we create (which will eventually be
enough to derive the base tag used by the stack frame) but that's not enough
to determine the specific tag for each variable, which is the stack frame's
base tag XOR a value (the "tag offset") that is unique for each variable in
a function.

In IR, the tag offset is most naturally represented as part of a location
expression on the llvm.dbg.declare instruction. However, the presence of the
tag offset in the variable's actual location expression is likely to confuse
debuggers which won't know about tag offsets, and moreover the tag offset
is not required for a debugger to determine the location of the variable on
the stack, so at the DWARF level it is represented as an attribute so that
it will be ignored by debuggers that don't know about it.

Diff Detail

Repository
rL LLVM

Event Timeline

pcc created this revision.Jun 10 2019, 8:40 PM

Can you please add this to either LangRef.rst or SourceLevelDebugging.rst and also explain how this operation composes with other DIExpressions? I'm thinking particularly about DW_OP_LLVM_fragment.
This also needs an assembler round-trip-test and probably some checks in Verifier.cpp.

pcc updated this revision to Diff 204126.Jun 11 2019, 11:57 AM
  • Address review comments
pcc added a comment.Jun 11 2019, 11:57 AM

Can you please add this to either LangRef.rst or SourceLevelDebugging.rst

Done.

and also explain how this operation composes with other DIExpressions? I'm thinking particularly about DW_OP_LLVM_fragment.

I think this composes quite naturally with other expressions that operate on pointers. Basically you can think of DW_OP_LLVM_tag_offset as adding a large value (base ^ tag_offset) << 56 to the pointer. Being an addition operation this is clearly commutative with other operations such as DW_OP_LLVM_fragment that also add values to the pointer.

This also needs an assembler round-trip-test

Done.

and probably some checks in Verifier.cpp.

Hmm, I'm not sure what else we need aside from the existing isValid() check in Verifier::visitDIExpression.

Hmm, I'm not sure what else we need aside from the existing isValid() check in Verifier::visitDIExpression.

If all tag values are legal and it composes with arbitrary other expressions then it's fine as is. Thanks!

pcc updated this revision to Diff 204623.Jun 13 2019, 1:51 PM
  • Apply tag offset expression to all declares

    This correctly handles the case where we end up with multiple declares pointing to the same alloca because a function was inlined multiple times.
pcc updated this revision to Diff 204879.Jun 14 2019, 4:21 PM
  • Use RetagMask to produce tag offset
eugenis accepted this revision.Jun 17 2019, 4:22 PM

LGTM

This revision is now accepted and ready to land.Jun 17 2019, 4:22 PM
This revision was automatically updated to reflect the committed changes.