From 092d9489ede3c8cfc4f7c6d56f3c61fa13f1056c Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Tue, 13 Jan 2015 23:39:11 +0000 Subject: Debug Info: Move the complex expression handling (=the remainder) of emitDebugLocValue() into DwarfExpression. Ought to be NFC, but it actually uncovered a bug in the debug-loc-asan.ll testcase. The testcase checks that the address of variable "y" is stored at [RSP+16], which also lines up with the comment. It also check(ed) that the *value* of "y" is stored in RDI before that, but that is actually incorrect, since RDI is the very value that is stored in [RSP+16]. Here's the assembler output: movb 2147450880(%rcx), %r8b #DEBUG_VALUE: bar:y <- RDI cmpb $0, %r8b movq %rax, 32(%rsp) # 8-byte Spill movq %rsi, 24(%rsp) # 8-byte Spill movq %rdi, 16(%rsp) # 8-byte Spill .Ltmp3: #DEBUG_VALUE: bar:y <- [RSP+16] Fixed the comment to spell out the correct register and the check to expect an address rather than a value. Note that the range that is emitted for the RDI location was and is still wrong, it claims to begin at the function prologue, but really it should start where RDI is first assigned. llvm-svn: 225851 --- llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp | 64 +++++++++++++++++++++++++ 1 file changed, 64 insertions(+) (limited to 'llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp') diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp index a3cd000b871..4c16ae70d1f 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp @@ -191,3 +191,67 @@ void DwarfExpression::AddUnsignedConstant(unsigned Value) { if (getDwarfVersion() >= 4) EmitOp(dwarf::DW_OP_stack_value); } + +static unsigned getOffsetOrZero(unsigned OffsetInBits, + unsigned PieceOffsetInBits) { + if (OffsetInBits == PieceOffsetInBits) + return 0; + assert(OffsetInBits >= PieceOffsetInBits && "overlapping pieces"); + return OffsetInBits; +} + +void DwarfExpression::AddMachineRegExpression(DIExpression Expr, + unsigned MachineReg, + unsigned PieceOffsetInBits) { + unsigned N = Expr.getNumElements(); + unsigned I = 0; + // Pattern-match combinations for which more efficient representations exist + // first. + if (N >= 3 && Expr.getElement(0) == dwarf::DW_OP_piece) { + unsigned SizeOfByte = 8; + unsigned OffsetInBits = Expr.getElement(1) * SizeOfByte; + unsigned SizeInBits = Expr.getElement(2) * SizeOfByte; + AddMachineRegPiece(MachineReg, SizeInBits, + getOffsetOrZero(OffsetInBits, PieceOffsetInBits)); + I = 3; + } else if (N >= 3 && Expr.getElement(0) == dwarf::DW_OP_plus && + Expr.getElement(2) == dwarf::DW_OP_deref) { + // [DW_OP_reg,Offset,DW_OP_plus,DW_OP_deref] --> [DW_OP_breg,Offset]. + unsigned Offset = Expr.getElement(1); + AddMachineRegIndirect(MachineReg, Offset); + I = 3; + } else if (N >= 1 && Expr.getElement(0) == dwarf::DW_OP_deref) { + // [DW_OP_reg,DW_OP_deref] --> [DW_OP_breg]. + AddMachineRegIndirect(MachineReg); + I = 1; + } else + AddMachineRegPiece(MachineReg); + + // Emit remaining elements of the expression. + AddExpression(Expr, I); +} + +void DwarfExpression::AddExpression(DIExpression Expr, unsigned I, + unsigned PieceOffsetInBits) { + unsigned N = Expr.getNumElements(); + for (; I < N; ++I) { + switch (Expr.getElement(I)) { + case dwarf::DW_OP_piece: { + unsigned SizeOfByte = 8; + unsigned OffsetInBits = Expr.getElement(++I) * SizeOfByte; + unsigned SizeInBits = Expr.getElement(++I) * SizeOfByte; + AddOpPiece(SizeInBits, getOffsetOrZero(OffsetInBits, PieceOffsetInBits)); + break; + } + case dwarf::DW_OP_plus: + EmitOp(dwarf::DW_OP_plus_uconst); + EmitUnsigned(Expr.getElement(++I)); + break; + case dwarf::DW_OP_deref: + EmitOp(dwarf::DW_OP_deref); + break; + default: + llvm_unreachable("unhandled opcode found in DIExpression"); + } + } +} -- cgit v1.2.3