1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
|
//===-- 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
|