summaryrefslogtreecommitdiff
path: root/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
diff options
context:
space:
mode:
Diffstat (limited to 'source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h')
-rw-r--r--source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h385
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_