1 //===-- DynamicLoaderPOSIXDYLD.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_DynamicLoaderPOSIXDYLD_h_
11 #define liblldb_DynamicLoaderPOSIXDYLD_h_
12 
13 // C Includes
14 // C++ Includes
15 // Other libraries and framework includes
16 // Project includes
17 #include "lldb/Breakpoint/StoppointCallbackContext.h"
18 #include "lldb/Target/DynamicLoader.h"
19 
20 #include "DYLDRendezvous.h"
21 
22 class AuxVector;
23 
24 class DynamicLoaderPOSIXDYLD : public lldb_private::DynamicLoader
25 {
26 public:
27     DynamicLoaderPOSIXDYLD(lldb_private::Process *process);
28 
29     ~DynamicLoaderPOSIXDYLD() override;
30 
31     static void
32     Initialize();
33 
34     static void
35     Terminate();
36 
37     static lldb_private::ConstString
38     GetPluginNameStatic();
39 
40     static const char *
41     GetPluginDescriptionStatic();
42 
43     static lldb_private::DynamicLoader *
44     CreateInstance(lldb_private::Process *process, bool force);
45 
46     //------------------------------------------------------------------
47     // DynamicLoader protocol
48     //------------------------------------------------------------------
49 
50     void
51     DidAttach() override;
52 
53     void
54     DidLaunch() override;
55 
56     lldb::ThreadPlanSP
57     GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
58                                  bool stop_others) override;
59 
60     lldb_private::Error
61     CanLoadImage() override;
62 
63     lldb::addr_t
64     GetThreadLocalData(const lldb::ModuleSP module, const lldb::ThreadSP thread) override;
65 
66     //------------------------------------------------------------------
67     // PluginInterface protocol
68     //------------------------------------------------------------------
69     lldb_private::ConstString
70     GetPluginName() override;
71 
72     uint32_t
73     GetPluginVersion() override;
74 
75 protected:
76     /// Runtime linker rendezvous structure.
77     DYLDRendezvous m_rendezvous;
78 
79     /// Virtual load address of the inferior process.
80     lldb::addr_t m_load_offset;
81 
82     /// Virtual entry address of the inferior process.
83     lldb::addr_t m_entry_point;
84 
85     /// Auxiliary vector of the inferior process.
86     std::unique_ptr<AuxVector> m_auxv;
87 
88     /// Rendezvous breakpoint.
89     lldb::break_id_t m_dyld_bid;
90 
91     /// Contains AT_SYSINFO_EHDR, which means a vDSO has been
92     /// mapped to the address space
93     lldb::addr_t m_vdso_base;
94 
95     /// Loaded module list. (link map for each module)
96     std::map<lldb::ModuleWP, lldb::addr_t, std::owner_less<lldb::ModuleWP>> m_loaded_modules;
97 
98     /// Enables a breakpoint on a function called by the runtime
99     /// linker each time a module is loaded or unloaded.
100     virtual 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 link_map_addr The virtual address of the link map for the @p module.
121     ///
122     /// @param base_addr The virtual base address @p module is loaded at.
123     void
124     UpdateLoadedSections(lldb::ModuleSP module,
125                          lldb::addr_t link_map_addr,
126                          lldb::addr_t base_addr,
127                          bool base_addr_is_offset) override;
128 
129     /// Removes the loaded sections from the target in @p module.
130     ///
131     /// @param module The module to traverse.
132     void
133     UnloadSections(const lldb::ModuleSP module) override;
134 
135     /// Resolves the entry point for the current inferior process and sets a
136     /// breakpoint at that address.
137     void
138     ProbeEntry();
139 
140     /// Callback routine invoked when we hit the breakpoint on process entry.
141     ///
142     /// This routine is responsible for resolving the load addresses of all
143     /// dependent modules required by the inferior and setting up the rendezvous
144     /// breakpoint.
145     static bool
146     EntryBreakpointHit(void *baton,
147                        lldb_private::StoppointCallbackContext *context,
148                        lldb::user_id_t break_id,
149                        lldb::user_id_t break_loc_id);
150 
151     /// Helper for the entry breakpoint callback.  Resolves the load addresses
152     /// of all dependent modules.
153     virtual void
154     LoadAllCurrentModules();
155 
156     /// Computes a value for m_load_offset returning the computed address on
157     /// success and LLDB_INVALID_ADDRESS on failure.
158     lldb::addr_t
159     ComputeLoadOffset();
160 
161     /// Computes a value for m_entry_point returning the computed address on
162     /// success and LLDB_INVALID_ADDRESS on failure.
163     lldb::addr_t
164     GetEntryPoint();
165 
166     /// Evaluate if Aux vectors contain vDSO information
167     /// in case they do, read and assign the address to m_vdso_base
168     void
169     EvalVdsoStatus();
170 
171     /// Loads Module from inferior process.
172     void
173     ResolveExecutableModule(lldb::ModuleSP &module_sp);
174 
175 private:
176     DISALLOW_COPY_AND_ASSIGN(DynamicLoaderPOSIXDYLD);
177 };
178 
179 #endif // liblldb_DynamicLoaderPOSIXDYLD_h_
180