blob: d8656e9c49dfe25ec5653dfe8cc63b6db80e52a2 [file] [log] [blame] [edit]
//===-- 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