Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Expression/ObjectFileJIT.cpp
39587 views
1
//===-- ObjectFileJIT.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 "llvm/ADT/StringRef.h"
10
11
#include "lldb/Core/Module.h"
12
#include "lldb/Core/ModuleSpec.h"
13
#include "lldb/Core/PluginManager.h"
14
#include "lldb/Core/Section.h"
15
#include "lldb/Expression/ObjectFileJIT.h"
16
#include "lldb/Target/Process.h"
17
#include "lldb/Target/SectionLoadList.h"
18
#include "lldb/Target/Target.h"
19
#include "lldb/Utility/ArchSpec.h"
20
#include "lldb/Utility/DataBuffer.h"
21
#include "lldb/Utility/DataBufferHeap.h"
22
#include "lldb/Utility/FileSpec.h"
23
#include "lldb/Utility/FileSpecList.h"
24
#include "lldb/Utility/Log.h"
25
#include "lldb/Utility/Timer.h"
26
#include "lldb/Utility/UUID.h"
27
28
using namespace lldb;
29
using namespace lldb_private;
30
31
char ObjectFileJIT::ID;
32
33
void ObjectFileJIT::Initialize() {
34
PluginManager::RegisterPlugin(GetPluginNameStatic(),
35
GetPluginDescriptionStatic(), CreateInstance,
36
CreateMemoryInstance, GetModuleSpecifications);
37
}
38
39
void ObjectFileJIT::Terminate() {
40
PluginManager::UnregisterPlugin(CreateInstance);
41
}
42
43
ObjectFile *ObjectFileJIT::CreateInstance(const lldb::ModuleSP &module_sp,
44
DataBufferSP data_sp,
45
lldb::offset_t data_offset,
46
const FileSpec *file,
47
lldb::offset_t file_offset,
48
lldb::offset_t length) {
49
// JIT'ed object file is backed by the ObjectFileJITDelegate, never read from
50
// a file
51
return nullptr;
52
}
53
54
ObjectFile *ObjectFileJIT::CreateMemoryInstance(const lldb::ModuleSP &module_sp,
55
WritableDataBufferSP data_sp,
56
const ProcessSP &process_sp,
57
lldb::addr_t header_addr) {
58
// JIT'ed object file is backed by the ObjectFileJITDelegate, never read from
59
// memory
60
return nullptr;
61
}
62
63
size_t ObjectFileJIT::GetModuleSpecifications(
64
const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
65
lldb::offset_t data_offset, lldb::offset_t file_offset,
66
lldb::offset_t length, lldb_private::ModuleSpecList &specs) {
67
// JIT'ed object file can't be read from a file on disk
68
return 0;
69
}
70
71
ObjectFileJIT::ObjectFileJIT(const lldb::ModuleSP &module_sp,
72
const ObjectFileJITDelegateSP &delegate_sp)
73
: ObjectFile(module_sp, nullptr, 0, 0, DataBufferSP(), 0), m_delegate_wp() {
74
if (delegate_sp) {
75
m_delegate_wp = delegate_sp;
76
m_data.SetByteOrder(delegate_sp->GetByteOrder());
77
m_data.SetAddressByteSize(delegate_sp->GetAddressByteSize());
78
}
79
}
80
81
ObjectFileJIT::~ObjectFileJIT() = default;
82
83
bool ObjectFileJIT::ParseHeader() {
84
// JIT code is never in a file, nor is it required to have any header
85
return false;
86
}
87
88
ByteOrder ObjectFileJIT::GetByteOrder() const { return m_data.GetByteOrder(); }
89
90
bool ObjectFileJIT::IsExecutable() const { return false; }
91
92
uint32_t ObjectFileJIT::GetAddressByteSize() const {
93
return m_data.GetAddressByteSize();
94
}
95
96
void ObjectFileJIT::ParseSymtab(Symtab &symtab) {
97
ObjectFileJITDelegateSP delegate_sp(m_delegate_wp.lock());
98
if (delegate_sp)
99
delegate_sp->PopulateSymtab(this, symtab);
100
}
101
102
bool ObjectFileJIT::IsStripped() {
103
return false; // JIT code that is in a module is never stripped
104
}
105
106
void ObjectFileJIT::CreateSections(SectionList &unified_section_list) {
107
if (!m_sections_up) {
108
m_sections_up = std::make_unique<SectionList>();
109
ObjectFileJITDelegateSP delegate_sp(m_delegate_wp.lock());
110
if (delegate_sp) {
111
delegate_sp->PopulateSectionList(this, *m_sections_up);
112
unified_section_list = *m_sections_up;
113
}
114
}
115
}
116
117
void ObjectFileJIT::Dump(Stream *s) {
118
ModuleSP module_sp(GetModule());
119
if (module_sp) {
120
std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
121
s->Printf("%p: ", static_cast<void *>(this));
122
s->Indent();
123
s->PutCString("ObjectFileJIT");
124
125
if (ArchSpec arch = GetArchitecture())
126
*s << ", arch = " << arch.GetArchitectureName();
127
128
s->EOL();
129
130
SectionList *sections = GetSectionList();
131
if (sections)
132
sections->Dump(s->AsRawOstream(), s->GetIndentLevel(), nullptr, true,
133
UINT32_MAX);
134
135
if (m_symtab_up)
136
m_symtab_up->Dump(s, nullptr, eSortOrderNone);
137
}
138
}
139
140
UUID ObjectFileJIT::GetUUID() {
141
// TODO: maybe get from delegate, not needed for first pass
142
return UUID();
143
}
144
145
uint32_t ObjectFileJIT::GetDependentModules(FileSpecList &files) {
146
// JIT modules don't have dependencies, but they could
147
// if external functions are called and we know where they are
148
files.Clear();
149
return 0;
150
}
151
152
lldb_private::Address ObjectFileJIT::GetEntryPointAddress() {
153
return Address();
154
}
155
156
lldb_private::Address ObjectFileJIT::GetBaseAddress() { return Address(); }
157
158
ObjectFile::Type ObjectFileJIT::CalculateType() { return eTypeJIT; }
159
160
ObjectFile::Strata ObjectFileJIT::CalculateStrata() { return eStrataJIT; }
161
162
ArchSpec ObjectFileJIT::GetArchitecture() {
163
if (ObjectFileJITDelegateSP delegate_sp = m_delegate_wp.lock())
164
return delegate_sp->GetArchitecture();
165
return ArchSpec();
166
}
167
168
bool ObjectFileJIT::SetLoadAddress(Target &target, lldb::addr_t value,
169
bool value_is_offset) {
170
size_t num_loaded_sections = 0;
171
SectionList *section_list = GetSectionList();
172
if (section_list) {
173
const size_t num_sections = section_list->GetSize();
174
// "value" is an offset to apply to each top level segment
175
for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
176
// Iterate through the object file sections to find all of the sections
177
// that size on disk (to avoid __PAGEZERO) and load them
178
SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
179
if (section_sp && section_sp->GetFileSize() > 0 &&
180
!section_sp->IsThreadSpecific()) {
181
if (target.GetSectionLoadList().SetSectionLoadAddress(
182
section_sp, section_sp->GetFileAddress() + value))
183
++num_loaded_sections;
184
}
185
}
186
}
187
return num_loaded_sections > 0;
188
}
189
190
size_t ObjectFileJIT::ReadSectionData(lldb_private::Section *section,
191
lldb::offset_t section_offset, void *dst,
192
size_t dst_len) {
193
lldb::offset_t file_size = section->GetFileSize();
194
if (section_offset < file_size) {
195
size_t src_len = file_size - section_offset;
196
if (src_len > dst_len)
197
src_len = dst_len;
198
const uint8_t *src =
199
((uint8_t *)(uintptr_t)section->GetFileOffset()) + section_offset;
200
201
memcpy(dst, src, src_len);
202
return src_len;
203
}
204
return 0;
205
}
206
207
size_t
208
ObjectFileJIT::ReadSectionData(lldb_private::Section *section,
209
lldb_private::DataExtractor &section_data) {
210
if (section->GetFileSize()) {
211
const void *src = (void *)(uintptr_t)section->GetFileOffset();
212
213
DataBufferSP data_sp =
214
std::make_shared<DataBufferHeap>(src, section->GetFileSize());
215
section_data.SetData(data_sp, 0, data_sp->GetByteSize());
216
section_data.SetByteOrder(GetByteOrder());
217
section_data.SetAddressByteSize(GetAddressByteSize());
218
return section_data.GetByteSize();
219
}
220
section_data.Clear();
221
return 0;
222
}
223
224