diff options
Diffstat (limited to 'source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h')
-rw-r--r-- | source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h | 385 |
1 files changed, 385 insertions, 0 deletions
diff --git a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h new file mode 100644 index 0000000000000..8fd60d0b6ac7d --- /dev/null +++ b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h @@ -0,0 +1,385 @@ +//===-- 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 +// C++ Includes +#include <vector> + +// Other libraries and framework includes +// Project includes +#include "lldb/Target/DynamicLoader.h" +#include "lldb/Host/FileSpec.h" +#include "lldb/Core/StructuredData.h" +#include "lldb/Core/UUID.h" +#include "lldb/Host/Mutex.h" +#include "lldb/Target/Process.h" +#include "lldb/Utility/SafeMachO.h" + +class DynamicLoaderMacOSXDYLD : public lldb_private::DynamicLoader +{ +public: + DynamicLoaderMacOSXDYLD(lldb_private::Process *process); + + ~DynamicLoaderMacOSXDYLD() override; + + //------------------------------------------------------------------ + // Static Functions + //------------------------------------------------------------------ + static void + Initialize(); + + static void + Terminate(); + + static lldb_private::ConstString + GetPluginNameStatic(); + + static const char * + GetPluginDescriptionStatic(); + + static lldb_private::DynamicLoader * + CreateInstance (lldb_private::Process *process, bool force); + + //------------------------------------------------------------------ + /// Called after attaching a process. + /// + /// Allow DynamicLoader plug-ins to execute some code after + /// attaching to a process. + //------------------------------------------------------------------ + void + DidAttach() override; + + void + DidLaunch() override; + + bool + ProcessDidExec() override; + + lldb::ThreadPlanSP + GetStepThroughTrampolinePlan(lldb_private::Thread &thread, + bool stop_others) override; + + size_t + FindEquivalentSymbols(lldb_private::Symbol *original_symbol, + lldb_private::ModuleList &module_list, + lldb_private::SymbolContextList &equivalent_symbols) override; + + lldb_private::Error + CanLoadImage() override; + + //------------------------------------------------------------------ + // PluginInterface protocol + //------------------------------------------------------------------ + lldb_private::ConstString + GetPluginName() override; + + uint32_t + GetPluginVersion() override; + + bool + AlwaysRelyOnEHUnwindInfo(lldb_private::SymbolContext &sym_ctx) override; + +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); + + static bool + NotifyBreakpointHit (void *baton, + lldb_private::StoppointCallbackContext *context, + lldb::user_id_t break_id, + lldb::user_id_t break_loc_id); + + uint32_t + AddrByteSize(); + + static lldb::ByteOrder + GetByteOrderFromMagic (uint32_t magic); + + bool + ReadMachHeader (lldb::addr_t addr, + llvm::MachO::mach_header *header, + lldb_private::DataExtractor *load_command_data); + + class Segment + { + public: + Segment() : + name(), + vmaddr(LLDB_INVALID_ADDRESS), + vmsize(0), + fileoff(0), + filesize(0), + maxprot(0), + initprot(0), + nsects(0), + flags(0) + { + } + + lldb_private::ConstString name; + lldb::addr_t vmaddr; + lldb::addr_t vmsize; + lldb::addr_t fileoff; + lldb::addr_t filesize; + uint32_t maxprot; + uint32_t initprot; + uint32_t nsects; + uint32_t flags; + + bool + operator==(const Segment& rhs) const + { + return name == rhs.name && vmaddr == rhs.vmaddr && vmsize == rhs.vmsize; + } + + 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 + llvm::MachO::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) + uint32_t load_stop_id; // The process stop ID that the sections for this image were loaded + + DYLDImageInfo() : + address(LLDB_INVALID_ADDRESS), + slide(0), + mod_date(0), + file_spec(), + uuid(), + header(), + segments(), + load_stop_id(0) + { + } + + void + Clear(bool load_cmd_data_only) + { + if (!load_cmd_data_only) + { + address = LLDB_INVALID_ADDRESS; + slide = 0; + mod_date = 0; + file_spec.Clear(); + ::memset (&header, 0, sizeof(header)); + } + uuid.Clear(); + segments.clear(); + load_stop_id = 0; + } + + 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(); + } + + uint32_t + GetAddressByteSize () + { + if (header.cputype) + { + if (header.cputype & llvm::MachO::CPU_ARCH_ABI64) + return 8; + else + return 4; + } + return 0; + } + + lldb::ByteOrder + GetByteOrder(); + + lldb_private::ArchSpec + GetArchitecture () const + { + return lldb_private::ArchSpec (lldb_private::eArchTypeMachO, header.cputype, header.cpusubtype); + } + + 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, + DYLDImageInfo& dylib_info, + lldb_private::FileSpec *lc_id_dylinker); + + bool + UpdateImageLoadAddress(lldb_private::Module *module, + DYLDImageInfo& info); + + bool + UnloadImageLoadAddress (lldb_private::Module *module, + DYLDImageInfo& info); + + lldb::ModuleSP + FindTargetModuleForDYLDImageInfo (DYLDImageInfo &image_info, + bool can_create, + bool *did_create_ptr); + + DYLDImageInfo * + GetImageInfo (lldb_private::Module *module); + + bool + NeedToLocateDYLD () const; + + bool + SetNotificationBreakpoint (); + + // There is a little tricky bit where you might initially attach while dyld is updating + // the all_image_infos, and you can't read the infos, so you have to continue and pick it + // up when you hit the update breakpoint. At that point, you need to run this initialize + // function, but when you do it that way you DON'T need to do the extra work you would at + // the breakpoint. + // So this function will only do actual work if the image infos haven't been read yet. + // If it does do any work, then it will return true, and false otherwise. That way you can + // call it in the breakpoint action, and if it returns true you're done. + bool + InitializeFromAllImageInfos (); + + bool + ReadAllImageInfosStructure (); + + bool + AddModulesUsingInfosFromDebugserver (lldb_private::StructuredData::ObjectSP image_details, DYLDImageInfo::collection &image_infos); + + bool + AddModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count); + + bool + AddModulesUsingImageInfos (DYLDImageInfo::collection &image_infos); + + bool + RemoveModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count); + + void + UpdateImageInfosHeaderAndLoadCommands(DYLDImageInfo::collection &image_infos, + uint32_t infos_count, + bool update_executable); + + bool + ReadImageInfos (lldb::addr_t image_infos_addr, + uint32_t image_infos_count, + DYLDImageInfo::collection &image_infos); + + + DYLDImageInfo m_dyld; // Info about the current dyld being used + lldb::ModuleWP m_dyld_module_wp; + lldb::addr_t m_dyld_all_image_infos_addr; + DYLDAllImageInfos m_dyld_all_image_infos; + uint32_t m_dyld_all_image_infos_stop_id; + lldb::user_id_t m_break_id; + DYLDImageInfo::collection m_dyld_image_infos; // Current shared libraries information + uint32_t m_dyld_image_infos_stop_id; // The process stop ID that "m_dyld_image_infos" is valid for + mutable lldb_private::Mutex m_mutex; + lldb_private::Process::Notifications m_notification_callbacks; + bool m_process_image_addr_is_all_images_infos; + +private: + DISALLOW_COPY_AND_ASSIGN (DynamicLoaderMacOSXDYLD); +}; + +#endif // liblldb_DynamicLoaderMacOSXDYLD_h_ |