Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/FreeBSD-Kernel/DynamicLoaderFreeBSDKernel.cpp
39642 views
1
//===-- DynamicLoaderFreeBSDKernel.cpp
2
//------------------------------------------===//
3
//
4
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5
// See https://llvm.org/LICENSE.txt for license information.
6
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7
//
8
//===----------------------------------------------------------------------===//
9
10
#include "lldb/Breakpoint/StoppointCallbackContext.h"
11
#include "lldb/Core/Debugger.h"
12
#include "lldb/Core/Module.h"
13
#include "lldb/Core/ModuleSpec.h"
14
#include "lldb/Core/PluginManager.h"
15
#include "lldb/Core/Section.h"
16
#include "lldb/Host/StreamFile.h"
17
#include "lldb/Interpreter/OptionValueProperties.h"
18
#include "lldb/Symbol/ObjectFile.h"
19
#include "lldb/Target/OperatingSystem.h"
20
#include "lldb/Target/RegisterContext.h"
21
#include "lldb/Target/StackFrame.h"
22
#include "lldb/Target/Target.h"
23
#include "lldb/Target/Thread.h"
24
#include "lldb/Target/ThreadPlanRunToAddress.h"
25
#include "lldb/Utility/DataBuffer.h"
26
#include "lldb/Utility/DataBufferHeap.h"
27
#include "lldb/Utility/LLDBLog.h"
28
#include "lldb/Utility/Log.h"
29
#include "lldb/Utility/State.h"
30
31
#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
32
33
#include "DynamicLoaderFreeBSDKernel.h"
34
#include <memory>
35
#include <mutex>
36
37
using namespace lldb;
38
using namespace lldb_private;
39
40
LLDB_PLUGIN_DEFINE(DynamicLoaderFreeBSDKernel)
41
42
void DynamicLoaderFreeBSDKernel::Initialize() {
43
PluginManager::RegisterPlugin(GetPluginNameStatic(),
44
GetPluginDescriptionStatic(), CreateInstance,
45
DebuggerInit);
46
}
47
48
void DynamicLoaderFreeBSDKernel::Terminate() {
49
PluginManager::UnregisterPlugin(CreateInstance);
50
}
51
52
llvm::StringRef DynamicLoaderFreeBSDKernel::GetPluginDescriptionStatic() {
53
return "The Dynamic Loader Plugin For FreeBSD Kernel";
54
}
55
56
static bool is_kernel(Module *module) {
57
if (!module)
58
return false;
59
60
ObjectFile *objfile = module->GetObjectFile();
61
if (!objfile)
62
return false;
63
if (objfile->GetType() != ObjectFile::eTypeExecutable)
64
return false;
65
if (objfile->GetStrata() != ObjectFile::eStrataUnknown &&
66
objfile->GetStrata() != ObjectFile::eStrataKernel)
67
return false;
68
69
return true;
70
}
71
72
static bool is_kmod(Module *module) {
73
if (!module)
74
return false;
75
if (!module->GetObjectFile())
76
return false;
77
ObjectFile *objfile = module->GetObjectFile();
78
if (objfile->GetType() != ObjectFile::eTypeObjectFile &&
79
objfile->GetType() != ObjectFile::eTypeSharedLibrary)
80
return false;
81
82
return true;
83
}
84
85
static bool is_reloc(Module *module) {
86
if (!module)
87
return false;
88
if (!module->GetObjectFile())
89
return false;
90
ObjectFile *objfile = module->GetObjectFile();
91
if (objfile->GetType() != ObjectFile::eTypeObjectFile)
92
return false;
93
94
return true;
95
}
96
97
// Instantiate Function of the FreeBSD Kernel Dynamic Loader Plugin called when
98
// Register the Plugin
99
DynamicLoader *
100
DynamicLoaderFreeBSDKernel::CreateInstance(lldb_private::Process *process,
101
bool force) {
102
// Check the environment when the plugin is not force loaded
103
Module *exec = process->GetTarget().GetExecutableModulePointer();
104
if (exec && !is_kernel(exec)) {
105
return nullptr;
106
}
107
if (!force) {
108
// Check if the target is kernel
109
const llvm::Triple &triple_ref =
110
process->GetTarget().GetArchitecture().GetTriple();
111
if (!triple_ref.isOSFreeBSD()) {
112
return nullptr;
113
}
114
}
115
116
// At this point we have checked the target is a FreeBSD kernel and all we
117
// have to do is to find the kernel address
118
const addr_t kernel_address = FindFreeBSDKernel(process);
119
120
if (CheckForKernelImageAtAddress(process, kernel_address).IsValid())
121
return new DynamicLoaderFreeBSDKernel(process, kernel_address);
122
123
return nullptr;
124
}
125
126
addr_t
127
DynamicLoaderFreeBSDKernel::FindFreeBSDKernel(lldb_private::Process *process) {
128
addr_t kernel_addr = process->GetImageInfoAddress();
129
if (kernel_addr == LLDB_INVALID_ADDRESS)
130
kernel_addr = FindKernelAtLoadAddress(process);
131
return kernel_addr;
132
}
133
134
// Get the kernel address if the kernel is not loaded with a slide
135
addr_t DynamicLoaderFreeBSDKernel::FindKernelAtLoadAddress(
136
lldb_private::Process *process) {
137
Module *exe_module = process->GetTarget().GetExecutableModulePointer();
138
139
if (!is_kernel(exe_module))
140
return LLDB_INVALID_ADDRESS;
141
142
ObjectFile *exe_objfile = exe_module->GetObjectFile();
143
144
if (!exe_objfile->GetBaseAddress().IsValid())
145
return LLDB_INVALID_ADDRESS;
146
147
if (CheckForKernelImageAtAddress(
148
process, exe_objfile->GetBaseAddress().GetFileAddress())
149
.IsValid())
150
return exe_objfile->GetBaseAddress().GetFileAddress();
151
152
return LLDB_INVALID_ADDRESS;
153
}
154
155
// Read ELF header from memry and return
156
bool DynamicLoaderFreeBSDKernel::ReadELFHeader(Process *process,
157
lldb::addr_t addr,
158
llvm::ELF::Elf32_Ehdr &header,
159
bool *read_error) {
160
Status error;
161
if (read_error)
162
*read_error = false;
163
164
if (process->ReadMemory(addr, &header, sizeof(header), error) !=
165
sizeof(header)) {
166
if (read_error)
167
*read_error = true;
168
return false;
169
}
170
171
if (!header.checkMagic())
172
return false;
173
174
return true;
175
}
176
177
// Check the correctness of Kernel and return UUID
178
lldb_private::UUID DynamicLoaderFreeBSDKernel::CheckForKernelImageAtAddress(
179
Process *process, lldb::addr_t addr, bool *read_error) {
180
Log *log = GetLog(LLDBLog::DynamicLoader);
181
182
if (addr == LLDB_INVALID_ADDRESS) {
183
if (read_error)
184
*read_error = true;
185
return UUID();
186
}
187
188
LLDB_LOGF(log,
189
"DynamicLoaderFreeBSDKernel::CheckForKernelImageAtAddress: "
190
"looking for kernel binary at 0x%" PRIx64,
191
addr);
192
193
llvm::ELF::Elf32_Ehdr header;
194
if (!ReadELFHeader(process, addr, header)) {
195
*read_error = true;
196
return UUID();
197
}
198
199
// Check header type
200
if (header.e_type != llvm::ELF::ET_EXEC)
201
return UUID();
202
203
ModuleSP memory_module_sp =
204
process->ReadModuleFromMemory(FileSpec("temp_freebsd_kernel"), addr);
205
206
if (!memory_module_sp.get()) {
207
*read_error = true;
208
return UUID();
209
}
210
211
ObjectFile *exe_objfile = memory_module_sp->GetObjectFile();
212
if (exe_objfile == nullptr) {
213
LLDB_LOGF(log,
214
"DynamicLoaderFreeBSDKernel::CheckForKernelImageAtAddress "
215
"found a binary at 0x%" PRIx64
216
" but could not create an object file from memory",
217
addr);
218
return UUID();
219
}
220
221
// In here, I should check is_kernel for memory_module_sp
222
// However, the ReadModuleFromMemory reads wrong section so that this check
223
// will failed
224
ArchSpec kernel_arch(llvm::ELF::convertEMachineToArchName(header.e_machine));
225
226
if (!process->GetTarget().GetArchitecture().IsCompatibleMatch(kernel_arch))
227
process->GetTarget().SetArchitecture(kernel_arch);
228
229
std::string uuid_str;
230
if (memory_module_sp->GetUUID().IsValid()) {
231
uuid_str = "with UUID ";
232
uuid_str += memory_module_sp->GetUUID().GetAsString();
233
} else {
234
uuid_str = "and no LC_UUID found in load commands ";
235
}
236
LLDB_LOGF(log,
237
"DynamicLoaderFreeBSDKernel::CheckForKernelImageAtAddress: "
238
"kernel binary image found at 0x%" PRIx64 " with arch '%s' %s",
239
addr, kernel_arch.GetTriple().str().c_str(), uuid_str.c_str());
240
241
return memory_module_sp->GetUUID();
242
}
243
244
void DynamicLoaderFreeBSDKernel::DebuggerInit(
245
lldb_private::Debugger &debugger) {}
246
247
DynamicLoaderFreeBSDKernel::DynamicLoaderFreeBSDKernel(Process *process,
248
addr_t kernel_address)
249
: DynamicLoader(process), m_process(process),
250
m_linker_file_list_struct_addr(LLDB_INVALID_ADDRESS),
251
m_linker_file_head_addr(LLDB_INVALID_ADDRESS),
252
m_kernel_load_address(kernel_address), m_mutex() {
253
process->SetCanRunCode(false);
254
}
255
256
DynamicLoaderFreeBSDKernel::~DynamicLoaderFreeBSDKernel() { Clear(true); }
257
258
void DynamicLoaderFreeBSDKernel::Update() {
259
LoadKernelModules();
260
SetNotificationBreakPoint();
261
}
262
263
// Create in memory Module at the load address
264
bool DynamicLoaderFreeBSDKernel::KModImageInfo::ReadMemoryModule(
265
lldb_private::Process *process) {
266
Log *log = GetLog(LLDBLog::DynamicLoader);
267
if (m_memory_module_sp)
268
return true;
269
if (m_load_address == LLDB_INVALID_ADDRESS)
270
return false;
271
272
FileSpec file_spec(m_name);
273
274
ModuleSP memory_module_sp;
275
276
llvm::ELF::Elf32_Ehdr elf_eheader;
277
size_t size_to_read = 512;
278
279
if (ReadELFHeader(process, m_load_address, elf_eheader)) {
280
if (elf_eheader.e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS32) {
281
size_to_read = sizeof(llvm::ELF::Elf32_Ehdr) +
282
elf_eheader.e_phnum * elf_eheader.e_phentsize;
283
} else if (elf_eheader.e_ident[llvm::ELF::EI_CLASS] ==
284
llvm::ELF::ELFCLASS64) {
285
llvm::ELF::Elf64_Ehdr elf_eheader;
286
Status error;
287
if (process->ReadMemory(m_load_address, &elf_eheader, sizeof(elf_eheader),
288
error) == sizeof(elf_eheader))
289
size_to_read = sizeof(llvm::ELF::Elf64_Ehdr) +
290
elf_eheader.e_phnum * elf_eheader.e_phentsize;
291
}
292
}
293
294
memory_module_sp =
295
process->ReadModuleFromMemory(file_spec, m_load_address, size_to_read);
296
297
if (!memory_module_sp)
298
return false;
299
300
bool this_is_kernel = is_kernel(memory_module_sp.get());
301
302
if (!m_uuid.IsValid() && memory_module_sp->GetUUID().IsValid())
303
m_uuid = memory_module_sp->GetUUID();
304
305
m_memory_module_sp = memory_module_sp;
306
m_is_kernel = this_is_kernel;
307
308
// The kernel binary is from memory
309
if (this_is_kernel) {
310
LLDB_LOGF(log, "KextImageInfo::ReadMemoryModule read the kernel binary out "
311
"of memory");
312
313
if (memory_module_sp->GetArchitecture().IsValid())
314
process->GetTarget().SetArchitecture(memory_module_sp->GetArchitecture());
315
}
316
317
return true;
318
}
319
320
bool DynamicLoaderFreeBSDKernel::KModImageInfo::LoadImageUsingMemoryModule(
321
lldb_private::Process *process) {
322
Log *log = GetLog(LLDBLog::DynamicLoader);
323
324
if (IsLoaded())
325
return true;
326
327
Target &target = process->GetTarget();
328
329
if (IsKernel() && m_uuid.IsValid()) {
330
Stream &s = target.GetDebugger().GetOutputStream();
331
s.Printf("Kernel UUID: %s\n", m_uuid.GetAsString().c_str());
332
s.Printf("Load Address: 0x%" PRIx64 "\n", m_load_address);
333
}
334
335
// Test if the module is loaded into the taget,
336
// maybe the module is loaded manually by user by doing target module add
337
// So that we have to create the module manually
338
if (!m_module_sp) {
339
const ModuleList &target_images = target.GetImages();
340
m_module_sp = target_images.FindModule(m_uuid);
341
342
// Search in the file system
343
if (!m_module_sp) {
344
ModuleSpec module_spec(FileSpec(GetPath()), target.GetArchitecture());
345
if (IsKernel()) {
346
Status error;
347
if (PluginManager::DownloadObjectAndSymbolFile(module_spec, error,
348
true)) {
349
if (FileSystem::Instance().Exists(module_spec.GetFileSpec()))
350
m_module_sp = std::make_shared<Module>(module_spec.GetFileSpec(),
351
target.GetArchitecture());
352
}
353
}
354
355
if (!m_module_sp)
356
m_module_sp = target.GetOrCreateModule(module_spec, true);
357
if (IsKernel() && !m_module_sp) {
358
Stream &s = target.GetDebugger().GetOutputStream();
359
s.Printf("WARNING: Unable to locate kernel binary on the debugger "
360
"system.\n");
361
}
362
}
363
364
if (m_module_sp) {
365
// If the file is not kernel or kmod, the target should be loaded once and
366
// don't reload again
367
if (!IsKernel() && !is_kmod(m_module_sp.get())) {
368
ModuleSP existing_module_sp = target.GetImages().FindModule(m_uuid);
369
if (existing_module_sp &&
370
existing_module_sp->IsLoadedInTarget(&target)) {
371
LLDB_LOGF(log,
372
"'%s' with UUID %s is not a kmod or kernel, and is "
373
"already registered in target, not loading.",
374
m_name.c_str(), m_uuid.GetAsString().c_str());
375
return true;
376
}
377
}
378
m_uuid = m_module_sp->GetUUID();
379
380
// or append to the images
381
target.GetImages().AppendIfNeeded(m_module_sp, false);
382
}
383
}
384
385
// If this file is relocatable kernel module(x86_64), adjust it's
386
// section(PT_LOAD segment) and return Because the kernel module's load
387
// address is the text section. lldb cannot create full memory module upon
388
// relocatable file So what we do is to set the load address only.
389
if (is_kmod(m_module_sp.get()) && is_reloc(m_module_sp.get())) {
390
m_stop_id = process->GetStopID();
391
bool changed = false;
392
m_module_sp->SetLoadAddress(target, m_load_address, true, changed);
393
return true;
394
}
395
396
if (m_module_sp)
397
ReadMemoryModule(process);
398
399
// Calculate the slides of in memory module
400
if (!m_memory_module_sp || !m_module_sp) {
401
m_module_sp.reset();
402
return false;
403
}
404
405
ObjectFile *ondisk_object_file = m_module_sp->GetObjectFile();
406
ObjectFile *memory_object_file = m_memory_module_sp->GetObjectFile();
407
408
if (!ondisk_object_file || !memory_object_file)
409
m_module_sp.reset();
410
411
// Find the slide address
412
addr_t fixed_slide = LLDB_INVALID_ADDRESS;
413
if (llvm::dyn_cast<ObjectFileELF>(memory_object_file)) {
414
addr_t load_address = memory_object_file->GetBaseAddress().GetFileAddress();
415
416
if (load_address != LLDB_INVALID_ADDRESS &&
417
m_load_address != load_address) {
418
fixed_slide = m_load_address - load_address;
419
LLDB_LOGF(log,
420
"kmod %s in-memory LOAD vmaddr is not correct, using a "
421
"fixed slide of 0x%" PRIx64,
422
m_name.c_str(), fixed_slide);
423
}
424
}
425
426
SectionList *ondisk_section_list = ondisk_object_file->GetSectionList();
427
SectionList *memory_section_list = memory_object_file->GetSectionList();
428
429
if (memory_section_list && ondisk_object_file) {
430
const uint32_t num_ondisk_sections = ondisk_section_list->GetSize();
431
uint32_t num_load_sections = 0;
432
433
for (uint32_t section_idx = 0; section_idx < num_ondisk_sections;
434
++section_idx) {
435
SectionSP on_disk_section_sp =
436
ondisk_section_list->GetSectionAtIndex(section_idx);
437
438
if (!on_disk_section_sp)
439
continue;
440
if (fixed_slide != LLDB_INVALID_ADDRESS) {
441
target.SetSectionLoadAddress(on_disk_section_sp,
442
on_disk_section_sp->GetFileAddress() +
443
fixed_slide);
444
445
} else {
446
const Section *memory_section =
447
memory_section_list
448
->FindSectionByName(on_disk_section_sp->GetName())
449
.get();
450
if (memory_section) {
451
target.SetSectionLoadAddress(on_disk_section_sp,
452
memory_section->GetFileAddress());
453
++num_load_sections;
454
}
455
}
456
}
457
458
if (num_load_sections)
459
m_stop_id = process->GetStopID();
460
else
461
m_module_sp.reset();
462
} else {
463
m_module_sp.reset();
464
}
465
466
if (IsLoaded() && m_module_sp && IsKernel()) {
467
Stream &s = target.GetDebugger().GetOutputStream();
468
ObjectFile *kernel_object_file = m_module_sp->GetObjectFile();
469
if (kernel_object_file) {
470
addr_t file_address =
471
kernel_object_file->GetBaseAddress().GetFileAddress();
472
if (m_load_address != LLDB_INVALID_ADDRESS &&
473
file_address != LLDB_INVALID_ADDRESS) {
474
s.Printf("Kernel slide 0x%" PRIx64 " in memory.\n",
475
m_load_address - file_address);
476
s.Printf("Loaded kernel file %s\n",
477
m_module_sp->GetFileSpec().GetPath().c_str());
478
}
479
}
480
s.Flush();
481
}
482
483
return IsLoaded();
484
}
485
486
// This function is work for kernel file, others it wil reset load address and
487
// return false
488
bool DynamicLoaderFreeBSDKernel::KModImageInfo::LoadImageUsingFileAddress(
489
lldb_private::Process *process) {
490
if (IsLoaded())
491
return true;
492
493
if (m_module_sp) {
494
bool changed = false;
495
if (m_module_sp->SetLoadAddress(process->GetTarget(), 0, true, changed))
496
m_stop_id = process->GetStopID();
497
}
498
499
return false;
500
}
501
502
// Get the head of found_list
503
bool DynamicLoaderFreeBSDKernel::ReadKmodsListHeader() {
504
std::lock_guard<decltype(m_mutex)> guard(m_mutex);
505
506
if (m_linker_file_list_struct_addr.IsValid()) {
507
// Get tqh_first struct element from linker_files
508
Status error;
509
addr_t address = m_process->ReadPointerFromMemory(
510
m_linker_file_list_struct_addr.GetLoadAddress(&m_process->GetTarget()),
511
error);
512
if (address != LLDB_INVALID_ADDRESS && error.Success()) {
513
m_linker_file_head_addr = Address(address);
514
} else {
515
m_linker_file_list_struct_addr.Clear();
516
return false;
517
}
518
519
if (!m_linker_file_head_addr.IsValid() ||
520
m_linker_file_head_addr.GetFileAddress() == 0) {
521
m_linker_file_list_struct_addr.Clear();
522
return false;
523
}
524
}
525
return true;
526
}
527
528
// Parse Kmod info in found_list
529
bool DynamicLoaderFreeBSDKernel::ParseKmods(Address linker_files_head_addr) {
530
std::lock_guard<decltype(m_mutex)> guard(m_mutex);
531
KModImageInfo::collection_type linker_files_list;
532
Log *log = GetLog(LLDBLog::DynamicLoader);
533
534
if (!ReadAllKmods(linker_files_head_addr, linker_files_list))
535
return false;
536
LLDB_LOGF(
537
log,
538
"Kmod-changed breakpoint hit, there are %zu kernel modules currently.\n",
539
linker_files_list.size());
540
541
ModuleList &modules = m_process->GetTarget().GetImages();
542
ModuleList remove_modules;
543
ModuleList add_modules;
544
545
for (ModuleSP module : modules.Modules()) {
546
if (is_kernel(module.get()))
547
continue;
548
if (is_kmod(module.get()))
549
remove_modules.AppendIfNeeded(module);
550
}
551
552
m_process->GetTarget().ModulesDidUnload(remove_modules, false);
553
554
for (KModImageInfo &image_info : linker_files_list) {
555
if (m_kld_name_to_uuid.find(image_info.GetName()) !=
556
m_kld_name_to_uuid.end())
557
image_info.SetUUID(m_kld_name_to_uuid[image_info.GetName()]);
558
bool failed_to_load = false;
559
if (!image_info.LoadImageUsingMemoryModule(m_process)) {
560
image_info.LoadImageUsingFileAddress(m_process);
561
failed_to_load = true;
562
} else {
563
m_linker_files_list.push_back(image_info);
564
m_kld_name_to_uuid[image_info.GetName()] = image_info.GetUUID();
565
}
566
567
if (!failed_to_load)
568
add_modules.AppendIfNeeded(image_info.GetModule());
569
}
570
m_process->GetTarget().ModulesDidLoad(add_modules);
571
return true;
572
}
573
574
// Read all kmod from a given arrays of list
575
bool DynamicLoaderFreeBSDKernel::ReadAllKmods(
576
Address linker_files_head_addr,
577
KModImageInfo::collection_type &kmods_list) {
578
579
// Get offset of next member and load address symbol
580
static ConstString kld_off_address_symbol_name("kld_off_address");
581
static ConstString kld_off_next_symbol_name("kld_off_next");
582
static ConstString kld_off_filename_symbol_name("kld_off_filename");
583
static ConstString kld_off_pathname_symbol_name("kld_off_pathname");
584
const Symbol *kld_off_address_symbol =
585
m_kernel_image_info.GetModule()->FindFirstSymbolWithNameAndType(
586
kld_off_address_symbol_name, eSymbolTypeData);
587
const Symbol *kld_off_next_symbol =
588
m_kernel_image_info.GetModule()->FindFirstSymbolWithNameAndType(
589
kld_off_next_symbol_name, eSymbolTypeData);
590
const Symbol *kld_off_filename_symbol =
591
m_kernel_image_info.GetModule()->FindFirstSymbolWithNameAndType(
592
kld_off_filename_symbol_name, eSymbolTypeData);
593
const Symbol *kld_off_pathname_symbol =
594
m_kernel_image_info.GetModule()->FindFirstSymbolWithNameAndType(
595
kld_off_pathname_symbol_name, eSymbolTypeData);
596
597
if (!kld_off_address_symbol || !kld_off_next_symbol ||
598
!kld_off_filename_symbol || !kld_off_pathname_symbol)
599
return false;
600
601
Status error;
602
const int32_t kld_off_address = m_process->ReadSignedIntegerFromMemory(
603
kld_off_address_symbol->GetAddress().GetLoadAddress(
604
&m_process->GetTarget()),
605
4, 0, error);
606
if (error.Fail())
607
return false;
608
const int32_t kld_off_next = m_process->ReadSignedIntegerFromMemory(
609
kld_off_next_symbol->GetAddress().GetLoadAddress(&m_process->GetTarget()),
610
4, 0, error);
611
if (error.Fail())
612
return false;
613
const int32_t kld_off_filename = m_process->ReadSignedIntegerFromMemory(
614
kld_off_filename_symbol->GetAddress().GetLoadAddress(
615
&m_process->GetTarget()),
616
4, 0, error);
617
if (error.Fail())
618
return false;
619
620
const int32_t kld_off_pathname = m_process->ReadSignedIntegerFromMemory(
621
kld_off_pathname_symbol->GetAddress().GetLoadAddress(
622
&m_process->GetTarget()),
623
4, 0, error);
624
if (error.Fail())
625
return false;
626
627
// Parse KMods
628
addr_t kld_load_addr(LLDB_INVALID_ADDRESS);
629
char kld_filename[255];
630
char kld_pathname[255];
631
addr_t current_kld =
632
linker_files_head_addr.GetLoadAddress(&m_process->GetTarget());
633
634
while (current_kld != 0) {
635
addr_t kld_filename_addr =
636
m_process->ReadPointerFromMemory(current_kld + kld_off_filename, error);
637
if (error.Fail())
638
return false;
639
addr_t kld_pathname_addr =
640
m_process->ReadPointerFromMemory(current_kld + kld_off_pathname, error);
641
if (error.Fail())
642
return false;
643
644
m_process->ReadCStringFromMemory(kld_filename_addr, kld_filename,
645
sizeof(kld_filename), error);
646
if (error.Fail())
647
return false;
648
m_process->ReadCStringFromMemory(kld_pathname_addr, kld_pathname,
649
sizeof(kld_pathname), error);
650
if (error.Fail())
651
return false;
652
kld_load_addr =
653
m_process->ReadPointerFromMemory(current_kld + kld_off_address, error);
654
if (error.Fail())
655
return false;
656
657
kmods_list.emplace_back();
658
KModImageInfo &kmod_info = kmods_list.back();
659
kmod_info.SetName(kld_filename);
660
kmod_info.SetLoadAddress(kld_load_addr);
661
kmod_info.SetPath(kld_pathname);
662
663
current_kld =
664
m_process->ReadPointerFromMemory(current_kld + kld_off_next, error);
665
if (kmod_info.GetName() == "kernel")
666
kmods_list.pop_back();
667
if (error.Fail())
668
return false;
669
}
670
671
return true;
672
}
673
674
// Read all kmods
675
void DynamicLoaderFreeBSDKernel::ReadAllKmods() {
676
std::lock_guard<decltype(m_mutex)> guard(m_mutex);
677
678
if (ReadKmodsListHeader()) {
679
if (m_linker_file_head_addr.IsValid()) {
680
if (!ParseKmods(m_linker_file_head_addr))
681
m_linker_files_list.clear();
682
}
683
}
684
}
685
686
// Load all Kernel Modules
687
void DynamicLoaderFreeBSDKernel::LoadKernelModules() {
688
Log *log = GetLog(LLDBLog::DynamicLoader);
689
LLDB_LOGF(log, "DynamicLoaderFreeBSDKernel::LoadKernelModules "
690
"Start loading Kernel Module");
691
692
// Initialize Kernel Image Information at the first time
693
if (m_kernel_image_info.GetLoadAddress() == LLDB_INVALID_ADDRESS) {
694
ModuleSP module_sp = m_process->GetTarget().GetExecutableModule();
695
if (is_kernel(module_sp.get())) {
696
m_kernel_image_info.SetModule(module_sp);
697
m_kernel_image_info.SetIsKernel(true);
698
}
699
700
// Set name for kernel
701
llvm::StringRef kernel_name("freebsd_kernel");
702
module_sp = m_kernel_image_info.GetModule();
703
if (module_sp.get() && module_sp->GetObjectFile() &&
704
!module_sp->GetObjectFile()->GetFileSpec().GetFilename().IsEmpty())
705
kernel_name = module_sp->GetObjectFile()
706
->GetFileSpec()
707
.GetFilename()
708
.GetStringRef();
709
m_kernel_image_info.SetName(kernel_name.data());
710
711
if (m_kernel_image_info.GetLoadAddress() == LLDB_INVALID_ADDRESS) {
712
m_kernel_image_info.SetLoadAddress(m_kernel_load_address);
713
}
714
715
// Build In memory Module
716
if (m_kernel_image_info.GetLoadAddress() != LLDB_INVALID_ADDRESS) {
717
// If the kernel is not loaded in the memory, use file to load
718
if (!m_kernel_image_info.LoadImageUsingMemoryModule(m_process))
719
m_kernel_image_info.LoadImageUsingFileAddress(m_process);
720
}
721
}
722
723
LoadOperatingSystemPlugin(false);
724
725
if (!m_kernel_image_info.IsLoaded() || !m_kernel_image_info.GetModule()) {
726
m_kernel_image_info.Clear();
727
return;
728
}
729
730
static ConstString modlist_symbol_name("linker_files");
731
732
const Symbol *symbol =
733
m_kernel_image_info.GetModule()->FindFirstSymbolWithNameAndType(
734
modlist_symbol_name, lldb::eSymbolTypeData);
735
736
if (symbol) {
737
m_linker_file_list_struct_addr = symbol->GetAddress();
738
ReadAllKmods();
739
} else {
740
LLDB_LOGF(log, "DynamicLoaderFreeBSDKernel::LoadKernelModules "
741
"cannot file modlist symbol");
742
}
743
}
744
745
// Update symbol when use kldload by setting callback function on kldload
746
void DynamicLoaderFreeBSDKernel::SetNotificationBreakPoint() {}
747
748
// Hook called when attach to a process
749
void DynamicLoaderFreeBSDKernel::DidAttach() {
750
PrivateInitialize(m_process);
751
Update();
752
}
753
754
// Hook called after attach to a process
755
void DynamicLoaderFreeBSDKernel::DidLaunch() {
756
PrivateInitialize(m_process);
757
Update();
758
}
759
760
// Clear all member except kernel address
761
void DynamicLoaderFreeBSDKernel::Clear(bool clear_process) {
762
std::lock_guard<decltype(m_mutex)> guard(m_mutex);
763
if (clear_process)
764
m_process = nullptr;
765
m_linker_file_head_addr.Clear();
766
m_linker_file_list_struct_addr.Clear();
767
m_kernel_image_info.Clear();
768
m_linker_files_list.clear();
769
}
770
771
// Reinitialize class
772
void DynamicLoaderFreeBSDKernel::PrivateInitialize(Process *process) {
773
Clear(true);
774
m_process = process;
775
}
776
777
ThreadPlanSP DynamicLoaderFreeBSDKernel::GetStepThroughTrampolinePlan(
778
lldb_private::Thread &thread, bool stop_others) {
779
Log *log = GetLog(LLDBLog::Step);
780
LLDB_LOGF(log, "DynamicLoaderFreeBSDKernel::GetStepThroughTrampolinePlan is "
781
"not yet implemented.");
782
return {};
783
}
784
785
Status DynamicLoaderFreeBSDKernel::CanLoadImage() {
786
Status error("shared object cannot be loaded into kernel");
787
return error;
788
}
789
790