32#include "llvm/Support/Error.h"
56 return "The Dynamic Loader Plugin For FreeBSD Kernel";
69 case llvm::Triple::x86:
70 case llvm::Triple::x86_64:
71 case llvm::Triple::arm:
72 case llvm::Triple::aarch64:
73 case llvm::Triple::riscv64:
76 case llvm::Triple::ppc64:
77 case llvm::Triple::ppc64le:
84 if (objfile->
GetType() != expected_type)
102 case llvm::Triple::x86_64:
104 case llvm::Triple::x86:
105 case llvm::Triple::arm:
106 case llvm::Triple::aarch64:
107 case llvm::Triple::riscv64:
108 case llvm::Triple::ppc64:
109 case llvm::Triple::ppc64le:
117 llvm::StringRef target_path) {
118 if (!module || module->GetSymbolFileFileSpec())
121 FileSpec local_file =
module->GetFileSpec();
127 std::string local_path = local_file.
GetPath();
128 std::string normalized_target_path = target_file.
GetPath();
129 llvm::StringRef local_sysroot(local_path);
130 if (!local_sysroot.consume_back(normalized_target_path))
133 std::string debug_path = local_sysroot.str();
134 debug_path +=
"/usr/lib/debug";
135 debug_path += normalized_target_path;
136 debug_path +=
".debug";
141 module->SetSymbolFileFileSpec(debug_file);
149 ObjectFile *objfile =
module->GetObjectFile();
154 case llvm::Triple::x86_64:
173 const llvm::Triple &triple_ref =
175 if (!triple_ref.isOSFreeBSD()) {
234 llvm::ELF::Elf32_Ehdr &header,
248 if (!header.checkMagic())
258 bool local_read_error;
261 read_error = &local_read_error;
270 "DynamicLoaderFreeBSDKernel::CheckForKernelImageAtAddress: "
271 "looking for kernel binary at 0x%" PRIx64,
274 llvm::ELF::Elf32_Ehdr header;
280 uint16_t expected_type;
281 switch (header.e_machine) {
282 case llvm::ELF::EM_386:
283 case llvm::ELF::EM_X86_64:
284 case llvm::ELF::EM_ARM:
285 case llvm::ELF::EM_AARCH64:
286 case llvm::ELF::EM_RISCV:
287 expected_type = llvm::ELF::ET_EXEC;
289 case llvm::ELF::EM_PPC64:
290 expected_type = llvm::ELF::ET_DYN;
296 if (header.e_type != expected_type)
299 llvm::Expected<ModuleSP> memory_module_sp_or_err =
301 if (
auto err = memory_module_sp_or_err.takeError()) {
303 "DynamicLoaderFreeBSDKernel::CheckForKernelImageAtAddress: "
304 "Failed to read module in memory -- {0}");
309 ModuleSP memory_module_sp = *memory_module_sp_or_err;
310 if (!memory_module_sp.get()) {
315 ObjectFile *exe_objfile = memory_module_sp->GetObjectFile();
316 if (exe_objfile ==
nullptr) {
318 "DynamicLoaderFreeBSDKernel::CheckForKernelImageAtAddress "
319 "found a binary at 0x%" PRIx64
320 " but could not create an object file from memory",
328 ArchSpec kernel_arch(llvm::ELF::convertEMachineToArchName(header.e_machine));
333 std::string uuid_str;
334 if (memory_module_sp->GetUUID().IsValid()) {
335 uuid_str =
"with UUID ";
336 uuid_str += memory_module_sp->GetUUID().GetAsString();
338 uuid_str =
"and no LC_UUID found in load commands ";
341 "DynamicLoaderFreeBSDKernel::CheckForKernelImageAtAddress: "
342 "kernel binary image found at 0x%" PRIx64
" with arch '%s' %s",
343 addr, kernel_arch.
GetTriple().str().c_str(), uuid_str.c_str());
345 return memory_module_sp->GetUUID();
378 llvm::ELF::Elf32_Ehdr elf_eheader;
379 size_t size_to_read = 512;
382 if (elf_eheader.e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS32) {
383 size_to_read =
sizeof(llvm::ELF::Elf32_Ehdr) +
384 elf_eheader.e_phnum * elf_eheader.e_phentsize;
385 }
else if (elf_eheader.e_ident[llvm::ELF::EI_CLASS] ==
386 llvm::ELF::ELFCLASS64) {
387 llvm::ELF::Elf64_Ehdr elf_eheader;
390 error) ==
sizeof(elf_eheader) &&
392 size_to_read =
sizeof(llvm::ELF::Elf64_Ehdr) +
393 elf_eheader.e_phnum * elf_eheader.e_phentsize;
397 llvm::Expected<ModuleSP> memory_module_sp_or_err =
399 if (
auto err = memory_module_sp_or_err.takeError()) {
401 "KextImageInfo::ReadMemoryModule: Failed to read module "
402 "from memory -- {0}");
405 memory_module_sp = *memory_module_sp_or_err;
407 if (!memory_module_sp)
410 bool this_is_kernel =
is_kernel(memory_module_sp.get());
412 if (!
m_uuid.IsValid() && memory_module_sp->GetUUID().IsValid())
413 m_uuid = memory_module_sp->GetUUID();
419 if (this_is_kernel) {
420 LLDB_LOGF(log,
"KextImageInfo::ReadMemoryModule read the kernel binary out "
423 if (memory_module_sp->GetArchitecture().IsValid())
441 s->Printf(
"Kernel UUID: %s\n",
m_uuid.GetAsString().c_str());
470 "WARNING: Unable to locate kernel binary on the debugger "
483 if (existing_module_sp &&
484 existing_module_sp->IsLoadedInTarget(&target)) {
486 "'%s' with UUID %s is not a kmod or kernel, and is "
487 "already registered in target, not loading.",
505 bool changed =
false;
522 if (!ondisk_object_file || !memory_object_file)
527 if (llvm::dyn_cast<ObjectFileELF>(memory_object_file)) {
534 "kmod %s in-memory LOAD vmaddr is not correct, using a "
535 "fixed slide of 0x%" PRIx64,
536 m_name.c_str(), fixed_slide);
543 if (memory_section_list && ondisk_object_file) {
544 const uint32_t num_ondisk_sections = ondisk_section_list->
GetSize();
545 uint32_t num_load_sections = 0;
547 for (uint32_t section_idx = 0; section_idx < num_ondisk_sections;
552 if (!on_disk_section_sp)
556 on_disk_section_sp->GetFileAddress() +
561 const Section *memory_section =
565 if (memory_section) {
573 if (num_load_sections)
584 if (kernel_object_file) {
589 s->Printf(
"Kernel slide 0x%" PRIx64
" in memory.\n",
591 s->Printf(
"Loaded kernel file %s\n",
608 bool changed =
false;
622 llvm::Expected<lldb::addr_t> address =
m_process->ReadPointerFromMemory(
625 llvm::consumeError(address.takeError());
646 if (!
ReadAllKmods(linker_files_head_addr, linker_files_list))
650 "Kmod-changed breakpoint hit, there are %zu kernel modules currently.\n",
651 linker_files_list.size());
664 m_process->GetTarget().ModulesDidUnload(remove_modules,
false);
669 image_info.SetUUID(it->second);
670 bool failed_to_load =
false;
671 if (!image_info.LoadImageUsingMemoryModule(
m_process)) {
672 image_info.LoadImageUsingFileAddress(
m_process);
673 failed_to_load =
true;
682 m_process->GetTarget().ModulesDidLoad(add_modules);
688 Address linker_files_head_addr,
692 static ConstString kld_off_address_symbol_name(
"kld_off_address");
693 static ConstString kld_off_next_symbol_name(
"kld_off_next");
694 static ConstString kld_off_filename_symbol_name(
"kld_off_filename");
695 static ConstString kld_off_pathname_symbol_name(
"kld_off_pathname");
696 const Symbol *kld_off_address_symbol =
699 const Symbol *kld_off_next_symbol =
702 const Symbol *kld_off_filename_symbol =
705 const Symbol *kld_off_pathname_symbol =
709 if (!kld_off_address_symbol || !kld_off_next_symbol ||
710 !kld_off_filename_symbol || !kld_off_pathname_symbol)
714 const int32_t kld_off_address =
m_process->ReadSignedIntegerFromMemory(
720 const int32_t kld_off_next =
m_process->ReadSignedIntegerFromMemory(
725 const int32_t kld_off_filename =
m_process->ReadSignedIntegerFromMemory(
732 const int32_t kld_off_pathname =
m_process->ReadSignedIntegerFromMemory(
741 char kld_filename[255];
742 char kld_pathname[255];
746 while (current_kld != 0) {
747 llvm::Expected<lldb::addr_t> kld_filename_addr =
748 m_process->ReadPointerFromMemory(current_kld + kld_off_filename);
749 if (!kld_filename_addr) {
750 llvm::consumeError(kld_filename_addr.takeError());
753 llvm::Expected<lldb::addr_t> kld_pathname_addr =
754 m_process->ReadPointerFromMemory(current_kld + kld_off_pathname);
755 if (!kld_pathname_addr) {
756 llvm::consumeError(kld_pathname_addr.takeError());
760 m_process->ReadCStringFromMemory(*kld_filename_addr, kld_filename,
761 sizeof(kld_filename),
error);
764 m_process->ReadCStringFromMemory(*kld_pathname_addr, kld_pathname,
765 sizeof(kld_pathname),
error);
768 llvm::Expected<lldb::addr_t> kld_load_addr_or_err =
769 m_process->ReadPointerFromMemory(current_kld + kld_off_address);
770 if (!kld_load_addr_or_err) {
771 llvm::consumeError(kld_load_addr_or_err.takeError());
774 kld_load_addr = *kld_load_addr_or_err;
776 kmods_list.emplace_back();
778 kmod_info.
SetName(kld_filename);
780 kmod_info.
SetPath(kld_pathname);
782 llvm::Expected<lldb::addr_t> next_kld =
783 m_process->ReadPointerFromMemory(current_kld + kld_off_next);
785 if (kmod_info.
GetName() ==
"kernel")
786 kmods_list.pop_back();
789 llvm::consumeError(next_kld.takeError());
792 current_kld = *next_kld;
813 LLDB_LOGF(log,
"DynamicLoaderFreeBSDKernel::LoadKernelModules "
814 "Start loading Kernel Module");
825 llvm::StringRef kernel_name(
"freebsd_kernel");
827 if (module_sp.get() && module_sp->GetObjectFile() &&
828 !module_sp->GetObjectFile()->GetFileSpec().GetFilename().empty())
829 kernel_name = module_sp->GetObjectFile()->GetFileSpec().GetFilename();
851 static ConstString modlist_symbol_name(
"linker_files");
861 LLDB_LOGF(log,
"DynamicLoaderFreeBSDKernel::LoadKernelModules "
862 "cannot file modlist symbol");
901 LLDB_LOGF(log,
"DynamicLoaderFreeBSDKernel::GetStepThroughTrampolinePlan is "
902 "not yet implemented.");
static llvm::raw_ostream & error(Stream &strm)
static bool is_kernel(Module *module)
static bool is_reloc(Module *module)
static bool set_debug_file(const ModuleSP &module, llvm::StringRef target_path)
static bool is_kernel(Module *module)
static bool is_kmod(Module *module)
#define LLDB_LOGF(log,...)
#define LLDB_LOG_ERROR(log, error,...)
#define LLDB_PLUGIN_DEFINE(PluginName)
bool LoadImageUsingFileAddress(lldb_private::Process *process)
lldb::addr_t m_load_address
std::string GetName() const
bool ReadMemoryModule(lldb_private::Process *process)
void SetLoadAddress(lldb::addr_t load_address)
bool LoadImageUsingMemoryModule(lldb_private::Process *process)
void SetPath(const char *path)
std::string GetPath() const
lldb::ModuleSP m_module_sp
lldb::ModuleSP m_memory_module_sp
lldb_private::UUID m_uuid
std::vector< KModImageInfo > collection_type
void SetName(const char *name)
void DidAttach() override
Called after attaching a process.
DynamicLoaderFreeBSDKernel(lldb_private::Process *process, lldb::addr_t kernel_addr)
KModImageInfo::collection_type m_linker_files_list
static llvm::StringRef GetPluginNameStatic()
bool ReadKmodsListHeader()
lldb_private::Address m_linker_file_list_struct_addr
lldb_private::Process * m_process
void PrivateInitialize(lldb_private::Process *process)
lldb_private::Address m_linker_file_head_addr
lldb::ThreadPlanSP GetStepThroughTrampolinePlan(lldb_private::Thread &thread, bool stop_others) override
Provides a plan to step through the dynamic loader trampoline for the current state of thread.
bool ParseKmods(lldb_private::Address linker_files_head_address)
static void DebuggerInit(lldb_private::Debugger &debugger)
void SetNotificationBreakPoint()
static lldb::addr_t FindFreeBSDKernel(lldb_private::Process *process)
void Clear(bool clear_process)
lldb_private::Status CanLoadImage() override
Ask if it is ok to try and load or unload an shared library (image).
~DynamicLoaderFreeBSDKernel() override
std::unordered_map< std::string, lldb_private::UUID > m_kld_name_to_uuid
void DidLaunch() override
Called after launching a process.
lldb::addr_t m_kernel_load_address
static lldb::addr_t FindKernelAtLoadAddress(lldb_private::Process *process)
KModImageInfo m_kernel_image_info
static llvm::StringRef GetPluginDescriptionStatic()
static lldb_private::UUID CheckForKernelImageAtAddress(lldb_private::Process *process, lldb::addr_t address, bool *read_error=nullptr)
static lldb_private::DynamicLoader * CreateInstance(lldb_private::Process *process, bool force)
static bool ReadELFHeader(lldb_private::Process *process, lldb::addr_t address, llvm::ELF::Elf32_Ehdr &header, bool *read_error=nullptr)
std::recursive_mutex m_mutex
A section + offset based address class.
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
lldb::addr_t GetFileAddress() const
Get the file address.
bool IsValid() const
Check if the object state is valid.
An architecture specification class.
llvm::Triple & GetTriple()
Architecture triple accessor.
bool IsCompatibleMatch(const ArchSpec &rhs) const
Shorthand for IsMatch(rhs, CompatibleMatch).
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
A uniqued constant string class.
A class to manage flag bits.
lldb::StreamUP GetAsyncOutputStream()
A plug-in interface definition class for dynamic loaders.
void LoadOperatingSystemPlugin(bool flush)
DynamicLoader(Process *process)
Construct with a process.
bool IsAbsolute() const
Returns true if the filespec represents an absolute path.
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
static FileSystem & Instance()
A collection class for Module objects.
bool AppendIfNeeded(const lldb::ModuleSP &new_module, bool notify=true)
Append a module to the module list, if it is not already there.
lldb::ModuleSP FindModule(const Module *module_ptr) const
ModuleIterable Modules() const
A class that describes an executable image and its associated object and symbol files.
virtual ObjectFile * GetObjectFile()
Get the object file representation for the current architecture.
const ArchSpec & GetArchitecture() const
Get const accessor for the module architecture.
A plug-in interface definition class for object file parsers.
@ eTypeExecutable
A normal executable.
@ eTypeObjectFile
An intermediate object file.
@ eTypeSharedLibrary
A shared library that can be used during execution.
virtual SectionList * GetSectionList(bool update_module_section_list=true)
Gets the section list for the currently selected architecture (and object for archives).
virtual lldb_private::Address GetBaseAddress()
Returns base address of this object file.
static bool DownloadObjectAndSymbolFile(ModuleSpec &module_spec, Status &error, bool force_lookup=true, bool copy_executable=true)
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
A plug-in interface definition class for debugging a process.
virtual size_t ReadMemory(const ProcessAddress &process_addr, void *buf, size_t size, Status &error)
Read of memory from a process.
llvm::Expected< lldb::ModuleSP > ReadModuleFromMemory(const FileSpec &file_spec, lldb::addr_t header_addr, size_t size_to_read=512)
Creates and populates a module using an in-memory object file.
virtual lldb::addr_t GetImageInfoAddress()
Get the image information address for the current process.
void SetCanRunCode(bool can_run_code)
Sets whether executing code in this process is possible.
uint32_t GetStopID() const
Target & GetTarget()
Get the target object pointer for this module.
lldb::SectionSP FindSectionByName(llvm::StringRef section_name) const
lldb::SectionSP GetSectionAtIndex(size_t idx) const
lldb::addr_t GetFileAddress() const
static Status FromErrorString(const char *str)
Address GetAddress() const
Module * GetExecutableModulePointer()
Debugger & GetDebugger() const
lldb::ModuleSP GetOrCreateModule(const ModuleSpec &module_spec, bool notify, Status *error_ptr=nullptr)
Find a binary on the system and return its Module, or return an existing Module that is already in th...
bool SetArchitecture(const ArchSpec &arch_spec, bool set_platform=false, bool merge=true)
Set the architecture for this target.
const ModuleList & GetImages() const
Get accessor for the images for this process.
const ArchSpec & GetArchitecture() const
bool SetSectionLoadAddress(const lldb::SectionSP §ion, lldb::addr_t load_addr, bool warn_multiple=false)
Represents UUID's of various sizes.
#define LLDB_INVALID_ADDRESS
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
std::shared_ptr< lldb_private::ThreadPlan > ThreadPlanSP
std::shared_ptr< lldb_private::Section > SectionSP
std::unique_ptr< lldb_private::Stream > StreamUP
std::shared_ptr< lldb_private::Module > ModuleSP