1//===-- DynamicLoader.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_DynamicLoader_h_
11#define liblldb_DynamicLoader_h_
12
13// Project includes
14#include "lldb/lldb-private.h"
15#include "lldb/Core/Error.h"
16#include "lldb/Core/PluginInterface.h"
17
18namespace lldb_private {
19
20//----------------------------------------------------------------------
21/// @class DynamicLoader DynamicLoader.h "lldb/Target/DynamicLoader.h"
22/// @brief A plug-in interface definition class for dynamic loaders.
23///
24/// Dynamic loader plug-ins track image (shared library) loading and
25/// unloading. The class is initialized given a live process that is
26/// halted at its entry point or just after attaching.
27///
28/// Dynamic loader plug-ins can track the process by registering
29/// callbacks using the:
30/// Process::RegisterNotificationCallbacks (const Notifications&)
31/// function.
32///
33/// Breakpoints can also be set in the process which can register
34/// functions that get called using:
35/// Process::BreakpointSetCallback (lldb::user_id_t, BreakpointHitCallback, void *).
36/// These breakpoint callbacks return a boolean value that indicates if
37/// the process should continue or halt and should return the global
38/// setting for this using:
39/// DynamicLoader::StopWhenImagesChange() const.
40//----------------------------------------------------------------------
41class DynamicLoader :
42    public PluginInterface
43{
44public:
45    //------------------------------------------------------------------
46    /// Find a dynamic loader plugin for a given process.
47    ///
48    /// Scans the installed DynamicLoader plug-ins and tries to find
49    /// an instance that can be used to track image changes in \a
50    /// process.
51    ///
52    /// @param[in] process
53    ///     The process for which to try and locate a dynamic loader
54    ///     plug-in instance.
55    ///
56    /// @param[in] plugin_name
57    ///     An optional name of a specific dynamic loader plug-in that
58    ///     should be used. If NULL, pick the best plug-in.
59    //------------------------------------------------------------------
60    static DynamicLoader*
61    FindPlugin (Process *process, const char *plugin_name);
62
63    //------------------------------------------------------------------
64    /// Construct with a process.
65    //------------------------------------------------------------------
66    DynamicLoader (Process *process);
67
68    //------------------------------------------------------------------
69    /// Destructor.
70    ///
71    /// The destructor is virtual since this class is designed to be
72    /// inherited from by the plug-in instance.
73    //------------------------------------------------------------------
74    virtual
75    ~DynamicLoader ();
76
77    //------------------------------------------------------------------
78    /// Called after attaching a process.
79    ///
80    /// Allow DynamicLoader plug-ins to execute some code after
81    /// attaching to a process.
82    //------------------------------------------------------------------
83    virtual void
84    DidAttach () = 0;
85
86    //------------------------------------------------------------------
87    /// Called after launching a process.
88    ///
89    /// Allow DynamicLoader plug-ins to execute some code after
90    /// the process has stopped for the first time on launch.
91    //------------------------------------------------------------------
92    virtual void
93    DidLaunch () = 0;
94
95
96    //------------------------------------------------------------------
97    /// Helper function that can be used to detect when a process has
98    /// called exec and is now a new and different process. This can
99    /// be called when necessary to try and detect the exec. The process
100    /// might be able to answer this question, but sometimes it might
101    /// not be able and the dynamic loader often knows what the program
102    /// entry point is. So the process and the dynamic loader can work
103    /// together to detect this.
104    //------------------------------------------------------------------
105    virtual bool
106    ProcessDidExec ()
107    {
108        return false;
109    }
110    //------------------------------------------------------------------
111    /// Get whether the process should stop when images change.
112    ///
113    /// When images (executables and shared libraries) get loaded or
114    /// unloaded, often debug sessions will want to try and resolve or
115    /// unresolve breakpoints that are set in these images. Any
116    /// breakpoints set by DynamicLoader plug-in instances should
117    /// return this value to ensure consistent debug session behaviour.
118    ///
119    /// @return
120    ///     Returns \b true if the process should stop when images
121    ///     change, \b false if the process should resume.
122    //------------------------------------------------------------------
123    bool
124    GetStopWhenImagesChange () const;
125
126    //------------------------------------------------------------------
127    /// Set whether the process should stop when images change.
128    ///
129    /// When images (executables and shared libraries) get loaded or
130    /// unloaded, often debug sessions will want to try and resolve or
131    /// unresolve breakpoints that are set in these images. The default
132    /// is set so that the process stops when images change, but this
133    /// can be overridden using this function callback.
134    ///
135    /// @param[in] stop
136    ///     Boolean value that indicates whether the process should stop
137    ///     when images change.
138    //------------------------------------------------------------------
139    void
140    SetStopWhenImagesChange (bool stop);
141
142    //------------------------------------------------------------------
143    /// Provides a plan to step through the dynamic loader trampoline
144    /// for the current state of \a thread.
145    ///
146    ///
147    /// @param[in] stop_others
148    ///     Whether the plan should be set to stop other threads.
149    ///
150    /// @return
151    ///    A pointer to the plan (caller owned) or NULL if we are not at such
152    ///    a trampoline.
153    //------------------------------------------------------------------
154    virtual lldb::ThreadPlanSP
155    GetStepThroughTrampolinePlan (Thread &thread, bool stop_others) = 0;
156
157
158    //------------------------------------------------------------------
159    /// Some dynamic loaders provide features where there are a group of symbols "equivalent to"
160    /// a given symbol one of which will be chosen when the symbol is bound.  If you want to
161    /// set a breakpoint on one of these symbols, you really need to set it on all the
162    /// equivalent symbols.
163    ///
164    ///
165    /// @param[in] original_symbol
166    ///     The symbol for which we are finding equivalences.
167    ///
168    /// @param[in] module_list
169    ///     The set of modules in which to search.
170    ///
171    /// @param[out] equivalent_symbols
172    ///     The equivalent symbol list - any equivalent symbols found are appended to this list.
173    ///
174    /// @return
175    ///    Number of equivalent symbols found.
176    //------------------------------------------------------------------
177    virtual size_t
178    FindEquivalentSymbols (Symbol *original_symbol, ModuleList &module_list, SymbolContextList &equivalent_symbols)
179    {
180        return 0;
181    }
182
183    //------------------------------------------------------------------
184    /// Ask if it is ok to try and load or unload an shared library
185    /// (image).
186    ///
187    /// The dynamic loader often knows when it would be ok to try and
188    /// load or unload a shared library. This function call allows the
189    /// dynamic loader plug-ins to check any current dyld state to make
190    /// sure it is an ok time to load a shared library.
191    ///
192    /// @return
193    ///     \b true if it is currently ok to try and load a shared
194    ///     library into the process, \b false otherwise.
195    //------------------------------------------------------------------
196    virtual Error
197    CanLoadImage () = 0;
198
199    //------------------------------------------------------------------
200    /// Ask if the eh_frame information for the given SymbolContext should
201    /// be relied on even when it's the first frame in a stack unwind.
202    ///
203    /// The CFI instructions from the eh_frame section are normally only
204    /// valid at call sites -- places where a program could throw an
205    /// exception and need to unwind out.  But some Modules may be known
206    /// to the system as having reliable eh_frame information at all call
207    /// sites.  This would be the case if the Module's contents are largely
208    /// hand-written assembly with hand-written eh_frame information.
209    /// Normally when unwinding from a function at the beginning of a stack
210    /// unwind lldb will examine the assembly instructions to understand
211    /// how the stack frame is set up and where saved registers are stored.
212    /// But with hand-written assembly this is not reliable enough -- we need
213    /// to consult those function's hand-written eh_frame information.
214    ///
215    /// @return
216    ///     \b True if the symbol context should use eh_frame instructions
217    ///     unconditionally when unwinding from this frame.  Else \b false,
218    ///     the normal lldb unwind behavior of only using eh_frame when the
219    ///     function appears in the middle of the stack.
220    //------------------------------------------------------------------
221    virtual bool
222    AlwaysRelyOnEHUnwindInfo (SymbolContext &sym_ctx)
223    {
224       return false;
225    }
226
227protected:
228    //------------------------------------------------------------------
229    // Member variables.
230    //------------------------------------------------------------------
231    Process* m_process; ///< The process that this dynamic loader plug-in is tracking.
232private:
233    DISALLOW_COPY_AND_ASSIGN (DynamicLoader);
234
235};
236
237} // namespace lldb_private
238
239#endif  // liblldb_DynamicLoader_h_
240