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