blob: ea7a900d39c55b607a82261ddc022ad96bc2a203 [file] [log] [blame]
Jason Molenda5fe4d142016-07-17 21:27:32 +00001//===-- DynamicLoaderDarwin.h -------------------------------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Jason Molenda5fe4d142016-07-17 21:27:32 +00006//
7//===----------------------------------------------------------------------===//
8
9#ifndef liblldb_DynamicLoaderDarwin_h_
10#define liblldb_DynamicLoaderDarwin_h_
11
Jason Molenda5fe4d142016-07-17 21:27:32 +000012#include <map>
13#include <mutex>
14#include <vector>
15
Pavel Labath77044732018-09-12 12:26:05 +000016#include "lldb/Host/SafeMachO.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000017#include "lldb/Target/DynamicLoader.h"
Jason Molenda5fe4d142016-07-17 21:27:32 +000018#include "lldb/Target/Process.h"
Zachary Turner5713a052017-03-22 18:40:07 +000019#include "lldb/Utility/FileSpec.h"
Pavel Labathf2a8bcc2017-06-27 10:45:31 +000020#include "lldb/Utility/StructuredData.h"
Zachary Turner5713a052017-03-22 18:40:07 +000021#include "lldb/Utility/UUID.h"
Jason Molenda5fe4d142016-07-17 21:27:32 +000022
Jason Molenda9ab5dc22016-07-21 08:30:55 +000023#include "llvm/ADT/Triple.h"
24
Jason Molenda5fe4d142016-07-17 21:27:32 +000025namespace lldb_private {
26
Kate Stoneb9c1b512016-09-06 20:57:50 +000027class DynamicLoaderDarwin : public lldb_private::DynamicLoader {
Jason Molenda5fe4d142016-07-17 21:27:32 +000028public:
Kate Stoneb9c1b512016-09-06 20:57:50 +000029 DynamicLoaderDarwin(lldb_private::Process *process);
Jason Molenda5fe4d142016-07-17 21:27:32 +000030
Raphael Isemann17566302019-05-03 10:03:28 +000031 ~DynamicLoaderDarwin() override;
Jason Molenda5fe4d142016-07-17 21:27:32 +000032
Kate Stoneb9c1b512016-09-06 20:57:50 +000033 /// Called after attaching a process.
34 ///
35 /// Allow DynamicLoader plug-ins to execute some code after
36 /// attaching to a process.
Kate Stoneb9c1b512016-09-06 20:57:50 +000037 void DidAttach() override;
Jason Molenda5fe4d142016-07-17 21:27:32 +000038
Kate Stoneb9c1b512016-09-06 20:57:50 +000039 void DidLaunch() override;
Jason Molenda5fe4d142016-07-17 21:27:32 +000040
Kate Stoneb9c1b512016-09-06 20:57:50 +000041 lldb::ThreadPlanSP GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
42 bool stop_others) override;
Jason Molenda5fe4d142016-07-17 21:27:32 +000043
Adrian Prantl1ad655e2019-10-17 19:56:40 +000044 void FindEquivalentSymbols(
Kate Stoneb9c1b512016-09-06 20:57:50 +000045 lldb_private::Symbol *original_symbol,
46 lldb_private::ModuleList &module_list,
47 lldb_private::SymbolContextList &equivalent_symbols) override;
Jason Molenda5fe4d142016-07-17 21:27:32 +000048
Kate Stoneb9c1b512016-09-06 20:57:50 +000049 lldb::addr_t GetThreadLocalData(const lldb::ModuleSP module,
50 const lldb::ThreadSP thread,
51 lldb::addr_t tls_file_addr) override;
Jason Molenda5fe4d142016-07-17 21:27:32 +000052
Kate Stoneb9c1b512016-09-06 20:57:50 +000053 bool AlwaysRelyOnEHUnwindInfo(lldb_private::SymbolContext &sym_ctx) override;
Jason Molenda5fe4d142016-07-17 21:27:32 +000054
Kate Stoneb9c1b512016-09-06 20:57:50 +000055 virtual void DoInitialImageFetch() = 0;
56
57 virtual bool NeedToDoInitialImageFetch() = 0;
Jason Molenda5fe4d142016-07-17 21:27:32 +000058
59protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +000060 void PrivateInitialize(lldb_private::Process *process);
Jason Molenda5fe4d142016-07-17 21:27:32 +000061
Kate Stoneb9c1b512016-09-06 20:57:50 +000062 void PrivateProcessStateChanged(lldb_private::Process *process,
63 lldb::StateType state);
Jason Molenda5fe4d142016-07-17 21:27:32 +000064
Kate Stoneb9c1b512016-09-06 20:57:50 +000065 void Clear(bool clear_process);
Jason Molenda5fe4d142016-07-17 21:27:32 +000066
Kate Stoneb9c1b512016-09-06 20:57:50 +000067 // Clear method for classes derived from this one
68 virtual void DoClear() = 0;
Jason Molenda5fe4d142016-07-17 21:27:32 +000069
Kate Stoneb9c1b512016-09-06 20:57:50 +000070 void SetDYLDModule(lldb::ModuleSP &dyld_module_sp);
Jason Molenda5fe4d142016-07-17 21:27:32 +000071
Kate Stoneb9c1b512016-09-06 20:57:50 +000072 lldb::ModuleSP GetDYLDModule();
Jason Molenda5fe4d142016-07-17 21:27:32 +000073
Kate Stoneb9c1b512016-09-06 20:57:50 +000074 class Segment {
75 public:
76 Segment()
77 : name(), vmaddr(LLDB_INVALID_ADDRESS), vmsize(0), fileoff(0),
78 filesize(0), maxprot(0), initprot(0), nsects(0), flags(0) {}
Jason Molenda5fe4d142016-07-17 21:27:32 +000079
Kate Stoneb9c1b512016-09-06 20:57:50 +000080 lldb_private::ConstString name;
81 lldb::addr_t vmaddr;
82 lldb::addr_t vmsize;
83 lldb::addr_t fileoff;
84 lldb::addr_t filesize;
85 uint32_t maxprot;
86 uint32_t initprot;
87 uint32_t nsects;
88 uint32_t flags;
Jason Molenda5fe4d142016-07-17 21:27:32 +000089
Kate Stoneb9c1b512016-09-06 20:57:50 +000090 bool operator==(const Segment &rhs) const {
91 return name == rhs.name && vmaddr == rhs.vmaddr && vmsize == rhs.vmsize;
Jason Molenda5fe4d142016-07-17 21:27:32 +000092 }
93
Kate Stoneb9c1b512016-09-06 20:57:50 +000094 void PutToLog(lldb_private::Log *log, lldb::addr_t slide) const;
95 };
Jason Molenda5fe4d142016-07-17 21:27:32 +000096
Kate Stoneb9c1b512016-09-06 20:57:50 +000097 struct ImageInfo {
Adrian Prantl24610612019-09-04 17:23:15 +000098 /// Address of mach header for this dylib.
99 lldb::addr_t address = LLDB_INVALID_ADDRESS;
100 /// The amount to slide all segments by if there is a global
101 /// slide.
102 lldb::addr_t slide = 0;
103 /// Modification date for this dylib.
104 lldb::addr_t mod_date = 0;
105 /// Resolved path for this dylib.
106 lldb_private::FileSpec file_spec;
107 /// UUID for this dylib if it has one, else all zeros.
108 lldb_private::UUID uuid;
109 /// The mach header for this image.
110 llvm::MachO::mach_header header;
111 /// All segment vmaddr and vmsize pairs for this executable (from
112 /// memory of inferior).
113 std::vector<Segment> segments;
114 /// The process stop ID that the sections for this image were
115 /// loaded.
116 uint32_t load_stop_id = 0;
117 /// LC_VERSION_MIN_... load command os type.
118 llvm::Triple::OSType os_type = llvm::Triple::OSType::UnknownOS;
119 /// LC_VERSION_MIN_... load command os environment.
120 llvm::Triple::EnvironmentType os_env =
121 llvm::Triple::EnvironmentType::UnknownEnvironment;
122 /// LC_VERSION_MIN_... SDK.
123 std::string min_version_os_sdk;
Jason Molenda5fe4d142016-07-17 21:27:32 +0000124
Adrian Prantl24610612019-09-04 17:23:15 +0000125 ImageInfo() = default;
Jason Molenda5fe4d142016-07-17 21:27:32 +0000126
Kate Stoneb9c1b512016-09-06 20:57:50 +0000127 void Clear(bool load_cmd_data_only) {
128 if (!load_cmd_data_only) {
129 address = LLDB_INVALID_ADDRESS;
130 slide = 0;
131 mod_date = 0;
132 file_spec.Clear();
133 ::memset(&header, 0, sizeof(header));
134 }
135 uuid.Clear();
136 segments.clear();
137 load_stop_id = 0;
138 os_type = llvm::Triple::OSType::UnknownOS;
Adrian Prantl24610612019-09-04 17:23:15 +0000139 os_env = llvm::Triple::EnvironmentType::UnknownEnvironment;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000140 min_version_os_sdk.clear();
141 }
Jason Molenda5fe4d142016-07-17 21:27:32 +0000142
Kate Stoneb9c1b512016-09-06 20:57:50 +0000143 bool operator==(const ImageInfo &rhs) const {
144 return address == rhs.address && slide == rhs.slide &&
145 mod_date == rhs.mod_date && file_spec == rhs.file_spec &&
146 uuid == rhs.uuid &&
147 memcmp(&header, &rhs.header, sizeof(header)) == 0 &&
Adrian Prantl24610612019-09-04 17:23:15 +0000148 segments == rhs.segments && os_type == rhs.os_type &&
149 os_env == rhs.os_env;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000150 }
Jason Molenda5fe4d142016-07-17 21:27:32 +0000151
Kate Stoneb9c1b512016-09-06 20:57:50 +0000152 bool UUIDValid() const { return uuid.IsValid(); }
Jason Molenda5fe4d142016-07-17 21:27:32 +0000153
Kate Stoneb9c1b512016-09-06 20:57:50 +0000154 uint32_t GetAddressByteSize() {
155 if (header.cputype) {
156 if (header.cputype & llvm::MachO::CPU_ARCH_ABI64)
157 return 8;
158 else
159 return 4;
160 }
161 return 0;
162 }
Jason Molenda5fe4d142016-07-17 21:27:32 +0000163
Adrian Prantl24610612019-09-04 17:23:15 +0000164 lldb_private::ArchSpec GetArchitecture() const;
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000165
Adrian Prantl0e4c4822019-03-06 21:22:25 +0000166 const Segment *FindSegment(lldb_private::ConstString name) const;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000167
168 void PutToLog(lldb_private::Log *log) const;
169
170 typedef std::vector<ImageInfo> collection;
171 typedef collection::iterator iterator;
172 typedef collection::const_iterator const_iterator;
173 };
174
175 bool UpdateImageLoadAddress(lldb_private::Module *module, ImageInfo &info);
176
177 bool UnloadModuleSections(lldb_private::Module *module, ImageInfo &info);
178
179 lldb::ModuleSP FindTargetModuleForImageInfo(ImageInfo &image_info,
180 bool can_create,
181 bool *did_create_ptr);
182
183 void UnloadImages(const std::vector<lldb::addr_t> &solib_addresses);
184
185 void UnloadAllImages();
186
187 virtual bool SetNotificationBreakpoint() = 0;
188
189 virtual void ClearNotificationBreakpoint() = 0;
190
191 virtual bool DidSetNotificationBreakpoint() = 0;
192
193 typedef std::map<uint64_t, lldb::addr_t> PthreadKeyToTLSMap;
194 typedef std::map<lldb::user_id_t, PthreadKeyToTLSMap> ThreadIDToTLSMap;
195
196 std::recursive_mutex &GetMutex() const { return m_mutex; }
197
198 lldb::ModuleSP GetPThreadLibraryModule();
199
200 lldb_private::Address GetPthreadSetSpecificAddress();
201
202 bool JSONImageInformationIntoImageInfo(
203 lldb_private::StructuredData::ObjectSP image_details,
204 ImageInfo::collection &image_infos);
205
206 // If image_infos contains / may contain dyld or executable image, call this
207 // method
208 // to keep our internal record keeping of the special binaries up-to-date.
209 void
210 UpdateSpecialBinariesFromNewImageInfos(ImageInfo::collection &image_infos);
211
212 // if image_info is a dyld binary, call this method
213 void UpdateDYLDImageInfoFromNewImageInfo(ImageInfo &image_info);
214
215 // If image_infos contains / may contain executable image, call this method
216 // to keep our internal record keeping of the special dyld binary up-to-date.
217 void AddExecutableModuleIfInImageInfos(ImageInfo::collection &image_infos);
218
219 bool AddModulesUsingImageInfos(ImageInfo::collection &image_infos);
220
221 // Whether we should use the new dyld SPI to get shared library information,
222 // or read
223 // it directly out of the dyld_all_image_infos. Whether we use the (newer)
224 // DynamicLoaderMacOS
225 // plugin or the (older) DynamicLoaderMacOSX plugin.
226 static bool UseDYLDSPI(lldb_private::Process *process);
227
228 lldb::ModuleWP m_dyld_module_wp; // the dyld whose file type (mac, ios, etc)
229 // matches the process
230 lldb::ModuleWP m_libpthread_module_wp;
231 lldb_private::Address m_pthread_getspecific_addr;
232 ThreadIDToTLSMap m_tid_to_tls_map;
233 ImageInfo::collection
234 m_dyld_image_infos; // Current shared libraries information
235 uint32_t m_dyld_image_infos_stop_id; // The process stop ID that
236 // "m_dyld_image_infos" is valid for
237 ImageInfo m_dyld;
238 mutable std::recursive_mutex m_mutex;
Jason Molenda5fe4d142016-07-17 21:27:32 +0000239
240private:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000241 DISALLOW_COPY_AND_ASSIGN(DynamicLoaderDarwin);
Jason Molenda5fe4d142016-07-17 21:27:32 +0000242};
243
244} // namespace lldb_private
245
246#endif // liblldb_DynamicLoaderDarwin_h_