//===-- DynamicLoaderFreeBSDKernel.h -----------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLDB_SOURCE_PLUGINS_DYNAMICLOADER_FREEBSD_KERNEL_DYNAMICLOADERFREEBSDKERNEL_H #define LLDB_SOURCE_PLUGINS_DYNAMICLOADER_FREEBSD_KERNEL_DYNAMICLOADERFREEBSDKERNEL_H #include #include #include #include "lldb/Target/DynamicLoader.h" #include "lldb/Target/Process.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/UUID.h" #include "llvm/BinaryFormat/ELF.h" class DynamicLoaderFreeBSDKernel : public lldb_private::DynamicLoader { public: DynamicLoaderFreeBSDKernel(lldb_private::Process *process, lldb::addr_t kernel_addr); ~DynamicLoaderFreeBSDKernel() override; // Static Functions static void Initialize(); static void Terminate(); static llvm::StringRef GetPluginNameStatic() { return "freebsd-kernel"; } static llvm::StringRef GetPluginDescriptionStatic(); static lldb_private::DynamicLoader * CreateInstance(lldb_private::Process *process, bool force); static void DebuggerInit(lldb_private::Debugger &debugger); static lldb::addr_t FindFreeBSDKernel(lldb_private::Process *process); // Hooks for time point that after attach to some proccess void DidAttach() override; void DidLaunch() override; lldb::ThreadPlanSP GetStepThroughTrampolinePlan(lldb_private::Thread &thread, bool stop_others) override; lldb_private::Status CanLoadImage() override; llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } protected: class KModImageInfo { public: KModImageInfo() : m_module_sp(), m_memory_module_sp(), m_uuid(), m_name(), m_path() {} void Clear() { m_load_address = LLDB_INVALID_ADDRESS; m_name.clear(); m_uuid.Clear(); m_module_sp.reset(); m_memory_module_sp.reset(); m_stop_id = UINT32_MAX; m_path.clear(); } void SetLoadAddress(lldb::addr_t load_address) { m_load_address = load_address; } lldb::addr_t GetLoadAddress() const { return m_load_address; } void SetUUID(const lldb_private::UUID uuid) { m_uuid = uuid; } lldb_private::UUID GetUUID() const { return m_uuid; } void SetName(const char *name) { m_name = name; } std::string GetName() const { return m_name; } void SetPath(const char *path) { m_path = path; } std::string GetPath() const { return m_path; } void SetModule(lldb::ModuleSP module) { m_module_sp = module; } lldb::ModuleSP GetModule() { return m_module_sp; } void SetIsKernel(bool is_kernel) { m_is_kernel = is_kernel; } bool IsKernel() const { return m_is_kernel; }; void SetStopID(uint32_t stop_id) { m_stop_id = stop_id; } uint32_t GetStopID() { return m_stop_id; } bool IsLoaded() const { return m_stop_id != UINT32_MAX; }; bool ReadMemoryModule(lldb_private::Process *process); bool LoadImageUsingMemoryModule(lldb_private::Process *process); bool LoadImageUsingFileAddress(lldb_private::Process *process); using collection_type = std::vector; private: lldb::ModuleSP m_module_sp; lldb::ModuleSP m_memory_module_sp; lldb::addr_t m_load_address = LLDB_INVALID_ADDRESS; lldb_private::UUID m_uuid; bool m_is_kernel = false; std::string m_name; std::string m_path; uint32_t m_stop_id = UINT32_MAX; }; void PrivateInitialize(lldb_private::Process *process); void Clear(bool clear_process); void Update(); void LoadKernelModules(); void ReadAllKmods(); bool ReadAllKmods(lldb_private::Address linker_files_head_address, KModImageInfo::collection_type &kmods_list); bool ReadKmodsListHeader(); bool ParseKmods(lldb_private::Address linker_files_head_address); void SetNotificationBreakPoint(); static lldb_private::UUID CheckForKernelImageAtAddress(lldb_private::Process *process, lldb::addr_t address, bool *read_error = nullptr); static lldb::addr_t FindKernelAtLoadAddress(lldb_private::Process *process); static bool ReadELFHeader(lldb_private::Process *process, lldb::addr_t address, llvm::ELF::Elf32_Ehdr &header, bool *read_error = nullptr); lldb_private::Process *m_process; lldb_private::Address m_linker_file_list_struct_addr; lldb_private::Address m_linker_file_head_addr; lldb::addr_t m_kernel_load_address; KModImageInfo m_kernel_image_info; KModImageInfo::collection_type m_linker_files_list; std::recursive_mutex m_mutex; std::unordered_map m_kld_name_to_uuid; private: DynamicLoaderFreeBSDKernel(const DynamicLoaderFreeBSDKernel &) = delete; const DynamicLoaderFreeBSDKernel & operator=(const DynamicLoaderFreeBSDKernel &) = delete; }; #endif