1061da546Spatrick //===-- DynamicLoaderDarwin.h -------------------------------*- C++ -*-===// 2061da546Spatrick // 3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information. 5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6061da546Spatrick // 7061da546Spatrick //===----------------------------------------------------------------------===// 8061da546Spatrick 9dda28197Spatrick #ifndef LLDB_SOURCE_PLUGINS_DYNAMICLOADER_MACOSX_DYLD_DYNAMICLOADERDARWIN_H 10dda28197Spatrick #define LLDB_SOURCE_PLUGINS_DYNAMICLOADER_MACOSX_DYLD_DYNAMICLOADERDARWIN_H 11061da546Spatrick 12061da546Spatrick #include <map> 13061da546Spatrick #include <mutex> 14061da546Spatrick #include <vector> 15061da546Spatrick 16061da546Spatrick #include "lldb/Host/SafeMachO.h" 17061da546Spatrick #include "lldb/Target/DynamicLoader.h" 18061da546Spatrick #include "lldb/Target/Process.h" 19061da546Spatrick #include "lldb/Utility/FileSpec.h" 20061da546Spatrick #include "lldb/Utility/StructuredData.h" 21061da546Spatrick #include "lldb/Utility/UUID.h" 22061da546Spatrick 23061da546Spatrick #include "llvm/ADT/Triple.h" 24061da546Spatrick 25061da546Spatrick namespace lldb_private { 26061da546Spatrick 27061da546Spatrick class DynamicLoaderDarwin : public lldb_private::DynamicLoader { 28061da546Spatrick public: 29061da546Spatrick DynamicLoaderDarwin(lldb_private::Process *process); 30061da546Spatrick 31061da546Spatrick ~DynamicLoaderDarwin() override; 32061da546Spatrick 33061da546Spatrick /// Called after attaching a process. 34061da546Spatrick /// 35061da546Spatrick /// Allow DynamicLoader plug-ins to execute some code after 36061da546Spatrick /// attaching to a process. 37061da546Spatrick void DidAttach() override; 38061da546Spatrick 39061da546Spatrick void DidLaunch() override; 40061da546Spatrick 41061da546Spatrick lldb::ThreadPlanSP GetStepThroughTrampolinePlan(lldb_private::Thread &thread, 42061da546Spatrick bool stop_others) override; 43061da546Spatrick 44061da546Spatrick void FindEquivalentSymbols( 45061da546Spatrick lldb_private::Symbol *original_symbol, 46061da546Spatrick lldb_private::ModuleList &module_list, 47061da546Spatrick lldb_private::SymbolContextList &equivalent_symbols) override; 48061da546Spatrick 49061da546Spatrick lldb::addr_t GetThreadLocalData(const lldb::ModuleSP module, 50061da546Spatrick const lldb::ThreadSP thread, 51061da546Spatrick lldb::addr_t tls_file_addr) override; 52061da546Spatrick 53061da546Spatrick bool AlwaysRelyOnEHUnwindInfo(lldb_private::SymbolContext &sym_ctx) override; 54061da546Spatrick 55061da546Spatrick virtual void DoInitialImageFetch() = 0; 56061da546Spatrick 57061da546Spatrick virtual bool NeedToDoInitialImageFetch() = 0; 58061da546Spatrick 59061da546Spatrick protected: 60061da546Spatrick void PrivateInitialize(lldb_private::Process *process); 61061da546Spatrick 62061da546Spatrick void PrivateProcessStateChanged(lldb_private::Process *process, 63061da546Spatrick lldb::StateType state); 64061da546Spatrick 65061da546Spatrick void Clear(bool clear_process); 66061da546Spatrick 67061da546Spatrick // Clear method for classes derived from this one 68061da546Spatrick virtual void DoClear() = 0; 69061da546Spatrick 70061da546Spatrick void SetDYLDModule(lldb::ModuleSP &dyld_module_sp); 71061da546Spatrick 72061da546Spatrick lldb::ModuleSP GetDYLDModule(); 73061da546Spatrick 74*f6aab3d8Srobert void ClearDYLDModule(); 75*f6aab3d8Srobert 76061da546Spatrick class Segment { 77061da546Spatrick public: Segment()78be691f3bSpatrick Segment() : name() {} 79061da546Spatrick 80061da546Spatrick lldb_private::ConstString name; 81be691f3bSpatrick lldb::addr_t vmaddr = LLDB_INVALID_ADDRESS; 82be691f3bSpatrick lldb::addr_t vmsize = 0; 83be691f3bSpatrick lldb::addr_t fileoff = 0; 84be691f3bSpatrick lldb::addr_t filesize = 0; 85be691f3bSpatrick uint32_t maxprot = 0; 86be691f3bSpatrick uint32_t initprot = 0; 87be691f3bSpatrick uint32_t nsects = 0; 88be691f3bSpatrick uint32_t flags = 0; 89061da546Spatrick 90061da546Spatrick bool operator==(const Segment &rhs) const { 91061da546Spatrick return name == rhs.name && vmaddr == rhs.vmaddr && vmsize == rhs.vmsize; 92061da546Spatrick } 93061da546Spatrick 94061da546Spatrick void PutToLog(lldb_private::Log *log, lldb::addr_t slide) const; 95061da546Spatrick }; 96061da546Spatrick 97061da546Spatrick struct ImageInfo { 98061da546Spatrick /// Address of mach header for this dylib. 99061da546Spatrick lldb::addr_t address = LLDB_INVALID_ADDRESS; 100061da546Spatrick /// The amount to slide all segments by if there is a global 101061da546Spatrick /// slide. 102061da546Spatrick lldb::addr_t slide = 0; 103061da546Spatrick /// Modification date for this dylib. 104061da546Spatrick lldb::addr_t mod_date = 0; 105061da546Spatrick /// Resolved path for this dylib. 106061da546Spatrick lldb_private::FileSpec file_spec; 107061da546Spatrick /// UUID for this dylib if it has one, else all zeros. 108061da546Spatrick lldb_private::UUID uuid; 109061da546Spatrick /// The mach header for this image. 110061da546Spatrick llvm::MachO::mach_header header; 111061da546Spatrick /// All segment vmaddr and vmsize pairs for this executable (from 112061da546Spatrick /// memory of inferior). 113061da546Spatrick std::vector<Segment> segments; 114061da546Spatrick /// The process stop ID that the sections for this image were 115061da546Spatrick /// loaded. 116061da546Spatrick uint32_t load_stop_id = 0; 117061da546Spatrick /// LC_VERSION_MIN_... load command os type. 118061da546Spatrick llvm::Triple::OSType os_type = llvm::Triple::OSType::UnknownOS; 119061da546Spatrick /// LC_VERSION_MIN_... load command os environment. 120061da546Spatrick llvm::Triple::EnvironmentType os_env = 121061da546Spatrick llvm::Triple::EnvironmentType::UnknownEnvironment; 122061da546Spatrick /// LC_VERSION_MIN_... SDK. 123061da546Spatrick std::string min_version_os_sdk; 124061da546Spatrick 125061da546Spatrick ImageInfo() = default; 126061da546Spatrick ClearImageInfo127061da546Spatrick void Clear(bool load_cmd_data_only) { 128061da546Spatrick if (!load_cmd_data_only) { 129061da546Spatrick address = LLDB_INVALID_ADDRESS; 130061da546Spatrick slide = 0; 131061da546Spatrick mod_date = 0; 132061da546Spatrick file_spec.Clear(); 133061da546Spatrick ::memset(&header, 0, sizeof(header)); 134061da546Spatrick } 135061da546Spatrick uuid.Clear(); 136061da546Spatrick segments.clear(); 137061da546Spatrick load_stop_id = 0; 138061da546Spatrick os_type = llvm::Triple::OSType::UnknownOS; 139061da546Spatrick os_env = llvm::Triple::EnvironmentType::UnknownEnvironment; 140061da546Spatrick min_version_os_sdk.clear(); 141061da546Spatrick } 142061da546Spatrick 143061da546Spatrick bool operator==(const ImageInfo &rhs) const { 144061da546Spatrick return address == rhs.address && slide == rhs.slide && 145061da546Spatrick mod_date == rhs.mod_date && file_spec == rhs.file_spec && 146061da546Spatrick uuid == rhs.uuid && 147061da546Spatrick memcmp(&header, &rhs.header, sizeof(header)) == 0 && 148061da546Spatrick segments == rhs.segments && os_type == rhs.os_type && 149061da546Spatrick os_env == rhs.os_env; 150061da546Spatrick } 151061da546Spatrick UUIDValidImageInfo152061da546Spatrick bool UUIDValid() const { return uuid.IsValid(); } 153061da546Spatrick GetAddressByteSizeImageInfo154061da546Spatrick uint32_t GetAddressByteSize() { 155061da546Spatrick if (header.cputype) { 156061da546Spatrick if (header.cputype & llvm::MachO::CPU_ARCH_ABI64) 157061da546Spatrick return 8; 158061da546Spatrick else 159061da546Spatrick return 4; 160061da546Spatrick } 161061da546Spatrick return 0; 162061da546Spatrick } 163061da546Spatrick 164061da546Spatrick lldb_private::ArchSpec GetArchitecture() const; 165061da546Spatrick 166061da546Spatrick const Segment *FindSegment(lldb_private::ConstString name) const; 167061da546Spatrick 168061da546Spatrick void PutToLog(lldb_private::Log *log) const; 169061da546Spatrick 170061da546Spatrick typedef std::vector<ImageInfo> collection; 171061da546Spatrick typedef collection::iterator iterator; 172061da546Spatrick typedef collection::const_iterator const_iterator; 173061da546Spatrick }; 174061da546Spatrick 175061da546Spatrick bool UpdateImageLoadAddress(lldb_private::Module *module, ImageInfo &info); 176061da546Spatrick 177061da546Spatrick bool UnloadModuleSections(lldb_private::Module *module, ImageInfo &info); 178061da546Spatrick 179061da546Spatrick lldb::ModuleSP FindTargetModuleForImageInfo(ImageInfo &image_info, 180061da546Spatrick bool can_create, 181061da546Spatrick bool *did_create_ptr); 182061da546Spatrick 183061da546Spatrick void UnloadImages(const std::vector<lldb::addr_t> &solib_addresses); 184061da546Spatrick 185061da546Spatrick void UnloadAllImages(); 186061da546Spatrick 187061da546Spatrick virtual bool SetNotificationBreakpoint() = 0; 188061da546Spatrick 189061da546Spatrick virtual void ClearNotificationBreakpoint() = 0; 190061da546Spatrick 191061da546Spatrick virtual bool DidSetNotificationBreakpoint() = 0; 192061da546Spatrick 193061da546Spatrick typedef std::map<uint64_t, lldb::addr_t> PthreadKeyToTLSMap; 194061da546Spatrick typedef std::map<lldb::user_id_t, PthreadKeyToTLSMap> ThreadIDToTLSMap; 195061da546Spatrick GetMutex()196061da546Spatrick std::recursive_mutex &GetMutex() const { return m_mutex; } 197061da546Spatrick 198061da546Spatrick lldb::ModuleSP GetPThreadLibraryModule(); 199061da546Spatrick 200061da546Spatrick lldb_private::Address GetPthreadSetSpecificAddress(); 201061da546Spatrick 202061da546Spatrick bool JSONImageInformationIntoImageInfo( 203061da546Spatrick lldb_private::StructuredData::ObjectSP image_details, 204061da546Spatrick ImageInfo::collection &image_infos); 205061da546Spatrick 206061da546Spatrick // If image_infos contains / may contain dyld or executable image, call this 207061da546Spatrick // method 208061da546Spatrick // to keep our internal record keeping of the special binaries up-to-date. 209061da546Spatrick void 210061da546Spatrick UpdateSpecialBinariesFromNewImageInfos(ImageInfo::collection &image_infos); 211061da546Spatrick 212061da546Spatrick // if image_info is a dyld binary, call this method 213061da546Spatrick void UpdateDYLDImageInfoFromNewImageInfo(ImageInfo &image_info); 214061da546Spatrick 215061da546Spatrick // If image_infos contains / may contain executable image, call this method 216061da546Spatrick // to keep our internal record keeping of the special dyld binary up-to-date. 217061da546Spatrick void AddExecutableModuleIfInImageInfos(ImageInfo::collection &image_infos); 218061da546Spatrick 219061da546Spatrick bool AddModulesUsingImageInfos(ImageInfo::collection &image_infos); 220061da546Spatrick 221061da546Spatrick // Whether we should use the new dyld SPI to get shared library information, 222061da546Spatrick // or read 223061da546Spatrick // it directly out of the dyld_all_image_infos. Whether we use the (newer) 224061da546Spatrick // DynamicLoaderMacOS 225061da546Spatrick // plugin or the (older) DynamicLoaderMacOSX plugin. 226061da546Spatrick static bool UseDYLDSPI(lldb_private::Process *process); 227061da546Spatrick 228061da546Spatrick lldb::ModuleWP m_dyld_module_wp; // the dyld whose file type (mac, ios, etc) 229061da546Spatrick // matches the process 230061da546Spatrick lldb::ModuleWP m_libpthread_module_wp; 231061da546Spatrick lldb_private::Address m_pthread_getspecific_addr; 232061da546Spatrick ThreadIDToTLSMap m_tid_to_tls_map; 233061da546Spatrick ImageInfo::collection 234061da546Spatrick m_dyld_image_infos; // Current shared libraries information 235061da546Spatrick uint32_t m_dyld_image_infos_stop_id; // The process stop ID that 236061da546Spatrick // "m_dyld_image_infos" is valid for 237061da546Spatrick ImageInfo m_dyld; 238061da546Spatrick mutable std::recursive_mutex m_mutex; 239061da546Spatrick 240061da546Spatrick private: 241dda28197Spatrick DynamicLoaderDarwin(const DynamicLoaderDarwin &) = delete; 242dda28197Spatrick const DynamicLoaderDarwin &operator=(const DynamicLoaderDarwin &) = delete; 243061da546Spatrick }; 244061da546Spatrick 245061da546Spatrick } // namespace lldb_private 246061da546Spatrick 247dda28197Spatrick #endif // LLDB_SOURCE_PLUGINS_DYNAMICLOADER_MACOSX_DYLD_DYNAMICLOADERDARWIN_H 248