blob: aff03b5d1d01a063ccd52c1bd0748fab06eecaa1 [file] [log] [blame]
Greg Clayton944b8282011-08-22 22:30:57 +00001//===-- DynamicLoaderDarwinKernel.h -----------------------------*- C++ -*-===//
Greg Clayton7b242382011-07-08 00:48:09 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Greg Clayton944b8282011-08-22 22:30:57 +000010#ifndef liblldb_DynamicLoaderDarwinKernel_h_
11#define liblldb_DynamicLoaderDarwinKernel_h_
Greg Clayton7b242382011-07-08 00:48:09 +000012
13// C Includes
14// C++ Includes
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000015#include <mutex>
Greg Clayton7b242382011-07-08 00:48:09 +000016#include <string>
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000017#include <vector>
Greg Clayton7b242382011-07-08 00:48:09 +000018
19// Other libraries and framework includes
Eugene Zelenko4c3f2b92015-10-21 01:03:30 +000020// Project includes
Zachary Turner0e1d52a2017-03-04 01:28:55 +000021#include "lldb/Utility/UUID.h"
Greg Clayton7b242382011-07-08 00:48:09 +000022#include "lldb/Host/FileSpec.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000023#include "lldb/Target/DynamicLoader.h"
Greg Clayton7b242382011-07-08 00:48:09 +000024#include "lldb/Target/Process.h"
25
Kate Stoneb9c1b512016-09-06 20:57:50 +000026class DynamicLoaderDarwinKernel : public lldb_private::DynamicLoader {
Greg Clayton7b242382011-07-08 00:48:09 +000027public:
Kate Stoneb9c1b512016-09-06 20:57:50 +000028 DynamicLoaderDarwinKernel(lldb_private::Process *process,
29 lldb::addr_t kernel_addr);
Eugene Zelenko4c3f2b92015-10-21 01:03:30 +000030
Kate Stoneb9c1b512016-09-06 20:57:50 +000031 ~DynamicLoaderDarwinKernel() override;
Eugene Zelenko4c3f2b92015-10-21 01:03:30 +000032
Kate Stoneb9c1b512016-09-06 20:57:50 +000033 //------------------------------------------------------------------
34 // Static Functions
35 //------------------------------------------------------------------
36 static void Initialize();
Greg Clayton7b242382011-07-08 00:48:09 +000037
Kate Stoneb9c1b512016-09-06 20:57:50 +000038 static void Terminate();
Greg Clayton7b242382011-07-08 00:48:09 +000039
Kate Stoneb9c1b512016-09-06 20:57:50 +000040 static lldb_private::ConstString GetPluginNameStatic();
Greg Clayton7b242382011-07-08 00:48:09 +000041
Kate Stoneb9c1b512016-09-06 20:57:50 +000042 static const char *GetPluginDescriptionStatic();
Greg Clayton7b242382011-07-08 00:48:09 +000043
Kate Stoneb9c1b512016-09-06 20:57:50 +000044 static lldb_private::DynamicLoader *
45 CreateInstance(lldb_private::Process *process, bool force);
Greg Clayton7b242382011-07-08 00:48:09 +000046
Kate Stoneb9c1b512016-09-06 20:57:50 +000047 static void DebuggerInitialize(lldb_private::Debugger &debugger);
Greg Claytone8cd0c92012-10-19 18:02:49 +000048
Kate Stoneb9c1b512016-09-06 20:57:50 +000049 static lldb::addr_t SearchForDarwinKernel(lldb_private::Process *process);
Jason Molenda880988a2016-02-06 04:55:26 +000050
Kate Stoneb9c1b512016-09-06 20:57:50 +000051 //------------------------------------------------------------------
52 /// Called after attaching a process.
53 ///
54 /// Allow DynamicLoader plug-ins to execute some code after
55 /// attaching to a process.
56 //------------------------------------------------------------------
57 void DidAttach() override;
Greg Clayton7b242382011-07-08 00:48:09 +000058
Kate Stoneb9c1b512016-09-06 20:57:50 +000059 void DidLaunch() override;
Greg Clayton7b242382011-07-08 00:48:09 +000060
Kate Stoneb9c1b512016-09-06 20:57:50 +000061 lldb::ThreadPlanSP GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
62 bool stop_others) override;
Greg Clayton7b242382011-07-08 00:48:09 +000063
Kate Stoneb9c1b512016-09-06 20:57:50 +000064 lldb_private::Error CanLoadImage() override;
Greg Clayton7b242382011-07-08 00:48:09 +000065
Kate Stoneb9c1b512016-09-06 20:57:50 +000066 //------------------------------------------------------------------
67 // PluginInterface protocol
68 //------------------------------------------------------------------
69 lldb_private::ConstString GetPluginName() override;
Greg Clayton7b242382011-07-08 00:48:09 +000070
Kate Stoneb9c1b512016-09-06 20:57:50 +000071 uint32_t GetPluginVersion() override;
Greg Clayton7b242382011-07-08 00:48:09 +000072
73protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +000074 void PrivateInitialize(lldb_private::Process *process);
Greg Clayton7b242382011-07-08 00:48:09 +000075
Kate Stoneb9c1b512016-09-06 20:57:50 +000076 void PrivateProcessStateChanged(lldb_private::Process *process,
77 lldb::StateType state);
Jason Molenda306bd0a2013-02-19 05:42:46 +000078
Kate Stoneb9c1b512016-09-06 20:57:50 +000079 void UpdateIfNeeded();
Greg Clayton7b242382011-07-08 00:48:09 +000080
Kate Stoneb9c1b512016-09-06 20:57:50 +000081 void LoadKernelModuleIfNeeded();
Greg Clayton7b242382011-07-08 00:48:09 +000082
Kate Stoneb9c1b512016-09-06 20:57:50 +000083 void Clear(bool clear_process);
Greg Clayton7b242382011-07-08 00:48:09 +000084
Kate Stoneb9c1b512016-09-06 20:57:50 +000085 void PutToLog(lldb_private::Log *log) const;
Greg Clayton7b242382011-07-08 00:48:09 +000086
Kate Stoneb9c1b512016-09-06 20:57:50 +000087 static bool
88 BreakpointHitCallback(void *baton,
89 lldb_private::StoppointCallbackContext *context,
90 lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
Greg Clayton7b242382011-07-08 00:48:09 +000091
Kate Stoneb9c1b512016-09-06 20:57:50 +000092 bool BreakpointHit(lldb_private::StoppointCallbackContext *context,
93 lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
94 uint32_t GetAddrByteSize() { return m_kernel.GetAddressByteSize(); }
95
96 static lldb::ByteOrder GetByteOrderFromMagic(uint32_t magic);
97
98 enum {
99 KERNEL_MODULE_MAX_NAME = 64u,
100 // Versions less than 2 didn't have an entry size,
101 // they had a 64 bit name, 16 byte UUID, 8 byte addr,
102 // 8 byte size, 8 byte version, 4 byte load tag, and
103 // 4 byte flags
104 KERNEL_MODULE_ENTRY_SIZE_VERSION_1 = 64u + 16u + 8u + 8u + 8u + 4u + 4u
105 };
106
107 // class KextImageInfo represents a single kext or kernel binary image.
108 // The class was designed to hold the information from the
109 // OSKextLoadedKextSummary
110 // structure (in libkern/libkern/OSKextLibPrivate.h from xnu). The kernel
111 // maintains
112 // a list of loded kexts in memory (the OSKextLoadedKextSummaryHeader
113 // structure,
114 // which points to an array of OSKextLoadedKextSummary's).
115 //
116 // A KextImageInfos may have -
117 //
118 // 1. The load address, name, UUID, and size of a kext/kernel binary in memory
119 // (read straight out of the kernel's list-of-kexts loaded)
120 // 2. A ModuleSP based on a MemoryModule read out of the kernel's memory
121 // (very unlikely to have any symbolic information)
122 // 3. A ModuleSP for an on-disk copy of the kext binary, possibly with debug
123 // info
124 // or a dSYM
125 //
126 // For performance reasons, the developer may prefer that lldb not load the
127 // kexts out
128 // of memory at the start of a kernel session. But we should build up /
129 // maintain a
130 // list of kexts that the kernel has told us about so we can relocate a kext
131 // module
132 // later if the user explicitly adds it to the target.
133
134 class KextImageInfo {
135 public:
136 KextImageInfo()
137 : m_name(), m_module_sp(), m_memory_module_sp(),
138 m_load_process_stop_id(UINT32_MAX), m_uuid(),
139 m_load_address(LLDB_INVALID_ADDRESS), m_size(0),
140 m_kernel_image(false) {}
141
142 void Clear() {
143 m_load_address = LLDB_INVALID_ADDRESS;
144 m_size = 0;
145 m_name.clear();
146 m_uuid.Clear();
147 m_module_sp.reset();
148 m_memory_module_sp.reset();
149 m_load_process_stop_id = UINT32_MAX;
Greg Clayton7b242382011-07-08 00:48:09 +0000150 }
151
Kate Stoneb9c1b512016-09-06 20:57:50 +0000152 bool LoadImageAtFileAddress(lldb_private::Process *process);
Greg Clayton7b242382011-07-08 00:48:09 +0000153
Kate Stoneb9c1b512016-09-06 20:57:50 +0000154 bool LoadImageUsingMemoryModule(lldb_private::Process *process);
Greg Clayton7b242382011-07-08 00:48:09 +0000155
Kate Stoneb9c1b512016-09-06 20:57:50 +0000156 bool IsLoaded() { return m_load_process_stop_id != UINT32_MAX; }
Jason Molenda306bd0a2013-02-19 05:42:46 +0000157
Kate Stoneb9c1b512016-09-06 20:57:50 +0000158 void SetLoadAddress(
159 lldb::addr_t load_addr); // Address of the Mach-O header for this binary
Greg Clayton7b242382011-07-08 00:48:09 +0000160
Kate Stoneb9c1b512016-09-06 20:57:50 +0000161 lldb::addr_t
162 GetLoadAddress() const; // Address of the Mach-O header for this binary
Greg Clayton7b242382011-07-08 00:48:09 +0000163
Kate Stoneb9c1b512016-09-06 20:57:50 +0000164 lldb_private::UUID GetUUID() const;
Greg Clayton02c322c2012-03-21 22:50:54 +0000165
Kate Stoneb9c1b512016-09-06 20:57:50 +0000166 void SetUUID(const lldb_private::UUID &uuid);
Jason Molenda306bd0a2013-02-19 05:42:46 +0000167
Kate Stoneb9c1b512016-09-06 20:57:50 +0000168 void SetName(const char *);
Greg Clayton7b242382011-07-08 00:48:09 +0000169
Kate Stoneb9c1b512016-09-06 20:57:50 +0000170 std::string GetName() const;
Jason Molenda306bd0a2013-02-19 05:42:46 +0000171
Kate Stoneb9c1b512016-09-06 20:57:50 +0000172 void SetModule(lldb::ModuleSP module);
Jason Molenda306bd0a2013-02-19 05:42:46 +0000173
Kate Stoneb9c1b512016-09-06 20:57:50 +0000174 lldb::ModuleSP GetModule();
Jason Molenda306bd0a2013-02-19 05:42:46 +0000175
Kate Stoneb9c1b512016-09-06 20:57:50 +0000176 // try to fill in m_memory_module_sp from memory based on the m_load_address
177 bool ReadMemoryModule(lldb_private::Process *process);
Jason Molenda306bd0a2013-02-19 05:42:46 +0000178
Kate Stoneb9c1b512016-09-06 20:57:50 +0000179 bool IsKernel()
180 const; // true if this is the mach_kernel; false if this is a kext
Jason Molenda306bd0a2013-02-19 05:42:46 +0000181
Kate Stoneb9c1b512016-09-06 20:57:50 +0000182 void SetIsKernel(bool is_kernel);
Jason Molenda306bd0a2013-02-19 05:42:46 +0000183
Kate Stoneb9c1b512016-09-06 20:57:50 +0000184 uint64_t GetSize() const;
Jason Molenda306bd0a2013-02-19 05:42:46 +0000185
Kate Stoneb9c1b512016-09-06 20:57:50 +0000186 void SetSize(uint64_t size);
Greg Clayton7b242382011-07-08 00:48:09 +0000187
Greg Clayton7b242382011-07-08 00:48:09 +0000188 uint32_t
Kate Stoneb9c1b512016-09-06 20:57:50 +0000189 GetProcessStopId() const; // the stop-id when this binary was first noticed
Jason Molenda306bd0a2013-02-19 05:42:46 +0000190
Kate Stoneb9c1b512016-09-06 20:57:50 +0000191 void SetProcessStopId(uint32_t stop_id);
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000192
Kate Stoneb9c1b512016-09-06 20:57:50 +0000193 bool operator==(const KextImageInfo &rhs);
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000194
Kate Stoneb9c1b512016-09-06 20:57:50 +0000195 uint32_t GetAddressByteSize(); // as determined by Mach-O header
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000196
Kate Stoneb9c1b512016-09-06 20:57:50 +0000197 lldb::ByteOrder GetByteOrder(); // as determined by Mach-O header
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000198
Kate Stoneb9c1b512016-09-06 20:57:50 +0000199 lldb_private::ArchSpec
200 GetArchitecture() const; // as determined by Mach-O header
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000201
Kate Stoneb9c1b512016-09-06 20:57:50 +0000202 void PutToLog(lldb_private::Log *log) const;
Jason Molenda306bd0a2013-02-19 05:42:46 +0000203
Kate Stoneb9c1b512016-09-06 20:57:50 +0000204 typedef std::vector<KextImageInfo> collection;
205 typedef collection::iterator iterator;
206 typedef collection::const_iterator const_iterator;
207
208 private:
209 std::string m_name;
210 lldb::ModuleSP m_module_sp;
211 lldb::ModuleSP m_memory_module_sp;
212 uint32_t m_load_process_stop_id; // the stop-id when this module was added
213 // to the Target
214 lldb_private::UUID
215 m_uuid; // UUID for this dylib if it has one, else all zeros
216 lldb::addr_t m_load_address;
217 uint64_t m_size;
218 bool m_kernel_image; // true if this is the kernel, false if this is a kext
219 };
220
221 struct OSKextLoadedKextSummaryHeader {
222 uint32_t version;
223 uint32_t entry_size;
224 uint32_t entry_count;
225 lldb::addr_t image_infos_addr;
226
227 OSKextLoadedKextSummaryHeader()
228 : version(0), entry_size(0), entry_count(0),
229 image_infos_addr(LLDB_INVALID_ADDRESS) {}
230
231 uint32_t GetSize() {
232 switch (version) {
233 case 0:
234 return 0; // Can't know the size without a valid version
235 case 1:
236 return 8; // Version 1 only had a version + entry_count
237 default:
238 break;
239 }
240 // Version 2 and above has version, entry_size, entry_count, and reserved
241 return 16;
242 }
243
244 void Clear() {
245 version = 0;
246 entry_size = 0;
247 entry_count = 0;
248 image_infos_addr = LLDB_INVALID_ADDRESS;
249 }
250
251 bool IsValid() const { return version >= 1 || version <= 2; }
252 };
253
254 void RegisterNotificationCallbacks();
255
256 void UnregisterNotificationCallbacks();
257
258 void SetNotificationBreakpointIfNeeded();
259
260 bool ReadAllKextSummaries();
261
262 bool ReadKextSummaryHeader();
263
264 bool ParseKextSummaries(const lldb_private::Address &kext_summary_addr,
265 uint32_t count);
266
267 void
268 UpdateImageInfosHeaderAndLoadCommands(KextImageInfo::collection &image_infos,
269 uint32_t infos_count,
270 bool update_executable);
271
272 uint32_t ReadKextSummaries(const lldb_private::Address &kext_summary_addr,
273 uint32_t image_infos_count,
274 KextImageInfo::collection &image_infos);
275
276 static lldb::addr_t
277 SearchForKernelAtSameLoadAddr(lldb_private::Process *process);
278
279 static lldb::addr_t
280 SearchForKernelWithDebugHints(lldb_private::Process *process);
281
282 static lldb::addr_t SearchForKernelNearPC(lldb_private::Process *process);
283
284 static lldb::addr_t
285 SearchForKernelViaExhaustiveSearch(lldb_private::Process *process);
286
287 static lldb_private::UUID
288 CheckForKernelImageAtAddress(lldb::addr_t addr,
289 lldb_private::Process *process);
290
291 lldb::addr_t m_kernel_load_address;
292 KextImageInfo m_kernel; // Info about the current kernel image being used
293
294 lldb_private::Address m_kext_summary_header_ptr_addr;
295 lldb_private::Address m_kext_summary_header_addr;
296 OSKextLoadedKextSummaryHeader m_kext_summary_header;
297 KextImageInfo::collection m_known_kexts;
298 mutable std::recursive_mutex m_mutex;
299 lldb::user_id_t m_break_id;
Greg Clayton7b242382011-07-08 00:48:09 +0000300
301private:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000302 DISALLOW_COPY_AND_ASSIGN(DynamicLoaderDarwinKernel);
Greg Clayton7b242382011-07-08 00:48:09 +0000303};
304
Eugene Zelenko4c3f2b92015-10-21 01:03:30 +0000305#endif // liblldb_DynamicLoaderDarwinKernel_h_