172 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLDB_SOURCE_PLUGINS_DYNAMICLOADER_FREEBSD_KERNEL_DYNAMICLOADERFREEBSDKERNEL_H10#define LLDB_SOURCE_PLUGINS_DYNAMICLOADER_FREEBSD_KERNEL_DYNAMICLOADERFREEBSDKERNEL_H11 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 22class DynamicLoaderFreeBSDKernel : public lldb_private::DynamicLoader {23public:24 DynamicLoaderFreeBSDKernel(lldb_private::Process *process,25 lldb::addr_t kernel_addr);26 27 ~DynamicLoaderFreeBSDKernel() override;28 29 // Static Functions30 31 static void Initialize();32 33 static void Terminate();34 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 proccess47 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 56 llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }57 58protected:59 class KModImageInfo {60 public:61 KModImageInfo()62 : m_module_sp(), m_memory_module_sp(), m_uuid(), m_name(), m_path() {}63 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 74 void SetLoadAddress(lldb::addr_t load_address) {75 m_load_address = load_address;76 }77 78 lldb::addr_t GetLoadAddress() const { return m_load_address; }79 80 void SetUUID(const lldb_private::UUID uuid) { m_uuid = uuid; }81 82 lldb_private::UUID GetUUID() const { return m_uuid; }83 84 void SetName(const char *name) { m_name = name; }85 86 std::string GetName() const { return m_name; }87 88 void SetPath(const char *path) { m_path = path; }89 90 std::string GetPath() const { return m_path; }91 92 void SetModule(lldb::ModuleSP module) { m_module_sp = module; }93 94 lldb::ModuleSP GetModule() { return m_module_sp; }95 96 void SetIsKernel(bool is_kernel) { m_is_kernel = is_kernel; }97 98 bool IsKernel() const { return m_is_kernel; };99 100 void SetStopID(uint32_t stop_id) { m_stop_id = stop_id; }101 102 uint32_t GetStopID() { return m_stop_id; }103 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::UUID145 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 164private:165 DynamicLoaderFreeBSDKernel(const DynamicLoaderFreeBSDKernel &) = delete;166 167 const DynamicLoaderFreeBSDKernel &168 operator=(const DynamicLoaderFreeBSDKernel &) = delete;169};170 171#endif172