blob: 9e2229f2647b9a308147ee934f8bd1cdce952d1e [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
20#include "llvm/Support/MachO.h"
21
22#include "lldb/Target/DynamicLoader.h"
23#include "lldb/Host/FileSpec.h"
24#include "lldb/Host/TimeValue.h"
25#include "lldb/Core/UUID.h"
26#include "lldb/Host/Mutex.h"
27#include "lldb/Target/Process.h"
28
Greg Clayton944b8282011-08-22 22:30:57 +000029class DynamicLoaderDarwinKernel : public lldb_private::DynamicLoader
Greg Clayton7b242382011-07-08 00:48:09 +000030{
31public:
32 //------------------------------------------------------------------
33 // Static Functions
34 //------------------------------------------------------------------
35 static void
36 Initialize();
37
38 static void
39 Terminate();
40
41 static const char *
42 GetPluginNameStatic();
43
44 static const char *
45 GetPluginDescriptionStatic();
46
47 static lldb_private::DynamicLoader *
48 CreateInstance (lldb_private::Process *process, bool force);
49
Greg Clayton944b8282011-08-22 22:30:57 +000050 DynamicLoaderDarwinKernel (lldb_private::Process *process);
Greg Clayton7b242382011-07-08 00:48:09 +000051
52 virtual
Greg Clayton944b8282011-08-22 22:30:57 +000053 ~DynamicLoaderDarwinKernel ();
Greg Clayton7b242382011-07-08 00:48:09 +000054 //------------------------------------------------------------------
55 /// Called after attaching a process.
56 ///
57 /// Allow DynamicLoader plug-ins to execute some code after
58 /// attaching to a process.
59 //------------------------------------------------------------------
60 virtual void
61 DidAttach ();
62
63 virtual void
64 DidLaunch ();
65
66 virtual lldb::ThreadPlanSP
67 GetStepThroughTrampolinePlan (lldb_private::Thread &thread,
68 bool stop_others);
69
70 virtual lldb_private::Error
71 CanLoadImage ();
72
73 //------------------------------------------------------------------
74 // PluginInterface protocol
75 //------------------------------------------------------------------
76 virtual const char *
77 GetPluginName();
78
79 virtual const char *
80 GetShortPluginName();
81
82 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);
Greg Clayton374972e2011-07-09 17:15:55 +000092
93 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
112 BreakpointHit (lldb_private::StoppointCallbackContext *context,
113 lldb::user_id_t break_id,
114 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
134 struct OSKextLoadedKextSummary
135 {
136 char name[KERNEL_MODULE_MAX_NAME];
137 lldb::ModuleSP module_sp;
Greg Claytonc859e2d2012-02-13 23:10:39 +0000138 uint32_t load_process_stop_id;
Jason Molenda87a04b22012-10-19 03:40:45 +0000139 lldb_private::UUID uuid; // UUID for this dylib if it has one, else all zeros
Greg Clayton0d9fc762011-07-08 03:21:57 +0000140 lldb_private::Address so_address; // The section offset address for this kext in case it can be read from object files
Greg Clayton7b242382011-07-08 00:48:09 +0000141 uint64_t address;
142 uint64_t size;
143 uint64_t version;
144 uint32_t load_tag;
145 uint32_t flags;
146 uint64_t reference_list;
Jason Molenda87a04b22012-10-19 03:40:45 +0000147 bool kernel_image; // true if this is the kernel, false if this is a kext
Greg Clayton7b242382011-07-08 00:48:09 +0000148
149 OSKextLoadedKextSummary() :
150 module_sp (),
Greg Claytonc859e2d2012-02-13 23:10:39 +0000151 load_process_stop_id (UINT32_MAX),
Greg Clayton7b242382011-07-08 00:48:09 +0000152 uuid (),
Greg Clayton0d9fc762011-07-08 03:21:57 +0000153 so_address (),
Greg Clayton7b242382011-07-08 00:48:09 +0000154 address (LLDB_INVALID_ADDRESS),
155 size (0),
156 version (0),
157 load_tag (0),
158 flags (0),
Jason Molenda87a04b22012-10-19 03:40:45 +0000159 reference_list (0),
160 kernel_image (false)
Greg Clayton7b242382011-07-08 00:48:09 +0000161 {
162 name[0] = '\0';
163 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000164
165 bool
166 IsLoaded ()
167 {
168 return load_process_stop_id != UINT32_MAX;
169 }
Greg Clayton7b242382011-07-08 00:48:09 +0000170
171 void
172 Clear (bool load_cmd_data_only)
173 {
174 if (!load_cmd_data_only)
175 {
Greg Clayton0d9fc762011-07-08 03:21:57 +0000176 so_address.Clear();
Greg Clayton7b242382011-07-08 00:48:09 +0000177 address = LLDB_INVALID_ADDRESS;
178 size = 0;
179 version = 0;
180 load_tag = 0;
181 flags = 0;
182 reference_list = 0;
183 name[0] = '\0';
Greg Clayton7b242382011-07-08 00:48:09 +0000184 }
185 module_sp.reset();
Greg Claytonc859e2d2012-02-13 23:10:39 +0000186 load_process_stop_id = UINT32_MAX;
Greg Clayton7b242382011-07-08 00:48:09 +0000187 }
188
189 bool
Greg Clayton02c322c2012-03-21 22:50:54 +0000190 LoadImageAtFileAddress (lldb_private::Process *process);
191
192 bool
Greg Claytonc859e2d2012-02-13 23:10:39 +0000193 LoadImageUsingMemoryModule (lldb_private::Process *process);
194
195// bool
196// operator == (const OSKextLoadedKextSummary& rhs) const
197// {
198// return address == rhs.address
199// && size == rhs.size
200// //&& module_sp.get() == rhs.module_sp.get()
201// && uuid == rhs.uuid
202// && version == rhs.version
203// && load_tag == rhs.load_tag
204// && flags == rhs.flags
205// && reference_list == rhs.reference_list
206// && strncmp (name, rhs.name, KERNEL_MODULE_MAX_NAME) == 0;
207// }
208//
Greg Clayton7b242382011-07-08 00:48:09 +0000209 bool
210 UUIDValid() const
211 {
212 return uuid.IsValid();
213 }
214
215 uint32_t
Greg Clayton1f746072012-08-29 21:13:06 +0000216 GetAddressByteSize ();
Greg Clayton7b242382011-07-08 00:48:09 +0000217
218 lldb::ByteOrder
Greg Clayton1f746072012-08-29 21:13:06 +0000219 GetByteOrder();
Greg Clayton7b242382011-07-08 00:48:09 +0000220
221 lldb_private::ArchSpec
Greg Clayton1f746072012-08-29 21:13:06 +0000222 GetArchitecture () const;
Greg Clayton7b242382011-07-08 00:48:09 +0000223
Greg Clayton7b242382011-07-08 00:48:09 +0000224 void
225 PutToLog (lldb_private::Log *log) const;
226
227 typedef std::vector<OSKextLoadedKextSummary> collection;
228 typedef collection::iterator iterator;
229 typedef collection::const_iterator const_iterator;
230 };
231
232 struct OSKextLoadedKextSummaryHeader
233 {
234 uint32_t version;
235 uint32_t entry_size;
236 uint32_t entry_count;
Greg Clayton7b242382011-07-08 00:48:09 +0000237 lldb::addr_t image_infos_addr;
238
239 OSKextLoadedKextSummaryHeader() :
240 version (0),
241 entry_size (0),
242 entry_count (0),
Greg Clayton7b242382011-07-08 00:48:09 +0000243 image_infos_addr (LLDB_INVALID_ADDRESS)
244 {
245 }
246
Greg Claytona63d08c2011-07-19 03:57:15 +0000247 uint32_t
248 GetSize()
249 {
250 switch (version)
251 {
252 case 0: return 0; // Can't know the size without a valid version
253 case 1: return 8; // Version 1 only had a version + entry_count
254 default: break;
255 }
256 // Version 2 and above has version, entry_size, entry_count, and reserved
257 return 16;
258 }
259
Greg Clayton7b242382011-07-08 00:48:09 +0000260 void
261 Clear()
262 {
263 version = 0;
264 entry_size = 0;
265 entry_count = 0;
Greg Clayton7b242382011-07-08 00:48:09 +0000266 image_infos_addr = LLDB_INVALID_ADDRESS;
267 }
268
269 bool
270 IsValid() const
271 {
272 return version >= 1 || version <= 2;
273 }
274 };
275
276 void
277 RegisterNotificationCallbacks();
278
279 void
280 UnregisterNotificationCallbacks();
281
Greg Clayton374972e2011-07-09 17:15:55 +0000282 void
283 SetNotificationBreakpointIfNeeded ();
Greg Clayton7b242382011-07-08 00:48:09 +0000284
285 bool
Greg Clayton374972e2011-07-09 17:15:55 +0000286 ReadAllKextSummaries ();
Greg Clayton7b242382011-07-08 00:48:09 +0000287
288 bool
289 ReadKextSummaryHeader ();
290
291 bool
Greg Clayton0d9fc762011-07-08 03:21:57 +0000292 ParseKextSummaries (const lldb_private::Address &kext_summary_addr,
293 uint32_t count);
Greg Clayton7b242382011-07-08 00:48:09 +0000294
295 bool
296 AddModulesUsingImageInfos (OSKextLoadedKextSummary::collection &image_infos);
297
Greg Clayton7b242382011-07-08 00:48:09 +0000298 void
299 UpdateImageInfosHeaderAndLoadCommands(OSKextLoadedKextSummary::collection &image_infos,
300 uint32_t infos_count,
301 bool update_executable);
302
Greg Clayton7b242382011-07-08 00:48:09 +0000303 uint32_t
Greg Clayton0d9fc762011-07-08 03:21:57 +0000304 ReadKextSummaries (const lldb_private::Address &kext_summary_addr,
Greg Clayton7b242382011-07-08 00:48:09 +0000305 uint32_t image_infos_count,
306 OSKextLoadedKextSummary::collection &image_infos);
307
Greg Clayton7b242382011-07-08 00:48:09 +0000308 OSKextLoadedKextSummary m_kernel; // Info about the current kernel image being used
Greg Claytond16e1e52011-07-12 17:06:17 +0000309 lldb_private::Address m_kext_summary_header_ptr_addr;
Greg Clayton0d9fc762011-07-08 03:21:57 +0000310 lldb_private::Address m_kext_summary_header_addr;
Greg Clayton7b242382011-07-08 00:48:09 +0000311 OSKextLoadedKextSummaryHeader m_kext_summary_header;
Greg Clayton7b242382011-07-08 00:48:09 +0000312 OSKextLoadedKextSummary::collection m_kext_summaries;
Greg Clayton7b242382011-07-08 00:48:09 +0000313 mutable lldb_private::Mutex m_mutex;
Greg Clayton374972e2011-07-09 17:15:55 +0000314 lldb::user_id_t m_break_id;
Greg Clayton7b242382011-07-08 00:48:09 +0000315
316private:
Greg Clayton944b8282011-08-22 22:30:57 +0000317 DISALLOW_COPY_AND_ASSIGN (DynamicLoaderDarwinKernel);
Greg Clayton7b242382011-07-08 00:48:09 +0000318};
319
Greg Clayton944b8282011-08-22 22:30:57 +0000320#endif // liblldb_DynamicLoaderDarwinKernel_h_