Fix incomplete commit of http://llvm.org/viewvc/llvm-project?rev=147609&view=rev:

This patch combines common code from Linux and FreeBSD into
a new POSIX platform.  It also contains fixes for 64bit FreeBSD.

The patch is based on changes by Mark Peek <mp@FreeBSD.org> and
"K. Macy" <kmacy@freebsd.org> in their github repo located at
https://github.com/fbsd/lldb.

llvm-svn: 147613
diff --git a/lldb/source/Plugins/DynamicLoader/Linux-DYLD/AuxVector.cpp b/lldb/source/Plugins/DynamicLoader/Linux-DYLD/AuxVector.cpp
deleted file mode 100644
index e69de29..0000000
--- a/lldb/source/Plugins/DynamicLoader/Linux-DYLD/AuxVector.cpp
+++ /dev/null
diff --git a/lldb/source/Plugins/DynamicLoader/Linux-DYLD/AuxVector.h b/lldb/source/Plugins/DynamicLoader/Linux-DYLD/AuxVector.h
deleted file mode 100644
index e69de29..0000000
--- a/lldb/source/Plugins/DynamicLoader/Linux-DYLD/AuxVector.h
+++ /dev/null
diff --git a/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DYLDRendezvous.cpp b/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DYLDRendezvous.cpp
deleted file mode 100644
index e69de29..0000000
--- a/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DYLDRendezvous.cpp
+++ /dev/null
diff --git a/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DYLDRendezvous.h b/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DYLDRendezvous.h
deleted file mode 100644
index e69de29..0000000
--- a/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DYLDRendezvous.h
+++ /dev/null
diff --git a/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DynamicLoaderLinuxDYLD.cpp b/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DynamicLoaderLinuxDYLD.cpp
deleted file mode 100644
index e69de29..0000000
--- a/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DynamicLoaderLinuxDYLD.cpp
+++ /dev/null
diff --git a/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DynamicLoaderLinuxDYLD.h b/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DynamicLoaderLinuxDYLD.h
deleted file mode 100644
index e69de29..0000000
--- a/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DynamicLoaderLinuxDYLD.h
+++ /dev/null
diff --git a/lldb/source/Plugins/DynamicLoader/Linux-DYLD/Makefile b/lldb/source/Plugins/DynamicLoader/Linux-DYLD/Makefile
deleted file mode 100644
index e69de29..0000000
--- a/lldb/source/Plugins/DynamicLoader/Linux-DYLD/Makefile
+++ /dev/null
diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp
new file mode 100644
index 0000000..9311e70
--- /dev/null
+++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp
@@ -0,0 +1,153 @@
+//===-- AuxVector.cpp -------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// C Includes
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+// C++ Includes
+// Other libraries and framework includes
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Target/Process.h"
+
+#include "AuxVector.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+static bool
+GetMaxU64(DataExtractor &data,
+          uint32_t *offset, uint64_t *value, unsigned int byte_size)
+{
+    uint32_t saved_offset = *offset;
+    *value = data.GetMaxU64(offset, byte_size);
+    return *offset != saved_offset;
+}
+
+static bool
+ParseAuxvEntry(DataExtractor &data, AuxVector::Entry &entry, 
+               uint32_t *offset, unsigned int byte_size)
+{
+    if (!GetMaxU64(data, offset, &entry.type, byte_size))
+        return false;
+
+    if (!GetMaxU64(data, offset, &entry.value, byte_size))
+        return false;
+
+    return true;
+}
+
+DataBufferSP
+AuxVector::GetAuxvData()
+{
+
+    return lldb_private::Host::GetAuxvData(m_process);
+}
+
+void
+AuxVector::ParseAuxv(DataExtractor &data)
+{
+    const unsigned int byte_size  = m_process->GetAddressByteSize();
+    uint32_t offset = 0;
+
+    for (;;) 
+    {
+        Entry entry;
+
+        if (!ParseAuxvEntry(data, entry, &offset, byte_size))
+            break;
+
+        if (entry.type == AT_NULL)
+            break;
+
+        if (entry.type == AT_IGNORE)
+            continue;
+
+        m_auxv.push_back(entry);
+    }
+}
+
+AuxVector::AuxVector(Process *process)
+    : m_process(process)
+{
+    DataExtractor data;
+    LogSP log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+
+    data.SetData(GetAuxvData());
+    data.SetByteOrder(m_process->GetByteOrder());
+    data.SetAddressByteSize(m_process->GetAddressByteSize());
+    
+    ParseAuxv(data);
+
+    if (log)
+        DumpToLog(log);
+}
+
+AuxVector::iterator 
+AuxVector::FindEntry(EntryType type) const
+{
+    for (iterator I = begin(); I != end(); ++I)
+    {
+        if (I->type == static_cast<uint64_t>(type))
+            return I;
+    }
+
+    return end();
+}
+
+void
+AuxVector::DumpToLog(LogSP log) const
+{
+    if (!log)
+        return;
+
+    log->PutCString("AuxVector: ");
+    for (iterator I = begin(); I != end(); ++I)
+    {
+        log->Printf("   %s [%d]: %lx", GetEntryName(*I), I->type, I->value);
+    }
+}
+
+const char *
+AuxVector::GetEntryName(EntryType type)
+{
+    const char *name;
+
+#define ENTRY_NAME(_type) _type: name = #_type
+    switch (type) 
+    {
+    default:
+        name = "unkown";
+        break;
+
+    case ENTRY_NAME(AT_NULL);   break;
+    case ENTRY_NAME(AT_IGNORE); break;
+    case ENTRY_NAME(AT_EXECFD); break;
+    case ENTRY_NAME(AT_PHDR);   break;
+    case ENTRY_NAME(AT_PHENT);  break;
+    case ENTRY_NAME(AT_PHNUM);  break;
+    case ENTRY_NAME(AT_PAGESZ); break;
+    case ENTRY_NAME(AT_BASE);   break;
+    case ENTRY_NAME(AT_FLAGS);  break;
+    case ENTRY_NAME(AT_ENTRY);  break;
+    case ENTRY_NAME(AT_NOTELF); break;
+    case ENTRY_NAME(AT_UID);    break;
+    case ENTRY_NAME(AT_EUID);   break;
+    case ENTRY_NAME(AT_GID);    break;
+    case ENTRY_NAME(AT_EGID);   break;
+    case ENTRY_NAME(AT_CLKTCK); break;
+    }
+#undef ENTRY_NAME
+
+    return name;
+}
+
diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h
new file mode 100644
index 0000000..7a5b370
--- /dev/null
+++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h
@@ -0,0 +1,97 @@
+//===-- AuxVector.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_AuxVector_H_
+#define liblldb_AuxVector_H_
+
+// C Includes
+// C++ Includes
+#include <vector>
+
+// Other libraries and framework includes
+#include "lldb/lldb-forward-rtti.h"
+
+namespace lldb_private {
+class DataExtractor;
+} 
+
+/// @class AuxVector
+/// @brief Represents a processes auxiliary vector.
+///
+/// When a process is loaded on Linux a vector of values is placed onto the
+/// stack communicating operating system specific information.  On construction
+/// this class locates and parses this information and provides a simple
+/// read-only interface to the entries found.
+class AuxVector {
+
+public:
+    AuxVector(lldb_private::Process *process);
+
+    struct Entry {
+        uint64_t type;
+        uint64_t value;
+
+        Entry() : type(0), value(0) { }
+    };
+
+    /// Constants describing the type of entry.
+    enum EntryType {
+        AT_NULL   = 0,          ///< End of auxv.
+        AT_IGNORE = 1,          ///< Ignore entry.
+        AT_EXECFD = 2,          ///< File descriptor of program.
+        AT_PHDR   = 3,          ///< Program headers.
+        AT_PHENT  = 4,          ///< Size of program header.
+        AT_PHNUM  = 5,          ///< Number of program headers.
+        AT_PAGESZ = 6,          ///< Page size.
+        AT_BASE   = 7,          ///< Interpreter base address.
+        AT_FLAGS  = 8,          ///< Flags.
+        AT_ENTRY  = 9,          ///< Program entry point.
+        AT_NOTELF = 10,         ///< Set if program is not an ELF.
+        AT_UID    = 11,         ///< UID.
+        AT_EUID   = 12,         ///< Effective UID.
+        AT_GID    = 13,         ///< GID.
+        AT_EGID   = 14,         ///< Effective GID.
+        AT_CLKTCK = 17          ///< Clock frequency (e.g. times(2)).
+    };
+
+private:
+    typedef std::vector<Entry> EntryVector;
+
+public:
+    typedef EntryVector::const_iterator iterator;
+
+    iterator begin() const { return m_auxv.begin(); }
+    iterator end() const { return m_auxv.end(); }
+
+    iterator 
+    FindEntry(EntryType type) const;
+
+    static const char *
+    GetEntryName(const Entry &entry) { 
+        return GetEntryName(static_cast<EntryType>(entry.type)); 
+    }
+
+    static const char *
+    GetEntryName(EntryType type);
+
+    void
+    DumpToLog(lldb::LogSP log) const;
+
+private:
+    lldb_private::Process *m_process;
+    EntryVector m_auxv;
+
+    lldb::DataBufferSP
+    GetAuxvData();
+
+    void
+    ParseAuxv(lldb_private::DataExtractor &data);
+};
+
+#endif
diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
new file mode 100644
index 0000000..aa00f54
--- /dev/null
+++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
@@ -0,0 +1,330 @@
+//===-- DYLDRendezvous.cpp --------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+
+#include "DYLDRendezvous.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+/// Locates the address of the rendezvous structure.  Returns the address on
+/// success and LLDB_INVALID_ADDRESS on failure.
+static addr_t
+ResolveRendezvousAddress(Process *process)
+{
+    addr_t info_location;
+    addr_t info_addr;
+    Error error;
+    size_t size;
+
+    info_location = process->GetImageInfoAddress();
+
+    if (info_location == LLDB_INVALID_ADDRESS)
+        return LLDB_INVALID_ADDRESS;
+
+    info_addr = 0;
+    size = process->DoReadMemory(info_location, &info_addr,
+                                 process->GetAddressByteSize(), error);
+    if (size != process->GetAddressByteSize() || error.Fail())
+        return LLDB_INVALID_ADDRESS;
+
+    if (info_addr == 0)
+        return LLDB_INVALID_ADDRESS;
+
+    return info_addr;
+}
+
+DYLDRendezvous::DYLDRendezvous(Process *process)
+    : m_process(process),
+      m_rendezvous_addr(LLDB_INVALID_ADDRESS),
+      m_current(),
+      m_previous(),
+      m_soentries(),
+      m_added_soentries(),
+      m_removed_soentries()
+{
+    // Cache a copy of the executable path
+    m_process->GetTarget().GetExecutableModule().get()->GetFileSpec().GetPath(m_exe_path, PATH_MAX);
+}
+
+bool
+DYLDRendezvous::Resolve()
+{
+    const size_t word_size = 4;
+    Rendezvous info;
+    size_t address_size;
+    size_t padding;
+    addr_t info_addr;
+    addr_t cursor;
+
+    address_size = m_process->GetAddressByteSize();
+    padding = address_size - word_size;
+
+    if (m_rendezvous_addr == LLDB_INVALID_ADDRESS)
+        cursor = info_addr = ResolveRendezvousAddress(m_process);
+    else
+        cursor = info_addr = m_rendezvous_addr;
+    
+    if (cursor == LLDB_INVALID_ADDRESS)
+        return false;
+
+    if (!(cursor = ReadMemory(cursor, &info.version, word_size)))
+        return false;
+
+    if (!(cursor = ReadMemory(cursor + padding, &info.map_addr, address_size)))
+        return false;
+
+    if (!(cursor = ReadMemory(cursor, &info.brk, address_size)))
+        return false;
+
+    if (!(cursor = ReadMemory(cursor, &info.state, word_size)))
+        return false;
+
+    if (!(cursor = ReadMemory(cursor + padding, &info.ldbase, address_size)))
+        return false;
+
+    // The rendezvous was successfully read.  Update our internal state.
+    m_rendezvous_addr = info_addr;
+    m_previous = m_current;
+    m_current = info;
+
+    return UpdateSOEntries();
+}
+
+bool
+DYLDRendezvous::IsValid()
+{
+    return m_rendezvous_addr != LLDB_INVALID_ADDRESS;
+}
+
+bool
+DYLDRendezvous::UpdateSOEntries()
+{
+    SOEntry entry;
+
+    if (m_current.map_addr == 0)
+        return false;
+
+    // When the previous and current states are consistent this is the first
+    // time we have been asked to update.  Just take a snapshot of the currently
+    // loaded modules.
+    if (m_previous.state == eConsistent && m_current.state == eConsistent) 
+        return TakeSnapshot(m_soentries);
+
+    // If we are about to add or remove a shared object clear out the current
+    // state and take a snapshot of the currently loaded images.
+    if (m_current.state == eAdd || m_current.state == eDelete)
+    {
+        assert(m_previous.state == eConsistent);
+        m_soentries.clear();
+        m_added_soentries.clear();
+        m_removed_soentries.clear();
+        return TakeSnapshot(m_soentries);
+    }
+    assert(m_current.state == eConsistent);
+
+    // Otherwise check the previous state to determine what to expect and update
+    // accordingly.
+    if (m_previous.state == eAdd)
+        return UpdateSOEntriesForAddition();
+    else if (m_previous.state == eDelete)
+        return UpdateSOEntriesForDeletion();
+
+    return false;
+}
+ 
+bool
+DYLDRendezvous::UpdateSOEntriesForAddition()
+{
+    SOEntry entry;
+    iterator pos;
+
+    assert(m_previous.state == eAdd);
+
+    if (m_current.map_addr == 0)
+        return false;
+
+    for (addr_t cursor = m_current.map_addr; cursor != 0; cursor = entry.next)
+    {
+        if (!ReadSOEntryFromMemory(cursor, entry))
+            return false;
+
+        // Only add shared libraries and not the executable.
+        // On Linux this is indicated by an empty path in the entry.
+        // On FreeBSD it is the name of the executable.
+        if (entry.path.empty() || ::strcmp(entry.path.c_str(), m_exe_path) == 0)
+            continue;
+
+        pos = std::find(m_soentries.begin(), m_soentries.end(), entry);
+        if (pos == m_soentries.end())
+        {
+            m_soentries.push_back(entry);
+            m_added_soentries.push_back(entry);
+        }
+    }
+
+    return true;
+}
+
+bool
+DYLDRendezvous::UpdateSOEntriesForDeletion()
+{
+    SOEntryList entry_list;
+    iterator pos;
+
+    assert(m_previous.state == eDelete);
+
+    if (!TakeSnapshot(entry_list))
+        return false;
+
+    for (iterator I = begin(); I != end(); ++I)
+    {
+        pos = std::find(entry_list.begin(), entry_list.end(), *I);
+        if (pos == entry_list.end())
+            m_removed_soentries.push_back(*I);
+    }
+
+    m_soentries = entry_list;
+    return true;
+}
+
+bool
+DYLDRendezvous::TakeSnapshot(SOEntryList &entry_list)
+{
+    SOEntry entry;
+
+    if (m_current.map_addr == 0)
+        return false;
+
+    for (addr_t cursor = m_current.map_addr; cursor != 0; cursor = entry.next)
+    {
+        if (!ReadSOEntryFromMemory(cursor, entry))
+            return false;
+
+        // Only add shared libraries and not the executable.
+        // On Linux this is indicated by an empty path in the entry.
+        // On FreeBSD it is the name of the executable.
+        if (entry.path.empty() || ::strcmp(entry.path.c_str(), m_exe_path) == 0)
+            continue;
+
+        entry_list.push_back(entry);
+    }
+
+    return true;
+}
+
+addr_t
+DYLDRendezvous::ReadMemory(addr_t addr, void *dst, size_t size)
+{
+    size_t bytes_read;
+    Error error;
+
+    bytes_read = m_process->DoReadMemory(addr, dst, size, error);
+    if (bytes_read != size || error.Fail())
+        return 0;
+
+    return addr + bytes_read;
+}
+
+std::string
+DYLDRendezvous::ReadStringFromMemory(addr_t addr)
+{
+    std::string str;
+    Error error;
+    size_t size;
+    char c;
+
+    if (addr == LLDB_INVALID_ADDRESS)
+        return std::string();
+
+    for (;;) {
+        size = m_process->DoReadMemory(addr, &c, 1, error);
+        if (size != 1 || error.Fail())
+            return std::string();
+        if (c == 0)
+            break;
+        else {
+            str.push_back(c);
+            addr++;
+        }
+    }
+
+    return str;
+}
+
+bool
+DYLDRendezvous::ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry)
+{
+    size_t address_size = m_process->GetAddressByteSize();
+
+    entry.clear();
+    
+    if (!(addr = ReadMemory(addr, &entry.base_addr, address_size)))
+        return false;
+    
+    if (!(addr = ReadMemory(addr, &entry.path_addr, address_size)))
+        return false;
+    
+    if (!(addr = ReadMemory(addr, &entry.dyn_addr, address_size)))
+        return false;
+    
+    if (!(addr = ReadMemory(addr, &entry.next, address_size)))
+        return false;
+    
+    if (!(addr = ReadMemory(addr, &entry.prev, address_size)))
+        return false;
+    
+    entry.path = ReadStringFromMemory(entry.path_addr);
+    
+    return true;
+}
+
+void
+DYLDRendezvous::DumpToLog(LogSP log) const
+{
+    int state = GetState();
+
+    if (!log)
+        return;
+
+    log->PutCString("DYLDRendezvous:");
+    log->Printf("   Address: %lx", GetRendezvousAddress());
+    log->Printf("   Version: %d",  GetVersion());
+    log->Printf("   Link   : %lx", GetLinkMapAddress());
+    log->Printf("   Break  : %lx", GetBreakAddress());
+    log->Printf("   LDBase : %lx", GetLDBase());
+    log->Printf("   State  : %s", 
+                (state == eConsistent) ? "consistent" :
+                (state == eAdd)        ? "add"        :
+                (state == eDelete)     ? "delete"     : "unknown");
+    
+    iterator I = begin();
+    iterator E = end();
+
+    if (I != E) 
+        log->PutCString("DYLDRendezvous SOEntries:");
+    
+    for (int i = 1; I != E; ++I, ++i) 
+    {
+        log->Printf("\n   SOEntry [%d] %s", i, I->path.c_str());
+        log->Printf("      Base : %lx", I->base_addr);
+        log->Printf("      Path : %lx", I->path_addr);
+        log->Printf("      Dyn  : %lx", I->dyn_addr);
+        log->Printf("      Next : %lx", I->next);
+        log->Printf("      Prev : %lx", I->prev);
+    }
+}
diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
new file mode 100644
index 0000000..3402a72
--- /dev/null
+++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
@@ -0,0 +1,230 @@
+//===-- DYLDRendezvous.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_Rendezvous_H_
+#define liblldb_Rendezvous_H_
+
+// C Includes
+// C++ Includes
+#include <list>
+#include <string>
+
+// Other libraries and framework includes
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-types.h"
+
+namespace lldb_private {
+class Process;
+}
+
+/// @class DYLDRendezvous
+/// @brief Interface to the runtime linker.
+///
+/// A structure is present in a processes memory space which is updated by the
+/// runtime liker each time a module is loaded or unloaded.  This class provides
+/// an interface to this structure and maintains a consistent snapshot of the
+/// currently loaded modules.
+class DYLDRendezvous {
+
+    // This structure is used to hold the contents of the debug rendezvous
+    // information (struct r_debug) as found in the inferiors memory.  Note that
+    // the layout of this struct is not binary compatible, it is simply large
+    // enough to hold the information on both 32 and 64 bit platforms.
+    struct Rendezvous {
+        uint64_t     version;
+        lldb::addr_t map_addr;
+        lldb::addr_t brk;
+        uint64_t     state;
+        lldb::addr_t ldbase;
+
+        Rendezvous()
+            : version(0), map_addr(0), brk(0), state(0), ldbase(0) { }
+    };
+
+public:
+    DYLDRendezvous(lldb_private::Process *process);
+
+    /// Update the internal snapshot of runtime linker rendezvous and recompute
+    /// the currently loaded modules.
+    ///
+    /// This method should be called once one start up, then once each time the
+    /// runtime linker enters the function given by GetBreakAddress().
+    ///
+    /// @returns true on success and false on failure.
+    ///
+    /// @see GetBreakAddress().
+    bool 
+    Resolve();
+
+    /// @returns true if this rendezvous has been located in the inferiors
+    /// address space and false otherwise.
+    bool 
+    IsValid();
+
+    /// @returns the address of the rendezvous structure in the inferiors
+    /// address space.
+    lldb::addr_t
+    GetRendezvousAddress() const { return m_rendezvous_addr; }
+
+    /// @returns the version of the rendezvous protocol being used.
+    int
+    GetVersion() const { return m_current.version; }
+
+    /// @returns address in the inferiors address space containing the linked
+    /// list of shared object descriptors.
+    lldb::addr_t 
+    GetLinkMapAddress() const { return m_current.map_addr; }
+
+    /// A breakpoint should be set at this address and Resolve called on each
+    /// hit.
+    ///
+    /// @returns the address of a function called by the runtime linker each
+    /// time a module is loaded/unloaded, or about to be loaded/unloaded.
+    ///
+    /// @see Resolve()
+    lldb::addr_t
+    GetBreakAddress() const { return m_current.brk; }
+
+    /// Returns the current state of the rendezvous structure.
+    int
+    GetState() const { return m_current.state; }
+
+    /// @returns the base address of the runtime linker in the inferiors address
+    /// space.
+    lldb::addr_t
+    GetLDBase() const { return m_current.ldbase; }
+
+    /// @returns true if modules have been loaded into the inferior since the
+    /// last call to Resolve().
+    bool
+    ModulesDidLoad() const { return !m_added_soentries.empty(); }
+
+    /// @returns true if modules have been unloaded from the inferior since the
+    /// last call to Resolve().
+    bool
+    ModulesDidUnload() const { return !m_removed_soentries.empty(); }
+
+    void
+    DumpToLog(lldb::LogSP log) const;
+
+    /// @brief Constants describing the state of the rendezvous.
+    ///
+    /// @see GetState().
+    enum RendezvousState {
+        eConsistent,
+        eAdd,
+        eDelete
+    };
+
+    /// @brief Structure representing the shared objects currently loaded into
+    /// the inferior process.
+    ///
+    /// This object is a rough analogue to the struct link_map object which
+    /// actually lives in the inferiors memory.
+    struct SOEntry {
+        lldb::addr_t base_addr; ///< Base address of the loaded object.
+        lldb::addr_t path_addr; ///< String naming the shared object.
+        lldb::addr_t dyn_addr;  ///< Dynamic section of shared object.
+        lldb::addr_t next;      ///< Address of next so_entry.
+        lldb::addr_t prev;      ///< Address of previous so_entry.
+        std::string  path;      ///< File name of shared object.
+
+        SOEntry() { clear(); }
+
+        bool operator ==(const SOEntry &entry) {
+            return this->path == entry.path;
+        }
+
+        void clear() {
+            base_addr = 0;
+            path_addr = 0;
+            dyn_addr  = 0;
+            next = 0;
+            prev = 0;
+            path.clear();
+        }
+    };
+
+protected:
+    typedef std::list<SOEntry> SOEntryList;
+
+public:
+    typedef SOEntryList::const_iterator iterator;
+
+    /// Iterators over all currently loaded modules.
+    iterator begin() const { return m_soentries.begin(); }
+    iterator end() const { return m_soentries.end(); }
+
+    /// Iterators over all modules loaded into the inferior since the last call
+    /// to Resolve().
+    iterator loaded_begin() const { return m_added_soentries.begin(); }
+    iterator loaded_end() const { return m_added_soentries.end(); }
+
+    /// Iterators over all modules unloaded from the inferior since the last
+    /// call to Resolve().
+    iterator unloaded_begin() const { return m_removed_soentries.begin(); }
+    iterator unloaded_end() const { return m_removed_soentries.end(); }
+    
+protected:
+    lldb_private::Process *m_process;
+
+    // Cached copy of executable pathname
+    char m_exe_path[PATH_MAX];
+
+    /// Location of the r_debug structure in the inferiors address space.
+    lldb::addr_t m_rendezvous_addr;
+
+    /// Current and previous snapshots of the rendezvous structure.
+    Rendezvous m_current;
+    Rendezvous m_previous;
+
+    /// List of SOEntry objects corresponding to the current link map state.
+    SOEntryList m_soentries;
+
+    /// List of SOEntry's added to the link map since the last call to Resolve().
+    SOEntryList m_added_soentries;
+
+    /// List of SOEntry's removed from the link map since the last call to
+    /// Resolve().
+    SOEntryList m_removed_soentries;
+
+    /// Reads @p size bytes from the inferiors address space starting at @p
+    /// addr.
+    ///
+    /// @returns addr + size if the read was successful and false otherwise.
+    lldb::addr_t
+    ReadMemory(lldb::addr_t addr, void *dst, size_t size);
+
+    /// Reads a null-terminated C string from the memory location starting at @p
+    /// addr.
+    std::string
+    ReadStringFromMemory(lldb::addr_t addr);
+
+    /// Reads an SOEntry starting at @p addr.
+    bool
+    ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry);
+
+    /// Updates the current set of SOEntries, the set of added entries, and the
+    /// set of removed entries.
+    bool
+    UpdateSOEntries();
+
+    bool
+    UpdateSOEntriesForAddition();
+
+    bool
+    UpdateSOEntriesForDeletion();
+
+    /// Reads the current list of shared objects according to the link map
+    /// supplied by the runtime linker.
+    bool
+    TakeSnapshot(SOEntryList &entry_list);
+};
+
+#endif
diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
new file mode 100644
index 0000000..05100cb
--- /dev/null
+++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
@@ -0,0 +1,425 @@
+//===-- DynamicLoaderPOSIX.h ------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlanRunToAddress.h"
+
+#include "AuxVector.h"
+#include "DynamicLoaderPOSIXDYLD.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+void
+DynamicLoaderPOSIXDYLD::Initialize()
+{
+    PluginManager::RegisterPlugin(GetPluginNameStatic(),
+                                  GetPluginDescriptionStatic(),
+                                  CreateInstance);
+}
+
+void
+DynamicLoaderPOSIXDYLD::Terminate()
+{
+}
+
+const char *
+DynamicLoaderPOSIXDYLD::GetPluginName()
+{
+    return "DynamicLoaderPOSIXDYLD";
+}
+
+const char *
+DynamicLoaderPOSIXDYLD::GetShortPluginName()
+{
+    return "linux-dyld";
+}
+
+const char *
+DynamicLoaderPOSIXDYLD::GetPluginNameStatic()
+{
+    return "dynamic-loader.linux-dyld";
+}
+
+const char *
+DynamicLoaderPOSIXDYLD::GetPluginDescriptionStatic()
+{
+    return "Dynamic loader plug-in that watches for shared library "
+           "loads/unloads in POSIX processes.";
+}
+
+void
+DynamicLoaderPOSIXDYLD::GetPluginCommandHelp(const char *command, Stream *strm)
+{
+}
+
+uint32_t
+DynamicLoaderPOSIXDYLD::GetPluginVersion()
+{
+    return 1;
+}
+
+DynamicLoader *
+DynamicLoaderPOSIXDYLD::CreateInstance(Process *process, bool force)
+{
+    bool create = force;
+    if (!create)
+    {
+        const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
+        if (triple_ref.getOS() == llvm::Triple::Linux ||
+            triple_ref.getOS() == llvm::Triple::FreeBSD)
+            create = true;
+    }
+    
+    if (create)
+        return new DynamicLoaderPOSIXDYLD (process);
+    return NULL;
+}
+
+DynamicLoaderPOSIXDYLD::DynamicLoaderPOSIXDYLD(Process *process)
+    : DynamicLoader(process),
+      m_rendezvous(process),
+      m_load_offset(LLDB_INVALID_ADDRESS),
+      m_entry_point(LLDB_INVALID_ADDRESS),
+      m_auxv(NULL)
+{
+}
+
+DynamicLoaderPOSIXDYLD::~DynamicLoaderPOSIXDYLD()
+{
+}
+
+void
+DynamicLoaderPOSIXDYLD::DidAttach()
+{
+    ModuleSP executable;
+    addr_t load_offset;
+
+    m_auxv.reset(new AuxVector(m_process));
+
+    executable = m_process->GetTarget().GetExecutableModule();
+    load_offset = ComputeLoadOffset();
+
+    if (executable.get() && load_offset != LLDB_INVALID_ADDRESS)
+    {
+        ModuleList module_list;
+        module_list.Append(executable);
+        UpdateLoadedSections(executable, load_offset);
+        LoadAllCurrentModules();
+        m_process->GetTarget().ModulesDidLoad(module_list);
+    }
+}
+
+void
+DynamicLoaderPOSIXDYLD::DidLaunch()
+{
+    ModuleSP executable;
+    addr_t load_offset;
+
+    m_auxv.reset(new AuxVector(m_process));
+
+    executable = m_process->GetTarget().GetExecutableModule();
+    load_offset = ComputeLoadOffset();
+
+    if (executable.get() && load_offset != LLDB_INVALID_ADDRESS)
+    {
+        ModuleList module_list;
+        module_list.Append(executable);
+        UpdateLoadedSections(executable, load_offset);
+        ProbeEntry();
+        m_process->GetTarget().ModulesDidLoad(module_list);
+    }
+}
+
+Error
+DynamicLoaderPOSIXDYLD::ExecutePluginCommand(Args &command, Stream *strm)
+{
+    return Error();
+}
+
+Log *
+DynamicLoaderPOSIXDYLD::EnablePluginLogging(Stream *strm, Args &command)
+{
+    return NULL;
+}
+
+Error
+DynamicLoaderPOSIXDYLD::CanLoadImage()
+{
+    return Error();
+}
+
+void
+DynamicLoaderPOSIXDYLD::UpdateLoadedSections(ModuleSP module, addr_t base_addr)
+{
+    ObjectFile *obj_file = module->GetObjectFile();
+    SectionList *sections = obj_file->GetSectionList();
+    SectionLoadList &load_list = m_process->GetTarget().GetSectionLoadList();
+    const size_t num_sections = sections->GetSize();
+
+    for (unsigned i = 0; i < num_sections; ++i)
+    {
+        Section *section = sections->GetSectionAtIndex(i).get();
+        lldb::addr_t new_load_addr = section->GetFileAddress() + base_addr;
+        lldb::addr_t old_load_addr = load_list.GetSectionLoadAddress(section);
+
+        // If the file address of the section is zero then this is not an
+        // allocatable/loadable section (property of ELF sh_addr).  Skip it.
+        if (new_load_addr == base_addr)
+            continue;
+
+        if (old_load_addr == LLDB_INVALID_ADDRESS ||
+            old_load_addr != new_load_addr)
+            load_list.SetSectionLoadAddress(section, new_load_addr);
+    }
+}
+
+void
+DynamicLoaderPOSIXDYLD::ProbeEntry()
+{
+    Breakpoint *entry_break;
+    addr_t entry;
+
+    if ((entry = GetEntryPoint()) == LLDB_INVALID_ADDRESS)
+        return;
+    
+    entry_break = m_process->GetTarget().CreateBreakpoint(entry, true).get();
+    entry_break->SetCallback(EntryBreakpointHit, this, true);
+}
+
+// The runtime linker has run and initialized the rendezvous structure once the
+// process has hit its entry point.  When we hit the corresponding breakpoint we
+// interrogate the rendezvous structure to get the load addresses of all
+// dependent modules for the process.  Similarly, we can discover the runtime
+// linker function and setup a breakpoint to notify us of any dynamically loaded
+// modules (via dlopen).
+bool
+DynamicLoaderPOSIXDYLD::EntryBreakpointHit(void *baton, 
+                                           StoppointCallbackContext *context, 
+                                           user_id_t break_id, 
+                                           user_id_t break_loc_id)
+{
+    DynamicLoaderPOSIXDYLD* dyld_instance;
+
+    dyld_instance = static_cast<DynamicLoaderPOSIXDYLD*>(baton);
+    dyld_instance->LoadAllCurrentModules();
+    dyld_instance->SetRendezvousBreakpoint();
+    return false; // Continue running.
+}
+
+void
+DynamicLoaderPOSIXDYLD::SetRendezvousBreakpoint()
+{
+    Breakpoint *dyld_break;
+    addr_t break_addr;
+
+    break_addr = m_rendezvous.GetBreakAddress();
+    dyld_break = m_process->GetTarget().CreateBreakpoint(break_addr, true).get();
+    dyld_break->SetCallback(RendezvousBreakpointHit, this, true);
+}
+
+bool
+DynamicLoaderPOSIXDYLD::RendezvousBreakpointHit(void *baton, 
+                                                StoppointCallbackContext *context, 
+                                                user_id_t break_id, 
+                                                user_id_t break_loc_id)
+{
+    DynamicLoaderPOSIXDYLD* dyld_instance;
+
+    dyld_instance = static_cast<DynamicLoaderPOSIXDYLD*>(baton);
+    dyld_instance->RefreshModules();
+
+    // Return true to stop the target, false to just let the target run.
+    return dyld_instance->GetStopWhenImagesChange();
+}
+
+void
+DynamicLoaderPOSIXDYLD::RefreshModules()
+{
+    if (!m_rendezvous.Resolve())
+        return;
+
+    DYLDRendezvous::iterator I;
+    DYLDRendezvous::iterator E;
+
+    ModuleList &loaded_modules = m_process->GetTarget().GetImages();
+
+    if (m_rendezvous.ModulesDidLoad()) 
+    {
+        ModuleList new_modules;
+
+        E = m_rendezvous.loaded_end();
+        for (I = m_rendezvous.loaded_begin(); I != E; ++I)
+        {
+            FileSpec file(I->path.c_str(), true);
+            ModuleSP module_sp = LoadModuleAtAddress(file, I->base_addr);
+            if (module_sp.get())
+                new_modules.Append(module_sp);
+        }
+        m_process->GetTarget().ModulesDidLoad(new_modules);
+    }
+    
+    if (m_rendezvous.ModulesDidUnload())
+    {
+        ModuleList old_modules;
+
+        E = m_rendezvous.unloaded_end();
+        for (I = m_rendezvous.unloaded_begin(); I != E; ++I)
+        {
+            FileSpec file(I->path.c_str(), true);
+            ModuleSP module_sp = 
+                loaded_modules.FindFirstModuleForFileSpec(file, NULL, NULL);
+            if (module_sp.get())
+                old_modules.Append(module_sp);
+        }
+        m_process->GetTarget().ModulesDidUnload(old_modules);
+    }
+}
+
+ThreadPlanSP
+DynamicLoaderPOSIXDYLD::GetStepThroughTrampolinePlan(Thread &thread, bool stop)
+{
+    LogSP log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+    ThreadPlanSP thread_plan_sp;
+
+    StackFrame *frame = thread.GetStackFrameAtIndex(0).get();
+    const SymbolContext &context = frame->GetSymbolContext(eSymbolContextSymbol);
+    Symbol *sym = context.symbol;
+
+    if (sym == NULL || !sym->IsTrampoline())
+        return thread_plan_sp;
+
+    const ConstString &sym_name = sym->GetMangled().GetName(Mangled::ePreferMangled);
+    if (!sym_name)
+        return thread_plan_sp;
+
+    SymbolContextList target_symbols;
+    Target &target = thread.GetProcess().GetTarget();
+    ModuleList &images = target.GetImages();
+
+    images.FindSymbolsWithNameAndType(sym_name, eSymbolTypeCode, target_symbols);
+    size_t num_targets = target_symbols.GetSize();
+    if (!num_targets)
+        return thread_plan_sp;
+
+    typedef std::vector<lldb::addr_t> AddressVector;
+    AddressVector addrs;
+    for (size_t i = 0; i < num_targets; ++i)
+    {
+        SymbolContext context;
+        AddressRange range;
+        if (target_symbols.GetContextAtIndex(i, context))
+        {
+            context.GetAddressRange(eSymbolContextEverything, 0, false, range);
+            lldb::addr_t addr = range.GetBaseAddress().GetLoadAddress(&target);
+            if (addr != LLDB_INVALID_ADDRESS)
+                addrs.push_back(addr);
+        }
+    }
+
+    if (addrs.size() > 0) 
+    {
+        AddressVector::iterator start = addrs.begin();
+        AddressVector::iterator end = addrs.end();
+
+        std::sort(start, end);
+        addrs.erase(std::unique(start, end), end);
+        thread_plan_sp.reset(new ThreadPlanRunToAddress(thread, addrs, stop));
+    }
+
+    return thread_plan_sp;
+}
+
+void
+DynamicLoaderPOSIXDYLD::LoadAllCurrentModules()
+{
+    DYLDRendezvous::iterator I;
+    DYLDRendezvous::iterator E;
+    ModuleList module_list;
+    
+    if (!m_rendezvous.Resolve())
+        return;
+
+    for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I)
+    {
+        FileSpec file(I->path.c_str(), false);
+        ModuleSP module_sp = LoadModuleAtAddress(file, I->base_addr);
+        if (module_sp.get())
+            module_list.Append(module_sp);
+    }
+
+    m_process->GetTarget().ModulesDidLoad(module_list);
+}
+
+ModuleSP
+DynamicLoaderPOSIXDYLD::LoadModuleAtAddress(const FileSpec &file, addr_t base_addr)
+{
+    Target &target = m_process->GetTarget();
+    ModuleList &modules = target.GetImages();
+    ModuleSP module_sp;
+
+    if ((module_sp = modules.FindFirstModuleForFileSpec(file, NULL, NULL))) 
+    {
+        UpdateLoadedSections(module_sp, base_addr);
+    }
+    else if ((module_sp = target.GetSharedModule(file, target.GetArchitecture()))) 
+    {
+        UpdateLoadedSections(module_sp, base_addr);
+        modules.Append(module_sp);
+    }
+
+    return module_sp;
+}
+
+addr_t
+DynamicLoaderPOSIXDYLD::ComputeLoadOffset()
+{
+    addr_t virt_entry;
+
+    if (m_load_offset != LLDB_INVALID_ADDRESS)
+        return m_load_offset;
+
+    if ((virt_entry = GetEntryPoint()) == LLDB_INVALID_ADDRESS)
+        return LLDB_INVALID_ADDRESS;
+
+    ModuleSP module = m_process->GetTarget().GetExecutableModule();
+    ObjectFile *exe = module->GetObjectFile();
+    Address file_entry = exe->GetEntryPointAddress();
+
+    if (!file_entry.IsValid())
+        return LLDB_INVALID_ADDRESS;
+            
+    m_load_offset = virt_entry - file_entry.GetFileAddress();
+    return m_load_offset;
+}
+
+addr_t
+DynamicLoaderPOSIXDYLD::GetEntryPoint()
+{
+    if (m_entry_point != LLDB_INVALID_ADDRESS)
+        return m_entry_point;
+
+    if (m_auxv.get() == NULL)
+        return LLDB_INVALID_ADDRESS;
+
+    AuxVector::iterator I = m_auxv->FindEntry(AuxVector::AT_ENTRY);
+
+    if (I == m_auxv->end())
+        return LLDB_INVALID_ADDRESS;
+
+    m_entry_point = static_cast<addr_t>(I->value);
+    return m_entry_point;
+}
diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h
new file mode 100644
index 0000000..8cca6ee
--- /dev/null
+++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h
@@ -0,0 +1,165 @@
+//===-- DynamicLoaderPOSIX.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_DynamicLoaderPOSIX_H_
+#define liblldb_DynamicLoaderPOSIX_H_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+#include "lldb/Breakpoint/StoppointCallbackContext.h"
+#include "lldb/Target/DynamicLoader.h"
+
+#include "DYLDRendezvous.h"
+
+class AuxVector;
+
+class DynamicLoaderPOSIXDYLD : public lldb_private::DynamicLoader
+{
+public:
+
+    static void
+    Initialize();
+
+    static void
+    Terminate();
+
+    static const char *
+    GetPluginNameStatic();
+
+    static const char *
+    GetPluginDescriptionStatic();
+
+    static lldb_private::DynamicLoader *
+    CreateInstance(lldb_private::Process *process, bool force);
+
+    DynamicLoaderPOSIXDYLD(lldb_private::Process *process);
+
+    virtual
+    ~DynamicLoaderPOSIXDYLD();
+
+    //------------------------------------------------------------------
+    // DynamicLoader protocol
+    //------------------------------------------------------------------
+
+    virtual void
+    DidAttach();
+
+    virtual void
+    DidLaunch();
+
+    virtual lldb::ThreadPlanSP
+    GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
+                                 bool stop_others);
+
+    virtual lldb_private::Error
+    CanLoadImage();
+
+    //------------------------------------------------------------------
+    // PluginInterface protocol
+    //------------------------------------------------------------------
+    virtual const char *
+    GetPluginName();
+
+    virtual const char *
+    GetShortPluginName();
+
+    virtual uint32_t
+    GetPluginVersion();
+
+    virtual void
+    GetPluginCommandHelp(const char *command, lldb_private::Stream *strm);
+
+    virtual lldb_private::Error
+    ExecutePluginCommand(lldb_private::Args &command, lldb_private::Stream *strm);
+
+    virtual lldb_private::Log *
+    EnablePluginLogging(lldb_private::Stream *strm, lldb_private::Args &command);
+
+protected:
+    /// Runtime linker rendezvous structure.
+    DYLDRendezvous m_rendezvous;
+
+    /// Virtual load address of the inferior process.
+    lldb::addr_t m_load_offset;
+
+    /// Virtual entry address of the inferior process.
+    lldb::addr_t m_entry_point;
+
+    /// Auxiliary vector of the inferior process.
+    std::auto_ptr<AuxVector> m_auxv;
+
+    /// Enables a breakpoint on a function called by the runtime
+    /// linker each time a module is loaded or unloaded.
+    void
+    SetRendezvousBreakpoint();
+
+    /// Callback routine which updates the current list of loaded modules based
+    /// on the information supplied by the runtime linker.
+    static bool
+    RendezvousBreakpointHit(void *baton, 
+                            lldb_private::StoppointCallbackContext *context, 
+                            lldb::user_id_t break_id, 
+                            lldb::user_id_t break_loc_id);
+    
+    /// Helper method for RendezvousBreakpointHit.  Updates LLDB's current set
+    /// of loaded modules.
+    void
+    RefreshModules();
+
+    /// Updates the load address of every allocatable section in @p module.
+    ///
+    /// @param module The module to traverse.
+    ///
+    /// @param base_addr The virtual base address @p module is loaded at.
+    void
+    UpdateLoadedSections(lldb::ModuleSP module, 
+                         lldb::addr_t base_addr = 0);
+
+    /// Locates or creates a module given by @p file and updates/loads the
+    /// resulting module at the virtual base address @p base_addr.
+    lldb::ModuleSP
+    LoadModuleAtAddress(const lldb_private::FileSpec &file, lldb::addr_t base_addr);
+
+    /// Resolves the entry point for the current inferior process and sets a
+    /// breakpoint at that address.
+    void
+    ProbeEntry();
+
+    /// Callback routine invoked when we hit the breakpoint on process entry.
+    ///
+    /// This routine is responsible for resolving the load addresses of all
+    /// dependent modules required by the inferior and setting up the rendezvous
+    /// breakpoint.
+    static bool
+    EntryBreakpointHit(void *baton, 
+                       lldb_private::StoppointCallbackContext *context, 
+                       lldb::user_id_t break_id, 
+                       lldb::user_id_t break_loc_id);
+
+    /// Helper for the entry breakpoint callback.  Resolves the load addresses
+    /// of all dependent modules.
+    void
+    LoadAllCurrentModules();
+
+    /// Computes a value for m_load_offset returning the computed address on
+    /// success and LLDB_INVALID_ADDRESS on failure.
+    lldb::addr_t
+    ComputeLoadOffset();
+
+    /// Computes a value for m_entry_point returning the computed address on
+    /// success and LLDB_INVALID_ADDRESS on failure.
+    lldb::addr_t
+    GetEntryPoint();
+
+private:
+    DISALLOW_COPY_AND_ASSIGN(DynamicLoaderPOSIXDYLD);
+};
+
+#endif  // liblldb_DynamicLoaderPOSIXDYLD_H_
diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/Makefile b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/Makefile
new file mode 100644
index 0000000..70ea1f3
--- /dev/null
+++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/Makefile
@@ -0,0 +1,14 @@
+##===- source/Plugins/DynamicLoader/POSIX-DYLD/Makefile ----*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+
+LLDB_LEVEL := ../../../..
+LIBRARYNAME := lldbPluginDynamicLoaderPOSIX
+BUILD_ARCHIVE = 1
+
+include $(LLDB_LEVEL)/Makefile