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