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 25 namespace lldb_private { 26 27 class DynamicLoaderDarwin : public lldb_private::DynamicLoader { 28 public: 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 59 std::optional<lldb_private::Address> GetStartAddress() override; 60 61 static void CreateSettings(lldb_private::Debugger &debugger); 62 63 protected: 64 void PrivateInitialize(lldb_private::Process *process); 65 66 void PrivateProcessStateChanged(lldb_private::Process *process, 67 lldb::StateType state); 68 69 void Clear(bool clear_process); 70 71 // Clear method for classes derived from this one 72 virtual void DoClear() = 0; 73 74 void SetDYLDModule(lldb::ModuleSP &dyld_module_sp); 75 76 lldb::ModuleSP GetDYLDModule(); 77 78 void ClearDYLDModule(); 79 80 class Segment { 81 public: 82 Segment() : name() {} 83 84 lldb_private::ConstString name; 85 lldb::addr_t vmaddr = LLDB_INVALID_ADDRESS; 86 lldb::addr_t vmsize = 0; 87 lldb::addr_t fileoff = 0; 88 lldb::addr_t filesize = 0; 89 uint32_t maxprot = 0; 90 uint32_t initprot = 0; 91 uint32_t nsects = 0; 92 uint32_t flags = 0; 93 94 bool operator==(const Segment &rhs) const { 95 return name == rhs.name && vmaddr == rhs.vmaddr && vmsize == rhs.vmsize; 96 } 97 98 void PutToLog(lldb_private::Log *log, lldb::addr_t slide) const; 99 }; 100 101 struct ImageInfo { 102 /// Address of mach header for this dylib. 103 lldb::addr_t address = LLDB_INVALID_ADDRESS; 104 /// The amount to slide all segments by if there is a global 105 /// slide. 106 lldb::addr_t slide = 0; 107 /// Resolved path for this dylib. 108 lldb_private::FileSpec file_spec; 109 /// UUID for this dylib if it has one, else all zeros. 110 lldb_private::UUID uuid; 111 /// The mach header for this image. 112 llvm::MachO::mach_header header; 113 /// All segment vmaddr and vmsize pairs for this executable (from 114 /// memory of inferior). 115 std::vector<Segment> segments; 116 /// The process stop ID that the sections for this image were 117 /// loaded. 118 uint32_t load_stop_id = 0; 119 /// LC_VERSION_MIN_... load command os type. 120 llvm::Triple::OSType os_type = llvm::Triple::OSType::UnknownOS; 121 /// LC_VERSION_MIN_... load command os environment. 122 llvm::Triple::EnvironmentType os_env = 123 llvm::Triple::EnvironmentType::UnknownEnvironment; 124 /// LC_VERSION_MIN_... SDK. 125 std::string min_version_os_sdk; 126 127 ImageInfo() = default; 128 129 void Clear(bool load_cmd_data_only) { 130 if (!load_cmd_data_only) { 131 address = LLDB_INVALID_ADDRESS; 132 slide = 0; 133 file_spec.Clear(); 134 ::memset(&header, 0, sizeof(header)); 135 } 136 uuid.Clear(); 137 segments.clear(); 138 load_stop_id = 0; 139 os_type = llvm::Triple::OSType::UnknownOS; 140 os_env = llvm::Triple::EnvironmentType::UnknownEnvironment; 141 min_version_os_sdk.clear(); 142 } 143 144 bool operator==(const ImageInfo &rhs) const { 145 return address == rhs.address && slide == rhs.slide && 146 file_spec == rhs.file_spec && uuid == rhs.uuid && 147 memcmp(&header, &rhs.header, sizeof(header)) == 0 && 148 segments == rhs.segments && os_type == rhs.os_type && 149 os_env == rhs.os_env; 150 } 151 152 bool UUIDValid() const { return uuid.IsValid(); } 153 154 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 } 163 164 lldb_private::ArchSpec GetArchitecture() const; 165 166 const Segment *FindSegment(lldb_private::ConstString name) const; 167 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(const 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 // Finds/loads modules for a given `image_infos` and returns pairs 207 // (ImageInfo, ModuleSP). 208 // Prefer using this method rather than calling `FindTargetModuleForImageInfo` 209 // directly as this method may load the modules in parallel. 210 std::vector<std::pair<ImageInfo, lldb::ModuleSP>> 211 PreloadModulesFromImageInfos(const ImageInfo::collection &image_infos); 212 213 // If `images` contains / may contain dyld or executable image, call this 214 // method to keep our internal record keeping of the special binaries 215 // up-to-date. 216 void UpdateSpecialBinariesFromPreloadedModules( 217 std::vector<std::pair<ImageInfo, lldb::ModuleSP>> &images); 218 219 // if image_info is a dyld binary, call this method 220 bool UpdateDYLDImageInfoFromNewImageInfo(ImageInfo &image_info); 221 222 // If image_infos contains / may contain executable image, call this method 223 // to keep our internal record keeping of the special dyld binary up-to-date. 224 void AddExecutableModuleIfInImageInfos(ImageInfo::collection &image_infos); 225 226 bool AddModulesUsingImageInfos(ImageInfo::collection &image_infos); 227 bool AddModulesUsingPreloadedModules( 228 std::vector<std::pair<ImageInfo, lldb::ModuleSP>> &images); 229 230 // Whether we should use the new dyld SPI to get shared library information, 231 // or read 232 // it directly out of the dyld_all_image_infos. Whether we use the (newer) 233 // DynamicLoaderMacOS 234 // plugin or the (older) DynamicLoaderMacOSX plugin. 235 static bool UseDYLDSPI(lldb_private::Process *process); 236 237 lldb::ModuleWP m_dyld_module_wp; // the dyld whose file type (mac, ios, etc) 238 // matches the process 239 lldb::ModuleWP m_libpthread_module_wp; 240 lldb_private::Address m_pthread_getspecific_addr; 241 ThreadIDToTLSMap m_tid_to_tls_map; 242 ImageInfo::collection 243 m_dyld_image_infos; // Current shared libraries information 244 uint32_t m_dyld_image_infos_stop_id; // The process stop ID that 245 // "m_dyld_image_infos" is valid for 246 ImageInfo m_dyld; 247 mutable std::recursive_mutex m_mutex; 248 249 private: 250 DynamicLoaderDarwin(const DynamicLoaderDarwin &) = delete; 251 const DynamicLoaderDarwin &operator=(const DynamicLoaderDarwin &) = delete; 252 }; 253 254 } // namespace lldb_private 255 256 #endif // LLDB_SOURCE_PLUGINS_DYNAMICLOADER_MACOSX_DYLD_DYNAMICLOADERDARWIN_H 257