DynamicLoaderMacOSXDYLD.h revision b66cd074ec097b5b0a6f2ce292f5072aa1217ca6
1//===-- 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// 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/Core/FileSpec.h"
24#include "lldb/Core/UUID.h"
25#include "lldb/Host/Mutex.h"
26#include "lldb/Target/Process.h"
27
28class 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        {
146            case llvm::MachO::HeaderMagic32:
147            case llvm::MachO::HeaderMagic32Swapped:
148                return 4;
149
150            case llvm::MachO::HeaderMagic64:
151            case llvm::MachO::HeaderMagic64Swapped:
152                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        {
165            case llvm::MachO::HeaderMagic32:
166            case llvm::MachO::HeaderMagic64:
167                return lldb::eByteOrderHost;
168
169            case llvm::MachO::HeaderMagic32Swapped:
170            case llvm::MachO::HeaderMagic64Swapped:
171                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,
184                    llvm::MachO::mach_header *header,
185                    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
220        llvm::MachO::mach_header header;      // The mach header for this image
221        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;
353
354private:
355    DISALLOW_COPY_AND_ASSIGN (DynamicLoaderMacOSXDYLD);
356};
357
358#endif  // liblldb_DynamicLoaderMacOSXDYLD_h_
359