12341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen//===-- DYLDRendezvous.cpp --------------------------------------*- C++ -*-===//
22341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen//
32341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen//                     The LLVM Compiler Infrastructure
42341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen//
52341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen// This file is distributed under the University of Illinois Open Source
62341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen// License. See LICENSE.TXT for details.
72341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen//
82341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen//===----------------------------------------------------------------------===//
92341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
102341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen// C Includes
112341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen// C++ Includes
122341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen// Other libraries and framework includes
132341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen#include "lldb/Core/ArchSpec.h"
142341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen#include "lldb/Core/Error.h"
152341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen#include "lldb/Core/Log.h"
1649ce8969d3154e1560106cfe530444c09410f217Greg Clayton#include "lldb/Core/Module.h"
172341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen#include "lldb/Target/Process.h"
182341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen#include "lldb/Target/Target.h"
192341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
202341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen#include "DYLDRendezvous.h"
212341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
222341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chenusing namespace lldb;
232341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chenusing namespace lldb_private;
242341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
252341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen/// Locates the address of the rendezvous structure.  Returns the address on
262341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen/// success and LLDB_INVALID_ADDRESS on failure.
272341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chenstatic addr_t
282341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny ChenResolveRendezvousAddress(Process *process)
292341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen{
302341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    addr_t info_location;
312341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    addr_t info_addr;
322341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    Error error;
332341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    size_t size;
342341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
352341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    info_location = process->GetImageInfoAddress();
362341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
372341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    if (info_location == LLDB_INVALID_ADDRESS)
382341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        return LLDB_INVALID_ADDRESS;
392341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
402341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    info_addr = 0;
412341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    size = process->DoReadMemory(info_location, &info_addr,
422341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen                                 process->GetAddressByteSize(), error);
432341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    if (size != process->GetAddressByteSize() || error.Fail())
442341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        return LLDB_INVALID_ADDRESS;
452341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
462341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    if (info_addr == 0)
472341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        return LLDB_INVALID_ADDRESS;
482341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
492341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    return info_addr;
502341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen}
512341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
522341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny ChenDYLDRendezvous::DYLDRendezvous(Process *process)
532341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    : m_process(process),
542341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen      m_rendezvous_addr(LLDB_INVALID_ADDRESS),
552341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen      m_current(),
562341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen      m_previous(),
572341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen      m_soentries(),
582341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen      m_added_soentries(),
592341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen      m_removed_soentries()
602341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen{
612341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    // Cache a copy of the executable path
626c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    if (m_process)
636c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    {
646c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor        Module *exe_mod = m_process->GetTarget().GetExecutableModulePointer();
656c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor        if (exe_mod)
666c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor            exe_mod->GetFileSpec().GetPath(m_exe_path, PATH_MAX);
676c1a8cfbb81ae38aee68f281b2af4010044cc00dAndrew Kaylor    }
682341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen}
692341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
702341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chenbool
712341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny ChenDYLDRendezvous::Resolve()
722341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen{
732341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    const size_t word_size = 4;
742341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    Rendezvous info;
752341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    size_t address_size;
762341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    size_t padding;
772341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    addr_t info_addr;
782341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    addr_t cursor;
792341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
802341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    address_size = m_process->GetAddressByteSize();
812341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    padding = address_size - word_size;
822341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
832341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    if (m_rendezvous_addr == LLDB_INVALID_ADDRESS)
842341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        cursor = info_addr = ResolveRendezvousAddress(m_process);
852341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    else
862341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        cursor = info_addr = m_rendezvous_addr;
872341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
882341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    if (cursor == LLDB_INVALID_ADDRESS)
892341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        return false;
902341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
912341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    if (!(cursor = ReadMemory(cursor, &info.version, word_size)))
922341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        return false;
932341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
942341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    if (!(cursor = ReadMemory(cursor + padding, &info.map_addr, address_size)))
952341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        return false;
962341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
972341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    if (!(cursor = ReadMemory(cursor, &info.brk, address_size)))
982341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        return false;
992341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
1002341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    if (!(cursor = ReadMemory(cursor, &info.state, word_size)))
1012341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        return false;
1022341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
1032341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    if (!(cursor = ReadMemory(cursor + padding, &info.ldbase, address_size)))
1042341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        return false;
1052341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
1062341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    // The rendezvous was successfully read.  Update our internal state.
1072341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    m_rendezvous_addr = info_addr;
1082341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    m_previous = m_current;
1092341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    m_current = info;
1102341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
1112341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    return UpdateSOEntries();
1122341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen}
1132341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
1142341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chenbool
1152341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny ChenDYLDRendezvous::IsValid()
1162341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen{
1172341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    return m_rendezvous_addr != LLDB_INVALID_ADDRESS;
1182341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen}
1192341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
1202341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chenbool
1212341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny ChenDYLDRendezvous::UpdateSOEntries()
1222341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen{
1232341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    SOEntry entry;
1242341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
1252341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    if (m_current.map_addr == 0)
1262341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        return false;
1272341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
1282341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    // When the previous and current states are consistent this is the first
1292341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    // time we have been asked to update.  Just take a snapshot of the currently
1302341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    // loaded modules.
1312341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    if (m_previous.state == eConsistent && m_current.state == eConsistent)
1322341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        return TakeSnapshot(m_soentries);
1332341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
1342341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    // If we are about to add or remove a shared object clear out the current
1352341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    // state and take a snapshot of the currently loaded images.
1362341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    if (m_current.state == eAdd || m_current.state == eDelete)
1372341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    {
1382341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        assert(m_previous.state == eConsistent);
1392341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        m_soentries.clear();
1402341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        m_added_soentries.clear();
1412341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        m_removed_soentries.clear();
1422341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        return TakeSnapshot(m_soentries);
1432341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    }
1442341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    assert(m_current.state == eConsistent);
1452341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
1462341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    // Otherwise check the previous state to determine what to expect and update
1472341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    // accordingly.
1482341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    if (m_previous.state == eAdd)
1492341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        return UpdateSOEntriesForAddition();
1502341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    else if (m_previous.state == eDelete)
1512341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        return UpdateSOEntriesForDeletion();
1522341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
1532341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    return false;
1542341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen}
1552341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
1562341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chenbool
1572341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny ChenDYLDRendezvous::UpdateSOEntriesForAddition()
1582341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen{
1592341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    SOEntry entry;
1602341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    iterator pos;
1612341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
1622341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    assert(m_previous.state == eAdd);
1632341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
1642341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    if (m_current.map_addr == 0)
1652341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        return false;
1662341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
1672341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    for (addr_t cursor = m_current.map_addr; cursor != 0; cursor = entry.next)
1682341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    {
1692341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        if (!ReadSOEntryFromMemory(cursor, entry))
1702341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen            return false;
1712341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
1722341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        // Only add shared libraries and not the executable.
1732341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        // On Linux this is indicated by an empty path in the entry.
1742341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        // On FreeBSD it is the name of the executable.
1752341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        if (entry.path.empty() || ::strcmp(entry.path.c_str(), m_exe_path) == 0)
1762341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen            continue;
1772341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
1782341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        pos = std::find(m_soentries.begin(), m_soentries.end(), entry);
1792341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        if (pos == m_soentries.end())
1802341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        {
1812341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen            m_soentries.push_back(entry);
1822341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen            m_added_soentries.push_back(entry);
1832341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        }
1842341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    }
1852341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
1862341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    return true;
1872341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen}
1882341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
1892341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chenbool
1902341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny ChenDYLDRendezvous::UpdateSOEntriesForDeletion()
1912341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen{
1922341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    SOEntryList entry_list;
1932341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    iterator pos;
1942341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
1952341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    assert(m_previous.state == eDelete);
1962341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
1972341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    if (!TakeSnapshot(entry_list))
1982341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        return false;
1992341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
2002341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    for (iterator I = begin(); I != end(); ++I)
2012341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    {
2022341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        pos = std::find(entry_list.begin(), entry_list.end(), *I);
2032341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        if (pos == entry_list.end())
2042341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen            m_removed_soentries.push_back(*I);
2052341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    }
2062341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
2072341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    m_soentries = entry_list;
2082341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    return true;
2092341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen}
2102341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
2112341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chenbool
2122341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny ChenDYLDRendezvous::TakeSnapshot(SOEntryList &entry_list)
2132341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen{
2142341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    SOEntry entry;
2152341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
2162341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    if (m_current.map_addr == 0)
2172341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        return false;
2182341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
2192341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    for (addr_t cursor = m_current.map_addr; cursor != 0; cursor = entry.next)
2202341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    {
2212341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        if (!ReadSOEntryFromMemory(cursor, entry))
2222341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen            return false;
2232341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
2242341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        // Only add shared libraries and not the executable.
2252341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        // On Linux this is indicated by an empty path in the entry.
2262341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        // On FreeBSD it is the name of the executable.
2272341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        if (entry.path.empty() || ::strcmp(entry.path.c_str(), m_exe_path) == 0)
2282341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen            continue;
2292341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
2302341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        entry_list.push_back(entry);
2312341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    }
2322341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
2332341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    return true;
2342341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen}
2352341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
2362341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chenaddr_t
2372341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny ChenDYLDRendezvous::ReadMemory(addr_t addr, void *dst, size_t size)
2382341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen{
2392341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    size_t bytes_read;
2402341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    Error error;
2412341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
2422341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    bytes_read = m_process->DoReadMemory(addr, dst, size, error);
2432341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    if (bytes_read != size || error.Fail())
2442341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        return 0;
2452341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
2462341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    return addr + bytes_read;
2472341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen}
2482341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
2492341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chenstd::string
2502341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny ChenDYLDRendezvous::ReadStringFromMemory(addr_t addr)
2512341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen{
2522341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    std::string str;
2532341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    Error error;
2542341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    size_t size;
2552341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    char c;
2562341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
2572341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    if (addr == LLDB_INVALID_ADDRESS)
2582341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        return std::string();
2592341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
2602341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    for (;;) {
2612341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        size = m_process->DoReadMemory(addr, &c, 1, error);
2622341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        if (size != 1 || error.Fail())
2632341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen            return std::string();
2642341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        if (c == 0)
2652341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen            break;
2662341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        else {
2672341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen            str.push_back(c);
2682341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen            addr++;
2692341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        }
2702341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    }
2712341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
2722341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    return str;
2732341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen}
2742341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
2752341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chenbool
2762341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny ChenDYLDRendezvous::ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry)
2772341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen{
2782341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    size_t address_size = m_process->GetAddressByteSize();
2792341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
2802341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    entry.clear();
2812341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
2822341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    if (!(addr = ReadMemory(addr, &entry.base_addr, address_size)))
2832341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        return false;
2842341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
2852341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    if (!(addr = ReadMemory(addr, &entry.path_addr, address_size)))
2862341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        return false;
2872341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
2882341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    if (!(addr = ReadMemory(addr, &entry.dyn_addr, address_size)))
2892341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        return false;
2902341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
2912341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    if (!(addr = ReadMemory(addr, &entry.next, address_size)))
2922341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        return false;
2932341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
2942341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    if (!(addr = ReadMemory(addr, &entry.prev, address_size)))
2952341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        return false;
2962341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
2972341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    entry.path = ReadStringFromMemory(entry.path_addr);
2982341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
2992341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    return true;
3002341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen}
3012341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
3022341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chenvoid
303952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg ClaytonDYLDRendezvous::DumpToLog(Log *log) const
3042341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen{
3052341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    int state = GetState();
3062341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
3072341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    if (!log)
3082341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        return;
3092341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
3102341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    log->PutCString("DYLDRendezvous:");
3115f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea    log->Printf("   Address: %" PRIx64, GetRendezvousAddress());
31236da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton    log->Printf("   Version: %" PRIu64, GetVersion());
3135f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea    log->Printf("   Link   : %" PRIx64, GetLinkMapAddress());
3145f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea    log->Printf("   Break  : %" PRIx64, GetBreakAddress());
3155f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea    log->Printf("   LDBase : %" PRIx64, GetLDBase());
3162341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    log->Printf("   State  : %s",
3172341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen                (state == eConsistent) ? "consistent" :
3182341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen                (state == eAdd)        ? "add"        :
3192341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen                (state == eDelete)     ? "delete"     : "unknown");
3202341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
3212341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    iterator I = begin();
3222341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    iterator E = end();
3232341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
3242341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    if (I != E)
3252341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        log->PutCString("DYLDRendezvous SOEntries:");
3262341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen
3272341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    for (int i = 1; I != E; ++I, ++i)
3282341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    {
3292341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen        log->Printf("\n   SOEntry [%d] %s", i, I->path.c_str());
3305f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea        log->Printf("      Base : %" PRIx64, I->base_addr);
3315f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea        log->Printf("      Path : %" PRIx64, I->path_addr);
3325f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea        log->Printf("      Dyn  : %" PRIx64, I->dyn_addr);
3335f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea        log->Printf("      Next : %" PRIx64, I->next);
3345f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea        log->Printf("      Prev : %" PRIx64, I->prev);
3352341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen    }
3362341d35bc77ffa8597a85b1ffe50b5653a2ec46dJohnny Chen}
337