xref: /llvm-project/lldb/source/Plugins/DynamicLoader/FreeBSD-Kernel/DynamicLoaderFreeBSDKernel.cpp (revision 5dbfb49490c5f06c9c7843051471956b11ef2abd)
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