summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/DynamicLoader
diff options
context:
space:
mode:
authorJohnny Chen <johnny.chen@apple.com>2012-01-05 19:17:38 +0000
committerJohnny Chen <johnny.chen@apple.com>2012-01-05 19:17:38 +0000
commit30213ffc28b97229c0d06b1332eaced3deba62d7 (patch)
tree32b27820081f772dedf9dcec828ab8aef3406c96 /lldb/source/Plugins/DynamicLoader
parent99ab273a778d4836981f71dd7c947785dc3816b8 (diff)
downloadbcm5719-llvm-30213ffc28b97229c0d06b1332eaced3deba62d7.tar.gz
bcm5719-llvm-30213ffc28b97229c0d06b1332eaced3deba62d7.zip
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: 147609
Diffstat (limited to 'lldb/source/Plugins/DynamicLoader')
-rw-r--r--lldb/source/Plugins/DynamicLoader/Linux-DYLD/AuxVector.cpp191
-rw-r--r--lldb/source/Plugins/DynamicLoader/Linux-DYLD/AuxVector.h97
-rw-r--r--lldb/source/Plugins/DynamicLoader/Linux-DYLD/DYLDRendezvous.cpp322
-rw-r--r--lldb/source/Plugins/DynamicLoader/Linux-DYLD/DYLDRendezvous.h227
-rw-r--r--lldb/source/Plugins/DynamicLoader/Linux-DYLD/DynamicLoaderLinuxDYLD.cpp423
-rw-r--r--lldb/source/Plugins/DynamicLoader/Linux-DYLD/DynamicLoaderLinuxDYLD.h165
-rw-r--r--lldb/source/Plugins/DynamicLoader/Linux-DYLD/Makefile14
7 files changed, 0 insertions, 1439 deletions
diff --git a/lldb/source/Plugins/DynamicLoader/Linux-DYLD/AuxVector.cpp b/lldb/source/Plugins/DynamicLoader/Linux-DYLD/AuxVector.cpp
index 6954e4cac4d..e69de29bb2d 100644
--- a/lldb/source/Plugins/DynamicLoader/Linux-DYLD/AuxVector.cpp
+++ b/lldb/source/Plugins/DynamicLoader/Linux-DYLD/AuxVector.cpp
@@ -1,191 +0,0 @@
-//===-- 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()
-{
- static const size_t path_size = 128;
- static char path[path_size];
- DataBufferSP buf_sp;
- int fd;
-
- // Ideally, we would simply create a FileSpec and call ReadFileContents.
- // However, files in procfs have zero size (since they are, in general,
- // dynamically generated by the kernel) which is incompatible with the
- // current ReadFileContents implementation. Therefore we simply stream the
- // data into a DataBuffer ourselves.
- if (snprintf(path, path_size, "/proc/%d/auxv", m_process->GetID()) < 0)
- return buf_sp;
-
- if ((fd = open(path, O_RDONLY, 0)) < 0)
- return buf_sp;
-
- size_t bytes_read = 0;
- std::auto_ptr<DataBufferHeap> buf_ap(new DataBufferHeap(1024, 0));
- for (;;)
- {
- size_t avail = buf_ap->GetByteSize() - bytes_read;
- ssize_t status = read(fd, buf_ap->GetBytes() + bytes_read, avail);
-
- if (status < 0)
- break;
-
- bytes_read += status;
-
- if (status == 0)
- {
- buf_ap->SetByteSize(bytes_read);
- buf_sp.reset(buf_ap.release());
- break;
- }
-
- if (avail - status == 0)
- buf_ap->SetByteSize(2 * buf_ap->GetByteSize());
- }
-
- return buf_sp;
-}
-
-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/Linux-DYLD/AuxVector.h b/lldb/source/Plugins/DynamicLoader/Linux-DYLD/AuxVector.h
index 7a5b3700fce..e69de29bb2d 100644
--- a/lldb/source/Plugins/DynamicLoader/Linux-DYLD/AuxVector.h
+++ b/lldb/source/Plugins/DynamicLoader/Linux-DYLD/AuxVector.h
@@ -1,97 +0,0 @@
-//===-- 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/Linux-DYLD/DYLDRendezvous.cpp b/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DYLDRendezvous.cpp
index f10aedb63de..e69de29bb2d 100644
--- a/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DYLDRendezvous.cpp
+++ b/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DYLDRendezvous.cpp
@@ -1,322 +0,0 @@
-//===-- 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()
-{
-}
-
-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;
-
- if (entry.path.empty())
- 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;
-
- if (entry.path.empty())
- 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/Linux-DYLD/DYLDRendezvous.h b/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DYLDRendezvous.h
index e8052ae5b3e..e69de29bb2d 100644
--- a/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DYLDRendezvous.h
+++ b/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DYLDRendezvous.h
@@ -1,227 +0,0 @@
-//===-- 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;
-
- /// 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/Linux-DYLD/DynamicLoaderLinuxDYLD.cpp b/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DynamicLoaderLinuxDYLD.cpp
index caad7a01f9a..e69de29bb2d 100644
--- a/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DynamicLoaderLinuxDYLD.cpp
+++ b/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DynamicLoaderLinuxDYLD.cpp
@@ -1,423 +0,0 @@
-//===-- DynamicLoaderLinux.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 "DynamicLoaderLinuxDYLD.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-void
-DynamicLoaderLinuxDYLD::Initialize()
-{
- PluginManager::RegisterPlugin(GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance);
-}
-
-void
-DynamicLoaderLinuxDYLD::Terminate()
-{
-}
-
-const char *
-DynamicLoaderLinuxDYLD::GetPluginName()
-{
- return "DynamicLoaderLinuxDYLD";
-}
-
-const char *
-DynamicLoaderLinuxDYLD::GetShortPluginName()
-{
- return "linux-dyld";
-}
-
-const char *
-DynamicLoaderLinuxDYLD::GetPluginNameStatic()
-{
- return "dynamic-loader.linux-dyld";
-}
-
-const char *
-DynamicLoaderLinuxDYLD::GetPluginDescriptionStatic()
-{
- return "Dynamic loader plug-in that watches for shared library "
- "loads/unloads in Linux processes.";
-}
-
-void
-DynamicLoaderLinuxDYLD::GetPluginCommandHelp(const char *command, Stream *strm)
-{
-}
-
-uint32_t
-DynamicLoaderLinuxDYLD::GetPluginVersion()
-{
- return 1;
-}
-
-DynamicLoader *
-DynamicLoaderLinuxDYLD::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)
- create = true;
- }
-
- if (create)
- return new DynamicLoaderLinuxDYLD (process);
- return NULL;
-}
-
-DynamicLoaderLinuxDYLD::DynamicLoaderLinuxDYLD(Process *process)
- : DynamicLoader(process),
- m_rendezvous(process),
- m_load_offset(LLDB_INVALID_ADDRESS),
- m_entry_point(LLDB_INVALID_ADDRESS),
- m_auxv(NULL)
-{
-}
-
-DynamicLoaderLinuxDYLD::~DynamicLoaderLinuxDYLD()
-{
-}
-
-void
-DynamicLoaderLinuxDYLD::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);
- m_process->GetTarget().ModulesDidLoad(module_list);
- }
-}
-
-void
-DynamicLoaderLinuxDYLD::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
-DynamicLoaderLinuxDYLD::ExecutePluginCommand(Args &command, Stream *strm)
-{
- return Error();
-}
-
-Log *
-DynamicLoaderLinuxDYLD::EnablePluginLogging(Stream *strm, Args &command)
-{
- return NULL;
-}
-
-Error
-DynamicLoaderLinuxDYLD::CanLoadImage()
-{
- return Error();
-}
-
-void
-DynamicLoaderLinuxDYLD::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
-DynamicLoaderLinuxDYLD::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
-DynamicLoaderLinuxDYLD::EntryBreakpointHit(void *baton,
- StoppointCallbackContext *context,
- user_id_t break_id,
- user_id_t break_loc_id)
-{
- DynamicLoaderLinuxDYLD* dyld_instance;
-
- dyld_instance = static_cast<DynamicLoaderLinuxDYLD*>(baton);
- dyld_instance->LoadAllCurrentModules();
- dyld_instance->SetRendezvousBreakpoint();
- return false; // Continue running.
-}
-
-void
-DynamicLoaderLinuxDYLD::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
-DynamicLoaderLinuxDYLD::RendezvousBreakpointHit(void *baton,
- StoppointCallbackContext *context,
- user_id_t break_id,
- user_id_t break_loc_id)
-{
- DynamicLoaderLinuxDYLD* dyld_instance;
-
- dyld_instance = static_cast<DynamicLoaderLinuxDYLD*>(baton);
- dyld_instance->RefreshModules();
-
- // Return true to stop the target, false to just let the target run.
- return dyld_instance->GetStopWhenImagesChange();
-}
-
-void
-DynamicLoaderLinuxDYLD::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
-DynamicLoaderLinuxDYLD::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
-DynamicLoaderLinuxDYLD::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
-DynamicLoaderLinuxDYLD::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
-DynamicLoaderLinuxDYLD::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
-DynamicLoaderLinuxDYLD::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/Linux-DYLD/DynamicLoaderLinuxDYLD.h b/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DynamicLoaderLinuxDYLD.h
index bead75c76dd..e69de29bb2d 100644
--- a/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DynamicLoaderLinuxDYLD.h
+++ b/lldb/source/Plugins/DynamicLoader/Linux-DYLD/DynamicLoaderLinuxDYLD.h
@@ -1,165 +0,0 @@
-//===-- DynamicLoaderLinux.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_DynamicLoaderLinux_H_
-#define liblldb_DynamicLoaderLinux_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 DynamicLoaderLinuxDYLD : 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);
-
- DynamicLoaderLinuxDYLD(lldb_private::Process *process);
-
- virtual
- ~DynamicLoaderLinuxDYLD();
-
- //------------------------------------------------------------------
- // 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(DynamicLoaderLinuxDYLD);
-};
-
-#endif // liblldb_DynamicLoaderLinuxDYLD_H_
diff --git a/lldb/source/Plugins/DynamicLoader/Linux-DYLD/Makefile b/lldb/source/Plugins/DynamicLoader/Linux-DYLD/Makefile
index 94025dd3eba..e69de29bb2d 100644
--- a/lldb/source/Plugins/DynamicLoader/Linux-DYLD/Makefile
+++ b/lldb/source/Plugins/DynamicLoader/Linux-DYLD/Makefile
@@ -1,14 +0,0 @@
-##===- source/Plugins/DynamicLoader/Linux-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 := lldbPluginDynamicLoaderLinux
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
OpenPOWER on IntegriCloud