1 //===-- DynamicLoaderPOSIX.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_DynamicLoaderPOSIX_H_
11 #define liblldb_DynamicLoaderPOSIX_H_
12 
13 // C Includes
14 // C++ Includes
15 // Other libraries and framework includes
16 #include "lldb/Breakpoint/StoppointCallbackContext.h"
17 #include "lldb/Target/DynamicLoader.h"
18 
19 #include "DYLDRendezvous.h"
20 
21 class AuxVector;
22 
23 class DynamicLoaderPOSIXDYLD : public lldb_private::DynamicLoader
24 {
25 public:
26 
27     static void
28     Initialize();
29 
30     static void
31     Terminate();
32 
33     static lldb_private::ConstString
34     GetPluginNameStatic();
35 
36     static const char *
37     GetPluginDescriptionStatic();
38 
39     static lldb_private::DynamicLoader *
40     CreateInstance(lldb_private::Process *process, bool force);
41 
42     DynamicLoaderPOSIXDYLD(lldb_private::Process *process);
43 
44     virtual
45     ~DynamicLoaderPOSIXDYLD();
46 
47     //------------------------------------------------------------------
48     // DynamicLoader protocol
49     //------------------------------------------------------------------
50 
51     virtual void
52     DidAttach();
53 
54     virtual void
55     DidLaunch();
56 
57     virtual lldb::ThreadPlanSP
58     GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
59                                  bool stop_others);
60 
61     virtual lldb_private::Error
62     CanLoadImage();
63 
64     //------------------------------------------------------------------
65     // PluginInterface protocol
66     //------------------------------------------------------------------
67     virtual lldb_private::ConstString
68     GetPluginName();
69 
70     virtual uint32_t
71     GetPluginVersion();
72 
73     virtual void
74     GetPluginCommandHelp(const char *command, lldb_private::Stream *strm);
75 
76     virtual lldb_private::Error
77     ExecutePluginCommand(lldb_private::Args &command, lldb_private::Stream *strm);
78 
79     virtual lldb_private::Log *
80     EnablePluginLogging(lldb_private::Stream *strm, lldb_private::Args &command);
81 
82 protected:
83     /// Runtime linker rendezvous structure.
84     DYLDRendezvous m_rendezvous;
85 
86     /// Virtual load address of the inferior process.
87     lldb::addr_t m_load_offset;
88 
89     /// Virtual entry address of the inferior process.
90     lldb::addr_t m_entry_point;
91 
92     /// Auxiliary vector of the inferior process.
93     std::unique_ptr<AuxVector> m_auxv;
94 
95     /// Rendezvous breakpoint.
96     lldb::break_id_t m_dyld_bid;
97 
98     /// Enables a breakpoint on a function called by the runtime
99     /// linker each time a module is loaded or unloaded.
100     void
101     SetRendezvousBreakpoint();
102 
103     /// Callback routine which updates the current list of loaded modules based
104     /// on the information supplied by the runtime linker.
105     static bool
106     RendezvousBreakpointHit(void *baton,
107                             lldb_private::StoppointCallbackContext *context,
108                             lldb::user_id_t break_id,
109                             lldb::user_id_t break_loc_id);
110 
111     /// Helper method for RendezvousBreakpointHit.  Updates LLDB's current set
112     /// of loaded modules.
113     void
114     RefreshModules();
115 
116     /// Updates the load address of every allocatable section in @p module.
117     ///
118     /// @param module The module to traverse.
119     ///
120     /// @param base_addr The virtual base address @p module is loaded at.
121     void
122     UpdateLoadedSections(lldb::ModuleSP module,
123                          lldb::addr_t base_addr = 0);
124 
125     /// Locates or creates a module given by @p file and updates/loads the
126     /// resulting module at the virtual base address @p base_addr.
127     lldb::ModuleSP
128     LoadModuleAtAddress(const lldb_private::FileSpec &file, lldb::addr_t base_addr);
129 
130     /// Resolves the entry point for the current inferior process and sets a
131     /// breakpoint at that address.
132     void
133     ProbeEntry();
134 
135     /// Callback routine invoked when we hit the breakpoint on process entry.
136     ///
137     /// This routine is responsible for resolving the load addresses of all
138     /// dependent modules required by the inferior and setting up the rendezvous
139     /// breakpoint.
140     static bool
141     EntryBreakpointHit(void *baton,
142                        lldb_private::StoppointCallbackContext *context,
143                        lldb::user_id_t break_id,
144                        lldb::user_id_t break_loc_id);
145 
146     /// Helper for the entry breakpoint callback.  Resolves the load addresses
147     /// of all dependent modules.
148     void
149     LoadAllCurrentModules();
150 
151     /// Computes a value for m_load_offset returning the computed address on
152     /// success and LLDB_INVALID_ADDRESS on failure.
153     lldb::addr_t
154     ComputeLoadOffset();
155 
156     /// Computes a value for m_entry_point returning the computed address on
157     /// success and LLDB_INVALID_ADDRESS on failure.
158     lldb::addr_t
159     GetEntryPoint();
160 
161     /// Checks to see if the target module has changed, updates the target
162     /// accordingly and returns the target executable module.
163     lldb::ModuleSP
164     GetTargetExecutable();
165 
166 private:
167     DISALLOW_COPY_AND_ASSIGN(DynamicLoaderPOSIXDYLD);
168 };
169 
170 #endif  // liblldb_DynamicLoaderPOSIXDYLD_H_
171