blob: 98042188b18a6122f48deb262e927dc40f2231db [file] [log] [blame]
Jason Molenda5fe4d142016-07-17 21:27:32 +00001//===-- DynamicLoaderDarwin.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_DynamicLoaderDarwin_h_
11#define liblldb_DynamicLoaderDarwin_h_
12
13// C Includes
14// C++ Includes
15#include <map>
16#include <mutex>
17#include <vector>
18
19// Other libraries and framework includes
20// Project includes
21#include "lldb/Target/DynamicLoader.h"
22#include "lldb/Host/FileSpec.h"
23#include "lldb/Core/StructuredData.h"
24#include "lldb/Core/UUID.h"
25#include "lldb/Host/Mutex.h"
26#include "lldb/Target/Process.h"
27#include "lldb/Utility/SafeMachO.h"
28
Jason Molenda9ab5dc22016-07-21 08:30:55 +000029#include "llvm/ADT/Triple.h"
30
Jason Molenda5fe4d142016-07-17 21:27:32 +000031namespace lldb_private {
32
33class DynamicLoaderDarwin : public lldb_private::DynamicLoader
34{
35public:
36 DynamicLoaderDarwin(lldb_private::Process *process);
37
38 virtual ~DynamicLoaderDarwin() override;
39
40 //------------------------------------------------------------------
41 /// Called after attaching a process.
42 ///
43 /// Allow DynamicLoader plug-ins to execute some code after
44 /// attaching to a process.
45 //------------------------------------------------------------------
46 void
47 DidAttach() override;
48
49 void
50 DidLaunch() override;
51
52 lldb::ThreadPlanSP
53 GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
54 bool stop_others) override;
55
56 size_t
57 FindEquivalentSymbols(lldb_private::Symbol *original_symbol,
58 lldb_private::ModuleList &module_list,
59 lldb_private::SymbolContextList &equivalent_symbols) override;
60
61 lldb::addr_t
62 GetThreadLocalData(const lldb::ModuleSP module, const lldb::ThreadSP thread, lldb::addr_t tls_file_addr) override;
63
64 bool
65 AlwaysRelyOnEHUnwindInfo(lldb_private::SymbolContext &sym_ctx) override;
66
67 virtual void
68 DoInitialImageFetch () = 0;
69
70 virtual bool
71 NeedToDoInitialImageFetch () = 0;
72
73protected:
74 void
75 PrivateInitialize (lldb_private::Process *process);
76
77 void
78 PrivateProcessStateChanged (lldb_private::Process *process,
79 lldb::StateType state);
80
81 void
82 Clear (bool clear_process);
83
84 // Clear method for classes derived from this one
85 virtual void
86 DoClear () = 0;
87
88 void
89 SetDYLDModule (lldb::ModuleSP &dyld_module_sp);
90
91 lldb::ModuleSP
92 GetDYLDModule ();
93
94 class Segment
95 {
96 public:
97 Segment() :
98 name(),
99 vmaddr(LLDB_INVALID_ADDRESS),
100 vmsize(0),
101 fileoff(0),
102 filesize(0),
103 maxprot(0),
104 initprot(0),
105 nsects(0),
106 flags(0)
107 {
108 }
109
110 lldb_private::ConstString name;
111 lldb::addr_t vmaddr;
112 lldb::addr_t vmsize;
113 lldb::addr_t fileoff;
114 lldb::addr_t filesize;
115 uint32_t maxprot;
116 uint32_t initprot;
117 uint32_t nsects;
118 uint32_t flags;
119
120 bool
121 operator==(const Segment& rhs) const
122 {
123 return name == rhs.name && vmaddr == rhs.vmaddr && vmsize == rhs.vmsize;
124 }
125
126 void
127 PutToLog (lldb_private::Log *log,
128 lldb::addr_t slide) const;
129
130 };
131
132 struct ImageInfo
133 {
134 lldb::addr_t address; // Address of mach header for this dylib
135 lldb::addr_t slide; // The amount to slide all segments by if there is a global slide.
136 lldb::addr_t mod_date; // Modification date for this dylib
137 lldb_private::FileSpec file_spec; // Resolved path for this dylib
138 lldb_private::UUID uuid; // UUID for this dylib if it has one, else all zeros
139 llvm::MachO::mach_header header; // The mach header for this image
140 std::vector<Segment> segments; // All segment vmaddr and vmsize pairs for this executable (from memory of inferior)
141 uint32_t load_stop_id; // The process stop ID that the sections for this image were loaded
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000142 llvm::Triple::OSType os_type; // LC_VERSION_MIN_... load command os type
143 std::string min_version_os_sdk; // LC_VERSION_MIN_... sdk value
Jason Molenda5fe4d142016-07-17 21:27:32 +0000144
145 ImageInfo() :
146 address(LLDB_INVALID_ADDRESS),
147 slide(0),
148 mod_date(0),
149 file_spec(),
150 uuid(),
151 header(),
152 segments(),
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000153 load_stop_id(0),
154 os_type (llvm::Triple::OSType::UnknownOS),
155 min_version_os_sdk()
Jason Molenda5fe4d142016-07-17 21:27:32 +0000156 {
157 }
158
159 void
160 Clear(bool load_cmd_data_only)
161 {
162 if (!load_cmd_data_only)
163 {
164 address = LLDB_INVALID_ADDRESS;
165 slide = 0;
166 mod_date = 0;
167 file_spec.Clear();
168 ::memset (&header, 0, sizeof(header));
169 }
170 uuid.Clear();
171 segments.clear();
172 load_stop_id = 0;
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000173 os_type = llvm::Triple::OSType::UnknownOS;
174 min_version_os_sdk.clear();
Jason Molenda5fe4d142016-07-17 21:27:32 +0000175 }
176
177 bool
178 operator == (const ImageInfo& rhs) const
179 {
180 return address == rhs.address
181 && slide == rhs.slide
182 && mod_date == rhs.mod_date
183 && file_spec == rhs.file_spec
184 && uuid == rhs.uuid
185 && memcmp(&header, &rhs.header, sizeof(header)) == 0
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000186 && segments == rhs.segments
187 && os_type == rhs.os_type;
Jason Molenda5fe4d142016-07-17 21:27:32 +0000188 }
189
190 bool
191 UUIDValid() const
192 {
193 return uuid.IsValid();
194 }
195
196 uint32_t
197 GetAddressByteSize ()
198 {
199 if (header.cputype)
200 {
201 if (header.cputype & llvm::MachO::CPU_ARCH_ABI64)
202 return 8;
203 else
204 return 4;
205 }
206 return 0;
207 }
208
209 lldb_private::ArchSpec
210 GetArchitecture () const
211 {
212 return lldb_private::ArchSpec (lldb_private::eArchTypeMachO, header.cputype, header.cpusubtype);
213 }
214
215 const Segment *
216 FindSegment (const lldb_private::ConstString &name) const;
217
218 void
219 PutToLog (lldb_private::Log *log) const;
220
221 typedef std::vector<ImageInfo> collection;
222 typedef collection::iterator iterator;
223 typedef collection::const_iterator const_iterator;
224 };
225
226 bool
227 UpdateImageLoadAddress(lldb_private::Module *module, ImageInfo& info);
228
229 bool
230 UnloadModuleSections (lldb_private::Module *module, ImageInfo& info);
231
Jason Molenda5fe4d142016-07-17 21:27:32 +0000232 lldb::ModuleSP
233 FindTargetModuleForImageInfo (ImageInfo &image_info,
234 bool can_create,
235 bool *did_create_ptr);
236
237 void
238 UnloadImages (const std::vector<lldb::addr_t> &solib_addresses);
239
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000240 void
241 UnloadAllImages ();
242
Jason Molenda5fe4d142016-07-17 21:27:32 +0000243 virtual bool
244 SetNotificationBreakpoint () = 0;
245
246 virtual void
247 ClearNotificationBreakpoint () = 0;
248
249 virtual bool
250 DidSetNotificationBreakpoint () = 0;
251
252 typedef std::map<uint64_t, lldb::addr_t> PthreadKeyToTLSMap;
253 typedef std::map<lldb::user_id_t, PthreadKeyToTLSMap> ThreadIDToTLSMap;
254
255 std::recursive_mutex &
256 GetMutex () const
257 {
258 return m_mutex;
259 }
260
261 lldb::ModuleSP
262 GetPThreadLibraryModule();
263
264 lldb_private::Address
265 GetPthreadSetSpecificAddress();
266
267 bool
268 JSONImageInformationIntoImageInfo (lldb_private::StructuredData::ObjectSP image_details, ImageInfo::collection &image_infos);
269
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000270 // If image_infos contains / may contain dyld or executable image, call this method
271 // to keep our internal record keeping of the special binaries up-to-date.
Jason Molenda5fe4d142016-07-17 21:27:32 +0000272 void
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000273 UpdateSpecialBinariesFromNewImageInfos (ImageInfo::collection &image_infos);
Jason Molenda5fe4d142016-07-17 21:27:32 +0000274
275 // if image_info is a dyld binary, call this method
276 void
277 UpdateDYLDImageInfoFromNewImageInfo (ImageInfo &image_info);
278
279 // If image_infos contains / may contain executable image, call this method
280 // to keep our internal record keeping of the special dyld binary up-to-date.
281 void
282 AddExecutableModuleIfInImageInfos (ImageInfo::collection &image_infos);
283
284 bool
285 AddModulesUsingImageInfos (ImageInfo::collection &image_infos);
286
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000287 // Whether we should use the new dyld SPI to get shared library information, or read
288 // it directly out of the dyld_all_image_infos. Whether we use the (newer) DynamicLoaderMacOS
289 // plugin or the (older) DynamicLoaderMacOSX plugin.
290 static bool
291 UseDYLDSPI (lldb_private::Process *process);
292
293 lldb::ModuleWP m_dyld_module_wp; // the dyld whose file type (mac, ios, etc) matches the process
Jason Molenda5fe4d142016-07-17 21:27:32 +0000294 lldb::ModuleWP m_libpthread_module_wp;
295 lldb_private::Address m_pthread_getspecific_addr;
296 ThreadIDToTLSMap m_tid_to_tls_map;
297 ImageInfo::collection m_dyld_image_infos; // Current shared libraries information
298 uint32_t m_dyld_image_infos_stop_id; // The process stop ID that "m_dyld_image_infos" is valid for
299 ImageInfo m_dyld;
300 mutable std::recursive_mutex m_mutex;
301
302private:
303 DISALLOW_COPY_AND_ASSIGN (DynamicLoaderDarwin);
304};
305
306} // namespace lldb_private
307
308#endif // liblldb_DynamicLoaderDarwin_h_