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