DynamicLoaderMacOSXDYLD.h revision e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1
1//===-- DynamicLoaderMacOSXDYLD.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_DynamicLoaderMacOSXDYLD_h_ 11#define liblldb_DynamicLoaderMacOSXDYLD_h_ 12 13// C Includes 14// C++ Includes 15#include <map> 16#include <vector> 17#include <string> 18 19// Other libraries and framework includes 20#include "llvm/Support/MachO.h" 21 22#include "lldb/Target/DynamicLoader.h" 23#include "lldb/Host/FileSpec.h" 24#include "lldb/Core/UUID.h" 25#include "lldb/Host/Mutex.h" 26#include "lldb/Target/Process.h" 27 28class DynamicLoaderMacOSXDYLD : public lldb_private::DynamicLoader 29{ 30public: 31 //------------------------------------------------------------------ 32 // Static Functions 33 //------------------------------------------------------------------ 34 static void 35 Initialize(); 36 37 static void 38 Terminate(); 39 40 static const char * 41 GetPluginNameStatic(); 42 43 static const char * 44 GetPluginDescriptionStatic(); 45 46 static lldb_private::DynamicLoader * 47 CreateInstance (lldb_private::Process *process, bool force); 48 49 DynamicLoaderMacOSXDYLD (lldb_private::Process *process); 50 51 virtual 52 ~DynamicLoaderMacOSXDYLD (); 53 //------------------------------------------------------------------ 54 /// Called after attaching a process. 55 /// 56 /// Allow DynamicLoader plug-ins to execute some code after 57 /// attaching to a process. 58 //------------------------------------------------------------------ 59 virtual void 60 DidAttach (); 61 62 virtual void 63 DidLaunch (); 64 65 virtual lldb::ThreadPlanSP 66 GetStepThroughTrampolinePlan (lldb_private::Thread &thread, 67 bool stop_others); 68 69 virtual lldb_private::Error 70 CanLoadImage (); 71 72 //------------------------------------------------------------------ 73 // PluginInterface protocol 74 //------------------------------------------------------------------ 75 virtual const char * 76 GetPluginName(); 77 78 virtual const char * 79 GetShortPluginName(); 80 81 virtual uint32_t 82 GetPluginVersion(); 83 84protected: 85 void 86 PrivateInitialize (lldb_private::Process *process); 87 88 void 89 PrivateProcessStateChanged (lldb_private::Process *process, 90 lldb::StateType state); 91 bool 92 LocateDYLD (); 93 94 bool 95 DidSetNotificationBreakpoint () const; 96 97 void 98 Clear (bool clear_process); 99 100 void 101 PutToLog (lldb_private::Log *log) const; 102 103 bool 104 ReadDYLDInfoFromMemoryAndSetNotificationCallback (lldb::addr_t addr); 105 106 uint32_t 107 UpdateAllImageInfos (); 108 109 static bool 110 NotifyBreakpointHit (void *baton, 111 lldb_private::StoppointCallbackContext *context, 112 lldb::user_id_t break_id, 113 lldb::user_id_t break_loc_id); 114 void 115 UpdateAllImageInfosHeaderAndLoadCommands (); 116 117 bool 118 UpdateCommPageLoadAddress (lldb_private::Module *module); 119 120 uint32_t 121 AddrByteSize() 122 { 123 switch (m_dyld.header.magic) 124 { 125 case llvm::MachO::HeaderMagic32: 126 case llvm::MachO::HeaderMagic32Swapped: 127 return 4; 128 129 case llvm::MachO::HeaderMagic64: 130 case llvm::MachO::HeaderMagic64Swapped: 131 return 8; 132 133 default: 134 break; 135 } 136 return 0; 137 } 138 139 static lldb::ByteOrder 140 GetByteOrderFromMagic (uint32_t magic) 141 { 142 switch (magic) 143 { 144 case llvm::MachO::HeaderMagic32: 145 case llvm::MachO::HeaderMagic64: 146 return lldb::endian::InlHostByteOrder(); 147 148 case llvm::MachO::HeaderMagic32Swapped: 149 case llvm::MachO::HeaderMagic64Swapped: 150 if (lldb::endian::InlHostByteOrder() == lldb::eByteOrderBig) 151 return lldb::eByteOrderLittle; 152 else 153 return lldb::eByteOrderBig; 154 155 default: 156 break; 157 } 158 return lldb::eByteOrderInvalid; 159 } 160 161 bool 162 ReadMachHeader (lldb::addr_t addr, 163 llvm::MachO::mach_header *header, 164 lldb_private::DataExtractor *load_command_data); 165 class Segment 166 { 167 public: 168 169 Segment() : 170 name(), 171 addr(LLDB_INVALID_ADDRESS), 172 size(0) 173 { 174 } 175 176 lldb_private::ConstString name; 177 lldb::addr_t addr; 178 lldb::addr_t size; 179 180 bool 181 operator==(const Segment& rhs) const 182 { 183 return name == rhs.name && addr == rhs.addr && size == rhs.size; 184 } 185 186 void 187 PutToLog (lldb_private::Log *log, 188 lldb::addr_t slide) const; 189 190 }; 191 192 struct DYLDImageInfo 193 { 194 lldb::addr_t address; // Address of mach header for this dylib 195 lldb::addr_t slide; // The amount to slide all segments by if there is a global slide. 196 lldb::addr_t mod_date; // Modification date for this dylib 197 lldb_private::FileSpec file_spec; // Resolved path for this dylib 198 lldb_private::UUID uuid; // UUID for this dylib if it has one, else all zeros 199 llvm::MachO::mach_header header; // The mach header for this image 200 std::vector<Segment> segments; // All segment vmaddr and vmsize pairs for this executable (from memory of inferior) 201 202 DYLDImageInfo() : 203 address(LLDB_INVALID_ADDRESS), 204 slide(0), 205 mod_date(0), 206 file_spec(), 207 uuid(), 208 header(), 209 segments() 210 { 211 } 212 213 void 214 Clear(bool load_cmd_data_only) 215 { 216 if (!load_cmd_data_only) 217 { 218 address = LLDB_INVALID_ADDRESS; 219 slide = 0; 220 mod_date = 0; 221 file_spec.Clear(); 222 ::memset (&header, 0, sizeof(header)); 223 } 224 uuid.Clear(); 225 segments.clear(); 226 } 227 228 bool 229 operator == (const DYLDImageInfo& rhs) const 230 { 231 return address == rhs.address 232 && slide == rhs.slide 233 && mod_date == rhs.mod_date 234 && file_spec == rhs.file_spec 235 && uuid == rhs.uuid 236 && memcmp(&header, &rhs.header, sizeof(header)) == 0 237 && segments == rhs.segments; 238 } 239 240 bool 241 UUIDValid() const 242 { 243 return uuid.IsValid(); 244 } 245 246 uint32_t 247 GetAddressByteSize () 248 { 249 if (header.cputype) 250 { 251 if (header.cputype & llvm::MachO::CPUArchABI64) 252 return 8; 253 else 254 return 4; 255 } 256 return 0; 257 } 258 259 lldb::ByteOrder 260 GetByteOrder() 261 { 262 switch (header.magic) 263 { 264 case llvm::MachO::HeaderMagic32: // MH_MAGIC 265 case llvm::MachO::HeaderMagic64: // MH_MAGIC_64 266 return lldb::endian::InlHostByteOrder(); 267 268 case llvm::MachO::HeaderMagic32Swapped: // MH_CIGAM 269 case llvm::MachO::HeaderMagic64Swapped: // MH_CIGAM_64 270 if (lldb::endian::InlHostByteOrder() == lldb::eByteOrderLittle) 271 return lldb::eByteOrderBig; 272 else 273 return lldb::eByteOrderLittle; 274 default: 275 assert (!"invalid header.magic value"); 276 break; 277 } 278 return lldb::endian::InlHostByteOrder(); 279 } 280 281 const Segment * 282 FindSegment (const lldb_private::ConstString &name) const; 283 284 void 285 PutToLog (lldb_private::Log *log) const; 286 287 typedef std::vector<DYLDImageInfo> collection; 288 typedef collection::iterator iterator; 289 typedef collection::const_iterator const_iterator; 290 }; 291 292 struct DYLDAllImageInfos 293 { 294 uint32_t version; 295 uint32_t dylib_info_count; // Version >= 1 296 lldb::addr_t dylib_info_addr; // Version >= 1 297 lldb::addr_t notification; // Version >= 1 298 bool processDetachedFromSharedRegion; // Version >= 1 299 bool libSystemInitialized; // Version >= 2 300 lldb::addr_t dyldImageLoadAddress; // Version >= 2 301 302 DYLDAllImageInfos() : 303 version (0), 304 dylib_info_count (0), 305 dylib_info_addr (LLDB_INVALID_ADDRESS), 306 notification (LLDB_INVALID_ADDRESS), 307 processDetachedFromSharedRegion (false), 308 libSystemInitialized (false), 309 dyldImageLoadAddress (LLDB_INVALID_ADDRESS) 310 { 311 } 312 313 void 314 Clear() 315 { 316 version = 0; 317 dylib_info_count = 0; 318 dylib_info_addr = LLDB_INVALID_ADDRESS; 319 notification = LLDB_INVALID_ADDRESS; 320 processDetachedFromSharedRegion = false; 321 libSystemInitialized = false; 322 dyldImageLoadAddress = LLDB_INVALID_ADDRESS; 323 } 324 325 bool 326 IsValid() const 327 { 328 return version >= 1 || version <= 6; 329 } 330 }; 331 332 void 333 RegisterNotificationCallbacks(); 334 335 void 336 UnregisterNotificationCallbacks(); 337 338 uint32_t 339 ParseLoadCommands (const lldb_private::DataExtractor& data, 340 struct DYLDImageInfo& dylib_info, 341 lldb_private::FileSpec *lc_id_dylinker); 342 343 bool 344 UpdateImageLoadAddress(lldb_private::Module *module, 345 struct DYLDImageInfo& info); 346 347 bool 348 UnloadImageLoadAddress (lldb_private::Module *module, 349 struct DYLDImageInfo& info); 350 351 DYLDImageInfo * 352 GetImageInfo (const lldb_private::FileSpec &file_spec, 353 const lldb_private::UUID &uuid); 354 355 bool 356 NeedToLocateDYLD () const; 357 358 bool 359 SetNotificationBreakpoint (); 360 361 bool 362 ReadAllImageInfosStructure (); 363 364 DYLDImageInfo m_dyld; // Info about the current dyld being used 365 lldb::addr_t m_dyld_all_image_infos_addr; 366 DYLDAllImageInfos m_dyld_all_image_infos; 367 uint32_t m_dyld_all_image_infos_stop_id; 368 lldb::user_id_t m_break_id; 369 DYLDImageInfo::collection m_dyld_image_infos; // Current shared libraries information 370 uint32_t m_dyld_image_infos_stop_id; // The process stop ID that "m_dyld_image_infos" is valid for 371 mutable lldb_private::Mutex m_mutex; 372 lldb_private::Process::Notifications m_notification_callbacks; 373 374private: 375 DISALLOW_COPY_AND_ASSIGN (DynamicLoaderMacOSXDYLD); 376}; 377 378#endif // liblldb_DynamicLoaderMacOSXDYLD_h_ 379