1//===-- DynamicLoaderDarwin.h -------------------------------*- C++ -*-===//
2//
3// 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
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLDB_SOURCE_PLUGINS_DYNAMICLOADER_MACOSX_DYLD_DYNAMICLOADERDARWIN_H
10#define LLDB_SOURCE_PLUGINS_DYNAMICLOADER_MACOSX_DYLD_DYNAMICLOADERDARWIN_H
11
12#include <map>
13#include <mutex>
14#include <vector>
15
16#include "lldb/Host/SafeMachO.h"
17#include "lldb/Target/DynamicLoader.h"
18#include "lldb/Target/Process.h"
19#include "lldb/Utility/FileSpec.h"
20#include "lldb/Utility/StructuredData.h"
21#include "lldb/Utility/UUID.h"
22
23#include "llvm/TargetParser/Triple.h"
24
25namespace lldb_private {
26
27class DynamicLoaderDarwin : public lldb_private::DynamicLoader {
28public:
29 DynamicLoaderDarwin(lldb_private::Process *process);
30
31 ~DynamicLoaderDarwin() override;
32
33 /// Called after attaching a process.
34 ///
35 /// Allow DynamicLoader plug-ins to execute some code after
36 /// attaching to a process.
37 void DidAttach() override;
38
39 void DidLaunch() override;
40
41 lldb::ThreadPlanSP GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
42 bool stop_others) override;
43
44 void FindEquivalentSymbols(
45 lldb_private::Symbol *original_symbol,
46 lldb_private::ModuleList &module_list,
47 lldb_private::SymbolContextList &equivalent_symbols) override;
48
49 lldb::addr_t GetThreadLocalData(const lldb::ModuleSP module,
50 const lldb::ThreadSP thread,
51 lldb::addr_t tls_file_addr) override;
52
53 bool AlwaysRelyOnEHUnwindInfo(lldb_private::SymbolContext &sym_ctx) override;
54
55 virtual void DoInitialImageFetch() = 0;
56
57 virtual bool NeedToDoInitialImageFetch() = 0;
58
59protected:
60 void PrivateInitialize(lldb_private::Process *process);
61
62 void PrivateProcessStateChanged(lldb_private::Process *process,
63 lldb::StateType state);
64
65 void Clear(bool clear_process);
66
67 // Clear method for classes derived from this one
68 virtual void DoClear() = 0;
69
70 void SetDYLDModule(lldb::ModuleSP &dyld_module_sp);
71
72 lldb::ModuleSP GetDYLDModule();
73
74 void ClearDYLDModule();
75
76 class Segment {
77 public:
78 Segment() : name() {}
79
80 lldb_private::ConstString name;
81 lldb::addr_t vmaddr = LLDB_INVALID_ADDRESS;
82 lldb::addr_t vmsize = 0;
83 lldb::addr_t fileoff = 0;
84 lldb::addr_t filesize = 0;
85 uint32_t maxprot = 0;
86 uint32_t initprot = 0;
87 uint32_t nsects = 0;
88 uint32_t flags = 0;
89
90 bool operator==(const Segment &rhs) const {
91 return name == rhs.name && vmaddr == rhs.vmaddr && vmsize == rhs.vmsize;
92 }
93
94 void PutToLog(lldb_private::Log *log, lldb::addr_t slide) const;
95 };
96
97 struct ImageInfo {
98 /// 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 /// Resolved path for this dylib.
104 lldb_private::FileSpec file_spec;
105 /// UUID for this dylib if it has one, else all zeros.
106 lldb_private::UUID uuid;
107 /// The mach header for this image.
108 llvm::MachO::mach_header header;
109 /// All segment vmaddr and vmsize pairs for this executable (from
110 /// memory of inferior).
111 std::vector<Segment> segments;
112 /// The process stop ID that the sections for this image were
113 /// loaded.
114 uint32_t load_stop_id = 0;
115 /// LC_VERSION_MIN_... load command os type.
116 llvm::Triple::OSType os_type = llvm::Triple::OSType::UnknownOS;
117 /// LC_VERSION_MIN_... load command os environment.
118 llvm::Triple::EnvironmentType os_env =
119 llvm::Triple::EnvironmentType::UnknownEnvironment;
120 /// LC_VERSION_MIN_... SDK.
121 std::string min_version_os_sdk;
122
123 ImageInfo() = default;
124
125 void Clear(bool load_cmd_data_only) {
126 if (!load_cmd_data_only) {
127 address = LLDB_INVALID_ADDRESS;
128 slide = 0;
129 file_spec.Clear();
130 ::memset(s: &header, c: 0, n: sizeof(header));
131 }
132 uuid.Clear();
133 segments.clear();
134 load_stop_id = 0;
135 os_type = llvm::Triple::OSType::UnknownOS;
136 os_env = llvm::Triple::EnvironmentType::UnknownEnvironment;
137 min_version_os_sdk.clear();
138 }
139
140 bool operator==(const ImageInfo &rhs) const {
141 return address == rhs.address && slide == rhs.slide &&
142 file_spec == rhs.file_spec && uuid == rhs.uuid &&
143 memcmp(s1: &header, s2: &rhs.header, n: sizeof(header)) == 0 &&
144 segments == rhs.segments && os_type == rhs.os_type &&
145 os_env == rhs.os_env;
146 }
147
148 bool UUIDValid() const { return uuid.IsValid(); }
149
150 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 }
159
160 lldb_private::ArchSpec GetArchitecture() const;
161
162 const Segment *FindSegment(lldb_private::ConstString name) const;
163
164 void PutToLog(lldb_private::Log *log) const;
165
166 typedef std::vector<ImageInfo> collection;
167 typedef collection::iterator iterator;
168 typedef collection::const_iterator const_iterator;
169 };
170
171 bool UpdateImageLoadAddress(lldb_private::Module *module, ImageInfo &info);
172
173 bool UnloadModuleSections(lldb_private::Module *module, ImageInfo &info);
174
175 lldb::ModuleSP FindTargetModuleForImageInfo(ImageInfo &image_info,
176 bool can_create,
177 bool *did_create_ptr);
178
179 void UnloadImages(const std::vector<lldb::addr_t> &solib_addresses);
180
181 void UnloadAllImages();
182
183 virtual bool SetNotificationBreakpoint() = 0;
184
185 virtual void ClearNotificationBreakpoint() = 0;
186
187 virtual bool DidSetNotificationBreakpoint() = 0;
188
189 typedef std::map<uint64_t, lldb::addr_t> PthreadKeyToTLSMap;
190 typedef std::map<lldb::user_id_t, PthreadKeyToTLSMap> ThreadIDToTLSMap;
191
192 std::recursive_mutex &GetMutex() const { return m_mutex; }
193
194 lldb::ModuleSP GetPThreadLibraryModule();
195
196 lldb_private::Address GetPthreadSetSpecificAddress();
197
198 bool JSONImageInformationIntoImageInfo(
199 lldb_private::StructuredData::ObjectSP image_details,
200 ImageInfo::collection &image_infos);
201
202 // If image_infos contains / may contain dyld or executable image, call this
203 // method
204 // to keep our internal record keeping of the special binaries up-to-date.
205 void
206 UpdateSpecialBinariesFromNewImageInfos(ImageInfo::collection &image_infos);
207
208 // if image_info is a dyld binary, call this method
209 void UpdateDYLDImageInfoFromNewImageInfo(ImageInfo &image_info);
210
211 // If image_infos contains / may contain executable image, call this method
212 // to keep our internal record keeping of the special dyld binary up-to-date.
213 void AddExecutableModuleIfInImageInfos(ImageInfo::collection &image_infos);
214
215 bool AddModulesUsingImageInfos(ImageInfo::collection &image_infos);
216
217 // Whether we should use the new dyld SPI to get shared library information,
218 // or read
219 // it directly out of the dyld_all_image_infos. Whether we use the (newer)
220 // DynamicLoaderMacOS
221 // plugin or the (older) DynamicLoaderMacOSX plugin.
222 static bool UseDYLDSPI(lldb_private::Process *process);
223
224 lldb::ModuleWP m_dyld_module_wp; // the dyld whose file type (mac, ios, etc)
225 // matches the process
226 lldb::ModuleWP m_libpthread_module_wp;
227 lldb_private::Address m_pthread_getspecific_addr;
228 ThreadIDToTLSMap m_tid_to_tls_map;
229 ImageInfo::collection
230 m_dyld_image_infos; // Current shared libraries information
231 uint32_t m_dyld_image_infos_stop_id; // The process stop ID that
232 // "m_dyld_image_infos" is valid for
233 ImageInfo m_dyld;
234 mutable std::recursive_mutex m_mutex;
235
236private:
237 DynamicLoaderDarwin(const DynamicLoaderDarwin &) = delete;
238 const DynamicLoaderDarwin &operator=(const DynamicLoaderDarwin &) = delete;
239};
240
241} // namespace lldb_private
242
243#endif // LLDB_SOURCE_PLUGINS_DYNAMICLOADER_MACOSX_DYLD_DYNAMICLOADERDARWIN_H
244

source code of lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h