brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.6 KiB · 37528b8 Raw
255 lines · c
1//===-- DynamicLoaderDarwin.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_MACOSX_DYLD_DYNAMICLOADERDARWIN_H10#define LLDB_SOURCE_PLUGINS_DYNAMICLOADER_MACOSX_DYLD_DYNAMICLOADERDARWIN_H11 12#include <map>13#include <mutex>14#include <vector>15 16#include "lldb/Host/SafeMachO.h"17#include "lldb/Target/DynamicLoader.h"18#include "lldb/Target/Process.h"19#include "lldb/Utility/FileSpec.h"20#include "lldb/Utility/StructuredData.h"21#include "lldb/Utility/UUID.h"22 23#include "llvm/TargetParser/Triple.h"24 25namespace lldb_private {26 27class DynamicLoaderDarwin : public lldb_private::DynamicLoader {28public:29  DynamicLoaderDarwin(lldb_private::Process *process);30 31  ~DynamicLoaderDarwin() override;32 33  /// Called after attaching a process.34  ///35  /// Allow DynamicLoader plug-ins to execute some code after36  /// attaching to a process.37  void DidAttach() override;38 39  void DidLaunch() override;40 41  lldb::ThreadPlanSP GetStepThroughTrampolinePlan(lldb_private::Thread &thread,42                                                  bool stop_others) override;43 44  void FindEquivalentSymbols(45      lldb_private::Symbol *original_symbol,46      lldb_private::ModuleList &module_list,47      lldb_private::SymbolContextList &equivalent_symbols) override;48 49  lldb::addr_t GetThreadLocalData(const lldb::ModuleSP module,50                                  const lldb::ThreadSP thread,51                                  lldb::addr_t tls_file_addr) override;52 53  bool AlwaysRelyOnEHUnwindInfo(lldb_private::SymbolContext &sym_ctx) override;54 55  virtual void DoInitialImageFetch() = 0;56 57  virtual bool NeedToDoInitialImageFetch() = 0;58 59  std::optional<lldb_private::Address> GetStartAddress() override;60 61protected:62  void PrivateInitialize(lldb_private::Process *process);63 64  void PrivateProcessStateChanged(lldb_private::Process *process,65                                  lldb::StateType state);66 67  void Clear(bool clear_process);68 69  // Clear method for classes derived from this one70  virtual void DoClear() = 0;71 72  void SetDYLDModule(lldb::ModuleSP &dyld_module_sp);73 74  lldb::ModuleSP GetDYLDModule();75 76  void ClearDYLDModule();77 78  class Segment {79  public:80    Segment() : name() {}81 82    lldb_private::ConstString name;83    lldb::addr_t vmaddr = LLDB_INVALID_ADDRESS;84    lldb::addr_t vmsize = 0;85    lldb::addr_t fileoff = 0;86    lldb::addr_t filesize = 0;87    uint32_t maxprot = 0;88    uint32_t initprot = 0;89    uint32_t nsects = 0;90    uint32_t flags = 0;91 92    bool operator==(const Segment &rhs) const {93      return name == rhs.name && vmaddr == rhs.vmaddr && vmsize == rhs.vmsize;94    }95 96    void PutToLog(lldb_private::Log *log, lldb::addr_t slide) const;97  };98 99  struct ImageInfo {100    /// Address of mach header for this dylib.101    lldb::addr_t address = LLDB_INVALID_ADDRESS;102    /// The amount to slide all segments by if there is a global103    /// slide.104    lldb::addr_t slide = 0;105    /// Resolved path for this dylib.106    lldb_private::FileSpec file_spec;107    /// UUID for this dylib if it has one, else all zeros.108    lldb_private::UUID uuid;109    /// The mach header for this image.110    llvm::MachO::mach_header header;111    /// All segment vmaddr and vmsize pairs for this executable (from112    /// memory of inferior).113    std::vector<Segment> segments;114    /// The process stop ID that the sections for this image were115    /// loaded.116    uint32_t load_stop_id = 0;117    /// LC_VERSION_MIN_... load command os type.118    llvm::Triple::OSType os_type = llvm::Triple::OSType::UnknownOS;119    /// LC_VERSION_MIN_... load command os environment.120    llvm::Triple::EnvironmentType os_env =121        llvm::Triple::EnvironmentType::UnknownEnvironment;122    /// LC_VERSION_MIN_... SDK.123    std::string min_version_os_sdk;124 125    ImageInfo() = default;126 127    void Clear(bool load_cmd_data_only) {128      if (!load_cmd_data_only) {129        address = LLDB_INVALID_ADDRESS;130        slide = 0;131        file_spec.Clear();132        ::memset(&header, 0, sizeof(header));133      }134      uuid.Clear();135      segments.clear();136      load_stop_id = 0;137      os_type = llvm::Triple::OSType::UnknownOS;138      os_env = llvm::Triple::EnvironmentType::UnknownEnvironment;139      min_version_os_sdk.clear();140    }141 142    bool operator==(const ImageInfo &rhs) const {143      return address == rhs.address && slide == rhs.slide &&144             file_spec == rhs.file_spec && uuid == rhs.uuid &&145             memcmp(&header, &rhs.header, sizeof(header)) == 0 &&146             segments == rhs.segments && os_type == rhs.os_type &&147             os_env == rhs.os_env;148    }149 150    bool UUIDValid() const { return uuid.IsValid(); }151 152    uint32_t GetAddressByteSize() {153      if (header.cputype) {154        if (header.cputype & llvm::MachO::CPU_ARCH_ABI64)155          return 8;156        else157          return 4;158      }159      return 0;160    }161 162    lldb_private::ArchSpec GetArchitecture() const;163 164    const Segment *FindSegment(lldb_private::ConstString name) const;165 166    void PutToLog(lldb_private::Log *log) const;167 168    typedef std::vector<ImageInfo> collection;169    typedef collection::iterator iterator;170    typedef collection::const_iterator const_iterator;171  };172 173  bool UpdateImageLoadAddress(lldb_private::Module *module, ImageInfo &info);174 175  bool UnloadModuleSections(lldb_private::Module *module, ImageInfo &info);176 177  lldb::ModuleSP FindTargetModuleForImageInfo(const ImageInfo &image_info,178                                              bool can_create,179                                              bool *did_create_ptr);180 181  void UnloadImages(const std::vector<lldb::addr_t> &solib_addresses);182 183  void UnloadAllImages();184 185  virtual bool SetNotificationBreakpoint() = 0;186 187  virtual void ClearNotificationBreakpoint() = 0;188 189  virtual bool DidSetNotificationBreakpoint() = 0;190 191  typedef std::map<uint64_t, lldb::addr_t> PthreadKeyToTLSMap;192  typedef std::map<lldb::user_id_t, PthreadKeyToTLSMap> ThreadIDToTLSMap;193 194  std::recursive_mutex &GetMutex() const { return m_mutex; }195 196  lldb::ModuleSP GetPThreadLibraryModule();197 198  lldb_private::Address GetPthreadSetSpecificAddress();199 200  bool JSONImageInformationIntoImageInfo(201      lldb_private::StructuredData::ObjectSP image_details,202      ImageInfo::collection &image_infos);203 204  // Finds/loads modules for a given `image_infos` and returns pairs205  // (ImageInfo, ModuleSP).206  // Prefer using this method rather than calling `FindTargetModuleForImageInfo`207  // directly as this method may load the modules in parallel.208  std::vector<std::pair<ImageInfo, lldb::ModuleSP>>209  PreloadModulesFromImageInfos(const ImageInfo::collection &image_infos);210 211  // If `images` contains / may contain dyld or executable image, call this212  // method to keep our internal record keeping of the special binaries213  // up-to-date.214  void UpdateSpecialBinariesFromPreloadedModules(215      std::vector<std::pair<ImageInfo, lldb::ModuleSP>> &images);216 217  // if image_info is a dyld binary, call this method218  bool UpdateDYLDImageInfoFromNewImageInfo(ImageInfo &image_info);219 220  // If image_infos contains / may contain executable image, call this method221  // to keep our internal record keeping of the special dyld binary up-to-date.222  void AddExecutableModuleIfInImageInfos(ImageInfo::collection &image_infos);223 224  bool AddModulesUsingImageInfos(ImageInfo::collection &image_infos);225  bool AddModulesUsingPreloadedModules(226      std::vector<std::pair<ImageInfo, lldb::ModuleSP>> &images);227 228  // Whether we should use the new dyld SPI to get shared library information,229  // or read230  // it directly out of the dyld_all_image_infos.  Whether we use the (newer)231  // DynamicLoaderMacOS232  // plugin or the (older) DynamicLoaderMacOSX plugin.233  static bool UseDYLDSPI(lldb_private::Process *process);234 235  lldb::ModuleWP m_dyld_module_wp; // the dyld whose file type (mac, ios, etc)236                                   // matches the process237  lldb::ModuleWP m_libpthread_module_wp;238  lldb_private::Address m_pthread_getspecific_addr;239  ThreadIDToTLSMap m_tid_to_tls_map;240  ImageInfo::collection241      m_dyld_image_infos;              // Current shared libraries information242  uint32_t m_dyld_image_infos_stop_id; // The process stop ID that243                                       // "m_dyld_image_infos" is valid for244  ImageInfo m_dyld;245  mutable std::recursive_mutex m_mutex;246 247private:248  DynamicLoaderDarwin(const DynamicLoaderDarwin &) = delete;249  const DynamicLoaderDarwin &operator=(const DynamicLoaderDarwin &) = delete;250};251 252} // namespace lldb_private253 254#endif // LLDB_SOURCE_PLUGINS_DYNAMICLOADER_MACOSX_DYLD_DYNAMICLOADERDARWIN_H255