Path: blob/main/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/FreeBSD-Kernel/DynamicLoaderFreeBSDKernel.cpp
39642 views
//===-- DynamicLoaderFreeBSDKernel.cpp1//------------------------------------------===//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-exception6//7//===----------------------------------------------------------------------===//89#include "lldb/Breakpoint/StoppointCallbackContext.h"10#include "lldb/Core/Debugger.h"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/Host/StreamFile.h"16#include "lldb/Interpreter/OptionValueProperties.h"17#include "lldb/Symbol/ObjectFile.h"18#include "lldb/Target/OperatingSystem.h"19#include "lldb/Target/RegisterContext.h"20#include "lldb/Target/StackFrame.h"21#include "lldb/Target/Target.h"22#include "lldb/Target/Thread.h"23#include "lldb/Target/ThreadPlanRunToAddress.h"24#include "lldb/Utility/DataBuffer.h"25#include "lldb/Utility/DataBufferHeap.h"26#include "lldb/Utility/LLDBLog.h"27#include "lldb/Utility/Log.h"28#include "lldb/Utility/State.h"2930#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"3132#include "DynamicLoaderFreeBSDKernel.h"33#include <memory>34#include <mutex>3536using namespace lldb;37using namespace lldb_private;3839LLDB_PLUGIN_DEFINE(DynamicLoaderFreeBSDKernel)4041void DynamicLoaderFreeBSDKernel::Initialize() {42PluginManager::RegisterPlugin(GetPluginNameStatic(),43GetPluginDescriptionStatic(), CreateInstance,44DebuggerInit);45}4647void DynamicLoaderFreeBSDKernel::Terminate() {48PluginManager::UnregisterPlugin(CreateInstance);49}5051llvm::StringRef DynamicLoaderFreeBSDKernel::GetPluginDescriptionStatic() {52return "The Dynamic Loader Plugin For FreeBSD Kernel";53}5455static bool is_kernel(Module *module) {56if (!module)57return false;5859ObjectFile *objfile = module->GetObjectFile();60if (!objfile)61return false;62if (objfile->GetType() != ObjectFile::eTypeExecutable)63return false;64if (objfile->GetStrata() != ObjectFile::eStrataUnknown &&65objfile->GetStrata() != ObjectFile::eStrataKernel)66return false;6768return true;69}7071static bool is_kmod(Module *module) {72if (!module)73return false;74if (!module->GetObjectFile())75return false;76ObjectFile *objfile = module->GetObjectFile();77if (objfile->GetType() != ObjectFile::eTypeObjectFile &&78objfile->GetType() != ObjectFile::eTypeSharedLibrary)79return false;8081return true;82}8384static bool is_reloc(Module *module) {85if (!module)86return false;87if (!module->GetObjectFile())88return false;89ObjectFile *objfile = module->GetObjectFile();90if (objfile->GetType() != ObjectFile::eTypeObjectFile)91return false;9293return true;94}9596// Instantiate Function of the FreeBSD Kernel Dynamic Loader Plugin called when97// Register the Plugin98DynamicLoader *99DynamicLoaderFreeBSDKernel::CreateInstance(lldb_private::Process *process,100bool force) {101// Check the environment when the plugin is not force loaded102Module *exec = process->GetTarget().GetExecutableModulePointer();103if (exec && !is_kernel(exec)) {104return nullptr;105}106if (!force) {107// Check if the target is kernel108const llvm::Triple &triple_ref =109process->GetTarget().GetArchitecture().GetTriple();110if (!triple_ref.isOSFreeBSD()) {111return nullptr;112}113}114115// At this point we have checked the target is a FreeBSD kernel and all we116// have to do is to find the kernel address117const addr_t kernel_address = FindFreeBSDKernel(process);118119if (CheckForKernelImageAtAddress(process, kernel_address).IsValid())120return new DynamicLoaderFreeBSDKernel(process, kernel_address);121122return nullptr;123}124125addr_t126DynamicLoaderFreeBSDKernel::FindFreeBSDKernel(lldb_private::Process *process) {127addr_t kernel_addr = process->GetImageInfoAddress();128if (kernel_addr == LLDB_INVALID_ADDRESS)129kernel_addr = FindKernelAtLoadAddress(process);130return kernel_addr;131}132133// Get the kernel address if the kernel is not loaded with a slide134addr_t DynamicLoaderFreeBSDKernel::FindKernelAtLoadAddress(135lldb_private::Process *process) {136Module *exe_module = process->GetTarget().GetExecutableModulePointer();137138if (!is_kernel(exe_module))139return LLDB_INVALID_ADDRESS;140141ObjectFile *exe_objfile = exe_module->GetObjectFile();142143if (!exe_objfile->GetBaseAddress().IsValid())144return LLDB_INVALID_ADDRESS;145146if (CheckForKernelImageAtAddress(147process, exe_objfile->GetBaseAddress().GetFileAddress())148.IsValid())149return exe_objfile->GetBaseAddress().GetFileAddress();150151return LLDB_INVALID_ADDRESS;152}153154// Read ELF header from memry and return155bool DynamicLoaderFreeBSDKernel::ReadELFHeader(Process *process,156lldb::addr_t addr,157llvm::ELF::Elf32_Ehdr &header,158bool *read_error) {159Status error;160if (read_error)161*read_error = false;162163if (process->ReadMemory(addr, &header, sizeof(header), error) !=164sizeof(header)) {165if (read_error)166*read_error = true;167return false;168}169170if (!header.checkMagic())171return false;172173return true;174}175176// Check the correctness of Kernel and return UUID177lldb_private::UUID DynamicLoaderFreeBSDKernel::CheckForKernelImageAtAddress(178Process *process, lldb::addr_t addr, bool *read_error) {179Log *log = GetLog(LLDBLog::DynamicLoader);180181if (addr == LLDB_INVALID_ADDRESS) {182if (read_error)183*read_error = true;184return UUID();185}186187LLDB_LOGF(log,188"DynamicLoaderFreeBSDKernel::CheckForKernelImageAtAddress: "189"looking for kernel binary at 0x%" PRIx64,190addr);191192llvm::ELF::Elf32_Ehdr header;193if (!ReadELFHeader(process, addr, header)) {194*read_error = true;195return UUID();196}197198// Check header type199if (header.e_type != llvm::ELF::ET_EXEC)200return UUID();201202ModuleSP memory_module_sp =203process->ReadModuleFromMemory(FileSpec("temp_freebsd_kernel"), addr);204205if (!memory_module_sp.get()) {206*read_error = true;207return UUID();208}209210ObjectFile *exe_objfile = memory_module_sp->GetObjectFile();211if (exe_objfile == nullptr) {212LLDB_LOGF(log,213"DynamicLoaderFreeBSDKernel::CheckForKernelImageAtAddress "214"found a binary at 0x%" PRIx64215" but could not create an object file from memory",216addr);217return UUID();218}219220// In here, I should check is_kernel for memory_module_sp221// However, the ReadModuleFromMemory reads wrong section so that this check222// will failed223ArchSpec kernel_arch(llvm::ELF::convertEMachineToArchName(header.e_machine));224225if (!process->GetTarget().GetArchitecture().IsCompatibleMatch(kernel_arch))226process->GetTarget().SetArchitecture(kernel_arch);227228std::string uuid_str;229if (memory_module_sp->GetUUID().IsValid()) {230uuid_str = "with UUID ";231uuid_str += memory_module_sp->GetUUID().GetAsString();232} else {233uuid_str = "and no LC_UUID found in load commands ";234}235LLDB_LOGF(log,236"DynamicLoaderFreeBSDKernel::CheckForKernelImageAtAddress: "237"kernel binary image found at 0x%" PRIx64 " with arch '%s' %s",238addr, kernel_arch.GetTriple().str().c_str(), uuid_str.c_str());239240return memory_module_sp->GetUUID();241}242243void DynamicLoaderFreeBSDKernel::DebuggerInit(244lldb_private::Debugger &debugger) {}245246DynamicLoaderFreeBSDKernel::DynamicLoaderFreeBSDKernel(Process *process,247addr_t kernel_address)248: DynamicLoader(process), m_process(process),249m_linker_file_list_struct_addr(LLDB_INVALID_ADDRESS),250m_linker_file_head_addr(LLDB_INVALID_ADDRESS),251m_kernel_load_address(kernel_address), m_mutex() {252process->SetCanRunCode(false);253}254255DynamicLoaderFreeBSDKernel::~DynamicLoaderFreeBSDKernel() { Clear(true); }256257void DynamicLoaderFreeBSDKernel::Update() {258LoadKernelModules();259SetNotificationBreakPoint();260}261262// Create in memory Module at the load address263bool DynamicLoaderFreeBSDKernel::KModImageInfo::ReadMemoryModule(264lldb_private::Process *process) {265Log *log = GetLog(LLDBLog::DynamicLoader);266if (m_memory_module_sp)267return true;268if (m_load_address == LLDB_INVALID_ADDRESS)269return false;270271FileSpec file_spec(m_name);272273ModuleSP memory_module_sp;274275llvm::ELF::Elf32_Ehdr elf_eheader;276size_t size_to_read = 512;277278if (ReadELFHeader(process, m_load_address, elf_eheader)) {279if (elf_eheader.e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS32) {280size_to_read = sizeof(llvm::ELF::Elf32_Ehdr) +281elf_eheader.e_phnum * elf_eheader.e_phentsize;282} else if (elf_eheader.e_ident[llvm::ELF::EI_CLASS] ==283llvm::ELF::ELFCLASS64) {284llvm::ELF::Elf64_Ehdr elf_eheader;285Status error;286if (process->ReadMemory(m_load_address, &elf_eheader, sizeof(elf_eheader),287error) == sizeof(elf_eheader))288size_to_read = sizeof(llvm::ELF::Elf64_Ehdr) +289elf_eheader.e_phnum * elf_eheader.e_phentsize;290}291}292293memory_module_sp =294process->ReadModuleFromMemory(file_spec, m_load_address, size_to_read);295296if (!memory_module_sp)297return false;298299bool this_is_kernel = is_kernel(memory_module_sp.get());300301if (!m_uuid.IsValid() && memory_module_sp->GetUUID().IsValid())302m_uuid = memory_module_sp->GetUUID();303304m_memory_module_sp = memory_module_sp;305m_is_kernel = this_is_kernel;306307// The kernel binary is from memory308if (this_is_kernel) {309LLDB_LOGF(log, "KextImageInfo::ReadMemoryModule read the kernel binary out "310"of memory");311312if (memory_module_sp->GetArchitecture().IsValid())313process->GetTarget().SetArchitecture(memory_module_sp->GetArchitecture());314}315316return true;317}318319bool DynamicLoaderFreeBSDKernel::KModImageInfo::LoadImageUsingMemoryModule(320lldb_private::Process *process) {321Log *log = GetLog(LLDBLog::DynamicLoader);322323if (IsLoaded())324return true;325326Target &target = process->GetTarget();327328if (IsKernel() && m_uuid.IsValid()) {329Stream &s = target.GetDebugger().GetOutputStream();330s.Printf("Kernel UUID: %s\n", m_uuid.GetAsString().c_str());331s.Printf("Load Address: 0x%" PRIx64 "\n", m_load_address);332}333334// Test if the module is loaded into the taget,335// maybe the module is loaded manually by user by doing target module add336// So that we have to create the module manually337if (!m_module_sp) {338const ModuleList &target_images = target.GetImages();339m_module_sp = target_images.FindModule(m_uuid);340341// Search in the file system342if (!m_module_sp) {343ModuleSpec module_spec(FileSpec(GetPath()), target.GetArchitecture());344if (IsKernel()) {345Status error;346if (PluginManager::DownloadObjectAndSymbolFile(module_spec, error,347true)) {348if (FileSystem::Instance().Exists(module_spec.GetFileSpec()))349m_module_sp = std::make_shared<Module>(module_spec.GetFileSpec(),350target.GetArchitecture());351}352}353354if (!m_module_sp)355m_module_sp = target.GetOrCreateModule(module_spec, true);356if (IsKernel() && !m_module_sp) {357Stream &s = target.GetDebugger().GetOutputStream();358s.Printf("WARNING: Unable to locate kernel binary on the debugger "359"system.\n");360}361}362363if (m_module_sp) {364// If the file is not kernel or kmod, the target should be loaded once and365// don't reload again366if (!IsKernel() && !is_kmod(m_module_sp.get())) {367ModuleSP existing_module_sp = target.GetImages().FindModule(m_uuid);368if (existing_module_sp &&369existing_module_sp->IsLoadedInTarget(&target)) {370LLDB_LOGF(log,371"'%s' with UUID %s is not a kmod or kernel, and is "372"already registered in target, not loading.",373m_name.c_str(), m_uuid.GetAsString().c_str());374return true;375}376}377m_uuid = m_module_sp->GetUUID();378379// or append to the images380target.GetImages().AppendIfNeeded(m_module_sp, false);381}382}383384// If this file is relocatable kernel module(x86_64), adjust it's385// section(PT_LOAD segment) and return Because the kernel module's load386// address is the text section. lldb cannot create full memory module upon387// relocatable file So what we do is to set the load address only.388if (is_kmod(m_module_sp.get()) && is_reloc(m_module_sp.get())) {389m_stop_id = process->GetStopID();390bool changed = false;391m_module_sp->SetLoadAddress(target, m_load_address, true, changed);392return true;393}394395if (m_module_sp)396ReadMemoryModule(process);397398// Calculate the slides of in memory module399if (!m_memory_module_sp || !m_module_sp) {400m_module_sp.reset();401return false;402}403404ObjectFile *ondisk_object_file = m_module_sp->GetObjectFile();405ObjectFile *memory_object_file = m_memory_module_sp->GetObjectFile();406407if (!ondisk_object_file || !memory_object_file)408m_module_sp.reset();409410// Find the slide address411addr_t fixed_slide = LLDB_INVALID_ADDRESS;412if (llvm::dyn_cast<ObjectFileELF>(memory_object_file)) {413addr_t load_address = memory_object_file->GetBaseAddress().GetFileAddress();414415if (load_address != LLDB_INVALID_ADDRESS &&416m_load_address != load_address) {417fixed_slide = m_load_address - load_address;418LLDB_LOGF(log,419"kmod %s in-memory LOAD vmaddr is not correct, using a "420"fixed slide of 0x%" PRIx64,421m_name.c_str(), fixed_slide);422}423}424425SectionList *ondisk_section_list = ondisk_object_file->GetSectionList();426SectionList *memory_section_list = memory_object_file->GetSectionList();427428if (memory_section_list && ondisk_object_file) {429const uint32_t num_ondisk_sections = ondisk_section_list->GetSize();430uint32_t num_load_sections = 0;431432for (uint32_t section_idx = 0; section_idx < num_ondisk_sections;433++section_idx) {434SectionSP on_disk_section_sp =435ondisk_section_list->GetSectionAtIndex(section_idx);436437if (!on_disk_section_sp)438continue;439if (fixed_slide != LLDB_INVALID_ADDRESS) {440target.SetSectionLoadAddress(on_disk_section_sp,441on_disk_section_sp->GetFileAddress() +442fixed_slide);443444} else {445const Section *memory_section =446memory_section_list447->FindSectionByName(on_disk_section_sp->GetName())448.get();449if (memory_section) {450target.SetSectionLoadAddress(on_disk_section_sp,451memory_section->GetFileAddress());452++num_load_sections;453}454}455}456457if (num_load_sections)458m_stop_id = process->GetStopID();459else460m_module_sp.reset();461} else {462m_module_sp.reset();463}464465if (IsLoaded() && m_module_sp && IsKernel()) {466Stream &s = target.GetDebugger().GetOutputStream();467ObjectFile *kernel_object_file = m_module_sp->GetObjectFile();468if (kernel_object_file) {469addr_t file_address =470kernel_object_file->GetBaseAddress().GetFileAddress();471if (m_load_address != LLDB_INVALID_ADDRESS &&472file_address != LLDB_INVALID_ADDRESS) {473s.Printf("Kernel slide 0x%" PRIx64 " in memory.\n",474m_load_address - file_address);475s.Printf("Loaded kernel file %s\n",476m_module_sp->GetFileSpec().GetPath().c_str());477}478}479s.Flush();480}481482return IsLoaded();483}484485// This function is work for kernel file, others it wil reset load address and486// return false487bool DynamicLoaderFreeBSDKernel::KModImageInfo::LoadImageUsingFileAddress(488lldb_private::Process *process) {489if (IsLoaded())490return true;491492if (m_module_sp) {493bool changed = false;494if (m_module_sp->SetLoadAddress(process->GetTarget(), 0, true, changed))495m_stop_id = process->GetStopID();496}497498return false;499}500501// Get the head of found_list502bool DynamicLoaderFreeBSDKernel::ReadKmodsListHeader() {503std::lock_guard<decltype(m_mutex)> guard(m_mutex);504505if (m_linker_file_list_struct_addr.IsValid()) {506// Get tqh_first struct element from linker_files507Status error;508addr_t address = m_process->ReadPointerFromMemory(509m_linker_file_list_struct_addr.GetLoadAddress(&m_process->GetTarget()),510error);511if (address != LLDB_INVALID_ADDRESS && error.Success()) {512m_linker_file_head_addr = Address(address);513} else {514m_linker_file_list_struct_addr.Clear();515return false;516}517518if (!m_linker_file_head_addr.IsValid() ||519m_linker_file_head_addr.GetFileAddress() == 0) {520m_linker_file_list_struct_addr.Clear();521return false;522}523}524return true;525}526527// Parse Kmod info in found_list528bool DynamicLoaderFreeBSDKernel::ParseKmods(Address linker_files_head_addr) {529std::lock_guard<decltype(m_mutex)> guard(m_mutex);530KModImageInfo::collection_type linker_files_list;531Log *log = GetLog(LLDBLog::DynamicLoader);532533if (!ReadAllKmods(linker_files_head_addr, linker_files_list))534return false;535LLDB_LOGF(536log,537"Kmod-changed breakpoint hit, there are %zu kernel modules currently.\n",538linker_files_list.size());539540ModuleList &modules = m_process->GetTarget().GetImages();541ModuleList remove_modules;542ModuleList add_modules;543544for (ModuleSP module : modules.Modules()) {545if (is_kernel(module.get()))546continue;547if (is_kmod(module.get()))548remove_modules.AppendIfNeeded(module);549}550551m_process->GetTarget().ModulesDidUnload(remove_modules, false);552553for (KModImageInfo &image_info : linker_files_list) {554if (m_kld_name_to_uuid.find(image_info.GetName()) !=555m_kld_name_to_uuid.end())556image_info.SetUUID(m_kld_name_to_uuid[image_info.GetName()]);557bool failed_to_load = false;558if (!image_info.LoadImageUsingMemoryModule(m_process)) {559image_info.LoadImageUsingFileAddress(m_process);560failed_to_load = true;561} else {562m_linker_files_list.push_back(image_info);563m_kld_name_to_uuid[image_info.GetName()] = image_info.GetUUID();564}565566if (!failed_to_load)567add_modules.AppendIfNeeded(image_info.GetModule());568}569m_process->GetTarget().ModulesDidLoad(add_modules);570return true;571}572573// Read all kmod from a given arrays of list574bool DynamicLoaderFreeBSDKernel::ReadAllKmods(575Address linker_files_head_addr,576KModImageInfo::collection_type &kmods_list) {577578// Get offset of next member and load address symbol579static ConstString kld_off_address_symbol_name("kld_off_address");580static ConstString kld_off_next_symbol_name("kld_off_next");581static ConstString kld_off_filename_symbol_name("kld_off_filename");582static ConstString kld_off_pathname_symbol_name("kld_off_pathname");583const Symbol *kld_off_address_symbol =584m_kernel_image_info.GetModule()->FindFirstSymbolWithNameAndType(585kld_off_address_symbol_name, eSymbolTypeData);586const Symbol *kld_off_next_symbol =587m_kernel_image_info.GetModule()->FindFirstSymbolWithNameAndType(588kld_off_next_symbol_name, eSymbolTypeData);589const Symbol *kld_off_filename_symbol =590m_kernel_image_info.GetModule()->FindFirstSymbolWithNameAndType(591kld_off_filename_symbol_name, eSymbolTypeData);592const Symbol *kld_off_pathname_symbol =593m_kernel_image_info.GetModule()->FindFirstSymbolWithNameAndType(594kld_off_pathname_symbol_name, eSymbolTypeData);595596if (!kld_off_address_symbol || !kld_off_next_symbol ||597!kld_off_filename_symbol || !kld_off_pathname_symbol)598return false;599600Status error;601const int32_t kld_off_address = m_process->ReadSignedIntegerFromMemory(602kld_off_address_symbol->GetAddress().GetLoadAddress(603&m_process->GetTarget()),6044, 0, error);605if (error.Fail())606return false;607const int32_t kld_off_next = m_process->ReadSignedIntegerFromMemory(608kld_off_next_symbol->GetAddress().GetLoadAddress(&m_process->GetTarget()),6094, 0, error);610if (error.Fail())611return false;612const int32_t kld_off_filename = m_process->ReadSignedIntegerFromMemory(613kld_off_filename_symbol->GetAddress().GetLoadAddress(614&m_process->GetTarget()),6154, 0, error);616if (error.Fail())617return false;618619const int32_t kld_off_pathname = m_process->ReadSignedIntegerFromMemory(620kld_off_pathname_symbol->GetAddress().GetLoadAddress(621&m_process->GetTarget()),6224, 0, error);623if (error.Fail())624return false;625626// Parse KMods627addr_t kld_load_addr(LLDB_INVALID_ADDRESS);628char kld_filename[255];629char kld_pathname[255];630addr_t current_kld =631linker_files_head_addr.GetLoadAddress(&m_process->GetTarget());632633while (current_kld != 0) {634addr_t kld_filename_addr =635m_process->ReadPointerFromMemory(current_kld + kld_off_filename, error);636if (error.Fail())637return false;638addr_t kld_pathname_addr =639m_process->ReadPointerFromMemory(current_kld + kld_off_pathname, error);640if (error.Fail())641return false;642643m_process->ReadCStringFromMemory(kld_filename_addr, kld_filename,644sizeof(kld_filename), error);645if (error.Fail())646return false;647m_process->ReadCStringFromMemory(kld_pathname_addr, kld_pathname,648sizeof(kld_pathname), error);649if (error.Fail())650return false;651kld_load_addr =652m_process->ReadPointerFromMemory(current_kld + kld_off_address, error);653if (error.Fail())654return false;655656kmods_list.emplace_back();657KModImageInfo &kmod_info = kmods_list.back();658kmod_info.SetName(kld_filename);659kmod_info.SetLoadAddress(kld_load_addr);660kmod_info.SetPath(kld_pathname);661662current_kld =663m_process->ReadPointerFromMemory(current_kld + kld_off_next, error);664if (kmod_info.GetName() == "kernel")665kmods_list.pop_back();666if (error.Fail())667return false;668}669670return true;671}672673// Read all kmods674void DynamicLoaderFreeBSDKernel::ReadAllKmods() {675std::lock_guard<decltype(m_mutex)> guard(m_mutex);676677if (ReadKmodsListHeader()) {678if (m_linker_file_head_addr.IsValid()) {679if (!ParseKmods(m_linker_file_head_addr))680m_linker_files_list.clear();681}682}683}684685// Load all Kernel Modules686void DynamicLoaderFreeBSDKernel::LoadKernelModules() {687Log *log = GetLog(LLDBLog::DynamicLoader);688LLDB_LOGF(log, "DynamicLoaderFreeBSDKernel::LoadKernelModules "689"Start loading Kernel Module");690691// Initialize Kernel Image Information at the first time692if (m_kernel_image_info.GetLoadAddress() == LLDB_INVALID_ADDRESS) {693ModuleSP module_sp = m_process->GetTarget().GetExecutableModule();694if (is_kernel(module_sp.get())) {695m_kernel_image_info.SetModule(module_sp);696m_kernel_image_info.SetIsKernel(true);697}698699// Set name for kernel700llvm::StringRef kernel_name("freebsd_kernel");701module_sp = m_kernel_image_info.GetModule();702if (module_sp.get() && module_sp->GetObjectFile() &&703!module_sp->GetObjectFile()->GetFileSpec().GetFilename().IsEmpty())704kernel_name = module_sp->GetObjectFile()705->GetFileSpec()706.GetFilename()707.GetStringRef();708m_kernel_image_info.SetName(kernel_name.data());709710if (m_kernel_image_info.GetLoadAddress() == LLDB_INVALID_ADDRESS) {711m_kernel_image_info.SetLoadAddress(m_kernel_load_address);712}713714// Build In memory Module715if (m_kernel_image_info.GetLoadAddress() != LLDB_INVALID_ADDRESS) {716// If the kernel is not loaded in the memory, use file to load717if (!m_kernel_image_info.LoadImageUsingMemoryModule(m_process))718m_kernel_image_info.LoadImageUsingFileAddress(m_process);719}720}721722LoadOperatingSystemPlugin(false);723724if (!m_kernel_image_info.IsLoaded() || !m_kernel_image_info.GetModule()) {725m_kernel_image_info.Clear();726return;727}728729static ConstString modlist_symbol_name("linker_files");730731const Symbol *symbol =732m_kernel_image_info.GetModule()->FindFirstSymbolWithNameAndType(733modlist_symbol_name, lldb::eSymbolTypeData);734735if (symbol) {736m_linker_file_list_struct_addr = symbol->GetAddress();737ReadAllKmods();738} else {739LLDB_LOGF(log, "DynamicLoaderFreeBSDKernel::LoadKernelModules "740"cannot file modlist symbol");741}742}743744// Update symbol when use kldload by setting callback function on kldload745void DynamicLoaderFreeBSDKernel::SetNotificationBreakPoint() {}746747// Hook called when attach to a process748void DynamicLoaderFreeBSDKernel::DidAttach() {749PrivateInitialize(m_process);750Update();751}752753// Hook called after attach to a process754void DynamicLoaderFreeBSDKernel::DidLaunch() {755PrivateInitialize(m_process);756Update();757}758759// Clear all member except kernel address760void DynamicLoaderFreeBSDKernel::Clear(bool clear_process) {761std::lock_guard<decltype(m_mutex)> guard(m_mutex);762if (clear_process)763m_process = nullptr;764m_linker_file_head_addr.Clear();765m_linker_file_list_struct_addr.Clear();766m_kernel_image_info.Clear();767m_linker_files_list.clear();768}769770// Reinitialize class771void DynamicLoaderFreeBSDKernel::PrivateInitialize(Process *process) {772Clear(true);773m_process = process;774}775776ThreadPlanSP DynamicLoaderFreeBSDKernel::GetStepThroughTrampolinePlan(777lldb_private::Thread &thread, bool stop_others) {778Log *log = GetLog(LLDBLog::Step);779LLDB_LOGF(log, "DynamicLoaderFreeBSDKernel::GetStepThroughTrampolinePlan is "780"not yet implemented.");781return {};782}783784Status DynamicLoaderFreeBSDKernel::CanLoadImage() {785Status error("shared object cannot be loaded into kernel");786return error;787}788789790