31#include "llvm/Support/Error.h"
55 return "The Dynamic Loader Plugin For FreeBSD Kernel";
111 const llvm::Triple &triple_ref =
113 if (!triple_ref.isOSFreeBSD()) {
160 llvm::ELF::Elf32_Ehdr &header,
174 if (!header.checkMagic())
192 "DynamicLoaderFreeBSDKernel::CheckForKernelImageAtAddress: "
193 "looking for kernel binary at 0x%" PRIx64,
196 llvm::ELF::Elf32_Ehdr header;
203 if (header.e_type != llvm::ELF::ET_EXEC)
206 llvm::Expected<ModuleSP> memory_module_sp_or_err =
208 if (
auto err = memory_module_sp_or_err.takeError()) {
210 "DynamicLoaderFreeBSDKernel::CheckForKernelImageAtAddress: "
211 "Failed to read module in memory -- {0}");
216 ModuleSP memory_module_sp = *memory_module_sp_or_err;
217 if (!memory_module_sp.get()) {
222 ObjectFile *exe_objfile = memory_module_sp->GetObjectFile();
223 if (exe_objfile ==
nullptr) {
225 "DynamicLoaderFreeBSDKernel::CheckForKernelImageAtAddress "
226 "found a binary at 0x%" PRIx64
227 " but could not create an object file from memory",
235 ArchSpec kernel_arch(llvm::ELF::convertEMachineToArchName(header.e_machine));
240 std::string uuid_str;
241 if (memory_module_sp->GetUUID().IsValid()) {
242 uuid_str =
"with UUID ";
243 uuid_str += memory_module_sp->GetUUID().GetAsString();
245 uuid_str =
"and no LC_UUID found in load commands ";
248 "DynamicLoaderFreeBSDKernel::CheckForKernelImageAtAddress: "
249 "kernel binary image found at 0x%" PRIx64
" with arch '%s' %s",
250 addr, kernel_arch.
GetTriple().str().c_str(), uuid_str.c_str());
252 return memory_module_sp->GetUUID();
285 llvm::ELF::Elf32_Ehdr elf_eheader;
286 size_t size_to_read = 512;
289 if (elf_eheader.e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS32) {
290 size_to_read =
sizeof(llvm::ELF::Elf32_Ehdr) +
291 elf_eheader.e_phnum * elf_eheader.e_phentsize;
292 }
else if (elf_eheader.e_ident[llvm::ELF::EI_CLASS] ==
293 llvm::ELF::ELFCLASS64) {
294 llvm::ELF::Elf64_Ehdr elf_eheader;
297 error) ==
sizeof(elf_eheader) &&
299 size_to_read =
sizeof(llvm::ELF::Elf64_Ehdr) +
300 elf_eheader.e_phnum * elf_eheader.e_phentsize;
304 llvm::Expected<ModuleSP> memory_module_sp_or_err =
306 if (
auto err = memory_module_sp_or_err.takeError()) {
308 "KextImageInfo::ReadMemoryModule: Failed to read module "
309 "from memory -- {0}");
312 memory_module_sp = *memory_module_sp_or_err;
314 if (!memory_module_sp)
317 bool this_is_kernel =
is_kernel(memory_module_sp.get());
319 if (!
m_uuid.IsValid() && memory_module_sp->GetUUID().IsValid())
320 m_uuid = memory_module_sp->GetUUID();
326 if (this_is_kernel) {
327 LLDB_LOGF(log,
"KextImageInfo::ReadMemoryModule read the kernel binary out "
330 if (memory_module_sp->GetArchitecture().IsValid())
348 s->Printf(
"Kernel UUID: %s\n",
m_uuid.GetAsString().c_str());
377 "WARNING: Unable to locate kernel binary on the debugger "
387 if (existing_module_sp &&
388 existing_module_sp->IsLoadedInTarget(&target)) {
390 "'%s' with UUID %s is not a kmod or kernel, and is "
391 "already registered in target, not loading.",
409 bool changed =
false;
426 if (!ondisk_object_file || !memory_object_file)
431 if (llvm::dyn_cast<ObjectFileELF>(memory_object_file)) {
438 "kmod %s in-memory LOAD vmaddr is not correct, using a "
439 "fixed slide of 0x%" PRIx64,
440 m_name.c_str(), fixed_slide);
447 if (memory_section_list && ondisk_object_file) {
448 const uint32_t num_ondisk_sections = ondisk_section_list->
GetSize();
449 uint32_t num_load_sections = 0;
451 for (uint32_t section_idx = 0; section_idx < num_ondisk_sections;
456 if (!on_disk_section_sp)
460 on_disk_section_sp->GetFileAddress() +
464 const Section *memory_section =
468 if (memory_section) {
476 if (num_load_sections)
487 if (kernel_object_file) {
492 s->Printf(
"Kernel slide 0x%" PRIx64
" in memory.\n",
494 s->Printf(
"Loaded kernel file %s\n",
511 bool changed =
false;
525 llvm::Expected<lldb::addr_t> address =
m_process->ReadPointerFromMemory(
528 llvm::consumeError(address.takeError());
549 if (!
ReadAllKmods(linker_files_head_addr, linker_files_list))
553 "Kmod-changed breakpoint hit, there are %zu kernel modules currently.\n",
554 linker_files_list.size());
567 m_process->GetTarget().ModulesDidUnload(remove_modules,
false);
572 image_info.SetUUID(it->second);
573 bool failed_to_load =
false;
574 if (!image_info.LoadImageUsingMemoryModule(
m_process)) {
575 image_info.LoadImageUsingFileAddress(
m_process);
576 failed_to_load =
true;
585 m_process->GetTarget().ModulesDidLoad(add_modules);
591 Address linker_files_head_addr,
595 static ConstString kld_off_address_symbol_name(
"kld_off_address");
596 static ConstString kld_off_next_symbol_name(
"kld_off_next");
597 static ConstString kld_off_filename_symbol_name(
"kld_off_filename");
598 static ConstString kld_off_pathname_symbol_name(
"kld_off_pathname");
599 const Symbol *kld_off_address_symbol =
602 const Symbol *kld_off_next_symbol =
605 const Symbol *kld_off_filename_symbol =
608 const Symbol *kld_off_pathname_symbol =
612 if (!kld_off_address_symbol || !kld_off_next_symbol ||
613 !kld_off_filename_symbol || !kld_off_pathname_symbol)
617 const int32_t kld_off_address =
m_process->ReadSignedIntegerFromMemory(
623 const int32_t kld_off_next =
m_process->ReadSignedIntegerFromMemory(
628 const int32_t kld_off_filename =
m_process->ReadSignedIntegerFromMemory(
635 const int32_t kld_off_pathname =
m_process->ReadSignedIntegerFromMemory(
644 char kld_filename[255];
645 char kld_pathname[255];
649 while (current_kld != 0) {
650 llvm::Expected<lldb::addr_t> kld_filename_addr =
651 m_process->ReadPointerFromMemory(current_kld + kld_off_filename);
652 if (!kld_filename_addr) {
653 llvm::consumeError(kld_filename_addr.takeError());
656 llvm::Expected<lldb::addr_t> kld_pathname_addr =
657 m_process->ReadPointerFromMemory(current_kld + kld_off_pathname);
658 if (!kld_pathname_addr) {
659 llvm::consumeError(kld_pathname_addr.takeError());
663 m_process->ReadCStringFromMemory(*kld_filename_addr, kld_filename,
664 sizeof(kld_filename),
error);
667 m_process->ReadCStringFromMemory(*kld_pathname_addr, kld_pathname,
668 sizeof(kld_pathname),
error);
671 llvm::Expected<lldb::addr_t> kld_load_addr_or_err =
672 m_process->ReadPointerFromMemory(current_kld + kld_off_address);
673 if (!kld_load_addr_or_err) {
674 llvm::consumeError(kld_load_addr_or_err.takeError());
677 kld_load_addr = *kld_load_addr_or_err;
679 kmods_list.emplace_back();
681 kmod_info.
SetName(kld_filename);
683 kmod_info.
SetPath(kld_pathname);
685 llvm::Expected<lldb::addr_t> next_kld =
686 m_process->ReadPointerFromMemory(current_kld + kld_off_next);
688 if (kmod_info.
GetName() ==
"kernel")
689 kmods_list.pop_back();
692 llvm::consumeError(next_kld.takeError());
695 current_kld = *next_kld;
716 LLDB_LOGF(log,
"DynamicLoaderFreeBSDKernel::LoadKernelModules "
717 "Start loading Kernel Module");
728 llvm::StringRef kernel_name(
"freebsd_kernel");
730 if (module_sp.get() && module_sp->GetObjectFile() &&
731 !module_sp->GetObjectFile()->GetFileSpec().GetFilename().empty())
732 kernel_name = module_sp->GetObjectFile()->GetFileSpec().GetFilename();
754 static ConstString modlist_symbol_name(
"linker_files");
764 LLDB_LOGF(log,
"DynamicLoaderFreeBSDKernel::LoadKernelModules "
765 "cannot file modlist symbol");
804 LLDB_LOGF(log,
"DynamicLoaderFreeBSDKernel::GetStepThroughTrampolinePlan is "
805 "not yet implemented.");
static llvm::raw_ostream & error(Stream &strm)
static bool is_kernel(Module *module)
static bool is_reloc(Module *module)
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).
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.
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.
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