forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			246 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			246 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			C++
		
	
	
	
| //===-- DynamicLoaderDarwin.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_DynamicLoaderDarwin_h_
 | |
| #define liblldb_DynamicLoaderDarwin_h_
 | |
| 
 | |
| // C Includes
 | |
| // C++ Includes
 | |
| #include <map>
 | |
| #include <mutex>
 | |
| #include <vector>
 | |
| 
 | |
| // Other libraries and framework includes
 | |
| // Project includes
 | |
| #include "lldb/Target/DynamicLoader.h"
 | |
| #include "lldb/Target/Process.h"
 | |
| #include "lldb/Utility/FileSpec.h"
 | |
| #include "lldb/Utility/SafeMachO.h"
 | |
| #include "lldb/Utility/StructuredData.h"
 | |
| #include "lldb/Utility/UUID.h"
 | |
| 
 | |
| #include "llvm/ADT/Triple.h"
 | |
| 
 | |
| namespace lldb_private {
 | |
| 
 | |
| class DynamicLoaderDarwin : public lldb_private::DynamicLoader {
 | |
| public:
 | |
|   DynamicLoaderDarwin(lldb_private::Process *process);
 | |
| 
 | |
|   virtual ~DynamicLoaderDarwin() override;
 | |
| 
 | |
|   //------------------------------------------------------------------
 | |
|   /// Called after attaching a process.
 | |
|   ///
 | |
|   /// Allow DynamicLoader plug-ins to execute some code after
 | |
|   /// attaching to a process.
 | |
|   //------------------------------------------------------------------
 | |
|   void DidAttach() override;
 | |
| 
 | |
|   void DidLaunch() override;
 | |
| 
 | |
|   lldb::ThreadPlanSP GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
 | |
|                                                   bool stop_others) override;
 | |
| 
 | |
|   size_t FindEquivalentSymbols(
 | |
|       lldb_private::Symbol *original_symbol,
 | |
|       lldb_private::ModuleList &module_list,
 | |
|       lldb_private::SymbolContextList &equivalent_symbols) override;
 | |
| 
 | |
|   lldb::addr_t GetThreadLocalData(const lldb::ModuleSP module,
 | |
|                                   const lldb::ThreadSP thread,
 | |
|                                   lldb::addr_t tls_file_addr) override;
 | |
| 
 | |
|   bool AlwaysRelyOnEHUnwindInfo(lldb_private::SymbolContext &sym_ctx) override;
 | |
| 
 | |
|   virtual void DoInitialImageFetch() = 0;
 | |
| 
 | |
|   virtual bool NeedToDoInitialImageFetch() = 0;
 | |
| 
 | |
| protected:
 | |
|   void PrivateInitialize(lldb_private::Process *process);
 | |
| 
 | |
|   void PrivateProcessStateChanged(lldb_private::Process *process,
 | |
|                                   lldb::StateType state);
 | |
| 
 | |
|   void Clear(bool clear_process);
 | |
| 
 | |
|   // Clear method for classes derived from this one
 | |
|   virtual void DoClear() = 0;
 | |
| 
 | |
|   void SetDYLDModule(lldb::ModuleSP &dyld_module_sp);
 | |
| 
 | |
|   lldb::ModuleSP GetDYLDModule();
 | |
| 
 | |
|   class Segment {
 | |
|   public:
 | |
|     Segment()
 | |
|         : name(), vmaddr(LLDB_INVALID_ADDRESS), vmsize(0), fileoff(0),
 | |
|           filesize(0), maxprot(0), initprot(0), nsects(0), flags(0) {}
 | |
| 
 | |
|     lldb_private::ConstString name;
 | |
|     lldb::addr_t vmaddr;
 | |
|     lldb::addr_t vmsize;
 | |
|     lldb::addr_t fileoff;
 | |
|     lldb::addr_t filesize;
 | |
|     uint32_t maxprot;
 | |
|     uint32_t initprot;
 | |
|     uint32_t nsects;
 | |
|     uint32_t flags;
 | |
| 
 | |
|     bool operator==(const Segment &rhs) const {
 | |
|       return name == rhs.name && vmaddr == rhs.vmaddr && vmsize == rhs.vmsize;
 | |
|     }
 | |
| 
 | |
|     void PutToLog(lldb_private::Log *log, lldb::addr_t slide) const;
 | |
|   };
 | |
| 
 | |
|   struct ImageInfo {
 | |
|     lldb::addr_t address;  // Address of mach header for this dylib
 | |
|     lldb::addr_t slide;    // The amount to slide all segments by if there is a
 | |
|                            // global slide.
 | |
|     lldb::addr_t mod_date; // Modification date for this dylib
 | |
|     lldb_private::FileSpec file_spec; // Resolved path for this dylib
 | |
|     lldb_private::UUID
 | |
|         uuid; // UUID for this dylib if it has one, else all zeros
 | |
|     llvm::MachO::mach_header header; // The mach header for this image
 | |
|     std::vector<Segment> segments;   // All segment vmaddr and vmsize pairs for
 | |
|                                    // this executable (from memory of inferior)
 | |
|     uint32_t load_stop_id; // The process stop ID that the sections for this
 | |
|                            // image were loaded
 | |
|     llvm::Triple::OSType os_type;   // LC_VERSION_MIN_... load command os type
 | |
|     std::string min_version_os_sdk; // LC_VERSION_MIN_... sdk value
 | |
| 
 | |
|     ImageInfo()
 | |
|         : address(LLDB_INVALID_ADDRESS), slide(0), mod_date(0), file_spec(),
 | |
|           uuid(), header(), segments(), load_stop_id(0),
 | |
|           os_type(llvm::Triple::OSType::UnknownOS), min_version_os_sdk() {}
 | |
| 
 | |
|     void Clear(bool load_cmd_data_only) {
 | |
|       if (!load_cmd_data_only) {
 | |
|         address = LLDB_INVALID_ADDRESS;
 | |
|         slide = 0;
 | |
|         mod_date = 0;
 | |
|         file_spec.Clear();
 | |
|         ::memset(&header, 0, sizeof(header));
 | |
|       }
 | |
|       uuid.Clear();
 | |
|       segments.clear();
 | |
|       load_stop_id = 0;
 | |
|       os_type = llvm::Triple::OSType::UnknownOS;
 | |
|       min_version_os_sdk.clear();
 | |
|     }
 | |
| 
 | |
|     bool operator==(const ImageInfo &rhs) const {
 | |
|       return address == rhs.address && slide == rhs.slide &&
 | |
|              mod_date == rhs.mod_date && file_spec == rhs.file_spec &&
 | |
|              uuid == rhs.uuid &&
 | |
|              memcmp(&header, &rhs.header, sizeof(header)) == 0 &&
 | |
|              segments == rhs.segments && os_type == rhs.os_type;
 | |
|     }
 | |
| 
 | |
|     bool UUIDValid() const { return uuid.IsValid(); }
 | |
| 
 | |
|     uint32_t GetAddressByteSize() {
 | |
|       if (header.cputype) {
 | |
|         if (header.cputype & llvm::MachO::CPU_ARCH_ABI64)
 | |
|           return 8;
 | |
|         else
 | |
|           return 4;
 | |
|       }
 | |
|       return 0;
 | |
|     }
 | |
| 
 | |
|     lldb_private::ArchSpec GetArchitecture() const {
 | |
|       return lldb_private::ArchSpec(lldb_private::eArchTypeMachO,
 | |
|                                     header.cputype, header.cpusubtype);
 | |
|     }
 | |
| 
 | |
|     const Segment *FindSegment(const lldb_private::ConstString &name) const;
 | |
| 
 | |
|     void PutToLog(lldb_private::Log *log) const;
 | |
| 
 | |
|     typedef std::vector<ImageInfo> collection;
 | |
|     typedef collection::iterator iterator;
 | |
|     typedef collection::const_iterator const_iterator;
 | |
|   };
 | |
| 
 | |
|   bool UpdateImageLoadAddress(lldb_private::Module *module, ImageInfo &info);
 | |
| 
 | |
|   bool UnloadModuleSections(lldb_private::Module *module, ImageInfo &info);
 | |
| 
 | |
|   lldb::ModuleSP FindTargetModuleForImageInfo(ImageInfo &image_info,
 | |
|                                               bool can_create,
 | |
|                                               bool *did_create_ptr);
 | |
| 
 | |
|   void UnloadImages(const std::vector<lldb::addr_t> &solib_addresses);
 | |
| 
 | |
|   void UnloadAllImages();
 | |
| 
 | |
|   virtual bool SetNotificationBreakpoint() = 0;
 | |
| 
 | |
|   virtual void ClearNotificationBreakpoint() = 0;
 | |
| 
 | |
|   virtual bool DidSetNotificationBreakpoint() = 0;
 | |
| 
 | |
|   typedef std::map<uint64_t, lldb::addr_t> PthreadKeyToTLSMap;
 | |
|   typedef std::map<lldb::user_id_t, PthreadKeyToTLSMap> ThreadIDToTLSMap;
 | |
| 
 | |
|   std::recursive_mutex &GetMutex() const { return m_mutex; }
 | |
| 
 | |
|   lldb::ModuleSP GetPThreadLibraryModule();
 | |
| 
 | |
|   lldb_private::Address GetPthreadSetSpecificAddress();
 | |
| 
 | |
|   bool JSONImageInformationIntoImageInfo(
 | |
|       lldb_private::StructuredData::ObjectSP image_details,
 | |
|       ImageInfo::collection &image_infos);
 | |
| 
 | |
|   // If image_infos contains / may contain dyld or executable image, call this
 | |
|   // method
 | |
|   // to keep our internal record keeping of the special binaries up-to-date.
 | |
|   void
 | |
|   UpdateSpecialBinariesFromNewImageInfos(ImageInfo::collection &image_infos);
 | |
| 
 | |
|   // if image_info is a dyld binary, call this method
 | |
|   void UpdateDYLDImageInfoFromNewImageInfo(ImageInfo &image_info);
 | |
| 
 | |
|   // If image_infos contains / may contain executable image, call this method
 | |
|   // to keep our internal record keeping of the special dyld binary up-to-date.
 | |
|   void AddExecutableModuleIfInImageInfos(ImageInfo::collection &image_infos);
 | |
| 
 | |
|   bool AddModulesUsingImageInfos(ImageInfo::collection &image_infos);
 | |
| 
 | |
|   // Whether we should use the new dyld SPI to get shared library information,
 | |
|   // or read
 | |
|   // it directly out of the dyld_all_image_infos.  Whether we use the (newer)
 | |
|   // DynamicLoaderMacOS
 | |
|   // plugin or the (older) DynamicLoaderMacOSX plugin.
 | |
|   static bool UseDYLDSPI(lldb_private::Process *process);
 | |
| 
 | |
|   lldb::ModuleWP m_dyld_module_wp; // the dyld whose file type (mac, ios, etc)
 | |
|                                    // matches the process
 | |
|   lldb::ModuleWP m_libpthread_module_wp;
 | |
|   lldb_private::Address m_pthread_getspecific_addr;
 | |
|   ThreadIDToTLSMap m_tid_to_tls_map;
 | |
|   ImageInfo::collection
 | |
|       m_dyld_image_infos;              // Current shared libraries information
 | |
|   uint32_t m_dyld_image_infos_stop_id; // The process stop ID that
 | |
|                                        // "m_dyld_image_infos" is valid for
 | |
|   ImageInfo m_dyld;
 | |
|   mutable std::recursive_mutex m_mutex;
 | |
| 
 | |
| private:
 | |
|   DISALLOW_COPY_AND_ASSIGN(DynamicLoaderDarwin);
 | |
| };
 | |
| 
 | |
| } // namespace lldb_private
 | |
| 
 | |
| #endif // liblldb_DynamicLoaderDarwin_h_
 |