2017-08-18 05:26:39 +08:00
|
|
|
//===- llvm/CodeGen/DwarfExpression.cpp - Dwarf Debug Framework -----------===//
|
2015-01-13 06:19:22 +08:00
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2015-01-13 06:19:22 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file contains support for writing dwarf debug info into asm files.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "DwarfExpression.h"
|
2019-03-19 21:16:28 +08:00
|
|
|
#include "DwarfCompileUnit.h"
|
2017-08-18 05:26:39 +08:00
|
|
|
#include "llvm/ADT/APInt.h"
|
2015-01-13 06:19:22 +08:00
|
|
|
#include "llvm/ADT/SmallBitVector.h"
|
2017-06-07 11:48:56 +08:00
|
|
|
#include "llvm/BinaryFormat/Dwarf.h"
|
2019-08-02 07:27:28 +08:00
|
|
|
#include "llvm/CodeGen/Register.h"
|
2017-11-17 09:07:10 +08:00
|
|
|
#include "llvm/CodeGen/TargetRegisterInfo.h"
|
2017-08-18 05:26:39 +08:00
|
|
|
#include "llvm/IR/DebugInfoMetadata.h"
|
|
|
|
#include "llvm/Support/ErrorHandling.h"
|
|
|
|
#include <algorithm>
|
|
|
|
#include <cassert>
|
|
|
|
#include <cstdint>
|
2015-01-13 06:19:22 +08:00
|
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
|
2018-09-05 18:18:36 +08:00
|
|
|
void DwarfExpression::emitConstu(uint64_t Value) {
|
|
|
|
if (Value < 32)
|
|
|
|
emitOp(dwarf::DW_OP_lit0 + Value);
|
|
|
|
else if (Value == std::numeric_limits<uint64_t>::max()) {
|
|
|
|
// Only do this for 64-bit values as the DWARF expression stack uses
|
|
|
|
// target-address-size values.
|
|
|
|
emitOp(dwarf::DW_OP_lit0);
|
|
|
|
emitOp(dwarf::DW_OP_not);
|
|
|
|
} else {
|
|
|
|
emitOp(dwarf::DW_OP_constu);
|
|
|
|
emitUnsigned(Value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-17 01:42:45 +08:00
|
|
|
void DwarfExpression::addReg(int DwarfReg, const char *Comment) {
|
2017-04-18 09:21:53 +08:00
|
|
|
assert(DwarfReg >= 0 && "invalid negative dwarf register number");
|
2019-05-23 18:37:13 +08:00
|
|
|
assert((isUnknownLocation() || isRegisterLocation()) &&
|
2017-04-18 09:21:53 +08:00
|
|
|
"location description already locked down");
|
|
|
|
LocationKind = Register;
|
|
|
|
if (DwarfReg < 32) {
|
|
|
|
emitOp(dwarf::DW_OP_reg0 + DwarfReg, Comment);
|
2015-01-13 06:19:22 +08:00
|
|
|
} else {
|
2017-03-17 01:42:45 +08:00
|
|
|
emitOp(dwarf::DW_OP_regx, Comment);
|
|
|
|
emitUnsigned(DwarfReg);
|
2015-01-13 06:19:22 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-23 01:19:55 +08:00
|
|
|
void DwarfExpression::addBReg(int DwarfReg, int Offset) {
|
2015-01-13 06:19:22 +08:00
|
|
|
assert(DwarfReg >= 0 && "invalid negative dwarf register number");
|
2019-05-23 18:37:13 +08:00
|
|
|
assert(!isRegisterLocation() && "location description already locked down");
|
2015-01-13 06:19:22 +08:00
|
|
|
if (DwarfReg < 32) {
|
2017-03-17 01:42:45 +08:00
|
|
|
emitOp(dwarf::DW_OP_breg0 + DwarfReg);
|
2015-01-13 06:19:22 +08:00
|
|
|
} else {
|
2017-03-17 01:42:45 +08:00
|
|
|
emitOp(dwarf::DW_OP_bregx);
|
|
|
|
emitUnsigned(DwarfReg);
|
2015-01-13 06:19:22 +08:00
|
|
|
}
|
2017-03-17 01:42:45 +08:00
|
|
|
emitSigned(Offset);
|
2015-01-13 06:19:22 +08:00
|
|
|
}
|
|
|
|
|
2017-03-22 09:15:57 +08:00
|
|
|
void DwarfExpression::addFBReg(int Offset) {
|
|
|
|
emitOp(dwarf::DW_OP_fbreg);
|
|
|
|
emitSigned(Offset);
|
|
|
|
}
|
|
|
|
|
2017-03-17 01:42:45 +08:00
|
|
|
void DwarfExpression::addOpPiece(unsigned SizeInBits, unsigned OffsetInBits) {
|
2016-12-10 04:43:40 +08:00
|
|
|
if (!SizeInBits)
|
|
|
|
return;
|
|
|
|
|
2015-01-13 06:19:22 +08:00
|
|
|
const unsigned SizeOfByte = 8;
|
|
|
|
if (OffsetInBits > 0 || SizeInBits % SizeOfByte) {
|
2017-03-17 01:42:45 +08:00
|
|
|
emitOp(dwarf::DW_OP_bit_piece);
|
|
|
|
emitUnsigned(SizeInBits);
|
|
|
|
emitUnsigned(OffsetInBits);
|
2015-01-13 06:19:22 +08:00
|
|
|
} else {
|
2017-03-17 01:42:45 +08:00
|
|
|
emitOp(dwarf::DW_OP_piece);
|
2015-01-13 06:19:22 +08:00
|
|
|
unsigned ByteSize = SizeInBits / SizeOfByte;
|
2017-03-17 01:42:45 +08:00
|
|
|
emitUnsigned(ByteSize);
|
2015-01-13 06:19:22 +08:00
|
|
|
}
|
2016-12-10 04:43:40 +08:00
|
|
|
this->OffsetInBits += SizeInBits;
|
2015-01-13 06:19:22 +08:00
|
|
|
}
|
|
|
|
|
2017-03-17 01:42:45 +08:00
|
|
|
void DwarfExpression::addShr(unsigned ShiftBy) {
|
2018-09-05 18:18:36 +08:00
|
|
|
emitConstu(ShiftBy);
|
2017-03-17 01:42:45 +08:00
|
|
|
emitOp(dwarf::DW_OP_shr);
|
2015-01-13 06:19:22 +08:00
|
|
|
}
|
|
|
|
|
2017-03-17 01:42:45 +08:00
|
|
|
void DwarfExpression::addAnd(unsigned Mask) {
|
2018-09-05 18:18:36 +08:00
|
|
|
emitConstu(Mask);
|
2017-03-17 01:42:45 +08:00
|
|
|
emitOp(dwarf::DW_OP_and);
|
2017-03-17 01:14:56 +08:00
|
|
|
}
|
|
|
|
|
2017-03-17 01:42:45 +08:00
|
|
|
bool DwarfExpression::addMachineReg(const TargetRegisterInfo &TRI,
|
2016-12-22 14:10:41 +08:00
|
|
|
unsigned MachineReg, unsigned MaxSize) {
|
2019-08-02 07:27:28 +08:00
|
|
|
if (!llvm::Register::isPhysicalRegister(MachineReg)) {
|
2017-03-22 09:15:57 +08:00
|
|
|
if (isFrameRegister(TRI, MachineReg)) {
|
|
|
|
DwarfRegs.push_back({-1, 0, nullptr});
|
|
|
|
return true;
|
|
|
|
}
|
2015-01-26 03:04:08 +08:00
|
|
|
return false;
|
2017-03-22 09:15:57 +08:00
|
|
|
}
|
2015-01-26 03:04:08 +08:00
|
|
|
|
2015-03-03 06:02:33 +08:00
|
|
|
int Reg = TRI.getDwarfRegNum(MachineReg, false);
|
2015-01-13 06:19:22 +08:00
|
|
|
|
|
|
|
// If this is a valid register number, emit it.
|
|
|
|
if (Reg >= 0) {
|
2017-03-22 09:15:57 +08:00
|
|
|
DwarfRegs.push_back({Reg, 0, nullptr});
|
2015-01-14 09:01:28 +08:00
|
|
|
return true;
|
2015-01-13 06:19:22 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Walk up the super-register chain until we find a valid number.
|
2016-12-06 02:04:47 +08:00
|
|
|
// For example, EAX on x86_64 is a 32-bit fragment of RAX with offset 0.
|
2015-03-03 06:02:33 +08:00
|
|
|
for (MCSuperRegIterator SR(MachineReg, &TRI); SR.isValid(); ++SR) {
|
|
|
|
Reg = TRI.getDwarfRegNum(*SR, false);
|
2015-01-13 06:19:22 +08:00
|
|
|
if (Reg >= 0) {
|
2015-03-03 06:02:33 +08:00
|
|
|
unsigned Idx = TRI.getSubRegIndex(*SR, MachineReg);
|
|
|
|
unsigned Size = TRI.getSubRegIdxSize(Idx);
|
|
|
|
unsigned RegOffset = TRI.getSubRegIdxOffset(Idx);
|
2017-03-22 09:15:57 +08:00
|
|
|
DwarfRegs.push_back({Reg, 0, "super-register"});
|
2016-12-10 04:43:40 +08:00
|
|
|
// Use a DW_OP_bit_piece to describe the sub-register.
|
|
|
|
setSubRegisterPiece(Size, RegOffset);
|
2015-01-14 09:01:28 +08:00
|
|
|
return true;
|
2015-01-13 06:19:22 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Otherwise, attempt to find a covering set of sub-register numbers.
|
|
|
|
// For example, Q0 on ARM is a composition of D0+D1.
|
2016-12-10 04:43:40 +08:00
|
|
|
unsigned CurPos = 0;
|
2017-04-25 02:55:33 +08:00
|
|
|
// The size of the register in bits.
|
|
|
|
const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(MachineReg);
|
|
|
|
unsigned RegSize = TRI.getRegSizeInBits(*RC);
|
2015-01-13 06:19:22 +08:00
|
|
|
// Keep track of the bits in the register we already emitted, so we
|
2018-02-14 03:54:00 +08:00
|
|
|
// can avoid emitting redundant aliasing subregs. Because this is
|
|
|
|
// just doing a greedy scan of all subregisters, it is possible that
|
|
|
|
// this doesn't find a combination of subregisters that fully cover
|
|
|
|
// the register (even though one may exist).
|
2015-01-13 06:19:22 +08:00
|
|
|
SmallBitVector Coverage(RegSize, false);
|
2015-03-03 06:02:33 +08:00
|
|
|
for (MCSubRegIterator SR(MachineReg, &TRI); SR.isValid(); ++SR) {
|
|
|
|
unsigned Idx = TRI.getSubRegIndex(MachineReg, *SR);
|
|
|
|
unsigned Size = TRI.getSubRegIdxSize(Idx);
|
|
|
|
unsigned Offset = TRI.getSubRegIdxOffset(Idx);
|
|
|
|
Reg = TRI.getDwarfRegNum(*SR, false);
|
2017-10-11 04:33:43 +08:00
|
|
|
if (Reg < 0)
|
|
|
|
continue;
|
2015-01-13 06:19:22 +08:00
|
|
|
|
|
|
|
// Intersection between the bits we already emitted and the bits
|
|
|
|
// covered by this subregister.
|
2017-08-29 07:07:43 +08:00
|
|
|
SmallBitVector CurSubReg(RegSize, false);
|
|
|
|
CurSubReg.set(Offset, Offset + Size);
|
2015-01-13 06:19:22 +08:00
|
|
|
|
|
|
|
// If this sub-register has a DWARF number and we haven't covered
|
2019-11-21 05:02:23 +08:00
|
|
|
// its range, and its range covers the value, emit a DWARF piece for it.
|
|
|
|
if (Offset < MaxSize && CurSubReg.test(Coverage)) {
|
2017-03-22 09:15:57 +08:00
|
|
|
// Emit a piece for any gap in the coverage.
|
|
|
|
if (Offset > CurPos)
|
2019-11-21 05:02:23 +08:00
|
|
|
DwarfRegs.push_back(
|
|
|
|
{-1, Offset - CurPos, "no DWARF register encoding"});
|
2017-03-22 09:15:57 +08:00
|
|
|
DwarfRegs.push_back(
|
|
|
|
{Reg, std::min<unsigned>(Size, MaxSize - Offset), "sub-register"});
|
2015-01-13 06:19:22 +08:00
|
|
|
}
|
2019-11-21 05:02:23 +08:00
|
|
|
// Mark it as emitted.
|
|
|
|
Coverage.set(Offset, Offset + Size);
|
|
|
|
CurPos = Offset + Size;
|
2015-01-13 06:19:22 +08:00
|
|
|
}
|
2018-02-14 03:54:00 +08:00
|
|
|
// Failed to find any DWARF encoding.
|
|
|
|
if (CurPos == 0)
|
|
|
|
return false;
|
|
|
|
// Found a partial or complete DWARF encoding.
|
|
|
|
if (CurPos < RegSize)
|
|
|
|
DwarfRegs.push_back({-1, RegSize - CurPos, "no DWARF register encoding"});
|
|
|
|
return true;
|
2015-01-13 06:19:22 +08:00
|
|
|
}
|
2015-01-13 08:04:06 +08:00
|
|
|
|
2017-03-17 01:42:45 +08:00
|
|
|
void DwarfExpression::addStackValue() {
|
2016-04-08 08:38:37 +08:00
|
|
|
if (DwarfVersion >= 4)
|
2017-03-17 01:42:45 +08:00
|
|
|
emitOp(dwarf::DW_OP_stack_value);
|
2016-04-08 08:38:37 +08:00
|
|
|
}
|
|
|
|
|
2017-03-17 01:42:45 +08:00
|
|
|
void DwarfExpression::addSignedConstant(int64_t Value) {
|
2019-05-23 18:37:13 +08:00
|
|
|
assert(isImplicitLocation() || isUnknownLocation());
|
2017-04-18 09:21:53 +08:00
|
|
|
LocationKind = Implicit;
|
2017-03-17 01:42:45 +08:00
|
|
|
emitOp(dwarf::DW_OP_consts);
|
|
|
|
emitSigned(Value);
|
2015-01-13 08:04:06 +08:00
|
|
|
}
|
|
|
|
|
2017-03-17 01:42:45 +08:00
|
|
|
void DwarfExpression::addUnsignedConstant(uint64_t Value) {
|
2019-05-23 18:37:13 +08:00
|
|
|
assert(isImplicitLocation() || isUnknownLocation());
|
2017-04-18 09:21:53 +08:00
|
|
|
LocationKind = Implicit;
|
2018-09-05 18:18:36 +08:00
|
|
|
emitConstu(Value);
|
2016-04-08 08:38:37 +08:00
|
|
|
}
|
|
|
|
|
2017-03-17 01:42:45 +08:00
|
|
|
void DwarfExpression::addUnsignedConstant(const APInt &Value) {
|
2019-05-23 18:37:13 +08:00
|
|
|
assert(isImplicitLocation() || isUnknownLocation());
|
2017-04-18 09:21:53 +08:00
|
|
|
LocationKind = Implicit;
|
|
|
|
|
2016-04-08 08:38:37 +08:00
|
|
|
unsigned Size = Value.getBitWidth();
|
|
|
|
const uint64_t *Data = Value.getRawData();
|
|
|
|
|
|
|
|
// Chop it up into 64-bit pieces, because that's the maximum that
|
2017-03-17 01:42:45 +08:00
|
|
|
// addUnsignedConstant takes.
|
2016-04-08 08:38:37 +08:00
|
|
|
unsigned Offset = 0;
|
|
|
|
while (Offset < Size) {
|
2017-03-17 01:42:45 +08:00
|
|
|
addUnsignedConstant(*Data++);
|
2016-04-08 08:38:37 +08:00
|
|
|
if (Offset == 0 && Size <= 64)
|
|
|
|
break;
|
2017-04-18 09:21:53 +08:00
|
|
|
addStackValue();
|
|
|
|
addOpPiece(std::min(Size - Offset, 64u), Offset);
|
2016-04-08 08:38:37 +08:00
|
|
|
Offset += 64;
|
|
|
|
}
|
2015-01-13 08:04:06 +08:00
|
|
|
}
|
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
|
|
|
|
2017-04-20 07:42:25 +08:00
|
|
|
bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI,
|
2016-11-03 00:12:20 +08:00
|
|
|
DIExpressionCursor &ExprCursor,
|
2017-04-20 07:42:25 +08:00
|
|
|
unsigned MachineReg,
|
2016-12-06 02:04:47 +08:00
|
|
|
unsigned FragmentOffsetInBits) {
|
2017-03-22 09:15:57 +08:00
|
|
|
auto Fragment = ExprCursor.getFragmentInfo();
|
2017-04-26 03:40:53 +08:00
|
|
|
if (!addMachineReg(TRI, MachineReg, Fragment ? Fragment->SizeInBits : ~1U)) {
|
|
|
|
LocationKind = Unknown;
|
2017-03-22 09:15:57 +08:00
|
|
|
return false;
|
2017-04-26 03:40:53 +08:00
|
|
|
}
|
2015-01-22 08:00:59 +08:00
|
|
|
|
2017-03-22 09:15:57 +08:00
|
|
|
bool HasComplexExpression = false;
|
2017-03-22 01:14:30 +08:00
|
|
|
auto Op = ExprCursor.peek();
|
2017-03-22 09:15:57 +08:00
|
|
|
if (Op && Op->getOp() != dwarf::DW_OP_LLVM_fragment)
|
|
|
|
HasComplexExpression = true;
|
|
|
|
|
2017-03-22 09:16:01 +08:00
|
|
|
// If the register can only be described by a complex expression (i.e.,
|
|
|
|
// multiple subregisters) it doesn't safely compose with another complex
|
|
|
|
// expression. For example, it is not possible to apply a DW_OP_deref
|
|
|
|
// operation to multiple DW_OP_pieces.
|
|
|
|
if (HasComplexExpression && DwarfRegs.size() > 1) {
|
|
|
|
DwarfRegs.clear();
|
2017-04-26 03:40:53 +08:00
|
|
|
LocationKind = Unknown;
|
2017-03-22 09:16:01 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-08-01 00:51:28 +08:00
|
|
|
// Handle simple register locations. If we are supposed to emit
|
|
|
|
// a call site parameter expression and if that expression is just a register
|
|
|
|
// location, emit it with addBReg and offset 0, because we should emit a DWARF
|
|
|
|
// expression representing a value, rather than a location.
|
2019-11-15 01:20:58 +08:00
|
|
|
if (!isMemoryLocation() && !HasComplexExpression && (!isParameterValue() ||
|
|
|
|
isEntryValue())) {
|
2017-03-22 09:15:57 +08:00
|
|
|
for (auto &Reg : DwarfRegs) {
|
|
|
|
if (Reg.DwarfRegNo >= 0)
|
|
|
|
addReg(Reg.DwarfRegNo, Reg.Comment);
|
|
|
|
addOpPiece(Reg.Size);
|
|
|
|
}
|
2019-06-27 21:52:34 +08:00
|
|
|
|
[DebugInfo] Add a DW_OP_LLVM_entry_value operation
Summary:
Internally in LLVM's metadata we use DW_OP_entry_value operations with
the same semantics as DWARF; that is, its operand specifies the number
of bytes that the entry value covers.
At the time of emitting entry values we don't know the emitted size of
the DWARF expression that the entry value will cover. Currently the size
is hardcoded to 1 in DIExpression, and other values causes the verifier
to fail. As the size is 1, that effectively means that we can only have
valid entry values for registers that can be encoded in one byte, which
are the registers with DWARF numbers 0 to 31 (as they can be encoded as
single-byte DW_OP_reg0..DW_OP_reg31 rather than a multi-byte
DW_OP_regx). It is a bit confusing, but it seems like llvm-dwarfdump
will print an operation "correctly", even if the byte size is less than
that, which may make it seem that we emit correct DWARF for registers
with DWARF numbers > 31. If you instead use readelf for such cases, it
will interpret the number of specified bytes as a DWARF expression. This
seems like a limitation in llvm-dwarfdump.
As suggested in D66746, a way forward would be to add an internal
variant of DW_OP_entry_value, DW_OP_LLVM_entry_value, whose operand
instead specifies the number of operations that the entry value covers,
and we then translate that into the byte size at the time of emission.
In this patch that internal operation is added. This patch keeps the
limitation that a entry value can only be applied to simple register
locations, but it will fix the issue with the size operand being
incorrect for DWARF numbers > 31.
Reviewers: aprantl, vsk, djtodoro, NikolaPrica
Reviewed By: aprantl
Subscribers: jyknight, fedor.sergeev, hiraditya, llvm-commits
Tags: #debug-info, #llvm
Differential Revision: https://reviews.llvm.org/D67492
llvm-svn: 374881
2019-10-15 19:31:21 +08:00
|
|
|
if (isEntryValue())
|
|
|
|
finalizeEntryValue();
|
|
|
|
|
2019-08-01 00:51:28 +08:00
|
|
|
if (isEntryValue() && !isParameterValue() && DwarfVersion >= 4)
|
2019-06-27 21:52:34 +08:00
|
|
|
emitOp(dwarf::DW_OP_stack_value);
|
|
|
|
|
2017-03-22 09:15:57 +08:00
|
|
|
DwarfRegs.clear();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-04-18 09:21:53 +08:00
|
|
|
// Don't emit locations that cannot be expressed without DW_OP_stack_value.
|
2017-04-21 04:42:33 +08:00
|
|
|
if (DwarfVersion < 4)
|
2018-10-19 14:12:02 +08:00
|
|
|
if (any_of(ExprCursor, [](DIExpression::ExprOperand Op) -> bool {
|
|
|
|
return Op.getOp() == dwarf::DW_OP_stack_value;
|
|
|
|
})) {
|
2017-04-21 04:42:33 +08:00
|
|
|
DwarfRegs.clear();
|
2017-04-26 03:40:53 +08:00
|
|
|
LocationKind = Unknown;
|
2017-04-21 04:42:33 +08:00
|
|
|
return false;
|
|
|
|
}
|
2017-04-18 09:21:53 +08:00
|
|
|
|
2017-03-22 09:15:57 +08:00
|
|
|
assert(DwarfRegs.size() == 1);
|
|
|
|
auto Reg = DwarfRegs[0];
|
2017-04-18 09:21:53 +08:00
|
|
|
bool FBReg = isFrameRegister(TRI, MachineReg);
|
|
|
|
int SignedOffset = 0;
|
2017-03-22 09:15:57 +08:00
|
|
|
assert(Reg.Size == 0 && "subregister has same size as superregister");
|
|
|
|
|
|
|
|
// Pattern-match combinations for which more efficient representations exist.
|
2017-06-14 00:54:44 +08:00
|
|
|
// [Reg, DW_OP_plus_uconst, Offset] --> [DW_OP_breg, Offset].
|
|
|
|
if (Op && (Op->getOp() == dwarf::DW_OP_plus_uconst)) {
|
[DwarfExpression] Disallow some rewrites to avoid undefined behavior
Summary:
The value operand in DW_OP_plus_uconst/DW_OP_constu value can be
large (it uses uint64_t as representation internally in LLVM).
This means that in the uint64_t to int conversions, previously done
by DwarfExpression::addMachineRegExpression, could lose information.
Also, the negation done in "-Offset" was undefined behavior in case
Offset was exactly INT_MIN.
To avoid the above problems, we now avoid transformation like
[Reg, DW_OP_plus_uconst, Offset] --> [DW_OP_breg, Offset]
and
[Reg, DW_OP_constu, Offset, DW_OP_plus] --> [DW_OP_breg, Offset]
when Offset > INT_MAX.
And we avoid to transform
[Reg, DW_OP_constu, Offset, DW_OP_minus] --> [DW_OP_breg,-Offset]
when Offset > INT_MAX+1.
The patch also adjusts DwarfCompileUnit::constructVariableDIEImpl
to make sure that "DW_OP_constu, Offset, DW_OP_minus" is used
instead of "DW_OP_plus_uconst, Offset" when creating DIExpressions
with negative frame index offsets.
Notice that this might just be the tip of the iceberg. There
are lots of fishy handling related to these constants. I think both
DIExpression::appendOffset and DIExpression::extractIfOffset may
trigger undefined behavior for certain values.
Reviewers: sdesmalen, rnk, JDevlieghere
Reviewed By: JDevlieghere
Subscribers: jholewinski, aprantl, hiraditya, ychen, uabelho, llvm-commits
Tags: #debug-info, #llvm
Differential Revision: https://reviews.llvm.org/D67263
llvm-svn: 371304
2019-09-07 19:40:10 +08:00
|
|
|
uint64_t Offset = Op->getArg(0);
|
|
|
|
uint64_t IntMax = static_cast<uint64_t>(std::numeric_limits<int>::max());
|
|
|
|
if (Offset <= IntMax) {
|
|
|
|
SignedOffset = Offset;
|
|
|
|
ExprCursor.take();
|
|
|
|
}
|
2017-06-14 00:54:44 +08:00
|
|
|
}
|
|
|
|
|
2017-06-14 21:14:38 +08:00
|
|
|
// [Reg, DW_OP_constu, Offset, DW_OP_plus] --> [DW_OP_breg, Offset]
|
|
|
|
// [Reg, DW_OP_constu, Offset, DW_OP_minus] --> [DW_OP_breg,-Offset]
|
2017-04-18 09:21:53 +08:00
|
|
|
// If Reg is a subregister we need to mask it out before subtracting.
|
2017-06-14 21:14:38 +08:00
|
|
|
if (Op && Op->getOp() == dwarf::DW_OP_constu) {
|
[DwarfExpression] Disallow some rewrites to avoid undefined behavior
Summary:
The value operand in DW_OP_plus_uconst/DW_OP_constu value can be
large (it uses uint64_t as representation internally in LLVM).
This means that in the uint64_t to int conversions, previously done
by DwarfExpression::addMachineRegExpression, could lose information.
Also, the negation done in "-Offset" was undefined behavior in case
Offset was exactly INT_MIN.
To avoid the above problems, we now avoid transformation like
[Reg, DW_OP_plus_uconst, Offset] --> [DW_OP_breg, Offset]
and
[Reg, DW_OP_constu, Offset, DW_OP_plus] --> [DW_OP_breg, Offset]
when Offset > INT_MAX.
And we avoid to transform
[Reg, DW_OP_constu, Offset, DW_OP_minus] --> [DW_OP_breg,-Offset]
when Offset > INT_MAX+1.
The patch also adjusts DwarfCompileUnit::constructVariableDIEImpl
to make sure that "DW_OP_constu, Offset, DW_OP_minus" is used
instead of "DW_OP_plus_uconst, Offset" when creating DIExpressions
with negative frame index offsets.
Notice that this might just be the tip of the iceberg. There
are lots of fishy handling related to these constants. I think both
DIExpression::appendOffset and DIExpression::extractIfOffset may
trigger undefined behavior for certain values.
Reviewers: sdesmalen, rnk, JDevlieghere
Reviewed By: JDevlieghere
Subscribers: jholewinski, aprantl, hiraditya, ychen, uabelho, llvm-commits
Tags: #debug-info, #llvm
Differential Revision: https://reviews.llvm.org/D67263
llvm-svn: 371304
2019-09-07 19:40:10 +08:00
|
|
|
uint64_t Offset = Op->getArg(0);
|
|
|
|
uint64_t IntMax = static_cast<uint64_t>(std::numeric_limits<int>::max());
|
2017-06-14 21:14:38 +08:00
|
|
|
auto N = ExprCursor.peekNext();
|
[DwarfExpression] Disallow some rewrites to avoid undefined behavior
Summary:
The value operand in DW_OP_plus_uconst/DW_OP_constu value can be
large (it uses uint64_t as representation internally in LLVM).
This means that in the uint64_t to int conversions, previously done
by DwarfExpression::addMachineRegExpression, could lose information.
Also, the negation done in "-Offset" was undefined behavior in case
Offset was exactly INT_MIN.
To avoid the above problems, we now avoid transformation like
[Reg, DW_OP_plus_uconst, Offset] --> [DW_OP_breg, Offset]
and
[Reg, DW_OP_constu, Offset, DW_OP_plus] --> [DW_OP_breg, Offset]
when Offset > INT_MAX.
And we avoid to transform
[Reg, DW_OP_constu, Offset, DW_OP_minus] --> [DW_OP_breg,-Offset]
when Offset > INT_MAX+1.
The patch also adjusts DwarfCompileUnit::constructVariableDIEImpl
to make sure that "DW_OP_constu, Offset, DW_OP_minus" is used
instead of "DW_OP_plus_uconst, Offset" when creating DIExpressions
with negative frame index offsets.
Notice that this might just be the tip of the iceberg. There
are lots of fishy handling related to these constants. I think both
DIExpression::appendOffset and DIExpression::extractIfOffset may
trigger undefined behavior for certain values.
Reviewers: sdesmalen, rnk, JDevlieghere
Reviewed By: JDevlieghere
Subscribers: jholewinski, aprantl, hiraditya, ychen, uabelho, llvm-commits
Tags: #debug-info, #llvm
Differential Revision: https://reviews.llvm.org/D67263
llvm-svn: 371304
2019-09-07 19:40:10 +08:00
|
|
|
if (N && N->getOp() == dwarf::DW_OP_plus && Offset <= IntMax) {
|
|
|
|
SignedOffset = Offset;
|
|
|
|
ExprCursor.consume(2);
|
|
|
|
} else if (N && N->getOp() == dwarf::DW_OP_minus &&
|
|
|
|
!SubRegisterSizeInBits && Offset <= IntMax + 1) {
|
|
|
|
SignedOffset = -static_cast<int64_t>(Offset);
|
2017-06-14 21:14:38 +08:00
|
|
|
ExprCursor.consume(2);
|
|
|
|
}
|
2016-12-22 14:10:41 +08:00
|
|
|
}
|
2017-06-14 21:14:38 +08:00
|
|
|
|
2017-04-18 09:21:53 +08:00
|
|
|
if (FBReg)
|
|
|
|
addFBReg(SignedOffset);
|
|
|
|
else
|
|
|
|
addBReg(Reg.DwarfRegNo, SignedOffset);
|
|
|
|
DwarfRegs.clear();
|
|
|
|
return true;
|
|
|
|
}
|
2017-03-22 09:15:57 +08:00
|
|
|
|
[DebugInfo] Add a DW_OP_LLVM_entry_value operation
Summary:
Internally in LLVM's metadata we use DW_OP_entry_value operations with
the same semantics as DWARF; that is, its operand specifies the number
of bytes that the entry value covers.
At the time of emitting entry values we don't know the emitted size of
the DWARF expression that the entry value will cover. Currently the size
is hardcoded to 1 in DIExpression, and other values causes the verifier
to fail. As the size is 1, that effectively means that we can only have
valid entry values for registers that can be encoded in one byte, which
are the registers with DWARF numbers 0 to 31 (as they can be encoded as
single-byte DW_OP_reg0..DW_OP_reg31 rather than a multi-byte
DW_OP_regx). It is a bit confusing, but it seems like llvm-dwarfdump
will print an operation "correctly", even if the byte size is less than
that, which may make it seem that we emit correct DWARF for registers
with DWARF numbers > 31. If you instead use readelf for such cases, it
will interpret the number of specified bytes as a DWARF expression. This
seems like a limitation in llvm-dwarfdump.
As suggested in D66746, a way forward would be to add an internal
variant of DW_OP_entry_value, DW_OP_LLVM_entry_value, whose operand
instead specifies the number of operations that the entry value covers,
and we then translate that into the byte size at the time of emission.
In this patch that internal operation is added. This patch keeps the
limitation that a entry value can only be applied to simple register
locations, but it will fix the issue with the size operand being
incorrect for DWARF numbers > 31.
Reviewers: aprantl, vsk, djtodoro, NikolaPrica
Reviewed By: aprantl
Subscribers: jyknight, fedor.sergeev, hiraditya, llvm-commits
Tags: #debug-info, #llvm
Differential Revision: https://reviews.llvm.org/D67492
llvm-svn: 374881
2019-10-15 19:31:21 +08:00
|
|
|
void DwarfExpression::beginEntryValueExpression(
|
|
|
|
DIExpressionCursor &ExprCursor) {
|
2019-06-27 21:52:34 +08:00
|
|
|
auto Op = ExprCursor.take();
|
2019-10-15 22:23:11 +08:00
|
|
|
(void)Op;
|
[DebugInfo] Add a DW_OP_LLVM_entry_value operation
Summary:
Internally in LLVM's metadata we use DW_OP_entry_value operations with
the same semantics as DWARF; that is, its operand specifies the number
of bytes that the entry value covers.
At the time of emitting entry values we don't know the emitted size of
the DWARF expression that the entry value will cover. Currently the size
is hardcoded to 1 in DIExpression, and other values causes the verifier
to fail. As the size is 1, that effectively means that we can only have
valid entry values for registers that can be encoded in one byte, which
are the registers with DWARF numbers 0 to 31 (as they can be encoded as
single-byte DW_OP_reg0..DW_OP_reg31 rather than a multi-byte
DW_OP_regx). It is a bit confusing, but it seems like llvm-dwarfdump
will print an operation "correctly", even if the byte size is less than
that, which may make it seem that we emit correct DWARF for registers
with DWARF numbers > 31. If you instead use readelf for such cases, it
will interpret the number of specified bytes as a DWARF expression. This
seems like a limitation in llvm-dwarfdump.
As suggested in D66746, a way forward would be to add an internal
variant of DW_OP_entry_value, DW_OP_LLVM_entry_value, whose operand
instead specifies the number of operations that the entry value covers,
and we then translate that into the byte size at the time of emission.
In this patch that internal operation is added. This patch keeps the
limitation that a entry value can only be applied to simple register
locations, but it will fix the issue with the size operand being
incorrect for DWARF numbers > 31.
Reviewers: aprantl, vsk, djtodoro, NikolaPrica
Reviewed By: aprantl
Subscribers: jyknight, fedor.sergeev, hiraditya, llvm-commits
Tags: #debug-info, #llvm
Differential Revision: https://reviews.llvm.org/D67492
llvm-svn: 374881
2019-10-15 19:31:21 +08:00
|
|
|
assert(Op && Op->getOp() == dwarf::DW_OP_LLVM_entry_value);
|
2019-06-27 21:52:34 +08:00
|
|
|
assert(!isMemoryLocation() &&
|
|
|
|
"We don't support entry values of memory locations yet");
|
[DebugInfo] Add a DW_OP_LLVM_entry_value operation
Summary:
Internally in LLVM's metadata we use DW_OP_entry_value operations with
the same semantics as DWARF; that is, its operand specifies the number
of bytes that the entry value covers.
At the time of emitting entry values we don't know the emitted size of
the DWARF expression that the entry value will cover. Currently the size
is hardcoded to 1 in DIExpression, and other values causes the verifier
to fail. As the size is 1, that effectively means that we can only have
valid entry values for registers that can be encoded in one byte, which
are the registers with DWARF numbers 0 to 31 (as they can be encoded as
single-byte DW_OP_reg0..DW_OP_reg31 rather than a multi-byte
DW_OP_regx). It is a bit confusing, but it seems like llvm-dwarfdump
will print an operation "correctly", even if the byte size is less than
that, which may make it seem that we emit correct DWARF for registers
with DWARF numbers > 31. If you instead use readelf for such cases, it
will interpret the number of specified bytes as a DWARF expression. This
seems like a limitation in llvm-dwarfdump.
As suggested in D66746, a way forward would be to add an internal
variant of DW_OP_entry_value, DW_OP_LLVM_entry_value, whose operand
instead specifies the number of operations that the entry value covers,
and we then translate that into the byte size at the time of emission.
In this patch that internal operation is added. This patch keeps the
limitation that a entry value can only be applied to simple register
locations, but it will fix the issue with the size operand being
incorrect for DWARF numbers > 31.
Reviewers: aprantl, vsk, djtodoro, NikolaPrica
Reviewed By: aprantl
Subscribers: jyknight, fedor.sergeev, hiraditya, llvm-commits
Tags: #debug-info, #llvm
Differential Revision: https://reviews.llvm.org/D67492
llvm-svn: 374881
2019-10-15 19:31:21 +08:00
|
|
|
assert(!IsEmittingEntryValue && "Already emitting entry value?");
|
|
|
|
assert(Op->getArg(0) == 1 &&
|
|
|
|
"Can currently only emit entry values covering a single operation");
|
2019-06-27 21:52:34 +08:00
|
|
|
|
2019-08-27 04:53:12 +08:00
|
|
|
emitOp(CU.getDwarf5OrGNULocationAtom(dwarf::DW_OP_entry_value));
|
[DebugInfo] Add a DW_OP_LLVM_entry_value operation
Summary:
Internally in LLVM's metadata we use DW_OP_entry_value operations with
the same semantics as DWARF; that is, its operand specifies the number
of bytes that the entry value covers.
At the time of emitting entry values we don't know the emitted size of
the DWARF expression that the entry value will cover. Currently the size
is hardcoded to 1 in DIExpression, and other values causes the verifier
to fail. As the size is 1, that effectively means that we can only have
valid entry values for registers that can be encoded in one byte, which
are the registers with DWARF numbers 0 to 31 (as they can be encoded as
single-byte DW_OP_reg0..DW_OP_reg31 rather than a multi-byte
DW_OP_regx). It is a bit confusing, but it seems like llvm-dwarfdump
will print an operation "correctly", even if the byte size is less than
that, which may make it seem that we emit correct DWARF for registers
with DWARF numbers > 31. If you instead use readelf for such cases, it
will interpret the number of specified bytes as a DWARF expression. This
seems like a limitation in llvm-dwarfdump.
As suggested in D66746, a way forward would be to add an internal
variant of DW_OP_entry_value, DW_OP_LLVM_entry_value, whose operand
instead specifies the number of operations that the entry value covers,
and we then translate that into the byte size at the time of emission.
In this patch that internal operation is added. This patch keeps the
limitation that a entry value can only be applied to simple register
locations, but it will fix the issue with the size operand being
incorrect for DWARF numbers > 31.
Reviewers: aprantl, vsk, djtodoro, NikolaPrica
Reviewed By: aprantl
Subscribers: jyknight, fedor.sergeev, hiraditya, llvm-commits
Tags: #debug-info, #llvm
Differential Revision: https://reviews.llvm.org/D67492
llvm-svn: 374881
2019-10-15 19:31:21 +08:00
|
|
|
IsEmittingEntryValue = true;
|
|
|
|
enableTemporaryBuffer();
|
|
|
|
}
|
|
|
|
|
|
|
|
void DwarfExpression::finalizeEntryValue() {
|
|
|
|
assert(IsEmittingEntryValue && "Entry value not open?");
|
|
|
|
disableTemporaryBuffer();
|
|
|
|
|
|
|
|
// Emit the entry value's size operand.
|
|
|
|
unsigned Size = getTemporaryBufferSize();
|
|
|
|
emitUnsigned(Size);
|
|
|
|
|
|
|
|
// Emit the entry value's DWARF block operand.
|
|
|
|
commitTemporaryBuffer();
|
|
|
|
|
|
|
|
IsEmittingEntryValue = false;
|
2019-06-27 21:52:34 +08:00
|
|
|
}
|
|
|
|
|
2017-04-18 09:21:53 +08:00
|
|
|
/// Assuming a well-formed expression, match "DW_OP_deref* DW_OP_LLVM_fragment?".
|
|
|
|
static bool isMemoryLocation(DIExpressionCursor ExprCursor) {
|
|
|
|
while (ExprCursor) {
|
|
|
|
auto Op = ExprCursor.take();
|
|
|
|
switch (Op->getOp()) {
|
|
|
|
case dwarf::DW_OP_deref:
|
|
|
|
case dwarf::DW_OP_LLVM_fragment:
|
2017-03-22 09:15:57 +08:00
|
|
|
break;
|
2017-04-18 09:21:53 +08:00
|
|
|
default:
|
|
|
|
return false;
|
2017-03-22 09:15:57 +08:00
|
|
|
}
|
2015-01-22 08:00:59 +08:00
|
|
|
}
|
2017-03-22 09:15:57 +08:00
|
|
|
return true;
|
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
|
|
|
}
|
|
|
|
|
2017-03-17 01:42:45 +08:00
|
|
|
void DwarfExpression::addExpression(DIExpressionCursor &&ExprCursor,
|
2016-12-06 02:04:47 +08:00
|
|
|
unsigned FragmentOffsetInBits) {
|
2017-04-18 09:21:53 +08:00
|
|
|
// If we need to mask out a subregister, do it now, unless the next
|
|
|
|
// operation would emit an OpPiece anyway.
|
|
|
|
auto N = ExprCursor.peek();
|
|
|
|
if (SubRegisterSizeInBits && N && (N->getOp() != dwarf::DW_OP_LLVM_fragment))
|
|
|
|
maskSubRegister();
|
|
|
|
|
2019-03-19 21:16:28 +08:00
|
|
|
Optional<DIExpression::ExprOperand> PrevConvertOp = None;
|
|
|
|
|
2016-11-03 00:12:20 +08:00
|
|
|
while (ExprCursor) {
|
|
|
|
auto Op = ExprCursor.take();
|
2019-08-01 00:51:28 +08:00
|
|
|
uint64_t OpNum = Op->getOp();
|
|
|
|
|
|
|
|
if (OpNum >= dwarf::DW_OP_reg0 && OpNum <= dwarf::DW_OP_reg31) {
|
|
|
|
emitOp(OpNum);
|
|
|
|
continue;
|
|
|
|
} else if (OpNum >= dwarf::DW_OP_breg0 && OpNum <= dwarf::DW_OP_breg31) {
|
|
|
|
addBReg(OpNum - dwarf::DW_OP_breg0, Op->getArg(0));
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (OpNum) {
|
2016-12-06 02:04:47 +08:00
|
|
|
case dwarf::DW_OP_LLVM_fragment: {
|
2016-12-10 04:43:40 +08:00
|
|
|
unsigned SizeInBits = Op->getArg(1);
|
|
|
|
unsigned FragmentOffset = Op->getArg(0);
|
|
|
|
// The fragment offset must have already been adjusted by emitting an
|
|
|
|
// empty DW_OP_piece / DW_OP_bit_piece before we emitted the base
|
|
|
|
// location.
|
|
|
|
assert(OffsetInBits >= FragmentOffset && "fragment offset not added?");
|
2019-11-21 05:02:23 +08:00
|
|
|
assert(SizeInBits >= OffsetInBits - FragmentOffset && "size underflow");
|
2016-12-10 04:43:40 +08:00
|
|
|
|
2017-04-18 09:21:53 +08:00
|
|
|
// If addMachineReg already emitted DW_OP_piece operations to represent
|
2016-12-10 04:43:40 +08:00
|
|
|
// a super-register by splicing together sub-registers, subtract the size
|
|
|
|
// of the pieces that was already emitted.
|
|
|
|
SizeInBits -= OffsetInBits - FragmentOffset;
|
|
|
|
|
2017-04-18 09:21:53 +08:00
|
|
|
// If addMachineReg requested a DW_OP_bit_piece to stencil out a
|
2016-12-10 04:43:40 +08:00
|
|
|
// sub-register that is smaller than the current fragment's size, use it.
|
|
|
|
if (SubRegisterSizeInBits)
|
|
|
|
SizeInBits = std::min<unsigned>(SizeInBits, SubRegisterSizeInBits);
|
2017-04-18 09:21:53 +08:00
|
|
|
|
|
|
|
// Emit a DW_OP_stack_value for implicit location descriptions.
|
2019-05-23 18:37:13 +08:00
|
|
|
if (isImplicitLocation())
|
2017-04-18 09:21:53 +08:00
|
|
|
addStackValue();
|
|
|
|
|
|
|
|
// Emit the DW_OP_piece.
|
2017-03-17 01:42:45 +08:00
|
|
|
addOpPiece(SizeInBits, SubRegisterOffsetInBits);
|
2016-12-10 04:43:40 +08:00
|
|
|
setSubRegisterPiece(0, 0);
|
2017-04-18 09:21:53 +08:00
|
|
|
// Reset the location description kind.
|
|
|
|
LocationKind = Unknown;
|
|
|
|
return;
|
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
|
|
|
}
|
2017-06-14 00:54:44 +08:00
|
|
|
case dwarf::DW_OP_plus_uconst:
|
2019-05-23 18:37:13 +08:00
|
|
|
assert(!isRegisterLocation());
|
2017-03-17 01:42:45 +08:00
|
|
|
emitOp(dwarf::DW_OP_plus_uconst);
|
|
|
|
emitUnsigned(Op->getArg(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
|
|
|
break;
|
2017-06-14 21:14:38 +08:00
|
|
|
case dwarf::DW_OP_plus:
|
2015-10-01 03:55:43 +08:00
|
|
|
case dwarf::DW_OP_minus:
|
2017-09-21 18:04:02 +08:00
|
|
|
case dwarf::DW_OP_mul:
|
2018-02-13 09:09:52 +08:00
|
|
|
case dwarf::DW_OP_div:
|
|
|
|
case dwarf::DW_OP_mod:
|
2018-02-10 03:19:55 +08:00
|
|
|
case dwarf::DW_OP_or:
|
2018-02-14 21:10:35 +08:00
|
|
|
case dwarf::DW_OP_and:
|
2018-02-13 09:09:46 +08:00
|
|
|
case dwarf::DW_OP_xor:
|
2018-02-13 09:09:49 +08:00
|
|
|
case dwarf::DW_OP_shl:
|
|
|
|
case dwarf::DW_OP_shr:
|
|
|
|
case dwarf::DW_OP_shra:
|
2018-07-07 01:32:39 +08:00
|
|
|
case dwarf::DW_OP_lit0:
|
|
|
|
case dwarf::DW_OP_not:
|
|
|
|
case dwarf::DW_OP_dup:
|
2019-08-01 00:51:28 +08:00
|
|
|
emitOp(OpNum);
|
2015-10-01 03:55:43 +08:00
|
|
|
break;
|
2017-08-18 05:26:39 +08:00
|
|
|
case dwarf::DW_OP_deref:
|
2019-05-23 18:37:13 +08:00
|
|
|
assert(!isRegisterLocation());
|
|
|
|
if (!isMemoryLocation() && ::isMemoryLocation(ExprCursor))
|
2017-04-18 09:21:53 +08:00
|
|
|
// Turning this into a memory location description makes the deref
|
|
|
|
// implicit.
|
|
|
|
LocationKind = Memory;
|
|
|
|
else
|
|
|
|
emitOp(dwarf::DW_OP_deref);
|
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
|
|
|
break;
|
2016-09-13 09:12:59 +08:00
|
|
|
case dwarf::DW_OP_constu:
|
2019-05-23 18:37:13 +08:00
|
|
|
assert(!isRegisterLocation());
|
2018-09-05 18:18:36 +08:00
|
|
|
emitConstu(Op->getArg(0));
|
2016-09-13 09:12:59 +08:00
|
|
|
break;
|
2019-03-19 21:16:28 +08:00
|
|
|
case dwarf::DW_OP_LLVM_convert: {
|
|
|
|
unsigned BitSize = Op->getArg(0);
|
|
|
|
dwarf::TypeKind Encoding = static_cast<dwarf::TypeKind>(Op->getArg(1));
|
|
|
|
if (DwarfVersion >= 5) {
|
|
|
|
emitOp(dwarf::DW_OP_convert);
|
|
|
|
// Reuse the base_type if we already have one in this CU otherwise we
|
|
|
|
// create a new one.
|
|
|
|
unsigned I = 0, E = CU.ExprRefedBaseTypes.size();
|
|
|
|
for (; I != E; ++I)
|
|
|
|
if (CU.ExprRefedBaseTypes[I].BitSize == BitSize &&
|
|
|
|
CU.ExprRefedBaseTypes[I].Encoding == Encoding)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (I == E)
|
|
|
|
CU.ExprRefedBaseTypes.emplace_back(BitSize, Encoding);
|
|
|
|
|
|
|
|
// If targeting a location-list; simply emit the index into the raw
|
|
|
|
// byte stream as ULEB128, DwarfDebug::emitDebugLocEntry has been
|
|
|
|
// fitted with means to extract it later.
|
|
|
|
// If targeting a inlined DW_AT_location; insert a DIEBaseTypeRef
|
|
|
|
// (containing the index and a resolve mechanism during emit) into the
|
|
|
|
// DIE value list.
|
|
|
|
emitBaseTypeRef(I);
|
|
|
|
} else {
|
|
|
|
if (PrevConvertOp && PrevConvertOp->getArg(0) < BitSize) {
|
|
|
|
if (Encoding == dwarf::DW_ATE_signed)
|
|
|
|
emitLegacySExt(PrevConvertOp->getArg(0));
|
|
|
|
else if (Encoding == dwarf::DW_ATE_unsigned)
|
|
|
|
emitLegacyZExt(PrevConvertOp->getArg(0));
|
|
|
|
PrevConvertOp = None;
|
|
|
|
} else {
|
|
|
|
PrevConvertOp = Op;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2016-09-13 09:12:59 +08:00
|
|
|
case dwarf::DW_OP_stack_value:
|
2017-04-18 09:21:53 +08:00
|
|
|
LocationKind = Implicit;
|
2016-09-13 09:12:59 +08:00
|
|
|
break;
|
2017-03-08 08:28:57 +08:00
|
|
|
case dwarf::DW_OP_swap:
|
2019-05-23 18:37:13 +08:00
|
|
|
assert(!isRegisterLocation());
|
2017-03-17 01:42:45 +08:00
|
|
|
emitOp(dwarf::DW_OP_swap);
|
2017-03-08 08:28:57 +08:00
|
|
|
break;
|
|
|
|
case dwarf::DW_OP_xderef:
|
2019-05-23 18:37:13 +08:00
|
|
|
assert(!isRegisterLocation());
|
2017-03-17 01:42:45 +08:00
|
|
|
emitOp(dwarf::DW_OP_xderef);
|
2017-03-08 08:28:57 +08:00
|
|
|
break;
|
2019-04-30 15:58:57 +08:00
|
|
|
case dwarf::DW_OP_deref_size:
|
|
|
|
emitOp(dwarf::DW_OP_deref_size);
|
|
|
|
emitData1(Op->getArg(0));
|
|
|
|
break;
|
2019-06-18 07:39:41 +08:00
|
|
|
case dwarf::DW_OP_LLVM_tag_offset:
|
|
|
|
TagOffset = Op->getArg(0);
|
|
|
|
break;
|
2019-08-01 00:51:28 +08:00
|
|
|
case dwarf::DW_OP_regx:
|
|
|
|
emitOp(dwarf::DW_OP_regx);
|
|
|
|
emitUnsigned(Op->getArg(0));
|
|
|
|
break;
|
|
|
|
case dwarf::DW_OP_bregx:
|
|
|
|
emitOp(dwarf::DW_OP_bregx);
|
|
|
|
emitUnsigned(Op->getArg(0));
|
|
|
|
emitSigned(Op->getArg(1));
|
|
|
|
break;
|
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
|
|
|
default:
|
2015-04-22 02:44:06 +08:00
|
|
|
llvm_unreachable("unhandled opcode found in expression");
|
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
|
|
|
}
|
|
|
|
}
|
2017-04-18 09:21:53 +08:00
|
|
|
|
2019-08-01 00:51:28 +08:00
|
|
|
if (isImplicitLocation() && !isParameterValue())
|
2017-04-18 09:21:53 +08:00
|
|
|
// Turn this into an implicit location description.
|
|
|
|
addStackValue();
|
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
|
|
|
}
|
2016-12-10 04:43:40 +08:00
|
|
|
|
2017-03-17 01:42:45 +08:00
|
|
|
/// add masking operations to stencil out a subregister.
|
2017-03-17 01:14:56 +08:00
|
|
|
void DwarfExpression::maskSubRegister() {
|
|
|
|
assert(SubRegisterSizeInBits && "no subregister was registered");
|
|
|
|
if (SubRegisterOffsetInBits > 0)
|
2017-03-17 01:42:45 +08:00
|
|
|
addShr(SubRegisterOffsetInBits);
|
2017-03-17 02:06:04 +08:00
|
|
|
uint64_t Mask = (1ULL << (uint64_t)SubRegisterSizeInBits) - 1ULL;
|
2017-03-17 01:42:45 +08:00
|
|
|
addAnd(Mask);
|
2017-03-17 01:14:56 +08:00
|
|
|
}
|
|
|
|
|
2016-12-10 04:43:40 +08:00
|
|
|
void DwarfExpression::finalize() {
|
2017-03-22 09:15:57 +08:00
|
|
|
assert(DwarfRegs.size() == 0 && "dwarf registers not emitted");
|
2017-03-17 01:14:56 +08:00
|
|
|
// Emit any outstanding DW_OP_piece operations to mask out subregisters.
|
|
|
|
if (SubRegisterSizeInBits == 0)
|
|
|
|
return;
|
|
|
|
// Don't emit a DW_OP_piece for a subregister at offset 0.
|
|
|
|
if (SubRegisterOffsetInBits == 0)
|
|
|
|
return;
|
2017-03-17 01:42:45 +08:00
|
|
|
addOpPiece(SubRegisterSizeInBits, SubRegisterOffsetInBits);
|
2016-12-10 04:43:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void DwarfExpression::addFragmentOffset(const DIExpression *Expr) {
|
|
|
|
if (!Expr || !Expr->isFragment())
|
|
|
|
return;
|
|
|
|
|
2016-12-22 13:27:12 +08:00
|
|
|
uint64_t FragmentOffset = Expr->getFragmentInfo()->OffsetInBits;
|
2016-12-10 04:43:40 +08:00
|
|
|
assert(FragmentOffset >= OffsetInBits &&
|
|
|
|
"overlapping or duplicate fragments");
|
|
|
|
if (FragmentOffset > OffsetInBits)
|
2017-03-17 01:42:45 +08:00
|
|
|
addOpPiece(FragmentOffset - OffsetInBits);
|
2016-12-10 04:43:40 +08:00
|
|
|
OffsetInBits = FragmentOffset;
|
|
|
|
}
|
2019-03-19 21:16:28 +08:00
|
|
|
|
|
|
|
void DwarfExpression::emitLegacySExt(unsigned FromBits) {
|
|
|
|
// (((X >> (FromBits - 1)) * (~0)) << FromBits) | X
|
|
|
|
emitOp(dwarf::DW_OP_dup);
|
|
|
|
emitOp(dwarf::DW_OP_constu);
|
|
|
|
emitUnsigned(FromBits - 1);
|
|
|
|
emitOp(dwarf::DW_OP_shr);
|
|
|
|
emitOp(dwarf::DW_OP_lit0);
|
|
|
|
emitOp(dwarf::DW_OP_not);
|
|
|
|
emitOp(dwarf::DW_OP_mul);
|
|
|
|
emitOp(dwarf::DW_OP_constu);
|
|
|
|
emitUnsigned(FromBits);
|
|
|
|
emitOp(dwarf::DW_OP_shl);
|
|
|
|
emitOp(dwarf::DW_OP_or);
|
|
|
|
}
|
|
|
|
|
|
|
|
void DwarfExpression::emitLegacyZExt(unsigned FromBits) {
|
|
|
|
// (X & (1 << FromBits - 1))
|
|
|
|
emitOp(dwarf::DW_OP_constu);
|
|
|
|
emitUnsigned((1ULL << FromBits) - 1);
|
|
|
|
emitOp(dwarf::DW_OP_and);
|
|
|
|
}
|