10b57cec5SDimitry Andric //===- llvm/CodeGen/DwarfExpression.cpp - Dwarf Debug Framework -----------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file contains support for writing dwarf debug info into asm files. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "DwarfExpression.h" 140b57cec5SDimitry Andric #include "DwarfCompileUnit.h" 150b57cec5SDimitry Andric #include "llvm/ADT/APInt.h" 160b57cec5SDimitry Andric #include "llvm/ADT/SmallBitVector.h" 170b57cec5SDimitry Andric #include "llvm/BinaryFormat/Dwarf.h" 18*8bcb0991SDimitry Andric #include "llvm/CodeGen/Register.h" 190b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h" 200b57cec5SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h" 210b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 220b57cec5SDimitry Andric #include <algorithm> 230b57cec5SDimitry Andric #include <cassert> 240b57cec5SDimitry Andric #include <cstdint> 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric using namespace llvm; 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric void DwarfExpression::emitConstu(uint64_t Value) { 290b57cec5SDimitry Andric if (Value < 32) 300b57cec5SDimitry Andric emitOp(dwarf::DW_OP_lit0 + Value); 310b57cec5SDimitry Andric else if (Value == std::numeric_limits<uint64_t>::max()) { 320b57cec5SDimitry Andric // Only do this for 64-bit values as the DWARF expression stack uses 330b57cec5SDimitry Andric // target-address-size values. 340b57cec5SDimitry Andric emitOp(dwarf::DW_OP_lit0); 350b57cec5SDimitry Andric emitOp(dwarf::DW_OP_not); 360b57cec5SDimitry Andric } else { 370b57cec5SDimitry Andric emitOp(dwarf::DW_OP_constu); 380b57cec5SDimitry Andric emitUnsigned(Value); 390b57cec5SDimitry Andric } 400b57cec5SDimitry Andric } 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric void DwarfExpression::addReg(int DwarfReg, const char *Comment) { 430b57cec5SDimitry Andric assert(DwarfReg >= 0 && "invalid negative dwarf register number"); 440b57cec5SDimitry Andric assert((isUnknownLocation() || isRegisterLocation()) && 450b57cec5SDimitry Andric "location description already locked down"); 460b57cec5SDimitry Andric LocationKind = Register; 470b57cec5SDimitry Andric if (DwarfReg < 32) { 480b57cec5SDimitry Andric emitOp(dwarf::DW_OP_reg0 + DwarfReg, Comment); 490b57cec5SDimitry Andric } else { 500b57cec5SDimitry Andric emitOp(dwarf::DW_OP_regx, Comment); 510b57cec5SDimitry Andric emitUnsigned(DwarfReg); 520b57cec5SDimitry Andric } 530b57cec5SDimitry Andric } 540b57cec5SDimitry Andric 550b57cec5SDimitry Andric void DwarfExpression::addBReg(int DwarfReg, int Offset) { 560b57cec5SDimitry Andric assert(DwarfReg >= 0 && "invalid negative dwarf register number"); 570b57cec5SDimitry Andric assert(!isRegisterLocation() && "location description already locked down"); 580b57cec5SDimitry Andric if (DwarfReg < 32) { 590b57cec5SDimitry Andric emitOp(dwarf::DW_OP_breg0 + DwarfReg); 600b57cec5SDimitry Andric } else { 610b57cec5SDimitry Andric emitOp(dwarf::DW_OP_bregx); 620b57cec5SDimitry Andric emitUnsigned(DwarfReg); 630b57cec5SDimitry Andric } 640b57cec5SDimitry Andric emitSigned(Offset); 650b57cec5SDimitry Andric } 660b57cec5SDimitry Andric 670b57cec5SDimitry Andric void DwarfExpression::addFBReg(int Offset) { 680b57cec5SDimitry Andric emitOp(dwarf::DW_OP_fbreg); 690b57cec5SDimitry Andric emitSigned(Offset); 700b57cec5SDimitry Andric } 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric void DwarfExpression::addOpPiece(unsigned SizeInBits, unsigned OffsetInBits) { 730b57cec5SDimitry Andric if (!SizeInBits) 740b57cec5SDimitry Andric return; 750b57cec5SDimitry Andric 760b57cec5SDimitry Andric const unsigned SizeOfByte = 8; 770b57cec5SDimitry Andric if (OffsetInBits > 0 || SizeInBits % SizeOfByte) { 780b57cec5SDimitry Andric emitOp(dwarf::DW_OP_bit_piece); 790b57cec5SDimitry Andric emitUnsigned(SizeInBits); 800b57cec5SDimitry Andric emitUnsigned(OffsetInBits); 810b57cec5SDimitry Andric } else { 820b57cec5SDimitry Andric emitOp(dwarf::DW_OP_piece); 830b57cec5SDimitry Andric unsigned ByteSize = SizeInBits / SizeOfByte; 840b57cec5SDimitry Andric emitUnsigned(ByteSize); 850b57cec5SDimitry Andric } 860b57cec5SDimitry Andric this->OffsetInBits += SizeInBits; 870b57cec5SDimitry Andric } 880b57cec5SDimitry Andric 890b57cec5SDimitry Andric void DwarfExpression::addShr(unsigned ShiftBy) { 900b57cec5SDimitry Andric emitConstu(ShiftBy); 910b57cec5SDimitry Andric emitOp(dwarf::DW_OP_shr); 920b57cec5SDimitry Andric } 930b57cec5SDimitry Andric 940b57cec5SDimitry Andric void DwarfExpression::addAnd(unsigned Mask) { 950b57cec5SDimitry Andric emitConstu(Mask); 960b57cec5SDimitry Andric emitOp(dwarf::DW_OP_and); 970b57cec5SDimitry Andric } 980b57cec5SDimitry Andric 990b57cec5SDimitry Andric bool DwarfExpression::addMachineReg(const TargetRegisterInfo &TRI, 1000b57cec5SDimitry Andric unsigned MachineReg, unsigned MaxSize) { 101*8bcb0991SDimitry Andric if (!llvm::Register::isPhysicalRegister(MachineReg)) { 1020b57cec5SDimitry Andric if (isFrameRegister(TRI, MachineReg)) { 1030b57cec5SDimitry Andric DwarfRegs.push_back({-1, 0, nullptr}); 1040b57cec5SDimitry Andric return true; 1050b57cec5SDimitry Andric } 1060b57cec5SDimitry Andric return false; 1070b57cec5SDimitry Andric } 1080b57cec5SDimitry Andric 1090b57cec5SDimitry Andric int Reg = TRI.getDwarfRegNum(MachineReg, false); 1100b57cec5SDimitry Andric 1110b57cec5SDimitry Andric // If this is a valid register number, emit it. 1120b57cec5SDimitry Andric if (Reg >= 0) { 1130b57cec5SDimitry Andric DwarfRegs.push_back({Reg, 0, nullptr}); 1140b57cec5SDimitry Andric return true; 1150b57cec5SDimitry Andric } 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric // Walk up the super-register chain until we find a valid number. 1180b57cec5SDimitry Andric // For example, EAX on x86_64 is a 32-bit fragment of RAX with offset 0. 1190b57cec5SDimitry Andric for (MCSuperRegIterator SR(MachineReg, &TRI); SR.isValid(); ++SR) { 1200b57cec5SDimitry Andric Reg = TRI.getDwarfRegNum(*SR, false); 1210b57cec5SDimitry Andric if (Reg >= 0) { 1220b57cec5SDimitry Andric unsigned Idx = TRI.getSubRegIndex(*SR, MachineReg); 1230b57cec5SDimitry Andric unsigned Size = TRI.getSubRegIdxSize(Idx); 1240b57cec5SDimitry Andric unsigned RegOffset = TRI.getSubRegIdxOffset(Idx); 1250b57cec5SDimitry Andric DwarfRegs.push_back({Reg, 0, "super-register"}); 1260b57cec5SDimitry Andric // Use a DW_OP_bit_piece to describe the sub-register. 1270b57cec5SDimitry Andric setSubRegisterPiece(Size, RegOffset); 1280b57cec5SDimitry Andric return true; 1290b57cec5SDimitry Andric } 1300b57cec5SDimitry Andric } 1310b57cec5SDimitry Andric 1320b57cec5SDimitry Andric // Otherwise, attempt to find a covering set of sub-register numbers. 1330b57cec5SDimitry Andric // For example, Q0 on ARM is a composition of D0+D1. 1340b57cec5SDimitry Andric unsigned CurPos = 0; 1350b57cec5SDimitry Andric // The size of the register in bits. 1360b57cec5SDimitry Andric const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(MachineReg); 1370b57cec5SDimitry Andric unsigned RegSize = TRI.getRegSizeInBits(*RC); 1380b57cec5SDimitry Andric // Keep track of the bits in the register we already emitted, so we 1390b57cec5SDimitry Andric // can avoid emitting redundant aliasing subregs. Because this is 1400b57cec5SDimitry Andric // just doing a greedy scan of all subregisters, it is possible that 1410b57cec5SDimitry Andric // this doesn't find a combination of subregisters that fully cover 1420b57cec5SDimitry Andric // the register (even though one may exist). 1430b57cec5SDimitry Andric SmallBitVector Coverage(RegSize, false); 1440b57cec5SDimitry Andric for (MCSubRegIterator SR(MachineReg, &TRI); SR.isValid(); ++SR) { 1450b57cec5SDimitry Andric unsigned Idx = TRI.getSubRegIndex(MachineReg, *SR); 1460b57cec5SDimitry Andric unsigned Size = TRI.getSubRegIdxSize(Idx); 1470b57cec5SDimitry Andric unsigned Offset = TRI.getSubRegIdxOffset(Idx); 1480b57cec5SDimitry Andric Reg = TRI.getDwarfRegNum(*SR, false); 1490b57cec5SDimitry Andric if (Reg < 0) 1500b57cec5SDimitry Andric continue; 1510b57cec5SDimitry Andric 1520b57cec5SDimitry Andric // Intersection between the bits we already emitted and the bits 1530b57cec5SDimitry Andric // covered by this subregister. 1540b57cec5SDimitry Andric SmallBitVector CurSubReg(RegSize, false); 1550b57cec5SDimitry Andric CurSubReg.set(Offset, Offset + Size); 1560b57cec5SDimitry Andric 1570b57cec5SDimitry Andric // If this sub-register has a DWARF number and we haven't covered 1580b57cec5SDimitry Andric // its range, emit a DWARF piece for it. 1590b57cec5SDimitry Andric if (CurSubReg.test(Coverage)) { 1600b57cec5SDimitry Andric // Emit a piece for any gap in the coverage. 1610b57cec5SDimitry Andric if (Offset > CurPos) 1620b57cec5SDimitry Andric DwarfRegs.push_back({-1, Offset - CurPos, "no DWARF register encoding"}); 1630b57cec5SDimitry Andric DwarfRegs.push_back( 1640b57cec5SDimitry Andric {Reg, std::min<unsigned>(Size, MaxSize - Offset), "sub-register"}); 1650b57cec5SDimitry Andric if (Offset >= MaxSize) 1660b57cec5SDimitry Andric break; 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric // Mark it as emitted. 1690b57cec5SDimitry Andric Coverage.set(Offset, Offset + Size); 1700b57cec5SDimitry Andric CurPos = Offset + Size; 1710b57cec5SDimitry Andric } 1720b57cec5SDimitry Andric } 1730b57cec5SDimitry Andric // Failed to find any DWARF encoding. 1740b57cec5SDimitry Andric if (CurPos == 0) 1750b57cec5SDimitry Andric return false; 1760b57cec5SDimitry Andric // Found a partial or complete DWARF encoding. 1770b57cec5SDimitry Andric if (CurPos < RegSize) 1780b57cec5SDimitry Andric DwarfRegs.push_back({-1, RegSize - CurPos, "no DWARF register encoding"}); 1790b57cec5SDimitry Andric return true; 1800b57cec5SDimitry Andric } 1810b57cec5SDimitry Andric 1820b57cec5SDimitry Andric void DwarfExpression::addStackValue() { 1830b57cec5SDimitry Andric if (DwarfVersion >= 4) 1840b57cec5SDimitry Andric emitOp(dwarf::DW_OP_stack_value); 1850b57cec5SDimitry Andric } 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric void DwarfExpression::addSignedConstant(int64_t Value) { 1880b57cec5SDimitry Andric assert(isImplicitLocation() || isUnknownLocation()); 1890b57cec5SDimitry Andric LocationKind = Implicit; 1900b57cec5SDimitry Andric emitOp(dwarf::DW_OP_consts); 1910b57cec5SDimitry Andric emitSigned(Value); 1920b57cec5SDimitry Andric } 1930b57cec5SDimitry Andric 1940b57cec5SDimitry Andric void DwarfExpression::addUnsignedConstant(uint64_t Value) { 1950b57cec5SDimitry Andric assert(isImplicitLocation() || isUnknownLocation()); 1960b57cec5SDimitry Andric LocationKind = Implicit; 1970b57cec5SDimitry Andric emitConstu(Value); 1980b57cec5SDimitry Andric } 1990b57cec5SDimitry Andric 2000b57cec5SDimitry Andric void DwarfExpression::addUnsignedConstant(const APInt &Value) { 2010b57cec5SDimitry Andric assert(isImplicitLocation() || isUnknownLocation()); 2020b57cec5SDimitry Andric LocationKind = Implicit; 2030b57cec5SDimitry Andric 2040b57cec5SDimitry Andric unsigned Size = Value.getBitWidth(); 2050b57cec5SDimitry Andric const uint64_t *Data = Value.getRawData(); 2060b57cec5SDimitry Andric 2070b57cec5SDimitry Andric // Chop it up into 64-bit pieces, because that's the maximum that 2080b57cec5SDimitry Andric // addUnsignedConstant takes. 2090b57cec5SDimitry Andric unsigned Offset = 0; 2100b57cec5SDimitry Andric while (Offset < Size) { 2110b57cec5SDimitry Andric addUnsignedConstant(*Data++); 2120b57cec5SDimitry Andric if (Offset == 0 && Size <= 64) 2130b57cec5SDimitry Andric break; 2140b57cec5SDimitry Andric addStackValue(); 2150b57cec5SDimitry Andric addOpPiece(std::min(Size - Offset, 64u), Offset); 2160b57cec5SDimitry Andric Offset += 64; 2170b57cec5SDimitry Andric } 2180b57cec5SDimitry Andric } 2190b57cec5SDimitry Andric 2200b57cec5SDimitry Andric bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI, 2210b57cec5SDimitry Andric DIExpressionCursor &ExprCursor, 2220b57cec5SDimitry Andric unsigned MachineReg, 2230b57cec5SDimitry Andric unsigned FragmentOffsetInBits) { 2240b57cec5SDimitry Andric auto Fragment = ExprCursor.getFragmentInfo(); 2250b57cec5SDimitry Andric if (!addMachineReg(TRI, MachineReg, Fragment ? Fragment->SizeInBits : ~1U)) { 2260b57cec5SDimitry Andric LocationKind = Unknown; 2270b57cec5SDimitry Andric return false; 2280b57cec5SDimitry Andric } 2290b57cec5SDimitry Andric 2300b57cec5SDimitry Andric bool HasComplexExpression = false; 2310b57cec5SDimitry Andric auto Op = ExprCursor.peek(); 2320b57cec5SDimitry Andric if (Op && Op->getOp() != dwarf::DW_OP_LLVM_fragment) 2330b57cec5SDimitry Andric HasComplexExpression = true; 2340b57cec5SDimitry Andric 2350b57cec5SDimitry Andric // If the register can only be described by a complex expression (i.e., 2360b57cec5SDimitry Andric // multiple subregisters) it doesn't safely compose with another complex 2370b57cec5SDimitry Andric // expression. For example, it is not possible to apply a DW_OP_deref 2380b57cec5SDimitry Andric // operation to multiple DW_OP_pieces. 2390b57cec5SDimitry Andric if (HasComplexExpression && DwarfRegs.size() > 1) { 2400b57cec5SDimitry Andric DwarfRegs.clear(); 2410b57cec5SDimitry Andric LocationKind = Unknown; 2420b57cec5SDimitry Andric return false; 2430b57cec5SDimitry Andric } 2440b57cec5SDimitry Andric 245*8bcb0991SDimitry Andric // Handle simple register locations. If we are supposed to emit 246*8bcb0991SDimitry Andric // a call site parameter expression and if that expression is just a register 247*8bcb0991SDimitry Andric // location, emit it with addBReg and offset 0, because we should emit a DWARF 248*8bcb0991SDimitry Andric // expression representing a value, rather than a location. 249*8bcb0991SDimitry Andric if (!isMemoryLocation() && !HasComplexExpression && 250*8bcb0991SDimitry Andric (!isParameterValue() || isEntryValue())) { 2510b57cec5SDimitry Andric for (auto &Reg : DwarfRegs) { 2520b57cec5SDimitry Andric if (Reg.DwarfRegNo >= 0) 2530b57cec5SDimitry Andric addReg(Reg.DwarfRegNo, Reg.Comment); 2540b57cec5SDimitry Andric addOpPiece(Reg.Size); 2550b57cec5SDimitry Andric } 2560b57cec5SDimitry Andric 257*8bcb0991SDimitry Andric if (isEntryValue()) 258*8bcb0991SDimitry Andric finalizeEntryValue(); 259*8bcb0991SDimitry Andric 260*8bcb0991SDimitry Andric if (isEntryValue() && !isParameterValue() && DwarfVersion >= 4) 2610b57cec5SDimitry Andric emitOp(dwarf::DW_OP_stack_value); 2620b57cec5SDimitry Andric 2630b57cec5SDimitry Andric DwarfRegs.clear(); 2640b57cec5SDimitry Andric return true; 2650b57cec5SDimitry Andric } 2660b57cec5SDimitry Andric 2670b57cec5SDimitry Andric // Don't emit locations that cannot be expressed without DW_OP_stack_value. 2680b57cec5SDimitry Andric if (DwarfVersion < 4) 2690b57cec5SDimitry Andric if (any_of(ExprCursor, [](DIExpression::ExprOperand Op) -> bool { 2700b57cec5SDimitry Andric return Op.getOp() == dwarf::DW_OP_stack_value; 2710b57cec5SDimitry Andric })) { 2720b57cec5SDimitry Andric DwarfRegs.clear(); 2730b57cec5SDimitry Andric LocationKind = Unknown; 2740b57cec5SDimitry Andric return false; 2750b57cec5SDimitry Andric } 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andric assert(DwarfRegs.size() == 1); 2780b57cec5SDimitry Andric auto Reg = DwarfRegs[0]; 2790b57cec5SDimitry Andric bool FBReg = isFrameRegister(TRI, MachineReg); 2800b57cec5SDimitry Andric int SignedOffset = 0; 2810b57cec5SDimitry Andric assert(Reg.Size == 0 && "subregister has same size as superregister"); 2820b57cec5SDimitry Andric 2830b57cec5SDimitry Andric // Pattern-match combinations for which more efficient representations exist. 2840b57cec5SDimitry Andric // [Reg, DW_OP_plus_uconst, Offset] --> [DW_OP_breg, Offset]. 2850b57cec5SDimitry Andric if (Op && (Op->getOp() == dwarf::DW_OP_plus_uconst)) { 286*8bcb0991SDimitry Andric uint64_t Offset = Op->getArg(0); 287*8bcb0991SDimitry Andric uint64_t IntMax = static_cast<uint64_t>(std::numeric_limits<int>::max()); 288*8bcb0991SDimitry Andric if (Offset <= IntMax) { 289*8bcb0991SDimitry Andric SignedOffset = Offset; 2900b57cec5SDimitry Andric ExprCursor.take(); 2910b57cec5SDimitry Andric } 292*8bcb0991SDimitry Andric } 2930b57cec5SDimitry Andric 2940b57cec5SDimitry Andric // [Reg, DW_OP_constu, Offset, DW_OP_plus] --> [DW_OP_breg, Offset] 2950b57cec5SDimitry Andric // [Reg, DW_OP_constu, Offset, DW_OP_minus] --> [DW_OP_breg,-Offset] 2960b57cec5SDimitry Andric // If Reg is a subregister we need to mask it out before subtracting. 2970b57cec5SDimitry Andric if (Op && Op->getOp() == dwarf::DW_OP_constu) { 298*8bcb0991SDimitry Andric uint64_t Offset = Op->getArg(0); 299*8bcb0991SDimitry Andric uint64_t IntMax = static_cast<uint64_t>(std::numeric_limits<int>::max()); 3000b57cec5SDimitry Andric auto N = ExprCursor.peekNext(); 301*8bcb0991SDimitry Andric if (N && N->getOp() == dwarf::DW_OP_plus && Offset <= IntMax) { 302*8bcb0991SDimitry Andric SignedOffset = Offset; 303*8bcb0991SDimitry Andric ExprCursor.consume(2); 304*8bcb0991SDimitry Andric } else if (N && N->getOp() == dwarf::DW_OP_minus && 305*8bcb0991SDimitry Andric !SubRegisterSizeInBits && Offset <= IntMax + 1) { 306*8bcb0991SDimitry Andric SignedOffset = -static_cast<int64_t>(Offset); 3070b57cec5SDimitry Andric ExprCursor.consume(2); 3080b57cec5SDimitry Andric } 3090b57cec5SDimitry Andric } 3100b57cec5SDimitry Andric 3110b57cec5SDimitry Andric if (FBReg) 3120b57cec5SDimitry Andric addFBReg(SignedOffset); 3130b57cec5SDimitry Andric else 3140b57cec5SDimitry Andric addBReg(Reg.DwarfRegNo, SignedOffset); 3150b57cec5SDimitry Andric DwarfRegs.clear(); 3160b57cec5SDimitry Andric return true; 3170b57cec5SDimitry Andric } 3180b57cec5SDimitry Andric 319*8bcb0991SDimitry Andric void DwarfExpression::beginEntryValueExpression( 320*8bcb0991SDimitry Andric DIExpressionCursor &ExprCursor) { 3210b57cec5SDimitry Andric auto Op = ExprCursor.take(); 322*8bcb0991SDimitry Andric (void)Op; 323*8bcb0991SDimitry Andric assert(Op && Op->getOp() == dwarf::DW_OP_LLVM_entry_value); 3240b57cec5SDimitry Andric assert(!isMemoryLocation() && 3250b57cec5SDimitry Andric "We don't support entry values of memory locations yet"); 326*8bcb0991SDimitry Andric assert(!IsEmittingEntryValue && "Already emitting entry value?"); 327*8bcb0991SDimitry Andric assert(Op->getArg(0) == 1 && 328*8bcb0991SDimitry Andric "Can currently only emit entry values covering a single operation"); 3290b57cec5SDimitry Andric 330*8bcb0991SDimitry Andric emitOp(CU.getDwarf5OrGNULocationAtom(dwarf::DW_OP_entry_value)); 331*8bcb0991SDimitry Andric IsEmittingEntryValue = true; 332*8bcb0991SDimitry Andric enableTemporaryBuffer(); 333*8bcb0991SDimitry Andric } 334*8bcb0991SDimitry Andric 335*8bcb0991SDimitry Andric void DwarfExpression::finalizeEntryValue() { 336*8bcb0991SDimitry Andric assert(IsEmittingEntryValue && "Entry value not open?"); 337*8bcb0991SDimitry Andric disableTemporaryBuffer(); 338*8bcb0991SDimitry Andric 339*8bcb0991SDimitry Andric // Emit the entry value's size operand. 340*8bcb0991SDimitry Andric unsigned Size = getTemporaryBufferSize(); 341*8bcb0991SDimitry Andric emitUnsigned(Size); 342*8bcb0991SDimitry Andric 343*8bcb0991SDimitry Andric // Emit the entry value's DWARF block operand. 344*8bcb0991SDimitry Andric commitTemporaryBuffer(); 345*8bcb0991SDimitry Andric 346*8bcb0991SDimitry Andric IsEmittingEntryValue = false; 3470b57cec5SDimitry Andric } 3480b57cec5SDimitry Andric 3490b57cec5SDimitry Andric /// Assuming a well-formed expression, match "DW_OP_deref* DW_OP_LLVM_fragment?". 3500b57cec5SDimitry Andric static bool isMemoryLocation(DIExpressionCursor ExprCursor) { 3510b57cec5SDimitry Andric while (ExprCursor) { 3520b57cec5SDimitry Andric auto Op = ExprCursor.take(); 3530b57cec5SDimitry Andric switch (Op->getOp()) { 3540b57cec5SDimitry Andric case dwarf::DW_OP_deref: 3550b57cec5SDimitry Andric case dwarf::DW_OP_LLVM_fragment: 3560b57cec5SDimitry Andric break; 3570b57cec5SDimitry Andric default: 3580b57cec5SDimitry Andric return false; 3590b57cec5SDimitry Andric } 3600b57cec5SDimitry Andric } 3610b57cec5SDimitry Andric return true; 3620b57cec5SDimitry Andric } 3630b57cec5SDimitry Andric 3640b57cec5SDimitry Andric void DwarfExpression::addExpression(DIExpressionCursor &&ExprCursor, 3650b57cec5SDimitry Andric unsigned FragmentOffsetInBits) { 3660b57cec5SDimitry Andric // If we need to mask out a subregister, do it now, unless the next 3670b57cec5SDimitry Andric // operation would emit an OpPiece anyway. 3680b57cec5SDimitry Andric auto N = ExprCursor.peek(); 3690b57cec5SDimitry Andric if (SubRegisterSizeInBits && N && (N->getOp() != dwarf::DW_OP_LLVM_fragment)) 3700b57cec5SDimitry Andric maskSubRegister(); 3710b57cec5SDimitry Andric 3720b57cec5SDimitry Andric Optional<DIExpression::ExprOperand> PrevConvertOp = None; 3730b57cec5SDimitry Andric 3740b57cec5SDimitry Andric while (ExprCursor) { 3750b57cec5SDimitry Andric auto Op = ExprCursor.take(); 376*8bcb0991SDimitry Andric uint64_t OpNum = Op->getOp(); 377*8bcb0991SDimitry Andric 378*8bcb0991SDimitry Andric if (OpNum >= dwarf::DW_OP_reg0 && OpNum <= dwarf::DW_OP_reg31) { 379*8bcb0991SDimitry Andric emitOp(OpNum); 380*8bcb0991SDimitry Andric continue; 381*8bcb0991SDimitry Andric } else if (OpNum >= dwarf::DW_OP_breg0 && OpNum <= dwarf::DW_OP_breg31) { 382*8bcb0991SDimitry Andric addBReg(OpNum - dwarf::DW_OP_breg0, Op->getArg(0)); 383*8bcb0991SDimitry Andric continue; 384*8bcb0991SDimitry Andric } 385*8bcb0991SDimitry Andric 386*8bcb0991SDimitry Andric switch (OpNum) { 3870b57cec5SDimitry Andric case dwarf::DW_OP_LLVM_fragment: { 3880b57cec5SDimitry Andric unsigned SizeInBits = Op->getArg(1); 3890b57cec5SDimitry Andric unsigned FragmentOffset = Op->getArg(0); 3900b57cec5SDimitry Andric // The fragment offset must have already been adjusted by emitting an 3910b57cec5SDimitry Andric // empty DW_OP_piece / DW_OP_bit_piece before we emitted the base 3920b57cec5SDimitry Andric // location. 3930b57cec5SDimitry Andric assert(OffsetInBits >= FragmentOffset && "fragment offset not added?"); 3940b57cec5SDimitry Andric 3950b57cec5SDimitry Andric // If addMachineReg already emitted DW_OP_piece operations to represent 3960b57cec5SDimitry Andric // a super-register by splicing together sub-registers, subtract the size 3970b57cec5SDimitry Andric // of the pieces that was already emitted. 3980b57cec5SDimitry Andric SizeInBits -= OffsetInBits - FragmentOffset; 3990b57cec5SDimitry Andric 4000b57cec5SDimitry Andric // If addMachineReg requested a DW_OP_bit_piece to stencil out a 4010b57cec5SDimitry Andric // sub-register that is smaller than the current fragment's size, use it. 4020b57cec5SDimitry Andric if (SubRegisterSizeInBits) 4030b57cec5SDimitry Andric SizeInBits = std::min<unsigned>(SizeInBits, SubRegisterSizeInBits); 4040b57cec5SDimitry Andric 4050b57cec5SDimitry Andric // Emit a DW_OP_stack_value for implicit location descriptions. 4060b57cec5SDimitry Andric if (isImplicitLocation()) 4070b57cec5SDimitry Andric addStackValue(); 4080b57cec5SDimitry Andric 4090b57cec5SDimitry Andric // Emit the DW_OP_piece. 4100b57cec5SDimitry Andric addOpPiece(SizeInBits, SubRegisterOffsetInBits); 4110b57cec5SDimitry Andric setSubRegisterPiece(0, 0); 4120b57cec5SDimitry Andric // Reset the location description kind. 4130b57cec5SDimitry Andric LocationKind = Unknown; 4140b57cec5SDimitry Andric return; 4150b57cec5SDimitry Andric } 4160b57cec5SDimitry Andric case dwarf::DW_OP_plus_uconst: 4170b57cec5SDimitry Andric assert(!isRegisterLocation()); 4180b57cec5SDimitry Andric emitOp(dwarf::DW_OP_plus_uconst); 4190b57cec5SDimitry Andric emitUnsigned(Op->getArg(0)); 4200b57cec5SDimitry Andric break; 4210b57cec5SDimitry Andric case dwarf::DW_OP_plus: 4220b57cec5SDimitry Andric case dwarf::DW_OP_minus: 4230b57cec5SDimitry Andric case dwarf::DW_OP_mul: 4240b57cec5SDimitry Andric case dwarf::DW_OP_div: 4250b57cec5SDimitry Andric case dwarf::DW_OP_mod: 4260b57cec5SDimitry Andric case dwarf::DW_OP_or: 4270b57cec5SDimitry Andric case dwarf::DW_OP_and: 4280b57cec5SDimitry Andric case dwarf::DW_OP_xor: 4290b57cec5SDimitry Andric case dwarf::DW_OP_shl: 4300b57cec5SDimitry Andric case dwarf::DW_OP_shr: 4310b57cec5SDimitry Andric case dwarf::DW_OP_shra: 4320b57cec5SDimitry Andric case dwarf::DW_OP_lit0: 4330b57cec5SDimitry Andric case dwarf::DW_OP_not: 4340b57cec5SDimitry Andric case dwarf::DW_OP_dup: 435*8bcb0991SDimitry Andric emitOp(OpNum); 4360b57cec5SDimitry Andric break; 4370b57cec5SDimitry Andric case dwarf::DW_OP_deref: 4380b57cec5SDimitry Andric assert(!isRegisterLocation()); 439*8bcb0991SDimitry Andric // For more detailed explanation see llvm.org/PR43343. 440*8bcb0991SDimitry Andric assert(!isParameterValue() && "Parameter entry values should not be " 441*8bcb0991SDimitry Andric "dereferenced due to safety reasons."); 4420b57cec5SDimitry Andric if (!isMemoryLocation() && ::isMemoryLocation(ExprCursor)) 4430b57cec5SDimitry Andric // Turning this into a memory location description makes the deref 4440b57cec5SDimitry Andric // implicit. 4450b57cec5SDimitry Andric LocationKind = Memory; 4460b57cec5SDimitry Andric else 4470b57cec5SDimitry Andric emitOp(dwarf::DW_OP_deref); 4480b57cec5SDimitry Andric break; 4490b57cec5SDimitry Andric case dwarf::DW_OP_constu: 4500b57cec5SDimitry Andric assert(!isRegisterLocation()); 4510b57cec5SDimitry Andric emitConstu(Op->getArg(0)); 4520b57cec5SDimitry Andric break; 4530b57cec5SDimitry Andric case dwarf::DW_OP_LLVM_convert: { 4540b57cec5SDimitry Andric unsigned BitSize = Op->getArg(0); 4550b57cec5SDimitry Andric dwarf::TypeKind Encoding = static_cast<dwarf::TypeKind>(Op->getArg(1)); 4560b57cec5SDimitry Andric if (DwarfVersion >= 5) { 4570b57cec5SDimitry Andric emitOp(dwarf::DW_OP_convert); 4580b57cec5SDimitry Andric // Reuse the base_type if we already have one in this CU otherwise we 4590b57cec5SDimitry Andric // create a new one. 4600b57cec5SDimitry Andric unsigned I = 0, E = CU.ExprRefedBaseTypes.size(); 4610b57cec5SDimitry Andric for (; I != E; ++I) 4620b57cec5SDimitry Andric if (CU.ExprRefedBaseTypes[I].BitSize == BitSize && 4630b57cec5SDimitry Andric CU.ExprRefedBaseTypes[I].Encoding == Encoding) 4640b57cec5SDimitry Andric break; 4650b57cec5SDimitry Andric 4660b57cec5SDimitry Andric if (I == E) 4670b57cec5SDimitry Andric CU.ExprRefedBaseTypes.emplace_back(BitSize, Encoding); 4680b57cec5SDimitry Andric 4690b57cec5SDimitry Andric // If targeting a location-list; simply emit the index into the raw 4700b57cec5SDimitry Andric // byte stream as ULEB128, DwarfDebug::emitDebugLocEntry has been 4710b57cec5SDimitry Andric // fitted with means to extract it later. 4720b57cec5SDimitry Andric // If targeting a inlined DW_AT_location; insert a DIEBaseTypeRef 4730b57cec5SDimitry Andric // (containing the index and a resolve mechanism during emit) into the 4740b57cec5SDimitry Andric // DIE value list. 4750b57cec5SDimitry Andric emitBaseTypeRef(I); 4760b57cec5SDimitry Andric } else { 4770b57cec5SDimitry Andric if (PrevConvertOp && PrevConvertOp->getArg(0) < BitSize) { 4780b57cec5SDimitry Andric if (Encoding == dwarf::DW_ATE_signed) 4790b57cec5SDimitry Andric emitLegacySExt(PrevConvertOp->getArg(0)); 4800b57cec5SDimitry Andric else if (Encoding == dwarf::DW_ATE_unsigned) 4810b57cec5SDimitry Andric emitLegacyZExt(PrevConvertOp->getArg(0)); 4820b57cec5SDimitry Andric PrevConvertOp = None; 4830b57cec5SDimitry Andric } else { 4840b57cec5SDimitry Andric PrevConvertOp = Op; 4850b57cec5SDimitry Andric } 4860b57cec5SDimitry Andric } 4870b57cec5SDimitry Andric break; 4880b57cec5SDimitry Andric } 4890b57cec5SDimitry Andric case dwarf::DW_OP_stack_value: 4900b57cec5SDimitry Andric LocationKind = Implicit; 4910b57cec5SDimitry Andric break; 4920b57cec5SDimitry Andric case dwarf::DW_OP_swap: 4930b57cec5SDimitry Andric assert(!isRegisterLocation()); 4940b57cec5SDimitry Andric emitOp(dwarf::DW_OP_swap); 4950b57cec5SDimitry Andric break; 4960b57cec5SDimitry Andric case dwarf::DW_OP_xderef: 4970b57cec5SDimitry Andric assert(!isRegisterLocation()); 4980b57cec5SDimitry Andric emitOp(dwarf::DW_OP_xderef); 4990b57cec5SDimitry Andric break; 5000b57cec5SDimitry Andric case dwarf::DW_OP_deref_size: 5010b57cec5SDimitry Andric emitOp(dwarf::DW_OP_deref_size); 5020b57cec5SDimitry Andric emitData1(Op->getArg(0)); 5030b57cec5SDimitry Andric break; 5040b57cec5SDimitry Andric case dwarf::DW_OP_LLVM_tag_offset: 5050b57cec5SDimitry Andric TagOffset = Op->getArg(0); 5060b57cec5SDimitry Andric break; 507*8bcb0991SDimitry Andric case dwarf::DW_OP_regx: 508*8bcb0991SDimitry Andric emitOp(dwarf::DW_OP_regx); 509*8bcb0991SDimitry Andric emitUnsigned(Op->getArg(0)); 510*8bcb0991SDimitry Andric break; 511*8bcb0991SDimitry Andric case dwarf::DW_OP_bregx: 512*8bcb0991SDimitry Andric emitOp(dwarf::DW_OP_bregx); 513*8bcb0991SDimitry Andric emitUnsigned(Op->getArg(0)); 514*8bcb0991SDimitry Andric emitSigned(Op->getArg(1)); 515*8bcb0991SDimitry Andric break; 5160b57cec5SDimitry Andric default: 5170b57cec5SDimitry Andric llvm_unreachable("unhandled opcode found in expression"); 5180b57cec5SDimitry Andric } 5190b57cec5SDimitry Andric } 5200b57cec5SDimitry Andric 521*8bcb0991SDimitry Andric if (isImplicitLocation() && !isParameterValue()) 5220b57cec5SDimitry Andric // Turn this into an implicit location description. 5230b57cec5SDimitry Andric addStackValue(); 5240b57cec5SDimitry Andric } 5250b57cec5SDimitry Andric 5260b57cec5SDimitry Andric /// add masking operations to stencil out a subregister. 5270b57cec5SDimitry Andric void DwarfExpression::maskSubRegister() { 5280b57cec5SDimitry Andric assert(SubRegisterSizeInBits && "no subregister was registered"); 5290b57cec5SDimitry Andric if (SubRegisterOffsetInBits > 0) 5300b57cec5SDimitry Andric addShr(SubRegisterOffsetInBits); 5310b57cec5SDimitry Andric uint64_t Mask = (1ULL << (uint64_t)SubRegisterSizeInBits) - 1ULL; 5320b57cec5SDimitry Andric addAnd(Mask); 5330b57cec5SDimitry Andric } 5340b57cec5SDimitry Andric 5350b57cec5SDimitry Andric void DwarfExpression::finalize() { 5360b57cec5SDimitry Andric assert(DwarfRegs.size() == 0 && "dwarf registers not emitted"); 5370b57cec5SDimitry Andric // Emit any outstanding DW_OP_piece operations to mask out subregisters. 5380b57cec5SDimitry Andric if (SubRegisterSizeInBits == 0) 5390b57cec5SDimitry Andric return; 5400b57cec5SDimitry Andric // Don't emit a DW_OP_piece for a subregister at offset 0. 5410b57cec5SDimitry Andric if (SubRegisterOffsetInBits == 0) 5420b57cec5SDimitry Andric return; 5430b57cec5SDimitry Andric addOpPiece(SubRegisterSizeInBits, SubRegisterOffsetInBits); 5440b57cec5SDimitry Andric } 5450b57cec5SDimitry Andric 5460b57cec5SDimitry Andric void DwarfExpression::addFragmentOffset(const DIExpression *Expr) { 5470b57cec5SDimitry Andric if (!Expr || !Expr->isFragment()) 5480b57cec5SDimitry Andric return; 5490b57cec5SDimitry Andric 5500b57cec5SDimitry Andric uint64_t FragmentOffset = Expr->getFragmentInfo()->OffsetInBits; 5510b57cec5SDimitry Andric assert(FragmentOffset >= OffsetInBits && 5520b57cec5SDimitry Andric "overlapping or duplicate fragments"); 5530b57cec5SDimitry Andric if (FragmentOffset > OffsetInBits) 5540b57cec5SDimitry Andric addOpPiece(FragmentOffset - OffsetInBits); 5550b57cec5SDimitry Andric OffsetInBits = FragmentOffset; 5560b57cec5SDimitry Andric } 5570b57cec5SDimitry Andric 5580b57cec5SDimitry Andric void DwarfExpression::emitLegacySExt(unsigned FromBits) { 5590b57cec5SDimitry Andric // (((X >> (FromBits - 1)) * (~0)) << FromBits) | X 5600b57cec5SDimitry Andric emitOp(dwarf::DW_OP_dup); 5610b57cec5SDimitry Andric emitOp(dwarf::DW_OP_constu); 5620b57cec5SDimitry Andric emitUnsigned(FromBits - 1); 5630b57cec5SDimitry Andric emitOp(dwarf::DW_OP_shr); 5640b57cec5SDimitry Andric emitOp(dwarf::DW_OP_lit0); 5650b57cec5SDimitry Andric emitOp(dwarf::DW_OP_not); 5660b57cec5SDimitry Andric emitOp(dwarf::DW_OP_mul); 5670b57cec5SDimitry Andric emitOp(dwarf::DW_OP_constu); 5680b57cec5SDimitry Andric emitUnsigned(FromBits); 5690b57cec5SDimitry Andric emitOp(dwarf::DW_OP_shl); 5700b57cec5SDimitry Andric emitOp(dwarf::DW_OP_or); 5710b57cec5SDimitry Andric } 5720b57cec5SDimitry Andric 5730b57cec5SDimitry Andric void DwarfExpression::emitLegacyZExt(unsigned FromBits) { 5740b57cec5SDimitry Andric // (X & (1 << FromBits - 1)) 5750b57cec5SDimitry Andric emitOp(dwarf::DW_OP_constu); 5760b57cec5SDimitry Andric emitUnsigned((1ULL << FromBits) - 1); 5770b57cec5SDimitry Andric emitOp(dwarf::DW_OP_and); 5780b57cec5SDimitry Andric } 579