1//===-- DWARFExpression.cpp -----------------------------------------------===// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7//===----------------------------------------------------------------------===// 26 std::vector<Desc> Descriptions;
27 Descriptions.resize(0xff);
70for (
uint16_t LA = DW_OP_lit0; LA <= DW_OP_lit31; ++LA)
72for (
uint16_t LA = DW_OP_reg0; LA <= DW_OP_reg31; ++LA)
74for (
uint16_t LA = DW_OP_breg0; LA <= DW_OP_breg31; ++LA)
90 Descriptions[DW_OP_implicit_value] =
93 Descriptions[DW_OP_implicit_pointer] =
99 Descriptions[DW_OP_regval_type] =
101 Descriptions[DW_OP_WASM_location] =
107// This Description acts as a marker that getSubOpDesc must be called 108// to fetch the final Description for the operation. Each such final 109// Description must share the same first SizeSubOpLEB operand. 115// Handle possible corrupted or unsupported operation. 116if (Opcode >= Descriptions.
size())
118return Descriptions[Opcode];
127staticconstexprunsigned LlvmUserDescriptionsSize = 1
128#define HANDLE_DW_OP_LLVM_USEROP(ID, NAME) +1 129#include "llvm/BinaryFormat/Dwarf.def" 131 std::vector<Desc> Descriptions;
132 Descriptions.resize(LlvmUserDescriptionsSize);
138assert(Opcode == DW_OP_LLVM_user);
145 std::optional<DwarfFormat>
Format) {
147 Opcode = Data.getU8(&
Offset);
155for (
unsigned Operand = 0; Operand <
Desc.
Op.
size(); ++Operand) {
161assert(Operand == 0 &&
"SubOp operand must be the first operand");
162 Operands[Operand] = Data.getULEB128(&
Offset);
167"SizeSubOpLEB Description must begin with SizeSubOpLEB operand");
170 Operands[Operand] = Data.getU8(&
Offset);
172 Operands[Operand] = (int8_t)Operands[Operand];
175 Operands[Operand] = Data.getU16(&
Offset);
177 Operands[Operand] = (int16_t)Operands[Operand];
180 Operands[Operand] = Data.getU32(&
Offset);
182 Operands[Operand] = (int32_t)Operands[Operand];
185 Operands[Operand] = Data.getU64(&
Offset);
188 Operands[Operand] = Data.getUnsigned(&
Offset, AddressSize);
198 Operands[Operand] = Data.getSLEB128(&
Offset);
200 Operands[Operand] = Data.getULEB128(&
Offset);
203 Operands[Operand] = Data.getULEB128(&
Offset);
207switch (Operands[0]) {
212 Operands[Operand] = Data.getULEB128(&
Offset);
214case 3:
// global as uint32 215 Operands[Operand] = Data.getU32(&
Offset);
218returnfalse;
// Unknown Wasm location 222// We need a size, so this cannot be the first operand 225// Store the offset of the block as the value. 226 Operands[Operand] =
Offset;
227Offset += Operands[Operand - 1];
233 OperandEndOffsets[Operand] =
Offset;
249auto Die = U->getDIEForOffset(U->getOffset() +
Operands[Operand]);
250if (Die && Die.getTag() == dwarf::DW_TAG_base_type) {
256OS <<
" \"" << *
Name <<
"\"";
272if (Opcode == DW_OP_bregx || Opcode == DW_OP_regx ||
273 Opcode == DW_OP_regval_type)
275elseif (Opcode >= DW_OP_breg0 && Opcode < DW_OP_bregx)
276 DwarfRegNum = Opcode - DW_OP_breg0;
278 DwarfRegNum = Opcode - DW_OP_reg0;
282if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31) ||
283 Opcode == DW_OP_bregx)
288if (Opcode == DW_OP_regval_type)
306OS <<
"<decoding error>";
314if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31) ||
315 (Opcode >= DW_OP_reg0 && Opcode <= DW_OP_reg31) ||
316 Opcode == DW_OP_bregx || Opcode == DW_OP_regx ||
317 Opcode == DW_OP_regval_type)
321for (
unsigned Operand = 0; Operand <
Desc.
Op.
size(); ++Operand) {
327assert(!SubName.
empty() &&
"DW_OP SubOp has no name!");
330// For DW_OP_convert the operand may be 0 to indicate that conversion to 331// the generic type should be done. The same holds for DW_OP_reinterpret, 332// which is currently not supported. 333if (Opcode == DW_OP_convert &&
Operands[Operand] == 0)
343case 3:
// global as uint32 351for (
unsigned i = 0; i <
Operands[Operand - 1]; ++i)
356elseif (Opcode != DW_OP_entry_value &&
357 Opcode != DW_OP_GNU_entry_value)
368if (Data.getData().empty())
371for (
auto &
Op : *
this) {
372 DumpOpts.
IsEH = IsEH;
375while (FailOffset < Data.getData().size())
376OS <<
format(
" %02x", Data.getU8(&FailOffset));
388if (EntryValExprSize) {
390if (EntryValExprSize == 0)
400for (
unsigned Operand = 0; Operand <
Op.Desc.
Op.
size(); ++Operand) {
404// For DW_OP_convert the operand may be 0 to indicate that conversion to 405// the generic type should be done, so don't look up a base type in that 406// case. The same holds for DW_OP_reinterpret, which is currently not 408if (
Op.Opcode == DW_OP_convert &&
Op.Operands[Operand] == 0)
410auto Die = U->getDIEForOffset(U->getOffset() +
Op.Operands[Operand]);
411if (!Die || Die.getTag() != dwarf::DW_TAG_base_type)
420for (
auto &
Op : *
this)
427/// A user-facing string representation of a DWARF expression. This might be an 428/// Address expression, in which case it will be implicitly dereferenced, or a 452case dwarf::DW_OP_regx: {
453// DW_OP_regx: A register, with the register num given as an operand. 454// Printed as the plain register name. 456autoRegName = GetNameForDWARFReg(DwarfRegNum,
false);
463case dwarf::DW_OP_bregx: {
466autoRegName = GetNameForDWARFReg(DwarfRegNum,
false);
475case dwarf::DW_OP_entry_value:
476case dwarf::DW_OP_GNU_entry_value: {
477// DW_OP_entry_value contains a sub-expression which must be rendered 489case dwarf::DW_OP_stack_value: {
490// The top stack entry should be treated as the actual value of tne 491// variable, rather than the address of the variable in memory. 496case dwarf::DW_OP_nop: {
499case dwarf::DW_OP_LLVM_user: {
504if (Opcode >= dwarf::DW_OP_reg0 && Opcode <= dwarf::DW_OP_reg31) {
505// DW_OP_reg<N>: A register, with the register num implied by the 506// opcode. Printed as the plain register name. 507uint64_t DwarfRegNum = Opcode - dwarf::DW_OP_reg0;
508autoRegName = GetNameForDWARFReg(DwarfRegNum,
false);
513 }
elseif (Opcode >= dwarf::DW_OP_breg0 &&
514 Opcode <= dwarf::DW_OP_breg31) {
515int DwarfRegNum = Opcode - dwarf::DW_OP_breg0;
517autoRegName = GetNameForDWARFReg(DwarfRegNum,
false);
525// If we hit an unknown operand, we don't know its effect on the stack, 526// so bail out on the whole expression. 528 << (int)Opcode <<
")>";
536if (Stack.size() != 1) {
537OS <<
"<stack of size " << Stack.size() <<
", expected 1>";
542OS <<
"[" << Stack.front().String <<
"]";
544OS << Stack.front().String;
556if (AddressSize !=
RHS.AddressSize || Format !=
RHS.Format)
558return Data.getData() ==
RHS.Data.getData();
mir Rename Register Operands
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallString class.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
This class represents an Operation in the Expression.
std::optional< unsigned > getSubCode() const
@ DwarfNA
Serves as a marker for unused entries.
static bool verify(const Operation &Op, DWARFUnit *U)
Verify Op. Does not affect the return of isError().
bool print(raw_ostream &OS, DIDumpOptions DumpOpts, const DWARFExpression *Expr, DWARFUnit *U) const
uint64_t getEndOffset() const
@ SizeSubOpLEB
The operand is a ULEB128 encoded SubOpcode.
@ SizeBlock
Preceding operand contains block size.
uint64_t getRawOperand(unsigned Idx) const
An iterator to go through the expression operations.
bool verify(DWARFUnit *U)
bool printCompact(raw_ostream &OS, std::function< StringRef(uint64_t RegNum, bool IsEH)> GetNameForDWARFReg=nullptr)
Print the expression in a format intended to be compact and useful to a user, but not perfectly unamb...
bool operator==(const DWARFExpression &RHS) const
void print(raw_ostream &OS, DIDumpOptions DumpOpts, DWARFUnit *U, bool IsEH=false) const
static bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS, DIDumpOptions DumpOpts, uint8_t Opcode, const ArrayRef< uint64_t > Operands)
uint8_t getU8(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint8_t value from *offset_ptr.
Lightweight error class with error context and mandatory checking.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an SmallVector or SmallString.
StringRef SubOperationEncodingString(unsigned OpEncoding, unsigned SubOpEncoding)
StringRef OperationEncodingString(unsigned Encoding)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
uint8_t getDwarfOffsetByteSize(DwarfFormat Format)
The size of a reference determined by the DWARF 32/64-bit format.
This is an optimization pass for GlobalISel generic memory operations.
static Desc getSubOpDesc(unsigned Opcode, unsigned SubOpcode)
static std::vector< Desc > getOpDescriptions()
static bool printCompactDWARFExpr(raw_ostream &OS, DWARFExpression::iterator I, const DWARFExpression::iterator E, std::function< StringRef(uint64_t RegNum, bool IsEH)> GetNameForDWARFReg=nullptr)
static void prettyPrintBaseTypeRef(DWARFUnit *U, raw_ostream &OS, DIDumpOptions DumpOpts, ArrayRef< uint64_t > Operands, unsigned Operand)
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
static Desc getDescImpl(ArrayRef< Desc > Descriptions, unsigned Opcode)
DWARFExpression::Operation Op
static Desc getOpDesc(unsigned Opcode)
static std::vector< Desc > getSubOpDescriptions()
Container for dump options that control which debug information will be dumped.
std::function< llvm::StringRef(uint64_t DwarfRegNum, bool IsEH)> GetNameForDWARFReg
Description of the encoding of one expression Op.
DwarfVersion Version
Dwarf version where the Op was introduced.
SmallVector< Encoding > Op
Encoding for Op operands.
A user-facing string representation of a DWARF expression.
PrintedExpr(ExprKind K=Address)