787 lines · cpp
1//===-- DynamicLoaderFreeBSDKernel.cpp2//------------------------------------------===//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-exception7//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 37using namespace lldb;38using namespace lldb_private;39 40LLDB_PLUGIN_DEFINE(DynamicLoaderFreeBSDKernel)41 42void DynamicLoaderFreeBSDKernel::Initialize() {43 PluginManager::RegisterPlugin(GetPluginNameStatic(),44 GetPluginDescriptionStatic(), CreateInstance,45 DebuggerInit);46}47 48void DynamicLoaderFreeBSDKernel::Terminate() {49 PluginManager::UnregisterPlugin(CreateInstance);50}51 52llvm::StringRef DynamicLoaderFreeBSDKernel::GetPluginDescriptionStatic() {53 return "The Dynamic Loader Plugin For FreeBSD Kernel";54}55 56static 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 72static 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 85static 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 when98// Register the Plugin99DynamicLoader *100DynamicLoaderFreeBSDKernel::CreateInstance(lldb_private::Process *process,101 bool force) {102 // Check the environment when the plugin is not force loaded103 Module *exec = process->GetTarget().GetExecutableModulePointer();104 if (exec && !is_kernel(exec)) {105 return nullptr;106 }107 if (!force) {108 // Check if the target is kernel109 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 we117 // have to do is to find the kernel address118 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 126addr_t127DynamicLoaderFreeBSDKernel::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 slide135addr_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 return156bool 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 UUID178lldb_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 type200 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%" PRIx64216 " 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_sp222 // However, the ReadModuleFromMemory reads wrong section so that this check223 // will failed224 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 244void DynamicLoaderFreeBSDKernel::DebuggerInit(245 lldb_private::Debugger &debugger) {}246 247DynamicLoaderFreeBSDKernel::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 256DynamicLoaderFreeBSDKernel::~DynamicLoaderFreeBSDKernel() { Clear(true); }257 258void DynamicLoaderFreeBSDKernel::Update() {259 LoadKernelModules();260 SetNotificationBreakPoint();261}262 263// Create in memory Module at the load address264bool 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 memory309 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 320bool 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 lldb::StreamUP s = target.GetDebugger().GetAsyncOutputStream();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 add337 // So that we have to create the module manually338 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 system343 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 target.GetDebugger().GetAsyncOutputStream()->Printf(359 "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 and366 // don't reload again367 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 images381 target.GetImages().AppendIfNeeded(m_module_sp, false);382 }383 }384 385 // If this file is relocatable kernel module(x86_64), adjust it's386 // section(PT_LOAD segment) and return Because the kernel module's load387 // address is the text section. lldb cannot create full memory module upon388 // 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 module400 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 address412 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_list448 ->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 else461 m_module_sp.reset();462 } else {463 m_module_sp.reset();464 }465 466 if (IsLoaded() && m_module_sp && IsKernel()) {467 lldb::StreamUP s = target.GetDebugger().GetAsyncOutputStream();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 }481 482 return IsLoaded();483}484 485// This function is work for kernel file, others it wil reset load address and486// return false487bool DynamicLoaderFreeBSDKernel::KModImageInfo::LoadImageUsingFileAddress(488 lldb_private::Process *process) {489 if (IsLoaded())490 return true;491 492 if (m_module_sp) {493 bool changed = false;494 if (m_module_sp->SetLoadAddress(process->GetTarget(), 0, true, changed))495 m_stop_id = process->GetStopID();496 }497 498 return false;499}500 501// Get the head of found_list502bool DynamicLoaderFreeBSDKernel::ReadKmodsListHeader() {503 std::lock_guard<decltype(m_mutex)> guard(m_mutex);504 505 if (m_linker_file_list_struct_addr.IsValid()) {506 // Get tqh_first struct element from linker_files507 Status error;508 addr_t address = m_process->ReadPointerFromMemory(509 m_linker_file_list_struct_addr.GetLoadAddress(&m_process->GetTarget()),510 error);511 if (address != LLDB_INVALID_ADDRESS && error.Success()) {512 m_linker_file_head_addr = Address(address);513 } else {514 m_linker_file_list_struct_addr.Clear();515 return false;516 }517 518 if (!m_linker_file_head_addr.IsValid() ||519 m_linker_file_head_addr.GetFileAddress() == 0) {520 m_linker_file_list_struct_addr.Clear();521 return false;522 }523 }524 return true;525}526 527// Parse Kmod info in found_list528bool DynamicLoaderFreeBSDKernel::ParseKmods(Address linker_files_head_addr) {529 std::lock_guard<decltype(m_mutex)> guard(m_mutex);530 KModImageInfo::collection_type linker_files_list;531 Log *log = GetLog(LLDBLog::DynamicLoader);532 533 if (!ReadAllKmods(linker_files_head_addr, linker_files_list))534 return false;535 LLDB_LOGF(536 log,537 "Kmod-changed breakpoint hit, there are %zu kernel modules currently.\n",538 linker_files_list.size());539 540 ModuleList &modules = m_process->GetTarget().GetImages();541 ModuleList remove_modules;542 ModuleList add_modules;543 544 for (ModuleSP module : modules.Modules()) {545 if (is_kernel(module.get()))546 continue;547 if (is_kmod(module.get()))548 remove_modules.AppendIfNeeded(module);549 }550 551 m_process->GetTarget().ModulesDidUnload(remove_modules, false);552 553 for (KModImageInfo &image_info : linker_files_list) {554 auto it = m_kld_name_to_uuid.find(image_info.GetName());555 if (it != m_kld_name_to_uuid.end())556 image_info.SetUUID(it->second);557 bool failed_to_load = false;558 if (!image_info.LoadImageUsingMemoryModule(m_process)) {559 image_info.LoadImageUsingFileAddress(m_process);560 failed_to_load = true;561 } else {562 m_linker_files_list.push_back(image_info);563 m_kld_name_to_uuid[image_info.GetName()] = image_info.GetUUID();564 }565 566 if (!failed_to_load)567 add_modules.AppendIfNeeded(image_info.GetModule());568 }569 m_process->GetTarget().ModulesDidLoad(add_modules);570 return true;571}572 573// Read all kmod from a given arrays of list574bool DynamicLoaderFreeBSDKernel::ReadAllKmods(575 Address linker_files_head_addr,576 KModImageInfo::collection_type &kmods_list) {577 578 // Get offset of next member and load address symbol579 static ConstString kld_off_address_symbol_name("kld_off_address");580 static ConstString kld_off_next_symbol_name("kld_off_next");581 static ConstString kld_off_filename_symbol_name("kld_off_filename");582 static ConstString kld_off_pathname_symbol_name("kld_off_pathname");583 const Symbol *kld_off_address_symbol =584 m_kernel_image_info.GetModule()->FindFirstSymbolWithNameAndType(585 kld_off_address_symbol_name, eSymbolTypeData);586 const Symbol *kld_off_next_symbol =587 m_kernel_image_info.GetModule()->FindFirstSymbolWithNameAndType(588 kld_off_next_symbol_name, eSymbolTypeData);589 const Symbol *kld_off_filename_symbol =590 m_kernel_image_info.GetModule()->FindFirstSymbolWithNameAndType(591 kld_off_filename_symbol_name, eSymbolTypeData);592 const Symbol *kld_off_pathname_symbol =593 m_kernel_image_info.GetModule()->FindFirstSymbolWithNameAndType(594 kld_off_pathname_symbol_name, eSymbolTypeData);595 596 if (!kld_off_address_symbol || !kld_off_next_symbol ||597 !kld_off_filename_symbol || !kld_off_pathname_symbol)598 return false;599 600 Status error;601 const int32_t kld_off_address = m_process->ReadSignedIntegerFromMemory(602 kld_off_address_symbol->GetAddress().GetLoadAddress(603 &m_process->GetTarget()),604 4, 0, error);605 if (error.Fail())606 return false;607 const int32_t kld_off_next = m_process->ReadSignedIntegerFromMemory(608 kld_off_next_symbol->GetAddress().GetLoadAddress(&m_process->GetTarget()),609 4, 0, error);610 if (error.Fail())611 return false;612 const int32_t kld_off_filename = m_process->ReadSignedIntegerFromMemory(613 kld_off_filename_symbol->GetAddress().GetLoadAddress(614 &m_process->GetTarget()),615 4, 0, error);616 if (error.Fail())617 return false;618 619 const int32_t kld_off_pathname = m_process->ReadSignedIntegerFromMemory(620 kld_off_pathname_symbol->GetAddress().GetLoadAddress(621 &m_process->GetTarget()),622 4, 0, error);623 if (error.Fail())624 return false;625 626 // Parse KMods627 addr_t kld_load_addr(LLDB_INVALID_ADDRESS);628 char kld_filename[255];629 char kld_pathname[255];630 addr_t current_kld =631 linker_files_head_addr.GetLoadAddress(&m_process->GetTarget());632 633 while (current_kld != 0) {634 addr_t kld_filename_addr =635 m_process->ReadPointerFromMemory(current_kld + kld_off_filename, error);636 if (error.Fail())637 return false;638 addr_t kld_pathname_addr =639 m_process->ReadPointerFromMemory(current_kld + kld_off_pathname, error);640 if (error.Fail())641 return false;642 643 m_process->ReadCStringFromMemory(kld_filename_addr, kld_filename,644 sizeof(kld_filename), error);645 if (error.Fail())646 return false;647 m_process->ReadCStringFromMemory(kld_pathname_addr, kld_pathname,648 sizeof(kld_pathname), error);649 if (error.Fail())650 return false;651 kld_load_addr =652 m_process->ReadPointerFromMemory(current_kld + kld_off_address, error);653 if (error.Fail())654 return false;655 656 kmods_list.emplace_back();657 KModImageInfo &kmod_info = kmods_list.back();658 kmod_info.SetName(kld_filename);659 kmod_info.SetLoadAddress(kld_load_addr);660 kmod_info.SetPath(kld_pathname);661 662 current_kld =663 m_process->ReadPointerFromMemory(current_kld + kld_off_next, error);664 if (kmod_info.GetName() == "kernel")665 kmods_list.pop_back();666 if (error.Fail())667 return false;668 }669 670 return true;671}672 673// Read all kmods674void DynamicLoaderFreeBSDKernel::ReadAllKmods() {675 std::lock_guard<decltype(m_mutex)> guard(m_mutex);676 677 if (ReadKmodsListHeader()) {678 if (m_linker_file_head_addr.IsValid()) {679 if (!ParseKmods(m_linker_file_head_addr))680 m_linker_files_list.clear();681 }682 }683}684 685// Load all Kernel Modules686void DynamicLoaderFreeBSDKernel::LoadKernelModules() {687 Log *log = GetLog(LLDBLog::DynamicLoader);688 LLDB_LOGF(log, "DynamicLoaderFreeBSDKernel::LoadKernelModules "689 "Start loading Kernel Module");690 691 // Initialize Kernel Image Information at the first time692 if (m_kernel_image_info.GetLoadAddress() == LLDB_INVALID_ADDRESS) {693 ModuleSP module_sp = m_process->GetTarget().GetExecutableModule();694 if (is_kernel(module_sp.get())) {695 m_kernel_image_info.SetModule(module_sp);696 m_kernel_image_info.SetIsKernel(true);697 }698 699 // Set name for kernel700 llvm::StringRef kernel_name("freebsd_kernel");701 module_sp = m_kernel_image_info.GetModule();702 if (module_sp.get() && module_sp->GetObjectFile() &&703 !module_sp->GetObjectFile()->GetFileSpec().GetFilename().IsEmpty())704 kernel_name = module_sp->GetObjectFile()705 ->GetFileSpec()706 .GetFilename()707 .GetStringRef();708 m_kernel_image_info.SetName(kernel_name.data());709 710 if (m_kernel_image_info.GetLoadAddress() == LLDB_INVALID_ADDRESS) {711 m_kernel_image_info.SetLoadAddress(m_kernel_load_address);712 }713 714 // Build In memory Module715 if (m_kernel_image_info.GetLoadAddress() != LLDB_INVALID_ADDRESS) {716 // If the kernel is not loaded in the memory, use file to load717 if (!m_kernel_image_info.LoadImageUsingMemoryModule(m_process))718 m_kernel_image_info.LoadImageUsingFileAddress(m_process);719 }720 }721 722 LoadOperatingSystemPlugin(false);723 724 if (!m_kernel_image_info.IsLoaded() || !m_kernel_image_info.GetModule()) {725 m_kernel_image_info.Clear();726 return;727 }728 729 static ConstString modlist_symbol_name("linker_files");730 731 const Symbol *symbol =732 m_kernel_image_info.GetModule()->FindFirstSymbolWithNameAndType(733 modlist_symbol_name, lldb::eSymbolTypeData);734 735 if (symbol) {736 m_linker_file_list_struct_addr = symbol->GetAddress();737 ReadAllKmods();738 } else {739 LLDB_LOGF(log, "DynamicLoaderFreeBSDKernel::LoadKernelModules "740 "cannot file modlist symbol");741 }742}743 744// Update symbol when use kldload by setting callback function on kldload745void DynamicLoaderFreeBSDKernel::SetNotificationBreakPoint() {}746 747// Hook called when attach to a process748void DynamicLoaderFreeBSDKernel::DidAttach() {749 PrivateInitialize(m_process);750 Update();751}752 753// Hook called after attach to a process754void DynamicLoaderFreeBSDKernel::DidLaunch() {755 PrivateInitialize(m_process);756 Update();757}758 759// Clear all member except kernel address760void DynamicLoaderFreeBSDKernel::Clear(bool clear_process) {761 std::lock_guard<decltype(m_mutex)> guard(m_mutex);762 if (clear_process)763 m_process = nullptr;764 m_linker_file_head_addr.Clear();765 m_linker_file_list_struct_addr.Clear();766 m_kernel_image_info.Clear();767 m_linker_files_list.clear();768}769 770// Reinitialize class771void DynamicLoaderFreeBSDKernel::PrivateInitialize(Process *process) {772 Clear(true);773 m_process = process;774}775 776ThreadPlanSP DynamicLoaderFreeBSDKernel::GetStepThroughTrampolinePlan(777 lldb_private::Thread &thread, bool stop_others) {778 Log *log = GetLog(LLDBLog::Step);779 LLDB_LOGF(log, "DynamicLoaderFreeBSDKernel::GetStepThroughTrampolinePlan is "780 "not yet implemented.");781 return {};782}783 784Status DynamicLoaderFreeBSDKernel::CanLoadImage() {785 return Status::FromErrorString("shared object cannot be loaded into kernel");786}787