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