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
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 Functions
30
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 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
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::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
164private:
165 DynamicLoaderFreeBSDKernel(const DynamicLoaderFreeBSDKernel &) = delete;
166
167 const DynamicLoaderFreeBSDKernel &
168 operator=(const DynamicLoaderFreeBSDKernel &) = delete;
169};
170
171#endif
172

source code of lldb/source/Plugins/DynamicLoader/FreeBSD-Kernel/DynamicLoaderFreeBSDKernel.h