blob: 9a6f90f7984c7039e1579e5b85f14d9ab4393575 [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;
Greg Clayton7b242382011-07-08 00:48:09 +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;
Greg Clayton7b242382011-07-08 00:48:09 +0000147
148 OSKextLoadedKextSummary() :
149 module_sp (),
Greg Claytonc859e2d2012-02-13 23:10:39 +0000150 load_process_stop_id (UINT32_MAX),
Greg Clayton7b242382011-07-08 00:48:09 +0000151 uuid (),
Greg Clayton0d9fc762011-07-08 03:21:57 +0000152 so_address (),
Greg Clayton7b242382011-07-08 00:48:09 +0000153 address (LLDB_INVALID_ADDRESS),
154 size (0),
155 version (0),
156 load_tag (0),
157 flags (0),
Greg Claytonc859e2d2012-02-13 23:10:39 +0000158 reference_list (0)
Greg Clayton7b242382011-07-08 00:48:09 +0000159 {
160 name[0] = '\0';
161 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000162
163 bool
164 IsLoaded ()
165 {
166 return load_process_stop_id != UINT32_MAX;
167 }
Greg Clayton7b242382011-07-08 00:48:09 +0000168
169 void
170 Clear (bool load_cmd_data_only)
171 {
172 if (!load_cmd_data_only)
173 {
Greg Clayton0d9fc762011-07-08 03:21:57 +0000174 so_address.Clear();
Greg Clayton7b242382011-07-08 00:48:09 +0000175 address = LLDB_INVALID_ADDRESS;
176 size = 0;
177 version = 0;
178 load_tag = 0;
179 flags = 0;
180 reference_list = 0;
181 name[0] = '\0';
Greg Clayton7b242382011-07-08 00:48:09 +0000182 }
183 module_sp.reset();
Greg Claytonc859e2d2012-02-13 23:10:39 +0000184 load_process_stop_id = UINT32_MAX;
Greg Clayton7b242382011-07-08 00:48:09 +0000185 }
186
187 bool
Greg Clayton02c322c2012-03-21 22:50:54 +0000188 LoadImageAtFileAddress (lldb_private::Process *process);
189
190 bool
Greg Claytonc859e2d2012-02-13 23:10:39 +0000191 LoadImageUsingMemoryModule (lldb_private::Process *process);
192
193// bool
194// operator == (const OSKextLoadedKextSummary& rhs) const
195// {
196// return address == rhs.address
197// && size == rhs.size
198// //&& module_sp.get() == rhs.module_sp.get()
199// && uuid == rhs.uuid
200// && version == rhs.version
201// && load_tag == rhs.load_tag
202// && flags == rhs.flags
203// && reference_list == rhs.reference_list
204// && strncmp (name, rhs.name, KERNEL_MODULE_MAX_NAME) == 0;
205// }
206//
Greg Clayton7b242382011-07-08 00:48:09 +0000207 bool
208 UUIDValid() const
209 {
210 return uuid.IsValid();
211 }
212
213 uint32_t
Greg Clayton1f746072012-08-29 21:13:06 +0000214 GetAddressByteSize ();
Greg Clayton7b242382011-07-08 00:48:09 +0000215
216 lldb::ByteOrder
Greg Clayton1f746072012-08-29 21:13:06 +0000217 GetByteOrder();
Greg Clayton7b242382011-07-08 00:48:09 +0000218
219 lldb_private::ArchSpec
Greg Clayton1f746072012-08-29 21:13:06 +0000220 GetArchitecture () const;
Greg Clayton7b242382011-07-08 00:48:09 +0000221
Greg Clayton7b242382011-07-08 00:48:09 +0000222 void
223 PutToLog (lldb_private::Log *log) const;
224
225 typedef std::vector<OSKextLoadedKextSummary> collection;
226 typedef collection::iterator iterator;
227 typedef collection::const_iterator const_iterator;
228 };
229
230 struct OSKextLoadedKextSummaryHeader
231 {
232 uint32_t version;
233 uint32_t entry_size;
234 uint32_t entry_count;
Greg Clayton7b242382011-07-08 00:48:09 +0000235 lldb::addr_t image_infos_addr;
236
237 OSKextLoadedKextSummaryHeader() :
238 version (0),
239 entry_size (0),
240 entry_count (0),
Greg Clayton7b242382011-07-08 00:48:09 +0000241 image_infos_addr (LLDB_INVALID_ADDRESS)
242 {
243 }
244
Greg Claytona63d08c2011-07-19 03:57:15 +0000245 uint32_t
246 GetSize()
247 {
248 switch (version)
249 {
250 case 0: return 0; // Can't know the size without a valid version
251 case 1: return 8; // Version 1 only had a version + entry_count
252 default: break;
253 }
254 // Version 2 and above has version, entry_size, entry_count, and reserved
255 return 16;
256 }
257
Greg Clayton7b242382011-07-08 00:48:09 +0000258 void
259 Clear()
260 {
261 version = 0;
262 entry_size = 0;
263 entry_count = 0;
Greg Clayton7b242382011-07-08 00:48:09 +0000264 image_infos_addr = LLDB_INVALID_ADDRESS;
265 }
266
267 bool
268 IsValid() const
269 {
270 return version >= 1 || version <= 2;
271 }
272 };
273
274 void
275 RegisterNotificationCallbacks();
276
277 void
278 UnregisterNotificationCallbacks();
279
Greg Clayton374972e2011-07-09 17:15:55 +0000280 void
281 SetNotificationBreakpointIfNeeded ();
Greg Clayton7b242382011-07-08 00:48:09 +0000282
283 bool
Greg Clayton374972e2011-07-09 17:15:55 +0000284 ReadAllKextSummaries ();
Greg Clayton7b242382011-07-08 00:48:09 +0000285
286 bool
287 ReadKextSummaryHeader ();
288
289 bool
Greg Clayton0d9fc762011-07-08 03:21:57 +0000290 ParseKextSummaries (const lldb_private::Address &kext_summary_addr,
291 uint32_t count);
Greg Clayton7b242382011-07-08 00:48:09 +0000292
293 bool
294 AddModulesUsingImageInfos (OSKextLoadedKextSummary::collection &image_infos);
295
Greg Clayton7b242382011-07-08 00:48:09 +0000296 void
297 UpdateImageInfosHeaderAndLoadCommands(OSKextLoadedKextSummary::collection &image_infos,
298 uint32_t infos_count,
299 bool update_executable);
300
Greg Clayton7b242382011-07-08 00:48:09 +0000301 uint32_t
Greg Clayton0d9fc762011-07-08 03:21:57 +0000302 ReadKextSummaries (const lldb_private::Address &kext_summary_addr,
Greg Clayton7b242382011-07-08 00:48:09 +0000303 uint32_t image_infos_count,
304 OSKextLoadedKextSummary::collection &image_infos);
305
Greg Clayton7b242382011-07-08 00:48:09 +0000306 OSKextLoadedKextSummary m_kernel; // Info about the current kernel image being used
Greg Claytond16e1e52011-07-12 17:06:17 +0000307 lldb_private::Address m_kext_summary_header_ptr_addr;
Greg Clayton0d9fc762011-07-08 03:21:57 +0000308 lldb_private::Address m_kext_summary_header_addr;
Greg Clayton7b242382011-07-08 00:48:09 +0000309 OSKextLoadedKextSummaryHeader m_kext_summary_header;
Greg Clayton7b242382011-07-08 00:48:09 +0000310 OSKextLoadedKextSummary::collection m_kext_summaries;
Greg Clayton7b242382011-07-08 00:48:09 +0000311 mutable lldb_private::Mutex m_mutex;
Greg Clayton374972e2011-07-09 17:15:55 +0000312 lldb::user_id_t m_break_id;
Greg Clayton7b242382011-07-08 00:48:09 +0000313
314private:
Greg Clayton944b8282011-08-22 22:30:57 +0000315 DISALLOW_COPY_AND_ASSIGN (DynamicLoaderDarwinKernel);
Greg Clayton7b242382011-07-08 00:48:09 +0000316};
317
Greg Clayton944b8282011-08-22 22:30:57 +0000318#endif // liblldb_DynamicLoaderDarwinKernel_h_