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