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