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