2015-01-13 06:19:22 +08:00
|
|
|
//===-- llvm/CodeGen/DwarfExpression.h - Dwarf Compile Unit ---*- C++ -*--===//
|
|
|
|
//
|
|
|
|
// 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 compile unit.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXPRESSION_H
|
|
|
|
#define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXPRESSION_H
|
|
|
|
|
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
2015-01-14 07:39:11 +08:00
|
|
|
#include "llvm/IR/DebugInfo.h"
|
2015-01-14 19:23:27 +08:00
|
|
|
#include "llvm/Support/DataTypes.h"
|
2015-01-13 06:19:22 +08:00
|
|
|
|
|
|
|
namespace llvm {
|
|
|
|
|
2015-01-13 07:36:56 +08:00
|
|
|
class AsmPrinter;
|
2015-01-13 08:04:06 +08:00
|
|
|
class ByteStreamer;
|
2015-01-13 07:36:56 +08:00
|
|
|
class TargetRegisterInfo;
|
2015-01-14 09:01:22 +08:00
|
|
|
class DwarfUnit;
|
|
|
|
class DIELoc;
|
2015-01-13 06:19:22 +08:00
|
|
|
|
|
|
|
/// Base class containing the logic for constructing DWARF expressions
|
|
|
|
/// independently of whether they are emitted into a DIE or into a .debug_loc
|
|
|
|
/// entry.
|
|
|
|
class DwarfExpression {
|
2015-01-13 06:19:26 +08:00
|
|
|
protected:
|
2015-01-13 07:36:56 +08:00
|
|
|
// Various convenience accessors that extract things out of AsmPrinter.
|
2015-03-03 06:02:33 +08:00
|
|
|
const TargetRegisterInfo &TRI;
|
|
|
|
unsigned DwarfVersion;
|
2015-01-13 07:36:56 +08:00
|
|
|
|
2015-01-13 06:19:22 +08:00
|
|
|
public:
|
2015-03-03 06:02:33 +08:00
|
|
|
DwarfExpression(const TargetRegisterInfo &TRI,
|
2015-05-21 06:37:48 +08:00
|
|
|
unsigned DwarfVersion)
|
|
|
|
: TRI(TRI), DwarfVersion(DwarfVersion) {}
|
2015-01-13 07:36:50 +08:00
|
|
|
virtual ~DwarfExpression() {}
|
2015-01-13 06:19:22 +08:00
|
|
|
|
2015-01-14 07:11:07 +08:00
|
|
|
/// Output a dwarf operand and an optional assembler comment.
|
|
|
|
virtual void EmitOp(uint8_t Op, const char *Comment = nullptr) = 0;
|
|
|
|
/// Emit a raw signed value.
|
2015-03-11 03:23:37 +08:00
|
|
|
virtual void EmitSigned(int64_t Value) = 0;
|
2015-01-14 07:11:07 +08:00
|
|
|
/// Emit a raw unsigned value.
|
2015-03-11 03:23:37 +08:00
|
|
|
virtual void EmitUnsigned(uint64_t Value) = 0;
|
2015-01-14 07:11:07 +08:00
|
|
|
/// Return whether the given machine register is the frame register in the
|
|
|
|
/// current function.
|
2015-01-14 07:10:43 +08:00
|
|
|
virtual bool isFrameRegister(unsigned MachineReg) = 0;
|
2015-01-13 06:19:26 +08:00
|
|
|
|
2015-01-13 06:19:22 +08:00
|
|
|
/// Emit a dwarf register operation.
|
2015-01-14 07:11:07 +08:00
|
|
|
void AddReg(int DwarfReg, const char *Comment = nullptr);
|
2015-01-13 06:19:22 +08:00
|
|
|
/// Emit an (double-)indirect dwarf register operation.
|
|
|
|
void AddRegIndirect(int DwarfReg, int Offset, bool Deref = false);
|
|
|
|
|
|
|
|
/// Emit a dwarf register operation for describing
|
|
|
|
/// - a small value occupying only part of a register or
|
|
|
|
/// - a register representing only part of a value.
|
|
|
|
void AddOpPiece(unsigned SizeInBits, unsigned OffsetInBits = 0);
|
|
|
|
/// Emit a shift-right dwarf expression.
|
|
|
|
void AddShr(unsigned ShiftBy);
|
|
|
|
|
2015-01-13 06:19:26 +08:00
|
|
|
/// Emit an indirect dwarf register operation for the given machine register.
|
2015-01-14 09:01:28 +08:00
|
|
|
/// \return false if no DWARF register exists for MachineReg.
|
2015-01-14 07:11:07 +08:00
|
|
|
bool AddMachineRegIndirect(unsigned MachineReg, int Offset = 0);
|
2015-01-13 06:19:26 +08:00
|
|
|
|
2015-01-13 06:19:22 +08:00
|
|
|
/// \brief Emit a partial DWARF register operation.
|
2015-01-14 07:11:07 +08:00
|
|
|
/// \param MachineReg the register
|
|
|
|
/// \param PieceSizeInBits size and
|
|
|
|
/// \param PieceOffsetInBits offset of the piece in bits, if this is one
|
|
|
|
/// piece of an aggregate value.
|
2015-01-13 06:19:22 +08:00
|
|
|
///
|
|
|
|
/// If size and offset is zero an operation for the entire
|
|
|
|
/// register is emitted: Some targets do not provide a DWARF
|
|
|
|
/// register number for every register. If this is the case, this
|
|
|
|
/// function will attempt to emit a DWARF register by emitting a
|
|
|
|
/// piece of a super-register or by piecing together multiple
|
|
|
|
/// subregisters that alias the register.
|
2015-01-14 09:01:28 +08:00
|
|
|
///
|
|
|
|
/// \return false if no DWARF register exists for MachineReg.
|
|
|
|
bool AddMachineRegPiece(unsigned MachineReg, unsigned PieceSizeInBits = 0,
|
2015-01-13 06:19:22 +08:00
|
|
|
unsigned PieceOffsetInBits = 0);
|
2015-01-13 08:04:06 +08:00
|
|
|
|
|
|
|
/// Emit a signed constant.
|
|
|
|
void AddSignedConstant(int Value);
|
|
|
|
/// Emit an unsigned constant.
|
|
|
|
void AddUnsignedConstant(unsigned Value);
|
|
|
|
|
2015-04-22 02:44:06 +08:00
|
|
|
/// \brief Emit an entire expression on top of a machine register location.
|
|
|
|
///
|
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
2015-01-14 07:39:11 +08:00
|
|
|
/// \param PieceOffsetInBits If this is one piece out of a fragmented
|
|
|
|
/// location, this is the offset of the piece inside the entire variable.
|
2015-01-14 09:01:28 +08:00
|
|
|
/// \return false if no DWARF register exists for MachineReg.
|
2015-04-30 00:38:44 +08:00
|
|
|
bool AddMachineRegExpression(const DIExpression *Expr, unsigned MachineReg,
|
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
2015-01-14 07:39:11 +08:00
|
|
|
unsigned PieceOffsetInBits = 0);
|
2015-01-22 08:00:59 +08:00
|
|
|
/// Emit a the operations remaining the DIExpressionIterator I.
|
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
2015-01-14 07:39:11 +08:00
|
|
|
/// \param PieceOffsetInBits If this is one piece out of a fragmented
|
|
|
|
/// location, this is the offset of the piece inside the entire variable.
|
2015-04-30 00:38:44 +08:00
|
|
|
void AddExpression(DIExpression::expr_op_iterator I,
|
|
|
|
DIExpression::expr_op_iterator E,
|
2015-02-18 06:30:56 +08:00
|
|
|
unsigned PieceOffsetInBits = 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.
llvm-svn: 225851
2015-01-14 07:39:11 +08:00
|
|
|
};
|
2015-01-13 08:04:06 +08:00
|
|
|
|
|
|
|
/// DwarfExpression implementation for .debug_loc entries.
|
|
|
|
class DebugLocDwarfExpression : public DwarfExpression {
|
|
|
|
ByteStreamer &BS;
|
|
|
|
|
|
|
|
public:
|
2015-03-03 06:02:33 +08:00
|
|
|
DebugLocDwarfExpression(const TargetRegisterInfo &TRI,
|
2015-05-21 06:37:48 +08:00
|
|
|
unsigned DwarfVersion, ByteStreamer &BS)
|
|
|
|
: DwarfExpression(TRI, DwarfVersion), BS(BS) {}
|
2015-01-13 08:04:06 +08:00
|
|
|
|
2015-01-14 07:11:07 +08:00
|
|
|
void EmitOp(uint8_t Op, const char *Comment = nullptr) override;
|
2015-03-11 03:23:37 +08:00
|
|
|
void EmitSigned(int64_t Value) override;
|
|
|
|
void EmitUnsigned(uint64_t Value) override;
|
2015-01-14 07:10:43 +08:00
|
|
|
bool isFrameRegister(unsigned MachineReg) override;
|
2015-01-13 06:19:22 +08:00
|
|
|
};
|
2015-01-14 09:01:22 +08:00
|
|
|
|
|
|
|
/// DwarfExpression implementation for singular DW_AT_location.
|
|
|
|
class DIEDwarfExpression : public DwarfExpression {
|
2015-03-03 06:02:33 +08:00
|
|
|
const AsmPrinter &AP;
|
2015-01-14 09:01:22 +08:00
|
|
|
DwarfUnit &DU;
|
|
|
|
DIELoc &DIE;
|
|
|
|
|
|
|
|
public:
|
2015-03-03 06:02:33 +08:00
|
|
|
DIEDwarfExpression(const AsmPrinter &AP, DwarfUnit &DU, DIELoc &DIE);
|
2015-01-14 09:01:22 +08:00
|
|
|
void EmitOp(uint8_t Op, const char *Comment = nullptr) override;
|
2015-03-11 03:23:37 +08:00
|
|
|
void EmitSigned(int64_t Value) override;
|
|
|
|
void EmitUnsigned(uint64_t Value) override;
|
2015-01-14 09:01:22 +08:00
|
|
|
bool isFrameRegister(unsigned MachineReg) override;
|
|
|
|
};
|
2015-06-19 23:57:42 +08:00
|
|
|
} // namespace llvm
|
2015-01-13 06:19:22 +08:00
|
|
|
|
|
|
|
#endif
|