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