DynamicLoaderMacOSXDYLD.h revision 1674b12bbc3dae7b9543b8c5f958e90ddc767fa4
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
28#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        {
148            case llvm::MachO::HeaderMagic32:
149            case llvm::MachO::HeaderMagic32Swapped:
150                return 4;
151
152            case llvm::MachO::HeaderMagic64:
153            case llvm::MachO::HeaderMagic64Swapped:
154                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        {
167            case llvm::MachO::HeaderMagic32:
168            case llvm::MachO::HeaderMagic64:
169                return lldb::eByteOrderHost;
170
171            case llvm::MachO::HeaderMagic32Swapped:
172            case llvm::MachO::HeaderMagic64Swapped:
173                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,
186                    llvm::MachO::mach_header *header,
187                    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
222        llvm::MachO::mach_header header;      // The mach header for this image
223        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_
362