1 //===-- PDBLocationToDWARFExpression.cpp ------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "PDBLocationToDWARFExpression.h"
11 #include "lldb/Core/Section.h"
12 #include "lldb/Core/StreamBuffer.h"
13 #include "lldb/Core/dwarf.h"
14 #include "lldb/Expression/DWARFExpression.h"
15 #include "lldb/Symbol/Variable.h"
16 #include "lldb/Utility/DataBufferHeap.h"
18 #include "llvm/DebugInfo/CodeView/CodeView.h"
19 #include "llvm/DebugInfo/PDB/IPDBSession.h"
20 #include "llvm/DebugInfo/PDB/PDBSymbolData.h"
22 #include "Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.h"
23 #include "Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.h"
26 using namespace lldb_private;
27 using namespace lldb_private::npdb;
28 using namespace llvm::pdb;
30 static std::unique_ptr<IPDBFrameData>
31 GetCorrespondingFrameData(const IPDBSession &session,
32 const Variable::RangeList &ranges) {
33 auto enumFrameData = session.getFrameData();
37 std::unique_ptr<IPDBFrameData> found;
38 while (auto fd = enumFrameData->getNext()) {
39 Range<lldb::addr_t, lldb::addr_t> fdRange(fd->getVirtualAddress(),
40 fd->getLengthBlock());
42 for (size_t i = 0; i < ranges.GetSize(); i++) {
43 auto range = ranges.GetEntryAtIndex(i);
47 if (!range->DoesIntersect(fdRange))
50 found = std::move(fd);
59 static bool EmitVFrameEvaluationDWARFExpression(
60 llvm::StringRef program, llvm::Triple::ArchType arch_type, Stream &stream) {
61 // VFrame value always stored in $TO pseudo-register
62 return TranslateFPOProgramToDWARFExpression(program, "$T0", arch_type,
66 DWARFExpression ConvertPDBLocationToDWARFExpression(
67 ModuleSP module, const PDBSymbolData &symbol,
68 const Variable::RangeList &ranges, bool &is_constant) {
72 return DWARFExpression();
74 const ArchSpec &architecture = module->GetArchitecture();
75 llvm::Triple::ArchType arch_type = architecture.GetMachine();
76 ByteOrder byte_order = architecture.GetByteOrder();
77 uint32_t address_size = architecture.GetAddressByteSize();
78 uint32_t byte_size = architecture.GetDataByteSize();
79 if (byte_order == eByteOrderInvalid || address_size == 0)
80 return DWARFExpression();
82 RegisterKind register_kind = eRegisterKindDWARF;
83 StreamBuffer<32> stream(Stream::eBinary, address_size, byte_order);
84 switch (symbol.getLocationType()) {
85 case PDB_LocType::Static:
86 case PDB_LocType::TLS: {
87 stream.PutHex8(DW_OP_addr);
89 SectionList *section_list = module->GetSectionList();
91 return DWARFExpression();
93 uint32_t section_id = symbol.getAddressSection();
95 auto section = section_list->FindSectionByID(section_id);
97 return DWARFExpression();
99 uint32_t offset = symbol.getAddressOffset();
100 stream.PutMaxHex64(section->GetFileAddress() + offset, address_size,
107 case PDB_LocType::RegRel: {
109 auto reg_id = symbol.getRegisterId();
110 if (reg_id == llvm::codeview::RegisterId::VFRAME) {
111 if (auto fd = GetCorrespondingFrameData(symbol.getSession(), ranges)) {
112 if (EmitVFrameEvaluationDWARFExpression(fd->getProgram(), arch_type,
114 int32_t offset = symbol.getOffset();
115 stream.PutHex8(DW_OP_consts);
116 stream.PutSLEB128(offset);
117 stream.PutHex8(DW_OP_plus);
119 register_kind = eRegisterKindLLDB;
126 register_kind = eRegisterKindGeneric;
127 reg_num = LLDB_REGNUM_GENERIC_FP;
129 register_kind = eRegisterKindLLDB;
130 reg_num = GetLLDBRegisterNumber(arch_type, reg_id);
131 if (reg_num == LLDB_INVALID_REGNUM)
132 return DWARFExpression();
136 stream.PutHex8(DW_OP_bregx);
137 stream.PutULEB128(reg_num);
139 stream.PutHex8(DW_OP_breg0 + reg_num);
141 int32_t offset = symbol.getOffset();
142 stream.PutSLEB128(offset);
148 case PDB_LocType::Enregistered: {
149 register_kind = eRegisterKindLLDB;
150 uint32_t reg_num = GetLLDBRegisterNumber(arch_type, symbol.getRegisterId());
151 if (reg_num == LLDB_INVALID_REGNUM)
152 return DWARFExpression();
155 stream.PutHex8(DW_OP_regx);
156 stream.PutULEB128(reg_num);
158 stream.PutHex8(DW_OP_reg0 + reg_num);
164 case PDB_LocType::Constant: {
165 Variant value = symbol.getValue();
166 stream.PutRawBytes(&value.Value, sizeof(value.Value),
167 endian::InlHostByteOrder());
171 return DWARFExpression();
174 DataBufferSP buffer =
175 std::make_shared<DataBufferHeap>(stream.GetData(), stream.GetSize());
176 DataExtractor extractor(buffer, byte_order, address_size, byte_size);
177 DWARFExpression result(module, extractor, nullptr, 0, buffer->GetByteSize());
178 result.SetRegisterKind(register_kind);