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