brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.3 KiB · c34e02e Raw
245 lines · c
1//===-- HexagonDYLDRendezvous.h ---------------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLDB_SOURCE_PLUGINS_DYNAMICLOADER_HEXAGON_DYLD_HEXAGONDYLDRENDEZVOUS_H10#define LLDB_SOURCE_PLUGINS_DYNAMICLOADER_HEXAGON_DYLD_HEXAGONDYLDRENDEZVOUS_H11 12#include <limits.h>13#include <list>14#include <map>15#include <string>16 17#include "lldb/lldb-defines.h"18#include "lldb/lldb-types.h"19 20namespace lldb_private {21class Process;22}23 24/// \class HexagonDYLDRendezvous25/// Interface to the runtime linker.26///27/// A structure is present in a processes memory space which is updated by the28/// runtime liker each time a module is loaded or unloaded.  This class29/// provides an interface to this structure and maintains a consistent30/// snapshot of the currently loaded modules.31class HexagonDYLDRendezvous {32 33  // This structure is used to hold the contents of the debug rendezvous34  // information (struct r_debug) as found in the inferiors memory.  Note that35  // the layout of this struct is not binary compatible, it is simply large36  // enough to hold the information on both 32 and 64 bit platforms.37  struct Rendezvous {38    uint64_t version = 0;39    lldb::addr_t map_addr = LLDB_INVALID_ADDRESS;40    lldb::addr_t brk = LLDB_INVALID_ADDRESS;41    uint64_t state = 0;42    lldb::addr_t ldbase = 0;43 44    Rendezvous() = default;45  };46 47public:48  // Various metadata supplied by the inferior's threading library to describe49  // the per-thread state.50  struct ThreadInfo {51    bool valid;             // whether we read valid metadata52    uint32_t dtv_offset;    // offset of DTV pointer within pthread53    uint32_t dtv_slot_size; // size of one DTV slot54    uint32_t modid_offset;  // offset of module ID within link_map55    uint32_t tls_offset;    // offset of TLS pointer within DTV slot56  };57 58  HexagonDYLDRendezvous(lldb_private::Process *process);59 60  /// Update the internal snapshot of runtime linker rendezvous and recompute61  /// the currently loaded modules.62  ///63  /// This method should be called once one start up, then once each time the64  /// runtime linker enters the function given by GetBreakAddress().65  ///66  /// \returns true on success and false on failure.67  ///68  /// \see GetBreakAddress().69  bool Resolve();70 71  /// \returns true if this rendezvous has been located in the inferiors72  /// address space and false otherwise.73  bool IsValid();74 75  /// \returns the address of the rendezvous structure in the inferiors76  /// address space.77  lldb::addr_t GetRendezvousAddress() const { return m_rendezvous_addr; }78 79  /// Provide the dyld structure address80  void SetRendezvousAddress(lldb::addr_t);81 82  /// \returns the version of the rendezvous protocol being used.83  uint64_t GetVersion() const { return m_current.version; }84 85  /// \returns address in the inferiors address space containing the linked86  /// list of shared object descriptors.87  lldb::addr_t GetLinkMapAddress() const { return m_current.map_addr; }88 89  /// A breakpoint should be set at this address and Resolve called on each90  /// hit.91  ///92  /// \returns the address of a function called by the runtime linker each93  /// time a module is loaded/unloaded, or about to be loaded/unloaded.94  ///95  /// \see Resolve()96  lldb::addr_t GetBreakAddress() const { return m_current.brk; }97 98  /// In hexagon it is possible that we can know the dyld breakpoint without99  /// having to find it from the rendezvous structure100  ///101  void SetBreakAddress(lldb::addr_t addr) { m_current.brk = addr; }102 103  /// Returns the current state of the rendezvous structure.104  uint64_t GetState() const { return m_current.state; }105 106  /// \returns the base address of the runtime linker in the inferiors address107  /// space.108  lldb::addr_t GetLDBase() const { return m_current.ldbase; }109 110  /// \returns the thread layout metadata from the inferiors thread library.111  const ThreadInfo &GetThreadInfo();112 113  /// \returns true if modules have been loaded into the inferior since the114  /// last call to Resolve().115  bool ModulesDidLoad() const { return !m_added_soentries.empty(); }116 117  /// \returns true if modules have been unloaded from the inferior since the118  /// last call to Resolve().119  bool ModulesDidUnload() const { return !m_removed_soentries.empty(); }120 121  void DumpToLog(lldb_private::Log *log) const;122 123  /// Constants describing the state of the rendezvous.124  ///125  /// \see GetState().126  enum RendezvousState {127    eConsistent = 0,128    eAdd,129    eDelete,130  };131 132  /// Structure representing the shared objects currently loaded into the133  /// inferior process.134  ///135  /// This object is a rough analogue to the struct link_map object which136  /// actually lives in the inferiors memory.137  struct SOEntry {138    lldb::addr_t link_addr; ///< Address of this link_map.139    lldb::addr_t base_addr; ///< Base address of the loaded object.140    lldb::addr_t path_addr; ///< String naming the shared object.141    lldb::addr_t dyn_addr;  ///< Dynamic section of shared object.142    lldb::addr_t next;      ///< Address of next so_entry.143    lldb::addr_t prev;      ///< Address of previous so_entry.144    std::string path;       ///< File name of shared object.145 146    SOEntry() { clear(); }147 148    bool operator==(const SOEntry &entry) { return this->path == entry.path; }149 150    void clear() {151      link_addr = 0;152      base_addr = 0;153      path_addr = 0;154      dyn_addr = 0;155      next = 0;156      prev = 0;157      path.clear();158    }159  };160 161protected:162  typedef std::list<SOEntry> SOEntryList;163 164public:165  typedef SOEntryList::const_iterator iterator;166 167  /// Iterators over all currently loaded modules.168  iterator begin() const { return m_soentries.begin(); }169  iterator end() const { return m_soentries.end(); }170 171  /// Iterators over all modules loaded into the inferior since the last call172  /// to Resolve().173  iterator loaded_begin() const { return m_added_soentries.begin(); }174  iterator loaded_end() const { return m_added_soentries.end(); }175 176  /// Iterators over all modules unloaded from the inferior since the last177  /// call to Resolve().178  iterator unloaded_begin() const { return m_removed_soentries.begin(); }179  iterator unloaded_end() const { return m_removed_soentries.end(); }180 181protected:182  lldb_private::Process *m_process;183 184  // Cached copy of executable pathname185  char m_exe_path[PATH_MAX];186 187  /// Location of the r_debug structure in the inferiors address space.188  lldb::addr_t m_rendezvous_addr;189 190  /// Current and previous snapshots of the rendezvous structure.191  Rendezvous m_current;192  Rendezvous m_previous;193 194  /// List of SOEntry objects corresponding to the current link map state.195  SOEntryList m_soentries;196 197  /// List of SOEntry's added to the link map since the last call to198  /// Resolve().199  SOEntryList m_added_soentries;200 201  /// List of SOEntry's removed from the link map since the last call to202  /// Resolve().203  SOEntryList m_removed_soentries;204 205  /// Threading metadata read from the inferior.206  ThreadInfo m_thread_info;207 208  /// Reads an unsigned integer of \p size bytes from the inferior's address209  /// space starting at \p addr.210  ///211  /// \returns addr + size if the read was successful and false otherwise.212  lldb::addr_t ReadWord(lldb::addr_t addr, uint64_t *dst, size_t size);213 214  /// Reads an address from the inferior's address space starting at \p addr.215  ///216  /// \returns addr + target address size if the read was successful and217  /// 0 otherwise.218  lldb::addr_t ReadPointer(lldb::addr_t addr, lldb::addr_t *dst);219 220  /// Reads a null-terminated C string from the memory location starting at @p221  /// addr.222  std::string ReadStringFromMemory(lldb::addr_t addr);223 224  /// Reads an SOEntry starting at \p addr.225  bool ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry);226 227  /// Updates the current set of SOEntries, the set of added entries, and the228  /// set of removed entries.229  bool UpdateSOEntries();230 231  bool UpdateSOEntriesForAddition();232 233  bool UpdateSOEntriesForDeletion();234 235  /// Reads the current list of shared objects according to the link map236  /// supplied by the runtime linker.237  bool TakeSnapshot(SOEntryList &entry_list);238 239  enum PThreadField { eSize, eNElem, eOffset };240 241  bool FindMetadata(const char *name, PThreadField field, uint32_t &value);242};243 244#endif // LLDB_SOURCE_PLUGINS_DYNAMICLOADER_HEXAGON_DYLD_HEXAGONDYLDRENDEZVOUS_H245