2015-01-12 22:19:22 +00:00
|
|
|
//===-- llvm/CodeGen/DwarfExpression.cpp - Dwarf Debug Framework ----------===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file contains support for writing dwarf debug info into asm files.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "DwarfExpression.h"
|
2015-01-12 23:36:56 +00:00
|
|
|
#include "DwarfDebug.h"
|
2015-01-12 22:19:22 +00:00
|
|
|
#include "llvm/ADT/SmallBitVector.h"
|
2015-01-12 23:36:56 +00:00
|
|
|
#include "llvm/CodeGen/AsmPrinter.h"
|
2015-01-12 22:19:22 +00:00
|
|
|
#include "llvm/Support/Dwarf.h"
|
|
|
|
#include "llvm/Target/TargetMachine.h"
|
|
|
|
#include "llvm/Target/TargetRegisterInfo.h"
|
|
|
|
#include "llvm/Target/TargetSubtargetInfo.h"
|
|
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
|
2015-01-13 00:04:06 +00:00
|
|
|
void DwarfExpression::AddReg(int DwarfReg, const char *Comment) {
|
2015-01-12 22:19:22 +00:00
|
|
|
assert(DwarfReg >= 0 && "invalid negative dwarf register number");
|
|
|
|
if (DwarfReg < 32) {
|
|
|
|
EmitOp(dwarf::DW_OP_reg0 + DwarfReg, Comment);
|
|
|
|
} else {
|
|
|
|
EmitOp(dwarf::DW_OP_regx, Comment);
|
|
|
|
EmitUnsigned(DwarfReg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void DwarfExpression::AddRegIndirect(int DwarfReg, int Offset, bool Deref) {
|
|
|
|
assert(DwarfReg >= 0 && "invalid negative dwarf register number");
|
|
|
|
if (DwarfReg < 32) {
|
|
|
|
EmitOp(dwarf::DW_OP_breg0 + DwarfReg);
|
|
|
|
} else {
|
|
|
|
EmitOp(dwarf::DW_OP_bregx);
|
|
|
|
EmitUnsigned(DwarfReg);
|
|
|
|
}
|
|
|
|
EmitSigned(Offset);
|
|
|
|
if (Deref)
|
|
|
|
EmitOp(dwarf::DW_OP_deref);
|
|
|
|
}
|
|
|
|
|
2015-01-13 00:04:06 +00:00
|
|
|
void DwarfExpression::AddOpPiece(unsigned SizeInBits, unsigned OffsetInBits) {
|
2015-01-12 22:19:22 +00:00
|
|
|
assert(SizeInBits > 0 && "piece has size zero");
|
|
|
|
const unsigned SizeOfByte = 8;
|
|
|
|
if (OffsetInBits > 0 || SizeInBits % SizeOfByte) {
|
|
|
|
EmitOp(dwarf::DW_OP_bit_piece);
|
|
|
|
EmitUnsigned(SizeInBits);
|
|
|
|
EmitUnsigned(OffsetInBits);
|
|
|
|
} else {
|
|
|
|
EmitOp(dwarf::DW_OP_piece);
|
|
|
|
unsigned ByteSize = SizeInBits / SizeOfByte;
|
|
|
|
EmitUnsigned(ByteSize);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void DwarfExpression::AddShr(unsigned ShiftBy) {
|
|
|
|
EmitOp(dwarf::DW_OP_constu);
|
|
|
|
EmitUnsigned(ShiftBy);
|
|
|
|
EmitOp(dwarf::DW_OP_shr);
|
|
|
|
}
|
|
|
|
|
2015-01-12 22:19:26 +00:00
|
|
|
bool DwarfExpression::AddMachineRegIndirect(unsigned MachineReg, int Offset) {
|
2015-01-13 23:10:43 +00:00
|
|
|
if (isFrameRegister(MachineReg)) {
|
2015-01-12 22:19:26 +00:00
|
|
|
// If variable offset is based in frame register then use fbreg.
|
|
|
|
EmitOp(dwarf::DW_OP_fbreg);
|
|
|
|
EmitSigned(Offset);
|
2015-03-03 20:12:52 +00:00
|
|
|
return true;
|
2015-01-12 22:19:26 +00:00
|
|
|
}
|
2015-03-03 20:12:52 +00:00
|
|
|
|
|
|
|
int DwarfReg = TRI.getDwarfRegNum(MachineReg, false);
|
|
|
|
if (DwarfReg < 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
AddRegIndirect(DwarfReg, Offset);
|
2015-01-12 22:19:26 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-01-14 01:01:28 +00:00
|
|
|
bool DwarfExpression::AddMachineRegPiece(unsigned MachineReg,
|
2015-01-12 22:19:22 +00:00
|
|
|
unsigned PieceSizeInBits,
|
|
|
|
unsigned PieceOffsetInBits) {
|
2015-03-02 22:02:33 +00:00
|
|
|
if (!TRI.isPhysicalRegister(MachineReg))
|
2015-01-25 19:04:08 +00:00
|
|
|
return false;
|
|
|
|
|
2015-03-02 22:02:33 +00:00
|
|
|
int Reg = TRI.getDwarfRegNum(MachineReg, false);
|
2015-01-12 22:19:22 +00:00
|
|
|
|
|
|
|
// If this is a valid register number, emit it.
|
|
|
|
if (Reg >= 0) {
|
|
|
|
AddReg(Reg);
|
2015-01-12 22:37:16 +00:00
|
|
|
if (PieceSizeInBits)
|
|
|
|
AddOpPiece(PieceSizeInBits, PieceOffsetInBits);
|
2015-01-14 01:01:28 +00:00
|
|
|
return true;
|
2015-01-12 22:19:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Walk up the super-register chain until we find a valid number.
|
|
|
|
// For example, EAX on x86_64 is a 32-bit piece of RAX with offset 0.
|
2015-03-02 22:02:33 +00:00
|
|
|
for (MCSuperRegIterator SR(MachineReg, &TRI); SR.isValid(); ++SR) {
|
|
|
|
Reg = TRI.getDwarfRegNum(*SR, false);
|
2015-01-12 22:19:22 +00:00
|
|
|
if (Reg >= 0) {
|
2015-03-02 22:02:33 +00:00
|
|
|
unsigned Idx = TRI.getSubRegIndex(*SR, MachineReg);
|
|
|
|
unsigned Size = TRI.getSubRegIdxSize(Idx);
|
|
|
|
unsigned RegOffset = TRI.getSubRegIdxOffset(Idx);
|
2015-01-12 22:19:22 +00:00
|
|
|
AddReg(Reg, "super-register");
|
|
|
|
if (PieceOffsetInBits == RegOffset) {
|
|
|
|
AddOpPiece(Size, RegOffset);
|
|
|
|
} else {
|
|
|
|
// If this is part of a variable in a sub-register at a
|
|
|
|
// non-zero offset, we need to manually shift the value into
|
|
|
|
// place, since the DW_OP_piece describes the part of the
|
|
|
|
// variable, not the position of the subregister.
|
|
|
|
if (RegOffset)
|
|
|
|
AddShr(RegOffset);
|
|
|
|
AddOpPiece(Size, PieceOffsetInBits);
|
|
|
|
}
|
2015-01-14 01:01:28 +00:00
|
|
|
return true;
|
2015-01-12 22:19:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Otherwise, attempt to find a covering set of sub-register numbers.
|
|
|
|
// For example, Q0 on ARM is a composition of D0+D1.
|
|
|
|
//
|
|
|
|
// Keep track of the current position so we can emit the more
|
|
|
|
// efficient DW_OP_piece.
|
|
|
|
unsigned CurPos = PieceOffsetInBits;
|
|
|
|
// The size of the register in bits, assuming 8 bits per byte.
|
2015-03-02 22:02:33 +00:00
|
|
|
unsigned RegSize = TRI.getMinimalPhysRegClass(MachineReg)->getSize() * 8;
|
2015-01-12 22:19:22 +00:00
|
|
|
// Keep track of the bits in the register we already emitted, so we
|
|
|
|
// can avoid emitting redundant aliasing subregs.
|
|
|
|
SmallBitVector Coverage(RegSize, false);
|
2015-03-02 22:02:33 +00:00
|
|
|
for (MCSubRegIterator SR(MachineReg, &TRI); SR.isValid(); ++SR) {
|
|
|
|
unsigned Idx = TRI.getSubRegIndex(MachineReg, *SR);
|
|
|
|
unsigned Size = TRI.getSubRegIdxSize(Idx);
|
|
|
|
unsigned Offset = TRI.getSubRegIdxOffset(Idx);
|
|
|
|
Reg = TRI.getDwarfRegNum(*SR, false);
|
2015-01-12 22:19:22 +00:00
|
|
|
|
|
|
|
// Intersection between the bits we already emitted and the bits
|
|
|
|
// covered by this subregister.
|
|
|
|
SmallBitVector Intersection(RegSize, false);
|
|
|
|
Intersection.set(Offset, Offset + Size);
|
|
|
|
Intersection ^= Coverage;
|
|
|
|
|
|
|
|
// If this sub-register has a DWARF number and we haven't covered
|
|
|
|
// its range, emit a DWARF piece for it.
|
|
|
|
if (Reg >= 0 && Intersection.any()) {
|
|
|
|
AddReg(Reg, "sub-register");
|
|
|
|
AddOpPiece(Size, Offset == CurPos ? 0 : Offset);
|
|
|
|
CurPos = Offset + Size;
|
|
|
|
|
|
|
|
// Mark it as emitted.
|
|
|
|
Coverage.set(Offset, Offset + Size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-14 01:01:28 +00:00
|
|
|
return CurPos > PieceOffsetInBits;
|
2015-01-12 22:19:22 +00:00
|
|
|
}
|
2015-01-13 00:04:06 +00:00
|
|
|
|
|
|
|
void DwarfExpression::AddSignedConstant(int Value) {
|
|
|
|
EmitOp(dwarf::DW_OP_consts);
|
|
|
|
EmitSigned(Value);
|
|
|
|
// The proper way to describe a constant value is
|
|
|
|
// DW_OP_constu <const>, DW_OP_stack_value.
|
|
|
|
// Unfortunately, DW_OP_stack_value was not available until DWARF-4,
|
|
|
|
// so we will continue to generate DW_OP_constu <const> for DWARF-2
|
|
|
|
// and DWARF-3. Technically, this is incorrect since DW_OP_const <const>
|
|
|
|
// actually describes a value at a constant addess, not a constant value.
|
|
|
|
// However, in the past there was no better way to describe a constant
|
|
|
|
// value, so the producers and consumers started to rely on heuristics
|
|
|
|
// to disambiguate the value vs. location status of the expression.
|
|
|
|
// See PR21176 for more details.
|
2015-06-09 18:01:51 +00:00
|
|
|
if (DwarfVersion >= 4)
|
|
|
|
EmitOp(dwarf::DW_OP_stack_value);
|
2015-01-13 00:04:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DwarfExpression::AddUnsignedConstant(unsigned Value) {
|
|
|
|
EmitOp(dwarf::DW_OP_constu);
|
|
|
|
EmitUnsigned(Value);
|
|
|
|
// cf. comment in DwarfExpression::AddSignedConstant().
|
2015-06-09 18:01:51 +00:00
|
|
|
if (DwarfVersion >= 4)
|
|
|
|
EmitOp(dwarf::DW_OP_stack_value);
|
2015-01-13 00:04:06 +00:00
|
|
|
}
|
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
2015-01-13 23:39:11 +00:00
|
|
|
|
|
|
|
static unsigned getOffsetOrZero(unsigned OffsetInBits,
|
|
|
|
unsigned PieceOffsetInBits) {
|
|
|
|
if (OffsetInBits == PieceOffsetInBits)
|
|
|
|
return 0;
|
|
|
|
assert(OffsetInBits >= PieceOffsetInBits && "overlapping pieces");
|
|
|
|
return OffsetInBits;
|
|
|
|
}
|
|
|
|
|
2015-04-29 16:38:44 +00:00
|
|
|
bool DwarfExpression::AddMachineRegExpression(const DIExpression *Expr,
|
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
2015-01-13 23:39:11 +00:00
|
|
|
unsigned MachineReg,
|
|
|
|
unsigned PieceOffsetInBits) {
|
2015-04-07 03:45:57 +00:00
|
|
|
auto I = Expr->expr_op_begin();
|
|
|
|
auto E = Expr->expr_op_end();
|
2015-03-04 17:39:33 +00:00
|
|
|
if (I == E)
|
2015-01-22 00:00:59 +00:00
|
|
|
return AddMachineRegPiece(MachineReg);
|
|
|
|
|
2015-03-04 17:39:33 +00:00
|
|
|
// Pattern-match combinations for which more efficient representations exist
|
|
|
|
// first.
|
2015-01-22 00:00:59 +00:00
|
|
|
bool ValidReg = false;
|
2015-04-07 03:45:57 +00:00
|
|
|
switch (I->getOp()) {
|
2015-02-09 23:57:15 +00:00
|
|
|
case dwarf::DW_OP_bit_piece: {
|
2015-04-07 03:45:57 +00:00
|
|
|
unsigned OffsetInBits = I->getArg(0);
|
|
|
|
unsigned SizeInBits = I->getArg(1);
|
2015-01-22 00:00:59 +00:00
|
|
|
// Piece always comes at the end of the expression.
|
|
|
|
return AddMachineRegPiece(MachineReg, SizeInBits,
|
|
|
|
getOffsetOrZero(OffsetInBits, PieceOffsetInBits));
|
|
|
|
}
|
2015-03-04 17:39:33 +00:00
|
|
|
case dwarf::DW_OP_plus: {
|
2015-06-09 18:01:51 +00:00
|
|
|
// [DW_OP_reg,Offset,DW_OP_plus,DW_OP_deref] --> [DW_OP_breg,Offset].
|
2015-04-07 03:45:57 +00:00
|
|
|
auto N = I.getNext();
|
|
|
|
if (N != E && N->getOp() == dwarf::DW_OP_deref) {
|
2015-06-09 18:01:51 +00:00
|
|
|
unsigned Offset = I->getArg(0);
|
2015-01-22 00:00:59 +00:00
|
|
|
ValidReg = AddMachineRegIndirect(MachineReg, Offset);
|
|
|
|
std::advance(I, 2);
|
2015-06-09 18:01:51 +00:00
|
|
|
break;
|
|
|
|
} else
|
|
|
|
ValidReg = AddMachineRegPiece(MachineReg);
|
2015-03-04 17:39:33 +00:00
|
|
|
}
|
|
|
|
case dwarf::DW_OP_deref: {
|
|
|
|
// [DW_OP_reg,DW_OP_deref] --> [DW_OP_breg].
|
|
|
|
ValidReg = AddMachineRegIndirect(MachineReg);
|
|
|
|
++I;
|
|
|
|
break;
|
|
|
|
}
|
2015-01-22 00:00:59 +00:00
|
|
|
default:
|
|
|
|
llvm_unreachable("unsupported operand");
|
|
|
|
}
|
2015-01-14 01:01:28 +00:00
|
|
|
|
|
|
|
if (!ValidReg)
|
|
|
|
return false;
|
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
2015-01-13 23:39:11 +00:00
|
|
|
|
|
|
|
// Emit remaining elements of the expression.
|
2015-03-04 17:39:33 +00:00
|
|
|
AddExpression(I, E, PieceOffsetInBits);
|
2015-01-14 01:01:28 +00:00
|
|
|
return true;
|
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
2015-01-13 23:39:11 +00:00
|
|
|
}
|
|
|
|
|
2015-04-29 16:38:44 +00:00
|
|
|
void DwarfExpression::AddExpression(DIExpression::expr_op_iterator I,
|
|
|
|
DIExpression::expr_op_iterator E,
|
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
2015-01-13 23:39:11 +00:00
|
|
|
unsigned PieceOffsetInBits) {
|
2015-02-17 22:30:56 +00:00
|
|
|
for (; I != E; ++I) {
|
2015-04-07 03:45:57 +00:00
|
|
|
switch (I->getOp()) {
|
2015-02-09 23:57:15 +00:00
|
|
|
case dwarf::DW_OP_bit_piece: {
|
2015-04-07 03:45:57 +00:00
|
|
|
unsigned OffsetInBits = I->getArg(0);
|
|
|
|
unsigned SizeInBits = I->getArg(1);
|
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
2015-01-13 23:39:11 +00:00
|
|
|
AddOpPiece(SizeInBits, getOffsetOrZero(OffsetInBits, PieceOffsetInBits));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case dwarf::DW_OP_plus:
|
|
|
|
EmitOp(dwarf::DW_OP_plus_uconst);
|
2015-04-07 03:45:57 +00:00
|
|
|
EmitUnsigned(I->getArg(0));
|
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
2015-01-13 23:39:11 +00:00
|
|
|
break;
|
|
|
|
case dwarf::DW_OP_deref:
|
|
|
|
EmitOp(dwarf::DW_OP_deref);
|
|
|
|
break;
|
|
|
|
default:
|
2015-04-21 18:44:06 +00:00
|
|
|
llvm_unreachable("unhandled opcode found in expression");
|
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
2015-01-13 23:39:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|