blob: 2e1f6b879f930471be5c88ba79286077ff921cd6 [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
15#include <map>
16#include <vector>
17#include <string>
18
19// Other libraries and framework includes
Jim Ingham46d005d2014-04-02 22:53:21 +000020
Greg Clayton7b242382011-07-08 00:48:09 +000021#include "lldb/Target/DynamicLoader.h"
22#include "lldb/Host/FileSpec.h"
23#include "lldb/Host/TimeValue.h"
24#include "lldb/Core/UUID.h"
25#include "lldb/Host/Mutex.h"
26#include "lldb/Target/Process.h"
27
Greg Clayton944b8282011-08-22 22:30:57 +000028class DynamicLoaderDarwinKernel : public lldb_private::DynamicLoader
Greg Clayton7b242382011-07-08 00:48:09 +000029{
30public:
31 //------------------------------------------------------------------
32 // Static Functions
33 //------------------------------------------------------------------
34 static void
35 Initialize();
36
37 static void
38 Terminate();
39
Greg Clayton57abc5d2013-05-10 21:47:16 +000040 static lldb_private::ConstString
Greg Clayton7b242382011-07-08 00:48:09 +000041 GetPluginNameStatic();
42
43 static const char *
44 GetPluginDescriptionStatic();
45
46 static lldb_private::DynamicLoader *
47 CreateInstance (lldb_private::Process *process, bool force);
48
Greg Claytone8cd0c92012-10-19 18:02:49 +000049 static void
50 DebuggerInitialize (lldb_private::Debugger &debugger);
51
Jason Molenda6ba6d3d2013-01-30 04:39:32 +000052 DynamicLoaderDarwinKernel (lldb_private::Process *process, lldb::addr_t kernel_addr);
Greg Clayton7b242382011-07-08 00:48:09 +000053
54 virtual
Greg Clayton944b8282011-08-22 22:30:57 +000055 ~DynamicLoaderDarwinKernel ();
Jason Molenda306bd0a2013-02-19 05:42:46 +000056
Greg Clayton7b242382011-07-08 00:48:09 +000057 //------------------------------------------------------------------
58 /// Called after attaching a process.
59 ///
60 /// Allow DynamicLoader plug-ins to execute some code after
61 /// attaching to a process.
62 //------------------------------------------------------------------
63 virtual void
64 DidAttach ();
65
66 virtual void
67 DidLaunch ();
68
69 virtual lldb::ThreadPlanSP
70 GetStepThroughTrampolinePlan (lldb_private::Thread &thread,
71 bool stop_others);
72
73 virtual lldb_private::Error
74 CanLoadImage ();
75
76 //------------------------------------------------------------------
77 // PluginInterface protocol
78 //------------------------------------------------------------------
Greg Clayton57abc5d2013-05-10 21:47:16 +000079 virtual lldb_private::ConstString
Greg Clayton7b242382011-07-08 00:48:09 +000080 GetPluginName();
81
Greg Clayton7b242382011-07-08 00:48:09 +000082 virtual uint32_t
83 GetPluginVersion();
84
85protected:
86 void
87 PrivateInitialize (lldb_private::Process *process);
88
89 void
90 PrivateProcessStateChanged (lldb_private::Process *process,
91 lldb::StateType state);
Jason Molenda306bd0a2013-02-19 05:42:46 +000092
Greg Clayton374972e2011-07-09 17:15:55 +000093 void
94 UpdateIfNeeded();
Greg Clayton7b242382011-07-08 00:48:09 +000095
Greg Clayton374972e2011-07-09 17:15:55 +000096 void
97 LoadKernelModuleIfNeeded ();
Greg Clayton7b242382011-07-08 00:48:09 +000098
99 void
100 Clear (bool clear_process);
101
102 void
103 PutToLog (lldb_private::Log *log) const;
104
105 static bool
Greg Clayton374972e2011-07-09 17:15:55 +0000106 BreakpointHitCallback (void *baton,
107 lldb_private::StoppointCallbackContext *context,
108 lldb::user_id_t break_id,
109 lldb::user_id_t break_loc_id);
Greg Clayton7b242382011-07-08 00:48:09 +0000110
Greg Clayton374972e2011-07-09 17:15:55 +0000111 bool
Jason Molenda306bd0a2013-02-19 05:42:46 +0000112 BreakpointHit (lldb_private::StoppointCallbackContext *context,
113 lldb::user_id_t break_id,
Greg Clayton374972e2011-07-09 17:15:55 +0000114 lldb::user_id_t break_loc_id);
Greg Clayton7b242382011-07-08 00:48:09 +0000115 uint32_t
Greg Claytonc859e2d2012-02-13 23:10:39 +0000116 GetAddrByteSize()
Greg Clayton7b242382011-07-08 00:48:09 +0000117 {
Greg Claytonc859e2d2012-02-13 23:10:39 +0000118 return m_kernel.GetAddressByteSize();
Greg Clayton7b242382011-07-08 00:48:09 +0000119 }
120
121 static lldb::ByteOrder
Greg Clayton1f746072012-08-29 21:13:06 +0000122 GetByteOrderFromMagic (uint32_t magic);
Greg Clayton7b242382011-07-08 00:48:09 +0000123
Greg Claytona63d08c2011-07-19 03:57:15 +0000124 enum
125 {
126 KERNEL_MODULE_MAX_NAME = 64u,
127 // Versions less than 2 didn't have an entry size,
128 // they had a 64 bit name, 16 byte UUID, 8 byte addr,
129 // 8 byte size, 8 byte version, 4 byte load tag, and
130 // 4 byte flags
131 KERNEL_MODULE_ENTRY_SIZE_VERSION_1 = 64u + 16u + 8u + 8u + 8u + 4u + 4u
132 };
Greg Clayton7b242382011-07-08 00:48:09 +0000133
Jason Molenda306bd0a2013-02-19 05:42:46 +0000134 // class KextImageInfo represents a single kext or kernel binary image.
135 // The class was designed to hold the information from the OSKextLoadedKextSummary
136 // structure (in libkern/libkern/OSKextLibPrivate.h from xnu). The kernel maintains
137 // a list of loded kexts in memory (the OSKextLoadedKextSummaryHeader structure,
138 // which points to an array of OSKextLoadedKextSummary's).
139 //
140 // A KextImageInfos may have -
141 //
142 // 1. The load address, name, UUID, and size of a kext/kernel binary in memory
143 // (read straight out of the kernel's list-of-kexts loaded)
144 // 2. A ModuleSP based on a MemoryModule read out of the kernel's memory
145 // (very unlikely to have any symbolic information)
146 // 3. A ModuleSP for an on-disk copy of the kext binary, possibly with debug info
147 // or a dSYM
148 //
149 // For performance reasons, the developer may prefer that lldb not load the kexts out
150 // of memory at the start of a kernel session. But we should build up / maintain a
151 // list of kexts that the kernel has told us about so we can relocate a kext module
152 // later if the user explicitly adds it to the target.
153
154 class KextImageInfo
155 {
156 public:
157 KextImageInfo () :
158 m_name (),
159 m_module_sp (),
160 m_memory_module_sp (),
161 m_load_process_stop_id (UINT32_MAX),
162 m_uuid (),
163 m_load_address (LLDB_INVALID_ADDRESS),
164 m_size (0),
165 m_kernel_image (false)
166 { }
Greg Clayton7b242382011-07-08 00:48:09 +0000167
168 void
Jason Molenda306bd0a2013-02-19 05:42:46 +0000169 Clear ()
Greg Clayton7b242382011-07-08 00:48:09 +0000170 {
Jason Molenda306bd0a2013-02-19 05:42:46 +0000171 m_load_address = LLDB_INVALID_ADDRESS;
172 m_size = 0;
173 m_name.clear ();
174 m_uuid.Clear();
175 m_module_sp.reset();
176 m_memory_module_sp.reset();
177 m_load_process_stop_id = UINT32_MAX;
Greg Clayton7b242382011-07-08 00:48:09 +0000178 }
179
180 bool
Greg Clayton02c322c2012-03-21 22:50:54 +0000181 LoadImageAtFileAddress (lldb_private::Process *process);
182
183 bool
Greg Claytonc859e2d2012-02-13 23:10:39 +0000184 LoadImageUsingMemoryModule (lldb_private::Process *process);
Jason Molenda306bd0a2013-02-19 05:42:46 +0000185
Greg Clayton7b242382011-07-08 00:48:09 +0000186 bool
Jason Molenda306bd0a2013-02-19 05:42:46 +0000187 IsLoaded ()
Greg Clayton7b242382011-07-08 00:48:09 +0000188 {
Jason Molenda306bd0a2013-02-19 05:42:46 +0000189 return m_load_process_stop_id != UINT32_MAX;
Greg Clayton7b242382011-07-08 00:48:09 +0000190 }
191
Jason Molenda306bd0a2013-02-19 05:42:46 +0000192 void
193 SetLoadAddress (lldb::addr_t load_addr); // Address of the Mach-O header for this binary
194
195 lldb::addr_t
196 GetLoadAddress () const; // Address of the Mach-O header for this binary
197
198 lldb_private::UUID
199 GetUUID () const;
200
201 void
202 SetUUID (const lldb_private::UUID &uuid);
203
204 void
205 SetName (const char *);
206
207 std::string
208 GetName () const;
209
210 void
211 SetModule (lldb::ModuleSP module);
212
213 lldb::ModuleSP
214 GetModule ();
215
216 // try to fill in m_memory_module_sp from memory based on the m_load_address
217 bool
218 ReadMemoryModule (lldb_private::Process *process);
219
220 bool
221 IsKernel () const; // true if this is the mach_kernel; false if this is a kext
222
223 void
224 SetIsKernel (bool is_kernel);
225
226 uint64_t
227 GetSize () const;
228
229 void
230 SetSize (uint64_t size);
231
Greg Clayton7b242382011-07-08 00:48:09 +0000232 uint32_t
Jason Molenda306bd0a2013-02-19 05:42:46 +0000233 GetProcessStopId () const; // the stop-id when this binary was first noticed
234
235 void
236 SetProcessStopId (uint32_t stop_id);
237
238 bool
239 operator== (const KextImageInfo &rhs);
240
241 uint32_t
242 GetAddressByteSize (); // as determined by Mach-O header
Greg Clayton7b242382011-07-08 00:48:09 +0000243
244 lldb::ByteOrder
Jason Molenda306bd0a2013-02-19 05:42:46 +0000245 GetByteOrder(); // as determined by Mach-O header
Greg Clayton7b242382011-07-08 00:48:09 +0000246
247 lldb_private::ArchSpec
Jason Molenda306bd0a2013-02-19 05:42:46 +0000248 GetArchitecture () const; // as determined by Mach-O header
Greg Clayton7b242382011-07-08 00:48:09 +0000249
Greg Clayton7b242382011-07-08 00:48:09 +0000250 void
251 PutToLog (lldb_private::Log *log) const;
252
Jason Molenda306bd0a2013-02-19 05:42:46 +0000253 typedef std::vector<KextImageInfo> collection;
Greg Clayton7b242382011-07-08 00:48:09 +0000254 typedef collection::iterator iterator;
255 typedef collection::const_iterator const_iterator;
Jason Molenda306bd0a2013-02-19 05:42:46 +0000256
257 private:
258 std::string m_name;
259 lldb::ModuleSP m_module_sp;
260 lldb::ModuleSP m_memory_module_sp;
261 uint32_t m_load_process_stop_id; // the stop-id when this module was added to the Target
262 lldb_private::UUID m_uuid; // UUID for this dylib if it has one, else all zeros
263 lldb::addr_t m_load_address;
264 uint64_t m_size;
265 bool m_kernel_image; // true if this is the kernel, false if this is a kext
266
Greg Clayton7b242382011-07-08 00:48:09 +0000267 };
268
269 struct OSKextLoadedKextSummaryHeader
270 {
271 uint32_t version;
272 uint32_t entry_size;
273 uint32_t entry_count;
Greg Clayton7b242382011-07-08 00:48:09 +0000274 lldb::addr_t image_infos_addr;
275
276 OSKextLoadedKextSummaryHeader() :
277 version (0),
278 entry_size (0),
279 entry_count (0),
Greg Clayton7b242382011-07-08 00:48:09 +0000280 image_infos_addr (LLDB_INVALID_ADDRESS)
281 {
282 }
283
Greg Claytona63d08c2011-07-19 03:57:15 +0000284 uint32_t
285 GetSize()
286 {
287 switch (version)
288 {
289 case 0: return 0; // Can't know the size without a valid version
290 case 1: return 8; // Version 1 only had a version + entry_count
291 default: break;
292 }
293 // Version 2 and above has version, entry_size, entry_count, and reserved
Jason Molenda306bd0a2013-02-19 05:42:46 +0000294 return 16;
Greg Claytona63d08c2011-07-19 03:57:15 +0000295 }
296
Greg Clayton7b242382011-07-08 00:48:09 +0000297 void
298 Clear()
299 {
300 version = 0;
301 entry_size = 0;
302 entry_count = 0;
Greg Clayton7b242382011-07-08 00:48:09 +0000303 image_infos_addr = LLDB_INVALID_ADDRESS;
304 }
305
306 bool
307 IsValid() const
308 {
309 return version >= 1 || version <= 2;
310 }
311 };
312
313 void
314 RegisterNotificationCallbacks();
315
316 void
317 UnregisterNotificationCallbacks();
318
Greg Clayton374972e2011-07-09 17:15:55 +0000319 void
320 SetNotificationBreakpointIfNeeded ();
Greg Clayton7b242382011-07-08 00:48:09 +0000321
322 bool
Greg Clayton374972e2011-07-09 17:15:55 +0000323 ReadAllKextSummaries ();
Greg Clayton7b242382011-07-08 00:48:09 +0000324
325 bool
326 ReadKextSummaryHeader ();
Jason Molenda306bd0a2013-02-19 05:42:46 +0000327
Greg Clayton7b242382011-07-08 00:48:09 +0000328 bool
Jason Molenda306bd0a2013-02-19 05:42:46 +0000329 ParseKextSummaries (const lldb_private::Address &kext_summary_addr,
Greg Clayton0d9fc762011-07-08 03:21:57 +0000330 uint32_t count);
Jason Molenda306bd0a2013-02-19 05:42:46 +0000331
Greg Clayton7b242382011-07-08 00:48:09 +0000332 void
Jason Molenda306bd0a2013-02-19 05:42:46 +0000333 UpdateImageInfosHeaderAndLoadCommands(KextImageInfo::collection &image_infos,
334 uint32_t infos_count,
Greg Clayton7b242382011-07-08 00:48:09 +0000335 bool update_executable);
336
Greg Clayton7b242382011-07-08 00:48:09 +0000337 uint32_t
Greg Clayton0d9fc762011-07-08 03:21:57 +0000338 ReadKextSummaries (const lldb_private::Address &kext_summary_addr,
Jason Molenda306bd0a2013-02-19 05:42:46 +0000339 uint32_t image_infos_count,
340 KextImageInfo::collection &image_infos);
341
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000342 static lldb::addr_t
Greg Claytona1b5dd92013-05-22 21:00:49 +0000343 SearchForDarwinKernel (lldb_private::Process *process);
344
345 static lldb::addr_t
Jason Molenda6ba6d3d2013-01-30 04:39:32 +0000346 SearchForKernelAtSameLoadAddr (lldb_private::Process *process);
347
348 static lldb::addr_t
349 SearchForKernelWithDebugHints (lldb_private::Process *process);
350
351 static lldb::addr_t
352 SearchForKernelNearPC (lldb_private::Process *process);
353
354 static lldb::addr_t
355 SearchForKernelViaExhaustiveSearch (lldb_private::Process *process);
356
357 static lldb_private::UUID
358 CheckForKernelImageAtAddress (lldb::addr_t addr, lldb_private::Process *process);
359
Jason Molenda306bd0a2013-02-19 05:42:46 +0000360 lldb::addr_t m_kernel_load_address;
361 KextImageInfo m_kernel; // Info about the current kernel image being used
362
363 lldb_private::Address m_kext_summary_header_ptr_addr;
364 lldb_private::Address m_kext_summary_header_addr;
365 OSKextLoadedKextSummaryHeader m_kext_summary_header;
366 KextImageInfo::collection m_known_kexts;
367 mutable lldb_private::Mutex m_mutex;
368 lldb::user_id_t m_break_id;
Greg Clayton7b242382011-07-08 00:48:09 +0000369
370private:
Greg Clayton944b8282011-08-22 22:30:57 +0000371 DISALLOW_COPY_AND_ASSIGN (DynamicLoaderDarwinKernel);
Greg Clayton7b242382011-07-08 00:48:09 +0000372};
373
Greg Clayton944b8282011-08-22 22:30:57 +0000374#endif // liblldb_DynamicLoaderDarwinKernel_h_