diff options
| author | Peter Collingbourne <peter@pcc.me.uk> | 2019-06-17 23:39:41 +0000 |
|---|---|---|
| committer | Peter Collingbourne <peter@pcc.me.uk> | 2019-06-17 23:39:41 +0000 |
| commit | fb9ce100d19be130d004d03088ccd4af295f3435 (patch) | |
| tree | 83f492dda41a0acb0aeabd5211c238750c530ddc /llvm/lib/CodeGen | |
| parent | c3b6d777553d59a032680493b2fbb55d4d41a32a (diff) | |
| download | bcm5719-llvm-fb9ce100d19be130d004d03088ccd4af295f3435.tar.gz bcm5719-llvm-fb9ce100d19be130d004d03088ccd4af295f3435.zip | |
hwasan: Add a tag_offset DWARF attribute to instrumented stack variables.
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.
Differential Revision: https://reviews.llvm.org/D63119
llvm-svn: 363635
Diffstat (limited to 'llvm/lib/CodeGen')
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp | 3 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp | 3 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h | 2 |
3 files changed, 8 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index 37e963ed63b..f0ceba50f14 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -683,6 +683,9 @@ DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV, NVPTXAddressSpace ? *NVPTXAddressSpace : NVPTX_ADDR_local_space); } addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize()); + if (DwarfExpr.TagOffset) + addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1, + *DwarfExpr.TagOffset); return VariableDie; } diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp index c7c28320202..d483a30e499 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp @@ -438,6 +438,9 @@ void DwarfExpression::addExpression(DIExpressionCursor &&ExprCursor, emitOp(dwarf::DW_OP_deref_size); emitData1(Op->getArg(0)); break; + case dwarf::DW_OP_LLVM_tag_offset: + TagOffset = Op->getArg(0); + break; default: llvm_unreachable("unhandled opcode found in expression"); } diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h index 6985debe613..3a9347a3e0a 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h @@ -140,6 +140,8 @@ public: return LocationKind == Implicit; } + Optional<uint8_t> TagOffset; + protected: /// Push a DW_OP_piece / DW_OP_bit_piece for emitting later, if one is needed /// to represent a subregister. |

