blob: b3e00830fdd949f42a081aae2a6a1b51ae38d5c4 [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
Kate Stoneb9c1b512016-09-06 20:57:50 +000031 virtual ~DynamicLoaderDarwin() override;
Jason Molenda5fe4d142016-07-17 21:27:32 +000032
Kate Stoneb9c1b512016-09-06 20:57:50 +000033 //------------------------------------------------------------------
34 /// Called after attaching a process.
35 ///
36 /// Allow DynamicLoader plug-ins to execute some code after
37 /// attaching to a process.
38 //------------------------------------------------------------------
39 void DidAttach() override;
Jason Molenda5fe4d142016-07-17 21:27:32 +000040
Kate Stoneb9c1b512016-09-06 20:57:50 +000041 void DidLaunch() override;
Jason Molenda5fe4d142016-07-17 21:27:32 +000042
Kate Stoneb9c1b512016-09-06 20:57:50 +000043 lldb::ThreadPlanSP GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
44 bool stop_others) override;
Jason Molenda5fe4d142016-07-17 21:27:32 +000045
Kate Stoneb9c1b512016-09-06 20:57:50 +000046 size_t FindEquivalentSymbols(
47 lldb_private::Symbol *original_symbol,
48 lldb_private::ModuleList &module_list,
49 lldb_private::SymbolContextList &equivalent_symbols) override;
Jason Molenda5fe4d142016-07-17 21:27:32 +000050
Kate Stoneb9c1b512016-09-06 20:57:50 +000051 lldb::addr_t GetThreadLocalData(const lldb::ModuleSP module,
52 const lldb::ThreadSP thread,
53 lldb::addr_t tls_file_addr) override;
Jason Molenda5fe4d142016-07-17 21:27:32 +000054
Kate Stoneb9c1b512016-09-06 20:57:50 +000055 bool AlwaysRelyOnEHUnwindInfo(lldb_private::SymbolContext &sym_ctx) override;
Jason Molenda5fe4d142016-07-17 21:27:32 +000056
Kate Stoneb9c1b512016-09-06 20:57:50 +000057 virtual void DoInitialImageFetch() = 0;
58
59 virtual bool NeedToDoInitialImageFetch() = 0;
Jason Molenda5fe4d142016-07-17 21:27:32 +000060
61protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +000062 void PrivateInitialize(lldb_private::Process *process);
Jason Molenda5fe4d142016-07-17 21:27:32 +000063
Kate Stoneb9c1b512016-09-06 20:57:50 +000064 void PrivateProcessStateChanged(lldb_private::Process *process,
65 lldb::StateType state);
Jason Molenda5fe4d142016-07-17 21:27:32 +000066
Kate Stoneb9c1b512016-09-06 20:57:50 +000067 void Clear(bool clear_process);
Jason Molenda5fe4d142016-07-17 21:27:32 +000068
Kate Stoneb9c1b512016-09-06 20:57:50 +000069 // Clear method for classes derived from this one
70 virtual void DoClear() = 0;
Jason Molenda5fe4d142016-07-17 21:27:32 +000071
Kate Stoneb9c1b512016-09-06 20:57:50 +000072 void SetDYLDModule(lldb::ModuleSP &dyld_module_sp);
Jason Molenda5fe4d142016-07-17 21:27:32 +000073
Kate Stoneb9c1b512016-09-06 20:57:50 +000074 lldb::ModuleSP GetDYLDModule();
Jason Molenda5fe4d142016-07-17 21:27:32 +000075
Kate Stoneb9c1b512016-09-06 20:57:50 +000076 class Segment {
77 public:
78 Segment()
79 : name(), vmaddr(LLDB_INVALID_ADDRESS), vmsize(0), fileoff(0),
80 filesize(0), maxprot(0), initprot(0), nsects(0), flags(0) {}
Jason Molenda5fe4d142016-07-17 21:27:32 +000081
Kate Stoneb9c1b512016-09-06 20:57:50 +000082 lldb_private::ConstString name;
83 lldb::addr_t vmaddr;
84 lldb::addr_t vmsize;
85 lldb::addr_t fileoff;
86 lldb::addr_t filesize;
87 uint32_t maxprot;
88 uint32_t initprot;
89 uint32_t nsects;
90 uint32_t flags;
Jason Molenda5fe4d142016-07-17 21:27:32 +000091
Kate Stoneb9c1b512016-09-06 20:57:50 +000092 bool operator==(const Segment &rhs) const {
93 return name == rhs.name && vmaddr == rhs.vmaddr && vmsize == rhs.vmsize;
Jason Molenda5fe4d142016-07-17 21:27:32 +000094 }
95
Kate Stoneb9c1b512016-09-06 20:57:50 +000096 void PutToLog(lldb_private::Log *log, lldb::addr_t slide) const;
97 };
Jason Molenda5fe4d142016-07-17 21:27:32 +000098
Kate Stoneb9c1b512016-09-06 20:57:50 +000099 struct ImageInfo {
100 lldb::addr_t address; // Address of mach header for this dylib
101 lldb::addr_t slide; // The amount to slide all segments by if there is a
102 // global slide.
103 lldb::addr_t mod_date; // Modification date for this dylib
104 lldb_private::FileSpec file_spec; // Resolved path for this dylib
105 lldb_private::UUID
106 uuid; // UUID for this dylib if it has one, else all zeros
107 llvm::MachO::mach_header header; // The mach header for this image
108 std::vector<Segment> segments; // All segment vmaddr and vmsize pairs for
109 // this executable (from memory of inferior)
110 uint32_t load_stop_id; // The process stop ID that the sections for this
111 // image were loaded
112 llvm::Triple::OSType os_type; // LC_VERSION_MIN_... load command os type
113 std::string min_version_os_sdk; // LC_VERSION_MIN_... sdk value
Jason Molenda5fe4d142016-07-17 21:27:32 +0000114
Kate Stoneb9c1b512016-09-06 20:57:50 +0000115 ImageInfo()
116 : address(LLDB_INVALID_ADDRESS), slide(0), mod_date(0), file_spec(),
117 uuid(), header(), segments(), load_stop_id(0),
118 os_type(llvm::Triple::OSType::UnknownOS), min_version_os_sdk() {}
Jason Molenda5fe4d142016-07-17 21:27:32 +0000119
Kate Stoneb9c1b512016-09-06 20:57:50 +0000120 void Clear(bool load_cmd_data_only) {
121 if (!load_cmd_data_only) {
122 address = LLDB_INVALID_ADDRESS;
123 slide = 0;
124 mod_date = 0;
125 file_spec.Clear();
126 ::memset(&header, 0, sizeof(header));
127 }
128 uuid.Clear();
129 segments.clear();
130 load_stop_id = 0;
131 os_type = llvm::Triple::OSType::UnknownOS;
132 min_version_os_sdk.clear();
133 }
Jason Molenda5fe4d142016-07-17 21:27:32 +0000134
Kate Stoneb9c1b512016-09-06 20:57:50 +0000135 bool operator==(const ImageInfo &rhs) const {
136 return address == rhs.address && slide == rhs.slide &&
137 mod_date == rhs.mod_date && file_spec == rhs.file_spec &&
138 uuid == rhs.uuid &&
139 memcmp(&header, &rhs.header, sizeof(header)) == 0 &&
140 segments == rhs.segments && os_type == rhs.os_type;
141 }
Jason Molenda5fe4d142016-07-17 21:27:32 +0000142
Kate Stoneb9c1b512016-09-06 20:57:50 +0000143 bool UUIDValid() const { return uuid.IsValid(); }
Jason Molenda5fe4d142016-07-17 21:27:32 +0000144
Kate Stoneb9c1b512016-09-06 20:57:50 +0000145 uint32_t GetAddressByteSize() {
146 if (header.cputype) {
147 if (header.cputype & llvm::MachO::CPU_ARCH_ABI64)
148 return 8;
149 else
150 return 4;
151 }
152 return 0;
153 }
Jason Molenda5fe4d142016-07-17 21:27:32 +0000154
Kate Stoneb9c1b512016-09-06 20:57:50 +0000155 lldb_private::ArchSpec GetArchitecture() const {
156 return lldb_private::ArchSpec(lldb_private::eArchTypeMachO,
157 header.cputype, header.cpusubtype);
158 }
Jason Molenda9ab5dc22016-07-21 08:30:55 +0000159
Kate Stoneb9c1b512016-09-06 20:57:50 +0000160 const Segment *FindSegment(const lldb_private::ConstString &name) const;
161
162 void PutToLog(lldb_private::Log *log) const;
163
164 typedef std::vector<ImageInfo> collection;
165 typedef collection::iterator iterator;
166 typedef collection::const_iterator const_iterator;
167 };
168
169 bool UpdateImageLoadAddress(lldb_private::Module *module, ImageInfo &info);
170
171 bool UnloadModuleSections(lldb_private::Module *module, ImageInfo &info);
172
173 lldb::ModuleSP FindTargetModuleForImageInfo(ImageInfo &image_info,
174 bool can_create,
175 bool *did_create_ptr);
176
177 void UnloadImages(const std::vector<lldb::addr_t> &solib_addresses);
178
179 void UnloadAllImages();
180
181 virtual bool SetNotificationBreakpoint() = 0;
182
183 virtual void ClearNotificationBreakpoint() = 0;
184
185 virtual bool DidSetNotificationBreakpoint() = 0;
186
187 typedef std::map<uint64_t, lldb::addr_t> PthreadKeyToTLSMap;
188 typedef std::map<lldb::user_id_t, PthreadKeyToTLSMap> ThreadIDToTLSMap;
189
190 std::recursive_mutex &GetMutex() const { return m_mutex; }
191
192 lldb::ModuleSP GetPThreadLibraryModule();
193
194 lldb_private::Address GetPthreadSetSpecificAddress();
195
196 bool JSONImageInformationIntoImageInfo(
197 lldb_private::StructuredData::ObjectSP image_details,
198 ImageInfo::collection &image_infos);
199
200 // If image_infos contains / may contain dyld or executable image, call this
201 // method
202 // to keep our internal record keeping of the special binaries up-to-date.
203 void
204 UpdateSpecialBinariesFromNewImageInfos(ImageInfo::collection &image_infos);
205
206 // if image_info is a dyld binary, call this method
207 void UpdateDYLDImageInfoFromNewImageInfo(ImageInfo &image_info);
208
209 // If image_infos contains / may contain executable image, call this method
210 // to keep our internal record keeping of the special dyld binary up-to-date.
211 void AddExecutableModuleIfInImageInfos(ImageInfo::collection &image_infos);
212
213 bool AddModulesUsingImageInfos(ImageInfo::collection &image_infos);
214
215 // Whether we should use the new dyld SPI to get shared library information,
216 // or read
217 // it directly out of the dyld_all_image_infos. Whether we use the (newer)
218 // DynamicLoaderMacOS
219 // plugin or the (older) DynamicLoaderMacOSX plugin.
220 static bool UseDYLDSPI(lldb_private::Process *process);
221
222 lldb::ModuleWP m_dyld_module_wp; // the dyld whose file type (mac, ios, etc)
223 // matches the process
224 lldb::ModuleWP m_libpthread_module_wp;
225 lldb_private::Address m_pthread_getspecific_addr;
226 ThreadIDToTLSMap m_tid_to_tls_map;
227 ImageInfo::collection
228 m_dyld_image_infos; // Current shared libraries information
229 uint32_t m_dyld_image_infos_stop_id; // The process stop ID that
230 // "m_dyld_image_infos" is valid for
231 ImageInfo m_dyld;
232 mutable std::recursive_mutex m_mutex;
Jason Molenda5fe4d142016-07-17 21:27:32 +0000233
234private:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000235 DISALLOW_COPY_AND_ASSIGN(DynamicLoaderDarwin);
Jason Molenda5fe4d142016-07-17 21:27:32 +0000236};
237
238} // namespace lldb_private
239
240#endif // liblldb_DynamicLoaderDarwin_h_