blob: a02d1ad9bee36e80f0b23e49c4a89d44a250d470 [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
Kate Stoneb9c1b512016-09-06 20:57:50 +000021#include "lldb/Target/DynamicLoader.h"
Jason Molenda5fe4d142016-07-17 21:27:32 +000022#include "lldb/Target/Process.h"
Zachary Turner5713a052017-03-22 18:40:07 +000023#include "lldb/Utility/FileSpec.h"
Jason Molenda5fe4d142016-07-17 21:27:32 +000024#include "lldb/Utility/SafeMachO.h"
Pavel Labathf2a8bcc2017-06-27 10:45:31 +000025#include "lldb/Utility/StructuredData.h"
Zachary Turner5713a052017-03-22 18:40:07 +000026#include "lldb/Utility/UUID.h"
Jason Molenda5fe4d142016-07-17 21:27:32 +000027
Jason Molenda9ab5dc22016-07-21 08:30:55 +000028#include "llvm/ADT/Triple.h"
29
Jason Molenda5fe4d142016-07-17 21:27:32 +000030namespace lldb_private {
31
Kate Stoneb9c1b512016-09-06 20:57:50 +000032class DynamicLoaderDarwin : public lldb_private::DynamicLoader {
Jason Molenda5fe4d142016-07-17 21:27:32 +000033public:
Kate Stoneb9c1b512016-09-06 20:57:50 +000034 DynamicLoaderDarwin(lldb_private::Process *process);
Jason Molenda5fe4d142016-07-17 21:27:32 +000035
Kate Stoneb9c1b512016-09-06 20:57:50 +000036 virtual ~DynamicLoaderDarwin() override;
Jason Molenda5fe4d142016-07-17 21:27:32 +000037
Kate Stoneb9c1b512016-09-06 20:57:50 +000038 //------------------------------------------------------------------
39 /// Called after attaching a process.
40 ///
41 /// Allow DynamicLoader plug-ins to execute some code after
42 /// attaching to a process.
43 //------------------------------------------------------------------
44 void DidAttach() override;
Jason Molenda5fe4d142016-07-17 21:27:32 +000045
Kate Stoneb9c1b512016-09-06 20:57:50 +000046 void DidLaunch() override;
Jason Molenda5fe4d142016-07-17 21:27:32 +000047
Kate Stoneb9c1b512016-09-06 20:57:50 +000048 lldb::ThreadPlanSP GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
49 bool stop_others) override;
Jason Molenda5fe4d142016-07-17 21:27:32 +000050
Kate Stoneb9c1b512016-09-06 20:57:50 +000051 size_t FindEquivalentSymbols(
52 lldb_private::Symbol *original_symbol,
53 lldb_private::ModuleList &module_list,
54 lldb_private::SymbolContextList &equivalent_symbols) override;
Jason Molenda5fe4d142016-07-17 21:27:32 +000055
Kate Stoneb9c1b512016-09-06 20:57:50 +000056 lldb::addr_t GetThreadLocalData(const lldb::ModuleSP module,
57 const lldb::ThreadSP thread,
58 lldb::addr_t tls_file_addr) override;
Jason Molenda5fe4d142016-07-17 21:27:32 +000059
Kate Stoneb9c1b512016-09-06 20:57:50 +000060 bool AlwaysRelyOnEHUnwindInfo(lldb_private::SymbolContext &sym_ctx) override;
Jason Molenda5fe4d142016-07-17 21:27:32 +000061
Kate Stoneb9c1b512016-09-06 20:57:50 +000062 virtual void DoInitialImageFetch() = 0;
63
64 virtual bool NeedToDoInitialImageFetch() = 0;
Jason Molenda5fe4d142016-07-17 21:27:32 +000065
66protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +000067 void PrivateInitialize(lldb_private::Process *process);
Jason Molenda5fe4d142016-07-17 21:27:32 +000068
Kate Stoneb9c1b512016-09-06 20:57:50 +000069 void PrivateProcessStateChanged(lldb_private::Process *process,
70 lldb::StateType state);
Jason Molenda5fe4d142016-07-17 21:27:32 +000071
Kate Stoneb9c1b512016-09-06 20:57:50 +000072 void Clear(bool clear_process);
Jason Molenda5fe4d142016-07-17 21:27:32 +000073
Kate Stoneb9c1b512016-09-06 20:57:50 +000074 // Clear method for classes derived from this one
75 virtual void DoClear() = 0;
Jason Molenda5fe4d142016-07-17 21:27:32 +000076
Kate Stoneb9c1b512016-09-06 20:57:50 +000077 void SetDYLDModule(lldb::ModuleSP &dyld_module_sp);
Jason Molenda5fe4d142016-07-17 21:27:32 +000078
Kate Stoneb9c1b512016-09-06 20:57:50 +000079 lldb::ModuleSP GetDYLDModule();
Jason Molenda5fe4d142016-07-17 21:27:32 +000080
Kate Stoneb9c1b512016-09-06 20:57:50 +000081 class Segment {
82 public:
83 Segment()
84 : name(), vmaddr(LLDB_INVALID_ADDRESS), vmsize(0), fileoff(0),
85 filesize(0), maxprot(0), initprot(0), nsects(0), flags(0) {}
Jason Molenda5fe4d142016-07-17 21:27:32 +000086
Kate Stoneb9c1b512016-09-06 20:57:50 +000087 lldb_private::ConstString name;
88 lldb::addr_t vmaddr;
89 lldb::addr_t vmsize;
90 lldb::addr_t fileoff;
91 lldb::addr_t filesize;
92 uint32_t maxprot;
93 uint32_t initprot;
94 uint32_t nsects;
95 uint32_t flags;
Jason Molenda5fe4d142016-07-17 21:27:32 +000096
Kate Stoneb9c1b512016-09-06 20:57:50 +000097 bool operator==(const Segment &rhs) const {
98 return name == rhs.name && vmaddr == rhs.vmaddr && vmsize == rhs.vmsize;
Jason Molenda5fe4d142016-07-17 21:27:32 +000099 }
100
Kate Stoneb9c1b512016-09-06 20:57:50 +0000101 void PutToLog(lldb_private::Log *log, lldb::addr_t slide) const;
102 };
Jason Molenda5fe4d142016-07-17 21:27:32 +0000103
Kate Stoneb9c1b512016-09-06 20:57:50 +0000104 struct ImageInfo {
105 lldb::addr_t address; // Address of mach header for this dylib
106 lldb::addr_t slide; // The amount to slide all segments by if there is a
107 // global slide.
108 lldb::addr_t mod_date; // Modification date for this dylib
109 lldb_private::FileSpec file_spec; // Resolved path for this dylib
110 lldb_private::UUID
111 uuid; // UUID for this dylib if it has one, else all zeros
112 llvm::MachO::mach_header header; // The mach header for this image
113 std::vector<Segment> segments; // All segment vmaddr and vmsize pairs for
114 // this executable (from memory of inferior)
115 uint32_t load_stop_id; // The process stop ID that the sections for this
116 // image were loaded
117 llvm::Triple::OSType os_type; // LC_VERSION_MIN_... load command os type
118 std::string min_version_os_sdk; // LC_VERSION_MIN_... sdk value
Jason Molenda5fe4d142016-07-17 21:27:32 +0000119
Kate Stoneb9c1b512016-09-06 20:57:50 +0000120 ImageInfo()
121 : address(LLDB_INVALID_ADDRESS), slide(0), mod_date(0), file_spec(),
122 uuid(), header(), segments(), load_stop_id(0),
123 os_type(llvm::Triple::OSType::UnknownOS), min_version_os_sdk() {}
Jason Molenda5fe4d142016-07-17 21:27:32 +0000124
Kate Stoneb9c1b512016-09-06 20:57:50 +0000125 void Clear(bool load_cmd_data_only) {
126 if (!load_cmd_data_only) {
127 address = LLDB_INVALID_ADDRESS;
128 slide = 0;
129 mod_date = 0;
130 file_spec.Clear();
131 ::memset(&header, 0, sizeof(header));
132 }
133 uuid.Clear();
134 segments.clear();
135 load_stop_id = 0;
136 os_type = llvm::Triple::OSType::UnknownOS;
137 min_version_os_sdk.clear();
138 }
Jason Molenda5fe4d142016-07-17 21:27:32 +0000139
Kate Stoneb9c1b512016-09-06 20:57:50 +0000140 bool operator==(const ImageInfo &rhs) const {
141 return address == rhs.address && slide == rhs.slide &&
142 mod_date == rhs.mod_date && file_spec == rhs.file_spec &&
143 uuid == rhs.uuid &&
144 memcmp(&header, &rhs.header, sizeof(header)) == 0 &&
145 segments == rhs.segments && os_type == rhs.os_type;
146 }
Jason Molenda5fe4d142016-07-17 21:27:32 +0000147
Kate Stoneb9c1b512016-09-06 20:57:50 +0000148 bool UUIDValid() const { return uuid.IsValid(); }
Jason Molenda5fe4d142016-07-17 21:27:32 +0000149
Kate Stoneb9c1b512016-09-06 20:57:50 +0000150 uint32_t GetAddressByteSize() {
151 if (header.cputype) {
152 if (header.cputype & llvm::MachO::CPU_ARCH_ABI64)
153 return 8;
154 else
155 return 4;
156 }
157 return 0;
158 }
Jason Molenda5fe4d142016-07-17 21:27:32 +0000159
Kate Stoneb9c1b512016-09-06 20:57:50 +0000160 lldb_private::ArchSpec GetArchitecture() const {
161 return lldb_private::ArchSpec(lldb_private::eArchTypeMachO,
162 header.cputype, header.cpusubtype);
163 }
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000164
Kate Stoneb9c1b512016-09-06 20:57:50 +0000165 const Segment *FindSegment(const lldb_private::ConstString &name) const;
166
167 void PutToLog(lldb_private::Log *log) const;
168
169 typedef std::vector<ImageInfo> collection;
170 typedef collection::iterator iterator;
171 typedef collection::const_iterator const_iterator;
172 };
173
174 bool UpdateImageLoadAddress(lldb_private::Module *module, ImageInfo &info);
175
176 bool UnloadModuleSections(lldb_private::Module *module, ImageInfo &info);
177
178 lldb::ModuleSP FindTargetModuleForImageInfo(ImageInfo &image_info,
179 bool can_create,
180 bool *did_create_ptr);
181
182 void UnloadImages(const std::vector<lldb::addr_t> &solib_addresses);
183
184 void UnloadAllImages();
185
186 virtual bool SetNotificationBreakpoint() = 0;
187
188 virtual void ClearNotificationBreakpoint() = 0;
189
190 virtual bool DidSetNotificationBreakpoint() = 0;
191
192 typedef std::map<uint64_t, lldb::addr_t> PthreadKeyToTLSMap;
193 typedef std::map<lldb::user_id_t, PthreadKeyToTLSMap> ThreadIDToTLSMap;
194
195 std::recursive_mutex &GetMutex() const { return m_mutex; }
196
197 lldb::ModuleSP GetPThreadLibraryModule();
198
199 lldb_private::Address GetPthreadSetSpecificAddress();
200
201 bool JSONImageInformationIntoImageInfo(
202 lldb_private::StructuredData::ObjectSP image_details,
203 ImageInfo::collection &image_infos);
204
205 // If image_infos contains / may contain dyld or executable image, call this
206 // method
207 // to keep our internal record keeping of the special binaries up-to-date.
208 void
209 UpdateSpecialBinariesFromNewImageInfos(ImageInfo::collection &image_infos);
210
211 // if image_info is a dyld binary, call this method
212 void UpdateDYLDImageInfoFromNewImageInfo(ImageInfo &image_info);
213
214 // If image_infos contains / may contain executable image, call this method
215 // to keep our internal record keeping of the special dyld binary up-to-date.
216 void AddExecutableModuleIfInImageInfos(ImageInfo::collection &image_infos);
217
218 bool AddModulesUsingImageInfos(ImageInfo::collection &image_infos);
219
220 // Whether we should use the new dyld SPI to get shared library information,
221 // or read
222 // it directly out of the dyld_all_image_infos. Whether we use the (newer)
223 // DynamicLoaderMacOS
224 // plugin or the (older) DynamicLoaderMacOSX plugin.
225 static bool UseDYLDSPI(lldb_private::Process *process);
226
227 lldb::ModuleWP m_dyld_module_wp; // the dyld whose file type (mac, ios, etc)
228 // matches the process
229 lldb::ModuleWP m_libpthread_module_wp;
230 lldb_private::Address m_pthread_getspecific_addr;
231 ThreadIDToTLSMap m_tid_to_tls_map;
232 ImageInfo::collection
233 m_dyld_image_infos; // Current shared libraries information
234 uint32_t m_dyld_image_infos_stop_id; // The process stop ID that
235 // "m_dyld_image_infos" is valid for
236 ImageInfo m_dyld;
237 mutable std::recursive_mutex m_mutex;
Jason Molenda5fe4d142016-07-17 21:27:32 +0000238
239private:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000240 DISALLOW_COPY_AND_ASSIGN(DynamicLoaderDarwin);
Jason Molenda5fe4d142016-07-17 21:27:32 +0000241};
242
243} // namespace lldb_private
244
245#endif // liblldb_DynamicLoaderDarwin_h_