| //===-- 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 <mutex> | |
| #include <string> | |
| #include <vector> | |
| #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<KModImageInfo>; | |
| 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<std::string, lldb_private::UUID> m_kld_name_to_uuid; | |
| private: | |
| DynamicLoaderFreeBSDKernel(const DynamicLoaderFreeBSDKernel &) = delete; | |
| const DynamicLoaderFreeBSDKernel & | |
| operator=(const DynamicLoaderFreeBSDKernel &) = delete; | |
| }; | |
| #endif |