[Lldb-commits] [lldb] r275733 - Refactor (with some rewriting) the DynamicLoaderMacOSX plugin into

Jason Molenda via lldb-commits lldb-commits at lists.llvm.org
Sun Jul 17 14:27:32 PDT 2016


Author: jmolenda
Date: Sun Jul 17 16:27:32 2016
New Revision: 275733

URL: http://llvm.org/viewvc/llvm-project?rev=275733&view=rev
Log:
Refactor (with some rewriting) the DynamicLoaderMacOSX plugin into
a base class and a derived class, with the derived class containing
the methods specific to reading dyld's all_image_infos, dyld's
method of specifying images that have been loaded or unloaded, the
place where we put a breakpoint in dyld to get notified about newly
loaded or unloaded images.

This is in preparation for a second derived class which will use
some alternate methods for getting this information; that will be
a separate commit in the next few days.

There's a couple of ivars that should probably be in the derived
DyanmicLoaderMacOSX class instead of the base DynamicLoaderDarwin
class (m_dyld_image_infos, m_dyld_image_infos_stop_id).  I don't
think I'll need to use these in the new derived class - I'll 
move them down to DynamicLoaderMacOSX if it works out that way;
it'll simplify locking if I can do that.

<rdar://problem/25251243> 

Added:
    lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
    lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h
Modified:
    lldb/trunk/include/lldb/Target/DynamicLoader.h
    lldb/trunk/lldb.xcodeproj/project.pbxproj
    lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/CMakeLists.txt
    lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
    lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h

Modified: lldb/trunk/include/lldb/Target/DynamicLoader.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/DynamicLoader.h?rev=275733&r1=275732&r2=275733&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/DynamicLoader.h (original)
+++ lldb/trunk/include/lldb/Target/DynamicLoader.h Sun Jul 17 16:27:32 2016
@@ -71,7 +71,7 @@ public:
     /// The destructor is virtual since this class is designed to be
     /// inherited from by the plug-in instance.
     //------------------------------------------------------------------
-    ~DynamicLoader() override;
+    virtual ~DynamicLoader() override;
 
     //------------------------------------------------------------------
     /// Called after attaching a process.

Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=275733&r1=275732&r2=275733&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Sun Jul 17 16:27:32 2016
@@ -892,6 +892,8 @@
 		AF25AB26188F685C0030DEC3 /* AppleGetQueuesHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF25AB24188F685C0030DEC3 /* AppleGetQueuesHandler.cpp */; };
 		AF26703A1852D01E00B6CC36 /* Queue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF2670381852D01E00B6CC36 /* Queue.cpp */; };
 		AF26703B1852D01E00B6CC36 /* QueueList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF2670391852D01E00B6CC36 /* QueueList.cpp */; };
+		AF27AD551D3603EA00CF2833 /* DynamicLoaderDarwin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF27AD531D3603EA00CF2833 /* DynamicLoaderDarwin.cpp */; };
+		AF27AD561D3603EA00CF2833 /* DynamicLoaderDarwin.h in Headers */ = {isa = PBXBuildFile; fileRef = AF27AD541D3603EA00CF2833 /* DynamicLoaderDarwin.h */; };
 		AF2BA6EC1A707E3400C5248A /* UriParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33064C991A5C7A330033D415 /* UriParser.cpp */; };
 		AF2BCA6C18C7EFDE005B4526 /* JITLoaderGDB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF2BCA6918C7EFDE005B4526 /* JITLoaderGDB.cpp */; };
 		AF33B4BE1C1FA441001B28D9 /* NetBSDSignals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF33B4BC1C1FA441001B28D9 /* NetBSDSignals.cpp */; };
@@ -2813,6 +2815,8 @@
 		AF25AB25188F685C0030DEC3 /* AppleGetQueuesHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppleGetQueuesHandler.h; sourceTree = "<group>"; };
 		AF2670381852D01E00B6CC36 /* Queue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Queue.cpp; path = source/Target/Queue.cpp; sourceTree = "<group>"; };
 		AF2670391852D01E00B6CC36 /* QueueList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = QueueList.cpp; path = source/Target/QueueList.cpp; sourceTree = "<group>"; };
+		AF27AD531D3603EA00CF2833 /* DynamicLoaderDarwin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DynamicLoaderDarwin.cpp; sourceTree = "<group>"; };
+		AF27AD541D3603EA00CF2833 /* DynamicLoaderDarwin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DynamicLoaderDarwin.h; sourceTree = "<group>"; };
 		AF2BCA6918C7EFDE005B4526 /* JITLoaderGDB.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITLoaderGDB.cpp; sourceTree = "<group>"; };
 		AF2BCA6A18C7EFDE005B4526 /* JITLoaderGDB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITLoaderGDB.h; sourceTree = "<group>"; };
 		AF33B4BC1C1FA441001B28D9 /* NetBSDSignals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NetBSDSignals.cpp; path = Utility/NetBSDSignals.cpp; sourceTree = "<group>"; };
@@ -3291,6 +3295,8 @@
 		260C897910F57C5600BB2B04 /* MacOSX-DYLD */ = {
 			isa = PBXGroup;
 			children = (
+				AF27AD531D3603EA00CF2833 /* DynamicLoaderDarwin.cpp */,
+				AF27AD541D3603EA00CF2833 /* DynamicLoaderDarwin.h */,
 				260C897A10F57C5600BB2B04 /* DynamicLoaderMacOSXDYLD.cpp */,
 				260C897B10F57C5600BB2B04 /* DynamicLoaderMacOSXDYLD.h */,
 			);
@@ -6072,6 +6078,7 @@
 				260A63171861008E00FECF8E /* IOHandler.h in Headers */,
 				267F68581CC02EAE0086832B /* RegisterContextPOSIX_s390x.h in Headers */,
 				6D0F614F1C80AB0C00A4ECEE /* JavaLanguageRuntime.h in Headers */,
+				AF27AD561D3603EA00CF2833 /* DynamicLoaderDarwin.h in Headers */,
 				AFCB2BBE1BF577F40018B553 /* PythonExceptionState.h in Headers */,
 				267F684B1CC02DED0086832B /* ABISysV_s390x.h in Headers */,
 				AF8AD6311BEC28A400150209 /* PlatformAppleWatchSimulator.h in Headers */,
@@ -6825,6 +6832,7 @@
 				2689008413353E2200698AC0 /* CommandObjectRegexCommand.cpp in Sources */,
 				2689008513353E2200698AC0 /* CommandReturnObject.cpp in Sources */,
 				6D95DC001B9DC057000E318A /* DIERef.cpp in Sources */,
+				AF27AD551D3603EA00CF2833 /* DynamicLoaderDarwin.cpp in Sources */,
 				3FDFE53519A29327009756A7 /* HostInfoBase.cpp in Sources */,
 				26474CBE18D0CB2D0073DEBA /* RegisterContextMach_i386.cpp in Sources */,
 				2689008613353E2200698AC0 /* Options.cpp in Sources */,

Modified: lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/CMakeLists.txt?rev=275733&r1=275732&r2=275733&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/CMakeLists.txt (original)
+++ lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/CMakeLists.txt Sun Jul 17 16:27:32 2016
@@ -1,3 +1,4 @@
 add_lldb_library(lldbPluginDynamicLoaderMacOSXDYLD
   DynamicLoaderMacOSXDYLD.cpp
+  DynamicLoaderDarwin.cpp
   )

Added: lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp?rev=275733&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp (added)
+++ lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp Sun Jul 17 16:27:32 2016
@@ -0,0 +1,1143 @@
+//===-- DynamicLoaderDarwin.cpp -----------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Breakpoint/StoppointCallbackContext.h"
+#include "lldb/Core/DataBuffer.h"
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Section.h"
+#include "lldb/Core/State.h"
+#include "lldb/Expression/DiagnosticManager.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/Function.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Target/ABI.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlanCallFunction.h"
+#include "lldb/Target/ThreadPlanRunToAddress.h"
+
+#include "DynamicLoaderDarwin.h"
+
+//#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
+#ifdef ENABLE_DEBUG_PRINTF
+#include <stdio.h>
+#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
+#else
+#define DEBUG_PRINTF(fmt, ...)
+#endif
+
+#ifndef __APPLE__
+#include "Utility/UuidCompatibility.h"
+#else
+#include <uuid/uuid.h>
+#endif
+
+using namespace lldb;
+using namespace lldb_private;
+
+
+//----------------------------------------------------------------------
+// Constructor
+//----------------------------------------------------------------------
+DynamicLoaderDarwin::DynamicLoaderDarwin (Process* process) 
+    : DynamicLoader(process),
+      m_dyld_module_wp(),
+      m_libpthread_module_wp(),
+      m_pthread_getspecific_addr(),
+      m_tid_to_tls_map(),
+      m_dyld_image_infos(),
+      m_dyld_image_infos_stop_id(UINT32_MAX),
+      m_dyld(),
+      m_mutex()
+{
+}
+
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+DynamicLoaderDarwin::~DynamicLoaderDarwin()
+{
+}
+
+//------------------------------------------------------------------
+/// Called after attaching a process.
+///
+/// Allow DynamicLoader plug-ins to execute some code after
+/// attaching to a process.
+//------------------------------------------------------------------
+void
+DynamicLoaderDarwin::DidAttach ()
+{
+    PrivateInitialize(m_process);
+    DoInitialImageFetch ();
+    SetNotificationBreakpoint ();
+}
+
+//------------------------------------------------------------------
+/// Called after attaching a process.
+///
+/// Allow DynamicLoader plug-ins to execute some code after
+/// attaching to a process.
+//------------------------------------------------------------------
+void
+DynamicLoaderDarwin::DidLaunch ()
+{
+    PrivateInitialize(m_process);
+    DoInitialImageFetch ();
+    SetNotificationBreakpoint ();
+}
+
+
+//----------------------------------------------------------------------
+// Clear out the state of this class.
+//----------------------------------------------------------------------
+void
+DynamicLoaderDarwin::Clear (bool clear_process)
+{
+    std::lock_guard<std::recursive_mutex> guard(m_mutex);
+    if (clear_process)
+        m_process = NULL;
+    m_dyld_image_infos.clear();
+    m_dyld_image_infos_stop_id = UINT32_MAX;
+    m_dyld.Clear(false);
+}
+
+ModuleSP
+DynamicLoaderDarwin::FindTargetModuleForImageInfo (ImageInfo &image_info, bool can_create, bool *did_create_ptr)
+{
+    if (did_create_ptr)
+        *did_create_ptr = false;
+    
+    Target &target = m_process->GetTarget();
+    const ModuleList &target_images = target.GetImages();
+    ModuleSpec module_spec (image_info.file_spec);
+    module_spec.GetUUID() = image_info.uuid;
+    ModuleSP module_sp (target_images.FindFirstModule (module_spec));
+    
+    if (module_sp && !module_spec.GetUUID().IsValid() && !module_sp->GetUUID().IsValid())
+    {
+        // No UUID, we must rely upon the cached module modification 
+        // time and the modification time of the file on disk
+        if (module_sp->GetModificationTime() != module_sp->GetFileSpec().GetModificationTime())
+            module_sp.reset();
+    }
+
+    if (!module_sp)
+    {
+        if (can_create)
+        {
+            module_sp = target.GetSharedModule (module_spec);
+            if (!module_sp || module_sp->GetObjectFile() == NULL)
+                module_sp = m_process->ReadModuleFromMemory (image_info.file_spec, image_info.address);
+
+            if (did_create_ptr)
+                *did_create_ptr = (bool) module_sp;
+        }
+    }
+    return module_sp;
+}
+
+DynamicLoaderDarwin::ImageInfo *
+DynamicLoaderDarwin::FindImageInfoForAddress (addr_t load_address)
+{
+    std::lock_guard<std::recursive_mutex> guard(m_mutex);
+    const size_t image_count = m_dyld_image_infos.size();
+    for (size_t i = 0; i < image_count; i++)
+    {
+        if (load_address == m_dyld_image_infos[i].address)
+        {
+            return &m_dyld_image_infos[i];
+        }
+    }
+    return NULL;
+}
+
+void
+DynamicLoaderDarwin::UnloadImages (const std::vector<lldb::addr_t> &solib_addresses)
+{
+    std::lock_guard<std::recursive_mutex> guard(m_mutex);
+    if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
+        return;
+
+    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
+    Target &target = m_process->GetTarget();
+    if (log)
+        log->Printf ("Removing %" PRId64 " modules.", (uint64_t) solib_addresses.size());
+
+    ModuleList unloaded_module_list;
+
+    for (addr_t solib_addr : solib_addresses)
+    {
+        Address header;
+        if (header.SetLoadAddress (solib_addr, &target))
+        {
+            if (header.GetOffset() == 0)
+            {
+                ModuleSP module_to_remove (header.GetModule());
+                if (module_to_remove.get())
+                {
+                    if (log)
+                        log->Printf ("Removing module at address 0x%" PRIx64, solib_addr);
+                    // remove the sections from the Target
+                    UnloadSections (module_to_remove);
+                    // add this to the list of modules to remove
+                    unloaded_module_list.AppendIfNeeded (module_to_remove);
+                    // remove the entry from the m_dyld_image_infos
+                    ImageInfo::collection::iterator pos, end = m_dyld_image_infos.end();
+                    for (pos = m_dyld_image_infos.begin(); pos != end; pos++)
+                    {
+                        if (solib_addr == (*pos).address)
+                        {
+                            m_dyld_image_infos.erase(pos);
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    if (unloaded_module_list.GetSize() > 0)
+    {
+        if (log)
+        {
+            log->PutCString("Unloaded:");
+            unloaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderDarwin::UnloadModules");
+        }
+        m_process->GetTarget().GetImages().Remove (unloaded_module_list);
+        m_dyld_image_infos_stop_id = m_process->GetStopID();
+    }
+}
+
+//----------------------------------------------------------------------
+// Update the load addresses for all segments in MODULE using the
+// updated INFO that is passed in.
+//----------------------------------------------------------------------
+bool
+DynamicLoaderDarwin::UpdateImageLoadAddress (Module *module, ImageInfo& info)
+{
+    bool changed = false;
+    if (module)
+    {
+        ObjectFile *image_object_file = module->GetObjectFile();
+        if (image_object_file)
+        {
+            SectionList *section_list = image_object_file->GetSectionList ();
+            if (section_list)
+            {
+                std::vector<uint32_t> inaccessible_segment_indexes;
+                // We now know the slide amount, so go through all sections
+                // and update the load addresses with the correct values.
+                const size_t num_segments = info.segments.size();
+                for (size_t i=0; i<num_segments; ++i)
+                {
+                    // Only load a segment if it has protections. Things like
+                    // __PAGEZERO don't have any protections, and they shouldn't
+                    // be slid
+                    SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name));
+
+                    if (info.segments[i].maxprot == 0)
+                    {
+                        inaccessible_segment_indexes.push_back(i);
+                    }
+                    else
+                    {
+                        const addr_t new_section_load_addr = info.segments[i].vmaddr + info.slide;
+                        static ConstString g_section_name_LINKEDIT ("__LINKEDIT");
+
+                        if (section_sp)
+                        {
+                            // __LINKEDIT sections from files in the shared cache
+                            // can overlap so check to see what the segment name is
+                            // and pass "false" so we don't warn of overlapping
+                            // "Section" objects, and "true" for all other sections.
+                            const bool warn_multiple = section_sp->GetName() != g_section_name_LINKEDIT;
+
+                            changed = m_process->GetTarget().SetSectionLoadAddress (section_sp, new_section_load_addr, warn_multiple);
+                        }
+                        else
+                        {
+                            Host::SystemLog (Host::eSystemLogWarning, 
+                                             "warning: unable to find and load segment named '%s' at 0x%" PRIx64 " in '%s' in macosx dynamic loader plug-in.\n",
+                                             info.segments[i].name.AsCString("<invalid>"),
+                                             (uint64_t)new_section_load_addr,
+                                             image_object_file->GetFileSpec().GetPath().c_str());
+                        }
+                    }
+                }
+                
+                // If the loaded the file (it changed) and we have segments that
+                // are not readable or writeable, add them to the invalid memory
+                // region cache for the process. This will typically only be
+                // the __PAGEZERO segment in the main executable. We might be able
+                // to apply this more generally to more sections that have no
+                // protections in the future, but for now we are going to just
+                // do __PAGEZERO.
+                if (changed && !inaccessible_segment_indexes.empty())
+                {
+                    for (uint32_t i=0; i<inaccessible_segment_indexes.size(); ++i)
+                    {
+                        const uint32_t seg_idx = inaccessible_segment_indexes[i];
+                        SectionSP section_sp(section_list->FindSectionByName(info.segments[seg_idx].name));
+
+                        if (section_sp)
+                        {
+                            static ConstString g_pagezero_section_name("__PAGEZERO");
+                            if (g_pagezero_section_name == section_sp->GetName())
+                            {
+                                // __PAGEZERO never slides...
+                                const lldb::addr_t vmaddr = info.segments[seg_idx].vmaddr;
+                                const lldb::addr_t vmsize = info.segments[seg_idx].vmsize;
+                                Process::LoadRange pagezero_range (vmaddr, vmsize);
+                                m_process->AddInvalidMemoryRegion(pagezero_range);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    // We might have an in memory image that was loaded as soon as it was created
+    if (info.load_stop_id == m_process->GetStopID())
+        changed = true;
+    else if (changed)
+    {
+        // Update the stop ID when this library was updated
+        info.load_stop_id = m_process->GetStopID();
+    }
+    return changed;
+}
+
+//----------------------------------------------------------------------
+// Unload the segments in MODULE using the INFO that is passed in.
+//----------------------------------------------------------------------
+bool
+DynamicLoaderDarwin::UnloadModuleSections (Module *module, ImageInfo& info)
+{
+    bool changed = false;
+    if (module)
+    {
+        ObjectFile *image_object_file = module->GetObjectFile();
+        if (image_object_file)
+        {
+            SectionList *section_list = image_object_file->GetSectionList ();
+            if (section_list)
+            {
+                const size_t num_segments = info.segments.size();
+                for (size_t i=0; i<num_segments; ++i)
+                {
+                    SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name));
+                    if (section_sp)
+                    {
+                        const addr_t old_section_load_addr = info.segments[i].vmaddr + info.slide;
+                        if (m_process->GetTarget().SetSectionUnloaded (section_sp, old_section_load_addr))
+                            changed = true;
+                    }
+                    else
+                    {
+                        Host::SystemLog (Host::eSystemLogWarning, 
+                                         "warning: unable to find and unload segment named '%s' in '%s' in macosx dynamic loader plug-in.\n",
+                                         info.segments[i].name.AsCString("<invalid>"),
+                                         image_object_file->GetFileSpec().GetPath().c_str());
+                    }
+                }
+            }
+        }
+    }
+    return changed;
+}
+
+
+// Given a JSON dictionary (from debugserver, most likely) of binary images loaded in the inferior
+// process, add the images to the ImageInfo collection.
+
+bool
+DynamicLoaderDarwin::JSONImageInformationIntoImageInfo (StructuredData::ObjectSP image_details, ImageInfo::collection &image_infos)
+{
+    StructuredData::ObjectSP images_sp = image_details->GetAsDictionary()->GetValueForKey("images");
+    if (images_sp.get() == nullptr)
+        return false;
+
+    image_infos.resize (images_sp->GetAsArray()->GetSize());
+
+    for (size_t i = 0; i < image_infos.size(); i++)
+    {
+        StructuredData::ObjectSP image_sp = images_sp->GetAsArray()->GetItemAtIndex(i);
+        if (image_sp.get() == nullptr || image_sp->GetAsDictionary() == nullptr)
+            return false;
+        StructuredData::Dictionary *image = image_sp->GetAsDictionary();
+        if (image->HasKey("load_address") == false 
+            || image->HasKey("pathname") == false 
+            || image->HasKey("mod_date") == false
+            || image->HasKey("mach_header") == false 
+            || image->GetValueForKey("mach_header")->GetAsDictionary() == nullptr
+            || image->HasKey("segments") == false 
+            || image->GetValueForKey("segments")->GetAsArray() == nullptr
+            || image->HasKey("uuid") == false )
+        {
+            return false;
+        }
+        image_infos[i].address = image->GetValueForKey("load_address")->GetAsInteger()->GetValue();
+        image_infos[i].mod_date = image->GetValueForKey("mod_date")->GetAsInteger()->GetValue();
+        image_infos[i].file_spec.SetFile(image->GetValueForKey("pathname")->GetAsString()->GetValue().c_str(), false);
+
+        StructuredData::Dictionary *mh = image->GetValueForKey("mach_header")->GetAsDictionary();
+        image_infos[i].header.magic = mh->GetValueForKey("magic")->GetAsInteger()->GetValue();
+        image_infos[i].header.cputype = mh->GetValueForKey("cputype")->GetAsInteger()->GetValue();
+        image_infos[i].header.cpusubtype = mh->GetValueForKey("cpusubtype")->GetAsInteger()->GetValue();
+        image_infos[i].header.filetype = mh->GetValueForKey("filetype")->GetAsInteger()->GetValue();
+
+        // Fields that aren't used by DynamicLoaderDarwin so debugserver doesn't currently send them
+        // in the reply.
+
+        if (mh->HasKey("flags"))
+            image_infos[i].header.flags = mh->GetValueForKey("flags")->GetAsInteger()->GetValue();
+        else
+            image_infos[i].header.flags = 0;
+
+        if (mh->HasKey("ncmds"))
+            image_infos[i].header.ncmds = mh->GetValueForKey("ncmds")->GetAsInteger()->GetValue();
+        else
+            image_infos[i].header.ncmds = 0;
+
+        if (mh->HasKey("sizeofcmds"))
+            image_infos[i].header.sizeofcmds = mh->GetValueForKey("sizeofcmds")->GetAsInteger()->GetValue();
+        else
+            image_infos[i].header.sizeofcmds = 0;
+
+        StructuredData::Array *segments = image->GetValueForKey("segments")->GetAsArray();
+        uint32_t segcount = segments->GetSize();
+        for (size_t j = 0; j < segcount; j++)
+        {
+            Segment segment;
+            StructuredData::Dictionary *seg = segments->GetItemAtIndex(j)->GetAsDictionary();
+            segment.name = ConstString(seg->GetValueForKey("name")->GetAsString()->GetValue().c_str());
+            segment.vmaddr = seg->GetValueForKey("vmaddr")->GetAsInteger()->GetValue();
+            segment.vmsize = seg->GetValueForKey("vmsize")->GetAsInteger()->GetValue();
+            segment.fileoff = seg->GetValueForKey("fileoff")->GetAsInteger()->GetValue();
+            segment.filesize = seg->GetValueForKey("filesize")->GetAsInteger()->GetValue();
+            segment.maxprot = seg->GetValueForKey("maxprot")->GetAsInteger()->GetValue();
+
+            // Fields that aren't used by DynamicLoaderDarwin so debugserver doesn't currently send them
+            // in the reply.
+
+            if (seg->HasKey("initprot"))
+                segment.initprot = seg->GetValueForKey("initprot")->GetAsInteger()->GetValue();
+            else
+                segment.initprot = 0;
+
+            if (seg->HasKey("flags"))
+                segment.flags = seg->GetValueForKey("flags")->GetAsInteger()->GetValue();
+            else
+                segment.flags = 0;
+
+            if (seg->HasKey("nsects"))
+                segment.nsects = seg->GetValueForKey("nsects")->GetAsInteger()->GetValue();
+            else
+                segment.nsects = 0;
+
+            image_infos[i].segments.push_back (segment);
+        }
+
+        image_infos[i].uuid.SetFromCString (image->GetValueForKey("uuid")->GetAsString()->GetValue().c_str());
+
+        // All sections listed in the dyld image info structure will all
+        // either be fixed up already, or they will all be off by a single
+        // slide amount that is determined by finding the first segment
+        // that is at file offset zero which also has bytes (a file size
+        // that is greater than zero) in the object file.
+    
+        // Determine the slide amount (if any)
+        const size_t num_sections = image_infos[i].segments.size();
+        for (size_t k = 0; k < num_sections; ++k)
+        {
+            // Iterate through the object file sections to find the
+            // first section that starts of file offset zero and that
+            // has bytes in the file...
+            if ((image_infos[i].segments[k].fileoff == 0 && image_infos[i].segments[k].filesize > 0) 
+                || (image_infos[i].segments[k].name == ConstString("__TEXT")))
+            {
+                image_infos[i].slide = image_infos[i].address - image_infos[i].segments[k].vmaddr;
+                // We have found the slide amount, so we can exit
+                // this for loop.
+                break;
+            }
+        }
+    }
+
+ return true;
+}
+
+void
+DynamicLoaderDarwin::UpdateDYLDImageInfoFromNewImageInfos (ImageInfo::collection &image_infos)
+{
+    const size_t image_infos_size = image_infos.size();
+    for (size_t i = 0; i < image_infos_size; i++)
+    {
+        if (image_infos[i].header.filetype == llvm::MachO::MH_DYLINKER)
+        {
+            UpdateDYLDImageInfoFromNewImageInfo (image_infos[i]);
+            break; // FIXME simulator debugging w/ multiple dylds
+        }
+    }
+}
+
+void
+DynamicLoaderDarwin::UpdateDYLDImageInfoFromNewImageInfo (ImageInfo &image_info)
+{
+    // FIXME simulator debugging w/ multiple dylds
+    if (image_info.header.filetype == llvm::MachO::MH_DYLINKER)
+    {
+        const bool can_create = true;
+        ModuleSP dyld_sp = FindTargetModuleForImageInfo (image_info, can_create, NULL);
+        if (dyld_sp.get())
+        {
+            Target &target = m_process->GetTarget();
+            target.GetImages().AppendIfNeeded (dyld_sp);
+            UpdateImageLoadAddress (dyld_sp.get(), image_info);
+            SetDYLDModule (dyld_sp);
+        }
+    }
+}
+
+void
+DynamicLoaderDarwin::AddExecutableModuleIfInImageInfos (ImageInfo::collection &image_infos)
+{
+    const size_t image_infos_size = image_infos.size();
+    for (size_t i = 0; i < image_infos_size; i++)
+    {
+        if (image_infos[i].header.filetype == llvm::MachO::MH_EXECUTE)
+        {
+            Target &target = m_process->GetTarget();
+            const bool can_create = true;
+            ModuleSP exe_module_sp (FindTargetModuleForImageInfo (image_infos[i], can_create, NULL));
+    
+            if (exe_module_sp)
+            {
+                UpdateImageLoadAddress (exe_module_sp.get(), image_infos[i]);
+    
+                if (exe_module_sp.get() != target.GetExecutableModulePointer())
+                {
+                    // Don't load dependent images since we are in dyld where we will know
+                    // and find out about all images that are loaded. Also when setting the
+                    // executable module, it will clear the targets module list, and if we
+                    // have an in memory dyld module, it will get removed from the list
+                    // so we will need to add it back after setting the executable module,
+                    // so we first try and see if we already have a weak pointer to the
+                    // dyld module, make it into a shared pointer, then add the executable,
+                    // then re-add it back to make sure it is always in the list.
+                    
+                    const bool get_dependent_images = false;
+                    m_process->GetTarget().SetExecutableModule (exe_module_sp, 
+                                                                get_dependent_images);
+    
+                    UpdateDYLDImageInfoFromNewImageInfos (image_infos);
+                }
+            }
+        }
+    }
+}
+
+void
+DynamicLoaderDarwin::SetDYLDModule (lldb::ModuleSP &dyld_module_sp)
+{
+    m_dyld_module_wp = dyld_module_sp;
+}
+
+ModuleSP
+DynamicLoaderDarwin::GetDYLDModule ()
+{
+    ModuleSP dyld_sp (m_dyld_module_wp.lock());
+    return dyld_sp;
+}
+
+bool
+DynamicLoaderDarwin::AddModulesUsingImageInfos (ImageInfo::collection &image_infos)
+{
+    std::lock_guard<std::recursive_mutex> guard(m_mutex);
+    // Now add these images to the main list.
+    ModuleList loaded_module_list;
+    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
+    Target &target = m_process->GetTarget();
+    ModuleList& target_images = target.GetImages();
+    
+    for (uint32_t idx = 0; idx < image_infos.size(); ++idx)
+    {
+        if (log)
+        {
+            log->Printf ("Adding new image at address=0x%16.16" PRIx64 ".", image_infos[idx].address);
+            image_infos[idx].PutToLog (log);
+        }
+        
+        m_dyld_image_infos.push_back(image_infos[idx]);
+        
+        ModuleSP image_module_sp (FindTargetModuleForImageInfo (image_infos[idx], true, NULL));
+
+        if (image_module_sp)
+        {
+            ObjectFile *objfile = image_module_sp->GetObjectFile ();
+            if (objfile)
+            {
+                SectionList *sections = objfile->GetSectionList();
+                if (sections)
+                {
+                    ConstString commpage_dbstr("__commpage");
+                    Section *commpage_section = sections->FindSectionByName(commpage_dbstr).get();
+                    if (commpage_section)
+                    {
+                        ModuleSpec module_spec (objfile->GetFileSpec(), image_infos[idx].GetArchitecture ());
+                        module_spec.GetObjectName() = commpage_dbstr;
+                        ModuleSP commpage_image_module_sp(target_images.FindFirstModule (module_spec));
+                        if (!commpage_image_module_sp)
+                        {
+                            module_spec.SetObjectOffset (objfile->GetFileOffset() + commpage_section->GetFileOffset());
+                            module_spec.SetObjectSize (objfile->GetByteSize());
+                            commpage_image_module_sp  = target.GetSharedModule (module_spec);
+                            if (!commpage_image_module_sp || commpage_image_module_sp->GetObjectFile() == NULL)
+                            {
+                                commpage_image_module_sp = m_process->ReadModuleFromMemory (image_infos[idx].file_spec,
+                                                                                            image_infos[idx].address);
+                                // Always load a memory image right away in the target in case
+                                // we end up trying to read the symbol table from memory... The
+                                // __LINKEDIT will need to be mapped so we can figure out where
+                                // the symbol table bits are...
+                                bool changed = false;
+                                UpdateImageLoadAddress (commpage_image_module_sp.get(), image_infos[idx]);
+                                target.GetImages().Append(commpage_image_module_sp);
+                                if (changed)
+                                {
+                                    image_infos[idx].load_stop_id = m_process->GetStopID();
+                                    loaded_module_list.AppendIfNeeded (commpage_image_module_sp);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+
+            // UpdateImageLoadAddress will return true if any segments
+            // change load address. We need to check this so we don't
+            // mention that all loaded shared libraries are newly loaded
+            // each time we hit out dyld breakpoint since dyld will list all
+            // shared libraries each time.
+            if (UpdateImageLoadAddress (image_module_sp.get(), image_infos[idx]))
+            {
+                target_images.AppendIfNeeded(image_module_sp);
+                loaded_module_list.AppendIfNeeded (image_module_sp);
+            }
+        }
+    }
+    
+    if (loaded_module_list.GetSize() > 0)
+    {
+        if (log)
+            loaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderDarwin::ModulesDidLoad");
+        m_process->GetTarget().ModulesDidLoad (loaded_module_list);
+    }
+    return true;
+}
+
+
+//----------------------------------------------------------------------
+// On Mac OS X libobjc (the Objective-C runtime) has several critical dispatch
+// functions written in hand-written assembly, and also have hand-written unwind
+// information in the eh_frame section.  Normally we prefer analyzing the 
+// assembly instructions of a currently executing frame to unwind from that frame --
+// but on hand-written functions this profiling can fail.  We should use the
+// eh_frame instructions for these functions all the time.
+//
+// As an aside, it would be better if the eh_frame entries had a flag (or were
+// extensible so they could have an Apple-specific flag) which indicates that
+// the instructions are asynchronous -- accurate at every instruction, instead
+// of our normal default assumption that they are not.
+//----------------------------------------------------------------------
+
+bool
+DynamicLoaderDarwin::AlwaysRelyOnEHUnwindInfo (SymbolContext &sym_ctx)
+{
+    ModuleSP module_sp;
+    if (sym_ctx.symbol)
+    {
+        module_sp = sym_ctx.symbol->GetAddressRef().GetModule();
+    }
+    if (module_sp.get() == NULL && sym_ctx.function)
+    {
+        module_sp = sym_ctx.function->GetAddressRange().GetBaseAddress().GetModule();
+    }
+    if (module_sp.get() == NULL)
+        return false;
+
+    ObjCLanguageRuntime *objc_runtime = m_process->GetObjCLanguageRuntime();
+    if (objc_runtime != NULL && objc_runtime->IsModuleObjCLibrary (module_sp))
+    {
+        return true;
+    }
+
+    return false;
+}
+
+
+
+//----------------------------------------------------------------------
+// Dump a Segment to the file handle provided.
+//----------------------------------------------------------------------
+void
+DynamicLoaderDarwin::Segment::PutToLog (Log *log, lldb::addr_t slide) const
+{
+    if (log)
+    {
+        if (slide == 0)
+            log->Printf ("\t\t%16s [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")",
+                         name.AsCString(""), 
+                         vmaddr + slide, 
+                         vmaddr + slide + vmsize);
+        else
+            log->Printf ("\t\t%16s [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") slide = 0x%" PRIx64,
+                         name.AsCString(""), 
+                         vmaddr + slide, 
+                         vmaddr + slide + vmsize, 
+                         slide);
+    }
+}
+
+const DynamicLoaderDarwin::Segment *
+DynamicLoaderDarwin::ImageInfo::FindSegment (const ConstString &name) const
+{
+    const size_t num_segments = segments.size();
+    for (size_t i=0; i<num_segments; ++i)
+    {
+        if (segments[i].name == name)
+            return &segments[i];
+    }
+    return NULL;
+}
+
+
+//----------------------------------------------------------------------
+// Dump an image info structure to the file handle provided.
+//----------------------------------------------------------------------
+void
+DynamicLoaderDarwin::ImageInfo::PutToLog (Log *log) const
+{
+    if (log == NULL)
+        return;
+    const uint8_t *u = (const uint8_t *)uuid.GetBytes();
+
+    if (address == LLDB_INVALID_ADDRESS)
+    {
+        if (u)
+        {
+            log->Printf("\t                           modtime=0x%8.8" PRIx64 " uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X path='%s' (UNLOADED)",
+                        mod_date,
+                        u[ 0], u[ 1], u[ 2], u[ 3],
+                        u[ 4], u[ 5], u[ 6], u[ 7],
+                        u[ 8], u[ 9], u[10], u[11],
+                        u[12], u[13], u[14], u[15],
+                        file_spec.GetPath().c_str());
+        }
+        else
+            log->Printf("\t                           modtime=0x%8.8" PRIx64 " path='%s' (UNLOADED)",
+                        mod_date,
+                        file_spec.GetPath().c_str());
+    }
+    else
+    {
+        if (u)
+        {
+            log->Printf("\taddress=0x%16.16" PRIx64 " modtime=0x%8.8" PRIx64 " uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X path='%s'",
+                        address,
+                        mod_date,
+                        u[ 0], u[ 1], u[ 2], u[ 3],
+                        u[ 4], u[ 5], u[ 6], u[ 7],
+                        u[ 8], u[ 9], u[10], u[11],
+                        u[12], u[13], u[14], u[15],
+                        file_spec.GetPath().c_str());
+        }
+        else
+        {
+            log->Printf("\taddress=0x%16.16" PRIx64 " modtime=0x%8.8" PRIx64 " path='%s'",
+                        address,
+                        mod_date,
+                        file_spec.GetPath().c_str());
+
+        }
+        for (uint32_t i=0; i<segments.size(); ++i)
+            segments[i].PutToLog(log, slide);
+    }
+}
+
+void
+DynamicLoaderDarwin::PrivateInitialize(Process *process)
+{
+    DEBUG_PRINTF("DynamicLoaderDarwin::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
+    Clear(true);
+    m_process = process;
+    m_process->GetTarget().ClearAllLoadedSections();
+}
+
+//----------------------------------------------------------------------
+// Member function that gets called when the process state changes.
+//----------------------------------------------------------------------
+void
+DynamicLoaderDarwin::PrivateProcessStateChanged (Process *process, StateType state)
+{
+    DEBUG_PRINTF("DynamicLoaderDarwin::%s(%s)\n", __FUNCTION__, StateAsCString(state));
+    switch (state)
+    {
+    case eStateConnected:
+    case eStateAttaching:
+    case eStateLaunching:
+    case eStateInvalid:
+    case eStateUnloaded:
+    case eStateExited:
+    case eStateDetached:
+        Clear(false);
+        break;
+
+    case eStateStopped:
+        // Keep trying find dyld and set our notification breakpoint each time
+        // we stop until we succeed
+        if (!DidSetNotificationBreakpoint () && m_process->IsAlive())
+        {
+            if (NeedToDoInitialImageFetch ())
+                DoInitialImageFetch ();
+
+            SetNotificationBreakpoint ();
+        }
+        break;
+
+    case eStateRunning:
+    case eStateStepping:
+    case eStateCrashed:
+    case eStateSuspended:
+        break;
+    }
+}
+
+ThreadPlanSP
+DynamicLoaderDarwin::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others)
+{
+    ThreadPlanSP thread_plan_sp;
+    StackFrame *current_frame = thread.GetStackFrameAtIndex(0).get();
+    const SymbolContext &current_context = current_frame->GetSymbolContext(eSymbolContextSymbol);
+    Symbol *current_symbol = current_context.symbol;
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    TargetSP target_sp (thread.CalculateTarget());
+
+    if (current_symbol != NULL)
+    {
+        std::vector<Address>  addresses;
+        
+        if (current_symbol->IsTrampoline())
+        {
+            const ConstString &trampoline_name = current_symbol->GetMangled().GetName(current_symbol->GetLanguage(), Mangled::ePreferMangled);
+            
+            if (trampoline_name)
+            {
+                const ModuleList &images = target_sp->GetImages();
+                
+                SymbolContextList code_symbols;
+                images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeCode, code_symbols);
+                size_t num_code_symbols = code_symbols.GetSize();
+                
+                if (num_code_symbols > 0)
+                {
+                    for (uint32_t i = 0; i < num_code_symbols; i++)
+                    {
+                        SymbolContext context;
+                        AddressRange addr_range;
+                        if (code_symbols.GetContextAtIndex(i, context))
+                        {
+                            context.GetAddressRange (eSymbolContextEverything, 0, false, addr_range);
+                            addresses.push_back(addr_range.GetBaseAddress());
+                            if (log)
+                            {
+                                addr_t load_addr = addr_range.GetBaseAddress().GetLoadAddress(target_sp.get());
+
+                                log->Printf ("Found a trampoline target symbol at 0x%" PRIx64 ".", load_addr);
+                            }
+                        }
+                    }
+                }
+                
+                SymbolContextList reexported_symbols;
+                images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeReExported, reexported_symbols);
+                size_t num_reexported_symbols = reexported_symbols.GetSize();
+                if (num_reexported_symbols > 0)
+                {
+                    for (uint32_t i = 0; i < num_reexported_symbols; i++)
+                    {
+                        SymbolContext context;
+                        if (reexported_symbols.GetContextAtIndex(i, context))
+                        {
+                            if (context.symbol)
+                            {
+                                Symbol *actual_symbol = context.symbol->ResolveReExportedSymbol(*target_sp.get());
+                                if (actual_symbol)
+                                {
+                                    const Address actual_symbol_addr = actual_symbol->GetAddress();
+                                    if (actual_symbol_addr.IsValid())
+                                    {
+                                        addresses.push_back(actual_symbol_addr);
+                                        if (log)
+                                        {
+                                            lldb::addr_t load_addr = actual_symbol_addr.GetLoadAddress(target_sp.get());
+                                            log->Printf ("Found a re-exported symbol: %s at 0x%" PRIx64 ".",
+                                                         actual_symbol->GetName().GetCString(), load_addr);
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+                
+                SymbolContextList indirect_symbols;
+                images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeResolver, indirect_symbols);
+                size_t num_indirect_symbols = indirect_symbols.GetSize();
+                if (num_indirect_symbols > 0)
+                {
+                    for (uint32_t i = 0; i < num_indirect_symbols; i++)
+                    {
+                        SymbolContext context;
+                        AddressRange addr_range;
+                        if (indirect_symbols.GetContextAtIndex(i, context))
+                        {
+                            context.GetAddressRange (eSymbolContextEverything, 0, false, addr_range);
+                            addresses.push_back(addr_range.GetBaseAddress());
+                            if (log)
+                            {
+                                addr_t load_addr = addr_range.GetBaseAddress().GetLoadAddress(target_sp.get());
+
+                                log->Printf ("Found an indirect target symbol at 0x%" PRIx64 ".", load_addr);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        else if (current_symbol->GetType() == eSymbolTypeReExported)
+        {
+            // I am not sure we could ever end up stopped AT a re-exported symbol.  But just in case:
+            
+            const Symbol *actual_symbol = current_symbol->ResolveReExportedSymbol(*(target_sp.get()));
+            if (actual_symbol)
+            {
+                Address target_addr(actual_symbol->GetAddress());
+                if (target_addr.IsValid())
+                {
+                    if (log)
+                        log->Printf ("Found a re-exported symbol: %s pointing to: %s at 0x%" PRIx64 ".",
+                                     current_symbol->GetName().GetCString(),
+                                     actual_symbol->GetName().GetCString(),
+                                     target_addr.GetLoadAddress(target_sp.get()));
+                    addresses.push_back (target_addr.GetLoadAddress(target_sp.get()));
+                
+                }
+            }
+        }
+        
+        if (addresses.size() > 0)
+        {
+            // First check whether any of the addresses point to Indirect symbols, and if they do, resolve them:
+            std::vector<lldb::addr_t> load_addrs;
+            for (Address address : addresses)
+            {
+                Symbol *symbol = address.CalculateSymbolContextSymbol();
+                if (symbol && symbol->IsIndirect())
+                {
+                    Error error;
+                    Address symbol_address = symbol->GetAddress();
+                    addr_t resolved_addr = thread.GetProcess()->ResolveIndirectFunction(&symbol_address, error);
+                    if (error.Success())
+                    {
+                        load_addrs.push_back(resolved_addr);
+                        if (log)
+                            log->Printf("ResolveIndirectFunction found resolved target for %s at 0x%" PRIx64 ".",
+                                        symbol->GetName().GetCString(), resolved_addr);
+                    }
+                }
+                else
+                {
+                    load_addrs.push_back(address.GetLoadAddress(target_sp.get()));
+                }
+                
+            }
+            thread_plan_sp.reset (new ThreadPlanRunToAddress (thread, load_addrs, stop_others));
+        }
+    }
+    else
+    {
+        if (log)
+            log->Printf ("Could not find symbol for step through.");
+    }
+
+    return thread_plan_sp;
+}
+
+size_t
+DynamicLoaderDarwin::FindEquivalentSymbols (lldb_private::Symbol *original_symbol, 
+                                               lldb_private::ModuleList &images, 
+                                               lldb_private::SymbolContextList &equivalent_symbols)
+{
+    const ConstString &trampoline_name = original_symbol->GetMangled().GetName(original_symbol->GetLanguage(), Mangled::ePreferMangled);
+    if (!trampoline_name)
+        return 0;
+        
+    size_t initial_size = equivalent_symbols.GetSize();
+    
+    static const char *resolver_name_regex = "(_gc|_non_gc|\\$[A-Za-z0-9\\$]+)$";
+    std::string equivalent_regex_buf("^");
+    equivalent_regex_buf.append (trampoline_name.GetCString());
+    equivalent_regex_buf.append (resolver_name_regex);
+
+    RegularExpression equivalent_name_regex (equivalent_regex_buf.c_str());
+    const bool append = true;
+    images.FindSymbolsMatchingRegExAndType (equivalent_name_regex, eSymbolTypeCode, equivalent_symbols, append);
+    
+    return equivalent_symbols.GetSize() - initial_size;
+}
+
+lldb::ModuleSP
+DynamicLoaderDarwin::GetPThreadLibraryModule()
+{
+    ModuleSP module_sp = m_libpthread_module_wp.lock();
+    if (!module_sp)
+    {
+        SymbolContextList sc_list;
+        ModuleSpec module_spec;
+        module_spec.GetFileSpec().GetFilename().SetCString("libsystem_pthread.dylib");
+        ModuleList module_list;
+        if (m_process->GetTarget().GetImages().FindModules(module_spec, module_list))
+        {
+            if (module_list.GetSize() == 1)
+            {
+                module_sp = module_list.GetModuleAtIndex(0);
+                if (module_sp)
+                    m_libpthread_module_wp = module_sp;
+            }
+        }
+    }
+    return module_sp;
+}
+
+Address
+DynamicLoaderDarwin::GetPthreadSetSpecificAddress()
+{
+    if (!m_pthread_getspecific_addr.IsValid())
+    {
+        ModuleSP module_sp = GetPThreadLibraryModule();
+        if (module_sp)
+        {
+            lldb_private::SymbolContextList sc_list;
+            module_sp->FindSymbolsWithNameAndType(ConstString("pthread_getspecific"), eSymbolTypeCode, sc_list);
+            SymbolContext sc;
+            if (sc_list.GetContextAtIndex(0, sc))
+            {
+                if (sc.symbol)
+                    m_pthread_getspecific_addr = sc.symbol->GetAddress();
+            }
+        }
+    }
+    return m_pthread_getspecific_addr;
+}
+
+lldb::addr_t
+DynamicLoaderDarwin::GetThreadLocalData(const lldb::ModuleSP module_sp, const lldb::ThreadSP thread_sp,
+                                        lldb::addr_t tls_file_addr)
+{
+    if (!thread_sp || !module_sp)
+        return LLDB_INVALID_ADDRESS;
+
+    std::lock_guard<std::recursive_mutex> guard(m_mutex);
+
+    const uint32_t addr_size = m_process->GetAddressByteSize();
+    uint8_t buf[sizeof(lldb::addr_t) * 3];
+
+    lldb_private::Address tls_addr;
+    if (module_sp->ResolveFileAddress(tls_file_addr, tls_addr))
+    {
+        Error error;
+        const size_t tsl_data_size = addr_size * 3;
+        Target &target = m_process->GetTarget();
+        if (target.ReadMemory(tls_addr, false, buf, tsl_data_size, error) == tsl_data_size)
+        {
+            const ByteOrder byte_order = m_process->GetByteOrder();
+            DataExtractor data(buf, sizeof(buf), byte_order, addr_size);
+            lldb::offset_t offset = addr_size; // Skip the first pointer
+            const lldb::addr_t pthread_key = data.GetAddress(&offset);
+            const lldb::addr_t tls_offset = data.GetAddress(&offset);
+            if (pthread_key != 0)
+            {
+                // First check to see if we have already figured out the location
+                // of TLS data for the pthread_key on a specific thread yet. If we
+                // have we can re-use it since its location will not change unless
+                // the process execs.
+                const tid_t tid = thread_sp->GetID();
+                auto tid_pos = m_tid_to_tls_map.find(tid);
+                if (tid_pos != m_tid_to_tls_map.end())
+                {
+                    auto tls_pos = tid_pos->second.find(pthread_key);
+                    if (tls_pos != tid_pos->second.end())
+                    {
+                        return tls_pos->second + tls_offset;
+                    }
+                }
+                StackFrameSP frame_sp = thread_sp->GetStackFrameAtIndex(0);
+                if (frame_sp)
+                {
+                    ClangASTContext *clang_ast_context = target.GetScratchClangASTContext();
+
+                    if (!clang_ast_context)
+                        return LLDB_INVALID_ADDRESS;
+
+                    CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+                    Address pthread_getspecific_addr = GetPthreadSetSpecificAddress();
+                    if (pthread_getspecific_addr.IsValid())
+                    {
+                        EvaluateExpressionOptions options;
+
+                        lldb::ThreadPlanSP thread_plan_sp(
+                            new ThreadPlanCallFunction(*thread_sp, pthread_getspecific_addr, clang_void_ptr_type,
+                                                       llvm::ArrayRef<lldb::addr_t>(pthread_key), options));
+
+                        DiagnosticManager execution_errors;
+                        ExecutionContext exe_ctx(thread_sp);
+                        lldb::ExpressionResults results =
+                            m_process->RunThreadPlan(exe_ctx, thread_plan_sp, options, execution_errors);
+
+                        if (results == lldb::eExpressionCompleted)
+                        {
+                            lldb::ValueObjectSP result_valobj_sp = thread_plan_sp->GetReturnValueObject();
+                            if (result_valobj_sp)
+                            {
+                                const lldb::addr_t pthread_key_data = result_valobj_sp->GetValueAsUnsigned(0);
+                                if (pthread_key_data)
+                                {
+                                    m_tid_to_tls_map[tid].insert(std::make_pair(pthread_key, pthread_key_data));
+                                    return pthread_key_data + tls_offset;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return LLDB_INVALID_ADDRESS;
+}
+

Added: lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h?rev=275733&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h (added)
+++ lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.h Sun Jul 17 16:27:32 2016
@@ -0,0 +1,293 @@
+//===-- DynamicLoaderDarwin.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_DynamicLoaderDarwin_h_
+#define liblldb_DynamicLoaderDarwin_h_
+
+// C Includes
+// C++ Includes
+#include <map>
+#include <mutex>
+#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"
+
+namespace lldb_private {
+
+class DynamicLoaderDarwin : public lldb_private::DynamicLoader
+{
+public:
+    DynamicLoaderDarwin(lldb_private::Process *process);
+
+    virtual ~DynamicLoaderDarwin() override;
+
+    //------------------------------------------------------------------
+    /// Called after attaching a process.
+    ///
+    /// Allow DynamicLoader plug-ins to execute some code after
+    /// attaching to a process.
+    //------------------------------------------------------------------
+    void
+    DidAttach() override;
+
+    void
+    DidLaunch() 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::addr_t
+    GetThreadLocalData(const lldb::ModuleSP module, const lldb::ThreadSP thread, lldb::addr_t tls_file_addr) override;
+
+    bool
+    AlwaysRelyOnEHUnwindInfo(lldb_private::SymbolContext &sym_ctx) override;
+
+    virtual void
+    DoInitialImageFetch () = 0;
+
+    virtual bool
+    NeedToDoInitialImageFetch () = 0;
+
+protected:
+    void
+    PrivateInitialize (lldb_private::Process *process);
+
+    void
+    PrivateProcessStateChanged (lldb_private::Process *process,
+                                lldb::StateType state);
+
+    void
+    Clear (bool clear_process);
+
+    // Clear method for classes derived from this one
+    virtual void
+    DoClear () = 0;
+
+    void
+    SetDYLDModule (lldb::ModuleSP &dyld_module_sp);
+
+    lldb::ModuleSP
+    GetDYLDModule ();
+
+    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 ImageInfo
+    {
+        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
+
+        ImageInfo() :
+            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 ImageInfo& 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_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<ImageInfo> collection;
+        typedef collection::iterator iterator;
+        typedef collection::const_iterator const_iterator;
+    };
+
+    bool
+    UpdateImageLoadAddress(lldb_private::Module *module, ImageInfo& info);
+
+    bool
+    UnloadModuleSections (lldb_private::Module *module, ImageInfo& info);
+
+    ImageInfo *
+    FindImageInfoForAddress (lldb::addr_t load_address);
+
+    lldb::ModuleSP
+    FindTargetModuleForImageInfo (ImageInfo &image_info,
+                                  bool can_create,
+                                  bool *did_create_ptr);
+
+    void
+    UnloadImages (const std::vector<lldb::addr_t> &solib_addresses);
+
+    virtual bool
+    SetNotificationBreakpoint () = 0;
+
+    virtual void
+    ClearNotificationBreakpoint () = 0;
+
+    virtual bool
+    DidSetNotificationBreakpoint () = 0;
+
+    typedef std::map<uint64_t, lldb::addr_t> PthreadKeyToTLSMap;
+    typedef std::map<lldb::user_id_t, PthreadKeyToTLSMap> ThreadIDToTLSMap;
+    
+    std::recursive_mutex &
+    GetMutex () const
+    {
+        return m_mutex;
+    }
+
+    lldb::ModuleSP
+    GetPThreadLibraryModule();
+
+    lldb_private::Address
+    GetPthreadSetSpecificAddress();
+
+    bool
+    JSONImageInformationIntoImageInfo (lldb_private::StructuredData::ObjectSP image_details, ImageInfo::collection &image_infos);
+
+    // If image_infos contains / may contain dyld image, call this method
+    // to keep our internal record keeping of the special dyld binary up-to-date.
+    void
+    UpdateDYLDImageInfoFromNewImageInfos (ImageInfo::collection &image_infos);
+
+    // if image_info is a dyld binary, call this method
+    void
+    UpdateDYLDImageInfoFromNewImageInfo (ImageInfo &image_info);
+
+    // If image_infos contains / may contain executable image, call this method
+    // to keep our internal record keeping of the special dyld binary up-to-date.
+    void
+    AddExecutableModuleIfInImageInfos (ImageInfo::collection &image_infos);
+
+    bool
+    AddModulesUsingImageInfos (ImageInfo::collection &image_infos);
+
+    lldb::ModuleWP m_dyld_module_wp;
+    lldb::ModuleWP m_libpthread_module_wp;
+    lldb_private::Address m_pthread_getspecific_addr;
+    ThreadIDToTLSMap m_tid_to_tls_map;
+    ImageInfo::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
+    ImageInfo  m_dyld;
+    mutable std::recursive_mutex m_mutex;
+
+private:
+    DISALLOW_COPY_AND_ASSIGN (DynamicLoaderDarwin);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_DynamicLoaderDarwin_h_

Modified: lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp?rev=275733&r1=275732&r2=275733&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp (original)
+++ lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp Sun Jul 17 16:27:32 2016
@@ -17,20 +17,19 @@
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Core/State.h"
-#include "lldb/Expression/DiagnosticManager.h"
 #include "lldb/Symbol/ClangASTContext.h"
 #include "lldb/Symbol/Function.h"
 #include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Target/ABI.h"
 #include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/Target/ABI.h"
 #include "lldb/Target/RegisterContext.h"
-#include "lldb/Target/StackFrame.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Target/Thread.h"
-#include "lldb/Target/ThreadPlanCallFunction.h"
 #include "lldb/Target/ThreadPlanRunToAddress.h"
+#include "lldb/Target/StackFrame.h"
 
 #include "DynamicLoaderMacOSXDYLD.h"
+#include "DynamicLoaderDarwin.h"
 
 //#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
 #ifdef ENABLE_DEBUG_PRINTF
@@ -49,47 +48,6 @@
 using namespace lldb;
 using namespace lldb_private;
 
-/// FIXME - The ObjC Runtime trampoline handler doesn't really belong here.
-/// I am putting it here so I can invoke it in the Trampoline code here, but
-/// it should be moved to the ObjC Runtime support when it is set up.
-
-
-DynamicLoaderMacOSXDYLD::DYLDImageInfo *
-DynamicLoaderMacOSXDYLD::GetImageInfo (Module *module)
-{
-    const UUID &module_uuid = module->GetUUID();
-    DYLDImageInfo::collection::iterator pos, end = m_dyld_image_infos.end();
-
-    // First try just by UUID as it is the safest.
-    if (module_uuid.IsValid())
-    {
-        for (pos = m_dyld_image_infos.begin(); pos != end; ++pos)
-        {
-            if (pos->uuid == module_uuid)
-                return &(*pos);
-        }
-        
-        if (m_dyld.uuid == module_uuid)
-            return &m_dyld;
-    }
-
-    // Next try by platform path only for things that don't have a valid UUID
-    // since if a file has a valid UUID in real life it should also in the
-    // dyld info. This is the next safest because the paths in the dyld info
-    // are platform paths, not local paths. For local debugging platform == local
-    // paths.
-    const FileSpec &platform_file_spec = module->GetPlatformFileSpec();
-    for (pos = m_dyld_image_infos.begin(); pos != end; ++pos)
-    {
-        if (pos->file_spec == platform_file_spec && pos->uuid.IsValid() == false)
-            return &(*pos);
-    }
-    
-    if (m_dyld.file_spec == platform_file_spec && m_dyld.uuid.IsValid() == false)
-        return &m_dyld;
-
-    return NULL;
-}
 
 //----------------------------------------------------------------------
 // Create an instance of this class. This function is filled into
@@ -140,21 +98,14 @@ DynamicLoaderMacOSXDYLD::CreateInstance
 //----------------------------------------------------------------------
 // Constructor
 //----------------------------------------------------------------------
-DynamicLoaderMacOSXDYLD::DynamicLoaderMacOSXDYLD(Process *process)
-    : DynamicLoader(process),
-      m_dyld(),
-      m_dyld_module_wp(),
-      m_libpthread_module_wp(),
-      m_pthread_getspecific_addr(),
-      m_dyld_all_image_infos_addr(LLDB_INVALID_ADDRESS),
-      m_dyld_all_image_infos(),
-      m_tid_to_tls_map(),
-      m_dyld_all_image_infos_stop_id(UINT32_MAX),
-      m_break_id(LLDB_INVALID_BREAK_ID),
-      m_dyld_image_infos(),
-      m_dyld_image_infos_stop_id(UINT32_MAX),
-      m_mutex(),
-      m_process_image_addr_is_all_images_infos(false)
+DynamicLoaderMacOSXDYLD::DynamicLoaderMacOSXDYLD (Process* process) :
+    DynamicLoaderDarwin(process),
+    m_dyld_all_image_infos_addr(LLDB_INVALID_ADDRESS),
+    m_dyld_all_image_infos(),
+    m_dyld_all_image_infos_stop_id (UINT32_MAX),
+    m_break_id(LLDB_INVALID_BREAK_ID),
+    m_mutex(),
+    m_process_image_addr_is_all_images_infos (false)
 {
 }
 
@@ -163,40 +114,14 @@ DynamicLoaderMacOSXDYLD::DynamicLoaderMa
 //----------------------------------------------------------------------
 DynamicLoaderMacOSXDYLD::~DynamicLoaderMacOSXDYLD()
 {
-    Clear(true);
-}
-
-//------------------------------------------------------------------
-/// Called after attaching a process.
-///
-/// Allow DynamicLoader plug-ins to execute some code after
-/// attaching to a process.
-//------------------------------------------------------------------
-void
-DynamicLoaderMacOSXDYLD::DidAttach ()
-{
-    PrivateInitialize(m_process);
-    LocateDYLD ();
-    SetNotificationBreakpoint ();
-}
-
-//------------------------------------------------------------------
-/// Called after attaching a process.
-///
-/// Allow DynamicLoader plug-ins to execute some code after
-/// attaching to a process.
-//------------------------------------------------------------------
-void
-DynamicLoaderMacOSXDYLD::DidLaunch ()
-{
-    PrivateInitialize(m_process);
-    LocateDYLD ();
-    SetNotificationBreakpoint ();
+    if (LLDB_BREAK_ID_IS_VALID(m_break_id))
+        m_process->GetTarget().RemoveBreakpointByID (m_break_id);
 }
 
 bool
 DynamicLoaderMacOSXDYLD::ProcessDidExec ()
 {
+    std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
     bool did_exec = false;
     if (m_process)
     {
@@ -249,45 +174,48 @@ DynamicLoaderMacOSXDYLD::ProcessDidExec
     return did_exec;
 }
 
-
-
 //----------------------------------------------------------------------
 // Clear out the state of this class.
 //----------------------------------------------------------------------
 void
-DynamicLoaderMacOSXDYLD::Clear (bool clear_process)
+DynamicLoaderMacOSXDYLD::DoClear ()
 {
     std::lock_guard<std::recursive_mutex> guard(m_mutex);
 
     if (LLDB_BREAK_ID_IS_VALID(m_break_id))
         m_process->GetTarget().RemoveBreakpointByID (m_break_id);
 
-    if (clear_process)
-        m_process = NULL;
-    m_dyld.Clear(false);
     m_dyld_all_image_infos_addr = LLDB_INVALID_ADDRESS;
     m_dyld_all_image_infos.Clear();
     m_break_id = LLDB_INVALID_BREAK_ID;
-    m_dyld_image_infos.clear();
 }
 
 //----------------------------------------------------------------------
 // Check if we have found DYLD yet
 //----------------------------------------------------------------------
 bool
-DynamicLoaderMacOSXDYLD::DidSetNotificationBreakpoint() const
+DynamicLoaderMacOSXDYLD::DidSetNotificationBreakpoint()
 {
     return LLDB_BREAK_ID_IS_VALID (m_break_id);
 }
 
+void
+DynamicLoaderMacOSXDYLD::ClearNotificationBreakpoint ()
+{
+    if (LLDB_BREAK_ID_IS_VALID (m_break_id))
+    {
+        m_process->GetTarget().RemoveBreakpointByID (m_break_id);
+    }
+}
+
 //----------------------------------------------------------------------
 // Try and figure out where dyld is by first asking the Process
 // if it knows (which currently calls down in the lldb::Process
 // to get the DYLD info (available on SnowLeopard only). If that fails,
 // then check in the default addresses.
 //----------------------------------------------------------------------
-bool
-DynamicLoaderMacOSXDYLD::LocateDYLD()
+void
+DynamicLoaderMacOSXDYLD::DoInitialImageFetch()
 {
     if (m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS)
     {
@@ -312,7 +240,8 @@ DynamicLoaderMacOSXDYLD::LocateDYLD()
                 case llvm::MachO::MH_CIGAM:
                 case llvm::MachO::MH_CIGAM_64:
                     m_process_image_addr_is_all_images_infos = false;
-                    return ReadDYLDInfoFromMemoryAndSetNotificationCallback(shlib_addr);
+                    ReadDYLDInfoFromMemoryAndSetNotificationCallback(shlib_addr);
+                    return;
                     
                 default:
                     break;
@@ -329,9 +258,10 @@ DynamicLoaderMacOSXDYLD::LocateDYLD()
         if (ReadAllImageInfosStructure ())
         {
             if (m_dyld_all_image_infos.dyldImageLoadAddress != LLDB_INVALID_ADDRESS)
-                return ReadDYLDInfoFromMemoryAndSetNotificationCallback (m_dyld_all_image_infos.dyldImageLoadAddress);
+                ReadDYLDInfoFromMemoryAndSetNotificationCallback (m_dyld_all_image_infos.dyldImageLoadAddress);
             else
-                return ReadDYLDInfoFromMemoryAndSetNotificationCallback (m_dyld_all_image_infos_addr & 0xfffffffffff00000ull);
+                ReadDYLDInfoFromMemoryAndSetNotificationCallback (m_dyld_all_image_infos_addr & 0xfffffffffff00000ull);
+            return;
         }
     }
 
@@ -343,53 +273,18 @@ DynamicLoaderMacOSXDYLD::LocateDYLD()
         const ArchSpec &exe_arch = executable->GetArchitecture();
         if (exe_arch.GetAddressByteSize() == 8)
         {
-            return ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x7fff5fc00000ull);
+            ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x7fff5fc00000ull);
         }
         else if (exe_arch.GetMachine() == llvm::Triple::arm || exe_arch.GetMachine() == llvm::Triple::thumb || exe_arch.GetMachine() == llvm::Triple::aarch64)
         {
-            return ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x2fe00000);
+            ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x2fe00000);
         }
         else
         {
-            return ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x8fe00000);
-        }
-    }
-    return false;
-}
-
-ModuleSP
-DynamicLoaderMacOSXDYLD::FindTargetModuleForDYLDImageInfo (DYLDImageInfo &image_info, bool can_create, bool *did_create_ptr)
-{
-    if (did_create_ptr)
-        *did_create_ptr = false;
-    
-    Target &target = m_process->GetTarget();
-    const ModuleList &target_images = target.GetImages();
-    ModuleSpec module_spec (image_info.file_spec);
-    module_spec.GetUUID() = image_info.uuid;
-    ModuleSP module_sp (target_images.FindFirstModule (module_spec));
-    
-    if (module_sp && !module_spec.GetUUID().IsValid() && !module_sp->GetUUID().IsValid())
-    {
-        // No UUID, we must rely upon the cached module modification 
-        // time and the modification time of the file on disk
-        if (module_sp->GetModificationTime() != module_sp->GetFileSpec().GetModificationTime())
-            module_sp.reset();
-    }
-
-    if (!module_sp)
-    {
-        if (can_create)
-        {
-            module_sp = target.GetSharedModule (module_spec);
-            if (!module_sp || module_sp->GetObjectFile() == NULL)
-                module_sp = m_process->ReadModuleFromMemory (image_info.file_spec, image_info.address);
-
-            if (did_create_ptr)
-                *did_create_ptr = (bool) module_sp;
+            ReadDYLDInfoFromMemoryAndSetNotificationCallback(0x8fe00000);
         }
     }
-    return module_sp;
+    return;
 }
 
 //----------------------------------------------------------------------
@@ -399,6 +294,7 @@ DynamicLoaderMacOSXDYLD::FindTargetModul
 bool
 DynamicLoaderMacOSXDYLD::ReadDYLDInfoFromMemoryAndSetNotificationCallback(lldb::addr_t addr)
 {
+    std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
     DataExtractor data; // Load command data
     if (ReadMachHeader (addr, &m_dyld.header, &data))
     {
@@ -410,12 +306,11 @@ DynamicLoaderMacOSXDYLD::ReadDYLDInfoFro
             {
                 if (m_dyld.file_spec)
                 {
-                    dyld_module_sp = FindTargetModuleForDYLDImageInfo (m_dyld, true, NULL);
+                    UpdateDYLDImageInfoFromNewImageInfo (m_dyld);
 
-                    if (dyld_module_sp)
-                        UpdateImageLoadAddress (dyld_module_sp.get(), m_dyld);
                 }
             }
+            dyld_module_sp = GetDYLDModule();
 
             Target &target = m_process->GetTarget();
 
@@ -443,7 +338,7 @@ DynamicLoaderMacOSXDYLD::ReadDYLDInfoFro
                 ModuleList modules;
                 modules.Append(dyld_module_sp);
                 target.ModulesDidLoad(modules);
-                m_dyld_module_wp = dyld_module_sp;
+                SetDYLDModule (dyld_module_sp);
             }
             return true;
         }
@@ -452,152 +347,12 @@ DynamicLoaderMacOSXDYLD::ReadDYLDInfoFro
 }
 
 bool
-DynamicLoaderMacOSXDYLD::NeedToLocateDYLD () const
+DynamicLoaderMacOSXDYLD::NeedToDoInitialImageFetch ()
 {
     return m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS;
 }
 
 //----------------------------------------------------------------------
-// Update the load addresses for all segments in MODULE using the
-// updated INFO that is passed in.
-//----------------------------------------------------------------------
-bool
-DynamicLoaderMacOSXDYLD::UpdateImageLoadAddress (Module *module, DYLDImageInfo& info)
-{
-    bool changed = false;
-    if (module)
-    {
-        ObjectFile *image_object_file = module->GetObjectFile();
-        if (image_object_file)
-        {
-            SectionList *section_list = image_object_file->GetSectionList ();
-            if (section_list)
-            {
-                std::vector<uint32_t> inaccessible_segment_indexes;
-                // We now know the slide amount, so go through all sections
-                // and update the load addresses with the correct values.
-                const size_t num_segments = info.segments.size();
-                for (size_t i=0; i<num_segments; ++i)
-                {
-                    // Only load a segment if it has protections. Things like
-                    // __PAGEZERO don't have any protections, and they shouldn't
-                    // be slid
-                    SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name));
-
-                    if (info.segments[i].maxprot == 0)
-                    {
-                        inaccessible_segment_indexes.push_back(i);
-                    }
-                    else
-                    {
-                        const addr_t new_section_load_addr = info.segments[i].vmaddr + info.slide;
-                        static ConstString g_section_name_LINKEDIT ("__LINKEDIT");
-
-                        if (section_sp)
-                        {
-                            // __LINKEDIT sections from files in the shared cache
-                            // can overlap so check to see what the segment name is
-                            // and pass "false" so we don't warn of overlapping
-                            // "Section" objects, and "true" for all other sections.
-                            const bool warn_multiple = section_sp->GetName() != g_section_name_LINKEDIT;
-
-                            changed = m_process->GetTarget().SetSectionLoadAddress (section_sp, new_section_load_addr, warn_multiple);
-                        }
-                        else
-                        {
-                            Host::SystemLog (Host::eSystemLogWarning, 
-                                             "warning: unable to find and load segment named '%s' at 0x%" PRIx64 " in '%s' in macosx dynamic loader plug-in.\n",
-                                             info.segments[i].name.AsCString("<invalid>"),
-                                             (uint64_t)new_section_load_addr,
-                                             image_object_file->GetFileSpec().GetPath().c_str());
-                        }
-                    }
-                }
-                
-                // If the loaded the file (it changed) and we have segments that
-                // are not readable or writeable, add them to the invalid memory
-                // region cache for the process. This will typically only be
-                // the __PAGEZERO segment in the main executable. We might be able
-                // to apply this more generally to more sections that have no
-                // protections in the future, but for now we are going to just
-                // do __PAGEZERO.
-                if (changed && !inaccessible_segment_indexes.empty())
-                {
-                    for (uint32_t i=0; i<inaccessible_segment_indexes.size(); ++i)
-                    {
-                        const uint32_t seg_idx = inaccessible_segment_indexes[i];
-                        SectionSP section_sp(section_list->FindSectionByName(info.segments[seg_idx].name));
-
-                        if (section_sp)
-                        {
-                            static ConstString g_pagezero_section_name("__PAGEZERO");
-                            if (g_pagezero_section_name == section_sp->GetName())
-                            {
-                                // __PAGEZERO never slides...
-                                const lldb::addr_t vmaddr = info.segments[seg_idx].vmaddr;
-                                const lldb::addr_t vmsize = info.segments[seg_idx].vmsize;
-                                Process::LoadRange pagezero_range (vmaddr, vmsize);
-                                m_process->AddInvalidMemoryRegion(pagezero_range);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-    // We might have an in memory image that was loaded as soon as it was created
-    if (info.load_stop_id == m_process->GetStopID())
-        changed = true;
-    else if (changed)
-    {
-        // Update the stop ID when this library was updated
-        info.load_stop_id = m_process->GetStopID();
-    }
-    return changed;
-}
-
-//----------------------------------------------------------------------
-// Update the load addresses for all segments in MODULE using the
-// updated INFO that is passed in.
-//----------------------------------------------------------------------
-bool
-DynamicLoaderMacOSXDYLD::UnloadImageLoadAddress (Module *module, DYLDImageInfo& info)
-{
-    bool changed = false;
-    if (module)
-    {
-        ObjectFile *image_object_file = module->GetObjectFile();
-        if (image_object_file)
-        {
-            SectionList *section_list = image_object_file->GetSectionList ();
-            if (section_list)
-            {
-                const size_t num_segments = info.segments.size();
-                for (size_t i=0; i<num_segments; ++i)
-                {
-                    SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name));
-                    if (section_sp)
-                    {
-                        const addr_t old_section_load_addr = info.segments[i].vmaddr + info.slide;
-                        if (m_process->GetTarget().SetSectionUnloaded (section_sp, old_section_load_addr))
-                            changed = true;
-                    }
-                    else
-                    {
-                        Host::SystemLog (Host::eSystemLogWarning, 
-                                         "warning: unable to find and unload segment named '%s' in '%s' in macosx dynamic loader plug-in.\n",
-                                         info.segments[i].name.AsCString("<invalid>"),
-                                         image_object_file->GetFileSpec().GetPath().c_str());
-                    }
-                }
-            }
-        }
-    }
-    return changed;
-}
-
-
-//----------------------------------------------------------------------
 // Static callback function that gets called when our DYLD notification
 // breakpoint gets hit. We update all of our image infos and then
 // let our super class DynamicLoader class decide if we should stop
@@ -814,181 +569,16 @@ DynamicLoaderMacOSXDYLD::ReadAllImageInf
 }
 
 
-// This method is an amalgamation of code from 
-//   ReadMachHeader()
-//   ParseLoadCommands()
-//   UpdateImageInfosHeaderAndLoadCommands()
-// but written to extract everything from the JSON packet from debugserver, instead of using memory reads.
-
-bool
-DynamicLoaderMacOSXDYLD::AddModulesUsingInfosFromDebugserver (StructuredData::ObjectSP image_details, DYLDImageInfo::collection &image_infos)
-{
-    StructuredData::ObjectSP images_sp = image_details->GetAsDictionary()->GetValueForKey("images");
-    if (images_sp.get() == nullptr)
-        return false;
-
-    image_infos.resize (images_sp->GetAsArray()->GetSize());
-
-    uint32_t exe_idx = UINT32_MAX;
-
-    for (size_t i = 0; i < image_infos.size(); i++)
-    {
-        StructuredData::ObjectSP image_sp = images_sp->GetAsArray()->GetItemAtIndex(i);
-        if (image_sp.get() == nullptr || image_sp->GetAsDictionary() == nullptr)
-            return false;
-        StructuredData::Dictionary *image = image_sp->GetAsDictionary();
-        if (image->HasKey("load_address") == false 
-            || image->HasKey("pathname") == false 
-            || image->HasKey("mod_date") == false
-            || image->HasKey("mach_header") == false 
-            || image->GetValueForKey("mach_header")->GetAsDictionary() == nullptr
-            || image->HasKey("segments") == false 
-            || image->GetValueForKey("segments")->GetAsArray() == nullptr
-            || image->HasKey("uuid") == false )
-        {
-            return false;
-        }
-        image_infos[i].address = image->GetValueForKey("load_address")->GetAsInteger()->GetValue();
-        image_infos[i].mod_date = image->GetValueForKey("mod_date")->GetAsInteger()->GetValue();
-        image_infos[i].file_spec.SetFile(image->GetValueForKey("pathname")->GetAsString()->GetValue().c_str(), false);
-
-        StructuredData::Dictionary *mh = image->GetValueForKey("mach_header")->GetAsDictionary();
-        image_infos[i].header.magic = mh->GetValueForKey("magic")->GetAsInteger()->GetValue();
-        image_infos[i].header.cputype = mh->GetValueForKey("cputype")->GetAsInteger()->GetValue();
-        image_infos[i].header.cpusubtype = mh->GetValueForKey("cpusubtype")->GetAsInteger()->GetValue();
-        image_infos[i].header.filetype = mh->GetValueForKey("filetype")->GetAsInteger()->GetValue();
-
-        // Fields that aren't used by DynamicLoaderMacOSXDYLD so debugserver doesn't currently send them
-        // in the reply.
-
-        if (mh->HasKey("flags"))
-            image_infos[i].header.flags = mh->GetValueForKey("flags")->GetAsInteger()->GetValue();
-        else
-            image_infos[i].header.flags = 0;
-
-        if (mh->HasKey("ncmds"))
-            image_infos[i].header.ncmds = mh->GetValueForKey("ncmds")->GetAsInteger()->GetValue();
-        else
-            image_infos[i].header.ncmds = 0;
-
-        if (mh->HasKey("sizeofcmds"))
-            image_infos[i].header.sizeofcmds = mh->GetValueForKey("sizeofcmds")->GetAsInteger()->GetValue();
-        else
-            image_infos[i].header.sizeofcmds = 0;
-
-        if (image_infos[i].header.filetype == llvm::MachO::MH_EXECUTE)
-            exe_idx = i;
-
-        StructuredData::Array *segments = image->GetValueForKey("segments")->GetAsArray();
-        uint32_t segcount = segments->GetSize();
-        for (size_t j = 0; j < segcount; j++)
-        {
-            Segment segment;
-            StructuredData::Dictionary *seg = segments->GetItemAtIndex(j)->GetAsDictionary();
-            segment.name = ConstString(seg->GetValueForKey("name")->GetAsString()->GetValue().c_str());
-            segment.vmaddr = seg->GetValueForKey("vmaddr")->GetAsInteger()->GetValue();
-            segment.vmsize = seg->GetValueForKey("vmsize")->GetAsInteger()->GetValue();
-            segment.fileoff = seg->GetValueForKey("fileoff")->GetAsInteger()->GetValue();
-            segment.filesize = seg->GetValueForKey("filesize")->GetAsInteger()->GetValue();
-            segment.maxprot = seg->GetValueForKey("maxprot")->GetAsInteger()->GetValue();
-
-            // Fields that aren't used by DynamicLoaderMacOSXDYLD so debugserver doesn't currently send them
-            // in the reply.
-
-            if (seg->HasKey("initprot"))
-                segment.initprot = seg->GetValueForKey("initprot")->GetAsInteger()->GetValue();
-            else
-                segment.initprot = 0;
-
-            if (seg->HasKey("flags"))
-                segment.flags = seg->GetValueForKey("flags")->GetAsInteger()->GetValue();
-            else
-                segment.flags = 0;
-
-            if (seg->HasKey("nsects"))
-                segment.nsects = seg->GetValueForKey("nsects")->GetAsInteger()->GetValue();
-            else
-                segment.nsects = 0;
-
-            image_infos[i].segments.push_back (segment);
-        }
-
-        image_infos[i].uuid.SetFromCString (image->GetValueForKey("uuid")->GetAsString()->GetValue().c_str());
-
-        // All sections listed in the dyld image info structure will all
-        // either be fixed up already, or they will all be off by a single
-        // slide amount that is determined by finding the first segment
-        // that is at file offset zero which also has bytes (a file size
-        // that is greater than zero) in the object file.
-    
-        // Determine the slide amount (if any)
-        const size_t num_sections = image_infos[i].segments.size();
-        for (size_t k = 0; k < num_sections; ++k)
-        {
-            // Iterate through the object file sections to find the
-            // first section that starts of file offset zero and that
-            // has bytes in the file...
-            if ((image_infos[i].segments[k].fileoff == 0 && image_infos[i].segments[k].filesize > 0) 
-                || (image_infos[i].segments[k].name == ConstString("__TEXT")))
-            {
-                image_infos[i].slide = image_infos[i].address - image_infos[i].segments[k].vmaddr;
-                // We have found the slide amount, so we can exit
-                // this for loop.
-                break;
-            }
-        }
-    }
-
-    Target &target = m_process->GetTarget();
-
-    if (exe_idx < image_infos.size())
-    {
-        const bool can_create = true;
-        ModuleSP exe_module_sp (FindTargetModuleForDYLDImageInfo (image_infos[exe_idx], can_create, NULL));
-
-        if (exe_module_sp)
-        {
-            UpdateImageLoadAddress (exe_module_sp.get(), image_infos[exe_idx]);
-
-            if (exe_module_sp.get() != target.GetExecutableModulePointer())
-            {
-                // Don't load dependent images since we are in dyld where we will know
-                // and find out about all images that are loaded. Also when setting the
-                // executable module, it will clear the targets module list, and if we
-                // have an in memory dyld module, it will get removed from the list
-                // so we will need to add it back after setting the executable module,
-                // so we first try and see if we already have a weak pointer to the
-                // dyld module, make it into a shared pointer, then add the executable,
-                // then re-add it back to make sure it is always in the list.
-                ModuleSP dyld_module_sp(m_dyld_module_wp.lock());
-                
-                const bool get_dependent_images = false;
-                m_process->GetTarget().SetExecutableModule (exe_module_sp, 
-                                                            get_dependent_images);
-
-                if (dyld_module_sp)
-                {
-                   if(target.GetImages().AppendIfNeeded (dyld_module_sp))
-                   {
-                        // Also add it to the section list.
-                        UpdateImageLoadAddress(dyld_module_sp.get(), m_dyld);
-                   }
-                }
-            }
-        }
-    }
- return true;
-}
-
 bool
 DynamicLoaderMacOSXDYLD::AddModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count)
 {
-    DYLDImageInfo::collection image_infos;
+    ImageInfo::collection image_infos;
     Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
     if (log)
         log->Printf ("Adding %d modules.\n", image_infos_count);
-
+        
     std::lock_guard<std::recursive_mutex> guard(m_mutex);
+    std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
     if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
         return true;
 
@@ -1000,8 +590,9 @@ DynamicLoaderMacOSXDYLD::AddModulesUsing
         && image_infos_json_sp->GetAsDictionary()->GetValueForKey("images")->GetAsArray()->GetSize() == image_infos_count)
     {
         bool return_value = false;
-        if (AddModulesUsingInfosFromDebugserver (image_infos_json_sp, image_infos))
+        if (JSONImageInformationIntoImageInfo (image_infos_json_sp, image_infos))
         {
+            AddExecutableModuleIfInImageInfos (image_infos);
             return_value = AddModulesUsingImageInfos (image_infos);
         }
         m_dyld_image_infos_stop_id = m_process->GetStopID();
@@ -1017,101 +608,14 @@ DynamicLoaderMacOSXDYLD::AddModulesUsing
     return return_value;
 }
 
-// Adds the modules in image_infos to m_dyld_image_infos.  
-// NB don't call this passing in m_dyld_image_infos.
-
-bool
-DynamicLoaderMacOSXDYLD::AddModulesUsingImageInfos (DYLDImageInfo::collection &image_infos)
-{
-    // Now add these images to the main list.
-    ModuleList loaded_module_list;
-    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
-    Target &target = m_process->GetTarget();
-    ModuleList& target_images = target.GetImages();
-    
-    for (uint32_t idx = 0; idx < image_infos.size(); ++idx)
-    {
-        if (log)
-        {
-            log->Printf ("Adding new image at address=0x%16.16" PRIx64 ".", image_infos[idx].address);
-            image_infos[idx].PutToLog (log);
-        }
-        
-        m_dyld_image_infos.push_back(image_infos[idx]);
-        
-        ModuleSP image_module_sp (FindTargetModuleForDYLDImageInfo (image_infos[idx], true, NULL));
-
-        if (image_module_sp)
-        {
-            ObjectFile *objfile = image_module_sp->GetObjectFile ();
-            if (objfile)
-            {
-                SectionList *sections = objfile->GetSectionList();
-                if (sections)
-                {
-                    ConstString commpage_dbstr("__commpage");
-                    Section *commpage_section = sections->FindSectionByName(commpage_dbstr).get();
-                    if (commpage_section)
-                    {
-                        ModuleSpec module_spec (objfile->GetFileSpec(), image_infos[idx].GetArchitecture ());
-                        module_spec.GetObjectName() = commpage_dbstr;
-                        ModuleSP commpage_image_module_sp(target_images.FindFirstModule (module_spec));
-                        if (!commpage_image_module_sp)
-                        {
-                            module_spec.SetObjectOffset (objfile->GetFileOffset() + commpage_section->GetFileOffset());
-                            module_spec.SetObjectSize (objfile->GetByteSize());
-                            commpage_image_module_sp  = target.GetSharedModule (module_spec);
-                            if (!commpage_image_module_sp || commpage_image_module_sp->GetObjectFile() == NULL)
-                            {
-                                commpage_image_module_sp = m_process->ReadModuleFromMemory (image_infos[idx].file_spec,
-                                                                                            image_infos[idx].address);
-                                // Always load a memory image right away in the target in case
-                                // we end up trying to read the symbol table from memory... The
-                                // __LINKEDIT will need to be mapped so we can figure out where
-                                // the symbol table bits are...
-                                bool changed = false;
-                                UpdateImageLoadAddress (commpage_image_module_sp.get(), image_infos[idx]);
-                                target.GetImages().Append(commpage_image_module_sp);
-                                if (changed)
-                                {
-                                    image_infos[idx].load_stop_id = m_process->GetStopID();
-                                    loaded_module_list.AppendIfNeeded (commpage_image_module_sp);
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-
-            // UpdateImageLoadAddress will return true if any segments
-            // change load address. We need to check this so we don't
-            // mention that all loaded shared libraries are newly loaded
-            // each time we hit out dyld breakpoint since dyld will list all
-            // shared libraries each time.
-            if (UpdateImageLoadAddress (image_module_sp.get(), image_infos[idx]))
-            {
-                target_images.AppendIfNeeded(image_module_sp);
-                loaded_module_list.AppendIfNeeded (image_module_sp);
-            }
-        }
-    }
-    
-    if (loaded_module_list.GetSize() > 0)
-    {
-        if (log)
-            loaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderMacOSXDYLD::ModulesDidLoad");
-        m_process->GetTarget().ModulesDidLoad (loaded_module_list);
-    }
-    return true;
-}
-
 bool
 DynamicLoaderMacOSXDYLD::RemoveModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count)
 {
-    DYLDImageInfo::collection image_infos;
+    ImageInfo::collection image_infos;
     Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
-
+    
     std::lock_guard<std::recursive_mutex> guard(m_mutex);
+    std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
     if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
         return true;
 
@@ -1142,7 +646,7 @@ DynamicLoaderMacOSXDYLD::RemoveModulesUs
         // Also copy over the uuid from the old entry to the removed entry so we can 
         // use it to lookup the module in the module list.
         
-        DYLDImageInfo::collection::iterator pos, end = m_dyld_image_infos.end();
+        ImageInfo::collection::iterator pos, end = m_dyld_image_infos.end();
         for (pos = m_dyld_image_infos.begin(); pos != end; pos++)
         {
             if (image_infos[idx].address == (*pos).address)
@@ -1152,12 +656,12 @@ DynamicLoaderMacOSXDYLD::RemoveModulesUs
                 // Add the module from this image_info to the "unloaded_module_list".  We'll remove them all at
                 // one go later on.
                 
-                ModuleSP unload_image_module_sp (FindTargetModuleForDYLDImageInfo (image_infos[idx], false, NULL));
+                ModuleSP unload_image_module_sp (FindTargetModuleForImageInfo (image_infos[idx], false, NULL));
                 if (unload_image_module_sp.get())
                 {
                     // When we unload, be sure to use the image info from the old list,
                     // since that has sections correctly filled in.
-                    UnloadImageLoadAddress (unload_image_module_sp.get(), *pos);
+                    UnloadModuleSections (unload_image_module_sp.get(), *pos);
                     unloaded_module_list.AppendIfNeeded (unload_image_module_sp);
                 }
                 else
@@ -1201,9 +705,10 @@ DynamicLoaderMacOSXDYLD::RemoveModulesUs
 bool
 DynamicLoaderMacOSXDYLD::ReadImageInfos (lldb::addr_t image_infos_addr, 
                                          uint32_t image_infos_count, 
-                                         DYLDImageInfo::collection &image_infos)
+                                         ImageInfo::collection &image_infos)
 {
-    const ByteOrder endian = m_dyld.GetByteOrder();
+    std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
+    const ByteOrder endian = GetByteOrderFromMagic (m_dyld.header.magic);
     const uint32_t addr_size = m_dyld.GetAddressByteSize();
 
     image_infos.resize(image_infos_count);
@@ -1252,8 +757,9 @@ bool
 DynamicLoaderMacOSXDYLD::InitializeFromAllImageInfos ()
 {
     Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
-
+    
     std::lock_guard<std::recursive_mutex> guard(m_mutex);
+    std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
     if (m_process->GetStopID() == m_dyld_image_infos_stop_id
           || m_dyld_image_infos.size() != 0)
         return false;
@@ -1289,7 +795,7 @@ DynamicLoaderMacOSXDYLD::InitializeFromA
         const ModuleList &target_modules = target.GetImages();
         ModuleList not_loaded_modules;
         std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
-
+        
         size_t num_modules = target_modules.GetSize();
         for (size_t i = 0; i < num_modules; i++)
         {
@@ -1394,7 +900,7 @@ DynamicLoaderMacOSXDYLD::ReadMachHeader
 // Parse the load commands for an image
 //----------------------------------------------------------------------
 uint32_t
-DynamicLoaderMacOSXDYLD::ParseLoadCommands (const DataExtractor& data, DYLDImageInfo& dylib_info, FileSpec *lc_id_dylinker)
+DynamicLoaderMacOSXDYLD::ParseLoadCommands (const DataExtractor& data, ImageInfo& dylib_info, FileSpec *lc_id_dylinker)
 {
     lldb::offset_t offset = 0;
     uint32_t cmd_idx;
@@ -1491,7 +997,7 @@ DynamicLoaderMacOSXDYLD::ParseLoadComman
 //----------------------------------------------------------------------
 
 void
-DynamicLoaderMacOSXDYLD::UpdateImageInfosHeaderAndLoadCommands(DYLDImageInfo::collection &image_infos, 
+DynamicLoaderMacOSXDYLD::UpdateImageInfosHeaderAndLoadCommands(ImageInfo::collection &image_infos, 
                                                                uint32_t infos_count, 
                                                                bool update_executable)
 {
@@ -1518,7 +1024,7 @@ DynamicLoaderMacOSXDYLD::UpdateImageInfo
     if (exe_idx < image_infos.size())
     {
         const bool can_create = true;
-        ModuleSP exe_module_sp (FindTargetModuleForDYLDImageInfo (image_infos[exe_idx], can_create, NULL));
+        ModuleSP exe_module_sp (FindTargetModuleForImageInfo (image_infos[exe_idx], can_create, NULL));
 
         if (exe_module_sp)
         {
@@ -1534,7 +1040,7 @@ DynamicLoaderMacOSXDYLD::UpdateImageInfo
                 // so we first try and see if we already have a weak pointer to the
                 // dyld module, make it into a shared pointer, then add the executable,
                 // then re-add it back to make sure it is always in the list.
-                ModuleSP dyld_module_sp(m_dyld_module_wp.lock());
+                ModuleSP dyld_module_sp(GetDYLDModule ());
                 
                 const bool get_dependent_images = false;
                 m_process->GetTarget().SetExecutableModule (exe_module_sp, 
@@ -1544,6 +1050,8 @@ DynamicLoaderMacOSXDYLD::UpdateImageInfo
                 {
                    if(target.GetImages().AppendIfNeeded (dyld_module_sp))
                    {
+                        std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
+
                         // Also add it to the section list.
                         UpdateImageLoadAddress(dyld_module_sp.get(), m_dyld);
                    }
@@ -1553,133 +1061,6 @@ DynamicLoaderMacOSXDYLD::UpdateImageInfo
     }
 }
 
-//----------------------------------------------------------------------
-// On Mac OS X libobjc (the Objective-C runtime) has several critical dispatch
-// functions written in hand-written assembly, and also have hand-written unwind
-// information in the eh_frame section.  Normally we prefer analyzing the 
-// assembly instructions of a currently executing frame to unwind from that frame --
-// but on hand-written functions this profiling can fail.  We should use the
-// eh_frame instructions for these functions all the time.
-//
-// As an aside, it would be better if the eh_frame entries had a flag (or were
-// extensible so they could have an Apple-specific flag) which indicates that
-// the instructions are asynchronous -- accurate at every instruction, instead
-// of our normal default assumption that they are not.
-//----------------------------------------------------------------------
-
-bool
-DynamicLoaderMacOSXDYLD::AlwaysRelyOnEHUnwindInfo (SymbolContext &sym_ctx)
-{
-    ModuleSP module_sp;
-    if (sym_ctx.symbol)
-    {
-        module_sp = sym_ctx.symbol->GetAddressRef().GetModule();
-    }
-    if (module_sp.get() == NULL && sym_ctx.function)
-    {
-        module_sp = sym_ctx.function->GetAddressRange().GetBaseAddress().GetModule();
-    }
-    if (module_sp.get() == NULL)
-        return false;
-
-    ObjCLanguageRuntime *objc_runtime = m_process->GetObjCLanguageRuntime();
-    if (objc_runtime != NULL && objc_runtime->IsModuleObjCLibrary (module_sp))
-    {
-        return true;
-    }
-
-    return false;
-}
-
-
-
-//----------------------------------------------------------------------
-// Dump a Segment to the file handle provided.
-//----------------------------------------------------------------------
-void
-DynamicLoaderMacOSXDYLD::Segment::PutToLog (Log *log, lldb::addr_t slide) const
-{
-    if (log)
-    {
-        if (slide == 0)
-            log->Printf ("\t\t%16s [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")",
-                         name.AsCString(""), 
-                         vmaddr + slide, 
-                         vmaddr + slide + vmsize);
-        else
-            log->Printf ("\t\t%16s [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") slide = 0x%" PRIx64,
-                         name.AsCString(""), 
-                         vmaddr + slide, 
-                         vmaddr + slide + vmsize, 
-                         slide);
-    }
-}
-
-const DynamicLoaderMacOSXDYLD::Segment *
-DynamicLoaderMacOSXDYLD::DYLDImageInfo::FindSegment (const ConstString &name) const
-{
-    const size_t num_segments = segments.size();
-    for (size_t i=0; i<num_segments; ++i)
-    {
-        if (segments[i].name == name)
-            return &segments[i];
-    }
-    return NULL;
-}
-
-
-//----------------------------------------------------------------------
-// Dump an image info structure to the file handle provided.
-//----------------------------------------------------------------------
-void
-DynamicLoaderMacOSXDYLD::DYLDImageInfo::PutToLog (Log *log) const
-{
-    if (log == NULL)
-        return;
-    const uint8_t *u = (const uint8_t *)uuid.GetBytes();
-
-    if (address == LLDB_INVALID_ADDRESS)
-    {
-        if (u)
-        {
-            log->Printf("\t                           modtime=0x%8.8" PRIx64 " uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X path='%s' (UNLOADED)",
-                        mod_date,
-                        u[ 0], u[ 1], u[ 2], u[ 3],
-                        u[ 4], u[ 5], u[ 6], u[ 7],
-                        u[ 8], u[ 9], u[10], u[11],
-                        u[12], u[13], u[14], u[15],
-                        file_spec.GetPath().c_str());
-        }
-        else
-            log->Printf("\t                           modtime=0x%8.8" PRIx64 " path='%s' (UNLOADED)",
-                        mod_date,
-                        file_spec.GetPath().c_str());
-    }
-    else
-    {
-        if (u)
-        {
-            log->Printf("\taddress=0x%16.16" PRIx64 " modtime=0x%8.8" PRIx64 " uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X path='%s'",
-                        address,
-                        mod_date,
-                        u[ 0], u[ 1], u[ 2], u[ 3],
-                        u[ 4], u[ 5], u[ 6], u[ 7],
-                        u[ 8], u[ 9], u[10], u[11],
-                        u[12], u[13], u[14], u[15],
-                        file_spec.GetPath().c_str());
-        }
-        else
-        {
-            log->Printf("\taddress=0x%16.16" PRIx64 " modtime=0x%8.8" PRIx64 " path='%s'",
-                        address,
-                        mod_date,
-                        file_spec.GetPath().c_str());
-
-        }
-        for (uint32_t i=0; i<segments.size(); ++i)
-            segments[i].PutToLog(log, slide);
-    }
-}
 
 //----------------------------------------------------------------------
 // Dump the _dyld_all_image_infos members and all current image infos
@@ -1692,6 +1073,7 @@ DynamicLoaderMacOSXDYLD::PutToLog(Log *l
         return;
 
     std::lock_guard<std::recursive_mutex> guard(m_mutex);
+    std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
     log->Printf("dyld_all_image_infos = { version=%d, count=%d, addr=0x%8.8" PRIx64 ", notify=0x%8.8" PRIx64 " }",
                     m_dyld_all_image_infos.version,
                     m_dyld_all_image_infos.dylib_info_count,
@@ -1707,15 +1089,6 @@ DynamicLoaderMacOSXDYLD::PutToLog(Log *l
     }
 }
 
-void
-DynamicLoaderMacOSXDYLD::PrivateInitialize(Process *process)
-{
-    DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
-    Clear(true);
-    m_process = process;
-    m_process->GetTarget().ClearAllLoadedSections();
-}
-
 bool
 DynamicLoaderMacOSXDYLD::SetNotificationBreakpoint ()
 {
@@ -1735,6 +1108,8 @@ DynamicLoaderMacOSXDYLD::SetNotification
                 ModuleSP dyld_module_sp = m_dyld_module_wp.lock();
                 if (dyld_module_sp)
                 {
+                    std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
+
                     UpdateImageLoadAddress (dyld_module_sp.get(), m_dyld);
                     resolved = m_process->GetTarget().ResolveLoadAddress(m_dyld_all_image_infos.notification, so_addr);
                 }
@@ -1752,229 +1127,6 @@ DynamicLoaderMacOSXDYLD::SetNotification
     return m_break_id != LLDB_INVALID_BREAK_ID;
 }
 
-//----------------------------------------------------------------------
-// Member function that gets called when the process state changes.
-//----------------------------------------------------------------------
-void
-DynamicLoaderMacOSXDYLD::PrivateProcessStateChanged (Process *process, StateType state)
-{
-    DEBUG_PRINTF("DynamicLoaderMacOSXDYLD::%s(%s)\n", __FUNCTION__, StateAsCString(state));
-    switch (state)
-    {
-    case eStateConnected:
-    case eStateAttaching:
-    case eStateLaunching:
-    case eStateInvalid:
-    case eStateUnloaded:
-    case eStateExited:
-    case eStateDetached:
-        Clear(false);
-        break;
-
-    case eStateStopped:
-        // Keep trying find dyld and set our notification breakpoint each time
-        // we stop until we succeed
-        if (!DidSetNotificationBreakpoint () && m_process->IsAlive())
-        {
-            if (NeedToLocateDYLD ())
-                LocateDYLD ();
-
-            SetNotificationBreakpoint ();
-        }
-        break;
-
-    case eStateRunning:
-    case eStateStepping:
-    case eStateCrashed:
-    case eStateSuspended:
-        break;
-    }
-}
-
-ThreadPlanSP
-DynamicLoaderMacOSXDYLD::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others)
-{
-    ThreadPlanSP thread_plan_sp;
-    StackFrame *current_frame = thread.GetStackFrameAtIndex(0).get();
-    const SymbolContext &current_context = current_frame->GetSymbolContext(eSymbolContextSymbol);
-    Symbol *current_symbol = current_context.symbol;
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
-    TargetSP target_sp (thread.CalculateTarget());
-
-    if (current_symbol != NULL)
-    {
-        std::vector<Address>  addresses;
-        
-        if (current_symbol->IsTrampoline())
-        {
-            const ConstString &trampoline_name = current_symbol->GetMangled().GetName(current_symbol->GetLanguage(), Mangled::ePreferMangled);
-            
-            if (trampoline_name)
-            {
-                const ModuleList &images = target_sp->GetImages();
-                
-                SymbolContextList code_symbols;
-                images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeCode, code_symbols);
-                size_t num_code_symbols = code_symbols.GetSize();
-                
-                if (num_code_symbols > 0)
-                {
-                    for (uint32_t i = 0; i < num_code_symbols; i++)
-                    {
-                        SymbolContext context;
-                        AddressRange addr_range;
-                        if (code_symbols.GetContextAtIndex(i, context))
-                        {
-                            context.GetAddressRange (eSymbolContextEverything, 0, false, addr_range);
-                            addresses.push_back(addr_range.GetBaseAddress());
-                            if (log)
-                            {
-                                addr_t load_addr = addr_range.GetBaseAddress().GetLoadAddress(target_sp.get());
-
-                                log->Printf ("Found a trampoline target symbol at 0x%" PRIx64 ".", load_addr);
-                            }
-                        }
-                    }
-                }
-                
-                SymbolContextList reexported_symbols;
-                images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeReExported, reexported_symbols);
-                size_t num_reexported_symbols = reexported_symbols.GetSize();
-                if (num_reexported_symbols > 0)
-                {
-                    for (uint32_t i = 0; i < num_reexported_symbols; i++)
-                    {
-                        SymbolContext context;
-                        if (reexported_symbols.GetContextAtIndex(i, context))
-                        {
-                            if (context.symbol)
-                            {
-                                Symbol *actual_symbol = context.symbol->ResolveReExportedSymbol(*target_sp.get());
-                                if (actual_symbol)
-                                {
-                                    const Address actual_symbol_addr = actual_symbol->GetAddress();
-                                    if (actual_symbol_addr.IsValid())
-                                    {
-                                        addresses.push_back(actual_symbol_addr);
-                                        if (log)
-                                        {
-                                            lldb::addr_t load_addr = actual_symbol_addr.GetLoadAddress(target_sp.get());
-                                            log->Printf ("Found a re-exported symbol: %s at 0x%" PRIx64 ".",
-                                                         actual_symbol->GetName().GetCString(), load_addr);
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-                
-                SymbolContextList indirect_symbols;
-                images.FindSymbolsWithNameAndType(trampoline_name, eSymbolTypeResolver, indirect_symbols);
-                size_t num_indirect_symbols = indirect_symbols.GetSize();
-                if (num_indirect_symbols > 0)
-                {
-                    for (uint32_t i = 0; i < num_indirect_symbols; i++)
-                    {
-                        SymbolContext context;
-                        AddressRange addr_range;
-                        if (indirect_symbols.GetContextAtIndex(i, context))
-                        {
-                            context.GetAddressRange (eSymbolContextEverything, 0, false, addr_range);
-                            addresses.push_back(addr_range.GetBaseAddress());
-                            if (log)
-                            {
-                                addr_t load_addr = addr_range.GetBaseAddress().GetLoadAddress(target_sp.get());
-
-                                log->Printf ("Found an indirect target symbol at 0x%" PRIx64 ".", load_addr);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        else if (current_symbol->GetType() == eSymbolTypeReExported)
-        {
-            // I am not sure we could ever end up stopped AT a re-exported symbol.  But just in case:
-            
-            const Symbol *actual_symbol = current_symbol->ResolveReExportedSymbol(*(target_sp.get()));
-            if (actual_symbol)
-            {
-                Address target_addr(actual_symbol->GetAddress());
-                if (target_addr.IsValid())
-                {
-                    if (log)
-                        log->Printf ("Found a re-exported symbol: %s pointing to: %s at 0x%" PRIx64 ".",
-                                     current_symbol->GetName().GetCString(),
-                                     actual_symbol->GetName().GetCString(),
-                                     target_addr.GetLoadAddress(target_sp.get()));
-                    addresses.push_back (target_addr.GetLoadAddress(target_sp.get()));
-                
-                }
-            }
-        }
-        
-        if (addresses.size() > 0)
-        {
-            // First check whether any of the addresses point to Indirect symbols, and if they do, resolve them:
-            std::vector<lldb::addr_t> load_addrs;
-            for (Address address : addresses)
-            {
-                Symbol *symbol = address.CalculateSymbolContextSymbol();
-                if (symbol && symbol->IsIndirect())
-                {
-                    Error error;
-                    Address symbol_address = symbol->GetAddress();
-                    addr_t resolved_addr = thread.GetProcess()->ResolveIndirectFunction(&symbol_address, error);
-                    if (error.Success())
-                    {
-                        load_addrs.push_back(resolved_addr);
-                        if (log)
-                            log->Printf("ResolveIndirectFunction found resolved target for %s at 0x%" PRIx64 ".",
-                                        symbol->GetName().GetCString(), resolved_addr);
-                    }
-                }
-                else
-                {
-                    load_addrs.push_back(address.GetLoadAddress(target_sp.get()));
-                }
-                
-            }
-            thread_plan_sp.reset (new ThreadPlanRunToAddress (thread, load_addrs, stop_others));
-        }
-    }
-    else
-    {
-        if (log)
-            log->Printf ("Could not find symbol for step through.");
-    }
-
-    return thread_plan_sp;
-}
-
-size_t
-DynamicLoaderMacOSXDYLD::FindEquivalentSymbols (lldb_private::Symbol *original_symbol, 
-                                               lldb_private::ModuleList &images, 
-                                               lldb_private::SymbolContextList &equivalent_symbols)
-{
-    const ConstString &trampoline_name = original_symbol->GetMangled().GetName(original_symbol->GetLanguage(), Mangled::ePreferMangled);
-    if (!trampoline_name)
-        return 0;
-        
-    size_t initial_size = equivalent_symbols.GetSize();
-    
-    static const char *resolver_name_regex = "(_gc|_non_gc|\\$[A-Za-z0-9\\$]+)$";
-    std::string equivalent_regex_buf("^");
-    equivalent_regex_buf.append (trampoline_name.GetCString());
-    equivalent_regex_buf.append (resolver_name_regex);
-
-    RegularExpression equivalent_name_regex (equivalent_regex_buf.c_str());
-    const bool append = true;
-    images.FindSymbolsMatchingRegExAndType (equivalent_name_regex, eSymbolTypeCode, equivalent_symbols, append);
-    
-    return equivalent_symbols.GetSize() - initial_size;
-}
-
 Error
 DynamicLoaderMacOSXDYLD::CanLoadImage ()
 {
@@ -1995,135 +1147,6 @@ DynamicLoaderMacOSXDYLD::CanLoadImage ()
     return error;
 }
 
-lldb::ModuleSP
-DynamicLoaderMacOSXDYLD::GetPThreadLibraryModule()
-{
-    ModuleSP module_sp = m_libpthread_module_wp.lock();
-    if (!module_sp)
-    {
-        SymbolContextList sc_list;
-        ModuleSpec module_spec;
-        module_spec.GetFileSpec().GetFilename().SetCString("libsystem_pthread.dylib");
-        ModuleList module_list;
-        if (m_process->GetTarget().GetImages().FindModules(module_spec, module_list))
-        {
-            if (module_list.GetSize() == 1)
-            {
-                module_sp = module_list.GetModuleAtIndex(0);
-                if (module_sp)
-                    m_libpthread_module_wp = module_sp;
-            }
-        }
-    }
-    return module_sp;
-}
-
-Address
-DynamicLoaderMacOSXDYLD::GetPthreadSetSpecificAddress()
-{
-    if (!m_pthread_getspecific_addr.IsValid())
-    {
-        ModuleSP module_sp = GetPThreadLibraryModule();
-        if (module_sp)
-        {
-            lldb_private::SymbolContextList sc_list;
-            module_sp->FindSymbolsWithNameAndType(ConstString("pthread_getspecific"), eSymbolTypeCode, sc_list);
-            SymbolContext sc;
-            if (sc_list.GetContextAtIndex(0, sc))
-            {
-                if (sc.symbol)
-                    m_pthread_getspecific_addr = sc.symbol->GetAddress();
-            }
-        }
-    }
-    return m_pthread_getspecific_addr;
-}
-
-lldb::addr_t
-DynamicLoaderMacOSXDYLD::GetThreadLocalData(const lldb::ModuleSP module_sp, const lldb::ThreadSP thread_sp,
-                                            lldb::addr_t tls_file_addr)
-{
-    if (!thread_sp || !module_sp)
-        return LLDB_INVALID_ADDRESS;
-
-    std::lock_guard<std::recursive_mutex> guard(m_mutex);
-
-    const uint32_t addr_size = m_process->GetAddressByteSize();
-    uint8_t buf[sizeof(lldb::addr_t) * 3];
-
-    lldb_private::Address tls_addr;
-    if (module_sp->ResolveFileAddress(tls_file_addr, tls_addr))
-    {
-        Error error;
-        const size_t tsl_data_size = addr_size * 3;
-        Target &target = m_process->GetTarget();
-        if (target.ReadMemory(tls_addr, false, buf, tsl_data_size, error) == tsl_data_size)
-        {
-            const ByteOrder byte_order = m_process->GetByteOrder();
-            DataExtractor data(buf, sizeof(buf), byte_order, addr_size);
-            lldb::offset_t offset = addr_size; // Skip the first pointer
-            const lldb::addr_t pthread_key = data.GetAddress(&offset);
-            const lldb::addr_t tls_offset = data.GetAddress(&offset);
-            if (pthread_key != 0)
-            {
-                // First check to see if we have already figured out the location
-                // of TLS data for the pthread_key on a specific thread yet. If we
-                // have we can re-use it since its location will not change unless
-                // the process execs.
-                const tid_t tid = thread_sp->GetID();
-                auto tid_pos = m_tid_to_tls_map.find(tid);
-                if (tid_pos != m_tid_to_tls_map.end())
-                {
-                    auto tls_pos = tid_pos->second.find(pthread_key);
-                    if (tls_pos != tid_pos->second.end())
-                    {
-                        return tls_pos->second + tls_offset;
-                    }
-                }
-                StackFrameSP frame_sp = thread_sp->GetStackFrameAtIndex(0);
-                if (frame_sp)
-                {
-                    ClangASTContext *clang_ast_context = target.GetScratchClangASTContext();
-
-                    if (!clang_ast_context)
-                        return LLDB_INVALID_ADDRESS;
-
-                    CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
-                    Address pthread_getspecific_addr = GetPthreadSetSpecificAddress();
-                    if (pthread_getspecific_addr.IsValid())
-                    {
-                        EvaluateExpressionOptions options;
-
-                        lldb::ThreadPlanSP thread_plan_sp(
-                            new ThreadPlanCallFunction(*thread_sp, pthread_getspecific_addr, clang_void_ptr_type,
-                                                       llvm::ArrayRef<lldb::addr_t>(pthread_key), options));
-
-                        DiagnosticManager execution_errors;
-                        ExecutionContext exe_ctx(thread_sp);
-                        lldb::ExpressionResults results =
-                            m_process->RunThreadPlan(exe_ctx, thread_plan_sp, options, execution_errors);
-
-                        if (results == lldb::eExpressionCompleted)
-                        {
-                            lldb::ValueObjectSP result_valobj_sp = thread_plan_sp->GetReturnValueObject();
-                            if (result_valobj_sp)
-                            {
-                                const lldb::addr_t pthread_key_data = result_valobj_sp->GetValueAsUnsigned(0);
-                                if (pthread_key_data)
-                                {
-                                    m_tid_to_tls_map[tid].insert(std::make_pair(pthread_key, pthread_key_data));
-                                    return pthread_key_data + tls_offset;
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-    return LLDB_INVALID_ADDRESS;
-}
-
 void
 DynamicLoaderMacOSXDYLD::Initialize()
 {
@@ -2171,6 +1194,8 @@ DynamicLoaderMacOSXDYLD::GetPluginVersio
 uint32_t
 DynamicLoaderMacOSXDYLD::AddrByteSize()
 {
+    std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex());
+
     switch (m_dyld.header.magic)
     {
         case llvm::MachO::MH_MAGIC:
@@ -2188,7 +1213,7 @@ DynamicLoaderMacOSXDYLD::AddrByteSize()
 }
 
 lldb::ByteOrder
-DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic (uint32_t magic)
+DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic(uint32_t magic)
 {
     switch (magic)
     {
@@ -2208,10 +1233,3 @@ DynamicLoaderMacOSXDYLD::GetByteOrderFro
     }
     return lldb::eByteOrderInvalid;
 }
-
-lldb::ByteOrder
-DynamicLoaderMacOSXDYLD::DYLDImageInfo::GetByteOrder()
-{
-    return DynamicLoaderMacOSXDYLD::GetByteOrderFromMagic(header.magic);
-}
-

Modified: lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h?rev=275733&r1=275732&r2=275733&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h (original)
+++ lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h Sun Jul 17 16:27:32 2016
@@ -12,9 +12,8 @@
 
 // C Includes
 // C++ Includes
-#include <map>
-#include <mutex>
 #include <vector>
+#include <mutex>
 
 // Other libraries and framework includes
 // Project includes
@@ -25,12 +24,14 @@
 #include "lldb/Target/Process.h"
 #include "lldb/Utility/SafeMachO.h"
 
-class DynamicLoaderMacOSXDYLD : public lldb_private::DynamicLoader
+#include "DynamicLoaderDarwin.h"
+
+class DynamicLoaderMacOSXDYLD : public lldb_private::DynamicLoaderDarwin
 {
 public:
     DynamicLoaderMacOSXDYLD(lldb_private::Process *process);
 
-    ~DynamicLoaderMacOSXDYLD() override;
+    virtual ~DynamicLoaderMacOSXDYLD() override;
 
     //------------------------------------------------------------------
     // Static Functions
@@ -56,30 +57,12 @@ public:
     /// 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;
 
-    lldb::addr_t
-    GetThreadLocalData(const lldb::ModuleSP module, const lldb::ThreadSP thread, lldb::addr_t tls_file_addr) override;
-
     //------------------------------------------------------------------
     // PluginInterface protocol
     //------------------------------------------------------------------
@@ -89,28 +72,21 @@ public:
     uint32_t
     GetPluginVersion() override;
 
-    bool
-    AlwaysRelyOnEHUnwindInfo(lldb_private::SymbolContext &sym_ctx) override;
-
 protected:
     void
-    PrivateInitialize (lldb_private::Process *process);
+    PutToLog(lldb_private::Log *log) const;
 
     void
-    PrivateProcessStateChanged (lldb_private::Process *process,
-                                lldb::StateType state);
+    DoInitialImageFetch () override;
 
     bool
-    LocateDYLD ();
+    NeedToDoInitialImageFetch () override;
 
     bool
-    DidSetNotificationBreakpoint () const;
-
-    void
-    Clear (bool clear_process);
+    DidSetNotificationBreakpoint () override;
 
     void
-    PutToLog (lldb_private::Log *log) const;
+    DoClear () override;
 
     bool
     ReadDYLDInfoFromMemoryAndSetNotificationCallback (lldb::addr_t addr);
@@ -124,141 +100,15 @@ protected:
     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;
-    };
+    uint32_t
+    ParseLoadCommands (const lldb_private::DataExtractor& data,
+                       ImageInfo& dylib_info,
+                       lldb_private::FileSpec *lc_id_dylinker);
 
     struct DYLDAllImageInfos
     {
@@ -300,40 +150,14 @@ protected:
         }
     };
 
-    typedef std::map<uint64_t, lldb::addr_t> PthreadKeyToTLSMap;
-    typedef std::map<lldb::user_id_t, PthreadKeyToTLSMap> ThreadIDToTLSMap;
-    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);
+    static lldb::ByteOrder
+    GetByteOrderFromMagic(uint32_t magic);
 
     bool
-    NeedToLocateDYLD () const;
+    SetNotificationBreakpoint () override;
 
-    bool
-    SetNotificationBreakpoint ();
+    void
+    ClearNotificationBreakpoint () override;
 
     // 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
@@ -350,46 +174,26 @@ protected:
     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, 
+    UpdateImageInfosHeaderAndLoadCommands(ImageInfo::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);
-
-    lldb::ModuleSP
-    GetPThreadLibraryModule();
-
-    lldb_private::Address
-    GetPthreadSetSpecificAddress();
+                    ImageInfo::collection &image_infos);
 
-    DYLDImageInfo m_dyld;               // Info about the current dyld being used
-    lldb::ModuleWP m_dyld_module_wp;
-    lldb::ModuleWP m_libpthread_module_wp;
-    lldb_private::Address m_pthread_getspecific_addr;
     lldb::addr_t m_dyld_all_image_infos_addr;
     DYLDAllImageInfos m_dyld_all_image_infos;
-    ThreadIDToTLSMap m_tid_to_tls_map;
     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 std::recursive_mutex m_mutex;
-    lldb_private::Process::Notifications m_notification_callbacks;
     bool m_process_image_addr_is_all_images_infos;
 
 private:




More information about the lldb-commits mailing list