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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225851 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Adrian Prantl
2015-01-13 23:39:11 +00:00
parent 656da67bc0
commit 57ed5ffc76
5 changed files with 97 additions and 52 deletions

View File

@ -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");
}
}
}