Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp
39644 views
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
9
#include "PDBLocationToDWARFExpression.h"
10
11
#include "lldb/Core/Section.h"
12
#include "lldb/Core/dwarf.h"
13
#include "lldb/Expression/DWARFExpression.h"
14
#include "lldb/Symbol/Variable.h"
15
#include "lldb/Utility/DataBufferHeap.h"
16
#include "lldb/Utility/StreamBuffer.h"
17
18
#include "llvm/DebugInfo/CodeView/CodeView.h"
19
#include "llvm/DebugInfo/PDB/IPDBSession.h"
20
#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
21
22
#include "Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.h"
23
#include "Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.h"
24
25
using namespace lldb;
26
using namespace lldb_private;
27
using namespace lldb_private::npdb;
28
using namespace lldb_private::dwarf;
29
using namespace llvm::pdb;
30
31
static std::unique_ptr<IPDBFrameData>
32
GetCorrespondingFrameData(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
60
static bool EmitVFrameEvaluationDWARFExpression(
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
67
DWARFExpression ConvertPDBLocationToDWARFExpression(
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
uint32_t byte_size = architecture.GetDataByteSize();
80
if (byte_order == eByteOrderInvalid || address_size == 0)
81
return DWARFExpression();
82
83
RegisterKind register_kind = eRegisterKindDWARF;
84
StreamBuffer<32> stream(Stream::eBinary, address_size, byte_order);
85
switch (symbol.getLocationType()) {
86
case PDB_LocType::Static:
87
case PDB_LocType::TLS: {
88
stream.PutHex8(DW_OP_addr);
89
90
SectionList *section_list = module->GetSectionList();
91
if (!section_list)
92
return DWARFExpression();
93
94
uint32_t section_id = symbol.getAddressSection();
95
96
auto section = section_list->FindSectionByID(section_id);
97
if (!section)
98
return DWARFExpression();
99
100
uint32_t offset = symbol.getAddressOffset();
101
stream.PutMaxHex64(section->GetFileAddress() + offset, address_size,
102
byte_order);
103
104
is_constant = false;
105
106
break;
107
}
108
case PDB_LocType::RegRel: {
109
uint32_t reg_num;
110
auto reg_id = symbol.getRegisterId();
111
if (reg_id == llvm::codeview::RegisterId::VFRAME) {
112
if (auto fd = GetCorrespondingFrameData(symbol.getSession(), ranges)) {
113
if (EmitVFrameEvaluationDWARFExpression(fd->getProgram(), arch_type,
114
stream)) {
115
int32_t offset = symbol.getOffset();
116
stream.PutHex8(DW_OP_consts);
117
stream.PutSLEB128(offset);
118
stream.PutHex8(DW_OP_plus);
119
120
register_kind = eRegisterKindLLDB;
121
122
is_constant = false;
123
break;
124
}
125
}
126
127
register_kind = eRegisterKindGeneric;
128
reg_num = LLDB_REGNUM_GENERIC_FP;
129
} else {
130
register_kind = eRegisterKindLLDB;
131
reg_num = GetLLDBRegisterNumber(arch_type, reg_id);
132
if (reg_num == LLDB_INVALID_REGNUM)
133
return DWARFExpression();
134
}
135
136
if (reg_num > 31) {
137
stream.PutHex8(DW_OP_bregx);
138
stream.PutULEB128(reg_num);
139
} else
140
stream.PutHex8(DW_OP_breg0 + reg_num);
141
142
int32_t offset = symbol.getOffset();
143
stream.PutSLEB128(offset);
144
145
is_constant = false;
146
147
break;
148
}
149
case PDB_LocType::Enregistered: {
150
register_kind = eRegisterKindLLDB;
151
uint32_t reg_num = GetLLDBRegisterNumber(arch_type, symbol.getRegisterId());
152
if (reg_num == LLDB_INVALID_REGNUM)
153
return DWARFExpression();
154
155
if (reg_num > 31) {
156
stream.PutHex8(DW_OP_regx);
157
stream.PutULEB128(reg_num);
158
} else
159
stream.PutHex8(DW_OP_reg0 + reg_num);
160
161
is_constant = false;
162
163
break;
164
}
165
case PDB_LocType::Constant: {
166
Variant value = symbol.getValue();
167
stream.PutRawBytes(&value.Value, sizeof(value.Value),
168
endian::InlHostByteOrder());
169
break;
170
}
171
default:
172
return DWARFExpression();
173
}
174
175
DataBufferSP buffer =
176
std::make_shared<DataBufferHeap>(stream.GetData(), stream.GetSize());
177
DataExtractor extractor(buffer, byte_order, address_size, byte_size);
178
DWARFExpression result(extractor);
179
result.SetRegisterKind(register_kind);
180
181
return result;
182
}
183
184