DynamicLoaderMacOSXDYLD.h revision b66cd074ec097b5b0a6f2ce292f5072aa1217ca6
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/Core/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); 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 //------------------------------------------------------------------ 66 // Process::Notifications callback functions 67 //------------------------------------------------------------------ 68 static void 69 Initialize (void *baton, 70 lldb_private::Process *process); 71 72 static void 73 ProcessStateChanged (void *baton, 74 lldb_private::Process *process, 75 lldb::StateType state); 76 77 virtual lldb::ThreadPlanSP 78 GetStepThroughTrampolinePlan (lldb_private::Thread &thread, 79 bool stop_others); 80 81 82 //------------------------------------------------------------------ 83 // PluginInterface protocol 84 //------------------------------------------------------------------ 85 virtual const char * 86 GetPluginName(); 87 88 virtual const char * 89 GetShortPluginName(); 90 91 virtual uint32_t 92 GetPluginVersion(); 93 94 virtual void 95 GetPluginCommandHelp (const char *command, lldb_private::Stream *strm); 96 97 virtual lldb_private::Error 98 ExecutePluginCommand (lldb_private::Args &command, lldb_private::Stream *strm); 99 100 virtual lldb_private::Log * 101 EnablePluginLogging (lldb_private::Stream *strm, lldb_private::Args &command); 102 103 104 105protected: 106 void 107 PrivateInitialize (lldb_private::Process *process); 108 109 void 110 PrivateProcessStateChanged (lldb_private::Process *process, 111 lldb::StateType state); 112 bool 113 LocateDYLD (); 114 115 bool 116 DidSetNotificationBreakpoint () const; 117 118 void 119 Clear (bool clear_process); 120 121 void 122 PutToLog (lldb_private::Log *log) const; 123 124 bool 125 ReadDYLDInfoFromMemoryAndSetNotificationCallback (lldb::addr_t addr); 126 127 uint32_t 128 UpdateAllImageInfos (); 129 130 static bool 131 NotifyBreakpointHit (void *baton, 132 lldb_private::StoppointCallbackContext *context, 133 lldb::user_id_t break_id, 134 lldb::user_id_t break_loc_id); 135 void 136 UpdateAllImageInfosHeaderAndLoadCommands (); 137 138 bool 139 UpdateCommPageLoadAddress (lldb_private::Module *module); 140 141 uint32_t 142 AddrByteSize() 143 { 144 switch (m_dyld.header.magic) 145 { 146 case llvm::MachO::HeaderMagic32: 147 case llvm::MachO::HeaderMagic32Swapped: 148 return 4; 149 150 case llvm::MachO::HeaderMagic64: 151 case llvm::MachO::HeaderMagic64Swapped: 152 return 8; 153 154 default: 155 break; 156 } 157 return 0; 158 } 159 160 static lldb::ByteOrder 161 GetByteOrderFromMagic (uint32_t magic) 162 { 163 switch (magic) 164 { 165 case llvm::MachO::HeaderMagic32: 166 case llvm::MachO::HeaderMagic64: 167 return lldb::eByteOrderHost; 168 169 case llvm::MachO::HeaderMagic32Swapped: 170 case llvm::MachO::HeaderMagic64Swapped: 171 if (lldb::eByteOrderHost == lldb::eByteOrderBig) 172 return lldb::eByteOrderLittle; 173 else 174 return lldb::eByteOrderBig; 175 176 default: 177 break; 178 } 179 return lldb::eByteOrderInvalid; 180 } 181 182 bool 183 ReadMachHeader (lldb::addr_t addr, 184 llvm::MachO::mach_header *header, 185 lldb_private::DataExtractor *load_command_data); 186 class Segment 187 { 188 public: 189 190 Segment() : 191 name(), 192 addr(LLDB_INVALID_ADDRESS), 193 size(0) 194 { 195 } 196 197 lldb_private::ConstString name; 198 lldb::addr_t addr; 199 lldb::addr_t size; 200 201 bool 202 operator==(const Segment& rhs) const 203 { 204 return name == rhs.name && addr == rhs.addr && size == rhs.size; 205 } 206 207 void 208 PutToLog (lldb_private::Log *log, 209 lldb::addr_t slide) const; 210 211 }; 212 213 struct DYLDImageInfo 214 { 215 lldb::addr_t address; // Address of mach header for this dylib 216 lldb::addr_t slide; // The amount to slide all segments by if there is a global slide. 217 lldb::addr_t mod_date; // Modification date for this dylib 218 lldb_private::FileSpec file_spec; // Resolved path for this dylib 219 lldb_private::UUID uuid; // UUID for this dylib if it has one, else all zeros 220 llvm::MachO::mach_header header; // The mach header for this image 221 std::vector<Segment> segments; // All segment vmaddr and vmsize pairs for this executable (from memory of inferior) 222 223 DYLDImageInfo() : 224 address(LLDB_INVALID_ADDRESS), 225 slide(0), 226 mod_date(0), 227 file_spec(), 228 uuid(), 229 header(), 230 segments() 231 { 232 } 233 234 void 235 Clear(bool load_cmd_data_only) 236 { 237 if (!load_cmd_data_only) 238 { 239 address = LLDB_INVALID_ADDRESS; 240 slide = 0; 241 mod_date = 0; 242 file_spec.Clear(); 243 ::bzero (&header, sizeof(header)); 244 } 245 uuid.Clear(); 246 segments.clear(); 247 } 248 249 bool 250 operator == (const DYLDImageInfo& rhs) const 251 { 252 return address == rhs.address 253 && slide == rhs.slide 254 && mod_date == rhs.mod_date 255 && file_spec == rhs.file_spec 256 && uuid == rhs.uuid 257 && memcmp(&header, &rhs.header, sizeof(header)) == 0 258 && segments == rhs.segments; 259 } 260 261 bool 262 UUIDValid() const 263 { 264 return uuid.IsValid(); 265 } 266 267 const Segment * 268 FindSegment (const lldb_private::ConstString &name) const; 269 270 void 271 PutToLog (lldb_private::Log *log) const; 272 273 typedef std::vector<DYLDImageInfo> collection; 274 typedef collection::iterator iterator; 275 typedef collection::const_iterator const_iterator; 276 }; 277 278 struct DYLDAllImageInfos 279 { 280 uint32_t version; 281 uint32_t dylib_info_count; // Version >= 1 282 lldb::addr_t dylib_info_addr; // Version >= 1 283 lldb::addr_t notification; // Version >= 1 284 bool processDetachedFromSharedRegion; // Version >= 1 285 bool libSystemInitialized; // Version >= 2 286 lldb::addr_t dyldImageLoadAddress; // Version >= 2 287 288 DYLDAllImageInfos() : 289 version (0), 290 dylib_info_count (0), 291 dylib_info_addr (LLDB_INVALID_ADDRESS), 292 notification (LLDB_INVALID_ADDRESS), 293 processDetachedFromSharedRegion (false), 294 libSystemInitialized (false), 295 dyldImageLoadAddress (LLDB_INVALID_ADDRESS) 296 { 297 } 298 299 void 300 Clear() 301 { 302 version = 0; 303 dylib_info_count = 0; 304 dylib_info_addr = LLDB_INVALID_ADDRESS; 305 notification = LLDB_INVALID_ADDRESS; 306 processDetachedFromSharedRegion = false; 307 libSystemInitialized = false; 308 dyldImageLoadAddress = LLDB_INVALID_ADDRESS; 309 } 310 311 bool 312 IsValid() const 313 { 314 return version >= 1 || version <= 6; 315 } 316 }; 317 318 void 319 RegisterNotificationCallbacks(); 320 321 void 322 UnregisterNotificationCallbacks(); 323 324 uint32_t 325 ParseLoadCommands (const lldb_private::DataExtractor& data, 326 struct DYLDImageInfo& dylib_info, 327 lldb_private::FileSpec *lc_id_dylinker); 328 329 bool 330 UpdateImageLoadAddress(lldb_private::Module *module, 331 struct DYLDImageInfo& info); 332 333 bool 334 UnloadImageLoadAddress (lldb_private::Module *module, 335 struct DYLDImageInfo& info); 336 337 bool 338 NeedToLocateDYLD () const; 339 340 bool 341 SetNotificationBreakpoint (); 342 343 bool 344 ReadAllImageInfosStructure (); 345 346 DYLDImageInfo m_dyld; // Info about the curent dyld being used 347 lldb::addr_t m_dyld_all_image_infos_addr; 348 DYLDAllImageInfos m_dyld_all_image_infos; 349 lldb::user_id_t m_break_id; 350 DYLDImageInfo::collection m_dyld_image_infos; // Current shared libraries information 351 mutable lldb_private::Mutex m_mutex; 352 lldb_private::Process::Notifications m_notification_callbacks; 353 354private: 355 DISALLOW_COPY_AND_ASSIGN (DynamicLoaderMacOSXDYLD); 356}; 357 358#endif // liblldb_DynamicLoaderMacOSXDYLD_h_ 359