1 //===-- DynamicLoaderFreeBSDKernel.h -----------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLDB_SOURCE_PLUGINS_DYNAMICLOADER_FREEBSD_KERNEL_DYNAMICLOADERFREEBSDKERNEL_H 10 #define LLDB_SOURCE_PLUGINS_DYNAMICLOADER_FREEBSD_KERNEL_DYNAMICLOADERFREEBSDKERNEL_H 11 12 #include <mutex> 13 #include <string> 14 #include <vector> 15 16 #include "lldb/Target/DynamicLoader.h" 17 #include "lldb/Target/Process.h" 18 #include "lldb/Utility/FileSpec.h" 19 #include "lldb/Utility/UUID.h" 20 #include "llvm/BinaryFormat/ELF.h" 21 22 class DynamicLoaderFreeBSDKernel : public lldb_private::DynamicLoader { 23 public: 24 DynamicLoaderFreeBSDKernel(lldb_private::Process *process, 25 lldb::addr_t kernel_addr); 26 27 ~DynamicLoaderFreeBSDKernel() override; 28 29 // Static Functions 30 31 static void Initialize(); 32 33 static void Terminate(); 34 GetPluginNameStatic()35 static llvm::StringRef GetPluginNameStatic() { return "freebsd-kernel"; } 36 37 static llvm::StringRef GetPluginDescriptionStatic(); 38 39 static lldb_private::DynamicLoader * 40 CreateInstance(lldb_private::Process *process, bool force); 41 42 static void DebuggerInit(lldb_private::Debugger &debugger); 43 44 static lldb::addr_t FindFreeBSDKernel(lldb_private::Process *process); 45 46 // Hooks for time point that after attach to some proccess 47 void DidAttach() override; 48 49 void DidLaunch() override; 50 51 lldb::ThreadPlanSP GetStepThroughTrampolinePlan(lldb_private::Thread &thread, 52 bool stop_others) override; 53 54 lldb_private::Status CanLoadImage() override; 55 GetPluginName()56 llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } 57 58 protected: 59 class KModImageInfo { 60 public: KModImageInfo()61 KModImageInfo() 62 : m_module_sp(), m_memory_module_sp(), m_uuid(), m_name(), m_path() {} 63 Clear()64 void Clear() { 65 m_load_address = LLDB_INVALID_ADDRESS; 66 m_name.clear(); 67 m_uuid.Clear(); 68 m_module_sp.reset(); 69 m_memory_module_sp.reset(); 70 m_stop_id = UINT32_MAX; 71 m_path.clear(); 72 } 73 SetLoadAddress(lldb::addr_t load_address)74 void SetLoadAddress(lldb::addr_t load_address) { 75 m_load_address = load_address; 76 } 77 GetLoadAddress()78 lldb::addr_t GetLoadAddress() const { return m_load_address; } 79 SetUUID(const lldb_private::UUID uuid)80 void SetUUID(const lldb_private::UUID uuid) { m_uuid = uuid; } 81 GetUUID()82 lldb_private::UUID GetUUID() const { return m_uuid; } 83 SetName(const char * name)84 void SetName(const char *name) { m_name = name; } 85 GetName()86 std::string GetName() const { return m_name; } 87 SetPath(const char * path)88 void SetPath(const char *path) { m_path = path; } 89 GetPath()90 std::string GetPath() const { return m_path; } 91 SetModule(lldb::ModuleSP module)92 void SetModule(lldb::ModuleSP module) { m_module_sp = module; } 93 GetModule()94 lldb::ModuleSP GetModule() { return m_module_sp; } 95 SetIsKernel(bool is_kernel)96 void SetIsKernel(bool is_kernel) { m_is_kernel = is_kernel; } 97 IsKernel()98 bool IsKernel() const { return m_is_kernel; }; 99 SetStopID(uint32_t stop_id)100 void SetStopID(uint32_t stop_id) { m_stop_id = stop_id; } 101 GetStopID()102 uint32_t GetStopID() { return m_stop_id; } 103 IsLoaded()104 bool IsLoaded() const { return m_stop_id != UINT32_MAX; }; 105 106 bool ReadMemoryModule(lldb_private::Process *process); 107 108 bool LoadImageUsingMemoryModule(lldb_private::Process *process); 109 110 bool LoadImageUsingFileAddress(lldb_private::Process *process); 111 112 using collection_type = std::vector<KModImageInfo>; 113 114 private: 115 lldb::ModuleSP m_module_sp; 116 lldb::ModuleSP m_memory_module_sp; 117 lldb::addr_t m_load_address = LLDB_INVALID_ADDRESS; 118 lldb_private::UUID m_uuid; 119 bool m_is_kernel = false; 120 std::string m_name; 121 std::string m_path; 122 uint32_t m_stop_id = UINT32_MAX; 123 }; 124 125 void PrivateInitialize(lldb_private::Process *process); 126 127 void Clear(bool clear_process); 128 129 void Update(); 130 131 void LoadKernelModules(); 132 133 void ReadAllKmods(); 134 135 bool ReadAllKmods(lldb_private::Address linker_files_head_address, 136 KModImageInfo::collection_type &kmods_list); 137 138 bool ReadKmodsListHeader(); 139 140 bool ParseKmods(lldb_private::Address linker_files_head_address); 141 142 void SetNotificationBreakPoint(); 143 144 static lldb_private::UUID 145 CheckForKernelImageAtAddress(lldb_private::Process *process, 146 lldb::addr_t address, 147 bool *read_error = nullptr); 148 149 static lldb::addr_t FindKernelAtLoadAddress(lldb_private::Process *process); 150 151 static bool ReadELFHeader(lldb_private::Process *process, 152 lldb::addr_t address, llvm::ELF::Elf32_Ehdr &header, 153 bool *read_error = nullptr); 154 155 lldb_private::Process *m_process; 156 lldb_private::Address m_linker_file_list_struct_addr; 157 lldb_private::Address m_linker_file_head_addr; 158 lldb::addr_t m_kernel_load_address; 159 KModImageInfo m_kernel_image_info; 160 KModImageInfo::collection_type m_linker_files_list; 161 std::recursive_mutex m_mutex; 162 std::unordered_map<std::string, lldb_private::UUID> m_kld_name_to_uuid; 163 164 private: 165 DynamicLoaderFreeBSDKernel(const DynamicLoaderFreeBSDKernel &) = delete; 166 167 const DynamicLoaderFreeBSDKernel & 168 operator=(const DynamicLoaderFreeBSDKernel &) = delete; 169 }; 170 171 #endif 172