forked from OSchip/llvm-project
228 lines
7.1 KiB
C++
228 lines
7.1 KiB
C++
//===-- 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
|