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" 188bcb0991SDimitry 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) { 1018bcb0991SDimitry 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 158*480093f4SDimitry Andric // its range, and its range covers the value, emit a DWARF piece for it. 159*480093f4SDimitry Andric if (Offset < MaxSize && CurSubReg.test(Coverage)) { 1600b57cec5SDimitry Andric // Emit a piece for any gap in the coverage. 1610b57cec5SDimitry Andric if (Offset > CurPos) 162*480093f4SDimitry Andric DwarfRegs.push_back( 163*480093f4SDimitry Andric {-1, Offset - CurPos, "no DWARF register encoding"}); 1640b57cec5SDimitry Andric DwarfRegs.push_back( 1650b57cec5SDimitry Andric {Reg, std::min<unsigned>(Size, MaxSize - Offset), "sub-register"}); 166*480093f4SDimitry Andric } 1670b57cec5SDimitry Andric // Mark it as emitted. 1680b57cec5SDimitry Andric Coverage.set(Offset, Offset + Size); 1690b57cec5SDimitry Andric CurPos = Offset + Size; 1700b57cec5SDimitry Andric } 1710b57cec5SDimitry Andric // Failed to find any DWARF encoding. 1720b57cec5SDimitry Andric if (CurPos == 0) 1730b57cec5SDimitry Andric return false; 1740b57cec5SDimitry Andric // Found a partial or complete DWARF encoding. 1750b57cec5SDimitry Andric if (CurPos < RegSize) 1760b57cec5SDimitry Andric DwarfRegs.push_back({-1, RegSize - CurPos, "no DWARF register encoding"}); 1770b57cec5SDimitry Andric return true; 1780b57cec5SDimitry Andric } 1790b57cec5SDimitry Andric 1800b57cec5SDimitry Andric void DwarfExpression::addStackValue() { 1810b57cec5SDimitry Andric if (DwarfVersion >= 4) 1820b57cec5SDimitry Andric emitOp(dwarf::DW_OP_stack_value); 1830b57cec5SDimitry Andric } 1840b57cec5SDimitry Andric 1850b57cec5SDimitry Andric void DwarfExpression::addSignedConstant(int64_t Value) { 1860b57cec5SDimitry Andric assert(isImplicitLocation() || isUnknownLocation()); 1870b57cec5SDimitry Andric LocationKind = Implicit; 1880b57cec5SDimitry Andric emitOp(dwarf::DW_OP_consts); 1890b57cec5SDimitry Andric emitSigned(Value); 1900b57cec5SDimitry Andric } 1910b57cec5SDimitry Andric 1920b57cec5SDimitry Andric void DwarfExpression::addUnsignedConstant(uint64_t Value) { 1930b57cec5SDimitry Andric assert(isImplicitLocation() || isUnknownLocation()); 1940b57cec5SDimitry Andric LocationKind = Implicit; 1950b57cec5SDimitry Andric emitConstu(Value); 1960b57cec5SDimitry Andric } 1970b57cec5SDimitry Andric 1980b57cec5SDimitry Andric void DwarfExpression::addUnsignedConstant(const APInt &Value) { 1990b57cec5SDimitry Andric assert(isImplicitLocation() || isUnknownLocation()); 2000b57cec5SDimitry Andric LocationKind = Implicit; 2010b57cec5SDimitry Andric 2020b57cec5SDimitry Andric unsigned Size = Value.getBitWidth(); 2030b57cec5SDimitry Andric const uint64_t *Data = Value.getRawData(); 2040b57cec5SDimitry Andric 2050b57cec5SDimitry Andric // Chop it up into 64-bit pieces, because that's the maximum that 2060b57cec5SDimitry Andric // addUnsignedConstant takes. 2070b57cec5SDimitry Andric unsigned Offset = 0; 2080b57cec5SDimitry Andric while (Offset < Size) { 2090b57cec5SDimitry Andric addUnsignedConstant(*Data++); 2100b57cec5SDimitry Andric if (Offset == 0 && Size <= 64) 2110b57cec5SDimitry Andric break; 2120b57cec5SDimitry Andric addStackValue(); 2130b57cec5SDimitry Andric addOpPiece(std::min(Size - Offset, 64u), Offset); 2140b57cec5SDimitry Andric Offset += 64; 2150b57cec5SDimitry Andric } 2160b57cec5SDimitry Andric } 2170b57cec5SDimitry Andric 2180b57cec5SDimitry Andric bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI, 2190b57cec5SDimitry Andric DIExpressionCursor &ExprCursor, 2200b57cec5SDimitry Andric unsigned MachineReg, 2210b57cec5SDimitry Andric unsigned FragmentOffsetInBits) { 2220b57cec5SDimitry Andric auto Fragment = ExprCursor.getFragmentInfo(); 2230b57cec5SDimitry Andric if (!addMachineReg(TRI, MachineReg, Fragment ? Fragment->SizeInBits : ~1U)) { 2240b57cec5SDimitry Andric LocationKind = Unknown; 2250b57cec5SDimitry Andric return false; 2260b57cec5SDimitry Andric } 2270b57cec5SDimitry Andric 2280b57cec5SDimitry Andric bool HasComplexExpression = false; 2290b57cec5SDimitry Andric auto Op = ExprCursor.peek(); 2300b57cec5SDimitry Andric if (Op && Op->getOp() != dwarf::DW_OP_LLVM_fragment) 2310b57cec5SDimitry Andric HasComplexExpression = true; 2320b57cec5SDimitry Andric 2330b57cec5SDimitry Andric // If the register can only be described by a complex expression (i.e., 2340b57cec5SDimitry Andric // multiple subregisters) it doesn't safely compose with another complex 2350b57cec5SDimitry Andric // expression. For example, it is not possible to apply a DW_OP_deref 2360b57cec5SDimitry Andric // operation to multiple DW_OP_pieces. 2370b57cec5SDimitry Andric if (HasComplexExpression && DwarfRegs.size() > 1) { 2380b57cec5SDimitry Andric DwarfRegs.clear(); 2390b57cec5SDimitry Andric LocationKind = Unknown; 2400b57cec5SDimitry Andric return false; 2410b57cec5SDimitry Andric } 2420b57cec5SDimitry Andric 2438bcb0991SDimitry Andric // Handle simple register locations. If we are supposed to emit 2448bcb0991SDimitry Andric // a call site parameter expression and if that expression is just a register 2458bcb0991SDimitry Andric // location, emit it with addBReg and offset 0, because we should emit a DWARF 2468bcb0991SDimitry Andric // expression representing a value, rather than a location. 247*480093f4SDimitry Andric if (!isMemoryLocation() && !HasComplexExpression && (!isParameterValue() || 248*480093f4SDimitry Andric isEntryValue())) { 2490b57cec5SDimitry Andric for (auto &Reg : DwarfRegs) { 2500b57cec5SDimitry Andric if (Reg.DwarfRegNo >= 0) 2510b57cec5SDimitry Andric addReg(Reg.DwarfRegNo, Reg.Comment); 2520b57cec5SDimitry Andric addOpPiece(Reg.Size); 2530b57cec5SDimitry Andric } 2540b57cec5SDimitry Andric 2558bcb0991SDimitry Andric if (isEntryValue()) 2568bcb0991SDimitry Andric finalizeEntryValue(); 2578bcb0991SDimitry Andric 2588bcb0991SDimitry Andric if (isEntryValue() && !isParameterValue() && DwarfVersion >= 4) 2590b57cec5SDimitry Andric emitOp(dwarf::DW_OP_stack_value); 2600b57cec5SDimitry Andric 2610b57cec5SDimitry Andric DwarfRegs.clear(); 2620b57cec5SDimitry Andric return true; 2630b57cec5SDimitry Andric } 2640b57cec5SDimitry Andric 2650b57cec5SDimitry Andric // Don't emit locations that cannot be expressed without DW_OP_stack_value. 2660b57cec5SDimitry Andric if (DwarfVersion < 4) 2670b57cec5SDimitry Andric if (any_of(ExprCursor, [](DIExpression::ExprOperand Op) -> bool { 2680b57cec5SDimitry Andric return Op.getOp() == dwarf::DW_OP_stack_value; 2690b57cec5SDimitry Andric })) { 2700b57cec5SDimitry Andric DwarfRegs.clear(); 2710b57cec5SDimitry Andric LocationKind = Unknown; 2720b57cec5SDimitry Andric return false; 2730b57cec5SDimitry Andric } 2740b57cec5SDimitry Andric 2750b57cec5SDimitry Andric assert(DwarfRegs.size() == 1); 2760b57cec5SDimitry Andric auto Reg = DwarfRegs[0]; 2770b57cec5SDimitry Andric bool FBReg = isFrameRegister(TRI, MachineReg); 2780b57cec5SDimitry Andric int SignedOffset = 0; 2790b57cec5SDimitry Andric assert(Reg.Size == 0 && "subregister has same size as superregister"); 2800b57cec5SDimitry Andric 2810b57cec5SDimitry Andric // Pattern-match combinations for which more efficient representations exist. 2820b57cec5SDimitry Andric // [Reg, DW_OP_plus_uconst, Offset] --> [DW_OP_breg, Offset]. 2830b57cec5SDimitry Andric if (Op && (Op->getOp() == dwarf::DW_OP_plus_uconst)) { 2848bcb0991SDimitry Andric uint64_t Offset = Op->getArg(0); 2858bcb0991SDimitry Andric uint64_t IntMax = static_cast<uint64_t>(std::numeric_limits<int>::max()); 2868bcb0991SDimitry Andric if (Offset <= IntMax) { 2878bcb0991SDimitry Andric SignedOffset = Offset; 2880b57cec5SDimitry Andric ExprCursor.take(); 2890b57cec5SDimitry Andric } 2908bcb0991SDimitry Andric } 2910b57cec5SDimitry Andric 2920b57cec5SDimitry Andric // [Reg, DW_OP_constu, Offset, DW_OP_plus] --> [DW_OP_breg, Offset] 2930b57cec5SDimitry Andric // [Reg, DW_OP_constu, Offset, DW_OP_minus] --> [DW_OP_breg,-Offset] 2940b57cec5SDimitry Andric // If Reg is a subregister we need to mask it out before subtracting. 2950b57cec5SDimitry Andric if (Op && Op->getOp() == dwarf::DW_OP_constu) { 2968bcb0991SDimitry Andric uint64_t Offset = Op->getArg(0); 2978bcb0991SDimitry Andric uint64_t IntMax = static_cast<uint64_t>(std::numeric_limits<int>::max()); 2980b57cec5SDimitry Andric auto N = ExprCursor.peekNext(); 2998bcb0991SDimitry Andric if (N && N->getOp() == dwarf::DW_OP_plus && Offset <= IntMax) { 3008bcb0991SDimitry Andric SignedOffset = Offset; 3018bcb0991SDimitry Andric ExprCursor.consume(2); 3028bcb0991SDimitry Andric } else if (N && N->getOp() == dwarf::DW_OP_minus && 3038bcb0991SDimitry Andric !SubRegisterSizeInBits && Offset <= IntMax + 1) { 3048bcb0991SDimitry Andric SignedOffset = -static_cast<int64_t>(Offset); 3050b57cec5SDimitry Andric ExprCursor.consume(2); 3060b57cec5SDimitry Andric } 3070b57cec5SDimitry Andric } 3080b57cec5SDimitry Andric 3090b57cec5SDimitry Andric if (FBReg) 3100b57cec5SDimitry Andric addFBReg(SignedOffset); 3110b57cec5SDimitry Andric else 3120b57cec5SDimitry Andric addBReg(Reg.DwarfRegNo, SignedOffset); 3130b57cec5SDimitry Andric DwarfRegs.clear(); 3140b57cec5SDimitry Andric return true; 3150b57cec5SDimitry Andric } 3160b57cec5SDimitry Andric 3178bcb0991SDimitry Andric void DwarfExpression::beginEntryValueExpression( 3188bcb0991SDimitry Andric DIExpressionCursor &ExprCursor) { 3190b57cec5SDimitry Andric auto Op = ExprCursor.take(); 3208bcb0991SDimitry Andric (void)Op; 3218bcb0991SDimitry Andric assert(Op && Op->getOp() == dwarf::DW_OP_LLVM_entry_value); 3220b57cec5SDimitry Andric assert(!isMemoryLocation() && 3230b57cec5SDimitry Andric "We don't support entry values of memory locations yet"); 3248bcb0991SDimitry Andric assert(!IsEmittingEntryValue && "Already emitting entry value?"); 3258bcb0991SDimitry Andric assert(Op->getArg(0) == 1 && 3268bcb0991SDimitry Andric "Can currently only emit entry values covering a single operation"); 3270b57cec5SDimitry Andric 3288bcb0991SDimitry Andric emitOp(CU.getDwarf5OrGNULocationAtom(dwarf::DW_OP_entry_value)); 3298bcb0991SDimitry Andric IsEmittingEntryValue = true; 3308bcb0991SDimitry Andric enableTemporaryBuffer(); 3318bcb0991SDimitry Andric } 3328bcb0991SDimitry Andric 3338bcb0991SDimitry Andric void DwarfExpression::finalizeEntryValue() { 3348bcb0991SDimitry Andric assert(IsEmittingEntryValue && "Entry value not open?"); 3358bcb0991SDimitry Andric disableTemporaryBuffer(); 3368bcb0991SDimitry Andric 3378bcb0991SDimitry Andric // Emit the entry value's size operand. 3388bcb0991SDimitry Andric unsigned Size = getTemporaryBufferSize(); 3398bcb0991SDimitry Andric emitUnsigned(Size); 3408bcb0991SDimitry Andric 3418bcb0991SDimitry Andric // Emit the entry value's DWARF block operand. 3428bcb0991SDimitry Andric commitTemporaryBuffer(); 3438bcb0991SDimitry Andric 3448bcb0991SDimitry Andric IsEmittingEntryValue = false; 3450b57cec5SDimitry Andric } 3460b57cec5SDimitry Andric 3470b57cec5SDimitry Andric /// Assuming a well-formed expression, match "DW_OP_deref* DW_OP_LLVM_fragment?". 3480b57cec5SDimitry Andric static bool isMemoryLocation(DIExpressionCursor ExprCursor) { 3490b57cec5SDimitry Andric while (ExprCursor) { 3500b57cec5SDimitry Andric auto Op = ExprCursor.take(); 3510b57cec5SDimitry Andric switch (Op->getOp()) { 3520b57cec5SDimitry Andric case dwarf::DW_OP_deref: 3530b57cec5SDimitry Andric case dwarf::DW_OP_LLVM_fragment: 3540b57cec5SDimitry Andric break; 3550b57cec5SDimitry Andric default: 3560b57cec5SDimitry Andric return false; 3570b57cec5SDimitry Andric } 3580b57cec5SDimitry Andric } 3590b57cec5SDimitry Andric return true; 3600b57cec5SDimitry Andric } 3610b57cec5SDimitry Andric 3620b57cec5SDimitry Andric void DwarfExpression::addExpression(DIExpressionCursor &&ExprCursor, 3630b57cec5SDimitry Andric unsigned FragmentOffsetInBits) { 3640b57cec5SDimitry Andric // If we need to mask out a subregister, do it now, unless the next 3650b57cec5SDimitry Andric // operation would emit an OpPiece anyway. 3660b57cec5SDimitry Andric auto N = ExprCursor.peek(); 3670b57cec5SDimitry Andric if (SubRegisterSizeInBits && N && (N->getOp() != dwarf::DW_OP_LLVM_fragment)) 3680b57cec5SDimitry Andric maskSubRegister(); 3690b57cec5SDimitry Andric 3700b57cec5SDimitry Andric Optional<DIExpression::ExprOperand> PrevConvertOp = None; 3710b57cec5SDimitry Andric 3720b57cec5SDimitry Andric while (ExprCursor) { 3730b57cec5SDimitry Andric auto Op = ExprCursor.take(); 3748bcb0991SDimitry Andric uint64_t OpNum = Op->getOp(); 3758bcb0991SDimitry Andric 3768bcb0991SDimitry Andric if (OpNum >= dwarf::DW_OP_reg0 && OpNum <= dwarf::DW_OP_reg31) { 3778bcb0991SDimitry Andric emitOp(OpNum); 3788bcb0991SDimitry Andric continue; 3798bcb0991SDimitry Andric } else if (OpNum >= dwarf::DW_OP_breg0 && OpNum <= dwarf::DW_OP_breg31) { 3808bcb0991SDimitry Andric addBReg(OpNum - dwarf::DW_OP_breg0, Op->getArg(0)); 3818bcb0991SDimitry Andric continue; 3828bcb0991SDimitry Andric } 3838bcb0991SDimitry Andric 3848bcb0991SDimitry Andric switch (OpNum) { 3850b57cec5SDimitry Andric case dwarf::DW_OP_LLVM_fragment: { 3860b57cec5SDimitry Andric unsigned SizeInBits = Op->getArg(1); 3870b57cec5SDimitry Andric unsigned FragmentOffset = Op->getArg(0); 3880b57cec5SDimitry Andric // The fragment offset must have already been adjusted by emitting an 3890b57cec5SDimitry Andric // empty DW_OP_piece / DW_OP_bit_piece before we emitted the base 3900b57cec5SDimitry Andric // location. 3910b57cec5SDimitry Andric assert(OffsetInBits >= FragmentOffset && "fragment offset not added?"); 392*480093f4SDimitry Andric assert(SizeInBits >= OffsetInBits - FragmentOffset && "size underflow"); 3930b57cec5SDimitry Andric 3940b57cec5SDimitry Andric // If addMachineReg already emitted DW_OP_piece operations to represent 3950b57cec5SDimitry Andric // a super-register by splicing together sub-registers, subtract the size 3960b57cec5SDimitry Andric // of the pieces that was already emitted. 3970b57cec5SDimitry Andric SizeInBits -= OffsetInBits - FragmentOffset; 3980b57cec5SDimitry Andric 3990b57cec5SDimitry Andric // If addMachineReg requested a DW_OP_bit_piece to stencil out a 4000b57cec5SDimitry Andric // sub-register that is smaller than the current fragment's size, use it. 4010b57cec5SDimitry Andric if (SubRegisterSizeInBits) 4020b57cec5SDimitry Andric SizeInBits = std::min<unsigned>(SizeInBits, SubRegisterSizeInBits); 4030b57cec5SDimitry Andric 4040b57cec5SDimitry Andric // Emit a DW_OP_stack_value for implicit location descriptions. 4050b57cec5SDimitry Andric if (isImplicitLocation()) 4060b57cec5SDimitry Andric addStackValue(); 4070b57cec5SDimitry Andric 4080b57cec5SDimitry Andric // Emit the DW_OP_piece. 4090b57cec5SDimitry Andric addOpPiece(SizeInBits, SubRegisterOffsetInBits); 4100b57cec5SDimitry Andric setSubRegisterPiece(0, 0); 4110b57cec5SDimitry Andric // Reset the location description kind. 4120b57cec5SDimitry Andric LocationKind = Unknown; 4130b57cec5SDimitry Andric return; 4140b57cec5SDimitry Andric } 4150b57cec5SDimitry Andric case dwarf::DW_OP_plus_uconst: 4160b57cec5SDimitry Andric assert(!isRegisterLocation()); 4170b57cec5SDimitry Andric emitOp(dwarf::DW_OP_plus_uconst); 4180b57cec5SDimitry Andric emitUnsigned(Op->getArg(0)); 4190b57cec5SDimitry Andric break; 4200b57cec5SDimitry Andric case dwarf::DW_OP_plus: 4210b57cec5SDimitry Andric case dwarf::DW_OP_minus: 4220b57cec5SDimitry Andric case dwarf::DW_OP_mul: 4230b57cec5SDimitry Andric case dwarf::DW_OP_div: 4240b57cec5SDimitry Andric case dwarf::DW_OP_mod: 4250b57cec5SDimitry Andric case dwarf::DW_OP_or: 4260b57cec5SDimitry Andric case dwarf::DW_OP_and: 4270b57cec5SDimitry Andric case dwarf::DW_OP_xor: 4280b57cec5SDimitry Andric case dwarf::DW_OP_shl: 4290b57cec5SDimitry Andric case dwarf::DW_OP_shr: 4300b57cec5SDimitry Andric case dwarf::DW_OP_shra: 4310b57cec5SDimitry Andric case dwarf::DW_OP_lit0: 4320b57cec5SDimitry Andric case dwarf::DW_OP_not: 4330b57cec5SDimitry Andric case dwarf::DW_OP_dup: 4348bcb0991SDimitry Andric emitOp(OpNum); 4350b57cec5SDimitry Andric break; 4360b57cec5SDimitry Andric case dwarf::DW_OP_deref: 4370b57cec5SDimitry Andric assert(!isRegisterLocation()); 4380b57cec5SDimitry Andric if (!isMemoryLocation() && ::isMemoryLocation(ExprCursor)) 4390b57cec5SDimitry Andric // Turning this into a memory location description makes the deref 4400b57cec5SDimitry Andric // implicit. 4410b57cec5SDimitry Andric LocationKind = Memory; 4420b57cec5SDimitry Andric else 4430b57cec5SDimitry Andric emitOp(dwarf::DW_OP_deref); 4440b57cec5SDimitry Andric break; 4450b57cec5SDimitry Andric case dwarf::DW_OP_constu: 4460b57cec5SDimitry Andric assert(!isRegisterLocation()); 4470b57cec5SDimitry Andric emitConstu(Op->getArg(0)); 4480b57cec5SDimitry Andric break; 4490b57cec5SDimitry Andric case dwarf::DW_OP_LLVM_convert: { 4500b57cec5SDimitry Andric unsigned BitSize = Op->getArg(0); 4510b57cec5SDimitry Andric dwarf::TypeKind Encoding = static_cast<dwarf::TypeKind>(Op->getArg(1)); 4520b57cec5SDimitry Andric if (DwarfVersion >= 5) { 4530b57cec5SDimitry Andric emitOp(dwarf::DW_OP_convert); 4540b57cec5SDimitry Andric // Reuse the base_type if we already have one in this CU otherwise we 4550b57cec5SDimitry Andric // create a new one. 4560b57cec5SDimitry Andric unsigned I = 0, E = CU.ExprRefedBaseTypes.size(); 4570b57cec5SDimitry Andric for (; I != E; ++I) 4580b57cec5SDimitry Andric if (CU.ExprRefedBaseTypes[I].BitSize == BitSize && 4590b57cec5SDimitry Andric CU.ExprRefedBaseTypes[I].Encoding == Encoding) 4600b57cec5SDimitry Andric break; 4610b57cec5SDimitry Andric 4620b57cec5SDimitry Andric if (I == E) 4630b57cec5SDimitry Andric CU.ExprRefedBaseTypes.emplace_back(BitSize, Encoding); 4640b57cec5SDimitry Andric 4650b57cec5SDimitry Andric // If targeting a location-list; simply emit the index into the raw 4660b57cec5SDimitry Andric // byte stream as ULEB128, DwarfDebug::emitDebugLocEntry has been 4670b57cec5SDimitry Andric // fitted with means to extract it later. 4680b57cec5SDimitry Andric // If targeting a inlined DW_AT_location; insert a DIEBaseTypeRef 4690b57cec5SDimitry Andric // (containing the index and a resolve mechanism during emit) into the 4700b57cec5SDimitry Andric // DIE value list. 4710b57cec5SDimitry Andric emitBaseTypeRef(I); 4720b57cec5SDimitry Andric } else { 4730b57cec5SDimitry Andric if (PrevConvertOp && PrevConvertOp->getArg(0) < BitSize) { 4740b57cec5SDimitry Andric if (Encoding == dwarf::DW_ATE_signed) 4750b57cec5SDimitry Andric emitLegacySExt(PrevConvertOp->getArg(0)); 4760b57cec5SDimitry Andric else if (Encoding == dwarf::DW_ATE_unsigned) 4770b57cec5SDimitry Andric emitLegacyZExt(PrevConvertOp->getArg(0)); 4780b57cec5SDimitry Andric PrevConvertOp = None; 4790b57cec5SDimitry Andric } else { 4800b57cec5SDimitry Andric PrevConvertOp = Op; 4810b57cec5SDimitry Andric } 4820b57cec5SDimitry Andric } 4830b57cec5SDimitry Andric break; 4840b57cec5SDimitry Andric } 4850b57cec5SDimitry Andric case dwarf::DW_OP_stack_value: 4860b57cec5SDimitry Andric LocationKind = Implicit; 4870b57cec5SDimitry Andric break; 4880b57cec5SDimitry Andric case dwarf::DW_OP_swap: 4890b57cec5SDimitry Andric assert(!isRegisterLocation()); 4900b57cec5SDimitry Andric emitOp(dwarf::DW_OP_swap); 4910b57cec5SDimitry Andric break; 4920b57cec5SDimitry Andric case dwarf::DW_OP_xderef: 4930b57cec5SDimitry Andric assert(!isRegisterLocation()); 4940b57cec5SDimitry Andric emitOp(dwarf::DW_OP_xderef); 4950b57cec5SDimitry Andric break; 4960b57cec5SDimitry Andric case dwarf::DW_OP_deref_size: 4970b57cec5SDimitry Andric emitOp(dwarf::DW_OP_deref_size); 4980b57cec5SDimitry Andric emitData1(Op->getArg(0)); 4990b57cec5SDimitry Andric break; 5000b57cec5SDimitry Andric case dwarf::DW_OP_LLVM_tag_offset: 5010b57cec5SDimitry Andric TagOffset = Op->getArg(0); 5020b57cec5SDimitry Andric break; 5038bcb0991SDimitry Andric case dwarf::DW_OP_regx: 5048bcb0991SDimitry Andric emitOp(dwarf::DW_OP_regx); 5058bcb0991SDimitry Andric emitUnsigned(Op->getArg(0)); 5068bcb0991SDimitry Andric break; 5078bcb0991SDimitry Andric case dwarf::DW_OP_bregx: 5088bcb0991SDimitry Andric emitOp(dwarf::DW_OP_bregx); 5098bcb0991SDimitry Andric emitUnsigned(Op->getArg(0)); 5108bcb0991SDimitry Andric emitSigned(Op->getArg(1)); 5118bcb0991SDimitry Andric break; 5120b57cec5SDimitry Andric default: 5130b57cec5SDimitry Andric llvm_unreachable("unhandled opcode found in expression"); 5140b57cec5SDimitry Andric } 5150b57cec5SDimitry Andric } 5160b57cec5SDimitry Andric 5178bcb0991SDimitry Andric if (isImplicitLocation() && !isParameterValue()) 5180b57cec5SDimitry Andric // Turn this into an implicit location description. 5190b57cec5SDimitry Andric addStackValue(); 5200b57cec5SDimitry Andric } 5210b57cec5SDimitry Andric 5220b57cec5SDimitry Andric /// add masking operations to stencil out a subregister. 5230b57cec5SDimitry Andric void DwarfExpression::maskSubRegister() { 5240b57cec5SDimitry Andric assert(SubRegisterSizeInBits && "no subregister was registered"); 5250b57cec5SDimitry Andric if (SubRegisterOffsetInBits > 0) 5260b57cec5SDimitry Andric addShr(SubRegisterOffsetInBits); 5270b57cec5SDimitry Andric uint64_t Mask = (1ULL << (uint64_t)SubRegisterSizeInBits) - 1ULL; 5280b57cec5SDimitry Andric addAnd(Mask); 5290b57cec5SDimitry Andric } 5300b57cec5SDimitry Andric 5310b57cec5SDimitry Andric void DwarfExpression::finalize() { 5320b57cec5SDimitry Andric assert(DwarfRegs.size() == 0 && "dwarf registers not emitted"); 5330b57cec5SDimitry Andric // Emit any outstanding DW_OP_piece operations to mask out subregisters. 5340b57cec5SDimitry Andric if (SubRegisterSizeInBits == 0) 5350b57cec5SDimitry Andric return; 5360b57cec5SDimitry Andric // Don't emit a DW_OP_piece for a subregister at offset 0. 5370b57cec5SDimitry Andric if (SubRegisterOffsetInBits == 0) 5380b57cec5SDimitry Andric return; 5390b57cec5SDimitry Andric addOpPiece(SubRegisterSizeInBits, SubRegisterOffsetInBits); 5400b57cec5SDimitry Andric } 5410b57cec5SDimitry Andric 5420b57cec5SDimitry Andric void DwarfExpression::addFragmentOffset(const DIExpression *Expr) { 5430b57cec5SDimitry Andric if (!Expr || !Expr->isFragment()) 5440b57cec5SDimitry Andric return; 5450b57cec5SDimitry Andric 5460b57cec5SDimitry Andric uint64_t FragmentOffset = Expr->getFragmentInfo()->OffsetInBits; 5470b57cec5SDimitry Andric assert(FragmentOffset >= OffsetInBits && 5480b57cec5SDimitry Andric "overlapping or duplicate fragments"); 5490b57cec5SDimitry Andric if (FragmentOffset > OffsetInBits) 5500b57cec5SDimitry Andric addOpPiece(FragmentOffset - OffsetInBits); 5510b57cec5SDimitry Andric OffsetInBits = FragmentOffset; 5520b57cec5SDimitry Andric } 5530b57cec5SDimitry Andric 5540b57cec5SDimitry Andric void DwarfExpression::emitLegacySExt(unsigned FromBits) { 5550b57cec5SDimitry Andric // (((X >> (FromBits - 1)) * (~0)) << FromBits) | X 5560b57cec5SDimitry Andric emitOp(dwarf::DW_OP_dup); 5570b57cec5SDimitry Andric emitOp(dwarf::DW_OP_constu); 5580b57cec5SDimitry Andric emitUnsigned(FromBits - 1); 5590b57cec5SDimitry Andric emitOp(dwarf::DW_OP_shr); 5600b57cec5SDimitry Andric emitOp(dwarf::DW_OP_lit0); 5610b57cec5SDimitry Andric emitOp(dwarf::DW_OP_not); 5620b57cec5SDimitry Andric emitOp(dwarf::DW_OP_mul); 5630b57cec5SDimitry Andric emitOp(dwarf::DW_OP_constu); 5640b57cec5SDimitry Andric emitUnsigned(FromBits); 5650b57cec5SDimitry Andric emitOp(dwarf::DW_OP_shl); 5660b57cec5SDimitry Andric emitOp(dwarf::DW_OP_or); 5670b57cec5SDimitry Andric } 5680b57cec5SDimitry Andric 5690b57cec5SDimitry Andric void DwarfExpression::emitLegacyZExt(unsigned FromBits) { 5700b57cec5SDimitry Andric // (X & (1 << FromBits - 1)) 5710b57cec5SDimitry Andric emitOp(dwarf::DW_OP_constu); 5720b57cec5SDimitry Andric emitUnsigned((1ULL << FromBits) - 1); 5730b57cec5SDimitry Andric emitOp(dwarf::DW_OP_and); 5740b57cec5SDimitry Andric } 575*480093f4SDimitry Andric 576*480093f4SDimitry Andric void DwarfExpression::addWasmLocation(unsigned Index, int64_t Offset) { 577*480093f4SDimitry Andric assert(LocationKind == Implicit || LocationKind == Unknown); 578*480093f4SDimitry Andric LocationKind = Implicit; 579*480093f4SDimitry Andric emitOp(dwarf::DW_OP_WASM_location); 580*480093f4SDimitry Andric emitUnsigned(Index); 581*480093f4SDimitry Andric emitSigned(Offset); 582*480093f4SDimitry Andric } 583