LLDB mainline
PDBLocationToDWARFExpression.cpp
Go to the documentation of this file.
1//===-- PDBLocationToDWARFExpression.cpp ----------------------------------===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
10
11#include "lldb/Core/Section.h"
12#include "lldb/Core/dwarf.h"
17
18#include "llvm/DebugInfo/CodeView/CodeView.h"
19#include "llvm/DebugInfo/PDB/IPDBSession.h"
20#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
21
24
25using namespace lldb;
26using namespace lldb_private;
27using namespace lldb_private::npdb;
28using namespace llvm::dwarf;
29using namespace llvm::pdb;
30
31static std::unique_ptr<IPDBFrameData>
32GetCorrespondingFrameData(const IPDBSession &session,
33 const Variable::RangeList &ranges) {
34 auto enumFrameData = session.getFrameData();
35 if (!enumFrameData)
36 return nullptr;
37
38 std::unique_ptr<IPDBFrameData> found;
39 while (auto fd = enumFrameData->getNext()) {
40 Range<lldb::addr_t, lldb::addr_t> fdRange(fd->getVirtualAddress(),
41 fd->getLengthBlock());
42
43 for (size_t i = 0; i < ranges.GetSize(); i++) {
44 auto range = ranges.GetEntryAtIndex(i);
45 if (!range)
46 continue;
47
48 if (!range->DoesIntersect(fdRange))
49 continue;
50
51 found = std::move(fd);
52
53 break;
54 }
55 }
56
57 return found;
58}
59
61 llvm::StringRef program, llvm::Triple::ArchType arch_type, Stream &stream) {
62 // VFrame value always stored in $TO pseudo-register
63 return TranslateFPOProgramToDWARFExpression(program, "$T0", arch_type,
64 stream);
65}
66
68 ModuleSP module, const PDBSymbolData &symbol,
69 const Variable::RangeList &ranges, bool &is_constant) {
70 is_constant = true;
71
72 if (!module)
73 return DWARFExpression();
74
75 const ArchSpec &architecture = module->GetArchitecture();
76 llvm::Triple::ArchType arch_type = architecture.GetMachine();
77 ByteOrder byte_order = architecture.GetByteOrder();
78 uint32_t address_size = architecture.GetAddressByteSize();
79 if (byte_order == eByteOrderInvalid || address_size == 0)
80 return DWARFExpression();
81
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);
88
89 SectionList *section_list = module->GetSectionList();
90 if (!section_list)
91 return DWARFExpression();
92
93 uint32_t section_id = symbol.getAddressSection();
94
95 auto section = section_list->FindSectionByID(section_id);
96 if (!section)
97 return DWARFExpression();
98
99 uint32_t offset = symbol.getAddressOffset();
100 stream.PutMaxHex64(section->GetFileAddress() + offset, address_size,
101 byte_order);
102
103 is_constant = false;
104
105 break;
106 }
107 case PDB_LocType::RegRel: {
108 uint32_t reg_num;
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,
113 stream)) {
114 int32_t offset = symbol.getOffset();
115 stream.PutHex8(DW_OP_consts);
116 stream.PutSLEB128(offset);
117 stream.PutHex8(DW_OP_plus);
118
119 register_kind = eRegisterKindLLDB;
120
121 is_constant = false;
122 break;
123 }
124 }
125
126 register_kind = eRegisterKindGeneric;
127 reg_num = LLDB_REGNUM_GENERIC_FP;
128 } else {
129 register_kind = eRegisterKindLLDB;
130 reg_num = GetLLDBRegisterNumber(arch_type, reg_id);
131 if (reg_num == LLDB_INVALID_REGNUM)
132 return DWARFExpression();
133 }
134
135 if (reg_num > 31) {
136 stream.PutHex8(DW_OP_bregx);
137 stream.PutULEB128(reg_num);
138 } else
139 stream.PutHex8(DW_OP_breg0 + reg_num);
140
141 int32_t offset = symbol.getOffset();
142 stream.PutSLEB128(offset);
143
144 is_constant = false;
145
146 break;
147 }
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();
153
154 if (reg_num > 31) {
155 stream.PutHex8(DW_OP_regx);
156 stream.PutULEB128(reg_num);
157 } else
158 stream.PutHex8(DW_OP_reg0 + reg_num);
159
160 is_constant = false;
161
162 break;
163 }
164 case PDB_LocType::Constant: {
165 Variant value = symbol.getValue();
166 stream.PutRawBytes(&value.Value, sizeof(value.Value),
168 break;
169 }
170 default:
171 return DWARFExpression();
172 }
173
174 DataBufferSP buffer =
175 std::make_shared<DataBufferHeap>(stream.GetData(), stream.GetSize());
176 DataExtractor extractor(buffer, byte_order, address_size);
177 DWARFExpression result(extractor);
178 result.SetRegisterKind(register_kind);
179
180 return result;
181}
static bool EmitVFrameEvaluationDWARFExpression(llvm::StringRef program, llvm::Triple::ArchType arch_type, Stream &stream)
DWARFExpression ConvertPDBLocationToDWARFExpression(ModuleSP module, const PDBSymbolData &symbol, const Variable::RangeList &ranges, bool &is_constant)
static std::unique_ptr< IPDBFrameData > GetCorrespondingFrameData(const IPDBSession &session, const Variable::RangeList &ranges)
An architecture specification class.
Definition ArchSpec.h:32
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
Definition ArchSpec.cpp:681
lldb::ByteOrder GetByteOrder() const
Returns the byte order for the architecture specification.
Definition ArchSpec.cpp:730
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
Definition ArchSpec.cpp:673
"lldb/Expression/DWARFExpression.h" Encapsulates a DWARF location expression and interprets it.
void SetRegisterKind(lldb::RegisterKind reg_kind)
Set the call-frame-info style register kind.
An data extractor class.
const Entry * GetEntryAtIndex(size_t i) const
Definition RangeMap.h:297
size_t GetSize() const
Definition RangeMap.h:295
lldb::SectionSP FindSectionByID(lldb::user_id_t sect_id) const
Definition Section.cpp:582
const char * GetData() const
A stream class that can stream formatted output to a file.
Definition Stream.h:28
size_t size_t PutHex8(uint8_t uvalue)
Append an uint8_t value in the hexadecimal format to the stream.
Definition Stream.cpp:269
@ eBinary
Get and put data as binary instead of as the default string mode.
Definition Stream.h:32
size_t PutULEB128(uint64_t uval)
Output a ULEB128 number to the stream.
Definition Stream.cpp:57
size_t PutSLEB128(int64_t uval)
Output a SLEB128 number to the stream.
Definition Stream.cpp:49
size_t PutRawBytes(const void *s, size_t src_len, lldb::ByteOrder src_byte_order=lldb::eByteOrderInvalid, lldb::ByteOrder dst_byte_order=lldb::eByteOrderInvalid)
Definition Stream.cpp:364
size_t PutMaxHex64(uint64_t uvalue, size_t byte_size, lldb::ByteOrder byte_order=lldb::eByteOrderInvalid)
Definition Stream.cpp:323
RangeVector< lldb::addr_t, lldb::addr_t > RangeList
Definition Variable.h:27
#define LLDB_INVALID_REGNUM
#define LLDB_REGNUM_GENERIC_FP
lldb::ByteOrder InlHostByteOrder()
Definition Endian.h:25
bool TranslateFPOProgramToDWARFExpression(llvm::StringRef program, llvm::StringRef register_name, llvm::Triple::ArchType arch_type, lldb_private::Stream &stream)
uint32_t GetLLDBRegisterNumber(llvm::Triple::ArchType arch_type, llvm::codeview::RegisterId register_id)
A class that represents a running process on the host machine.
ByteOrder
Byte ordering definitions.
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::Module > ModuleSP
RegisterKind
Register numbering types.
@ eRegisterKindGeneric
insn ptr reg, stack ptr reg, etc not specific to any particular target
@ eRegisterKindLLDB
lldb's internal register numbers
@ eRegisterKindDWARF
the register numbers seen DWARF