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