Path: blob/main/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h
39654 views
//===-- HexagonDYLDRendezvous.h ---------------------------------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#ifndef LLDB_SOURCE_PLUGINS_DYNAMICLOADER_HEXAGON_DYLD_HEXAGONDYLDRENDEZVOUS_H9#define LLDB_SOURCE_PLUGINS_DYNAMICLOADER_HEXAGON_DYLD_HEXAGONDYLDRENDEZVOUS_H1011#include <limits.h>12#include <list>13#include <map>14#include <string>1516#include "lldb/lldb-defines.h"17#include "lldb/lldb-types.h"1819namespace lldb_private {20class Process;21}2223/// \class HexagonDYLDRendezvous24/// Interface to the runtime linker.25///26/// A structure is present in a processes memory space which is updated by the27/// runtime liker each time a module is loaded or unloaded. This class28/// provides an interface to this structure and maintains a consistent29/// snapshot of the currently loaded modules.30class HexagonDYLDRendezvous {3132// This structure is used to hold the contents of the debug rendezvous33// information (struct r_debug) as found in the inferiors memory. Note that34// the layout of this struct is not binary compatible, it is simply large35// enough to hold the information on both 32 and 64 bit platforms.36struct Rendezvous {37uint64_t version = 0;38lldb::addr_t map_addr = LLDB_INVALID_ADDRESS;39lldb::addr_t brk = LLDB_INVALID_ADDRESS;40uint64_t state = 0;41lldb::addr_t ldbase = 0;4243Rendezvous() = default;44};4546public:47// Various metadata supplied by the inferior's threading library to describe48// the per-thread state.49struct ThreadInfo {50bool valid; // whether we read valid metadata51uint32_t dtv_offset; // offset of DTV pointer within pthread52uint32_t dtv_slot_size; // size of one DTV slot53uint32_t modid_offset; // offset of module ID within link_map54uint32_t tls_offset; // offset of TLS pointer within DTV slot55};5657HexagonDYLDRendezvous(lldb_private::Process *process);5859/// Update the internal snapshot of runtime linker rendezvous and recompute60/// the currently loaded modules.61///62/// This method should be called once one start up, then once each time the63/// runtime linker enters the function given by GetBreakAddress().64///65/// \returns true on success and false on failure.66///67/// \see GetBreakAddress().68bool Resolve();6970/// \returns true if this rendezvous has been located in the inferiors71/// address space and false otherwise.72bool IsValid();7374/// \returns the address of the rendezvous structure in the inferiors75/// address space.76lldb::addr_t GetRendezvousAddress() const { return m_rendezvous_addr; }7778/// Provide the dyld structure address79void SetRendezvousAddress(lldb::addr_t);8081/// \returns the version of the rendezvous protocol being used.82uint64_t GetVersion() const { return m_current.version; }8384/// \returns address in the inferiors address space containing the linked85/// list of shared object descriptors.86lldb::addr_t GetLinkMapAddress() const { return m_current.map_addr; }8788/// A breakpoint should be set at this address and Resolve called on each89/// hit.90///91/// \returns the address of a function called by the runtime linker each92/// time a module is loaded/unloaded, or about to be loaded/unloaded.93///94/// \see Resolve()95lldb::addr_t GetBreakAddress() const { return m_current.brk; }9697/// In hexagon it is possible that we can know the dyld breakpoint without98/// having to find it from the rendezvous structure99///100void SetBreakAddress(lldb::addr_t addr) { m_current.brk = addr; }101102/// Returns the current state of the rendezvous structure.103uint64_t GetState() const { return m_current.state; }104105/// \returns the base address of the runtime linker in the inferiors address106/// space.107lldb::addr_t GetLDBase() const { return m_current.ldbase; }108109/// \returns the thread layout metadata from the inferiors thread library.110const ThreadInfo &GetThreadInfo();111112/// \returns true if modules have been loaded into the inferior since the113/// last call to Resolve().114bool ModulesDidLoad() const { return !m_added_soentries.empty(); }115116/// \returns true if modules have been unloaded from the inferior since the117/// last call to Resolve().118bool ModulesDidUnload() const { return !m_removed_soentries.empty(); }119120void DumpToLog(lldb_private::Log *log) const;121122/// Constants describing the state of the rendezvous.123///124/// \see GetState().125enum RendezvousState {126eConsistent = 0,127eAdd,128eDelete,129};130131/// Structure representing the shared objects currently loaded into the132/// inferior process.133///134/// This object is a rough analogue to the struct link_map object which135/// actually lives in the inferiors memory.136struct SOEntry {137lldb::addr_t link_addr; ///< Address of this link_map.138lldb::addr_t base_addr; ///< Base address of the loaded object.139lldb::addr_t path_addr; ///< String naming the shared object.140lldb::addr_t dyn_addr; ///< Dynamic section of shared object.141lldb::addr_t next; ///< Address of next so_entry.142lldb::addr_t prev; ///< Address of previous so_entry.143std::string path; ///< File name of shared object.144145SOEntry() { clear(); }146147bool operator==(const SOEntry &entry) { return this->path == entry.path; }148149void clear() {150link_addr = 0;151base_addr = 0;152path_addr = 0;153dyn_addr = 0;154next = 0;155prev = 0;156path.clear();157}158};159160protected:161typedef std::list<SOEntry> SOEntryList;162163public:164typedef SOEntryList::const_iterator iterator;165166/// Iterators over all currently loaded modules.167iterator begin() const { return m_soentries.begin(); }168iterator end() const { return m_soentries.end(); }169170/// Iterators over all modules loaded into the inferior since the last call171/// to Resolve().172iterator loaded_begin() const { return m_added_soentries.begin(); }173iterator loaded_end() const { return m_added_soentries.end(); }174175/// Iterators over all modules unloaded from the inferior since the last176/// call to Resolve().177iterator unloaded_begin() const { return m_removed_soentries.begin(); }178iterator unloaded_end() const { return m_removed_soentries.end(); }179180protected:181lldb_private::Process *m_process;182183// Cached copy of executable pathname184char m_exe_path[PATH_MAX];185186/// Location of the r_debug structure in the inferiors address space.187lldb::addr_t m_rendezvous_addr;188189/// Current and previous snapshots of the rendezvous structure.190Rendezvous m_current;191Rendezvous m_previous;192193/// List of SOEntry objects corresponding to the current link map state.194SOEntryList m_soentries;195196/// List of SOEntry's added to the link map since the last call to197/// Resolve().198SOEntryList m_added_soentries;199200/// List of SOEntry's removed from the link map since the last call to201/// Resolve().202SOEntryList m_removed_soentries;203204/// Threading metadata read from the inferior.205ThreadInfo m_thread_info;206207/// Reads an unsigned integer of \p size bytes from the inferior's address208/// space starting at \p addr.209///210/// \returns addr + size if the read was successful and false otherwise.211lldb::addr_t ReadWord(lldb::addr_t addr, uint64_t *dst, size_t size);212213/// Reads an address from the inferior's address space starting at \p addr.214///215/// \returns addr + target address size if the read was successful and216/// 0 otherwise.217lldb::addr_t ReadPointer(lldb::addr_t addr, lldb::addr_t *dst);218219/// Reads a null-terminated C string from the memory location starting at @p220/// addr.221std::string ReadStringFromMemory(lldb::addr_t addr);222223/// Reads an SOEntry starting at \p addr.224bool ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry);225226/// Updates the current set of SOEntries, the set of added entries, and the227/// set of removed entries.228bool UpdateSOEntries();229230bool UpdateSOEntriesForAddition();231232bool UpdateSOEntriesForDeletion();233234/// Reads the current list of shared objects according to the link map235/// supplied by the runtime linker.236bool TakeSnapshot(SOEntryList &entry_list);237238enum PThreadField { eSize, eNElem, eOffset };239240bool FindMetadata(const char *name, PThreadField field, uint32_t &value);241};242243#endif // LLDB_SOURCE_PLUGINS_DYNAMICLOADER_HEXAGON_DYLD_HEXAGONDYLDRENDEZVOUS_H244245246