blob: 44fb329e35e97997347bfc78c3c4ef6047d91037 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- DynamicLoaderMacOSXDYLD.h -------------------------------*- C++ -*-===//
2//
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
10#ifndef liblldb_DynamicLoaderMacOSXDYLD_h_
11#define liblldb_DynamicLoaderMacOSXDYLD_h_
12
13// C Includes
Chris Lattner24943d22010-06-08 16:52:24 +000014// C++ Includes
15#include <map>
16#include <vector>
17#include <string>
18
19// Other libraries and framework includes
Greg Clayton1674b122010-07-21 22:12:05 +000020#include "llvm/Support/MachO.h"
21
Chris Lattner24943d22010-06-08 16:52:24 +000022#include "lldb/Target/DynamicLoader.h"
23#include "lldb/Core/FileSpec.h"
24#include "lldb/Core/UUID.h"
25#include "lldb/Host/Mutex.h"
26#include "lldb/Target/Process.h"
Greg Clayton1674b122010-07-21 22:12:05 +000027
Chris Lattner24943d22010-06-08 16:52:24 +000028#include "ObjCTrampolineHandler.h"
29
30class DynamicLoaderMacOSXDYLD : public lldb_private::DynamicLoader
31{
32public:
33 //------------------------------------------------------------------
34 // Static Functions
35 //------------------------------------------------------------------
36 static void
37 Initialize();
38
39 static void
40 Terminate();
41
42 static const char *
43 GetPluginNameStatic();
44
45 static const char *
46 GetPluginDescriptionStatic();
47
48 static lldb_private::DynamicLoader *
49 CreateInstance (lldb_private::Process *process);
50
51 DynamicLoaderMacOSXDYLD (lldb_private::Process *process);
52
53 virtual
54 ~DynamicLoaderMacOSXDYLD ();
55 //------------------------------------------------------------------
56 /// Called after attaching a process.
57 ///
58 /// Allow DynamicLoader plug-ins to execute some code after
59 /// attaching to a process.
60 //------------------------------------------------------------------
61 virtual void
62 DidAttach ();
63
64 virtual void
65 DidLaunch ();
66
67 //------------------------------------------------------------------
68 // Process::Notifications callback functions
69 //------------------------------------------------------------------
70 static void
71 Initialize (void *baton,
72 lldb_private::Process *process);
73
74 static void
75 ProcessStateChanged (void *baton,
76 lldb_private::Process *process,
77 lldb::StateType state);
78
79 virtual lldb::ThreadPlanSP
80 GetStepThroughTrampolinePlan (lldb_private::Thread &thread,
81 bool stop_others);
82
83
84 //------------------------------------------------------------------
85 // PluginInterface protocol
86 //------------------------------------------------------------------
87 virtual const char *
88 GetPluginName();
89
90 virtual const char *
91 GetShortPluginName();
92
93 virtual uint32_t
94 GetPluginVersion();
95
96 virtual void
97 GetPluginCommandHelp (const char *command, lldb_private::Stream *strm);
98
99 virtual lldb_private::Error
100 ExecutePluginCommand (lldb_private::Args &command, lldb_private::Stream *strm);
101
102 virtual lldb_private::Log *
103 EnablePluginLogging (lldb_private::Stream *strm, lldb_private::Args &command);
104
105
106
107protected:
108 void
109 PrivateInitialize (lldb_private::Process *process);
110
111 void
112 PrivateProcessStateChanged (lldb_private::Process *process,
113 lldb::StateType state);
114 bool
115 LocateDYLD ();
116
117 bool
118 DidSetNotificationBreakpoint () const;
119
120 void
121 Clear (bool clear_process);
122
123 void
124 PutToLog (lldb_private::Log *log) const;
125
126 bool
127 ReadDYLDInfoFromMemoryAndSetNotificationCallback (lldb::addr_t addr);
128
129 uint32_t
130 UpdateAllImageInfos ();
131
132 static bool
133 NotifyBreakpointHit (void *baton,
134 lldb_private::StoppointCallbackContext *context,
135 lldb::user_id_t break_id,
136 lldb::user_id_t break_loc_id);
137 void
138 UpdateAllImageInfosHeaderAndLoadCommands ();
139
140 bool
141 UpdateCommPageLoadAddress (lldb_private::Module *module);
142
143 uint32_t
144 AddrByteSize()
145 {
146 switch (m_dyld.header.magic)
147 {
Greg Clayton1674b122010-07-21 22:12:05 +0000148 case llvm::MachO::HeaderMagic32:
149 case llvm::MachO::HeaderMagic32Swapped:
Chris Lattner24943d22010-06-08 16:52:24 +0000150 return 4;
151
Greg Clayton1674b122010-07-21 22:12:05 +0000152 case llvm::MachO::HeaderMagic64:
153 case llvm::MachO::HeaderMagic64Swapped:
Chris Lattner24943d22010-06-08 16:52:24 +0000154 return 8;
155
156 default:
157 break;
158 }
159 return 0;
160 }
161
162 static lldb::ByteOrder
163 GetByteOrderFromMagic (uint32_t magic)
164 {
165 switch (magic)
166 {
Greg Clayton1674b122010-07-21 22:12:05 +0000167 case llvm::MachO::HeaderMagic32:
168 case llvm::MachO::HeaderMagic64:
Chris Lattner24943d22010-06-08 16:52:24 +0000169 return lldb::eByteOrderHost;
170
Greg Clayton1674b122010-07-21 22:12:05 +0000171 case llvm::MachO::HeaderMagic32Swapped:
172 case llvm::MachO::HeaderMagic64Swapped:
Chris Lattner24943d22010-06-08 16:52:24 +0000173 if (lldb::eByteOrderHost == lldb::eByteOrderBig)
174 return lldb::eByteOrderLittle;
175 else
176 return lldb::eByteOrderBig;
177
178 default:
179 break;
180 }
181 return lldb::eByteOrderInvalid;
182 }
183
184 bool
185 ReadMachHeader (lldb::addr_t addr,
Greg Clayton1674b122010-07-21 22:12:05 +0000186 llvm::MachO::mach_header *header,
Chris Lattner24943d22010-06-08 16:52:24 +0000187 lldb_private::DataExtractor *load_command_data);
188 class Segment
189 {
190 public:
191
192 Segment() :
193 name(),
194 addr(LLDB_INVALID_ADDRESS),
195 size(0)
196 {
197 }
198
199 lldb_private::ConstString name;
200 lldb::addr_t addr;
201 lldb::addr_t size;
202
203 bool
204 operator==(const Segment& rhs) const
205 {
206 return name == rhs.name && addr == rhs.addr && size == rhs.size;
207 }
208
209 void
210 PutToLog (lldb_private::Log *log,
211 lldb::addr_t slide) const;
212
213 };
214
215 struct DYLDImageInfo
216 {
217 lldb::addr_t address; // Address of mach header for this dylib
218 lldb::addr_t slide; // The amount to slide all segments by if there is a global slide.
219 lldb::addr_t mod_date; // Modification date for this dylib
220 lldb_private::FileSpec file_spec; // Resolved path for this dylib
221 lldb_private::UUID uuid; // UUID for this dylib if it has one, else all zeros
Greg Clayton1674b122010-07-21 22:12:05 +0000222 llvm::MachO::mach_header header; // The mach header for this image
Chris Lattner24943d22010-06-08 16:52:24 +0000223 std::vector<Segment> segments; // All segment vmaddr and vmsize pairs for this executable (from memory of inferior)
224
225 DYLDImageInfo() :
226 address(LLDB_INVALID_ADDRESS),
227 slide(0),
228 mod_date(0),
229 file_spec(),
230 uuid(),
231 header(),
232 segments()
233 {
234 }
235
236 void
237 Clear(bool load_cmd_data_only)
238 {
239 if (!load_cmd_data_only)
240 {
241 address = LLDB_INVALID_ADDRESS;
242 slide = 0;
243 mod_date = 0;
244 file_spec.Clear();
245 ::bzero (&header, sizeof(header));
246 }
247 uuid.Clear();
248 segments.clear();
249 }
250
251 bool
252 operator == (const DYLDImageInfo& rhs) const
253 {
254 return address == rhs.address
255 && slide == rhs.slide
256 && mod_date == rhs.mod_date
257 && file_spec == rhs.file_spec
258 && uuid == rhs.uuid
259 && memcmp(&header, &rhs.header, sizeof(header)) == 0
260 && segments == rhs.segments;
261 }
262
263 bool
264 UUIDValid() const
265 {
266 return uuid.IsValid();
267 }
268
269 const Segment *
270 FindSegment (const lldb_private::ConstString &name) const;
271
272 void
273 PutToLog (lldb_private::Log *log) const;
274
275 typedef std::vector<DYLDImageInfo> collection;
276 typedef collection::iterator iterator;
277 typedef collection::const_iterator const_iterator;
278 };
279
280 struct DYLDAllImageInfos
281 {
282 uint32_t version;
283 uint32_t dylib_info_count; // Version >= 1
284 lldb::addr_t dylib_info_addr; // Version >= 1
285 lldb::addr_t notification; // Version >= 1
286 bool processDetachedFromSharedRegion; // Version >= 1
287 bool libSystemInitialized; // Version >= 2
288 lldb::addr_t dyldImageLoadAddress; // Version >= 2
289
290 DYLDAllImageInfos() :
291 version (0),
292 dylib_info_count (0),
293 dylib_info_addr (LLDB_INVALID_ADDRESS),
294 notification (LLDB_INVALID_ADDRESS),
295 processDetachedFromSharedRegion (false),
296 libSystemInitialized (false),
297 dyldImageLoadAddress (LLDB_INVALID_ADDRESS)
298 {
299 }
300
301 void
302 Clear()
303 {
304 version = 0;
305 dylib_info_count = 0;
306 dylib_info_addr = LLDB_INVALID_ADDRESS;
307 notification = LLDB_INVALID_ADDRESS;
308 processDetachedFromSharedRegion = false;
309 libSystemInitialized = false;
310 dyldImageLoadAddress = LLDB_INVALID_ADDRESS;
311 }
312
313 bool
314 IsValid() const
315 {
316 return version >= 1 || version <= 6;
317 }
318 };
319
320 void
321 RegisterNotificationCallbacks();
322
323 void
324 UnregisterNotificationCallbacks();
325
326 uint32_t
327 ParseLoadCommands (const lldb_private::DataExtractor& data,
328 struct DYLDImageInfo& dylib_info,
329 lldb_private::FileSpec *lc_id_dylinker);
330
331 bool
332 UpdateImageLoadAddress(lldb_private::Module *module,
333 struct DYLDImageInfo& info);
334
335 bool
336 UnloadImageLoadAddress (lldb_private::Module *module,
337 struct DYLDImageInfo& info);
338
339 bool
340 NeedToLocateDYLD () const;
341
342 bool
343 SetNotificationBreakpoint ();
344
345 bool
346 ReadAllImageInfosStructure ();
347
348 DYLDImageInfo m_dyld; // Info about the curent dyld being used
349 lldb::addr_t m_dyld_all_image_infos_addr;
350 DYLDAllImageInfos m_dyld_all_image_infos;
351 lldb::user_id_t m_break_id;
352 DYLDImageInfo::collection m_dyld_image_infos; // Current shared libraries information
353 mutable lldb_private::Mutex m_mutex;
354 lldb_private::Process::Notifications m_notification_callbacks;
355 std::auto_ptr<lldb_private::ObjCTrampolineHandler> m_objc_trampoline_handler_ap;
356
357private:
358 DISALLOW_COPY_AND_ASSIGN (DynamicLoaderMacOSXDYLD);
359};
360
361#endif // liblldb_DynamicLoaderMacOSXDYLD_h_