1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 03:33:20 +01:00
llvm-mirror/include/llvm/DebugInfo/DWARF/DWARFExpression.h
Reid Kleckner 96e8543691 [dwarfdump] Pretty print location expressions and location lists
Summary:
Based on Fred's patch here: https://reviews.llvm.org/D6771

I can't seem to commandeer the old review, so I'm creating a new one.

With that change the locations exrpessions are pretty printed inline in the
DIE tree. The output looks like this for debug_loc entries:

    DW_AT_location [DW_FORM_data4]        (0x00000000
       0x0000000000000001 - 0x000000000000000b: DW_OP_consts +3
       0x000000000000000b - 0x0000000000000012: DW_OP_consts +7
       0x0000000000000012 - 0x000000000000001b: DW_OP_reg0 RAX, DW_OP_piece 0x4
       0x000000000000001b - 0x0000000000000024: DW_OP_breg5 RDI+0)

And like this for debug_loc.dwo entries:
    DW_AT_location [DW_FORM_sec_offset]   (0x00000000
      Addr idx 2 (w/ length 190): DW_OP_consts +0, DW_OP_stack_value
      Addr idx 3 (w/ length 23): DW_OP_reg0 RAX, DW_OP_piece 0x4)

Simple locations without ranges are printed inline:

   DW_AT_location [DW_FORM_block1]       (DW_OP_reg4 RSI, DW_OP_piece 0x4, DW_OP_bit_piece 0x20 0x0)

The debug_loc(.dwo) dumping in changed accordingly to factor the code.

Reviewers: dblaikie, aprantl, friss

Subscribers: mgorny, javed.absar, hiraditya, llvm-commits, JDevlieghere

Differential Revision: https://reviews.llvm.org/D37123

llvm-svn: 312042
2017-08-29 21:41:21 +00:00

152 lines
4.5 KiB
C++

//===--- DWARFExpression.h - DWARF Expression handling ----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_DEBUGINFO_DWARFEXPRESSION_H
#define LLVM_DEBUGINFO_DWARFEXPRESSION_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/DataExtractor.h"
namespace llvm {
class DWARFUnit;
class MCRegisterInfo;
class raw_ostream;
class DWARFExpression {
public:
class iterator;
/// This class represents an Operation in the Expression. Each operation can
/// have up to 2 oprerands.
///
/// An Operation can be in Error state (check with isError()). This
/// means that it couldn't be decoded successfully and if it is the
/// case, all others fields contain undefined values.
class Operation {
public:
/// Size and signedness of expression operations' operands.
enum Encoding : uint8_t {
Size1 = 0,
Size2 = 1,
Size4 = 2,
Size8 = 3,
SizeLEB = 4,
SizeAddr = 5,
SizeRefAddr = 6,
SizeBlock = 7, ///< Preceding operand contains block size
SignBit = 0x8,
SignedSize1 = SignBit | Size1,
SignedSize2 = SignBit | Size2,
SignedSize4 = SignBit | Size4,
SignedSize8 = SignBit | Size8,
SignedSizeLEB = SignBit | SizeLEB,
SizeNA = 0xFF ///< Unused operands get this encoding.
};
enum DwarfVersion : uint8_t {
DwarfNA, ///< Serves as a marker for unused entries
Dwarf2 = 2,
Dwarf3,
Dwarf4
};
/// Description of the encoding of one expression Op.
struct Description {
DwarfVersion Version; ///< Dwarf version where the Op was introduced.
Encoding Op[2]; ///< Encoding for Op operands, or SizeNA.
Description(DwarfVersion Version = DwarfNA, Encoding Op1 = SizeNA,
Encoding Op2 = SizeNA)
: Version(Version) {
Op[0] = Op1;
Op[1] = Op2;
}
};
private:
friend class DWARFExpression::iterator;
uint8_t Opcode; ///< The Op Opcode, DW_OP_<something>.
Description Desc;
bool Error;
uint32_t EndOffset;
uint64_t Operands[2];
public:
Description &getDescription() { return Desc; }
uint8_t getCode() { return Opcode; }
uint64_t getRawOperand(unsigned Idx) { return Operands[Idx]; }
uint32_t getEndOffset() { return EndOffset; }
bool extract(DataExtractor Data, uint16_t Version, uint8_t AddressSize,
uint32_t Offset);
bool isError() { return Error; }
bool print(raw_ostream &OS, const DWARFExpression *U,
const MCRegisterInfo *RegInfo, bool isEH);
};
/// An iterator to go through the expression operations.
class iterator
: public iterator_facade_base<iterator, std::forward_iterator_tag, Operation> {
friend class DWARFExpression;
DWARFExpression *Expr;
uint32_t Offset;
Operation Op;
iterator(DWARFExpression *Expr, uint32_t Offset)
: Expr(Expr), Offset(Offset) {
Op.Error =
Offset >= Expr->Data.getData().size() ||
!Op.extract(Expr->Data, Expr->Version, Expr->AddressSize, Offset);
}
public:
class Operation &operator++() {
Offset = Op.isError() ? Expr->Data.getData().size() : Op.EndOffset;
Op.Error =
Offset >= Expr->Data.getData().size() ||
!Op.extract(Expr->Data, Expr->Version, Expr->AddressSize, Offset);
return Op;
}
class Operation &operator*() {
return Op;
}
// Comparison operators are provided out of line.
friend bool operator==(const iterator &, const iterator &);
};
DWARFExpression(DataExtractor Data, uint16_t Version, uint8_t AddressSize)
: Data(Data), Version(Version), AddressSize(AddressSize) {
assert(AddressSize == 8 || AddressSize == 4);
}
iterator begin() { return iterator(this, 0); }
iterator end() { return iterator(this, Data.getData().size()); }
void print(raw_ostream &OS, const MCRegisterInfo *RegInfo);
private:
DataExtractor Data;
uint16_t Version;
uint8_t AddressSize;
};
inline bool operator==(const DWARFExpression::iterator &LHS,
const DWARFExpression::iterator &RHS) {
return LHS.Expr == RHS.Expr && LHS.Offset == RHS.Offset;
}
inline bool operator!=(const DWARFExpression::iterator &LHS,
const DWARFExpression::iterator &RHS) {
return !(LHS == RHS);
}
}
#endif