diff options
Diffstat (limited to 'lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h')
-rw-r--r-- | lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h | 360 |
1 files changed, 360 insertions, 0 deletions
diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h new file mode 100644 index 00000000000..724a8b6bd6d --- /dev/null +++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h @@ -0,0 +1,360 @@ +//===-- DynamicLoaderMacOSXDYLD.h -------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_DynamicLoaderMacOSXDYLD_h_ +#define liblldb_DynamicLoaderMacOSXDYLD_h_ + +// C Includes +#include <mach-o/loader.h> + +// C++ Includes +#include <map> +#include <vector> +#include <string> + +// Other libraries and framework includes +#include "lldb/Target/DynamicLoader.h" +#include "lldb/Core/FileSpec.h" +#include "lldb/Core/UUID.h" +#include "lldb/Host/Mutex.h" +#include "lldb/Target/Process.h" +#include "ObjCTrampolineHandler.h" + +class DynamicLoaderMacOSXDYLD : public lldb_private::DynamicLoader +{ +public: + //------------------------------------------------------------------ + // Static Functions + //------------------------------------------------------------------ + static void + Initialize(); + + static void + Terminate(); + + static const char * + GetPluginNameStatic(); + + static const char * + GetPluginDescriptionStatic(); + + static lldb_private::DynamicLoader * + CreateInstance (lldb_private::Process *process); + + DynamicLoaderMacOSXDYLD (lldb_private::Process *process); + + virtual + ~DynamicLoaderMacOSXDYLD (); + //------------------------------------------------------------------ + /// Called after attaching a process. + /// + /// Allow DynamicLoader plug-ins to execute some code after + /// attaching to a process. + //------------------------------------------------------------------ + virtual void + DidAttach (); + + virtual void + DidLaunch (); + + //------------------------------------------------------------------ + // Process::Notifications callback functions + //------------------------------------------------------------------ + static void + Initialize (void *baton, + lldb_private::Process *process); + + static void + ProcessStateChanged (void *baton, + lldb_private::Process *process, + lldb::StateType state); + + virtual lldb::ThreadPlanSP + GetStepThroughTrampolinePlan (lldb_private::Thread &thread, + bool stop_others); + + + //------------------------------------------------------------------ + // PluginInterface protocol + //------------------------------------------------------------------ + virtual const char * + GetPluginName(); + + virtual const char * + GetShortPluginName(); + + virtual uint32_t + GetPluginVersion(); + + virtual void + GetPluginCommandHelp (const char *command, lldb_private::Stream *strm); + + virtual lldb_private::Error + ExecutePluginCommand (lldb_private::Args &command, lldb_private::Stream *strm); + + virtual lldb_private::Log * + EnablePluginLogging (lldb_private::Stream *strm, lldb_private::Args &command); + + + +protected: + void + PrivateInitialize (lldb_private::Process *process); + + void + PrivateProcessStateChanged (lldb_private::Process *process, + lldb::StateType state); + bool + LocateDYLD (); + + bool + DidSetNotificationBreakpoint () const; + + void + Clear (bool clear_process); + + void + PutToLog (lldb_private::Log *log) const; + + bool + ReadDYLDInfoFromMemoryAndSetNotificationCallback (lldb::addr_t addr); + + uint32_t + UpdateAllImageInfos (); + + static bool + NotifyBreakpointHit (void *baton, + lldb_private::StoppointCallbackContext *context, + lldb::user_id_t break_id, + lldb::user_id_t break_loc_id); + void + UpdateAllImageInfosHeaderAndLoadCommands (); + + bool + UpdateCommPageLoadAddress (lldb_private::Module *module); + + uint32_t + AddrByteSize() + { + switch (m_dyld.header.magic) + { + case MH_MAGIC: + case MH_CIGAM: + return 4; + + case MH_MAGIC_64: + case MH_CIGAM_64: + return 8; + + default: + break; + } + return 0; + } + + static lldb::ByteOrder + GetByteOrderFromMagic (uint32_t magic) + { + switch (magic) + { + case MH_MAGIC: + case MH_MAGIC_64: + return lldb::eByteOrderHost; + + case MH_CIGAM: + case MH_CIGAM_64: + if (lldb::eByteOrderHost == lldb::eByteOrderBig) + return lldb::eByteOrderLittle; + else + return lldb::eByteOrderBig; + + default: + break; + } + return lldb::eByteOrderInvalid; + } + + bool + ReadMachHeader (lldb::addr_t addr, + struct mach_header *header, + lldb_private::DataExtractor *load_command_data); + class Segment + { + public: + + Segment() : + name(), + addr(LLDB_INVALID_ADDRESS), + size(0) + { + } + + lldb_private::ConstString name; + lldb::addr_t addr; + lldb::addr_t size; + + bool + operator==(const Segment& rhs) const + { + return name == rhs.name && addr == rhs.addr && size == rhs.size; + } + + void + PutToLog (lldb_private::Log *log, + lldb::addr_t slide) const; + + }; + + struct DYLDImageInfo + { + lldb::addr_t address; // Address of mach header for this dylib + lldb::addr_t slide; // The amount to slide all segments by if there is a global slide. + lldb::addr_t mod_date; // Modification date for this dylib + lldb_private::FileSpec file_spec; // Resolved path for this dylib + lldb_private::UUID uuid; // UUID for this dylib if it has one, else all zeros + struct mach_header header; // The mach header for this image + std::vector<Segment> segments; // All segment vmaddr and vmsize pairs for this executable (from memory of inferior) + + DYLDImageInfo() : + address(LLDB_INVALID_ADDRESS), + slide(0), + mod_date(0), + file_spec(), + uuid(), + header(), + segments() + { + } + + void + Clear(bool load_cmd_data_only) + { + if (!load_cmd_data_only) + { + address = LLDB_INVALID_ADDRESS; + slide = 0; + mod_date = 0; + file_spec.Clear(); + ::bzero (&header, sizeof(header)); + } + uuid.Clear(); + segments.clear(); + } + + bool + operator == (const DYLDImageInfo& rhs) const + { + return address == rhs.address + && slide == rhs.slide + && mod_date == rhs.mod_date + && file_spec == rhs.file_spec + && uuid == rhs.uuid + && memcmp(&header, &rhs.header, sizeof(header)) == 0 + && segments == rhs.segments; + } + + bool + UUIDValid() const + { + return uuid.IsValid(); + } + + const Segment * + FindSegment (const lldb_private::ConstString &name) const; + + void + PutToLog (lldb_private::Log *log) const; + + typedef std::vector<DYLDImageInfo> collection; + typedef collection::iterator iterator; + typedef collection::const_iterator const_iterator; + }; + + struct DYLDAllImageInfos + { + uint32_t version; + uint32_t dylib_info_count; // Version >= 1 + lldb::addr_t dylib_info_addr; // Version >= 1 + lldb::addr_t notification; // Version >= 1 + bool processDetachedFromSharedRegion; // Version >= 1 + bool libSystemInitialized; // Version >= 2 + lldb::addr_t dyldImageLoadAddress; // Version >= 2 + + DYLDAllImageInfos() : + version (0), + dylib_info_count (0), + dylib_info_addr (LLDB_INVALID_ADDRESS), + notification (LLDB_INVALID_ADDRESS), + processDetachedFromSharedRegion (false), + libSystemInitialized (false), + dyldImageLoadAddress (LLDB_INVALID_ADDRESS) + { + } + + void + Clear() + { + version = 0; + dylib_info_count = 0; + dylib_info_addr = LLDB_INVALID_ADDRESS; + notification = LLDB_INVALID_ADDRESS; + processDetachedFromSharedRegion = false; + libSystemInitialized = false; + dyldImageLoadAddress = LLDB_INVALID_ADDRESS; + } + + bool + IsValid() const + { + return version >= 1 || version <= 6; + } + }; + + void + RegisterNotificationCallbacks(); + + void + UnregisterNotificationCallbacks(); + + uint32_t + ParseLoadCommands (const lldb_private::DataExtractor& data, + struct DYLDImageInfo& dylib_info, + lldb_private::FileSpec *lc_id_dylinker); + + bool + UpdateImageLoadAddress(lldb_private::Module *module, + struct DYLDImageInfo& info); + + bool + UnloadImageLoadAddress (lldb_private::Module *module, + struct DYLDImageInfo& info); + + bool + NeedToLocateDYLD () const; + + bool + SetNotificationBreakpoint (); + + bool + ReadAllImageInfosStructure (); + + DYLDImageInfo m_dyld; // Info about the curent dyld being used + lldb::addr_t m_dyld_all_image_infos_addr; + DYLDAllImageInfos m_dyld_all_image_infos; + lldb::user_id_t m_break_id; + DYLDImageInfo::collection m_dyld_image_infos; // Current shared libraries information + mutable lldb_private::Mutex m_mutex; + lldb_private::Process::Notifications m_notification_callbacks; + std::auto_ptr<lldb_private::ObjCTrampolineHandler> m_objc_trampoline_handler_ap; + +private: + DISALLOW_COPY_AND_ASSIGN (DynamicLoaderMacOSXDYLD); +}; + +#endif // liblldb_DynamicLoaderMacOSXDYLD_h_ |