DynamicLoaderMacOSXDYLD.h revision 49ce8969d3154e1560106cfe530444c09410f217
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 size_t 70 FindEquivalentSymbols (lldb_private::Symbol *original_symbol, 71 lldb_private::ModuleList &module_list, 72 lldb_private::SymbolContextList &equivalent_symbols); 73 74 virtual lldb_private::Error 75 CanLoadImage (); 76 77 //------------------------------------------------------------------ 78 // PluginInterface protocol 79 //------------------------------------------------------------------ 80 virtual const char * 81 GetPluginName(); 82 83 virtual const char * 84 GetShortPluginName(); 85 86 virtual uint32_t 87 GetPluginVersion(); 88 89 virtual bool 90 AlwaysRelyOnEHUnwindInfo (lldb_private::SymbolContext &sym_ctx); 91 92protected: 93 void 94 PrivateInitialize (lldb_private::Process *process); 95 96 void 97 PrivateProcessStateChanged (lldb_private::Process *process, 98 lldb::StateType state); 99 bool 100 LocateDYLD (); 101 102 bool 103 DidSetNotificationBreakpoint () const; 104 105 void 106 Clear (bool clear_process); 107 108 void 109 PutToLog (lldb_private::Log *log) const; 110 111 bool 112 ReadDYLDInfoFromMemoryAndSetNotificationCallback (lldb::addr_t addr); 113 114 static bool 115 NotifyBreakpointHit (void *baton, 116 lldb_private::StoppointCallbackContext *context, 117 lldb::user_id_t break_id, 118 lldb::user_id_t break_loc_id); 119 120 uint32_t 121 AddrByteSize(); 122 123 static lldb::ByteOrder 124 GetByteOrderFromMagic (uint32_t magic); 125 126 bool 127 ReadMachHeader (lldb::addr_t addr, 128 llvm::MachO::mach_header *header, 129 lldb_private::DataExtractor *load_command_data); 130 class Segment 131 { 132 public: 133 134 Segment() : 135 name(), 136 vmaddr(LLDB_INVALID_ADDRESS), 137 vmsize(0), 138 fileoff(0), 139 filesize(0), 140 maxprot(0), 141 initprot(0), 142 nsects(0), 143 flags(0) 144 { 145 } 146 147 lldb_private::ConstString name; 148 lldb::addr_t vmaddr; 149 lldb::addr_t vmsize; 150 lldb::addr_t fileoff; 151 lldb::addr_t filesize; 152 uint32_t maxprot; 153 uint32_t initprot; 154 uint32_t nsects; 155 uint32_t flags; 156 157 bool 158 operator==(const Segment& rhs) const 159 { 160 return name == rhs.name && vmaddr == rhs.vmaddr && vmsize == rhs.vmsize; 161 } 162 163 void 164 PutToLog (lldb_private::Log *log, 165 lldb::addr_t slide) const; 166 167 }; 168 169 struct DYLDImageInfo 170 { 171 lldb::addr_t address; // Address of mach header for this dylib 172 lldb::addr_t slide; // The amount to slide all segments by if there is a global slide. 173 lldb::addr_t mod_date; // Modification date for this dylib 174 lldb_private::FileSpec file_spec; // Resolved path for this dylib 175 lldb_private::UUID uuid; // UUID for this dylib if it has one, else all zeros 176 llvm::MachO::mach_header header; // The mach header for this image 177 std::vector<Segment> segments; // All segment vmaddr and vmsize pairs for this executable (from memory of inferior) 178 179 DYLDImageInfo() : 180 address(LLDB_INVALID_ADDRESS), 181 slide(0), 182 mod_date(0), 183 file_spec(), 184 uuid(), 185 header(), 186 segments() 187 { 188 } 189 190 void 191 Clear(bool load_cmd_data_only) 192 { 193 if (!load_cmd_data_only) 194 { 195 address = LLDB_INVALID_ADDRESS; 196 slide = 0; 197 mod_date = 0; 198 file_spec.Clear(); 199 ::memset (&header, 0, sizeof(header)); 200 } 201 uuid.Clear(); 202 segments.clear(); 203 } 204 205 bool 206 operator == (const DYLDImageInfo& rhs) const 207 { 208 return address == rhs.address 209 && slide == rhs.slide 210 && mod_date == rhs.mod_date 211 && file_spec == rhs.file_spec 212 && uuid == rhs.uuid 213 && memcmp(&header, &rhs.header, sizeof(header)) == 0 214 && segments == rhs.segments; 215 } 216 217 bool 218 UUIDValid() const 219 { 220 return uuid.IsValid(); 221 } 222 223 uint32_t 224 GetAddressByteSize () 225 { 226 if (header.cputype) 227 { 228 if (header.cputype & llvm::MachO::CPUArchABI64) 229 return 8; 230 else 231 return 4; 232 } 233 return 0; 234 } 235 236 lldb::ByteOrder 237 GetByteOrder(); 238 239 lldb_private::ArchSpec 240 GetArchitecture () const 241 { 242 return lldb_private::ArchSpec (lldb_private::eArchTypeMachO, header.cputype, header.cpusubtype); 243 } 244 245 const Segment * 246 FindSegment (const lldb_private::ConstString &name) const; 247 248 void 249 PutToLog (lldb_private::Log *log) const; 250 251 typedef std::vector<DYLDImageInfo> collection; 252 typedef collection::iterator iterator; 253 typedef collection::const_iterator const_iterator; 254 }; 255 256 struct DYLDAllImageInfos 257 { 258 uint32_t version; 259 uint32_t dylib_info_count; // Version >= 1 260 lldb::addr_t dylib_info_addr; // Version >= 1 261 lldb::addr_t notification; // Version >= 1 262 bool processDetachedFromSharedRegion; // Version >= 1 263 bool libSystemInitialized; // Version >= 2 264 lldb::addr_t dyldImageLoadAddress; // Version >= 2 265 266 DYLDAllImageInfos() : 267 version (0), 268 dylib_info_count (0), 269 dylib_info_addr (LLDB_INVALID_ADDRESS), 270 notification (LLDB_INVALID_ADDRESS), 271 processDetachedFromSharedRegion (false), 272 libSystemInitialized (false), 273 dyldImageLoadAddress (LLDB_INVALID_ADDRESS) 274 { 275 } 276 277 void 278 Clear() 279 { 280 version = 0; 281 dylib_info_count = 0; 282 dylib_info_addr = LLDB_INVALID_ADDRESS; 283 notification = LLDB_INVALID_ADDRESS; 284 processDetachedFromSharedRegion = false; 285 libSystemInitialized = false; 286 dyldImageLoadAddress = LLDB_INVALID_ADDRESS; 287 } 288 289 bool 290 IsValid() const 291 { 292 return version >= 1 || version <= 6; 293 } 294 }; 295 296 void 297 RegisterNotificationCallbacks(); 298 299 void 300 UnregisterNotificationCallbacks(); 301 302 uint32_t 303 ParseLoadCommands (const lldb_private::DataExtractor& data, 304 DYLDImageInfo& dylib_info, 305 lldb_private::FileSpec *lc_id_dylinker); 306 307 bool 308 UpdateImageLoadAddress(lldb_private::Module *module, 309 DYLDImageInfo& info); 310 311 bool 312 UnloadImageLoadAddress (lldb_private::Module *module, 313 DYLDImageInfo& info); 314 315 lldb::ModuleSP 316 FindTargetModuleForDYLDImageInfo (const DYLDImageInfo &image_info, 317 bool can_create, 318 bool *did_create_ptr); 319 320 DYLDImageInfo * 321 GetImageInfo (lldb_private::Module *module); 322 323 bool 324 NeedToLocateDYLD () const; 325 326 bool 327 SetNotificationBreakpoint (); 328 329 // There is a little tricky bit where you might initially attach while dyld is updating 330 // the all_image_infos, and you can't read the infos, so you have to continue and pick it 331 // up when you hit the update breakpoint. At that point, you need to run this initialize 332 // function, but when you do it that way you DON'T need to do the extra work you would at 333 // the breakpoint. 334 // So this function will only do actual work if the image infos haven't been read yet. 335 // If it does do any work, then it will return true, and false otherwise. That way you can 336 // call it in the breakpoint action, and if it returns true you're done. 337 bool 338 InitializeFromAllImageInfos (); 339 340 bool 341 ReadAllImageInfosStructure (); 342 343 bool 344 AddModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count); 345 346 bool 347 AddModulesUsingImageInfos (DYLDImageInfo::collection &image_infos); 348 349 bool 350 RemoveModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count); 351 352 void 353 UpdateImageInfosHeaderAndLoadCommands(DYLDImageInfo::collection &image_infos, 354 uint32_t infos_count, 355 bool update_executable); 356 357 bool 358 UpdateCommPageLoadAddress (lldb_private::Module *module); 359 360 bool 361 ReadImageInfos (lldb::addr_t image_infos_addr, 362 uint32_t image_infos_count, 363 DYLDImageInfo::collection &image_infos); 364 365 366 DYLDImageInfo m_dyld; // Info about the current dyld being used 367 lldb::addr_t m_dyld_all_image_infos_addr; 368 DYLDAllImageInfos m_dyld_all_image_infos; 369 uint32_t m_dyld_all_image_infos_stop_id; 370 lldb::user_id_t m_break_id; 371 DYLDImageInfo::collection m_dyld_image_infos; // Current shared libraries information 372 uint32_t m_dyld_image_infos_stop_id; // The process stop ID that "m_dyld_image_infos" is valid for 373 mutable lldb_private::Mutex m_mutex; 374 lldb_private::Process::Notifications m_notification_callbacks; 375 376private: 377 DISALLOW_COPY_AND_ASSIGN (DynamicLoaderMacOSXDYLD); 378}; 379 380#endif // liblldb_DynamicLoaderMacOSXDYLD_h_ 381